factor out MPEG Transport Stream stuff from transport.[ch] to ts.[ch]

This commit is contained in:
Andreas Öman 2007-09-30 09:58:23 +00:00
parent 9dfe20d357
commit 9b56068c75
9 changed files with 207 additions and 107 deletions

View file

@ -1,7 +1,7 @@
-include ../config.mak
SRCS = main.c dispatch.c channels.c transports.c teletext.c psi.c \
subscriptions.c
subscriptions.c ts.c
SRCS += pvr.c pvr_rec.c

View file

@ -41,6 +41,7 @@
#include "channels.h"
#include "transports.h"
#include "dvb_support.h"
#include "ts.h"
static void dvr_fd_callback(int events, void *opaque, int fd);
@ -74,7 +75,7 @@ dvb_dvr_process_packets(th_dvb_adapter_t *tda, uint8_t *tsb, int r)
while(r >= 188) {
pid = (tsb[1] & 0x1f) << 8 | tsb[2];
LIST_FOREACH(t, &tda->tda_transports, tht_adapter_link)
transport_recv_tsb(t, pid, tsb, 1, AV_NOPTS_VALUE);
ts_recv_tsb(t, pid, tsb, 1, AV_NOPTS_VALUE);
r -= 188;
tsb += 188;
}

View file

@ -40,6 +40,7 @@
#include "transports.h"
#include "dispatch.h"
#include "psi.h"
#include "ts.h"
static struct th_transport_list iptv_probing_transports;
static struct th_transport_list iptv_stale_transports;
@ -61,7 +62,7 @@ iptv_fd_callback(int events, void *opaque, int fd)
while(r >= 188) {
pid = (tsb[1] & 0x1f) << 8 | tsb[2];
transport_recv_tsb(t, pid, tsb, 1, AV_NOPTS_VALUE);
ts_recv_tsb(t, pid, tsb, 1, AV_NOPTS_VALUE);
r -= 188;
tsb += 188;
}
@ -221,7 +222,7 @@ iptv_configure_transport(th_transport_t *t, const char *iptv_type,
ifname, inet_ntoa(t->tht_iptv_group_addr), t->tht_iptv_port);
t->tht_name = strdup(buf);
pi = transport_add_pid(t, 0, HTSTV_TABLE);
pi = ts_add_pid(t, 0, HTSTV_TABLE);
pi->tp_got_section = iptv_parse_pat;
t->tht_channel = channel_find(channel_name, 1);

5
psi.c
View file

@ -27,6 +27,7 @@
#include "psi.h"
#include "transports.h"
#include "dvb_support.h"
#include "ts.h"
int
psi_section_reassemble(psi_section_t *ps, uint8_t *data, int len,
@ -86,7 +87,7 @@ psi_parse_pat(th_transport_t *t, uint8_t *ptr, int len,
pid = (ptr[2] & 0x1f) << 8 | ptr[3];
if(prognum != 0) {
pi = transport_add_pid(t, pid, HTSTV_TABLE);
pi = ts_add_pid(t, pid, HTSTV_TABLE);
pi->tp_got_section = pmt_callback;
}
@ -193,7 +194,7 @@ psi_parse_pmt(th_transport_t *t, uint8_t *ptr, int len, int chksvcid)
}
if(hts_stream_type != 0)
transport_add_pid(t, pid, hts_stream_type);
ts_add_pid(t, pid, hts_stream_type);
}
return 0;
}

View file

@ -171,98 +171,6 @@ transport_compute_weight(struct th_transport_list *head)
/*
* Process transport stream packets
*/
void
transport_recv_tsb(th_transport_t *t, int pid, uint8_t *tsb, int scanpcr,
int64_t pcr)
{
th_pid_t *pi = NULL;
th_subscription_t *s;
int cc, err = 0, afc, afl = 0;
int len, pusi;
LIST_FOREACH(pi, &t->tht_pids, tp_link)
if(pi->tp_pid == pid)
break;
if(pi == NULL)
return;
avgstat_add(&t->tht_rate, 188, dispatch_clock);
afc = (tsb[3] >> 4) & 3;
if(afc & 1) {
cc = tsb[3] & 0xf;
if(pi->tp_cc_valid && cc != pi->tp_cc) {
/* Incorrect CC */
avgstat_add(&t->tht_cc_errors, 1, dispatch_clock);
err = 1;
}
pi->tp_cc_valid = 1;
pi->tp_cc = (cc + 1) & 0xf;
}
if(afc & 2) {
afl = tsb[4] + 1;
if(afl > 0 && scanpcr && tsb[5] & 0x10) {
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;
}
}
switch(pi->tp_type) {
case HTSTV_TABLE:
if(pi->tp_section == NULL)
pi->tp_section = calloc(1, sizeof(struct psi_section));
afl += 4;
if(err || afl >= 188) {
pi->tp_section->ps_offset = -1; /* hold parser until next pusi */
break;
}
pusi = tsb[1] & 0x40;
if(pusi) {
len = tsb[afl++];
if(len > 0) {
if(len > 188 - afl)
break;
if(!psi_section_reassemble(pi->tp_section, tsb + afl, len, 0, 1))
pi->tp_got_section(t, pi, pi->tp_section->ps_data,
pi->tp_section->ps_offset);
afl += len;
}
}
if(!psi_section_reassemble(pi->tp_section, tsb + afl, 188 - afl, pusi, 1))
pi->tp_got_section(t, pi, pi->tp_section->ps_data,
pi->tp_section->ps_offset);
break;
case HTSTV_TELETEXT:
teletext_input(t, tsb);
break;
default:
LIST_FOREACH(s, &t->tht_subscriptions, ths_transport_link) {
s->ths_total_err += err;
s->ths_callback(s, tsb, pi, pcr);
}
break;
}
}
static void

View file

@ -25,14 +25,8 @@ unsigned int transport_compute_weight(struct th_transport_list *head);
void transport_flush_subscribers(th_transport_t *t);
void transport_recv_tsb(th_transport_t *t, int pid, uint8_t *tsb,
int scanpcr, int64_t pcr);
void transport_monitor_init(th_transport_t *t);
th_pid_t *transport_add_pid(th_transport_t *t, uint16_t pid,
tv_streamtype_t type);
int transport_set_channel(th_transport_t *th, th_channel_t *ch);
void transport_link(th_transport_t *t, th_channel_t *ch);

167
ts.c Normal file
View file

@ -0,0 +1,167 @@
/*
* tvheadend, MPEG transport stream functions
* Copyright (C) 2007 Andreas Öman
*
* 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 <pthread.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <linux/dvb/frontend.h>
#include <linux/dvb/dmx.h>
#include <libhts/htscfg.h>
#include <ffmpeg/avcodec.h>
#include "tvhead.h"
#include "dispatch.h"
#include "dvb_dvr.h"
#include "teletext.h"
#include "transports.h"
#include "subscriptions.h"
#include "v4l.h"
#include "dvb_dvr.h"
#include "iptv_input.h"
#include "psi.h"
/*
* Process transport stream packets
*/
void
ts_recv_tsb(th_transport_t *t, int pid, uint8_t *tsb, int scanpcr, int64_t pcr)
{
th_pid_t *pi = NULL;
th_subscription_t *s;
int cc, err = 0, afc, afl = 0;
int len, pusi;
LIST_FOREACH(pi, &t->tht_pids, tp_link)
if(pi->tp_pid == pid)
break;
if(pi == NULL)
return;
avgstat_add(&t->tht_rate, 188, dispatch_clock);
afc = (tsb[3] >> 4) & 3;
if(afc & 1) {
cc = tsb[3] & 0xf;
if(pi->tp_cc_valid && cc != pi->tp_cc) {
/* Incorrect CC */
avgstat_add(&t->tht_cc_errors, 1, dispatch_clock);
err = 1;
}
pi->tp_cc_valid = 1;
pi->tp_cc = (cc + 1) & 0xf;
}
if(afc & 2) {
afl = tsb[4] + 1;
if(afl > 0 && scanpcr && tsb[5] & 0x10) {
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;
}
}
switch(pi->tp_type) {
case HTSTV_TABLE:
if(pi->tp_section == NULL)
pi->tp_section = calloc(1, sizeof(struct psi_section));
afl += 4;
if(err || afl >= 188) {
pi->tp_section->ps_offset = -1; /* hold parser until next pusi */
break;
}
pusi = tsb[1] & 0x40;
if(pusi) {
len = tsb[afl++];
if(len > 0) {
if(len > 188 - afl)
break;
if(!psi_section_reassemble(pi->tp_section, tsb + afl, len, 0, 1))
pi->tp_got_section(t, pi, pi->tp_section->ps_data,
pi->tp_section->ps_offset);
afl += len;
}
}
if(!psi_section_reassemble(pi->tp_section, tsb + afl, 188 - afl, pusi, 1))
pi->tp_got_section(t, pi, pi->tp_section->ps_data,
pi->tp_section->ps_offset);
break;
case HTSTV_TELETEXT:
teletext_input(t, tsb);
break;
default:
LIST_FOREACH(s, &t->tht_subscriptions, ths_transport_link) {
s->ths_total_err += err;
s->ths_callback(s, tsb, pi, pcr);
}
break;
}
}
/*
*
*/
th_pid_t *
ts_add_pid(th_transport_t *t, uint16_t pid, tv_streamtype_t type)
{
th_pid_t *pi;
int i = 0;
LIST_FOREACH(pi, &t->tht_pids, tp_link) {
i++;
if(pi->tp_pid == pid)
return pi;
}
pi = calloc(1, sizeof(th_pid_t));
pi->tp_index = i;
pi->tp_pid = pid;
pi->tp_type = type;
pi->tp_demuxer_fd = -1;
LIST_INSERT_HEAD(&t->tht_pids, pi, tp_link);
return pi;
}

27
ts.h Normal file
View file

@ -0,0 +1,27 @@
/*
* tvheadend, MPEG transport stream functions
* Copyright (C) 2007 Andreas Öman
*
* 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/>.
*/
#ifndef TS_H
#define TS_H
void ts_recv_tsb(th_transport_t *t, int pid, uint8_t *tsb,
int scanpcr, int64_t pcr);
th_pid_t *ts_add_pid(th_transport_t *t, uint16_t pid, tv_streamtype_t type);
#endif /* TS_H */

7
v4l.c
View file

@ -45,6 +45,7 @@ extern AVInputFormat mpegps_demuxer;
#include "channels.h"
#include "dispatch.h"
#include "transports.h"
#include "ts.h"
static struct th_v4l_adapter_list v4l_adapters;
@ -92,8 +93,8 @@ v4l_configure_transport(th_transport_t *t, const char *muxname,
t->tht_v4l_frequency =
atoi(config_get_str_sub(&ce->ce_sub, "frequency", "0"));
transport_add_pid(t, 100, HTSTV_MPEG2VIDEO);
transport_add_pid(t, 101, HTSTV_MPEG2AUDIO);
ts_add_pid(t, 100, HTSTV_MPEG2VIDEO);
ts_add_pid(t, 101, HTSTV_MPEG2AUDIO);
snprintf(buf, sizeof(buf), "Analog: %s (%.2f MHz)", muxname,
(float)t->tht_v4l_frequency / 1000000.0f);
@ -554,7 +555,7 @@ v4l_ts_generate(th_v4l_adapter_t *tva, uint8_t *ptr, int len, int type,
LIST_FOREACH(t, &tva->tva_transports, tht_adapter_link) {
transport_recv_tsb(t, p.tp_pid, tsb0, 0, pcr);
ts_recv_tsb(t, p.tp_pid, tsb0, 0, pcr);
pcr = AV_NOPTS_VALUE;
}