FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/msmpeg4.c
Date: 2024-11-20 23:03:26
Exec Total Coverage
Lines: 100 145 69.0%
Functions: 5 6 83.3%
Branches: 40 70 57.1%

Line Branch Exec Source
1 /*
2 * MSMPEG4 backend for encoder and decoder
3 * Copyright (c) 2001 Fabrice Bellard
4 * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
5 *
6 * msmpeg4v1 & v2 stuff by Michael Niedermayer <michaelni@gmx.at>
7 *
8 * This file is part of FFmpeg.
9 *
10 * FFmpeg is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
14 *
15 * FFmpeg is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with FFmpeg; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 */
24
25 /**
26 * @file
27 * MSMPEG4 backend for encoder and decoder
28 */
29
30 #include "config.h"
31
32 #include "libavutil/thread.h"
33 #if ARCH_X86
34 #include "libavutil/x86/asm.h"
35 #endif
36
37 #include "avcodec.h"
38 #include "idctdsp.h"
39 #include "mpegvideo.h"
40 #include "msmpeg4.h"
41 #include "mpeg4videodata.h"
42 #include "msmpeg4data.h"
43 #include "msmpeg4_vc1_data.h"
44
45 /*
46 * You can also call this codec: MPEG-4 with a twist!
47 *
48 * TODO:
49 * - (encoding) select best mv table (two choices)
50 * - (encoding) select best vlc/dc table
51 */
52
53 /* This table is practically identical to the one from H.263
54 * except that it is inverted. */
55 43 static av_cold void init_h263_dc_for_msmpeg4(void)
56 {
57
2/2
✓ Branch 0 taken 22016 times.
✓ Branch 1 taken 43 times.
22059 for (int level = -256; level < 256; level++) {
58 int uni_code, uni_len;
59 int size, v, l;
60 /* find number of bits */
61 22016 size = 0;
62 22016 v = abs(level);
63
2/2
✓ Branch 0 taken 154585 times.
✓ Branch 1 taken 22016 times.
176601 while (v) {
64 154585 v >>= 1;
65 154585 size++;
66 }
67
68
2/2
✓ Branch 0 taken 11008 times.
✓ Branch 1 taken 11008 times.
22016 if (level < 0)
69 11008 l = (-level) ^ ((1 << size) - 1);
70 else
71 11008 l = level;
72
73 /* luminance H.263 */
74 22016 uni_code = ff_mpeg4_DCtab_lum[size][0];
75 22016 uni_len = ff_mpeg4_DCtab_lum[size][1];
76 22016 uni_code ^= (1 << uni_len) - 1; //M$ does not like compatibility
77
78
2/2
✓ Branch 0 taken 21973 times.
✓ Branch 1 taken 43 times.
22016 if (size > 0) {
79 21973 uni_code <<= size; uni_code |= l;
80 21973 uni_len += size;
81
2/2
✓ Branch 0 taken 43 times.
✓ Branch 1 taken 21930 times.
21973 if (size > 8) {
82 43 uni_code <<= 1; uni_code |= 1;
83 43 uni_len++;
84 }
85 }
86 22016 ff_v2_dc_lum_table[level + 256][0] = uni_code;
87 22016 ff_v2_dc_lum_table[level + 256][1] = uni_len;
88
89 /* chrominance H.263 */
90 22016 uni_code = ff_mpeg4_DCtab_chrom[size][0];
91 22016 uni_len = ff_mpeg4_DCtab_chrom[size][1];
92 22016 uni_code ^= (1 << uni_len) - 1; //M$ does not like compatibility
93
94
2/2
✓ Branch 0 taken 21973 times.
✓ Branch 1 taken 43 times.
22016 if (size > 0) {
95 21973 uni_code <<= size; uni_code |= l;
96 21973 uni_len +=size;
97
2/2
✓ Branch 0 taken 43 times.
✓ Branch 1 taken 21930 times.
21973 if (size > 8) {
98 43 uni_code <<= 1; uni_code |= 1;
99 43 uni_len++;
100 }
101 }
102 22016 ff_v2_dc_chroma_table[level + 256][0] = uni_code;
103 22016 ff_v2_dc_chroma_table[level + 256][1] = uni_len;
104 }
105 43 }
106
107 43 static av_cold void msmpeg4_common_init_static(void)
108 {
109 static uint8_t rl_table_store[NB_RL_TABLES][2][2 * MAX_RUN + MAX_LEVEL + 3];
110
111
2/2
✓ Branch 0 taken 258 times.
✓ Branch 1 taken 43 times.
301 for (int i = 0; i < NB_RL_TABLES; i++)
112 258 ff_rl_init(&ff_rl_table[i], rl_table_store[i]);
113
114 43 init_h263_dc_for_msmpeg4();
115 43 }
116
117 62 av_cold void ff_msmpeg4_common_init(MpegEncContext *s)
118 {
119 static AVOnce init_static_once = AV_ONCE_INIT;
120
121
3/4
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 18 times.
✓ Branch 2 taken 29 times.
✗ Branch 3 not taken.
62 switch(s->msmpeg4_version){
122 15 case MSMP4_V1:
123 case MSMP4_V2:
124 // Correct *_dc_scale_tables (ff_mpeg1_dc_scale_table) is the default
125 15 break;
126 18 case MSMP4_V3:
127
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 5 times.
18 if(s->workaround_bugs){
128 13 s->y_dc_scale_table= ff_old_ff_y_dc_scale_table;
129 13 s->c_dc_scale_table= ff_wmv1_c_dc_scale_table;
130 } else{
131 5 s->y_dc_scale_table= ff_mpeg4_y_dc_scale_table;
132 5 s->c_dc_scale_table= ff_mpeg4_c_dc_scale_table;
133 }
134 18 break;
135 29 case MSMP4_WMV1:
136 case MSMP4_WMV2:
137 29 s->y_dc_scale_table= ff_wmv1_y_dc_scale_table;
138 29 s->c_dc_scale_table= ff_wmv1_c_dc_scale_table;
139 29 break;
140 }
141
142
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 33 times.
62 if (s->msmpeg4_version >= MSMP4_WMV1) {
143 29 ff_init_scantable(s->idsp.idct_permutation, &s->intra_scantable, ff_wmv1_scantable[1]);
144 29 ff_init_scantable(s->idsp.idct_permutation, &s->inter_scantable, ff_wmv1_scantable[0]);
145 29 ff_permute_scantable(s->permutated_intra_h_scantable, ff_wmv1_scantable[2],
146 29 s->idsp.idct_permutation);
147 29 ff_permute_scantable(s->permutated_intra_v_scantable, ff_wmv1_scantable[3],
148 29 s->idsp.idct_permutation);
149 }
150 //Note the default tables are set in common_init in mpegvideo.c
151
152 62 ff_thread_once(&init_static_once, msmpeg4_common_init_static);
153 62 }
154
155 /* predict coded block */
156 168960 int ff_msmpeg4_coded_block_pred(MpegEncContext * s, int n, uint8_t **coded_block_ptr)
157 {
158 int xy, wrap, pred, a, b, c;
159
160 168960 xy = s->block_index[n];
161 168960 wrap = s->b8_stride;
162
163 /* B C
164 * A X
165 */
166 168960 a = s->coded_block[xy - 1 ];
167 168960 b = s->coded_block[xy - 1 - wrap];
168 168960 c = s->coded_block[xy - wrap];
169
170
2/2
✓ Branch 0 taken 150152 times.
✓ Branch 1 taken 18808 times.
168960 if (b == c) {
171 150152 pred = a;
172 } else {
173 18808 pred = c;
174 }
175
176 /* store value */
177 168960 *coded_block_ptr = &s->coded_block[xy];
178
179 168960 return pred;
180 }
181
182 static int get_dc(uint8_t *src, int stride, int scale, int block_size)
183 {
184 int y;
185 int sum=0;
186 for(y=0; y<block_size; y++){
187 int x;
188 for(x=0; x<block_size; x++){
189 sum+=src[x + y*stride];
190 }
191 }
192 return FASTDIV((sum + (scale>>1)), scale);
193 }
194
195 /* dir = 0: left, dir = 1: top prediction */
196 433272 int ff_msmpeg4_pred_dc(MpegEncContext *s, int n,
197 int16_t **dc_val_ptr, int *dir_ptr)
198 {
199 int a, b, c, wrap, pred, scale;
200 int16_t *dc_val;
201
202 /* find prediction */
203
2/2
✓ Branch 0 taken 288848 times.
✓ Branch 1 taken 144424 times.
433272 if (n < 4) {
204 288848 scale = s->y_dc_scale;
205 } else {
206 144424 scale = s->c_dc_scale;
207 }
208
209 433272 wrap = s->block_wrap[n];
210 433272 dc_val= s->dc_val[0] + s->block_index[n];
211
212 /* B C
213 * A X
214 */
215 433272 a = dc_val[ - 1];
216 433272 b = dc_val[ - 1 - wrap];
217 433272 c = dc_val[ - wrap];
218
219
6/6
✓ Branch 0 taken 19830 times.
✓ Branch 1 taken 413442 times.
✓ Branch 2 taken 13220 times.
✓ Branch 3 taken 6610 times.
✓ Branch 4 taken 6624 times.
✓ Branch 5 taken 6596 times.
433272 if (s->first_slice_line && !(n & 2) && s->msmpeg4_version < MSMP4_WMV1)
220 6624 b=c=1024;
221
222 /* XXX: the following solution consumes divisions, but it does not
223 necessitate to modify mpegvideo.c. The problem comes from the
224 fact they decided to store the quantized DC (which would lead
225 to problems if Q could vary !) */
226 #if ARCH_X86 && HAVE_7REGS && HAVE_EBX_AVAILABLE
227 433272 __asm__ volatile(
228 "movl %3, %%eax \n\t"
229 "shrl $1, %%eax \n\t"
230 "addl %%eax, %2 \n\t"
231 "addl %%eax, %1 \n\t"
232 "addl %0, %%eax \n\t"
233 "imull %4 \n\t"
234 "movl %%edx, %0 \n\t"
235 "movl %1, %%eax \n\t"
236 "imull %4 \n\t"
237 "movl %%edx, %1 \n\t"
238 "movl %2, %%eax \n\t"
239 "imull %4 \n\t"
240 "movl %%edx, %2 \n\t"
241 : "+b" (a), "+c" (b), "+D" (c)
242 433272 : "g" (scale), "S" (ff_inverse[scale])
243 : "%eax", "%edx"
244 );
245 #else
246 /* Divisions are costly everywhere; optimize the most common case. */
247 if (scale == 8) {
248 a = (a + (8 >> 1)) / 8;
249 b = (b + (8 >> 1)) / 8;
250 c = (c + (8 >> 1)) / 8;
251 } else {
252 a = FASTDIV((a + (scale >> 1)), scale);
253 b = FASTDIV((b + (scale >> 1)), scale);
254 c = FASTDIV((c + (scale >> 1)), scale);
255 }
256 #endif
257 /* XXX: WARNING: they did not choose the same test as MPEG-4. This
258 is very important ! */
259
2/2
✓ Branch 0 taken 212484 times.
✓ Branch 1 taken 220788 times.
433272 if (s->msmpeg4_version > MSMP4_V3) {
260
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 212484 times.
212484 if(s->inter_intra_pred){
261 uint8_t *dest;
262 int wrap;
263
264 if(n==1){
265 pred=a;
266 *dir_ptr = 0;
267 }else if(n==2){
268 pred=c;
269 *dir_ptr = 1;
270 }else if(n==3){
271 if (abs(a - b) < abs(b - c)) {
272 pred = c;
273 *dir_ptr = 1;
274 } else {
275 pred = a;
276 *dir_ptr = 0;
277 }
278 }else{
279 int bs = 8 >> s->avctx->lowres;
280 if(n<4){
281 wrap= s->linesize;
282 dest = s->cur_pic.data[0] + (((n >> 1) + 2*s->mb_y) * bs* wrap ) + ((n & 1) + 2*s->mb_x) * bs;
283 }else{
284 wrap= s->uvlinesize;
285 dest = s->cur_pic.data[n - 3] + (s->mb_y * bs * wrap) + s->mb_x * bs;
286 }
287 if(s->mb_x==0) a= (1024 + (scale>>1))/scale;
288 else a= get_dc(dest-bs, wrap, scale*8>>(2*s->avctx->lowres), bs);
289 if(s->mb_y==0) c= (1024 + (scale>>1))/scale;
290 else c= get_dc(dest-bs*wrap, wrap, scale*8>>(2*s->avctx->lowres), bs);
291
292 if (s->h263_aic_dir==0) {
293 pred= a;
294 *dir_ptr = 0;
295 }else if (s->h263_aic_dir==1) {
296 if(n==0){
297 pred= c;
298 *dir_ptr = 1;
299 }else{
300 pred= a;
301 *dir_ptr = 0;
302 }
303 }else if (s->h263_aic_dir==2) {
304 if(n==0){
305 pred= a;
306 *dir_ptr = 0;
307 }else{
308 pred= c;
309 *dir_ptr = 1;
310 }
311 } else {
312 pred= c;
313 *dir_ptr = 1;
314 }
315 }
316 }else{
317
2/2
✓ Branch 0 taken 86305 times.
✓ Branch 1 taken 126179 times.
212484 if (abs(a - b) < abs(b - c)) {
318 86305 pred = c;
319 86305 *dir_ptr = 1;
320 } else {
321 126179 pred = a;
322 126179 *dir_ptr = 0;
323 }
324 }
325 }else{
326
2/2
✓ Branch 0 taken 116422 times.
✓ Branch 1 taken 104366 times.
220788 if (abs(a - b) <= abs(b - c)) {
327 116422 pred = c;
328 116422 *dir_ptr = 1;
329 } else {
330 104366 pred = a;
331 104366 *dir_ptr = 0;
332 }
333 }
334
335 /* update predictor */
336 433272 *dc_val_ptr = &dc_val[0];
337 433272 return pred;
338 }
339
340