1 /*
2  * This file is part of mpv.
3  *
4  * mpv is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * mpv 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 Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with mpv.  If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef MPLAYER_SUB_H
19 #define MPLAYER_SUB_H
20 
21 #include <stddef.h>
22 #include <stdbool.h>
23 #include <stdint.h>
24 
25 #include "options/m_option.h"
26 
27 // NOTE: VOs must support at least SUBBITMAP_RGBA.
28 enum sub_bitmap_format {
29     SUBBITMAP_EMPTY = 0,// no bitmaps; always has num_parts==0
30     SUBBITMAP_LIBASS,   // A8, with a per-surface blend color (libass.color)
31     SUBBITMAP_RGBA,     // IMGFMT_BGRA (MSB=A, LSB=B), scaled, premultiplied alpha
32 
33     SUBBITMAP_COUNT
34 };
35 
36 struct sub_bitmap {
37     void *bitmap;
38     int stride;
39     // Note: not clipped, going outside the screen area is allowed
40     //       (except for SUBBITMAP_LIBASS, which is always clipped)
41     int w, h;
42     int x, y;
43     int dw, dh;
44 
45     // If the containing struct sub_bitmaps has the packed field set, then this
46     // is the position within the source. (Strictly speaking this is redundant
47     // with the bitmap pointer.)
48     int src_x, src_y;
49 
50     struct {
51         uint32_t color;
52     } libass;
53 };
54 
55 struct sub_bitmaps {
56     // For VO cache state (limited by MAX_OSD_PARTS)
57     int render_index;
58 
59     enum sub_bitmap_format format;
60 
61     struct sub_bitmap *parts;
62     int num_parts;
63 
64     // Packed representation of the bitmap data. If non-NULL, then the
65     // parts[].bitmap pointer points into the image data here (and stride will
66     // correspond to packed->stride[0]).
67     //  SUBBITMAP_RGBA: IMGFMT_BGRA (exact match)
68     //  SUBBITMAP_LIBASS: IMGFMT_Y8 (not the same, but compatible layout)
69     // Other formats have this set to NULL.
70     struct mp_image *packed;
71 
72     // Bounding box for the packed image. All parts will be within the bounding
73     // box. (The origin of the box is at (0,0).)
74     int packed_w, packed_h;
75 
76     int change_id;  // Incremented on each change (0 is never used)
77 };
78 
79 struct sub_bitmap_list {
80     // Combined change_id - of any of the existing items change (even if they
81     // e.g. go away and are removed from items[]), this is incremented.
82     int64_t change_id;
83 
84     // Bounding box for rendering. It's notable that SUBBITMAP_LIBASS images are
85     // always within these bounds, while SUBBITMAP_RGBA is not necessarily.
86     int w, h;
87 
88     // Sorted by sub_bitmaps.render_index. Unused parts are not in the array,
89     // and you cannot index items[] with render_index.
90     struct sub_bitmaps **items;
91     int num_items;
92 };
93 
94 struct sub_bitmap_copy_cache;
95 struct sub_bitmaps *sub_bitmaps_copy(struct sub_bitmap_copy_cache **cache,
96                                      struct sub_bitmaps *in);
97 
98 struct mp_osd_res {
99     int w, h; // screen dimensions, including black borders
100     int mt, mb, ml, mr; // borders (top, bottom, left, right)
101     double display_par;
102 };
103 
104 bool osd_res_equals(struct mp_osd_res a, struct mp_osd_res b);
105 
106 // 0 <= sub_bitmaps.render_index < MAX_OSD_PARTS
107 #define MAX_OSD_PARTS 5
108 
109 // Start of OSD symbols in osd_font.pfb
110 #define OSD_CODEPOINTS 0xE000
111 
112 // OSD symbols. osd_font.pfb has them starting from codepoint OSD_CODEPOINTS.
113 // Symbols with a value >= 32 are normal unicode codepoints.
114 enum mp_osd_font_codepoints {
115     OSD_PLAY = 0x01,
116     OSD_PAUSE = 0x02,
117     OSD_STOP = 0x03,
118     OSD_REW = 0x04,
119     OSD_FFW = 0x05,
120     OSD_CLOCK = 0x06,
121     OSD_CONTRAST = 0x07,
122     OSD_SATURATION = 0x08,
123     OSD_VOLUME = 0x09,
124     OSD_BRIGHTNESS = 0x0A,
125     OSD_HUE = 0x0B,
126     OSD_BALANCE = 0x0C,
127     OSD_PANSCAN = 0x50,
128 
129     OSD_PB_START = 0x10,
130     OSD_PB_0 = 0x11,
131     OSD_PB_END = 0x12,
132     OSD_PB_1 = 0x13,
133 };
134 
135 
136 // Never valid UTF-8, so we expect it's free for use.
137 // Specially interpreted by osd_libass.c, in order to allow/escape ASS tags.
138 #define OSD_ASS_0 "\xFD"
139 #define OSD_ASS_1 "\xFE"
140 
141 struct osd_style_opts {
142     char *font;
143     float font_size;
144     struct m_color color;
145     struct m_color border_color;
146     struct m_color shadow_color;
147     struct m_color back_color;
148     float border_size;
149     float shadow_offset;
150     float spacing;
151     int margin_x;
152     int margin_y;
153     int align_x;
154     int align_y;
155     float blur;
156     int bold;
157     int italic;
158     int justify;
159     int font_provider;
160 };
161 
162 extern const struct m_sub_options osd_style_conf;
163 extern const struct m_sub_options sub_style_conf;
164 
165 struct osd_state;
166 struct osd_object;
167 struct mpv_global;
168 struct dec_sub;
169 
170 struct osd_state *osd_create(struct mpv_global *global);
171 void osd_changed(struct osd_state *osd);
172 void osd_free(struct osd_state *osd);
173 
174 bool osd_query_and_reset_want_redraw(struct osd_state *osd);
175 
176 void osd_set_text(struct osd_state *osd, const char *text);
177 void osd_set_sub(struct osd_state *osd, int index, struct dec_sub *dec_sub);
178 
179 bool osd_get_render_subs_in_filter(struct osd_state *osd);
180 void osd_set_render_subs_in_filter(struct osd_state *osd, bool s);
181 void osd_set_force_video_pts(struct osd_state *osd, double video_pts);
182 double osd_get_force_video_pts(struct osd_state *osd);
183 
184 struct osd_progbar_state {
185     int type;           // <0: disabled, 1-255: symbol, else: no symbol
186     float value;        // range 0.0-1.0
187     float *stops;       // used for chapter indicators (0.0-1.0 each)
188     int num_stops;
189 };
190 void osd_set_progbar(struct osd_state *osd, struct osd_progbar_state *s);
191 
192 void osd_set_external2(struct osd_state *osd, struct sub_bitmaps *imgs);
193 
194 enum mp_osd_draw_flags {
195     OSD_DRAW_SUB_FILTER = (1 << 0),
196     OSD_DRAW_SUB_ONLY   = (1 << 1),
197     OSD_DRAW_OSD_ONLY   = (1 << 2),
198 };
199 
200 void osd_draw(struct osd_state *osd, struct mp_osd_res res,
201               double video_pts, int draw_flags,
202               const bool formats[SUBBITMAP_COUNT],
203               void (*cb)(void *ctx, struct sub_bitmaps *imgs), void *cb_ctx);
204 
205 struct sub_bitmap_list *osd_render(struct osd_state *osd, struct mp_osd_res res,
206                                    double video_pts, int draw_flags,
207                                    const bool formats[SUBBITMAP_COUNT]);
208 
209 struct mp_image;
210 void osd_draw_on_image(struct osd_state *osd, struct mp_osd_res res,
211                        double video_pts, int draw_flags, struct mp_image *dest);
212 
213 struct mp_image_pool;
214 void osd_draw_on_image_p(struct osd_state *osd, struct mp_osd_res res,
215                          double video_pts, int draw_flags,
216                          struct mp_image_pool *pool, struct mp_image *dest);
217 
218 void osd_resize(struct osd_state *osd, struct mp_osd_res res);
219 
220 struct mp_image_params;
221 struct mp_osd_res osd_res_from_image_params(const struct mp_image_params *p);
222 
223 struct mp_osd_res osd_get_vo_res(struct osd_state *osd);
224 
225 void osd_rescale_bitmaps(struct sub_bitmaps *imgs, int frame_w, int frame_h,
226                          struct mp_osd_res res, double compensate_par);
227 
228 struct osd_external_ass {
229     void *owner; // unique pointer (NULL is also allowed)
230     int64_t id;
231     int format;
232     char *data;
233     int res_x, res_y;
234     int z;
235     bool hidden;
236 
237     double *out_rc; // hack to pass boundary rect, [x0, y0, x1, y1]
238 };
239 
240 // defined in osd_libass.c and osd_dummy.c
241 void osd_set_external(struct osd_state *osd, struct osd_external_ass *ov);
242 void osd_set_external_remove_owner(struct osd_state *osd, void *owner);
243 void osd_get_text_size(struct osd_state *osd, int *out_screen_h, int *out_font_h);
244 void osd_get_function_sym(char *buffer, size_t buffer_size, int osd_function);
245 
246 #endif /* MPLAYER_SUB_H */
247