[FFmpeg-soc] [soc]: r586 - dirac/libavcodec/dirac.c
marco
subversion at mplayerhq.hu
Wed Aug 1 15:28:08 CEST 2007
Author: marco
Date: Wed Aug 1 15:28:08 2007
New Revision: 586
Log:
manage reference frames
Modified:
dirac/libavcodec/dirac.c
Modified: dirac/libavcodec/dirac.c
==============================================================================
--- dirac/libavcodec/dirac.c (original)
+++ dirac/libavcodec/dirac.c Wed Aug 1 15:28:08 2007
@@ -32,8 +32,6 @@
#include "bitstream.h"
#include "golomb.h"
#include "dirac_arith.h"
-#undef printf
-#include <stdio.h>
typedef enum {
TRANSFER_FUNC_TV,
@@ -224,6 +222,9 @@ struct dirac_blockmotion {
int dc[3];
};
+/* XXX */
+#define REFFRAME_CNT 20
+
typedef struct DiracContext {
int next_picture;
int access_unit;
@@ -234,6 +235,10 @@ typedef struct DiracContext {
AVFrame picture;
+ int picnum;
+ int refcnt;
+ AVFrame refframes[REFFRAME_CNT]; /* XXX */
+
struct source_parameters source;
struct sequence_parameters sequence;
struct decoding_parameters decoding;
@@ -262,8 +267,8 @@ typedef struct DiracContext {
int globalmc_flag; ///< use global motion compensation flag
/** global motion compensation parameters */
struct globalmc_parameters globalmc;
- int ref1; ///< first reference picture
- int ref2; ///< second reference picture
+ uint32_t ref1; ///< first reference picture
+ uint32_t ref2; ///< second reference picture
/* Current component. */
int padded_width; ///< padded width of the current component
@@ -1813,6 +1818,56 @@ static int dirac_idwt(AVCodecContext *av
return 0;
}
+static int reference_frame_idx(AVCodecContext *avctx, int framenr) {
+ DiracContext *s = avctx->priv_data;
+ int i;
+
+ for (i = 0; i < s->refcnt; i++) {
+ AVFrame *f = &s->refframes[i];
+ if (f->coded_picture_number == framenr)
+ return i;
+ }
+
+ return -1;
+}
+
+static int dirac_motion_compensation(AVCodecContext *avctx, int *coeffs, int comp) {
+ DiracContext *s = avctx->priv_data;
+ int x, y;
+ int width, height;
+ int xblen, yblen;
+ int xbsep, ybsep;
+ int xoffset, yoffset;
+
+ AVFrame *ref1 = 0, *ref2 = 0;
+
+ if (comp == 0) {
+ width = s->sequence.luma_width;
+ height = s->sequence.luma_height;
+ xblen = s->frame_decoding.luma_yblen;
+ yblen = s->frame_decoding.luma_xblen;
+ } else {
+ width = s->sequence.chroma_width;
+ height = s->sequence.chroma_height;
+ xblen = s->frame_decoding.chroma_yblen;
+ yblen = s->frame_decoding.chroma_xblen;
+ }
+
+ xoffset = (xblen - ybsep) / 2;
+ yoffset = (yblen - ybsep) / 2;
+
+ ref1 = &s->refframes[s->ref1];
+ if (s->refs == 2)
+ ref2 = &s->refframes[s->ref2];
+
+/* for (y = 0; y < height; y++) */
+/* for (x = 0; x < width; x++) { */
+/* coeffs[y * s->padded_width + x] += motion_comp(avctx, x, y, coeffs, */
+/* } */
+
+ return 0;
+}
+
/**
* Decode an intra frame.
*
@@ -1871,10 +1926,9 @@ static int dirac_decode_frame(AVCodecCon
*/
static int parse_frame(AVCodecContext *avctx) {
DiracContext *s = avctx->priv_data;
- int picnum;
int retire;
int filter;
- int i;
+ int i, j;
GetBitContext *gb = s->gb;
/* Setup decoding parameter defaults for this frame. */
@@ -1882,20 +1936,39 @@ static int parse_frame(AVCodecContext *a
s->picture.pict_type = FF_I_TYPE;
s->picture.key_frame = 1;
- s->picture.reference = 0;
- picnum = get_bits_long(gb, 32);
+ s->picnum = get_bits_long(gb, 32);
if (s->refs) {
- s->ref1 = dirac_get_se_golomb(gb);
+ s->ref1 = s->picnum + dirac_get_se_golomb(gb);
if (s->refs == 2)
- s->ref2 = dirac_get_se_golomb(gb);
+ s->ref2 = s->picnum + dirac_get_se_golomb(gb);
}
+ /* Retire the reference frames that are not used anymore. */
retire = dirac_get_ue_golomb(gb);
+ for (i = 0; i < retire; i++) {
+ int retire_num;
+ AVFrame *f;
+ int idx;
- for (i = 0; i < retire; i++)
- dirac_get_se_golomb(gb); /* XXX */
+ retire_num = dirac_get_se_golomb(gb) + s->picnum;
+
+ idx = reference_frame_idx(avctx, retire_num);
+ if (idx == -1) {
+ av_log(avctx, AV_LOG_WARNING, "frame to retire #%d not found\n", retire_num);
+ continue;
+ }
+
+ f = &s->refframes[idx];
+ if (f->data[0] != NULL)
+ avctx->release_buffer(avctx, f);
+ s->refcnt--;
+
+ for (j = idx; j < idx + s->refcnt; j++) {
+ s->refframes[j] = s->refframes[j + 1];
+ }
+ }
if (s->refs) {
align_get_bits(gb);
@@ -2040,8 +2113,14 @@ static int decode_frame(AVCodecContext *
avcodec_set_dimensions(avctx, s->sequence.luma_width,
s->sequence.luma_height);
- if (s->picture.data[0] != NULL)
- avctx->release_buffer(avctx, &s->picture);
+ if (s->picture.data[0] != NULL) {
+ if (s->picture.reference)
+ avcodec_get_frame_defaults(&s->picture);
+ else
+ avctx->release_buffer(avctx, &s->picture);
+ }
+
+ s->picture.reference = (parse_code & 0x04) == 0x04;
if (avctx->get_buffer(avctx, &s->picture) < 0) {
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
@@ -2051,6 +2130,12 @@ static int decode_frame(AVCodecContext *
if (dirac_decode_frame(avctx))
return -1;
+ s->picture.coded_picture_number = s->picnum;
+
+ if (s->picture.reference) {
+ s->refframes[s->refcnt++] = s->picture;
+ }
+
*data_size = sizeof(AVFrame);
*picture = s->picture;
More information about the FFmpeg-soc
mailing list