[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