[FFmpeg-soc] [soc]: r494 - in dirac: dirac.c dirac_arith.c dirac_arith.h
marco
subversion at mplayerhq.hu
Fri Jul 20 16:04:37 CEST 2007
Author: marco
Date: Fri Jul 20 16:04:36 2007
New Revision: 494
Log:
Move arithmetic decoding to a separate file.
Added:
dirac/dirac_arith.c
dirac/dirac_arith.h
Modified:
dirac/dirac.c
Modified: dirac/dirac.c
==============================================================================
--- dirac/dirac.c (original)
+++ dirac/dirac.c Fri Jul 20 16:04:36 2007
@@ -25,6 +25,7 @@
#include "dsputil.h"
#include "bitstream.h"
#include "golomb.h"
+#include "dirac_arith.h"
typedef enum {
TRANSFER_FUNC_TV,
@@ -191,51 +192,6 @@ static const transfer_func_t preset_tran
static const float preset_kr[3] = { 0.2126, 0.299, 0 /* XXX */ };
static const float preset_kb[3] = {0.0722, 0.114, 0 /* XXX */ };
-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)
-
typedef struct DiracContext {
int next_picture;
int access_unit;
@@ -264,12 +220,8 @@ typedef struct DiracContext {
int padded_width;
int padded_height;
- /* Arithmetic decoding. */
- unsigned int arith_low;
- unsigned int arith_range;
- unsigned int arith_code;
- unsigned int arith_bits_left;
- unsigned int arith_contexts[ARITH_CONTEXT_COUNT];
+ /* State of arithmetic decoding. */
+ struct dirac_arith_state arith;
} DiracContext;
static int decode_init(AVCodecContext *avctx){
@@ -547,118 +499,7 @@ static int parse_access_unit_header(AVCo
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. */
-
-static void arith_init (AVCodecContext *avctx, GetBitContext *gb, int length) {
- DiracContext *s = avctx->priv_data;
- int i;
-
- align_get_bits(gb);
- s->arith_bits_left = 8 * length - 16;
- s->arith_low = 0;
- s->arith_range = 0x10000;
- s->arith_code = get_bits_long(gb, 16);
-
- /* Initialize contexts. */
- for (i = 0; i < ARITH_CONTEXT_COUNT; i++) {
- s->arith_contexts[i] = 0x8000;
- }
-}
-
-static unsigned 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 (AVCodecContext *avctx, int context) {
- DiracContext *s = avctx->priv_data;
- GetBitContext *gb = s->gb;
- unsigned int prob_zero = s->arith_contexts[context];
- unsigned int count;
- unsigned int range_times_prob;
- unsigned int ret;
-
- count = s->arith_code - s->arith_low;
- range_times_prob = (s->arith_range * prob_zero) >> 16;
- if (count >= range_times_prob) {
- ret = 1;
- s->arith_low += range_times_prob;
- s->arith_range -= range_times_prob;
- } else {
- ret = 0;
- s->arith_range = range_times_prob;
- }
-
- /* Update contexts. */
- if (ret)
- s->arith_contexts[context] -= arith_lookup[s->arith_contexts[context] >> 8];
- else
- s->arith_contexts[context] += arith_lookup[255 - (s->arith_contexts[context] >> 8)];
-
- while (s->arith_range <= 0x4000) {
- if (((s->arith_low + s->arith_range - 1)^s->arith_low) >= 0x8000) {
- s->arith_code ^= 0x4000;
- s->arith_low ^= 0x4000;
- }
- s->arith_low <<= 1;
- s->arith_range <<= 1;
- s->arith_low &= 0xFFFF;
- s->arith_code <<= 1;
- if (s->arith_bits_left > 0) {
- s->arith_code |= get_bits (gb, 1);
- s->arith_bits_left--;
- }
- else {
- /* Get default: */
- s->arith_code |= 1;
- }
- s->arith_code &= 0xffff;
- }
-
- return ret;
-}
-
-struct context_set {
- unsigned int follow[6];
- unsigned int follow_length;
- unsigned int data;
- unsigned int sign;
-};
-
-struct context_set context_sets_waveletcoeff[12] = {
+static struct dirac_arith_context_set context_sets_waveletcoeff[12] = {
{
/* Parent = 0, Zero neighbourhood, sign predict 0 */
.follow = { ARITH_CONTEXT_ZPZN_F1, ARITH_CONTEXT_ZP_F2,
@@ -765,40 +606,6 @@ struct context_set context_sets_waveletc
}
};
-static unsigned int follow_context (int index, struct context_set *context_set) {
- int pos;
- pos = FFMIN(index, context_set->follow_length - 1);
- return context_set->follow[pos];
-}
-
-static unsigned int arith_read_uint (AVCodecContext *avctx, struct context_set *context_set) {
- int ret = 1;
- int index = 0;
-
- while (arith_get_bit (avctx, follow_context(index, context_set)) == 0) {
- ret <<= 1;
- if (arith_get_bit (avctx, context_set->data))
- ret++;
- index++;
- }
- ret--;
- return ret;
-}
-
-static int arith_read_int (AVCodecContext *avctx, struct context_set *context_set) {
- int ret = arith_read_uint (avctx, context_set);
- if (ret != 0 && arith_get_bit(avctx, context_set->sign))
- ret = -ret;
- return ret;
-}
-
-static void arith_flush(AVCodecContext *avctx) {
- DiracContext *s = avctx->priv_data;
- GetBitContext *gb = s->gb;
-
- skip_bits_long(gb, s->arith_bits_left);
- s->arith_bits_left = 0;
-}
static int inline subband_width(AVCodecContext *avctx, int level) {
DiracContext *s = avctx->priv_data;
@@ -926,7 +733,7 @@ static void coeff_unpack(AVCodecContext
int sign_pred;
int idx;
int coeff;
- struct context_set *context;
+ struct dirac_arith_context_set *context;
DiracContext *s = avctx->priv_data;
int vdata, hdata;
@@ -962,7 +769,7 @@ static void coeff_unpack(AVCodecContext
context = &context_sets_waveletcoeff[idx];
- coeff = arith_read_int(avctx, context);
+ coeff = dirac_arith_read_int(&s->arith, context);
vdata = coeff_posy(avctx, level, orientation, v);
hdata = coeff_posx(avctx, level, orientation, h);
coeff = coeff_dequant(coeff, quant);
@@ -985,7 +792,7 @@ static void codeblock(AVCodecContext *av
if (blockcnt != 1 && orientation != subband_ll) {
/* Determine if this codeblock is a zero block. */
- zero = arith_get_bit(avctx, ARITH_CONTEXT_ZERO_BLOCK);
+ zero = dirac_arith_get_bit(&s->arith, ARITH_CONTEXT_ZERO_BLOCK);
}
if (zero)
@@ -1047,12 +854,12 @@ static int subband(AVCodecContext *avctx
} else {
quant = dirac_get_ue_golomb(gb);
- arith_init(avctx, gb, length);
+ dirac_arith_init(&s->arith, gb, length);
for (y = 0; y < s->codeblocksv[level]; y++)
for (x = 0; x < s->codeblocksh[level]; x++)
codeblock(avctx, data, level, orientation, x, y, quant);
- arith_flush(avctx);
+ dirac_arith_flush(&s->arith);
}
/* XXX: This should be done for intra frames only. */
Added: dirac/dirac_arith.c
==============================================================================
--- (empty file)
+++ dirac/dirac_arith.c Fri Jul 20 16:04:36 2007
@@ -0,0 +1,156 @@
+/* -*- 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
+ */
+
+#include "dirac_arith.h"
+
+static unsigned 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
+};
+
+void dirac_arith_init (dirac_arith_state_t arith,
+ GetBitContext *gb, int length) {
+ int i;
+
+ align_get_bits(gb);
+ arith->bits_left = 8 * length - 16;
+ arith->low = 0;
+ arith->range = 0x10000;
+ arith->code = get_bits_long(gb, 16);
+ arith->gb = gb;
+
+ /* Initialize contexts. */
+ for (i = 0; i < ARITH_CONTEXT_COUNT; i++) {
+ arith->contexts[i] = 0x8000;
+ }
+}
+
+int dirac_arith_get_bit (dirac_arith_state_t arith, int context) {
+ GetBitContext *gb = arith->gb;
+ unsigned int prob_zero = arith->contexts[context];
+ unsigned int count;
+ unsigned int range_times_prob;
+ unsigned 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] -= arith_lookup[arith->contexts[context] >> 8];
+ else
+ arith->contexts[context] += arith_lookup[255 - (arith->contexts[context] >> 8)];
+
+ while (arith->range <= 0x4000) {
+ 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--;
+ }
+ else {
+ /* Get default: */
+ arith->code |= 1;
+ }
+ arith->code &= 0xffff;
+ }
+
+ return ret;
+}
+
+static unsigned inline int follow_context (int index,
+ struct dirac_arith_context_set *context_set) {
+ int pos;
+ pos = FFMIN(index, context_set->follow_length - 1);
+ return context_set->follow[pos];
+}
+
+unsigned int dirac_arith_read_uint (dirac_arith_state_t arith,
+ struct dirac_arith_context_set *context_set) {
+ int ret = 1;
+ int index = 0;
+
+ while (dirac_arith_get_bit (arith, follow_context(index, context_set)) == 0) {
+ ret <<= 1;
+ if (dirac_arith_get_bit (arith, context_set->data))
+ ret++;
+ index++;
+ }
+ ret--;
+ return ret;
+}
+
+int dirac_arith_read_int (dirac_arith_state_t arith,
+ struct dirac_arith_context_set *context_set) {
+ int ret = dirac_arith_read_uint (arith, context_set);
+ if (ret != 0 && dirac_arith_get_bit(arith, context_set->sign))
+ ret = -ret;
+ return ret;
+}
+
+void dirac_arith_flush(dirac_arith_state_t arith) {
+ skip_bits_long(arith->gb, arith->bits_left);
+ arith->bits_left = 0;
+}
Added: dirac/dirac_arith.h
==============================================================================
--- (empty file)
+++ dirac/dirac_arith.h Fri Jul 20 16:04:36 2007
@@ -0,0 +1,98 @@
+/* -*- 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
+ */
+
+#include "bitstream.h"
+
+#define ARITH_CONTEXT_COUNT (ARITH_CONTEXT_DC_SIGN + 1)
+
+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
+};
+
+typedef struct dirac_arith_state {
+ /* Arithmetic decoding. */
+ unsigned int low;
+ unsigned int range;
+ unsigned int code;
+ unsigned int bits_left;
+ unsigned int contexts[ARITH_CONTEXT_COUNT];
+
+ GetBitContext *gb;
+} *dirac_arith_state_t;
+
+struct dirac_arith_context_set {
+ unsigned int follow[6];
+ unsigned int follow_length;
+ unsigned int data;
+ unsigned int sign;
+};
+
+void dirac_arith_init (dirac_arith_state_t arith,
+ GetBitContext *gb, int length);
+
+int dirac_arith_get_bit (dirac_arith_state_t arith, int context);
+
+unsigned int dirac_arith_read_uint (dirac_arith_state_t arith,
+ struct dirac_arith_context_set *context_set);
+
+int dirac_arith_read_int (dirac_arith_state_t arith,
+ struct dirac_arith_context_set *context_set);
+
+void dirac_arith_flush(dirac_arith_state_t arith);
More information about the FFmpeg-soc
mailing list