sd_ass: handle libavformat ASS comment packets as well

Currently, we are filtering libavformat style ASS packets by checking
whether they are prefixed "Dialogue: ". Unfortunately, comment packets
are demuxed too. These start with "Comment: ", so they are not caught.

Change the filtering, and use the codec ID instead. libavformat uses
"ssa" as codec ID for ASS subtitles, while mpv uses "ass". Also, at
least FFmpeg will change the ASS packet format to the same format mpv
and Matroska use, and identify these with "ass" as codec ID, so this is
works out nicely.
This commit is contained in:
wm4 2013-06-23 22:09:04 +02:00
parent bd45eb468c
commit 1058d80a5e
2 changed files with 14 additions and 18 deletions

View File

@ -41,17 +41,14 @@ struct sd_ass_priv {
char last_text[500];
};
static bool is_native_ass(const char *t)
{
return strcmp(t, "ass") == 0 || strcmp(t, "ssa") == 0;
}
static bool supports_format(const char *format)
{
// ass-text is produced by converters and the subreader.c ssa parser; this
// format has ASS tags, but doesn't start with any prelude, nor does it
// have extradata.
return format && (is_native_ass(format) || strcmp(format, "ass-text") == 0);
return format && (strcmp(format, "ass") == 0 ||
strcmp(format, "ssa") == 0 ||
strcmp(format, "ass-text") == 0);
}
static void free_last_event(ASS_Track *track)
@ -64,7 +61,7 @@ static void free_last_event(ASS_Track *track)
static int init(struct sd *sd)
{
struct MPOpts *opts = sd->opts;
if (!sd->ass_library || !sd->ass_renderer)
if (!sd->ass_library || !sd->ass_renderer || !sd->codec)
return -1;
bool is_converted = sd->converted_from != NULL;
@ -99,16 +96,15 @@ static void decode(struct sd *sd, struct demux_packet *packet)
unsigned char *text = data;
struct sd_ass_priv *ctx = sd->priv;
ASS_Track *track = ctx->ass_track;
if (is_native_ass(sd->codec)) {
if (bstr_startswith0((bstr){data, data_len}, "Dialogue: ")) {
// broken ffmpeg ASS packet format
ctx->flush_on_seek = true;
ass_process_data(track, data, data_len);
} else {
ass_process_chunk(track, data, data_len,
(long long)(pts*1000 + 0.5),
(long long)(duration*1000 + 0.5));
}
if (strcmp(sd->codec, "ass") == 0) {
ass_process_chunk(track, data, data_len,
(long long)(pts*1000 + 0.5),
(long long)(duration*1000 + 0.5));
return;
} else if (strcmp(sd->codec, "ssa") == 0) {
// broken ffmpeg ASS packet format
ctx->flush_on_seek = true;
ass_process_data(track, data, data_len);
return;
}
// plaintext subs

View File

@ -87,7 +87,7 @@ static int init(struct sd *sd)
avctx->time_base = (AVRational) {1, 1000};
priv->avctx = avctx;
sd->priv = priv;
sd->output_codec = "ass";
sd->output_codec = "ssa";
sd->output_extradata = avctx->subtitle_header;
sd->output_extradata_len = avctx->subtitle_header_size;
if (sd->output_extradata) {