FFmpeg  4.3
vc2enc_dwt.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2007 Marco Gerards <marco@gnu.org>
3  * Copyright (C) 2016 Open Broadcast Systems Ltd.
4  * Author 2016 Rostislav Pehlivanov <atomnuker@gmail.com>
5  *
6  * This file is part of FFmpeg.
7  *
8  * FFmpeg is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * FFmpeg is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with FFmpeg; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 #include "libavutil/attributes.h"
24 #include "libavutil/mem.h"
25 #include "vc2enc_dwt.h"
26 
27 /* Since the transforms spit out interleaved coefficients, this function
28  * rearranges the coefficients into the more traditional subdivision,
29  * making it easier to encode and perform another level. */
30 static av_always_inline void deinterleave(dwtcoef *linell, ptrdiff_t stride,
31  int width, int height, dwtcoef *synthl)
32 {
33  int x, y;
34  ptrdiff_t synthw = width << 1;
35  dwtcoef *linehl = linell + width;
36  dwtcoef *linelh = linell + height*stride;
37  dwtcoef *linehh = linelh + width;
38 
39  /* Deinterleave the coefficients. */
40  for (y = 0; y < height; y++) {
41  for (x = 0; x < width; x++) {
42  linell[x] = synthl[(x << 1)];
43  linehl[x] = synthl[(x << 1) + 1];
44  linelh[x] = synthl[(x << 1) + synthw];
45  linehh[x] = synthl[(x << 1) + synthw + 1];
46  }
47  synthl += synthw << 1;
48  linell += stride;
49  linelh += stride;
50  linehl += stride;
51  linehh += stride;
52  }
53 }
54 
56  ptrdiff_t stride, int width, int height)
57 {
58  int x, y;
59  dwtcoef *datal = data, *synth = t->buffer, *synthl = synth;
60  const ptrdiff_t synth_width = width << 1;
61  const ptrdiff_t synth_height = height << 1;
62 
63  /*
64  * Shift in one bit that is used for additional precision and copy
65  * the data to the buffer.
66  */
67  for (y = 0; y < synth_height; y++) {
68  for (x = 0; x < synth_width; x++)
69  synthl[x] = datal[x] * 2;
70  synthl += synth_width;
71  datal += stride;
72  }
73 
74  /* Horizontal synthesis. */
75  synthl = synth;
76  for (y = 0; y < synth_height; y++) {
77  /* Lifting stage 2. */
78  synthl[1] -= (8*synthl[0] + 9*synthl[2] - synthl[4] + 8) >> 4;
79  for (x = 1; x < width - 2; x++)
80  synthl[2*x + 1] -= (9*synthl[2*x] + 9*synthl[2*x + 2] - synthl[2*x + 4] -
81  synthl[2 * x - 2] + 8) >> 4;
82  synthl[synth_width - 1] -= (17*synthl[synth_width - 2] -
83  synthl[synth_width - 4] + 8) >> 4;
84  synthl[synth_width - 3] -= (8*synthl[synth_width - 2] +
85  9*synthl[synth_width - 4] -
86  synthl[synth_width - 6] + 8) >> 4;
87  /* Lifting stage 1. */
88  synthl[0] += (synthl[1] + synthl[1] + 2) >> 2;
89  for (x = 1; x < width - 1; x++)
90  synthl[2*x] += (synthl[2*x - 1] + synthl[2*x + 1] + 2) >> 2;
91 
92  synthl[synth_width - 2] += (synthl[synth_width - 3] +
93  synthl[synth_width - 1] + 2) >> 2;
94  synthl += synth_width;
95  }
96 
97  /* Vertical synthesis: Lifting stage 2. */
98  synthl = synth + synth_width;
99  for (x = 0; x < synth_width; x++)
100  synthl[x] -= (8*synthl[x - synth_width] + 9*synthl[x + synth_width] -
101  synthl[x + 3 * synth_width] + 8) >> 4;
102 
103  synthl = synth + (synth_width << 1);
104  for (y = 1; y < height - 2; y++) {
105  for (x = 0; x < synth_width; x++)
106  synthl[x + synth_width] -= (9*synthl[x] +
107  9*synthl[x + 2 * synth_width] -
108  synthl[x - 2 * synth_width] -
109  synthl[x + 4 * synth_width] + 8) >> 4;
110  synthl += synth_width << 1;
111  }
112 
113  synthl = synth + (synth_height - 1) * synth_width;
114  for (x = 0; x < synth_width; x++) {
115  synthl[x] -= (17*synthl[x - synth_width] -
116  synthl[x - 3*synth_width] + 8) >> 4;
117  synthl[x - 2*synth_width] -= (9*synthl[x - 3*synth_width] +
118  8*synthl[x - 1*synth_width] - synthl[x - 5*synth_width] + 8) >> 4;
119  }
120 
121  /* Vertical synthesis: Lifting stage 1. */
122  synthl = synth;
123  for (x = 0; x < synth_width; x++)
124  synthl[x] += (synthl[x + synth_width] + synthl[x + synth_width] + 2) >> 2;
125 
126  synthl = synth + (synth_width << 1);
127  for (y = 1; y < height - 1; y++) {
128  for (x = 0; x < synth_width; x++)
129  synthl[x] += (synthl[x - synth_width] + synthl[x + synth_width] + 2) >> 2;
130  synthl += synth_width << 1;
131  }
132 
133  synthl = synth + (synth_height - 2) * synth_width;
134  for (x = 0; x < synth_width; x++)
135  synthl[x] += (synthl[x - synth_width] + synthl[x + synth_width] + 2) >> 2;
136 
137  deinterleave(data, stride, width, height, synth);
138 }
139 
141  ptrdiff_t stride, int width, int height)
142 {
143  int x, y;
144  dwtcoef *synth = t->buffer, *synthl = synth, *datal = data;
145  const ptrdiff_t synth_width = width << 1;
146  const ptrdiff_t synth_height = height << 1;
147 
148  /*
149  * Shift in one bit that is used for additional precision and copy
150  * the data to the buffer.
151  */
152  for (y = 0; y < synth_height; y++) {
153  for (x = 0; x < synth_width; x++)
154  synthl[x] = datal[x] << 1;
155  synthl += synth_width;
156  datal += stride;
157  }
158 
159  /* Horizontal synthesis. */
160  synthl = synth;
161  for (y = 0; y < synth_height; y++) {
162  /* Lifting stage 2. */
163  for (x = 0; x < width - 1; x++)
164  synthl[2 * x + 1] -= (synthl[2 * x] + synthl[2 * x + 2] + 1) >> 1;
165 
166  synthl[synth_width - 1] -= (2*synthl[synth_width - 2] + 1) >> 1;
167 
168  /* Lifting stage 1. */
169  synthl[0] += (2*synthl[1] + 2) >> 2;
170  for (x = 1; x < width - 1; x++)
171  synthl[2 * x] += (synthl[2 * x - 1] + synthl[2 * x + 1] + 2) >> 2;
172 
173  synthl[synth_width - 2] += (synthl[synth_width - 3] + synthl[synth_width - 1] + 2) >> 2;
174 
175  synthl += synth_width;
176  }
177 
178  /* Vertical synthesis: Lifting stage 2. */
179  synthl = synth + synth_width;
180  for (x = 0; x < synth_width; x++)
181  synthl[x] -= (synthl[x - synth_width] + synthl[x + synth_width] + 1) >> 1;
182 
183  synthl = synth + (synth_width << 1);
184  for (y = 1; y < height - 1; y++) {
185  for (x = 0; x < synth_width; x++)
186  synthl[x + synth_width] -= (synthl[x] + synthl[x + synth_width * 2] + 1) >> 1;
187  synthl += (synth_width << 1);
188  }
189 
190  synthl = synth + (synth_height - 1) * synth_width;
191  for (x = 0; x < synth_width; x++)
192  synthl[x] -= (2*synthl[x - synth_width] + 1) >> 1;
193 
194  /* Vertical synthesis: Lifting stage 1. */
195  synthl = synth;
196  for (x = 0; x < synth_width; x++)
197  synthl[x] += (2*synthl[synth_width + x] + 2) >> 2;
198 
199  synthl = synth + (synth_width << 1);
200  for (y = 1; y < height - 1; y++) {
201  for (x = 0; x < synth_width; x++)
202  synthl[x] += (synthl[x + synth_width] + synthl[x - synth_width] + 2) >> 2;
203  synthl += (synth_width << 1);
204  }
205 
206  synthl = synth + (synth_height - 2)*synth_width;
207  for (x = 0; x < synth_width; x++)
208  synthl[x] += (synthl[x - synth_width] + synthl[x + synth_width] + 2) >> 2;
209 
210 
211  deinterleave(data, stride, width, height, synth);
212 }
213 
215  ptrdiff_t stride, int width, int height,
216  const int s)
217 {
218  int x, y;
219  dwtcoef *synth = t->buffer, *synthl = synth, *datal = data;
220  const ptrdiff_t synth_width = width << 1;
221  const ptrdiff_t synth_height = height << 1;
222 
223  /* Horizontal synthesis. */
224  for (y = 0; y < synth_height; y++) {
225  for (x = 0; x < synth_width; x += 2) {
226  synthl[y*synth_width + x + 1] = (datal[y*stride + x + 1] << s) -
227  (datal[y*stride + x] << s);
228  synthl[y*synth_width + x] = (datal[y*stride + x + 0] << s) +
229  ((synthl[y*synth_width + x + 1] + 1) >> 1);
230  }
231  }
232 
233  /* Vertical synthesis. */
234  for (x = 0; x < synth_width; x++) {
235  for (y = 0; y < synth_height; y += 2) {
236  synthl[(y + 1)*synth_width + x] = synthl[(y + 1)*synth_width + x] -
237  synthl[y*synth_width + x];
238  synthl[y*synth_width + x] = synthl[y*synth_width + x] +
239  ((synthl[(y + 1)*synth_width + x] + 1) >> 1);
240  }
241  }
242 
243  deinterleave(data, stride, width, height, synth);
244 }
245 
247  ptrdiff_t stride, int width, int height)
248 {
249  dwt_haar(t, data, stride, width, height, 0);
250 }
251 
253  ptrdiff_t stride, int width, int height)
254 {
255  dwt_haar(t, data, stride, width, height, 1);
256 }
257 
259  int p_height, int slice_w, int slice_h)
260 {
261  s->vc2_subband_dwt[VC2_TRANSFORM_9_7] = vc2_subband_dwt_97;
262  s->vc2_subband_dwt[VC2_TRANSFORM_5_3] = vc2_subband_dwt_53;
263  s->vc2_subband_dwt[VC2_TRANSFORM_HAAR] = vc2_subband_dwt_haar;
265 
266  /* Pad by the slice size, only matters for non-Haar wavelets */
267  s->buffer = av_calloc((p_stride + slice_w)*(p_height + slice_h), sizeof(dwtcoef));
268  if (!s->buffer)
269  return 1;
270 
271  s->padding = (slice_h >> 1)*p_stride + (slice_w >> 1);
272  s->buffer += s->padding;
273 
274  return 0;
275 }
276 
278 {
279  av_free(s->buffer - s->padding);
280  s->buffer = NULL;
281 }
stride
int stride
Definition: mace.c:144
VC2_TRANSFORM_9_7
@ VC2_TRANSFORM_9_7
Definition: vc2enc_dwt.h:31
dwtcoef
int32_t dwtcoef
Definition: vc2enc_dwt.h:28
data
const char data[16]
Definition: mxf.c:91
ff_vc2enc_free_transforms
av_cold void ff_vc2enc_free_transforms(VC2TransformContext *s)
Definition: vc2enc_dwt.c:277
x
FFmpeg Automated Testing Environment ************************************Introduction Using FATE from your FFmpeg source directory Submitting the results to the FFmpeg result aggregation server Uploading new samples to the fate suite FATE makefile targets and variables Makefile targets Makefile variables Examples Introduction **************FATE is an extended regression suite on the client side and a means for results aggregation and presentation on the server side The first part of this document explains how you can use FATE from your FFmpeg source directory to test your ffmpeg binary The second part describes how you can run FATE to submit the results to FFmpeg’s FATE server In any way you can have a look at the publicly viewable FATE results by visiting this as it can be seen if some test on some platform broke with their recent contribution This usually happens on the platforms the developers could not test on The second part of this document describes how you can run FATE to submit your results to FFmpeg’s FATE server If you want to submit your results be sure to check that your combination of OS and compiler is not already listed on the above mentioned website In the third part you can find a comprehensive listing of FATE makefile targets and variables Using FATE from your FFmpeg source directory **********************************************If you want to run FATE on your machine you need to have the samples in place You can get the samples via the build target fate rsync Use this command from the top level source this will cause FATE to fail NOTE To use a custom wrapper to run the pass ‘ target exec’ to ‘configure’ or set the TARGET_EXEC Make variable Submitting the results to the FFmpeg result aggregation server ****************************************************************To submit your results to the server you should run fate through the shell script ‘tests fate sh’ from the FFmpeg sources This script needs to be invoked with a configuration file as its first argument tests fate sh path to fate_config A configuration file template with comments describing the individual configuration variables can be found at ‘doc fate_config sh template’ Create a configuration that suits your based on the configuration template The ‘slot’ configuration variable can be any string that is not yet but it is suggested that you name it adhering to the following pattern ‘ARCH OS COMPILER COMPILER VERSION’ The configuration file itself will be sourced in a shell therefore all shell features may be used This enables you to setup the environment as you need it for your build For your first test runs the ‘fate_recv’ variable should be empty or commented out This will run everything as normal except that it will omit the submission of the results to the server The following files should be present in $workdir as specified in the configuration it may help to try out the ‘ssh’ command with one or more ‘ v’ options You should get detailed output concerning your SSH configuration and the authentication process The only thing left is to automate the execution of the fate sh script and the synchronisation of the samples directory Uploading new samples to the fate suite *****************************************If you need a sample uploaded send a mail to samples request This is for developers who have an account on the fate suite server If you upload new please make sure they are as small as space on each network bandwidth and so on benefit from smaller test cases Also keep in mind older checkouts use existing sample that means in practice generally do not remove or overwrite files as it likely would break older checkouts or releases Also all needed samples for a commit should be ideally before the push If you need an account for frequently uploading samples or you wish to help others by doing that send a mail to ffmpeg devel rsync vauL Duo x
Definition: fate.txt:150
av_cold
#define av_cold
Definition: attributes.h:90
ff_vc2enc_init_transforms
av_cold int ff_vc2enc_init_transforms(VC2TransformContext *s, int p_stride, int p_height, int slice_w, int slice_h)
Definition: vc2enc_dwt.c:258
width
#define width
s
#define s(width, name)
Definition: cbs_vp9.c:257
vc2enc_dwt.h
vc2_subband_dwt_haar_shift
static void vc2_subband_dwt_haar_shift(VC2TransformContext *t, dwtcoef *data, ptrdiff_t stride, int width, int height)
Definition: vc2enc_dwt.c:252
NULL
#define NULL
Definition: coverity.c:32
vc2_subband_dwt_haar
static void vc2_subband_dwt_haar(VC2TransformContext *t, dwtcoef *data, ptrdiff_t stride, int width, int height)
Definition: vc2enc_dwt.c:246
vc2_subband_dwt_53
static void vc2_subband_dwt_53(VC2TransformContext *t, dwtcoef *data, ptrdiff_t stride, int width, int height)
Definition: vc2enc_dwt.c:140
VC2TransformContext
Definition: vc2enc_dwt.h:42
deinterleave
static av_always_inline void deinterleave(dwtcoef *linell, ptrdiff_t stride, int width, int height, dwtcoef *synthl)
Definition: vc2enc_dwt.c:30
height
#define height
attributes.h
VC2TransformContext::buffer
dwtcoef * buffer
Definition: vc2enc_dwt.h:43
av_always_inline
#define av_always_inline
Definition: attributes.h:49
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Non-inlined equivalent of av_mallocz_array().
Definition: mem.c:245
VC2_TRANSFORM_HAAR
@ VC2_TRANSFORM_HAAR
Definition: vc2enc_dwt.h:34
mem.h
dwt_haar
static av_always_inline void dwt_haar(VC2TransformContext *t, dwtcoef *data, ptrdiff_t stride, int width, int height, const int s)
Definition: vc2enc_dwt.c:214
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
vc2_subband_dwt_97
static void vc2_subband_dwt_97(VC2TransformContext *t, dwtcoef *data, ptrdiff_t stride, int width, int height)
Definition: vc2enc_dwt.c:55
VC2_TRANSFORM_HAAR_S
@ VC2_TRANSFORM_HAAR_S
Definition: vc2enc_dwt.h:35
VC2_TRANSFORM_5_3
@ VC2_TRANSFORM_5_3
Definition: vc2enc_dwt.h:32