FFmpeg
sw_range_convert.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 
21 #include "libavutil/common.h"
22 #include "libavutil/intreadwrite.h"
23 #include "libavutil/mem.h"
24 #include "libavutil/mem_internal.h"
25 
26 #include "libswscale/swscale.h"
28 
29 #include "checkasm.h"
30 
31 static const enum AVPixelFormat pixel_formats[] = {
38 };
39 
40 static void randomize_buffers(int16_t *buf0, int16_t *buf1, int bit_depth, int width)
41 {
42  int32_t *buf0_32 = (int32_t *) buf0;
43  int32_t *buf1_32 = (int32_t *) buf1;
44  int mask = (1 << bit_depth) - 1;
45  int src_shift = bit_depth <= 14 ? 15 - bit_depth : 19 - bit_depth;
46  for (int i = 0; i < width; i++) {
47  int32_t r = rnd() & mask;
48  if (bit_depth == 16) {
49  buf0_32[i] = r << src_shift;
50  buf1_32[i] = r << src_shift;
51  } else {
52  buf0[i] = r << src_shift;
53  buf1[i] = r << src_shift;
54  }
55  }
56 }
57 
58 static void check_lumConvertRange(int from)
59 {
60  const char *func_str = from ? "lumRangeFromJpeg" : "lumRangeToJpeg";
61 #define LARGEST_INPUT_SIZE 1920
62  static const int input_sizes[] = {8, LARGEST_INPUT_SIZE};
63  SwsContext *sws;
64  SwsInternal *c;
65 
66  LOCAL_ALIGNED_32(int16_t, dst0, [LARGEST_INPUT_SIZE * 2]);
67  LOCAL_ALIGNED_32(int16_t, dst1, [LARGEST_INPUT_SIZE * 2]);
68 
69  declare_func(void, int16_t *dst, int width);
70 
72  if (sws_init_context(sws, NULL, NULL) < 0)
73  fail();
74 
75  c = sws_internal(sws);
76  sws->src_range = from;
77  sws->dst_range = !from;
78 
79  for (int pfi = 0; pfi < FF_ARRAY_ELEMS(pixel_formats); pfi++) {
82  int bit_depth = desc->comp[0].depth;
83  int sample_size = bit_depth == 16 ? sizeof(int32_t) : sizeof(int16_t);
86  c->dstBpc = bit_depth;
88  for (int dstWi = 0; dstWi < FF_ARRAY_ELEMS(input_sizes); dstWi++) {
89  int width = input_sizes[dstWi];
90  if (check_func(c->lumConvertRange, "%s%d_%d", func_str, bit_depth, width)) {
91  randomize_buffers(dst0, dst1, bit_depth, width);
92  call_ref(dst0, width);
93  call_new(dst1, width);
94  if (memcmp(dst0, dst1, width * sample_size))
95  fail();
96  if (width == LARGEST_INPUT_SIZE && (bit_depth == 8 || bit_depth == 16))
97  bench_new(dst1, width);
98  }
99  }
100  }
101 
103 }
104 #undef LARGEST_INPUT_SIZE
105 
106 static void check_chrConvertRange(int from)
107 {
108  const char *func_str = from ? "chrRangeFromJpeg" : "chrRangeToJpeg";
109 #define LARGEST_INPUT_SIZE 1920
110  static const int input_sizes[] = {8, LARGEST_INPUT_SIZE};
111  SwsContext *sws;
112  SwsInternal *c;
113 
114  LOCAL_ALIGNED_32(int16_t, dstU0, [LARGEST_INPUT_SIZE * 2]);
115  LOCAL_ALIGNED_32(int16_t, dstV0, [LARGEST_INPUT_SIZE * 2]);
116  LOCAL_ALIGNED_32(int16_t, dstU1, [LARGEST_INPUT_SIZE * 2]);
117  LOCAL_ALIGNED_32(int16_t, dstV1, [LARGEST_INPUT_SIZE * 2]);
118 
119  declare_func(void, int16_t *dstU, int16_t *dstV, int width);
120 
122  if (sws_init_context(sws, NULL, NULL) < 0)
123  fail();
124 
125  c = sws_internal(sws);
126  sws->src_range = from;
127  sws->dst_range = !from;
128 
129  for (int pfi = 0; pfi < FF_ARRAY_ELEMS(pixel_formats); pfi++) {
130  enum AVPixelFormat pix_fmt = pixel_formats[pfi];
132  int bit_depth = desc->comp[0].depth;
133  int sample_size = bit_depth == 16 ? sizeof(int32_t) : sizeof(int16_t);
136  c->dstBpc = bit_depth;
138  for (int dstWi = 0; dstWi < FF_ARRAY_ELEMS(input_sizes); dstWi++) {
139  int width = input_sizes[dstWi];
140  if (check_func(c->chrConvertRange, "%s%d_%d", func_str, bit_depth, width)) {
141  randomize_buffers(dstU0, dstU1, bit_depth, width);
142  randomize_buffers(dstV0, dstV1, bit_depth, width);
143  call_ref(dstU0, dstV0, width);
144  call_new(dstU1, dstV1, width);
145  if (memcmp(dstU0, dstU1, width * sample_size) ||
146  memcmp(dstV0, dstV1, width * sample_size))
147  fail();
148  if (width == LARGEST_INPUT_SIZE && (bit_depth == 8 || bit_depth == 16))
149  bench_new(dstU1, dstV1, width);
150  }
151  }
152  }
153 
155 }
156 #undef LARGEST_INPUT_SIZE
157 
159 {
161  report("lumRangeFromJpeg");
163  report("chrRangeFromJpeg");
165  report("lumRangeToJpeg");
167  report("chrRangeToJpeg");
168 }
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:71
r
const char * r
Definition: vf_curves.c:127
mem_internal.h
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:3170
sws_freeContext
void sws_freeContext(SwsContext *swsContext)
Free the swscaler context swsContext.
Definition: utils.c:2447
mask
int mask
Definition: mediacodecdec_common.c:154
check_func
#define check_func(func,...)
Definition: checkasm.h:180
call_ref
#define call_ref(...)
Definition: checkasm.h:195
bit_depth
static void bit_depth(AudioStatsContext *s, const uint64_t *const mask, uint8_t *depth)
Definition: af_astats.c:246
fail
#define fail()
Definition: checkasm.h:189
checkasm.h
sws_init_context
av_warn_unused_result int sws_init_context(SwsContext *sws_context, SwsFilter *srcFilter, SwsFilter *dstFilter)
Initialize the swscaler context sws_context.
Definition: utils.c:2082
check_chrConvertRange
static void check_chrConvertRange(int from)
Definition: sw_range_convert.c:106
AV_PIX_FMT_YUV444P10
#define AV_PIX_FMT_YUV444P10
Definition: pixfmt.h:505
LARGEST_INPUT_SIZE
#define LARGEST_INPUT_SIZE
rnd
#define rnd()
Definition: checkasm.h:173
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
intreadwrite.h
AV_PIX_FMT_YUV444P16
#define AV_PIX_FMT_YUV444P16
Definition: pixfmt.h:515
pix_fmt
static enum AVPixelFormat pix_fmt
Definition: demux_decode.c:41
input_sizes
static const int input_sizes[]
Definition: sw_rgb.c:347
from
const char * from
Definition: jacosubdec.c:66
call_new
#define call_new(...)
Definition: checkasm.h:298
NULL
#define NULL
Definition: coverity.c:32
LOCAL_ALIGNED_32
#define LOCAL_ALIGNED_32(t, v,...)
Definition: mem_internal.h:130
SwsContext::src_range
int src_range
Source is full range.
Definition: swscale.h:224
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
sws_alloc_context
SwsContext * sws_alloc_context(void)
Allocate an empty SwsContext and set its fields to default values.
Definition: utils.c:1227
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:83
AV_PIX_FMT_YUV444P12
#define AV_PIX_FMT_YUV444P12
Definition: pixfmt.h:509
SwsContext::dst_format
int dst_format
Destination pixel format.
Definition: swscale.h:223
sws
static SwsContext * sws[3]
Definition: swscale.c:69
report
#define report
Definition: checkasm.h:192
randomize_buffers
static void randomize_buffers(int16_t *buf0, int16_t *buf1, int bit_depth, int width)
Definition: sw_range_convert.c:40
bench_new
#define bench_new(...)
Definition: checkasm.h:369
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
ff_sws_init_scale
void ff_sws_init_scale(SwsInternal *c)
Definition: swscale.c:611
common.h
swscale_internal.h
check_lumConvertRange
static void check_lumConvertRange(int from)
Definition: sw_range_convert.c:58
AV_PIX_FMT_YUV444P9
#define AV_PIX_FMT_YUV444P9
Definition: pixfmt.h:501
SwsInternal
Definition: swscale_internal.h:317
AV_PIX_FMT_YUV444P
@ AV_PIX_FMT_YUV444P
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition: pixfmt.h:78
desc
const char * desc
Definition: libsvtav1.c:79
checkasm_check_sw_range_convert
void checkasm_check_sw_range_convert(void)
Definition: sw_range_convert.c:158
mem.h
SwsContext::src_format
int src_format
Source pixel format.
Definition: swscale.h:222
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
declare_func
#define declare_func(ret,...)
Definition: checkasm.h:184
SwsContext::dst_range
int dst_range
Destination is full range.
Definition: swscale.h:225
int32_t
int32_t
Definition: audioconvert.c:56
sws_internal
static SwsInternal * sws_internal(const SwsContext *sws)
Definition: swscale_internal.h:74
AV_PIX_FMT_YUV444P14
#define AV_PIX_FMT_YUV444P14
Definition: pixfmt.h:512
width
#define width
Definition: dsp.h:85
SwsContext
Main external API structure.
Definition: swscale.h:174
pixel_formats
static enum AVPixelFormat pixel_formats[]
Definition: sw_range_convert.c:31
swscale.h