summaryrefslogtreecommitdiffstats
path: root/libhb/decvobsub.c
diff options
context:
space:
mode:
authorJohn Stebbins <[email protected]>2016-05-24 14:12:07 -0700
committerJohn Stebbins <[email protected]>2016-05-24 14:12:07 -0700
commite8c37c88b864f515aacda7a1a8fbcda9ed6b8bad (patch)
tree96b423f89f5a78af0a64db32d64b9dae50c63f67 /libhb/decvobsub.c
parent76595a4b2131536eb3e498b161944057e882d038 (diff)
sync: correct timestamp discontinuities in sync instead of reader (#192)
* sync: correct timestamp discontinuities in sync instead of reader This patch passes discontinuity information through the pipeline till it reaches sync.c. The timestamps are passed through the pipeline as read and unmodified to sync.c (instead of attempting to correct discontinuities in reader). In sync, when we see a discontinuity, we know where the next timestamp should be based on the timestamp and duration of the previous buffer (before the discontinuity). So we calculate an "SCR" offset based on the timestamp after the discontinuity and what we calculate it should be. The old discontinuity handling code was broken due to the following. The MPEG STD timing model relies heavily on the decoder having an STC that is phase lock looped to the PCRs in the stream. When decoding a broadcast stream, the decoder can count on the time measure between PCRs using the STC to match to a high degree of accuracy. I.e. STC - lastSTC == PCR - lastPCR. When a discontinuity occurs, the decoder calculates a new PCR offset = PCR - STC. I.e. the offset is the new PCR value minus what it would have been if there had been no discontinuity. The above does not work without a reliable STC, which we do not have. We have been attempting to approximate one by avereraging the duration of received packets and extrapolating an "STC" based on the last PTS and the average packet duration. But this is highly variable and unreliable. * decavcodec: fix data type of next_pts It needs to be double so that partial ticks are not lost * deccc608sub: clarify comment * sync: allow queueing more audio Audio is small, and there is often a significant amount of audio in the stream before the first video frame. * sync: improve handling of damaged streams When data is missing, the audio decoder was extrapolating timestamps from the last pts before the error caused by the missing data which caused sync issues. Also, missing data can cause the video decoder to output a frame out of order with the wrong scr sequence. Drop such frames.
Diffstat (limited to 'libhb/decvobsub.c')
-rw-r--r--libhb/decvobsub.c46
1 files changed, 30 insertions, 16 deletions
diff --git a/libhb/decvobsub.c b/libhb/decvobsub.c
index 85644c47d..4fb98685b 100644
--- a/libhb/decvobsub.c
+++ b/libhb/decvobsub.c
@@ -38,8 +38,10 @@ struct hb_work_private_s
int size_got;
int size_rle;
int64_t pts;
+ int current_scr_sequence;
int64_t pts_start;
int64_t pts_stop;
+ int scr_sequence;
int pts_forced;
int x;
int y;
@@ -127,7 +129,8 @@ int decsubWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
pv->size_got = in->size;
if( in->s.start >= 0 )
{
- pv->pts = in->s.start;
+ pv->pts = in->s.start;
+ pv->current_scr_sequence = in->s.scr_sequence;
}
}
}
@@ -141,7 +144,8 @@ int decsubWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
pv->size_got += in->size;
if( in->s.start >= 0 )
{
- pv->pts = in->s.start;
+ pv->pts = in->s.start;
+ pv->current_scr_sequence = in->s.scr_sequence;
}
}
else
@@ -180,7 +184,8 @@ int decsubWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
// of the current sub as the start of the next.
// This can happen if reader invalidates timestamps while
// waiting for an audio to update the SCR.
- pv->pts = pv->pts_stop;
+ pv->pts = pv->pts_stop;
+ pv->current_scr_sequence = pv->scr_sequence;
}
}
@@ -255,21 +260,26 @@ static void ParseControls( hb_work_object_t * w )
switch( command )
{
case 0x00: // 0x00 - FSTA_DSP - Forced Start Display, no arguments
- pv->pts_start = pv->pts + date * 1024;
- pv->pts_forced = 1;
+ pv->pts_start = pv->pts + date * 1024;
+ pv->scr_sequence = pv->current_scr_sequence;
+ pv->pts_forced = 1;
w->subtitle->hits++;
w->subtitle->forced_hits++;
break;
case 0x01: // 0x01 - STA_DSP - Start Display, no arguments
- pv->pts_start = pv->pts + date * 1024;
- pv->pts_forced = 0;
+ pv->pts_start = pv->pts + date * 1024;
+ pv->scr_sequence = pv->current_scr_sequence;
+ pv->pts_forced = 0;
w->subtitle->hits++;
break;
case 0x02: // 0x02 - STP_DSP - Stop Display, no arguments
- if(pv->pts_stop == AV_NOPTS_VALUE)
- pv->pts_stop = pv->pts + date * 1024;
+ if (pv->pts_stop == AV_NOPTS_VALUE)
+ {
+ pv->pts_stop = pv->pts + date * 1024;
+ pv->scr_sequence = pv->current_scr_sequence;
+ }
break;
case 0x03: // 0x03 - SET_COLOR - Set Colour indices
@@ -346,7 +356,8 @@ static void ParseControls( hb_work_object_t * w )
// fading-out
if (currAlpha < lastAlpha && pv->pts_stop == AV_NOPTS_VALUE)
{
- pv->pts_stop = pv->pts + date * 1024;
+ pv->pts_stop = pv->pts + date * 1024;
+ pv->scr_sequence = pv->current_scr_sequence;
}
i += 2;
@@ -382,7 +393,8 @@ static void ParseControls( hb_work_object_t * w )
if( pv->pts_start == AV_NOPTS_VALUE )
{
// Set pts to end of last sub if the start time is unknown.
- pv->pts_start = pv->pts;
+ pv->pts_start = pv->pts;
+ pv->scr_sequence = pv->current_scr_sequence;
}
}
@@ -535,9 +547,10 @@ static hb_buffer_t * CropSubtitle( hb_work_object_t * w, uint8_t * raw )
realheight = crop[1] - crop[0] + 1;
buf = hb_frame_buffer_init( AV_PIX_FMT_YUVA420P, realwidth, realheight );
- buf->s.frametype = HB_FRAME_SUBTITLE;
- buf->s.start = pv->pts_start;
- buf->s.stop = pv->pts_stop;
+ buf->s.frametype = HB_FRAME_SUBTITLE;
+ buf->s.start = pv->pts_start;
+ buf->s.stop = pv->pts_stop;
+ buf->s.scr_sequence = pv->scr_sequence;
buf->f.x = pv->x + crop[2];
buf->f.y = pv->y + crop[0];
@@ -606,8 +619,9 @@ static hb_buffer_t * Decode( hb_work_object_t * w )
if (w->subtitle->config.dest == PASSTHRUSUB)
{
- pv->buf->s.start = pv->pts_start;
- pv->buf->s.stop = pv->pts_stop;
+ pv->buf->s.start = pv->pts_start;
+ pv->buf->s.stop = pv->pts_stop;
+ pv->buf->s.scr_sequence = pv->scr_sequence;
buf = pv->buf;
pv->buf = NULL;
return buf;