Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
SAT>IP Server: improve PID handling (using new fcn set)
  • Loading branch information
perexg committed Mar 11, 2015
1 parent c522d71 commit 9a6d096
Show file tree
Hide file tree
Showing 6 changed files with 258 additions and 114 deletions.
1 change: 1 addition & 0 deletions Makefile
Expand Up @@ -230,6 +230,7 @@ SRCS-$(CONFIG_MPEGTS) += \
src/descrambler/descrambler.c \
src/descrambler/caclient.c \
src/input/mpegts.c \
src/input/mpegts/mpegts_pid.c \
src/input/mpegts/mpegts_input.c \
src/input/mpegts/mpegts_network.c \
src/input/mpegts/mpegts_mux.c \
Expand Down
28 changes: 28 additions & 0 deletions src/input/mpegts.h
Expand Up @@ -37,6 +37,8 @@
#define MPEGTS_PID_NONE 0xFFFF

/* Types */
typedef int16_t mpegts_apid_t;
typedef struct mpegts_apids mpegts_apids_t;
typedef struct mpegts_table mpegts_table_t;
typedef struct mpegts_psi_section mpegts_psi_section_t;
typedef struct mpegts_network mpegts_network_t;
Expand Down Expand Up @@ -73,6 +75,31 @@ void mpegts_init ( int linuxdvb_mask, str_list_t *satip_client,
str_list_t *tsfiles, int tstuners );
void mpegts_done ( void );

/* **************************************************************************
* PIDs
* *************************************************************************/

struct mpegts_apids {
mpegts_apid_t *pids;
int alloc;
int count;
int all;
};

int mpegts_pid_init ( mpegts_apids_t *pids, mpegts_apid_t *vals, int count );
void mpegts_pid_done ( mpegts_apids_t *pids );
void mpegts_pid_reset ( mpegts_apids_t *pids );
int mpegts_pid_add ( mpegts_apids_t *pids, mpegts_apid_t pid );
int mpegts_pid_add_group ( mpegts_apids_t *pids, mpegts_apids_t *vals );
int mpegts_pid_del ( mpegts_apids_t *pids, mpegts_apid_t pid );
int mpegts_pid_del_group ( mpegts_apids_t *pids, mpegts_apids_t *vals );
int mpegts_pid_find_index ( mpegts_apids_t *pids, mpegts_apid_t pid );
static inline int mpegts_pid_exists ( mpegts_apids_t *pids, mpegts_apid_t pid )
{ return pids->all || mpegts_pid_find_index(pids, pid) >= 0; }
int mpegts_pid_copy ( mpegts_apids_t *dst, mpegts_apids_t *src );
int mpegts_pid_compare ( mpegts_apids_t *dst, mpegts_apids_t *src,
mpegts_apids_t *add, mpegts_apids_t *del );

/* **************************************************************************
* Data / SI processing
* *************************************************************************/
Expand Down Expand Up @@ -920,6 +947,7 @@ static inline mpegts_service_t *mpegts_service_find_by_uuid(const char *uuid)

void mpegts_service_delete ( service_t *s, int delconf );


/*
* MPEG-TS event handler
*/
Expand Down
172 changes: 172 additions & 0 deletions src/input/mpegts/mpegts_pid.c
@@ -0,0 +1,172 @@
/*
* MPEGTS PID list management
* Copyright (C) 2015 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 "input.h"

int
mpegts_pid_init(mpegts_apids_t *pids, mpegts_apid_t *vals, int count)
{
int alloc = count + 32;
mpegts_apid_t *p = calloc(alloc, sizeof(*pids));

if (p == NULL)
return -1;
pids->pids = p;
pids->alloc = alloc;
pids->all = 0;
if (vals) {
memcpy(p, vals, count * sizeof(*pids));
pids->count = count;
}
return 0;
}

void
mpegts_pid_done(mpegts_apids_t *pids)
{
free(pids->pids);
pids->pids = NULL;
pids->alloc = pids->count = 0;
}

void
mpegts_pid_reset(mpegts_apids_t *pids)
{
pids->alloc = pids->count = 0;
}

int
mpegts_pid_add(mpegts_apids_t *pids, mpegts_apid_t pid)
{
mpegts_apid_t *p;
int i;

assert(pids);
assert(pid >= 0 && pid <= 8191);
if (pids->alloc == pids->count) {
i = pids->alloc + 32;
p = realloc(pids->pids, i * sizeof(*p));
if (p == NULL)
return -1;
pids->pids = p;
pids->alloc = i;
}
p = pids->pids;
for (i = pids->count++; i > 0 && p[i - 1] > pid; i--)
p[i] = p[i - 1];
p[i] = pid;
return 0;
}

int
mpegts_pid_add_group(mpegts_apids_t *pids, mpegts_apids_t *vals)
{
int i, r;

for (i = 0; i < vals->count; i++) {
r = mpegts_pid_add(pids, vals->pids[i]);
if (r)
return r;
}
return 0;
}

int
mpegts_pid_find_index(mpegts_apids_t *pids, mpegts_apid_t pid)
{
mpegts_apid_t *p = pids->pids;
int first = 0, last = pids->count - 1, i;
for (i = last / 2; first <= last; i = (first + last) / 2) {
if (p[i] < pid)
first = i + 1;
else if (p[i] == pid)
return i;
else
last = i - 1;
}
return -1;
}

int
mpegts_pid_del(mpegts_apids_t *pids, mpegts_apid_t pid)
{
int i;

assert(pids);
assert(pid >= 0 && pid <= 8191);
if ((i = mpegts_pid_find_index(pids, pid)) >= 0) {
memmove(&pids->pids[i], &pids->pids[i+1],
(pids->count - i - 1) * sizeof(mpegts_apid_t));
pids->count--;
return 0;
} else {
return -1;
}
}

int
mpegts_pid_del_group(mpegts_apids_t *pids, mpegts_apids_t *vals)
{
int i, r;

for (i = 0; i < vals->count; i++) {
r = mpegts_pid_del(pids, vals->pids[i]);
if (r)
return r;
}
return 0;
}

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->alloc = i;
}
dst->count = src->count;
dst->all = src->all;
memcpy(dst->pids, src->pids, src->count * sizeof(mpegts_apid_t));
return 0;
}

int
mpegts_pid_compare(mpegts_apids_t *dst, mpegts_apids_t *src,
mpegts_apids_t *add, mpegts_apids_t *del)
{
int i;

if (mpegts_pid_init(add, NULL, 0) ||
mpegts_pid_init(del, NULL, 0))
return -1;
for (i = 0; i < src->count; i++)
if (mpegts_pid_find_index(dst, src->pids[i]) < 0)
mpegts_pid_add(del, src->pids[i]);
for (i = 0; i < dst->count; i++)
if (mpegts_pid_find_index(src, dst->pids[i]) < 0)
mpegts_pid_add(add, dst->pids[i]);
return add->count || del->count;
}
25 changes: 15 additions & 10 deletions src/satip/rtp.c
Expand Up @@ -41,7 +41,7 @@ typedef struct satip_rtp_session {
int frontend;
int source;
dvb_mux_conf_t dmc;
int16_t pids[RTSP_PIDS];
mpegts_apids_t pids;
udp_multisend_t um;
struct iovec *um_iovec;
int um_packet;
Expand Down Expand Up @@ -109,15 +109,18 @@ static int
satip_rtp_loop(satip_rtp_session_t *rtp, uint8_t *data, int len)
{
int i, j, pid, last_pid = -1, r;
int16_t *pids = rtp->pids;
mpegts_apid_t *pids = rtp->pids.pids;
struct iovec *v = rtp->um_iovec + rtp->um_packet;

assert((len % 188) == 0);
for ( ; len >= 188 ; data += 188, len -= 188) {
pid = ((data[1] & 0x1f) << 8) | data[2];
if (pid != last_pid) {
for (i = 0, j = -1; i < RTSP_PIDS && (j = pids[i]) >= 0; i++)
if (pid != last_pid && !rtp->pids.all) {
for (i = 0; i < rtp->pids.count; i++) {
j = pids[i];
if (pid < j) break;
if (j == pid) goto found;
}
continue;
found:
last_pid = pid;
Expand Down Expand Up @@ -238,7 +241,7 @@ void satip_rtp_queue(void *id, th_subscription_t *subs,
struct sockaddr_storage *peer, int port,
int fd_rtp, int fd_rtcp,
int frontend, int source, dvb_mux_conf_t *dmc,
int16_t *pids)
mpegts_apids_t *pids)
{
satip_rtp_session_t *rtp = calloc(1, sizeof(*rtp));

Expand All @@ -254,7 +257,8 @@ void satip_rtp_queue(void *id, th_subscription_t *subs,
rtp->fd_rtcp = fd_rtcp;
rtp->subs = subs;
rtp->sq = sq;
memcpy(rtp->pids, pids, sizeof(*pids)*RTSP_PIDS);
mpegts_pid_init(&rtp->pids, NULL, pids->count);
mpegts_pid_copy(&rtp->pids, pids);
udp_multisend_init(&rtp->um, RTP_PACKETS, RTP_PAYLOAD, &rtp->um_iovec);
satip_rtp_header(rtp);
rtp->frontend = frontend;
Expand All @@ -268,15 +272,15 @@ void satip_rtp_queue(void *id, th_subscription_t *subs,
pthread_mutex_unlock(&satip_rtp_lock);
}

void satip_rtp_update_pids(void *id, int16_t *pids)
void satip_rtp_update_pids(void *id, mpegts_apids_t *pids)
{
satip_rtp_session_t *rtp;

pthread_mutex_lock(&satip_rtp_lock);
rtp = satip_rtp_find(id);
if (rtp) {
pthread_mutex_lock(&rtp->lock);
memcpy(rtp->pids, pids, sizeof(*pids)*RTSP_PIDS);
mpegts_pid_copy(&rtp->pids, pids);
pthread_mutex_unlock(&rtp->lock);
}
pthread_mutex_unlock(&satip_rtp_lock);
Expand All @@ -299,6 +303,7 @@ void satip_rtp_close(void *id)
pthread_mutex_unlock(&satip_rtp_lock);
pthread_join(rtp->tid, NULL);
udp_multisend_free(&rtp->um);
mpegts_pid_done(&rtp->pids);
free(rtp);
} else {
pthread_mutex_unlock(&satip_rtp_lock);
Expand Down Expand Up @@ -365,8 +370,8 @@ satip_rtcp_build(satip_rtp_session_t *rtp, uint8_t *msg)
}

pids[0] = 0;
for (i = len = 0; i < RTSP_PIDS && rtp->pids[i] >= 0; i++)
len += snprintf(pids + len, sizeof(pids) - len, "%d,", rtp->pids[i]);
for (i = len = 0; i < rtp->pids.count; i++)
len += snprintf(pids + len, sizeof(pids) - len, "%d,", rtp->pids.pids[i]);
if (len && pids[len-1] == ',')
pids[len-1] = '\0';

Expand Down

0 comments on commit 9a6d096

Please sign in to comment.