[FFmpeg-devel] [PATCH 2/2] diracdec: Add HQ Profile support

Kieran Kunhya kierank at ob-encoder.com
Tue Dec 8 20:27:42 CET 2015


From: Rostislav Pehlivanov <atomnuker at gmail.com>

---
 libavcodec/dirac.c          |  31 ++--
 libavcodec/dirac.h          |  28 ++++
 libavcodec/dirac_dwt.h      |   2 +-
 libavcodec/diracdec.c       | 357 +++++++++++++++++++++++++++-----------------
 libavformat/oggparsedirac.c |   3 +-
 5 files changed, 265 insertions(+), 156 deletions(-)

diff --git a/libavcodec/dirac.c b/libavcodec/dirac.c
index aa82dd9..67447c5 100644
--- a/libavcodec/dirac.c
+++ b/libavcodec/dirac.c
@@ -109,10 +109,11 @@ static const struct {
     { AVCOL_PRI_BT709,     AVCOL_SPC_BT709,   AVCOL_TRC_UNSPECIFIED /* DCinema */ },
 };
 
-/* [DIRAC_STD] Table 10.2 Supported chroma sampling formats + luma Offset */
-static const enum AVPixelFormat dirac_pix_fmt[2][3] = {
-    { AV_PIX_FMT_YUV444P,  AV_PIX_FMT_YUV422P,  AV_PIX_FMT_YUV420P  },
-    { AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ420P },
+/* [DIRAC_STD] Table 10.2 Supported chroma sampling formats */
+static const enum AVPixelFormat dirac_pix_fmt[3][3] = {
+    {AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV444P10, AV_PIX_FMT_YUV444P12},
+    {AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV422P12},
+    {AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUV420P12},
 };
 
 /* [DIRAC_STD] 10.3 Parse Source Parameters.
@@ -236,13 +237,9 @@ static int parse_source_parameters(AVCodecContext *avctx, GetBitContext *gb,
         avctx->color_range = pixel_range_presets[idx].color_range;
     }
 
-    if (luma_depth > 8)
-        av_log(avctx, AV_LOG_WARNING, "Bitdepth greater than 8\n");
-
-
     *bit_depth = luma_depth;
 
-    avctx->pix_fmt = dirac_pix_fmt[!luma_offset][source->chroma_format];
+    avctx->pix_fmt = dirac_pix_fmt[source->chroma_format][source->pixel_range_index-2];
     avcodec_get_chroma_sub_sample(avctx->pix_fmt, &chroma_x_shift, &chroma_y_shift);
     if ((source->width % (1<<chroma_x_shift)) || (source->height % (1<<chroma_y_shift))) {
         av_log(avctx, AV_LOG_ERROR, "Dimensions must be an integer multiple of the chroma subsampling\n");
@@ -294,24 +291,24 @@ static int parse_source_parameters(AVCodecContext *avctx, GetBitContext *gb,
 /* [DIRAC_STD] 10. Sequence Header. sequence_header() */
 int avpriv_dirac_parse_sequence_header(AVCodecContext *avctx, GetBitContext *gb,
                                        dirac_source_params *source,
+                                       DiracVersionInfo *version,
                                        int *bit_depth)
 {
-    unsigned version_major;
     unsigned video_format, picture_coding_mode;
     int ret;
 
     /* [DIRAC_SPEC] 10.1 Parse Parameters. parse_parameters() */
-    version_major  = svq3_get_ue_golomb(gb);
-    svq3_get_ue_golomb(gb); /* version_minor */
-    avctx->profile = svq3_get_ue_golomb(gb);
-    avctx->level   = svq3_get_ue_golomb(gb);
+    version->major  = svq3_get_ue_golomb(gb);
+    version->minor  = svq3_get_ue_golomb(gb);
+    avctx->profile  = svq3_get_ue_golomb(gb);
+    avctx->level    = svq3_get_ue_golomb(gb);
     /* [DIRAC_SPEC] sequence_header() -> base_video_format as defined in
      * 10.2 Base Video Format, table 10.1 Dirac predefined video formats */
-    video_format   = svq3_get_ue_golomb(gb);
+    video_format    = svq3_get_ue_golomb(gb);
 
-    if (version_major < 2)
+    if (version->major < 2)
         av_log(avctx, AV_LOG_WARNING, "Stream is old and may not work\n");
-    else if (version_major > 2)
+    else if (version->major > 2)
         av_log(avctx, AV_LOG_WARNING, "Stream may have unhandled features\n");
 
     if (video_format > 20U)
diff --git a/libavcodec/dirac.h b/libavcodec/dirac.h
index 14653f1..b4982f8 100644
--- a/libavcodec/dirac.h
+++ b/libavcodec/dirac.h
@@ -34,6 +34,33 @@
 #include "avcodec.h"
 #include "get_bits.h"
 
+/**
+ * Parse code values:
+ *
+ * Dirac Specification ->
+ * 9.6.1  Table 9.1
+ *
+ * VC-2 Specification  ->
+ * 10.4.1 Table 10.1
+ */
+
+enum DiracParseCodes {
+    DIRAC_PCODE_SEQ_HEADER      = 0x00,
+    DIRAC_PCODE_END_SEQ         = 0x10,
+    DIRAC_PCODE_AUX             = 0x20,
+    DIRAC_PCODE_PAD             = 0x30,
+    DIRAC_PCODE_PICTURE_CODED   = 0x08,
+    DIRAC_PCODE_PICTURE_RAW     = 0x48,
+    DIRAC_PCODE_PICTURE_LOW_DEL = 0xC8,
+    DIRAC_PCODE_PICTURE_HQ      = 0xE8,
+    DIRAC_PCODE_MAGIC           = 0x42424344,
+};
+
+typedef struct DiracVersionInfo {
+    int major;
+    int minor;
+} DiracVersionInfo;
+
 typedef struct dirac_source_params {
     unsigned width;
     unsigned height;
@@ -56,6 +83,7 @@ typedef struct dirac_source_params {
 
 int avpriv_dirac_parse_sequence_header(AVCodecContext *avctx, GetBitContext *gb,
                                        dirac_source_params *source,
+                                       DiracVersionInfo *version,
                                        int *bit_depth);
 
 #endif /* AVCODEC_DIRAC_H */
diff --git a/libavcodec/dirac_dwt.h b/libavcodec/dirac_dwt.h
index 41842b5..e885373 100644
--- a/libavcodec/dirac_dwt.h
+++ b/libavcodec/dirac_dwt.h
@@ -24,7 +24,7 @@
 #include <stdint.h>
 
 typedef int DWTELEM;
-typedef short IDWTELEM;
+typedef int IDWTELEM;
 
 #define MAX_DWT_SUPPORT 8
 #define MAX_DECOMPOSITIONS 8
diff --git a/libavcodec/diracdec.c b/libavcodec/diracdec.c
index b293ac8..e8828df 100644
--- a/libavcodec/diracdec.c
+++ b/libavcodec/diracdec.c
@@ -57,7 +57,7 @@
 #define MAX_REFERENCE_FRAMES 8
 #define MAX_DELAY 5         /* limit for main profile for frame coding (TODO: field coding) */
 #define MAX_FRAMES (MAX_REFERENCE_FRAMES + MAX_DELAY + 1)
-#define MAX_QUANT 68        /* max quant for VC-2 */
+#define MAX_QUANT 255        /* max quant for VC-2 */
 #define MAX_BLOCKSIZE 32    /* maximum xblen/yblen we support */
 
 /**
@@ -140,6 +140,7 @@ typedef struct DiracContext {
     MpegvideoEncDSPContext mpvencdsp;
     VideoDSPContext vdsp;
     DiracDSPContext diracdsp;
+    DiracVersionInfo version;
     GetBitContext gb;
     dirac_source_params source;
     int seen_sequence_header;
@@ -153,7 +154,11 @@ typedef struct DiracContext {
 
     int zero_res;               /* zero residue flag                         */
     int is_arith;               /* whether coeffs use arith or golomb coding */
+    int core_syntax;            /* use core syntax only                      */
     int low_delay;              /* use the low delay syntax                  */
+    int hq_picture;             /* high quality picture, enables low_delay   */
+    int ld_picture;             /* use low delay picture, turns on low_delay */
+    int dc_prediction;          /* has dc prediction                         */
     int globalmc_flag;          /* use global motion compensation            */
     int num_refs;               /* number of reference pictures              */
 
@@ -168,19 +173,25 @@ typedef struct DiracContext {
     unsigned old_delta_quant;
     unsigned codeblock_mode;
 
+    unsigned num_x;              /* number of horizontal slices               */
+    unsigned num_y;              /* number of vertical slices                 */
+
     struct {
         unsigned width;
         unsigned height;
     } codeblock[MAX_DWT_LEVELS+1];
 
     struct {
-        unsigned num_x;         /* number of horizontal slices               */
-        unsigned num_y;         /* number of vertical slices                 */
         AVRational bytes;       /* average bytes per slice                   */
         uint8_t quant[MAX_DWT_LEVELS][4]; /* [DIRAC_STD] E.1 */
     } lowdelay;
 
     struct {
+        unsigned prefix_bytes;
+        unsigned size_scaler;
+    } highquality;
+
+    struct {
         int pan_tilt[2];        /* pan/tilt vector                           */
         int zrs[2][2];          /* zoom/rotate/shear matrix                  */
         int perspective[2];     /* perspective vector                        */
@@ -224,17 +235,6 @@ typedef struct DiracContext {
     DiracFrame all_frames[MAX_FRAMES];
 } DiracContext;
 
-/**
- * Dirac Specification ->
- * Parse code values. 9.6.1 Table 9.1
- */
-enum dirac_parse_code {
-    pc_seq_header         = 0x00,
-    pc_eos                = 0x10,
-    pc_aux_data           = 0x20,
-    pc_padding            = 0x30,
-};
-
 enum dirac_subband {
     subband_ll = 0,
     subband_hl = 1,
@@ -253,26 +253,42 @@ static const uint8_t default_qmat[][4][4] = {
     { { 3,  1,  1,  0}, { 0,  4,  4,  2}, { 0,  6,  6,  5}, { 0,  9,  9,  7} },
 };
 
-static const int qscale_tab[MAX_QUANT+1] = {
-    4,     5,     6,     7,     8,    10,    11,    13,
-    16,    19,    23,    27,    32,    38,    45,    54,
-    64,    76,    91,   108,   128,   152,   181,   215,
-    256,   304,   362,   431,   512,   609,   724,   861,
-    1024,  1218,  1448,  1722,  2048,  2435,  2896,  3444,
-    4096,  4871,  5793,  6889,  8192,  9742, 11585, 13777,
-    16384, 19484, 23170, 27554, 32768, 38968, 46341, 55109,
-    65536, 77936
+static const int32_t qscale_tab[150] = {
+        4,         5,         6,         7,          8,        10,        11,        13,
+       16,        19,        23,        27,         32,        38,        45,        54,
+       64,        76,        91,       108,        128,       152,       181,       215,
+      256,       304,       362,       431,        512,       609,       724,       861,
+     1024,      1218,      1448,      1722,       2048,      2435,      2896,      3444,
+     4096,      4871,      5793,      6889,       8192,      9742,     11585,     13777,
+    16384,     19484,    -13317,     27554,      32768,     -1581,      9853,    -10518,
+    65536,     -3164,    -16782,    -21037,     131072,     -6328,      2922,     23552,
+   262144,    -12658,      5844,    -18524,     524288,     15232,     11689,     28578,
+  1048576,    -10085,    -13110,     -8471,    2097152,    -20170,     10267,    -16943,
+  4194304,       208,    -15954,     31741,    8388608,       416,      4579,     -2146,
+ 16777216,       832,      9158,     -4293,   33554432,      1663,    -18172,     -8587,
+ 67108864,      3326,       143,    -17175,   134217728,     6653,       285,     31276,
+268435456,     13306,       570,     -3075,   536870912,   -13938,      1140,     -6152,
+1073741824,    12672,      2281,    -12304, -2147483648,   -15205,      4561,    -24610,
+         0,    10138,      9122,     16407,           0,   -20274,    -18243,    -32813,
 };
 
-static const int qoffset_intra_tab[MAX_QUANT+1] = {
-    1,     2,     3,     4,     4,     5,     6,     7,
-    8,    10,    12,    14,    16,    19,    23,    27,
-    32,    38,    46,    54,    64,    76,    91,   108,
-    128,   152,   181,   216,   256,   305,   362,   431,
-    512,   609,   724,   861,  1024,  1218,  1448,  1722,
-    2048,  2436,  2897,  3445,  4096,  4871,  5793,  6889,
-    8192,  9742, 11585, 13777, 16384, 19484, 23171, 27555,
-    32768, 38968
+static const int32_t qoffset_intra_tab[150] = {
+        1,         2,         3,         4,         4,         5,         6,         7,
+        8,        10,        12,        14,          16,        19,        23,        27,
+       32,        38,        46,        54,          64,        76,        91,       108,
+      128,       152,       181,       216,         256,       305,       362,       431,
+      512,       609,       724,       861,        1024,      1218,      1448,      1722,
+     2048,      2436,      2897,      3445,        4096,      4871,      5793,      6889,
+     8192,      9742,     -6658,     13777,       16384,      -790,      4927,     -5258,
+    32768,     -1581,     -8390,    -10518,       65536,     -3163,      1461,     11776,
+   131072,     -6328,      2922,     -9261,      262144,      7616,      5845,     14289,
+   524288,     -5042,     -6554,     -4235,     1048576,    -10084,      5134,     -8471,
+  2097152,       104,     -7976,     15871,     4194304,       208,      2290,     -1072,
+  8388608,       416,      4579,     -2146,    16777216,       832,     -9085,     -4293,
+ 33554432,      1663,        72,     -8587,    67108864,      3327,       143,     15638,
+134217728,      6653,       285,     -1537,   268435456,     -6968,       570,     -3075,
+536870912,      6336,      1141,     -6151, -1073741823,     -7602,      2281,    -12304,
+        0,      5069,      4561,      8204,           0,    -10136,     -9121,    -16406,
 };
 
 static const int qoffset_inter_tab[MAX_QUANT+1] = {
@@ -466,7 +482,7 @@ static av_cold int dirac_decode_end(AVCodecContext *avctx)
 
 #define SIGN_CTX(x) (CTX_SIGN_ZERO + ((x) > 0) - ((x) < 0))
 
-static inline int coeff_unpack_golomb(GetBitContext *gb, int qfactor, int qoffset)
+static av_always_inline int coeff_unpack_golomb(GetBitContext *gb, int qfactor, int qoffset)
 {
     int sign, coeff;
 
@@ -584,18 +600,6 @@ static inline void codeblock(DiracContext *s, SubBand *b,
      }
 }
 
-#define PARSE_VALUES(type, x, gb, ebits, buf1, buf2) \
-    type *buf = (type *)buf1; \
-    buf[x] = coeff_unpack_golomb(gb, qfactor, qoffset); \
-    if (get_bits_count(gb) >= ebits) \
-        return; \
-    if (buf2) { \
-        buf = (type *)buf2; \
-        buf[x] = coeff_unpack_golomb(gb, qfactor, qoffset); \
-        if (get_bits_count(gb) >= ebits) \
-            return; \
-    } \
-
 /**
  * Dirac Specification ->
  * 13.3 intra_dc_prediction(band)
@@ -719,49 +723,68 @@ static void decode_component(DiracContext *s, int comp)
         avctx->execute(avctx, decode_subband_golomb, bands, NULL, num_bands, sizeof(SubBand*));
 }
 
-/* [DIRAC_STD] 13.5.5.2 Luma slice subband data. luma_slice_band(level,orient,sx,sy) --> if b2 == NULL */
-/* [DIRAC_STD] 13.5.5.3 Chroma slice subband data. chroma_slice_band(level,orient,sx,sy) --> if b2 != NULL */
-static void lowdelay_subband(DiracContext *s, GetBitContext *gb, int quant,
-                             int slice_x, int slice_y, int bits_end,
-                             SubBand *b1, SubBand *b2)
+#define PARSE_VALUES(type, x, gb, ebits, buf1, buf2) \
+    type *buf = (type *)buf1; \
+    buf[x] = coeff_unpack_golomb(gb, qfactor, qoffset); \
+    if (get_bits_count(gb) >= ebits) \
+        return; \
+    if (buf2) { \
+        buf = (type *)buf2; \
+        buf[x] = coeff_unpack_golomb(gb, qfactor, qoffset); \
+        if (get_bits_count(gb) >= ebits) \
+            return; \
+    } \
+
+static void decode_subband(DiracContext *s, GetBitContext *gb, int quant,
+                           int slice_x, int slice_y, int bits_end,
+                           SubBand *b1, SubBand *b2)
 {
-    int left   = b1->width  * slice_x    / s->lowdelay.num_x;
-    int right  = b1->width  *(slice_x+1) / s->lowdelay.num_x;
-    int top    = b1->height * slice_y    / s->lowdelay.num_y;
-    int bottom = b1->height *(slice_y+1) / s->lowdelay.num_y;
+    int left   = b1->width  * slice_x    / s->num_x;
+    int right  = b1->width  *(slice_x+1) / s->num_x;
+    int top    = b1->height * slice_y    / s->num_y;
+    int bottom = b1->height *(slice_y+1) / s->num_y;
 
-    int qfactor = qscale_tab[FFMIN(quant, MAX_QUANT)];
-    int qoffset = qoffset_intra_tab[FFMIN(quant, MAX_QUANT)];
+    int qfactor = qscale_tab[quant & 0x7f];
+    int qoffset = qoffset_intra_tab[quant & 0x7f];
 
     uint8_t *buf1 =      b1->ibuf + top * b1->stride;
     uint8_t *buf2 = b2 ? b2->ibuf + top * b2->stride: NULL;
     int x, y;
-    /* we have to constantly check for overread since the spec explicitly
-       requires this, with the meaning that all remaining coeffs are set to 0 */
+
     if (get_bits_count(gb) >= bits_end)
         return;
 
-    for (y = top; y < bottom; y++) {
-        for (x = left; x < right; x++) {
-            if (s->pshift) {
+    if (s->pshift) {
+        for (y = top; y < bottom; y++) {
+            for (x = left; x < right; x++) {
                 PARSE_VALUES(int32_t, x, gb, bits_end, buf1, buf2);
-            } else {
+            }
+
+            buf1 += b1->stride;
+            if (buf2)
+                buf2 += b2->stride;
+        }
+    }
+    else {
+        for (y = top; y < bottom; y++) {
+            for (x = left; x < right; x++) {
                 PARSE_VALUES(int16_t, x, gb, bits_end, buf1, buf2);
             }
+
+            buf1 += b1->stride;
+            if (buf2)
+                buf2 += b2->stride;
         }
-        buf1 += b1->stride;
-        if (buf2)
-            buf2 += b2->stride;
     }
 }
 
-struct lowdelay_slice {
+/* Used by Low Delay and High Quality profiles */
+typedef struct DiracSlice {
     GetBitContext gb;
     int slice_x;
     int slice_y;
     int bytes;
-};
-
+} DiracSlice;
 
 /**
  * Dirac Specification ->
@@ -770,7 +793,7 @@ struct lowdelay_slice {
 static int decode_lowdelay_slice(AVCodecContext *avctx, void *arg)
 {
     DiracContext *s = avctx->priv_data;
-    struct lowdelay_slice *slice = arg;
+    DiracSlice *slice = arg;
     GetBitContext *gb = &slice->gb;
     enum dirac_subband orientation;
     int level, quant, chroma_bits, chroma_end;
@@ -784,8 +807,8 @@ static int decode_lowdelay_slice(AVCodecContext *avctx, void *arg)
     for (level = 0; level < s->wavelet_depth; level++)
         for (orientation = !!level; orientation < 4; orientation++) {
             quant = FFMAX(quant_base - s->lowdelay.quant[level][orientation], 0);
-            lowdelay_subband(s, gb, quant, slice->slice_x, slice->slice_y, luma_end,
-                             &s->plane[0].band[level][orientation], NULL);
+            decode_subband(s, gb, quant, slice->slice_x, slice->slice_y, luma_end,
+                           &s->plane[0].band[level][orientation], NULL);
         }
 
     /* consume any unused bits from luma */
@@ -797,10 +820,48 @@ static int decode_lowdelay_slice(AVCodecContext *avctx, void *arg)
     for (level = 0; level < s->wavelet_depth; level++)
         for (orientation = !!level; orientation < 4; orientation++) {
             quant = FFMAX(quant_base - s->lowdelay.quant[level][orientation], 0);
-            lowdelay_subband(s, gb, quant, slice->slice_x, slice->slice_y, chroma_end,
-                             &s->plane[1].band[level][orientation],
-                             &s->plane[2].band[level][orientation]);
+            decode_subband(s, gb, quant, slice->slice_x, slice->slice_y, chroma_end,
+                           &s->plane[1].band[level][orientation],
+                           &s->plane[2].band[level][orientation]);
+        }
+
+    return 0;
+}
+
+/**
+ * VC-2 Specification ->
+ * 13.5.3 hq_slice(sx,sy)
+ */
+static int decode_hq_slice(DiracContext *s, GetBitContext *gb,
+                           int slice_x, int slice_y)
+{
+    int i, quant, level, orientation, quant_idx;
+    uint8_t quants[MAX_DWT_LEVELS][4];
+
+    skip_bits_long(gb, 8*s->highquality.prefix_bytes);
+    quant_idx = get_bits(gb, 8);
+
+    /* Slice quantization (slice_quantizers() in the specs) */
+    for (level = 0; level < s->wavelet_depth; level++) {
+        for (orientation = !!level; orientation < 4; orientation++) {
+            quant = FFMAX(quant_idx - s->lowdelay.quant[level][orientation], 0);
+            quants[level][orientation] = quant;
+        }
+    }
+
+    /* Luma + 2 Chroma planes */
+    for (i = 0; i < 3; i++) {
+        int length = s->highquality.size_scaler * get_bits(gb, 8);
+        int bits_left = 8 * length;
+        int bits_end = get_bits_count(gb) + bits_left;
+        for (level = 0; level < s->wavelet_depth; level++) {
+            for (orientation = !!level; orientation < 4; orientation++) {
+                decode_subband(s, gb, quants[level][orientation], slice_x, slice_y, bits_end,
+                               &s->plane[i].band[level][orientation], NULL);
+            }
         }
+        skip_bits_long(gb, bits_end - get_bits_count(gb));
+    }
 
     return 0;
 }
@@ -814,10 +875,10 @@ static int decode_lowdelay(DiracContext *s)
     AVCodecContext *avctx = s->avctx;
     int slice_x, slice_y, bytes, bufsize;
     const uint8_t *buf;
-    struct lowdelay_slice *slices;
+    DiracSlice *slices;
     int slice_num = 0;
 
-    slices = av_mallocz_array(s->lowdelay.num_x, s->lowdelay.num_y * sizeof(struct lowdelay_slice));
+    slices = av_mallocz_array(s->num_x, s->num_y * sizeof(DiracSlice));
     if (!slices)
         return AVERROR(ENOMEM);
 
@@ -826,35 +887,46 @@ static int decode_lowdelay(DiracContext *s)
     buf = s->gb.buffer + get_bits_count(&s->gb)/8;
     bufsize = get_bits_left(&s->gb);
 
-    for (slice_y = 0; bufsize > 0 && slice_y < s->lowdelay.num_y; slice_y++)
-        for (slice_x = 0; bufsize > 0 && slice_x < s->lowdelay.num_x; slice_x++) {
-            bytes = (slice_num+1) * s->lowdelay.bytes.num / s->lowdelay.bytes.den
-                - slice_num    * s->lowdelay.bytes.num / s->lowdelay.bytes.den;
-
-            slices[slice_num].bytes   = bytes;
-            slices[slice_num].slice_x = slice_x;
-            slices[slice_num].slice_y = slice_y;
-            init_get_bits(&slices[slice_num].gb, buf, bufsize);
-            slice_num++;
-
-            buf     += bytes;
-            if (bufsize/8 >= bytes)
-                bufsize -= bytes*8;
-            else
-                bufsize = 0;
+    if (s->hq_picture) {
+        for (slice_y = 0; slice_y < s->num_y; slice_y++) {
+            for (slice_x = 0; slice_x < s->num_x; slice_x++) {
+                decode_hq_slice(s, &s->gb, slice_x, slice_y);
+            }
         }
-
-    avctx->execute(avctx, decode_lowdelay_slice, slices, NULL, slice_num,
-                   sizeof(struct lowdelay_slice)); /* [DIRAC_STD] 13.5.2 Slices */
-    if (s->pshift) {
-        intra_dc_prediction_10(&s->plane[0].band[0][0]);
-        intra_dc_prediction_10(&s->plane[1].band[0][0]);
-        intra_dc_prediction_10(&s->plane[2].band[0][0]);
     } else {
-        intra_dc_prediction_8(&s->plane[0].band[0][0]);
-        intra_dc_prediction_8(&s->plane[1].band[0][0]);
-        intra_dc_prediction_8(&s->plane[2].band[0][0]);
+        for (slice_y = 0; bufsize > 0 && slice_y < s->num_y; slice_y++) {
+            for (slice_x = 0; bufsize > 0 && slice_x < s->num_x; slice_x++) {
+                bytes = (slice_num+1) * s->lowdelay.bytes.num / s->lowdelay.bytes.den
+                    - slice_num    * s->lowdelay.bytes.num / s->lowdelay.bytes.den;
+                slices[slice_num].bytes   = bytes;
+                slices[slice_num].slice_x = slice_x;
+                slices[slice_num].slice_y = slice_y;
+                init_get_bits(&slices[slice_num].gb, buf, bufsize);
+                slice_num++;
+
+                buf     += bytes;
+                if (bufsize/8 >= bytes)
+                    bufsize -= bytes*8;
+                else
+                    bufsize = 0;
+            }
+        }
+        avctx->execute(avctx, decode_lowdelay_slice, slices, NULL, slice_num,
+                       sizeof(DiracSlice)); /* [DIRAC_STD] 13.5.2 Slices */
     }
+
+    if (s->dc_prediction) {
+        if (s->pshift) {
+            intra_dc_prediction_10(&s->plane[0].band[0][0]); /* [DIRAC_STD] 13.3 intra_dc_prediction() */
+            intra_dc_prediction_10(&s->plane[1].band[0][0]); /* [DIRAC_STD] 13.3 intra_dc_prediction() */
+            intra_dc_prediction_10(&s->plane[2].band[0][0]); /* [DIRAC_STD] 13.3 intra_dc_prediction() */
+        } else {
+            intra_dc_prediction_8(&s->plane[0].band[0][0]);
+            intra_dc_prediction_8(&s->plane[1].band[0][0]);
+            intra_dc_prediction_8(&s->plane[2].band[0][0]);
+        }
+    }
+
     av_free(slices);
     return 0;
 }
@@ -1057,29 +1129,19 @@ static int dirac_unpack_idwt_params(DiracContext *s)
 
     CHECKEDREAD(s->wavelet_depth, tmp > MAX_DWT_LEVELS || tmp < 1, "invalid number of DWT decompositions\n")
 
-    if (!s->low_delay) {
-        /* Codeblock parameters (core syntax only) */
-        if (get_bits1(gb)) {
-            for (i = 0; i <= s->wavelet_depth; i++) {
-                CHECKEDREAD(s->codeblock[i].width , tmp < 1 || tmp > (s->avctx->width >>s->wavelet_depth-i), "codeblock width invalid\n")
-                CHECKEDREAD(s->codeblock[i].height, tmp < 1 || tmp > (s->avctx->height>>s->wavelet_depth-i), "codeblock height invalid\n")
+    if (s->low_delay) {
+        s->num_x        = svq3_get_ue_golomb(gb);
+        s->num_y        = svq3_get_ue_golomb(gb);
+        if (s->ld_picture) {
+            s->lowdelay.bytes.num = svq3_get_ue_golomb(gb);
+            s->lowdelay.bytes.den = svq3_get_ue_golomb(gb);
+            if (s->lowdelay.bytes.den <= 0) {
+                av_log(s->avctx,AV_LOG_ERROR,"Invalid lowdelay.bytes.den\n");
+                return AVERROR_INVALIDDATA;
             }
-
-            CHECKEDREAD(s->codeblock_mode, tmp > 1, "unknown codeblock mode\n")
-        } else
-            for (i = 0; i <= s->wavelet_depth; i++)
-                s->codeblock[i].width = s->codeblock[i].height = 1;
-    } else {
-        /* Slice parameters + quantization matrix*/
-        /*[DIRAC_STD] 11.3.4 Slice coding Parameters (low delay syntax only). slice_parameters() */
-        s->lowdelay.num_x     = svq3_get_ue_golomb(gb);
-        s->lowdelay.num_y     = svq3_get_ue_golomb(gb);
-        s->lowdelay.bytes.num = svq3_get_ue_golomb(gb);
-        s->lowdelay.bytes.den = svq3_get_ue_golomb(gb);
-
-        if (s->lowdelay.bytes.den <= 0) {
-            av_log(s->avctx,AV_LOG_ERROR,"Invalid lowdelay.bytes.den\n");
-            return AVERROR_INVALIDDATA;
+        } else if (s->hq_picture) {
+            s->highquality.prefix_bytes = svq3_get_ue_golomb(gb);
+            s->highquality.size_scaler  = svq3_get_ue_golomb(gb);
         }
 
         /* [DIRAC_STD] 11.3.5 Quantisation matrices (low-delay syntax). quant_matrix() */
@@ -1107,6 +1169,19 @@ static int dirac_unpack_idwt_params(DiracContext *s)
                 }
         }
     }
+    /* Codeblock parameters (core syntax only) */
+    if (s->core_syntax) {
+        if (get_bits1(gb)) {
+            for (i = 0; i <= s->wavelet_depth; i++) {
+                CHECKEDREAD(s->codeblock[i].width , tmp < 1 || tmp > (s->avctx->width >>s->wavelet_depth-i), "codeblock width invalid\n")
+                CHECKEDREAD(s->codeblock[i].height, tmp < 1 || tmp > (s->avctx->height>>s->wavelet_depth-i), "codeblock height invalid\n")
+            }
+            CHECKEDREAD(s->codeblock_mode, tmp > 1, "unknown codeblock mode\n")
+        } else {
+            for (i = 0; i <= s->wavelet_depth; i++)
+                s->codeblock[i].width = s->codeblock[i].height = 1;
+        }
+    }
     return 0;
 }
 
@@ -1615,7 +1690,8 @@ static int interpolate_refplane(DiracContext *s, DiracFrame *ref, int plane, int
     int i, edge = EDGE_WIDTH/2;
 
     ref->hpel[plane][0] = ref->avframe->data[plane];
-    s->mpvencdsp.draw_edges(ref->hpel[plane][0], ref->avframe->linesize[plane], width, height, edge, edge, EDGE_TOP | EDGE_BOTTOM); /* EDGE_TOP | EDGE_BOTTOM values just copied to make it build, this needs to be ensured */
+    s->mpvencdsp.draw_edges(ref->hpel[plane][0], ref->avframe->linesize[plane], width, height, edge, edge, EDGE_TOP | EDGE_BOTTOM);
+    /* EDGE_TOP | EDGE_BOTTOM values just copied to make it build, this needs to be ensured */
 
     /* no need for hpel if we only have fpel vectors */
     if (!s->mv_precision)
@@ -1890,7 +1966,8 @@ static int dirac_decode_data_unit(AVCodecContext *avctx, const uint8_t *buf, int
 {
     DiracContext *s   = avctx->priv_data;
     DiracFrame *pic   = NULL;
-    int ret, i, parse_code;
+    int ret, i;
+    uint8_t parse_code;
     unsigned tmp;
 
     if (size < DATA_UNIT_HEADER_SIZE)
@@ -1900,14 +1977,13 @@ static int dirac_decode_data_unit(AVCodecContext *avctx, const uint8_t *buf, int
 
     init_get_bits(&s->gb, &buf[13], 8*(size - DATA_UNIT_HEADER_SIZE));
 
-    if (parse_code == pc_seq_header) {
+    if (parse_code == DIRAC_PCODE_SEQ_HEADER) {
         if (s->seen_sequence_header)
             return 0;
 
         /* [DIRAC_STD] 10. Sequence header */
-        ret = avpriv_dirac_parse_sequence_header(avctx, &s->gb, &s->source,
+        ret = avpriv_dirac_parse_sequence_header(avctx, &s->gb, &s->source, &s->version,
                                                  &s->bit_depth);
-        s->pshift = s->bit_depth > 8;
         if (ret < 0)
             return ret;
 
@@ -1920,10 +1996,10 @@ static int dirac_decode_data_unit(AVCodecContext *avctx, const uint8_t *buf, int
             return ret;
 
         s->seen_sequence_header = 1;
-    } else if (parse_code == pc_eos) { /* [DIRAC_STD] End of Sequence */
+    } else if (parse_code == DIRAC_PCODE_END_SEQ) { /* [DIRAC_STD] End of Sequence */
         free_sequence_buffers(s);
         s->seen_sequence_header = 0;
-    } else if (parse_code == pc_aux_data) {
+    } else if (parse_code == DIRAC_PCODE_AUX) {
         if (buf[13] == 1) {     /* encoder implementation/version */
             int ver[3];
             /* versions older than 1.0.8 don't store quant delta for
@@ -1955,12 +2031,19 @@ static int dirac_decode_data_unit(AVCodecContext *avctx, const uint8_t *buf, int
             av_log(avctx, AV_LOG_ERROR, "num_refs of 3\n");
             return AVERROR_INVALIDDATA;
         }
-        s->num_refs    = tmp;
-        s->is_arith    = (parse_code & 0x48) == 0x08;          /* [DIRAC_STD] using_ac()      */
-        s->low_delay   = (parse_code & 0x88) == 0x88;          /* [DIRAC_STD] is_low_delay()  */
-        pic->reference = (parse_code & 0x0C) == 0x0C;  /* [DIRAC_STD]  is_reference() */
-        pic->avframe->key_frame = s->num_refs == 0;             /* [DIRAC_STD] is_intra()      */
-        pic->avframe->pict_type = s->num_refs + 1;              /* Definition of AVPictureType in avutil.h */
+        s->num_refs      = tmp;
+        s->is_arith      = (parse_code & 0x48) == 0x08;          /* [DIRAC_STD] using_ac()            */
+        s->low_delay     = (parse_code & 0x88) == 0x88;          /* [DIRAC_STD] is_low_delay()        */
+        s->core_syntax   = (parse_code & 0x88) == 0x08;          /* [DIRAC_STD] is_core_syntax()      */
+        s->ld_picture    = (parse_code & 0xF8) == 0xC8;          /* [DIRAC_STD] is_ld_picture()       */
+        s->hq_picture    = (parse_code & 0xF8) == 0xE8;          /* [DIRAC_STD] is_hq_picture()       */
+        s->dc_prediction = (parse_code & 0x28) == 0x08;          /* [DIRAC_STD] using_dc_prediction() */
+        pic->reference   = (parse_code & 0x0C) == 0x0C;          /* [DIRAC_STD] is_reference()        */
+        pic->avframe->key_frame = s->num_refs == 0;              /* [DIRAC_STD] is_intra()            */
+        pic->avframe->pict_type = s->num_refs + 1;               /* Definition of AVPictureType in avutil.h */
+
+        if (s->version.minor == 2 && parse_code == 0x88)
+            s->ld_picture = 1;
 
         if ((ret = get_buffer_with_edge(avctx, pic->avframe, (parse_code & 0x0C) == 0x0C ? AV_GET_BUFFER_FLAG_REF : 0)) < 0)
             return ret;
diff --git a/libavformat/oggparsedirac.c b/libavformat/oggparsedirac.c
index b317f5a..2835ac7 100644
--- a/libavformat/oggparsedirac.c
+++ b/libavformat/oggparsedirac.c
@@ -30,6 +30,7 @@ static int dirac_header(AVFormatContext *s, int idx)
     struct ogg_stream *os = ogg->streams + idx;
     AVStream *st = s->streams[idx];
     dirac_source_params source;
+    DiracVersionInfo version;
     GetBitContext gb;
     int ret, bit_depth;
 
@@ -41,7 +42,7 @@ static int dirac_header(AVFormatContext *s, int idx)
     if (ret < 0)
         return ret;
 
-    ret = avpriv_dirac_parse_sequence_header(st->codec, &gb, &source, &bit_depth);
+    ret = avpriv_dirac_parse_sequence_header(st->codec, &gb, &source, &version, &bit_depth);
     if (ret < 0)
         return ret;
 
-- 
1.9.1



More information about the ffmpeg-devel mailing list