[FFmpeg-soc] [soc]: r724 - dirac/libavcodec/dirac.c
marco
subversion at mplayerhq.hu
Sun Aug 12 19:39:11 CEST 2007
Author: marco
Date: Sun Aug 12 19:39:11 2007
New Revision: 724
Log:
restructure MC code
Modified:
dirac/libavcodec/dirac.c
Modified: dirac/libavcodec/dirac.c
==============================================================================
--- dirac/libavcodec/dirac.c (original)
+++ dirac/libavcodec/dirac.c Sun Aug 12 19:39:11 2007
@@ -282,6 +282,12 @@ typedef struct DiracContext {
/* Current component. */
int padded_width; ///< padded width of the current component
int padded_height; ///< padded height of the current component
+ int width;
+ int height;
+ int xbsep;
+ int ybsep;
+ int xblen;
+ int yblen;
int *sbsplit;
struct dirac_blockmotion *blmotion;
@@ -2102,49 +2108,6 @@ static int upconvert(AVCodecContext *avc
return val >> s->frame_decoding.mv_precision;
}
-static int motion_comp_blockpred(AVCodecContext *avctx, uint8_t *refframe,
- int ref, struct dirac_blockmotion *currblock,
- int x, int y, int width, int height,
- int comp) {
- DiracContext *s = avctx->priv_data;
- int vect[2];
- int px, py;
-
- if (!currblock->use_global) {
- /* XXX */
- if (ref == 0) {
- vect[0] = currblock->ref1[0];
- vect[1] = currblock->ref1[1];
- } else {
- vect[0] = currblock->ref2[0];
- vect[1] = currblock->ref2[1];
- }
- } else {
- dprintf(avctx, "global motion compensation has not been implemented yet\n");
- /* XXX */
- vect[0] = 0;
- vect[1] = 0;
- }
-
- if (comp != 0) {
- if (s->chroma_hratio)
- vect[0] >>= 1;
- if (s->chroma_vratio)
- vect[1] >>= 1;
- }
-
- if (s->frame_decoding.mv_precision > 0) {
- px = (x << s->frame_decoding.mv_precision) + vect[0];
- py = (y << s->frame_decoding.mv_precision) + vect[1];
- } else {
- px = (x + vect[0]) << 1;
- py = (y + vect[1]) << 1;
- }
-
- /* Upconversion. */
- return upconvert(avctx, refframe, width, height, px, py, comp);
-}
-
static inline int spatial_wt(int i, int x, int bsep, int blen,
int offset, int blocks) {
int pos = x - (i * bsep - offset);
@@ -2159,141 +2122,275 @@ static inline int spatial_wt(int i, int
return av_clip(blen - 2*FFABS(pos - (blen - 1) / 2), 0, max);
}
-static void motion_comp(AVCodecContext *avctx, int i, int j,
- struct dirac_blockmotion *currblock,
- AVFrame *ref1, AVFrame *ref2, int16_t *coeffs, int comp) {
+static void motion_comp_block2refs(AVCodecContext *avctx, int16_t *coeffs,
+ int i, int j,
+ uint8_t *ref1, uint8_t *ref2,
+ struct dirac_blockmotion *currblock,
+ int comp) {
DiracContext *s = avctx->priv_data;
- uint16_t *line;
- int width, height;
- int xblen, yblen;
- int xbsep, ybsep;
- int xoffset, yoffset;
- int val;
int x, y;
+ int16_t *line;
+ int px1, py1;
+ int px2, py2;
+ int xoffset, yoffset;
+ int xstart, ystart;
+ int xstop, ystop;
int hbits, vbits;
int total_wt_bits;
+ int vect1[2];
+ int vect2[2];
- int xstart, ystart;
- int xstop, ystop;
+ xoffset = (s->xblen - s->xbsep) / 2;
+ yoffset = (s->yblen - s->ybsep) / 2;
+ xstart = FFMAX(0, i * s->xbsep - xoffset);
+ ystart = FFMAX(0, j * s->ybsep - yoffset);
+ xstop = FFMIN(xstart + s->xblen, s->width);
+ ystop = FFMIN(ystart + s->yblen, s->height);
- if (comp == 0) {
- width = s->sequence.luma_width;
- height = s->sequence.luma_height;
- xblen = s->frame_decoding.luma_xblen;
- yblen = s->frame_decoding.luma_yblen;
- xbsep = s->frame_decoding.luma_xbsep;
- ybsep = s->frame_decoding.luma_ybsep;
- } else {
- width = s->sequence.chroma_width;
- height = s->sequence.chroma_height;
- xblen = s->frame_decoding.chroma_xblen;
- yblen = s->frame_decoding.chroma_yblen;
- xbsep = s->frame_decoding.chroma_xbsep;
- ybsep = s->frame_decoding.chroma_ybsep;
+ hbits = av_log2(xoffset) + 2;
+ vbits = av_log2(yoffset) + 2;
+ total_wt_bits = hbits + vbits
+ + s->frame_decoding.picture_weight_precision;
+
+ vect1[0] = currblock->ref1[0];
+ vect1[1] = currblock->ref1[1];
+ vect2[0] = currblock->ref2[0];
+ vect2[1] = currblock->ref2[1];
+
+ if (comp != 0) {
+ if (s->chroma_hratio) {
+ vect1[0] >>= 1;
+ vect2[0] >>= 1;
+ }
+ if (s->chroma_vratio) {
+ vect1[1] >>= 1;
+ vect2[1] >>= 1;
+ }
}
- xoffset = (xblen - xbsep) / 2;
- yoffset = (yblen - ybsep) / 2;
+ line = &coeffs[s->padded_width * ystart];
+ for (y = ystart; y < ystop; y++) {
+ for (x = xstart; x < xstop; x++) {
+ int val1 = 0;
+ int val2 = 0;
+ int val = 0;
+
+ if (s->frame_decoding.mv_precision > 0) {
+ px1 = (x << s->frame_decoding.mv_precision) + vect1[0];
+ py1 = (y << s->frame_decoding.mv_precision) + vect1[1];
+ px2 = (x << s->frame_decoding.mv_precision) + vect2[0];
+ py2 = (y << s->frame_decoding.mv_precision) + vect2[1];
+ } else {
+ px1 = (x + vect1[0]) << 1;
+ py1 = (y + vect1[1]) << 1;
+ px2 = (x + vect2[0]) << 1;
+ py2 = (y + vect2[1]) << 1;
+ }
+
+ val1 = upconvert(avctx, ref1, s->ref1width, s->ref1height,
+ px1, py1, comp);
+ val1 *= s->frame_decoding.picture_weight_ref1;
+
+ val2 = upconvert(avctx, ref2, s->ref2width, s->ref2height,
+ px2, py2, comp);
+ val2 *= s->frame_decoding.picture_weight_ref2;
+
+ val = val1 + val2;
+ val = (val
+ * spatial_wt(i, x, s->xbsep, s->xblen,
+ xoffset, s->blwidth)
+ * spatial_wt(j, y, s->ybsep, s->yblen,
+ yoffset, s->blheight));
+
+ val = (val + (1 << (total_wt_bits - 1))) >> total_wt_bits;
+ line[x] += val;
+ }
+ line += s->padded_width;
+ }
+}
+
+static void motion_comp_block1ref(AVCodecContext *avctx, int16_t *coeffs,
+ int i, int j,
+ uint8_t *refframe, int ref,
+ struct dirac_blockmotion *currblock,
+ int comp) {
+ DiracContext *s = avctx->priv_data;
+ int x, y;
+ int16_t *line;
+ int px, py;
+ int xoffset, yoffset;
+ int xstart, ystart;
+ int xstop, ystop;
+ int hbits, vbits;
+ int total_wt_bits;
+ int vect[2];
+
+ xoffset = (s->xblen - s->xbsep) / 2;
+ yoffset = (s->yblen - s->ybsep) / 2;
+ xstart = FFMAX(0, i * s->xbsep - xoffset);
+ ystart = FFMAX(0, j * s->ybsep - yoffset);
+ xstop = FFMIN(xstart + s->xblen, s->width);
+ ystop = FFMIN(ystart + s->yblen, s->height);
hbits = av_log2(xoffset) + 2;
vbits = av_log2(yoffset) + 2;
total_wt_bits = hbits + vbits
- + s->frame_decoding.picture_weight_precision;
+ + s->frame_decoding.picture_weight_precision;
- xstart = FFMAX(0, i * xbsep - xoffset);
- ystart = FFMAX(0, j * ybsep - yoffset);
- xstop = FFMIN(xstart + xblen, width);
- ystop = FFMIN(ystart + yblen, height);
+ if (ref == 0) {
+ vect[0] = currblock->ref1[0];
+ vect[1] = currblock->ref1[1];
+ } else {
+ vect[0] = currblock->ref2[0];
+ vect[1] = currblock->ref2[1];
+ }
+
+ if (comp != 0) {
+ if (s->chroma_hratio)
+ vect[0] >>= 1;
+ if (s->chroma_vratio)
+ vect[1] >>= 1;
+ }
line = &coeffs[s->padded_width * ystart];
for (y = ystart; y < ystop; y++) {
for (x = xstart; x < xstop; x++) {
- if (currblock->use_ref[0] == 0 && currblock->use_ref[1] == 0) {
- /* Intra */
- val = currblock->dc[comp];
- val <<= s->frame_decoding.picture_weight_precision;
- } else if (currblock->use_ref[1] == 0) {
- /* Reference frame 1 only. */
- val = motion_comp_blockpred(avctx, s->ref1data, 0,
- currblock, x, y, s->ref1width,
- s->ref1height, comp);
- val *= (s->frame_decoding.picture_weight_ref1
- + s->frame_decoding.picture_weight_ref2);
- } else if (currblock->use_ref[0] == 0) {
- /* Reference frame 2 only. */
- val = motion_comp_blockpred(avctx, s->ref2data, 1,
- currblock, x, y, s->ref2width,
- s->ref2height, comp);
- val *= (s->frame_decoding.picture_weight_ref1
- + s->frame_decoding.picture_weight_ref2);
+ int val = 0;
+
+ if (s->frame_decoding.mv_precision > 0) {
+ px = (x << s->frame_decoding.mv_precision) + vect[0];
+ py = (y << s->frame_decoding.mv_precision) + vect[1];
} else {
- /* Reference frame 1 and 2. */
- int val1, val2;
- val1 = motion_comp_blockpred(avctx, s->ref1data, 0,
- currblock, x, y, s->ref1width,
- s->ref1height, comp);
- val1 *= s->frame_decoding.picture_weight_ref1;
- val2 = motion_comp_blockpred(avctx, s->ref2data, 1,
- currblock, x, y, s->ref2width,
- s->ref2height, comp);
- val2 *= s->frame_decoding.picture_weight_ref2;
- val = val1 + val2;
+ px = (x + vect[0]) << 1;
+ py = (y + vect[1]) << 1;
}
- val = val
- * spatial_wt(i, x, xbsep, xblen, xoffset, s->blwidth)
- * spatial_wt(j, y, ybsep, yblen, yoffset, s->blheight);
+ val = upconvert(avctx, refframe, s->ref1width, s->ref1height,
+ px, py, comp);
+ val *= s->frame_decoding.picture_weight_ref1
+ + s->frame_decoding.picture_weight_ref2;
+
+ val = (val
+ * spatial_wt(i, x, s->xbsep, s->xblen,
+ xoffset, s->blwidth)
+ * spatial_wt(j, y, s->ybsep, s->yblen,
+ yoffset, s->blheight));
val = (val + (1 << (total_wt_bits - 1))) >> total_wt_bits;
+ line[x] += val;
+ }
+ line += s->padded_width;
+ }
+}
+
+static inline void motion_comp_dc_block(AVCodecContext *avctx, uint16_t *coeffs,
+ int i, int j, int dcval) {
+ DiracContext *s = avctx->priv_data;
+ int x, y;
+ int16_t *line;
+ int xoffset, yoffset;
+ int xstart, ystart;
+ int xstop, ystop;
+ int hbits, vbits;
+ int total_wt_bits;
+
+ xoffset = (s->xblen - s->xbsep) / 2;
+ yoffset = (s->yblen - s->ybsep) / 2;
+ xstart = FFMAX(0, i * s->xbsep - xoffset);
+ ystart = FFMAX(0, j * s->ybsep - yoffset);
+ xstop = FFMIN(xstart + s->xblen, s->width);
+ ystop = FFMIN(ystart + s->yblen, s->height);
+
+ hbits = av_log2(xoffset) + 2;
+ vbits = av_log2(yoffset) + 2;
+
+ total_wt_bits = hbits + vbits
+ + s->frame_decoding.picture_weight_precision;
+
+ dcval <<= s->frame_decoding.picture_weight_precision;
+ line = &coeffs[s->padded_width * ystart];
+ for (y = ystart; y < ystop; y++) {
+ for (x = xstart; x < xstop; x++) {
+ int val;
+
+ val = dcval;
+ val *= spatial_wt(i, x, s->xbsep, s->xblen, xoffset, s->blwidth)
+ * spatial_wt(j, y, s->ybsep, s->yblen, yoffset, s->blheight);
+ val = (val + (1 << (total_wt_bits - 1))) >> total_wt_bits;
line[x] += val;
}
- line += s->padded_width;
+ line += s->padded_width;
}
}
+static void motion_comp(AVCodecContext *avctx, int i, int j,
+ struct dirac_blockmotion *currblock,
+ AVFrame *ref1, AVFrame *ref2, int16_t *coeffs, int comp) {
+ DiracContext *s = avctx->priv_data;
+
+ if (currblock->use_ref[0] == 0 && currblock->use_ref[1] == 0) {
+ /* Intra */
+ motion_comp_dc_block(avctx, coeffs, i, j, currblock->dc[comp]);
+ } else if (currblock->use_ref[1] == 0) {
+ /* Reference frame 1 only. */
+ motion_comp_block1ref(avctx, coeffs, i, j, s->ref1data, 0, currblock, comp);
+ } else if (currblock->use_ref[0] == 0) {
+ /* Reference frame 2 only. */
+ motion_comp_block1ref(avctx, coeffs, i, j, s->ref2data, 1, currblock, comp);
+ } else {
+ motion_comp_block2refs(avctx, coeffs, i, j, s->ref1data, s->ref2data, currblock, comp);
+ }
+}
+
static int dirac_motion_compensation(AVCodecContext *avctx, int16_t *coeffs,
int comp) {
DiracContext *s = avctx->priv_data;
- int width, height;
int i, j;
int refidx1, refidx2 = 0;
AVFrame *ref1 = 0, *ref2 = 0;
struct dirac_blockmotion *currblock;
if (comp == 0) {
- width = s->sequence.luma_width;
- height = s->sequence.luma_height;
+ s->width = s->sequence.luma_width;
+ s->height = s->sequence.luma_height;
+ s->xblen = s->frame_decoding.luma_xblen;
+ s->yblen = s->frame_decoding.luma_yblen;
+ s->xbsep = s->frame_decoding.luma_xbsep;
+ s->ybsep = s->frame_decoding.luma_ybsep;
} else {
- width = s->sequence.chroma_width;
- height = s->sequence.chroma_height;
-
+ s->width = s->sequence.chroma_width;
+ s->height = s->sequence.chroma_height;
+ s->xblen = s->frame_decoding.chroma_xblen;
+ s->yblen = s->frame_decoding.chroma_yblen;
+ s->xbsep = s->frame_decoding.chroma_xbsep;
+ s->ybsep = s->frame_decoding.chroma_ybsep;
}
refidx1 = reference_frame_idx(avctx, s->ref1);
ref1 = &s->refframes[refidx1];
- s->ref1width = width << 1;
- s->ref1height = height << 1;
+ s->ref1width = s->width << 1;
+ s->ref1height = s->height << 1;
s->ref1data = av_malloc(s->ref1width * s->ref1height);
if (!s->ref1data) {
av_log(avctx, AV_LOG_ERROR, "av_malloc() failed\n");
return -1;
}
- interpolate_frame_halfpel(ref1, width, height, s->ref1data, comp);
+ interpolate_frame_halfpel(ref1, s->width, s->height, s->ref1data, comp);
/* XXX: somehow merge with the code above. */
if (s->refs == 2) {
refidx2 = reference_frame_idx(avctx, s->ref2);
ref2 = &s->refframes[refidx2];
- s->ref2width = width << 1;
- s->ref2height = height << 1;
+ s->ref2width = s->width << 1;
+ s->ref2height = s->height << 1;
s->ref2data = av_malloc(s->ref2width * s->ref2height);
if (!s->ref2data) {
av_log(avctx, AV_LOG_ERROR, "av_malloc() failed\n");
return -1;
}
- interpolate_frame_halfpel(ref2, width, height, s->ref2data, comp);
+ interpolate_frame_halfpel(ref2, s->width, s->height, s->ref2data, comp);
}
else
s->ref2data = NULL;
More information about the FFmpeg-soc
mailing list