[FFmpeg-soc] [soc]: r905 - dirac/libavcodec/dirac.c
marco
subversion at mplayerhq.hu
Fri Aug 17 13:47:40 CEST 2007
Author: marco
Date: Fri Aug 17 13:47:39 2007
New Revision: 905
Log:
coefficient encoding
Modified:
dirac/libavcodec/dirac.c
Modified: dirac/libavcodec/dirac.c
==============================================================================
--- dirac/libavcodec/dirac.c (original)
+++ dirac/libavcodec/dirac.c Fri Aug 17 13:47:39 2007
@@ -948,22 +948,13 @@ static void codeblock(DiracContext *s, i
qoffset, qfactor);
}
-/**
- * Intra DC Prediction
- *
- * @param data coefficients
- */
-static void intra_dc_prediction(DiracContext *s, int16_t *data) {
+static inline int intra_dc_coeff_prediction(DiracContext *s, int16_t *coeff,
+ int x, int y) {
int pred;
- int x, y;
- int16_t *line = data;
-
- for (y = 0; y < subband_height(s, 0); y++) {
- for (x = 0; x < subband_width(s, 0); x++) {
if (x > 0 && y > 0) {
- pred = (line[x - 1]
- + line[x - s->padded_width]
- + line[x - s->padded_width - 1]);
+ pred = (coeff[-1]
+ + coeff[-s->padded_width]
+ + coeff[-s->padded_width - 1]);
if (pred > 0)
pred = (pred + 1) / 3;
else /* XXX: For now just do what the reference
@@ -971,13 +962,27 @@ static void intra_dc_prediction(DiracCon
pred = -((-pred)+1)/3;
} else if (x > 0) {
/* Just use the coefficient left of this one. */
- pred = data[x - 1];
+ pred = coeff[-1];
} else if (y > 0)
- pred = line[-s->padded_width];
+ pred = coeff[-s->padded_width];
else
pred = 0;
- line[x] += pred;
+ return pred;
+}
+
+/**
+ * Intra DC Prediction
+ *
+ * @param data coefficients
+ */
+static void intra_dc_prediction(DiracContext *s, int16_t *data) {
+ int x, y;
+ int16_t *line = data;
+
+ for (y = 0; y < subband_height(s, 0); y++) {
+ for (x = 0; x < subband_width(s, 0); x++) {
+ line[x] += intra_dc_coeff_prediction(s, &line[x], x, y);
}
line += s->padded_width;
}
@@ -3311,6 +3316,157 @@ static void dirac_encode_access_unit_hea
dirac_encode_source_parameters(s);
}
+
+
+static void encode_coeff(DiracContext *s, uint16_t *coeffs, int level,
+ int orientation, int x, int y) {
+ int parent = 0;
+ int nhood;
+ int idx;
+ int coeff;
+ int xpos, ypos;
+ struct dirac_arith_context_set *context;
+ uint16_t *coeffp;
+
+ xpos = coeff_posx(s, level, orientation, x);
+ ypos = coeff_posy(s, level, orientation, y);
+
+ coeffp = &coeffs[xpos + ypos * s->padded_width];
+ coeff = *coeffp;
+
+ /* The value of the pixel belonging to the lower level. */
+ if (level >= 2) {
+ int px = coeff_posx(s, level - 1, orientation, x >> 1);
+ int py = coeff_posy(s, level - 1, orientation, y >> 1);
+ parent = coeffs[s->padded_width * py + px] != 0;
+ }
+
+ /* Determine if the pixel has only zeros in its neighbourhood. */
+ nhood = zero_neighbourhood(s, coeffp, y, x);
+
+ /* Calculate an index into context_sets_waveletcoeff. */
+ idx = parent * 6 + (!nhood) * 3;
+ idx += sign_predict(s, coeffp, orientation, y, x);
+
+ context = &context_sets_waveletcoeff[idx];
+
+ /* XXX: Quantization. */
+
+ /* Write out the coefficient. */
+ dirac_arith_write_int(&s->arith, context, coeff);
+}
+
+static void encode_codeblock(DiracContext *s, uint16_t *coeffs, int level,
+ int orientation, int xpos, int ypos) {
+ int blockcnt_one = (s->codeblocksh[level] + s->codeblocksv[level]) == 2;
+ int left, right, top, bottom;
+ int x, y;
+
+ left = (subband_width(s, level) * xpos ) / s->codeblocksh[level];
+ right = (subband_width(s, level) * (xpos + 1)) / s->codeblocksh[level];
+ top = (subband_height(s, level) * ypos ) / s->codeblocksv[level];
+ bottom = (subband_height(s, level) * (ypos + 1)) / s->codeblocksv[level];
+
+ if (!blockcnt_one) {
+ /* XXX: Check if this is a zero codeblock. For now just
+ encode like it isn't. */
+ dirac_arith_put_bit(&s->arith, ARITH_CONTEXT_ZERO_BLOCK, 0);
+ }
+
+ for (y = top; y < bottom; y++)
+ for (x = left; x < right; x++)
+ encode_coeff(s, coeffs, level, orientation, y, x);
+}
+
+static void intra_dc_coding(DiracContext *s, int16_t *coeffs) {
+ int x, y;
+ int16_t *line = coeffs + (subband_height(s, 0) - 1) * s->padded_width;
+
+ /* Just do the inverse of intra_dc_prediction. Start at the right
+ bottom corner and remove the predicted value from the
+ coefficient, the decoder can easily reconstruct this. */
+
+ for (y = subband_height(s, 0); y > 0; y--) {
+ for (x = subband_width(s, 0); x > 0; x--) {
+ line[x] -= intra_dc_coeff_prediction(s, &line[x], x, y);
+ }
+ line -= s->padded_width;
+ }
+}
+
+static int encode_subband(DiracContext *s, int level,
+ int orientation, uint16_t *coeffs) {
+ int xpos, ypos;
+ /* Encode the data. */
+
+ if (s->refs == 0 && level == 0)
+ intra_dc_coding(s, coeffs);
+
+ for (ypos = 0; ypos < s->codeblocksv[level]; ypos++)
+ for (xpos = 0; xpos < s->codeblocksh[level]; xpos++)
+ encode_codeblock(s, coeffs, level, orientation, xpos, ypos);
+
+
+ /* XXX: Write length. */
+
+ /* XXX: Write quantizer index. */
+
+ /* XXX: Write out encoded data. */
+
+ return 0;
+}
+
+static int dirac_encode_component(DiracContext *s, int comp) {
+ int level;
+ subband_t subband;
+ int16_t *coeffs;
+
+ /* XXX: Initialize coeffs here with DWT coefficients. */
+
+ encode_subband(s, 0, subband_ll, coeffs);
+ for (level = 0; level < 4; level++) {
+ for (subband = 1; subband < subband_hh; subband++) {
+ encode_subband(s, level, subband, coeffs);
+ }
+ }
+
+ return 0;
+}
+
+static int dirac_encode_frame(DiracContext *s) {
+ PutBitContext *pb = &s->pb;
+ int comp;
+
+ /* Write picture header. */
+ put_bits(pb, 32, s->avctx->frame_number);
+
+ /* XXX: Write reference frames. */
+
+ /* XXX: Write retire pictures list. */
+
+
+ /* Wavelet transform parameters. */
+
+ /* Override default filter. */
+ put_bits(pb, 1, 1);
+
+ /* Set hte default filter to Haar. */
+ dirac_set_ue_golomb(pb, 4);
+
+ /* Do not override the default depth. */
+ put_bits(pb, 1, 0);
+
+ /* Do not override spatial partitioning. */
+ put_bits(pb, 1, 0);
+
+
+ /* Write the transform data. */
+ for (comp = 0; comp < 3; comp++)
+ dirac_encode_component(s, comp);
+
+ return 0;
+}
+
static int encode_frame(AVCodecContext *avctx, unsigned char *buf,
int buf_size, void *data) {
DiracContext *s = avctx->priv_data;
More information about the FFmpeg-soc
mailing list