summaryrefslogtreecommitdiffstats
path: root/libhb
diff options
context:
space:
mode:
authorjstebbins <[email protected]>2009-05-19 22:27:11 +0000
committerjstebbins <[email protected]>2009-05-19 22:27:11 +0000
commit0ac869507784e807357b06b61fbb4b69f4191278 (patch)
treea02e240d25553da68c349850db28472b7b16b3e9 /libhb
parent568bd4e88feaee724e71cc8cd5bd9e93dd549de0 (diff)
mkv soft subtitle support
- new libmkv 0.6.4 with subtitle track support - muxmkv supports vobsub and closed caption subtitles - added subtitle format, source, and dest initialization to dvdnav - moved subtitle_force flag into hb_subtitle_t struct as it needs to be settable per subtitle - gtk ui added subtitle tab which allows selection of multiple subtitles - reorgainize subtitle sync code to prevent dropping of subtitles when multiple subtitles are enabled git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@2428 b64f7644-9d1e-0410-96f1-a4d463321fa5
Diffstat (limited to 'libhb')
-rw-r--r--libhb/common.h5
-rw-r--r--libhb/decvobsub.c102
-rw-r--r--libhb/dvdnav.c4
-rw-r--r--libhb/encvobsub.c18
-rw-r--r--libhb/fifo.c1
-rw-r--r--libhb/muxmkv.c87
-rw-r--r--libhb/reader.c2
-rw-r--r--libhb/sync.c246
-rw-r--r--libhb/work.c8
9 files changed, 279 insertions, 194 deletions
diff --git a/libhb/common.h b/libhb/common.h
index 516318907..224b40c78 100644
--- a/libhb/common.h
+++ b/libhb/common.h
@@ -238,7 +238,6 @@ struct hb_job_s
int indepth_scan;
hb_subtitle_t ** select_subtitle;
- int subtitle_force;
char * native_language;
int angle; // dvd angle to encode
@@ -445,6 +444,7 @@ struct hb_subtitle_s
enum subtype { PICTURESUB, TEXTSUB } format;
enum subsource { VOBSUB, SRTSUB, CC608SUB, CC708SUB } source;
enum subdest { RENDERSUB, PASSTHRUSUB } dest;
+ int force;
char lang[1024];
char iso639_2[4];
uint8_t type; /* Closed Caption, Childrens, Directors etc */
@@ -639,6 +639,9 @@ struct hb_work_object_s
/* Pointer hb_audio_t so we have access to the info in the audio worker threads. */
hb_audio_t * audio;
+ /* Pointer hb_subtitle_t so we have access to the info in the subtitle worker threads. */
+ hb_subtitle_t * subtitle;
+
hb_work_private_t * private_data;
hb_thread_t * thread;
diff --git a/libhb/decvobsub.c b/libhb/decvobsub.c
index fd1f89179..e5633d54d 100644
--- a/libhb/decvobsub.c
+++ b/libhb/decvobsub.c
@@ -8,27 +8,27 @@
struct hb_work_private_s
{
- hb_job_t * job;
-
- uint8_t buf[0xFFFF];
- int size_sub;
- int size_got;
- int size_rle;
- int64_t pts;
- int64_t pts_start;
- int64_t pts_stop;
- int pts_forced;
- int x;
- int y;
- int width;
- int height;
- int stream_id;
-
- int offsets[2];
- uint8_t lum[4];
- uint8_t chromaU[4];
- uint8_t chromaV[4];
- uint8_t alpha[4];
+ hb_job_t * job;
+
+ hb_buffer_t * buf;
+ int size_sub;
+ int size_got;
+ int size_rle;
+ int64_t pts;
+ int64_t pts_start;
+ int64_t pts_stop;
+ int pts_forced;
+ int x;
+ int y;
+ int width;
+ int height;
+ int stream_id;
+
+ int offsets[2];
+ uint8_t lum[4];
+ uint8_t chromaU[4];
+ uint8_t chromaV[4];
+ uint8_t alpha[4];
};
static hb_buffer_t * Decode( hb_work_object_t * );
@@ -76,7 +76,10 @@ int decsubWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
pv->size_sub = size_sub;
pv->size_rle = size_rle;
- memcpy( pv->buf, in->data, in->size );
+ pv->buf = hb_buffer_init( 0xFFFF );
+ memcpy( pv->buf->data, in->data, in->size );
+ pv->buf->id = in->id;
+ pv->buf->sequence = in->sequence;
pv->size_got = in->size;
pv->pts = in->start;
}
@@ -86,7 +89,9 @@ int decsubWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
/* We are waiting for the end of the current subtitle */
if( in->size <= pv->size_sub - pv->size_got )
{
- memcpy( pv->buf + pv->size_got, in->data, in->size );
+ memcpy( pv->buf->data + pv->size_got, in->data, in->size );
+ pv->buf->id = in->id;
+ pv->buf->sequence = in->sequence;
pv->size_got += in->size;
if( in->start >= 0 )
{
@@ -99,11 +104,14 @@ int decsubWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
if( pv->size_sub && pv->size_sub == pv->size_got )
{
+ pv->buf->size = pv->size_sub;
+
/* We got a complete subtitle, decode it */
*buf_out = Decode( w );
if( buf_out && *buf_out )
{
+ (*buf_out)->id = in->id;
(*buf_out)->sequence = in->sequence;
}
@@ -145,6 +153,7 @@ static void ParseControls( hb_work_object_t * w )
hb_job_t * job = pv->job;
hb_title_t * title = job->title;
hb_subtitle_t * subtitle;
+ uint8_t * buf = pv->buf->data;
int i, n;
int command;
@@ -161,12 +170,12 @@ static void ParseControls( hb_work_object_t * w )
for( i = pv->size_rle; ; )
{
- date = ( pv->buf[i] << 8 ) | pv->buf[i+1]; i += 2;
- next = ( pv->buf[i] << 8 ) | pv->buf[i+1]; i += 2;
+ date = ( buf[i] << 8 ) | buf[i+1]; i += 2;
+ next = ( buf[i] << 8 ) | buf[i+1]; i += 2;
for( ;; )
{
- command = pv->buf[i++];
+ command = buf[i++];
/*
* There are eight commands available for
@@ -224,10 +233,10 @@ static void ParseControls( hb_work_object_t * w )
int colors[4];
int j;
- colors[0] = (pv->buf[i+0]>>4)&0x0f;
- colors[1] = (pv->buf[i+0])&0x0f;
- colors[2] = (pv->buf[i+1]>>4)&0x0f;
- colors[3] = (pv->buf[i+1])&0x0f;
+ colors[0] = (buf[i+0]>>4)&0x0f;
+ colors[1] = (buf[i+0])&0x0f;
+ colors[2] = (buf[i+1]>>4)&0x0f;
+ colors[3] = (buf[i+1])&0x0f;
for( j = 0; j < 4; j++ )
{
@@ -267,10 +276,10 @@ static void ParseControls( hb_work_object_t * w )
*/
uint8_t alpha[4];
- alpha[3] = (pv->buf[i+0]>>4)&0x0f;
- alpha[2] = (pv->buf[i+0])&0x0f;
- alpha[1] = (pv->buf[i+1]>>4)&0x0f;
- alpha[0] = (pv->buf[i+1])&0x0f;
+ alpha[3] = (buf[i+0]>>4)&0x0f;
+ alpha[2] = (buf[i+0])&0x0f;
+ alpha[1] = (buf[i+1]>>4)&0x0f;
+ alpha[0] = (buf[i+1])&0x0f;
int lastAlpha = pv->alpha[3] + pv->alpha[2] + pv->alpha[1] + pv->alpha[0];
@@ -296,17 +305,17 @@ static void ParseControls( hb_work_object_t * w )
}
case 0x05: // 0x05 - SET_DAREA - defines the display area
{
- pv->x = (pv->buf[i+0]<<4) | ((pv->buf[i+1]>>4)&0x0f);
- pv->width = (((pv->buf[i+1]&0x0f)<<8)| pv->buf[i+2]) - pv->x + 1;
- pv->y = (pv->buf[i+3]<<4)| ((pv->buf[i+4]>>4)&0x0f);
- pv->height = (((pv->buf[i+4]&0x0f)<<8)| pv->buf[i+5]) - pv->y + 1;
+ pv->x = (buf[i+0]<<4) | ((buf[i+1]>>4)&0x0f);
+ pv->width = (((buf[i+1]&0x0f)<<8)| buf[i+2]) - pv->x + 1;
+ pv->y = (buf[i+3]<<4)| ((buf[i+4]>>4)&0x0f);
+ pv->height = (((buf[i+4]&0x0f)<<8)| buf[i+5]) - pv->y + 1;
i += 6;
break;
}
case 0x06: // 0x06 - SET_DSPXA - defines the pixel data addresses
{
- pv->offsets[0] = ( pv->buf[i] << 8 ) | pv->buf[i+1]; i += 2;
- pv->offsets[1] = ( pv->buf[i] << 8 ) | pv->buf[i+1]; i += 2;
+ pv->offsets[0] = ( buf[i] << 8 ) | buf[i+1]; i += 2;
+ pv->offsets[1] = ( buf[i] << 8 ) | buf[i+1]; i += 2;
break;
}
}
@@ -475,7 +484,7 @@ static hb_buffer_t * Decode( hb_work_object_t * w )
/* Get infos about the subtitle */
ParseControls( w );
- if( job->indepth_scan || ( job->subtitle_force && pv->pts_forced == 0 ) )
+ if( job->indepth_scan || ( w->subtitle->force && pv->pts_forced == 0 ) )
{
/*
* Don't encode subtitles when doing a scan.
@@ -486,11 +495,18 @@ static hb_buffer_t * Decode( hb_work_object_t * w )
return NULL;
}
+ if (w->subtitle->dest == PASSTHRUSUB)
+ {
+ pv->buf->start = pv->pts_start;
+ pv->buf->stop = pv->pts_stop;
+ return pv->buf;
+ }
+
/* Do the actual decoding now */
buf_raw = malloc( ( pv->width * pv->height ) * 4 );
#define GET_NEXT_NIBBLE code = ( code << 4 ) | ( ( ( *offset & 1 ) ? \
-( pv->buf[((*offset)>>1)] & 0xF ) : ( pv->buf[((*offset)>>1)] >> 4 ) ) ); \
+( pv->buf->data[((*offset)>>1)] & 0xF ) : ( pv->buf->data[((*offset)>>1)] >> 4 ) ) ); \
(*offset)++
offsets[0] = pv->offsets[0] * 2;
@@ -547,6 +563,8 @@ static hb_buffer_t * Decode( hb_work_object_t * w )
}
}
+ hb_buffer_close( &pv->buf );
+
/* Crop subtitle (remove transparent borders) */
buf = CropSubtitle( w, buf_raw );
diff --git a/libhb/dvdnav.c b/libhb/dvdnav.c
index 5fde4cba7..515de1ee0 100644
--- a/libhb/dvdnav.c
+++ b/libhb/dvdnav.c
@@ -619,11 +619,15 @@ static hb_title_t * hb_dvdnav_title_scan( hb_dvd_t * e, int t )
lang = lang_for_code( ifo->vtsi_mat->vts_subp_attr[i].lang_code );
subtitle = calloc( sizeof( hb_subtitle_t ), 1 );
+ subtitle->track = i+1;
subtitle->id = ( ( 0x20 + position ) << 8 ) | 0xbd;
snprintf( subtitle->lang, sizeof( subtitle->lang ), "%s",
strlen(lang->native_name) ? lang->native_name : lang->eng_name);
snprintf( subtitle->iso639_2, sizeof( subtitle->iso639_2 ), "%s",
lang->iso639_2);
+ subtitle->format = PICTURESUB;
+ subtitle->source = VOBSUB;
+ subtitle->dest = RENDERSUB; // By default render (burn-in) the VOBSUB.
subtitle->type = lang_extension;
diff --git a/libhb/encvobsub.c b/libhb/encvobsub.c
index ee49d7ad6..20a9879d6 100644
--- a/libhb/encvobsub.c
+++ b/libhb/encvobsub.c
@@ -26,9 +26,15 @@ int encsubInit( hb_work_object_t * w, hb_job_t * job )
int encsubWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
hb_buffer_t ** buf_out )
{
- hb_work_private_t * pv = w->private_data;
hb_buffer_t * in = *buf_in;
+ if (w->subtitle->source != VOBSUB)
+ {
+ // Invalid source, send EOF, this shouldn't ever happen
+ hb_log("encvobsub: invalid subtitle source");
+ hb_buffer_close( buf_in );
+ *buf_out = hb_buffer_init(0);
+ }
if ( in->size <= 0 )
{
/* EOF on input stream - send it downstream & say that we're done */
@@ -38,10 +44,14 @@ int encsubWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
}
/*
- * Don't do anything at present, just pass the buffer on.
+ * Not much to do, just pass the buffer on.
+ * Some day, we may re-encode bd subtitles here ;)
*/
- *buf_out = in;
- *buf_in = NULL;
+ if (buf_out)
+ {
+ *buf_out = in;
+ *buf_in = NULL;
+ }
return HB_WORK_OK;
}
diff --git a/libhb/fifo.c b/libhb/fifo.c
index c756f5673..7337874bf 100644
--- a/libhb/fifo.c
+++ b/libhb/fifo.c
@@ -191,6 +191,7 @@ void hb_buffer_close( hb_buffer_t ** _b )
if( buffer_pool && b->data && !hb_fifo_is_full( buffer_pool ) )
{
hb_fifo_push_head( buffer_pool, b );
+ *_b = NULL;
return;
}
/* either the pool is full or this size doesn't use a pool - free the buf */
diff --git a/libhb/muxmkv.c b/libhb/muxmkv.c
index c3d627979..04f9ae595 100644
--- a/libhb/muxmkv.c
+++ b/libhb/muxmkv.c
@@ -34,6 +34,27 @@ struct hb_mux_data_s
int sub_format;
};
+static int yuv2rgb(int yuv)
+{
+ double y, Cr, Cb;
+ int r, g, b;
+
+ y = (yuv >> 16) & 0xff;
+ Cr = (yuv >> 8) & 0xff;
+ Cb = (yuv) & 0xff;
+
+ r = 1.164 * (y - 16) + 2.018 * (Cb - 128);
+ g = 1.164 * (y - 16) - 0.813 * (Cr - 128) - 0.391 * (Cb - 128);
+ b = 1.164 * (y - 16) + 1.596 * (Cr - 128);
+ r = (r < 0) ? 0 : r;
+ g = (g < 0) ? 0 : g;
+ b = (b < 0) ? 0 : b;
+ r = (r > 255) ? 255 : r;
+ g = (g > 255) ? 255 : g;
+ b = (b > 255) ? 255 : b;
+ return (r << 16) | (g << 8) | b;
+}
+
/**********************************************************************
* MKVInit
**********************************************************************
@@ -48,7 +69,7 @@ static int MKVInit( hb_mux_object_t * m )
uint8_t *avcC = NULL;
uint8_t default_track_flag = 1;
- int avcC_len, i;
+ int avcC_len, i, j;
ogg_packet *ogg_headers[3];
mk_TrackConfig *track;
@@ -261,7 +282,7 @@ static int MKVInit( hb_mux_object_t * m )
for( i = 0; i < hb_list_count( title->list_subtitle ); i++ )
{
hb_subtitle_t * subtitle;
- uint32_t * palette;
+ uint32_t rgb[16];
char subidx[2048];
int len;
@@ -270,28 +291,39 @@ static int MKVInit( hb_mux_object_t * m )
continue;
memset(track, 0, sizeof(mk_TrackConfig));
+ switch (subtitle->format)
+ {
+ case PICTURESUB:
+ track->codecID = MK_SUBTITLE_VOBSUB;
+ for (j = 0; j < 16; j++)
+ rgb[j] = yuv2rgb(title->palette[j]);
+ len = snprintf(subidx, 2048, subidx_fmt,
+ title->width, title->height,
+ 0, 0, "OFF",
+ rgb[0], rgb[1], rgb[2], rgb[3],
+ rgb[4], rgb[5], rgb[6], rgb[7],
+ rgb[8], rgb[9], rgb[10], rgb[11],
+ rgb[12], rgb[13], rgb[14], rgb[15]);
+ track->codecPrivate = subidx;
+ track->codecPrivateSize = len + 1;
+ break;
+ case TEXTSUB:
+ track->codecID = MK_SUBTITLE_UTF8;
+ break;
+ default:
+ continue;
+ }
mux_data = calloc(1, sizeof( hb_mux_data_t ) );
subtitle->mux_data = mux_data;
mux_data->subtitle = 1;
mux_data->sub_format = subtitle->format;
- palette = title->palette;
- len = snprintf(subidx, 2048, subidx_fmt, title->width, title->height,
- 0, 0, "OFF",
- palette[0], palette[1], palette[2], palette[3],
- palette[4], palette[5], palette[6], palette[7],
- palette[8], palette[9], palette[10], palette[11],
- palette[12], palette[13], palette[14], palette[15]);
- track->codecPrivate = subidx;
- track->codecPrivateSize = len + 1;
- track->codecID = MK_SUBTITLE_VOBSUB;
track->flagEnabled = 1;
track->trackType = MK_TRACK_SUBTITLE;
track->language = subtitle->iso639_2;
mux_data->track = mk_createTrack(m->file, track);
-
}
if( mk_writeHeader( m->file, "HandBrake " HB_PROJECT_VERSION) < 0 )
@@ -362,19 +394,33 @@ static int MKVMux( hb_mux_object_t * m, hb_mux_data_t * mux_data,
*job->die = 1;
}
mk_addFrameData(m->file, mux_data->track, op->packet, op->bytes);
- mk_setFrameFlags(m->file, mux_data->track, timecode, 1);
+ mk_setFrameFlags(m->file, mux_data->track, timecode, 1, 0);
return 0;
}
}
else if ( mux_data->subtitle )
{
timecode = buf->start * TIMECODE_SCALE;
+ if( mk_startFrame(m->file, mux_data->track) < 0)
+ {
+ hb_error( "Failed to write frame to output file, Disk Full?" );
+ *job->die = 1;
+ }
if( mux_data->sub_format == TEXTSUB )
{
- hb_log("MuxMKV: Text Sub:%lld: %s", buf->start, buf->data);
- // TODO: add CC data to track
- return 0;
+ uint64_t duration;
+
+ duration = buf->stop * TIMECODE_SCALE - timecode;
+ mk_addFrameData(m->file, mux_data->track, buf->data, buf->size);
+ mk_setFrameFlags(m->file, mux_data->track, timecode, 1, duration);
}
+ else
+ {
+ mk_addFrameData(m->file, mux_data->track, buf->data, buf->size);
+ mk_setFrameFlags(m->file, mux_data->track, timecode, 1, 0);
+ }
+ mk_flushFrame(m->file, mux_data->track);
+ return 0;
}
else
{
@@ -391,7 +437,7 @@ static int MKVMux( hb_mux_object_t * m, hb_mux_data_t * mux_data,
*job->die = 1;
}
mk_addFrameData(m->file, mux_data->track, op->packet, op->bytes);
- mk_setFrameFlags(m->file, mux_data->track, timecode, 1);
+ mk_setFrameFlags(m->file, mux_data->track, timecode, 1, 0);
return 0;
}
}
@@ -403,7 +449,10 @@ static int MKVMux( hb_mux_object_t * m, hb_mux_data_t * mux_data,
}
mk_addFrameData(m->file, mux_data->track, buf->data, buf->size);
mk_setFrameFlags(m->file, mux_data->track, timecode,
- ((job->vcodec == HB_VCODEC_X264 && mux_data == job->mux_data) ? (buf->frametype == HB_FRAME_IDR) : ((buf->frametype & HB_FRAME_KEY) != 0)) );
+ ((job->vcodec == HB_VCODEC_X264 &&
+ mux_data == job->mux_data) ?
+ (buf->frametype == HB_FRAME_IDR) :
+ ((buf->frametype & HB_FRAME_KEY) != 0)), 0 );
return 0;
}
diff --git a/libhb/reader.c b/libhb/reader.c
index dd478151b..c865ea85f 100644
--- a/libhb/reader.c
+++ b/libhb/reader.c
@@ -527,7 +527,7 @@ static hb_fifo_t ** GetFifoForId( hb_job_t * job, int id )
subtitle = hb_list_item( title->list_subtitle, i );
if (id == subtitle->id) {
subtitle->hits++;
- if( !job->indepth_scan || job->subtitle_force )
+ if( !job->indepth_scan || subtitle->force )
{
/*
* Pass the subtitles to be processed if we are not scanning, or if
diff --git a/libhb/sync.c b/libhb/sync.c
index 1001ed50c..d76907987 100644
--- a/libhb/sync.c
+++ b/libhb/sync.c
@@ -485,7 +485,9 @@ static void SyncVideo( hb_work_object_t * w )
when the second one starts */
sub2 = hb_fifo_see2( subtitle->fifo_raw );
if( sub2 && sub->stop > sub2->start )
+ {
sub->stop = sub2->start;
+ }
// hb_log("0x%x: video seq: %lld subtitle sequence: %lld",
// sub, cur->sequence, sub->sequence);
@@ -508,120 +510,160 @@ static void SyncVideo( hb_work_object_t * w )
* and we'll deal with it in the next block of
* code.
*/
- break;
- }
-
- /*
- * The subtitle is older than this picture, trash it
- */
- sub = hb_fifo_get( subtitle->fifo_raw );
- hb_buffer_close( &sub );
- }
-
- if( sub && sub->size == 0 )
- {
- /*
- * Continue immediately on subtitle EOF
- */
- break;
- }
- /*
- * There is a valid subtitle, is it time to display it?
- */
- if( sub )
- {
- if( sub->stop > sub->start)
- {
/*
- * Normal subtitle which ends after it starts, check to
- * see that the current video is between the start and end.
+ * There is a valid subtitle, is it time to display it?
*/
- if( cur->start > sub->start &&
- cur->start < sub->stop )
+ if( sub->stop > sub->start)
{
/*
- * We should be playing this, so leave the
- * subtitle in place.
- *
- * fall through to display
+ * Normal subtitle which ends after it starts,
+ * check to see that the current video is between
+ * the start and end.
*/
- if( ( sub->stop - sub->start ) < ( 3 * 90000 ) )
+ if( cur->start > sub->start &&
+ cur->start < sub->stop )
{
/*
- * Subtitle is on for less than three seconds, extend
- * the time that it is displayed to make it easier
- * to read. Make it 3 seconds or until the next
- * subtitle is displayed.
- *
- * This is in response to Indochine which only
- * displays subs for 1 second - too fast to read.
- */
- sub->stop = sub->start + ( 3 * 90000 );
+ * We should be playing this, so leave the
+ * subtitle in place.
+ *
+ * fall through to display
+ */
+ if( ( sub->stop - sub->start ) < ( 3 * 90000 ) )
+ {
+ /*
+ * Subtitle is on for less than three
+ * seconds, extend the time that it is
+ * displayed to make it easier to read.
+ * Make it 3 seconds or until the next
+ * subtitle is displayed.
+ *
+ * This is in response to Indochine which
+ * only displays subs for 1 second -
+ * too fast to read.
+ */
+ sub->stop = sub->start + ( 3 * 90000 );
- sub2 = hb_fifo_see2( subtitle->fifo_raw );
+ sub2 = hb_fifo_see2( subtitle->fifo_raw );
- if( sub2 && sub->stop > sub2->start )
- {
- sub->stop = sub2->start;
+ if( sub2 && sub->stop > sub2->start )
+ {
+ sub->stop = sub2->start;
+ }
}
}
+ else
+ {
+ /*
+ * Defer until the play point is within
+ * the subtitle
+ */
+ sub = NULL;
+ }
}
else
{
/*
- * Defer until the play point is within the subtitle
+ * The end of the subtitle is less than the start,
+ * this is a sign of a PTS discontinuity.
*/
- sub = NULL;
+ if( sub->start > cur->start )
+ {
+ /*
+ * we haven't reached the start time yet, or
+ * we have jumped backwards after having
+ * already started this subtitle.
+ */
+ if( cur->start < sub->stop )
+ {
+ /*
+ * We have jumped backwards and so should
+ * continue displaying this subtitle.
+ *
+ * fall through to display.
+ */
+ }
+ else
+ {
+ /*
+ * Defer until the play point is
+ * within the subtitle
+ */
+ sub = NULL;
+ }
+ } else {
+ /*
+ * Play this subtitle as the start is
+ * greater than our video point.
+ *
+ * fall through to display/
+ */
+ }
}
+ break;
}
else
{
+
/*
- * The end of the subtitle is less than the start, this is a
- * sign of a PTS discontinuity.
+ * The subtitle is older than this picture, trash it
*/
- if( sub->start > cur->start )
+ sub = hb_fifo_get( subtitle->fifo_raw );
+ hb_buffer_close( &sub );
+ }
+ }
+
+ /* If we have a subtitle for this picture, copy it */
+ /* FIXME: we should avoid this memcpy */
+ if( sub )
+ {
+ if( sub->size > 0 )
+ {
+ if( subtitle->dest == RENDERSUB )
{
- /*
- * we haven't reached the start time yet, or
- * we have jumped backwards after having
- * already started this subtitle.
- */
- if( cur->start < sub->stop )
- {
- /*
- * We have jumped backwards and so should
- * continue displaying this subtitle.
- *
- * fall through to display.
- */
- }
- else
+ if ( cur->sub == NULL )
{
/*
- * Defer until the play point is within the subtitle
+ * Tack onto the video buffer for rendering
*/
- sub = NULL;
+ cur->sub = hb_buffer_init( sub->size );
+ cur->sub->x = sub->x;
+ cur->sub->y = sub->y;
+ cur->sub->width = sub->width;
+ cur->sub->height = sub->height;
+ memcpy( cur->sub->data, sub->data, sub->size );
}
} else {
/*
- * Play this subtitle as the start is greater than our
- * video point.
- *
- * fall through to display/
+ * Pass-Through, pop it off of the raw queue,
+ * rewrite times and make it available to be
+ * reencoded.
*/
+ uint64_t sub_duration;
+ sub = hb_fifo_get( subtitle->fifo_raw );
+ sub_duration = sub->stop - sub->start;
+ sub->start = cur->start;
+ buf_tmp = hb_fifo_see( job->fifo_raw );
+ int64_t duration = buf_tmp->start - cur->start;
+ sub->stop = sub->start + duration;
+ hb_fifo_push( subtitle->fifo_sync, sub );
+ }
+ } else {
+ /*
+ * EOF - consume for rendered, else pass through
+ */
+ if( subtitle->dest == RENDERSUB )
+ {
+ sub = hb_fifo_get( subtitle->fifo_raw );
+ hb_buffer_close( &sub );
+ } else {
+ sub = hb_fifo_get( subtitle->fifo_raw );
+ hb_fifo_push( subtitle->fifo_out, sub );
}
}
}
}
- if( sub )
- {
- /*
- * Got a sub to display...
- */
- break;
- }
} // end subtitles
/*
@@ -639,6 +681,7 @@ static void SyncVideo( hb_work_object_t * w )
*/
buf_tmp = cur;
pv->cur = cur = hb_fifo_get( job->fifo_raw );
+ cur->sub = NULL;
pv->next_pts = cur->start;
int64_t duration = cur->start - buf_tmp->start;
if ( duration <= 0 )
@@ -659,51 +702,6 @@ static void SyncVideo( hb_work_object_t * w )
pv->chap_mark = 0;
}
- /* If we have a subtitle for this picture, copy it */
- /* FIXME: we should avoid this memcpy */
- if( sub && subtitle &&
- subtitle->format == PICTURESUB )
- {
- if( sub->size > 0 )
- {
- if( subtitle->dest == RENDERSUB )
- {
- /*
- * Tack onto the video buffer for rendering
- */
- buf_tmp->sub = hb_buffer_init( sub->size );
- buf_tmp->sub->x = sub->x;
- buf_tmp->sub->y = sub->y;
- buf_tmp->sub->width = sub->width;
- buf_tmp->sub->height = sub->height;
- memcpy( buf_tmp->sub->data, sub->data, sub->size );
- } else {
- /*
- * Pass-Through, pop it off of the raw queue, rewrite times and
- * make it available to be reencoded.
- */
- uint64_t sub_duration;
- sub = hb_fifo_get( subtitle->fifo_raw );
- sub_duration = sub->stop - sub->start;
- sub->start = buf_tmp->start;
- sub->stop = sub->start + duration;
- hb_fifo_push( subtitle->fifo_sync, sub );
- }
- } else {
- /*
- * EOF - consume for rendered, else pass through
- */
- if( subtitle->dest == RENDERSUB )
- {
- sub = hb_fifo_get( subtitle->fifo_raw );
- hb_buffer_close( &sub );
- } else {
- sub = hb_fifo_get( subtitle->fifo_raw );
- hb_fifo_push( subtitle->fifo_out, sub );
- }
- }
- }
-
/* Push the frame to the renderer */
hb_fifo_push( job->fifo_sync, buf_tmp );
diff --git a/libhb/work.c b/libhb/work.c
index 7b270ca70..59dea5dfe 100644
--- a/libhb/work.c
+++ b/libhb/work.c
@@ -501,16 +501,16 @@ static void do_job( hb_job_t * job, int cpu_count )
*
* select_subtitle implies that we did a scan.
*/
- if( !job->indepth_scan && job->subtitle_force &&
+ if( !job->indepth_scan && subtitle->force &&
job->select_subtitle )
{
if( subtitle->forced_hits == 0 )
{
- job->subtitle_force = 0;
+ subtitle->force = 0;
}
}
- if( (!job->indepth_scan || job->subtitle_force) &&
+ if( (!job->indepth_scan || subtitle->force) &&
subtitle->source == VOBSUB ) {
/*
* Don't add threads for subtitles when we are scanning, unless
@@ -519,6 +519,7 @@ static void do_job( hb_job_t * job, int cpu_count )
w = hb_get_work( WORK_DECVOBSUB );
w->fifo_in = subtitle->fifo_in;
w->fifo_out = subtitle->fifo_raw;
+ w->subtitle = subtitle;
hb_list_add( job->list_work, w );
}
@@ -541,6 +542,7 @@ static void do_job( hb_job_t * job, int cpu_count )
w = hb_get_work( WORK_ENCVOBSUB );
w->fifo_in = subtitle->fifo_sync;
w->fifo_out = subtitle->fifo_out;
+ w->subtitle = subtitle;
hb_list_add( job->list_work, w );
}
}