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/>.
20 #include <libavcodec/avcodec.h>
23 #include "libmpdemux/stheader.h"
26 // Current code still pushes subs directly to global spudec
30 AVCodecContext
*avctx
;
32 struct sub_bitmap
*inbitmaps
;
33 struct sub_bitmap
*outbitmaps
;
38 static int init(struct sh_sub
*sh
, struct osd_state
*osd
)
42 struct sd_lavc_priv
*priv
= talloc_zero(NULL
, struct sd_lavc_priv
);
43 enum CodecID cid
= CODEC_ID_NONE
;
46 cid
= CODEC_ID_DVB_SUBTITLE
; break;
48 cid
= CODEC_ID_HDMV_PGS_SUBTITLE
; break;
50 cid
= CODEC_ID_XSUB
; break;
52 cid
= CODEC_ID_DVD_SUBTITLE
; break;
54 AVCodecContext
*ctx
= NULL
;
55 AVCodec
*sub_codec
= avcodec_find_decoder(cid
);
58 ctx
= avcodec_alloc_context3(sub_codec
);
61 ctx
->extradata_size
= sh
->extradata_len
;
62 ctx
->extradata
= sh
->extradata
;
63 if (avcodec_open2(ctx
, sub_codec
, NULL
) < 0)
70 mp_msg(MSGT_SUBREADER
, MSGL_ERR
,
71 "Could not open libavcodec subtitle decoder\n");
77 static void clear(struct sd_lavc_priv
*priv
)
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
)
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
,
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
;
111 av_init_packet(&pkt
);
114 pkt
.pts
= pts
* 1000;
116 pkt
.convergence_duration
= duration
* 1000;
118 int res
= avcodec_decode_subtitle2(ctx
, &sub
, &got_sub
, &pkt
);
119 if (res
< 0 || !got_sub
)
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
);
139 priv
->inbitmaps
= talloc_array(priv
, struct sub_bitmap
,
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
,
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
;
163 mp_msg(MSGT_SUBREADER
, MSGL_ERR
, "sd_lavc: unsupported subtitle "
164 "type from libavcodec\n");
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))
179 if (!osd
->support_rgba
)
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
;
189 int inh
= priv
->avctx
->height
;
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
;
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
);
233 const struct sd_functions sd_lavc
= {
236 .get_bitmaps
= get_bitmaps
,