[FFmpeg-soc] [soc]: r309 - dirac/dirac.c
marco
subversion at mplayerhq.hu
Tue Jul 3 19:57:05 CEST 2007
Author: marco
Date: Tue Jul 3 19:57:05 2007
New Revision: 309
Log:
Some cleanups and added defaults from the spec. Please don't review this code yet until I finished the cleanup.
Modified:
dirac/dirac.c
Modified: dirac/dirac.c
==============================================================================
--- dirac/dirac.c (original)
+++ dirac/dirac.c Tue Jul 3 19:57:05 2007
@@ -26,7 +26,6 @@
#include "bitstream.h"
#include "golomb.h"
-
/* TODO:
- Compare svq3 golomb to Dirac spec.
@@ -37,24 +36,180 @@
*/
+typedef enum {
+ TRANSFER_FUNC_TV,
+ TRANSFER_FUNC_EXTENDED_GAMUT,
+ TRANSFER_FUNC_LINEAR,
+ TRANSFER_FUNC_DCI_GAMMA
+} transfer_func_t;
+
+struct source_parameters
+{
+ /* Interlacing. */
+ int interlaced;
+ int top_field_first;
+ int sequential_fields;
+
+ AVRational frame_rate;
+
+ AVRational aspect_ratio;
+
+ /* Clean area. */
+ int clean_width;
+ int clean_height;
+ int clean_left_offset;
+ int clean_right_offset;
+
+ /* Luma and chroma offsets. */
+ int luma_offset;
+ int luma_excursion;
+ int chroma_offset;
+ int chroma_excursion;
+
+ int color_spec;
+ int color_primaries; /* XXX: ??? */
+
+ float k_r;
+ float k_b; /* XXX: ??? */
+
+ transfer_func_t transfer_function;
+};
+
+struct sequence_parameters
+{
+ /* Information about the frames. */
+ int luma_width;
+ int luma_height;
+ /* 0: 4:4:4, 1: 4:2:2, 2: 4:2:0 */
+ int chroma_format;
+ int video_depth;
+
+ /* Calculated: */
+ int chroma_width;
+ int chroma_height;
+};
+
+struct decoding_parameters
+{
+ int wavelet_depth;
+ int wavelet_idx_intra;
+ int wavelet_idx_inter;
+
+ int luma_xbsep;
+ int luma_xblen;
+ int luma_ybsep;
+ int luma_yblen;
+
+ int mv_precision;
+
+ int picture_weight_ref1;
+ int picture_weight_ref2;
+ int picture_weight_bits;
+
+ /* Codeblocks h*v. */
+ int intra_hlevel_012, intra_vlevel_012;
+ int intra_hlevel_other, intra_vlevel_other;
+ int inter_hlevel_01, inter_vlevel_01;
+ int inter_hlevel_2, inter_vlevel_2;
+ int inter_hlevel_other, inter_vlevel_other;
+ int slice_width;
+ int slide_height;
+ int slice_bits;
+};
+
+/* Defaults for sequence parameters. */
+static const struct sequence_parameters sequence_parameters_defaults[13] =
+{
+ /* Width Height Chroma format Depth */
+ { 640, 480, 2, 8 },
+ { 176, 120, 2, 8 },
+ { 176, 144, 2, 8 },
+ { 352, 240, 2, 8 },
+ { 352, 288, 2, 8 },
+ { 704, 480, 2, 8 },
+ { 704, 576, 2, 8 },
+
+ { 720, 480, 2, 8 },
+ { 720, 576, 2, 8 },
+ { 1280, 720, 2, 8 },
+ { 1920, 1080, 2, 8 },
+ { 2048, 1556, 0, 16 },
+ { 4096, 3112, 0, 16 },
+};
+
+/* Defaults for source parameters. */
+static const struct source_parameters source_parameters_defaults[13] =
+{
+ { 0, 1, 0, {30, 1}, {1, 1}, 640, 480, 0, 0, 0, 255, 128, 254, 0, 0, 0.2126, 0.0722, TRANSFER_FUNC_TV },
+ { 0, 1, 0, {15000, 1001}, {10, 11}, 176, 120, 0, 0, 0, 255, 128, 254, 1, 0, 0.299, 0.144, TRANSFER_FUNC_TV },
+ { 0, 1, 0, {25, 2}, {12, 11}, 176, 144, 0, 0, 0, 255, 128, 254, 2, 0, 0.299, 0.144, TRANSFER_FUNC_TV },
+ { 0, 1, 0, {15000, 1001}, {10, 11}, 352, 240, 0, 0, 0, 255, 128, 254, 1, 0, 0.299, 0.144, TRANSFER_FUNC_TV },
+ { 0, 1, 0, {25, 2}, {12, 11}, 352, 288, 0, 0, 0, 255, 128, 254, 2, 0, 0.299, 0.144, TRANSFER_FUNC_TV },
+ { 0, 1, 0, {15000, 1001}, {10, 11}, 704, 480, 0, 0, 0, 255, 128, 254, 1, 0, 0.299, 0.144, TRANSFER_FUNC_TV },
+ { 0, 1, 0, {25, 2}, {12, 11}, 704, 576, 0, 0, 0, 255, 128, 254, 2, 0, 0.299, 0.144, TRANSFER_FUNC_TV },
+
+ { 0, 1, 0, {24000, 1001}, {10, 11}, 720, 480, 0, 0, 16, 235, 128, 224, 1, 0, 0.299, 0.144, TRANSFER_FUNC_TV },
+ { 0, 1, 0, {35, 1}, {12, 11}, 720, 576, 0, 0, 16, 235, 128, 224, 2, 0, 0.299, 0.144, TRANSFER_FUNC_TV },
+ { 0, 1, 0, {24, 1}, {1, 1}, 1280, 720, 0, 0, 16, 235, 128, 224, 0, 0, 0.2126, 0.0722, TRANSFER_FUNC_TV },
+ { 0, 1, 0, {24, 1}, {1, 1}, 1920, 1080, 0, 0, 16, 235, 128, 224, 0, 0, 0.2126, 0.0722, TRANSFER_FUNC_TV },
+ { 0, 1, 0, {24, 1}, {1, 1}, 2048, 1536, 0, 0, 0, 65535, 32768, 65534, 3, 0, 0.25, 0.25, TRANSFER_FUNC_LINEAR },
+ { 0, 1, 0, {24, 1}, {1, 1}, 4096, 3072, 0, 0, 0, 65535, 32768, 65534, 3, 0, 0.25, 0.25, TRANSFER_FUNC_LINEAR },
+};
+
+/* Defaults for decoding parameters. */
+static const struct decoding_parameters decoding_parameters_defaults[13] =
+{
+ { 4, 0, 1, 8, 12, 8, 12, 2, 1, 1, 1, 1, 1, 4, 3, 1, 1, 8, 6, 12, 8, 32, 32, 512 },
+ { 4, 0, 1, 4, 8, 4, 8, 2, 1, 1, 1, 1, 1, 4, 3, 1, 1, 8, 6, 12, 8, 16, 16, 512 },
+ { 4, 0, 1, 4, 8, 4, 8, 2, 1, 1, 1, 1, 1, 4, 3, 1, 1, 8, 6, 12, 8, 16, 16, 512 },
+ { 4, 0, 1, 8, 12, 8, 12, 2, 1, 1, 1, 1, 1, 4, 3, 1, 1, 8, 6, 12, 8, 32, 32, 512 },
+ { 4, 0, 1, 8, 12, 8, 12, 2, 1, 1, 1, 1, 1, 4, 3, 1, 1, 8, 6, 12, 8, 32, 32, 512 },
+ { 4, 0, 1, 8, 12, 8, 12, 2, 1, 1, 1, 1, 1, 4, 3, 1, 1, 8, 6, 12, 8, 32, 32, 512 },
+ { 4, 0, 1, 8, 12, 8, 12, 2, 1, 1, 1, 1, 1, 4, 3, 1, 1, 8, 6, 12, 8, 32, 32, 512 },
+
+ { 4, 0, 1, 8, 12, 8, 12, 2, 1, 1, 1, 1, 1, 4, 3, 1, 1, 8, 6, 12, 8, 32, 32, 512 },
+ { 4, 0, 1, 8, 12, 8, 12, 2, 1, 1, 1, 1, 1, 4, 3, 1, 1, 8, 6, 12, 8, 32, 32, 512 },
+ { 4, 0, 1, 12, 16, 12, 16, 2, 1, 1, 1, 1, 1, 4, 3, 1, 1, 8, 6, 12, 8, 48, 48, 768 },
+ { 4, 0, 1, 16, 24, 16, 24, 2, 1, 1, 1, 1, 1, 4, 3, 1, 1, 8, 6, 12, 8, 48, 48, 1024 },
+ { 4, 6, 1, 16, 24, 16, 24, 2, 1, 1, 1, 1, 1, 4, 3, 1, 1, 8, 6, 12, 8, 48, 48, 1024 },
+ { 4, 6, 0, 16, 24, 16, 24, 2, 1, 1, 1, 1, 1, 4, 3, 1, 1, 8, 6, 12, 8, 48, 48, 1024 }
+};
+
+static const AVRational preset_frame_rates[8] =
+{
+ {24000, 1001}, {24, 1}, {25, 1}, {30000, 1001},
+ {30, 1}, {50, 1}, {60000, 1001}, {60, 1}
+};
+
+static const AVRational preset_aspect_ratios[3] =
+{
+ {1, 1}, {10, 11}, {12, 11}
+};
+
+static const int preset_luma_offset[3] = { 0, 16, 64 };
+static const int preset_luma_excursion[3] = { 255, 235, 876 };
+static const int preset_chroma_offset[3] = { 128, 128, 512 };
+static const int preset_chroma_excursion[3] = { 255, 224, 896 };
+
+static const int preset_primaries[4] = { 0, 1, 2, 3 };
+static const int preset_matrix[4] = {0, 1, 1, 2 };
+static const transfer_func_t preset_transfer_func[4] =
+{
+ TRANSFER_FUNC_TV, TRANSFER_FUNC_TV, TRANSFER_FUNC_DCI_GAMMA
+};
+static const float preset_kr[3] = { 0.2126, 0.299, 0 /* XXX */ };
+static const float preset_kb[3] = {0.0722, 0.114, 0 /* XXX */ };
typedef struct DiracContext {
+ int next_picture;
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;
+ struct source_parameters source;
+ struct sequence_parameters sequence;
+ struct decoding_parameters decoding;
int codeblocksh[7]; /* XXX: 7 levels. */
int codeblocksv[7]; /* XXX: 7 levels. */
@@ -106,100 +261,194 @@ static int parse_access_unit_header (AVC
uint32_t video_format;
/* Parse parameters. */
+ s->next_picture = get_bits_long(gb, 32);
- /* XXX: Picture number of next frame. */
- skip_bits_long(gb, 32);
version_major = dirac_golomb(gb);
version_minor = dirac_golomb(gb);
+ /* XXX: Don't check the version yet, existing encoders do not yet
+ set this to a sane value (0.6 at the moment). */
+
+ /* XXX: Not yet documented in the spec. This is actually the main
+ thing that is missing. */
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, "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. */
+ /* Fill in defaults for the source parameters. */
+ memcpy(&s->source, &source_parameters_defaults[video_format],
+ sizeof(s->source));
+
+ /* Fill in defaults for the sequence parameters. */
+ memcpy(&s->sequence, &sequence_parameters_defaults[video_format],
+ sizeof(s->sequence));
+
+ /* Fill in defaults for the decoding parameters. */
+ memcpy(&s->decoding, &decoding_parameters_defaults[video_format],
+ sizeof(s->decoding));
/* Set custom dimensions. */
if (get_bits(gb, 1)) {
- s->luma_width = dirac_golomb(gb);
- s->luma_height = dirac_golomb(gb);
+ s->sequence.luma_width = dirac_golomb(gb);
+ s->sequence.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. */
+ s->sequence.chroma_format = dirac_golomb(gb);
+ dprintf (avctx, "Chroma index: %d\n", s->sequence.chroma_format);
+ }
+ /* Set the chroma dimensions. */
+ switch (s->sequence.chroma_format) {
+ case 0:
+ /* 4:4:4 */
+ s->sequence.chroma_width = s->sequence.luma_width;
+ s->sequence.chroma_height = s->sequence.luma_height;
+ break;
+
+ case 1:
+ /* 4:2:2 */
+ s->sequence.chroma_width = s->sequence.luma_width >> 1;
+ s->sequence.chroma_height = s->sequence.luma_height;
+ break;
+
+ case 2:
+ /* 4:2:0 */
+ s->sequence.chroma_width = s->sequence.luma_width >> 1;
+ s->sequence.chroma_height = s->sequence.luma_height >> 1;
+ break;
}
+ /* Override the video depth. */
if (get_bits(gb, 1)) {
- s->depth = dirac_golomb(gb);
- dprintf (avctx, "override depth: %d\n", s->depth);
+ s->sequence.video_depth = dirac_golomb(gb);
+ dprintf (avctx, "override depth: %d\n", s->sequence.video_depth);
}
- dprintf(avctx, "Video mode: %dx%d@%d\n", s->luma_width, s->luma_height, s->depth);
+ dprintf(avctx, "Video mode: %dx%d@%d\n", s->sequence.luma_width, s->sequence.luma_height, s->sequence.video_depth);
/* Access Unit Source parameters. */
-
if (get_bits(gb, 1)) {
/* Interlace. */
+ s->source.interlaced = get_bits(gb, 1);
+
+ if (s->source.interlaced) {
+ if (get_bits(gb, 1))
+ s->source.top_field_first = get_bits(gb, 1);
+
+ if (get_bits(gb, 1))
+ s->source.sequential_fields = get_bits(gb, 1);
+ }
+
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);
+ s->source.frame_rate.num = dirac_golomb(gb);
+ s->source.frame_rate.den = dirac_golomb(gb);
dprintf (avctx, "Framerate index: %d/%d = %f\n",
- s->framerate_numer, s->framerate_denom,
- (double) s->framerate_numer / s->framerate_denom);
+ s->source.frame_rate.num, s->source.frame_rate.den,
+ (double) s->source.frame_rate.num / s->source.frame_rate.den);
+
+ } else {
+ /* Use a pre-set framerate. */
+ s->source.frame_rate = preset_frame_rates[idx - 1];
+ }
+ }
+ /* Override aspect ratio. */
+ if (get_bits(gb, 1)) {
+ int idx = dirac_golomb(gb);
+ if (! idx) {
+ s->source.aspect_ratio.num = dirac_golomb(gb);
+ s->source.aspect_ratio.den = dirac_golomb(gb);
+ } else {
+ /* Use a pre-set aspect ratio. */
+ s->source.aspect_ratio = preset_aspect_ratios[idx - 1];
}
- /* XXX: else use presets from Appendix E. */
}
- /* Clean area. */
+
+ /* Override 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);
+ s->source.clean_width = dirac_golomb(gb);
+ s->source.clean_height = dirac_golomb(gb);
+ s->source.clean_left_offset = dirac_golomb(gb);
+ s->source.clean_right_offset = dirac_golomb(gb);
+ dprintf (avctx, "Clean area %dx%d %d:%d\n", s->source.clean_width, s->source.clean_height,
+ s->source.clean_left_offset, s->source.clean_right_offset);
}
- /* Signal range. */
+ /* Override signal range. */
if (get_bits(gb, 1)) {
- dprintf(avctx, "Signal range flag\n");
+ int idx = dirac_golomb(gb);
+ if (! idx) {
+ s->source.luma_offset = dirac_golomb(gb);
+ s->source.luma_excursion = dirac_golomb(gb);
+ s->source.chroma_offset = dirac_golomb(gb);
+ s->source.chroma_excursion = dirac_golomb(gb);
+ } else {
+ /* Use a pre-set signal range. */
+ s->source.luma_offset = preset_luma_offset[idx - 1];
+ s->source.luma_excursion = preset_luma_excursion[idx - 1];
+ s->source.chroma_offset = preset_chroma_offset[idx - 1];
+ s->source.chroma_excursion = preset_chroma_excursion[idx - 1];
+ }
+ dprintf(avctx, "Signal range flag: %d\n", idx);
}
/* 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 */
+ s->source.color_primaries = preset_primaries[idx];
+ s->source.k_r = preset_kr[preset_matrix[idx]];
+ s->source.k_b = preset_kb[preset_matrix[idx]];
+ s->source.transfer_function = preset_transfer_func[idx];
- if (idx == 0) {
+ /* XXX: color_spec? */
+
+ if (! idx) {
/* Color primaries. */
if (get_bits(gb, 1)) {
+ int primaries_idx = dirac_golomb(gb);
+ s->source.color_primaries = preset_primaries[primaries_idx];
+
dprintf(avctx, "Color primaries flag\n");
}
+ /* Override matrix. */
+ if (get_bits(gb, 1)) {
+ int matrix_idx = dirac_golomb(gb);
+
+ s->source.k_r = preset_kr[preset_matrix[matrix_idx]];
+ s->source.k_b = preset_kb[preset_matrix[matrix_idx]];
+
+ dprintf(avctx, "matrix flag\n");
+
+ }
+
/* Transfer function. */
if (get_bits(gb, 1)) {
+ int transfer_idx = dirac_golomb(gb);
+ s->source.transfer_function = preset_transfer_func[transfer_idx];
+
dprintf(avctx, "Transfer function flag\n");
}
+ } else {
}
+
+ dprintf(avctx, "Color specification flag\n");
+ dprintf (avctx, "Color spec idx: %d\n", idx);
}
dprintf (avctx, "Header read!\n");
@@ -511,6 +760,11 @@ static void codeblock (AVCodecContext *a
int blockcnt = s->codeblocksh[level] * s->codeblocksv[level];
int zero = 0;
+ int bottom;
+ int top;
+ int left;
+ int right;
+
if (blockcnt != 1) {
/* Determine if this codeblock is a zero block. */
zero = arith_get_bit(gb, ARITH_CONTEXT_ZERO_BLOCK);
@@ -520,6 +774,9 @@ static void codeblock (AVCodecContext *a
return; /* All coefficients remain 0. */
/* XXX: Quantization. */
+
+ // left = (width * x) /
+
}
static int subband (AVCodecContext *avctx, GetBitContext *gb, int level, subband_t band) {
More information about the FFmpeg-soc
mailing list