Add support for commercial break detection using teletext rundown pages

This commit is contained in:
Andreas Öman 2007-08-10 08:13:53 +00:00
parent bce35303aa
commit 26e65f02bd
4 changed files with 66 additions and 21 deletions

View file

@ -1,6 +1,6 @@
include ../config.mak
SRCS = main.c dispatch.c channels.c transports.c
SRCS = main.c dispatch.c channels.c transports.c teletext.c
SRCS += pvr.c pvr_rec.c

View file

@ -103,8 +103,8 @@ pvr_recorder_thread(void *aux)
ts_pid_t *tsp;
void *opaque = NULL;
th_subscription_t *s;
char txt[50];
char txt[50], txt2[50], *t;
LIST_INIT(&pids);
pthread_mutex_lock(&pvr_mutex);
@ -172,8 +172,13 @@ pvr_recorder_thread(void *aux)
txt[0] = 0;
}
syslog(LOG_INFO, "pvr: \"%s\" - Recording started%s",
pvrr->pvrr_printname, txt);
ctime_r(&pvrr->pvrr_stop, txt2);
t = strchr(txt2, '\n');
if(t != NULL)
*t = 0;
syslog(LOG_INFO, "pvr: \"%s\" - Recording started%s, ends at %s",
pvrr->pvrr_printname, txt, txt2);
pvrr->pvrr_status = HTSTV_PVR_STATUS_PAUSED_WAIT_FOR_START;
pvr_inform_status_change(pvrr);
@ -373,12 +378,18 @@ pvr_generate_filename(pvr_rec_t *pvrr)
config_get_str("pvrdir", "."), chname, out);
while(1) {
if(stat(fullname, &st) == -1)
if(stat(fullname, &st) == -1) {
syslog(LOG_DEBUG, "pvr: File \"%s\" -- %s -- Using for recording",
fullname, strerror(errno));
break;
}
tally++;
snprintf(fullname, sizeof(fullname), "%s/%s-%s-%d",
config_get_str("pvrdir", "."), chname, out, tally);
syslog(LOG_DEBUG, "pvr: Testing filename \"%s\"", fullname);
}
pvrr->pvrr_filename = strdup(fullname);
@ -680,6 +691,7 @@ pwo_writepkt(pvr_rec_t *pvrr, th_subscription_t *s, uint32_t startcode,
tv_streamtype_t type)
{
pwo_ffmpeg_t *pf = pvrr->pvrr_opaque;
th_transport_t *th = s->ths_transport;
uint8_t flags, hlen, x;
int64_t dts = AV_NOPTS_VALUE, pts = AV_NOPTS_VALUE;
int r, rlen, i, g, fs;
@ -826,7 +838,7 @@ pwo_writepkt(pvr_rec_t *pvrr, th_subscription_t *s, uint32_t startcode,
switch(pvrr->pvrr_status) {
case HTSTV_PVR_STATUS_PAUSED_WAIT_FOR_START:
case HTSTV_PVR_STATUS_PAUSED_COMMERCIAL:
break;
return 0;
case HTSTV_PVR_STATUS_WAIT_KEY_FRAME:
if(st->codec->codec_type == CODEC_TYPE_VIDEO &&
@ -836,6 +848,13 @@ pwo_writepkt(pvr_rec_t *pvrr, th_subscription_t *s, uint32_t startcode,
return 0;
}
break;
case HTSTV_PVR_STATUS_RECORDING:
if(th != NULL && th->tht_tt_commercial_advice == COMMERCIAL_YES) {
pvrr->pvrr_status = HTSTV_PVR_STATUS_PAUSED_COMMERCIAL;
return 0;
}
default:
break;
}

View file

@ -31,9 +31,9 @@
#include "tvhead.h"
#include "teletext.h"
#include "client.h"
static void teletext_rundown(th_transport_t *t, tt_page_t *ttp);
static void teletext_rundown(th_transport_t *t, th_channel_t *ch,
tt_page_t *ttp);
#define bitreverse(b) \
(((b) * 0x0202020202ULL & 0x010884422010ULL) % 1023)
@ -181,7 +181,7 @@ tt_decode_line(th_transport_t *t, uint8_t *buf)
int page, magidx, i;
tt_mag_t *mag;
th_channel_t *ch = t->tht_channel;
tt_decoder_t *ttd = &ch->thc_tt;
tt_decoder_t *ttd = &ch->ch_tt;
tt_page_t *ttp;
mpag = ham_decode(buf[0], buf[1]);
@ -223,9 +223,9 @@ tt_decode_line(th_transport_t *t, uint8_t *buf)
}
if(update_tt_clock(t, (char *)buf + 34)) {
if(ch->thc_teletext_rundown != 0) {
ttp = tt_get_page(ttd, ch->thc_teletext_rundown);
teletext_rundown(t, ttp);
if(ch->ch_teletext_rundown != 0) {
ttp = tt_get_page(ttd, ch->ch_teletext_rundown);
teletext_rundown(t, ch, ttp);
}
}
@ -255,8 +255,8 @@ tt_decode_line(th_transport_t *t, uint8_t *buf)
break;
}
if(ttp->ttp_page == ch->thc_teletext_rundown)
teletext_rundown(t, ttp);
if(ttp->ttp_page == ch->ch_teletext_rundown)
teletext_rundown(t, ch, ttp);
}
}
@ -308,17 +308,23 @@ tt_time_to_len(const char *buf)
return l;
}
/*
* Decode the Swedish TV4 teletext rundown page to figure out if we are
* currently in a commercial break
*/
static void
teletext_rundown(th_transport_t *t, tt_page_t *ttp)
teletext_rundown(th_transport_t *t, th_channel_t *ch, tt_page_t *ttp)
{
char r[50];
int i;
time_t ti, d, l;
int curlen = -1;
th_commercial_advice_t prev;
#if 0
printf("%c", 0x0c);
printf("%-20s %s",
printf("%-20s %s\n",
t->tht_tt_rundown_content_length > 400 ? "real stuff" : "commercial",
ctime(&t->tht_tt_clock));
#endif
@ -337,12 +343,30 @@ teletext_rundown(th_transport_t *t, tt_page_t *ttp)
/* Currently playing show */
curlen = l;
}
// printf("%02d|%s|\t(%5lds) : %ld, %d\n", i, r, l, d, curlen);
// printf("%02d|%s|\t(%5lds) : %ld, %d\n", i, r, l, d, curlen);
}
t->tht_tt_rundown_content_length = curlen;
prev = t->tht_tt_commercial_advice;
if(curlen < 0) {
t->tht_tt_commercial_advice = COMMERCIAL_UNKNOWN;
return;
}
if(curlen < 400)
t->tht_tt_commercial_advice = COMMERCIAL_YES;
else
t->tht_tt_commercial_advice = COMMERCIAL_NO;
if(prev != t->tht_tt_commercial_advice) {
syslog(LOG_DEBUG,
"teletext-rundown: \"%s\" on \"%s\": "
"%s commercial break (chunk %ds)",
ch->ch_name, t->tht_name,
t->tht_tt_commercial_advice == COMMERCIAL_YES ? "In" : "Not in",
curlen);
}
}

View file

@ -39,7 +39,7 @@
#include "input_dvb.h"
#include "input_v4l.h"
#include "input_iptv.h"
#include "teletext.h"
#include "transports.h"
/*
@ -94,6 +94,8 @@ transport_purge(th_transport_t *t)
default:
break;
}
t->tht_tt_commercial_advice = COMMERCIAL_UNKNOWN;
}
@ -346,7 +348,7 @@ transport_recv_tsb(th_transport_t *t, int pid, uint8_t *tsb)
if(pi->type == HTSTV_TELETEXT) {
/* teletext */
// teletext_input(t, tsb);
teletext_input(t, tsb);
continue;
}