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
24
29
32
34
39
41 {
43
49
50 return 0;
51 }
52
54 {
63 int err, device_is_derived;
64
68
70
72 device_is_derived = 0;
73
76
77 if (
ctx->derive_device_type) {
79
85 }
86
89 if (err < 0) {
91 "device context: %d.\n", err);
93 }
94 device_is_derived = 1;
95 }
96
101 }
102
106 // Map between two hardware formats (including the case of
107 // undoing an existing mapping).
108
109 if (!device) {
111 "required to map to a hardware format.\n");
114 }
115
118 device,
121 if (err < 0) {
123 "frames context: %d.\n", err);
125 }
126
130 // Map between two hardware formats, but do it in reverse.
131 // Make a new hwframe context for the target type, and then
132 // overwrite the input hwframe context with a derived context
133 // mapped from that back to the source type.
136
138 if (!
ctx->hwframes_ref) {
141 }
143
148
151
153 if (err < 0) {
155 "target frames context: %d.\n", err);
157 }
158
164 if (err < 0) {
166 "derived source frames context: %d.\n", err);
168 }
169
170 // Here is the naughty bit. This overwriting changes what
171 // ff_get_video_buffer() in the previous filter returns -
172 // it will now give a frame allocated here mapped back to
173 // the format it expects. If there were any additional
174 // constraints on the output frames there then this may
175 // break nastily.
178
182 // Map from a hardware format to a software format, or
183 // undo an existing such mapping.
184
186 if (!
ctx->hwframes_ref) {
189 }
190
191 } else {
192 // Non-matching formats - not supported.
193
195 "hwmap: from %s (%s) to %s.\n",
201 }
203 // Map from a software format to a hardware format. This
204 // creates a new hwframe context like hwupload, but then
205 // returns frames mapped from that to the previous link in
206 // order to fill them without an additional copy.
207
208 if (!device) {
210 "required to create new frames with reverse "
211 "mapping.\n");
214 }
215
217
219 if (!
ctx->hwframes_ref) {
222 }
224
229
232
234 if (err < 0) {
236 "context for reverse mapping: %d.\n", err);
238 }
239
240 } else {
242 "context (a device, or frames on input).\n");
244 }
245
250 }
251
254
255 if (device_is_derived)
257 return 0;
258
260 if (device_is_derived)
263 return err;
264 }
265
267 {
272
275 int err;
276
280 "frame for software mapping.\n");
282 }
283
288 }
289
291 if (err) {
293 "software: %d.\n", err);
297 }
298
301 } else {
303 }
304 }
305
307 {
312 int err;
313
317
322 }
323
326 if (!
map->hw_frames_ctx) {
329 }
330
331 if (
ctx->reverse && !
input->hw_frames_ctx) {
332 // If we mapped backwards from hardware to software, we need
333 // to attach the hardware frame context to the input frame to
334 // make the mapping visible to av_hwframe_map().
336 if (!
input->hw_frames_ctx) {
339 }
340 }
341
343 if (err < 0) {
346 }
347
349 if (err < 0)
351
353
357
359
363 return err;
364 }
365
367 {
369
371 }
372
373 #define OFFSET(x) offsetof(HWMapContext, x)
374 #define FLAGS (AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM)
376 { "mode", "Frame mapping mode",
379 0, INT_MAX,
FLAGS, .unit =
"mode" },
380
381 { "read", "Mapping should be readable",
383 INT_MIN, INT_MAX,
FLAGS, .unit =
"mode" },
384 { "write", "Mapping should be writeable",
386 INT_MIN, INT_MAX,
FLAGS, .unit =
"mode" },
387 { "overwrite", "Mapping will always overwrite the entire frame",
389 INT_MIN, INT_MAX,
FLAGS, .unit =
"mode" },
390 { "direct", "Mapping should not involve any copying",
392 INT_MIN, INT_MAX,
FLAGS, .unit =
"mode" },
393
394 { "derive_device", "Derive a new device of this type",
397 { "reverse", "Map in reverse (create and allocate in the sink)",
399 { .i64 = 0 }, 0, 1,
FLAGS },
400
402 };
403
405
407 {
412 },
413 };
414
416 {
420 },
421 };
422
428 .priv_class = &hwmap_class,
434 };