mirror of
https://github.com/mpv-player/mpv
synced 2025-04-21 22:57:00 +00:00
vd_lavc: feed A53_CC side data packets into the demuxer for eia_608 decoding
This commit is contained in:
parent
ed3e5330ec
commit
f9cefbfec4
@ -160,6 +160,10 @@ struct demux_stream {
|
|||||||
int64_t last_pos;
|
int64_t last_pos;
|
||||||
struct demux_packet *head;
|
struct demux_packet *head;
|
||||||
struct demux_packet *tail;
|
struct demux_packet *tail;
|
||||||
|
|
||||||
|
// for closed captions (demuxer_feed_caption)
|
||||||
|
struct sh_stream *cc;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Return "a", or if that is NOPTS, return "def".
|
// 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)
|
void demux_add_packet(struct sh_stream *stream, demux_packet_t *dp)
|
||||||
{
|
{
|
||||||
struct demux_stream *ds = stream ? stream->ds : NULL;
|
struct demux_stream *ds = stream ? stream->ds : NULL;
|
||||||
|
@ -237,6 +237,7 @@ void free_demuxer(struct demuxer *demuxer);
|
|||||||
void free_demuxer_and_stream(struct demuxer *demuxer);
|
void free_demuxer_and_stream(struct demuxer *demuxer);
|
||||||
|
|
||||||
void demux_add_packet(struct sh_stream *stream, demux_packet_t *dp);
|
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);
|
struct demux_packet *demux_read_packet(struct sh_stream *sh);
|
||||||
int demux_read_packet_async(struct sh_stream *sh, struct demux_packet **out_pkt);
|
int demux_read_packet_async(struct sh_stream *sh, struct demux_packet **out_pkt);
|
||||||
|
18
sub/sd_ass.c
18
sub/sd_ass.c
@ -51,6 +51,7 @@ struct sd_ass_priv {
|
|||||||
double sub_speed, video_fps, frame_fps;
|
double sub_speed, video_fps, frame_fps;
|
||||||
int64_t *seen_packets;
|
int64_t *seen_packets;
|
||||||
int num_seen_packets;
|
int num_seen_packets;
|
||||||
|
bool duration_unknown;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void mangle_colors(struct sd *sd, struct sub_bitmaps *parts);
|
static void mangle_colors(struct sd *sd, struct sub_bitmaps *parts);
|
||||||
@ -176,6 +177,9 @@ static int init(struct sd *sd)
|
|||||||
return -1;
|
return -1;
|
||||||
extradata = lavc_conv_get_extradata(ctx->converter);
|
extradata = lavc_conv_get_extradata(ctx->converter);
|
||||||
extradata_size = extradata ? strlen(extradata) : 0;
|
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);
|
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;
|
struct sd_ass_priv *ctx = sd->priv;
|
||||||
ASS_Track *track = ctx->ass_track;
|
ASS_Track *track = ctx->ass_track;
|
||||||
if (ctx->converter) {
|
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;
|
return;
|
||||||
char **r = lavc_conv_decode(ctx->converter, packet);
|
char **r = lavc_conv_decode(ctx->converter, packet);
|
||||||
for (int n = 0; r && r[n]; n++)
|
for (int n = 0; r && r[n]; n++)
|
||||||
ass_process_data(track, r[n], strlen(r[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 {
|
} else {
|
||||||
// Note that for this packet format, libass has an internal mechanism
|
// Note that for this packet format, libass has an internal mechanism
|
||||||
// for discarding duplicate (already seen) packets.
|
// 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 {
|
} else {
|
||||||
ass_set_storage_size(renderer, 0, 0);
|
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)
|
if (no_ass)
|
||||||
fill_plaintext(sd, pts);
|
fill_plaintext(sd, pts);
|
||||||
long long ts = find_timestamp(sd, pts);
|
|
||||||
mp_ass_render_frame(renderer, track, ts, &ctx->parts, res);
|
mp_ass_render_frame(renderer, track, ts, &ctx->parts, res);
|
||||||
talloc_steal(ctx, ctx->parts);
|
talloc_steal(ctx, ctx->parts);
|
||||||
|
|
||||||
|
@ -41,6 +41,7 @@
|
|||||||
#include "video/img_format.h"
|
#include "video/img_format.h"
|
||||||
#include "video/filter/vf.h"
|
#include "video/filter/vf.h"
|
||||||
#include "video/decode/dec_video.h"
|
#include "video/decode/dec_video.h"
|
||||||
|
#include "demux/demux.h"
|
||||||
#include "demux/stheader.h"
|
#include "demux/stheader.h"
|
||||||
#include "demux/packet.h"
|
#include "demux/packet.h"
|
||||||
#include "video/csputils.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_pts = mp_pts_from_av(ctx->pic->pkt_pts, NULL);
|
||||||
vd->codec_dts = mp_pts_from_av(ctx->pic->pkt_dts, 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);
|
struct mp_image *mpi = mp_image_from_av_frame(ctx->pic);
|
||||||
av_frame_unref(ctx->pic);
|
av_frame_unref(ctx->pic);
|
||||||
if (!mpi)
|
if (!mpi)
|
||||||
|
Loading…
Reference in New Issue
Block a user