[FFmpeg-soc] [soc]: r1305 - dirac/libavcodec/dirac.c
marco
subversion at mplayerhq.hu
Sun Sep 9 11:56:05 CEST 2007
Author: marco
Date: Sun Sep 9 11:56:05 2007
New Revision: 1305
Log:
Pack ME data
Modified:
dirac/libavcodec/dirac.c
Modified: dirac/libavcodec/dirac.c
==============================================================================
--- dirac/libavcodec/dirac.c (original)
+++ dirac/libavcodec/dirac.c Sun Sep 9 11:56:05 2007
@@ -3284,6 +3284,259 @@ static int dirac_encode_component(DiracC
return 0;
}
+
+static void blockmode_encode(DiracContext *s, int x, int y) {
+ int res = s->blmotion[y * s->blwidth + x].use_ref & DIRAC_REF_MASK_REF1;
+ res ^= mode_prediction(s, x, y, DIRAC_REF_MASK_REF1, 0);
+ dirac_arith_put_bit(&s->arith, ARITH_CONTEXT_PMODE_REF2, res);
+
+ if (s->refs == 2) {
+ res = (s->blmotion[y * s->blwidth + x].use_ref
+ & DIRAC_REF_MASK_REF2) >> 1;
+ res ^= mode_prediction(s, x, y, DIRAC_REF_MASK_REF2, 1);
+ dirac_arith_put_bit(&s->arith, ARITH_CONTEXT_PMODE_REF2, res);
+ }
+}
+
+static void blockglob_encode(DiracContext *s, int x, int y) {
+ /* Global motion compensation is not used at all. */
+ if (!s->globalmc_flag)
+ return;
+
+ /* Global motion compensation is not used for this block. */
+ if (s->blmotion[y * s->blwidth + x].use_ref & 3) {
+ int res = (s->blmotion[y * s->blwidth + x].use_ref
+ & DIRAC_REF_MASK_GLOBAL) >> 2;
+ res ^= mode_prediction(s, x, y, DIRAC_REF_MASK_GLOBAL, 2);
+ dirac_arith_put_bit(&s->arith, ARITH_CONTEXT_GLOBAL_BLOCK, res);
+ }
+}
+
+static void dirac_pack_motion_vector(DiracContext *s,
+ int ref, int dir,
+ int x, int y) {
+ int res;
+ const int refmask = (ref + 1) | DIRAC_REF_MASK_GLOBAL;
+
+ /* First determine if for this block in the specific reference
+ frame a motion vector is required. */
+ if ((s->blmotion[y * s->blwidth + x].use_ref & refmask) != ref + 1)
+ return;
+
+ res = s->blmotion[y * s->blwidth + x].vect[ref][dir];
+ res -= motion_vector_prediction(s, x, y, ref, dir);
+ dirac_arith_write_int(&s->arith, &context_set_mv, res);
+}
+
+static void dirac_pack_motion_vectors(DiracContext *s,
+ int ref, int dir) {
+ PutBitContext pb;
+ char *buf;
+ unsigned int length;
+ int x, y;
+
+ init_put_bits(&pb, s->encodebuf, (1 << 20) * 8);
+ dirac_arith_coder_init(&s->arith, &pb);
+ for (y = 0; y < s->sbheight; y++)
+ for (x = 0; x < s->sbwidth; x++) {
+ int q, p;
+ int blkcnt = 1 << s->sbsplit[y * s->sbwidth + x];
+ int step = 4 >> s->sbsplit[y * s->sbwidth + x];
+
+ for (q = 0; q < blkcnt; q++)
+ for (p = 0; p < blkcnt; p++) {
+ dirac_pack_motion_vector(s, ref, dir,
+ 4 * x + p * step,
+ 4 * y + q * step);
+ }
+ }
+ /* XXX: Put this in a function. */
+ dirac_arith_coder_flush(&s->arith);
+ flush_put_bits(&pb);
+ length = put_bits_count(&pb) / 8;
+ dirac_set_ue_golomb(&s->pb, length);
+ align_put_bits(&s->pb);
+ /* XXX: Use memmove. */
+ flush_put_bits(&s->pb);
+ buf = pbBufPtr(&s->pb);
+ memcpy(buf, s->encodebuf, length);
+ skip_put_bytes(&s->pb, length);
+}
+
+static void pack_block_dc(DiracContext *s, int x, int y, int comp) {
+ int res;
+
+ if (s->blmotion[y * s->blwidth + x].use_ref & 3)
+ return;
+
+ res = s->blmotion[y * s->blwidth + x].dc[comp];
+ res -= block_dc_prediction(s, x, y, comp);
+ dirac_arith_write_int(&s->arith, &context_set_dc, res);
+}
+
+static int dirac_encode_blockdata(DiracContext *s) {
+ int i;
+ unsigned int length;
+ int comp;
+ int x, y;
+ PutBitContext pb;
+ char *buf;
+
+#define DIVRNDUP(a, b) ((a + b - 1) / b)
+
+ s->sbwidth = DIVRNDUP(s->sequence.luma_width,
+ (s->frame_decoding.luma_xbsep << 2));
+ s->sbheight = DIVRNDUP(s->sequence.luma_height,
+ (s->frame_decoding.luma_ybsep << 2));
+ s->blwidth = s->sbwidth << 2;
+ s->blheight = s->sbheight << 2;
+
+ /* XXX: This should be done before calling this function, but for
+ now it is more convenient to do this here. */
+ s->sbsplit = av_mallocz(s->sbwidth * s->sbheight * sizeof(int));
+ if (!s->sbsplit) {
+ av_log(s->avctx, AV_LOG_ERROR, "avcodec_check_dimensions() failed\n");
+ return -1;
+ }
+
+ s->blmotion = av_mallocz(s->blwidth * s->blheight * sizeof(*s->blmotion));
+ if (!s->blmotion) {
+ av_freep(&s->sbsplit);
+ av_log(s->avctx, AV_LOG_ERROR, "avcodec_check_dimensions() failed\n");
+ return -1;
+ }
+
+ /* XXX: Fill the Motion Vectors with semi-random data for
+ testing. */
+
+ /* Superblock splitmodes. XXX: Just (for now) encode "2", so that
+ blocks are not split at all. */
+ init_put_bits(&pb, s->encodebuf, (1 << 20) * 8);
+ dirac_arith_coder_init(&s->arith, &pb);
+ for (y = 0; y < s->sbheight; y++)
+ for (x = 0; x < s->sbwidth; x++) {
+ int res;
+ s->sbsplit[y * s->sbwidth + x] = 2;
+ res = s->sbsplit[y * s->sbwidth + x] - split_prediction(s, x, y);
+
+ /* This should be unsigned, because this is under modulo
+ 3, it is ok to add 3. */
+ if (res < 0)
+ res += 3;
+
+ dirac_arith_write_int(&s->arith, &context_set_split, res);
+ }
+ /* XXX: Put this in a function. */
+ dirac_arith_coder_flush(&s->arith);
+ flush_put_bits(&pb);
+ length = put_bits_count(&pb) / 8;
+ dirac_set_ue_golomb(&s->pb, length);
+ align_put_bits(&s->pb);
+ /* XXX: Use memmove. */
+ flush_put_bits(&s->pb);
+ buf = pbBufPtr(&s->pb);
+ memcpy(buf, s->encodebuf, length);
+ skip_put_bytes(&s->pb, length);
+
+
+ /* Prediction modes. */
+ init_put_bits(&pb, s->encodebuf, (1 << 20) * 8);
+ dirac_arith_coder_init(&s->arith, &pb);
+ for (y = 0; y < s->sbheight; y++)
+ for (x = 0; x < s->sbwidth; x++) {
+ int q, p;
+ int blkcnt = 1 << s->sbsplit[y * s->sbwidth + x];
+ int step = 4 >> s->sbsplit[y * s->sbwidth + x];
+
+ for (q = 0; q < blkcnt; q++)
+ for (p = 0; p < blkcnt; p++) {
+ blockmode_encode(s,
+ 4 * x + p * step,
+ 4 * y + q * step);
+ blockglob_encode(s,
+ 4 * x + p * step,
+ 4 * y + q * step);
+ }
+ }
+ /* XXX: Put this in a function. */
+ dirac_arith_coder_flush(&s->arith);
+ flush_put_bits(&pb);
+ length = put_bits_count(&pb) / 8;
+ dirac_set_ue_golomb(&s->pb, length);
+ align_put_bits(&s->pb);
+ /* XXX: Use memmove. */
+ flush_put_bits(&s->pb);
+ buf = pbBufPtr(&s->pb);
+ memcpy(buf, s->encodebuf, length);
+ skip_put_bytes(&s->pb, length);
+
+ /* Pack the motion vectors. */
+ for (i = 0; i < s->refs; i++) {
+ dirac_pack_motion_vectors(s, i, 0);
+ dirac_pack_motion_vectors(s, i, 1);
+ }
+
+ /* Unpack the DC values for all the three components (YUV). */
+ for (comp = 0; comp < 3; comp++) {
+ /* Unpack the DC values. */
+ init_put_bits(&pb, s->encodebuf, (1 << 20) * 8);
+ dirac_arith_coder_init(&s->arith, &pb);
+ for (y = 0; y < s->sbheight; y++)
+ for (x = 0; x < s->sbwidth; x++) {
+ int q, p;
+ int blkcnt = 1 << s->sbsplit[y * s->sbwidth + x];
+ int step = 4 >> s->sbsplit[y * s->sbwidth + x];
+
+ for (q = 0; q < blkcnt; q++)
+ for (p = 0; p < blkcnt; p++) {
+ pack_block_dc(s,
+ 4 * x + p * step,
+ 4 * y + q * step,
+ comp);
+ }
+ }
+ /* XXX: Put this in a function. */
+ dirac_arith_coder_flush(&s->arith);
+ flush_put_bits(&pb);
+ length = put_bits_count(&pb) / 8;
+ dirac_set_ue_golomb(&s->pb, length);
+ align_put_bits(&s->pb);
+ /* XXX: Use memmove. */
+ flush_put_bits(&s->pb);
+ buf = pbBufPtr(&s->pb);
+ memcpy(buf, s->encodebuf, length);
+ skip_put_bytes(&s->pb, length);
+ }
+
+ return 0;
+}
+
+static int dirac_encode_predparams(DiracContext *s) {
+ PutBitContext *pb = &s->pb;
+
+ /* Use default block parameters. */
+ put_bits(pb, 1, 0);
+
+ /* Motion vector precision: Use qpel interpolation (2 bits
+ precision) for now. */
+ put_bits(pb, 1, 1);
+ dirac_set_ue_golomb(pb, 2);
+
+ /* Do not use Global Motion Estimation. */
+ put_bits(pb, 1, 0);
+
+ /* Do not encode the picture prediction mode, this is not yet
+ used. */
+ put_bits(pb, 1, 0);
+
+ /* Use default weights for the reference frames. */
+ put_bits(pb, 1, 0);
+
+
+ return 0;
+}
+
+
static int dirac_encode_frame(DiracContext *s) {
PutBitContext *pb = &s->pb;
int comp;
More information about the FFmpeg-soc
mailing list