h263.c 11.7 KB
Newer Older
Fabrice Bellard's avatar
Fabrice Bellard committed
1 2
/*
 * H263/MPEG4 backend for ffmpeg encoder and decoder
3
 * Copyright (c) 2000,2001 Fabrice Bellard
4
 * H263+ support.
5
 * Copyright (c) 2001 Juan J. Sierralta P
6
 * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
Fabrice Bellard's avatar
Fabrice Bellard committed
7
 *
8 9 10
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
11 12
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
13
 * version 2.1 of the License, or (at your option) any later version.
Fabrice Bellard's avatar
Fabrice Bellard committed
14
 *
15
 * FFmpeg is distributed in the hope that it will be useful,
Fabrice Bellard's avatar
Fabrice Bellard committed
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
Fabrice Bellard's avatar
Fabrice Bellard committed
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
Fabrice Bellard's avatar
Fabrice Bellard committed
23
 */
Michael Niedermayer's avatar
Michael Niedermayer committed
24 25

/**
26
 * @file
Michael Niedermayer's avatar
Michael Niedermayer committed
27
 * h263/mpeg4 codec.
Michael Niedermayer's avatar
Michael Niedermayer committed
28
 */
29

30
//#define DEBUG
31 32
#include <limits.h>

Fabrice Bellard's avatar
Fabrice Bellard committed
33 34 35
#include "dsputil.h"
#include "avcodec.h"
#include "mpegvideo.h"
36
#include "h263.h"
Fabrice Bellard's avatar
Fabrice Bellard committed
37
#include "h263data.h"
38
#include "mathops.h"
39
#include "unary.h"
40
#include "flv.h"
41
#include "mpeg4video.h"
Fabrice Bellard's avatar
Fabrice Bellard committed
42

43 44 45
//#undef NDEBUG
//#include <assert.h>

46
uint8_t ff_h263_static_rl_table_store[2][2][2*MAX_RUN + MAX_LEVEL + 3];
47

48

49 50
void ff_h263_update_motion_val(MpegEncContext * s){
    const int mb_xy = s->mb_y * s->mb_stride + s->mb_x;
51
               //FIXME a lot of that is only needed for !low_delay
52
    const int wrap = s->b8_stride;
53
    const int xy = s->block_index[0];
54 55

    s->current_picture.mbskip_table[mb_xy]= s->mb_skipped;
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70

    if(s->mv_type != MV_TYPE_8X8){
        int motion_x, motion_y;
        if (s->mb_intra) {
            motion_x = 0;
            motion_y = 0;
        } else if (s->mv_type == MV_TYPE_16X16) {
            motion_x = s->mv[0][0][0];
            motion_y = s->mv[0][0][1];
        } else /*if (s->mv_type == MV_TYPE_FIELD)*/ {
            int i;
            motion_x = s->mv[0][0][0] + s->mv[0][1][0];
            motion_y = s->mv[0][0][1] + s->mv[0][1][1];
            motion_x = (motion_x>>1) | (motion_x&1);
            for(i=0; i<2; i++){
71 72
                s->p_field_mv_table[i][0][mb_xy][0]= s->mv[0][i][0];
                s->p_field_mv_table[i][0][mb_xy][1]= s->mv[0][i][1];
73
            }
74 75 76 77
            s->current_picture.ref_index[0][4*mb_xy    ]=
            s->current_picture.ref_index[0][4*mb_xy + 1]= s->field_select[0][0];
            s->current_picture.ref_index[0][4*mb_xy + 2]=
            s->current_picture.ref_index[0][4*mb_xy + 3]= s->field_select[0][1];
78
        }
79

80
        /* no update if 8X8 because it has been done during parsing */
81 82 83 84 85 86 87 88
        s->current_picture.motion_val[0][xy][0] = motion_x;
        s->current_picture.motion_val[0][xy][1] = motion_y;
        s->current_picture.motion_val[0][xy + 1][0] = motion_x;
        s->current_picture.motion_val[0][xy + 1][1] = motion_y;
        s->current_picture.motion_val[0][xy + wrap][0] = motion_x;
        s->current_picture.motion_val[0][xy + wrap][1] = motion_y;
        s->current_picture.motion_val[0][xy + 1 + wrap][0] = motion_x;
        s->current_picture.motion_val[0][xy + 1 + wrap][1] = motion_y;
89 90 91
    }

    if(s->encoding){ //FIXME encoding MUST be cleaned up
92
        if (s->mv_type == MV_TYPE_8X8)
93
            s->current_picture.mb_type[mb_xy]= MB_TYPE_L0 | MB_TYPE_8x8;
94 95
        else if(s->mb_intra)
            s->current_picture.mb_type[mb_xy]= MB_TYPE_INTRA;
96 97 98 99 100
        else
            s->current_picture.mb_type[mb_xy]= MB_TYPE_L0 | MB_TYPE_16x16;
    }
}

101
int h263_pred_dc(MpegEncContext * s, int n, int16_t **dc_val_ptr)
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
{
    int x, y, wrap, a, c, pred_dc;
    int16_t *dc_val;

    /* find prediction */
    if (n < 4) {
        x = 2 * s->mb_x + (n & 1);
        y = 2 * s->mb_y + ((n & 2) >> 1);
        wrap = s->b8_stride;
        dc_val = s->dc_val[0];
    } else {
        x = s->mb_x;
        y = s->mb_y;
        wrap = s->mb_stride;
        dc_val = s->dc_val[n - 4 + 1];
    }
    /* B C
     * A X
     */
    a = dc_val[(x - 1) + (y) * wrap];
    c = dc_val[(x) + (y - 1) * wrap];

    /* No prediction outside GOB boundary */
    if(s->first_slice_line && n!=3){
        if(n!=2) c= 1024;
        if(n!=1 && s->mb_x == s->resync_mb_x) a= 1024;
    }
    /* just DC prediction */
    if (a != 1024 && c != 1024)
        pred_dc = (a + c) >> 1;
    else if (a != 1024)
        pred_dc = a;
    else
        pred_dc = c;

    /* we assume pred is positive */
    *dc_val_ptr = &dc_val[x + y * wrap];
    return pred_dc;
}

Michael Niedermayer's avatar
Michael Niedermayer committed
142
void ff_h263_loop_filter(MpegEncContext * s){
Michael Niedermayer's avatar
Michael Niedermayer committed
143 144 145 146 147 148 149
    int qp_c;
    const int linesize  = s->linesize;
    const int uvlinesize= s->uvlinesize;
    const int xy = s->mb_y * s->mb_stride + s->mb_x;
    uint8_t *dest_y = s->dest[0];
    uint8_t *dest_cb= s->dest[1];
    uint8_t *dest_cr= s->dest[2];
150

151
//    if(s->pict_type==AV_PICTURE_TYPE_B && !s->readable) return;
Michael Niedermayer's avatar
Michael Niedermayer committed
152 153 154 155 156 157 158 159 160 161 162 163 164

    /*
       Diag Top
       Left Center
    */
    if(!IS_SKIP(s->current_picture.mb_type[xy])){
        qp_c= s->qscale;
        s->dsp.h263_v_loop_filter(dest_y+8*linesize  , linesize, qp_c);
        s->dsp.h263_v_loop_filter(dest_y+8*linesize+8, linesize, qp_c);
    }else
        qp_c= 0;

    if(s->mb_y){
165
        int qp_dt, qp_tt, qp_tc;
Michael Niedermayer's avatar
Michael Niedermayer committed
166 167

        if(IS_SKIP(s->current_picture.mb_type[xy-s->mb_stride]))
168
            qp_tt=0;
169
        else
170
            qp_tt= s->current_picture.qscale_table[xy-s->mb_stride];
Michael Niedermayer's avatar
Michael Niedermayer committed
171

172
        if(qp_c)
Michael Niedermayer's avatar
Michael Niedermayer committed
173 174
            qp_tc= qp_c;
        else
175
            qp_tc= qp_tt;
176

Michael Niedermayer's avatar
Michael Niedermayer committed
177 178 179 180
        if(qp_tc){
            const int chroma_qp= s->chroma_qscale_table[qp_tc];
            s->dsp.h263_v_loop_filter(dest_y  ,   linesize, qp_tc);
            s->dsp.h263_v_loop_filter(dest_y+8,   linesize, qp_tc);
181

Michael Niedermayer's avatar
Michael Niedermayer committed
182 183 184
            s->dsp.h263_v_loop_filter(dest_cb , uvlinesize, chroma_qp);
            s->dsp.h263_v_loop_filter(dest_cr , uvlinesize, chroma_qp);
        }
185

186 187
        if(qp_tt)
            s->dsp.h263_h_loop_filter(dest_y-8*linesize+8  ,   linesize, qp_tt);
188

Michael Niedermayer's avatar
Michael Niedermayer committed
189
        if(s->mb_x){
190 191
            if(qp_tt || IS_SKIP(s->current_picture.mb_type[xy-1-s->mb_stride]))
                qp_dt= qp_tt;
Michael Niedermayer's avatar
Michael Niedermayer committed
192 193
            else
                qp_dt= s->current_picture.qscale_table[xy-1-s->mb_stride];
194

Michael Niedermayer's avatar
Michael Niedermayer committed
195 196 197 198
            if(qp_dt){
                const int chroma_qp= s->chroma_qscale_table[qp_dt];
                s->dsp.h263_h_loop_filter(dest_y -8*linesize  ,   linesize, qp_dt);
                s->dsp.h263_h_loop_filter(dest_cb-8*uvlinesize, uvlinesize, chroma_qp);
Michael Niedermayer's avatar
Michael Niedermayer committed
199
                s->dsp.h263_h_loop_filter(dest_cr-8*uvlinesize, uvlinesize, chroma_qp);
Michael Niedermayer's avatar
Michael Niedermayer committed
200 201 202 203 204 205 206 207 208
            }
        }
    }

    if(qp_c){
        s->dsp.h263_h_loop_filter(dest_y +8,   linesize, qp_c);
        if(s->mb_y + 1 == s->mb_height)
            s->dsp.h263_h_loop_filter(dest_y+8*linesize+8,   linesize, qp_c);
    }
209

Michael Niedermayer's avatar
Michael Niedermayer committed
210 211 212 213 214 215
    if(s->mb_x){
        int qp_lc;
        if(qp_c || IS_SKIP(s->current_picture.mb_type[xy-1]))
            qp_lc= qp_c;
        else
            qp_lc= s->current_picture.qscale_table[xy-1];
216

Michael Niedermayer's avatar
Michael Niedermayer committed
217 218 219 220 221 222 223 224 225 226 227 228
        if(qp_lc){
            s->dsp.h263_h_loop_filter(dest_y,   linesize, qp_lc);
            if(s->mb_y + 1 == s->mb_height){
                const int chroma_qp= s->chroma_qscale_table[qp_lc];
                s->dsp.h263_h_loop_filter(dest_y +8*  linesize,   linesize, qp_lc);
                s->dsp.h263_h_loop_filter(dest_cb             , uvlinesize, chroma_qp);
                s->dsp.h263_h_loop_filter(dest_cr             , uvlinesize, chroma_qp);
            }
        }
    }
}

229
void h263_pred_acdc(MpegEncContext * s, DCTELEM *block, int n)
230
{
231
    int x, y, wrap, a, c, pred_dc, scale, i;
232
    int16_t *dc_val, *ac_val, *ac_val1;
233 234 235

    /* find prediction */
    if (n < 4) {
236 237 238
        x = 2 * s->mb_x + (n & 1);
        y = 2 * s->mb_y + (n>> 1);
        wrap = s->b8_stride;
239
        dc_val = s->dc_val[0];
240
        ac_val = s->ac_val[0][0];
241 242
        scale = s->y_dc_scale;
    } else {
243 244 245
        x = s->mb_x;
        y = s->mb_y;
        wrap = s->mb_stride;
246
        dc_val = s->dc_val[n - 4 + 1];
247
        ac_val = s->ac_val[n - 4 + 1][0];
248 249
        scale = s->c_dc_scale;
    }
250

251 252
    ac_val += ((y) * wrap + (x)) * 16;
    ac_val1 = ac_val;
253

254
    /* B C
255
     * A X
256 257 258
     */
    a = dc_val[(x - 1) + (y) * wrap];
    c = dc_val[(x) + (y - 1) * wrap];
259

260
    /* No prediction outside GOB boundary */
Michael Niedermayer's avatar
Michael Niedermayer committed
261 262 263 264
    if(s->first_slice_line && n!=3){
        if(n!=2) c= 1024;
        if(n!=1 && s->mb_x == s->resync_mb_x) a= 1024;
    }
265

266
    if (s->ac_pred) {
Michael Niedermayer's avatar
Michael Niedermayer committed
267
        pred_dc = 1024;
268 269
        if (s->h263_aic_dir) {
            /* left prediction */
270 271 272
            if (a != 1024) {
                ac_val -= 16;
                for(i=1;i<8;i++) {
273
                    block[s->dsp.idct_permutation[i<<3]] += ac_val[i];
274 275
                }
                pred_dc = a;
276 277 278
            }
        } else {
            /* top prediction */
279 280 281
            if (c != 1024) {
                ac_val -= 16 * wrap;
                for(i=1;i<8;i++) {
282
                    block[s->dsp.idct_permutation[i   ]] += ac_val[i + 8];
283 284
                }
                pred_dc = c;
285 286
            }
        }
287 288 289 290 291 292 293 294
    } else {
        /* just DC prediction */
        if (a != 1024 && c != 1024)
            pred_dc = (a + c) >> 1;
        else if (a != 1024)
            pred_dc = a;
        else
            pred_dc = c;
295
    }
296

297 298
    /* we assume pred is positive */
    block[0]=block[0]*scale + pred_dc;
299

300 301
    if (block[0] < 0)
        block[0] = 0;
302
    else
Michael Niedermayer's avatar
Michael Niedermayer committed
303
        block[0] |= 1;
304

305 306
    /* Update AC/DC tables */
    dc_val[(x) + (y) * wrap] = block[0];
307

308 309
    /* left copy */
    for(i=1;i<8;i++)
310
        ac_val1[i    ] = block[s->dsp.idct_permutation[i<<3]];
311 312
    /* top copy */
    for(i=1;i<8;i++)
313
        ac_val1[8 + i] = block[s->dsp.idct_permutation[i   ]];
314 315
}

316
int16_t *h263_pred_motion(MpegEncContext * s, int block, int dir,
Fabrice Bellard's avatar
Fabrice Bellard committed
317 318
                        int *px, int *py)
{
319
    int wrap;
320 321 322 323
    int16_t *A, *B, *C, (*mot_val)[2];
    static const int off[4]= {2, 1, 1, -1};

    wrap = s->b8_stride;
324
    mot_val = s->current_picture.motion_val[dir] + s->block_index[block];
325 326 327 328

    A = mot_val[ - 1];
    /* special case for first (slice) line */
    if (s->first_slice_line && block<3) {
329
        // we can't just change some MVs to simulate that as we need them for the B frames (and ME)
330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349
        // and if we ever support non rectangular objects than we need to do a few ifs here anyway :(
        if(block==0){ //most common case
            if(s->mb_x  == s->resync_mb_x){ //rare
                *px= *py = 0;
            }else if(s->mb_x + 1 == s->resync_mb_x && s->h263_pred){ //rare
                C = mot_val[off[block] - wrap];
                if(s->mb_x==0){
                    *px = C[0];
                    *py = C[1];
                }else{
                    *px = mid_pred(A[0], 0, C[0]);
                    *py = mid_pred(A[1], 0, C[1]);
                }
            }else{
                *px = A[0];
                *py = A[1];
            }
        }else if(block==1){
            if(s->mb_x + 1 == s->resync_mb_x && s->h263_pred){ //rare
                C = mot_val[off[block] - wrap];
350 351 352 353 354 355 356 357 358 359 360
                *px = mid_pred(A[0], 0, C[0]);
                *py = mid_pred(A[1], 0, C[1]);
            }else{
                *px = A[0];
                *py = A[1];
            }
        }else{ /* block==2*/
            B = mot_val[ - wrap];
            C = mot_val[off[block] - wrap];
            if(s->mb_x == s->resync_mb_x) //rare
                A[0]=A[1]=0;
361

362 363 364
            *px = mid_pred(A[0], B[0], C[0]);
            *py = mid_pred(A[1], B[1], C[1]);
        }
365
    } else {
366 367 368 369
        B = mot_val[ - wrap];
        C = mot_val[off[block] - wrap];
        *px = mid_pred(A[0], B[0], C[0]);
        *py = mid_pred(A[1], B[1], C[1]);
370
    }
371
    return *mot_val;
372 373
}

374

375 376 377 378 379 380 381 382 383 384
/**
 * Get the GOB height based on picture height.
 */
int ff_h263_get_gob_height(MpegEncContext *s){
    if (s->height <= 400)
        return 1;
    else if (s->height <= 800)
        return  2;
    else
        return 4;
Fabrice Bellard's avatar
Fabrice Bellard committed
385
}