FFmpeg
Loading...
Searching...
No Matches
dnn_io_proc.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2020
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg 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 GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21#include "dnn_io_proc.h"
22#include "libavutil/imgutils.h"
23#include "libavutil/mem.h"
24#include "libswscale/swscale.h"
25#include "libavutil/avassert.h"
27
29{
30 switch (dt)
31 {
32 case DNN_FLOAT:
33 return sizeof(float);
34 case DNN_UINT8:
35 return sizeof(uint8_t);
36 default:
37 av_assert0(!"not supported yet.");
38 return 1;
39 }
40}
41
42int ff_proc_from_dnn_to_frame(AVFrame *frame, DNNData *output, void *log_ctx)
43{
44 struct SwsContext *sws_ctx;
45 int ret = 0;
46 int linesize[4] = { 0 };
47 void **dst_data = NULL;
48 void *middle_data = NULL;
49 void *dst_data_buf[4] = { NULL, NULL, NULL, NULL };
50 uint8_t *planar_data[4] = { 0 };
51 int plane_size = frame->width * frame->height * sizeof(uint8_t);
52 enum AVPixelFormat src_fmt = AV_PIX_FMT_NONE;
53 int src_datatype_size = get_datatype_size(output->dt);
54 int channel_idx;
55
56 int bytewidth = av_image_get_linesize(frame->format, frame->width, 0);
57 if (bytewidth < 0) {
58 return AVERROR(EINVAL);
59 }
60 /* scale == 1 and mean == 0 and dt == UINT8: passthrough */
61 if (fabsf(output->scale - 1) < 1e-6f && fabsf(output->mean) < 1e-6 && output->dt == DNN_UINT8)
62 src_fmt = AV_PIX_FMT_GRAY8;
63 /* (scale == 255 or scale == 0) and mean == 0 and dt == FLOAT: normalization */
64 else if ((fabsf(output->scale - 255) < 1e-6f || fabsf(output->scale) < 1e-6f) &&
65 fabsf(output->mean) < 1e-6 && output->dt == DNN_FLOAT)
66 src_fmt = AV_PIX_FMT_GRAYF32;
67 else {
68 av_log(log_ctx, AV_LOG_ERROR, "dnn_process output data doesn't type: UINT8 "
69 "scale: %f, mean: %f\n", output->scale, output->mean);
70 return AVERROR(ENOSYS);
71 }
72
73 dst_data = (void **)frame->data;
74 linesize[0] = frame->linesize[0];
75 if (output->layout == DL_NCHW) {
76 middle_data = av_malloc(plane_size * output->dims[1]);
77 if (!middle_data) {
78 ret = AVERROR(ENOMEM);
79 goto err;
80 }
81 dst_data_buf[0] = middle_data;
82 dst_data = dst_data_buf;
83 linesize[0] = frame->width * 3;
84 }
85
86 switch (frame->format) {
89 channel_idx = dnn_get_channel_idx_by_layout(output->layout);
90 if (output->dims[channel_idx] != 3) {
91 av_log(log_ctx, AV_LOG_ERROR,
92 "dnn_processing to a %s frame requires a 3-channel model "
93 "output, got %d channels; channel-reducing/expanding "
94 "models (e.g. single-channel matte output) are not "
95 "supported by this filter\n",
96 av_get_pix_fmt_name(frame->format), output->dims[channel_idx]);
97 ret = AVERROR(ENOSYS);
98 goto err;
99 }
100 sws_ctx = sws_getContext(frame->width * 3,
101 frame->height,
102 src_fmt,
103 frame->width * 3,
104 frame->height,
106 0, NULL, NULL, NULL);
107 if (!sws_ctx) {
108 av_log(log_ctx, AV_LOG_ERROR, "Impossible to create scale context for the conversion "
109 "fmt:%s s:%dx%d -> fmt:%s s:%dx%d\n",
110 av_get_pix_fmt_name(src_fmt), frame->width * 3, frame->height,
111 av_get_pix_fmt_name(AV_PIX_FMT_GRAY8), frame->width * 3, frame->height);
112 ret = AVERROR(EINVAL);
113 goto err;
114 }
115 sws_scale(sws_ctx, (const uint8_t *[4]){(const uint8_t *)output->data, 0, 0, 0},
116 (const int[4]){frame->width * 3 * src_datatype_size, 0, 0, 0}, 0, frame->height,
117 (uint8_t * const*)dst_data, linesize);
118 sws_freeContext(sws_ctx);
119 // convert data from planar to packed
120 if (output->layout == DL_NCHW) {
121 sws_ctx = sws_getContext(frame->width,
122 frame->height,
124 frame->width,
125 frame->height,
126 frame->format,
127 0, NULL, NULL, NULL);
128 if (!sws_ctx) {
129 av_log(log_ctx, AV_LOG_ERROR, "Impossible to create scale context for the conversion "
130 "fmt:%s s:%dx%d -> fmt:%s s:%dx%d\n",
132 av_get_pix_fmt_name(frame->format),frame->width, frame->height);
133 ret = AVERROR(EINVAL);
134 goto err;
135 }
136 if (frame->format == AV_PIX_FMT_RGB24) {
137 planar_data[0] = (uint8_t *)middle_data + plane_size;
138 planar_data[1] = (uint8_t *)middle_data + plane_size * 2;
139 planar_data[2] = (uint8_t *)middle_data;
140 } else if (frame->format == AV_PIX_FMT_BGR24) {
141 planar_data[0] = (uint8_t *)middle_data + plane_size;
142 planar_data[1] = (uint8_t *)middle_data;
143 planar_data[2] = (uint8_t *)middle_data + plane_size * 2;
144 }
145 sws_scale(sws_ctx, (const uint8_t * const *)planar_data,
146 (const int [4]){frame->width * sizeof(uint8_t),
147 frame->width * sizeof(uint8_t),
148 frame->width * sizeof(uint8_t), 0},
149 0, frame->height, frame->data, frame->linesize);
150 sws_freeContext(sws_ctx);
151 }
152 break;
154 av_image_copy_plane(frame->data[0], frame->linesize[0],
155 output->data, bytewidth,
156 bytewidth, frame->height);
157 break;
163 case AV_PIX_FMT_GRAY8:
164 case AV_PIX_FMT_NV12:
165 sws_ctx = sws_getContext(frame->width,
166 frame->height,
168 frame->width,
169 frame->height,
171 0, NULL, NULL, NULL);
172 if (!sws_ctx) {
173 av_log(log_ctx, AV_LOG_ERROR, "Impossible to create scale context for the conversion "
174 "fmt:%s s:%dx%d -> fmt:%s s:%dx%d\n",
175 av_get_pix_fmt_name(src_fmt), frame->width, frame->height,
177 ret = AVERROR(EINVAL);
178 goto err;
179 }
180 sws_scale(sws_ctx, (const uint8_t *[4]){(const uint8_t *)output->data, 0, 0, 0},
181 (const int[4]){frame->width * src_datatype_size, 0, 0, 0}, 0, frame->height,
182 (uint8_t * const*)frame->data, frame->linesize);
183 sws_freeContext(sws_ctx);
184 break;
185 default:
187 ret = AVERROR(ENOSYS);
188 goto err;
189 }
190
191err:
192 av_free(middle_data);
193 return ret;
194}
195
196int ff_proc_from_frame_to_dnn(AVFrame *frame, DNNData *input, void *log_ctx)
197{
198 struct SwsContext *sws_ctx;
199 int ret = 0;
200 int linesize[4] = { 0 };
201 void **src_data = NULL;
202 void *middle_data = NULL;
203 void *src_data_buf[4] = { NULL, NULL, NULL, NULL };
204 uint8_t *planar_data[4] = { 0 };
205 int plane_size = frame->width * frame->height * sizeof(uint8_t);
206 enum AVPixelFormat dst_fmt = AV_PIX_FMT_NONE;
207 int dst_datatype_size = get_datatype_size(input->dt);
208 int bytewidth = av_image_get_linesize(frame->format, frame->width, 0);
209 if (bytewidth < 0) {
210 return AVERROR(EINVAL);
211 }
212 /* scale == 1 and mean == 0 and dt == UINT8: passthrough */
213 if (fabsf(input->scale - 1) < 1e-6f && fabsf(input->mean) < 1e-6 && input->dt == DNN_UINT8)
214 dst_fmt = AV_PIX_FMT_GRAY8;
215 /* (scale == 255 or scale == 0) and mean == 0 and dt == FLOAT: normalization */
216 else if ((fabsf(input->scale - 255) < 1e-6f || fabsf(input->scale) < 1e-6f) &&
217 fabsf(input->mean) < 1e-6 && input->dt == DNN_FLOAT)
218 dst_fmt = AV_PIX_FMT_GRAYF32;
219 else {
220 av_log(log_ctx, AV_LOG_ERROR, "dnn_process input data doesn't support type: UINT8 "
221 "scale: %f, mean: %f\n", input->scale, input->mean);
222 return AVERROR(ENOSYS);
223 }
224
225 src_data = (void **)frame->data;
226 linesize[0] = frame->linesize[0];
227 if (input->layout == DL_NCHW) {
228 middle_data = av_malloc(plane_size * input->dims[1]);
229 if (!middle_data) {
230 ret = AVERROR(ENOMEM);
231 goto err;
232 }
233 src_data_buf[0] = middle_data;
234 src_data = src_data_buf;
235 linesize[0] = frame->width * 3;
236 }
237
238 switch (frame->format) {
239 case AV_PIX_FMT_RGB24:
240 case AV_PIX_FMT_BGR24:
241 // convert data from planar to packed
242 if (input->layout == DL_NCHW) {
243 sws_ctx = sws_getContext(frame->width,
244 frame->height,
245 frame->format,
246 frame->width,
247 frame->height,
249 0, NULL, NULL, NULL);
250 if (!sws_ctx) {
251 av_log(log_ctx, AV_LOG_ERROR, "Impossible to create scale context for the conversion "
252 "fmt:%s s:%dx%d -> fmt:%s s:%dx%d\n",
253 av_get_pix_fmt_name(frame->format), frame->width, frame->height,
255 ret = AVERROR(EINVAL);
256 goto err;
257 }
258 if (frame->format == AV_PIX_FMT_RGB24) {
259 planar_data[0] = (uint8_t *)middle_data + plane_size;
260 planar_data[1] = (uint8_t *)middle_data + plane_size * 2;
261 planar_data[2] = (uint8_t *)middle_data;
262 } else if (frame->format == AV_PIX_FMT_BGR24) {
263 planar_data[0] = (uint8_t *)middle_data + plane_size;
264 planar_data[1] = (uint8_t *)middle_data;
265 planar_data[2] = (uint8_t *)middle_data + plane_size * 2;
266 }
267 sws_scale(sws_ctx, (const uint8_t * const *)frame->data,
268 frame->linesize, 0, frame->height, planar_data,
269 (const int [4]){frame->width * sizeof(uint8_t),
270 frame->width * sizeof(uint8_t),
271 frame->width * sizeof(uint8_t), 0});
272 sws_freeContext(sws_ctx);
273 }
274 sws_ctx = sws_getContext(frame->width * 3,
275 frame->height,
277 frame->width * 3,
278 frame->height,
279 dst_fmt,
280 0, NULL, NULL, NULL);
281 if (!sws_ctx) {
282 av_log(log_ctx, AV_LOG_ERROR, "Impossible to create scale context for the conversion "
283 "fmt:%s s:%dx%d -> fmt:%s s:%dx%d\n",
284 av_get_pix_fmt_name(AV_PIX_FMT_GRAY8), frame->width * 3, frame->height,
285 av_get_pix_fmt_name(dst_fmt),frame->width * 3, frame->height);
286 ret = AVERROR(EINVAL);
287 goto err;
288 }
289 sws_scale(sws_ctx, (const uint8_t **)src_data,
290 linesize, 0, frame->height,
291 (uint8_t * const [4]){input->data, 0, 0, 0},
292 (const int [4]){frame->width * 3 * dst_datatype_size, 0, 0, 0});
293 sws_freeContext(sws_ctx);
294 break;
296 av_image_copy_plane(input->data, bytewidth,
297 frame->data[0], frame->linesize[0],
298 bytewidth, frame->height);
299 break;
305 case AV_PIX_FMT_GRAY8:
306 case AV_PIX_FMT_NV12:
307 sws_ctx = sws_getContext(frame->width,
308 frame->height,
310 frame->width,
311 frame->height,
312 dst_fmt,
313 0, NULL, NULL, NULL);
314 if (!sws_ctx) {
315 av_log(log_ctx, AV_LOG_ERROR, "Impossible to create scale context for the conversion "
316 "fmt:%s s:%dx%d -> fmt:%s s:%dx%d\n",
318 av_get_pix_fmt_name(dst_fmt),frame->width, frame->height);
319 ret = AVERROR(EINVAL);
320 goto err;
321 }
322 sws_scale(sws_ctx, (const uint8_t **)frame->data,
323 frame->linesize, 0, frame->height,
324 (uint8_t * const [4]){input->data, 0, 0, 0},
325 (const int [4]){frame->width * dst_datatype_size, 0, 0, 0});
326 sws_freeContext(sws_ctx);
327 break;
328 default:
330 ret = AVERROR(ENOSYS);
331 goto err;
332 }
333err:
334 av_free(middle_data);
335 return ret;
336}
337
339{
340 if (data->dt == DNN_UINT8) {
341 switch (data->order) {
342 case DCO_BGR:
343 return AV_PIX_FMT_BGR24;
344 case DCO_RGB:
345 return AV_PIX_FMT_RGB24;
346 default:
347 av_assert0(!"unsupported data pixel format.\n");
348 return AV_PIX_FMT_BGR24;
349 }
350 }
351
352 av_assert0(!"unsupported data type.\n");
353 return AV_PIX_FMT_BGR24;
354}
355
356static void detect_write_tensor(DNNData *input, const uint8_t *src,
357 int src_linesize, int w, int h);
358
359int ff_frame_to_dnn_classify(AVFrame *frame, DNNData *input, uint32_t bbox_index, void *log_ctx)
360{
362 int offsetx[4], offsety[4];
363 uint8_t *bbox_data[4];
364 struct SwsContext *sws_ctx;
365 int linesizes[4];
366 int ret = 0;
367 enum AVPixelFormat fmt;
368 int left, top, width, height;
369 int width_idx, height_idx;
371 const AVDetectionBBox *bbox;
373 int max_step[4] = { 0 };
374 av_assert0(sd);
375
376 /* (scale != 1 and scale != 0) or mean != 0 */
377 if ((fabsf(input->scale - 1) > 1e-6f && fabsf(input->scale) > 1e-6f) ||
378 fabsf(input->mean) > 1e-6f) {
379 av_log(log_ctx, AV_LOG_ERROR, "dnn_classify input data doesn't support "
380 "scale: %f, mean: %f\n", input->scale, input->mean);
381 return AVERROR(ENOSYS);
382 }
383
384 width_idx = dnn_get_width_idx_by_layout(input->layout);
385 height_idx = dnn_get_height_idx_by_layout(input->layout);
386
387 header = (const AVDetectionBBoxHeader *)sd->data;
388 bbox = av_get_detection_bbox(header, bbox_index);
389
390 left = bbox->x;
391 width = bbox->w;
392 top = bbox->y;
393 height = bbox->h;
394
395 desc = av_pix_fmt_desc_get(frame->format);
396 offsetx[1] = offsetx[2] = AV_CEIL_RSHIFT(left, desc->log2_chroma_w);
397 offsetx[0] = offsetx[3] = left;
398
399 offsety[1] = offsety[2] = AV_CEIL_RSHIFT(top, desc->log2_chroma_h);
400 offsety[0] = offsety[3] = top;
401
403 for (int k = 0; frame->data[k]; k++)
404 bbox_data[k] = frame->data[k] + offsety[k] * frame->linesize[k] + offsetx[k] * max_step[k];
405
406 if (input->layout == DL_NCHW) {
407 /*
408 * For NCHW layout, scale the bbox region into a packed RGB temp buffer,
409 * then deinterleave into the NCHW tensor using detect_write_tensor().
410 */
411 int dst_w = input->dims[width_idx];
412 int dst_h = input->dims[height_idx];
413 int tmp_linesize = dst_w * 3;
414 uint8_t *tmp_buf = av_malloc(tmp_linesize * dst_h);
415 if (!tmp_buf)
416 return AVERROR(ENOMEM);
417
418 sws_ctx = sws_getContext(width, height, frame->format,
421 if (!sws_ctx) {
422 av_log(log_ctx, AV_LOG_ERROR, "Failed to create scale context for the conversion "
423 "fmt:%s s:%dx%d -> fmt:%s s:%dx%d\n",
426 av_free(tmp_buf);
427 return AVERROR(EINVAL);
428 }
429
430 sws_scale(sws_ctx, (const uint8_t *const *)&bbox_data, frame->linesize,
431 0, height,
432 (uint8_t *const [4]){tmp_buf, 0, 0, 0},
433 (const int [4]){tmp_linesize, 0, 0, 0});
434 sws_freeContext(sws_ctx);
435
436 detect_write_tensor(input, tmp_buf, tmp_linesize, dst_w, dst_h);
437 av_free(tmp_buf);
438 } else {
439 fmt = get_pixel_format(input);
440 sws_ctx = sws_getContext(width, height, frame->format,
441 input->dims[width_idx],
442 input->dims[height_idx], fmt,
444 if (!sws_ctx) {
445 av_log(log_ctx, AV_LOG_ERROR, "Failed to create scale context for the conversion "
446 "fmt:%s s:%dx%d -> fmt:%s s:%dx%d\n",
449 input->dims[width_idx],
450 input->dims[height_idx]);
451 return AVERROR(EINVAL);
452 }
453
454 ret = av_image_fill_linesizes(linesizes, fmt, input->dims[width_idx]);
455 if (ret < 0) {
456 av_log(log_ctx, AV_LOG_ERROR, "unable to get linesizes with av_image_fill_linesizes");
457 sws_freeContext(sws_ctx);
458 return ret;
459 }
460
461 sws_scale(sws_ctx, (const uint8_t *const *)&bbox_data, frame->linesize,
462 0, height,
463 (uint8_t *const [4]){input->data, 0, 0, 0}, linesizes);
464 sws_freeContext(sws_ctx);
465 }
466
467 return ret;
468}
469
470/*
471 * Write packed 24bit RGB/BGR samples into the tensor type/layout the model expects.
472 */
473static void detect_write_tensor(DNNData *input, const uint8_t *src,
474 int src_linesize, int w, int h)
475{
476 const size_t plane_size = (size_t)w * h;
477
478 if (input->dt == DNN_FLOAT) {
479 float *dst = input->data;
480 if (input->layout == DL_NCHW) {
481 /* FLOAT + NCHW: deinterleave into planes while widening uint8 -> float. */
482 for (int c = 0; c < 3; c++)
483 for (int y = 0; y < h; y++) {
484 const uint8_t *row = src + (ptrdiff_t)y * src_linesize;
485 for (int x = 0; x < w; x++)
486 dst[c * plane_size + (size_t)y * w + x] = row[x * 3 + c];
487 }
488 } else {
489 /* FLOAT + NHWC : keep it packed, only widen uint8 -> float byte by byte. */
490 for (int y = 0; y < h; y++) {
491 const uint8_t *row = src + (ptrdiff_t)y * src_linesize;
492 for (int x = 0; x < w * 3; x++)
493 dst[(size_t)y * w * 3 + x] = row[x];
494 }
495 }
496 } else {
497 /* UINT8 + NCHW: deinterleave into 3 uint8 planes. */
498 uint8_t *dst = input->data;
499 for (int c = 0; c < 3; c++)
500 for (int y = 0; y < h; y++) {
501 const uint8_t *row = src + (ptrdiff_t)y * src_linesize;
502 for (int x = 0; x < w; x++)
503 dst[c * plane_size + (size_t)y * w + x] = row[x * 3 + c];
504 }
505 }
506}
507
508int ff_frame_to_dnn_detect(AVFrame *frame, DNNData *input, void *log_ctx)
509{
510 struct SwsContext *sws_ctx = NULL;
511 uint8_t *tmp_buf = NULL;
512 const uint8_t *src;
513 int src_linesize;
514 int linesizes[4];
515 int ret = 0, width_idx, height_idx, channel_idx;
516 int packed_u8, w, h;
517 enum AVPixelFormat fmt;
518
519 switch (input->order) {
520 case DCO_BGR: fmt = AV_PIX_FMT_BGR24; break;
521 case DCO_RGB: fmt = AV_PIX_FMT_RGB24; break;
522 default: fmt = AV_PIX_FMT_NONE; break;
523 }
524
525 /* (scale != 1 and scale != 0) or mean != 0 */
526 if ((fabsf(input->scale - 1) > 1e-6f && fabsf(input->scale) > 1e-6f) ||
527 fabsf(input->mean) > 1e-6f) {
528 av_log(log_ctx, AV_LOG_ERROR, "dnn_detect input data doesn't support "
529 "scale: %f, mean: %f\n", input->scale, input->mean);
530 return AVERROR(ENOSYS);
531 }
532
533 if (fmt == AV_PIX_FMT_NONE) {
534 av_log(log_ctx, AV_LOG_ERROR, "dnn_detect input data doesn't support "
535 "color order: %d\n", input->order);
536 return AVERROR(ENOSYS);
537 }
538
539 if (input->dt != DNN_UINT8 && input->dt != DNN_FLOAT) {
540 av_log(log_ctx, AV_LOG_ERROR, "dnn_detect input data doesn't support "
541 "data type: %d\n", input->dt);
542 return AVERROR(ENOSYS);
543 }
544
545 width_idx = dnn_get_width_idx_by_layout(input->layout);
546 height_idx = dnn_get_height_idx_by_layout(input->layout);
547 channel_idx = dnn_get_channel_idx_by_layout(input->layout);
548
549 w = input->dims[width_idx];
550 h = input->dims[height_idx];
551 if (w <= 0 || h <= 0) {
552 av_log(log_ctx, AV_LOG_ERROR, "dnn_detect input data has invalid "
553 "dimensions: %dx%d\n", w, h);
554 return AVERROR(EINVAL);
555 }
556
557 packed_u8 = (input->dt == DNN_UINT8) && (input->layout != DL_NCHW);
558 if (!packed_u8 && input->dims[channel_idx] != 3) {
559 av_log(log_ctx, AV_LOG_ERROR, "dnn_detect requires a 3-channel input, "
560 "but the model has %d channels\n",
561 input->dims[channel_idx]);
562 return AVERROR(ENOSYS);
563 }
564
565 ret = av_image_fill_linesizes(linesizes, fmt, w);
566 if (ret < 0) {
567 av_log(log_ctx, AV_LOG_ERROR, "unable to get linesizes with av_image_fill_linesizes");
568 return ret;
569 }
570
571 if (packed_u8) {
572 /* UINT8 + NHWC: sws_scale() writes straight into input->data in one pass. */
573 sws_ctx = sws_getContext(frame->width, frame->height, frame->format,
574 w, h, fmt, SWS_FAST_BILINEAR, NULL, NULL, NULL);
575 if (!sws_ctx) {
576 av_log(log_ctx, AV_LOG_ERROR, "Impossible to create scale context for the conversion "
577 "fmt:%s s:%dx%d -> fmt:%s s:%dx%d\n",
578 av_get_pix_fmt_name(frame->format), frame->width, frame->height,
579 av_get_pix_fmt_name(fmt), w, h);
580 return AVERROR(EINVAL);
581 }
582
583 sws_scale(sws_ctx, (const uint8_t *const *)frame->data, frame->linesize, 0, frame->height,
584 (uint8_t *const [4]){input->data, 0, 0, 0}, linesizes);
585 sws_freeContext(sws_ctx);
586 return 0;
587 }
588
589 if (frame->format == fmt && frame->width == w && frame->height == h) {
590 src = frame->data[0];
591 src_linesize = frame->linesize[0];
592 } else {
593 size_t tmp_size;
594
595 if (av_size_mult((size_t)linesizes[0], (size_t)h, &tmp_size) < 0) {
596 av_log(log_ctx, AV_LOG_ERROR, "dnn_detect temporary buffer size overflows\n");
597 return AVERROR(EINVAL);
598 }
599
600 tmp_buf = av_malloc(tmp_size);
601 if (!tmp_buf)
602 return AVERROR(ENOMEM);
603
604 sws_ctx = sws_getContext(frame->width, frame->height, frame->format,
605 w, h, fmt, SWS_FAST_BILINEAR, NULL, NULL, NULL);
606 if (!sws_ctx) {
607 av_log(log_ctx, AV_LOG_ERROR, "Impossible to create scale context for the conversion "
608 "fmt:%s s:%dx%d -> fmt:%s s:%dx%d\n",
609 av_get_pix_fmt_name(frame->format), frame->width, frame->height,
610 av_get_pix_fmt_name(fmt), w, h);
611 ret = AVERROR(EINVAL);
612 goto end;
613 }
614
615 sws_scale(sws_ctx, (const uint8_t *const *)frame->data, frame->linesize, 0, frame->height,
616 (uint8_t *const [4]){tmp_buf, 0, 0, 0}, linesizes);
617 sws_freeContext(sws_ctx);
618 sws_ctx = NULL;
619
620 src = tmp_buf;
621 src_linesize = linesizes[0];
622 }
623
624 detect_write_tensor(input, src, src_linesize, w, h);
625
626end:
627 av_freep(&tmp_buf);
628 return ret;
629}
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition dsp.h:97
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition avassert.h:42
static int BS_FUNC left(const BSCTX *bc)
Return the number of the bits left in a buffer.
#define AV_CEIL_RSHIFT(a, b)
Definition common.h:60
#define NULL
Definition coverity.c:32
static __device__ float fabsf(float a)
static AVFrame * frame
static av_always_inline AVDetectionBBox * av_get_detection_bbox(const AVDetectionBBoxHeader *header, unsigned int idx)
static int dnn_get_height_idx_by_layout(DNNLayout layout)
@ DL_NCHW
static int dnn_get_width_idx_by_layout(DNNLayout layout)
DNNDataType
@ DNN_UINT8
@ DNN_FLOAT
@ DCO_RGB
@ DCO_BGR
static int dnn_get_channel_idx_by_layout(DNNLayout layout)
static int get_datatype_size(DNNDataType dt)
Definition dnn_io_proc.c:28
int ff_proc_from_frame_to_dnn(AVFrame *frame, DNNData *input, void *log_ctx)
int ff_frame_to_dnn_detect(AVFrame *frame, DNNData *input, void *log_ctx)
static void detect_write_tensor(DNNData *input, const uint8_t *src, int src_linesize, int w, int h)
int ff_frame_to_dnn_classify(AVFrame *frame, DNNData *input, uint32_t bbox_index, void *log_ctx)
static enum AVPixelFormat get_pixel_format(DNNData *data)
int ff_proc_from_dnn_to_frame(AVFrame *frame, DNNData *output, void *log_ctx)
Definition dnn_io_proc.c:42
DNN input&output process between AVFrame and DNNData.
int ret
Definition ffplay.c:391
#define AVERROR(e)
Definition error.h:45
AVFrameSideData * av_frame_get_side_data(const AVFrame *frame, enum AVFrameSideDataType type)
Definition frame.c:662
@ AV_FRAME_DATA_DETECTION_BBOXES
Bounding boxes for object detection and classification, as described by AVDetectionBBoxHeader.
Definition frame.h:194
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
int av_size_mult(size_t a, size_t b, size_t *r)
Multiply two size_t values checking for overflow.
Definition mem.c:671
void av_image_copy_plane(uint8_t *dst, int dst_linesize, const uint8_t *src, int src_linesize, int bytewidth, int height)
Copy image plane from src to dst.
Definition imgutils.c:374
int av_image_get_linesize(enum AVPixelFormat pix_fmt, int width, int plane)
Compute the size of an image line with format pix_fmt and width width for the plane plane.
Definition imgutils.c:76
int av_image_fill_linesizes(int linesizes[4], enum AVPixelFormat pix_fmt, int width)
Fill plane linesizes for an image with pixel format pix_fmt and width width.
Definition imgutils.c:89
void av_image_fill_max_pixsteps(int max_pixsteps[4], int max_pixstep_comps[4], const AVPixFmtDescriptor *pixdesc)
Compute the max pixel step for each plane of an image with a format described by pixdesc.
Definition imgutils.c:35
int attribute_align_arg sws_scale(SwsContext *sws, const uint8_t *const srcSlice[], const int srcStride[], int srcSliceY, int srcSliceH, uint8_t *const dst[], const int dstStride[])
swscale wrapper, so we don't need to export the SwsContext.
Definition swscale.c:1682
SwsContext * sws_getContext(int srcW, int srcH, enum AVPixelFormat srcFormat, int dstW, int dstH, enum AVPixelFormat dstFormat, int flags, SwsFilter *srcFilter, SwsFilter *dstFilter, const double *param)
Allocate and return an SwsContext.
Definition utils.c:1989
void sws_freeContext(SwsContext *swsContext)
Free the swscaler context swsContext.
Definition utils.c:2320
@ SWS_FAST_BILINEAR
Scaler selection options.
Definition swscale.h:197
misc image utilities
void avpriv_report_missing_feature(void *avc, const char *msg,...) av_printf_format(2
Log a generic warning message about a missing feature.
const char * desc
Definition libsvtav1.c:83
uint8_t w
Definition llvidencdsp.c:39
Memory handling functions.
const char data[16]
Definition mxf.c:149
#define av_malloc(s)
Definition ops_static.c:52
const char * av_get_pix_fmt_name(enum AVPixelFormat pix_fmt)
Return the short name for a pixel format, NULL in case pix_fmt is unknown.
Definition pixdesc.c:3404
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition pixdesc.c:3484
#define AV_PIX_FMT_GRAYF32
Definition pixfmt.h:591
AVPixelFormat
Pixel format.
Definition pixfmt.h:71
@ AV_PIX_FMT_NV12
planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (firs...
Definition pixfmt.h:96
@ AV_PIX_FMT_NONE
Definition pixfmt.h:72
@ AV_PIX_FMT_RGB24
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition pixfmt.h:75
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition pixfmt.h:73
@ AV_PIX_FMT_YUV422P
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition pixfmt.h:77
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
Definition pixfmt.h:81
@ AV_PIX_FMT_YUV410P
planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y samples)
Definition pixfmt.h:79
@ AV_PIX_FMT_YUV411P
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples)
Definition pixfmt.h:80
@ AV_PIX_FMT_YUV444P
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition pixfmt.h:78
@ AV_PIX_FMT_BGR24
packed RGB 8:8:8, 24bpp, BGRBGR...
Definition pixfmt.h:76
@ AV_PIX_FMT_GBRP
planar GBR 4:4:4 24bpp
Definition pixfmt.h:165
static const uint8_t header[24]
Definition sdr2.c:68
int x
Distance in pixels from the left/top edge of the frame, together with width and height,...
Structure to hold side data for an AVFrame.
Definition frame.h:334
uint8_t * data
Definition frame.h:336
This structure describes decoded (raw) audio or video data.
Definition frame.h:479
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition pixdesc.h:69
float scale
DNNDataType dt
int dims[4]
DNNColorOrder order
void * data
DNNLayout layout
float mean
Main external API structure.
Definition swscale.h:227
int dst_h
Width and height of the destination frame.
Definition swscale.h:273
int dst_w
Definition swscale.h:273
external API header
#define av_free(p)
#define av_freep(p)
#define av_log(a,...)
#define src
Definition vp8dsp.c:248
#define height
Definition dsp.h:99
#define width
Definition dsp.h:99
static double c[64]