#include "streaming.h"
#include "tsfix.h"
-LIST_HEAD(tfstream_list, tfstream);
+#define PTS_MASK 0x1ffffffffLL
#define tsfixprintf(fmt...) // printf(fmt)
+LIST_HEAD(tfstream_list, tfstream);
+
/**
*
*/
streaming_component_type_t tfs_type;
int tfs_bad_dts;
+ int64_t tfs_local_ref;
int64_t tfs_last_dts_norm;
int64_t tfs_dts_epoch;
} tsfix_t;
+/**
+ * Compute the timestamp deltas
+ */
+static int64_t
+tsfix_ts_diff(int64_t ts1, int64_t ts2)
+{
+ int64_t r;
+ ts1 &= PTS_MASK;
+ ts2 &= PTS_MASK;
+
+ r = abs(ts1 - ts2);
+ if (r > (PTS_MASK / 4)) {
+ /* try to wrap the lowest value */
+ if (ts1 < ts2)
+ ts1 += PTS_MASK + 1;
+ else
+ ts2 += PTS_MASK + 1;
+ return abs(ts1 - ts2);
+ }
+ return r;
+}
+
/**
*
*/
tfs->tfs_type = type;
tfs->tfs_index = index;
+ tfs->tfs_local_ref = PTS_UNSET;
tfs->tfs_last_dts_norm = PTS_UNSET;
tfs->tfs_last_dts_in = PTS_UNSET;
tfs->tfs_dts_epoch = 0;
}
-#define PTS_MASK 0x1ffffffffLL
-
/**
*
*/
static void
normalize_ts(tsfix_t *tf, tfstream_t *tfs, th_pkt_t *pkt)
{
- int64_t dts, d;
+ int64_t ref, dts, d;
if(tf->tf_tsref == PTS_UNSET) {
pkt_ref_dec(pkt);
pkt->pkt_pts &= PTS_MASK;
/* Subtract the transport wide start offset */
- dts = pkt->pkt_dts - tf->tf_tsref;
+ ref = tfs->tfs_local_ref != PTS_UNSET ? tfs->tfs_local_ref : tf->tf_tsref;
+ dts = pkt->pkt_dts - ref;
if(tfs->tfs_last_dts_norm == PTS_UNSET) {
if(dts < 0) {
(SCT_ISVIDEO(tfs->tfs_type) && pkt->pkt_frametype == PKT_I_FRAME))) {
tf->tf_tsref = pkt->pkt_dts & PTS_MASK;
tsfixprintf("reference clock set to %"PRId64"\n", tf->tf_tsref);
+ } else {
+ /* For teletext, the encoders might use completely different timestamps */
+ /* If the difference is greater than 2 seconds, use the actual dts value */
+ if (tfs->tfs_type == SCT_TELETEXT && tfs->tfs_local_ref == PTS_UNSET &&
+ tf->tf_tsref != PTS_UNSET) {
+ int64_t diff = tsfix_ts_diff(tf->tf_tsref, pkt->pkt_dts);
+ if (diff > 2 * 90000) {
+ tvhwarn("parser", "The timediff for TELETEXT is big (%"PRId64"), using current dts", diff);
+ tfs->tfs_local_ref = pkt->pkt_dts;
+ } else {
+ tfs->tfs_local_ref = tf->tf_tsref;
+ }
+ }
}
int pdur = pkt->pkt_duration >> pkt->pkt_field;