blob: 872dc8db67f03cc7e0657c00d63fc456f9b48abc [file] [log] [blame]
Fabrice Bellardde6d9b62001-07-22 14:18:561/*
Diego Biurrun124e2882011-10-30 16:56:572 * MSMPEG4 backend for encoder and decoder
Diego Biurrun406792e2009-01-19 15:46:403 * Copyright (c) 2001 Fabrice Bellard
Michael Niedermayer8f2ab832004-01-10 16:04:554 * Copyright (c) 2002-2004 Michael Niedermayer <[email protected]>
Fabrice Bellardde6d9b62001-07-22 14:18:565 *
Diego Biurrun7b941772007-07-05 10:37:296 * msmpeg4v1 & v2 stuff by Michael Niedermayer <[email protected]>
7 *
Diego Biurrunb78e7192006-10-07 15:30:468 * This file is part of FFmpeg.
9 *
10 * FFmpeg is free software; you can redistribute it and/or
Fabrice Bellardff4ec492002-05-25 22:45:3311 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
Diego Biurrunb78e7192006-10-07 15:30:4613 * version 2.1 of the License, or (at your option) any later version.
Fabrice Bellardde6d9b62001-07-22 14:18:5614 *
Diego Biurrunb78e7192006-10-07 15:30:4615 * FFmpeg is distributed in the hope that it will be useful,
Fabrice Bellardde6d9b62001-07-22 14:18:5616 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Fabrice Bellardff4ec492002-05-25 22:45:3317 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
Fabrice Bellardde6d9b62001-07-22 14:18:5619 *
Fabrice Bellardff4ec492002-05-25 22:45:3320 * You should have received a copy of the GNU Lesser General Public
Diego Biurrunb78e7192006-10-07 15:30:4621 * License along with FFmpeg; if not, write to the Free Software
Diego Biurrun5509bff2006-01-12 22:43:2622 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Fabrice Bellardde6d9b62001-07-22 14:18:5623 */
Michael Niedermayer983e3242003-03-06 11:32:0424
25/**
Diego Biurrunba87f082010-04-20 14:45:3426 * @file
Diego Biurrun124e2882011-10-30 16:56:5727 * MSMPEG4 backend for encoder and decoder
Michael Niedermayer983e3242003-03-06 11:32:0428 */
29
Andreas Rheinhardtc8549d42024-03-28 18:19:5230#include "config.h"
31
Andreas Rheinhardt26798932020-12-10 04:37:5432#include "libavutil/thread.h"
Andreas Rheinhardtc8549d42024-03-28 18:19:5233#if ARCH_X86
34#include "libavutil/x86/asm.h"
35#endif
Andreas Rheinhardt26798932020-12-10 04:37:5436
Fabrice Bellard6000abf2002-05-18 23:03:2937#include "avcodec.h"
Diego Biurrune3fcb142014-01-24 10:55:1638#include "idctdsp.h"
Fabrice Bellardde6d9b62001-07-22 14:18:5639#include "mpegvideo.h"
Aurelien Jacobscc6de102007-11-07 23:41:3940#include "msmpeg4.h"
Andreas Rheinhardtc21433c2022-01-09 10:18:0941#include "mpeg4videodata.h"
Diego Biurrun2f4b4762012-02-18 13:28:4342#include "msmpeg4data.h"
Andreas Rheinhardtd1d30ed2022-10-30 15:32:0043#include "msmpeg4_vc1_data.h"
Michael Niedermayer92ba5ff2002-05-21 23:13:5744
Fabrice Bellardde6d9b62001-07-22 14:18:5645/*
Vittorio Giovara41ed7ab2016-04-27 17:45:2346 * You can also call this codec: MPEG-4 with a twist!
Fabrice Bellardde6d9b62001-07-22 14:18:5647 *
Diego Biurrun115329f2005-12-17 18:14:3848 * TODO:
Fabrice Bellardde6d9b62001-07-22 14:18:5649 * - (encoding) select best mv table (two choices)
Diego Biurrun115329f2005-12-17 18:14:3850 * - (encoding) select best vlc/dc table
Fabrice Bellardde6d9b62001-07-22 14:18:5651 */
Fabrice Bellardde6d9b62001-07-22 14:18:5652
Vittorio Giovara41ed7ab2016-04-27 17:45:2353/* This table is practically identical to the one from H.263
Diego Biurrun8380edd2009-12-30 14:15:1254 * except that it is inverted. */
55static av_cold void init_h263_dc_for_msmpeg4(void)
56{
Andreas Rheinhardt0d30c042020-12-10 04:42:3557 for (int level = -256; level < 256; level++) {
58 int uni_code, uni_len;
59 int size, v, l;
60 /* find number of bits */
61 size = 0;
62 v = abs(level);
63 while (v) {
64 v >>= 1;
65 size++;
Diego Biurrun8380edd2009-12-30 14:15:1266 }
Andreas Rheinhardt0d30c042020-12-10 04:42:3567
68 if (level < 0)
69 l = (-level) ^ ((1 << size) - 1);
70 else
71 l = level;
72
73 /* luminance H.263 */
74 uni_code = ff_mpeg4_DCtab_lum[size][0];
75 uni_len = ff_mpeg4_DCtab_lum[size][1];
76 uni_code ^= (1 << uni_len) - 1; //M$ does not like compatibility
77
78 if (size > 0) {
79 uni_code <<= size; uni_code |= l;
80 uni_len += size;
81 if (size > 8) {
82 uni_code <<= 1; uni_code |= 1;
83 uni_len++;
84 }
85 }
86 ff_v2_dc_lum_table[level + 256][0] = uni_code;
87 ff_v2_dc_lum_table[level + 256][1] = uni_len;
88
89 /* chrominance H.263 */
90 uni_code = ff_mpeg4_DCtab_chrom[size][0];
91 uni_len = ff_mpeg4_DCtab_chrom[size][1];
92 uni_code ^= (1 << uni_len) - 1; //M$ does not like compatibility
93
94 if (size > 0) {
95 uni_code <<= size; uni_code |= l;
96 uni_len +=size;
97 if (size > 8) {
98 uni_code <<= 1; uni_code |= 1;
99 uni_len++;
100 }
101 }
102 ff_v2_dc_chroma_table[level + 256][0] = uni_code;
103 ff_v2_dc_chroma_table[level + 256][1] = uni_len;
104 }
Diego Biurrun8380edd2009-12-30 14:15:12105}
106
Andreas Rheinhardt1d5d6662020-12-10 05:39:41107static 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 for (int i = 0; i < NB_RL_TABLES; i++)
112 ff_rl_init(&ff_rl_table[i], rl_table_store[i]);
113
114 init_h263_dc_for_msmpeg4();
115}
116
Diego Biurrun2f4b4762012-02-18 13:28:43117av_cold void ff_msmpeg4_common_init(MpegEncContext *s)
Michael Niedermayerf5957f32002-06-18 00:49:00118{
Andreas Rheinhardt26798932020-12-10 04:37:54119 static AVOnce init_static_once = AV_ONCE_INIT;
120
Michael Niedermayerf5957f32002-06-18 00:49:00121 switch(s->msmpeg4_version){
Andreas Rheinhardtb2ac7922024-04-28 21:18:35122 case MSMP4_V1:
123 case MSMP4_V2:
Andreas Rheinhardt1745d122024-06-13 06:46:56124 // Correct *_dc_scale_tables (ff_mpeg1_dc_scale_table) is the default
Michael Niedermayerf5957f32002-06-18 00:49:00125 break;
Andreas Rheinhardtb2ac7922024-04-28 21:18:35126 case MSMP4_V3:
Michael Niedermayerf5957f32002-06-18 00:49:00127 if(s->workaround_bugs){
Martin Storsjö1fec0552012-02-15 10:56:41128 s->y_dc_scale_table= ff_old_ff_y_dc_scale_table;
129 s->c_dc_scale_table= ff_wmv1_c_dc_scale_table;
Michael Niedermayerf5957f32002-06-18 00:49:00130 } else{
131 s->y_dc_scale_table= ff_mpeg4_y_dc_scale_table;
132 s->c_dc_scale_table= ff_mpeg4_c_dc_scale_table;
133 }
134 break;
Andreas Rheinhardtb2ac7922024-04-28 21:18:35135 case MSMP4_WMV1:
136 case MSMP4_WMV2:
Martin Storsjö1fec0552012-02-15 10:56:41137 s->y_dc_scale_table= ff_wmv1_y_dc_scale_table;
138 s->c_dc_scale_table= ff_wmv1_c_dc_scale_table;
Michael Niedermayerf5957f32002-06-18 00:49:00139 break;
Michael Niedermayerf5957f32002-06-18 00:49:00140 }
141
Andreas Rheinhardtb2ac7922024-04-28 21:18:35142 if (s->msmpeg4_version >= MSMP4_WMV1) {
Diego Biurrune3fcb142014-01-24 10:55:16143 ff_init_scantable(s->idsp.idct_permutation, &s->intra_scantable, ff_wmv1_scantable[1]);
Diego Biurrune3fcb142014-01-24 10:55:16144 ff_init_scantable(s->idsp.idct_permutation, &s->inter_scantable, ff_wmv1_scantable[0]);
Andreas Rheinhardt5ec9d262022-10-20 17:03:01145 ff_permute_scantable(s->permutated_intra_h_scantable, ff_wmv1_scantable[2],
146 s->idsp.idct_permutation);
147 ff_permute_scantable(s->permutated_intra_v_scantable, ff_wmv1_scantable[3],
148 s->idsp.idct_permutation);
Michael Niedermayerf5957f32002-06-18 00:49:00149 }
Michael Niedermayer2ad15162002-09-29 22:44:22150 //Note the default tables are set in common_init in mpegvideo.c
Diego Biurrun115329f2005-12-17 18:14:38151
Andreas Rheinhardt1d5d6662020-12-10 05:39:41152 ff_thread_once(&init_static_once, msmpeg4_common_init_static);
Michael Niedermayerf5957f32002-06-18 00:49:00153}
154
Fabrice Bellardde6d9b62001-07-22 14:18:56155/* predict coded block */
Aurelien Jacobs85f601e2007-11-07 23:23:35156int ff_msmpeg4_coded_block_pred(MpegEncContext * s, int n, uint8_t **coded_block_ptr)
Fabrice Bellardde6d9b62001-07-22 14:18:56157{
Michael Niedermayerdbbe8992002-03-29 01:53:59158 int xy, wrap, pred, a, b, c;
Fabrice Bellardde6d9b62001-07-22 14:18:56159
Michael Niedermayerdbbe8992002-03-29 01:53:59160 xy = s->block_index[n];
Michael Niedermayer137c8462004-04-16 01:01:45161 wrap = s->b8_stride;
Fabrice Bellardde6d9b62001-07-22 14:18:56162
163 /* B C
Diego Biurrun115329f2005-12-17 18:14:38164 * A X
Fabrice Bellardde6d9b62001-07-22 14:18:56165 */
Michael Niedermayerdbbe8992002-03-29 01:53:59166 a = s->coded_block[xy - 1 ];
167 b = s->coded_block[xy - 1 - wrap];
168 c = s->coded_block[xy - wrap];
Diego Biurrun115329f2005-12-17 18:14:38169
Fabrice Bellardde6d9b62001-07-22 14:18:56170 if (b == c) {
171 pred = a;
172 } else {
173 pred = c;
174 }
Diego Biurrun115329f2005-12-17 18:14:38175
Fabrice Bellardde6d9b62001-07-22 14:18:56176 /* store value */
Michael Niedermayerdbbe8992002-03-29 01:53:59177 *coded_block_ptr = &s->coded_block[xy];
Fabrice Bellardde6d9b62001-07-22 14:18:56178
179 return pred;
180}
181
Michael Niedermayer5dba8882013-06-24 01:44:30182static int get_dc(uint8_t *src, int stride, int scale, int block_size)
Michael Niedermayerde0f2f42002-07-07 08:34:46183{
184 int y;
185 int sum=0;
Michael Niedermayer5dba8882013-06-24 01:44:30186 for(y=0; y<block_size; y++){
Michael Niedermayerde0f2f42002-07-07 08:34:46187 int x;
Michael Niedermayer5dba8882013-06-24 01:44:30188 for(x=0; x<block_size; x++){
Michael Niedermayerde0f2f42002-07-07 08:34:46189 sum+=src[x + y*stride];
190 }
191 }
BEROd4961b32003-05-14 15:12:13192 return FASTDIV((sum + (scale>>1)), scale);
Michael Niedermayerde0f2f42002-07-07 08:34:46193}
194
Fabrice Bellardde6d9b62001-07-22 14:18:56195/* dir = 0: left, dir = 1: top prediction */
Diego Biurrun2f4b4762012-02-18 13:28:43196int ff_msmpeg4_pred_dc(MpegEncContext *s, int n,
197 int16_t **dc_val_ptr, int *dir_ptr)
Fabrice Bellardde6d9b62001-07-22 14:18:56198{
Michael Niedermayerdbbe8992002-03-29 01:53:59199 int a, b, c, wrap, pred, scale;
Måns Rullgårdb86216d2006-09-27 22:13:44200 int16_t *dc_val;
Fabrice Bellardde6d9b62001-07-22 14:18:56201
202 /* find prediction */
203 if (n < 4) {
Diego Biurrunbb270c02005-12-22 01:10:11204 scale = s->y_dc_scale;
Fabrice Bellardde6d9b62001-07-22 14:18:56205 } else {
Diego Biurrunbb270c02005-12-22 01:10:11206 scale = s->c_dc_scale;
Fabrice Bellardde6d9b62001-07-22 14:18:56207 }
Diego Biurrun115329f2005-12-17 18:14:38208
Michael Niedermayerdbbe8992002-03-29 01:53:59209 wrap = s->block_wrap[n];
210 dc_val= s->dc_val[0] + s->block_index[n];
Fabrice Bellardde6d9b62001-07-22 14:18:56211
212 /* B C
Diego Biurrun115329f2005-12-17 18:14:38213 * A X
Fabrice Bellardde6d9b62001-07-22 14:18:56214 */
Michael Niedermayerdbbe8992002-03-29 01:53:59215 a = dc_val[ - 1];
216 b = dc_val[ - 1 - wrap];
217 c = dc_val[ - wrap];
Diego Biurrun115329f2005-12-17 18:14:38218
Andreas Rheinhardtb2ac7922024-04-28 21:18:35219 if (s->first_slice_line && !(n & 2) && s->msmpeg4_version < MSMP4_WMV1)
Michael Niedermayer4d2858d2002-10-13 13:16:04220 b=c=1024;
Fabrice Bellardde6d9b62001-07-22 14:18:56221
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 !) */
Reimar Döffingerf2d702e2009-08-21 09:54:28226#if ARCH_X86 && HAVE_7REGS && HAVE_EBX_AVAILABLE
Diego Pettenòbe449fc2008-10-16 13:34:09227 __asm__ volatile(
Diego Biurrunbb270c02005-12-22 01:10:11228 "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"
Michael Niedermayerc03dc442013-04-09 14:25:12233 "imull %4 \n\t"
Diego Biurrunbb270c02005-12-22 01:10:11234 "movl %%edx, %0 \n\t"
235 "movl %1, %%eax \n\t"
Michael Niedermayerc03dc442013-04-09 14:25:12236 "imull %4 \n\t"
Diego Biurrunbb270c02005-12-22 01:10:11237 "movl %%edx, %1 \n\t"
238 "movl %2, %%eax \n\t"
Michael Niedermayerc03dc442013-04-09 14:25:12239 "imull %4 \n\t"
Diego Biurrunbb270c02005-12-22 01:10:11240 "movl %%edx, %2 \n\t"
241 : "+b" (a), "+c" (b), "+D" (c)
Måns Rullgård36cd3062006-11-12 18:49:36242 : "g" (scale), "S" (ff_inverse[scale])
Diego Biurrunbb270c02005-12-22 01:10:11243 : "%eax", "%edx"
Michael Niedermayer6f903d82002-01-14 04:34:52244 );
Zdenek Kabelac320680d2002-01-28 18:06:28245#else
Diego Biurrunc7f7bfc2013-11-13 19:39:56246 /* Divisions are costly everywhere; optimize the most common case. */
Nick Kurshev1e98dff2002-01-20 14:48:02247 if (scale == 8) {
Diego Biurrunbb270c02005-12-22 01:10:11248 a = (a + (8 >> 1)) / 8;
249 b = (b + (8 >> 1)) / 8;
250 c = (c + (8 >> 1)) / 8;
Nick Kurshev1e98dff2002-01-20 14:48:02251 } else {
Diego Biurrunbb270c02005-12-22 01:10:11252 a = FASTDIV((a + (scale >> 1)), scale);
253 b = FASTDIV((b + (scale >> 1)), scale);
254 c = FASTDIV((c + (scale >> 1)), scale);
Nick Kurshev1e98dff2002-01-20 14:48:02255 }
Michael Niedermayer6f903d82002-01-14 04:34:52256#endif
Vittorio Giovara41ed7ab2016-04-27 17:45:23257 /* XXX: WARNING: they did not choose the same test as MPEG-4. This
Fabrice Bellardde6d9b62001-07-22 14:18:56258 is very important ! */
Andreas Rheinhardtb2ac7922024-04-28 21:18:35259 if (s->msmpeg4_version > MSMP4_V3) {
Michael Niedermayerde0f2f42002-07-07 08:34:46260 if(s->inter_intra_pred){
261 uint8_t *dest;
262 int wrap;
Diego Biurrun115329f2005-12-17 18:14:38263
Michael Niedermayerde0f2f42002-07-07 08:34:46264 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{
Michael Niedermayer5dba8882013-06-24 01:44:30279 int bs = 8 >> s->avctx->lowres;
Michael Niedermayerde0f2f42002-07-07 08:34:46280 if(n<4){
281 wrap= s->linesize;
Andreas Rheinhardt7814dd72023-10-04 15:27:24282 dest = s->cur_pic.data[0] + (((n >> 1) + 2*s->mb_y) * bs* wrap ) + ((n & 1) + 2*s->mb_x) * bs;
Michael Niedermayerde0f2f42002-07-07 08:34:46283 }else{
Michael Niedermayer0fd90452002-07-15 14:15:10284 wrap= s->uvlinesize;
Andreas Rheinhardt7814dd72023-10-04 15:27:24285 dest = s->cur_pic.data[n - 3] + (s->mb_y * bs * wrap) + s->mb_x * bs;
Michael Niedermayerde0f2f42002-07-07 08:34:46286 }
287 if(s->mb_x==0) a= (1024 + (scale>>1))/scale;
Michael Niedermayer5dba8882013-06-24 01:44:30288 else a= get_dc(dest-bs, wrap, scale*8>>(2*s->avctx->lowres), bs);
Michael Niedermayerde0f2f42002-07-07 08:34:46289 if(s->mb_y==0) c= (1024 + (scale>>1))/scale;
Michael Niedermayer5dba8882013-06-24 01:44:30290 else c= get_dc(dest-bs*wrap, wrap, scale*8>>(2*s->avctx->lowres), bs);
Diego Biurrun115329f2005-12-17 18:14:38291
Michael Niedermayerde0f2f42002-07-07 08:34:46292 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 if (abs(a - b) < abs(b - c)) {
318 pred = c;
319 *dir_ptr = 1;
320 } else {
321 pred = a;
322 *dir_ptr = 0;
323 }
Michael Niedermayerbd5e1c72002-06-22 15:52:25324 }
325 }else{
326 if (abs(a - b) <= abs(b - c)) {
327 pred = c;
328 *dir_ptr = 1;
329 } else {
330 pred = a;
331 *dir_ptr = 0;
332 }
Fabrice Bellardde6d9b62001-07-22 14:18:56333 }
334
335 /* update predictor */
Michael Niedermayerdbbe8992002-03-29 01:53:59336 *dc_val_ptr = &dc_val[0];
Fabrice Bellardde6d9b62001-07-22 14:18:56337 return pred;
338}
339