/src/vlc/modules/codec/ttml/ttml.h
Line | Count | Source (jump to first uncovered line) |
1 | | /***************************************************************************** |
2 | | * ttml.h : TTML helpers |
3 | | ***************************************************************************** |
4 | | * Copyright (C) 2017 VLC authors and VideoLAN |
5 | | * |
6 | | * This program is free software; you can redistribute it and/or modify it |
7 | | * under the terms of the GNU Lesser General Public License as published by |
8 | | * the Free Software Foundation; either version 2.1 of the License, or |
9 | | * (at your option) any later version. |
10 | | * |
11 | | * This program is distributed in the hope that it will be useful, |
12 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | | * GNU Lesser General Public License for more details. |
15 | | * |
16 | | * You should have received a copy of the GNU Lesser General Public License |
17 | | * along with this program; if not, write to the Free Software Foundation, |
18 | | * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. |
19 | | *****************************************************************************/ |
20 | | |
21 | | #include <vlc_tick.h> |
22 | | #include <vlc_arrays.h> |
23 | | #include <vlc_memstream.h> |
24 | | #include <vlc_list.h> |
25 | | |
26 | | int tt_OpenDemux( vlc_object_t* p_this ); |
27 | | void tt_CloseDemux( vlc_object_t* p_demux ); |
28 | | |
29 | | int tt_OpenDecoder ( vlc_object_t * ); |
30 | | |
31 | | int tt_OpenEncoder ( vlc_object_t * ); |
32 | | |
33 | | enum |
34 | | { |
35 | | TT_TIMINGS_UNSPEC = 0, |
36 | | TT_TIMINGS_PARALLEL, |
37 | | TT_TIMINGS_SEQUENTIAL, |
38 | | }; |
39 | | |
40 | 1.15G | #define TT_FRAME_RATE 30 |
41 | | |
42 | | typedef struct |
43 | | { |
44 | | vlc_tick_t base; |
45 | | unsigned frames; |
46 | | //unsigned ticks; |
47 | | } tt_time_t; |
48 | | |
49 | | typedef struct |
50 | | { |
51 | | uint8_t i_type; |
52 | | tt_time_t begin; |
53 | | tt_time_t end; |
54 | | tt_time_t dur; |
55 | | } tt_timings_t; |
56 | | |
57 | | struct tt_searchkey |
58 | | { |
59 | | tt_time_t time; |
60 | | tt_time_t *p_last; |
61 | | }; |
62 | | |
63 | | /* namespaces */ |
64 | 1.45M | #define TT_NS "http://www.w3.org/ns/ttml" |
65 | 10.7k | #define TT_NS_PARAMETER TT_NS "#parameter" |
66 | 124k | #define TT_NS_STYLING TT_NS "#styling" |
67 | | #define TT_NS_METADATA TT_NS "#metadata" |
68 | | #define TT_NS_PROFILE TT_NS "/profile/" |
69 | | #define TT_NS_FEATURE TT_NS "/feature/" |
70 | | #define TT_NS_EXTENSION TT_NS "/extension/" |
71 | 205k | #define TT_NS_XML "http://www.w3.org/XML/1998/namespace" |
72 | 9.70k | #define TT_NS_SMPTE_TT_EXT "http://www.smpte-ra.org/schemas/2052-1/2010/smpte-tt" |
73 | | |
74 | | typedef struct |
75 | | { |
76 | | struct vlc_list nodes; |
77 | | } tt_namespaces_t; |
78 | | |
79 | | void tt_namespaces_Init( tt_namespaces_t *nss ); |
80 | | void tt_namespaces_Clean( tt_namespaces_t *nss ); |
81 | | void tt_namespaces_Register( tt_namespaces_t *nss, const char *psz_prefix, |
82 | | const char *psz_uri ); |
83 | | const char * tt_namespaces_GetURI( const tt_namespaces_t *nss, |
84 | | const char *psz_qn ); /* qn or prefix */ |
85 | | const char * tt_namespaces_GetPrefix( const tt_namespaces_t *nss, |
86 | | const char *psz_uri ); |
87 | | |
88 | | enum |
89 | | { |
90 | | TT_NODE_TYPE_ELEMENT, |
91 | | TT_NODE_TYPE_TEXT, |
92 | | }; |
93 | | |
94 | | typedef struct tt_basenode_t tt_basenode_t; |
95 | | typedef struct tt_node_t tt_node_t; |
96 | | |
97 | | #define TT_NODE_BASE_MEMBERS \ |
98 | | uint8_t i_type;\ |
99 | | tt_node_t *p_parent;\ |
100 | | tt_basenode_t *p_next; |
101 | | |
102 | | struct tt_basenode_t |
103 | | { |
104 | | TT_NODE_BASE_MEMBERS |
105 | | }; |
106 | | |
107 | | struct tt_node_t |
108 | | { |
109 | | TT_NODE_BASE_MEMBERS |
110 | | tt_basenode_t *p_child; |
111 | | char *psz_node_name; |
112 | | tt_timings_t timings; |
113 | | vlc_dictionary_t attr_dict; |
114 | | char *psz_namespace; |
115 | | }; |
116 | | |
117 | | typedef struct |
118 | | { |
119 | | TT_NODE_BASE_MEMBERS |
120 | | char *psz_text; |
121 | | } tt_textnode_t; |
122 | | |
123 | | static inline const char *tt_LocalName( const char *psz_qname ) |
124 | 12.2M | { |
125 | 12.2M | const char *psz_local = strchr( psz_qname, ':' ); |
126 | 12.2M | return psz_local ? psz_local + 1 : psz_qname; |
127 | 12.2M | } Line | Count | Source | 124 | 12.1M | { | 125 | 12.1M | const char *psz_local = strchr( psz_qname, ':' ); | 126 | 12.1M | return psz_local ? psz_local + 1 : psz_qname; | 127 | 12.1M | } |
Unexecuted instantiation: encttml.c:tt_LocalName Line | Count | Source | 124 | 151k | { | 125 | 151k | const char *psz_local = strchr( psz_qname, ':' ); | 126 | 151k | return psz_local ? psz_local + 1 : psz_qname; | 127 | 151k | } |
Unexecuted instantiation: genttml.c:tt_LocalName |
128 | | |
129 | | tt_textnode_t *tt_textnode_New( tt_node_t *p_parent, const char *psz_text ); |
130 | | tt_textnode_t *tt_subtextnode_New( tt_node_t *p_parent, const char *psz_text, size_t ); |
131 | | tt_node_t * tt_node_New( tt_node_t* p_parent, const char* psz_node_name, const char *psz_namespace ); |
132 | | tt_node_t * tt_node_NewRead( xml_reader_t* reader, tt_namespaces_t *, tt_node_t* p_parent, |
133 | | const char* psz_node_name, const char *psz_namespace ); |
134 | | void tt_node_RecursiveDelete( tt_node_t *p_node ); |
135 | | bool tt_node_Match( const tt_node_t *p_node, const char* psz_name, const char* psz_namespace ); |
136 | | const char * tt_node_GetAttribute( tt_namespaces_t *, const tt_node_t *p_node, |
137 | | const char *psz_name, const char *psz_namespace ); |
138 | | bool tt_node_HasChild( const tt_node_t *p_node ); |
139 | | int tt_node_AddAttribute( tt_node_t *p_node, const char *key, const char *value ); |
140 | | void tt_node_RemoveAttribute( tt_node_t *p_node, const char *key ); |
141 | | |
142 | | int tt_nodes_Read( xml_reader_t *p_reader, tt_namespaces_t *, tt_node_t *p_root_node ); |
143 | | |
144 | | void tt_timings_Resolve( tt_basenode_t *p_child, const tt_timings_t *p_container_timings, |
145 | | tt_time_t **pp_array, size_t *pi_count ); |
146 | | bool tt_timings_Contains( const tt_timings_t *p_range, const tt_time_t * ); |
147 | | size_t tt_timings_FindLowerIndex( const tt_time_t *p_times, size_t i_times, tt_time_t time, bool *pb_found ); |
148 | | |
149 | | static inline void tt_time_Init( tt_time_t *t ) |
150 | 2.22M | { |
151 | 2.22M | t->base = -1; |
152 | 2.22M | t->frames = 0; |
153 | 2.22M | } Line | Count | Source | 150 | 2.15M | { | 151 | 2.15M | t->base = -1; | 152 | 2.15M | t->frames = 0; | 153 | 2.15M | } |
Unexecuted instantiation: encttml.c:tt_time_Init Line | Count | Source | 150 | 75.0k | { | 151 | 75.0k | t->base = -1; | 152 | 75.0k | t->frames = 0; | 153 | 75.0k | } |
Unexecuted instantiation: genttml.c:tt_time_Init |
154 | | |
155 | | static inline tt_time_t tt_time_Create( vlc_tick_t i ) |
156 | 0 | { |
157 | 0 | tt_time_t t; |
158 | 0 | t.base = i; |
159 | 0 | t.frames = 0; |
160 | 0 | return t; |
161 | 0 | } Unexecuted instantiation: ttml.c:tt_time_Create Unexecuted instantiation: encttml.c:tt_time_Create Unexecuted instantiation: substtml.c:tt_time_Create Unexecuted instantiation: genttml.c:tt_time_Create |
162 | | |
163 | | static inline bool tt_time_Valid( const tt_time_t *t ) |
164 | 1.15G | { |
165 | 1.15G | return t->base != -1; |
166 | 1.15G | } Line | Count | Source | 164 | 1.15G | { | 165 | 1.15G | return t->base != -1; | 166 | 1.15G | } |
Unexecuted instantiation: encttml.c:tt_time_Valid Line | Count | Source | 164 | 527k | { | 165 | 527k | return t->base != -1; | 166 | 527k | } |
Line | Count | Source | 164 | 2.33M | { | 165 | 2.33M | return t->base != -1; | 166 | 2.33M | } |
|
167 | | |
168 | | static inline vlc_tick_t tt_time_Convert( const tt_time_t *t ) |
169 | 1.14G | { |
170 | 1.14G | if( !tt_time_Valid( t ) ) |
171 | 0 | return VLC_TICK_INVALID; |
172 | 1.14G | else |
173 | 1.14G | return t->base + vlc_tick_from_samples( t->frames, TT_FRAME_RATE); |
174 | 1.14G | } Line | Count | Source | 169 | 1.14G | { | 170 | 1.14G | if( !tt_time_Valid( t ) ) | 171 | 0 | return VLC_TICK_INVALID; | 172 | 1.14G | else | 173 | 1.14G | return t->base + vlc_tick_from_samples( t->frames, TT_FRAME_RATE); | 174 | 1.14G | } |
Unexecuted instantiation: encttml.c:tt_time_Convert substtml.c:tt_time_Convert Line | Count | Source | 169 | 224k | { | 170 | 224k | if( !tt_time_Valid( t ) ) | 171 | 0 | return VLC_TICK_INVALID; | 172 | 224k | else | 173 | 224k | return t->base + vlc_tick_from_samples( t->frames, TT_FRAME_RATE); | 174 | 224k | } |
Unexecuted instantiation: genttml.c:tt_time_Convert |
175 | | |
176 | | static inline int tt_time_Compare( const tt_time_t *t1, const tt_time_t *t2 ) |
177 | 6.44M | { |
178 | 6.44M | vlc_tick_t ttt1 = tt_time_Convert( t1 ); |
179 | 6.44M | vlc_tick_t ttt2 = tt_time_Convert( t2 ); |
180 | 6.44M | if (ttt1 < ttt2) |
181 | 1.50M | return -1; |
182 | 4.93M | return ttt1 > ttt2; |
183 | 6.44M | } Line | Count | Source | 177 | 6.44M | { | 178 | 6.44M | vlc_tick_t ttt1 = tt_time_Convert( t1 ); | 179 | 6.44M | vlc_tick_t ttt2 = tt_time_Convert( t2 ); | 180 | 6.44M | if (ttt1 < ttt2) | 181 | 1.50M | return -1; | 182 | 4.93M | return ttt1 > ttt2; | 183 | 6.44M | } |
Unexecuted instantiation: encttml.c:tt_time_Compare Unexecuted instantiation: substtml.c:tt_time_Compare Unexecuted instantiation: genttml.c:tt_time_Compare |
184 | | |
185 | | static inline tt_time_t tt_time_Add( tt_time_t t1, tt_time_t t2 ) |
186 | 681k | { |
187 | 681k | t1.base += t2.base; |
188 | 681k | t1.frames += t2.frames; |
189 | 681k | t1.base += vlc_tick_from_samples( t1.frames, TT_FRAME_RATE ); |
190 | 681k | t1.frames = t1.frames % TT_FRAME_RATE; |
191 | 681k | return t1; |
192 | 681k | } Line | Count | Source | 186 | 681k | { | 187 | 681k | t1.base += t2.base; | 188 | 681k | t1.frames += t2.frames; | 189 | 681k | t1.base += vlc_tick_from_samples( t1.frames, TT_FRAME_RATE ); | 190 | 681k | t1.frames = t1.frames % TT_FRAME_RATE; | 191 | 681k | return t1; | 192 | 681k | } |
Unexecuted instantiation: encttml.c:tt_time_Add Unexecuted instantiation: substtml.c:tt_time_Add Unexecuted instantiation: genttml.c:tt_time_Add |
193 | | |
194 | | static inline tt_time_t tt_time_Sub( tt_time_t t1, tt_time_t t2 ) |
195 | 346k | { |
196 | 346k | if( t2.frames > t1.frames ) |
197 | 494 | { |
198 | 494 | unsigned diff = 1 + (t2.frames - t1.frames) / TT_FRAME_RATE; |
199 | 494 | t1.base -= vlc_tick_from_sec( diff ); |
200 | 494 | t1.frames += diff * TT_FRAME_RATE; |
201 | 494 | } |
202 | 346k | t1.frames -= t2.frames; |
203 | 346k | t1.base -= t2.base; |
204 | 346k | return t1; |
205 | 346k | } Line | Count | Source | 195 | 346k | { | 196 | 346k | if( t2.frames > t1.frames ) | 197 | 494 | { | 198 | 494 | unsigned diff = 1 + (t2.frames - t1.frames) / TT_FRAME_RATE; | 199 | 494 | t1.base -= vlc_tick_from_sec( diff ); | 200 | 494 | t1.frames += diff * TT_FRAME_RATE; | 201 | 494 | } | 202 | 346k | t1.frames -= t2.frames; | 203 | 346k | t1.base -= t2.base; | 204 | 346k | return t1; | 205 | 346k | } |
Unexecuted instantiation: encttml.c:tt_time_Sub Unexecuted instantiation: substtml.c:tt_time_Sub Unexecuted instantiation: genttml.c:tt_time_Sub |
206 | | |
207 | | /* Encoding */ |
208 | | |
209 | | char *tt_genTiming( tt_time_t t ); |
210 | | void tt_node_AttributesToText( struct vlc_memstream *p_stream, const tt_node_t* p_node ); |
211 | | void tt_node_ToText( struct vlc_memstream *p_stream, const tt_basenode_t *p_basenode, |
212 | | const tt_time_t *playbacktime ); |