FFmpeg  4.4.6
vf_dnn_processing.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2019 Guo Yejun
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 /**
22  * @file
23  * implementing a generic image processing filter using deep learning networks.
24  */
25 
26 #include "libavformat/avio.h"
27 #include "libavutil/opt.h"
28 #include "libavutil/pixdesc.h"
29 #include "libavutil/avassert.h"
30 #include "libavutil/imgutils.h"
31 #include "filters.h"
32 #include "dnn_filter_common.h"
33 #include "formats.h"
34 #include "internal.h"
35 #include "libswscale/swscale.h"
36 #include "libavutil/time.h"
37 
38 typedef struct DnnProcessingContext {
39  const AVClass *class;
44 
45 #define OFFSET(x) offsetof(DnnProcessingContext, dnnctx.x)
46 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_VIDEO_PARAM
47 static const AVOption dnn_processing_options[] = {
48  { "dnn_backend", "DNN backend", OFFSET(backend_type), AV_OPT_TYPE_INT, { .i64 = 0 }, INT_MIN, INT_MAX, FLAGS, "backend" },
49  { "native", "native backend flag", 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, 0, 0, FLAGS, "backend" },
50 #if (CONFIG_LIBTENSORFLOW == 1)
51  { "tensorflow", "tensorflow backend flag", 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, 0, 0, FLAGS, "backend" },
52 #endif
53 #if (CONFIG_LIBOPENVINO == 1)
54  { "openvino", "openvino backend flag", 0, AV_OPT_TYPE_CONST, { .i64 = 2 }, 0, 0, FLAGS, "backend" },
55 #endif
57  { NULL }
58 };
59 
60 AVFILTER_DEFINE_CLASS(dnn_processing);
61 
62 static av_cold int init(AVFilterContext *context)
63 {
64  DnnProcessingContext *ctx = context->priv;
65  return ff_dnn_init(&ctx->dnnctx, DFT_PROCESS_FRAME, context);
66 }
67 
68 static int query_formats(AVFilterContext *context)
69 {
70  static const enum AVPixelFormat pix_fmts[] = {
77  };
79  return ff_set_common_formats(context, fmts_list);
80 }
81 
82 #define LOG_FORMAT_CHANNEL_MISMATCH() \
83  av_log(ctx, AV_LOG_ERROR, \
84  "the frame's format %s does not match " \
85  "the model input channel %d\n", \
86  av_get_pix_fmt_name(fmt), \
87  model_input->channels);
88 
89 static int check_modelinput_inlink(const DNNData *model_input, const AVFilterLink *inlink)
90 {
91  AVFilterContext *ctx = inlink->dst;
92  enum AVPixelFormat fmt = inlink->format;
93 
94  // the design is to add explicit scale filter before this filter
95  if (model_input->height != -1 && model_input->height != inlink->h) {
96  av_log(ctx, AV_LOG_ERROR, "the model requires frame height %d but got %d\n",
97  model_input->height, inlink->h);
98  return AVERROR(EIO);
99  }
100  if (model_input->width != -1 && model_input->width != inlink->w) {
101  av_log(ctx, AV_LOG_ERROR, "the model requires frame width %d but got %d\n",
102  model_input->width, inlink->w);
103  return AVERROR(EIO);
104  }
105  if (model_input->dt != DNN_FLOAT) {
106  avpriv_report_missing_feature(ctx, "data type rather than DNN_FLOAT");
107  return AVERROR(EIO);
108  }
109 
110  switch (fmt) {
111  case AV_PIX_FMT_RGB24:
112  case AV_PIX_FMT_BGR24:
113  if (model_input->channels != 3) {
115  return AVERROR(EIO);
116  }
117  return 0;
118  case AV_PIX_FMT_GRAYF32:
119  case AV_PIX_FMT_YUV420P:
120  case AV_PIX_FMT_YUV422P:
121  case AV_PIX_FMT_YUV444P:
122  case AV_PIX_FMT_YUV410P:
123  case AV_PIX_FMT_YUV411P:
124  case AV_PIX_FMT_NV12:
125  if (model_input->channels != 1) {
127  return AVERROR(EIO);
128  }
129  return 0;
130  default:
132  return AVERROR(EIO);
133  }
134 
135  return 0;
136 }
137 
138 static int config_input(AVFilterLink *inlink)
139 {
140  AVFilterContext *context = inlink->dst;
141  DnnProcessingContext *ctx = context->priv;
142  DNNReturnType result;
143  DNNData model_input;
144  int check;
145 
146  result = ff_dnn_get_input(&ctx->dnnctx, &model_input);
147  if (result != DNN_SUCCESS) {
148  av_log(ctx, AV_LOG_ERROR, "could not get input from the model\n");
149  return AVERROR(EIO);
150  }
151 
152  check = check_modelinput_inlink(&model_input, inlink);
153  if (check != 0) {
154  return check;
155  }
156 
157  return 0;
158 }
159 
161 {
163  av_assert0(desc);
164  return !(desc->flags & AV_PIX_FMT_FLAG_RGB) && desc->nb_components == 3;
165 }
166 
167 static int prepare_uv_scale(AVFilterLink *outlink)
168 {
169  AVFilterContext *context = outlink->src;
170  DnnProcessingContext *ctx = context->priv;
171  AVFilterLink *inlink = context->inputs[0];
172  enum AVPixelFormat fmt = inlink->format;
173 
174  if (isPlanarYUV(fmt)) {
175  if (inlink->w != outlink->w || inlink->h != outlink->h) {
176  if (fmt == AV_PIX_FMT_NV12) {
177  ctx->sws_uv_scale = sws_getContext(inlink->w >> 1, inlink->h >> 1, AV_PIX_FMT_YA8,
178  outlink->w >> 1, outlink->h >> 1, AV_PIX_FMT_YA8,
180  ctx->sws_uv_height = inlink->h >> 1;
181  } else {
183  int sws_src_h = AV_CEIL_RSHIFT(inlink->h, desc->log2_chroma_h);
184  int sws_src_w = AV_CEIL_RSHIFT(inlink->w, desc->log2_chroma_w);
185  int sws_dst_h = AV_CEIL_RSHIFT(outlink->h, desc->log2_chroma_h);
186  int sws_dst_w = AV_CEIL_RSHIFT(outlink->w, desc->log2_chroma_w);
187  ctx->sws_uv_scale = sws_getContext(sws_src_w, sws_src_h, AV_PIX_FMT_GRAY8,
188  sws_dst_w, sws_dst_h, AV_PIX_FMT_GRAY8,
190  ctx->sws_uv_height = sws_src_h;
191  }
192  }
193  }
194 
195  return 0;
196 }
197 
198 static int config_output(AVFilterLink *outlink)
199 {
200  AVFilterContext *context = outlink->src;
201  DnnProcessingContext *ctx = context->priv;
202  DNNReturnType result;
203  AVFilterLink *inlink = context->inputs[0];
204 
205  // have a try run in case that the dnn model resize the frame
206  result = ff_dnn_get_output(&ctx->dnnctx, inlink->w, inlink->h, &outlink->w, &outlink->h);
207  if (result != DNN_SUCCESS) {
208  av_log(ctx, AV_LOG_ERROR, "could not get output from the model\n");
209  return AVERROR(EIO);
210  }
211 
212  prepare_uv_scale(outlink);
213 
214  return 0;
215 }
216 
218 {
219  const AVPixFmtDescriptor *desc;
220  int uv_height;
221 
222  if (!ctx->sws_uv_scale) {
223  av_assert0(in->height == out->height && in->width == out->width);
224  desc = av_pix_fmt_desc_get(in->format);
225  uv_height = AV_CEIL_RSHIFT(in->height, desc->log2_chroma_h);
226  for (int i = 1; i < 3; ++i) {
227  int bytewidth = av_image_get_linesize(in->format, in->width, i);
228  av_image_copy_plane(out->data[i], out->linesize[i],
229  in->data[i], in->linesize[i],
230  bytewidth, uv_height);
231  }
232  } else if (in->format == AV_PIX_FMT_NV12) {
233  sws_scale(ctx->sws_uv_scale, (const uint8_t **)(in->data + 1), in->linesize + 1,
234  0, ctx->sws_uv_height, out->data + 1, out->linesize + 1);
235  } else {
236  sws_scale(ctx->sws_uv_scale, (const uint8_t **)(in->data + 1), in->linesize + 1,
237  0, ctx->sws_uv_height, out->data + 1, out->linesize + 1);
238  sws_scale(ctx->sws_uv_scale, (const uint8_t **)(in->data + 2), in->linesize + 2,
239  0, ctx->sws_uv_height, out->data + 2, out->linesize + 2);
240  }
241 
242  return 0;
243 }
244 
245 static int filter_frame(AVFilterLink *inlink, AVFrame *in)
246 {
247  AVFilterContext *context = inlink->dst;
248  AVFilterLink *outlink = context->outputs[0];
249  DnnProcessingContext *ctx = context->priv;
250  DNNReturnType dnn_result;
251  AVFrame *out;
252 
253  out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
254  if (!out) {
255  av_frame_free(&in);
256  return AVERROR(ENOMEM);
257  }
259 
260  dnn_result = ff_dnn_execute_model(&ctx->dnnctx, in, out);
261  if (dnn_result != DNN_SUCCESS){
262  av_log(ctx, AV_LOG_ERROR, "failed to execute model\n");
263  av_frame_free(&in);
264  av_frame_free(&out);
265  return AVERROR(EIO);
266  }
267 
268  if (isPlanarYUV(in->format))
270 
271  av_frame_free(&in);
272  return ff_filter_frame(outlink, out);
273 }
274 
276 {
277  AVFilterLink *inlink = filter_ctx->inputs[0];
278  AVFilterLink *outlink = filter_ctx->outputs[0];
279  AVFrame *in = NULL;
280  int64_t pts;
281  int ret, status;
282  int got_frame = 0;
283 
284  FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink);
285 
286  do {
287  // drain all input frames
288  ret = ff_inlink_consume_frame(inlink, &in);
289  if (ret < 0)
290  return ret;
291  if (ret > 0) {
292  ret = filter_frame(inlink, in);
293  if (ret < 0)
294  return ret;
295  got_frame = 1;
296  }
297  } while (ret > 0);
298 
299  // if frame got, schedule to next filter
300  if (got_frame)
301  return 0;
302 
303  if (ff_inlink_acknowledge_status(inlink, &status, &pts)) {
304  if (status == AVERROR_EOF) {
305  ff_outlink_set_status(outlink, status, pts);
306  return ret;
307  }
308  }
309 
310  FF_FILTER_FORWARD_WANTED(outlink, inlink);
311 
312  return FFERROR_NOT_READY;
313 }
314 
315 static int flush_frame(AVFilterLink *outlink, int64_t pts, int64_t *out_pts)
316 {
317  DnnProcessingContext *ctx = outlink->src->priv;
318  int ret;
319  DNNAsyncStatusType async_state;
320 
321  ret = ff_dnn_flush(&ctx->dnnctx);
322  if (ret != DNN_SUCCESS) {
323  return -1;
324  }
325 
326  do {
327  AVFrame *in_frame = NULL;
328  AVFrame *out_frame = NULL;
329  async_state = ff_dnn_get_async_result(&ctx->dnnctx, &in_frame, &out_frame);
330  if (out_frame) {
331  if (isPlanarYUV(in_frame->format))
332  copy_uv_planes(ctx, out_frame, in_frame);
333  av_frame_free(&in_frame);
334  ret = ff_filter_frame(outlink, out_frame);
335  if (ret < 0)
336  return ret;
337  if (out_pts)
338  *out_pts = out_frame->pts + pts;
339  }
340  av_usleep(5000);
341  } while (async_state >= DAST_NOT_READY);
342 
343  return 0;
344 }
345 
347 {
348  AVFilterLink *inlink = filter_ctx->inputs[0];
349  AVFilterLink *outlink = filter_ctx->outputs[0];
351  AVFrame *in = NULL, *out = NULL;
352  int64_t pts;
353  int ret, status;
354  int got_frame = 0;
355  int async_state;
356 
357  FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink);
358 
359  do {
360  // drain all input frames
361  ret = ff_inlink_consume_frame(inlink, &in);
362  if (ret < 0)
363  return ret;
364  if (ret > 0) {
365  out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
366  if (!out) {
367  av_frame_free(&in);
368  return AVERROR(ENOMEM);
369  }
371  if (ff_dnn_execute_model_async(&ctx->dnnctx, in, out) != DNN_SUCCESS) {
372  return AVERROR(EIO);
373  }
374  }
375  } while (ret > 0);
376 
377  // drain all processed frames
378  do {
379  AVFrame *in_frame = NULL;
380  AVFrame *out_frame = NULL;
381  async_state = ff_dnn_get_async_result(&ctx->dnnctx, &in_frame, &out_frame);
382  if (out_frame) {
383  if (isPlanarYUV(in_frame->format))
384  copy_uv_planes(ctx, out_frame, in_frame);
385  av_frame_free(&in_frame);
386  ret = ff_filter_frame(outlink, out_frame);
387  if (ret < 0)
388  return ret;
389  got_frame = 1;
390  }
391  } while (async_state == DAST_SUCCESS);
392 
393  // if frame got, schedule to next filter
394  if (got_frame)
395  return 0;
396 
397  if (ff_inlink_acknowledge_status(inlink, &status, &pts)) {
398  if (status == AVERROR_EOF) {
399  int64_t out_pts = pts;
400  ret = flush_frame(outlink, pts, &out_pts);
401  ff_outlink_set_status(outlink, status, out_pts);
402  return ret;
403  }
404  }
405 
406  FF_FILTER_FORWARD_WANTED(outlink, inlink);
407 
408  return 0;
409 }
410 
412 {
414 
415  if (ctx->dnnctx.async)
416  return activate_async(filter_ctx);
417  else
418  return activate_sync(filter_ctx);
419 }
420 
422 {
423  DnnProcessingContext *context = ctx->priv;
424 
425  sws_freeContext(context->sws_uv_scale);
426  ff_dnn_uninit(&context->dnnctx);
427 }
428 
430  {
431  .name = "default",
432  .type = AVMEDIA_TYPE_VIDEO,
433  .config_props = config_input,
434  },
435  { NULL }
436 };
437 
439  {
440  .name = "default",
441  .type = AVMEDIA_TYPE_VIDEO,
442  .config_props = config_output,
443  },
444  { NULL }
445 };
446 
448  .name = "dnn_processing",
449  .description = NULL_IF_CONFIG_SMALL("Apply DNN processing filter to the input."),
450  .priv_size = sizeof(DnnProcessingContext),
451  .init = init,
452  .uninit = uninit,
456  .priv_class = &dnn_processing_class,
457  .activate = activate,
458 };
static const AVFilterPad inputs[]
Definition: af_acontrast.c:193
static const AVFilterPad outputs[]
Definition: af_acontrast.c:203
#define av_always_inline
Definition: attributes.h:45
#define av_cold
Definition: attributes.h:88
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(const int16_t *) pi >> 8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(const int32_t *) pi >> 24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31)))) #define SET_CONV_FUNC_GROUP(ofmt, ifmt) static void set_generic_function(AudioConvert *ac) { } void ff_audio_convert_free(AudioConvert **ac) { if(! *ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);} AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int sample_rate, int apply_map) { AudioConvert *ac;int in_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) return NULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method !=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt) > 2) { ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc) { av_free(ac);return NULL;} return ac;} in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar) { ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar ? ac->channels :1;} else if(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;else ac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);return ac;} int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in) { int use_generic=1;int len=in->nb_samples;int p;if(ac->dc) { av_log(ac->avr, AV_LOG_TRACE, "%d samples - audio_convert: %s to %s (dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));return ff_convert_dither(ac-> in
uint8_t
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:37
int ff_inlink_acknowledge_status(AVFilterLink *link, int *rstatus, int64_t *rpts)
Test and acknowledge the change of status on the link.
Definition: avfilter.c:1449
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1096
int ff_inlink_consume_frame(AVFilterLink *link, AVFrame **rframe)
Take a frame from the link's FIFO and update the link's stats.
Definition: avfilter.c:1494
Buffered I/O operations.
#define AV_CEIL_RSHIFT(a, b)
Definition: common.h:58
#define NULL
Definition: coverity.c:32
long long int64_t
Definition: coverity.c:34
static enum AVPixelFormat pix_fmt
DNNReturnType ff_dnn_execute_model_async(DnnContext *ctx, AVFrame *in_frame, AVFrame *out_frame)
DNNAsyncStatusType ff_dnn_get_async_result(DnnContext *ctx, AVFrame **in_frame, AVFrame **out_frame)
void ff_dnn_uninit(DnnContext *ctx)
DNNReturnType ff_dnn_execute_model(DnnContext *ctx, AVFrame *in_frame, AVFrame *out_frame)
DNNReturnType ff_dnn_get_input(DnnContext *ctx, DNNData *input)
DNNReturnType ff_dnn_flush(DnnContext *ctx)
DNNReturnType ff_dnn_get_output(DnnContext *ctx, int input_width, int input_height, int *output_width, int *output_height)
int ff_dnn_init(DnnContext *ctx, DNNFunctionType func_type, AVFilterContext *filter_ctx)
common functions for the dnn based filters
#define DNN_COMMON_OPTIONS
DNNAsyncStatusType
Definition: dnn_interface.h:44
@ DAST_NOT_READY
Definition: dnn_interface.h:47
@ DAST_SUCCESS
Definition: dnn_interface.h:48
DNNReturnType
Definition: dnn_interface.h:33
@ DNN_SUCCESS
Definition: dnn_interface.h:33
@ DFT_PROCESS_FRAME
Definition: dnn_interface.h:53
@ DNN_FLOAT
Definition: dnn_interface.h:37
#define FF_FILTER_FORWARD_WANTED(outlink, inlink)
Forward the frame_wanted_out flag from an output link to an input link.
Definition: filters.h:254
static void ff_outlink_set_status(AVFilterLink *link, int status, int64_t pts)
Set the status field of a link from the source filter.
Definition: filters.h:189
#define FFERROR_NOT_READY
Filters implementation helper functions.
Definition: filters.h:34
#define FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink)
Forward the status on an output link to an input link.
Definition: filters.h:199
int ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
A helper for query_formats() which sets all links to the same list of formats.
Definition: formats.c:587
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:286
@ AV_OPT_TYPE_CONST
Definition: opt.h:234
@ AV_OPT_TYPE_INT
Definition: opt.h:225
#define AVERROR_EOF
End of file.
Definition: error.h:55
#define AVERROR(e)
Definition: error.h:43
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:203
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition: frame.c:658
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:194
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
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:373
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
#define SWS_BICUBIC
Definition: swscale.h:60
void sws_freeContext(struct SwsContext *swsContext)
Free the swscaler context swsContext.
Definition: utils.c:2337
int attribute_align_arg sws_scale(struct SwsContext *c, 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:745
struct 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:1917
misc image utilities
int i
Definition: input.c:407
common internal API header
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:117
void avpriv_report_missing_feature(void *avc, const char *msg,...) av_printf_format(2
Log a generic warning message about a missing feature.
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:309
const char * desc
Definition: libsvtav1.c:79
#define check(x, y, S, v)
AVOptions.
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:2489
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2573
#define AV_PIX_FMT_FLAG_RGB
The pixel format contains RGB-like data (as opposed to YUV/grayscale).
Definition: pixdesc.h:148
#define AV_PIX_FMT_GRAYF32
Definition: pixfmt.h:431
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
@ 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:89
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:65
@ AV_PIX_FMT_RGB24
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition: pixfmt.h:68
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:66
@ AV_PIX_FMT_YUV422P
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition: pixfmt.h:70
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
Definition: pixfmt.h:74
@ AV_PIX_FMT_YUV410P
planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y samples)
Definition: pixfmt.h:72
@ AV_PIX_FMT_YUV411P
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples)
Definition: pixfmt.h:73
@ AV_PIX_FMT_YUV444P
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition: pixfmt.h:71
@ AV_PIX_FMT_BGR24
packed RGB 8:8:8, 24bpp, BGRBGR...
Definition: pixfmt.h:69
@ AV_PIX_FMT_YA8
8 bits gray, 8 bits alpha
Definition: pixfmt.h:143
Describe the class of an AVClass context structure.
Definition: log.h:67
An instance of a filter.
Definition: avfilter.h:341
AVFilterLink ** inputs
array of pointers to input links
Definition: avfilter.h:349
void * priv
private data for use by the filter
Definition: avfilter.h:356
AVFilterLink ** outputs
array of pointers to output links
Definition: avfilter.h:353
A list of supported formats for one end of a filter link.
Definition: formats.h:65
A filter pad used for either input or output.
Definition: internal.h:54
const char * name
Pad name.
Definition: internal.h:60
Filter definition.
Definition: avfilter.h:145
const char * name
Filter name.
Definition: avfilter.h:149
This structure describes decoded (raw) audio or video data.
Definition: frame.h:318
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:411
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames,...
Definition: frame.h:391
AVOption.
Definition: opt.h:248
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:81
int channels
Definition: dnn_interface.h:60
DNNDataType dt
Definition: dnn_interface.h:62
int height
Definition: dnn_interface.h:60
struct SwsContext * sws_uv_scale
external API header
#define av_log(a,...)
FILE * out
Definition: movenc.c:54
AVFormatContext * ctx
Definition: movenc.c:48
int av_usleep(unsigned usec)
Sleep for a period of time.
Definition: time.c:84
static int64_t pts
static FilteringContext * filter_ctx
Definition: transcoding.c:48
static int flush_frame(AVFilterLink *outlink, int64_t pts, int64_t *out_pts)
static int copy_uv_planes(DnnProcessingContext *ctx, AVFrame *out, const AVFrame *in)
static av_always_inline int isPlanarYUV(enum AVPixelFormat pix_fmt)
static int activate_async(AVFilterContext *filter_ctx)
static int check_modelinput_inlink(const DNNData *model_input, const AVFilterLink *inlink)
static int config_input(AVFilterLink *inlink)
static const AVFilterPad dnn_processing_outputs[]
static av_cold int init(AVFilterContext *context)
#define FLAGS
static int query_formats(AVFilterContext *context)
static int prepare_uv_scale(AVFilterLink *outlink)
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
static int activate(AVFilterContext *filter_ctx)
AVFILTER_DEFINE_CLASS(dnn_processing)
static const AVOption dnn_processing_options[]
static av_cold void uninit(AVFilterContext *ctx)
#define LOG_FORMAT_CHANNEL_MISMATCH()
static const AVFilterPad dnn_processing_inputs[]
static int activate_sync(AVFilterContext *filter_ctx)
#define OFFSET(x)
static int config_output(AVFilterLink *outlink)
AVFilter ff_vf_dnn_processing
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
Definition: video.c:104