yading@11
|
1 /*
|
yading@11
|
2 * This file is part of FFmpeg.
|
yading@11
|
3 *
|
yading@11
|
4 * FFmpeg is free software; you can redistribute it and/or
|
yading@11
|
5 * modify it under the terms of the GNU Lesser General Public
|
yading@11
|
6 * License as published by the Free Software Foundation; either
|
yading@11
|
7 * version 2.1 of the License, or (at your option) any later version.
|
yading@11
|
8 *
|
yading@11
|
9 * FFmpeg is distributed in the hope that it will be useful,
|
yading@11
|
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
yading@11
|
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
yading@11
|
12 * Lesser General Public License for more details.
|
yading@11
|
13 *
|
yading@11
|
14 * You should have received a copy of the GNU Lesser General Public
|
yading@11
|
15 * License along with FFmpeg; if not, write to the Free Software
|
yading@11
|
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
yading@11
|
17 */
|
yading@11
|
18
|
yading@11
|
19 /**
|
yading@11
|
20 * @file
|
yading@11
|
21 * misc parsing utilities
|
yading@11
|
22 */
|
yading@11
|
23
|
yading@11
|
24 #include <time.h>
|
yading@11
|
25
|
yading@11
|
26 #include "avstring.h"
|
yading@11
|
27 #include "avutil.h"
|
yading@11
|
28 #include "common.h"
|
yading@11
|
29 #include "eval.h"
|
yading@11
|
30 #include "log.h"
|
yading@11
|
31 #include "random_seed.h"
|
yading@11
|
32 #include "parseutils.h"
|
yading@11
|
33
|
yading@11
|
34 #ifdef TEST
|
yading@11
|
35
|
yading@11
|
36 #define av_get_random_seed av_get_random_seed_deterministic
|
yading@11
|
37 static uint32_t av_get_random_seed_deterministic(void);
|
yading@11
|
38
|
yading@11
|
39 #define time(t) 1331972053
|
yading@11
|
40
|
yading@11
|
41 #endif
|
yading@11
|
42
|
yading@11
|
43 int av_parse_ratio(AVRational *q, const char *str, int max,
|
yading@11
|
44 int log_offset, void *log_ctx)
|
yading@11
|
45 {
|
yading@11
|
46 char c;
|
yading@11
|
47 int ret;
|
yading@11
|
48
|
yading@11
|
49 if (sscanf(str, "%d:%d%c", &q->num, &q->den, &c) != 2) {
|
yading@11
|
50 double d;
|
yading@11
|
51 ret = av_expr_parse_and_eval(&d, str, NULL, NULL,
|
yading@11
|
52 NULL, NULL, NULL, NULL,
|
yading@11
|
53 NULL, log_offset, log_ctx);
|
yading@11
|
54 if (ret < 0)
|
yading@11
|
55 return ret;
|
yading@11
|
56 *q = av_d2q(d, max);
|
yading@11
|
57 } else {
|
yading@11
|
58 av_reduce(&q->num, &q->den, q->num, q->den, max);
|
yading@11
|
59 }
|
yading@11
|
60
|
yading@11
|
61 return 0;
|
yading@11
|
62 }
|
yading@11
|
63
|
yading@11
|
64 typedef struct {
|
yading@11
|
65 const char *abbr;
|
yading@11
|
66 int width, height;
|
yading@11
|
67 } VideoSizeAbbr;
|
yading@11
|
68
|
yading@11
|
69 typedef struct {
|
yading@11
|
70 const char *abbr;
|
yading@11
|
71 AVRational rate;
|
yading@11
|
72 } VideoRateAbbr;
|
yading@11
|
73
|
yading@11
|
74 static const VideoSizeAbbr video_size_abbrs[] = {
|
yading@11
|
75 { "ntsc", 720, 480 },
|
yading@11
|
76 { "pal", 720, 576 },
|
yading@11
|
77 { "qntsc", 352, 240 }, /* VCD compliant NTSC */
|
yading@11
|
78 { "qpal", 352, 288 }, /* VCD compliant PAL */
|
yading@11
|
79 { "sntsc", 640, 480 }, /* square pixel NTSC */
|
yading@11
|
80 { "spal", 768, 576 }, /* square pixel PAL */
|
yading@11
|
81 { "film", 352, 240 },
|
yading@11
|
82 { "ntsc-film", 352, 240 },
|
yading@11
|
83 { "sqcif", 128, 96 },
|
yading@11
|
84 { "qcif", 176, 144 },
|
yading@11
|
85 { "cif", 352, 288 },
|
yading@11
|
86 { "4cif", 704, 576 },
|
yading@11
|
87 { "16cif", 1408,1152 },
|
yading@11
|
88 { "qqvga", 160, 120 },
|
yading@11
|
89 { "qvga", 320, 240 },
|
yading@11
|
90 { "vga", 640, 480 },
|
yading@11
|
91 { "svga", 800, 600 },
|
yading@11
|
92 { "xga", 1024, 768 },
|
yading@11
|
93 { "uxga", 1600,1200 },
|
yading@11
|
94 { "qxga", 2048,1536 },
|
yading@11
|
95 { "sxga", 1280,1024 },
|
yading@11
|
96 { "qsxga", 2560,2048 },
|
yading@11
|
97 { "hsxga", 5120,4096 },
|
yading@11
|
98 { "wvga", 852, 480 },
|
yading@11
|
99 { "wxga", 1366, 768 },
|
yading@11
|
100 { "wsxga", 1600,1024 },
|
yading@11
|
101 { "wuxga", 1920,1200 },
|
yading@11
|
102 { "woxga", 2560,1600 },
|
yading@11
|
103 { "wqsxga", 3200,2048 },
|
yading@11
|
104 { "wquxga", 3840,2400 },
|
yading@11
|
105 { "whsxga", 6400,4096 },
|
yading@11
|
106 { "whuxga", 7680,4800 },
|
yading@11
|
107 { "cga", 320, 200 },
|
yading@11
|
108 { "ega", 640, 350 },
|
yading@11
|
109 { "hd480", 852, 480 },
|
yading@11
|
110 { "hd720", 1280, 720 },
|
yading@11
|
111 { "hd1080", 1920,1080 },
|
yading@11
|
112 { "2k", 2048,1080 }, /* Digital Cinema System Specification */
|
yading@11
|
113 { "2kflat", 1998,1080 },
|
yading@11
|
114 { "2kscope", 2048, 858 },
|
yading@11
|
115 { "4k", 4096,2160 }, /* Digital Cinema System Specification */
|
yading@11
|
116 { "4kflat", 3996,2160 },
|
yading@11
|
117 { "4kscope", 4096,1716 },
|
yading@11
|
118 };
|
yading@11
|
119
|
yading@11
|
120 static const VideoRateAbbr video_rate_abbrs[]= {
|
yading@11
|
121 { "ntsc", { 30000, 1001 } },
|
yading@11
|
122 { "pal", { 25, 1 } },
|
yading@11
|
123 { "qntsc", { 30000, 1001 } }, /* VCD compliant NTSC */
|
yading@11
|
124 { "qpal", { 25, 1 } }, /* VCD compliant PAL */
|
yading@11
|
125 { "sntsc", { 30000, 1001 } }, /* square pixel NTSC */
|
yading@11
|
126 { "spal", { 25, 1 } }, /* square pixel PAL */
|
yading@11
|
127 { "film", { 24, 1 } },
|
yading@11
|
128 { "ntsc-film", { 24000, 1001 } },
|
yading@11
|
129 };
|
yading@11
|
130
|
yading@11
|
131 int av_parse_video_size(int *width_ptr, int *height_ptr, const char *str)
|
yading@11
|
132 {
|
yading@11
|
133 int i;
|
yading@11
|
134 int n = FF_ARRAY_ELEMS(video_size_abbrs);
|
yading@11
|
135 const char *p;
|
yading@11
|
136 int width = 0, height = 0;
|
yading@11
|
137
|
yading@11
|
138 for (i = 0; i < n; i++) {
|
yading@11
|
139 if (!strcmp(video_size_abbrs[i].abbr, str)) {
|
yading@11
|
140 width = video_size_abbrs[i].width;
|
yading@11
|
141 height = video_size_abbrs[i].height;
|
yading@11
|
142 break;
|
yading@11
|
143 }
|
yading@11
|
144 }
|
yading@11
|
145 if (i == n) {
|
yading@11
|
146 width = strtol(str, (void*)&p, 10);
|
yading@11
|
147 if (*p)
|
yading@11
|
148 p++;
|
yading@11
|
149 height = strtol(p, (void*)&p, 10);
|
yading@11
|
150
|
yading@11
|
151 /* trailing extraneous data detected, like in 123x345foobar */
|
yading@11
|
152 if (*p)
|
yading@11
|
153 return AVERROR(EINVAL);
|
yading@11
|
154 }
|
yading@11
|
155 if (width <= 0 || height <= 0)
|
yading@11
|
156 return AVERROR(EINVAL);
|
yading@11
|
157 *width_ptr = width;
|
yading@11
|
158 *height_ptr = height;
|
yading@11
|
159 return 0;
|
yading@11
|
160 }
|
yading@11
|
161
|
yading@11
|
162 int av_parse_video_rate(AVRational *rate, const char *arg)
|
yading@11
|
163 {
|
yading@11
|
164 int i, ret;
|
yading@11
|
165 int n = FF_ARRAY_ELEMS(video_rate_abbrs);
|
yading@11
|
166
|
yading@11
|
167 /* First, we check our abbreviation table */
|
yading@11
|
168 for (i = 0; i < n; ++i)
|
yading@11
|
169 if (!strcmp(video_rate_abbrs[i].abbr, arg)) {
|
yading@11
|
170 *rate = video_rate_abbrs[i].rate;
|
yading@11
|
171 return 0;
|
yading@11
|
172 }
|
yading@11
|
173
|
yading@11
|
174 /* Then, we try to parse it as fraction */
|
yading@11
|
175 if ((ret = av_parse_ratio_quiet(rate, arg, 1001000)) < 0)
|
yading@11
|
176 return ret;
|
yading@11
|
177 if (rate->num <= 0 || rate->den <= 0)
|
yading@11
|
178 return AVERROR(EINVAL);
|
yading@11
|
179 return 0;
|
yading@11
|
180 }
|
yading@11
|
181
|
yading@11
|
182 typedef struct {
|
yading@11
|
183 const char *name; ///< a string representing the name of the color
|
yading@11
|
184 uint8_t rgb_color[3]; ///< RGB values for the color
|
yading@11
|
185 } ColorEntry;
|
yading@11
|
186
|
yading@11
|
187 static const ColorEntry color_table[] = {
|
yading@11
|
188 { "AliceBlue", { 0xF0, 0xF8, 0xFF } },
|
yading@11
|
189 { "AntiqueWhite", { 0xFA, 0xEB, 0xD7 } },
|
yading@11
|
190 { "Aqua", { 0x00, 0xFF, 0xFF } },
|
yading@11
|
191 { "Aquamarine", { 0x7F, 0xFF, 0xD4 } },
|
yading@11
|
192 { "Azure", { 0xF0, 0xFF, 0xFF } },
|
yading@11
|
193 { "Beige", { 0xF5, 0xF5, 0xDC } },
|
yading@11
|
194 { "Bisque", { 0xFF, 0xE4, 0xC4 } },
|
yading@11
|
195 { "Black", { 0x00, 0x00, 0x00 } },
|
yading@11
|
196 { "BlanchedAlmond", { 0xFF, 0xEB, 0xCD } },
|
yading@11
|
197 { "Blue", { 0x00, 0x00, 0xFF } },
|
yading@11
|
198 { "BlueViolet", { 0x8A, 0x2B, 0xE2 } },
|
yading@11
|
199 { "Brown", { 0xA5, 0x2A, 0x2A } },
|
yading@11
|
200 { "BurlyWood", { 0xDE, 0xB8, 0x87 } },
|
yading@11
|
201 { "CadetBlue", { 0x5F, 0x9E, 0xA0 } },
|
yading@11
|
202 { "Chartreuse", { 0x7F, 0xFF, 0x00 } },
|
yading@11
|
203 { "Chocolate", { 0xD2, 0x69, 0x1E } },
|
yading@11
|
204 { "Coral", { 0xFF, 0x7F, 0x50 } },
|
yading@11
|
205 { "CornflowerBlue", { 0x64, 0x95, 0xED } },
|
yading@11
|
206 { "Cornsilk", { 0xFF, 0xF8, 0xDC } },
|
yading@11
|
207 { "Crimson", { 0xDC, 0x14, 0x3C } },
|
yading@11
|
208 { "Cyan", { 0x00, 0xFF, 0xFF } },
|
yading@11
|
209 { "DarkBlue", { 0x00, 0x00, 0x8B } },
|
yading@11
|
210 { "DarkCyan", { 0x00, 0x8B, 0x8B } },
|
yading@11
|
211 { "DarkGoldenRod", { 0xB8, 0x86, 0x0B } },
|
yading@11
|
212 { "DarkGray", { 0xA9, 0xA9, 0xA9 } },
|
yading@11
|
213 { "DarkGreen", { 0x00, 0x64, 0x00 } },
|
yading@11
|
214 { "DarkKhaki", { 0xBD, 0xB7, 0x6B } },
|
yading@11
|
215 { "DarkMagenta", { 0x8B, 0x00, 0x8B } },
|
yading@11
|
216 { "DarkOliveGreen", { 0x55, 0x6B, 0x2F } },
|
yading@11
|
217 { "Darkorange", { 0xFF, 0x8C, 0x00 } },
|
yading@11
|
218 { "DarkOrchid", { 0x99, 0x32, 0xCC } },
|
yading@11
|
219 { "DarkRed", { 0x8B, 0x00, 0x00 } },
|
yading@11
|
220 { "DarkSalmon", { 0xE9, 0x96, 0x7A } },
|
yading@11
|
221 { "DarkSeaGreen", { 0x8F, 0xBC, 0x8F } },
|
yading@11
|
222 { "DarkSlateBlue", { 0x48, 0x3D, 0x8B } },
|
yading@11
|
223 { "DarkSlateGray", { 0x2F, 0x4F, 0x4F } },
|
yading@11
|
224 { "DarkTurquoise", { 0x00, 0xCE, 0xD1 } },
|
yading@11
|
225 { "DarkViolet", { 0x94, 0x00, 0xD3 } },
|
yading@11
|
226 { "DeepPink", { 0xFF, 0x14, 0x93 } },
|
yading@11
|
227 { "DeepSkyBlue", { 0x00, 0xBF, 0xFF } },
|
yading@11
|
228 { "DimGray", { 0x69, 0x69, 0x69 } },
|
yading@11
|
229 { "DodgerBlue", { 0x1E, 0x90, 0xFF } },
|
yading@11
|
230 { "FireBrick", { 0xB2, 0x22, 0x22 } },
|
yading@11
|
231 { "FloralWhite", { 0xFF, 0xFA, 0xF0 } },
|
yading@11
|
232 { "ForestGreen", { 0x22, 0x8B, 0x22 } },
|
yading@11
|
233 { "Fuchsia", { 0xFF, 0x00, 0xFF } },
|
yading@11
|
234 { "Gainsboro", { 0xDC, 0xDC, 0xDC } },
|
yading@11
|
235 { "GhostWhite", { 0xF8, 0xF8, 0xFF } },
|
yading@11
|
236 { "Gold", { 0xFF, 0xD7, 0x00 } },
|
yading@11
|
237 { "GoldenRod", { 0xDA, 0xA5, 0x20 } },
|
yading@11
|
238 { "Gray", { 0x80, 0x80, 0x80 } },
|
yading@11
|
239 { "Green", { 0x00, 0x80, 0x00 } },
|
yading@11
|
240 { "GreenYellow", { 0xAD, 0xFF, 0x2F } },
|
yading@11
|
241 { "HoneyDew", { 0xF0, 0xFF, 0xF0 } },
|
yading@11
|
242 { "HotPink", { 0xFF, 0x69, 0xB4 } },
|
yading@11
|
243 { "IndianRed", { 0xCD, 0x5C, 0x5C } },
|
yading@11
|
244 { "Indigo", { 0x4B, 0x00, 0x82 } },
|
yading@11
|
245 { "Ivory", { 0xFF, 0xFF, 0xF0 } },
|
yading@11
|
246 { "Khaki", { 0xF0, 0xE6, 0x8C } },
|
yading@11
|
247 { "Lavender", { 0xE6, 0xE6, 0xFA } },
|
yading@11
|
248 { "LavenderBlush", { 0xFF, 0xF0, 0xF5 } },
|
yading@11
|
249 { "LawnGreen", { 0x7C, 0xFC, 0x00 } },
|
yading@11
|
250 { "LemonChiffon", { 0xFF, 0xFA, 0xCD } },
|
yading@11
|
251 { "LightBlue", { 0xAD, 0xD8, 0xE6 } },
|
yading@11
|
252 { "LightCoral", { 0xF0, 0x80, 0x80 } },
|
yading@11
|
253 { "LightCyan", { 0xE0, 0xFF, 0xFF } },
|
yading@11
|
254 { "LightGoldenRodYellow", { 0xFA, 0xFA, 0xD2 } },
|
yading@11
|
255 { "LightGreen", { 0x90, 0xEE, 0x90 } },
|
yading@11
|
256 { "LightGrey", { 0xD3, 0xD3, 0xD3 } },
|
yading@11
|
257 { "LightPink", { 0xFF, 0xB6, 0xC1 } },
|
yading@11
|
258 { "LightSalmon", { 0xFF, 0xA0, 0x7A } },
|
yading@11
|
259 { "LightSeaGreen", { 0x20, 0xB2, 0xAA } },
|
yading@11
|
260 { "LightSkyBlue", { 0x87, 0xCE, 0xFA } },
|
yading@11
|
261 { "LightSlateGray", { 0x77, 0x88, 0x99 } },
|
yading@11
|
262 { "LightSteelBlue", { 0xB0, 0xC4, 0xDE } },
|
yading@11
|
263 { "LightYellow", { 0xFF, 0xFF, 0xE0 } },
|
yading@11
|
264 { "Lime", { 0x00, 0xFF, 0x00 } },
|
yading@11
|
265 { "LimeGreen", { 0x32, 0xCD, 0x32 } },
|
yading@11
|
266 { "Linen", { 0xFA, 0xF0, 0xE6 } },
|
yading@11
|
267 { "Magenta", { 0xFF, 0x00, 0xFF } },
|
yading@11
|
268 { "Maroon", { 0x80, 0x00, 0x00 } },
|
yading@11
|
269 { "MediumAquaMarine", { 0x66, 0xCD, 0xAA } },
|
yading@11
|
270 { "MediumBlue", { 0x00, 0x00, 0xCD } },
|
yading@11
|
271 { "MediumOrchid", { 0xBA, 0x55, 0xD3 } },
|
yading@11
|
272 { "MediumPurple", { 0x93, 0x70, 0xD8 } },
|
yading@11
|
273 { "MediumSeaGreen", { 0x3C, 0xB3, 0x71 } },
|
yading@11
|
274 { "MediumSlateBlue", { 0x7B, 0x68, 0xEE } },
|
yading@11
|
275 { "MediumSpringGreen", { 0x00, 0xFA, 0x9A } },
|
yading@11
|
276 { "MediumTurquoise", { 0x48, 0xD1, 0xCC } },
|
yading@11
|
277 { "MediumVioletRed", { 0xC7, 0x15, 0x85 } },
|
yading@11
|
278 { "MidnightBlue", { 0x19, 0x19, 0x70 } },
|
yading@11
|
279 { "MintCream", { 0xF5, 0xFF, 0xFA } },
|
yading@11
|
280 { "MistyRose", { 0xFF, 0xE4, 0xE1 } },
|
yading@11
|
281 { "Moccasin", { 0xFF, 0xE4, 0xB5 } },
|
yading@11
|
282 { "NavajoWhite", { 0xFF, 0xDE, 0xAD } },
|
yading@11
|
283 { "Navy", { 0x00, 0x00, 0x80 } },
|
yading@11
|
284 { "OldLace", { 0xFD, 0xF5, 0xE6 } },
|
yading@11
|
285 { "Olive", { 0x80, 0x80, 0x00 } },
|
yading@11
|
286 { "OliveDrab", { 0x6B, 0x8E, 0x23 } },
|
yading@11
|
287 { "Orange", { 0xFF, 0xA5, 0x00 } },
|
yading@11
|
288 { "OrangeRed", { 0xFF, 0x45, 0x00 } },
|
yading@11
|
289 { "Orchid", { 0xDA, 0x70, 0xD6 } },
|
yading@11
|
290 { "PaleGoldenRod", { 0xEE, 0xE8, 0xAA } },
|
yading@11
|
291 { "PaleGreen", { 0x98, 0xFB, 0x98 } },
|
yading@11
|
292 { "PaleTurquoise", { 0xAF, 0xEE, 0xEE } },
|
yading@11
|
293 { "PaleVioletRed", { 0xD8, 0x70, 0x93 } },
|
yading@11
|
294 { "PapayaWhip", { 0xFF, 0xEF, 0xD5 } },
|
yading@11
|
295 { "PeachPuff", { 0xFF, 0xDA, 0xB9 } },
|
yading@11
|
296 { "Peru", { 0xCD, 0x85, 0x3F } },
|
yading@11
|
297 { "Pink", { 0xFF, 0xC0, 0xCB } },
|
yading@11
|
298 { "Plum", { 0xDD, 0xA0, 0xDD } },
|
yading@11
|
299 { "PowderBlue", { 0xB0, 0xE0, 0xE6 } },
|
yading@11
|
300 { "Purple", { 0x80, 0x00, 0x80 } },
|
yading@11
|
301 { "Red", { 0xFF, 0x00, 0x00 } },
|
yading@11
|
302 { "RosyBrown", { 0xBC, 0x8F, 0x8F } },
|
yading@11
|
303 { "RoyalBlue", { 0x41, 0x69, 0xE1 } },
|
yading@11
|
304 { "SaddleBrown", { 0x8B, 0x45, 0x13 } },
|
yading@11
|
305 { "Salmon", { 0xFA, 0x80, 0x72 } },
|
yading@11
|
306 { "SandyBrown", { 0xF4, 0xA4, 0x60 } },
|
yading@11
|
307 { "SeaGreen", { 0x2E, 0x8B, 0x57 } },
|
yading@11
|
308 { "SeaShell", { 0xFF, 0xF5, 0xEE } },
|
yading@11
|
309 { "Sienna", { 0xA0, 0x52, 0x2D } },
|
yading@11
|
310 { "Silver", { 0xC0, 0xC0, 0xC0 } },
|
yading@11
|
311 { "SkyBlue", { 0x87, 0xCE, 0xEB } },
|
yading@11
|
312 { "SlateBlue", { 0x6A, 0x5A, 0xCD } },
|
yading@11
|
313 { "SlateGray", { 0x70, 0x80, 0x90 } },
|
yading@11
|
314 { "Snow", { 0xFF, 0xFA, 0xFA } },
|
yading@11
|
315 { "SpringGreen", { 0x00, 0xFF, 0x7F } },
|
yading@11
|
316 { "SteelBlue", { 0x46, 0x82, 0xB4 } },
|
yading@11
|
317 { "Tan", { 0xD2, 0xB4, 0x8C } },
|
yading@11
|
318 { "Teal", { 0x00, 0x80, 0x80 } },
|
yading@11
|
319 { "Thistle", { 0xD8, 0xBF, 0xD8 } },
|
yading@11
|
320 { "Tomato", { 0xFF, 0x63, 0x47 } },
|
yading@11
|
321 { "Turquoise", { 0x40, 0xE0, 0xD0 } },
|
yading@11
|
322 { "Violet", { 0xEE, 0x82, 0xEE } },
|
yading@11
|
323 { "Wheat", { 0xF5, 0xDE, 0xB3 } },
|
yading@11
|
324 { "White", { 0xFF, 0xFF, 0xFF } },
|
yading@11
|
325 { "WhiteSmoke", { 0xF5, 0xF5, 0xF5 } },
|
yading@11
|
326 { "Yellow", { 0xFF, 0xFF, 0x00 } },
|
yading@11
|
327 { "YellowGreen", { 0x9A, 0xCD, 0x32 } },
|
yading@11
|
328 };
|
yading@11
|
329
|
yading@11
|
330 static int color_table_compare(const void *lhs, const void *rhs)
|
yading@11
|
331 {
|
yading@11
|
332 return av_strcasecmp(lhs, ((const ColorEntry *)rhs)->name);
|
yading@11
|
333 }
|
yading@11
|
334
|
yading@11
|
335 #define ALPHA_SEP '@'
|
yading@11
|
336
|
yading@11
|
337 int av_parse_color(uint8_t *rgba_color, const char *color_string, int slen,
|
yading@11
|
338 void *log_ctx)
|
yading@11
|
339 {
|
yading@11
|
340 char *tail, color_string2[128];
|
yading@11
|
341 const ColorEntry *entry;
|
yading@11
|
342 int len, hex_offset = 0;
|
yading@11
|
343
|
yading@11
|
344 if (color_string[0] == '#') {
|
yading@11
|
345 hex_offset = 1;
|
yading@11
|
346 } else if (!strncmp(color_string, "0x", 2))
|
yading@11
|
347 hex_offset = 2;
|
yading@11
|
348
|
yading@11
|
349 if (slen < 0)
|
yading@11
|
350 slen = strlen(color_string);
|
yading@11
|
351 av_strlcpy(color_string2, color_string + hex_offset,
|
yading@11
|
352 FFMIN(slen-hex_offset+1, sizeof(color_string2)));
|
yading@11
|
353 if ((tail = strchr(color_string2, ALPHA_SEP)))
|
yading@11
|
354 *tail++ = 0;
|
yading@11
|
355 len = strlen(color_string2);
|
yading@11
|
356 rgba_color[3] = 255;
|
yading@11
|
357
|
yading@11
|
358 if (!av_strcasecmp(color_string2, "random") || !av_strcasecmp(color_string2, "bikeshed")) {
|
yading@11
|
359 int rgba = av_get_random_seed();
|
yading@11
|
360 rgba_color[0] = rgba >> 24;
|
yading@11
|
361 rgba_color[1] = rgba >> 16;
|
yading@11
|
362 rgba_color[2] = rgba >> 8;
|
yading@11
|
363 rgba_color[3] = rgba;
|
yading@11
|
364 } else if (hex_offset ||
|
yading@11
|
365 strspn(color_string2, "0123456789ABCDEFabcdef") == len) {
|
yading@11
|
366 char *tail;
|
yading@11
|
367 unsigned int rgba = strtoul(color_string2, &tail, 16);
|
yading@11
|
368
|
yading@11
|
369 if (*tail || (len != 6 && len != 8)) {
|
yading@11
|
370 av_log(log_ctx, AV_LOG_ERROR, "Invalid 0xRRGGBB[AA] color string: '%s'\n", color_string2);
|
yading@11
|
371 return AVERROR(EINVAL);
|
yading@11
|
372 }
|
yading@11
|
373 if (len == 8) {
|
yading@11
|
374 rgba_color[3] = rgba;
|
yading@11
|
375 rgba >>= 8;
|
yading@11
|
376 }
|
yading@11
|
377 rgba_color[0] = rgba >> 16;
|
yading@11
|
378 rgba_color[1] = rgba >> 8;
|
yading@11
|
379 rgba_color[2] = rgba;
|
yading@11
|
380 } else {
|
yading@11
|
381 entry = bsearch(color_string2,
|
yading@11
|
382 color_table,
|
yading@11
|
383 FF_ARRAY_ELEMS(color_table),
|
yading@11
|
384 sizeof(ColorEntry),
|
yading@11
|
385 color_table_compare);
|
yading@11
|
386 if (!entry) {
|
yading@11
|
387 av_log(log_ctx, AV_LOG_ERROR, "Cannot find color '%s'\n", color_string2);
|
yading@11
|
388 return AVERROR(EINVAL);
|
yading@11
|
389 }
|
yading@11
|
390 memcpy(rgba_color, entry->rgb_color, 3);
|
yading@11
|
391 }
|
yading@11
|
392
|
yading@11
|
393 if (tail) {
|
yading@11
|
394 double alpha;
|
yading@11
|
395 const char *alpha_string = tail;
|
yading@11
|
396 if (!strncmp(alpha_string, "0x", 2)) {
|
yading@11
|
397 alpha = strtoul(alpha_string, &tail, 16);
|
yading@11
|
398 } else {
|
yading@11
|
399 double norm_alpha = strtod(alpha_string, &tail);
|
yading@11
|
400 if (norm_alpha < 0.0 || norm_alpha > 1.0)
|
yading@11
|
401 alpha = 256;
|
yading@11
|
402 else
|
yading@11
|
403 alpha = 255 * norm_alpha;
|
yading@11
|
404 }
|
yading@11
|
405
|
yading@11
|
406 if (tail == alpha_string || *tail || alpha > 255 || alpha < 0) {
|
yading@11
|
407 av_log(log_ctx, AV_LOG_ERROR, "Invalid alpha value specifier '%s' in '%s'\n",
|
yading@11
|
408 alpha_string, color_string);
|
yading@11
|
409 return AVERROR(EINVAL);
|
yading@11
|
410 }
|
yading@11
|
411 rgba_color[3] = alpha;
|
yading@11
|
412 }
|
yading@11
|
413
|
yading@11
|
414 return 0;
|
yading@11
|
415 }
|
yading@11
|
416
|
yading@11
|
417 /* get a positive number between n_min and n_max, for a maximum length
|
yading@11
|
418 of len_max. Return -1 if error. */
|
yading@11
|
419 static int date_get_num(const char **pp,
|
yading@11
|
420 int n_min, int n_max, int len_max)
|
yading@11
|
421 {
|
yading@11
|
422 int i, val, c;
|
yading@11
|
423 const char *p;
|
yading@11
|
424
|
yading@11
|
425 p = *pp;
|
yading@11
|
426 val = 0;
|
yading@11
|
427 for(i = 0; i < len_max; i++) {
|
yading@11
|
428 c = *p;
|
yading@11
|
429 if (!av_isdigit(c))
|
yading@11
|
430 break;
|
yading@11
|
431 val = (val * 10) + c - '0';
|
yading@11
|
432 p++;
|
yading@11
|
433 }
|
yading@11
|
434 /* no number read ? */
|
yading@11
|
435 if (p == *pp)
|
yading@11
|
436 return -1;
|
yading@11
|
437 if (val < n_min || val > n_max)
|
yading@11
|
438 return -1;
|
yading@11
|
439 *pp = p;
|
yading@11
|
440 return val;
|
yading@11
|
441 }
|
yading@11
|
442
|
yading@11
|
443 char *av_small_strptime(const char *p, const char *fmt, struct tm *dt)
|
yading@11
|
444 {
|
yading@11
|
445 int c, val;
|
yading@11
|
446
|
yading@11
|
447 for(;;) {
|
yading@11
|
448 /* consume time string until a non whitespace char is found */
|
yading@11
|
449 while (av_isspace(*fmt)) {
|
yading@11
|
450 while (av_isspace(*p))
|
yading@11
|
451 p++;
|
yading@11
|
452 fmt++;
|
yading@11
|
453 }
|
yading@11
|
454 c = *fmt++;
|
yading@11
|
455 if (c == '\0') {
|
yading@11
|
456 return (char *)p;
|
yading@11
|
457 } else if (c == '%') {
|
yading@11
|
458 c = *fmt++;
|
yading@11
|
459 switch(c) {
|
yading@11
|
460 case 'H':
|
yading@11
|
461 case 'J':
|
yading@11
|
462 val = date_get_num(&p, 0, c == 'H' ? 23 : INT_MAX, 2);
|
yading@11
|
463 if (val == -1)
|
yading@11
|
464 return NULL;
|
yading@11
|
465 dt->tm_hour = val;
|
yading@11
|
466 break;
|
yading@11
|
467 case 'M':
|
yading@11
|
468 val = date_get_num(&p, 0, 59, 2);
|
yading@11
|
469 if (val == -1)
|
yading@11
|
470 return NULL;
|
yading@11
|
471 dt->tm_min = val;
|
yading@11
|
472 break;
|
yading@11
|
473 case 'S':
|
yading@11
|
474 val = date_get_num(&p, 0, 59, 2);
|
yading@11
|
475 if (val == -1)
|
yading@11
|
476 return NULL;
|
yading@11
|
477 dt->tm_sec = val;
|
yading@11
|
478 break;
|
yading@11
|
479 case 'Y':
|
yading@11
|
480 val = date_get_num(&p, 0, 9999, 4);
|
yading@11
|
481 if (val == -1)
|
yading@11
|
482 return NULL;
|
yading@11
|
483 dt->tm_year = val - 1900;
|
yading@11
|
484 break;
|
yading@11
|
485 case 'm':
|
yading@11
|
486 val = date_get_num(&p, 1, 12, 2);
|
yading@11
|
487 if (val == -1)
|
yading@11
|
488 return NULL;
|
yading@11
|
489 dt->tm_mon = val - 1;
|
yading@11
|
490 break;
|
yading@11
|
491 case 'd':
|
yading@11
|
492 val = date_get_num(&p, 1, 31, 2);
|
yading@11
|
493 if (val == -1)
|
yading@11
|
494 return NULL;
|
yading@11
|
495 dt->tm_mday = val;
|
yading@11
|
496 break;
|
yading@11
|
497 case '%':
|
yading@11
|
498 goto match;
|
yading@11
|
499 default:
|
yading@11
|
500 return NULL;
|
yading@11
|
501 }
|
yading@11
|
502 } else {
|
yading@11
|
503 match:
|
yading@11
|
504 if (c != *p)
|
yading@11
|
505 return NULL;
|
yading@11
|
506 p++;
|
yading@11
|
507 }
|
yading@11
|
508 }
|
yading@11
|
509 }
|
yading@11
|
510
|
yading@11
|
511 time_t av_timegm(struct tm *tm)
|
yading@11
|
512 {
|
yading@11
|
513 time_t t;
|
yading@11
|
514
|
yading@11
|
515 int y = tm->tm_year + 1900, m = tm->tm_mon + 1, d = tm->tm_mday;
|
yading@11
|
516
|
yading@11
|
517 if (m < 3) {
|
yading@11
|
518 m += 12;
|
yading@11
|
519 y--;
|
yading@11
|
520 }
|
yading@11
|
521
|
yading@11
|
522 t = 86400LL *
|
yading@11
|
523 (d + (153 * m - 457) / 5 + 365 * y + y / 4 - y / 100 + y / 400 - 719469);
|
yading@11
|
524
|
yading@11
|
525 t += 3600 * tm->tm_hour + 60 * tm->tm_min + tm->tm_sec;
|
yading@11
|
526
|
yading@11
|
527 return t;
|
yading@11
|
528 }
|
yading@11
|
529
|
yading@11
|
530 int av_parse_time(int64_t *timeval, const char *timestr, int duration)
|
yading@11
|
531 {
|
yading@11
|
532 const char *p, *q;
|
yading@11
|
533 int64_t t;
|
yading@11
|
534 time_t now;
|
yading@11
|
535 struct tm dt = { 0 };
|
yading@11
|
536 int today = 0, negative = 0, microseconds = 0;
|
yading@11
|
537 int i;
|
yading@11
|
538 static const char * const date_fmt[] = {
|
yading@11
|
539 "%Y-%m-%d",
|
yading@11
|
540 "%Y%m%d",
|
yading@11
|
541 };
|
yading@11
|
542 static const char * const time_fmt[] = {
|
yading@11
|
543 "%H:%M:%S",
|
yading@11
|
544 "%H%M%S",
|
yading@11
|
545 };
|
yading@11
|
546
|
yading@11
|
547 p = timestr;
|
yading@11
|
548 q = NULL;
|
yading@11
|
549 *timeval = INT64_MIN;
|
yading@11
|
550 if (!duration) {
|
yading@11
|
551 now = time(0);
|
yading@11
|
552
|
yading@11
|
553 if (!av_strcasecmp(timestr, "now")) {
|
yading@11
|
554 *timeval = (int64_t) now * 1000000;
|
yading@11
|
555 return 0;
|
yading@11
|
556 }
|
yading@11
|
557
|
yading@11
|
558 /* parse the year-month-day part */
|
yading@11
|
559 for (i = 0; i < FF_ARRAY_ELEMS(date_fmt); i++) {
|
yading@11
|
560 q = av_small_strptime(p, date_fmt[i], &dt);
|
yading@11
|
561 if (q)
|
yading@11
|
562 break;
|
yading@11
|
563 }
|
yading@11
|
564
|
yading@11
|
565 /* if the year-month-day part is missing, then take the
|
yading@11
|
566 * current year-month-day time */
|
yading@11
|
567 if (!q) {
|
yading@11
|
568 today = 1;
|
yading@11
|
569 q = p;
|
yading@11
|
570 }
|
yading@11
|
571 p = q;
|
yading@11
|
572
|
yading@11
|
573 if (*p == 'T' || *p == 't' || *p == ' ')
|
yading@11
|
574 p++;
|
yading@11
|
575
|
yading@11
|
576 /* parse the hour-minute-second part */
|
yading@11
|
577 for (i = 0; i < FF_ARRAY_ELEMS(time_fmt); i++) {
|
yading@11
|
578 q = av_small_strptime(p, time_fmt[i], &dt);
|
yading@11
|
579 if (q)
|
yading@11
|
580 break;
|
yading@11
|
581 }
|
yading@11
|
582 } else {
|
yading@11
|
583 /* parse timestr as a duration */
|
yading@11
|
584 if (p[0] == '-') {
|
yading@11
|
585 negative = 1;
|
yading@11
|
586 ++p;
|
yading@11
|
587 }
|
yading@11
|
588 /* parse timestr as HH:MM:SS */
|
yading@11
|
589 q = av_small_strptime(p, "%J:%M:%S", &dt);
|
yading@11
|
590 if (!q) {
|
yading@11
|
591 /* parse timestr as MM:SS */
|
yading@11
|
592 q = av_small_strptime(p, "%M:%S", &dt);
|
yading@11
|
593 dt.tm_hour = 0;
|
yading@11
|
594 }
|
yading@11
|
595 if (!q) {
|
yading@11
|
596 /* parse timestr as S+ */
|
yading@11
|
597 dt.tm_sec = strtol(p, (void *)&q, 10);
|
yading@11
|
598 if (q == p) /* the parsing didn't succeed */
|
yading@11
|
599 return AVERROR(EINVAL);
|
yading@11
|
600 dt.tm_min = 0;
|
yading@11
|
601 dt.tm_hour = 0;
|
yading@11
|
602 }
|
yading@11
|
603 }
|
yading@11
|
604
|
yading@11
|
605 /* Now we have all the fields that we can get */
|
yading@11
|
606 if (!q)
|
yading@11
|
607 return AVERROR(EINVAL);
|
yading@11
|
608
|
yading@11
|
609 /* parse the .m... part */
|
yading@11
|
610 if (*q == '.') {
|
yading@11
|
611 int n;
|
yading@11
|
612 q++;
|
yading@11
|
613 for (n = 100000; n >= 1; n /= 10, q++) {
|
yading@11
|
614 if (!av_isdigit(*q))
|
yading@11
|
615 break;
|
yading@11
|
616 microseconds += n * (*q - '0');
|
yading@11
|
617 }
|
yading@11
|
618 while (av_isdigit(*q))
|
yading@11
|
619 q++;
|
yading@11
|
620 }
|
yading@11
|
621
|
yading@11
|
622 if (duration) {
|
yading@11
|
623 t = dt.tm_hour * 3600 + dt.tm_min * 60 + dt.tm_sec;
|
yading@11
|
624 } else {
|
yading@11
|
625 int is_utc = *q == 'Z' || *q == 'z';
|
yading@11
|
626 q += is_utc;
|
yading@11
|
627 if (today) { /* fill in today's date */
|
yading@11
|
628 struct tm dt2 = is_utc ? *gmtime(&now) : *localtime(&now);
|
yading@11
|
629 dt2.tm_hour = dt.tm_hour;
|
yading@11
|
630 dt2.tm_min = dt.tm_min;
|
yading@11
|
631 dt2.tm_sec = dt.tm_sec;
|
yading@11
|
632 dt = dt2;
|
yading@11
|
633 }
|
yading@11
|
634 t = is_utc ? av_timegm(&dt) : mktime(&dt);
|
yading@11
|
635 }
|
yading@11
|
636
|
yading@11
|
637 /* Check that we are at the end of the string */
|
yading@11
|
638 if (*q)
|
yading@11
|
639 return AVERROR(EINVAL);
|
yading@11
|
640
|
yading@11
|
641 t *= 1000000;
|
yading@11
|
642 t += microseconds;
|
yading@11
|
643 *timeval = negative ? -t : t;
|
yading@11
|
644 return 0;
|
yading@11
|
645 }
|
yading@11
|
646
|
yading@11
|
647 int av_find_info_tag(char *arg, int arg_size, const char *tag1, const char *info)
|
yading@11
|
648 {
|
yading@11
|
649 const char *p;
|
yading@11
|
650 char tag[128], *q;
|
yading@11
|
651
|
yading@11
|
652 p = info;
|
yading@11
|
653 if (*p == '?')
|
yading@11
|
654 p++;
|
yading@11
|
655 for(;;) {
|
yading@11
|
656 q = tag;
|
yading@11
|
657 while (*p != '\0' && *p != '=' && *p != '&') {
|
yading@11
|
658 if ((q - tag) < sizeof(tag) - 1)
|
yading@11
|
659 *q++ = *p;
|
yading@11
|
660 p++;
|
yading@11
|
661 }
|
yading@11
|
662 *q = '\0';
|
yading@11
|
663 q = arg;
|
yading@11
|
664 if (*p == '=') {
|
yading@11
|
665 p++;
|
yading@11
|
666 while (*p != '&' && *p != '\0') {
|
yading@11
|
667 if ((q - arg) < arg_size - 1) {
|
yading@11
|
668 if (*p == '+')
|
yading@11
|
669 *q++ = ' ';
|
yading@11
|
670 else
|
yading@11
|
671 *q++ = *p;
|
yading@11
|
672 }
|
yading@11
|
673 p++;
|
yading@11
|
674 }
|
yading@11
|
675 }
|
yading@11
|
676 *q = '\0';
|
yading@11
|
677 if (!strcmp(tag, tag1))
|
yading@11
|
678 return 1;
|
yading@11
|
679 if (*p != '&')
|
yading@11
|
680 break;
|
yading@11
|
681 p++;
|
yading@11
|
682 }
|
yading@11
|
683 return 0;
|
yading@11
|
684 }
|
yading@11
|
685
|
yading@11
|
686 #ifdef TEST
|
yading@11
|
687
|
yading@11
|
688 static uint32_t randomv = MKTAG('L','A','V','U');
|
yading@11
|
689
|
yading@11
|
690 static uint32_t av_get_random_seed_deterministic(void)
|
yading@11
|
691 {
|
yading@11
|
692 return randomv = randomv * 1664525 + 1013904223;
|
yading@11
|
693 }
|
yading@11
|
694
|
yading@11
|
695 int main(void)
|
yading@11
|
696 {
|
yading@11
|
697 printf("Testing av_parse_video_rate()\n");
|
yading@11
|
698 {
|
yading@11
|
699 int i;
|
yading@11
|
700 static const char *const rates[] = {
|
yading@11
|
701 "-inf",
|
yading@11
|
702 "inf",
|
yading@11
|
703 "nan",
|
yading@11
|
704 "123/0",
|
yading@11
|
705 "-123 / 0",
|
yading@11
|
706 "",
|
yading@11
|
707 "/",
|
yading@11
|
708 " 123 / 321",
|
yading@11
|
709 "foo/foo",
|
yading@11
|
710 "foo/1",
|
yading@11
|
711 "1/foo",
|
yading@11
|
712 "0/0",
|
yading@11
|
713 "/0",
|
yading@11
|
714 "1/",
|
yading@11
|
715 "1",
|
yading@11
|
716 "0",
|
yading@11
|
717 "-123/123",
|
yading@11
|
718 "-foo",
|
yading@11
|
719 "123.23",
|
yading@11
|
720 ".23",
|
yading@11
|
721 "-.23",
|
yading@11
|
722 "-0.234",
|
yading@11
|
723 "-0.0000001",
|
yading@11
|
724 " 21332.2324 ",
|
yading@11
|
725 " -21332.2324 ",
|
yading@11
|
726 };
|
yading@11
|
727
|
yading@11
|
728 for (i = 0; i < FF_ARRAY_ELEMS(rates); i++) {
|
yading@11
|
729 int ret;
|
yading@11
|
730 AVRational q = { 0, 0 };
|
yading@11
|
731 ret = av_parse_video_rate(&q, rates[i]);
|
yading@11
|
732 printf("'%s' -> %d/%d %s\n",
|
yading@11
|
733 rates[i], q.num, q.den, ret ? "ERROR" : "OK");
|
yading@11
|
734 }
|
yading@11
|
735 }
|
yading@11
|
736
|
yading@11
|
737 printf("\nTesting av_parse_color()\n");
|
yading@11
|
738 {
|
yading@11
|
739 int i;
|
yading@11
|
740 uint8_t rgba[4];
|
yading@11
|
741 static const char *const color_names[] = {
|
yading@11
|
742 "bikeshed",
|
yading@11
|
743 "RaNdOm",
|
yading@11
|
744 "foo",
|
yading@11
|
745 "red",
|
yading@11
|
746 "Red ",
|
yading@11
|
747 "RED",
|
yading@11
|
748 "Violet",
|
yading@11
|
749 "Yellow",
|
yading@11
|
750 "Red",
|
yading@11
|
751 "0x000000",
|
yading@11
|
752 "0x0000000",
|
yading@11
|
753 "0xff000000",
|
yading@11
|
754 "0x3e34ff",
|
yading@11
|
755 "0x3e34ffaa",
|
yading@11
|
756 "0xffXXee",
|
yading@11
|
757 "0xfoobar",
|
yading@11
|
758 "0xffffeeeeeeee",
|
yading@11
|
759 "#ff0000",
|
yading@11
|
760 "#ffXX00",
|
yading@11
|
761 "ff0000",
|
yading@11
|
762 "ffXX00",
|
yading@11
|
763 "red@foo",
|
yading@11
|
764 "random@10",
|
yading@11
|
765 "0xff0000@1.0",
|
yading@11
|
766 "red@",
|
yading@11
|
767 "red@0xfff",
|
yading@11
|
768 "red@0xf",
|
yading@11
|
769 "red@2",
|
yading@11
|
770 "red@0.1",
|
yading@11
|
771 "red@-1",
|
yading@11
|
772 "red@0.5",
|
yading@11
|
773 "red@1.0",
|
yading@11
|
774 "red@256",
|
yading@11
|
775 "red@10foo",
|
yading@11
|
776 "red@-1.0",
|
yading@11
|
777 "red@-0.0",
|
yading@11
|
778 };
|
yading@11
|
779
|
yading@11
|
780 av_log_set_level(AV_LOG_DEBUG);
|
yading@11
|
781
|
yading@11
|
782 for (i = 0; i < FF_ARRAY_ELEMS(color_names); i++) {
|
yading@11
|
783 if (av_parse_color(rgba, color_names[i], -1, NULL) >= 0)
|
yading@11
|
784 printf("%s -> R(%d) G(%d) B(%d) A(%d)\n",
|
yading@11
|
785 color_names[i], rgba[0], rgba[1], rgba[2], rgba[3]);
|
yading@11
|
786 else
|
yading@11
|
787 printf("%s -> error\n", color_names[i]);
|
yading@11
|
788 }
|
yading@11
|
789 }
|
yading@11
|
790
|
yading@11
|
791 printf("\nTesting av_small_strptime()\n");
|
yading@11
|
792 {
|
yading@11
|
793 int i;
|
yading@11
|
794 struct tm tm = { 0 };
|
yading@11
|
795 struct fmt_timespec_entry {
|
yading@11
|
796 const char *fmt, *timespec;
|
yading@11
|
797 } fmt_timespec_entries[] = {
|
yading@11
|
798 { "%Y-%m-%d", "2012-12-21" },
|
yading@11
|
799 { "%Y - %m - %d", "2012-12-21" },
|
yading@11
|
800 { "%Y-%m-%d %H:%M:%S", "2012-12-21 20:12:21" },
|
yading@11
|
801 { " %Y - %m - %d %H : %M : %S", " 2012 - 12 - 21 20 : 12 : 21" },
|
yading@11
|
802 };
|
yading@11
|
803
|
yading@11
|
804 av_log_set_level(AV_LOG_DEBUG);
|
yading@11
|
805 for (i = 0; i < FF_ARRAY_ELEMS(fmt_timespec_entries); i++) {
|
yading@11
|
806 char *p;
|
yading@11
|
807 struct fmt_timespec_entry *e = &fmt_timespec_entries[i];
|
yading@11
|
808 printf("fmt:'%s' spec:'%s' -> ", e->fmt, e->timespec);
|
yading@11
|
809 p = av_small_strptime(e->timespec, e->fmt, &tm);
|
yading@11
|
810 if (p) {
|
yading@11
|
811 printf("%04d-%02d-%2d %02d:%02d:%02d\n",
|
yading@11
|
812 1900+tm.tm_year, tm.tm_mon+1, tm.tm_mday,
|
yading@11
|
813 tm.tm_hour, tm.tm_min, tm.tm_sec);
|
yading@11
|
814 } else {
|
yading@11
|
815 printf("error\n");
|
yading@11
|
816 }
|
yading@11
|
817 }
|
yading@11
|
818 }
|
yading@11
|
819
|
yading@11
|
820 printf("\nTesting av_parse_time()\n");
|
yading@11
|
821 {
|
yading@11
|
822 int i;
|
yading@11
|
823 int64_t tv;
|
yading@11
|
824 time_t tvi;
|
yading@11
|
825 struct tm *tm;
|
yading@11
|
826 static char tzstr[] = "TZ=CET-1";
|
yading@11
|
827 const char *time_string[] = {
|
yading@11
|
828 "now",
|
yading@11
|
829 "12:35:46",
|
yading@11
|
830 "2000-12-20 0:02:47.5z",
|
yading@11
|
831 "2000-12-20T010247.6",
|
yading@11
|
832 };
|
yading@11
|
833 const char *duration_string[] = {
|
yading@11
|
834 "2:34:56.79",
|
yading@11
|
835 "-1:23:45.67",
|
yading@11
|
836 "42.1729",
|
yading@11
|
837 "-1729.42",
|
yading@11
|
838 "12:34",
|
yading@11
|
839 };
|
yading@11
|
840
|
yading@11
|
841 av_log_set_level(AV_LOG_DEBUG);
|
yading@11
|
842 putenv(tzstr);
|
yading@11
|
843 printf("(now is 2012-03-17 09:14:13 +0100, local time is UTC+1)\n");
|
yading@11
|
844 for (i = 0; i < FF_ARRAY_ELEMS(time_string); i++) {
|
yading@11
|
845 printf("%-24s -> ", time_string[i]);
|
yading@11
|
846 if (av_parse_time(&tv, time_string[i], 0)) {
|
yading@11
|
847 printf("error\n");
|
yading@11
|
848 } else {
|
yading@11
|
849 tvi = tv / 1000000;
|
yading@11
|
850 tm = gmtime(&tvi);
|
yading@11
|
851 printf("%14"PRIi64".%06d = %04d-%02d-%02dT%02d:%02d:%02dZ\n",
|
yading@11
|
852 tv / 1000000, (int)(tv % 1000000),
|
yading@11
|
853 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
|
yading@11
|
854 tm->tm_hour, tm->tm_min, tm->tm_sec);
|
yading@11
|
855 }
|
yading@11
|
856 }
|
yading@11
|
857 for (i = 0; i < FF_ARRAY_ELEMS(duration_string); i++) {
|
yading@11
|
858 printf("%-24s -> ", duration_string[i]);
|
yading@11
|
859 if (av_parse_time(&tv, duration_string[i], 1)) {
|
yading@11
|
860 printf("error\n");
|
yading@11
|
861 } else {
|
yading@11
|
862 printf("%+21"PRIi64"\n", tv);
|
yading@11
|
863 }
|
yading@11
|
864 }
|
yading@11
|
865 }
|
yading@11
|
866
|
yading@11
|
867 return 0;
|
yading@11
|
868 }
|
yading@11
|
869
|
yading@11
|
870 #endif /* TEST */
|