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

📄 motion_est.c

📁 Trolltech公司发布的图形界面操作系统。可在qt-embedded-2.3.7平台上编译为嵌入式图形界面操作系统。
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * Motion estimation  * Copyright (c) 2000,2001 Fabrice Bellard. * Copyright (c) 2002 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> */#include <stdlib.h>#include <stdio.h>#include "avcodec.h"#include "dsputil.h"#include "mpegvideo.h"#define SQ(a) ((a)*(a))#define INTER_BIAS	257#define P_LAST P[0]#define P_LEFT P[1]#define P_TOP P[2]#define P_TOPRIGHT P[3]#define P_MEDIAN P[4]#define P_LAST_LEFT P[5]#define P_LAST_RIGHT P[6]#define P_LAST_TOP P[7]#define P_LAST_BOTTOM P[8]#define P_MV1 P[9]static int pix_dev(UINT8 * 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;}static int pix_norm(UINT8 * pix1, UINT8 * pix2, int line_size){    int s, i, j;    UINT32 *sq = squareTbl + 256;    s = 0;    for (i = 0; i < 16; i++) {	for (j = 0; j < 16; j += 8) {	    s += sq[pix1[0] - pix2[0]];	    s += sq[pix1[1] - pix2[1]];	    s += sq[pix1[2] - pix2[2]];	    s += sq[pix1[3] - pix2[3]];	    s += sq[pix1[4] - pix2[4]];	    s += sq[pix1[5] - pix2[5]];	    s += sq[pix1[6] - pix2[6]];	    s += sq[pix1[7] - pix2[7]];	    pix1 += 8;	    pix2 += 8;	}	pix1 += line_size - 16;	pix2 += line_size - 16;    }    return s;}static inline void no_motion_search(MpegEncContext * s,				    int *mx_ptr, int *my_ptr){    *mx_ptr = 16 * s->mb_x;    *my_ptr = 16 * s->mb_y;}static int full_motion_search(MpegEncContext * s,                              int *mx_ptr, int *my_ptr, int range,                              int xmin, int ymin, int xmax, int ymax, uint8_t *ref_picture){    int x1, y1, x2, y2, xx, yy, x, y;    int mx, my, dmin, d;    UINT8 *pix;    xx = 16 * s->mb_x;    yy = 16 * s->mb_y;    x1 = xx - range + 1;	/* we loose one pixel to avoid boundary pb with half pixel pred */    if (x1 < xmin)	x1 = xmin;    x2 = xx + range - 1;    if (x2 > xmax)	x2 = xmax;    y1 = yy - range + 1;    if (y1 < ymin)	y1 = ymin;    y2 = yy + range - 1;    if (y2 > ymax)	y2 = ymax;    pix = s->new_picture[0] + (yy * s->linesize) + xx;    dmin = 0x7fffffff;    mx = 0;    my = 0;    for (y = y1; y <= y2; y++) {	for (x = x1; x <= x2; x++) {	    d = s->dsp.pix_abs16x16(pix, ref_picture + (y * s->linesize) + x,			     s->linesize);	    if (d < dmin ||		(d == dmin &&		 (abs(x - xx) + abs(y - yy)) <		 (abs(mx - xx) + abs(my - yy)))) {		dmin = d;		mx = x;		my = y;	    }	}    }    *mx_ptr = mx;    *my_ptr = my;#if 0    if (*mx_ptr < -(2 * range) || *mx_ptr >= (2 * range) ||	*my_ptr < -(2 * range) || *my_ptr >= (2 * range)) {	fprintf(stderr, "error %d %d\n", *mx_ptr, *my_ptr);    }#endif    return dmin;}static int log_motion_search(MpegEncContext * s,                             int *mx_ptr, int *my_ptr, int range,                             int xmin, int ymin, int xmax, int ymax, uint8_t *ref_picture){    int x1, y1, x2, y2, xx, yy, x, y;    int mx, my, dmin, d;    UINT8 *pix;    xx = s->mb_x << 4;    yy = s->mb_y << 4;    /* Left limit */    x1 = xx - range;    if (x1 < xmin)	x1 = xmin;    /* Right limit */    x2 = xx + range;    if (x2 > xmax)	x2 = xmax;    /* Upper limit */    y1 = yy - range;    if (y1 < ymin)	y1 = ymin;    /* Lower limit */    y2 = yy + range;    if (y2 > ymax)	y2 = ymax;    pix = s->new_picture[0] + (yy * s->linesize) + xx;    dmin = 0x7fffffff;    mx = 0;    my = 0;    do {	for (y = y1; y <= y2; y += range) {	    for (x = x1; x <= x2; x += range) {		d = s->dsp.pix_abs16x16(pix, ref_picture + (y * s->linesize) + x, s->linesize);		if (d < dmin || (d == dmin && (abs(x - xx) + abs(y - yy)) < (abs(mx - xx) + abs(my - yy)))) {		    dmin = d;		    mx = x;		    my = y;		}	    }	}	range = range >> 1;	x1 = mx - range;	if (x1 < xmin)	    x1 = xmin;	x2 = mx + range;	if (x2 > xmax)	    x2 = xmax;	y1 = my - range;	if (y1 < ymin)	    y1 = ymin;	y2 = my + range;	if (y2 > ymax)	    y2 = ymax;    } while (range >= 1);#ifdef DEBUG    fprintf(stderr, "log       - MX: %d\tMY: %d\n", mx, my);#endif    *mx_ptr = mx;    *my_ptr = my;    return dmin;}static int phods_motion_search(MpegEncContext * s,                               int *mx_ptr, int *my_ptr, int range,                               int xmin, int ymin, int xmax, int ymax, uint8_t *ref_picture){    int x1, y1, x2, y2, xx, yy, x, y, lastx, d;    int mx, my, dminx, dminy;    UINT8 *pix;    xx = s->mb_x << 4;    yy = s->mb_y << 4;    /* Left limit */    x1 = xx - range;    if (x1 < xmin)	x1 = xmin;    /* Right limit */    x2 = xx + range;    if (x2 > xmax)	x2 = xmax;    /* Upper limit */    y1 = yy - range;    if (y1 < ymin)	y1 = ymin;    /* Lower limit */    y2 = yy + range;    if (y2 > ymax)	y2 = ymax;    pix = s->new_picture[0] + (yy * s->linesize) + xx;    mx = 0;    my = 0;    x = xx;    y = yy;    do {        dminx = 0x7fffffff;        dminy = 0x7fffffff;	lastx = x;	for (x = x1; x <= x2; x += range) {	    d = s->dsp.pix_abs16x16(pix, ref_picture + (y * s->linesize) + x, s->linesize);	    if (d < dminx || (d == dminx && (abs(x - xx) + abs(y - yy)) < (abs(mx - xx) + abs(my - yy)))) {		dminx = d;		mx = x;	    }	}	x = lastx;	for (y = y1; y <= y2; y += range) {	    d = s->dsp.pix_abs16x16(pix, ref_picture + (y * s->linesize) + x, s->linesize);	    if (d < dminy || (d == dminy && (abs(x - xx) + abs(y - yy)) < (abs(mx - xx) + abs(my - yy)))) {		dminy = d;		my = y;	    }	}	range = range >> 1;	x = mx;	y = my;	x1 = mx - range;	if (x1 < xmin)	    x1 = xmin;	x2 = mx + range;	if (x2 > xmax)	    x2 = xmax;	y1 = my - range;	if (y1 < ymin)	    y1 = ymin;	y2 = my + range;	if (y2 > ymax)	    y2 = ymax;    } while (range >= 1);#ifdef DEBUG    fprintf(stderr, "phods     - MX: %d\tMY: %d\n", mx, my);#endif    /* half pixel search */    *mx_ptr = mx;    *my_ptr = my;    return dminy;}#define Z_THRESHOLD 256#define CHECK_MV(x,y)\{\    const int key= ((y)<<ME_MAP_MV_BITS) + (x) + map_generation;\    const int index= (((y)<<ME_MAP_SHIFT) + (x))&(ME_MAP_SIZE-1);\    if(map[index]!=key){\        d = s->dsp.pix_abs16x16(new_pic, old_pic + (x) + (y)*pic_stride, pic_stride);\        d += (mv_penalty[((x)<<shift)-pred_x] + mv_penalty[((y)<<shift)-pred_y])*quant;\        COPY3_IF_LT(dmin, d, best[0], x, best[1], y)\        map[index]= key;\        score_map[index]= d;\    }\}#define CHECK_MV_DIR(x,y,new_dir)\{\    const int key= ((y)<<ME_MAP_MV_BITS) + (x) + map_generation;\    const int index= (((y)<<ME_MAP_SHIFT) + (x))&(ME_MAP_SIZE-1);\    if(map[index]!=key){\        d = pix_abs(new_pic, old_pic + (x) + (y)*pic_stride, pic_stride);\        d += (mv_penalty[((x)<<shift)-pred_x] + mv_penalty[((y)<<shift)-pred_y])*quant;\        if(d<dmin){\            best[0]=x;\            best[1]=y;\            dmin=d;\            next_dir= new_dir;\        }\        map[index]= key;\        score_map[index]= d;\    }\}#define CHECK_MV4(x,y)\{\    const int key= ((y)<<ME_MAP_MV_BITS) + (x) + map_generation;\    const int index= (((y)<<ME_MAP_SHIFT) + (x))&(ME_MAP_SIZE-1);\    if(map[index]!=key){\        d = s->dsp.pix_abs8x8(new_pic, old_pic + (x) + (y)*pic_stride, pic_stride);\        d += (mv_penalty[((x)<<shift)-pred_x] + mv_penalty[((y)<<shift)-pred_y])*quant;\        COPY3_IF_LT(dmin, d, best[0], x, best[1], y)\        map[index]= key;\        score_map[index]= d;\    }\}#define check(x,y,S,v)\if( (x)<(xmin<<(S)) ) printf("%d %d %d %d %d xmin" #v, xmin, (x), (y), s->mb_x, s->mb_y);\if( (x)>(xmax<<(S)) ) printf("%d %d %d %d %d xmax" #v, xmax, (x), (y), s->mb_x, s->mb_y);\if( (y)<(ymin<<(S)) ) printf("%d %d %d %d %d ymin" #v, ymin, (x), (y), s->mb_x, s->mb_y);\if( (y)>(ymax<<(S)) ) printf("%d %d %d %d %d ymax" #v, ymax, (x), (y), s->mb_x, s->mb_y);\static inline int small_diamond_search(MpegEncContext * s, int *best, int dmin,                                       UINT8 *new_pic, UINT8 *old_pic, int pic_stride,                                       int pred_x, int pred_y, UINT16 *mv_penalty, int quant,                                       int xmin, int ymin, int xmax, int ymax, int shift,                                       uint32_t *map, uint16_t *score_map, int map_generation,                                       op_pixels_abs_func pix_abs){    int next_dir=-1;    for(;;){        int d;        const int dir= next_dir;        const int x= best[0];        const int y= best[1];        next_dir=-1;//printf("%d", dir);        if(dir!=2 && x>xmin) CHECK_MV_DIR(x-1, y  , 0)        if(dir!=3 && y>ymin) CHECK_MV_DIR(x  , y-1, 1)        if(dir!=0 && x<xmax) CHECK_MV_DIR(x+1, y  , 2)        if(dir!=1 && y<ymax) CHECK_MV_DIR(x  , y+1, 3)        if(next_dir==-1){            return dmin;        }    }/*    for(;;){        int d;        const int x= best[0];        const int y= best[1];        const int last_min=dmin;        if(x>xmin) CHECK_MV(x-1, y  )        if(y>xmin) CHECK_MV(x  , y-1)        if(x<xmax) CHECK_MV(x+1, y  )        if(y<xmax) CHECK_MV(x  , y+1)        if(x>xmin && y>ymin) CHECK_MV(x-1, y-1)        if(x>xmin && y<ymax) CHECK_MV(x-1, y+1)        if(x<xmax && y>ymin) CHECK_MV(x+1, y-1)        if(x<xmax && y<ymax) CHECK_MV(x+1, y+1)        if(x-1>xmin) CHECK_MV(x-2, y  )        if(y-1>xmin) CHECK_MV(x  , y-2)        if(x+1<xmax) CHECK_MV(x+2, y  )        if(y+1<xmax) CHECK_MV(x  , y+2)        if(x-1>xmin && y-1>ymin) CHECK_MV(x-2, y-2)        if(x-1>xmin && y+1<ymax) CHECK_MV(x-2, y+2)        if(x+1<xmax && y-1>ymin) CHECK_MV(x+2, y-2)        if(x+1<xmax && y+1<ymax) CHECK_MV(x+2, y+2)        if(dmin==last_min) return dmin;    }    */}#if 1#define SNAKE_1 3#define SNAKE_2 2#else#define SNAKE_1 7#define SNAKE_2 3#endif

⌨️ 快捷键说明

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