FFmpeg
Loading...
Searching...
No Matches
mpegvideoencdsp_init.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 <stdint.h>
20
22#include "libavutil/avassert.h"
23#include "libavutil/common.h"
24#include "libavutil/cpu.h"
25#include "libavutil/x86/asm.h"
26#include "libavutil/x86/cpu.h"
27#include "libavcodec/avcodec.h"
29#include "mpegvideoencdsp.h"
30
31int ff_pix_sum16_sse2(const uint8_t *pix, ptrdiff_t line_size);
32int ff_pix_sum16_xop(const uint8_t *pix, ptrdiff_t line_size);
33int ff_pix_norm1_sse2(const uint8_t *pix, ptrdiff_t line_size);
34void ff_add_8x8basis_ssse3(int16_t rem[64], const int16_t basis[64], int scale);
35
36#if HAVE_SSSE3_INLINE
37#define SCALE_OFFSET -1
38
39#define MAX_ABS 512
40
41static int try_8x8basis_ssse3(const int16_t rem[64], const int16_t weight[64], const int16_t basis[64], int scale)
42{
43 x86_reg i=0;
44
45 av_assert2(FFABS(scale) < MAX_ABS);
46 scale *= 1 << (16 + SCALE_OFFSET - BASIS_SHIFT + RECON_SHIFT);
47
48 __asm__ volatile(
49 "pxor %%xmm2, %%xmm2 \n\t"
50 "movd %4, %%xmm3 \n\t"
51 "punpcklwd %%xmm3, %%xmm3 \n\t"
52 "pshufd $0, %%xmm3, %%xmm3 \n\t"
53 ".p2align 4 \n\t"
54 "1: \n\t"
55 "movdqa (%1, %0), %%xmm0 \n\t"
56 "movdqa 16(%1, %0), %%xmm1 \n\t"
57 "pmulhrsw %%xmm3, %%xmm0 \n\t"
58 "pmulhrsw %%xmm3, %%xmm1 \n\t"
59 "paddw (%2, %0), %%xmm0 \n\t"
60 "paddw 16(%2, %0), %%xmm1 \n\t"
61 "psraw $6, %%xmm0 \n\t"
62 "psraw $6, %%xmm1 \n\t"
63 "pmullw (%3, %0), %%xmm0 \n\t"
64 "pmullw 16(%3, %0), %%xmm1 \n\t"
65 "pmaddwd %%xmm0, %%xmm0 \n\t"
66 "pmaddwd %%xmm1, %%xmm1 \n\t"
67 "paddd %%xmm1, %%xmm0 \n\t"
68 "psrld $4, %%xmm0 \n\t"
69 "paddd %%xmm0, %%xmm2 \n\t"
70 "add $32, %0 \n\t"
71 "cmp $128, %0 \n\t" //FIXME optimize & bench
72 " jb 1b \n\t"
73 "pshufd $0x0E, %%xmm2, %%xmm0 \n\t"
74 "paddd %%xmm0, %%xmm2 \n\t"
75 "pshufd $0x01, %%xmm2, %%xmm0 \n\t"
76 "paddd %%xmm0, %%xmm2 \n\t"
77 "psrld $2, %%xmm2 \n\t"
78 "movd %%xmm2, %0 \n\t"
79 : "+r" (i)
80 : "r"(basis), "r"(rem), "r"(weight), "g"(scale)
81 XMM_CLOBBERS_ONLY("%xmm0", "%xmm1", "%xmm2", "%xmm3")
82 );
83 return i;
84}
85
86/* Draw the edges of width 'w' of an image of size width, height */
87static void draw_edges_ssse3(uint8_t *buf, ptrdiff_t wrap, int width, int height,
88 int w, int h, int sides)
89{
90 uint8_t *ptr = buf, *last_line;
91 int i;
92
93 av_assert1(w == 16 || w == 8 || w == 4);
94
95 /* left and right */
96 __asm__ volatile (
97 "pcmpeqw %%xmm3, %%xmm3 \n\t"
98 "pxor %%xmm2, %%xmm2 \n\t"
99 "psrlw $14, %%xmm3 \n\t" // pw_3
100 "pshufb %%xmm2, %%xmm3 \n\t" // pb_3
101 "cmp $8, %4 \n\t"
102 "jg 16f \n\t"
103 "jl 4f \n\t"
104 "8: \n\t"
105 "movd (%0), %%xmm0 \n\t"
106 "movd -4(%0, %2), %%xmm1 \n\t"
107 "pshufb %%xmm2, %%xmm0 \n\t"
108 "pshufb %%xmm3, %%xmm1 \n\t"
109 "movq %%xmm0, -8(%0) \n\t"
110 "movq %%xmm1, (%0, %2) \n\t"
111 "add %1, %0 \n\t"
112 "cmp %3, %0 \n\t"
113 "jnz 8b \n\t"
114 "jmp 1f \n\t"
115 "4: \n\t"
116 "movd (%0), %%xmm0 \n\t"
117 "movd -4(%0, %2), %%xmm1 \n\t"
118 "pshufb %%xmm2, %%xmm0 \n\t"
119 "pshufb %%xmm3, %%xmm1 \n\t"
120 "movd %%xmm0, -4(%0) \n\t"
121 "movd %%xmm1, (%0, %2) \n\t"
122 "add %1, %0 \n\t"
123 "cmp %3, %0 \n\t"
124 "jnz 4b \n\t"
125 "jmp 1f \n\t"
126 "16: \n\t"
127 "movd (%0), %%xmm0 \n\t"
128 "movd -4(%0, %2), %%xmm1 \n\t"
129 "pshufb %%xmm2, %%xmm0 \n\t"
130 "pshufb %%xmm3, %%xmm1 \n\t"
131 "movdqu %%xmm0, -16(%0) \n\t"
132 "movdqu %%xmm1, (%0, %2) \n\t"
133 "add %1, %0 \n\t"
134 "cmp %3, %0 \n\t"
135 "jnz 16b \n\t"
136 "1: \n\t"
137 : "+r" (ptr)
138 : "r" ((x86_reg) wrap), "r" ((x86_reg) width), "r"(ptr + wrap * height), "r" (w)
139 XMM_CLOBBERS_ONLY("%xmm0", "%xmm1", "%xmm2", "%xmm3")
140 );
141
142 /* top and bottom + corners */
143 buf -= w;
144 last_line = buf + (height - 1) * wrap;
145 if (sides & EDGE_TOP)
146 for (i = 0; i < h; i++)
147 // top
148 memcpy(buf - (i + 1) * wrap, buf, width + w + w);
149 if (sides & EDGE_BOTTOM)
150 for (i = 0; i < h; i++)
151 // bottom
152 memcpy(last_line + (i + 1) * wrap, last_line, width + w + w);
153}
154#endif /* HAVE_SSSE3_INLINE */
155
157 AVCodecContext *avctx)
158{
160
162 c->denoise_dct = ff_mpv_denoise_dct_sse2;
163 c->pix_sum = ff_pix_sum16_sse2;
164 c->pix_norm1 = ff_pix_norm1_sse2;
165 }
166
167 if (EXTERNAL_XOP(cpu_flags)) {
168 c->pix_sum = ff_pix_sum16_xop;
169 }
170
171 if (X86_SSSE3(cpu_flags)) {
172#if HAVE_SSSE3_INLINE
173 if (!(avctx->flags & AV_CODEC_FLAG_BITEXACT)) {
174 c->try_8x8basis = try_8x8basis_ssse3;
175 }
176 if (avctx->bits_per_raw_sample <= 8) {
177 c->draw_edges = draw_edges_ssse3;
178 }
179#endif /* HAVE_SSSE3_INLINE */
180#if HAVE_SSSE3_EXTERNAL
181 c->add_8x8basis = ff_add_8x8basis_ssse3;
182#endif
183 }
184
185}
#define wrap(func)
Definition neontest.h:65
#define XMM_CLOBBERS_ONLY(...)
Definition asm.h:95
int x86_reg
Definition asm.h:71
__asm__(".macro parse_r var r\n\t" "\\var = -1\n\t" _IFC_REG(0) _IFC_REG(1) _IFC_REG(2) _IFC_REG(3) _IFC_REG(4) _IFC_REG(5) _IFC_REG(6) _IFC_REG(7) _IFC_REG(8) _IFC_REG(9) _IFC_REG(10) _IFC_REG(11) _IFC_REG(12) _IFC_REG(13) _IFC_REG(14) _IFC_REG(15) _IFC_REG(16) _IFC_REG(17) _IFC_REG(18) _IFC_REG(19) _IFC_REG(20) _IFC_REG(21) _IFC_REG(22) _IFC_REG(23) _IFC_REG(24) _IFC_REG(25) _IFC_REG(26) _IFC_REG(27) _IFC_REG(28) _IFC_REG(29) _IFC_REG(30) _IFC_REG(31) ".iflt \\var\n\t" ".error \"Unable to parse register name \\r\"\n\t" ".endif\n\t" ".endm")
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
Definition avassert.h:68
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Definition avassert.h:58
Libavcodec external API header.
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
common internal and external API header
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition common.h:74
#define AV_CODEC_FLAG_BITEXACT
Use only bitexact stuff (except (I)DCT).
Definition avcodec.h:322
static void scale(int *out, const int *in, const int w, const int h, const int shift)
Definition intra.c:278
Macro definitions for various function/variable attributes.
#define av_cold
Definition attributes.h:117
static atomic_int cpu_flags
Definition cpu.c:56
int av_get_cpu_flags(void)
Return the flags which specify extensions supported by the CPU.
Definition cpu.c:109
#define EXTERNAL_XOP(flags)
Definition cpu.h:67
#define X86_SSSE3(flags)
Definition cpu.h:34
#define EXTERNAL_SSE2(flags)
Definition cpu.h:53
uint8_t w
Definition llvidencdsp.c:39
static int16_t basis[64][64]
#define BASIS_SHIFT
#define EDGE_BOTTOM
#define RECON_SHIFT
#define EDGE_TOP
enum AVPixelFormat pix
Definition ohcodec.c:55
const h264_weight_func weight
main external API structure.
Definition avcodec.h:443
int bits_per_raw_sample
Bits per sample/pixel of internal libavcodec pixel/sample format.
Definition avcodec.h:1571
int flags
AV_CODEC_FLAG_*.
Definition avcodec.h:500
#define height
Definition dsp.h:89
#define width
Definition dsp.h:89
static double c[64]
EXTERN void ff_mpv_denoise_dct_sse2(int16_t block[64], int dct_error_sum[64], const uint16_t dct_offset[64])
av_cold void ff_mpegvideoencdsp_init_x86(MpegvideoEncDSPContext *c, AVCodecContext *avctx)
int ff_pix_norm1_sse2(const uint8_t *pix, ptrdiff_t line_size)
int ff_pix_sum16_xop(const uint8_t *pix, ptrdiff_t line_size)
int ff_pix_sum16_sse2(const uint8_t *pix, ptrdiff_t line_size)
void ff_add_8x8basis_ssse3(int16_t rem[64], const int16_t basis[64], int scale)