codecparsers: vc1: fix VLC decoding.
This commit is contained in:
parent
1a1935dacf
commit
52d8510ee0
@ -100,6 +100,13 @@ ensure_debug_category (void)
|
|||||||
} \
|
} \
|
||||||
} G_STMT_END
|
} G_STMT_END
|
||||||
|
|
||||||
|
typedef struct _VLCTable
|
||||||
|
{
|
||||||
|
guint value;
|
||||||
|
guint cword;
|
||||||
|
guint cbits;
|
||||||
|
} VLCTable;
|
||||||
|
|
||||||
const guint8 vc1_pquant_table[3][32] = {
|
const guint8 vc1_pquant_table[3][32] = {
|
||||||
{ /* Implicit quantizer */
|
{ /* Implicit quantizer */
|
||||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 6, 7, 8, 9, 10, 11, 12,
|
0, 1, 2, 3, 4, 5, 6, 7, 8, 6, 7, 8, 9, 10, 11, 12,
|
||||||
@ -140,30 +147,34 @@ const guint8 mvmode2_table[2][4] = {
|
|||||||
GST_VC1_MVMODE_1MV_HPEL_BILINEAR}
|
GST_VC1_MVMODE_1MV_HPEL_BILINEAR}
|
||||||
};
|
};
|
||||||
|
|
||||||
static const guint bfraction_vlc_table[] = {
|
#define GST_VC1_BFRACTION_RESERVED (GST_VC1_BFRACTION_BASIS + 1)
|
||||||
0x00, 3, 128,
|
#define GST_VC1_BFRACTION_PTYPE_BI (GST_VC1_BFRACTION_BASIS + 2)
|
||||||
0x01, 3, 85,
|
|
||||||
0x02, 3, 170,
|
/* Table 40: BFRACTION VLC Table */
|
||||||
0x03, 3, 64,
|
static const VLCTable vc1_bfraction_vlc_table[] = {
|
||||||
0x04, 3, 192,
|
{GST_VC1_BFRACTION_BASIS / 2, 0x00, 3},
|
||||||
0x05, 3, 51,
|
{GST_VC1_BFRACTION_BASIS / 3, 0x01, 3},
|
||||||
0x06, 3, 102,
|
{(GST_VC1_BFRACTION_BASIS * 2) / 3, 0x02, 3},
|
||||||
0x70, 3, 153,
|
{GST_VC1_BFRACTION_BASIS / 4, 0x02, 3},
|
||||||
0x71, 7, 204,
|
{(GST_VC1_BFRACTION_BASIS * 3) / 4, 0x04, 3},
|
||||||
0x72, 7, 43,
|
{GST_VC1_BFRACTION_BASIS / 5, 0x05, 3},
|
||||||
0x73, 7, 215,
|
{(GST_VC1_BFRACTION_BASIS * 2) / 5, 0x06, 3},
|
||||||
0x74, 7, 37,
|
{(GST_VC1_BFRACTION_BASIS * 3) / 5, 0x70, 7},
|
||||||
0x75, 7, 74,
|
{(GST_VC1_BFRACTION_BASIS * 4) / 5, 0x71, 7},
|
||||||
0x76, 7, 111,
|
{GST_VC1_BFRACTION_BASIS / 6, 0x72, 7},
|
||||||
0x77, 7, 148,
|
{(GST_VC1_BFRACTION_BASIS * 5) / 6, 0x73, 7},
|
||||||
0x78, 7, 185,
|
{GST_VC1_BFRACTION_BASIS / 7, 0x74, 7},
|
||||||
0x79, 7, 222,
|
{(GST_VC1_BFRACTION_BASIS * 2) / 7, 0x75, 7},
|
||||||
0x7a, 7, 32,
|
{(GST_VC1_BFRACTION_BASIS * 3) / 7, 0x76, 7},
|
||||||
0x7b, 7, 96,
|
{(GST_VC1_BFRACTION_BASIS * 4) / 7, 0x77, 7},
|
||||||
0x7c, 7, 160,
|
{(GST_VC1_BFRACTION_BASIS * 5) / 7, 0x78, 7},
|
||||||
0x7d, 7, 224,
|
{(GST_VC1_BFRACTION_BASIS * 6) / 7, 0x79, 7},
|
||||||
0x7e, 7, 0, /* Indicate sthat it is smtpe reserved */
|
{GST_VC1_BFRACTION_BASIS / 8, 0x7a, 7},
|
||||||
0x7f, 7, GST_VC1_PICTURE_TYPE_BI
|
{(GST_VC1_BFRACTION_BASIS * 3) / 8, 0x7b, 7},
|
||||||
|
{(GST_VC1_BFRACTION_BASIS * 5) / 8, 0x7c, 7},
|
||||||
|
{(GST_VC1_BFRACTION_BASIS * 7) / 8, 0x7d, 7},
|
||||||
|
{GST_VC1_BFRACTION_RESERVED, 0x7e, 7},
|
||||||
|
{GST_VC1_BFRACTION_PTYPE_BI, 0x7f, 7}
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Imode types */
|
/* Imode types */
|
||||||
@ -178,88 +189,91 @@ enum
|
|||||||
IMODE_COLSKIP
|
IMODE_COLSKIP
|
||||||
};
|
};
|
||||||
|
|
||||||
static const guint imode_vlc_table[] = {
|
/* Table 69: IMODE VLC Codetable */
|
||||||
0x02, 2, IMODE_NORM2, /* 10 */
|
static const VLCTable vc1_imode_vlc_table[] = {
|
||||||
0x03, 2, IMODE_NORM6, /* 11 */
|
{IMODE_NORM2, 0x02, 2},
|
||||||
0x02, 3, IMODE_ROWSKIP, /* 010 */
|
{IMODE_NORM6, 0x03, 2},
|
||||||
0x03, 3, IMODE_COLSKIP, /* 011 */
|
{IMODE_ROWSKIP, 0x02, 3},
|
||||||
0x01, 3, IMODE_DIFF2, /* 001 */
|
{IMODE_COLSKIP, 0x03, 3},
|
||||||
0x01, 4, IMODE_DIFF6, /* 0001 */
|
{IMODE_DIFF2, 0x01, 3},
|
||||||
0x00, 4, IMODE_RAW /* 0000 */
|
{IMODE_DIFF6, 0x01, 4},
|
||||||
|
{IMODE_RAW, 0x00, 4}
|
||||||
};
|
};
|
||||||
|
|
||||||
const guint vc1_norm2_codes_vlc_table[] = {
|
/* Table 80: Norm-2/Diff-2 Code Table */
|
||||||
0x00, 1, 1,
|
static const VLCTable vc1_norm2_vlc_table[4] = {
|
||||||
0x03, 2, 3,
|
{0, 0, 1},
|
||||||
0x04, 3, 3,
|
{2, 4, 3},
|
||||||
0x05, 3, 2
|
{1, 5, 3},
|
||||||
|
{3, 3, 2}
|
||||||
};
|
};
|
||||||
|
|
||||||
const guint norm6_vlc_table[256] = {
|
/* Table 81: Code table for 3x2 and 2x3 tiles */
|
||||||
0x001, 1, 0,
|
static const VLCTable vc1_norm6_vlc_table[64] = {
|
||||||
0x002, 4, 0,
|
{0, 1, 1},
|
||||||
0x003, 4, 0,
|
{1, 2, 4},
|
||||||
0x004, 4, 0,
|
{2, 3, 4},
|
||||||
0x005, 4, 0,
|
{3, 0, 8},
|
||||||
0x006, 4, 0,
|
{4, 4, 4},
|
||||||
0x007, 4, 0,
|
{5, 1, 8},
|
||||||
0x007, 6, 0,
|
{6, 2, 8},
|
||||||
0x000, 8, 0,
|
{7, (2 << 5) | 7, 10},
|
||||||
0x001, 8, 0,
|
{8, 5, 4},
|
||||||
0x002, 8, 0,
|
{9, 3, 8},
|
||||||
0x003, 8, 0,
|
{10, 4, 8},
|
||||||
0x004, 8, 0,
|
{11, (2 << 5) | 11, 10},
|
||||||
0x005, 8, 0,
|
{12, 5, 8},
|
||||||
0x006, 8, 0,
|
{13, (2 << 5) | 13, 10},
|
||||||
0x007, 8, 0,
|
{14, (2 << 5) | 14, 10},
|
||||||
0x008, 8, 0,
|
{15, (3 << 8) | 14, 13},
|
||||||
0x009, 8, 0,
|
{16, 6, 4},
|
||||||
0x00A, 8, 0,
|
{17, 6, 8},
|
||||||
0x00B, 8, 0,
|
{18, 7, 8},
|
||||||
0x00C, 8, 0,
|
{19, (2 << 5) | 19, 10},
|
||||||
0x00D, 8, 0,
|
{20, 8, 8},
|
||||||
0x00E, 8, 0,
|
{21, (2 << 5) | 21, 10},
|
||||||
0x037, 9, 0,
|
{22, (2 << 5) | 22, 10},
|
||||||
0x036, 9, 0,
|
{23, (3 << 8) | 13, 13},
|
||||||
0x035, 9, 0,
|
{24, 9, 8},
|
||||||
0x034, 9, 0,
|
{25, (2 << 5) | 25, 10},
|
||||||
0x033, 9, 0,
|
{26, (2 << 5) | 26, 10},
|
||||||
0x032, 9, 0,
|
{27, (3 << 8) | 12, 13},
|
||||||
0x047, 10, 0,
|
{28, (2 << 5) | 28, 10},
|
||||||
0x04B, 10, 0,
|
{29, (3 << 8) | 11, 13},
|
||||||
0x04D, 10, 0,
|
{30, (3 << 8) | 10, 13},
|
||||||
0x04E, 10, 0,
|
{31, (3 << 4) | 7, 9},
|
||||||
0x30E, 13, 0,
|
{32, 7, 4},
|
||||||
0x053, 10, 0,
|
{33, 10, 8},
|
||||||
0x055, 10, 0,
|
{34, 11, 8},
|
||||||
0x056, 10, 0,
|
{35, (2 << 5) | 3, 10},
|
||||||
0x30D, 13, 0,
|
{36, 12, 8},
|
||||||
0x059, 10, 0,
|
{37, (2 << 5) | 5, 10},
|
||||||
0x05A, 10, 0,
|
{38, (2 << 5) | 6, 10},
|
||||||
0x30C, 13, 0,
|
{39, (3 << 8) | 9, 13},
|
||||||
0x05C, 10, 0,
|
{40, 13, 8},
|
||||||
0x30B, 13, 0,
|
{41, (2 << 5) | 9, 10},
|
||||||
0x30A, 13, 0,
|
{42, (2 << 5) | 10, 10},
|
||||||
0x043, 10, 0,
|
{43, (3 << 8) | 8, 13},
|
||||||
0x045, 10, 0,
|
{44, (2 << 5) | 12, 10},
|
||||||
0x046, 10, 0,
|
{45, (3 << 8) | 7, 13},
|
||||||
0x309, 13, 0,
|
{46, (3 << 8) | 6, 13},
|
||||||
0x049, 10, 0,
|
{47, (3 << 4) | 6, 9},
|
||||||
0x04A, 10, 0,
|
{48, 14, 8},
|
||||||
0x308, 13, 0,
|
{49, (2 << 5) | 17, 10},
|
||||||
0x04C, 10, 0,
|
{50, (2 << 5) | 18, 10},
|
||||||
0x307, 13, 0,
|
{51, (3 << 8) | 5, 13},
|
||||||
0x306, 13, 0,
|
{52, (2 << 5) | 20, 10},
|
||||||
0x051, 10, 0,
|
{53, (3 << 8) | 4, 13},
|
||||||
0x052, 10, 0,
|
{54, (3 << 8) | 3, 13},
|
||||||
0x305, 13, 0,
|
{55, (3 << 4) | 5, 9},
|
||||||
0x054, 10, 0,
|
{56, (2 << 5) | 24, 10},
|
||||||
0x304, 13, 0,
|
{57, (3 << 8) | 2, 13},
|
||||||
0x303, 13, 0,
|
{58, (3 << 8) | 1, 13},
|
||||||
0x058, 10, 0,
|
{59, (3 << 4) | 4, 9},
|
||||||
0x302, 13, 0,
|
{60, (3 << 8) | 0, 13},
|
||||||
0x301, 13, 0,
|
{61, (3 << 4) | 3, 9},
|
||||||
0x300, 13, 0
|
{62, (3 << 4) | 2, 9},
|
||||||
|
{63, (3 << 1) | 1, 6}
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline guint8
|
static inline guint8
|
||||||
@ -345,32 +359,26 @@ calculate_nb_pan_scan_win (GstVC1AdvancedSeqHdr * advseqhdr,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* table should look like:
|
|
||||||
* {Value, nbBits, Meaning,
|
|
||||||
* ...
|
|
||||||
* } nbBits must be increasing
|
|
||||||
*/
|
|
||||||
static gboolean
|
static gboolean
|
||||||
decode_vlc (GstBitReader * br, guint * res, const guint * table, guint length)
|
decode_vlc (GstBitReader * br, guint * res, const VLCTable * table,
|
||||||
|
guint length)
|
||||||
{
|
{
|
||||||
guint8 i;
|
guint8 i;
|
||||||
guint cbits = 0;
|
guint cbits = 0;
|
||||||
guint32 value = 0;
|
guint32 value = 0;
|
||||||
|
|
||||||
for (i = 0; i < length; i += 3) {
|
for (i = 0; i < length; i++) {
|
||||||
if (cbits != table[i + 1]) {
|
if (cbits != table[i].cbits) {
|
||||||
cbits = table[i + 1];
|
cbits = table[i].cbits;
|
||||||
if (!gst_bit_reader_peek_bits_uint32 (br, &value, cbits)) {
|
if (!gst_bit_reader_peek_bits_uint32 (br, &value, cbits)) {
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value == table[i]) {
|
if (value == table[i].cword) {
|
||||||
SKIP (br, cbits);
|
SKIP (br, cbits);
|
||||||
if (res)
|
if (res)
|
||||||
*res = table[i + 2];
|
*res = table[i].value;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -393,7 +401,8 @@ bitplane_decoding (GstBitReader * br, guint height,
|
|||||||
guint i, j, offset = 0;
|
guint i, j, offset = 0;
|
||||||
|
|
||||||
SKIP (br, 1);
|
SKIP (br, 1);
|
||||||
if (!decode_vlc (br, &imode, imode_vlc_table, G_N_ELEMENTS (imode_vlc_table)))
|
if (!decode_vlc (br, &imode, vc1_imode_vlc_table,
|
||||||
|
G_N_ELEMENTS (vc1_imode_vlc_table)))
|
||||||
goto failed;
|
goto failed;
|
||||||
|
|
||||||
switch (imode) {
|
switch (imode) {
|
||||||
@ -415,8 +424,8 @@ bitplane_decoding (GstBitReader * br, guint height,
|
|||||||
|
|
||||||
for (i = offset; i < height * width; i += 2) {
|
for (i = offset; i < height * width; i += 2) {
|
||||||
/*guint x; */
|
/*guint x; */
|
||||||
if (!decode_vlc (br, NULL, vc1_norm2_codes_vlc_table,
|
if (!decode_vlc (br, NULL, vc1_norm2_vlc_table,
|
||||||
G_N_ELEMENTS (vc1_norm2_codes_vlc_table))) {
|
G_N_ELEMENTS (vc1_norm2_vlc_table))) {
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -431,8 +440,8 @@ bitplane_decoding (GstBitReader * br, guint height,
|
|||||||
|
|
||||||
for (i = 0; i < height; i += 3) {
|
for (i = 0; i < height; i += 3) {
|
||||||
for (j = width & 1; j < width; j += 2) {
|
for (j = width & 1; j < width; j += 2) {
|
||||||
if (!decode_vlc (br, NULL, norm6_vlc_table,
|
if (!decode_vlc (br, NULL, vc1_norm6_vlc_table,
|
||||||
G_N_ELEMENTS (norm6_vlc_table))) {
|
G_N_ELEMENTS (vc1_norm6_vlc_table))) {
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -440,8 +449,8 @@ bitplane_decoding (GstBitReader * br, guint height,
|
|||||||
} else {
|
} else {
|
||||||
for (i = height & 1; i < height; i += 2) {
|
for (i = height & 1; i < height; i += 2) {
|
||||||
for (j = width % 3; j < width; j += 3) {
|
for (j = width % 3; j < width; j += 3) {
|
||||||
if (!decode_vlc (br, NULL, norm6_vlc_table,
|
if (!decode_vlc (br, NULL, vc1_norm6_vlc_table,
|
||||||
G_N_ELEMENTS (norm6_vlc_table))) {
|
G_N_ELEMENTS (vc1_norm6_vlc_table))) {
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -806,13 +815,13 @@ parse_frame_header_advanced (GstBitReader * br, GstVC1FrameHdr * framehdr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (framehdr->ptype == GST_VC1_PICTURE_TYPE_B) {
|
if (framehdr->ptype == GST_VC1_PICTURE_TYPE_B) {
|
||||||
if (!decode_vlc (br, (guint *) & pic->bfraction, bfraction_vlc_table,
|
if (!decode_vlc (br, (guint *) & pic->bfraction, vc1_bfraction_vlc_table,
|
||||||
G_N_ELEMENTS (bfraction_vlc_table)))
|
G_N_ELEMENTS (vc1_bfraction_vlc_table)))
|
||||||
goto failed;
|
goto failed;
|
||||||
|
|
||||||
GST_DEBUG ("bfraction %u", pic->bfraction);
|
GST_DEBUG ("bfraction %u", pic->bfraction);
|
||||||
|
|
||||||
if (pic->bfraction == GST_VC1_PICTURE_TYPE_BI) {
|
if (pic->bfraction == GST_VC1_BFRACTION_PTYPE_BI) {
|
||||||
framehdr->ptype = GST_VC1_PICTURE_TYPE_BI;
|
framehdr->ptype = GST_VC1_PICTURE_TYPE_BI;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1033,11 +1042,11 @@ parse_frame_header (GstBitReader * br, GstVC1FrameHdr * framehdr,
|
|||||||
|
|
||||||
if (framehdr->ptype == GST_VC1_PICTURE_TYPE_B) {
|
if (framehdr->ptype == GST_VC1_PICTURE_TYPE_B) {
|
||||||
|
|
||||||
if (!decode_vlc (br, (guint *) & pic->bfraction, bfraction_vlc_table,
|
if (!decode_vlc (br, (guint *) & pic->bfraction, vc1_bfraction_vlc_table,
|
||||||
G_N_ELEMENTS (bfraction_vlc_table)))
|
G_N_ELEMENTS (vc1_bfraction_vlc_table)))
|
||||||
goto failed;
|
goto failed;
|
||||||
|
|
||||||
if (pic->bfraction == GST_VC1_PICTURE_TYPE_BI) {
|
if (pic->bfraction == GST_VC1_BFRACTION_PTYPE_BI) {
|
||||||
framehdr->ptype = GST_VC1_PICTURE_TYPE_BI;
|
framehdr->ptype = GST_VC1_PICTURE_TYPE_BI;
|
||||||
}
|
}
|
||||||
GST_DEBUG ("bfraction= %d", pic->bfraction);
|
GST_DEBUG ("bfraction= %d", pic->bfraction);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user