]> git.sesse.net Git - vlc/blob - modules/codec/substext.h
Split SPS/PPS parsing and annex b conversion to a reusable utility function
[vlc] / modules / codec / substext.h
1 struct subpicture_updater_sys_t {
2     char *text;
3     char *html;
4
5     int  align;
6     int  x;
7     int  y;
8
9     bool is_fixed;
10     int  fixed_width;
11     int  fixed_height;
12 };
13
14 static int SubpictureTextValidate(subpicture_t *subpic,
15                                   bool has_src_changed, const video_format_t *fmt_src,
16                                   bool has_dst_changed, const video_format_t *fmt_dst,
17                                   mtime_t ts)
18 {
19     subpicture_updater_sys_t *sys = subpic->updater.p_sys;
20     VLC_UNUSED(fmt_src); VLC_UNUSED(fmt_dst); VLC_UNUSED(ts);
21
22     if (!has_src_changed && !has_dst_changed)
23         return VLC_SUCCESS;
24     if (!sys->is_fixed && subpic->b_absolute && subpic->p_region &&
25         subpic->i_original_picture_width > 0 &&
26         subpic->i_original_picture_height > 0) {
27
28         sys->is_fixed     = true;
29         sys->x            = subpic->p_region->i_x;
30         sys->y            = subpic->p_region->i_y;
31         sys->fixed_width  = subpic->i_original_picture_width;
32         sys->fixed_height = subpic->i_original_picture_height;
33     }
34     return VLC_EGENERIC;
35 }
36 static void SubpictureTextUpdate(subpicture_t *subpic,
37                                  const video_format_t *fmt_src,
38                                  const video_format_t *fmt_dst,
39                                  mtime_t ts)
40 {
41     subpicture_updater_sys_t *sys = subpic->updater.p_sys;
42     VLC_UNUSED(fmt_src); VLC_UNUSED(ts);
43
44     if (fmt_dst->i_sar_num <= 0 || fmt_dst->i_sar_den <= 0)
45         return;
46
47     subpic->i_original_picture_width  = fmt_dst->i_width * fmt_dst->i_sar_num / fmt_dst->i_sar_den;
48     subpic->i_original_picture_height = fmt_dst->i_height;
49
50     video_format_t fmt;
51     video_format_Init(&fmt, VLC_CODEC_TEXT);
52     fmt.i_sar_num = 1;
53     fmt.i_sar_den = 1;
54
55     subpicture_region_t *r = subpic->p_region = subpicture_region_New(&fmt);
56     if (!r)
57         return;
58
59     r->psz_text = sys->text ? strdup(sys->text) : NULL;
60     r->psz_html = sys->html ? strdup(sys->html) : NULL;
61     r->i_align  = sys->align;
62     if (!sys->is_fixed) {
63         const float margin_ratio = 0.04;
64         const int   margin_h     = margin_ratio * fmt_dst->i_visible_width;
65         const int   margin_v     = margin_ratio * fmt_dst->i_visible_height;
66
67         r->i_x = 0;
68         if (r->i_align & SUBPICTURE_ALIGN_LEFT)
69             r->i_x += margin_h + fmt_dst->i_x_offset;
70         else if (r->i_align & SUBPICTURE_ALIGN_RIGHT)
71             r->i_x += margin_h + fmt_dst->i_width - (fmt_dst->i_visible_width + fmt_dst->i_x_offset);
72
73         r->i_y = 0;
74         if (r->i_align & SUBPICTURE_ALIGN_TOP )
75             r->i_y += margin_v + fmt_dst->i_y_offset;
76         else if (r->i_align & SUBPICTURE_ALIGN_BOTTOM )
77             r->i_y += margin_v + fmt_dst->i_height - (fmt_dst->i_visible_height + fmt_dst->i_y_offset);
78     } else {
79         /* FIXME it doesn't adapt on crop settings changes */
80         r->i_x = sys->x * fmt_dst->i_width  / sys->fixed_width;
81         r->i_y = sys->y * fmt_dst->i_height / sys->fixed_height;
82     }
83 }
84 static void SubpictureTextDestroy(subpicture_t *subpic)
85 {
86     subpicture_updater_sys_t *sys = subpic->updater.p_sys;
87
88     free(sys->text);
89     free(sys->html);
90     free(sys);
91 }
92
93 static inline subpicture_t *decoder_NewSubpictureText(decoder_t *decoder)
94 {
95     subpicture_updater_sys_t *sys = calloc(1, sizeof(*sys));
96     subpicture_updater_t updater = {
97         .pf_validate = SubpictureTextValidate,
98         .pf_update   = SubpictureTextUpdate,
99         .pf_destroy  = SubpictureTextDestroy,
100         .p_sys       = sys,
101     };
102     subpicture_t *subpic = decoder_NewSubpicture(decoder, &updater);
103     if (!subpic)
104         free(sys);
105     return subpic;
106 }