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 */
21
23 {
28 union {
38
39
41 {
43 int dstW =
desc->dst->width;
44
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;
51
54 else
56
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;
63
66 else
68 }
69
70 return 1;
71 }
72
74 {
75 const int chrSkipMask = (1 <<
desc->dst->v_chr_sub_sample) - 1;
76 if (sliceY & chrSkipMask)
77 return 0;
78 else {
81 int chrSliceY = sliceY >>
desc->dst->v_chr_sub_sample;
82
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;
93
99 } else {
102 }
103 }
104
105 return 1;
106 }
107
109 {
111 int dstW =
desc->dst->width;
112 int chrSliceY = sliceY >>
desc->dst->v_chr_sub_sample;
113
116 uint16_t *lum_filter = inst[0].
filter[0];
117 uint16_t *chr_filter = inst[1].
filter[0];
118
119 int firstLum =
FFMAX(1-lum_fsize, inst[0].filter_pos[ sliceY]);
120 int firstChr =
FFMAX(1-chr_fsize, inst[1].filter_pos[chrSliceY]);
121
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;
132
133
134 if (
c->yuv2packed1 && lum_fsize == 1 && chr_fsize == 1) {
// unscaled RGB
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) {
// unscaled RGB
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
148 ) { // bilinear upscale RGB
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);
157 } else { // general RGB
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;
163 }
164
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);
168 }
169 return 1;
170 }
171
173 {
175 int dstW =
desc->dst->width;
176 int chrSliceY = sliceY >>
desc->dst->v_chr_sub_sample;
177
180 uint16_t *lum_filter = inst[0].
filter[0];
181 uint16_t *chr_filter = inst[1].
filter[0];
182
183 int firstLum =
FFMAX(1-lum_fsize, inst[0].filter_pos[ sliceY]);
184 int firstChr =
FFMAX(1-chr_fsize, inst[1].filter_pos[chrSliceY]);
185
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;
194
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],
203
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);
208
209 return 1;
210
211 }
212
214 {
217
220 if (!lumCtx)
222
223
225 desc[0].instance = lumCtx;
228 desc[0].alpha =
c->needAlpha;
229
232 if (!chrCtx)
235 desc[1].instance = chrCtx;
238 }
239 } else {
241 if (!lumCtx)
243 chrCtx = &lumCtx[1];
244
246 desc[0].instance = lumCtx;
249 desc[0].alpha =
c->needAlpha;
250 }
251
253 c->yuv2packed1,
c->yuv2packed2,
c->yuv2packedX,
c->yuv2anyX,
c->use_mmx_vfilter);
254 return 0;
255 }
256
265 {
268 int idx =
c->numDesc - (
c->is_internal_gamma ? 2 : 1);
//FIXME avoid hardcoding indexes
269
272 chrCtx =
c->desc[idx].instance;
273
274 chrCtx->
filter[0] = use_mmx ? (int16_t*)
c->chrMmxFilter :
c->vChrFilter;
277 chrCtx->
isMMX = use_mmx;
278
279 --idx;
283 }
284
285 lumCtx =
c->desc[idx].instance;
286
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;
292
295
296 } else {
297 lumCtx =
c->desc[idx].instance;
298 chrCtx = &lumCtx[1];
299
300 lumCtx->
filter[0] =
c->vLumFilter;
303
304 chrCtx->
filter[0] =
c->vChrFilter;
307
308 lumCtx->
isMMX = use_mmx;
309 chrCtx->
isMMX = use_mmx;
310
311 if (yuv2packedX) {
312 if (
c->yuv2packed1 &&
c->vLumFilterSize == 1 &&
c->vChrFilterSize <= 2)
314 else if (
c->yuv2packed2 &&
c->vLumFilterSize == 2 &&
c->vChrFilterSize == 2)
317 } else
319 }
320 }
321
322