FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/msmpeg4.c
Date: 2022-01-16 20:33:26
Exec Total Coverage
Lines: 104 149 69.8%
Branches: 41 71 57.7%

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 "libavutil/thread.h"
31
32 #include "avcodec.h"
33 #include "idctdsp.h"
34 #include "mpegvideo.h"
35 #include "msmpeg4.h"
36 #include "libavutil/x86/asm.h"
37 #include "mpeg4videodata.h"
38 #include "msmpeg4data.h"
39 #include "mpegvideodata.h"
40 #include "vc1data.h"
41 #include "libavutil/imgutils.h"
42
43 /*
44 * You can also call this codec: MPEG-4 with a twist!
45 *
46 * TODO:
47 * - (encoding) select best mv table (two choices)
48 * - (encoding) select best vlc/dc table
49 */
50
51 /* This table is practically identical to the one from H.263
52 * except that it is inverted. */
53 60 static av_cold void init_h263_dc_for_msmpeg4(void)
54 {
55
2/2
✓ Branch 0 taken 30720 times.
✓ Branch 1 taken 60 times.
30780 for (int level = -256; level < 256; level++) {
56 int uni_code, uni_len;
57 int size, v, l;
58 /* find number of bits */
59 30720 size = 0;
60 30720 v = abs(level);
61
2/2
✓ Branch 0 taken 215700 times.
✓ Branch 1 taken 30720 times.
246420 while (v) {
62 215700 v >>= 1;
63 215700 size++;
64 }
65
66
2/2
✓ Branch 0 taken 15360 times.
✓ Branch 1 taken 15360 times.
30720 if (level < 0)
67 15360 l = (-level) ^ ((1 << size) - 1);
68 else
69 15360 l = level;
70
71 /* luminance H.263 */
72 30720 uni_code = ff_mpeg4_DCtab_lum[size][0];
73 30720 uni_len = ff_mpeg4_DCtab_lum[size][1];
74 30720 uni_code ^= (1 << uni_len) - 1; //M$ does not like compatibility
75
76
2/2
✓ Branch 0 taken 30660 times.
✓ Branch 1 taken 60 times.
30720 if (size > 0) {
77 30660 uni_code <<= size; uni_code |= l;
78 30660 uni_len += size;
79
2/2
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 30600 times.
30660 if (size > 8) {
80 60 uni_code <<= 1; uni_code |= 1;
81 60 uni_len++;
82 }
83 }
84 30720 ff_v2_dc_lum_table[level + 256][0] = uni_code;
85 30720 ff_v2_dc_lum_table[level + 256][1] = uni_len;
86
87 /* chrominance H.263 */
88 30720 uni_code = ff_mpeg4_DCtab_chrom[size][0];
89 30720 uni_len = ff_mpeg4_DCtab_chrom[size][1];
90 30720 uni_code ^= (1 << uni_len) - 1; //M$ does not like compatibility
91
92
2/2
✓ Branch 0 taken 30660 times.
✓ Branch 1 taken 60 times.
30720 if (size > 0) {
93 30660 uni_code <<= size; uni_code |= l;
94 30660 uni_len +=size;
95
2/2
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 30600 times.
30660 if (size > 8) {
96 60 uni_code <<= 1; uni_code |= 1;
97 60 uni_len++;
98 }
99 }
100 30720 ff_v2_dc_chroma_table[level + 256][0] = uni_code;
101 30720 ff_v2_dc_chroma_table[level + 256][1] = uni_len;
102 }
103 60 }
104
105 60 static av_cold void msmpeg4_common_init_static(void)
106 {
107 static uint8_t rl_table_store[NB_RL_TABLES][2][2 * MAX_RUN + MAX_LEVEL + 3];
108
109
2/2
✓ Branch 0 taken 360 times.
✓ Branch 1 taken 60 times.
420 for (int i = 0; i < NB_RL_TABLES; i++)
110 360 ff_rl_init(&ff_rl_table[i], rl_table_store[i]);
111
112 60 init_h263_dc_for_msmpeg4();
113 60 }
114
115 104 av_cold void ff_msmpeg4_common_init(MpegEncContext *s)
116 {
117 static AVOnce init_static_once = AV_ONCE_INIT;
118
119
4/5
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 18 times.
✓ Branch 2 taken 29 times.
✓ Branch 3 taken 42 times.
✗ Branch 4 not taken.
104 switch(s->msmpeg4_version){
120 15 case 1:
121 case 2:
122 15 s->y_dc_scale_table=
123 15 s->c_dc_scale_table= ff_mpeg1_dc_scale_table;
124 15 break;
125 18 case 3:
126
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 5 times.
18 if(s->workaround_bugs){
127 13 s->y_dc_scale_table= ff_old_ff_y_dc_scale_table;
128 13 s->c_dc_scale_table= ff_wmv1_c_dc_scale_table;
129 } else{
130 5 s->y_dc_scale_table= ff_mpeg4_y_dc_scale_table;
131 5 s->c_dc_scale_table= ff_mpeg4_c_dc_scale_table;
132 }
133 18 break;
134 29 case 4:
135 case 5:
136 29 s->y_dc_scale_table= ff_wmv1_y_dc_scale_table;
137 29 s->c_dc_scale_table= ff_wmv1_c_dc_scale_table;
138 29 break;
139 #if CONFIG_VC1_DECODER
140 42 case 6:
141 42 s->y_dc_scale_table= ff_wmv3_dc_scale_table;
142 42 s->c_dc_scale_table= ff_wmv3_dc_scale_table;
143 42 break;
144 #endif
145
146 }
147
148
149
2/2
✓ Branch 0 taken 71 times.
✓ Branch 1 taken 33 times.
104 if(s->msmpeg4_version>=4){
150 71 ff_init_scantable(s->idsp.idct_permutation, &s->intra_scantable, ff_wmv1_scantable[1]);
151 71 ff_init_scantable(s->idsp.idct_permutation, &s->intra_h_scantable, ff_wmv1_scantable[2]);
152 71 ff_init_scantable(s->idsp.idct_permutation, &s->intra_v_scantable, ff_wmv1_scantable[3]);
153 71 ff_init_scantable(s->idsp.idct_permutation, &s->inter_scantable, ff_wmv1_scantable[0]);
154 }
155 //Note the default tables are set in common_init in mpegvideo.c
156
157 104 ff_thread_once(&init_static_once, msmpeg4_common_init_static);
158 104 }
159
160 /* predict coded block */
161 222472 int ff_msmpeg4_coded_block_pred(MpegEncContext * s, int n, uint8_t **coded_block_ptr)
162 {
163 int xy, wrap, pred, a, b, c;
164
165 222472 xy = s->block_index[n];
166 222472 wrap = s->b8_stride;
167
168 /* B C
169 * A X
170 */
171 222472 a = s->coded_block[xy - 1 ];
172 222472 b = s->coded_block[xy - 1 - wrap];
173 222472 c = s->coded_block[xy - wrap];
174
175
2/2
✓ Branch 0 taken 194858 times.
✓ Branch 1 taken 27614 times.
222472 if (b == c) {
176 194858 pred = a;
177 } else {
178 27614 pred = c;
179 }
180
181 /* store value */
182 222472 *coded_block_ptr = &s->coded_block[xy];
183
184 222472 return pred;
185 }
186
187 static int get_dc(uint8_t *src, int stride, int scale, int block_size)
188 {
189 int y;
190 int sum=0;
191 for(y=0; y<block_size; y++){
192 int x;
193 for(x=0; x<block_size; x++){
194 sum+=src[x + y*stride];
195 }
196 }
197 return FASTDIV((sum + (scale>>1)), scale);
198 }
199
200 /* dir = 0: left, dir = 1: top prediction */
201 433272 int ff_msmpeg4_pred_dc(MpegEncContext *s, int n,
202 int16_t **dc_val_ptr, int *dir_ptr)
203 {
204 int a, b, c, wrap, pred, scale;
205 int16_t *dc_val;
206
207 /* find prediction */
208
2/2
✓ Branch 0 taken 288848 times.
✓ Branch 1 taken 144424 times.
433272 if (n < 4) {
209 288848 scale = s->y_dc_scale;
210 } else {
211 144424 scale = s->c_dc_scale;
212 }
213
214 433272 wrap = s->block_wrap[n];
215 433272 dc_val= s->dc_val[0] + s->block_index[n];
216
217 /* B C
218 * A X
219 */
220 433272 a = dc_val[ - 1];
221 433272 b = dc_val[ - 1 - wrap];
222 433272 c = dc_val[ - wrap];
223
224
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)==0 && s->msmpeg4_version<4){
225 6624 b=c=1024;
226 }
227
228 /* XXX: the following solution consumes divisions, but it does not
229 necessitate to modify mpegvideo.c. The problem comes from the
230 fact they decided to store the quantized DC (which would lead
231 to problems if Q could vary !) */
232 #if ARCH_X86 && HAVE_7REGS && HAVE_EBX_AVAILABLE
233 433272 __asm__ volatile(
234 "movl %3, %%eax \n\t"
235 "shrl $1, %%eax \n\t"
236 "addl %%eax, %2 \n\t"
237 "addl %%eax, %1 \n\t"
238 "addl %0, %%eax \n\t"
239 "imull %4 \n\t"
240 "movl %%edx, %0 \n\t"
241 "movl %1, %%eax \n\t"
242 "imull %4 \n\t"
243 "movl %%edx, %1 \n\t"
244 "movl %2, %%eax \n\t"
245 "imull %4 \n\t"
246 "movl %%edx, %2 \n\t"
247 : "+b" (a), "+c" (b), "+D" (c)
248 433272 : "g" (scale), "S" (ff_inverse[scale])
249 : "%eax", "%edx"
250 );
251 #else
252 /* Divisions are costly everywhere; optimize the most common case. */
253 if (scale == 8) {
254 a = (a + (8 >> 1)) / 8;
255 b = (b + (8 >> 1)) / 8;
256 c = (c + (8 >> 1)) / 8;
257 } else {
258 a = FASTDIV((a + (scale >> 1)), scale);
259 b = FASTDIV((b + (scale >> 1)), scale);
260 c = FASTDIV((c + (scale >> 1)), scale);
261 }
262 #endif
263 /* XXX: WARNING: they did not choose the same test as MPEG-4. This
264 is very important ! */
265
2/2
✓ Branch 0 taken 212484 times.
✓ Branch 1 taken 220788 times.
433272 if(s->msmpeg4_version>3){
266
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 212484 times.
212484 if(s->inter_intra_pred){
267 uint8_t *dest;
268 int wrap;
269
270 if(n==1){
271 pred=a;
272 *dir_ptr = 0;
273 }else if(n==2){
274 pred=c;
275 *dir_ptr = 1;
276 }else if(n==3){
277 if (abs(a - b) < abs(b - c)) {
278 pred = c;
279 *dir_ptr = 1;
280 } else {
281 pred = a;
282 *dir_ptr = 0;
283 }
284 }else{
285 int bs = 8 >> s->avctx->lowres;
286 if(n<4){
287 wrap= s->linesize;
288 dest= s->current_picture.f->data[0] + (((n >> 1) + 2*s->mb_y) * bs* wrap ) + ((n & 1) + 2*s->mb_x) * bs;
289 }else{
290 wrap= s->uvlinesize;
291 dest= s->current_picture.f->data[n - 3] + (s->mb_y * bs * wrap) + s->mb_x * bs;
292 }
293 if(s->mb_x==0) a= (1024 + (scale>>1))/scale;
294 else a= get_dc(dest-bs, wrap, scale*8>>(2*s->avctx->lowres), bs);
295 if(s->mb_y==0) c= (1024 + (scale>>1))/scale;
296 else c= get_dc(dest-bs*wrap, wrap, scale*8>>(2*s->avctx->lowres), bs);
297
298 if (s->h263_aic_dir==0) {
299 pred= a;
300 *dir_ptr = 0;
301 }else if (s->h263_aic_dir==1) {
302 if(n==0){
303 pred= c;
304 *dir_ptr = 1;
305 }else{
306 pred= a;
307 *dir_ptr = 0;
308 }
309 }else if (s->h263_aic_dir==2) {
310 if(n==0){
311 pred= a;
312 *dir_ptr = 0;
313 }else{
314 pred= c;
315 *dir_ptr = 1;
316 }
317 } else {
318 pred= c;
319 *dir_ptr = 1;
320 }
321 }
322 }else{
323
2/2
✓ Branch 0 taken 86305 times.
✓ Branch 1 taken 126179 times.
212484 if (abs(a - b) < abs(b - c)) {
324 86305 pred = c;
325 86305 *dir_ptr = 1;
326 } else {
327 126179 pred = a;
328 126179 *dir_ptr = 0;
329 }
330 }
331 }else{
332
2/2
✓ Branch 0 taken 116422 times.
✓ Branch 1 taken 104366 times.
220788 if (abs(a - b) <= abs(b - c)) {
333 116422 pred = c;
334 116422 *dir_ptr = 1;
335 } else {
336 104366 pred = a;
337 104366 *dir_ptr = 0;
338 }
339 }
340
341 /* update predictor */
342 433272 *dc_val_ptr = &dc_val[0];
343 433272 return pred;
344 }
345
346