diff options
author | jstebbins <[email protected]> | 2010-06-01 20:21:49 +0000 |
---|---|---|
committer | jstebbins <[email protected]> | 2010-06-01 20:21:49 +0000 |
commit | 9728615d2d5871efb7c37cdedb9175fa1b7844d6 (patch) | |
tree | 166ddd10201b26e90e3d810562408b7983e38985 | |
parent | f22a86152809db1e5a44b0a24b4c865c8f9f997d (diff) |
Add SSA subtitle support
Thanks to davidfster
git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@3342 b64f7644-9d1e-0410-96f1-a4d463321fa5
-rw-r--r-- | AUTHORS | 1 | ||||
-rw-r--r-- | gtk/src/hb-backend.c | 13 | ||||
-rw-r--r-- | gtk/src/main.c | 21 | ||||
-rw-r--r-- | gtk/src/subtitlehandler.c | 65 | ||||
-rw-r--r-- | libhb/common.h | 3 | ||||
-rw-r--r-- | libhb/dectx3gsub.c | 31 | ||||
-rw-r--r-- | libhb/hb.c | 2 | ||||
-rw-r--r-- | libhb/internal.h | 1 | ||||
-rw-r--r-- | libhb/stream.c | 7 | ||||
-rw-r--r-- | libhb/sync.c | 3 | ||||
-rw-r--r-- | libhb/work.c | 14 |
11 files changed, 78 insertions, 83 deletions
@@ -46,6 +46,7 @@ Edward Groenendaal <[email protected]> (eddyg) David Foster <unknown> (davidfstr) + Subtitles from file inputs + + SSA subtitle support Rodney Hester <[email protected]> (rhester) + iPod firmware 1.2+ 640x480 MPEG-4/H.264 support diff --git a/gtk/src/hb-backend.c b/gtk/src/hb-backend.c index 6f6cf0ce2..5f28ffea2 100644 --- a/gtk/src/hb-backend.c +++ b/gtk/src/hb-backend.c @@ -1155,17 +1155,24 @@ ghb_subtitle_source_name(gint source) switch (source) { case VOBSUB: - name = "Bitmap"; + name = "VOBSUB"; break; case TX3GSUB: + name = "TX3G"; + break; case UTF8SUB: + name = "UTF8"; + break; case CC708SUB: case CC608SUB: - name = "Text"; + name = "CC"; break; case SRTSUB: name = "SRT"; break; + case SSASUB: + name = "SSA"; + break; default: break; } @@ -1976,11 +1983,13 @@ subtitle_track_opts_set(GtkBuilder *builder, const gchar *name, gint titleindex) subtitle = (hb_subtitle_t *)hb_list_item(title->list_subtitle, ii); // Skip subtitles that must be burned if there is already // a burned subtitle in the list +#if 0 if (subtitle->source == VOBSUB) { options[ii] = g_strdup_printf("%d - %s", ii+1, subtitle->lang); } else +#endif { options[ii] = g_strdup_printf("%d - %s (%s)", ii+1, subtitle->lang, diff --git a/gtk/src/main.c b/gtk/src/main.c index 6d0d81441..e043623e0 100644 --- a/gtk/src/main.c +++ b/gtk/src/main.c @@ -406,10 +406,10 @@ bind_subtitle_tree_model (signal_user_data_t *ud) // values that I need // Track, force, burn, default, type, srt offset, track short, source // force visible, burn visible, offset visible - treestore = gtk_list_store_new(11, + treestore = gtk_list_store_new(10, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, - G_TYPE_BOOLEAN, G_TYPE_STRING, + G_TYPE_BOOLEAN, G_TYPE_INT, G_TYPE_STRING, G_TYPE_INT, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, @@ -420,19 +420,19 @@ bind_subtitle_tree_model (signal_user_data_t *ud) column = gtk_tree_view_column_new_with_attributes( _("Track"), cell, "text", 0, NULL); gtk_tree_view_append_column(treeview, GTK_TREE_VIEW_COLUMN(column)); - gtk_tree_view_column_set_min_width (column, 190); - gtk_tree_view_column_set_max_width (column, 190); + gtk_tree_view_column_set_min_width (column, 350); + gtk_tree_view_column_set_max_width (column, 350); cell = gtk_cell_renderer_toggle_new(); column = gtk_tree_view_column_new_with_attributes( - _("Forced Only"), cell, "active", 1, "visible", 8, NULL); + _("Forced Only"), cell, "active", 1, "visible", 7, NULL); gtk_tree_view_append_column(treeview, GTK_TREE_VIEW_COLUMN(column)); g_signal_connect(cell, "toggled", subtitle_forced_toggled_cb, ud); cell = gtk_cell_renderer_toggle_new(); gtk_cell_renderer_toggle_set_radio(GTK_CELL_RENDERER_TOGGLE(cell), TRUE); column = gtk_tree_view_column_new_with_attributes( - _("Burned In"), cell, "active", 2, "visible", 9, NULL); + _("Burned In"), cell, "active", 2, "visible", 8, NULL); gtk_tree_view_append_column(treeview, GTK_TREE_VIEW_COLUMN(column)); g_signal_connect(cell, "toggled", subtitle_burned_toggled_cb, ud); @@ -445,14 +445,7 @@ bind_subtitle_tree_model (signal_user_data_t *ud) cell = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes( - _("Type"), cell, "text", 4, NULL); - gtk_tree_view_append_column(treeview, GTK_TREE_VIEW_COLUMN(column)); - gtk_tree_view_column_set_min_width (column, 190); - gtk_tree_view_column_set_max_width (column, 190); - - cell = gtk_cell_renderer_text_new(); - column = gtk_tree_view_column_new_with_attributes( - _("Srt Offset"), cell, "text", 5, "visible", 10, NULL); + _("Srt Offset"), cell, "text", 4, "visible", 9, NULL); gtk_tree_view_append_column(treeview, GTK_TREE_VIEW_COLUMN(column)); diff --git a/gtk/src/subtitlehandler.c b/gtk/src/subtitlehandler.c index 44f06a094..fddb6a9fd 100644 --- a/gtk/src/subtitlehandler.c +++ b/gtk/src/subtitlehandler.c @@ -642,30 +642,6 @@ subtitle_default_toggled_cb( ghb_live_reset(ud); } -static const char* -subtitle_source_name(gint source) -{ - const gchar * name; - - switch (source) - { - case VOBSUB: - name = "Bitmap"; - break; - case CC708SUB: - case CC608SUB: - name = "Text"; - break; - case SRTSUB: - name = "SRT"; - break; - default: - name = "Unknown"; - break; - } - return name; -} - static void subtitle_list_refresh_selected(signal_user_data_t *ud) { @@ -721,8 +697,6 @@ subtitle_list_refresh_selected(signal_user_data_t *ud) lang = ghb_settings_combo_option(settings, "SrtLanguage"); code = ghb_settings_get_string(settings, "SrtCodeset"); - track = g_strdup_printf("%s (%s)", lang, code); - g_free(code); s_track = ghb_settings_get_string(settings, "SrtFile"); if (g_file_test(s_track, G_FILE_TEST_IS_REGULAR)) @@ -730,13 +704,16 @@ subtitle_list_refresh_selected(signal_user_data_t *ud) gchar *basename; basename = g_path_get_basename(s_track); + track = g_strdup_printf("%s (%s)(SRT)(%s)", lang, code, basename); source = g_strdup_printf("SRT (%s)", basename); g_free(basename); } else { + track = g_strdup_printf("%s (%s)(SRT)", lang, code); source = g_strdup_printf("SRT (none)"); } + g_free(code); offset = ghb_settings_get_int(settings, "SrtOffset"); forced = FALSE; @@ -746,7 +723,7 @@ subtitle_list_refresh_selected(signal_user_data_t *ud) { track = g_strdup( ghb_settings_combo_option(settings, "SubtitleTrack")); - source = g_strdup(subtitle_source_name(i_source)); + source = g_strdup(ghb_subtitle_source_name(i_source)); s_track = ghb_settings_get_string(settings, "SubtitleTrack"); forced = ghb_settings_get_boolean(settings, "SubtitleForced"); @@ -763,13 +740,12 @@ subtitle_list_refresh_selected(signal_user_data_t *ud) 1, forced, 2, burned, 3, def, - 4, source, - 5, offset, + 4, offset, // These are used to set combo box values when a list item is selected - 6, s_track, - 7, i_source, + 5, s_track, + 6, i_source, + 7, allow_burn_force, 8, allow_burn_force, - 9, allow_burn_force, -1); g_free(track); g_free(source); @@ -930,7 +906,7 @@ add_to_subtitle_list( s_track = ghb_settings_get_string(settings, "SubtitleTrack"); i_source = ghb_settings_get_int(settings, "SubtitleSource"); - source = subtitle_source_name(i_source); + source = ghb_subtitle_source_name(i_source); if (i_source == VOBSUB) allow_burn_force = TRUE; @@ -942,13 +918,12 @@ add_to_subtitle_list( 1, forced, 2, burned, 3, def, - 4, source, // These are used to set combo box values when a list item is selected - 6, s_track, - 7, i_source, + 5, s_track, + 6, i_source, + 7, allow_burn_force, 8, allow_burn_force, - 9, allow_burn_force, - 10, FALSE, + 9, FALSE, -1); gtk_tree_selection_select_iter(selection, &iter); g_free(s_track); @@ -975,7 +950,6 @@ add_to_srt_list( lang = ghb_settings_combo_option(settings, "SrtLanguage"); code = ghb_settings_get_string(settings, "SrtCodeset"); - track = g_strdup_printf("%s (%s)", lang, code); forced = FALSE; burned = FALSE; def = ghb_settings_get_boolean(settings, "SubtitleDefaultTrack"); @@ -986,11 +960,13 @@ add_to_srt_list( gchar *basename; basename = g_path_get_basename(filename); + track = g_strdup_printf("%s (%s)(SRT)(%s)", lang, code, basename); source = g_strdup_printf("SRT (%s)", basename); g_free(basename); } else { + track = g_strdup_printf("%s (%s)(SRT)", lang, code); source = g_strdup_printf("SRT (none)"); } i_source = SRTSUB; @@ -1003,14 +979,13 @@ add_to_srt_list( 1, forced, 2, burned, 3, def, - 4, source, - 5, offset, + 4, offset, // These are used to set combo box values when a list item is selected - 6, filename, - 7, i_source, + 5, filename, + 6, i_source, + 7, FALSE, 8, FALSE, - 9, FALSE, - 10, TRUE, + 9, TRUE, -1); gtk_tree_selection_select_iter(selection, &iter); g_free(code); diff --git a/libhb/common.h b/libhb/common.h index 0f9741924..7f2d61126 100644 --- a/libhb/common.h +++ b/libhb/common.h @@ -504,7 +504,7 @@ struct hb_subtitle_s hb_subtitle_config_t config; enum subtype { PICTURESUB, TEXTSUB } format; - enum subsource { VOBSUB, SRTSUB, CC608SUB, /*unused*/CC708SUB, UTF8SUB, TX3GSUB } source; + enum subsource { VOBSUB, SRTSUB, CC608SUB, /*unused*/CC708SUB, UTF8SUB, TX3GSUB, SSASUB } source; char lang[1024]; char iso639_2[4]; uint8_t type; /* Closed Caption, Childrens, Directors etc */ @@ -730,6 +730,7 @@ extern hb_work_object_t hb_deccc608; extern hb_work_object_t hb_decsrtsub; extern hb_work_object_t hb_decutf8sub; extern hb_work_object_t hb_dectx3gsub; +extern hb_work_object_t hb_decssasub; extern hb_work_object_t hb_render; extern hb_work_object_t hb_encavcodec; extern hb_work_object_t hb_encx264; diff --git a/libhb/dectx3gsub.c b/libhb/dectx3gsub.c index e9a178ec0..e466ac5d5 100644 --- a/libhb/dectx3gsub.c +++ b/libhb/dectx3gsub.c @@ -128,6 +128,8 @@ static hb_buffer_t *tx3g_decode_to_utf8( hb_buffer_t *in ) */ int maxOutputSize = textLength + (numStyleRecords * NUM_FACE_STYLE_FLAGS * (MAX_OPEN_TAG_SIZE + MAX_CLOSE_TAG_SIZE)); hb_buffer_t *out = hb_buffer_init( maxOutputSize ); + if ( out == NULL ) + goto fail; uint8_t *dst = out->data; int charIndex = 0; for ( pos = text, end = text + textLength; pos < end; pos++ ) { @@ -165,6 +167,7 @@ static hb_buffer_t *tx3g_decode_to_utf8( hb_buffer_t *in ) out->start = in->start; out->stop = in->stop; +fail: free( startStyle ); free( endStyle ); @@ -204,19 +207,21 @@ static int dectx3gWork( hb_work_object_t * w, hb_buffer_t ** buf_in, out = hb_buffer_init( 0 ); } - // We shouldn't be storing the extra NULL character, - // but the MP4 muxer expects this, unfortunately. - if ( out->size > 0 && out->data[out->size - 1] != '\0' ) { - // NOTE: out->size remains unchanged - hb_buffer_realloc( out, out->size + 1 ); - out->data[out->size] = '\0'; - } - - // If the input packet was non-empty, do not pass through - // an empty output packet (even if the subtitle was empty), - // as this would be interpreted as an end-of-stream - if ( in->size > 0 && out->size == 0 ) { - hb_buffer_close(&out); + if ( out != NULL ) { + // We shouldn't be storing the extra NULL character, + // but the MP4 muxer expects this, unfortunately. + if ( out->size > 0 && out->data[out->size - 1] != '\0' ) { + // NOTE: out->size remains unchanged + hb_buffer_realloc( out, out->size + 1 ); + out->data[out->size] = '\0'; + } + + // If the input packet was non-empty, do not pass through + // an empty output packet (even if the subtitle was empty), + // as this would be interpreted as an end-of-stream + if ( in->size > 0 && out->size == 0 ) { + hb_buffer_close(&out); + } } // Dispose the input packet, as it is no longer needed diff --git a/libhb/hb.c b/libhb/hb.c index 075bb81f1..a835d2766 100644 --- a/libhb/hb.c +++ b/libhb/hb.c @@ -318,6 +318,7 @@ hb_handle_t * hb_init( int verbose, int update_check ) hb_register( &hb_decsrtsub ); hb_register( &hb_decutf8sub ); hb_register( &hb_dectx3gsub ); + hb_register( &hb_decssasub ); hb_register( &hb_render ); hb_register( &hb_encavcodec ); hb_register( &hb_encx264 ); @@ -421,6 +422,7 @@ hb_handle_t * hb_init_dl( int verbose, int update_check ) hb_register( &hb_decsrtsub ); hb_register( &hb_decutf8sub ); hb_register( &hb_dectx3gsub ); + hb_register( &hb_decssasub ); hb_register( &hb_render ); hb_register( &hb_encavcodec ); hb_register( &hb_encx264 ); diff --git a/libhb/internal.h b/libhb/internal.h index f7092f104..135d73fcc 100644 --- a/libhb/internal.h +++ b/libhb/internal.h @@ -311,6 +311,7 @@ enum WORK_DECSRTSUB, WORK_DECUTF8SUB, WORK_DECTX3GSUB, + WORK_DECSSASUB, WORK_ENCVOBSUB, WORK_RENDER, WORK_ENCAVCODEC, diff --git a/libhb/stream.c b/libhb/stream.c index 35b705af4..24093e62a 100644 --- a/libhb/stream.c +++ b/libhb/stream.c @@ -2982,14 +2982,11 @@ static void add_ffmpeg_subtitle( hb_title_t *title, hb_stream_t *stream, int id subtitle->source = TX3GSUB; subtitle->config.dest = PASSTHRUSUB; break; - // TODO(davidfstr): implement SSA subtitle support - /* case CODEC_ID_SSA: subtitle->format = TEXTSUB; subtitle->source = SSASUB; subtitle->config.dest = PASSTHRUSUB; break; - */ default: hb_log( "add_ffmpeg_subtitle: unknown subtitle stream type: 0x%x", (int) codec->codec_id ); free(subtitle); @@ -3262,6 +3259,10 @@ static int ffmpeg_read( hb_stream_t *stream, hb_buffer_t *buf ) * VOB subtitles (CODEC_ID_DVD_SUBTITLE) do not have their duration stored in * either field. This is not a problem because the VOB decoder can extract this * information from the packet payload itself. + * + * SSA subtitles (CODEC_ID_SSA) do not have their duration stored in + * either field. This is not a problem because the SSA decoder can extract this + * information from the packet payload itself. */ enum CodecID ffmpeg_pkt_codec = stream->ffmpeg_ic->streams[stream->ffmpeg_pkt->stream_index]->codec->codec_id; if ( ffmpeg_pkt_codec == CODEC_ID_TEXT ) { diff --git a/libhb/sync.c b/libhb/sync.c index 8972c7244..9c36ee30a 100644 --- a/libhb/sync.c +++ b/libhb/sync.c @@ -566,7 +566,8 @@ int syncVideoWork( hb_work_object_t * w, hb_buffer_t ** buf_in, subtitle->source == CC708SUB || subtitle->source == SRTSUB || subtitle->source == UTF8SUB || - subtitle->source == TX3GSUB) + subtitle->source == TX3GSUB || + subtitle->source == SSASUB) { /* * Rewrite timestamps on subtitles that came from Closed Captions diff --git a/libhb/work.c b/libhb/work.c index d6e60ea3a..c1891a683 100644 --- a/libhb/work.c +++ b/libhb/work.c @@ -320,7 +320,8 @@ void hb_display_job_info( hb_job_t * job ) subtitle->source == VOBSUB ? "VOBSUB" : subtitle->source == CC608SUB || subtitle->source == CC708SUB ? "CC" : subtitle->source == UTF8SUB ? "UTF-8" : - subtitle->source == TX3GSUB ? "TX3G" : "Unknown", + subtitle->source == TX3GSUB ? "TX3G" : + subtitle->source == SSASUB ? "SSA" : "Unknown", subtitle->config.dest == RENDERSUB ? "Render/Burn in" : "Pass-Through", subtitle->config.force ? ", Forced Only" : "", subtitle->config.default_track ? ", Default" : "" ); @@ -797,14 +798,19 @@ static void do_job( hb_job_t * job, int cpu_count ) if( !job->indepth_scan && subtitle->source == TX3GSUB ) { - // TODO(davidfstr): For MP4 containers, an alternate work-object - // should be used that just passes the packets through, - // instead of downconverting to UTF-8 subtitles. w = hb_get_work( WORK_DECTX3GSUB ); 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 == SSASUB ) + { + w = hb_get_work( WORK_DECSSASUB ); + w->fifo_in = subtitle->fifo_in; + w->fifo_out = subtitle->fifo_raw; + hb_list_add( job->list_work, w ); + } if( !job->indepth_scan && subtitle->format == PICTURESUB |