summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-06-24 01:04:17 +0200
committerwm4 <wm4@nowhere>2013-06-25 00:11:57 +0200
commit0b2e073853beff170e8a9f8a5898e636cf636cf0 (patch)
treeaf480ee5f5cf68c7a983e2838ec37f457d7f4444
parent74c56309a33aa07fc79e193a619d8a47924da391 (diff)
downloadmpv-0b2e073853beff170e8a9f8a5898e636cf636cf0.tar.bz2
mpv-0b2e073853beff170e8a9f8a5898e636cf636cf0.tar.xz
dec_sub: allow postprocessing between decoders
Until now, timing and charset recoding postprocessing was applied on packets as they were output by the demuxer, and then passed to the decoders. Make it so that postprocessing can happen after some decoders in special situations.
-rw-r--r--sub/dec_sub.c55
1 files changed, 41 insertions, 14 deletions
diff --git a/sub/dec_sub.c b/sub/dec_sub.c
index c7562fe014..01ba109ad0 100644
--- a/sub/dec_sub.c
+++ b/sub/dec_sub.c
@@ -240,16 +240,22 @@ static struct demux_packet *recode_packet(struct demux_packet *in,
return pkt;
}
-void sub_decode(struct dec_sub *sub, struct demux_packet *packet)
+static void decode_chain_recode(struct dec_sub *sub, struct sd **sd, int num_sd,
+ struct demux_packet *packet)
{
- if (sub->num_sd > 0) {
+ if (num_sd > 0) {
struct demux_packet *recoded = NULL;
if (sub->charset)
recoded = recode_packet(packet, sub->charset);
- decode_chain(sub->sd, sub->num_sd, recoded ? recoded : packet);
+ decode_chain(sd, num_sd, recoded ? recoded : packet);
}
}
+void sub_decode(struct dec_sub *sub, struct demux_packet *packet)
+{
+ decode_chain_recode(sub, sub->sd, sub->num_sd, packet);
+}
+
static const char *guess_sub_cp(struct packet_list *subs, const char *usercp)
{
if (!mp_charset_requires_guess(usercp))
@@ -318,7 +324,7 @@ static void fix_overlaps_and_gaps(struct packet_list *subs)
}
}
-static void add_sub_list(struct dec_sub *sub, struct packet_list *subs)
+static void add_sub_list(struct dec_sub *sub, int at, struct packet_list *subs)
{
struct sd *sd = sub_get_last_sd(sub);
assert(sd);
@@ -326,7 +332,7 @@ static void add_sub_list(struct dec_sub *sub, struct packet_list *subs)
sd->no_remove_duplicates = true;
for (int n = 0; n < subs->num_packets; n++)
- sub_decode(sub, subs->packets[n]);
+ decode_chain_recode(sub, sub->sd + at, sub->num_sd - at, subs->packets[n]);
// Hack for broken FFmpeg packet format: make sd_ass keep the subtitle
// events on reset(), even if broken FFmpeg ASS packets were received
@@ -338,31 +344,52 @@ static void add_sub_list(struct dec_sub *sub, struct packet_list *subs)
sd->no_remove_duplicates = false;
}
+static void add_packet(struct packet_list *subs, struct demux_packet *pkt)
+{
+ pkt = demux_copy_packet(pkt);
+ talloc_steal(subs, pkt);
+ MP_TARRAY_APPEND(subs, subs->packets, subs->num_packets, pkt);
+}
+
// Read all packets from the demuxer and decode/add them. Returns false if
// there are circumstances which makes this not possible.
bool sub_read_all_packets(struct dec_sub *sub, struct sh_sub *sh)
{
struct MPOpts *opts = sub->opts;
- if (!sub_accept_packets_in_advance(sub) || sh->track)
+ if (!sub_accept_packets_in_advance(sub) || sh->track || sub->num_sd < 1)
return false;
- const char *codec = sh->gsh->codec ? sh->gsh->codec : "";
struct packet_list *subs = talloc_zero(NULL, struct packet_list);
+ // In some cases, we want to put the packets through a decoder first.
+ // Preprocess until sub->sd[preprocess].
+ int preprocess = 0;
+
+ // movtext is currently the only subtitle format that has text output,
+ // but binary input. Do charset conversion after converting to text.
+ if (sub->sd[0]->driver == &sd_movtext)
+ preprocess = 1;
+
for (;;) {
ds_get_next_pts(sh->ds);
struct demux_packet *pkt = ds_get_packet_sub(sh->ds);
if (!pkt)
break;
- pkt = demux_copy_packet(pkt);
- talloc_steal(subs, pkt);
- MP_TARRAY_APPEND(subs, subs->packets, subs->num_packets, pkt);
+ if (preprocess) {
+ decode_chain(sub->sd, preprocess, pkt);
+ while (1) {
+ pkt = get_decoded_packet(sub->sd[preprocess - 1]);
+ if (!pkt)
+ break;
+ add_packet(subs, pkt);
+ }
+ } else {
+ add_packet(subs, pkt);
+ }
}
- // Can't run auto-detection on movtext packets: it's the only codec that
- // even though it decodes to text has binary input data.
- if (opts->sub_cp && !sh->is_utf8 && strcmp(codec, "movtext") != 0)
+ if (opts->sub_cp && !sh->is_utf8)
sub->charset = guess_sub_cp(subs, opts->sub_cp);
if (sub->charset)
@@ -378,7 +405,7 @@ bool sub_read_all_packets(struct dec_sub *sub, struct sh_sub *sh)
if (!opts->suboverlap_enabled)
fix_overlaps_and_gaps(subs);
- add_sub_list(sub, subs);
+ add_sub_list(sub, preprocess, subs);
talloc_free(subs);
return true;