mp_msg: print messages to stdout, statusline to stderr
[mplayer.git] / sub / sd_lavc.c
blobdeedc0b1d67ecc89d2772e9464e4e43d6dabb530
1 /*
2 * This file is part of mplayer2.
4 * mplayer2 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 * mplayer2 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 mplayer2. If not, see <http://www.gnu.org/licenses/>.
18 #include <stdlib.h>
20 #include <libavcodec/avcodec.h>
22 #include "mp_msg.h"
23 #include "libmpdemux/stheader.h"
24 #include "sd.h"
25 #include "spudec.h"
26 // Current code still pushes subs directly to global spudec
27 #include "sub.h"
29 struct sd_lavc_priv {
30 AVCodecContext *avctx;
31 int count;
32 struct sub_bitmap *inbitmaps;
33 struct sub_bitmap *outbitmaps;
34 bool bitmaps_changed;
35 double endpts;
38 static int init(struct sh_sub *sh, struct osd_state *osd)
40 if (sh->initialized)
41 return 0;
42 struct sd_lavc_priv *priv = talloc_zero(NULL, struct sd_lavc_priv);
43 enum CodecID cid = CODEC_ID_NONE;
44 switch (sh->type) {
45 case 'b':
46 cid = CODEC_ID_DVB_SUBTITLE; break;
47 case 'p':
48 cid = CODEC_ID_HDMV_PGS_SUBTITLE; break;
49 case 'x':
50 cid = CODEC_ID_XSUB; break;
51 case 'v':
52 cid = CODEC_ID_DVD_SUBTITLE; break;
54 AVCodecContext *ctx = NULL;
55 AVCodec *sub_codec = avcodec_find_decoder(cid);
56 if (!sub_codec)
57 goto error;
58 ctx = avcodec_alloc_context3(sub_codec);
59 if (!ctx)
60 goto error;
61 ctx->extradata_size = sh->extradata_len;
62 ctx->extradata = sh->extradata;
63 if (avcodec_open2(ctx, sub_codec, NULL) < 0)
64 goto error;
65 priv->avctx = ctx;
66 sh->context = priv;
67 return 0;
69 error:
70 mp_msg(MSGT_SUBREADER, MSGL_ERR,
71 "Could not open libavcodec subtitle decoder\n");
72 av_free(ctx);
73 talloc_free(priv);
74 return -1;
77 static void clear(struct sd_lavc_priv *priv)
79 priv->count = 0;
80 talloc_free(priv->inbitmaps);
81 talloc_free(priv->outbitmaps);
82 priv->inbitmaps = priv->outbitmaps = NULL;
83 priv->bitmaps_changed = true;
84 priv->endpts = MP_NOPTS_VALUE;
87 static void old_spudec_render(AVCodecContext *ctx, AVSubtitle *sub,
88 double pts, double endpts)
90 if (!vo_spudec)
91 vo_spudec = spudec_new_scaled(NULL, ctx->width, ctx->height, NULL, 0);
92 spudec_set_paletted(vo_spudec,
93 sub->rects[0]->pict.data[0],
94 sub->rects[0]->pict.linesize[0],
95 sub->rects[0]->pict.data[1],
96 sub->rects[0]->x, sub->rects[0]->y,
97 sub->rects[0]->w, sub->rects[0]->h,
98 pts, endpts);
99 vo_osd_changed(OSDTYPE_SPU);
102 static void decode(struct sh_sub *sh, struct osd_state *osd, void *data,
103 int data_len, double pts, double duration)
105 struct sd_lavc_priv *priv = sh->context;
106 AVCodecContext *ctx = priv->avctx;
107 AVSubtitle sub;
108 AVPacket pkt;
110 clear(priv);
111 av_init_packet(&pkt);
112 pkt.data = data;
113 pkt.size = data_len;
114 pkt.pts = pts * 1000;
115 if (duration >= 0)
116 pkt.convergence_duration = duration * 1000;
117 int got_sub;
118 int res = avcodec_decode_subtitle2(ctx, &sub, &got_sub, &pkt);
119 if (res < 0 || !got_sub)
120 return;
121 if (pts != MP_NOPTS_VALUE) {
122 if (sub.end_display_time > sub.start_display_time)
123 duration = (sub.end_display_time - sub.start_display_time) / 1000.0;
124 pts += sub.start_display_time / 1000.0;
126 double endpts = MP_NOPTS_VALUE;
127 if (pts != MP_NOPTS_VALUE && duration >= 0)
128 endpts = pts + duration;
129 if (vo_spudec && sub.num_rects == 0)
130 spudec_set_paletted(vo_spudec, NULL, 0, NULL, 0, 0, 0, 0, pts, endpts);
131 if (sub.num_rects > 0) {
132 switch (sub.rects[0]->type) {
133 case SUBTITLE_BITMAP:
134 // Assume resolution heuristics only work for PGS and DVB
135 if (!osd->support_rgba || sh->type != 'p' && sh->type != 'b') {
136 old_spudec_render(ctx, &sub, pts, endpts);
137 break;
139 priv->inbitmaps = talloc_array(priv, struct sub_bitmap,
140 sub.num_rects);
141 for (int i = 0; i < sub.num_rects; i++) {
142 struct AVSubtitleRect *r = sub.rects[i];
143 struct sub_bitmap *b = &priv->inbitmaps[i];
144 uint32_t *outbmp = talloc_size(priv->inbitmaps,
145 r->w * r->h * 4);
146 b->bitmap = outbmp;
147 b->w = r->w;
148 b->h = r->h;
149 b->x = r->x;
150 b->y = r->y;
151 uint8_t *inbmp = r->pict.data[0];
152 uint32_t *palette = (uint32_t *) r->pict.data[1];
153 for (int y = 0; y < r->h; y++) {
154 for (int x = 0; x < r->w; x++)
155 *outbmp++ = palette[*inbmp++];
156 inbmp += r->pict.linesize[0] - r->w;
159 priv->count = sub.num_rects;
160 priv->endpts = endpts;
161 break;
162 default:
163 mp_msg(MSGT_SUBREADER, MSGL_ERR, "sd_lavc: unsupported subtitle "
164 "type from libavcodec\n");
165 break;
168 avsubtitle_free(&sub);
171 static void get_bitmaps(struct sh_sub *sh, struct osd_state *osd,
172 struct sub_bitmaps *res)
174 struct sd_lavc_priv *priv = sh->context;
176 if (priv->endpts != MP_NOPTS_VALUE && (osd->sub_pts >= priv->endpts ||
177 osd->sub_pts < priv->endpts - 300))
178 clear(priv);
179 if (!osd->support_rgba)
180 return;
181 if (priv->bitmaps_changed && priv->count > 0)
182 priv->outbitmaps = talloc_memdup(priv, priv->inbitmaps,
183 talloc_get_size(priv->inbitmaps));
184 bool pos_changed = false;
185 // Hope that PGS subs set these and 720/576 works for dvb subs
186 int inw = priv->avctx->width;
187 if (!inw)
188 inw = 720;
189 int inh = priv->avctx->height;
190 if (!inh)
191 inh = 576;
192 struct mp_eosd_res *d = &osd->dim;
193 double xscale = (double) (d->w - d->ml - d->mr) / inw;
194 double yscale = (double) (d->h - d->mt - d->mb) / inh;
195 for (int i = 0; i < priv->count; i++) {
196 struct sub_bitmap *bi = &priv->inbitmaps[i];
197 struct sub_bitmap *bo = &priv->outbitmaps[i];
198 #define SET(var, val) pos_changed |= var != (int)(val); var = (val)
199 SET(bo->x, bi->x * xscale + d->ml);
200 SET(bo->y, bi->y * yscale + d->mt);
201 SET(bo->dw, bi->w * xscale);
202 SET(bo->dh, bi->h * yscale);
204 res->parts = priv->outbitmaps;
205 res->part_count = priv->count;
206 if (priv->bitmaps_changed)
207 res->bitmap_id = ++res->bitmap_pos_id;
208 else if (pos_changed)
209 res->bitmap_pos_id++;
210 priv->bitmaps_changed = false;
211 res->type = SUBBITMAP_RGBA;
212 res->scaled = xscale != 1 || yscale != 1;
215 static void reset(struct sh_sub *sh, struct osd_state *osd)
217 struct sd_lavc_priv *priv = sh->context;
219 clear(priv);
220 // lavc might not do this right for all codecs; may need close+reopen
221 avcodec_flush_buffers(priv->avctx);
224 static void uninit(struct sh_sub *sh)
226 struct sd_lavc_priv *priv = sh->context;
228 avcodec_close(priv->avctx);
229 av_free(priv->avctx);
230 talloc_free(priv);
233 const struct sd_functions sd_lavc = {
234 .init = init,
235 .decode = decode,
236 .get_bitmaps = get_bitmaps,
237 .reset = reset,
238 .switch_off = reset,
239 .uninit = uninit,