FFmpeg
mpegvideoencdsp.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
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (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 GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with FFmpeg; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 #include <assert.h>
20 #include <stdint.h>
21 #include <string.h>
22 
23 #include "config.h"
24 #include "libavutil/avassert.h"
25 #include "libavutil/attributes.h"
26 #include "libavutil/imgutils.h"
27 #include "avcodec.h"
28 #include "me_cmp.h"
29 #include "mpegvideoencdsp.h"
30 
31 static int try_8x8basis_c(const int16_t rem[64], const int16_t weight[64],
32  const int16_t basis[64], int scale)
33 {
34  int i;
35  unsigned int sum = 0;
36 
37  for (i = 0; i < 8 * 8; i++) {
38  int b = rem[i] + ((basis[i] * scale +
39  (1 << (BASIS_SHIFT - RECON_SHIFT - 1))) >>
41  int w = weight[i];
42  b >>= RECON_SHIFT;
43  av_assert2(-512 < b && b < 512);
44 
45  sum += (w * b) * (w * b) >> 4;
46  }
47  return sum >> 2;
48 }
49 
50 static void add_8x8basis_c(int16_t rem[64], const int16_t basis[64], int scale)
51 {
52  int i;
53 
54  for (i = 0; i < 8 * 8; i++)
55  rem[i] += (basis[i] * scale +
56  (1 << (BASIS_SHIFT - RECON_SHIFT - 1))) >>
58 }
59 
60 static int pix_sum_c(const uint8_t *pix, ptrdiff_t line_size)
61 {
62  int s = 0, i, j;
63 
64  for (i = 0; i < 16; i++) {
65  for (j = 0; j < 16; j += 8) {
66  s += pix[0];
67  s += pix[1];
68  s += pix[2];
69  s += pix[3];
70  s += pix[4];
71  s += pix[5];
72  s += pix[6];
73  s += pix[7];
74  pix += 8;
75  }
76  pix += line_size - 16;
77  }
78  return s;
79 }
80 
81 static int pix_norm1_c(const uint8_t *pix, ptrdiff_t line_size)
82 {
83  int s = 0, i, j;
84  const uint32_t *sq = ff_square_tab + 256;
85 
86  for (i = 0; i < 16; i++) {
87  for (j = 0; j < 16; j += 8) {
88 #if HAVE_FAST_64BIT
89  register uint64_t x = *(uint64_t *) pix;
90  s += sq[x & 0xff];
91  s += sq[(x >> 8) & 0xff];
92  s += sq[(x >> 16) & 0xff];
93  s += sq[(x >> 24) & 0xff];
94  s += sq[(x >> 32) & 0xff];
95  s += sq[(x >> 40) & 0xff];
96  s += sq[(x >> 48) & 0xff];
97  s += sq[(x >> 56) & 0xff];
98 #else
99  register uint32_t x = *(uint32_t *) pix;
100  s += sq[x & 0xff];
101  s += sq[(x >> 8) & 0xff];
102  s += sq[(x >> 16) & 0xff];
103  s += sq[(x >> 24) & 0xff];
104  x = *(uint32_t *) (pix + 4);
105  s += sq[x & 0xff];
106  s += sq[(x >> 8) & 0xff];
107  s += sq[(x >> 16) & 0xff];
108  s += sq[(x >> 24) & 0xff];
109 #endif
110  pix += 8;
111  }
112  pix += line_size - 16;
113  }
114  return s;
115 }
116 
117 static av_always_inline void draw_edges_lr(uint8_t *ptr, ptrdiff_t wrap, int width, int height, int w)
118 {
119  for (int i = 0; i < height; i++) {
120  memset(ptr - w, ptr[0], w);
121  memset(ptr + width, ptr[width - 1], w);
122  ptr += wrap;
123  }
124 }
125 
126 /* draw the edges of width 'w' of an image of size width, height */
127 // FIXME: Check that this is OK for MPEG-4 interlaced.
128 static void draw_edges_8_c(uint8_t *buf, ptrdiff_t wrap, int width, int height,
129  int w, int h, int sides)
130 {
131  uint8_t *last_line;
132  int i;
133 
134  /* left and right */
135  if (w == 16) {
136  draw_edges_lr(buf, wrap, width, height, 16);
137  } else if (w == 8) {
138  draw_edges_lr(buf, wrap, width, height, 8);
139  } else {
140  av_assert1(w == 4);
141  draw_edges_lr(buf, wrap, width, height, 4);
142  }
143 
144  /* top and bottom + corners */
145  buf -= w;
146  last_line = buf + (height - 1) * wrap;
147  if (sides & EDGE_TOP)
148  for (i = 0; i < h; i++)
149  // top
150  memcpy(buf - (i + 1) * wrap, buf, width + w + w);
151  if (sides & EDGE_BOTTOM)
152  for (i = 0; i < h; i++)
153  // bottom
154  memcpy(last_line + (i + 1) * wrap, last_line, width + w + w);
155 }
156 
157 /* This wrapper function only serves to convert the stride parameters
158  * from ptrdiff_t to int for av_image_copy_plane(). */
159 static void copy_plane_wrapper(uint8_t *dst, ptrdiff_t dst_wrap,
160  const uint8_t *src, ptrdiff_t src_wrap,
161  int width, int height)
162 {
163  av_image_copy_plane(dst, dst_wrap, src, src_wrap, width, height);
164 }
165 
166 /* 2x2 -> 1x1 */
167 static void shrink22(uint8_t *dst, ptrdiff_t dst_wrap,
168  const uint8_t *src, ptrdiff_t src_wrap,
169  int width, int height)
170 {
171  int w;
172  const uint8_t *s1, *s2;
173  uint8_t *d;
174 
175  for (; height > 0; height--) {
176  s1 = src;
177  s2 = s1 + src_wrap;
178  d = dst;
179  for (w = width; w >= 4; w -= 4) {
180  d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
181  d[1] = (s1[2] + s1[3] + s2[2] + s2[3] + 2) >> 2;
182  d[2] = (s1[4] + s1[5] + s2[4] + s2[5] + 2) >> 2;
183  d[3] = (s1[6] + s1[7] + s2[6] + s2[7] + 2) >> 2;
184  s1 += 8;
185  s2 += 8;
186  d += 4;
187  }
188  for (; w > 0; w--) {
189  d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
190  s1 += 2;
191  s2 += 2;
192  d++;
193  }
194  src += 2 * src_wrap;
195  dst += dst_wrap;
196  }
197 }
198 
199 /* 4x4 -> 1x1 */
200 static void shrink44(uint8_t *dst, ptrdiff_t dst_wrap,
201  const uint8_t *src, ptrdiff_t src_wrap,
202  int width, int height)
203 {
204  int w;
205  const uint8_t *s1, *s2, *s3, *s4;
206  uint8_t *d;
207 
208  for (; height > 0; height--) {
209  s1 = src;
210  s2 = s1 + src_wrap;
211  s3 = s2 + src_wrap;
212  s4 = s3 + src_wrap;
213  d = dst;
214  for (w = width; w > 0; w--) {
215  d[0] = (s1[0] + s1[1] + s1[2] + s1[3] +
216  s2[0] + s2[1] + s2[2] + s2[3] +
217  s3[0] + s3[1] + s3[2] + s3[3] +
218  s4[0] + s4[1] + s4[2] + s4[3] + 8) >> 4;
219  s1 += 4;
220  s2 += 4;
221  s3 += 4;
222  s4 += 4;
223  d++;
224  }
225  src += 4 * src_wrap;
226  dst += dst_wrap;
227  }
228 }
229 
230 /* 8x8 -> 1x1 */
231 static void shrink88(uint8_t *dst, ptrdiff_t dst_wrap,
232  const uint8_t *src, ptrdiff_t src_wrap,
233  int width, int height)
234 {
235  int w, i;
236 
237  for (; height > 0; height--) {
238  for(w = width;w > 0; w--) {
239  int tmp = 0;
240  for (i = 0; i < 8; i++) {
241  tmp += src[0] + src[1] + src[2] + src[3] +
242  src[4] + src[5] + src[6] + src[7];
243  src += src_wrap;
244  }
245  *(dst++) = (tmp + 32) >> 6;
246  src += 8 - 8 * src_wrap;
247  }
248  src += 8 * src_wrap - 8 * width;
249  dst += dst_wrap - width;
250  }
251 }
252 
254  AVCodecContext *avctx)
255 {
256  c->try_8x8basis = try_8x8basis_c;
257  c->add_8x8basis = add_8x8basis_c;
258 
259  c->shrink[0] = copy_plane_wrapper;
260  c->shrink[1] = shrink22;
261  c->shrink[2] = shrink44;
262  c->shrink[3] = shrink88;
263 
264  c->pix_sum = pix_sum_c;
265  c->pix_norm1 = pix_norm1_c;
266 
267  c->draw_edges = draw_edges_8_c;
268 
269 #if ARCH_AARCH64
271 #elif ARCH_ARM
273 #elif ARCH_PPC
275 #elif ARCH_RISCV
277 #elif ARCH_X86
279 #elif ARCH_MIPS
281 #endif
282 }
add_8x8basis_c
static void add_8x8basis_c(int16_t rem[64], const int16_t basis[64], int scale)
Definition: mpegvideoencdsp.c:50
EDGE_BOTTOM
#define EDGE_BOTTOM
Definition: mpegvideoencdsp.h:30
copy_plane_wrapper
static void copy_plane_wrapper(uint8_t *dst, ptrdiff_t dst_wrap, const uint8_t *src, ptrdiff_t src_wrap, int width, int height)
Definition: mpegvideoencdsp.c:159
basis
static int16_t basis[64][64]
Definition: mpegvideo_enc.c:4210
tmp
static uint8_t tmp[11]
Definition: aes_ctr.c:28
w
uint8_t w
Definition: llviddspenc.c:38
b
#define b
Definition: input.c:41
ff_mpegvideoencdsp_init_x86
void ff_mpegvideoencdsp_init_x86(MpegvideoEncDSPContext *c, AVCodecContext *avctx)
Definition: mpegvideoencdsp_init.c:183
av_image_copy_plane
void av_image_copy_plane(uint8_t *dst, int dst_linesize, const uint8_t *src, int src_linesize, int bytewidth, int height)
Copy image plane from src to dst.
Definition: imgutils.c:374
ff_mpegvideoencdsp_init_mips
av_cold void ff_mpegvideoencdsp_init_mips(MpegvideoEncDSPContext *c, AVCodecContext *avctx)
Definition: mpegvideoencdsp_init_mips.c:26
wrap
#define wrap(func)
Definition: neontest.h:65
draw_edges_lr
static av_always_inline void draw_edges_lr(uint8_t *ptr, ptrdiff_t wrap, int width, int height, int w)
Definition: mpegvideoencdsp.c:117
weight
const h264_weight_func weight
Definition: h264dsp_init.c:33
shrink22
static void shrink22(uint8_t *dst, ptrdiff_t dst_wrap, const uint8_t *src, ptrdiff_t src_wrap, int width, int height)
Definition: mpegvideoencdsp.c:167
avassert.h
av_cold
#define av_cold
Definition: attributes.h:90
s
#define s(width, name)
Definition: cbs_vp9.c:198
BASIS_SHIFT
#define BASIS_SHIFT
Definition: mpegvideoencdsp.h:26
try_8x8basis_c
static int try_8x8basis_c(const int16_t rem[64], const int16_t weight[64], const int16_t basis[64], int scale)
Definition: mpegvideoencdsp.c:31
pix_sum_c
static int pix_sum_c(const uint8_t *pix, ptrdiff_t line_size)
Definition: mpegvideoencdsp.c:60
shrink44
static void shrink44(uint8_t *dst, ptrdiff_t dst_wrap, const uint8_t *src, ptrdiff_t src_wrap, int width, int height)
Definition: mpegvideoencdsp.c:200
ff_mpegvideoencdsp_init_ppc
av_cold void ff_mpegvideoencdsp_init_ppc(MpegvideoEncDSPContext *c, AVCodecContext *avctx)
Definition: mpegvideoencdsp.c:151
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
ff_mpegvideoencdsp_init_riscv
void ff_mpegvideoencdsp_init_riscv(MpegvideoEncDSPContext *c, AVCodecContext *avctx)
Definition: mpegvideoencdsp_init.c:32
height
#define height
Definition: dsp.h:85
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:83
pix_norm1_c
static int pix_norm1_c(const uint8_t *pix, ptrdiff_t line_size)
Definition: mpegvideoencdsp.c:81
RECON_SHIFT
#define RECON_SHIFT
Definition: mpegvideoencdsp.h:27
attributes.h
ff_mpegvideoencdsp_init_aarch64
av_cold void ff_mpegvideoencdsp_init_aarch64(MpegvideoEncDSPContext *c, AVCodecContext *avctx)
Definition: mpegvideoencdsp_init.c:34
MpegvideoEncDSPContext
Definition: mpegvideoencdsp.h:32
av_assert2
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
Definition: avassert.h:67
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
ff_square_tab
const uint32_t ff_square_tab[512]
Definition: me_cmp.c:37
av_assert1
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Definition: avassert.h:56
av_always_inline
#define av_always_inline
Definition: attributes.h:49
avcodec.h
shrink88
static void shrink88(uint8_t *dst, ptrdiff_t dst_wrap, const uint8_t *src, ptrdiff_t src_wrap, int width, int height)
Definition: mpegvideoencdsp.c:231
me_cmp.h
AVCodecContext
main external API structure.
Definition: avcodec.h:451
EDGE_TOP
#define EDGE_TOP
Definition: mpegvideoencdsp.h:29
draw_edges_8_c
static void draw_edges_8_c(uint8_t *buf, ptrdiff_t wrap, int width, int height, int w, int h, int sides)
Definition: mpegvideoencdsp.c:128
ff_mpegvideoencdsp_init_arm
av_cold void ff_mpegvideoencdsp_init_arm(MpegvideoEncDSPContext *c, AVCodecContext *avctx)
Definition: mpegvideoencdsp_init_arm.c:30
mpegvideoencdsp.h
scale
static void scale(int *out, const int *in, const int w, const int h, const int shift)
Definition: intra.c:291
ff_mpegvideoencdsp_init
av_cold void ff_mpegvideoencdsp_init(MpegvideoEncDSPContext *c, AVCodecContext *avctx)
Definition: mpegvideoencdsp.c:253
imgutils.h
h
h
Definition: vp9dsp_template.c:2070
width
#define width
Definition: dsp.h:85
src
#define src
Definition: vp8dsp.c:248