FFmpeg coverage


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