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

📄 motion_est.c

📁 Trolltech公司发布的图形界面操作系统。可在qt-embedded-2.3.10平台上编译为嵌入式图形界面操作系统。
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * Motion estimation  * Copyright (c) 2000,2001 Fabrice Bellard. * Copyright (c) 2002-2003 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA * * new Motion Estimation (X1/EPZS) by Michael Niedermayer <michaelni@gmx.at> */ /** * @file motion_est.c * Motion estimation. */ #include <stdlib.h>#include <stdio.h>#include <limits.h>#include "avcodec.h"#include "dsputil.h"#include "mpegvideo.h"//#undef NDEBUG//#include <assert.h>#define SQ(a) ((a)*(a))#define P_LEFT P[1]#define P_TOP P[2]#define P_TOPRIGHT P[3]#define P_MEDIAN P[4]#define P_MV1 P[9]static inline int sad_hpel_motion_search(MpegEncContext * s,				  int *mx_ptr, int *my_ptr, int dmin,				  int xmin, int ymin, int xmax, int ymax,                                  int pred_x, int pred_y, Picture *picture,                                  int n, int size, uint8_t * const mv_penalty);static inline int update_map_generation(MpegEncContext * s){    s->me.map_generation+= 1<<(ME_MAP_MV_BITS*2);    if(s->me.map_generation==0){        s->me.map_generation= 1<<(ME_MAP_MV_BITS*2);        memset(s->me.map, 0, sizeof(uint32_t)*ME_MAP_SIZE);    }    return s->me.map_generation;}/* shape adaptive search stuff */typedef struct Minima{    int height;    int x, y;    int checked;}Minima;static int minima_cmp(const void *a, const void *b){    const Minima *da = (const Minima *) a;    const Minima *db = (const Minima *) b;        return da->height - db->height;}                                  /* SIMPLE */#define RENAME(a) simple_ ## a#define CMP(d, x, y, size)\d = cmp(s, src_y, (ref_y) + (x) + (y)*(stride), stride);#define CMP_HPEL(d, dx, dy, x, y, size)\{\    const int dxy= (dx) + 2*(dy);\    hpel_put[0][dxy](s->me.scratchpad, (ref_y) + (x) + (y)*(stride), stride, (16>>size));\    d = cmp_sub(s, s->me.scratchpad, src_y, stride);\}#define CMP_QPEL(d, dx, dy, x, y, size)\{\    const int dxy= (dx) + 4*(dy);\    qpel_put[0][dxy](s->me.scratchpad, (ref_y) + (x) + (y)*(stride), stride);\    d = cmp_sub(s, s->me.scratchpad, src_y, stride);\}#include "motion_est_template.c"#undef RENAME#undef CMP#undef CMP_HPEL#undef CMP_QPEL#undef INIT/* SIMPLE CHROMA */#define RENAME(a) simple_chroma_ ## a#define CMP(d, x, y, size)\d = cmp(s, src_y, (ref_y) + (x) + (y)*(stride), stride);\if(chroma_cmp){\    int dxy= ((x)&1) + 2*((y)&1);\    int c= ((x)>>1) + ((y)>>1)*uvstride;\\    chroma_hpel_put[0][dxy](s->me.scratchpad, ref_u + c, uvstride, 8);\    d += chroma_cmp(s, s->me.scratchpad, src_u, uvstride);\    chroma_hpel_put[0][dxy](s->me.scratchpad, ref_v + c, uvstride, 8);\    d += chroma_cmp(s, s->me.scratchpad, src_v, uvstride);\}#define CMP_HPEL(d, dx, dy, x, y, size)\{\    const int dxy= (dx) + 2*(dy);\    hpel_put[0][dxy](s->me.scratchpad, (ref_y) + (x) + (y)*(stride), stride, (16>>size));\    d = cmp_sub(s, s->me.scratchpad, src_y, stride);\    if(chroma_cmp_sub){\        int cxy= (dxy) | ((x)&1) | (2*((y)&1));\        int c= ((x)>>1) + ((y)>>1)*uvstride;\        chroma_hpel_put[0][cxy](s->me.scratchpad, ref_u + c, uvstride, 8);\        d += chroma_cmp_sub(s, s->me.scratchpad, src_u, uvstride);\        chroma_hpel_put[0][cxy](s->me.scratchpad, ref_v + c, uvstride, 8);\        d += chroma_cmp_sub(s, s->me.scratchpad, src_v, uvstride);\    }\}#define CMP_QPEL(d, dx, dy, x, y, size)\{\    const int dxy= (dx) + 4*(dy);\    qpel_put[0][dxy](s->me.scratchpad, (ref_y) + (x) + (y)*(stride), stride);\    d = cmp_sub(s, s->me.scratchpad, src_y, stride);\    if(chroma_cmp_sub){\        int cxy, c;\        int cx= (4*(x) + (dx))/2;\        int cy= (4*(y) + (dy))/2;\        cx= (cx>>1)|(cx&1);\        cy= (cy>>1)|(cy&1);\        cxy= (cx&1) + 2*(cy&1);\        c= ((cx)>>1) + ((cy)>>1)*uvstride;\        chroma_hpel_put[0][cxy](s->me.scratchpad, ref_u + c, uvstride, 8);\        d += chroma_cmp_sub(s, s->me.scratchpad, src_u, uvstride);\        chroma_hpel_put[0][cxy](s->me.scratchpad, ref_v + c, uvstride, 8);\        d += chroma_cmp_sub(s, s->me.scratchpad, src_v, uvstride);\    }\}#include "motion_est_template.c"#undef RENAME#undef CMP#undef CMP_HPEL#undef CMP_QPEL#undef INIT/* SIMPLE DIRECT HPEL */#define RENAME(a) simple_direct_hpel_ ## a//FIXME precalc divisions stuff#define CMP_DIRECT(d, dx, dy, x, y, size, cmp_func)\if((x) >= xmin && 2*(x) + (dx) <= 2*xmax && (y) >= ymin && 2*(y) + (dy) <= 2*ymax){\    const int hx= 2*(x) + (dx);\    const int hy= 2*(y) + (dy);\    if(s->mv_type==MV_TYPE_8X8){\        int i;\        for(i=0; i<4; i++){\            int fx = s->me.direct_basis_mv[i][0] + hx;\            int fy = s->me.direct_basis_mv[i][1] + hy;\            int bx = hx ? fx - s->me.co_located_mv[i][0] : s->me.co_located_mv[i][0]*(time_pb - time_pp)/time_pp + (i &1)*16;\            int by = hy ? fy - s->me.co_located_mv[i][1] : s->me.co_located_mv[i][1]*(time_pb - time_pp)/time_pp + (i>>1)*16;\            int fxy= (fx&1) + 2*(fy&1);\            int bxy= (bx&1) + 2*(by&1);\\            uint8_t *dst= s->me.scratchpad + 8*(i&1) + 8*stride*(i>>1);\            hpel_put[1][fxy](dst, (ref_y ) + (fx>>1) + (fy>>1)*(stride), stride, 8);\            hpel_avg[1][bxy](dst, (ref2_y) + (bx>>1) + (by>>1)*(stride), stride, 8);\        }\    }else{\        int fx = s->me.direct_basis_mv[0][0] + hx;\        int fy = s->me.direct_basis_mv[0][1] + hy;\        int bx = hx ? fx - s->me.co_located_mv[0][0] : (s->me.co_located_mv[0][0]*(time_pb - time_pp)/time_pp);\        int by = hy ? fy - s->me.co_located_mv[0][1] : (s->me.co_located_mv[0][1]*(time_pb - time_pp)/time_pp);\        int fxy= (fx&1) + 2*(fy&1);\        int bxy= (bx&1) + 2*(by&1);\        \        assert((fx>>1) + 16*s->mb_x >= -16);\        assert((fy>>1) + 16*s->mb_y >= -16);\        assert((fx>>1) + 16*s->mb_x <= s->width);\        assert((fy>>1) + 16*s->mb_y <= s->height);\        assert((bx>>1) + 16*s->mb_x >= -16);\        assert((by>>1) + 16*s->mb_y >= -16);\        assert((bx>>1) + 16*s->mb_x <= s->width);\        assert((by>>1) + 16*s->mb_y <= s->height);\\        hpel_put[0][fxy](s->me.scratchpad, (ref_y ) + (fx>>1) + (fy>>1)*(stride), stride, 16);\        hpel_avg[0][bxy](s->me.scratchpad, (ref2_y) + (bx>>1) + (by>>1)*(stride), stride, 16);\    }\    d = cmp_func(s, s->me.scratchpad, src_y, stride);\}else\    d= 256*256*256*32;#define CMP_HPEL(d, dx, dy, x, y, size)\    CMP_DIRECT(d, dx, dy, x, y, size, cmp_sub)#define CMP(d, x, y, size)\    CMP_DIRECT(d, 0, 0, x, y, size, cmp)    #include "motion_est_template.c"#undef RENAME#undef CMP#undef CMP_HPEL#undef CMP_QPEL#undef INIT#undef CMP_DIRECT/* SIMPLE DIRECT QPEL */#define RENAME(a) simple_direct_qpel_ ## a#define CMP_DIRECT(d, dx, dy, x, y, size, cmp_func)\if((x) >= xmin && 4*(x) + (dx) <= 4*xmax && (y) >= ymin && 4*(y) + (dy) <= 4*ymax){\    const int qx= 4*(x) + (dx);\    const int qy= 4*(y) + (dy);\    if(s->mv_type==MV_TYPE_8X8){\        int i;\        for(i=0; i<4; i++){\            int fx = s->me.direct_basis_mv[i][0] + qx;\            int fy = s->me.direct_basis_mv[i][1] + qy;\            int bx = qx ? fx - s->me.co_located_mv[i][0] : s->me.co_located_mv[i][0]*(time_pb - time_pp)/time_pp + (i &1)*16;\            int by = qy ? fy - s->me.co_located_mv[i][1] : s->me.co_located_mv[i][1]*(time_pb - time_pp)/time_pp + (i>>1)*16;\            int fxy= (fx&3) + 4*(fy&3);\            int bxy= (bx&3) + 4*(by&3);\\            uint8_t *dst= s->me.scratchpad + 8*(i&1) + 8*stride*(i>>1);\            qpel_put[1][fxy](dst, (ref_y ) + (fx>>2) + (fy>>2)*(stride), stride);\            qpel_avg[1][bxy](dst, (ref2_y) + (bx>>2) + (by>>2)*(stride), stride);\        }\    }else{\        int fx = s->me.direct_basis_mv[0][0] + qx;\        int fy = s->me.direct_basis_mv[0][1] + qy;\        int bx = qx ? fx - s->me.co_located_mv[0][0] : s->me.co_located_mv[0][0]*(time_pb - time_pp)/time_pp;\        int by = qy ? fy - s->me.co_located_mv[0][1] : s->me.co_located_mv[0][1]*(time_pb - time_pp)/time_pp;\        int fxy= (fx&3) + 4*(fy&3);\        int bxy= (bx&3) + 4*(by&3);\\        qpel_put[1][fxy](s->me.scratchpad               , (ref_y ) + (fx>>2) + (fy>>2)*(stride)               , stride);\        qpel_put[1][fxy](s->me.scratchpad + 8           , (ref_y ) + (fx>>2) + (fy>>2)*(stride) + 8           , stride);\        qpel_put[1][fxy](s->me.scratchpad     + 8*stride, (ref_y ) + (fx>>2) + (fy>>2)*(stride)     + 8*stride, stride);\        qpel_put[1][fxy](s->me.scratchpad + 8 + 8*stride, (ref_y ) + (fx>>2) + (fy>>2)*(stride) + 8 + 8*stride, stride);\        qpel_avg[1][bxy](s->me.scratchpad               , (ref2_y) + (bx>>2) + (by>>2)*(stride)               , stride);\        qpel_avg[1][bxy](s->me.scratchpad + 8           , (ref2_y) + (bx>>2) + (by>>2)*(stride) + 8           , stride);\        qpel_avg[1][bxy](s->me.scratchpad     + 8*stride, (ref2_y) + (bx>>2) + (by>>2)*(stride)     + 8*stride, stride);\        qpel_avg[1][bxy](s->me.scratchpad + 8 + 8*stride, (ref2_y) + (bx>>2) + (by>>2)*(stride) + 8 + 8*stride, stride);\    }\    d = cmp_func(s, s->me.scratchpad, src_y, stride);\}else\    d= 256*256*256*32;#define CMP_QPEL(d, dx, dy, x, y, size)\    CMP_DIRECT(d, dx, dy, x, y, size, cmp_sub)#define CMP(d, x, y, size)\    CMP_DIRECT(d, 0, 0, x, y, size, cmp)#include "motion_est_template.c"#undef RENAME#undef CMP#undef CMP_HPEL#undef CMP_QPEL#undef INIT#undef CMP__DIRECTstatic int zero_cmp(void *s, uint8_t *a, uint8_t *b, int stride){    return 0;}static void set_cmp(MpegEncContext *s, me_cmp_func *cmp, int type){    DSPContext* c= &s->dsp;    int i;        memset(cmp, 0, sizeof(void*)*11);    switch(type&0xFF){    case FF_CMP_SAD:        cmp[0]= c->sad[0];        cmp[1]= c->sad[1];        break;    case FF_CMP_SATD:        cmp[0]= c->hadamard8_diff[0];        cmp[1]= c->hadamard8_diff[1];        break;    case FF_CMP_SSE:        cmp[0]= c->sse[0];        cmp[1]= c->sse[1];        break;    case FF_CMP_DCT:        cmp[0]= c->dct_sad[0];        cmp[1]= c->dct_sad[1];        break;    case FF_CMP_PSNR:        cmp[0]= c->quant_psnr[0];        cmp[1]= c->quant_psnr[1];        break;    case FF_CMP_BIT:        cmp[0]= c->bit[0];        cmp[1]= c->bit[1];        break;    case FF_CMP_RD:        cmp[0]= c->rd[0];        cmp[1]= c->rd[1];        break;    case FF_CMP_ZERO:        for(i=0; i<7; i++){            cmp[i]= zero_cmp;        }        break;    default:        av_log(s->avctx, AV_LOG_ERROR,"internal error in cmp function selection\n");    }}static inline int get_penalty_factor(MpegEncContext *s, int type){    switch(type&0xFF){    default:    case FF_CMP_SAD:        return s->qscale*2;    case FF_CMP_DCT:        return s->qscale*3;    case FF_CMP_SATD:        return s->qscale*6;    case FF_CMP_SSE:        return s->qscale*s->qscale*2;    case FF_CMP_BIT:        return 1;    case FF_CMP_RD:    case FF_CMP_PSNR:        return (s->qscale*s->qscale*185 + 64)>>7;    }}void ff_init_me(MpegEncContext *s){    set_cmp(s, s->dsp.me_pre_cmp, s->avctx->me_pre_cmp);    set_cmp(s, s->dsp.me_cmp, s->avctx->me_cmp);    set_cmp(s, s->dsp.me_sub_cmp, s->avctx->me_sub_cmp);    set_cmp(s, s->dsp.mb_cmp, s->avctx->mb_cmp);    if(s->flags&CODEC_FLAG_QPEL){        if(s->avctx->me_sub_cmp&FF_CMP_CHROMA)            s->me.sub_motion_search= simple_chroma_qpel_motion_search;        else            s->me.sub_motion_search= simple_qpel_motion_search;    }else{        if(s->avctx->me_sub_cmp&FF_CMP_CHROMA)            s->me.sub_motion_search= simple_chroma_hpel_motion_search;        else if(   s->avctx->me_sub_cmp == FF_CMP_SAD                 && s->avctx->    me_cmp == FF_CMP_SAD                 && s->avctx->    mb_cmp == FF_CMP_SAD)            s->me.sub_motion_search= sad_hpel_motion_search;        else            s->me.sub_motion_search= simple_hpel_motion_search;    }    if(s->avctx->me_cmp&FF_CMP_CHROMA){        s->me.motion_search[0]= simple_chroma_epzs_motion_search;        s->me.motion_search[1]= simple_chroma_epzs_motion_search4;    }else{        s->me.motion_search[0]= simple_epzs_motion_search;        s->me.motion_search[1]= simple_epzs_motion_search4;    }        if(s->avctx->me_pre_cmp&FF_CMP_CHROMA){        s->me.pre_motion_search= simple_chroma_epzs_motion_search;    }else{        s->me.pre_motion_search= simple_epzs_motion_search;    }        if(s->flags&CODEC_FLAG_QPEL){        if(s->avctx->mb_cmp&FF_CMP_CHROMA)            s->me.get_mb_score= simple_chroma_qpel_get_mb_score;        else            s->me.get_mb_score= simple_qpel_get_mb_score;    }else{        if(s->avctx->mb_cmp&FF_CMP_CHROMA)            s->me.get_mb_score= simple_chroma_hpel_get_mb_score;        else            s->me.get_mb_score= simple_hpel_get_mb_score;    }}      #if 0static int pix_dev(uint8_t * pix, int line_size, int mean){    int s, i, j;    s = 0;    for (i = 0; i < 16; i++) {	for (j = 0; j < 16; j += 8) {	    s += ABS(pix[0]-mean);	    s += ABS(pix[1]-mean);	    s += ABS(pix[2]-mean);	    s += ABS(pix[3]-mean);	    s += ABS(pix[4]-mean);	    s += ABS(pix[5]-mean);	    s += ABS(pix[6]-mean);	    s += ABS(pix[7]-mean);	    pix += 8;	}	pix += line_size - 16;    }    return s;}#endifstatic inline void no_motion_search(MpegEncContext * s,				    int *mx_ptr, int *my_ptr){    *mx_ptr = 16 * s->mb_x;

⌨️ 快捷键说明

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