Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ SRCS = src/version.c \
src/input.c \
src/http/http_client.c \
src/fsmonitor.c \
src/esfilter.c

SRCS += \
src/api.c \
Expand All @@ -124,7 +125,8 @@ SRCS += \
src/api/api_mpegts.c \
src/api/api_epg.c \
src/api/api_epggrab.c \
src/api/api_imagecache.c
src/api/api_imagecache.c \
src/api/api_esfilter.c

SRCS += \
src/parsers/parsers.c \
Expand Down
98 changes: 98 additions & 0 deletions docs/html/config_esfilter.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
<div class="hts-doc-text">

This table defines rules to filter and order the elementary streams
like video or audio from the input feed.

<p>
The execution order of commands is granted. It means that first rule
is executed for all available streams then second and so on.

<p>
If any elementary stream is not marked as ignored or exclusive, it is
used. If you like to ignore unknown elementary streams, add a rule
to the end of grid with the any (not defined) comparisons and
with the action ignore.

<p>
The rules for different elementary stream groups (video, audio,
teletext, subtitle, other) are executed separately (as visually edited).

<p>
The rules are listed / edited in a grid.

<ul>
<li>To edit a cell, double click on it. After a cell is changed it
will flags one of its corner to red to indicated that it has been
changed. To commit these changes back to Tvheadend press the
'Save changes' button. In order to change a Checkbox cell you only
have to click once in it.

<li>To add a new entry, press the 'Add entry' button. The new (empty) entry
will be created on the server but will not be in its enabled state.
You can now change all the cells to the desired values, check the
'enable' box and then press 'Save changes' to activate the new entry.

<li>To delete one or more entries, select the lines (by clicking once on
them), and press the 'Delete selected' button. A pop up
will ask you to confirm your request.

<li>To move up or down one or more entries, select the lines (by clicking
once on them), and press the 'Move up' or 'Move down' button.
</ul>

<p>
The columns have the following functions:

<dl>
<dt>Enabled
<dd>If selected, the rule will be enabled.

<dt>Stream Type
<dd>Select the elementary stream type to compare. Empty field means any.

<dt>Language
<dd>Select the language to compare. Empty field means any.

<dt>Service
<dd>The service to compare. Empty field means any.

<dt>PID
<dd>Program identification (PID) number to compare. Zero means any.
This comparison is processed only when service comparison is active.

<dt>Action
<dd>The rule action defines the operation when all comparisons succeeds.

<dl>

<dt>NONE
<dd>No action, may be used for the logging and a comparison verification.

<dt>USE
<dd>Use this elementary stream.

<dt>ONCE
<dd>Use this elementary stream only once per selected language.
The first successfully compared rule wins.

<dt>EXCLUSIVE
<dd>Use only this elementary stream. No other elementary streams
will be used.

<dt>EMPTY
<dd>Add this elementary stream only when no elementary streams are
used from previous rules.

<dt>IGNORE
<dd>Ignore this elementary stream. This stream is not used. Another
successfully compared rule with different action may override it.

</dl>

<dt>Log
<dd>Write a short message to log identifying the matched parameters.
It is useful for debugging your setup or structure of incoming
streams.

</dl>
</div>
1 change: 1 addition & 0 deletions src/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ void api_init ( void )
api_epggrab_init();
api_status_init();
api_imagecache_init();
api_esfilter_init();
}

void api_done ( void )
Expand Down
2 changes: 2 additions & 0 deletions src/api.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,14 @@ 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 );

/*
* IDnode
*/
typedef struct api_idnode_grid_conf
{
int tindex;
int start;
int limit;
idnode_filter_t filter;
Expand Down
96 changes: 96 additions & 0 deletions src/api/api_esfilter.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/*
* API - elementary stream filter related calls
*
* Copyright (C) 2014 Jaroslav Kysela
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include "tvheadend.h"
#include "esfilter.h"
#include "lang_codes.h"
#include "access.h"
#include "api.h"

static void
api_esfilter_grid
( 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);
}
}

static int
api_esfilter_create
( void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp,
esfilter_class_t cls )
{
htsmsg_t *conf;

if (!(conf = htsmsg_get_map(args, "conf")))
return EINVAL;

pthread_mutex_lock(&global_lock);
esfilter_create(cls, NULL, conf, 1);
pthread_mutex_unlock(&global_lock);

return 0;
}

#define ESFILTER(func, t) \
static void api_esfilter_grid_##func \
( idnode_set_t *ins, api_idnode_grid_conf_t *conf, htsmsg_t *args ) \
{ return api_esfilter_grid(ins, conf, args, (t)); } \
static int api_esfilter_create_##func \
( void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) \
{ return api_esfilter_create(opaque, op, args, resp, (t)); }

ESFILTER(video, ESF_CLASS_VIDEO);
ESFILTER(audio, ESF_CLASS_AUDIO);
ESFILTER(teletext, ESF_CLASS_TELETEXT);
ESFILTER(subtit, ESF_CLASS_SUBTIT);
ESFILTER(other, ESF_CLASS_OTHER);

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/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);
}
41 changes: 32 additions & 9 deletions src/api/api_idnode.c
Original file line number Diff line number Diff line change
Expand Up @@ -380,8 +380,8 @@ api_idnode_class
}

static int
api_idnode_delete
( void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp )
api_idnode_handler
( htsmsg_t *args, htsmsg_t **resp, void (*handler)(idnode_t *in) )
{
int err = 0;
idnode_t *in;
Expand All @@ -403,7 +403,7 @@ api_idnode_delete
HTSMSG_FOREACH(f, uuids) {
if (!(uuid = htsmsg_field_get_string(f))) continue;
if (!(in = idnode_find(uuid, NULL))) continue;
idnode_delete(in);
handler(in);
}

/* Single */
Expand All @@ -412,22 +412,45 @@ api_idnode_delete
if (!(in = idnode_find(uuid, NULL)))
err = ENOENT;
else
idnode_delete(in);
handler(in);
}

pthread_mutex_unlock(&global_lock);

return err;
}

static int
api_idnode_delete
( void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp )
{
return api_idnode_handler(args, resp, idnode_delete);
}

static int
api_idnode_moveup
( void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp )
{
return api_idnode_handler(args, resp, idnode_moveup);
}

static int
api_idnode_movedown
( void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp )
{
return api_idnode_handler(args, resp, idnode_movedown);
}

void api_idnode_init ( void )
{
static api_hook_t ah[] = {
{ "idnode/load", ACCESS_ANONYMOUS, api_idnode_load, NULL },
{ "idnode/save", ACCESS_ADMIN, api_idnode_save, NULL },
{ "idnode/tree", ACCESS_ANONYMOUS, api_idnode_tree, NULL },
{ "idnode/class", ACCESS_ANONYMOUS, api_idnode_class, NULL },
{ "idnode/delete", ACCESS_ADMIN, api_idnode_delete, NULL },
{ "idnode/load", ACCESS_ANONYMOUS, api_idnode_load, NULL },
{ "idnode/save", ACCESS_ADMIN, api_idnode_save, NULL },
{ "idnode/tree", ACCESS_ANONYMOUS, api_idnode_tree, NULL },
{ "idnode/class", ACCESS_ANONYMOUS, api_idnode_class, NULL },
{ "idnode/delete", ACCESS_ADMIN, api_idnode_delete, NULL },
{ "idnode/moveup", ACCESS_ADMIN, api_idnode_moveup, NULL },
{ "idnode/movedown", ACCESS_ADMIN, api_idnode_movedown, NULL },
{ NULL },
};

Expand Down
Loading