FFmpeg
vscale.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2015 Pedro Arthur <bygrandao@gmail.com>
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 #include "libavutil/mem.h"
21 #include "swscale_internal.h"
22 
23 typedef struct VScalerContext
24 {
25  uint16_t *filter[2];
28  int isMMX;
29  union {
36  } pfn;
39 
40 
41 static int lum_planar_vscale(SwsInternal *c, SwsFilterDescriptor *desc, int sliceY, int sliceH)
42 {
43  VScalerContext *inst = desc->instance;
44  int dstW = desc->dst->width;
45 
46  int first = FFMAX(1-inst->filter_size, inst->filter_pos[sliceY]);
47  int sp = first - desc->src->plane[0].sliceY;
48  int dp = sliceY - desc->dst->plane[0].sliceY;
49  uint8_t **src = desc->src->plane[0].line + sp;
50  uint8_t **dst = desc->dst->plane[0].line + dp;
51  uint16_t *filter = inst->filter[0] + (inst->isMMX ? 0 : sliceY * inst->filter_size);
52 
53  if (inst->filter_size == 1)
54  inst->pfn.yuv2planar1((const int16_t*)src[0], dst[0], dstW, c->lumDither8, 0);
55  else
56  inst->pfn.yuv2planarX(filter, inst->filter_size, (const int16_t**)src, dst[0], dstW, c->lumDither8, 0);
57 
58  if (desc->alpha) {
59  int sp = first - desc->src->plane[3].sliceY;
60  int dp = sliceY - desc->dst->plane[3].sliceY;
61  uint8_t **src = desc->src->plane[3].line + sp;
62  uint8_t **dst = desc->dst->plane[3].line + dp;
63  uint16_t *filter = inst->filter[1] + (inst->isMMX ? 0 : sliceY * inst->filter_size);
64 
65  if (inst->filter_size == 1)
66  inst->pfn.yuv2planar1((const int16_t*)src[0], dst[0], dstW, c->lumDither8, 0);
67  else
68  inst->pfn.yuv2planarX(filter, inst->filter_size, (const int16_t**)src, dst[0], dstW, c->lumDither8, 0);
69  }
70 
71  return 1;
72 }
73 
74 static int chr_planar_vscale(SwsInternal *c, SwsFilterDescriptor *desc, int sliceY, int sliceH)
75 {
76  const int chrSkipMask = (1 << desc->dst->v_chr_sub_sample) - 1;
77  if (sliceY & chrSkipMask)
78  return 0;
79  else {
80  VScalerContext *inst = desc->instance;
81  int dstW = AV_CEIL_RSHIFT(desc->dst->width, desc->dst->h_chr_sub_sample);
82  int chrSliceY = sliceY >> desc->dst->v_chr_sub_sample;
83 
84  int first = FFMAX(1-inst->filter_size, inst->filter_pos[chrSliceY]);
85  int sp1 = first - desc->src->plane[1].sliceY;
86  int sp2 = first - desc->src->plane[2].sliceY;
87  int dp1 = chrSliceY - desc->dst->plane[1].sliceY;
88  int dp2 = chrSliceY - desc->dst->plane[2].sliceY;
89  uint8_t **src1 = desc->src->plane[1].line + sp1;
90  uint8_t **src2 = desc->src->plane[2].line + sp2;
91  uint8_t **dst1 = desc->dst->plane[1].line + dp1;
92  uint8_t **dst2 = desc->dst->plane[2].line + dp2;
93  uint16_t *filter = inst->filter[0] + (inst->isMMX ? 0 : chrSliceY * inst->filter_size);
94 
95  if (c->yuv2nv12cX) {
96  inst->pfn.yuv2interleavedX(c->dstFormat, c->chrDither8, filter, inst->filter_size, (const int16_t**)src1, (const int16_t**)src2, dst1[0], dstW);
97  } else if (inst->filter_size == 1) {
98  inst->pfn.yuv2planar1((const int16_t*)src1[0], dst1[0], dstW, c->chrDither8, 0);
99  inst->pfn.yuv2planar1((const int16_t*)src2[0], dst2[0], dstW, c->chrDither8, 3);
100  } else {
101  inst->pfn.yuv2planarX(filter, inst->filter_size, (const int16_t**)src1, dst1[0], dstW, c->chrDither8, 0);
102  inst->pfn.yuv2planarX(filter, inst->filter_size, (const int16_t**)src2, dst2[0], dstW, c->chrDither8, inst->isMMX ? (c->uv_offx2 >> 1) : 3);
103  }
104  }
105 
106  return 1;
107 }
108 
109 static int packed_vscale(SwsInternal *c, SwsFilterDescriptor *desc, int sliceY, int sliceH)
110 {
111  VScalerContext *inst = desc->instance;
112  int dstW = desc->dst->width;
113  int chrSliceY = sliceY >> desc->dst->v_chr_sub_sample;
114 
115  int lum_fsize = inst[0].filter_size;
116  int chr_fsize = inst[1].filter_size;
117  uint16_t *lum_filter = inst[0].filter[0];
118  uint16_t *chr_filter = inst[1].filter[0];
119 
120  int firstLum = FFMAX(1-lum_fsize, inst[0].filter_pos[ sliceY]);
121  int firstChr = FFMAX(1-chr_fsize, inst[1].filter_pos[chrSliceY]);
122 
123  int sp0 = firstLum - desc->src->plane[0].sliceY;
124  int sp1 = firstChr - desc->src->plane[1].sliceY;
125  int sp2 = firstChr - desc->src->plane[2].sliceY;
126  int sp3 = firstLum - desc->src->plane[3].sliceY;
127  int dp = sliceY - desc->dst->plane[0].sliceY;
128  uint8_t **src0 = desc->src->plane[0].line + sp0;
129  uint8_t **src1 = desc->src->plane[1].line + sp1;
130  uint8_t **src2 = desc->src->plane[2].line + sp2;
131  uint8_t **src3 = desc->alpha ? desc->src->plane[3].line + sp3 : NULL;
132  uint8_t **dst = desc->dst->plane[0].line + dp;
133 
134 
135  if (c->yuv2packed1 && lum_fsize == 1 && chr_fsize == 1) { // unscaled RGB
136  inst->pfn.yuv2packed1(c, (const int16_t*)*src0, (const int16_t**)src1, (const int16_t**)src2,
137  (const int16_t*)(desc->alpha ? *src3 : NULL), *dst, dstW, 0, sliceY);
138  } else if (c->yuv2packed1 && lum_fsize == 1 && chr_fsize == 2 &&
139  chr_filter[2 * chrSliceY + 1] + chr_filter[2 * chrSliceY] == 4096 &&
140  chr_filter[2 * chrSliceY + 1] <= 4096U) { // unscaled RGB
141  int chrAlpha = chr_filter[2 * chrSliceY + 1];
142  inst->pfn.yuv2packed1(c, (const int16_t*)*src0, (const int16_t**)src1, (const int16_t**)src2,
143  (const int16_t*)(desc->alpha ? *src3 : NULL), *dst, dstW, chrAlpha, sliceY);
144  } else if (c->yuv2packed2 && lum_fsize == 2 && chr_fsize == 2 &&
145  lum_filter[2 * sliceY + 1] + lum_filter[2 * sliceY] == 4096 &&
146  lum_filter[2 * sliceY + 1] <= 4096U &&
147  chr_filter[2 * chrSliceY + 1] + chr_filter[2 * chrSliceY] == 4096 &&
148  chr_filter[2 * chrSliceY + 1] <= 4096U
149  ) { // bilinear upscale RGB
150  int lumAlpha = lum_filter[2 * sliceY + 1];
151  int chrAlpha = chr_filter[2 * chrSliceY + 1];
152  c->lumMmxFilter[2] =
153  c->lumMmxFilter[3] = lum_filter[2 * sliceY] * 0x10001;
154  c->chrMmxFilter[2] =
155  c->chrMmxFilter[3] = chr_filter[2 * chrSliceY] * 0x10001;
156  inst->pfn.yuv2packed2(c, (const int16_t**)src0, (const int16_t**)src1, (const int16_t**)src2, (const int16_t**)src3,
157  *dst, dstW, lumAlpha, chrAlpha, sliceY);
158  } else { // general RGB
159  if ((c->yuv2packed1 && lum_fsize == 1 && chr_fsize == 2) ||
160  (c->yuv2packed2 && lum_fsize == 2 && chr_fsize == 2)) {
161  if (!c->warned_unuseable_bilinear)
162  av_log(c, AV_LOG_INFO, "Optimized 2 tap filter code cannot be used\n");
163  c->warned_unuseable_bilinear = 1;
164  }
165 
166  inst->yuv2packedX(c, lum_filter + sliceY * lum_fsize,
167  (const int16_t**)src0, lum_fsize, chr_filter + chrSliceY * chr_fsize,
168  (const int16_t**)src1, (const int16_t**)src2, chr_fsize, (const int16_t**)src3, *dst, dstW, sliceY);
169  }
170  return 1;
171 }
172 
173 static int any_vscale(SwsInternal *c, SwsFilterDescriptor *desc, int sliceY, int sliceH)
174 {
175  VScalerContext *inst = desc->instance;
176  int dstW = desc->dst->width;
177  int chrSliceY = sliceY >> desc->dst->v_chr_sub_sample;
178 
179  int lum_fsize = inst[0].filter_size;
180  int chr_fsize = inst[1].filter_size;
181  uint16_t *lum_filter = inst[0].filter[0];
182  uint16_t *chr_filter = inst[1].filter[0];
183 
184  int firstLum = FFMAX(1-lum_fsize, inst[0].filter_pos[ sliceY]);
185  int firstChr = FFMAX(1-chr_fsize, inst[1].filter_pos[chrSliceY]);
186 
187  int sp0 = firstLum - desc->src->plane[0].sliceY;
188  int sp1 = firstChr - desc->src->plane[1].sliceY;
189  int sp2 = firstChr - desc->src->plane[2].sliceY;
190  int sp3 = firstLum - desc->src->plane[3].sliceY;
191  int dp0 = sliceY - desc->dst->plane[0].sliceY;
192  int dp1 = chrSliceY - desc->dst->plane[1].sliceY;
193  int dp2 = chrSliceY - desc->dst->plane[2].sliceY;
194  int dp3 = sliceY - desc->dst->plane[3].sliceY;
195 
196  uint8_t **src0 = desc->src->plane[0].line + sp0;
197  uint8_t **src1 = desc->src->plane[1].line + sp1;
198  uint8_t **src2 = desc->src->plane[2].line + sp2;
199  uint8_t **src3 = desc->alpha ? desc->src->plane[3].line + sp3 : NULL;
200  uint8_t *dst[4] = { desc->dst->plane[0].line[dp0],
201  desc->dst->plane[1].line[dp1],
202  desc->dst->plane[2].line[dp2],
203  desc->alpha ? desc->dst->plane[3].line[dp3] : NULL };
204 
205  av_assert1(!c->yuv2packed1 && !c->yuv2packed2);
206  inst->pfn.yuv2anyX(c, lum_filter + sliceY * lum_fsize,
207  (const int16_t**)src0, lum_fsize, chr_filter + sliceY * chr_fsize,
208  (const int16_t**)src1, (const int16_t**)src2, chr_fsize, (const int16_t**)src3, dst, dstW, sliceY);
209 
210  return 1;
211 
212 }
213 
215 {
216  VScalerContext *lumCtx = NULL;
217  VScalerContext *chrCtx = NULL;
218 
219  if (isPlanarYUV(c->dstFormat) || (isGray(c->dstFormat) && !isALPHA(c->dstFormat))) {
220  lumCtx = av_mallocz(sizeof(VScalerContext));
221  if (!lumCtx)
222  return AVERROR(ENOMEM);
223 
224 
225  desc[0].process = lum_planar_vscale;
226  desc[0].instance = lumCtx;
227  desc[0].src = src;
228  desc[0].dst = dst;
229  desc[0].alpha = c->needAlpha;
230 
231  if (!isGray(c->dstFormat)) {
232  chrCtx = av_mallocz(sizeof(VScalerContext));
233  if (!chrCtx)
234  return AVERROR(ENOMEM);
235  desc[1].process = chr_planar_vscale;
236  desc[1].instance = chrCtx;
237  desc[1].src = src;
238  desc[1].dst = dst;
239  }
240  } else {
241  lumCtx = av_calloc(2, sizeof(*lumCtx));
242  if (!lumCtx)
243  return AVERROR(ENOMEM);
244  chrCtx = &lumCtx[1];
245 
246  desc[0].process = c->yuv2packedX ? packed_vscale : any_vscale;
247  desc[0].instance = lumCtx;
248  desc[0].src = src;
249  desc[0].dst = dst;
250  desc[0].alpha = c->needAlpha;
251  }
252 
253  ff_init_vscale_pfn(c, c->yuv2plane1, c->yuv2planeX, c->yuv2nv12cX,
254  c->yuv2packed1, c->yuv2packed2, c->yuv2packedX, c->yuv2anyX, c->use_mmx_vfilter);
255  return 0;
256 }
257 
259  yuv2planar1_fn yuv2plane1,
261  yuv2interleavedX_fn yuv2nv12cX,
262  yuv2packed1_fn yuv2packed1,
263  yuv2packed2_fn yuv2packed2,
264  yuv2packedX_fn yuv2packedX,
265  yuv2anyX_fn yuv2anyX, int use_mmx)
266 {
267  VScalerContext *lumCtx = NULL;
268  VScalerContext *chrCtx = NULL;
269  int idx = c->numDesc - (c->is_internal_gamma ? 2 : 1); //FIXME avoid hardcoding indexes
270 
271  if (isPlanarYUV(c->dstFormat) || (isGray(c->dstFormat) && !isALPHA(c->dstFormat))) {
272  if (!isGray(c->dstFormat)) {
273  chrCtx = c->desc[idx].instance;
274 
275  chrCtx->filter[0] = use_mmx ? (int16_t*)c->chrMmxFilter : c->vChrFilter;
276  chrCtx->filter_size = c->vChrFilterSize;
277  chrCtx->filter_pos = c->vChrFilterPos;
278  chrCtx->isMMX = use_mmx;
279 
280  --idx;
281  if (yuv2nv12cX) chrCtx->pfn.yuv2interleavedX = yuv2nv12cX;
282  else if (c->vChrFilterSize == 1) chrCtx->pfn.yuv2planar1 = yuv2plane1;
283  else chrCtx->pfn.yuv2planarX = yuv2planeX;
284  }
285 
286  lumCtx = c->desc[idx].instance;
287 
288  lumCtx->filter[0] = use_mmx ? (int16_t*)c->lumMmxFilter : c->vLumFilter;
289  lumCtx->filter[1] = use_mmx ? (int16_t*)c->alpMmxFilter : c->vLumFilter;
290  lumCtx->filter_size = c->vLumFilterSize;
291  lumCtx->filter_pos = c->vLumFilterPos;
292  lumCtx->isMMX = use_mmx;
293 
294  if (c->vLumFilterSize == 1) lumCtx->pfn.yuv2planar1 = yuv2plane1;
295  else lumCtx->pfn.yuv2planarX = yuv2planeX;
296 
297  } else {
298  lumCtx = c->desc[idx].instance;
299  chrCtx = &lumCtx[1];
300 
301  lumCtx->filter[0] = c->vLumFilter;
302  lumCtx->filter_size = c->vLumFilterSize;
303  lumCtx->filter_pos = c->vLumFilterPos;
304 
305  chrCtx->filter[0] = c->vChrFilter;
306  chrCtx->filter_size = c->vChrFilterSize;
307  chrCtx->filter_pos = c->vChrFilterPos;
308 
309  lumCtx->isMMX = use_mmx;
310  chrCtx->isMMX = use_mmx;
311 
312  if (yuv2packedX) {
313  if (c->yuv2packed1 && c->vLumFilterSize == 1 && c->vChrFilterSize <= 2)
314  lumCtx->pfn.yuv2packed1 = yuv2packed1;
315  else if (c->yuv2packed2 && c->vLumFilterSize == 2 && c->vChrFilterSize == 2)
316  lumCtx->pfn.yuv2packed2 = yuv2packed2;
317  lumCtx->yuv2packedX = yuv2packedX;
318  } else
319  lumCtx->pfn.yuv2anyX = yuv2anyX;
320  }
321 }
yuv2planar1_fn
void(* yuv2planar1_fn)(const int16_t *src, uint8_t *dest, int dstW, const uint8_t *dither, int offset)
Write one line of horizontally scaled data to planar output without any additional vertical scaling (...
Definition: swscale_internal.h:121
lum_planar_vscale
static int lum_planar_vscale(SwsInternal *c, SwsFilterDescriptor *desc, int sliceY, int sliceH)
Definition: vscale.c:41
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
VScalerContext::filter_pos
int32_t * filter_pos
Definition: vscale.c:26
src1
const pixel * src1
Definition: h264pred_template.c:421
ff_init_vscale
int ff_init_vscale(SwsInternal *c, SwsFilterDescriptor *desc, SwsSlice *src, SwsSlice *dst)
initializes vertical scaling descriptors
Definition: vscale.c:214
SwsFilterDescriptor
Struct which holds all necessary data for processing a slice.
Definition: swscale_internal.h:1118
yuv2planeX
static void FUNC() yuv2planeX(const int16_t *filter, int filterSize, const int16_t **src, uint8_t *dest, int dstW, const uint8_t *dither, int offset)
Definition: swscale_ppc_template.c:84
VScalerContext::yuv2planar1
yuv2planar1_fn yuv2planar1
Definition: vscale.c:30
isGray
#define isGray(x)
Definition: swscale.c:42
filter
void(* filter)(uint8_t *src, int stride, int qscale)
Definition: h263dsp.c:29
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
any_vscale
static int any_vscale(SwsInternal *c, SwsFilterDescriptor *desc, int sliceY, int sliceH)
Definition: vscale.c:173
VScalerContext::yuv2anyX
yuv2anyX_fn yuv2anyX
Definition: vscale.c:35
VScalerContext::isMMX
int isMMX
Definition: vscale.c:28
first
trying all byte sequences megabyte in length and selecting the best looking sequence will yield cases to try But first
Definition: rate_distortion.txt:12
ff_init_vscale_pfn
void ff_init_vscale_pfn(SwsInternal *c, yuv2planar1_fn yuv2plane1, yuv2planarX_fn yuv2planeX, yuv2interleavedX_fn yuv2nv12cX, yuv2packed1_fn yuv2packed1, yuv2packed2_fn yuv2packed2, yuv2packedX_fn yuv2packedX, yuv2anyX_fn yuv2anyX, int use_mmx)
setup vertical scaler functions
Definition: vscale.c:258
yuv2packed2_fn
void(* yuv2packed2_fn)(SwsInternal *c, const int16_t *lumSrc[2], const int16_t *chrUSrc[2], const int16_t *chrVSrc[2], const int16_t *alpSrc[2], uint8_t *dest, int dstW, int yalpha, int uvalpha, int y)
Write one line of horizontally scaled Y/U/V/A to packed-pixel YUV/RGB output by doing bilinear scalin...
Definition: swscale_internal.h:227
VScalerContext::pfn
union VScalerContext::@461 pfn
AV_CEIL_RSHIFT
#define AV_CEIL_RSHIFT(a, b)
Definition: common.h:60
VScalerContext::yuv2planarX
yuv2planarX_fn yuv2planarX
Definition: vscale.c:31
if
if(ret)
Definition: filter_design.txt:179
NULL
#define NULL
Definition: coverity.c:32
VScalerContext::filter_size
int filter_size
Definition: vscale.c:27
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
yuv2packedX_fn
void(* yuv2packedX_fn)(SwsInternal *c, const int16_t *lumFilter, const int16_t **lumSrc, int lumFilterSize, const int16_t *chrFilter, const int16_t **chrUSrc, const int16_t **chrVSrc, int chrFilterSize, const int16_t **alpSrc, uint8_t *dest, int dstW, int y)
Write one line of horizontally scaled Y/U/V/A to packed-pixel YUV/RGB output by doing multi-point ver...
Definition: swscale_internal.h:259
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:83
VScalerContext::yuv2packedX
yuv2packedX_fn yuv2packedX
Definition: vscale.c:37
VScalerContext::yuv2packed2
yuv2packed2_fn yuv2packed2
Definition: vscale.c:34
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:220
yuv2anyX_fn
void(* yuv2anyX_fn)(SwsInternal *c, const int16_t *lumFilter, const int16_t **lumSrc, int lumFilterSize, const int16_t *chrFilter, const int16_t **chrUSrc, const int16_t **chrVSrc, int chrFilterSize, const int16_t **alpSrc, uint8_t **dest, int dstW, int y)
Write one line of horizontally scaled Y/U/V/A to YUV/RGB output by doing multi-point vertical scaling...
Definition: swscale_internal.h:293
src2
const pixel * src2
Definition: h264pred_template.c:422
av_assert1
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Definition: avassert.h:56
swscale_internal.h
yuv2interleavedX_fn
void(* yuv2interleavedX_fn)(enum AVPixelFormat dstFormat, const uint8_t *chrDither, const int16_t *chrFilter, int chrFilterSize, const int16_t **chrUSrc, const int16_t **chrVSrc, uint8_t *dest, int dstW)
Write one line of horizontally scaled chroma to interleaved output with multi-point vertical scaling ...
Definition: swscale_internal.h:157
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:256
SwsSlice
Struct which defines a slice of an image to be scaled or an output for a scaled slice.
Definition: swscale_internal.h:1103
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:264
yuv2packed1_fn
void(* yuv2packed1_fn)(SwsInternal *c, const int16_t *lumSrc, const int16_t *chrUSrc[2], const int16_t *chrVSrc[2], const int16_t *alpSrc, uint8_t *dest, int dstW, int uvalpha, int y)
Write one line of horizontally scaled Y/U/V/A to packed-pixel YUV/RGB output without any additional v...
Definition: swscale_internal.h:194
SwsInternal
Definition: swscale_internal.h:330
packed_vscale
static int packed_vscale(SwsInternal *c, SwsFilterDescriptor *desc, int sliceY, int sliceH)
Definition: vscale.c:109
U
#define U(x)
Definition: vpx_arith.h:37
yuv2planarX_fn
void(* yuv2planarX_fn)(const int16_t *filter, int filterSize, const int16_t **src, uint8_t *dest, int dstW, const uint8_t *dither, int offset)
Write one line of horizontally scaled data to planar output with multi-point vertical scaling between...
Definition: swscale_internal.h:137
VScalerContext::filter
uint16_t * filter[2]
Definition: vscale.c:25
src0
const pixel *const src0
Definition: h264pred_template.c:420
isPlanarYUV
static av_always_inline int isPlanarYUV(enum AVPixelFormat pix_fmt)
Definition: vf_dnn_processing.c:162
desc
const char * desc
Definition: libsvtav1.c:79
mem.h
chr_planar_vscale
static int chr_planar_vscale(SwsInternal *c, SwsFilterDescriptor *desc, int sliceY, int sliceH)
Definition: vscale.c:74
VScalerContext::yuv2interleavedX
yuv2interleavedX_fn yuv2interleavedX
Definition: vscale.c:32
int32_t
int32_t
Definition: audioconvert.c:56
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
VScalerContext::yuv2packed1
yuv2packed1_fn yuv2packed1
Definition: vscale.c:33
src
#define src
Definition: vp8dsp.c:248
isALPHA
static av_always_inline int isALPHA(enum AVPixelFormat pix_fmt)
Definition: swscale_internal.h:880
VScalerContext
Definition: vscale.c:23