FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/msmpeg4.c
Date: 2025-07-28 20:30:09
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 "mathops.h"
40 #include "mpegvideo.h"
41 #include "msmpeg4.h"
42 #include "mpeg4videodata.h"
43 #include "msmpeg4data.h"
44 #include "msmpeg4_vc1_data.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 MSMP4_V1:
124 case MSMP4_V2:
125 // Correct *_dc_scale_tables (ff_mpeg1_dc_scale_table) is the default
126 15 break;
127 18 case MSMP4_V3:
128
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 5 times.
18 if(s->workaround_bugs){
129 13 s->y_dc_scale_table= ff_old_ff_y_dc_scale_table;
130 13 s->c_dc_scale_table= ff_wmv1_c_dc_scale_table;
131 } else{
132 5 s->y_dc_scale_table= ff_mpeg4_y_dc_scale_table;
133 5 s->c_dc_scale_table= ff_mpeg4_c_dc_scale_table;
134 }
135 18 break;
136 29 case MSMP4_WMV1:
137 case MSMP4_WMV2:
138 29 s->y_dc_scale_table= ff_wmv1_y_dc_scale_table;
139 29 s->c_dc_scale_table= ff_wmv1_c_dc_scale_table;
140 29 break;
141 }
142
143
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 33 times.
62 if (s->msmpeg4_version >= MSMP4_WMV1) {
144 29 ff_init_scantable(s->idsp.idct_permutation, &s->intra_scantable, ff_wmv1_scantable[1]);
145 29 ff_init_scantable(s->idsp.idct_permutation, &s->inter_scantable, ff_wmv1_scantable[0]);
146 29 ff_permute_scantable(s->permutated_intra_h_scantable, ff_wmv1_scantable[2],
147 29 s->idsp.idct_permutation);
148 29 ff_permute_scantable(s->permutated_intra_v_scantable, ff_wmv1_scantable[3],
149 29 s->idsp.idct_permutation);
150 }
151 //Note the default tables are set in common_init in mpegvideo.c
152
153 62 ff_thread_once(&init_static_once, msmpeg4_common_init_static);
154 62 }
155
156 /* predict coded block */
157 168960 int ff_msmpeg4_coded_block_pred(MpegEncContext * s, int n, uint8_t **coded_block_ptr)
158 {
159 int xy, wrap, pred, a, b, c;
160
161 168960 xy = s->block_index[n];
162 168960 wrap = s->b8_stride;
163
164 /* B C
165 * A X
166 */
167 168960 a = s->coded_block[xy - 1 ];
168 168960 b = s->coded_block[xy - 1 - wrap];
169 168960 c = s->coded_block[xy - wrap];
170
171
2/2
✓ Branch 0 taken 150152 times.
✓ Branch 1 taken 18808 times.
168960 if (b == c) {
172 150152 pred = a;
173 } else {
174 18808 pred = c;
175 }
176
177 /* store value */
178 168960 *coded_block_ptr = &s->coded_block[xy];
179
180 168960 return pred;
181 }
182
183 static int get_dc(uint8_t *src, int stride, int scale, int block_size)
184 {
185 int y;
186 int sum=0;
187 for(y=0; y<block_size; y++){
188 int x;
189 for(x=0; x<block_size; x++){
190 sum+=src[x + y*stride];
191 }
192 }
193 return FASTDIV((sum + (scale>>1)), scale);
194 }
195
196 /* dir = 0: left, dir = 1: top prediction */
197 433272 int ff_msmpeg4_pred_dc(MpegEncContext *s, int n,
198 int16_t **dc_val_ptr, int *dir_ptr)
199 {
200 int a, b, c, wrap, pred, scale;
201 433272 int16_t *const dc_val = s->dc_val + s->block_index[n];
202
203 /* find prediction */
204
2/2
✓ Branch 0 taken 288848 times.
✓ Branch 1 taken 144424 times.
433272 if (n < 4) {
205 288848 scale = s->y_dc_scale;
206 } else {
207 144424 scale = s->c_dc_scale;
208 }
209
210 433272 wrap = s->block_wrap[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