From 19c1ea52330dff8476be1c49b58bdacaf7f060dc Mon Sep 17 00:00:00 2001 From: John Stebbins Date: Mon, 9 Dec 2019 16:27:04 -0800 Subject: decavsub: add DVB subtitle *burn-only* support passthrough will hopefully come later ;) --- libhb/common.c | 2 +- libhb/decavsub.c | 22 +++++++----------- libhb/handbrake/common.h | 16 ++++++++++--- libhb/rendersub.c | 3 +++ libhb/stream.c | 59 +++++++++++++++++++++++++++++++++++++++++------- 5 files changed, 76 insertions(+), 26 deletions(-) (limited to 'libhb') diff --git a/libhb/common.c b/libhb/common.c index 3898fa7db..4d74f5cee 100644 --- a/libhb/common.c +++ b/libhb/common.c @@ -5006,7 +5006,7 @@ int hb_subtitle_can_burn( int source ) { return source == VOBSUB || source == PGSSUB || source == SSASUB || source == CC608SUB || source == UTF8SUB || source == TX3GSUB || - source == IMPORTSRT || source == IMPORTSSA; + source == IMPORTSRT || source == IMPORTSSA || source == DVBSUB; } int hb_subtitle_can_pass( int source, int mux ) diff --git a/libhb/decavsub.c b/libhb/decavsub.c index 24669fe4c..3e57e8b69 100644 --- a/libhb/decavsub.c +++ b/libhb/decavsub.c @@ -31,9 +31,6 @@ struct hb_avsub_context_s // display) - when doing forced-only extraction, only pass empty subtitles // through if we've seen a forced sub since the last empty sub uint8_t seen_forced_sub; - // if we start encoding partway through the source, we may encounter empty - // subtitles before we see any actual subtitle content - discard them - uint8_t discard_subtitle; }; struct hb_work_private_s @@ -49,7 +46,6 @@ hb_avsub_context_t * decavsubInit( hb_work_object_t * w, hb_job_t * job ) { return NULL; } - ctx->discard_subtitle = 1; ctx->seen_forced_sub = 0; ctx->last_pts = AV_NOPTS_VALUE; ctx->job = job; @@ -287,6 +283,14 @@ int decavsubWork( hb_avsub_context_t * ctx, return HB_WORK_OK; } + // Ugly hack, but ffmpeg doesn't consume a trailing 0xff in + // DVB subtitle buffers :( + if (ctx->subtitle->source == DVBSUB && + avp.size > usedBytes && + avp.data[usedBytes] == 0xff) + { + usedBytes++; + } if (usedBytes <= avp.size) { avp.data += usedBytes; @@ -321,16 +325,6 @@ int decavsubWork( hb_avsub_context_t * ctx, clear_sub = 1; } - // Discard leading empty subtitles - ctx->discard_subtitle = ctx->discard_subtitle && clear_sub; - - // are we doing Foreign Audio Search? or subtitle needs to be discarded? - if (ctx->job->indepth_scan || ctx->discard_subtitle) - { - avsubtitle_free(&subtitle); - continue; - } - // do we need this subtitle? usable_sub = // Need all subs diff --git a/libhb/handbrake/common.h b/libhb/handbrake/common.h index 175eae8e5..0576d5aa6 100644 --- a/libhb/handbrake/common.h +++ b/libhb/handbrake/common.h @@ -966,9 +966,19 @@ struct hb_subtitle_s hb_subtitle_config_t config; enum subtype { PICTURESUB, TEXTSUB } format; - enum subsource { VOBSUB, CC608SUB, /*unused*/CC708SUB, - UTF8SUB, TX3GSUB, SSASUB, PGSSUB, - IMPORTSRT, IMPORTSSA, SRTSUB = IMPORTSRT } source; + enum subsource { + VOBSUB, + CC608SUB, + CC708SUB, // unused + UTF8SUB, + TX3GSUB, + SSASUB, + PGSSUB, + IMPORTSRT, + IMPORTSSA, + DVBSUB, + SRTSUB = IMPORTSRT + } source; const char * name; char lang[1024]; char iso639_2[4]; diff --git a/libhb/rendersub.c b/libhb/rendersub.c index bb35b438d..a04adbe90 100644 --- a/libhb/rendersub.c +++ b/libhb/rendersub.c @@ -1011,6 +1011,7 @@ static int hb_rendersub_post_init( hb_filter_object_t * filter, hb_job_t *job ) return cc608sub_post_init( filter, job ); } + case DVBSUB: case PGSSUB: { return pgssub_post_init( filter, job ); @@ -1050,6 +1051,7 @@ static int hb_rendersub_work( hb_filter_object_t * filter, return textsub_work( filter, buf_in, buf_out ); } + case DVBSUB: case PGSSUB: { return pgssub_work( filter, buf_in, buf_out ); @@ -1092,6 +1094,7 @@ static void hb_rendersub_close( hb_filter_object_t * filter ) textsub_close( filter ); } break; + case DVBSUB: case PGSSUB: { pgssub_close( filter ); diff --git a/libhb/stream.c b/libhb/stream.c index b3c304874..aecffab10 100644 --- a/libhb/stream.c +++ b/libhb/stream.c @@ -1913,14 +1913,14 @@ static const char *stream_type_name2(hb_stream_t *stream, hb_pes_stream_t *pes) break; } } - if ( st2codec[pes->stream_type].name ) - { - return st2codec[pes->stream_type].name; - } if ( pes->codec_name[0] != 0 ) { return pes->codec_name; } + if ( st2codec[pes->stream_type].name ) + { + return st2codec[pes->stream_type].name; + } if ( pes->codec & HB_ACODEC_FF_MASK ) { AVCodec * codec = avcodec_find_decoder( pes->codec_param ); @@ -1982,6 +1982,11 @@ static void pes_add_subtitle_to_title( { switch (pes->codec_param) { + case AV_CODEC_ID_DVB_SUBTITLE: + subtitle->source = DVBSUB; + subtitle->format = PICTURESUB; + subtitle->config.dest = RENDERSUB; + break; case AV_CODEC_ID_HDMV_PGS_SUBTITLE: subtitle->source = PGSSUB; subtitle->format = PICTURESUB; @@ -2618,10 +2623,10 @@ static void decode_element_descriptors( case 0x59: // DVB Subtitleing descriptor { - // We don't currently process subtitles from - // TS or PS streams. Set stream 'kind' to N stream->pes.list[pes_idx].stream_type = 0x00; - stream->pes.list[pes_idx].stream_kind = N; + stream->pes.list[pes_idx].stream_kind = S; + stream->pes.list[pes_idx].codec = WORK_DECAVSUB; + stream->pes.list[pes_idx].codec_param = AV_CODEC_ID_DVB_SUBTITLE; strncpy(stream->pes.list[pes_idx].codec_name, "DVB Subtitling", 80); bits_skip(bb, 8 * len); @@ -3160,6 +3165,21 @@ static int parse_pes_header( pes_info->header_len += 4; } } + if ( pes_info->stream_id == 0xbd && stream->hb_stream_type == transport ) + { + if ( bits_bytes_left(bb) < 2 ) + { + return 0; + } + int ssid = bits_peek(bb, 8); + if ( ssid == 0x20 ) + { + // DVB (subtitles) + bits_skip(bb, 8); + pes_info->bd_substream_id = bits_get(bb, 8); + pes_info->header_len += 2; + } + } return 1; } @@ -3250,7 +3270,15 @@ static int hb_parse_ps( return 0; } pes_info->packet_len = bits_get(&bb, 16); - pes_info->header_len = bb.pos >> 3; + if ( pes_info->stream_id == 0xbe ) + { + // Skip all stuffing + pes_info->header_len = 6 + pes_info->packet_len; + } + else + { + pes_info->header_len = bb.pos >> 3; + } return 1; } } @@ -4617,6 +4645,14 @@ static hb_buffer_t * generate_output_data(hb_stream_t *stream, int curstream) if (es_size <= 0) { + if (ts_stream->pes_info.packet_len > 0 && + ts_stream->packet_len >= ts_stream->pes_info.packet_len + 6) + { + ts_stream->pes_info_valid = 0; + ts_stream->packet_len = 0; + } + b->size = 0; + ts_stream->packet_offset = 0; return NULL; } @@ -5486,6 +5522,13 @@ static void add_ffmpeg_subtitle( hb_title_t *title, hb_stream_t *stream, int id hb_log( "add_ffmpeg_subtitle: malformed extradata for VOB subtitle track; " "subtitle colors likely to be wrong" ); break; + case AV_CODEC_ID_DVB_SUBTITLE: + subtitle->format = PICTURESUB; + subtitle->source = DVBSUB; + subtitle->config.dest = RENDERSUB; + subtitle->codec = WORK_DECAVSUB; + subtitle->codec_param = codecpar->codec_id; + break; case AV_CODEC_ID_TEXT: case AV_CODEC_ID_SUBRIP: subtitle->format = TEXTSUB; -- cgit v1.2.3