From d62dfce98fda79ef6cd10d4089141c81fe994223 Mon Sep 17 00:00:00 2001 From: John Stebbins Date: Fri, 2 Aug 2019 11:41:13 -0700 Subject: add subtitle track name read/write Works similar to audio track names. If source has a subtitle track name, hb_subtitle_t.name is set. To set output subtitle track name, set hb_subtitle_config_t.name. Source track names are available in title returned by hb_title_to_dict and hb_title_to_json in SubtitleList[].Name In job dict it is also SubtitleList[].Name hb_preset_job_init and hb_preset_job_init_json initialize output tracks with the source track name. Also adds subtitle name support to LinGui --- libhb/common.c | 18 ++++++++++++++++++ libhb/common.h | 20 +++++++++++--------- libhb/hb_json.c | 15 ++++++++++++++- libhb/muxavformat.c | 6 ++++++ libhb/preset.c | 17 ++++++++++------- libhb/stream.c | 10 +++++++--- 6 files changed, 66 insertions(+), 20 deletions(-) (limited to 'libhb') diff --git a/libhb/common.c b/libhb/common.c index e21590fa2..df5d60467 100644 --- a/libhb/common.c +++ b/libhb/common.c @@ -4809,6 +4809,14 @@ hb_subtitle_t *hb_subtitle_copy(const hb_subtitle_t *src) subtitle->extradata = malloc( src->extradata_size ); memcpy( subtitle->extradata, src->extradata, src->extradata_size ); } + if (src->name != NULL) + { + subtitle->name = strdup(src->name); + } + if (src->config.name != NULL) + { + subtitle->config.name = strdup(src->config.name); + } } return subtitle; } @@ -4846,6 +4854,8 @@ void hb_subtitle_close( hb_subtitle_t **sub ) { if ( sub && *sub ) { + free ((char*)(*sub)->name); + free ((char*)(*sub)->config.name); free ((*sub)->extradata); free(*sub); *sub = NULL; @@ -4905,6 +4915,10 @@ int hb_subtitle_add(const hb_job_t * job, const hb_subtitle_config_t * subtitlec // "track" in job->list_audio is an index into title->list_audio subtitle->track = track; subtitle->config = *subtitlecfg; + if (subtitlecfg->name != NULL && subtitlecfg->name[0] != 0) + { + subtitle->config.name = strdup(subtitlecfg->name); + } subtitle->out_track = hb_list_count(job->list_subtitle) + 1; hb_list_add(job->list_subtitle, subtitle); return 1; @@ -4944,6 +4958,10 @@ int hb_import_subtitle_add( const hb_job_t * job, strcpy(subtitle->iso639_2, lang->iso639_2); subtitle->config = *subtitlecfg; + if (subtitlecfg->name != NULL && subtitlecfg->name[0] != 0) + { + subtitle->config.name = strdup(subtitlecfg->name); + } hb_list_add(job->list_subtitle, subtitle); return 1; diff --git a/libhb/common.h b/libhb/common.h index e7c9b2b5f..6cf949881 100644 --- a/libhb/common.h +++ b/libhb/common.h @@ -297,13 +297,14 @@ void hb_image_close(hb_image_t **_image); struct hb_subtitle_config_s { enum subdest { RENDERSUB, PASSTHRUSUB } dest; - int force; - int default_track; - + int force; + int default_track; + const char * name; + /* SRT subtitle tracks only */ - char src_filename[256]; - char src_codeset[40]; - int64_t offset; + char src_filename[256]; + char src_codeset[40]; + int64_t offset; }; /******************************************************************************* @@ -966,9 +967,10 @@ struct hb_subtitle_s enum subsource { VOBSUB, CC608SUB, /*unused*/CC708SUB, UTF8SUB, TX3GSUB, SSASUB, PGSSUB, IMPORTSRT, IMPORTSSA, SRTSUB = IMPORTSRT } source; - char lang[1024]; - char iso639_2[4]; - uint32_t attributes; /* Closed Caption, Childrens, Directors etc */ + const char * name; + char lang[1024]; + char iso639_2[4]; + uint32_t attributes; /* Closed Caption, Childrens, Directors etc */ // Color lookup table for VOB subtitle tracks. Each entry is in YCbCr format. // Must be filled out by the demuxer for VOB subtitle tracks. diff --git a/libhb/hb_json.c b/libhb/hb_json.c index 08e9400a0..09ef619d7 100644 --- a/libhb/hb_json.c +++ b/libhb/hb_json.c @@ -441,6 +441,10 @@ static hb_dict_t* hb_title_to_dict_internal( hb_title_t *title ) hb_error("json pack failure: %s", error.text); return NULL; } + if (subtitle->name != NULL) + { + hb_dict_set_string(subtitle_dict, "Name", subtitle->name); + } hb_value_array_append(subtitle_list, subtitle_dict); } hb_dict_set(dict, "SubtitleList", subtitle_list); @@ -889,6 +893,10 @@ hb_dict_t* hb_job_to_dict( const hb_job_t * job ) "Burn", hb_value_bool(subtitle->config.dest == RENDERSUB), "Offset", hb_value_int(subtitle->config.offset)); } + if (subtitle->config.name != NULL) + { + hb_dict_set_string(subtitle_dict, "Name", subtitle->config.name); + } hb_value_array_append(subtitle_list, subtitle_dict); } @@ -1579,10 +1587,12 @@ hb_job_t* hb_dict_to_job( hb_handle_t * h, hb_dict_t *dict ) int burn = 0; const char *importfile = NULL; json_int_t offset = 0; + const char *name = NULL; result = json_unpack_ex(subtitle_dict, &error, 0, - "{s?i, s?{s:s}, s?{s:s}}", + "{s?i, s?s, s?{s:s}, s?{s:s}}", "Track", unpack_i(&track), + "Name", unpack_s(&name), // Support legacy "SRT" import "SRT", "Filename", unpack_s(&importfile), @@ -1594,6 +1604,7 @@ hb_job_t* hb_dict_to_job( hb_handle_t * h, hb_dict_t *dict ) hb_job_close(&job); return NULL; } + // Embedded subtitle track if (track >= 0 && importfile == NULL) { @@ -1602,6 +1613,7 @@ hb_job_t* hb_dict_to_job( hb_handle_t * h, hb_dict_t *dict ) if (subtitle != NULL) { sub_config = subtitle->config; + sub_config.name = name; result = json_unpack_ex(subtitle_dict, &error, 0, "{s?b, s?b, s?b, s?I}", "Default", unpack_b(&sub_config.default_track), @@ -1650,6 +1662,7 @@ hb_job_t* hb_dict_to_job( hb_handle_t * h, hb_dict_t *dict ) hb_job_close(&job); return NULL; } + sub_config.name = name; sub_config.offset = offset; sub_config.dest = burn ? RENDERSUB : PASSTHRUSUB; strncpy(sub_config.src_codeset, srtcodeset, 39); diff --git a/libhb/muxavformat.c b/libhb/muxavformat.c index e353b0e32..353e519fc 100644 --- a/libhb/muxavformat.c +++ b/libhb/muxavformat.c @@ -960,6 +960,12 @@ static int avformatInit( hb_mux_object_t * m ) { av_dict_set(&track->st->metadata, "language", lang, 0); } + if (subtitle->config.name != NULL && subtitle->config.name[0] != 0) + { + // Set subtitle track title + av_dict_set(&track->st->metadata, "title", + subtitle->config.name, 0); + } } if (need_fonts) diff --git a/libhb/preset.c b/libhb/preset.c index 949b5f4a7..5a7425a96 100644 --- a/libhb/preset.c +++ b/libhb/preset.c @@ -891,13 +891,15 @@ static int find_subtitle_track(const hb_title_t *title, } static void add_subtitle(hb_value_array_t *list, int track, - int make_default, int force, int burn) + int make_default, int force, int burn, + const char * name) { hb_dict_t *subtitle_dict = hb_dict_init(); - hb_dict_set(subtitle_dict, "Track", hb_value_int(track)); - hb_dict_set(subtitle_dict, "Default", hb_value_bool(make_default)); - hb_dict_set(subtitle_dict, "Forced", hb_value_bool(force)); - hb_dict_set(subtitle_dict, "Burn", hb_value_bool(burn)); + hb_dict_set_int(subtitle_dict, "Track", track); + hb_dict_set_bool(subtitle_dict, "Default", make_default); + hb_dict_set_bool(subtitle_dict, "Forced", force); + hb_dict_set_bool(subtitle_dict, "Burn", burn); + hb_dict_set_string(subtitle_dict, "Name", name); hb_value_array_append(list, subtitle_dict); } @@ -962,7 +964,7 @@ static void add_subtitle_for_lang(hb_value_array_t *list, hb_title_t *title, behavior->burn_first &= !burn; behavior->one_burned |= burn; behavior->used[t] = 1; - add_subtitle(list, t, make_default, 0 /*!force*/, burn); + add_subtitle(list, t, make_default, 0 /*!force*/, burn, subtitle->name); } } @@ -1180,7 +1182,8 @@ int hb_preset_job_add_subtitles(hb_handle_t *h, int title_index, behavior.burn_first); behavior.used[track] = 1; behavior.one_burned |= burn; - add_subtitle(list, track, 0 /*default*/, 0 /*!force*/, burn); + add_subtitle(list, track, 0 /*default*/, 0 /*!force*/, burn, + subtitle->name); break; } } diff --git a/libhb/stream.c b/libhb/stream.c index 1448ac4f0..8182cb35c 100644 --- a/libhb/stream.c +++ b/libhb/stream.c @@ -5414,6 +5414,8 @@ static void add_ffmpeg_subtitle( hb_title_t *title, hb_stream_t *stream, int id { AVStream * st = stream->ffmpeg_ic->streams[id]; AVCodecParameters * codecpar = st->codecpar; + AVDictionaryEntry * tag_lang = av_dict_get(st->metadata, "language", NULL, 0 ); + AVDictionaryEntry * tag_name = av_dict_get(st->metadata, "title", NULL, 0); hb_subtitle_t *subtitle = calloc( 1, sizeof(*subtitle) ); @@ -5474,16 +5476,18 @@ static void add_ffmpeg_subtitle( hb_title_t *title, hb_stream_t *stream, int id return; } - AVDictionaryEntry *tag; iso639_lang_t *lang; - tag = av_dict_get( st->metadata, "language", NULL, 0 ); - lang = lang_for_code2( tag ? tag->value : "und" ); + lang = lang_for_code2(tag_lang ? tag_lang->value : "und"); snprintf(subtitle->lang, sizeof( subtitle->lang ), "%s [%s]", strlen(lang->native_name) ? lang->native_name : lang->eng_name, hb_subsource_name(subtitle->source)); strncpy(subtitle->iso639_2, lang->iso639_2, 3); subtitle->iso639_2[3] = 0; + if (tag_name != NULL) + { + subtitle->name = strdup(tag_name->value); + } // Copy the extradata for the subtitle track if (codecpar->extradata != NULL) -- cgit v1.2.3