From f9cefbfec4d7bfec44991d4372aad4fc1b3167a5 Mon Sep 17 00:00:00 2001 From: Aman Gupta Date: Mon, 21 Dec 2015 17:35:15 -0800 Subject: [PATCH] vd_lavc: feed A53_CC side data packets into the demuxer for eia_608 decoding --- demux/demux.c | 25 +++++++++++++++++++++++++ demux/demux.h | 1 + sub/sd_ass.c | 18 ++++++++++++++++-- video/decode/vd_lavc.c | 11 +++++++++++ 4 files changed, 53 insertions(+), 2 deletions(-) diff --git a/demux/demux.c b/demux/demux.c index e286bf0e32..af0a93c03d 100644 --- a/demux/demux.c +++ b/demux/demux.c @@ -160,6 +160,10 @@ struct demux_stream { int64_t last_pos; struct demux_packet *head; struct demux_packet *tail; + + // for closed captions (demuxer_feed_caption) + struct sh_stream *cc; + }; // Return "a", or if that is NOPTS, return "def". @@ -361,6 +365,27 @@ const char *stream_type_name(enum stream_type type) } } +void demuxer_feed_caption(struct sh_stream *stream, demux_packet_t *dp) +{ + struct demuxer *demuxer = stream->ds->in->d_thread; + struct sh_stream *sh = stream->ds->cc; + + if (!sh) { + sh = demux_alloc_sh_stream(STREAM_SUB); + if (!sh) + return; + sh->codec->codec = "eia_608"; + stream->ds->cc = sh; + demux_add_sh_stream(demuxer, sh); + } + + if (demux_stream_is_selected(sh)) { + dp->pts = MP_ADD_PTS(dp->pts, -stream->ds->in->ts_offset); + dp->dts = MP_ADD_PTS(dp->dts, -stream->ds->in->ts_offset); + demux_add_packet(sh, dp); + } +} + void demux_add_packet(struct sh_stream *stream, demux_packet_t *dp) { struct demux_stream *ds = stream ? stream->ds : NULL; diff --git a/demux/demux.h b/demux/demux.h index 33cbe0f3b1..72ed15888b 100644 --- a/demux/demux.h +++ b/demux/demux.h @@ -237,6 +237,7 @@ void free_demuxer(struct demuxer *demuxer); void free_demuxer_and_stream(struct demuxer *demuxer); void demux_add_packet(struct sh_stream *stream, demux_packet_t *dp); +void demuxer_feed_caption(struct sh_stream *stream, demux_packet_t *dp); struct demux_packet *demux_read_packet(struct sh_stream *sh); int demux_read_packet_async(struct sh_stream *sh, struct demux_packet **out_pkt); diff --git a/sub/sd_ass.c b/sub/sd_ass.c index 2358ba45f6..5c56d3e0df 100644 --- a/sub/sd_ass.c +++ b/sub/sd_ass.c @@ -51,6 +51,7 @@ struct sd_ass_priv { double sub_speed, video_fps, frame_fps; int64_t *seen_packets; int num_seen_packets; + bool duration_unknown; }; static void mangle_colors(struct sd *sd, struct sub_bitmaps *parts); @@ -176,6 +177,9 @@ static int init(struct sd *sd) return -1; extradata = lavc_conv_get_extradata(ctx->converter); extradata_size = extradata ? strlen(extradata) : 0; + + if (strcmp(sd->codec->codec, "eia_608") == 0) + ctx->duration_unknown = 1; } ctx->ass_library = mp_ass_init(sd->global, sd->log); @@ -239,11 +243,18 @@ static void decode(struct sd *sd, struct demux_packet *packet) struct sd_ass_priv *ctx = sd->priv; ASS_Track *track = ctx->ass_track; if (ctx->converter) { - if (!sd->opts->sub_clear_on_seek && check_packet_seen(sd, packet->pos)) + if (!sd->opts->sub_clear_on_seek && packet->pos >= 0 && + check_packet_seen(sd, packet->pos)) return; char **r = lavc_conv_decode(ctx->converter, packet); for (int n = 0; r && r[n]; n++) ass_process_data(track, r[n], strlen(r[n])); + if (ctx->duration_unknown) { + for (int n = 0; n < track->n_events - 1; n++) { + track->events[n].Duration = track->events[n + 1].Start - + track->events[n].Start; + } + } } else { // Note that for this packet format, libass has an internal mechanism // for discarding duplicate (already seen) packets. @@ -426,9 +437,12 @@ static void get_bitmaps(struct sd *sd, struct mp_osd_res dim, double pts, } else { ass_set_storage_size(renderer, 0, 0); } + long long ts = find_timestamp(sd, pts); + if (ctx->duration_unknown && pts != MP_NOPTS_VALUE) { + mp_ass_flush_old_events(track, ts); + } if (no_ass) fill_plaintext(sd, pts); - long long ts = find_timestamp(sd, pts); mp_ass_render_frame(renderer, track, ts, &ctx->parts, res); talloc_steal(ctx, ctx->parts); diff --git a/video/decode/vd_lavc.c b/video/decode/vd_lavc.c index f47e72a1cd..9677e4c079 100644 --- a/video/decode/vd_lavc.c +++ b/video/decode/vd_lavc.c @@ -41,6 +41,7 @@ #include "video/img_format.h" #include "video/filter/vf.h" #include "video/decode/dec_video.h" +#include "demux/demux.h" #include "demux/stheader.h" #include "demux/packet.h" #include "video/csputils.h" @@ -680,6 +681,16 @@ static void decode(struct dec_video *vd, struct demux_packet *packet, vd->codec_pts = mp_pts_from_av(ctx->pic->pkt_pts, NULL); vd->codec_dts = mp_pts_from_av(ctx->pic->pkt_dts, NULL); + AVFrameSideData *sd = NULL; + sd = av_frame_get_side_data(ctx->pic, AV_FRAME_DATA_A53_CC); + if (sd) { + struct demux_packet *cc = new_demux_packet_from(sd->data, sd->size); + cc->pts = vd->codec_pts; + cc->dts = vd->codec_dts; + cc->pos = -1; + demuxer_feed_caption(vd->header, cc); + } + struct mp_image *mpi = mp_image_from_av_frame(ctx->pic); av_frame_unref(ctx->pic); if (!mpi)