cleanup: rename ass_* functions to mp_ass_*
[mplayer/glamo.git] / sub / sd_ass.c
blobbe2740bfa69885bb9d62359ba785c39e283fff14
1 /*
2 * This file is part of MPlayer.
4 * MPlayer is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * MPlayer is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 #include <stdlib.h>
20 #include <ass/ass.h>
21 #include <assert.h>
22 #include <string.h>
24 #include "talloc.h"
26 #include "mpcommon.h"
27 #include "libmpdemux/stheader.h"
28 #include "libvo/sub.h"
29 #include "ass_mp.h"
30 #include "sd.h"
31 #include "subassconvert.h"
33 struct sd_ass_priv {
34 struct ass_track *ass_track;
35 bool incomplete_event;
38 static void free_last_event(ASS_Track *track)
40 assert(track->n_events > 0);
41 ass_free_event(track, track->n_events - 1);
42 track->n_events--;
45 static void init(struct sh_sub *sh, struct osd_state *osd)
47 struct sd_ass_priv *ctx;
49 if (sh->initialized) {
50 ctx = sh->context;
51 } else {
52 ctx = talloc_zero(NULL, struct sd_ass_priv);
53 sh->context = ctx;
54 if (sh->type == 'a') {
55 ctx->ass_track = ass_new_track(ass_library);
56 if (sh->extradata)
57 ass_process_codec_private(ctx->ass_track, sh->extradata,
58 sh->extradata_len);
59 } else
60 ctx->ass_track = mp_ass_default_track(ass_library);
63 assert(osd->ass_track == NULL);
64 osd->ass_track = ctx->ass_track;
65 osd->vsfilter_aspect = sh->type == 'a';
66 osd->ass_track_changed = true;
69 static void decode(struct sh_sub *sh, struct osd_state *osd, void *data,
70 int data_len, double pts, double duration)
72 unsigned char *text = data;
73 struct sd_ass_priv *ctx = sh->context;
74 ASS_Track *track = ctx->ass_track;
76 if (sh->type == 'a') { // ssa/ass subs
77 ass_process_chunk(track, data, data_len,
78 (long long)(pts*1000 + 0.5),
79 (long long)(duration*1000 + 0.5));
80 return;
82 // plaintext subs
83 if (pts == MP_NOPTS_VALUE) {
84 mp_msg(MSGT_SUBREADER, MSGL_WARN, "Subtitle without pts, ignored\n");
85 return;
87 long long ipts = pts * 1000 + 0.5;
88 long long iduration = duration * 1000 + 0.5;
89 if (ctx->incomplete_event) {
90 ctx->incomplete_event = false;
91 ASS_Event *event = track->events + track->n_events - 1;
92 if (ipts <= event->Start)
93 free_last_event(track);
94 else
95 event->Duration = ipts - event->Start;
97 // Note: we rely on there being guaranteed 0 bytes after data packets
98 int len = strlen(text);
99 if (len < 5) {
100 // Some tracks use a whitespace (but not empty) packet to mark end
101 // of previous subtitle.
102 for (int i = 0; i < len; i++)
103 if (!strchr(" \f\n\r\t\v", text[i]))
104 goto not_all_whitespace;
105 return;
107 not_all_whitespace:;
108 char buf[500];
109 subassconvert_subrip(text, buf, sizeof(buf));
110 for (int i = 0; i < track->n_events; i++)
111 if (track->events[i].Start == ipts
112 && (duration <= 0 || track->events[i].Duration == iduration)
113 && strcmp(track->events[i].Text, buf) == 0)
114 return; // We've already added this subtitle
115 if (duration <= 0) {
116 iduration = 10000;
117 ctx->incomplete_event = true;
119 int eid = ass_alloc_event(track);
120 ASS_Event *event = track->events + eid;
121 event->Start = ipts;
122 event->Duration = iduration;
123 event->Text = strdup(buf);
126 static void reset(struct sh_sub *sh, struct osd_state *osd)
128 struct sd_ass_priv *ctx = sh->context;
129 if (ctx->incomplete_event)
130 free_last_event(ctx->ass_track);
131 ctx->incomplete_event = false;
134 static void switch_off(struct sh_sub *sh, struct osd_state *osd)
136 reset(sh, osd);
137 osd->ass_track = NULL;
140 static void uninit(struct sh_sub *sh)
142 struct sd_ass_priv *ctx = sh->context;
144 ass_free_track(ctx->ass_track);
145 talloc_free(ctx);
148 const struct sd_functions sd_ass = {
149 .init = init,
150 .decode = decode,
151 .reset = reset,
152 .switch_off = switch_off,
153 .uninit = uninit,