⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 motion_est_template.c

📁 ffmpeg源码分析
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Motion estimation * Copyright (c) 2002-2004 Michael Niedermayer * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * *//** * @file motion_est_template.c * Motion estimation template. *///lets hope gcc will remove the unused vars ...(gcc 3.2.2 seems to do it ...)#define LOAD_COMMON\    uint32_t attribute_unused * const score_map= c->score_map;\    const int attribute_unused xmin= c->xmin;\    const int attribute_unused ymin= c->ymin;\    const int attribute_unused xmax= c->xmax;\    const int attribute_unused ymax= c->ymax;\    uint8_t *mv_penalty= c->current_mv_penalty;\    const int pred_x= c->pred_x;\    const int pred_y= c->pred_y;\#define CHECK_HALF_MV(dx, dy, x, y)\{\    const int hx= 2*(x)+(dx);\    const int hy= 2*(y)+(dy);\    d= cmp(s, x, y, dx, dy, size, h, ref_index, src_index, cmp_sub, chroma_cmp_sub, flags);\    d += (mv_penalty[hx - pred_x] + mv_penalty[hy - pred_y])*penalty_factor;\    COPY3_IF_LT(dmin, d, bx, hx, by, hy)\}#if 0static int hpel_motion_search)(MpegEncContext * s,                                  int *mx_ptr, int *my_ptr, int dmin,                                  uint8_t *ref_data[3],                                  int size){    const int xx = 16 * s->mb_x + 8*(n&1);    const int yy = 16 * s->mb_y + 8*(n>>1);    const int mx = *mx_ptr;    const int my = *my_ptr;    const int penalty_factor= c->sub_penalty_factor;    LOAD_COMMON //   INIT; //FIXME factorize    me_cmp_func cmp, chroma_cmp, cmp_sub, chroma_cmp_sub;    if(s->no_rounding /*FIXME b_type*/){        hpel_put= &s->dsp.put_no_rnd_pixels_tab[size];        chroma_hpel_put= &s->dsp.put_no_rnd_pixels_tab[size+1];    }else{        hpel_put=& s->dsp.put_pixels_tab[size];        chroma_hpel_put= &s->dsp.put_pixels_tab[size+1];    }    cmpf= s->dsp.me_cmp[size];    chroma_cmpf= s->dsp.me_cmp[size+1];    cmp_sub= s->dsp.me_sub_cmp[size];    chroma_cmp_sub= s->dsp.me_sub_cmp[size+1];    if(c->skip){ //FIXME somehow move up (benchmark)        *mx_ptr = 0;        *my_ptr = 0;        return dmin;    }    if(c->avctx->me_cmp != c->avctx->me_sub_cmp){        CMP_HPEL(dmin, 0, 0, mx, my, size);        if(mx || my)            dmin += (mv_penalty[2*mx - pred_x] + mv_penalty[2*my - pred_y])*penalty_factor;    }    if (mx > xmin && mx < xmax &&        my > ymin && my < ymax) {        int bx=2*mx, by=2*my;        int d= dmin;        CHECK_HALF_MV(1, 1, mx-1, my-1)        CHECK_HALF_MV(0, 1, mx  , my-1)        CHECK_HALF_MV(1, 1, mx  , my-1)        CHECK_HALF_MV(1, 0, mx-1, my  )        CHECK_HALF_MV(1, 0, mx  , my  )        CHECK_HALF_MV(1, 1, mx-1, my  )        CHECK_HALF_MV(0, 1, mx  , my  )        CHECK_HALF_MV(1, 1, mx  , my  )        assert(bx >= xmin*2 || bx <= xmax*2 || by >= ymin*2 || by <= ymax*2);        *mx_ptr = bx;        *my_ptr = by;    }else{        *mx_ptr =2*mx;        *my_ptr =2*my;    }    return dmin;}#elsestatic int hpel_motion_search(MpegEncContext * s,                                  int *mx_ptr, int *my_ptr, int dmin,                                  int src_index, int ref_index,                                  int size, int h){    MotionEstContext * const c= &s->me;    const int mx = *mx_ptr;    const int my = *my_ptr;    const int penalty_factor= c->sub_penalty_factor;    me_cmp_func cmp_sub, chroma_cmp_sub;    int bx=2*mx, by=2*my;    LOAD_COMMON    int flags= c->sub_flags; //FIXME factorize    cmp_sub= s->dsp.me_sub_cmp[size];    chroma_cmp_sub= s->dsp.me_sub_cmp[size+1];    if(c->skip){ //FIXME move out of hpel?        *mx_ptr = 0;        *my_ptr = 0;        return dmin;    }    if(c->avctx->me_cmp != c->avctx->me_sub_cmp){        dmin= cmp(s, mx, my, 0, 0, size, h, ref_index, src_index, cmp_sub, chroma_cmp_sub, flags);        if(mx || my || size>0)            dmin += (mv_penalty[2*mx - pred_x] + mv_penalty[2*my - pred_y])*penalty_factor;    }    if (mx > xmin && mx < xmax &&        my > ymin && my < ymax) {        int d= dmin;        const int index= (my<<ME_MAP_SHIFT) + mx;        const int t= score_map[(index-(1<<ME_MAP_SHIFT))&(ME_MAP_SIZE-1)]                     + (mv_penalty[bx   - pred_x] + mv_penalty[by-2 - pred_y])*c->penalty_factor;        const int l= score_map[(index- 1               )&(ME_MAP_SIZE-1)]                     + (mv_penalty[bx-2 - pred_x] + mv_penalty[by   - pred_y])*c->penalty_factor;        const int r= score_map[(index+ 1               )&(ME_MAP_SIZE-1)]                     + (mv_penalty[bx+2 - pred_x] + mv_penalty[by   - pred_y])*c->penalty_factor;        const int b= score_map[(index+(1<<ME_MAP_SHIFT))&(ME_MAP_SIZE-1)]                     + (mv_penalty[bx   - pred_x] + mv_penalty[by+2 - pred_y])*c->penalty_factor;#if 1        int key;        int map_generation= c->map_generation;#ifndef NDEBUG        uint32_t *map= c->map;#endif        key= ((my-1)<<ME_MAP_MV_BITS) + (mx) + map_generation;        assert(map[(index-(1<<ME_MAP_SHIFT))&(ME_MAP_SIZE-1)] == key);        key= ((my+1)<<ME_MAP_MV_BITS) + (mx) + map_generation;        assert(map[(index+(1<<ME_MAP_SHIFT))&(ME_MAP_SIZE-1)] == key);        key= ((my)<<ME_MAP_MV_BITS) + (mx+1) + map_generation;        assert(map[(index+1)&(ME_MAP_SIZE-1)] == key);        key= ((my)<<ME_MAP_MV_BITS) + (mx-1) + map_generation;        assert(map[(index-1)&(ME_MAP_SIZE-1)] == key);#endif        if(t<=b){            CHECK_HALF_MV(0, 1, mx  ,my-1)            if(l<=r){                CHECK_HALF_MV(1, 1, mx-1, my-1)                if(t+r<=b+l){                    CHECK_HALF_MV(1, 1, mx  , my-1)                }else{                    CHECK_HALF_MV(1, 1, mx-1, my  )                }                CHECK_HALF_MV(1, 0, mx-1, my  )            }else{                CHECK_HALF_MV(1, 1, mx  , my-1)                if(t+l<=b+r){                    CHECK_HALF_MV(1, 1, mx-1, my-1)                }else{                    CHECK_HALF_MV(1, 1, mx  , my  )                }                CHECK_HALF_MV(1, 0, mx  , my  )            }        }else{            if(l<=r){                if(t+l<=b+r){                    CHECK_HALF_MV(1, 1, mx-1, my-1)                }else{                    CHECK_HALF_MV(1, 1, mx  , my  )                }                CHECK_HALF_MV(1, 0, mx-1, my)                CHECK_HALF_MV(1, 1, mx-1, my)            }else{                if(t+r<=b+l){                    CHECK_HALF_MV(1, 1, mx  , my-1)                }else{                    CHECK_HALF_MV(1, 1, mx-1, my)                }                CHECK_HALF_MV(1, 0, mx  , my)                CHECK_HALF_MV(1, 1, mx  , my)            }            CHECK_HALF_MV(0, 1, mx  , my)        }        assert(bx >= xmin*2 && bx <= xmax*2 && by >= ymin*2 && by <= ymax*2);    }    *mx_ptr = bx;    *my_ptr = by;    return dmin;}#endifstatic int no_sub_motion_search(MpegEncContext * s,          int *mx_ptr, int *my_ptr, int dmin,                                  int src_index, int ref_index,                                  int size, int h){    (*mx_ptr)<<=1;    (*my_ptr)<<=1;    return dmin;}int inline ff_get_mb_score(MpegEncContext * s, int mx, int my, int src_index,                               int ref_index, int size, int h, int add_rate){//    const int check_luma= s->dsp.me_sub_cmp != s->dsp.mb_cmp;    MotionEstContext * const c= &s->me;    const int penalty_factor= c->mb_penalty_factor;    const int flags= c->mb_flags;    const int qpel= flags & FLAG_QPEL;    const int mask= 1+2*qpel;    me_cmp_func cmp_sub, chroma_cmp_sub;    int d;    LOAD_COMMON //FIXME factorize    cmp_sub= s->dsp.mb_cmp[size];    chroma_cmp_sub= s->dsp.mb_cmp[size+1];//    assert(!c->skip);//    assert(c->avctx->me_sub_cmp != c->avctx->mb_cmp);    d= cmp(s, mx>>(qpel+1), my>>(qpel+1), mx&mask, my&mask, size, h, ref_index, src_index, cmp_sub, chroma_cmp_sub, flags);    //FIXME check cbp before adding penalty for (0,0) vector    if(add_rate && (mx || my || size>0))        d += (mv_penalty[mx - pred_x] + mv_penalty[my - pred_y])*penalty_factor;    return d;}#define CHECK_QUARTER_MV(dx, dy, x, y)\{\    const int hx= 4*(x)+(dx);\    const int hy= 4*(y)+(dy);\    d= cmp(s, x, y, dx, dy, size, h, ref_index, src_index, cmpf, chroma_cmpf, flags);\    d += (mv_penalty[hx - pred_x] + mv_penalty[hy - pred_y])*penalty_factor;\    COPY3_IF_LT(dmin, d, bx, hx, by, hy)\}static int qpel_motion_search(MpegEncContext * s,                                  int *mx_ptr, int *my_ptr, int dmin,                                  int src_index, int ref_index,                                  int size, int h){    MotionEstContext * const c= &s->me;    const int mx = *mx_ptr;    const int my = *my_ptr;    const int penalty_factor= c->sub_penalty_factor;    const int map_generation= c->map_generation;    const int subpel_quality= c->avctx->me_subpel_quality;    uint32_t *map= c->map;    me_cmp_func cmpf, chroma_cmpf;    me_cmp_func cmp_sub, chroma_cmp_sub;    LOAD_COMMON    int flags= c->sub_flags;    cmpf= s->dsp.me_cmp[size];    chroma_cmpf= s->dsp.me_cmp[size+1]; //factorize FIXME //FIXME factorize    cmp_sub= s->dsp.me_sub_cmp[size];    chroma_cmp_sub= s->dsp.me_sub_cmp[size+1];    if(c->skip){ //FIXME somehow move up (benchmark)        *mx_ptr = 0;        *my_ptr = 0;        return dmin;    }    if(c->avctx->me_cmp != c->avctx->me_sub_cmp){        dmin= cmp(s, mx, my, 0, 0, size, h, ref_index, src_index, cmp_sub, chroma_cmp_sub, flags);        if(mx || my || size>0)            dmin += (mv_penalty[4*mx - pred_x] + mv_penalty[4*my - pred_y])*penalty_factor;    }    if (mx > xmin && mx < xmax &&        my > ymin && my < ymax) {        int bx=4*mx, by=4*my;        int d= dmin;        int i, nx, ny;        const int index= (my<<ME_MAP_SHIFT) + mx;        const int t= score_map[(index-(1<<ME_MAP_SHIFT)  )&(ME_MAP_SIZE-1)];        const int l= score_map[(index- 1                 )&(ME_MAP_SIZE-1)];        const int r= score_map[(index+ 1                 )&(ME_MAP_SIZE-1)];        const int b= score_map[(index+(1<<ME_MAP_SHIFT)  )&(ME_MAP_SIZE-1)];        const int c= score_map[(index                    )&(ME_MAP_SIZE-1)];        int best[8];        int best_pos[8][2];        memset(best, 64, sizeof(int)*8);#if 1        if(s->me.dia_size>=2){            const int tl= score_map[(index-(1<<ME_MAP_SHIFT)-1)&(ME_MAP_SIZE-1)];            const int bl= score_map[(index+(1<<ME_MAP_SHIFT)-1)&(ME_MAP_SIZE-1)];            const int tr= score_map[(index-(1<<ME_MAP_SHIFT)+1)&(ME_MAP_SIZE-1)];            const int br= score_map[(index+(1<<ME_MAP_SHIFT)+1)&(ME_MAP_SIZE-1)];            for(ny= -3; ny <= 3; ny++){                for(nx= -3; nx <= 3; nx++){                    //FIXME this could overflow (unlikely though)                    const int64_t t2= nx*nx*(tr + tl - 2*t) + 4*nx*(tr-tl) + 32*t;                    const int64_t c2= nx*nx*( r +  l - 2*c) + 4*nx*( r- l) + 32*c;                    const int64_t b2= nx*nx*(br + bl - 2*b) + 4*nx*(br-bl) + 32*b;                    int score= (ny*ny*(b2 + t2 - 2*c2) + 4*ny*(b2 - t2) + 32*c2 + 512)>>10;                    int i;                    if((nx&3)==0 && (ny&3)==0) continue;                    score += (mv_penalty[4*mx + nx - pred_x] + mv_penalty[4*my + ny - pred_y])*penalty_factor;//                    if(nx&1) score-=1024*c->penalty_factor;//                    if(ny&1) score-=1024*c->penalty_factor;                    for(i=0; i<8; i++){                        if(score < best[i]){                            memmove(&best[i+1], &best[i], sizeof(int)*(7-i));                            memmove(&best_pos[i+1][0], &best_pos[i][0], sizeof(int)*2*(7-i));                            best[i]= score;                            best_pos[i][0]= nx + 4*mx;                            best_pos[i][1]= ny + 4*my;                            break;                        }                    }                }            }        }else{            int tl;            //FIXME this could overflow (unlikely though)            const int cx = 4*(r - l);            const int cx2= r + l - 2*c;            const int cy = 4*(b - t);            const int cy2= b + t - 2*c;            int cxy;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -