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
43 {
45
51
52 return 0;
53 }
54
56 {
65 int err, device_is_derived;
66
70
72
74 device_is_derived = 0;
75
78
79 if (
ctx->derive_device_type) {
81
87 }
88
91 if (err < 0) {
93 "device context: %d.\n", err);
95 }
96 device_is_derived = 1;
97 }
98
103 }
104
108 // Map between two hardware formats (including the case of
109 // undoing an existing mapping).
110
111 if (!device) {
113 "required to map to a hardware format.\n");
116 }
117
120 device,
123 if (err < 0) {
125 "frames context: %d.\n", err);
127 }
128
132 // Map between two hardware formats, but do it in reverse.
133 // Make a new hwframe context for the target type, and then
134 // overwrite the input hwframe context with a derived context
135 // mapped from that back to the source type.
138
140 if (!
ctx->hwframes_ref) {
143 }
145
150
153
155 if (err < 0) {
157 "target frames context: %d.\n", err);
159 }
160
166 if (err < 0) {
168 "derived source frames context: %d.\n", err);
170 }
171
172 // Here is the naughty bit. This overwriting changes what
173 // ff_get_video_buffer() in the previous filter returns -
174 // it will now give a frame allocated here mapped back to
175 // the format it expects. If there were any additional
176 // constraints on the output frames there then this may
177 // break nastily.
180
184 // Map from a hardware format to a software format, or
185 // undo an existing such mapping.
186
188 if (!
ctx->hwframes_ref) {
191 }
192
193 } else {
194 // Non-matching formats - not supported.
195
197 "hwmap: from %s (%s) to %s.\n",
203 }
205 // Map from a software format to a hardware format. This
206 // creates a new hwframe context like hwupload, but then
207 // returns frames mapped from that to the previous link in
208 // order to fill them without an additional copy.
209
210 if (!device) {
212 "required to create new frames with reverse "
213 "mapping.\n");
216 }
217
219
221 if (!
ctx->hwframes_ref) {
224 }
226
231
234
236 if (err < 0) {
238 "context for reverse mapping: %d.\n", err);
240 }
241
242 } else {
244 "context (a device, or frames on input).\n");
246 }
247
252 }
253
256
257 if (device_is_derived)
259 return 0;
260
262 if (device_is_derived)
265 return err;
266 }
267
269 {
274
277 int err;
278
282 "frame for software mapping.\n");
284 }
285
290 }
291
293 if (err) {
295 "software: %d.\n", err);
299 }
300
303 } else {
305 }
306 }
307
309 {
314 int err;
315
319
324 }
325
328 if (!
map->hw_frames_ctx) {
331 }
332
333 if (
ctx->reverse && !
input->hw_frames_ctx) {
334 // If we mapped backwards from hardware to software, we need
335 // to attach the hardware frame context to the input frame to
336 // make the mapping visible to av_hwframe_map().
338 if (!
input->hw_frames_ctx) {
341 }
342 }
343
345 if (err < 0) {
348 }
349
351 if (err < 0)
353
355
359
361
365 return err;
366 }
367
369 {
371
373 }
374
375 #define OFFSET(x) offsetof(HWMapContext, x)
376 #define FLAGS (AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM)
378 { "mode", "Frame mapping mode",
381 0, INT_MAX,
FLAGS, .unit =
"mode" },
382
383 { "read", "Mapping should be readable",
385 INT_MIN, INT_MAX,
FLAGS, .unit =
"mode" },
386 { "write", "Mapping should be writeable",
388 INT_MIN, INT_MAX,
FLAGS, .unit =
"mode" },
389 { "overwrite", "Mapping will always overwrite the entire frame",
391 INT_MIN, INT_MAX,
FLAGS, .unit =
"mode" },
392 { "direct", "Mapping should not involve any copying",
394 INT_MIN, INT_MAX,
FLAGS, .unit =
"mode" },
395
396 { "derive_device", "Derive a new device of this type",
399 { "reverse", "Map in reverse (create and allocate in the sink)",
401 { .i64 = 0 }, 0, 1,
FLAGS },
402
404 };
405
407
409 {
414 },
415 };
416
418 {
422 },
423 };
424
428 .p.priv_class = &hwmap_class,
436 };