Compare commits
1 commit
master
...
feature/pi
Author | SHA1 | Date | |
---|---|---|---|
![]() |
ac24fe6e82 |
12 changed files with 214 additions and 71 deletions
|
@ -29,6 +29,7 @@
|
|||
#include <string.h>
|
||||
|
||||
#include "settings.h"
|
||||
#include "config.h"
|
||||
|
||||
#include "tvheadend.h"
|
||||
#include "epg.h"
|
||||
|
@ -181,29 +182,15 @@ channel_class_tags_enum ( void *obj )
|
|||
static void
|
||||
channel_class_icon_notify ( void *obj )
|
||||
{
|
||||
channel_t *ch = obj;
|
||||
if (ch->ch_icon)
|
||||
imagecache_get_id(ch->ch_icon);
|
||||
(void)channel_get_icon(obj);
|
||||
}
|
||||
|
||||
static const void *
|
||||
channel_class_get_imagecache ( void *obj )
|
||||
channel_class_get_icon ( void *obj )
|
||||
{
|
||||
static char buf[512], *r;
|
||||
uint32_t id;
|
||||
channel_t *ch = obj;
|
||||
|
||||
if (!ch->ch_icon) {
|
||||
r = NULL;
|
||||
} else if ((id = imagecache_get_id(ch->ch_icon))) {
|
||||
snprintf(buf, sizeof(buf), "imagecache/%d", id);
|
||||
r = buf;
|
||||
} else {
|
||||
strncpy(buf, ch->ch_icon, sizeof(buf));
|
||||
r = buf;
|
||||
}
|
||||
|
||||
return &r;
|
||||
static const char *s;
|
||||
s = channel_get_icon(obj);
|
||||
return &s;
|
||||
}
|
||||
|
||||
static const char *
|
||||
|
@ -318,16 +305,16 @@ const idclass_t channel_class = {
|
|||
},
|
||||
{
|
||||
.type = PT_STR,
|
||||
.id = "icon",
|
||||
.name = "Icon",
|
||||
.off = offsetof(channel_t, ch_icon),
|
||||
.id = "usericon",
|
||||
.name = "User Icon",
|
||||
.off = offsetof(channel_t, ch_usericon),
|
||||
.notify = channel_class_icon_notify,
|
||||
},
|
||||
{
|
||||
.type = PT_STR,
|
||||
.id = "icon_public_url",
|
||||
.name = "Icon URL",
|
||||
.get = channel_class_get_imagecache,
|
||||
.id = "icon",
|
||||
.name = "Icon",
|
||||
.get = channel_class_get_icon,
|
||||
.opts = PO_RDONLY | PO_NOSAVE | PO_HIDDEN,
|
||||
},
|
||||
{
|
||||
|
@ -502,6 +489,52 @@ channel_get_number ( channel_t *ch )
|
|||
return 0;
|
||||
}
|
||||
|
||||
const char *
|
||||
channel_get_icon ( channel_t *ch )
|
||||
{
|
||||
static __thread char buf[512], buf2[512];
|
||||
channel_service_mapping_t *csm;
|
||||
const char *picon = config_get_picon_path(),
|
||||
*icon = ch->ch_usericon;
|
||||
uint32_t id;
|
||||
|
||||
/* No user icon - try access from services */
|
||||
if (!icon && picon) {
|
||||
LIST_FOREACH(csm, &ch->ch_services, csm_chn_link) {
|
||||
if (!(icon = service_get_channel_icon(csm->csm_svc))) continue;
|
||||
if (strncmp(icon, "picon://", 8)) {
|
||||
icon = NULL;
|
||||
continue;
|
||||
}
|
||||
sprintf(buf2, "%s/%s", picon, icon+8);
|
||||
ch->ch_usericon = strdup(icon);
|
||||
channel_save(ch);
|
||||
idnode_updated(&ch->ch_id);
|
||||
}
|
||||
}
|
||||
|
||||
/* Nothing */
|
||||
if (!icon || !*icon)
|
||||
return NULL;
|
||||
|
||||
/* Picon? */
|
||||
if (!strncmp(icon, "picon://", 8)) {
|
||||
if (!picon) return NULL;
|
||||
sprintf(buf2, "%s/%s", picon, icon+8);
|
||||
icon = buf2;
|
||||
}
|
||||
|
||||
/* Lookup imagecache ID */
|
||||
if ((id = imagecache_get_id(icon))) {
|
||||
snprintf(buf, sizeof(buf), "imagecache/%d", id);
|
||||
|
||||
} else {
|
||||
strncpy(buf, icon, sizeof(buf));
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
/* **************************************************************************
|
||||
* Creation/Deletion
|
||||
* *************************************************************************/
|
||||
|
@ -582,7 +615,7 @@ channel_delete ( channel_t *ch, int delconf )
|
|||
RB_REMOVE(&channels, ch, ch_link);
|
||||
idnode_unlink(&ch->ch_id);
|
||||
free(ch->ch_name);
|
||||
free(ch->ch_icon);
|
||||
free(ch->ch_usericon);
|
||||
free(ch);
|
||||
}
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ typedef struct channel
|
|||
/* Channel info */
|
||||
char *ch_name; // Note: do not access directly!
|
||||
int ch_number;
|
||||
char *ch_icon;
|
||||
char *ch_usericon;
|
||||
struct channel_tag_mapping_list ch_ctms;
|
||||
|
||||
/* Service/subscriptions */
|
||||
|
|
37
src/config.c
37
src/config.c
|
@ -492,7 +492,7 @@ config_migrate_v3 ( void )
|
|||
}
|
||||
|
||||
/*
|
||||
* v3 -> v4 : fix broken DVB network / mux files
|
||||
* v4 -> v5 : fix broken DVB network / mux files
|
||||
*/
|
||||
static void
|
||||
config_migrate_v5 ( void )
|
||||
|
@ -517,6 +517,28 @@ config_migrate_v5 ( void )
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* v5 -> v6 : change channel icon param
|
||||
*/
|
||||
static void
|
||||
config_migrate_v6 ( void )
|
||||
{
|
||||
htsmsg_t *c, *e;
|
||||
htsmsg_field_t *f;
|
||||
const char *str;
|
||||
|
||||
/* Remove linux prefix from class */
|
||||
if ((c = hts_settings_load_r(1, "channel"))) {
|
||||
HTSMSG_FOREACH(f, c) {
|
||||
if (!(e = htsmsg_field_get_map(f))) continue;
|
||||
if (!(str = htsmsg_get_str(e, "icon"))) continue;
|
||||
htsmsg_add_str(e, "usericon", str);
|
||||
htsmsg_delete_field(e, "icon");
|
||||
hts_settings_save(e, "channel/%s", f->hmf_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Migration table
|
||||
*/
|
||||
|
@ -525,7 +547,8 @@ static const config_migrate_t config_migrate_table[] = {
|
|||
config_migrate_v2,
|
||||
config_migrate_v3,
|
||||
config_migrate_v3, // Re-run due to bug in previous version of function
|
||||
config_migrate_v5
|
||||
config_migrate_v5,
|
||||
config_migrate_v6,
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -670,3 +693,13 @@ int config_set_muxconfpath ( const char *path )
|
|||
{
|
||||
return _config_set_str("muxconfpath", path);
|
||||
}
|
||||
|
||||
const char *config_get_picon_path ( void )
|
||||
{
|
||||
return htsmsg_get_str(config, "piconpath");
|
||||
}
|
||||
|
||||
int config_set_picon_path ( const char *str )
|
||||
{
|
||||
return _config_set_str("piconpath", str);
|
||||
}
|
||||
|
|
|
@ -37,4 +37,8 @@ const char *config_get_language ( void );
|
|||
int config_set_language ( const char *str )
|
||||
__attribute__((warn_unused_result));
|
||||
|
||||
const char *config_get_picon_path ( void );
|
||||
int config_set_picon_path ( const char *str )
|
||||
__attribute__((warn_unused_result));
|
||||
|
||||
#endif /* __TVH_CONFIG__H__ */
|
||||
|
|
|
@ -530,6 +530,7 @@ htsp_build_channel(channel_t *ch, const char *method, htsp_connection_t *htsp)
|
|||
channel_tag_t *ct;
|
||||
service_t *t;
|
||||
epg_broadcast_t *now, *next = NULL;
|
||||
const char *icon;
|
||||
|
||||
htsmsg_t *out = htsmsg_create_map();
|
||||
htsmsg_t *tags = htsmsg_create_list();
|
||||
|
@ -539,31 +540,30 @@ htsp_build_channel(channel_t *ch, const char *method, htsp_connection_t *htsp)
|
|||
htsmsg_add_u32(out, "channelNumber", channel_get_number(ch));
|
||||
|
||||
htsmsg_add_str(out, "channelName", channel_get_name(ch));
|
||||
if(ch->ch_icon != NULL) {
|
||||
uint32_t id;
|
||||
struct sockaddr_storage addr;
|
||||
socklen_t addrlen;
|
||||
if ((id = imagecache_get_id(ch->ch_icon))) {
|
||||
if ((icon = channel_get_icon(ch))) {
|
||||
|
||||
/* Handle older clients */
|
||||
if ((strstr(icon, "imagecache") == icon) && htsp->htsp_version < 8) {
|
||||
struct sockaddr_storage addr;
|
||||
socklen_t addrlen;
|
||||
size_t p = 0;
|
||||
char url[256];
|
||||
char buf[50];
|
||||
if (htsp->htsp_version < 8) {
|
||||
addrlen = sizeof(addr);
|
||||
getsockname(htsp->htsp_fd, (struct sockaddr*)&addr, &addrlen);
|
||||
tcp_get_ip_str((struct sockaddr*)&addr, buf, 50);
|
||||
strcpy(url, "http://");
|
||||
p = strlen(url);
|
||||
p += snprintf(url+p, sizeof(url)-p, "%s%s%s:%d%s",
|
||||
(addr.ss_family == AF_INET6)?"[":"",
|
||||
buf,
|
||||
(addr.ss_family == AF_INET6)?"]":"",
|
||||
tvheadend_webui_port,
|
||||
tvheadend_webroot ?: "");
|
||||
}
|
||||
snprintf(url+p, sizeof(url)-p, "/imagecache/%d", id);
|
||||
addrlen = sizeof(addr);
|
||||
getsockname(htsp->htsp_fd, (struct sockaddr*)&addr, &addrlen);
|
||||
tcp_get_ip_str((struct sockaddr*)&addr, buf, 50);
|
||||
strcpy(url, "http://");
|
||||
p = strlen(url);
|
||||
p += snprintf(url+p, sizeof(url)-p, "%s%s%s:%d%s",
|
||||
(addr.ss_family == AF_INET6)?"[":"",
|
||||
buf,
|
||||
(addr.ss_family == AF_INET6)?"]":"",
|
||||
tvheadend_webui_port,
|
||||
tvheadend_webroot ?: "");
|
||||
snprintf(url+p, sizeof(url)-p, "/%s", icon);
|
||||
htsmsg_add_str(out, "channelIcon", url);
|
||||
} else {
|
||||
htsmsg_add_str(out, "channelIcon", ch->ch_icon);
|
||||
htsmsg_add_str(out, "channelIcon", icon);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -44,16 +44,4 @@ uint32_t imagecache_get_id ( const char *url );
|
|||
|
||||
int imagecache_open ( uint32_t id );
|
||||
|
||||
#define htsmsg_add_imageurl(_msg, _fld, _fmt, _url)\
|
||||
{\
|
||||
char _tmp[64];\
|
||||
uint32_t _id = imagecache_get_id(_url);\
|
||||
if (_id) {\
|
||||
snprintf(_tmp, sizeof(_tmp), _fmt, _id);\
|
||||
htsmsg_add_str(_msg, _fld, _tmp);\
|
||||
} else {\
|
||||
htsmsg_add_str(_msg, _fld, _url);\
|
||||
}\
|
||||
}
|
||||
|
||||
#endif /* __IMAGE_CACHE_H__ */
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "input.h"
|
||||
#include "settings.h"
|
||||
#include "dvb_charset.h"
|
||||
#include "config.h"
|
||||
|
||||
/* **************************************************************************
|
||||
* Class definition
|
||||
|
@ -356,6 +357,55 @@ mpegts_service_provider_name ( service_t *s )
|
|||
return ((mpegts_service_t*)s)->s_dvb_provider;
|
||||
}
|
||||
|
||||
static const char *
|
||||
mpegts_service_channel_icon ( service_t *s )
|
||||
{
|
||||
mpegts_service_t *ms = (mpegts_service_t*)s;
|
||||
|
||||
/* DVB? */
|
||||
#if ENABLE_MPEGTS_DVB
|
||||
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;
|
||||
static __thread char buf[1024];
|
||||
dvb_mux_t *mmd = (dvb_mux_t*)ms->s_dvb_mux;
|
||||
|
||||
switch ( mmd->lm_tuning.dmc_fe_type) {
|
||||
case DVB_TYPE_S:
|
||||
if (mmd->lm_tuning.u.dmc_fe_qpsk.orbital_dir == 'E')
|
||||
hash = mmd->lm_tuning.u.dmc_fe_qpsk.orbital_pos;
|
||||
else
|
||||
hash = 0xFFFF - mmd->lm_tuning.u.dmc_fe_qpsk.orbital_pos;
|
||||
hash <<= 16;
|
||||
break;
|
||||
case DVB_TYPE_C:
|
||||
hash = 0xFFFF0000;
|
||||
break;
|
||||
case DVB_TYPE_T:
|
||||
hash = 0xEEEE0000;
|
||||
break;
|
||||
case DVB_TYPE_ATSC:
|
||||
hash = 0xDDDD0000;
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
snprintf(buf, sizeof(buf),
|
||||
"picon://1_0_%X_%X_%X_%X_%X_0_0_0.png",
|
||||
ms->s_dvb_servicetype,
|
||||
ms->s_dvb_service_id,
|
||||
ms->s_dvb_mux->mm_tsid,
|
||||
ms->s_dvb_mux->mm_onid,
|
||||
hash);
|
||||
return buf;
|
||||
}
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
mpegts_service_delete ( service_t *t, int delconf )
|
||||
{
|
||||
|
@ -419,6 +469,7 @@ mpegts_service_create0
|
|||
s->s_channel_number = mpegts_service_channel_number;
|
||||
s->s_channel_name = mpegts_service_channel_name;
|
||||
s->s_provider_name = mpegts_service_provider_name;
|
||||
s->s_channel_icon = mpegts_service_channel_icon;
|
||||
|
||||
pthread_mutex_lock(&s->s_stream_mutex);
|
||||
service_make_nicename((service_t*)s);
|
||||
|
|
|
@ -1393,6 +1393,17 @@ service_get_channel_number ( service_t *s )
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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);
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the encryption CAID from a service
|
||||
* only the first CA stream in a service is returned
|
||||
|
|
|
@ -294,6 +294,7 @@ typedef struct service {
|
|||
int (*s_channel_number) (struct service *);
|
||||
const char *(*s_channel_name) (struct service *);
|
||||
const char *(*s_provider_name) (struct service *);
|
||||
const char *(*s_channel_icon) (struct service *);
|
||||
|
||||
/**
|
||||
* Name usable for displaying to user
|
||||
|
@ -538,5 +539,6 @@ void sort_elementary_streams(service_t *t);
|
|||
|
||||
const char *service_get_channel_name (service_t *s);
|
||||
int service_get_channel_number (service_t *s);
|
||||
const char *service_get_channel_icon (service_t *s);
|
||||
|
||||
#endif // SERVICE_H__
|
||||
|
|
|
@ -789,8 +789,8 @@ extjs_epg(http_connection_t *hc, const char *remain, void *opaque)
|
|||
|
||||
htsmsg_add_str(m, "channel", channel_get_name(ch));
|
||||
htsmsg_add_u32(m, "channelid", channel_get_id(ch));
|
||||
if(ch->ch_icon != NULL)
|
||||
htsmsg_add_imageurl(m, "chicon", "imagecache/%d", ch->ch_icon);
|
||||
if ((s = channel_get_icon(ch)))
|
||||
htsmsg_add_str(m, "chicon", s);
|
||||
|
||||
if((s = epg_episode_get_title(ee, lang)))
|
||||
htsmsg_add_str(m, "title", s);
|
||||
|
@ -876,8 +876,8 @@ extjs_epgrelated(http_connection_t *hc, const char *remain, void *opaque)
|
|||
m = htsmsg_create_map();
|
||||
htsmsg_add_u32(m, "id", ebc->id);
|
||||
htsmsg_add_str(m, "channel", channel_get_name(ch));
|
||||
if (ch->ch_icon)
|
||||
htsmsg_add_imageurl(m, "chicon", "imagecache/%d", ch->ch_icon);
|
||||
if ((s = channel_get_icon(ch)))
|
||||
htsmsg_add_str(m, "chicon", s);
|
||||
htsmsg_add_u32(m, "start", ebc->start);
|
||||
htsmsg_add_msg(array, NULL, m);
|
||||
}
|
||||
|
@ -1331,9 +1331,8 @@ extjs_dvrlist(http_connection_t *hc, const char *remain, void *opaque,
|
|||
htsmsg_add_str(m, "channel", DVR_CH_NAME(de));
|
||||
if(de->de_channel != NULL) {
|
||||
htsmsg_add_str(m, "channelid", channel_get_uuid(de->de_channel));
|
||||
if (de->de_channel->ch_icon)
|
||||
htsmsg_add_imageurl(m, "chicon", "imagecache/%d",
|
||||
de->de_channel->ch_icon);
|
||||
if ((s = channel_get_icon(de->de_channel)))
|
||||
htsmsg_add_str(m, "chicon", s);
|
||||
}
|
||||
|
||||
htsmsg_add_str(m, "config_name", de->de_config_name);
|
||||
|
@ -1599,6 +1598,8 @@ extjs_config(http_connection_t *hc, const char *remain, void *opaque)
|
|||
save |= config_set_muxconfpath(str);
|
||||
if ((str = http_arg_get(&hc->hc_req_args, "language")))
|
||||
save |= config_set_language(str);
|
||||
if ((str = http_arg_get(&hc->hc_req_args, "piconpath")))
|
||||
save |= config_set_picon_path(str);
|
||||
if (save)
|
||||
config_save();
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ dumpchannels(htsbuf_queue_t *hq)
|
|||
ch->ch_refcount,
|
||||
ch->ch_zombie,
|
||||
channel_get_number(ch),
|
||||
ch->ch_icon ?: "<none set>");
|
||||
channel_get_icon(ch) ?: "<none set>");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -43,7 +43,8 @@ tvheadend.miscconf = function() {
|
|||
[
|
||||
'muxconfpath', 'language',
|
||||
'tvhtime_update_enabled', 'tvhtime_ntp_enabled',
|
||||
'tvhtime_tolerance', 'transcoding_enabled'
|
||||
'tvhtime_tolerance', 'transcoding_enabled',
|
||||
'piconpath'
|
||||
]);
|
||||
|
||||
/* ****************************************************************
|
||||
|
@ -126,6 +127,25 @@ tvheadend.miscconf = function() {
|
|||
items: [tvhtimeUpdateEnabled, tvhtimeNtpEnabled, tvhtimeTolerance]
|
||||
});
|
||||
|
||||
/*
|
||||
* Picons
|
||||
*/
|
||||
|
||||
var piconPath = new Ext.form.TextField({
|
||||
name: 'piconpath',
|
||||
fieldLabel: 'Picon path (e.g. file:///tmp/picons)',
|
||||
width: 400
|
||||
});
|
||||
|
||||
var piconPanel = new Ext.form.FieldSet({
|
||||
title: 'Picon',
|
||||
width: 700,
|
||||
autoHeight: true,
|
||||
collapsible: true,
|
||||
animCollapse: true,
|
||||
items: [piconPath]
|
||||
});
|
||||
|
||||
/*
|
||||
* Image cache
|
||||
*/
|
||||
|
@ -232,7 +252,7 @@ tvheadend.miscconf = function() {
|
|||
layout: 'form',
|
||||
defaultType: 'textfield',
|
||||
autoHeight: true,
|
||||
items: [languageWrap, dvbscanWrap, tvhtimePanel, transcodingPanel]
|
||||
items: [languageWrap, dvbscanWrap, tvhtimePanel, transcodingPanel, piconPanel]
|
||||
});
|
||||
|
||||
var _items = [confpanel];
|
||||
|
|
Loading…
Add table
Reference in a new issue