summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libhb/common.h7
-rw-r--r--libhb/deccc608sub.c125
-rw-r--r--libhb/deccc608sub.h3
-rw-r--r--libhb/decmpeg2.c80
-rw-r--r--libhb/decvobsub.c4
-rw-r--r--libhb/encvobsub.c4
-rw-r--r--libhb/hb.c7
-rw-r--r--libhb/hb.h10
-rw-r--r--libhb/internal.h5
-rw-r--r--libhb/sync.c30
-rw-r--r--libhb/work.c19
11 files changed, 206 insertions, 88 deletions
diff --git a/libhb/common.h b/libhb/common.h
index f8921f654..516318907 100644
--- a/libhb/common.h
+++ b/libhb/common.h
@@ -443,7 +443,7 @@ struct hb_subtitle_s
int track;
int id;
enum subtype { PICTURESUB, TEXTSUB } format;
- enum subsource { VOBSUB, SRTSUB, CCSUB } source;
+ enum subsource { VOBSUB, SRTSUB, CC608SUB, CC708SUB } source;
enum subdest { RENDERSUB, PASSTHRUSUB } dest;
char lang[1024];
char iso639_2[4];
@@ -654,8 +654,9 @@ struct hb_work_object_s
extern hb_work_object_t hb_sync;
extern hb_work_object_t hb_decmpeg2;
-extern hb_work_object_t hb_decsub;
-extern hb_work_object_t hb_encsub;
+extern hb_work_object_t hb_decvobsub;
+extern hb_work_object_t hb_encvobsub;
+extern hb_work_object_t hb_deccc608;
extern hb_work_object_t hb_render;
extern hb_work_object_t hb_encavcodec;
extern hb_work_object_t hb_encxvid;
diff --git a/libhb/deccc608sub.c b/libhb/deccc608sub.c
index 18d0e6b18..dbbc2d3e5 100644
--- a/libhb/deccc608sub.c
+++ b/libhb/deccc608sub.c
@@ -177,6 +177,10 @@ int general_608_init (struct s_write *wb)
wb->new_sentence = 1;
wb->new_channel = 1;
wb->in_xds_mode = 0;
+
+ wb->hb_buffer = NULL;
+ wb->hb_last_buffer = NULL;
+ wb->last_pts = 0;
return 0;
}
@@ -195,6 +199,10 @@ void general_608_close (struct s_write *wb)
if( wb->subline ) {
free(wb->subline);
}
+
+ if( wb->hb_buffer ) {
+ hb_buffer_close( &wb->hb_buffer );
+ }
}
@@ -1496,7 +1504,12 @@ void write_cc_line_as_transcript (struct eia608_screen *data, struct s_write *wb
memcpy( buffer->data, wb->subline, length + 1 );
//hb_log("CC %lld: %s", buffer->stop, wb->subline);
- hb_fifo_push( wb->subtitle->fifo_raw, buffer );
+ if (wb->hb_last_buffer) {
+ wb->hb_last_buffer->next = buffer;
+ } else {
+ wb->hb_buffer = buffer;
+ }
+ wb->hb_last_buffer = buffer;
XMLRPC_APPEND(wb->subline,length);
//fwrite (encoded_crlf, 1, encoded_crlf_length,wb->fh);
@@ -1622,7 +1635,12 @@ int write_cc_buffer_as_srt (struct eia608_screen *data, struct s_write *wb)
buffer->stop = ms_end;
memcpy( buffer->data, wb->subline, length + 1 );
- hb_fifo_push( wb->subtitle->fifo_raw, buffer );
+ if (wb->hb_last_buffer) {
+ wb->hb_last_buffer->next = buffer;
+ } else {
+ wb->hb_buffer = buffer;
+ }
+ wb->hb_last_buffer = buffer;
//fwrite (wb->subline, 1, length, wb->fh);
XMLRPC_APPEND(wb->subline,length);
@@ -2059,17 +2077,9 @@ void handle_command (/*const */ unsigned char c1, const unsigned char c2, struct
void handle_end_of_data (struct s_write *wb)
{
- hb_buffer_t *buffer;
-
// We issue a EraseDisplayedMemory here so if there's any captions pending
// they get written to file.
handle_command (0x14, 0x2c, wb); // EDM
-
- /*
- * At the end of the subtitle stream HB wants an empty buffer
- */
- buffer = hb_buffer_init( 0 );
- hb_fifo_push( wb->subtitle->fifo_raw, buffer );
}
void handle_double (const unsigned char c1, const unsigned char c2, struct s_write *wb)
@@ -2419,3 +2429,98 @@ unsigned char *debug_608toASC (unsigned char *cc_data, int channel)
}
return output;
}
+
+
+struct hb_work_private_s
+{
+ hb_job_t * job;
+ struct s_write * cc608;
+};
+
+int decccInit( hb_work_object_t * w, hb_job_t * job )
+{
+ int retval = 1;
+ hb_work_private_t * pv;
+
+ pv = calloc( 1, sizeof( hb_work_private_t ) );
+ if( pv )
+ {
+ w->private_data = pv;
+
+ pv->job = job;
+
+ pv->cc608 = calloc(1, sizeof(struct s_write));
+
+ if( pv->cc608 )
+ {
+ retval = general_608_init(pv->cc608);
+ if( !retval )
+ {
+ pv->cc608->data608 = calloc(1, sizeof(struct eia608));
+ if( !pv->cc608->data608 )
+ {
+ retval = 1;
+ }
+ }
+ }
+ }
+ return retval;
+}
+
+int decccWork( 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 ( in->size <= 0 )
+ {
+ /* EOF on input stream - send it downstream & say that we're done */
+ handle_end_of_data(pv->cc608);
+ /*
+ * Grab any pending buffer and output them with the EOF on the end
+ */
+ if (pv->cc608->hb_last_buffer) {
+ pv->cc608->hb_last_buffer->next = in;
+ *buf_out = pv->cc608->hb_buffer;
+ *buf_in = NULL;
+ pv->cc608->hb_buffer = NULL;
+ pv->cc608->hb_last_buffer = NULL;
+ } else {
+ *buf_out = in;
+ *buf_in = NULL;
+ }
+ return HB_WORK_DONE;
+ }
+
+ pv->cc608->last_pts = in->start;
+
+ process608(in->data, in->size, pv->cc608);
+
+ /*
+ * If there is one waiting then pass it on
+ */
+ *buf_out = pv->cc608->hb_buffer;
+ pv->cc608->hb_buffer = NULL;
+ pv->cc608->hb_last_buffer = NULL;
+
+ return HB_WORK_OK;
+}
+
+void decccClose( hb_work_object_t * w )
+{
+ hb_work_private_t * pv = w->private_data;
+ general_608_close( pv->cc608 );
+ free( pv->cc608->data608 );
+ free( pv->cc608 );
+ free( w->private_data );
+}
+
+hb_work_object_t hb_deccc608 =
+{
+ WORK_DECCC608,
+ "Closed Caption (608) decoder",
+ decccInit,
+ decccWork,
+ decccClose
+};
diff --git a/libhb/deccc608sub.h b/libhb/deccc608sub.h
index e6c1518a7..3e0288370 100644
--- a/libhb/deccc608sub.h
+++ b/libhb/deccc608sub.h
@@ -90,7 +90,8 @@ struct s_write {
int new_sentence;
int new_channel;
int in_xds_mode;
- hb_subtitle_t * subtitle;
+ hb_buffer_t *hb_buffer;
+ hb_buffer_t *hb_last_buffer;
uint64_t last_pts;
};
diff --git a/libhb/decmpeg2.c b/libhb/decmpeg2.c
index 756eb9768..2d5c7c494 100644
--- a/libhb/decmpeg2.c
+++ b/libhb/decmpeg2.c
@@ -7,7 +7,6 @@
#include "hb.h"
#include "hbffmpeg.h"
#include "mpeg2dec/mpeg2.h"
-#include "deccc608sub.h"
/* Cadence tracking */
#ifndef PIC_FLAG_REPEAT_FIRST_FIELD
@@ -47,7 +46,6 @@ typedef struct hb_libmpeg2_s
int64_t last_pts;
int cadence[12];
int flag;
- struct s_write cc608; /* Closed Captions */
hb_subtitle_t * subtitle;
} hb_libmpeg2_t;
@@ -64,9 +62,6 @@ static hb_libmpeg2_t * hb_libmpeg2_init()
m->info = mpeg2_info( m->libmpeg2 );
m->last_pts = -1;
- /* Closed Captions init, whether needed or not */
- general_608_init( &m->cc608 );
- m->cc608.data608 = calloc(1, sizeof(struct eia608));
return m;
}
@@ -74,6 +69,7 @@ static void hb_mpeg2_cc( hb_libmpeg2_t * m, uint8_t *cc_block )
{
uint8_t cc_valid = (*cc_block & 4) >>2;
uint8_t cc_type = *cc_block & 3;
+ hb_buffer_t *cc_buf;
if( !m->job )
{
@@ -89,7 +85,13 @@ static void hb_mpeg2_cc( hb_libmpeg2_t * m, uint8_t *cc_block )
{
case 0:
// CC1 stream
- process608( cc_block+1, 2, &m->cc608 );
+ cc_buf = hb_buffer_init( 2 );
+ if( cc_buf )
+ {
+ cc_buf->start = m->last_pts;
+ memcpy( cc_buf->data, cc_block+1, 2 );
+ hb_fifo_push( m->subtitle->fifo_in, cc_buf );
+ }
break;
case 1:
// CC2 stream
@@ -403,6 +405,8 @@ static int hb_libmpeg2_decode( hb_libmpeg2_t * m, hb_buffer_t * buf_es,
/*
* Look for Closed Captions if scanning (!job) or if closed captions have been requested.
+ *
+ * Send them on to the closed caption decoder if requested and found.
*/
if( ( !m->job || m->subtitle) &&
( m->info->user_data_len != 0 &&
@@ -418,8 +422,6 @@ static int hb_libmpeg2_decode( hb_libmpeg2_t * m, hb_buffer_t * buf_es,
int capcount=(header[0] & 0x1e) / 2;
header++;
- m->cc608.last_pts = m->last_pts;
-
/*
* Add closed captions to the title if we are scanning (no job).
*
@@ -439,7 +441,11 @@ static int hb_libmpeg2_decode( hb_libmpeg2_t * m, hb_buffer_t * buf_es,
for( i = 0; i < hb_list_count( m->title->list_subtitle ); i++ )
{
subtitle = hb_list_item( m->title->list_subtitle, i);
- if( subtitle && subtitle->source == CCSUB )
+ /*
+ * Let's call them 608 subs for now even if they aren't, since they
+ * are the only types we grok.
+ */
+ if( subtitle && subtitle->source == CC608SUB )
{
found = 1;
break;
@@ -454,7 +460,7 @@ static int hb_libmpeg2_decode( hb_libmpeg2_t * m, hb_buffer_t * buf_es,
snprintf( subtitle->lang, sizeof( subtitle->lang ), "Closed Captions");
snprintf( subtitle->iso639_2, sizeof( subtitle->iso639_2 ), "und");
subtitle->format = TEXTSUB;
- subtitle->source = CCSUB;
+ subtitle->source = CC608SUB;
subtitle->dest = PASSTHRUSUB;
subtitle->type = 5;
@@ -525,9 +531,6 @@ static void hb_libmpeg2_close( hb_libmpeg2_t ** _m )
mpeg2_close( m->libmpeg2 );
- free( m->cc608.data608 );
- general_608_close( &m->cc608 );
-
free( m );
*_m = NULL;
}
@@ -565,7 +568,8 @@ static int decmpeg2Init( hb_work_object_t * w, hb_job_t * job )
}
/*
- * If not scanning, then are we supposed to extract Closed Captions?
+ * If not scanning, then are we supposed to extract Closed Captions
+ * and send them to the decoder?
*/
if( job )
{
@@ -575,54 +579,15 @@ static int decmpeg2Init( hb_work_object_t * w, hb_job_t * job )
for( i = 0; i < hb_list_count( job->list_subtitle ); i++ )
{
subtitle = hb_list_item( job->list_subtitle, i);
- if( subtitle && subtitle->source == CCSUB )
+ if( subtitle && subtitle->source == CC608SUB )
{
pv->libmpeg2->subtitle = subtitle;
- pv->libmpeg2->cc608.subtitle = subtitle;
break;
}
}
}
- /*
- * During a scan add a Closed Caption subtitle track to the title,
- * since we may have CC. Don't bother actually trying to detect CC
- * since we'd have to go through too much of the source.
- *
- if( !job && w->title )
- {
- hb_subtitle_t * subtitle;
- int found = 0;
- int i;
-
- for( i = 0; i < hb_list_count( w->title->list_subtitle ); i++ )
- {
- subtitle = hb_list_item( w->title->list_subtitle, i);
- if( subtitle && subtitle->source == CCSUB )
- {
- found = 1;
- break;
- }
- }
-
- if( !found )
- {
- subtitle = calloc( sizeof( hb_subtitle_t ), 1 );
- subtitle->track = 0;
- subtitle->id = 0x0;
- snprintf( subtitle->lang, sizeof( subtitle->lang ), "Closed Captions");
- snprintf( subtitle->iso639_2, sizeof( subtitle->iso639_2 ), "und");
- subtitle->format = TEXTSUB;
- subtitle->source = CCSUB;
- subtitle->dest = PASSTHRUSUB;
- subtitle->type = 5;
-
- hb_list_add( w->title->list_subtitle, subtitle );
- }
- }
- */
-
return 0;
}
@@ -663,7 +628,12 @@ static int decmpeg2Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
*/
if( pv->libmpeg2->subtitle )
{
- handle_end_of_data( &pv->libmpeg2->cc608 );
+ hb_buffer_t *buf_eof = hb_buffer_init( 0 );
+
+ if( buf_eof )
+ {
+ hb_fifo_push( pv->libmpeg2->subtitle->fifo_in, buf_eof );
+ }
}
}
diff --git a/libhb/decvobsub.c b/libhb/decvobsub.c
index 102d18fe7..fd1f89179 100644
--- a/libhb/decvobsub.c
+++ b/libhb/decvobsub.c
@@ -122,9 +122,9 @@ void decsubClose( hb_work_object_t * w )
free( w->private_data );
}
-hb_work_object_t hb_decsub =
+hb_work_object_t hb_decvobsub =
{
- WORK_DECSUB,
+ WORK_DECVOBSUB,
"VOBSUB decoder",
decsubInit,
decsubWork,
diff --git a/libhb/encvobsub.c b/libhb/encvobsub.c
index e04fcd4fa..ee49d7ad6 100644
--- a/libhb/encvobsub.c
+++ b/libhb/encvobsub.c
@@ -51,9 +51,9 @@ void encsubClose( hb_work_object_t * w )
free( w->private_data );
}
-hb_work_object_t hb_encsub =
+hb_work_object_t hb_encvobsub =
{
- WORK_ENCSUB,
+ WORK_ENCVOBSUB,
"VOBSUB encoder",
encsubInit,
encsubWork,
diff --git a/libhb/hb.c b/libhb/hb.c
index cdde54f4f..661e1df47 100644
--- a/libhb/hb.c
+++ b/libhb/hb.c
@@ -229,13 +229,14 @@ hb_handle_t * hb_init_dl( int verbose, int update_check )
hb_register( &hb_sync );
hb_register( &hb_decmpeg2 );
- hb_register( &hb_decsub );
- hb_register( &hb_encsub );
+ hb_register( &hb_decvobsub );
+ hb_register( &hb_encvobsub );
+ hb_register( &hb_deccc608 );
hb_register( &hb_render );
hb_register( &hb_encavcodec );
hb_register( &hb_encxvid );
hb_register( &hb_encx264 );
- hb_register( &hb_enctheora );
+ hb_register( &hb_enctheora );
hb_register( &hb_deca52 );
hb_register( &hb_decdca );
hb_register( &hb_decavcodec );
diff --git a/libhb/hb.h b/libhb/hb.h
index 860f441e0..3cf308e3a 100644
--- a/libhb/hb.h
+++ b/libhb/hb.h
@@ -21,8 +21,9 @@ hb_handle_t * hb_init_dl ( int verbose, int update_check ); // hb_init for use w
hb_init_real( v, u ); \
hb_register( &hb_sync ); \
hb_register( &hb_decmpeg2 ); \
-hb_register( &hb_decsub ); \
-hb_register( &hb_encsub ); \
+hb_register( &hb_decvobsub ); \
+hb_register( &hb_encvobsub ); \
+hb_register( &hb_deccc608 ); \
hb_register( &hb_render ); \
hb_register( &hb_encavcodec ); \
hb_register( &hb_encxvid ); \
@@ -43,8 +44,9 @@ hb_register( &hb_encvorbis ); \
hb_init_real( v, u ); \
hb_register( &hb_sync ); \
hb_register( &hb_decmpeg2 ); \
-hb_register( &hb_decsub ); \
-hb_register( &hb_encsub ); \
+hb_register( &hb_decvobsub ); \
+hb_register( &hb_encvobsub ); \
+hb_register( &hb_deccc608 ); \
hb_register( &hb_render ); \
hb_register( &hb_encavcodec ); \
hb_register( &hb_encx264 ); \
diff --git a/libhb/internal.h b/libhb/internal.h
index f5df6cec9..b05e50a48 100644
--- a/libhb/internal.h
+++ b/libhb/internal.h
@@ -254,8 +254,9 @@ enum
{
WORK_SYNC = 1,
WORK_DECMPEG2,
- WORK_DECSUB,
- WORK_ENCSUB,
+ WORK_DECCC608,
+ WORK_DECVOBSUB,
+ WORK_ENCVOBSUB,
WORK_RENDER,
WORK_ENCAVCODEC,
WORK_ENCXVID,
diff --git a/libhb/sync.c b/libhb/sync.c
index 67093d1e6..c5842148c 100644
--- a/libhb/sync.c
+++ b/libhb/sync.c
@@ -293,6 +293,19 @@ static void SyncVideo( hb_work_object_t * w )
{
/* we got an end-of-stream. Feed it downstream & signal that we're done. */
hb_fifo_push( job->fifo_sync, hb_buffer_init( 0 ) );
+
+ /*
+ * Push through any subtitle EOFs in case they were not synced through.
+ */
+ for( i = 0; i < hb_list_count( job->list_subtitle ); i++)
+ {
+ subtitle = hb_list_item( job->list_subtitle, i );
+ if( subtitle->dest == PASSTHRUSUB )
+ {
+ hb_fifo_push( subtitle->fifo_out, hb_buffer_init( 0 ) );
+ }
+ }
+
pv->busy &=~ 1;
return;
}
@@ -313,6 +326,18 @@ static void SyncVideo( hb_work_object_t * w )
* video (we don't know its duration). On DVDs the final frame
* is often strange and dropping it seems to be a good idea. */
hb_fifo_push( job->fifo_sync, hb_buffer_init( 0 ) );
+
+ /*
+ * Push through any subtitle EOFs in case they were not synced through.
+ */
+ for( i = 0; i < hb_list_count( job->list_subtitle ); i++)
+ {
+ subtitle = hb_list_item( job->list_subtitle, i );
+ if( subtitle->dest == PASSTHRUSUB )
+ {
+ hb_fifo_push( subtitle->fifo_out, hb_buffer_init( 0 ) );
+ }
+ }
pv->busy &=~ 1;
return;
}
@@ -398,7 +423,8 @@ static void SyncVideo( hb_work_object_t * w )
/*
* Rewrite timestamps on subtitles that need it (on raw queue).
*/
- if( subtitle->source == CCSUB )
+ if( subtitle->source == CC608SUB ||
+ subtitle->source == CC708SUB )
{
/*
* Rewrite timestamps on subtitles that came from Closed Captions
@@ -416,7 +442,7 @@ static void SyncVideo( hb_work_object_t * w )
*
* Bypass the sync fifo altogether.
*/
- if( sub->size == 0 )
+ if( sub->size <= 0 )
{
sub = hb_fifo_get( subtitle->fifo_raw );
hb_fifo_push( subtitle->fifo_out, sub );
diff --git a/libhb/work.c b/libhb/work.c
index 323f4cf4a..7b270ca70 100644
--- a/libhb/work.c
+++ b/libhb/work.c
@@ -280,7 +280,9 @@ void hb_display_job_info( hb_job_t * job )
{
hb_log( " * subtitle track %i, %s (id %x) %s [%s] -> %s ", subtitle->track, subtitle->lang, subtitle->id,
subtitle->format == PICTURESUB ? "Picture" : "Text",
- subtitle->source == VOBSUB ? "VOBSUB" : (subtitle->source == CCSUB ? "CC" : "SRT"),
+ subtitle->source == VOBSUB ? "VOBSUB" :
+ ((subtitle->source == CC608SUB ||
+ subtitle->source == CC708SUB) ? "CC" : "SRT"),
subtitle->dest == RENDERSUB ? "Render/Burn in" : "Pass-Through");
}
}
@@ -508,12 +510,21 @@ static void do_job( hb_job_t * job, int cpu_count )
}
}
- if( !job->indepth_scan || job->subtitle_force ) {
+ if( (!job->indepth_scan || job->subtitle_force) &&
+ subtitle->source == VOBSUB ) {
/*
* Don't add threads for subtitles when we are scanning, unless
* looking for forced subtitles.
*/
- w = hb_get_work( WORK_DECSUB );
+ w = hb_get_work( WORK_DECVOBSUB );
+ w->fifo_in = subtitle->fifo_in;
+ w->fifo_out = subtitle->fifo_raw;
+ hb_list_add( job->list_work, w );
+ }
+
+ if( !job->indepth_scan && subtitle->source == CC608SUB )
+ {
+ w = hb_get_work( WORK_DECCC608 );
w->fifo_in = subtitle->fifo_in;
w->fifo_out = subtitle->fifo_raw;
hb_list_add( job->list_work, w );
@@ -527,7 +538,7 @@ static void do_job( hb_job_t * job, int cpu_count )
* Passing through a subtitle picture, this will have to
* be rle encoded before muxing.
*/
- w = hb_get_work( WORK_ENCSUB );
+ w = hb_get_work( WORK_ENCVOBSUB );
w->fifo_in = subtitle->fifo_sync;
w->fifo_out = subtitle->fifo_out;
hb_list_add( job->list_work, w );