40 #define NS(n) n < 0 ? (int)(n*65536.0-0.5+DBL_EPSILON) : (int)(n*65536.0+0.5)
41 #define CB(n) av_clip_uint8(n)
44 { { +0.7152, +0.0722, +0.2126 },
45 { -0.3850, +0.5000, -0.1150 },
46 { -0.4540, -0.0460, +0.5000 } },
47 { { +0.5900, +0.1100, +0.3000 },
48 { -0.3310, +0.5000, -0.1690 },
49 { -0.4210, -0.0790, +0.5000 } },
50 { { +0.5870, +0.1140, +0.2990 },
51 { -0.3313, +0.5000, -0.1687 },
52 { -0.4187, -0.0813, +0.5000 } },
53 { { +0.7010, +0.0870, +0.2120 },
54 { -0.3840, +0.5000, -0.1160 },
55 { -0.4450, -0.0550, +0.5000 } },
69 int yuv_convert[16][3][3];
76 #define OFFSET(x) offsetof(ColorMatrixContext, x)
77 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
129 for (i = 0; i < 3; i++)
130 for (j = 0; j < 3; j++)
131 cm[i][j] = yuv[i][0] * rgb[0][j] + yuv[i][1] * rgb[1][j] + yuv[i][2] * rgb[2][j];
137 double rgb_coeffd[4][3][3];
138 double yuv_convertd[16][3][3];
142 for (i = 0; i < 4; i++)
144 for (i = 0; i < 4; i++) {
145 for (j = 0; j < 4; j++) {
147 for (k = 0; k < 3; k++) {
161 static const char *
color_modes[] = {
"bt709",
"fcc",
"bt601",
"smpte240m"};
172 if (color->source == color->
dest) {
173 av_log(ctx,
AV_LOG_ERROR,
"Source and destination color space must not be identical\n");
183 const unsigned char *
srcp = src->
data[0];
197 for (y = 0; y <
height; y++) {
198 for (x = 0; x <
width; x += 4) {
199 const int u = srcp[x + 0] - 128;
200 const int v = srcp[x + 2] - 128;
201 const int uvval = c2 * u + c3 * v + 1081344;
202 dstp[x + 0] =
CB((c4 * u + c5 * v + 8421376) >> 16);
203 dstp[x + 1] =
CB((65536 * (srcp[x + 1] - 16) + uvval) >> 16);
204 dstp[x + 2] =
CB((c6 * u + c7 * v + 8421376) >> 16);
205 dstp[x + 3] =
CB((65536 * (srcp[x + 3] - 16) + uvval) >> 16);
215 const unsigned char *srcpU = src->
data[1];
216 const unsigned char *srcpV = src->
data[2];
217 const unsigned char *srcpY = src->
data[0];
218 const int src_pitchY = src->
linesize[0];
219 const int src_pitchUV = src->
linesize[1];
222 unsigned char *dstpU = dst->
data[1];
223 unsigned char *dstpV = dst->
data[2];
224 unsigned char *dstpY = dst->
data[0];
225 const int dst_pitchY = dst->
linesize[0];
226 const int dst_pitchUV = dst->
linesize[1];
235 for (y = 0; y <
height; y++) {
236 for (x = 0; x <
width; x += 2) {
237 const int u = srcpU[x >> 1] - 128;
238 const int v = srcpV[x >> 1] - 128;
239 const int uvval = c2 * u + c3 * v + 1081344;
240 dstpY[x + 0] =
CB((65536 * (srcpY[x + 0] - 16) + uvval) >> 16);
241 dstpY[x + 1] =
CB((65536 * (srcpY[x + 1] - 16) + uvval) >> 16);
242 dstpU[x >> 1] =
CB((c4 * u + c5 * v + 8421376) >> 16);
243 dstpV[x >> 1] =
CB((c6 * u + c7 * v + 8421376) >> 16);
247 srcpU += src_pitchUV;
248 srcpV += src_pitchUV;
249 dstpU += dst_pitchUV;
250 dstpV += dst_pitchUV;
257 const unsigned char *srcpU = src->
data[1];
258 const unsigned char *srcpV = src->
data[2];
259 const unsigned char *srcpY = src->
data[0];
260 const unsigned char *srcpN = src->
data[0] + src->
linesize[0];
261 const int src_pitchY = src->
linesize[0];
262 const int src_pitchUV = src->
linesize[1];
265 unsigned char *dstpU = dst->
data[1];
266 unsigned char *dstpV = dst->
data[2];
267 unsigned char *dstpY = dst->
data[0];
269 const int dst_pitchY = dst->
linesize[0];
270 const int dst_pitchUV = dst->
linesize[1];
279 for (y = 0; y <
height; y += 2) {
280 for (x = 0; x <
width; x += 2) {
281 const int u = srcpU[x >> 1] - 128;
282 const int v = srcpV[x >> 1] - 128;
283 const int uvval = c2 * u + c3 * v + 1081344;
284 dstpY[x + 0] =
CB((65536 * (srcpY[x + 0] - 16) + uvval) >> 16);
285 dstpY[x + 1] =
CB((65536 * (srcpY[x + 1] - 16) + uvval) >> 16);
286 dstpN[x + 0] =
CB((65536 * (srcpN[x + 0] - 16) + uvval) >> 16);
287 dstpN[x + 1] =
CB((65536 * (srcpN[x + 1] - 16) + uvval) >> 16);
288 dstpU[x >> 1] =
CB((c4 * u + c5 * v + 8421376) >> 16);
289 dstpV[x >> 1] =
CB((c6 * u + c7 * v + 8421376) >> 16);
291 srcpY += src_pitchY << 1;
292 dstpY += dst_pitchY << 1;
293 srcpN += src_pitchY << 1;
294 dstpN += dst_pitchY << 1;
295 srcpU += src_pitchUV;
296 srcpV += src_pitchUV;
297 dstpU += dst_pitchUV;
298 dstpV += dst_pitchUV;
355 av_log(ctx,
AV_LOG_ERROR,
"Input frame does not specify a supported colorspace, and none has been specified as source either\n");
358 color->
mode = source * 4 + color->
dest;
360 color->
mode = color->source * 4 + color->
dest;
362 switch(color->
dest) {
401 .
name =
"colormatrix",
406 .
inputs = colormatrix_inputs,
407 .
outputs = colormatrix_outputs,
408 .priv_class = &colormatrix_class,