38#define NS(n) ((n) < 0 ? (int)((n)*65536.0-0.5+DBL_EPSILON) : (int)((n)*65536.0+0.5))
39#define CB(n) av_clip_uint8(n)
42 { +0.7152, +0.0722, +0.2126 },
43 { +0.5900, +0.1100, +0.3000 },
44 { +0.5870, +0.1140, +0.2990 },
45 { +0.7010, +0.0870, +0.2120 },
46 { +0.6780, +0.0593, +0.2627 },
79#define OFFSET(x) offsetof(ColorMatrixContext, x)
80#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
136 for (
i = 0;
i < 3;
i++)
137 for (j = 0; j < 3; j++)
138 cm[
i][j] = yuv[
i][0] *
rgb[0][j] + yuv[
i][1] *
rgb[1][j] + yuv[
i][2] *
rgb[2][j];
144 double yuv_coeff[5][3][3];
145 double rgb_coeffd[5][3][3];
146 double yuv_convertd[25][3][3];
147 double bscale, rscale;
150 for (
i = 0;
i < 5;
i++) {
154 bscale = 0.5 / (yuv_coeff[
i][0][1] - 1.0);
155 rscale = 0.5 / (yuv_coeff[
i][0][2] - 1.0);
156 yuv_coeff[
i][1][0] = bscale * yuv_coeff[
i][0][0];
157 yuv_coeff[
i][1][1] = 0.5;
158 yuv_coeff[
i][1][2] = bscale * yuv_coeff[
i][0][2];
159 yuv_coeff[
i][2][0] = rscale * yuv_coeff[
i][0][0];
160 yuv_coeff[
i][2][1] = rscale * yuv_coeff[
i][0][1];
161 yuv_coeff[
i][2][2] = 0.5;
163 for (
i = 0;
i < 5;
i++)
165 for (
i = 0;
i < 5;
i++) {
166 for (j = 0; j < 5; j++) {
168 for (k = 0; k < 3; k++) {
169 color->yuv_convert[v][k][0] =
NS(yuv_convertd[v][k][0]);
170 color->yuv_convert[v][k][1] =
NS(yuv_convertd[v][k][1]);
171 color->yuv_convert[v][k][2] =
NS(yuv_convertd[v][k][2]);
173 if (
color->yuv_convert[v][0][0] != 65536 ||
color->yuv_convert[v][1][0] != 0 ||
174 color->yuv_convert[v][2][0] != 0) {
182static const char *
const color_modes[] = {
"bt709",
"fcc",
"bt601",
"smpte240m",
"bt2020"};
210 const int src_pitch =
src->linesize[0];
211 const int dst_pitch =
dst->linesize[0];
214 const unsigned char *srcp =
src->data[0] +
slice_start * src_pitch;
216 const int c2 = td->
c2;
217 const int c3 = td->
c3;
218 const int c4 = td->
c4;
219 const int c5 = td->
c5;
220 const int c6 = td->
c6;
221 const int c7 = td->
c7;
225 for (x = 0; x <
width; x += 4) {
226 const int u = srcp[x + 0] - 128;
227 const int v = srcp[x + 2] - 128;
228 const int uvval =
c2 *
u + c3 * v + 1081344;
229 dstp[x + 0] =
CB((c4 *
u + c5 * v + 8421376) >> 16);
230 dstp[x + 1] =
CB((65536 * (srcp[x + 1] - 16) + uvval) >> 16);
231 dstp[x + 2] =
CB((c6 *
u + c7 * v + 8421376) >> 16);
232 dstp[x + 3] =
CB((65536 * (srcp[x + 3] - 16) + uvval) >> 16);
250 const int src_pitchY =
src->linesize[0];
251 const int src_pitchUV =
src->linesize[1];
252 const unsigned char *srcpU =
src->data[1] +
slice_start * src_pitchUV;
253 const unsigned char *srcpV =
src->data[2] +
slice_start * src_pitchUV;
254 const unsigned char *srcpY =
src->data[0] +
slice_start * src_pitchY;
255 const int dst_pitchY =
dst->linesize[0];
256 const int dst_pitchUV =
dst->linesize[1];
260 const int c2 = td->
c2;
261 const int c3 = td->
c3;
262 const int c4 = td->
c4;
263 const int c5 = td->
c5;
264 const int c6 = td->
c6;
265 const int c7 = td->
c7;
269 for (x = 0; x <
width; x++) {
270 const int u = srcpU[x] - 128;
271 const int v = srcpV[x] - 128;
272 const int uvval =
c2 *
u + c3 * v + 1081344;
273 dstpY[x] =
CB((65536 * (srcpY[x] - 16) + uvval) >> 16);
274 dstpU[x] =
CB((c4 *
u + c5 * v + 8421376) >> 16);
275 dstpV[x] =
CB((c6 *
u + c7 * v + 8421376) >> 16);
279 srcpU += src_pitchUV;
280 srcpV += src_pitchUV;
281 dstpU += dst_pitchUV;
282 dstpV += dst_pitchUV;
297 const int src_pitchY =
src->linesize[0];
298 const int src_pitchUV =
src->linesize[1];
299 const unsigned char *srcpU =
src->data[1] +
slice_start * src_pitchUV;
300 const unsigned char *srcpV =
src->data[2] +
slice_start * src_pitchUV;
301 const unsigned char *srcpY =
src->data[0] +
slice_start * src_pitchY;
302 const int dst_pitchY =
dst->linesize[0];
303 const int dst_pitchUV =
dst->linesize[1];
307 const int c2 = td->
c2;
308 const int c3 = td->
c3;
309 const int c4 = td->
c4;
310 const int c5 = td->
c5;
311 const int c6 = td->
c6;
312 const int c7 = td->
c7;
316 for (x = 0; x <
width; x += 2) {
317 const int u = srcpU[x >> 1] - 128;
318 const int v = srcpV[x >> 1] - 128;
319 const int uvval =
c2 *
u + c3 * v + 1081344;
320 dstpY[x + 0] =
CB((65536 * (srcpY[x + 0] - 16) + uvval) >> 16);
321 dstpY[x + 1] =
CB((65536 * (srcpY[x + 1] - 16) + uvval) >> 16);
322 dstpU[x >> 1] =
CB((c4 *
u + c5 * v + 8421376) >> 16);
323 dstpV[x >> 1] =
CB((c6 *
u + c7 * v + 8421376) >> 16);
327 srcpU += src_pitchUV;
328 srcpV += src_pitchUV;
329 dstpU += dst_pitchUV;
330 dstpV += dst_pitchUV;
345 const int src_pitchY =
src->linesize[0];
346 const int src_pitchUV =
src->linesize[1];
347 const int dst_pitchY =
dst->linesize[0];
348 const int dst_pitchUV =
dst->linesize[1];
349 const unsigned char *srcpY =
src->data[0] + src_pitchY *
slice_start;
350 const unsigned char *srcpU =
src->data[1] + src_pitchUV * (
slice_start >> 1);
351 const unsigned char *srcpV =
src->data[2] + src_pitchUV * (
slice_start >> 1);
352 const unsigned char *srcpN =
src->data[0] + src_pitchY * (
slice_start + 1);
353 unsigned char *dstpU =
dst->data[1] + dst_pitchUV * (
slice_start >> 1);
354 unsigned char *dstpV =
dst->data[2] + dst_pitchUV * (
slice_start >> 1);
356 unsigned char *dstpN =
dst->data[0] + dst_pitchY * (
slice_start + 1);
357 const int c2 = td->
c2;
358 const int c3 = td->
c3;
359 const int c4 = td->
c4;
360 const int c5 = td->
c5;
361 const int c6 = td->
c6;
362 const int c7 = td->
c7;
366 for (x = 0; x <
width; x += 2) {
367 const int u = srcpU[x >> 1] - 128;
368 const int v = srcpV[x >> 1] - 128;
369 const int uvval =
c2 *
u + c3 * v + 1081344;
370 dstpY[x + 0] =
CB((65536 * (srcpY[x + 0] - 16) + uvval) >> 16);
371 dstpY[x + 1] =
CB((65536 * (srcpY[x + 1] - 16) + uvval) >> 16);
372 dstpN[x + 0] =
CB((65536 * (srcpN[x + 0] - 16) + uvval) >> 16);
373 dstpN[x + 1] =
CB((65536 * (srcpN[x + 1] - 16) + uvval) >> 16);
374 dstpU[x >> 1] =
CB((c4 *
u + c5 * v + 8421376) >> 16);
375 dstpV[x >> 1] =
CB((c6 *
u + c7 * v + 8421376) >> 16);
377 srcpY += src_pitchY << 1;
378 dstpY += dst_pitchY << 1;
379 srcpN += src_pitchY << 1;
380 dstpN += dst_pitchY << 1;
381 srcpU += src_pitchUV;
382 srcpV += src_pitchUV;
383 dstpU += dst_pitchUV;
384 dstpV += dst_pitchUV;
433 av_log(
ctx,
AV_LOG_ERROR,
"Input frame does not specify a supported colorspace, and none has been specified as source either\n");
441 switch(
color->dest) {
485 .p.name =
"colormatrix",
487 .p.priv_class = &colormatrix_class,
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
static int config_input(AVFilterLink *inlink)
const FFFilter ff_vf_colormatrix
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
int ff_filter_execute(AVFilterContext *ctx, avfilter_action_func *func, void *arg, int *ret, int nb_jobs)
int ff_filter_get_nb_threads(AVFilterContext *ctx)
Get number of threads for current filter instance.
Main libavfilter public API header.
#define i(width, name, range_min, range_max)
static int filter_frame(DBEDecodeContext *s, AVFrame *frame)
int(* init)(AVBSFContext *ctx)
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
@ AV_OPT_TYPE_INT
Underlying C type is int.
#define AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC
Some filters support a generic "enable" expression option that can be used to enable or disable a fil...
#define AVFILTER_FLAG_SLICE_THREADS
The filter supports multithreading by splitting frames into multiple parts and processing them concur...
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
#define AV_LOG_VERBOSE
Detailed information.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
#define u(width, name, range_min, range_max)
#define FILTER_INPUTS(array)
#define FILTER_OUTPUTS(array)
static int ff_slice_pos(int total, int jobnr, int nb_jobs)
Compute the boundary index for a slice when work of size total is split into nb_jobs slices.
#define FILTER_PIXFMTS(...)
#define AVFILTER_DEFINE_CLASS(fname)
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
static int slice_end(AVCodecContext *avctx, AVFrame *pict, int *got_output)
Handle slice ends.
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
@ AV_PIX_FMT_YUV422P
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
@ AV_PIX_FMT_UYVY422
packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1
@ AV_PIX_FMT_YUV444P
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
AVColorSpace
YUV colorspace type.
@ AVCOL_SPC_BT709
also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / derived in SMPTE RP 177 Annex B
@ AVCOL_SPC_BT470BG
also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601
@ AVCOL_SPC_BT2020_CL
ITU-R BT2020 constant luminance system.
@ AVCOL_SPC_BT2020_NCL
ITU-R BT2020 non-constant luminance system.
@ AVCOL_SPC_SMPTE170M
also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC / functionally identical to above
@ AVCOL_SPC_FCC
FCC Title 47 Code of Federal Regulations 73.682 (a)(20)
@ AVCOL_SPC_SMPTE240M
derived from 170M primaries and D65 white point, 170M is derived from BT470 System M's primaries
Describe the class of an AVClass context structure.
A link between two filters.
int w
agreed upon image width
int h
agreed upon image height
AVFilterContext * dst
dest filter
int format
agreed upon media format
A filter pad used for either input or output.
This structure describes decoded (raw) audio or video data.
enum AVColorSpace colorspace
YUV colorspace type.
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames,...
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
uint8_t log2_chroma_w
Amount to shift the luma width right to find the chroma width.
uint8_t log2_chroma_h
Amount to shift the luma height right to find the chroma height.
int yuv_convert[25][3][3]
Used for passing data between threads.
static AVFormatContext * ctx
static const double yuv_coeff_luma[5][3]
static int process_slice_yuv420p(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
static int process_slice_yuv444p(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
static int process_slice_yuv422p(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
static int filter_frame(AVFilterLink *link, AVFrame *in)
static void calc_coefficients(AVFilterContext *ctx)
static int config_input(AVFilterLink *inlink)
static const char *const color_modes[]
static void inverse3x3(double im[3][3], double m[3][3])
static const AVOption colormatrix_options[]
static void solve_coefficients(double cm[3][3], double rgb[3][3], double yuv[3][3])
static const AVFilterPad colormatrix_inputs[]
static int process_slice_uyvy422(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
const AVFilterPad ff_video_default_filterpad[1]
An AVFilterPad array whose only entry has name "default" and is of type AVMEDIA_TYPE_VIDEO.
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
static int slice_start(SliceContext *sc, VVCContext *s, VVCFrameContext *fc, const CodedBitstreamUnit *unit, const int is_first_slice)