FFmpeg coverage


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