Signed-off-by: Thomas Mundt <loudmax@yahoo.de>
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
... | ... |
@@ -40,11 +40,12 @@ |
40 | 40 |
#define NS(n) ((n) < 0 ? (int)((n)*65536.0-0.5+DBL_EPSILON) : (int)((n)*65536.0+0.5)) |
41 | 41 |
#define CB(n) av_clip_uint8(n) |
42 | 42 |
|
43 |
-static const double yuv_coeff_luma[4][3] = { |
|
43 |
+static const double yuv_coeff_luma[5][3] = { |
|
44 | 44 |
{ +0.7152, +0.0722, +0.2126 }, // Rec.709 (0) |
45 | 45 |
{ +0.5900, +0.1100, +0.3000 }, // FCC (1) |
46 | 46 |
{ +0.5870, +0.1140, +0.2990 }, // Rec.601 (ITU-R BT.470-2/SMPTE 170M) (2) |
47 | 47 |
{ +0.7010, +0.0870, +0.2120 }, // SMPTE 240M (3) |
48 |
+ { +0.6780, +0.0593, +0.2627 }, // Rec.2020 (4) |
|
48 | 49 |
}; |
49 | 50 |
|
50 | 51 |
enum ColorMode { |
... | ... |
@@ -53,12 +54,13 @@ enum ColorMode { |
53 | 53 |
COLOR_MODE_FCC, |
54 | 54 |
COLOR_MODE_BT601, |
55 | 55 |
COLOR_MODE_SMPTE240M, |
56 |
+ COLOR_MODE_BT2020, |
|
56 | 57 |
COLOR_MODE_COUNT |
57 | 58 |
}; |
58 | 59 |
|
59 | 60 |
typedef struct { |
60 | 61 |
const AVClass *class; |
61 |
- int yuv_convert[16][3][3]; |
|
62 |
+ int yuv_convert[25][3][3]; |
|
62 | 63 |
int interlaced; |
63 | 64 |
int source, dest; ///< ColorMode |
64 | 65 |
int mode; |
... | ... |
@@ -89,6 +91,7 @@ static const AVOption colormatrix_options[] = { |
89 | 89 |
{ "bt470bg", "set BT.470 colorspace", 0, AV_OPT_TYPE_CONST, {.i64=COLOR_MODE_BT601}, .flags=FLAGS, .unit="color_mode" }, |
90 | 90 |
{ "smpte170m", "set SMTPE-170M colorspace", 0, AV_OPT_TYPE_CONST, {.i64=COLOR_MODE_BT601}, .flags=FLAGS, .unit="color_mode" }, |
91 | 91 |
{ "smpte240m", "set SMPTE-240M colorspace", 0, AV_OPT_TYPE_CONST, {.i64=COLOR_MODE_SMPTE240M}, .flags=FLAGS, .unit="color_mode" }, |
92 |
+ { "bt2020", "set BT.2020 colorspace", 0, AV_OPT_TYPE_CONST, {.i64=COLOR_MODE_BT2020}, .flags=FLAGS, .unit="color_mode" }, |
|
92 | 93 |
{ NULL } |
93 | 94 |
}; |
94 | 95 |
|
... | ... |
@@ -140,13 +143,13 @@ static void solve_coefficients(double cm[3][3], double rgb[3][3], double yuv[3][ |
140 | 140 |
static void calc_coefficients(AVFilterContext *ctx) |
141 | 141 |
{ |
142 | 142 |
ColorMatrixContext *color = ctx->priv; |
143 |
- double yuv_coeff[4][3][3]; |
|
144 |
- double rgb_coeffd[4][3][3]; |
|
145 |
- double yuv_convertd[16][3][3]; |
|
143 |
+ double yuv_coeff[5][3][3]; |
|
144 |
+ double rgb_coeffd[5][3][3]; |
|
145 |
+ double yuv_convertd[25][3][3]; |
|
146 | 146 |
double bscale, rscale; |
147 | 147 |
int v = 0; |
148 | 148 |
int i, j, k; |
149 |
- for (i = 0; i < 4; i++) { |
|
149 |
+ for (i = 0; i < 5; i++) { |
|
150 | 150 |
yuv_coeff[i][0][0] = yuv_coeff_luma[i][0]; |
151 | 151 |
yuv_coeff[i][0][1] = yuv_coeff_luma[i][1]; |
152 | 152 |
yuv_coeff[i][0][2] = yuv_coeff_luma[i][2]; |
... | ... |
@@ -159,10 +162,10 @@ static void calc_coefficients(AVFilterContext *ctx) |
159 | 159 |
yuv_coeff[i][2][1] = rscale * yuv_coeff[i][0][1]; |
160 | 160 |
yuv_coeff[i][2][2] = 0.5; |
161 | 161 |
} |
162 |
- for (i = 0; i < 4; i++) |
|
162 |
+ for (i = 0; i < 5; i++) |
|
163 | 163 |
inverse3x3(rgb_coeffd[i], yuv_coeff[i]); |
164 |
- for (i = 0; i < 4; i++) { |
|
165 |
- for (j = 0; j < 4; j++) { |
|
164 |
+ for (i = 0; i < 5; i++) { |
|
165 |
+ for (j = 0; j < 5; j++) { |
|
166 | 166 |
solve_coefficients(yuv_convertd[v], rgb_coeffd[i], yuv_coeff[j]); |
167 | 167 |
for (k = 0; k < 3; k++) { |
168 | 168 |
color->yuv_convert[v][k][0] = NS(yuv_convertd[v][k][0]); |
... | ... |
@@ -178,7 +181,7 @@ static void calc_coefficients(AVFilterContext *ctx) |
178 | 178 |
} |
179 | 179 |
} |
180 | 180 |
|
181 |
-static const char * const color_modes[] = {"bt709", "fcc", "bt601", "smpte240m"}; |
|
181 |
+static const char * const color_modes[] = {"bt709", "fcc", "bt601", "smpte240m", "bt2020"}; |
|
182 | 182 |
|
183 | 183 |
static av_cold int init(AVFilterContext *ctx) |
184 | 184 |
{ |
... | ... |
@@ -441,20 +444,23 @@ static int filter_frame(AVFilterLink *link, AVFrame *in) |
441 | 441 |
case AVCOL_SPC_SMPTE240M : source = COLOR_MODE_SMPTE240M ; break; |
442 | 442 |
case AVCOL_SPC_BT470BG : source = COLOR_MODE_BT601 ; break; |
443 | 443 |
case AVCOL_SPC_SMPTE170M : source = COLOR_MODE_BT601 ; break; |
444 |
+ case AVCOL_SPC_BT2020_NCL: source = COLOR_MODE_BT2020 ; break; |
|
445 |
+ case AVCOL_SPC_BT2020_CL : source = COLOR_MODE_BT2020 ; break; |
|
444 | 446 |
default : |
445 | 447 |
av_log(ctx, AV_LOG_ERROR, "Input frame does not specify a supported colorspace, and none has been specified as source either\n"); |
446 | 448 |
av_frame_free(&out); |
447 | 449 |
return AVERROR(EINVAL); |
448 | 450 |
} |
449 |
- color->mode = source * 4 + color->dest; |
|
451 |
+ color->mode = source * 5 + color->dest; |
|
450 | 452 |
} else |
451 |
- color->mode = color->source * 4 + color->dest; |
|
453 |
+ color->mode = color->source * 5 + color->dest; |
|
452 | 454 |
|
453 | 455 |
switch(color->dest) { |
454 |
- case COLOR_MODE_BT709 : av_frame_set_colorspace(out, AVCOL_SPC_BT709) ; break; |
|
455 |
- case COLOR_MODE_FCC : av_frame_set_colorspace(out, AVCOL_SPC_FCC) ; break; |
|
456 |
- case COLOR_MODE_SMPTE240M: av_frame_set_colorspace(out, AVCOL_SPC_SMPTE240M); break; |
|
457 |
- case COLOR_MODE_BT601 : av_frame_set_colorspace(out, AVCOL_SPC_BT470BG) ; break; |
|
456 |
+ case COLOR_MODE_BT709 : av_frame_set_colorspace(out, AVCOL_SPC_BT709) ; break; |
|
457 |
+ case COLOR_MODE_FCC : av_frame_set_colorspace(out, AVCOL_SPC_FCC) ; break; |
|
458 |
+ case COLOR_MODE_SMPTE240M: av_frame_set_colorspace(out, AVCOL_SPC_SMPTE240M) ; break; |
|
459 |
+ case COLOR_MODE_BT601 : av_frame_set_colorspace(out, AVCOL_SPC_BT470BG) ; break; |
|
460 |
+ case COLOR_MODE_BT2020 : av_frame_set_colorspace(out, AVCOL_SPC_BT2020_NCL); break; |
|
458 | 461 |
} |
459 | 462 |
|
460 | 463 |
td.src = in; |