summaryrefslogtreecommitdiffstats
path: root/libhb/sync.c
diff options
context:
space:
mode:
authorJohn Stebbins <[email protected]>2016-05-17 16:06:26 -0600
committerJohn Stebbins <[email protected]>2016-05-17 16:06:26 -0600
commite164c82ba392f63dd2bd95bfc26fb93b364e06a6 (patch)
treeb11836f7fe47169ec030916d365abffc9f189ba8 /libhb/sync.c
parentfb09793d671bdd555c8dd09c1d9da146e7809144 (diff)
sync: sanitize subtitles in OutputBuffer
Diffstat (limited to 'libhb/sync.c')
-rw-r--r--libhb/sync.c84
1 files changed, 53 insertions, 31 deletions
diff --git a/libhb/sync.c b/libhb/sync.c
index ad27ac755..5320c7131 100644
--- a/libhb/sync.c
+++ b/libhb/sync.c
@@ -150,6 +150,9 @@ static void UpdateSearchState( sync_common_t * common, int64_t start,
int frame_count );
static hb_buffer_t * FilterAudioFrame( sync_stream_t * stream,
hb_buffer_t *buf );
+static hb_buffer_t * sanitizeSubtitle(sync_stream_t * stream,
+ hb_buffer_t * sub);
+
static int fillQueues( sync_common_t * common )
{
@@ -724,6 +727,29 @@ static void streamFlush( sync_stream_t * stream )
if (stream->type == SYNC_TYPE_AUDIO)
{
buf = FilterAudioFrame(stream, buf);
+ if (buf == NULL)
+ {
+ // FilterAudioFrame can consume the buffer with no output
+ continue;
+ }
+ }
+ int64_t subtitle_next_pts = AV_NOPTS_VALUE;
+ if (stream->type == SYNC_TYPE_SUBTITLE)
+ {
+ buf = sanitizeSubtitle(stream, buf);
+ if (buf == NULL)
+ {
+ // sanitizeSubtitle can consume the buffer with no output
+ continue;
+ }
+ // sanitizeSubtitle can return a list of subtitles.
+ // Find the pts of the last subtitle in the list
+ hb_buffer_t * sub = buf;
+ while (sub != NULL)
+ {
+ subtitle_next_pts = sub->s.start;
+ sub = sub->next;
+ }
}
if (stream->type == SYNC_TYPE_AUDIO ||
stream->type == SYNC_TYPE_VIDEO)
@@ -734,13 +760,7 @@ static void streamFlush( sync_stream_t * stream )
}
else
{
- // Last ditch effort to prevent timestamps from going backwards
- // This can (and should only) affect subtitle streams.
- if (buf->s.start < stream->next_pts)
- {
- buf->s.start = stream->next_pts;
- }
- stream->next_pts = buf->s.start;
+ stream->next_pts = subtitle_next_pts;
}
if (buf->s.stop > 0)
@@ -1084,10 +1104,28 @@ static void OutputBuffer( sync_common_t * common )
buf = FilterAudioFrame(out_stream, buf);
if (buf == NULL)
{
- // FilterAudioFrame can conume the buffer with no output
+ // FilterAudioFrame can consume the buffer with no output
continue;
}
}
+ int64_t subtitle_next_pts = AV_NOPTS_VALUE;
+ if (out_stream->type == SYNC_TYPE_SUBTITLE)
+ {
+ buf = sanitizeSubtitle(out_stream, buf);
+ if (buf == NULL)
+ {
+ // sanitizeSubtitle can consume the buffer with no output
+ continue;
+ }
+ // sanitizeSubtitle can return a list of subtitles.
+ // Find the pts of the last subtitle in the list
+ hb_buffer_t * sub = buf;
+ while (sub != NULL)
+ {
+ subtitle_next_pts = sub->s.start;
+ sub = sub->next;
+ }
+ }
if (out_stream->type == SYNC_TYPE_AUDIO ||
out_stream->type == SYNC_TYPE_VIDEO)
{
@@ -1097,21 +1135,9 @@ static void OutputBuffer( sync_common_t * common )
}
else
{
- // Last ditch effort to prevent timestamps from going backwards
- // This can (and should only) affect subtitle streams.
- if (buf->s.start < out_stream->next_pts)
- {
- buf->s.start = out_stream->next_pts;
- }
- if (buf->s.stop != AV_NOPTS_VALUE &&
- buf->s.stop < out_stream->next_pts)
- {
- buf->s.stop = out_stream->next_pts;
- }
- out_stream->next_pts = buf->s.start;
+ out_stream->next_pts = subtitle_next_pts;
}
-
if (buf->s.stop > 0)
{
out_stream->current_duration = buf->s.stop -
@@ -2372,16 +2398,16 @@ static int syncSubtitleWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
if (pv->common->done)
{
- hb_buffer_list_append(&pv->stream->out_queue, hb_buffer_eof_init());
- in = hb_buffer_list_clear(&pv->stream->out_queue);
- *buf_out = sanitizeSubtitle(pv->stream, in);
+ *buf_out = hb_buffer_list_clear(&pv->stream->out_queue);
return HB_WORK_DONE;
}
if (in->s.flags & HB_BUF_FLAG_EOF)
{
+ // sanitizeSubtitle requires EOF buffer to recognize that
+ // it needs to flush all subtitles.
+ hb_list_add(pv->stream->in_queue, hb_buffer_eof_init());
streamFlush(pv->stream);
- in = hb_buffer_list_clear(&pv->stream->out_queue);
- *buf_out = sanitizeSubtitle(pv->stream, in);
+ *buf_out = hb_buffer_list_clear(&pv->stream->out_queue);
if (pv->common->job->indepth_scan)
{
// When doing subtitle indepth scan, the pipeline ends at sync.
@@ -2394,11 +2420,7 @@ static int syncSubtitleWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
*buf_in = NULL;
QueueBuffer(pv->stream, in);
Synchronize(pv->common);
- in = hb_buffer_list_clear(&pv->stream->out_queue);
- if (in != NULL)
- {
- *buf_out = sanitizeSubtitle(pv->stream, in);
- }
+ *buf_out = hb_buffer_list_clear(&pv->stream->out_queue);
return HB_WORK_OK;
}