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 "config.h" |
20 |
|
|
#include "libavutil/attributes.h" |
21 |
|
|
#include "lossless_videoencdsp.h" |
22 |
|
|
#include "mathops.h" |
23 |
|
|
|
24 |
|
|
// 0x7f7f7f7f or 0x7f7f7f7f7f7f7f7f or whatever, depending on the cpu's native arithmetic size |
25 |
|
|
#define pb_7f (~0UL / 255 * 0x7f) |
26 |
|
|
#define pb_80 (~0UL / 255 * 0x80) |
27 |
|
|
|
28 |
|
443915 |
static void diff_bytes_c(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, intptr_t w) |
29 |
|
|
{ |
30 |
|
|
long i; |
31 |
|
|
|
32 |
|
|
#if !HAVE_FAST_UNALIGNED |
33 |
|
|
if (((long)src1 | (long)src2) & (sizeof(long) - 1)) { |
34 |
|
|
for (i = 0; i + 7 < w; i += 8) { |
35 |
|
|
dst[i + 0] = src1[i + 0] - src2[i + 0]; |
36 |
|
|
dst[i + 1] = src1[i + 1] - src2[i + 1]; |
37 |
|
|
dst[i + 2] = src1[i + 2] - src2[i + 2]; |
38 |
|
|
dst[i + 3] = src1[i + 3] - src2[i + 3]; |
39 |
|
|
dst[i + 4] = src1[i + 4] - src2[i + 4]; |
40 |
|
|
dst[i + 5] = src1[i + 5] - src2[i + 5]; |
41 |
|
|
dst[i + 6] = src1[i + 6] - src2[i + 6]; |
42 |
|
|
dst[i + 7] = src1[i + 7] - src2[i + 7]; |
43 |
|
|
} |
44 |
|
|
} else |
45 |
|
|
#endif |
46 |
✓✓ |
24322340 |
for (i = 0; i <= w - (int) sizeof(long); i += sizeof(long)) { |
47 |
|
23878425 |
long a = *(long *) (src1 + i); |
48 |
|
23878425 |
long b = *(long *) (src2 + i); |
49 |
|
23878425 |
*(long *) (dst + i) = ((a | pb_80) - (b & pb_7f)) ^ |
50 |
|
23878425 |
((a ^ b ^ pb_80) & pb_80); |
51 |
|
|
} |
52 |
✓✓ |
472551 |
for (; i < w; i++) |
53 |
|
28636 |
dst[i + 0] = src1[i + 0] - src2[i + 0]; |
54 |
|
443915 |
} |
55 |
|
|
|
56 |
|
215200 |
static void sub_median_pred_c(uint8_t *dst, const uint8_t *src1, |
57 |
|
|
const uint8_t *src2, intptr_t w, |
58 |
|
|
int *left, int *left_top) |
59 |
|
|
{ |
60 |
|
|
int i; |
61 |
|
|
uint8_t l, lt; |
62 |
|
|
|
63 |
|
215200 |
l = *left; |
64 |
|
215200 |
lt = *left_top; |
65 |
|
|
|
66 |
✓✓ |
68397600 |
for (i = 0; i < w; i++) { |
67 |
|
68182400 |
const int pred = mid_pred(l, src1[i], (l + src1[i] - lt) & 0xFF); |
68 |
|
68182400 |
lt = src1[i]; |
69 |
|
68182400 |
l = src2[i]; |
70 |
|
68182400 |
dst[i] = l - pred; |
71 |
|
|
} |
72 |
|
|
|
73 |
|
215200 |
*left = l; |
74 |
|
215200 |
*left_top = lt; |
75 |
|
215200 |
} |
76 |
|
|
|
77 |
|
803 |
static void sub_left_predict_c(uint8_t *dst, uint8_t *src, |
78 |
|
|
ptrdiff_t stride, ptrdiff_t width, int height) |
79 |
|
|
{ |
80 |
|
|
int i, j; |
81 |
|
803 |
uint8_t prev = 0x80; /* Set the initial value */ |
82 |
✓✓ |
216851 |
for (j = 0; j < height; j++) { |
83 |
✓✓ |
68645616 |
for (i = 0; i < width; i++) { |
84 |
|
68429568 |
*dst++ = src[i] - prev; |
85 |
|
68429568 |
prev = src[i]; |
86 |
|
|
} |
87 |
|
216048 |
src += stride; |
88 |
|
|
} |
89 |
|
803 |
} |
90 |
|
|
|
91 |
|
192 |
av_cold void ff_llvidencdsp_init(LLVidEncDSPContext *c) |
92 |
|
|
{ |
93 |
|
192 |
c->diff_bytes = diff_bytes_c; |
94 |
|
192 |
c->sub_median_pred = sub_median_pred_c; |
95 |
|
192 |
c->sub_left_predict = sub_left_predict_c; |
96 |
|
|
|
97 |
|
|
if (ARCH_X86) |
98 |
|
192 |
ff_llvidencdsp_init_x86(c); |
99 |
|
192 |
} |