1 /*
2 * This file is part of FFmpeg.
3 *
4 * FFmpeg 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 * FFmpeg 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 GNU
12 * 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 FFmpeg; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19 #include <string.h>
20
22
24
27
29 {
34 if (found)
37 }
38 }
39 return found;
40 }
41
43 {
48 }
50 }
51
53 {
54 int err;
57 if (err) {
60 }
65 }
66
68 {
69 // Make an automatic name of the form "type%d". We arbitrarily
70 // limit at 1000 anonymous devices of the same type - there is
71 // probably something else very wrong if you get to this limit.
74 size_t index_pos;
75 int index, index_limit = 1000;
76 index_pos = strlen(type_name);
83 break;
84 }
85 if (
index >= index_limit) {
88 }
90 }
91
93 {
94 // "type=name"
95 // "type=name,key=value,key2=value2"
96 // "type=name:device,key=value,key2=value2"
97 // "type:device,key=value,key2=value2"
98 // -> av_hwdevice_ctx_create()
99 // "type=name@name"
100 // "type@name"
101 // -> av_hwdevice_ctx_create_derived()
102
108 int err;
109 const char *errmsg, *p, *q;
110 size_t k;
111
112 k = strcspn(
arg,
":=@");
114
116 if (!type_name) {
119 }
122 errmsg = "unknown device type";
123 goto invalid;
124 }
125
126 if (*p == '=') {
127 k = strcspn(p + 1, ":@,");
128
133 }
135 errmsg = "named device already exists";
136 goto invalid;
137 }
138
139 p += 1 + k;
140 } else {
145 }
146 }
147
148 if (!*p) {
149 // New device with no parameters.
152 if (err < 0)
154
155 } else if (*p == ':') {
156 // New device with some parameters.
157 ++p;
158 q = strchr(p, ',');
159 if (q) {
160 if (q - p > 0) {
162 if (!device) {
165 }
166 }
168 if (err < 0) {
169 errmsg = "failed to parse options";
170 goto invalid;
171 }
172 }
173
175 q ? device : p[0] ? p :
NULL,
177 if (err < 0)
179
180 } else if (*p == '@') {
181 // Derive from existing device.
182
185 errmsg = "invalid source device name";
186 goto invalid;
187 }
188
191 if (err < 0)
193 } else if (*p == ',') {
195
196 if (err < 0) {
197 errmsg = "failed to parse options";
198 goto invalid;
199 }
200
203 if (err < 0)
205 } else {
206 errmsg = "parse error";
207 goto invalid;
208 }
209
211 if (!dev) {
214 }
215
219
220 if (dev_out)
221 *dev_out = dev;
222
224 err = 0;
225 done:
230 return err;
231 invalid:
233 "Invalid device specification \"%s\": %s\n",
arg, errmsg);
235 goto done;
238 "Device creation failed: %d.\n", err);
240 goto done;
241 }
242
244 const char *device,
246 {
250 int err;
251
256 }
257
259 if (err < 0) {
261 "Device creation failed: %d.\n", err);
263 }
264
266 if (!dev) {
269 }
270
274
275 if (dev_out)
276 *dev_out = dev;
277
278 return 0;
279
283 return err;
284 }
285
287 {
293 }
296 }
297
299 {
300 // Pick the last hardware device if the user doesn't pick the device for
301 // filters explicitly with the filter_hw_device option.
306
309 "%s of type %s is picked for filters by default. Set hardware "
310 "device explicitly with the filter_hw_device option if device "
311 "%s is not usable for filters.\n",
314
316 }
317
319 }