[FFmpeg-soc] [soc]: r735 - dirac/libavcodec/dirac.c
marco
subversion at mplayerhq.hu
Sun Aug 12 21:53:04 CEST 2007
Author: marco
Date: Sun Aug 12 21:53:03 2007
New Revision: 735
Log:
cache interpolated reference frame if it is used more often
Modified:
dirac/libavcodec/dirac.c
Modified: dirac/libavcodec/dirac.c
==============================================================================
--- dirac/libavcodec/dirac.c (original)
+++ dirac/libavcodec/dirac.c Sun Aug 12 21:53:03 2007
@@ -225,6 +225,11 @@ struct dirac_blockmotion {
/* XXX */
#define REFFRAME_CNT 20
+struct reference_frame {
+ AVFrame frame;
+ uint8_t *halfpel[3];
+};
+
typedef struct DiracContext {
int access_unit;
unsigned int profile;
@@ -236,7 +241,7 @@ typedef struct DiracContext {
uint32_t picnum;
int refcnt;
- AVFrame refframes[REFFRAME_CNT]; /* XXX */
+ struct reference_frame refframes[REFFRAME_CNT]; /* XXX */
int retirecnt;
uint32_t retireframe[REFFRAME_CNT];
@@ -1966,7 +1971,7 @@ static int reference_frame_idx(AVCodecCo
int i;
for (i = 0; i < s->refcnt; i++) {
- AVFrame *f = &s->refframes[i];
+ AVFrame *f = &s->refframes[i].frame;
if (f->display_picture_number == framenr)
return i;
}
@@ -2287,6 +2292,7 @@ static int dirac_motion_compensation(AVC
DiracContext *s = avctx->priv_data;
int i, j;
int refidx1, refidx2 = 0;
+ int cacheframe1 = 1, cacheframe2 = 1;
AVFrame *ref1 = 0, *ref2 = 0;
struct dirac_blockmotion *currblock;
int xstart, ystart;
@@ -2318,23 +2324,29 @@ static int dirac_motion_compensation(AVC
+ s->frame_decoding.picture_weight_precision;
refidx1 = reference_frame_idx(avctx, s->ref1);
- ref1 = &s->refframes[refidx1];
+ ref1 = &s->refframes[refidx1].frame;
s->ref1width = s->width << 1;
s->ref1height = s->height << 1;
+ if (s->refframes[refidx1].halfpel[comp] == NULL) {
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, s->width, s->height, s->ref1data, comp);
+ } else {
+ s->ref1data = s->refframes[refidx1].halfpel[comp];
+ cacheframe1 = 2;
+ }
/* XXX: somehow merge with the code above. */
if (s->refs == 2) {
refidx2 = reference_frame_idx(avctx, s->ref2);
- ref2 = &s->refframes[refidx2];
+ ref2 = &s->refframes[refidx2].frame;
s->ref2width = s->width << 1;
s->ref2height = s->height << 1;
+ if (s->refframes[refidx2].halfpel[comp] == NULL) {
s->ref2data = av_malloc(s->ref2width * s->ref2height);
if (!s->ref2data) {
av_log(avctx, AV_LOG_ERROR, "av_malloc() failed\n");
@@ -2342,6 +2354,10 @@ static int dirac_motion_compensation(AVC
}
interpolate_frame_halfpel(ref2, s->width, s->height,
s->ref2data, comp);
+ } else {
+ s->ref2data = s->refframes[refidx2].halfpel[comp];
+ cacheframe2 = 2;
+ }
}
else
s->ref2data = NULL;
@@ -2385,8 +2401,22 @@ static int dirac_motion_compensation(AVC
STOP_TIMER("motioncomp");
}
- av_free(s->ref1data);
- av_free(s->ref2data);
+ for (i = 0; i < s->retirecnt; i++) {
+ if (cacheframe1 == 1 && i == refidx1)
+ cacheframe1 = 0;
+ if (cacheframe2 == 1 && i == refidx2)
+ cacheframe2 = 0;
+ }
+
+ if (cacheframe1)
+ s->refframes[refidx1].halfpel[comp] = s->ref1data;
+ else
+ av_free(s->ref1data);
+
+ if (cacheframe2)
+ s->refframes[refidx2].halfpel[comp] = s->ref2data;
+ else
+ av_free(s->ref2data);
return 0;
}
@@ -2645,7 +2675,7 @@ static int decode_frame(AVCodecContext *
#if 1
for (i = 0; i < s->refcnt; i++)
dprintf(avctx, "Reference frame #%d\n",
- s->refframes[i].display_picture_number);
+ s->refframes[i].frame.display_picture_number);
if (s->refs)
dprintf(avctx, "First reference frame: #%d\n", s->ref1);
@@ -2665,13 +2695,16 @@ static int decode_frame(AVCodecContext *
return -1;
}
- s->refframes[s->refcnt++] = s->picture;
+ s->refframes[s->refcnt].halfpel[0] = 0;
+ s->refframes[s->refcnt].halfpel[1] = 0;
+ s->refframes[s->refcnt].halfpel[2] = 0;
+ s->refframes[s->refcnt++].frame = s->picture;
}
/* Retire frames that were reordered and displayed if they are no
reference frames either. */
for (i = 0; i < s->refcnt; i++) {
- AVFrame *f = &s->refframes[i];
+ AVFrame *f = &s->refframes[i].frame;
if (f->reference == 0
&& f->display_picture_number < avctx->frame_number) {
@@ -2690,7 +2723,7 @@ static int decode_frame(AVCodecContext *
continue;
}
- f = &s->refframes[idx];
+ f = &s->refframes[idx].frame;
/* Do not retire frames that were not displayed yet. */
if (f->display_picture_number >= avctx->frame_number) {
f->reference = 0;
@@ -2699,6 +2732,11 @@ static int decode_frame(AVCodecContext *
if (f->data[0] != NULL)
avctx->release_buffer(avctx, f);
+
+ av_free(s->refframes[idx].halfpel[0]);
+ av_free(s->refframes[idx].halfpel[1]);
+ av_free(s->refframes[idx].halfpel[2]);
+
s->refcnt--;
for (j = idx; j < idx + s->refcnt; j++) {
@@ -2711,7 +2749,11 @@ static int decode_frame(AVCodecContext *
if (!s->picture.reference) {
/* This picture needs to be shown at a later time. */
- s->refframes[s->refcnt++] = s->picture;
+
+ s->refframes[s->refcnt].halfpel[0] = 0;
+ s->refframes[s->refcnt].halfpel[1] = 0;
+ s->refframes[s->refcnt].halfpel[2] = 0;
+ s->refframes[s->refcnt++].frame = s->picture;
}
idx = reference_frame_idx(avctx, avctx->frame_number);
@@ -2720,7 +2762,7 @@ static int decode_frame(AVCodecContext *
*data_size = 0;
} else {
*data_size = sizeof(AVFrame);
- *picture = s->refframes[idx];
+ *picture = s->refframes[idx].frame;
}
} else {
/* The right frame at the right time :-) */
More information about the FFmpeg-soc
mailing list