FFmpeg
ops_memcpy.c
Go to the documentation of this file.
1 /**
2  * Copyright (C) 2025 Niklas Haas
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 "libavutil/avassert.h"
22 
23 #include "ops_backend.h"
24 
25 typedef struct MemcpyPriv {
27  int index[4]; /* or -1 to clear plane */
28  uint8_t clear_value[4];
29 } MemcpyPriv;
30 
31 /* Memcpy backend for trivial cases */
32 
33 static void process(const SwsOpExec *exec, const void *priv,
34  int x_start, int y_start, int x_end, int y_end)
35 {
36  const MemcpyPriv *p = priv;
37  const int lines = y_end - y_start;
38  av_assert1(x_start == 0 && x_end == exec->width);
39 
40  for (int i = 0; i < p->num_planes; i++) {
41  uint8_t *out = exec->out[i];
42  const int idx = p->index[i];
43  if (idx < 0) {
44  memset(out, p->clear_value[i], exec->out_stride[i] * lines);
45  } else if (exec->out_stride[i] == exec->in_stride[idx]) {
46  memcpy(out, exec->in[idx], exec->out_stride[i] * lines);
47  } else {
48  const int bytes = x_end * exec->block_size_out;
49  const uint8_t *in = exec->in[idx];
50  for (int y = y_start; y < y_end; y++) {
51  memcpy(out, in, bytes);
52  out += exec->out_stride[i];
53  in += exec->in_stride[idx];
54  }
55  }
56  }
57 }
58 
60 {
61  MemcpyPriv p = {0};
62 
63  for (int n = 0; n < ops->num_ops; n++) {
64  const SwsOp *op = &ops->ops[n];
65  switch (op->op) {
66  case SWS_OP_READ:
67  if ((op->rw.packed && op->rw.elems != 1) || op->rw.frac)
68  return AVERROR(ENOTSUP);
69  for (int i = 0; i < op->rw.elems; i++)
70  p.index[i] = i;
71  break;
72 
73  case SWS_OP_SWIZZLE: {
74  const MemcpyPriv orig = p;
75  for (int i = 0; i < 4; i++) {
76  /* Explicitly exclude swizzle masks that contain duplicates,
77  * because these are wasteful to implement as a memcpy */
78  for (int j = 0; j < i; j++) {
79  if (op->swizzle.in[i] == op->swizzle.in[j])
80  return AVERROR(ENOTSUP);
81  }
82  p.index[i] = orig.index[op->swizzle.in[i]];
83  }
84  break;
85  }
86 
87  case SWS_OP_CLEAR:
88  for (int i = 0; i < 4; i++) {
89  if (!op->c.q4[i].den)
90  continue;
91  if (op->c.q4[i].den != 1)
92  return AVERROR(ENOTSUP);
93 
94  /* Ensure all bytes to be cleared are the same, because we
95  * can't memset on multi-byte sequences */
96  uint8_t val = op->c.q4[i].num & 0xFF;
97  uint32_t ref = val;
98  switch (ff_sws_pixel_type_size(op->type)) {
99  case 2: ref *= 0x101; break;
100  case 4: ref *= 0x1010101; break;
101  }
102  if (ref != op->c.q4[i].num)
103  return AVERROR(ENOTSUP);
104  p.clear_value[i] = val;
105  p.index[i] = -1;
106  }
107  break;
108 
109  case SWS_OP_WRITE:
110  if ((op->rw.packed && op->rw.elems != 1) || op->rw.frac)
111  return AVERROR(ENOTSUP);
112  p.num_planes = op->rw.elems;
113  break;
114 
115  default:
116  return AVERROR(ENOTSUP);
117  }
118  }
119 
120  *out = (SwsCompiledOp) {
121  .block_size = 1,
122  .func = process,
123  .priv = av_memdup(&p, sizeof(p)),
124  .free = av_free,
125  };
126  return out->priv ? 0 : AVERROR(ENOMEM);
127 }
128 
130  .name = "memcpy",
131  .compile = compile,
132 };
SWS_OP_READ
@ SWS_OP_READ
Definition: ops.h:48
SWS_OP_SWIZZLE
@ SWS_OP_SWIZZLE
Definition: ops.h:58
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
ops_backend.h
out
FILE * out
Definition: movenc.c:55
SWS_OP_CLEAR
@ SWS_OP_CLEAR
Definition: ops.h:55
SwsOpExec::in
const uint8_t * in[4]
Definition: ops_internal.h:58
SwsOpExec::out_stride
ptrdiff_t out_stride[4]
Definition: ops_internal.h:63
SwsOpExec::in_stride
ptrdiff_t in_stride[4]
Definition: ops_internal.h:62
SwsOpBackend::name
const char * name
Definition: ops_internal.h:104
ff_sws_pixel_type_size
int ff_sws_pixel_type_size(SwsPixelType type)
Definition: ops.c:64
MemcpyPriv::num_planes
int num_planes
Definition: ops_memcpy.c:26
av_memdup
void * av_memdup(const void *p, size_t size)
Duplicate a buffer with av_malloc().
Definition: mem.c:304
SwsOpList::num_ops
int num_ops
Definition: ops.h:211
val
static double val(void *priv, double ch)
Definition: aeval.c:77
avassert.h
backend_murder
const SwsOpBackend backend_murder
Definition: ops_memcpy.c:129
op
static int op(uint8_t **dst, const uint8_t *dst_end, GetByteContext *gb, int pixel, int count, int *x, int width, int linesize)
Perform decode operation.
Definition: anm.c:76
MemcpyPriv::clear_value
uint8_t clear_value[4]
Definition: ops_memcpy.c:28
ctx
AVFormatContext * ctx
Definition: movenc.c:49
SwsOpBackend
Definition: ops_internal.h:103
SwsOpExec
Global execution context for all compiled functions.
Definition: ops_internal.h:56
compile
static int compile(SwsContext *ctx, SwsOpList *ops, SwsCompiledOp *out)
Definition: ops_memcpy.c:59
SwsOpExec::block_size_out
int32_t block_size_out
Definition: ops_internal.h:73
for
for(k=2;k<=8;++k)
Definition: h264pred_template.c:424
process
static void process(const SwsOpExec *exec, const void *priv, int x_start, int y_start, int x_end, int y_end)
Definition: ops_memcpy.c:33
MemcpyPriv::index
int index[4]
Definition: ops_memcpy.c:27
SWS_OP_WRITE
@ SWS_OP_WRITE
Definition: ops.h:49
SwsOpExec::out
uint8_t * out[4]
Definition: ops_internal.h:59
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
SwsOpList::ops
SwsOp * ops
Definition: ops.h:210
av_assert1
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Definition: avassert.h:57
SwsOp
Definition: ops.h:179
SwsOpExec::width
int32_t width
Definition: ops_internal.h:70
SwsCompiledOp
Definition: ops_internal.h:90
ref
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:117
Windows::Graphics::DirectX::Direct3D11::p
IDirect3DDxgiInterfaceAccess _COM_Outptr_ void ** p
Definition: vsrc_gfxcapture_winrt.hpp:53
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
MemcpyPriv
Copyright (C) 2025 Niklas Haas.
Definition: ops_memcpy.c:25
SwsOpList
Helper struct for representing a list of operations.
Definition: ops.h:209
SwsContext
Main external API structure.
Definition: swscale.h:189