yading@10
|
1 /*
|
yading@10
|
2 * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder
|
yading@10
|
3 * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
|
yading@10
|
4 *
|
yading@10
|
5 * This file is part of FFmpeg.
|
yading@10
|
6 *
|
yading@10
|
7 * FFmpeg is free software; you can redistribute it and/or
|
yading@10
|
8 * modify it under the terms of the GNU Lesser General Public
|
yading@10
|
9 * License as published by the Free Software Foundation; either
|
yading@10
|
10 * version 2.1 of the License, or (at your option) any later version.
|
yading@10
|
11 *
|
yading@10
|
12 * FFmpeg is distributed in the hope that it will be useful,
|
yading@10
|
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
yading@10
|
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
yading@10
|
15 * Lesser General Public License for more details.
|
yading@10
|
16 *
|
yading@10
|
17 * You should have received a copy of the GNU Lesser General Public
|
yading@10
|
18 * License along with FFmpeg; if not, write to the Free Software
|
yading@10
|
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
yading@10
|
20 */
|
yading@10
|
21
|
yading@10
|
22 /**
|
yading@10
|
23 * @file
|
yading@10
|
24 * H.264 / AVC / MPEG4 part10 codec.
|
yading@10
|
25 * non-MMX i386-specific optimizations for H.264
|
yading@10
|
26 * @author Michael Niedermayer <michaelni@gmx.at>
|
yading@10
|
27 */
|
yading@10
|
28
|
yading@10
|
29 #ifndef AVCODEC_X86_H264_I386_H
|
yading@10
|
30 #define AVCODEC_X86_H264_I386_H
|
yading@10
|
31
|
yading@10
|
32 #include <stddef.h>
|
yading@10
|
33
|
yading@10
|
34 #include "libavcodec/cabac.h"
|
yading@10
|
35 #include "cabac.h"
|
yading@10
|
36
|
yading@10
|
37 #if HAVE_INLINE_ASM
|
yading@10
|
38
|
yading@10
|
39 //FIXME use some macros to avoid duplicating get_cabac (cannot be done yet
|
yading@10
|
40 //as that would make optimization work hard)
|
yading@10
|
41 #if HAVE_7REGS
|
yading@10
|
42 #define decode_significance decode_significance_x86
|
yading@10
|
43 static int decode_significance_x86(CABACContext *c, int max_coeff,
|
yading@10
|
44 uint8_t *significant_coeff_ctx_base,
|
yading@10
|
45 int *index, x86_reg last_off){
|
yading@10
|
46 void *end= significant_coeff_ctx_base + max_coeff - 1;
|
yading@10
|
47 int minusstart= -(intptr_t)significant_coeff_ctx_base;
|
yading@10
|
48 int minusindex= 4-(intptr_t)index;
|
yading@10
|
49 int bit;
|
yading@10
|
50 x86_reg coeff_count;
|
yading@10
|
51
|
yading@10
|
52 #ifdef BROKEN_RELOCATIONS
|
yading@10
|
53 void *tables;
|
yading@10
|
54
|
yading@10
|
55 __asm__ volatile(
|
yading@10
|
56 "lea "MANGLE(ff_h264_cabac_tables)", %0 \n\t"
|
yading@10
|
57 : "=&r"(tables)
|
yading@10
|
58 );
|
yading@10
|
59 #endif
|
yading@10
|
60
|
yading@10
|
61 __asm__ volatile(
|
yading@10
|
62 "3: \n\t"
|
yading@10
|
63
|
yading@10
|
64 BRANCHLESS_GET_CABAC("%4", "%q4", "(%1)", "%3", "%w3",
|
yading@10
|
65 "%5", "%q5", "%k0", "%b0",
|
yading@10
|
66 "%c11(%6)", "%c12(%6)",
|
yading@10
|
67 AV_STRINGIFY(H264_NORM_SHIFT_OFFSET),
|
yading@10
|
68 AV_STRINGIFY(H264_LPS_RANGE_OFFSET),
|
yading@10
|
69 AV_STRINGIFY(H264_MLPS_STATE_OFFSET),
|
yading@10
|
70 "%13")
|
yading@10
|
71
|
yading@10
|
72 "test $1, %4 \n\t"
|
yading@10
|
73 " jz 4f \n\t"
|
yading@10
|
74 "add %10, %1 \n\t"
|
yading@10
|
75
|
yading@10
|
76 BRANCHLESS_GET_CABAC("%4", "%q4", "(%1)", "%3", "%w3",
|
yading@10
|
77 "%5", "%q5", "%k0", "%b0",
|
yading@10
|
78 "%c11(%6)", "%c12(%6)",
|
yading@10
|
79 AV_STRINGIFY(H264_NORM_SHIFT_OFFSET),
|
yading@10
|
80 AV_STRINGIFY(H264_LPS_RANGE_OFFSET),
|
yading@10
|
81 AV_STRINGIFY(H264_MLPS_STATE_OFFSET),
|
yading@10
|
82 "%13")
|
yading@10
|
83
|
yading@10
|
84 "sub %10, %1 \n\t"
|
yading@10
|
85 "mov %2, %0 \n\t"
|
yading@10
|
86 "movl %7, %%ecx \n\t"
|
yading@10
|
87 "add %1, %%"REG_c" \n\t"
|
yading@10
|
88 "movl %%ecx, (%0) \n\t"
|
yading@10
|
89
|
yading@10
|
90 "test $1, %4 \n\t"
|
yading@10
|
91 " jnz 5f \n\t"
|
yading@10
|
92
|
yading@10
|
93 "add"OPSIZE" $4, %2 \n\t"
|
yading@10
|
94
|
yading@10
|
95 "4: \n\t"
|
yading@10
|
96 "add $1, %1 \n\t"
|
yading@10
|
97 "cmp %8, %1 \n\t"
|
yading@10
|
98 " jb 3b \n\t"
|
yading@10
|
99 "mov %2, %0 \n\t"
|
yading@10
|
100 "movl %7, %%ecx \n\t"
|
yading@10
|
101 "add %1, %%"REG_c" \n\t"
|
yading@10
|
102 "movl %%ecx, (%0) \n\t"
|
yading@10
|
103 "5: \n\t"
|
yading@10
|
104 "add %9, %k0 \n\t"
|
yading@10
|
105 "shr $2, %k0 \n\t"
|
yading@10
|
106 : "=&q"(coeff_count), "+r"(significant_coeff_ctx_base), "+m"(index),
|
yading@10
|
107 "+&r"(c->low), "=&r"(bit), "+&r"(c->range)
|
yading@10
|
108 : "r"(c), "m"(minusstart), "m"(end), "m"(minusindex), "m"(last_off),
|
yading@10
|
109 "i"(offsetof(CABACContext, bytestream)),
|
yading@10
|
110 "i"(offsetof(CABACContext, bytestream_end))
|
yading@10
|
111 TABLES_ARG
|
yading@10
|
112 : "%"REG_c, "memory"
|
yading@10
|
113 );
|
yading@10
|
114 return coeff_count;
|
yading@10
|
115 }
|
yading@10
|
116
|
yading@10
|
117 #define decode_significance_8x8 decode_significance_8x8_x86
|
yading@10
|
118 static int decode_significance_8x8_x86(CABACContext *c,
|
yading@10
|
119 uint8_t *significant_coeff_ctx_base,
|
yading@10
|
120 int *index, uint8_t *last_coeff_ctx_base, const uint8_t *sig_off){
|
yading@10
|
121 int minusindex= 4-(intptr_t)index;
|
yading@10
|
122 int bit;
|
yading@10
|
123 x86_reg coeff_count;
|
yading@10
|
124 x86_reg last=0;
|
yading@10
|
125 x86_reg state;
|
yading@10
|
126
|
yading@10
|
127 #ifdef BROKEN_RELOCATIONS
|
yading@10
|
128 void *tables;
|
yading@10
|
129
|
yading@10
|
130 __asm__ volatile(
|
yading@10
|
131 "lea "MANGLE(ff_h264_cabac_tables)", %0 \n\t"
|
yading@10
|
132 : "=&r"(tables)
|
yading@10
|
133 );
|
yading@10
|
134 #endif
|
yading@10
|
135
|
yading@10
|
136 __asm__ volatile(
|
yading@10
|
137 "mov %1, %6 \n\t"
|
yading@10
|
138 "3: \n\t"
|
yading@10
|
139
|
yading@10
|
140 "mov %10, %0 \n\t"
|
yading@10
|
141 "movzbl (%0, %6), %k6 \n\t"
|
yading@10
|
142 "add %9, %6 \n\t"
|
yading@10
|
143
|
yading@10
|
144 BRANCHLESS_GET_CABAC("%4", "%q4", "(%6)", "%3", "%w3",
|
yading@10
|
145 "%5", "%q5", "%k0", "%b0",
|
yading@10
|
146 "%c12(%7)", "%c13(%7)",
|
yading@10
|
147 AV_STRINGIFY(H264_NORM_SHIFT_OFFSET),
|
yading@10
|
148 AV_STRINGIFY(H264_LPS_RANGE_OFFSET),
|
yading@10
|
149 AV_STRINGIFY(H264_MLPS_STATE_OFFSET),
|
yading@10
|
150 "%15")
|
yading@10
|
151
|
yading@10
|
152 "mov %1, %k6 \n\t"
|
yading@10
|
153 "test $1, %4 \n\t"
|
yading@10
|
154 " jz 4f \n\t"
|
yading@10
|
155
|
yading@10
|
156 #ifdef BROKEN_RELOCATIONS
|
yading@10
|
157 "movzbl %c14(%15, %q6), %k6\n\t"
|
yading@10
|
158 #else
|
yading@10
|
159 "movzbl "MANGLE(ff_h264_cabac_tables)"+%c14(%k6), %k6\n\t"
|
yading@10
|
160 #endif
|
yading@10
|
161 "add %11, %6 \n\t"
|
yading@10
|
162
|
yading@10
|
163 BRANCHLESS_GET_CABAC("%4", "%q4", "(%6)", "%3", "%w3",
|
yading@10
|
164 "%5", "%q5", "%k0", "%b0",
|
yading@10
|
165 "%c12(%7)", "%c13(%7)",
|
yading@10
|
166 AV_STRINGIFY(H264_NORM_SHIFT_OFFSET),
|
yading@10
|
167 AV_STRINGIFY(H264_LPS_RANGE_OFFSET),
|
yading@10
|
168 AV_STRINGIFY(H264_MLPS_STATE_OFFSET),
|
yading@10
|
169 "%15")
|
yading@10
|
170
|
yading@10
|
171 "mov %2, %0 \n\t"
|
yading@10
|
172 "mov %1, %k6 \n\t"
|
yading@10
|
173 "movl %k6, (%0) \n\t"
|
yading@10
|
174
|
yading@10
|
175 "test $1, %4 \n\t"
|
yading@10
|
176 " jnz 5f \n\t"
|
yading@10
|
177
|
yading@10
|
178 "add"OPSIZE" $4, %2 \n\t"
|
yading@10
|
179
|
yading@10
|
180 "4: \n\t"
|
yading@10
|
181 "addl $1, %k6 \n\t"
|
yading@10
|
182 "mov %k6, %1 \n\t"
|
yading@10
|
183 "cmpl $63, %k6 \n\t"
|
yading@10
|
184 " jb 3b \n\t"
|
yading@10
|
185 "mov %2, %0 \n\t"
|
yading@10
|
186 "movl %k6, (%0) \n\t"
|
yading@10
|
187 "5: \n\t"
|
yading@10
|
188 "addl %8, %k0 \n\t"
|
yading@10
|
189 "shr $2, %k0 \n\t"
|
yading@10
|
190 : "=&q"(coeff_count), "+m"(last), "+m"(index), "+&r"(c->low),
|
yading@10
|
191 "=&r"(bit), "+&r"(c->range), "=&r"(state)
|
yading@10
|
192 : "r"(c), "m"(minusindex), "m"(significant_coeff_ctx_base),
|
yading@10
|
193 "m"(sig_off), "m"(last_coeff_ctx_base),
|
yading@10
|
194 "i"(offsetof(CABACContext, bytestream)),
|
yading@10
|
195 "i"(offsetof(CABACContext, bytestream_end)),
|
yading@10
|
196 "i"(H264_LAST_COEFF_FLAG_OFFSET_8x8_OFFSET) TABLES_ARG
|
yading@10
|
197 : "%"REG_c, "memory"
|
yading@10
|
198 );
|
yading@10
|
199 return coeff_count;
|
yading@10
|
200 }
|
yading@10
|
201 #endif /* HAVE_7REGS && !defined(BROKEN_RELOCATIONS) */
|
yading@10
|
202
|
yading@10
|
203 #endif /* HAVE_INLINE_ASM */
|
yading@10
|
204 #endif /* AVCODEC_X86_H264_I386_H */
|