[FFmpeg-soc] [soc]: r244 - dirac/dirac.c

marco subversion at mplayerhq.hu
Sun Jun 10 16:24:57 CEST 2007


Author: marco
Date: Sun Jun 10 16:24:57 2007
New Revision: 244

Log:
Add initial code for the decoder, this code is far from finished and
has not been cleaned up.  Please do not review it yet.


Added:
   dirac/dirac.c

Added: dirac/dirac.c
==============================================================================
--- (empty file)
+++ dirac/dirac.c	Sun Jun 10 16:24:57 2007
@@ -0,0 +1,658 @@
+/* -*-  indent-tabs-mode:nil; c-basic-offset:4;  -*- */
+/*
+ * Copyright (C) 2007 Marco Gerards <marco at gnu.org>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#define DEBUG 1
+
+#include "avcodec.h"
+#include "dsputil.h"
+#include "bitstream.h"
+#include "golomb.h"
+
+
+/* TODO:
+
+- Compare svq3 golomb to Dirac spec.
+- Compare the CABAC implementation to the Dirac spec
+- Clean things up!!!
+- Make sure the coding style is correct
+- Fill in the missing bits
+
+*/
+
+
+
+typedef struct DiracContext {
+    int access_unit;
+    unsigned int profile;
+    unsigned int level;
+
+    unsigned int luma_width;
+    unsigned int luma_height;
+    unsigned int depth;
+
+    int framerate_numer;
+    int framerate_denom;
+
+    unsigned int clean_width;
+    unsigned int clean_height;
+    unsigned int clean_left_offset;
+    unsigned int clean_right_offset;
+
+    int codeblocksh[7]; /* XXX: 7 levels.  */
+    int codeblocksv[7]; /* XXX: 7 levels.  */
+} DiracContext;
+
+static int decode_init(AVCodecContext *avctx){
+    av_log_set_level (AV_LOG_DEBUG);
+    return 0;
+}
+
+static int decode_end(AVCodecContext *avctx)
+{
+    // DiracContext *s = avctx->priv_data;
+
+    return 0;
+}
+
+
+typedef enum {
+    pc_access_unit_header = 0x00,
+    pc_eos = 0x10,
+    pc_aux_data = 0x20,
+    pc_padding = 0x60,
+    pc_intra_ref = 0x0c
+} parse_code_t;
+
+typedef enum {
+    subband_ll = 0,
+    subband_hl = 1,
+    subband_lh = 2,
+    subband_hh = 3
+} subband_t;
+
+static int dirac_golomb(GetBitContext *gb) {
+    int val = 1;
+    while (! get_bits (gb, 1)) {
+        val <<= 1;
+        if (get_bits (gb, 1))
+            val++;
+    }
+    val--;
+    return val;
+}
+
+static int parse_access_unit_header (AVCodecContext *avctx, GetBitContext *gb) {
+    DiracContext *s = avctx->priv_data;
+    uint32_t version_major;
+    uint32_t version_minor;
+    uint32_t video_format;
+
+    /* Parse parameters.  */
+
+    /* XXX: Picture number of next frame.  */
+    skip_bits_long(gb, 32);
+    version_major = dirac_golomb(gb);
+    version_minor = dirac_golomb(gb);
+    s->profile = dirac_golomb(gb);
+    s->level = dirac_golomb(gb);
+    /* XXX: Check the version (0.6).  The current Dirac encoders don't
+       set this value properly anyways.  */
+    dprintf (avctx, "Access unit header: Version %d.%d\n", version_major, version_minor);
+    dprintf (avctx, "Profile: %d, Level: %d\n", s->profile, s->level);
+
+    /* Sequence parameters.  */
+    video_format = dirac_golomb(gb);
+    dprintf (avctx, "Video format: %d\n", video_format);
+
+    /* XXX: Fill in defaults.  */
+
+    /* Set custom dimensions.  */
+    if (get_bits(gb, 1)) {
+        s->luma_width = dirac_golomb(gb);
+        s->luma_height = dirac_golomb(gb);
+    }
+
+    /* Set chroma format.  */
+    if (get_bits(gb, 1)) {
+        int idx = dirac_golomb(gb);
+        dprintf (avctx, "Chroma index: %d\n", idx);
+        /* XXX: Set chroma dimensions by scaling luma dimensions.  */
+
+    }
+
+    if (get_bits(gb, 1)) {
+        s->depth = dirac_golomb(gb);
+        dprintf (avctx, "override depth: %d\n", s->depth);
+    }
+
+    dprintf(avctx, "Video mode: %dx%d@%d\n", s->luma_width, s->luma_height, s->depth);
+
+    /* Access Unit Source parameters.  */
+
+    if (get_bits(gb, 1)) {
+        /* Interlace.  */
+        dprintf(avctx, "Interlace!\n");
+        /* XXX: Currently not supported */
+    }
+
+    /* Framerate.  */
+    if (get_bits(gb, 1)) {
+        int idx = dirac_golomb(gb);
+        if (! idx) {
+            s->framerate_numer = dirac_golomb(gb);//svq3_get_ue_golomb(gb);
+            s->framerate_denom = dirac_golomb(gb);//svq3_get_ue_golomb(gb);
+            dprintf (avctx, "Framerate index: %d/%d = %f\n",
+                     s->framerate_numer, s->framerate_denom,
+                     (double) s->framerate_numer / s->framerate_denom);
+
+        }
+        /* XXX: else use presets from Appendix E.  */
+    }
+    /* Clean area.  */
+    if (get_bits(gb, 1)) {
+        s->clean_width = dirac_golomb(gb);
+        s->clean_height = dirac_golomb(gb);
+        s->clean_left_offset = dirac_golomb(gb);
+        s->clean_right_offset = dirac_golomb(gb);
+        dprintf (avctx, "Clean area %dx%d %d:%d\n", s->clean_width, s->clean_height,
+                 s->clean_left_offset, s->clean_right_offset);
+    }
+
+    /* Signal range.  */
+    if (get_bits(gb, 1)) {
+        dprintf(avctx, "Signal range flag\n");
+    }
+
+    /* Color spec.  */
+    if (get_bits(gb, 1)) {
+        int idx = dirac_golomb(gb);
+
+        dprintf(avctx, "Color specification flag\n");
+        dprintf (avctx, "Color spec idx: %d\n", idx);
+        /* XXX: preset */
+
+        if (idx == 0) {
+            /* Color primaries.  */
+            if (get_bits(gb, 1)) {
+                dprintf(avctx, "Color primaries flag\n");
+            }
+
+            /* Transfer function.  */
+            if (get_bits(gb, 1)) {
+                dprintf(avctx, "Transfer function flag\n");
+            }
+        }
+    }
+
+    dprintf (avctx, "Header read!\n");
+
+    return 0;
+}
+
+/* Arithmetic decoding.  XXX: Based on the pseudocode from the spec,
+   use ffmpeg code or integrate this properly into ffmpeg if nothing
+   is there.  */
+
+/* XXX: Ugly and will be cleaned up.  Move into DiracContext.  */
+static int arith_low;
+static int arith_range;
+static int arith_code;
+static int arith_bits_left;
+
+enum arith_context_indices {
+    ARITH_CONTEXT_SIGN_ZERO,
+    ARITH_CONTEXT_SIGN_POS,
+    ARITH_CONTEXT_SIGN_NEG,
+    ARITH_CONTEXT_ZPZN_F1,
+    ARITH_CONTEXT_ZPNN_F1,
+    ARITH_CONTEXT_ZP_F2,
+    ARITH_CONTEXT_ZP_F3,
+    ARITH_CONTEXT_ZP_F4,
+    ARITH_CONTEXT_ZP_F5,
+    ARITH_CONTEXT_ZP_F6,
+    ARITH_CONTEXT_NPZN_F1,
+    ARITH_CONTEXT_NPNN_F1,
+    ARITH_CONTEXT_NP_F2,
+    ARITH_CONTEXT_NP_F3,
+    ARITH_CONTEXT_NP_F4,
+    ARITH_CONTEXT_NP_F5,
+    ARITH_CONTEXT_NP_F6,
+    ARITH_CONTEXT_COEFF_DATA,
+    ARITH_CONTEXT_ZERO_BLOCK,
+    ARITH_CONTEXT_Q_OFFSET_FOLLOW,
+    ARITH_CONTEXT_Q_OFFSET_DATA,
+    ARITH_CONTEXT_Q_OFFSET_SIGN,
+
+    ARITH_CONTEXT_SB_F1,
+    ARITH_CONTEXT_SB_F2,
+    ARITH_CONTEXT_SB_DATA,
+    ARITH_CONTEXT_PMODE_REF1,
+    ARITH_CONTEXT_PMODE_REF2,
+    ARITH_CONTEXT_GLOBAL_BLOCK,
+    ARITH_CONTEXT_VECTOR_F1,
+    ARITH_CONTEXT_VECTOR_F2,
+    ARITH_CONTEXT_VECTOR_F3,
+    ARITH_CONTEXT_VECTOR_F4,
+    ARITH_CONTEXT_VECTOR_F5,
+    ARITH_CONTEXT_VECTOR_DATA,
+    ARITH_CONTEXT_VECTOR_SIGN,
+    ARITH_CONTEXT_DC_F1,
+    ARITH_CONTEXT_DC_F2,
+    ARITH_CONTEXT_DC_DATA,
+    ARITH_CONTEXT_DC_SIGN
+};
+
+#define ARITH_CONTEXT_COUNT (ARITH_CONTEXT_DC_SIGN + 1)
+
+/* XXX: Check the spec again on this.  */
+typedef int arith_context_t[1];
+static arith_context_t arith_contexts[ARITH_CONTEXT_COUNT];
+
+static void arith_init (GetBitContext *gb, int length) {
+    int i;
+
+    arith_bits_left = 8 * length;
+    arith_low = 0;
+    arith_range = 0x10000;
+    arith_code = get_bits_long(gb, 15);
+
+    /* Initialize contexts.  */
+    for (i = 0; i < ARITH_CONTEXT_COUNT; i++) {
+        arith_contexts[i][1] = 0x8000;
+    }
+}
+
+static void arith_renormalize (GetBitContext *gb) {
+    if ((arith_low + arith_range - 1) && arith_low >= 0x8000) {
+        arith_code &= 0x4000;
+        arith_low &= 0x4000;
+    }
+    arith_low <<= 1;
+    arith_range <<= 1;
+    arith_low &= 0xFFFF;
+    arith_code <<= 1;
+    if (arith_bits_left > 0) {
+        arith_code += get_bits (gb, 1);
+        arith_bits_left--;
+    }
+    arith_code &= 0xffff;
+}
+
+static int arith_lookup[256] = {
+    0, 2, 5, 8, 11, 15, 20, 24,
+    29, 35, 41, 47, 53, 60, 67, 74,
+    82, 89, 97, 106, 114, 123, 132, 141,
+    150, 160, 170, 180, 190, 201, 211, 222,
+    233, 244, 256, 267, 279, 291, 303, 315,
+    327, 340, 353, 366, 379, 392, 405, 419,
+    433, 447, 461, 475, 489, 504, 518, 533,
+    548, 563, 578, 593, 609, 624, 640, 656,
+    672, 688, 705, 721, 738, 754, 771, 788,
+    805, 822, 840, 857, 875, 892, 910, 928,
+    946, 964, 983, 1001, 1020, 1038, 1057, 1076,
+    1095, 1114, 1133, 1153, 1172, 1192, 1211, 1231,
+    1251, 1271, 1291, 1311, 1332, 1352, 1373, 1393,
+    1414, 1435, 1456, 1477, 1498, 1520, 1541, 1562,
+    1584, 1606, 1628, 1649, 1671, 1694, 1716, 1738,
+    1760, 1783, 1806, 1828, 1851, 1874, 1897, 1920,
+    1935, 1942, 1949, 1955, 1961, 1968, 1974, 1980,
+    1985, 1991, 1996, 2001, 2006, 2011, 2016, 2021,
+    2025, 2029, 2033, 2037, 2040, 2044, 2047, 2050,
+    2053, 2056, 2058, 2061, 2063, 2065, 2066, 2068,
+    2069, 2070, 2071, 2072, 2072, 2072, 2072, 2072,
+    2072, 2071, 2070, 2069, 2068, 2066, 2065, 2063,
+    2060, 2058, 2055, 2052, 2049, 2045, 2042, 2038,
+    2033, 2029, 2024, 2019, 2013, 2008, 2002, 1996,
+    1989, 1982, 1975, 1968, 1960, 1952, 1943, 1934,
+    1925, 1916, 1906, 1896, 1885, 1874, 1863, 1851,
+    1839, 1827, 1814, 1800, 1786, 1772, 1757, 1742,
+    1727, 1710, 1694, 1676, 1659, 1640, 1622, 1602,
+    1582, 1561, 1540, 1518, 1495, 1471, 1447, 1422,
+    1396, 1369, 1341, 1312, 1282, 1251, 1219, 1186,
+    1151, 1114, 1077, 1037,  995, 952, 906, 857,
+    805, 750,   690,  625,  553, 471, 376, 255
+};
+
+static int arith_get_bit (GetBitContext *gb, int context) {
+    int prob_zero = arith_contexts[context][1];
+    int count;
+    int range_times_prob;
+    int ret;
+
+    count = arith_code - arith_low;
+    range_times_prob = (arith_range * prob_zero) >> 16;
+    if (count >= range_times_prob) {
+        ret = 1;
+        arith_low += range_times_prob;
+        arith_range -= range_times_prob;
+    } else {
+        ret = 0;
+        arith_range = range_times_prob;
+    }
+
+    /* Update contexts. */
+    if (ret)
+        arith_contexts[context][1] -= arith_lookup[arith_contexts[context][1] >> 8];
+    else
+        arith_contexts[context][1] -= arith_lookup[255 - (arith_contexts[context][1] >> 8)];
+
+    while (arith_range <= 0x4000)
+        arith_renormalize (gb);
+    return ret;
+}
+
+struct context_set {
+    int follow[16]; /* XXX */
+    int follow_length;
+    int data;
+    int sign;
+};
+
+struct context_set context_sets_waveletcoeff[12] = {
+    {
+        /* Parent = 0, Zero neighbourhood, sign predict 0 */
+        .follow = { ARITH_CONTEXT_ZPZN_F1, ARITH_CONTEXT_ZP_F2,
+                    ARITH_CONTEXT_ZP_F3, ARITH_CONTEXT_ZP_F4,
+                    ARITH_CONTEXT_ZP_F5, ARITH_CONTEXT_ZP_F6, 0 },
+        .follow_length = 6,
+        .data = ARITH_CONTEXT_COEFF_DATA,
+        .sign = ARITH_CONTEXT_SIGN_ZERO,
+    }, {
+        /* Parent = 0, Zero neighbourhood, sign predict < 0 */
+        .follow = { ARITH_CONTEXT_ZPZN_F1, ARITH_CONTEXT_ZP_F2,
+                    ARITH_CONTEXT_ZP_F3, ARITH_CONTEXT_ZP_F4,
+                    ARITH_CONTEXT_ZP_F5, ARITH_CONTEXT_ZP_F6 },
+        .follow_length = 6,
+        .data = ARITH_CONTEXT_COEFF_DATA,
+        .sign = ARITH_CONTEXT_SIGN_NEG
+    }, {
+        /* Parent = 0, Zero neighbourhood, sign predict > 0 */
+        .follow = { ARITH_CONTEXT_ZPZN_F1, ARITH_CONTEXT_ZP_F2,
+                    ARITH_CONTEXT_ZP_F3, ARITH_CONTEXT_ZP_F4,
+                    ARITH_CONTEXT_ZP_F5, ARITH_CONTEXT_ZP_F6 },
+        .follow_length = 6,
+        .data = ARITH_CONTEXT_COEFF_DATA,
+        .sign = ARITH_CONTEXT_SIGN_POS
+    },
+
+    {
+        /* Parent = 0, No Zero neighbourhood, sign predict  0 */
+        .follow = { ARITH_CONTEXT_ZPNN_F1, ARITH_CONTEXT_ZP_F2,
+                    ARITH_CONTEXT_ZP_F3, ARITH_CONTEXT_ZP_F4,
+                    ARITH_CONTEXT_ZP_F5, ARITH_CONTEXT_ZP_F6 },
+        .follow_length = 6,
+        .data = ARITH_CONTEXT_COEFF_DATA,
+        .sign = ARITH_CONTEXT_SIGN_ZERO
+    }, {
+        /* Parent = 0, No Zero neighbourhood, sign predict < 0 */
+        .follow = { ARITH_CONTEXT_ZPNN_F1, ARITH_CONTEXT_ZP_F2,
+                    ARITH_CONTEXT_ZP_F3, ARITH_CONTEXT_ZP_F4,
+                    ARITH_CONTEXT_ZP_F5, ARITH_CONTEXT_ZP_F6 },
+        .follow_length = 6,
+        .data = ARITH_CONTEXT_COEFF_DATA,
+        .sign = ARITH_CONTEXT_SIGN_NEG
+    }, {
+        /* Parent = 0, No Zero neighbourhood, sign predict > 0 */
+        .follow = { ARITH_CONTEXT_ZPNN_F1, ARITH_CONTEXT_ZP_F2,
+                    ARITH_CONTEXT_ZP_F3, ARITH_CONTEXT_ZP_F4,
+                    ARITH_CONTEXT_ZP_F5, ARITH_CONTEXT_ZP_F6 },
+        .follow_length = 6,
+        .data = ARITH_CONTEXT_COEFF_DATA,
+        .sign = ARITH_CONTEXT_SIGN_POS
+    },
+
+    {
+        /* Parent != 0, Zero neighbourhood, sign predict 0 */
+        .follow = { ARITH_CONTEXT_NPZN_F1, ARITH_CONTEXT_NP_F2,
+                    ARITH_CONTEXT_NP_F3, ARITH_CONTEXT_NP_F4,
+                    ARITH_CONTEXT_NP_F5, ARITH_CONTEXT_NP_F6 },
+        .follow_length = 6,
+        .data = ARITH_CONTEXT_COEFF_DATA,
+        .sign = ARITH_CONTEXT_SIGN_ZERO
+    }, {
+        /* Parent != 0, Zero neighbourhood, sign predict < 0 */
+        .follow = { ARITH_CONTEXT_NPZN_F1, ARITH_CONTEXT_NP_F2,
+                    ARITH_CONTEXT_NP_F3, ARITH_CONTEXT_NP_F4,
+                    ARITH_CONTEXT_NP_F5, ARITH_CONTEXT_NP_F6 },
+        .follow_length = 6,
+        .data = ARITH_CONTEXT_COEFF_DATA,
+        .sign = ARITH_CONTEXT_SIGN_NEG
+    }, {
+        /* Parent != 0, Zero neighbourhood, sign predict > 0 */
+        .follow = { ARITH_CONTEXT_NPZN_F1, ARITH_CONTEXT_NP_F2,
+                    ARITH_CONTEXT_NP_F3, ARITH_CONTEXT_NP_F4,
+                    ARITH_CONTEXT_NP_F5, ARITH_CONTEXT_NP_F6 },
+        .follow_length = 6,
+        .data = ARITH_CONTEXT_COEFF_DATA,
+        .sign = ARITH_CONTEXT_SIGN_POS
+    },
+
+
+    {
+        /* Parent != 0, No Zero neighbourhood, sign predict 0 */
+        .follow = { ARITH_CONTEXT_NPNN_F1, ARITH_CONTEXT_NP_F2,
+                    ARITH_CONTEXT_NP_F3, ARITH_CONTEXT_NP_F4,
+                    ARITH_CONTEXT_NP_F5, ARITH_CONTEXT_NP_F6 },
+        .follow_length = 6,
+        .data = ARITH_CONTEXT_COEFF_DATA,
+        .sign = ARITH_CONTEXT_SIGN_ZERO
+    }, {
+        /* Parent != 0, No Zero neighbourhood, sign predict < 0 */
+        .follow = { ARITH_CONTEXT_NPNN_F1, ARITH_CONTEXT_NP_F2,
+                    ARITH_CONTEXT_NP_F3, ARITH_CONTEXT_NP_F4,
+                    ARITH_CONTEXT_NP_F5, ARITH_CONTEXT_NP_F6 },
+        .follow_length = 6,
+        .data = ARITH_CONTEXT_COEFF_DATA,
+        .sign = ARITH_CONTEXT_SIGN_NEG
+    }, {
+        /* Parent != 0, No Zero neighbourhood, sign predict > 0 */
+        .follow = { ARITH_CONTEXT_NPNN_F1, ARITH_CONTEXT_NP_F2,
+                    ARITH_CONTEXT_NP_F3, ARITH_CONTEXT_NP_F4,
+                    ARITH_CONTEXT_NP_F5, ARITH_CONTEXT_NP_F6 },
+        .follow_length = 6,
+        .data = ARITH_CONTEXT_COEFF_DATA,
+        .sign = ARITH_CONTEXT_SIGN_POS
+    }
+};
+
+static int follow_context (int index, struct context_set *context_set) {
+    int pos;
+    pos = (index < context_set->follow_length ? index
+           : context_set->follow_length) - 1;
+    return context_set->follow[pos];
+}
+
+static int arith_read_uint (GetBitContext *gb, struct context_set *context_set) {
+    int ret = 1;
+    int index = 0;
+
+    while (arith_get_bit (gb, follow_context(index, context_set)) == 0) {
+        ret <<= 1;
+        if (arith_get_bit (gb, context_set->data))
+            ret++;
+        index++;
+    }
+    ret--;
+    return ret;
+}
+
+static int arith_read_int (GetBitContext *gb, struct context_set *context_set) {
+    int ret = arith_read_uint (gb, context_set);
+    if (ret != 0 && arith_get_bit(gb, context_set->sign))
+        ret = -ret;
+    return ret;
+}
+
+static void arith_flush(GetBitContext *gb) {
+    skip_bits_long(gb, arith_bits_left);
+    arith_bits_left = 0;
+}
+
+static void codeblock (AVCodecContext *avctx, GetBitContext *gb, int level, int x, int y) {
+    DiracContext *s = avctx->priv_data;
+    int blockcnt = s->codeblocksh[level] * s->codeblocksv[level];
+    int zero = 0;
+
+    if (blockcnt != 1) {
+        /* Determine if this codeblock is a zero block.  */
+        zero = arith_get_bit(gb, ARITH_CONTEXT_ZERO_BLOCK);
+    }
+
+    if (zero)
+        return; /* All coefficients remain 0.  */
+
+    /* XXX: Quantization.  */
+}
+
+static int subband (AVCodecContext *avctx, GetBitContext *gb, int level, subband_t band) {
+    DiracContext *s = avctx->priv_data;
+    int length;
+    int quant;
+    int x, y;
+
+    length = dirac_golomb(gb);
+    if (! length)
+        {
+            align_get_bits(gb);
+            dprintf (avctx, "Zero subband\n");
+
+            return 0;
+        } else {
+            quant = dirac_golomb(gb);
+            dprintf (avctx, "Length: %d, quant: %d\n", length, quant);
+
+            arith_init(gb, length);
+
+            for (y = 0; y < s->codeblocksv[level]; y++)
+                for (x = 0; x < s->codeblocksh[level]; x++)
+                    codeblock(avctx, gb, level, x, y);
+            arith_flush(gb);
+        }
+
+    return 0;
+}
+
+
+static int decode_intra_frame(AVCodecContext *avctx, GetBitContext *gb,
+                              void *data, int *data_size) {
+    DiracContext *s = avctx->priv_data;
+    int picnum;
+    int retire;
+    int i;
+
+    picnum = get_bits_long(gb, 32);
+    retire = dirac_golomb(gb);
+
+    dprintf (avctx, "Picture #%d, retire: %d\n", picnum, retire);
+
+    align_get_bits(gb);
+
+    /* Wavelet transform data.  */
+    /* XXX: Skip all interframe stuff for now.  */
+
+    /* Wavelet transform parameters.  */
+    if (get_bits(gb, 1)) {
+        dprintf (avctx, "Non default filter\n");
+    } else {
+        dprintf (avctx, "Default filter, select (9, 3) for intra frame\n");
+    }
+
+    /* Wavelet depth.  */
+    if (get_bits(gb, 1)) {
+        dprintf (avctx, "Non default depth\n");
+    }
+    /* XXX: What's the default depth?  reference implementation: 4 */
+
+    /* Spatial partitioning.  */
+    if (get_bits(gb, 1)) {
+        int idx;
+
+        dprintf (avctx, "Spatial partitioning\n");
+
+        if (get_bits(gb, 1)) {
+            dprintf (avctx, "Non-default partitioning\n");
+        } else {
+            /* Set defaults for the codeblocks.  */
+            for (i = 0; i <= s->level; i++) {
+                s->codeblocksv[i] = i <= 2 ? 1 : 4;
+                s->codeblocksh[i] = i <= 2 ? 1 : 3;
+            }
+        }
+
+        idx = dirac_golomb(gb);
+        dprintf(avctx, "Codeblock mode idx: %d\n", idx);
+        /* XXX: Here 0, so single quant.  */
+    }
+
+    /* Coefficient unpacking.  */
+
+    /* Unpack LL, level 0.  */
+    subband (avctx, gb, 0, subband_ll);
+
+    return 0;
+}
+
+
+static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size){
+    DiracContext *s = avctx->priv_data;
+    GetBitContext gb;
+
+    int parse_code = buf[4];
+    dprintf (avctx, "Decoding frame: size=%d head=%c%c%c%c parse=%02x\n", buf_size, buf[0], buf[1], buf[2], buf[3], buf[4]);
+
+    init_get_bits(&gb, &buf[13], (buf_size - 13) * 8);
+
+    switch (parse_code) {
+    case pc_access_unit_header:
+        return parse_access_unit_header (avctx, &gb);
+    case pc_intra_ref:
+        return decode_intra_frame(avctx, &gb, data, data_size);
+    }
+
+    *data_size = 0;
+    return buf_size;
+}
+
+
+AVCodec dirac_decoder = {
+    "dirac",
+    CODEC_TYPE_VIDEO,
+    CODEC_ID_DIRAC,
+    sizeof(DiracContext),
+    decode_init,
+    NULL,
+    decode_end,
+    decode_frame,
+    0,
+    NULL
+};
+
+/* #ifdef CONFIG_ENCODERS */
+/* AVCodec dirac_encoder = { */
+/*     "dirac", */
+/*     CODEC_TYPE_VIDEO, */
+/*     CODEC_ID_DIRAC, */
+/*     sizeof(DiracContext), */
+/*     NULL, */
+/*     NULL, */
+/*     NULL, */
+/* }; */
+/* #endif */



More information about the FFmpeg-soc mailing list