FFmpeg
vf_colordetect.c
Go to the documentation of this file.
1 /*
2  * This file is part of FFmpeg.
3  *
4  * FFmpeg is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * FFmpeg is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with FFmpeg; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18 
19 #include <string.h>
20 #include "checkasm.h"
21 
23 #include "libavutil/mem_internal.h"
24 
25 #define WIDTH 256
26 #define HEIGHT 16
27 #define STRIDE (WIDTH + 32)
28 
29 static void check_range_detect(int depth)
30 {
31  const int mpeg_min = 16 << (depth - 8);
32  const int mpeg_max = 235 << (depth - 8);
33 
34  FFColorDetectDSPContext dsp = {0};
36 
37  declare_func(int, const uint8_t *, ptrdiff_t, ptrdiff_t, ptrdiff_t, int, int);
38 
39  /* Initialize to 128, which should always return 0 */
40  LOCAL_ALIGNED_32(uint8_t, in, [HEIGHT * STRIDE]);
41  memset(in, 0x80, HEIGHT * STRIDE);
42 
43  /* Place an out-of-range value in a random position near the center */
44  const int h2 = HEIGHT >> 1;
45  int idx0 = ((rnd() % h2) + h2) * STRIDE + (rnd() % WIDTH);
46  if (depth > 8) {
47  idx0 &= ~1;
48  in[idx0] = in[idx0 + 1] = 0;
49  } else {
50  in[idx0] = 0;
51  }
52 
53  int w = WIDTH;
54  if (depth > 8)
55  w /= 2;
56 
57  if (check_func(dsp.detect_range, "detect_range_%d", depth)) {
58  /* Test increasing height, to ensure we hit the placed 0 eventually */
59  for (int h = 1; h <= HEIGHT; h++) {
60  int res_ref = call_ref(in, STRIDE, w, h, mpeg_min, mpeg_max);
61  int res_new = call_new(in, STRIDE, w, h, mpeg_min, mpeg_max);
62  if (res_ref != res_new)
63  fail();
64  }
65 
66  /* Test performance of base case without any out-of-range values */
67  memset(in, 0x80, HEIGHT * STRIDE);
68  bench_new(in, STRIDE, w, HEIGHT, mpeg_min, mpeg_max);
69  }
70 }
71 
72 static void check_alpha_detect(int depth, enum AVColorRange range)
73 {
74  const int mpeg_min = 16 << (depth - 8);
75  const int mpeg_max = 235 << (depth - 8);
76  const int p = (1 << depth) - 1;
77  const int q = mpeg_max - mpeg_min;
78  const int k = p * mpeg_min + q + (1 << (depth - 1));
79 
80  FFColorDetectDSPContext dsp = {0};
81  ff_color_detect_dsp_init(&dsp, depth, range);
82 
83  declare_func(int, const uint8_t *, ptrdiff_t, const uint8_t *, ptrdiff_t,
84  ptrdiff_t, ptrdiff_t, int p, int q, int k);
85 
86  LOCAL_ALIGNED_32(uint8_t, luma, [HEIGHT * STRIDE]);
87  LOCAL_ALIGNED_32(uint8_t, alpha, [HEIGHT * STRIDE]);
88  memset(luma, 0x80, HEIGHT * STRIDE);
89  memset(alpha, 0xFF, HEIGHT * STRIDE);
90 
91  /* Try and force overflow */
92  if (depth > 8 && range == AVCOL_RANGE_MPEG) {
93  ((uint16_t *) luma)[0] = 235 << (depth - 8);
94  ((uint16_t *) luma)[1] = 16 << (depth - 8);
95  } else {
96  luma[0] = 235;
97  luma[1] = 16;
98  }
99 
100  /* Place an out-of-range value in a random position near the center */
101  const int h2 = HEIGHT >> 1;
102  int idx0 = ((rnd() % h2) + h2) * STRIDE + (rnd() % WIDTH);
103  if (depth > 8) {
104  idx0 &= ~1;
105  alpha[idx0] = alpha[idx0 + 1] = 0;
106  } else {
107  alpha[idx0] = 0;
108  }
109 
110  int w = WIDTH;
111  if (depth > 8)
112  w /= 2;
113 
114  if (check_func(dsp.detect_alpha, "detect_alpha_%d_%s", depth, range == AVCOL_RANGE_JPEG ? "full" : "limited")) {
115  /* Test increasing height, to ensure we hit the placed 0 eventually */
116  for (int h = 1; h <= HEIGHT; h++) {
117  int res_ref = call_ref(luma, STRIDE, alpha, STRIDE, w, h, p, q, k);
118  int res_new = call_new(luma, STRIDE, alpha, STRIDE, w, h, p, q, k);
119  if (res_ref != res_new)
120  fail();
121  }
122 
123  /* Test performance of base case without any out-of-range values */
124  memset(alpha, 0xFF, HEIGHT * STRIDE);
125  bench_new(luma, STRIDE, alpha, STRIDE, w, HEIGHT, p, q, k);
126  }
127 }
128 
130 {
131  for (int depth = 8; depth <= 16; depth += 8) {
132  check_range_detect(depth);
133  report("detect_range_%d", depth);
134 
137  report("detect_alpha_%d", depth);
138  }
139 }
mem_internal.h
vf_colordetect.h
w
uint8_t w
Definition: llviddspenc.c:38
AVCOL_RANGE_JPEG
@ AVCOL_RANGE_JPEG
Full range content.
Definition: pixfmt.h:767
check_func
#define check_func(func,...)
Definition: checkasm.h:190
checkasm_check_colordetect
void checkasm_check_colordetect(void)
Definition: vf_colordetect.c:129
call_ref
#define call_ref(...)
Definition: checkasm.h:205
check_alpha_detect
static void check_alpha_detect(int depth, enum AVColorRange range)
Definition: vf_colordetect.c:72
fail
#define fail()
Definition: checkasm.h:199
checkasm.h
HEIGHT
#define HEIGHT
Definition: vf_colordetect.c:26
rnd
#define rnd()
Definition: checkasm.h:183
ff_color_detect_dsp_init
av_cold void ff_color_detect_dsp_init(FFColorDetectDSPContext *dsp, int depth, enum AVColorRange color_range)
Definition: vf_colordetect.c:232
call_new
#define call_new(...)
Definition: checkasm.h:308
LOCAL_ALIGNED_32
#define LOCAL_ALIGNED_32(t, v,...)
Definition: mem_internal.h:132
AVCOL_RANGE_UNSPECIFIED
@ AVCOL_RANGE_UNSPECIFIED
Definition: pixfmt.h:733
range
enum AVColorRange range
Definition: mediacodec_wrapper.c:2594
FFColorDetectDSPContext::detect_range
int(* detect_range)(const uint8_t *data, ptrdiff_t stride, ptrdiff_t width, ptrdiff_t height, int mpeg_min, int mpeg_max)
Definition: vf_colordetect.h:30
WIDTH
#define WIDTH
Definition: vf_colordetect.c:25
report
#define report
Definition: checkasm.h:202
bench_new
#define bench_new(...)
Definition: checkasm.h:379
AVCOL_RANGE_MPEG
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
Definition: pixfmt.h:750
declare_func
#define declare_func(ret,...)
Definition: checkasm.h:194
alpha
static const int16_t alpha[]
Definition: ilbcdata.h:55
FFColorDetectDSPContext
Definition: vf_colordetect.h:28
STRIDE
#define STRIDE
Definition: vf_colordetect.c:27
FFColorDetectDSPContext::detect_alpha
int(* detect_alpha)(const uint8_t *color, ptrdiff_t color_stride, const uint8_t *alpha, ptrdiff_t alpha_stride, ptrdiff_t width, ptrdiff_t height, int p, int q, int k)
Definition: vf_colordetect.h:35
h
h
Definition: vp9dsp_template.c:2070
AVColorRange
AVColorRange
Visual content value range.
Definition: pixfmt.h:732
check_range_detect
static void check_range_detect(int depth)
Definition: vf_colordetect.c:29