annotate ffmpeg/libavcodec/msmpeg4.c @ 13:844d341cf643 tip

Back up before ISMIR
author Yading Song <yading.song@eecs.qmul.ac.uk>
date Thu, 31 Oct 2013 13:17:06 +0000
parents 6840f77b83aa
children
rev   line source
yading@10 1 /*
yading@10 2 * MSMPEG4 backend for encoder and decoder
yading@10 3 * Copyright (c) 2001 Fabrice Bellard
yading@10 4 * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
yading@10 5 *
yading@10 6 * msmpeg4v1 & v2 stuff by Michael Niedermayer <michaelni@gmx.at>
yading@10 7 *
yading@10 8 * This file is part of FFmpeg.
yading@10 9 *
yading@10 10 * FFmpeg is free software; you can redistribute it and/or
yading@10 11 * modify it under the terms of the GNU Lesser General Public
yading@10 12 * License as published by the Free Software Foundation; either
yading@10 13 * version 2.1 of the License, or (at your option) any later version.
yading@10 14 *
yading@10 15 * FFmpeg is distributed in the hope that it will be useful,
yading@10 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
yading@10 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
yading@10 18 * Lesser General Public License for more details.
yading@10 19 *
yading@10 20 * You should have received a copy of the GNU Lesser General Public
yading@10 21 * License along with FFmpeg; if not, write to the Free Software
yading@10 22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
yading@10 23 */
yading@10 24
yading@10 25 /**
yading@10 26 * @file
yading@10 27 * MSMPEG4 backend for encoder and decoder
yading@10 28 */
yading@10 29
yading@10 30 #include "avcodec.h"
yading@10 31 #include "dsputil.h"
yading@10 32 #include "mpegvideo.h"
yading@10 33 #include "msmpeg4.h"
yading@10 34 #include "libavutil/x86/asm.h"
yading@10 35 #include "h263.h"
yading@10 36 #include "mpeg4video.h"
yading@10 37 #include "msmpeg4data.h"
yading@10 38 #include "vc1data.h"
yading@10 39 #include "libavutil/imgutils.h"
yading@10 40
yading@10 41 /*
yading@10 42 * You can also call this codec : MPEG4 with a twist !
yading@10 43 *
yading@10 44 * TODO:
yading@10 45 * - (encoding) select best mv table (two choices)
yading@10 46 * - (encoding) select best vlc/dc table
yading@10 47 */
yading@10 48 //#define DEBUG
yading@10 49
yading@10 50 /* This table is practically identical to the one from h263
yading@10 51 * except that it is inverted. */
yading@10 52 static av_cold void init_h263_dc_for_msmpeg4(void)
yading@10 53 {
yading@10 54 int level, uni_code, uni_len;
yading@10 55
yading@10 56 if(ff_v2_dc_chroma_table[255 + 256][1])
yading@10 57 return;
yading@10 58
yading@10 59 for(level=-256; level<256; level++){
yading@10 60 int size, v, l;
yading@10 61 /* find number of bits */
yading@10 62 size = 0;
yading@10 63 v = abs(level);
yading@10 64 while (v) {
yading@10 65 v >>= 1;
yading@10 66 size++;
yading@10 67 }
yading@10 68
yading@10 69 if (level < 0)
yading@10 70 l= (-level) ^ ((1 << size) - 1);
yading@10 71 else
yading@10 72 l= level;
yading@10 73
yading@10 74 /* luminance h263 */
yading@10 75 uni_code= ff_mpeg4_DCtab_lum[size][0];
yading@10 76 uni_len = ff_mpeg4_DCtab_lum[size][1];
yading@10 77 uni_code ^= (1<<uni_len)-1; //M$ does not like compatibility
yading@10 78
yading@10 79 if (size > 0) {
yading@10 80 uni_code<<=size; uni_code|=l;
yading@10 81 uni_len+=size;
yading@10 82 if (size > 8){
yading@10 83 uni_code<<=1; uni_code|=1;
yading@10 84 uni_len++;
yading@10 85 }
yading@10 86 }
yading@10 87 ff_v2_dc_lum_table[level + 256][0] = uni_code;
yading@10 88 ff_v2_dc_lum_table[level + 256][1] = uni_len;
yading@10 89
yading@10 90 /* chrominance h263 */
yading@10 91 uni_code= ff_mpeg4_DCtab_chrom[size][0];
yading@10 92 uni_len = ff_mpeg4_DCtab_chrom[size][1];
yading@10 93 uni_code ^= (1<<uni_len)-1; //M$ does not like compatibility
yading@10 94
yading@10 95 if (size > 0) {
yading@10 96 uni_code<<=size; uni_code|=l;
yading@10 97 uni_len+=size;
yading@10 98 if (size > 8){
yading@10 99 uni_code<<=1; uni_code|=1;
yading@10 100 uni_len++;
yading@10 101 }
yading@10 102 }
yading@10 103 ff_v2_dc_chroma_table[level + 256][0] = uni_code;
yading@10 104 ff_v2_dc_chroma_table[level + 256][1] = uni_len;
yading@10 105
yading@10 106 }
yading@10 107 }
yading@10 108
yading@10 109 av_cold void ff_msmpeg4_common_init(MpegEncContext *s)
yading@10 110 {
yading@10 111 switch(s->msmpeg4_version){
yading@10 112 case 1:
yading@10 113 case 2:
yading@10 114 s->y_dc_scale_table=
yading@10 115 s->c_dc_scale_table= ff_mpeg1_dc_scale_table;
yading@10 116 break;
yading@10 117 case 3:
yading@10 118 if(s->workaround_bugs){
yading@10 119 s->y_dc_scale_table= ff_old_ff_y_dc_scale_table;
yading@10 120 s->c_dc_scale_table= ff_wmv1_c_dc_scale_table;
yading@10 121 } else{
yading@10 122 s->y_dc_scale_table= ff_mpeg4_y_dc_scale_table;
yading@10 123 s->c_dc_scale_table= ff_mpeg4_c_dc_scale_table;
yading@10 124 }
yading@10 125 break;
yading@10 126 case 4:
yading@10 127 case 5:
yading@10 128 s->y_dc_scale_table= ff_wmv1_y_dc_scale_table;
yading@10 129 s->c_dc_scale_table= ff_wmv1_c_dc_scale_table;
yading@10 130 break;
yading@10 131 #if CONFIG_VC1_DECODER
yading@10 132 case 6:
yading@10 133 s->y_dc_scale_table= ff_wmv3_dc_scale_table;
yading@10 134 s->c_dc_scale_table= ff_wmv3_dc_scale_table;
yading@10 135 break;
yading@10 136 #endif
yading@10 137
yading@10 138 }
yading@10 139
yading@10 140
yading@10 141 if(s->msmpeg4_version>=4){
yading@10 142 ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable , ff_wmv1_scantable[1]);
yading@10 143 ff_init_scantable(s->dsp.idct_permutation, &s->intra_h_scantable, ff_wmv1_scantable[2]);
yading@10 144 ff_init_scantable(s->dsp.idct_permutation, &s->intra_v_scantable, ff_wmv1_scantable[3]);
yading@10 145 ff_init_scantable(s->dsp.idct_permutation, &s->inter_scantable , ff_wmv1_scantable[0]);
yading@10 146 }
yading@10 147 //Note the default tables are set in common_init in mpegvideo.c
yading@10 148
yading@10 149 init_h263_dc_for_msmpeg4();
yading@10 150 }
yading@10 151
yading@10 152 /* predict coded block */
yading@10 153 int ff_msmpeg4_coded_block_pred(MpegEncContext * s, int n, uint8_t **coded_block_ptr)
yading@10 154 {
yading@10 155 int xy, wrap, pred, a, b, c;
yading@10 156
yading@10 157 xy = s->block_index[n];
yading@10 158 wrap = s->b8_stride;
yading@10 159
yading@10 160 /* B C
yading@10 161 * A X
yading@10 162 */
yading@10 163 a = s->coded_block[xy - 1 ];
yading@10 164 b = s->coded_block[xy - 1 - wrap];
yading@10 165 c = s->coded_block[xy - wrap];
yading@10 166
yading@10 167 if (b == c) {
yading@10 168 pred = a;
yading@10 169 } else {
yading@10 170 pred = c;
yading@10 171 }
yading@10 172
yading@10 173 /* store value */
yading@10 174 *coded_block_ptr = &s->coded_block[xy];
yading@10 175
yading@10 176 return pred;
yading@10 177 }
yading@10 178
yading@10 179 static int get_dc(uint8_t *src, int stride, int scale)
yading@10 180 {
yading@10 181 int y;
yading@10 182 int sum=0;
yading@10 183 for(y=0; y<8; y++){
yading@10 184 int x;
yading@10 185 for(x=0; x<8; x++){
yading@10 186 sum+=src[x + y*stride];
yading@10 187 }
yading@10 188 }
yading@10 189 return FASTDIV((sum + (scale>>1)), scale);
yading@10 190 }
yading@10 191
yading@10 192 /* dir = 0: left, dir = 1: top prediction */
yading@10 193 int ff_msmpeg4_pred_dc(MpegEncContext *s, int n,
yading@10 194 int16_t **dc_val_ptr, int *dir_ptr)
yading@10 195 {
yading@10 196 int a, b, c, wrap, pred, scale;
yading@10 197 int16_t *dc_val;
yading@10 198
yading@10 199 /* find prediction */
yading@10 200 if (n < 4) {
yading@10 201 scale = s->y_dc_scale;
yading@10 202 } else {
yading@10 203 scale = s->c_dc_scale;
yading@10 204 }
yading@10 205
yading@10 206 wrap = s->block_wrap[n];
yading@10 207 dc_val= s->dc_val[0] + s->block_index[n];
yading@10 208
yading@10 209 /* B C
yading@10 210 * A X
yading@10 211 */
yading@10 212 a = dc_val[ - 1];
yading@10 213 b = dc_val[ - 1 - wrap];
yading@10 214 c = dc_val[ - wrap];
yading@10 215
yading@10 216 if(s->first_slice_line && (n&2)==0 && s->msmpeg4_version<4){
yading@10 217 b=c=1024;
yading@10 218 }
yading@10 219
yading@10 220 /* XXX: the following solution consumes divisions, but it does not
yading@10 221 necessitate to modify mpegvideo.c. The problem comes from the
yading@10 222 fact they decided to store the quantized DC (which would lead
yading@10 223 to problems if Q could vary !) */
yading@10 224 #if ARCH_X86 && HAVE_7REGS && HAVE_EBX_AVAILABLE
yading@10 225 __asm__ volatile(
yading@10 226 "movl %3, %%eax \n\t"
yading@10 227 "shrl $1, %%eax \n\t"
yading@10 228 "addl %%eax, %2 \n\t"
yading@10 229 "addl %%eax, %1 \n\t"
yading@10 230 "addl %0, %%eax \n\t"
yading@10 231 "imull %4 \n\t"
yading@10 232 "movl %%edx, %0 \n\t"
yading@10 233 "movl %1, %%eax \n\t"
yading@10 234 "imull %4 \n\t"
yading@10 235 "movl %%edx, %1 \n\t"
yading@10 236 "movl %2, %%eax \n\t"
yading@10 237 "imull %4 \n\t"
yading@10 238 "movl %%edx, %2 \n\t"
yading@10 239 : "+b" (a), "+c" (b), "+D" (c)
yading@10 240 : "g" (scale), "S" (ff_inverse[scale])
yading@10 241 : "%eax", "%edx"
yading@10 242 );
yading@10 243 #else
yading@10 244 /* #elif ARCH_ALPHA */
yading@10 245 /* Divisions are extremely costly on Alpha; optimize the most
yading@10 246 common case. But they are costly everywhere...
yading@10 247 */
yading@10 248 if (scale == 8) {
yading@10 249 a = (a + (8 >> 1)) / 8;
yading@10 250 b = (b + (8 >> 1)) / 8;
yading@10 251 c = (c + (8 >> 1)) / 8;
yading@10 252 } else {
yading@10 253 a = FASTDIV((a + (scale >> 1)), scale);
yading@10 254 b = FASTDIV((b + (scale >> 1)), scale);
yading@10 255 c = FASTDIV((c + (scale >> 1)), scale);
yading@10 256 }
yading@10 257 #endif
yading@10 258 /* XXX: WARNING: they did not choose the same test as MPEG4. This
yading@10 259 is very important ! */
yading@10 260 if(s->msmpeg4_version>3){
yading@10 261 if(s->inter_intra_pred){
yading@10 262 uint8_t *dest;
yading@10 263 int wrap;
yading@10 264
yading@10 265 if(n==1){
yading@10 266 pred=a;
yading@10 267 *dir_ptr = 0;
yading@10 268 }else if(n==2){
yading@10 269 pred=c;
yading@10 270 *dir_ptr = 1;
yading@10 271 }else if(n==3){
yading@10 272 if (abs(a - b) < abs(b - c)) {
yading@10 273 pred = c;
yading@10 274 *dir_ptr = 1;
yading@10 275 } else {
yading@10 276 pred = a;
yading@10 277 *dir_ptr = 0;
yading@10 278 }
yading@10 279 }else{
yading@10 280 if(n<4){
yading@10 281 wrap= s->linesize;
yading@10 282 dest= s->current_picture.f.data[0] + (((n >> 1) + 2*s->mb_y) * 8* wrap ) + ((n & 1) + 2*s->mb_x) * 8;
yading@10 283 }else{
yading@10 284 wrap= s->uvlinesize;
yading@10 285 dest= s->current_picture.f.data[n - 3] + (s->mb_y * 8 * wrap) + s->mb_x * 8;
yading@10 286 }
yading@10 287 if(s->mb_x==0) a= (1024 + (scale>>1))/scale;
yading@10 288 else a= get_dc(dest-8, wrap, scale*8);
yading@10 289 if(s->mb_y==0) c= (1024 + (scale>>1))/scale;
yading@10 290 else c= get_dc(dest-8*wrap, wrap, scale*8);
yading@10 291
yading@10 292 if (s->h263_aic_dir==0) {
yading@10 293 pred= a;
yading@10 294 *dir_ptr = 0;
yading@10 295 }else if (s->h263_aic_dir==1) {
yading@10 296 if(n==0){
yading@10 297 pred= c;
yading@10 298 *dir_ptr = 1;
yading@10 299 }else{
yading@10 300 pred= a;
yading@10 301 *dir_ptr = 0;
yading@10 302 }
yading@10 303 }else if (s->h263_aic_dir==2) {
yading@10 304 if(n==0){
yading@10 305 pred= a;
yading@10 306 *dir_ptr = 0;
yading@10 307 }else{
yading@10 308 pred= c;
yading@10 309 *dir_ptr = 1;
yading@10 310 }
yading@10 311 } else {
yading@10 312 pred= c;
yading@10 313 *dir_ptr = 1;
yading@10 314 }
yading@10 315 }
yading@10 316 }else{
yading@10 317 if (abs(a - b) < abs(b - c)) {
yading@10 318 pred = c;
yading@10 319 *dir_ptr = 1;
yading@10 320 } else {
yading@10 321 pred = a;
yading@10 322 *dir_ptr = 0;
yading@10 323 }
yading@10 324 }
yading@10 325 }else{
yading@10 326 if (abs(a - b) <= abs(b - c)) {
yading@10 327 pred = c;
yading@10 328 *dir_ptr = 1;
yading@10 329 } else {
yading@10 330 pred = a;
yading@10 331 *dir_ptr = 0;
yading@10 332 }
yading@10 333 }
yading@10 334
yading@10 335 /* update predictor */
yading@10 336 *dc_val_ptr = &dc_val[0];
yading@10 337 return pred;
yading@10 338 }
yading@10 339