Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
F
ffmpeg.wasm-core
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Linshizhi
ffmpeg.wasm-core
Commits
431117dc
Commit
431117dc
authored
May 03, 2016
by
Ronald S. Bultje
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
vf_colorspace: add floyd-steinberg dithering option to full conversion.
parent
9486de5a
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
221 additions
and
3 deletions
+221
-3
filters.texi
doc/filters.texi
+13
-0
colorspacedsp.c
libavfilter/colorspacedsp.c
+13
-0
colorspacedsp.h
libavfilter/colorspacedsp.h
+6
-0
colorspacedsp_template.c
libavfilter/colorspacedsp_template.c
+128
-0
vf_colorspace.c
libavfilter/vf_colorspace.c
+61
-3
No files found.
doc/filters.texi
View file @
431117dc
...
@@ -5145,6 +5145,19 @@ YUV 4:4:4 planar 12-bits
...
@@ -5145,6 +5145,19 @@ YUV 4:4:4 planar 12-bits
Do a fast conversion, which skips gamma/primary correction. This will take
Do a fast conversion, which skips gamma/primary correction. This will take
significantly less CPU, but will be mathematically incorrect. To get output
significantly less CPU, but will be mathematically incorrect. To get output
compatible with that produced by the colormatrix filter, use fast=1.
compatible with that produced by the colormatrix filter, use fast=1.
@item dither
Specify dithering mode.
The accepted values are:
@table @samp
@item none
No dithering
@item fsb
Floyd-Steinberg dithering
@end table
@end table
@end table
The filter converts the transfer characteristics, color space and color
The filter converts the transfer characteristics, color space and color
...
...
libavfilter/colorspacedsp.c
View file @
431117dc
...
@@ -20,6 +20,10 @@
...
@@ -20,6 +20,10 @@
#include "colorspacedsp.h"
#include "colorspacedsp.h"
/*
* SS_W/H stands for "subsampling_w/h"
* it's analogous to AVPixFmtDescriptor->log2_chroma_w/h.
*/
#define SS_W 0
#define SS_W 0
#define SS_H 0
#define SS_H 0
...
@@ -114,6 +118,15 @@ void ff_colorspacedsp_init(ColorSpaceDSPContext *dsp)
...
@@ -114,6 +118,15 @@ void ff_colorspacedsp_init(ColorSpaceDSPContext *dsp)
init_rgb2yuv_fn
(
1
,
10
);
init_rgb2yuv_fn
(
1
,
10
);
init_rgb2yuv_fn
(
2
,
12
);
init_rgb2yuv_fn
(
2
,
12
);
#define init_rgb2yuv_fsb_fn(idx, bit) \
dsp->rgb2yuv_fsb[idx][0] = rgb2yuv_fsb_444p##bit##_c; \
dsp->rgb2yuv_fsb[idx][1] = rgb2yuv_fsb_422p##bit##_c; \
dsp->rgb2yuv_fsb[idx][2] = rgb2yuv_fsb_420p##bit##_c
init_rgb2yuv_fsb_fn
(
0
,
8
);
init_rgb2yuv_fsb_fn
(
1
,
10
);
init_rgb2yuv_fsb_fn
(
2
,
12
);
#define init_yuv2yuv_fn(idx1, idx2, bit1, bit2) \
#define init_yuv2yuv_fn(idx1, idx2, bit1, bit2) \
dsp->yuv2yuv[idx1][idx2][0] = yuv2yuv_444p##bit1##to##bit2##_c; \
dsp->yuv2yuv[idx1][idx2][0] = yuv2yuv_444p##bit1##to##bit2##_c; \
dsp->yuv2yuv[idx1][idx2][1] = yuv2yuv_422p##bit1##to##bit2##_c; \
dsp->yuv2yuv[idx1][idx2][1] = yuv2yuv_422p##bit1##to##bit2##_c; \
...
...
libavfilter/colorspacedsp.h
View file @
431117dc
...
@@ -32,6 +32,11 @@ typedef void (*rgb2yuv_fn)(uint8_t *yuv[3], ptrdiff_t yuv_stride[3],
...
@@ -32,6 +32,11 @@ typedef void (*rgb2yuv_fn)(uint8_t *yuv[3], ptrdiff_t yuv_stride[3],
int16_t
*
rgb
[
3
],
ptrdiff_t
rgb_stride
,
int16_t
*
rgb
[
3
],
ptrdiff_t
rgb_stride
,
int
w
,
int
h
,
const
int16_t
rgb2yuv_coeffs
[
3
][
3
][
8
],
int
w
,
int
h
,
const
int16_t
rgb2yuv_coeffs
[
3
][
3
][
8
],
const
int16_t
yuv_offset
[
8
]);
const
int16_t
yuv_offset
[
8
]);
typedef
void
(
*
rgb2yuv_fsb_fn
)(
uint8_t
*
yuv
[
3
],
ptrdiff_t
yuv_stride
[
3
],
int16_t
*
rgb
[
3
],
ptrdiff_t
rgb_stride
,
int
w
,
int
h
,
const
int16_t
rgb2yuv_coeffs
[
3
][
3
][
8
],
const
int16_t
yuv_offset
[
8
],
int
*
rnd
[
3
][
2
]);
typedef
void
(
*
yuv2yuv_fn
)(
uint8_t
*
yuv_out
[
3
],
ptrdiff_t
yuv_out_stride
[
3
],
typedef
void
(
*
yuv2yuv_fn
)(
uint8_t
*
yuv_out
[
3
],
ptrdiff_t
yuv_out_stride
[
3
],
uint8_t
*
yuv_in
[
3
],
ptrdiff_t
yuv_in_stride
[
3
],
uint8_t
*
yuv_in
[
3
],
ptrdiff_t
yuv_in_stride
[
3
],
int
w
,
int
h
,
const
int16_t
yuv2yuv_coeffs
[
3
][
3
][
8
],
int
w
,
int
h
,
const
int16_t
yuv2yuv_coeffs
[
3
][
3
][
8
],
...
@@ -40,6 +45,7 @@ typedef void (*yuv2yuv_fn)(uint8_t *yuv_out[3], ptrdiff_t yuv_out_stride[3],
...
@@ -40,6 +45,7 @@ typedef void (*yuv2yuv_fn)(uint8_t *yuv_out[3], ptrdiff_t yuv_out_stride[3],
typedef
struct
ColorSpaceDSPContext
{
typedef
struct
ColorSpaceDSPContext
{
yuv2rgb_fn
yuv2rgb
[
3
/* 0: 8bit, 1: 10bit, 2: 12bit */
][
3
/* 0: 444, 1: 422, 2: 420 */
];
yuv2rgb_fn
yuv2rgb
[
3
/* 0: 8bit, 1: 10bit, 2: 12bit */
][
3
/* 0: 444, 1: 422, 2: 420 */
];
rgb2yuv_fn
rgb2yuv
[
3
/* 0: 8bit, 1: 10bit, 2: 12bit */
][
3
/* 0: 444, 1: 422, 2: 420 */
];
rgb2yuv_fn
rgb2yuv
[
3
/* 0: 8bit, 1: 10bit, 2: 12bit */
][
3
/* 0: 444, 1: 422, 2: 420 */
];
rgb2yuv_fsb_fn
rgb2yuv_fsb
[
3
/* 0: 8bit, 1: 10bit, 2: 12bit */
][
3
/* 0: 444, 1: 422, 2: 420 */
];
yuv2yuv_fn
yuv2yuv
[
3
/* in_depth */
][
3
/* out_depth */
][
3
/* 0: 444, 1: 422, 2: 420 */
];
yuv2yuv_fn
yuv2yuv
[
3
/* in_depth */
][
3
/* out_depth */
][
3
/* 0: 444, 1: 422, 2: 420 */
];
void
(
*
multiply3x3
)(
int16_t
*
data
[
3
],
ptrdiff_t
stride
,
void
(
*
multiply3x3
)(
int16_t
*
data
[
3
],
ptrdiff_t
stride
,
...
...
libavfilter/colorspacedsp_template.c
View file @
431117dc
...
@@ -199,6 +199,134 @@ static void fn(rgb2yuv)(uint8_t *_yuv[3], ptrdiff_t yuv_stride[3],
...
@@ -199,6 +199,134 @@ static void fn(rgb2yuv)(uint8_t *_yuv[3], ptrdiff_t yuv_stride[3],
}
}
}
}
/* floyd-steinberg dithering - for any mid-top pixel A in a 3x2 block of pixels:
* 1 A 2
* 3 4 5
* the rounding error is distributed over the neighbouring pixels:
* 2: 7/16th, 3: 3/16th, 4: 5/16th and 5: 1/16th
*/
static
void
fn
(
rgb2yuv_fsb
)(
uint8_t
*
_yuv
[
3
],
ptrdiff_t
yuv_stride
[
3
],
int16_t
*
rgb
[
3
],
ptrdiff_t
s
,
int
w
,
int
h
,
const
int16_t
rgb2yuv_coeffs
[
3
][
3
][
8
],
const
int16_t
yuv_offset
[
8
],
int
*
rnd_scratch
[
3
][
2
])
{
pixel
**
yuv
=
(
pixel
**
)
_yuv
;
pixel
*
yuv0
=
yuv
[
0
],
*
yuv1
=
yuv
[
1
],
*
yuv2
=
yuv
[
2
];
const
int16_t
*
rgb0
=
rgb
[
0
],
*
rgb1
=
rgb
[
1
],
*
rgb2
=
rgb
[
2
];
int
y
,
x
;
const
int
sh
=
29
-
BIT_DEPTH
;
const
int
rnd
=
1
<<
(
sh
-
1
);
int
cry
=
rgb2yuv_coeffs
[
0
][
0
][
0
];
int
cgy
=
rgb2yuv_coeffs
[
0
][
1
][
0
];
int
cby
=
rgb2yuv_coeffs
[
0
][
2
][
0
];
int
cru
=
rgb2yuv_coeffs
[
1
][
0
][
0
];
int
cgu
=
rgb2yuv_coeffs
[
1
][
1
][
0
];
int
cburv
=
rgb2yuv_coeffs
[
1
][
2
][
0
];
int
cgv
=
rgb2yuv_coeffs
[
2
][
1
][
0
];
int
cbv
=
rgb2yuv_coeffs
[
2
][
2
][
0
];
ptrdiff_t
s0
=
yuv_stride
[
0
]
/
sizeof
(
pixel
);
const
int
uv_offset
=
128
<<
(
BIT_DEPTH
-
8
);
unsigned
mask
=
(
1
<<
sh
)
-
1
;
for
(
x
=
0
;
x
<
w
;
x
++
)
{
rnd_scratch
[
0
][
0
][
x
]
=
rnd_scratch
[
0
][
1
][
x
]
=
rnd
;
}
av_assert2
(
rgb2yuv_coeffs
[
1
][
2
][
0
]
==
rgb2yuv_coeffs
[
2
][
0
][
0
]);
w
=
AV_CEIL_RSHIFT
(
w
,
SS_W
);
h
=
AV_CEIL_RSHIFT
(
h
,
SS_H
);
for
(
x
=
0
;
x
<
w
;
x
++
)
{
rnd_scratch
[
1
][
0
][
x
]
=
rnd_scratch
[
1
][
1
][
x
]
=
rnd_scratch
[
2
][
0
][
x
]
=
rnd_scratch
[
2
][
1
][
x
]
=
rnd
;
}
for
(
y
=
0
;
y
<
h
;
y
++
)
{
for
(
x
=
0
;
x
<
w
;
x
++
)
{
int
r00
=
rgb0
[
x
<<
SS_W
],
g00
=
rgb1
[
x
<<
SS_W
],
b00
=
rgb2
[
x
<<
SS_W
];
int
y00
;
#if SS_W == 1
int
r01
=
rgb0
[
x
*
2
+
1
],
g01
=
rgb1
[
x
*
2
+
1
],
b01
=
rgb2
[
x
*
2
+
1
];
int
y01
;
#if SS_H == 1
int
r10
=
rgb0
[
x
*
2
+
0
+
s
],
g10
=
rgb1
[
x
*
2
+
0
+
s
],
b10
=
rgb2
[
x
*
2
+
0
+
s
];
int
r11
=
rgb0
[
x
*
2
+
1
+
s
],
g11
=
rgb1
[
x
*
2
+
1
+
s
],
b11
=
rgb2
[
x
*
2
+
1
+
s
];
int
y10
,
y11
;
#endif
#endif
int
u
,
v
,
diff
;
y00
=
r00
*
cry
+
g00
*
cgy
+
b00
*
cby
+
rnd_scratch
[
0
][
y
&
!
SS_H
][
x
<<
SS_W
];
diff
=
(
y00
&
mask
)
-
rnd
;
yuv0
[
x
<<
SS_W
]
=
av_clip_pixel
(
yuv_offset
[
0
]
+
(
y00
>>
sh
));
rnd_scratch
[
0
][
(
y
&
!
SS_H
)][(
x
<<
SS_W
)
+
1
]
+=
(
diff
*
7
+
8
)
>>
4
;
rnd_scratch
[
0
][
!
(
y
&
!
SS_H
)][(
x
<<
SS_W
)
-
1
]
+=
(
diff
*
3
+
8
)
>>
4
;
rnd_scratch
[
0
][
!
(
y
&
!
SS_H
)][(
x
<<
SS_W
)
+
0
]
+=
(
diff
*
5
+
8
)
>>
4
;
rnd_scratch
[
0
][
!
(
y
&
!
SS_H
)][(
x
<<
SS_W
)
+
1
]
+=
(
diff
*
1
+
8
)
>>
4
;
rnd_scratch
[
0
][
(
y
&
!
SS_H
)][(
x
<<
SS_W
)
+
0
]
=
rnd
;
#if SS_W == 1
y01
=
r01
*
cry
+
g01
*
cgy
+
b01
*
cby
+
rnd_scratch
[
0
][
y
&
!
SS_H
][
x
*
2
+
1
];
diff
=
(
y01
&
mask
)
-
rnd
;
yuv0
[
x
*
2
+
1
]
=
av_clip_pixel
(
yuv_offset
[
0
]
+
(
y01
>>
sh
));
rnd_scratch
[
0
][
(
y
&
!
SS_H
)][
x
*
2
+
2
]
+=
(
diff
*
7
+
8
)
>>
4
;
rnd_scratch
[
0
][
!
(
y
&
!
SS_H
)][
x
*
2
+
0
]
+=
(
diff
*
3
+
8
)
>>
4
;
rnd_scratch
[
0
][
!
(
y
&
!
SS_H
)][
x
*
2
+
1
]
+=
(
diff
*
5
+
8
)
>>
4
;
rnd_scratch
[
0
][
!
(
y
&
!
SS_H
)][
x
*
2
+
2
]
+=
(
diff
*
1
+
8
)
>>
4
;
rnd_scratch
[
0
][
(
y
&
!
SS_H
)][
x
*
2
+
1
]
=
rnd
;
#if SS_H == 1
y10
=
r10
*
cry
+
g10
*
cgy
+
b10
*
cby
+
rnd_scratch
[
0
][
1
][
x
*
2
+
0
];
diff
=
(
y10
&
mask
)
-
rnd
;
yuv0
[
x
*
2
+
0
+
s0
]
=
av_clip_pixel
(
yuv_offset
[
0
]
+
(
y10
>>
sh
));
rnd_scratch
[
0
][
1
][
x
*
2
+
1
]
+=
(
diff
*
7
+
8
)
>>
4
;
rnd_scratch
[
0
][
0
][
x
*
2
-
1
]
+=
(
diff
*
3
+
8
)
>>
4
;
rnd_scratch
[
0
][
0
][
x
*
2
+
0
]
+=
(
diff
*
5
+
8
)
>>
4
;
rnd_scratch
[
0
][
0
][
x
*
2
+
1
]
+=
(
diff
*
1
+
8
)
>>
4
;
rnd_scratch
[
0
][
1
][
x
*
2
+
0
]
=
rnd
;
y11
=
r11
*
cry
+
g11
*
cgy
+
b11
*
cby
+
rnd_scratch
[
0
][
1
][
x
*
2
+
1
];
diff
=
(
y11
&
mask
)
-
rnd
;
yuv0
[
x
*
2
+
1
+
s0
]
=
av_clip_pixel
(
yuv_offset
[
0
]
+
(
y11
>>
sh
));
rnd_scratch
[
0
][
1
][
x
*
2
+
2
]
+=
(
diff
*
7
+
8
)
>>
4
;
rnd_scratch
[
0
][
0
][
x
*
2
+
0
]
+=
(
diff
*
3
+
8
)
>>
4
;
rnd_scratch
[
0
][
0
][
x
*
2
+
1
]
+=
(
diff
*
5
+
8
)
>>
4
;
rnd_scratch
[
0
][
0
][
x
*
2
+
2
]
+=
(
diff
*
1
+
8
)
>>
4
;
rnd_scratch
[
0
][
1
][
x
*
2
+
1
]
=
rnd
;
#endif
#endif
u
=
avg
(
r00
,
r01
,
r10
,
r11
)
*
cru
+
avg
(
g00
,
g01
,
g10
,
g11
)
*
cgu
+
avg
(
b00
,
b01
,
b10
,
b11
)
*
cburv
+
rnd_scratch
[
1
][
y
&
1
][
x
];
diff
=
(
u
&
mask
)
-
rnd
;
yuv1
[
x
]
=
av_clip_pixel
(
uv_offset
+
(
u
>>
sh
));
rnd_scratch
[
1
][
(
y
&
1
)][
x
+
1
]
+=
(
diff
*
7
+
8
)
>>
4
;
rnd_scratch
[
1
][
!
(
y
&
1
)][
x
-
1
]
+=
(
diff
*
3
+
8
)
>>
4
;
rnd_scratch
[
1
][
!
(
y
&
1
)][
x
+
0
]
+=
(
diff
*
5
+
8
)
>>
4
;
rnd_scratch
[
1
][
!
(
y
&
1
)][
x
+
1
]
+=
(
diff
*
1
+
8
)
>>
4
;
rnd_scratch
[
1
][
(
y
&
1
)][
x
+
0
]
=
rnd
;
v
=
avg
(
r00
,
r01
,
r10
,
r11
)
*
cburv
+
avg
(
g00
,
g01
,
g10
,
g11
)
*
cgv
+
avg
(
b00
,
b01
,
b10
,
b11
)
*
cbv
+
rnd_scratch
[
2
][
y
&
1
][
x
];
diff
=
(
v
&
mask
)
-
rnd
;
yuv2
[
x
]
=
av_clip_pixel
(
uv_offset
+
(
v
>>
sh
));
rnd_scratch
[
2
][
(
y
&
1
)][
x
+
1
]
+=
(
diff
*
7
+
8
)
>>
4
;
rnd_scratch
[
2
][
!
(
y
&
1
)][
x
-
1
]
+=
(
diff
*
3
+
8
)
>>
4
;
rnd_scratch
[
2
][
!
(
y
&
1
)][
x
+
0
]
+=
(
diff
*
5
+
8
)
>>
4
;
rnd_scratch
[
2
][
!
(
y
&
1
)][
x
+
1
]
+=
(
diff
*
1
+
8
)
>>
4
;
rnd_scratch
[
2
][
(
y
&
1
)][
x
+
0
]
=
rnd
;
}
yuv0
+=
s0
*
(
1
<<
SS_H
);
yuv1
+=
yuv_stride
[
1
]
/
sizeof
(
pixel
);
yuv2
+=
yuv_stride
[
2
]
/
sizeof
(
pixel
);
rgb0
+=
s
*
(
1
<<
SS_H
);
rgb1
+=
s
*
(
1
<<
SS_H
);
rgb2
+=
s
*
(
1
<<
SS_H
);
}
}
#undef IN_BIT_DEPTH
#undef IN_BIT_DEPTH
#undef OUT_BIT_DEPTH
#undef OUT_BIT_DEPTH
#define OUT_BIT_DEPTH BIT_DEPTH
#define OUT_BIT_DEPTH BIT_DEPTH
...
...
libavfilter/vf_colorspace.c
View file @
431117dc
...
@@ -34,6 +34,12 @@
...
@@ -34,6 +34,12 @@
#include "internal.h"
#include "internal.h"
#include "video.h"
#include "video.h"
enum
DitherMode
{
DITHER_NONE
,
DITHER_FSB
,
DITHER_NB
,
};
enum
Colorspace
{
enum
Colorspace
{
CS_UNSPECIFIED
,
CS_UNSPECIFIED
,
CS_BT470M
,
CS_BT470M
,
...
@@ -121,10 +127,12 @@ typedef struct ColorSpaceContext {
...
@@ -121,10 +127,12 @@ typedef struct ColorSpaceContext {
enum
AVColorPrimaries
in_prm
,
out_prm
,
user_prm
;
enum
AVColorPrimaries
in_prm
,
out_prm
,
user_prm
;
enum
AVPixelFormat
in_format
,
user_format
;
enum
AVPixelFormat
in_format
,
user_format
;
int
fast_mode
;
int
fast_mode
;
enum
DitherMode
dither
;
int16_t
*
rgb
[
3
];
int16_t
*
rgb
[
3
];
ptrdiff_t
rgb_stride
;
ptrdiff_t
rgb_stride
;
unsigned
rgb_sz
;
unsigned
rgb_sz
;
int
*
dither_scratch
[
3
][
2
],
*
dither_scratch_base
[
3
][
2
];
const
struct
ColorPrimaries
*
in_primaries
,
*
out_primaries
;
const
struct
ColorPrimaries
*
in_primaries
,
*
out_primaries
;
int
lrgb2lrgb_passthrough
;
int
lrgb2lrgb_passthrough
;
...
@@ -142,6 +150,7 @@ typedef struct ColorSpaceContext {
...
@@ -142,6 +150,7 @@ typedef struct ColorSpaceContext {
DECLARE_ALIGNED
(
16
,
int16_t
,
yuv_offset
)[
2
/* in, out */
][
8
];
DECLARE_ALIGNED
(
16
,
int16_t
,
yuv_offset
)[
2
/* in, out */
][
8
];
yuv2rgb_fn
yuv2rgb
;
yuv2rgb_fn
yuv2rgb
;
rgb2yuv_fn
rgb2yuv
;
rgb2yuv_fn
rgb2yuv
;
rgb2yuv_fsb_fn
rgb2yuv_fsb
;
yuv2yuv_fn
yuv2yuv
;
yuv2yuv_fn
yuv2yuv
;
double
yuv2rgb_dbl_coeffs
[
3
][
3
],
rgb2yuv_dbl_coeffs
[
3
][
3
];
double
yuv2rgb_dbl_coeffs
[
3
][
3
],
rgb2yuv_dbl_coeffs
[
3
][
3
];
int
in_y_rng
,
in_uv_rng
,
out_y_rng
,
out_uv_rng
;
int
in_y_rng
,
in_uv_rng
,
out_y_rng
,
out_uv_rng
;
...
@@ -481,8 +490,13 @@ static int convert(AVFilterContext *ctx, void *data, int job_nr, int n_jobs)
...
@@ -481,8 +490,13 @@ static int convert(AVFilterContext *ctx, void *data, int job_nr, int n_jobs)
s
->
dsp
.
multiply3x3
(
rgb
,
s
->
rgb_stride
,
w
,
h
,
s
->
lrgb2lrgb_coeffs
);
s
->
dsp
.
multiply3x3
(
rgb
,
s
->
rgb_stride
,
w
,
h
,
s
->
lrgb2lrgb_coeffs
);
apply_lut
(
rgb
,
s
->
rgb_stride
,
w
,
h
,
s
->
delin_lut
);
apply_lut
(
rgb
,
s
->
rgb_stride
,
w
,
h
,
s
->
delin_lut
);
}
}
s
->
rgb2yuv
(
out_data
,
td
->
out_linesize
,
rgb
,
s
->
rgb_stride
,
w
,
h
,
if
(
s
->
dither
==
DITHER_FSB
)
{
s
->
rgb2yuv_coeffs
,
s
->
yuv_offset
[
1
]);
s
->
rgb2yuv_fsb
(
out_data
,
td
->
out_linesize
,
rgb
,
s
->
rgb_stride
,
w
,
h
,
s
->
rgb2yuv_coeffs
,
s
->
yuv_offset
[
1
],
s
->
dither_scratch
);
}
else
{
s
->
rgb2yuv
(
out_data
,
td
->
out_linesize
,
rgb
,
s
->
rgb_stride
,
w
,
h
,
s
->
rgb2yuv_coeffs
,
s
->
yuv_offset
[
1
]);
}
}
}
return
0
;
return
0
;
...
@@ -749,6 +763,8 @@ static int create_filtergraph(AVFilterContext *ctx,
...
@@ -749,6 +763,8 @@ static int create_filtergraph(AVFilterContext *ctx,
av_assert2
(
s
->
rgb2yuv_coeffs
[
1
][
2
][
0
]
==
s
->
rgb2yuv_coeffs
[
2
][
0
][
0
]);
av_assert2
(
s
->
rgb2yuv_coeffs
[
1
][
2
][
0
]
==
s
->
rgb2yuv_coeffs
[
2
][
0
][
0
]);
s
->
rgb2yuv
=
s
->
dsp
.
rgb2yuv
[(
out_desc
->
comp
[
0
].
depth
-
8
)
>>
1
]
s
->
rgb2yuv
=
s
->
dsp
.
rgb2yuv
[(
out_desc
->
comp
[
0
].
depth
-
8
)
>>
1
]
[
out_desc
->
log2_chroma_h
+
out_desc
->
log2_chroma_w
];
[
out_desc
->
log2_chroma_h
+
out_desc
->
log2_chroma_w
];
s
->
rgb2yuv_fsb
=
s
->
dsp
.
rgb2yuv_fsb
[(
out_desc
->
comp
[
0
].
depth
-
8
)
>>
1
]
[
out_desc
->
log2_chroma_h
+
out_desc
->
log2_chroma_w
];
emms
=
1
;
emms
=
1
;
}
}
...
@@ -799,6 +815,12 @@ static void uninit(AVFilterContext *ctx)
...
@@ -799,6 +815,12 @@ static void uninit(AVFilterContext *ctx)
av_freep
(
&
s
->
rgb
[
1
]);
av_freep
(
&
s
->
rgb
[
1
]);
av_freep
(
&
s
->
rgb
[
2
]);
av_freep
(
&
s
->
rgb
[
2
]);
s
->
rgb_sz
=
0
;
s
->
rgb_sz
=
0
;
av_freep
(
&
s
->
dither_scratch_base
[
0
][
0
]);
av_freep
(
&
s
->
dither_scratch_base
[
0
][
1
]);
av_freep
(
&
s
->
dither_scratch_base
[
1
][
0
]);
av_freep
(
&
s
->
dither_scratch_base
[
1
][
1
]);
av_freep
(
&
s
->
dither_scratch_base
[
2
][
0
]);
av_freep
(
&
s
->
dither_scratch_base
[
2
][
1
]);
av_freep
(
&
s
->
lin_lut
);
av_freep
(
&
s
->
lin_lut
);
}
}
...
@@ -839,15 +861,45 @@ static int filter_frame(AVFilterLink *link, AVFrame *in)
...
@@ -839,15 +861,45 @@ static int filter_frame(AVFilterLink *link, AVFrame *in)
out
->
color_range
=
s
->
user_rng
==
AVCOL_RANGE_UNSPECIFIED
?
out
->
color_range
=
s
->
user_rng
==
AVCOL_RANGE_UNSPECIFIED
?
in
->
color_range
:
s
->
user_rng
;
in
->
color_range
:
s
->
user_rng
;
if
(
rgb_sz
!=
s
->
rgb_sz
)
{
if
(
rgb_sz
!=
s
->
rgb_sz
)
{
const
AVPixFmtDescriptor
*
desc
=
av_pix_fmt_desc_get
(
out
->
format
);
int
uvw
=
in
->
width
>>
desc
->
log2_chroma_w
;
av_freep
(
&
s
->
rgb
[
0
]);
av_freep
(
&
s
->
rgb
[
0
]);
av_freep
(
&
s
->
rgb
[
1
]);
av_freep
(
&
s
->
rgb
[
1
]);
av_freep
(
&
s
->
rgb
[
2
]);
av_freep
(
&
s
->
rgb
[
2
]);
s
->
rgb_sz
=
0
;
s
->
rgb_sz
=
0
;
av_freep
(
&
s
->
dither_scratch_base
[
0
][
0
]);
av_freep
(
&
s
->
dither_scratch_base
[
0
][
1
]);
av_freep
(
&
s
->
dither_scratch_base
[
1
][
0
]);
av_freep
(
&
s
->
dither_scratch_base
[
1
][
1
]);
av_freep
(
&
s
->
dither_scratch_base
[
2
][
0
]);
av_freep
(
&
s
->
dither_scratch_base
[
2
][
1
]);
s
->
rgb
[
0
]
=
av_malloc
(
rgb_sz
);
s
->
rgb
[
0
]
=
av_malloc
(
rgb_sz
);
s
->
rgb
[
1
]
=
av_malloc
(
rgb_sz
);
s
->
rgb
[
1
]
=
av_malloc
(
rgb_sz
);
s
->
rgb
[
2
]
=
av_malloc
(
rgb_sz
);
s
->
rgb
[
2
]
=
av_malloc
(
rgb_sz
);
if
(
!
s
->
rgb
[
0
]
||
!
s
->
rgb
[
1
]
||
!
s
->
rgb
[
2
])
{
s
->
dither_scratch_base
[
0
][
0
]
=
av_malloc
(
sizeof
(
*
s
->
dither_scratch_base
[
0
][
0
])
*
(
in
->
width
+
4
));
s
->
dither_scratch_base
[
0
][
1
]
=
av_malloc
(
sizeof
(
*
s
->
dither_scratch_base
[
0
][
1
])
*
(
in
->
width
+
4
));
s
->
dither_scratch_base
[
1
][
0
]
=
av_malloc
(
sizeof
(
*
s
->
dither_scratch_base
[
1
][
0
])
*
(
uvw
+
4
));
s
->
dither_scratch_base
[
1
][
1
]
=
av_malloc
(
sizeof
(
*
s
->
dither_scratch_base
[
1
][
1
])
*
(
uvw
+
4
));
s
->
dither_scratch_base
[
2
][
0
]
=
av_malloc
(
sizeof
(
*
s
->
dither_scratch_base
[
2
][
0
])
*
(
uvw
+
4
));
s
->
dither_scratch_base
[
2
][
1
]
=
av_malloc
(
sizeof
(
*
s
->
dither_scratch_base
[
2
][
1
])
*
(
uvw
+
4
));
s
->
dither_scratch
[
0
][
0
]
=
&
s
->
dither_scratch_base
[
0
][
0
][
1
];
s
->
dither_scratch
[
0
][
1
]
=
&
s
->
dither_scratch_base
[
0
][
1
][
1
];
s
->
dither_scratch
[
1
][
0
]
=
&
s
->
dither_scratch_base
[
1
][
0
][
1
];
s
->
dither_scratch
[
1
][
1
]
=
&
s
->
dither_scratch_base
[
1
][
1
][
1
];
s
->
dither_scratch
[
2
][
0
]
=
&
s
->
dither_scratch_base
[
2
][
0
][
1
];
s
->
dither_scratch
[
2
][
1
]
=
&
s
->
dither_scratch_base
[
2
][
1
][
1
];
if
(
!
s
->
rgb
[
0
]
||
!
s
->
rgb
[
1
]
||
!
s
->
rgb
[
2
]
||
!
s
->
dither_scratch_base
[
0
][
0
]
||
!
s
->
dither_scratch_base
[
0
][
1
]
||
!
s
->
dither_scratch_base
[
1
][
0
]
||
!
s
->
dither_scratch_base
[
1
][
1
]
||
!
s
->
dither_scratch_base
[
2
][
0
]
||
!
s
->
dither_scratch_base
[
2
][
1
])
{
uninit
(
ctx
);
uninit
(
ctx
);
return
AVERROR
(
ENOMEM
);
return
AVERROR
(
ENOMEM
);
}
}
...
@@ -987,6 +1039,12 @@ static const AVOption colorspace_options[] = {
...
@@ -987,6 +1039,12 @@ static const AVOption colorspace_options[] = {
{
"fast"
,
"Ignore primary chromaticity and gamma correction"
,
{
"fast"
,
"Ignore primary chromaticity and gamma correction"
,
OFFSET
(
fast_mode
),
AV_OPT_TYPE_BOOL
,
{
.
i64
=
0
},
OFFSET
(
fast_mode
),
AV_OPT_TYPE_BOOL
,
{
.
i64
=
0
},
0
,
1
,
FLAGS
},
0
,
1
,
FLAGS
},
{
"dither"
,
"Dithering mode"
,
OFFSET
(
dither
),
AV_OPT_TYPE_INT
,
{
.
i64
=
DITHER_NONE
},
DITHER_NONE
,
DITHER_NB
-
1
,
FLAGS
,
"dither"
},
ENUM
(
"none"
,
DITHER_NONE
,
"dither"
),
ENUM
(
"fsb"
,
DITHER_FSB
,
"dither"
),
{
NULL
}
{
NULL
}
};
};
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment