[FFmpeg-soc] [soc]: r1238 - dirac/libavcodec/dirac.c
marco
subversion at mplayerhq.hu
Wed Aug 29 12:55:24 CEST 2007
Author: marco
Date: Wed Aug 29 12:55:24 2007
New Revision: 1238
Log:
use a precalculated spatial weighting matrix for non border cases
Modified:
dirac/libavcodec/dirac.c
Modified: dirac/libavcodec/dirac.c
==============================================================================
--- dirac/libavcodec/dirac.c (original)
+++ dirac/libavcodec/dirac.c Wed Aug 29 12:55:24 2007
@@ -282,6 +282,7 @@ typedef struct DiracContext {
/** global motion compensation parameters */
struct globalmc_parameters globalmc;
uint32_t ref[2]; ///< reference pictures
+ int16_t *spatialwt;
uint8_t *refdata[2];
int refwidth;
@@ -2022,6 +2023,7 @@ static void motion_comp_block2refs(Dirac
struct dirac_blockmotion *currblock,
int comp) {
int x, y;
+ int xs, ys;
int16_t *line;
uint8_t *refline1;
uint8_t *refline2;
@@ -2031,6 +2033,7 @@ static void motion_comp_block2refs(Dirac
int vect2[2];
int refxstart1, refystart1;
int refxstart2, refystart2;
+ uint16_t *spatialwt;
START_TIMER
@@ -2039,6 +2042,9 @@ START_TIMER
vect2[0] = currblock->vect[1][0];
vect2[1] = currblock->vect[1][1];
+ xs = FFMAX(xstart, 0);
+ ys = FFMAX(ystart, 0);
+
if (comp != 0) {
vect1[0] >>= s->chroma_hshift;
vect2[0] >>= s->chroma_hshift;
@@ -2047,30 +2053,33 @@ START_TIMER
}
if (s->frame_decoding.mv_precision > 0) {
- refxstart1 = (xstart << s->frame_decoding.mv_precision) + vect1[0];
+ refxstart1 = (xs << s->frame_decoding.mv_precision) + vect1[0];
refxstart1 >>= s->frame_decoding.mv_precision - 1;
- refystart1 = (ystart << s->frame_decoding.mv_precision) + vect1[1];
+ refystart1 = (ys << s->frame_decoding.mv_precision) + vect1[1];
refystart1 >>= s->frame_decoding.mv_precision - 1;
- refxstart2 = (xstart << s->frame_decoding.mv_precision) + vect2[0];
+ refxstart2 = (xs << s->frame_decoding.mv_precision) + vect2[0];
refxstart2 >>= s->frame_decoding.mv_precision - 1;
- refystart2 = (ystart << s->frame_decoding.mv_precision) + vect2[1];
+ refystart2 = (ys << s->frame_decoding.mv_precision) + vect2[1];
refystart2 >>= s->frame_decoding.mv_precision - 1;
} else {
- refxstart1 = (xstart + vect1[0]) << 1;
+ refxstart1 = (xs + vect1[0]) << 1;
refxstart1 >>= s->frame_decoding.mv_precision - 1;
- refystart1 = (ystart + vect1[1]) << 1;
+ refystart1 = (ys + vect1[1]) << 1;
refystart1 >>= s->frame_decoding.mv_precision - 1;
- refxstart2 = (xstart + vect2[0]) << 1;
+ refxstart2 = (xs + vect2[0]) << 1;
refxstart2 >>= s->frame_decoding.mv_precision - 1;
- refystart2 = (ystart + vect2[1]) << 1;
+ refystart2 = (ys + vect2[1]) << 1;
refystart2 >>= s->frame_decoding.mv_precision - 1;
}
- line = &coeffs[s->width * ystart];
+ spatialwt = &s->spatialwt[s->xblen * (ys - ystart)];
+
+ line = &coeffs[s->width * ys];
refline1 = &ref1[refystart1 * s->refwidth];
refline2 = &ref2[refystart2 * s->refwidth];
- for (y = ystart; y < ystop; y++) {
- for (x = xstart; x < xstop; x++) {
+ for (y = ys; y < ystop; y++) {
+ int bx = xs - xstart;
+ for (x = xs; x < xstop; x++) {
int val1 = 0;
int val2 = 0;
int val = 0;
@@ -2156,17 +2165,24 @@ START_TIMER
val1 *= s->frame_decoding.picture_weight_ref1;
val2 *= s->frame_decoding.picture_weight_ref2;
val = val1 + val2;
+ if (i > 0 && j > 0
+ && i < s->current_blwidth - 1 && j < s->current_blwidth - 1) {
+ val *= spatialwt[bx];
+ } else {
val = (val
* spatial_wt(i, x, s->xbsep, s->xblen,
s->xoffset, s->current_blwidth)
* spatial_wt(j, y, s->ybsep, s->yblen,
s->yoffset, s->current_blheight));
+ }
line[x] += val;
+ bx++;
}
refline1 += s->refwidth << 1;
refline2 += s->refwidth << 1;
line += s->width;
+ spatialwt += s->xblen;
}
STOP_TIMER("two_refframes");
@@ -2194,38 +2210,46 @@ static void motion_comp_block1ref(DiracC
struct dirac_blockmotion *currblock,
int comp) {
int x, y;
+ int xs, ys;
int16_t *line;
uint8_t *refline;
int px, py;
int vect[2];
int refxstart, refystart;
+ uint16_t *spatialwt;
START_TIMER
vect[0] = currblock->vect[ref][0];
vect[1] = currblock->vect[ref][1];
+ xs = FFMAX(xstart, 0);
+ ys = FFMAX(ystart, 0);
+
if (comp != 0) {
vect[0] >>= s->chroma_hshift;
vect[1] >>= s->chroma_vshift;
}
if (s->frame_decoding.mv_precision > 0) {
- refxstart = (xstart << s->frame_decoding.mv_precision) + vect[0];
+ refxstart = (xs << s->frame_decoding.mv_precision) + vect[0];
refxstart >>= s->frame_decoding.mv_precision - 1;
- refystart = (ystart << s->frame_decoding.mv_precision) + vect[1];
+ refystart = (ys << s->frame_decoding.mv_precision) + vect[1];
refystart >>= s->frame_decoding.mv_precision - 1;
} else {
- refxstart = (xstart + vect[0]) << 1;
+ refxstart = (xs + vect[0]) << 1;
refxstart >>= s->frame_decoding.mv_precision - 1;
- refystart = (ystart + vect[1]) << 1;
+ refystart = (ys + vect[1]) << 1;
refystart >>= s->frame_decoding.mv_precision - 1;
}
- line = &coeffs[s->width * ystart];
+ spatialwt = &s->spatialwt[s->xblen * (ys - ystart)];
+
+ line = &coeffs[s->width * ys];
refline = &refframe[refystart * s->refwidth];
- for (y = ystart; y < ystop; y++) {
- for (x = xstart; x < xstop; x++) {
+ for (y = ys; y < ystop; y++) {
+ int bx = xs - xstart;
+ for (x = xs; x < xstop; x++) {
int hx, hy;
int rx, ry;
/* XXX: This matrix can perhaps be stored in a fixed
@@ -2277,16 +2301,23 @@ START_TIMER
val *= s->frame_decoding.picture_weight_ref1
+ s->frame_decoding.picture_weight_ref2;
+ if (i > 0 && j > 0
+ && i < s->current_blwidth - 1 && j < s->current_blheight - 1) {
+ val *= spatialwt[bx];
+ } else {
val = (val
* spatial_wt(i, x, s->xbsep, s->xblen,
s->xoffset, s->current_blwidth)
* spatial_wt(j, y, s->ybsep, s->yblen,
s->yoffset, s->current_blheight));
+ }
line[x] += val;
+ bx++;
}
line += s->width;
refline += s->refwidth << 1;
+ spatialwt += s->xblen;
}
STOP_TIMER("single_refframe");
@@ -2309,24 +2340,38 @@ static inline void motion_comp_dc_block(
int xstart, int xstop, int ystart,
int ystop, int dcval) {
int x, y;
+ int xs, ys;
int16_t *line;
+ uint16_t *spatialwt;
+
+ ys = FFMAX(ystart, 0);
+ xs = FFMAX(xstart, 0);
dcval <<= s->frame_decoding.picture_weight_precision;
- line = &coeffs[s->width * ystart];
- for (y = ystart; y < ystop; y++) {
- for (x = xstart; x < xstop; x++) {
+ spatialwt = &s->spatialwt[s->xblen * (ys - ystart)];
+ line = &coeffs[s->width * ys];
+ for (y = ys; y < ystop; y++) {
+ int bx = xs - xstart;
+ for (x = xs; x < xstop; x++) {
int val;
+ if (i > 0 && j > 0
+ && i < s->current_blwidth - 1 && j < s->current_blheight - 1) {
+ val = dcval * spatialwt[bx];
+ } else {
val = dcval
* spatial_wt(i, x, s->xbsep, s->xblen,
s->xoffset, s->current_blwidth)
* spatial_wt(j, y, s->ybsep, s->yblen,
s->yoffset, s->current_blheight);
+ }
line[x] += val;
+ bx++;
}
line += s->width;
+ spatialwt += s->xblen;
}
}
@@ -2380,6 +2425,25 @@ static int dirac_motion_compensation(Dir
s->refwidth = s->width << 1;
s->refheight = s->height << 1;
+ s->spatialwt = av_malloc(s->xblen * s->yblen * sizeof(int16_t));
+ if (!s->spatialwt) {
+ av_log(s->avctx, AV_LOG_ERROR, "av_malloc() failed\n");
+ return -1;
+ }
+
+ /* Set up the spatial weighting matrix. */
+ for (x = 0; x < s->xblen; x++) {
+ for (y = 0; y < s->yblen; y++) {
+ int wh, wv;
+ const int xmax = 2 * (s->xblen - s->xbsep);
+ const int ymax = 2 * (s->yblen - s->ybsep);
+
+ wh = av_clip(s->xblen - FFABS(2*x - (s->xblen - 1)), 0, xmax);
+ wv = av_clip(s->yblen - FFABS(2*y - (s->yblen - 1)), 0, ymax);
+ s->spatialwt[x + y * s->xblen] = wh * wv;
+ }
+ }
+
if (avcodec_check_dimensions(s->avctx, s->refwidth, s->refheight)) {
av_log(s->avctx, AV_LOG_ERROR, "avcodec_check_dimensions() failed\n");
return -1;
@@ -2440,8 +2504,6 @@ static int dirac_motion_compensation(Dir
ystart = j * s->ybsep - s->yoffset;
xstop = FFMIN(xstart + s->xblen, s->width);
ystop = FFMIN(ystart + s->yblen, s->height);
- xstart = FFMAX(0, xstart);
- ystart = FFMAX(0, ystart);
/* Intra */
if ((block->use_ref & 3) == 0)
@@ -2486,6 +2548,8 @@ static int dirac_motion_compensation(Dir
STOP_TIMER("motioncomp");
}
+ av_freep(&s->spatialwt);
+
for (i = 0; i < s->retirecnt; i++) {
if (cacheframe[0] == 1 && i == refidx[0])
cacheframe[0] = 0;
More information about the FFmpeg-soc
mailing list