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
131 for (i = 0; i < 3; i++)
132 for (j = 0; j < 3; j++)
133 cm[i][j] = yuv[i][0] * rgb[0][j] + yuv[i][1] * rgb[1][j] + yuv[i][2] * rgb[2][j];
139 double rgb_coeffd[4][3][3];
140 double yuv_convertd[16][3][3];
144 for (i = 0; i < 4; i++)
146 for (i = 0; i < 4; i++) {
147 for (j = 0; j < 4; j++) {
149 for (k = 0; k < 3; k++) {
163 static const char *
const color_modes[] = {
"bt709",
"fcc",
"bt601",
"smpte240m"};
174 if (color->source == color->
dest) {
175 av_log(ctx,
AV_LOG_ERROR,
"Source and destination color space must not be identical\n");
185 const unsigned char *
srcp = src->
data[0];
199 for (y = 0; y <
height; y++) {
200 for (x = 0; x <
width; x += 4) {
201 const int u = srcp[x + 0] - 128;
202 const int v = srcp[x + 2] - 128;
203 const int uvval = c2 * u + c3 * v + 1081344;
204 dstp[x + 0] =
CB((c4 * u + c5 * v + 8421376) >> 16);
205 dstp[x + 1] =
CB((65536 * (srcp[x + 1] - 16) + uvval) >> 16);
206 dstp[x + 2] =
CB((c6 * u + c7 * v + 8421376) >> 16);
207 dstp[x + 3] =
CB((65536 * (srcp[x + 3] - 16) + uvval) >> 16);
217 const unsigned char *srcpU = src->
data[1];
218 const unsigned char *srcpV = src->
data[2];
219 const unsigned char *srcpY = src->
data[0];
220 const int src_pitchY = src->
linesize[0];
221 const int src_pitchUV = src->
linesize[1];
224 unsigned char *dstpU = dst->
data[1];
225 unsigned char *dstpV = dst->
data[2];
226 unsigned char *dstpY = dst->
data[0];
227 const int dst_pitchY = dst->
linesize[0];
228 const int dst_pitchUV = dst->
linesize[1];
237 for (y = 0; y <
height; y++) {
238 for (x = 0; x <
width; x += 2) {
239 const int u = srcpU[x >> 1] - 128;
240 const int v = srcpV[x >> 1] - 128;
241 const int uvval = c2 * u + c3 * v + 1081344;
242 dstpY[x + 0] =
CB((65536 * (srcpY[x + 0] - 16) + uvval) >> 16);
243 dstpY[x + 1] =
CB((65536 * (srcpY[x + 1] - 16) + uvval) >> 16);
244 dstpU[x >> 1] =
CB((c4 * u + c5 * v + 8421376) >> 16);
245 dstpV[x >> 1] =
CB((c6 * u + c7 * v + 8421376) >> 16);
249 srcpU += src_pitchUV;
250 srcpV += src_pitchUV;
251 dstpU += dst_pitchUV;
252 dstpV += dst_pitchUV;
259 const unsigned char *srcpU = src->
data[1];
260 const unsigned char *srcpV = src->
data[2];
261 const unsigned char *srcpY = src->
data[0];
262 const unsigned char *srcpN = src->
data[0] + src->
linesize[0];
263 const int src_pitchY = src->
linesize[0];
264 const int src_pitchUV = src->
linesize[1];
267 unsigned char *dstpU = dst->
data[1];
268 unsigned char *dstpV = dst->
data[2];
269 unsigned char *dstpY = dst->
data[0];
271 const int dst_pitchY = dst->
linesize[0];
272 const int dst_pitchUV = dst->
linesize[1];
281 for (y = 0; y <
height; y += 2) {
282 for (x = 0; x <
width; x += 2) {
283 const int u = srcpU[x >> 1] - 128;
284 const int v = srcpV[x >> 1] - 128;
285 const int uvval = c2 * u + c3 * v + 1081344;
286 dstpY[x + 0] =
CB((65536 * (srcpY[x + 0] - 16) + uvval) >> 16);
287 dstpY[x + 1] =
CB((65536 * (srcpY[x + 1] - 16) + uvval) >> 16);
288 dstpN[x + 0] =
CB((65536 * (srcpN[x + 0] - 16) + uvval) >> 16);
289 dstpN[x + 1] =
CB((65536 * (srcpN[x + 1] - 16) + uvval) >> 16);
290 dstpU[x >> 1] =
CB((c4 * u + c5 * v + 8421376) >> 16);
291 dstpV[x >> 1] =
CB((c6 * u + c7 * v + 8421376) >> 16);
293 srcpY += src_pitchY << 1;
294 dstpY += dst_pitchY << 1;
295 srcpN += src_pitchY << 1;
296 dstpN += dst_pitchY << 1;
297 srcpU += src_pitchUV;
298 srcpV += src_pitchUV;
299 dstpU += dst_pitchUV;
300 dstpV += dst_pitchUV;
358 av_log(ctx,
AV_LOG_ERROR,
"Input frame does not specify a supported colorspace, and none has been specified as source either\n");
362 color->
mode = source * 4 + color->
dest;
364 color->
mode = color->source * 4 + color->
dest;
366 switch(color->
dest) {
405 .
name =
"colormatrix",
410 .
inputs = colormatrix_inputs,
411 .
outputs = colormatrix_outputs,
412 .priv_class = &colormatrix_class,