Fabrice Bellard | de6d9b6 | 2001-07-22 14:18:56 | [diff] [blame] | 1 | /* |
Diego Biurrun | 124e288 | 2011-10-30 16:56:57 | [diff] [blame] | 2 | * MSMPEG4 backend for encoder and decoder |
Diego Biurrun | 406792e | 2009-01-19 15:46:40 | [diff] [blame] | 3 | * Copyright (c) 2001 Fabrice Bellard |
Michael Niedermayer | 8f2ab83 | 2004-01-10 16:04:55 | [diff] [blame] | 4 | * Copyright (c) 2002-2004 Michael Niedermayer <[email protected]> |
Fabrice Bellard | de6d9b6 | 2001-07-22 14:18:56 | [diff] [blame] | 5 | * |
Diego Biurrun | 7b94177 | 2007-07-05 10:37:29 | [diff] [blame] | 6 | * msmpeg4v1 & v2 stuff by Michael Niedermayer <[email protected]> |
| 7 | * |
Diego Biurrun | b78e719 | 2006-10-07 15:30:46 | [diff] [blame] | 8 | * This file is part of FFmpeg. |
| 9 | * |
| 10 | * FFmpeg is free software; you can redistribute it and/or |
Fabrice Bellard | ff4ec49 | 2002-05-25 22:45:33 | [diff] [blame] | 11 | * modify it under the terms of the GNU Lesser General Public |
| 12 | * License as published by the Free Software Foundation; either |
Diego Biurrun | b78e719 | 2006-10-07 15:30:46 | [diff] [blame] | 13 | * version 2.1 of the License, or (at your option) any later version. |
Fabrice Bellard | de6d9b6 | 2001-07-22 14:18:56 | [diff] [blame] | 14 | * |
Diego Biurrun | b78e719 | 2006-10-07 15:30:46 | [diff] [blame] | 15 | * FFmpeg is distributed in the hope that it will be useful, |
Fabrice Bellard | de6d9b6 | 2001-07-22 14:18:56 | [diff] [blame] | 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
Fabrice Bellard | ff4ec49 | 2002-05-25 22:45:33 | [diff] [blame] | 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 18 | * Lesser General Public License for more details. |
Fabrice Bellard | de6d9b6 | 2001-07-22 14:18:56 | [diff] [blame] | 19 | * |
Fabrice Bellard | ff4ec49 | 2002-05-25 22:45:33 | [diff] [blame] | 20 | * You should have received a copy of the GNU Lesser General Public |
Diego Biurrun | b78e719 | 2006-10-07 15:30:46 | [diff] [blame] | 21 | * License along with FFmpeg; if not, write to the Free Software |
Diego Biurrun | 5509bff | 2006-01-12 22:43:26 | [diff] [blame] | 22 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
Fabrice Bellard | de6d9b6 | 2001-07-22 14:18:56 | [diff] [blame] | 23 | */ |
Michael Niedermayer | 983e324 | 2003-03-06 11:32:04 | [diff] [blame] | 24 | |
| 25 | /** |
Diego Biurrun | ba87f08 | 2010-04-20 14:45:34 | [diff] [blame] | 26 | * @file |
Diego Biurrun | 124e288 | 2011-10-30 16:56:57 | [diff] [blame] | 27 | * MSMPEG4 backend for encoder and decoder |
Michael Niedermayer | 983e324 | 2003-03-06 11:32:04 | [diff] [blame] | 28 | */ |
| 29 | |
Andreas Rheinhardt | c8549d4 | 2024-03-28 18:19:52 | [diff] [blame] | 30 | #include "config.h" |
| 31 | |
Andreas Rheinhardt | 2679893 | 2020-12-10 04:37:54 | [diff] [blame] | 32 | #include "libavutil/thread.h" |
Andreas Rheinhardt | c8549d4 | 2024-03-28 18:19:52 | [diff] [blame] | 33 | #if ARCH_X86 |
| 34 | #include "libavutil/x86/asm.h" |
| 35 | #endif |
Andreas Rheinhardt | 2679893 | 2020-12-10 04:37:54 | [diff] [blame] | 36 | |
Fabrice Bellard | 6000abf | 2002-05-18 23:03:29 | [diff] [blame] | 37 | #include "avcodec.h" |
Diego Biurrun | e3fcb14 | 2014-01-24 10:55:16 | [diff] [blame] | 38 | #include "idctdsp.h" |
Fabrice Bellard | de6d9b6 | 2001-07-22 14:18:56 | [diff] [blame] | 39 | #include "mpegvideo.h" |
Aurelien Jacobs | cc6de10 | 2007-11-07 23:41:39 | [diff] [blame] | 40 | #include "msmpeg4.h" |
Andreas Rheinhardt | c21433c | 2022-01-09 10:18:09 | [diff] [blame] | 41 | #include "mpeg4videodata.h" |
Diego Biurrun | 2f4b476 | 2012-02-18 13:28:43 | [diff] [blame] | 42 | #include "msmpeg4data.h" |
Andreas Rheinhardt | d1d30ed | 2022-10-30 15:32:00 | [diff] [blame] | 43 | #include "msmpeg4_vc1_data.h" |
Michael Niedermayer | 92ba5ff | 2002-05-21 23:13:57 | [diff] [blame] | 44 | |
Fabrice Bellard | de6d9b6 | 2001-07-22 14:18:56 | [diff] [blame] | 45 | /* |
Vittorio Giovara | 41ed7ab | 2016-04-27 17:45:23 | [diff] [blame] | 46 | * You can also call this codec: MPEG-4 with a twist! |
Fabrice Bellard | de6d9b6 | 2001-07-22 14:18:56 | [diff] [blame] | 47 | * |
Diego Biurrun | 115329f | 2005-12-17 18:14:38 | [diff] [blame] | 48 | * TODO: |
Fabrice Bellard | de6d9b6 | 2001-07-22 14:18:56 | [diff] [blame] | 49 | * - (encoding) select best mv table (two choices) |
Diego Biurrun | 115329f | 2005-12-17 18:14:38 | [diff] [blame] | 50 | * - (encoding) select best vlc/dc table |
Fabrice Bellard | de6d9b6 | 2001-07-22 14:18:56 | [diff] [blame] | 51 | */ |
Fabrice Bellard | de6d9b6 | 2001-07-22 14:18:56 | [diff] [blame] | 52 | |
Vittorio Giovara | 41ed7ab | 2016-04-27 17:45:23 | [diff] [blame] | 53 | /* This table is practically identical to the one from H.263 |
Diego Biurrun | 8380edd | 2009-12-30 14:15:12 | [diff] [blame] | 54 | * except that it is inverted. */ |
| 55 | static av_cold void init_h263_dc_for_msmpeg4(void) |
| 56 | { |
Andreas Rheinhardt | 0d30c04 | 2020-12-10 04:42:35 | [diff] [blame] | 57 | 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 Biurrun | 8380edd | 2009-12-30 14:15:12 | [diff] [blame] | 66 | } |
Andreas Rheinhardt | 0d30c04 | 2020-12-10 04:42:35 | [diff] [blame] | 67 | |
| 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 Biurrun | 8380edd | 2009-12-30 14:15:12 | [diff] [blame] | 105 | } |
| 106 | |
Andreas Rheinhardt | 1d5d666 | 2020-12-10 05:39:41 | [diff] [blame] | 107 | static 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 Biurrun | 2f4b476 | 2012-02-18 13:28:43 | [diff] [blame] | 117 | av_cold void ff_msmpeg4_common_init(MpegEncContext *s) |
Michael Niedermayer | f5957f3 | 2002-06-18 00:49:00 | [diff] [blame] | 118 | { |
Andreas Rheinhardt | 2679893 | 2020-12-10 04:37:54 | [diff] [blame] | 119 | static AVOnce init_static_once = AV_ONCE_INIT; |
| 120 | |
Michael Niedermayer | f5957f3 | 2002-06-18 00:49:00 | [diff] [blame] | 121 | switch(s->msmpeg4_version){ |
Andreas Rheinhardt | b2ac792 | 2024-04-28 21:18:35 | [diff] [blame] | 122 | case MSMP4_V1: |
| 123 | case MSMP4_V2: |
Andreas Rheinhardt | 1745d12 | 2024-06-13 06:46:56 | [diff] [blame] | 124 | // Correct *_dc_scale_tables (ff_mpeg1_dc_scale_table) is the default |
Michael Niedermayer | f5957f3 | 2002-06-18 00:49:00 | [diff] [blame] | 125 | break; |
Andreas Rheinhardt | b2ac792 | 2024-04-28 21:18:35 | [diff] [blame] | 126 | case MSMP4_V3: |
Michael Niedermayer | f5957f3 | 2002-06-18 00:49:00 | [diff] [blame] | 127 | if(s->workaround_bugs){ |
Martin Storsjö | 1fec055 | 2012-02-15 10:56:41 | [diff] [blame] | 128 | 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 Niedermayer | f5957f3 | 2002-06-18 00:49:00 | [diff] [blame] | 130 | } 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 Rheinhardt | b2ac792 | 2024-04-28 21:18:35 | [diff] [blame] | 135 | case MSMP4_WMV1: |
| 136 | case MSMP4_WMV2: |
Martin Storsjö | 1fec055 | 2012-02-15 10:56:41 | [diff] [blame] | 137 | s->y_dc_scale_table= ff_wmv1_y_dc_scale_table; |
| 138 | s->c_dc_scale_table= ff_wmv1_c_dc_scale_table; |
Michael Niedermayer | f5957f3 | 2002-06-18 00:49:00 | [diff] [blame] | 139 | break; |
Michael Niedermayer | f5957f3 | 2002-06-18 00:49:00 | [diff] [blame] | 140 | } |
| 141 | |
Andreas Rheinhardt | b2ac792 | 2024-04-28 21:18:35 | [diff] [blame] | 142 | if (s->msmpeg4_version >= MSMP4_WMV1) { |
Diego Biurrun | e3fcb14 | 2014-01-24 10:55:16 | [diff] [blame] | 143 | ff_init_scantable(s->idsp.idct_permutation, &s->intra_scantable, ff_wmv1_scantable[1]); |
Diego Biurrun | e3fcb14 | 2014-01-24 10:55:16 | [diff] [blame] | 144 | ff_init_scantable(s->idsp.idct_permutation, &s->inter_scantable, ff_wmv1_scantable[0]); |
Andreas Rheinhardt | 5ec9d26 | 2022-10-20 17:03:01 | [diff] [blame] | 145 | 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 Niedermayer | f5957f3 | 2002-06-18 00:49:00 | [diff] [blame] | 149 | } |
Michael Niedermayer | 2ad1516 | 2002-09-29 22:44:22 | [diff] [blame] | 150 | //Note the default tables are set in common_init in mpegvideo.c |
Diego Biurrun | 115329f | 2005-12-17 18:14:38 | [diff] [blame] | 151 | |
Andreas Rheinhardt | 1d5d666 | 2020-12-10 05:39:41 | [diff] [blame] | 152 | ff_thread_once(&init_static_once, msmpeg4_common_init_static); |
Michael Niedermayer | f5957f3 | 2002-06-18 00:49:00 | [diff] [blame] | 153 | } |
| 154 | |
Fabrice Bellard | de6d9b6 | 2001-07-22 14:18:56 | [diff] [blame] | 155 | /* predict coded block */ |
Aurelien Jacobs | 85f601e | 2007-11-07 23:23:35 | [diff] [blame] | 156 | int ff_msmpeg4_coded_block_pred(MpegEncContext * s, int n, uint8_t **coded_block_ptr) |
Fabrice Bellard | de6d9b6 | 2001-07-22 14:18:56 | [diff] [blame] | 157 | { |
Michael Niedermayer | dbbe899 | 2002-03-29 01:53:59 | [diff] [blame] | 158 | int xy, wrap, pred, a, b, c; |
Fabrice Bellard | de6d9b6 | 2001-07-22 14:18:56 | [diff] [blame] | 159 | |
Michael Niedermayer | dbbe899 | 2002-03-29 01:53:59 | [diff] [blame] | 160 | xy = s->block_index[n]; |
Michael Niedermayer | 137c846 | 2004-04-16 01:01:45 | [diff] [blame] | 161 | wrap = s->b8_stride; |
Fabrice Bellard | de6d9b6 | 2001-07-22 14:18:56 | [diff] [blame] | 162 | |
| 163 | /* B C |
Diego Biurrun | 115329f | 2005-12-17 18:14:38 | [diff] [blame] | 164 | * A X |
Fabrice Bellard | de6d9b6 | 2001-07-22 14:18:56 | [diff] [blame] | 165 | */ |
Michael Niedermayer | dbbe899 | 2002-03-29 01:53:59 | [diff] [blame] | 166 | a = s->coded_block[xy - 1 ]; |
| 167 | b = s->coded_block[xy - 1 - wrap]; |
| 168 | c = s->coded_block[xy - wrap]; |
Diego Biurrun | 115329f | 2005-12-17 18:14:38 | [diff] [blame] | 169 | |
Fabrice Bellard | de6d9b6 | 2001-07-22 14:18:56 | [diff] [blame] | 170 | if (b == c) { |
| 171 | pred = a; |
| 172 | } else { |
| 173 | pred = c; |
| 174 | } |
Diego Biurrun | 115329f | 2005-12-17 18:14:38 | [diff] [blame] | 175 | |
Fabrice Bellard | de6d9b6 | 2001-07-22 14:18:56 | [diff] [blame] | 176 | /* store value */ |
Michael Niedermayer | dbbe899 | 2002-03-29 01:53:59 | [diff] [blame] | 177 | *coded_block_ptr = &s->coded_block[xy]; |
Fabrice Bellard | de6d9b6 | 2001-07-22 14:18:56 | [diff] [blame] | 178 | |
| 179 | return pred; |
| 180 | } |
| 181 | |
Michael Niedermayer | 5dba888 | 2013-06-24 01:44:30 | [diff] [blame] | 182 | static int get_dc(uint8_t *src, int stride, int scale, int block_size) |
Michael Niedermayer | de0f2f4 | 2002-07-07 08:34:46 | [diff] [blame] | 183 | { |
| 184 | int y; |
| 185 | int sum=0; |
Michael Niedermayer | 5dba888 | 2013-06-24 01:44:30 | [diff] [blame] | 186 | for(y=0; y<block_size; y++){ |
Michael Niedermayer | de0f2f4 | 2002-07-07 08:34:46 | [diff] [blame] | 187 | int x; |
Michael Niedermayer | 5dba888 | 2013-06-24 01:44:30 | [diff] [blame] | 188 | for(x=0; x<block_size; x++){ |
Michael Niedermayer | de0f2f4 | 2002-07-07 08:34:46 | [diff] [blame] | 189 | sum+=src[x + y*stride]; |
| 190 | } |
| 191 | } |
BERO | d4961b3 | 2003-05-14 15:12:13 | [diff] [blame] | 192 | return FASTDIV((sum + (scale>>1)), scale); |
Michael Niedermayer | de0f2f4 | 2002-07-07 08:34:46 | [diff] [blame] | 193 | } |
| 194 | |
Fabrice Bellard | de6d9b6 | 2001-07-22 14:18:56 | [diff] [blame] | 195 | /* dir = 0: left, dir = 1: top prediction */ |
Diego Biurrun | 2f4b476 | 2012-02-18 13:28:43 | [diff] [blame] | 196 | int ff_msmpeg4_pred_dc(MpegEncContext *s, int n, |
| 197 | int16_t **dc_val_ptr, int *dir_ptr) |
Fabrice Bellard | de6d9b6 | 2001-07-22 14:18:56 | [diff] [blame] | 198 | { |
Michael Niedermayer | dbbe899 | 2002-03-29 01:53:59 | [diff] [blame] | 199 | int a, b, c, wrap, pred, scale; |
Måns Rullgård | b86216d | 2006-09-27 22:13:44 | [diff] [blame] | 200 | int16_t *dc_val; |
Fabrice Bellard | de6d9b6 | 2001-07-22 14:18:56 | [diff] [blame] | 201 | |
| 202 | /* find prediction */ |
| 203 | if (n < 4) { |
Diego Biurrun | bb270c0 | 2005-12-22 01:10:11 | [diff] [blame] | 204 | scale = s->y_dc_scale; |
Fabrice Bellard | de6d9b6 | 2001-07-22 14:18:56 | [diff] [blame] | 205 | } else { |
Diego Biurrun | bb270c0 | 2005-12-22 01:10:11 | [diff] [blame] | 206 | scale = s->c_dc_scale; |
Fabrice Bellard | de6d9b6 | 2001-07-22 14:18:56 | [diff] [blame] | 207 | } |
Diego Biurrun | 115329f | 2005-12-17 18:14:38 | [diff] [blame] | 208 | |
Michael Niedermayer | dbbe899 | 2002-03-29 01:53:59 | [diff] [blame] | 209 | wrap = s->block_wrap[n]; |
| 210 | dc_val= s->dc_val[0] + s->block_index[n]; |
Fabrice Bellard | de6d9b6 | 2001-07-22 14:18:56 | [diff] [blame] | 211 | |
| 212 | /* B C |
Diego Biurrun | 115329f | 2005-12-17 18:14:38 | [diff] [blame] | 213 | * A X |
Fabrice Bellard | de6d9b6 | 2001-07-22 14:18:56 | [diff] [blame] | 214 | */ |
Michael Niedermayer | dbbe899 | 2002-03-29 01:53:59 | [diff] [blame] | 215 | a = dc_val[ - 1]; |
| 216 | b = dc_val[ - 1 - wrap]; |
| 217 | c = dc_val[ - wrap]; |
Diego Biurrun | 115329f | 2005-12-17 18:14:38 | [diff] [blame] | 218 | |
Andreas Rheinhardt | b2ac792 | 2024-04-28 21:18:35 | [diff] [blame] | 219 | if (s->first_slice_line && !(n & 2) && s->msmpeg4_version < MSMP4_WMV1) |
Michael Niedermayer | 4d2858d | 2002-10-13 13:16:04 | [diff] [blame] | 220 | b=c=1024; |
Fabrice Bellard | de6d9b6 | 2001-07-22 14:18:56 | [diff] [blame] | 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 !) */ |
Reimar Döffinger | f2d702e | 2009-08-21 09:54:28 | [diff] [blame] | 226 | #if ARCH_X86 && HAVE_7REGS && HAVE_EBX_AVAILABLE |
Diego Pettenò | be449fc | 2008-10-16 13:34:09 | [diff] [blame] | 227 | __asm__ volatile( |
Diego Biurrun | bb270c0 | 2005-12-22 01:10:11 | [diff] [blame] | 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" |
Michael Niedermayer | c03dc44 | 2013-04-09 14:25:12 | [diff] [blame] | 233 | "imull %4 \n\t" |
Diego Biurrun | bb270c0 | 2005-12-22 01:10:11 | [diff] [blame] | 234 | "movl %%edx, %0 \n\t" |
| 235 | "movl %1, %%eax \n\t" |
Michael Niedermayer | c03dc44 | 2013-04-09 14:25:12 | [diff] [blame] | 236 | "imull %4 \n\t" |
Diego Biurrun | bb270c0 | 2005-12-22 01:10:11 | [diff] [blame] | 237 | "movl %%edx, %1 \n\t" |
| 238 | "movl %2, %%eax \n\t" |
Michael Niedermayer | c03dc44 | 2013-04-09 14:25:12 | [diff] [blame] | 239 | "imull %4 \n\t" |
Diego Biurrun | bb270c0 | 2005-12-22 01:10:11 | [diff] [blame] | 240 | "movl %%edx, %2 \n\t" |
| 241 | : "+b" (a), "+c" (b), "+D" (c) |
Måns Rullgård | 36cd306 | 2006-11-12 18:49:36 | [diff] [blame] | 242 | : "g" (scale), "S" (ff_inverse[scale]) |
Diego Biurrun | bb270c0 | 2005-12-22 01:10:11 | [diff] [blame] | 243 | : "%eax", "%edx" |
Michael Niedermayer | 6f903d8 | 2002-01-14 04:34:52 | [diff] [blame] | 244 | ); |
Zdenek Kabelac | 320680d | 2002-01-28 18:06:28 | [diff] [blame] | 245 | #else |
Diego Biurrun | c7f7bfc | 2013-11-13 19:39:56 | [diff] [blame] | 246 | /* Divisions are costly everywhere; optimize the most common case. */ |
Nick Kurshev | 1e98dff | 2002-01-20 14:48:02 | [diff] [blame] | 247 | if (scale == 8) { |
Diego Biurrun | bb270c0 | 2005-12-22 01:10:11 | [diff] [blame] | 248 | a = (a + (8 >> 1)) / 8; |
| 249 | b = (b + (8 >> 1)) / 8; |
| 250 | c = (c + (8 >> 1)) / 8; |
Nick Kurshev | 1e98dff | 2002-01-20 14:48:02 | [diff] [blame] | 251 | } else { |
Diego Biurrun | bb270c0 | 2005-12-22 01:10:11 | [diff] [blame] | 252 | a = FASTDIV((a + (scale >> 1)), scale); |
| 253 | b = FASTDIV((b + (scale >> 1)), scale); |
| 254 | c = FASTDIV((c + (scale >> 1)), scale); |
Nick Kurshev | 1e98dff | 2002-01-20 14:48:02 | [diff] [blame] | 255 | } |
Michael Niedermayer | 6f903d8 | 2002-01-14 04:34:52 | [diff] [blame] | 256 | #endif |
Vittorio Giovara | 41ed7ab | 2016-04-27 17:45:23 | [diff] [blame] | 257 | /* XXX: WARNING: they did not choose the same test as MPEG-4. This |
Fabrice Bellard | de6d9b6 | 2001-07-22 14:18:56 | [diff] [blame] | 258 | is very important ! */ |
Andreas Rheinhardt | b2ac792 | 2024-04-28 21:18:35 | [diff] [blame] | 259 | if (s->msmpeg4_version > MSMP4_V3) { |
Michael Niedermayer | de0f2f4 | 2002-07-07 08:34:46 | [diff] [blame] | 260 | if(s->inter_intra_pred){ |
| 261 | uint8_t *dest; |
| 262 | int wrap; |
Diego Biurrun | 115329f | 2005-12-17 18:14:38 | [diff] [blame] | 263 | |
Michael Niedermayer | de0f2f4 | 2002-07-07 08:34:46 | [diff] [blame] | 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{ |
Michael Niedermayer | 5dba888 | 2013-06-24 01:44:30 | [diff] [blame] | 279 | int bs = 8 >> s->avctx->lowres; |
Michael Niedermayer | de0f2f4 | 2002-07-07 08:34:46 | [diff] [blame] | 280 | if(n<4){ |
| 281 | wrap= s->linesize; |
Andreas Rheinhardt | 7814dd7 | 2023-10-04 15:27:24 | [diff] [blame] | 282 | dest = s->cur_pic.data[0] + (((n >> 1) + 2*s->mb_y) * bs* wrap ) + ((n & 1) + 2*s->mb_x) * bs; |
Michael Niedermayer | de0f2f4 | 2002-07-07 08:34:46 | [diff] [blame] | 283 | }else{ |
Michael Niedermayer | 0fd9045 | 2002-07-15 14:15:10 | [diff] [blame] | 284 | wrap= s->uvlinesize; |
Andreas Rheinhardt | 7814dd7 | 2023-10-04 15:27:24 | [diff] [blame] | 285 | dest = s->cur_pic.data[n - 3] + (s->mb_y * bs * wrap) + s->mb_x * bs; |
Michael Niedermayer | de0f2f4 | 2002-07-07 08:34:46 | [diff] [blame] | 286 | } |
| 287 | if(s->mb_x==0) a= (1024 + (scale>>1))/scale; |
Michael Niedermayer | 5dba888 | 2013-06-24 01:44:30 | [diff] [blame] | 288 | else a= get_dc(dest-bs, wrap, scale*8>>(2*s->avctx->lowres), bs); |
Michael Niedermayer | de0f2f4 | 2002-07-07 08:34:46 | [diff] [blame] | 289 | if(s->mb_y==0) c= (1024 + (scale>>1))/scale; |
Michael Niedermayer | 5dba888 | 2013-06-24 01:44:30 | [diff] [blame] | 290 | else c= get_dc(dest-bs*wrap, wrap, scale*8>>(2*s->avctx->lowres), bs); |
Diego Biurrun | 115329f | 2005-12-17 18:14:38 | [diff] [blame] | 291 | |
Michael Niedermayer | de0f2f4 | 2002-07-07 08:34:46 | [diff] [blame] | 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 | 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 Niedermayer | bd5e1c7 | 2002-06-22 15:52:25 | [diff] [blame] | 324 | } |
| 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 Bellard | de6d9b6 | 2001-07-22 14:18:56 | [diff] [blame] | 333 | } |
| 334 | |
| 335 | /* update predictor */ |
Michael Niedermayer | dbbe899 | 2002-03-29 01:53:59 | [diff] [blame] | 336 | *dc_val_ptr = &dc_val[0]; |
Fabrice Bellard | de6d9b6 | 2001-07-22 14:18:56 | [diff] [blame] | 337 | return pred; |
| 338 | } |
| 339 | |