Go to the documentation of this file.
43 int dstW =
desc->dst->width;
47 int dp = sliceY -
desc->dst->plane[0].sliceY;
48 uint8_t **
src =
desc->src->plane[0].line +
sp;
49 uint8_t **dst =
desc->dst->plane[0].line + dp;
59 int dp = sliceY -
desc->dst->plane[3].sliceY;
60 uint8_t **
src =
desc->src->plane[3].line +
sp;
61 uint8_t **dst =
desc->dst->plane[3].line + dp;
75 const int chrSkipMask = (1 <<
desc->dst->v_chr_sub_sample) - 1;
76 if (sliceY & chrSkipMask)
81 int chrSliceY = sliceY >>
desc->dst->v_chr_sub_sample;
84 int sp1 =
first -
desc->src->plane[1].sliceY;
85 int sp2 =
first -
desc->src->plane[2].sliceY;
86 int dp1 = chrSliceY -
desc->dst->plane[1].sliceY;
87 int dp2 = chrSliceY -
desc->dst->plane[2].sliceY;
88 uint8_t **
src1 =
desc->src->plane[1].line + sp1;
89 uint8_t **
src2 =
desc->src->plane[2].line + sp2;
90 uint8_t **dst1 =
desc->dst->plane[1].line + dp1;
91 uint8_t **dst2 =
desc->dst->plane[2].line + dp2;
111 int dstW =
desc->dst->width;
112 int chrSliceY = sliceY >>
desc->dst->v_chr_sub_sample;
116 uint16_t *lum_filter = inst[0].
filter[0];
117 uint16_t *chr_filter = inst[1].
filter[0];
119 int firstLum =
FFMAX(1-lum_fsize, inst[0].filter_pos[ sliceY]);
120 int firstChr =
FFMAX(1-chr_fsize, inst[1].filter_pos[chrSliceY]);
122 int sp0 = firstLum -
desc->src->plane[0].sliceY;
123 int sp1 = firstChr -
desc->src->plane[1].sliceY;
124 int sp2 = firstChr -
desc->src->plane[2].sliceY;
125 int sp3 = firstLum -
desc->src->plane[3].sliceY;
126 int dp = sliceY -
desc->dst->plane[0].sliceY;
127 uint8_t **
src0 =
desc->src->plane[0].line + sp0;
128 uint8_t **
src1 =
desc->src->plane[1].line + sp1;
129 uint8_t **
src2 =
desc->src->plane[2].line + sp2;
130 uint8_t **src3 =
desc->alpha ?
desc->src->plane[3].line + sp3 :
NULL;
131 uint8_t **dst =
desc->dst->plane[0].line + dp;
134 if (
c->yuv2packed1 && lum_fsize == 1 && chr_fsize == 1) {
136 (
const int16_t*)(
desc->alpha ? *src3 :
NULL), *dst, dstW, 0, sliceY);
137 }
else if (
c->yuv2packed1 && lum_fsize == 1 && chr_fsize == 2 &&
138 chr_filter[2 * chrSliceY + 1] + chr_filter[2 * chrSliceY] == 4096 &&
139 chr_filter[2 * chrSliceY + 1] <= 4096
U) {
140 int chrAlpha = chr_filter[2 * chrSliceY + 1];
142 (
const int16_t*)(
desc->alpha ? *src3 :
NULL), *dst, dstW, chrAlpha, sliceY);
143 }
else if (
c->yuv2packed2 && lum_fsize == 2 && chr_fsize == 2 &&
144 lum_filter[2 * sliceY + 1] + lum_filter[2 * sliceY] == 4096 &&
145 lum_filter[2 * sliceY + 1] <= 4096
U &&
146 chr_filter[2 * chrSliceY + 1] + chr_filter[2 * chrSliceY] == 4096 &&
147 chr_filter[2 * chrSliceY + 1] <= 4096
U
149 int lumAlpha = lum_filter[2 * sliceY + 1];
150 int chrAlpha = chr_filter[2 * chrSliceY + 1];
152 c->lumMmxFilter[3] = lum_filter[2 * sliceY] * 0x10001;
154 c->chrMmxFilter[3] = chr_filter[2 * chrSliceY] * 0x10001;
156 *dst, dstW, lumAlpha, chrAlpha, sliceY);
158 if ((
c->yuv2packed1 && lum_fsize == 1 && chr_fsize == 2) ||
159 (
c->yuv2packed2 && lum_fsize == 2 && chr_fsize == 2)) {
160 if (!
c->warned_unuseable_bilinear)
162 c->warned_unuseable_bilinear = 1;
166 (
const int16_t**)
src0, lum_fsize, chr_filter + chrSliceY * chr_fsize,
167 (
const int16_t**)
src1, (
const int16_t**)
src2, chr_fsize, (
const int16_t**)src3, *dst, dstW, sliceY);
175 int dstW =
desc->dst->width;
176 int chrSliceY = sliceY >>
desc->dst->v_chr_sub_sample;
180 uint16_t *lum_filter = inst[0].
filter[0];
181 uint16_t *chr_filter = inst[1].
filter[0];
183 int firstLum =
FFMAX(1-lum_fsize, inst[0].filter_pos[ sliceY]);
184 int firstChr =
FFMAX(1-chr_fsize, inst[1].filter_pos[chrSliceY]);
186 int sp0 = firstLum -
desc->src->plane[0].sliceY;
187 int sp1 = firstChr -
desc->src->plane[1].sliceY;
188 int sp2 = firstChr -
desc->src->plane[2].sliceY;
189 int sp3 = firstLum -
desc->src->plane[3].sliceY;
190 int dp0 = sliceY -
desc->dst->plane[0].sliceY;
191 int dp1 = chrSliceY -
desc->dst->plane[1].sliceY;
192 int dp2 = chrSliceY -
desc->dst->plane[2].sliceY;
193 int dp3 = sliceY -
desc->dst->plane[3].sliceY;
195 uint8_t **
src0 =
desc->src->plane[0].line + sp0;
196 uint8_t **
src1 =
desc->src->plane[1].line + sp1;
197 uint8_t **
src2 =
desc->src->plane[2].line + sp2;
198 uint8_t **src3 =
desc->alpha ?
desc->src->plane[3].line + sp3 :
NULL;
199 uint8_t *dst[4] = {
desc->dst->plane[0].line[dp0],
200 desc->dst->plane[1].line[dp1],
201 desc->dst->plane[2].line[dp2],
206 (
const int16_t**)
src0, lum_fsize, chr_filter + sliceY * chr_fsize,
207 (
const int16_t**)
src1, (
const int16_t**)
src2, chr_fsize, (
const int16_t**)src3, dst, dstW, sliceY);
225 desc[0].instance = lumCtx;
228 desc[0].alpha =
c->needAlpha;
235 desc[1].instance = chrCtx;
246 desc[0].instance = lumCtx;
249 desc[0].alpha =
c->needAlpha;
253 c->yuv2packed1,
c->yuv2packed2,
c->yuv2packedX,
c->yuv2anyX,
c->use_mmx_vfilter);
268 int idx =
c->numDesc - (
c->is_internal_gamma ? 2 : 1);
272 chrCtx =
c->desc[idx].instance;
274 chrCtx->
filter[0] = use_mmx ? (int16_t*)
c->chrMmxFilter :
c->vChrFilter;
277 chrCtx->
isMMX = use_mmx;
285 lumCtx =
c->desc[idx].instance;
287 lumCtx->
filter[0] = use_mmx ? (int16_t*)
c->lumMmxFilter :
c->vLumFilter;
288 lumCtx->
filter[1] = use_mmx ? (int16_t*)
c->alpMmxFilter :
c->vLumFilter;
291 lumCtx->
isMMX = use_mmx;
297 lumCtx =
c->desc[idx].instance;
300 lumCtx->
filter[0] =
c->vLumFilter;
304 chrCtx->
filter[0] =
c->vChrFilter;
308 lumCtx->
isMMX = use_mmx;
309 chrCtx->
isMMX = use_mmx;
312 if (
c->yuv2packed1 &&
c->vLumFilterSize == 1 &&
c->vChrFilterSize <= 2)
314 else if (
c->yuv2packed2 &&
c->vLumFilterSize == 2 &&
c->vChrFilterSize == 2)
void(* yuv2packed2_fn)(struct SwsContext *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...
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 (...
void(* yuv2packed1_fn)(struct SwsContext *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...
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
Struct which holds all necessary data for processing a slice.
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)
yuv2planar1_fn yuv2planar1
filter_frame For filters that do not use the this method is called when a frame is pushed to the filter s input It can be called at any time except in a reentrant way If the input frame is enough to produce then the filter should push the output frames on the output link immediately As an exception to the previous rule if the input frame is enough to produce several output frames then the filter needs output only at least one per link The additional frames can be left buffered in the filter
void ff_init_vscale_pfn(SwsContext *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
void(* yuv2anyX_fn)(struct SwsContext *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...
static int chr_planar_vscale(SwsContext *c, SwsFilterDescriptor *desc, int sliceY, int sliceH)
trying all byte sequences megabyte in length and selecting the best looking sequence will yield cases to try But first
#define AV_CEIL_RSHIFT(a, b)
yuv2planarX_fn yuv2planarX
static int lum_planar_vscale(SwsContext *c, SwsFilterDescriptor *desc, int sliceY, int sliceH)
static int any_vscale(SwsContext *c, SwsFilterDescriptor *desc, int sliceY, int sliceH)
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
static int packed_vscale(SwsContext *c, SwsFilterDescriptor *desc, int sliceY, int sliceH)
yuv2packedX_fn yuv2packedX
yuv2packed2_fn yuv2packed2
union VScalerContext::@382 pfn
#define AV_LOG_INFO
Standard information.
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
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 ...
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Struct which defines a slice of an image to be scaled or an output for a scaled slice.
void * av_calloc(size_t nmemb, size_t size)
int ff_init_vscale(SwsContext *c, SwsFilterDescriptor *desc, SwsSlice *src, SwsSlice *dst)
initializes vertical scaling descriptors
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...
void(* yuv2packedX_fn)(struct SwsContext *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...
static av_always_inline int isPlanarYUV(enum AVPixelFormat pix_fmt)
yuv2interleavedX_fn yuv2interleavedX
yuv2packed1_fn yuv2packed1
static av_always_inline int isALPHA(enum AVPixelFormat pix_fmt)