mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-26 17:18:15 +00:00
codecs: gstvp9{decoder|statefulparser}: optionally parse compressed headers
Rework gstvp9{decoder|statefulparser} to optionally parse compressed headers. The information in these headers might be needed for accelerators downstream, so optionally parse them if downstream requests it. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1012>
This commit is contained in:
parent
9aaef931bf
commit
98dc7a64a0
4 changed files with 953 additions and 10 deletions
|
@ -339,8 +339,9 @@ gst_vp9_decoder_handle_frame (GstVideoDecoder * decoder,
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
pres = gst_vp9_stateful_parser_parse_frame_header (priv->parser, &frame_hdr,
|
pres =
|
||||||
map.data, map.size);
|
gst_vp9_stateful_parser_parse_uncompressed_frame_header (priv->parser,
|
||||||
|
&frame_hdr, map.data, map.size);
|
||||||
|
|
||||||
if (pres != GST_VP9_PARSER_OK) {
|
if (pres != GST_VP9_PARSER_OK) {
|
||||||
GST_ERROR_OBJECT (self, "Failed to parsing frame header");
|
GST_ERROR_OBJECT (self, "Failed to parsing frame header");
|
||||||
|
@ -348,6 +349,18 @@ gst_vp9_decoder_handle_frame (GstVideoDecoder * decoder,
|
||||||
goto unmap_and_error;
|
goto unmap_and_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (self->parse_compressed_headers && !frame_hdr.show_existing_frame) {
|
||||||
|
pres =
|
||||||
|
gst_vp9_stateful_parser_parse_compressed_frame_header (priv->parser,
|
||||||
|
&frame_hdr, map.data + frame_hdr.frame_header_length_in_bytes,
|
||||||
|
map.size);
|
||||||
|
|
||||||
|
if (pres != GST_VP9_PARSER_OK) {
|
||||||
|
GST_ERROR_OBJECT (self, "Failed to parse the compressed frame header");
|
||||||
|
goto unmap_and_error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (frame_hdr.show_existing_frame) {
|
if (frame_hdr.show_existing_frame) {
|
||||||
/* This is a non-intra, dummy frame */
|
/* This is a non-intra, dummy frame */
|
||||||
intra_only = FALSE;
|
intra_only = FALSE;
|
||||||
|
|
|
@ -51,6 +51,7 @@ struct _GstVp9Decoder
|
||||||
|
|
||||||
/*< protected >*/
|
/*< protected >*/
|
||||||
GstVideoCodecState * input_state;
|
GstVideoCodecState * input_state;
|
||||||
|
gboolean parse_compressed_headers;
|
||||||
|
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
GstVp9DecoderPrivate *priv;
|
GstVp9DecoderPrivate *priv;
|
||||||
|
|
|
@ -149,6 +149,550 @@ ensure_debug_category (void)
|
||||||
#define CHECK_ALLOWED(val, min, max) \
|
#define CHECK_ALLOWED(val, min, max) \
|
||||||
CHECK_ALLOWED_WITH_DEBUG (G_STRINGIFY (val), val, min, max)
|
CHECK_ALLOWED_WITH_DEBUG (G_STRINGIFY (val), val, min, max)
|
||||||
|
|
||||||
|
typedef struct _Vp9BoolDecoder
|
||||||
|
{
|
||||||
|
guint64 value;
|
||||||
|
guint32 range;
|
||||||
|
guint32 bits_left;
|
||||||
|
gint count_to_fill;
|
||||||
|
GstBitReader *bit_reader;
|
||||||
|
gboolean out_of_bits;
|
||||||
|
} Vp9BoolDecoder;
|
||||||
|
|
||||||
|
/* how much to shift to get range > 128 */
|
||||||
|
const static guint8 bool_shift_table[256] = {
|
||||||
|
0, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||||
|
3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||||
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const guint8 inv_map_table[255] = {
|
||||||
|
7, 20, 33, 46, 59, 72, 85, 98, 111, 124, 137, 150, 163, 176,
|
||||||
|
189, 202, 215, 228, 241, 254, 1, 2, 3, 4, 5, 6, 8, 9,
|
||||||
|
10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 22, 23, 24,
|
||||||
|
25, 26, 27, 28, 29, 30, 31, 32, 34, 35, 36, 37, 38, 39,
|
||||||
|
40, 41, 42, 43, 44, 45, 47, 48, 49, 50, 51, 52, 53, 54,
|
||||||
|
55, 56, 57, 58, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
|
||||||
|
70, 71, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
|
||||||
|
86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 99, 100,
|
||||||
|
101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 112, 113, 114, 115,
|
||||||
|
116, 117, 118, 119, 120, 121, 122, 123, 125, 126, 127, 128, 129, 130,
|
||||||
|
131, 132, 133, 134, 135, 136, 138, 139, 140, 141, 142, 143, 144, 145,
|
||||||
|
146, 147, 148, 149, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160,
|
||||||
|
161, 162, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
|
||||||
|
177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 190, 191,
|
||||||
|
192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 203, 204, 205, 206,
|
||||||
|
207, 208, 209, 210, 211, 212, 213, 214, 216, 217, 218, 219, 220, 221,
|
||||||
|
222, 223, 224, 225, 226, 227, 229, 230, 231, 232, 233, 234, 235, 236,
|
||||||
|
237, 238, 239, 240, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251,
|
||||||
|
252, 253, 253,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
fill_bool (Vp9BoolDecoder * bd)
|
||||||
|
{
|
||||||
|
guint max_bits_to_read;
|
||||||
|
guint bits_to_read;
|
||||||
|
guint64 data;
|
||||||
|
|
||||||
|
if (G_UNLIKELY (bd->bits_left < bd->count_to_fill)) {
|
||||||
|
GST_ERROR
|
||||||
|
("Invalid VP9 bitstream: the boolean decoder ran out of bits to read");
|
||||||
|
bd->out_of_bits = TRUE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
max_bits_to_read =
|
||||||
|
8 * (sizeof (bd->value) - sizeof (guint8)) + bd->count_to_fill;
|
||||||
|
bits_to_read = MIN (max_bits_to_read, bd->bits_left);
|
||||||
|
|
||||||
|
data =
|
||||||
|
gst_bit_reader_get_bits_uint64_unchecked (bd->bit_reader, bits_to_read);
|
||||||
|
|
||||||
|
bd->value |= data << (max_bits_to_read - bits_to_read);
|
||||||
|
bd->count_to_fill -= bits_to_read;
|
||||||
|
bd->bits_left -= bits_to_read;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
read_bool (Vp9BoolDecoder * bd, guint8 probability)
|
||||||
|
{
|
||||||
|
guint64 split;
|
||||||
|
guint64 big_split;
|
||||||
|
guint count;
|
||||||
|
gboolean bit;
|
||||||
|
|
||||||
|
if (bd->count_to_fill > 0)
|
||||||
|
fill_bool (bd);
|
||||||
|
|
||||||
|
split = 1 + (((bd->range - 1) * probability) >> 8);
|
||||||
|
big_split = split << 8 * (sizeof (bd->value) - sizeof (guint8));
|
||||||
|
|
||||||
|
if (bd->value < big_split) {
|
||||||
|
bd->range = split;
|
||||||
|
bit = FALSE;
|
||||||
|
} else {
|
||||||
|
bd->range -= split;
|
||||||
|
bd->value -= big_split;
|
||||||
|
bit = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
count = bool_shift_table[bd->range];
|
||||||
|
bd->range <<= count;
|
||||||
|
bd->value <<= count;
|
||||||
|
bd->count_to_fill += count;
|
||||||
|
|
||||||
|
return bit;
|
||||||
|
}
|
||||||
|
|
||||||
|
static guint
|
||||||
|
read_literal (Vp9BoolDecoder * bd, guint n)
|
||||||
|
{
|
||||||
|
guint ret = 0;
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
for (i = 0; G_UNLIKELY (!bd->out_of_bits) && i < n; i++) {
|
||||||
|
ret = 2 * ret + read_bool (bd, 128);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GstVp9ParserResult
|
||||||
|
init_bool (Vp9BoolDecoder * bd, GstBitReader * br, guint size_in_bytes)
|
||||||
|
{
|
||||||
|
gboolean marker_bit;
|
||||||
|
|
||||||
|
if (size_in_bytes < 1)
|
||||||
|
GST_ERROR ("VP9 Boolean Decoder has no bits to read");
|
||||||
|
|
||||||
|
if ((gst_bit_reader_get_pos (br) % 8) != 0)
|
||||||
|
GST_ERROR ("VP9 Boolean Decoder was passed an unaligned buffer");
|
||||||
|
|
||||||
|
bd->value = 0;
|
||||||
|
bd->range = 255;
|
||||||
|
bd->bits_left = 8 * size_in_bytes;
|
||||||
|
bd->bit_reader = br;
|
||||||
|
bd->count_to_fill = 8;
|
||||||
|
bd->out_of_bits = FALSE;
|
||||||
|
|
||||||
|
marker_bit = read_literal (bd, 1);
|
||||||
|
if (marker_bit != 0) {
|
||||||
|
GST_ERROR ("Marker bit should be zero was %d", marker_bit);
|
||||||
|
return GST_VP9_PARSER_BROKEN_DATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
return GST_VP9_PARSER_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GstVp9ParserResult
|
||||||
|
exit_bool (Vp9BoolDecoder * bd)
|
||||||
|
{
|
||||||
|
guint8 padding;
|
||||||
|
guint8 bits = bd->bits_left;
|
||||||
|
guint8 n;
|
||||||
|
|
||||||
|
while (bits) {
|
||||||
|
n = MIN (bits, 8);
|
||||||
|
padding = gst_bit_reader_get_bits_uint32_unchecked (bd->bit_reader, n);
|
||||||
|
if (padding != 0 || (n < 8 && (padding & 0xe0) == 0xc0)) {
|
||||||
|
GST_ERROR
|
||||||
|
("Invalid padding at end of frame. Total padding bits is %d and the wrong byte is: %x",
|
||||||
|
bd->bits_left, padding);
|
||||||
|
return GST_VP9_PARSER_BROKEN_DATA;
|
||||||
|
}
|
||||||
|
bits -= n;
|
||||||
|
}
|
||||||
|
|
||||||
|
return GST_VP9_PARSER_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static guint
|
||||||
|
decode_term_subexp (Vp9BoolDecoder * bd)
|
||||||
|
{
|
||||||
|
guint8 bit;
|
||||||
|
guint v;
|
||||||
|
/* only coded if update_prob is set */
|
||||||
|
gboolean prob_is_coded_in_bitstream;
|
||||||
|
guint delta;
|
||||||
|
|
||||||
|
prob_is_coded_in_bitstream = read_bool (bd, 252);
|
||||||
|
if (!prob_is_coded_in_bitstream)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
bit = read_literal (bd, 1);
|
||||||
|
if (bit == 0) {
|
||||||
|
delta = read_literal (bd, 4);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
bit = read_literal (bd, 1);
|
||||||
|
if (bit == 0) {
|
||||||
|
delta = read_literal (bd, 4) + 16;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
bit = read_literal (bd, 1);
|
||||||
|
if (bit == 0) {
|
||||||
|
delta = read_literal (bd, 5) + 32;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
v = read_literal (bd, 7);
|
||||||
|
if (v < 65) {
|
||||||
|
delta = v + 64;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
bit = read_literal (bd, 1);
|
||||||
|
delta = (v << 1) - 1 + bit;
|
||||||
|
end:
|
||||||
|
return inv_map_table[delta];
|
||||||
|
}
|
||||||
|
|
||||||
|
static guint8
|
||||||
|
read_mv_prob (Vp9BoolDecoder * bd)
|
||||||
|
{
|
||||||
|
gboolean update_mv_prob;
|
||||||
|
guint8 mv_prob;
|
||||||
|
guint8 prob = 0;
|
||||||
|
|
||||||
|
update_mv_prob = read_bool (bd, 252);
|
||||||
|
if (update_mv_prob) {
|
||||||
|
mv_prob = read_literal (bd, 7);
|
||||||
|
prob = (mv_prob << 1) | 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return prob;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GstVp9ParserResult
|
||||||
|
parse_mv_probs (GstVp9FrameHeader * hdr, Vp9BoolDecoder * bd)
|
||||||
|
{
|
||||||
|
guint i, j, k;
|
||||||
|
|
||||||
|
for (j = 0; j < GST_VP9_MV_JOINTS - 1; j++)
|
||||||
|
hdr->delta_probabilities.mv.joint[j] = read_mv_prob (bd);
|
||||||
|
|
||||||
|
for (i = 0; i < 2; i++) {
|
||||||
|
hdr->delta_probabilities.mv.sign[i] = read_mv_prob (bd);
|
||||||
|
|
||||||
|
for (j = 0; j < GST_VP9_MV_CLASSES - 1; j++)
|
||||||
|
hdr->delta_probabilities.mv.klass[i][j] = read_mv_prob (bd);
|
||||||
|
|
||||||
|
hdr->delta_probabilities.mv.class0_bit[i] = read_mv_prob (bd);
|
||||||
|
|
||||||
|
for (j = 0; j < GST_VP9_MV_OFFSET_BITS; j++)
|
||||||
|
hdr->delta_probabilities.mv.bits[i][j] = read_mv_prob (bd);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 2; i++) {
|
||||||
|
for (j = 0; j < GST_VP9_CLASS0_SIZE; j++)
|
||||||
|
for (k = 0; k < GST_VP9_MV_FR_SIZE - 1; k++)
|
||||||
|
hdr->delta_probabilities.mv.class0_fr[i][j][k] = read_mv_prob (bd);
|
||||||
|
|
||||||
|
for (k = 0; k < GST_VP9_MV_FR_SIZE - 1; k++)
|
||||||
|
hdr->delta_probabilities.mv.fr[i][k] = read_mv_prob (bd);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hdr->allow_high_precision_mv) {
|
||||||
|
for (i = 0; i < 2; i++) {
|
||||||
|
hdr->delta_probabilities.mv.class0_hp[i] = read_mv_prob (bd);
|
||||||
|
hdr->delta_probabilities.mv.hp[i] = read_mv_prob (bd);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return GST_VP9_PARSER_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GstVp9ParserResult
|
||||||
|
parse_partition_probs (GstVp9FrameHeader * hdr, Vp9BoolDecoder * bd)
|
||||||
|
{
|
||||||
|
guint i, j;
|
||||||
|
|
||||||
|
for (i = 0; i < GST_VP9_PARTITION_CONTEXTS; i++)
|
||||||
|
for (j = 0; j < GST_VP9_PARTITION_TYPES - 1; j++)
|
||||||
|
hdr->delta_probabilities.partition[i][j] = decode_term_subexp (bd);
|
||||||
|
|
||||||
|
return GST_VP9_PARSER_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GstVp9ParserResult
|
||||||
|
parse_y_mode_probs (GstVp9FrameHeader * hdr, Vp9BoolDecoder * bd)
|
||||||
|
{
|
||||||
|
guint i, j;
|
||||||
|
|
||||||
|
for (i = 0; i < GST_VP9_BLOCK_SIZE_GROUPS; i++)
|
||||||
|
for (j = 0; j < GST_VP9_INTRA_MODES - 1; j++)
|
||||||
|
hdr->delta_probabilities.y_mode[i][j] = decode_term_subexp (bd);
|
||||||
|
|
||||||
|
return GST_VP9_PARSER_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GstVp9ParserResult
|
||||||
|
parse_frame_reference_mode_probs (GstVp9FrameHeader * hdr, Vp9BoolDecoder * bd)
|
||||||
|
{
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
if (hdr->reference_mode == GST_VP9_REFERENCE_MODE_SELECT)
|
||||||
|
for (i = 0; i < GST_VP9_COMP_MODE_CONTEXTS; i++)
|
||||||
|
hdr->delta_probabilities.comp_mode[i] = decode_term_subexp (bd);
|
||||||
|
|
||||||
|
if (hdr->reference_mode != GST_VP9_REFERENCE_MODE_COMPOUND_REFERENCE)
|
||||||
|
for (i = 0; i < GST_VP9_REF_CONTEXTS; i++) {
|
||||||
|
hdr->delta_probabilities.single_ref[i][0] = decode_term_subexp (bd);
|
||||||
|
hdr->delta_probabilities.single_ref[i][1] = decode_term_subexp (bd);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hdr->reference_mode != GST_VP9_REFERENCE_MODE_SINGLE_REFERENCE)
|
||||||
|
for (i = 0; i < GST_VP9_REF_CONTEXTS; i++)
|
||||||
|
hdr->delta_probabilities.comp_ref[i] = decode_term_subexp (bd);
|
||||||
|
|
||||||
|
return GST_VP9_PARSER_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GstVp9ParserResult
|
||||||
|
parse_frame_reference (GstVp9FrameHeader * hdr, Vp9BoolDecoder * bd)
|
||||||
|
{
|
||||||
|
gboolean compound_ref_allowed = FALSE;
|
||||||
|
guint8 non_single_reference;
|
||||||
|
guint8 reference_select;
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
for (i = GST_VP9_REF_FRAME_LAST; i < GST_VP9_REFS_PER_FRAME; i++)
|
||||||
|
if (hdr->ref_frame_sign_bias[i + 1] !=
|
||||||
|
hdr->ref_frame_sign_bias[GST_VP9_REF_FRAME_LAST])
|
||||||
|
compound_ref_allowed = TRUE;
|
||||||
|
|
||||||
|
if (compound_ref_allowed) {
|
||||||
|
non_single_reference = read_literal (bd, 1);
|
||||||
|
if (!non_single_reference)
|
||||||
|
hdr->reference_mode = GST_VP9_REFERENCE_MODE_SINGLE_REFERENCE;
|
||||||
|
else {
|
||||||
|
reference_select = read_literal (bd, 1);
|
||||||
|
if (!reference_select)
|
||||||
|
hdr->reference_mode = GST_VP9_REFERENCE_MODE_COMPOUND_REFERENCE;
|
||||||
|
else
|
||||||
|
hdr->reference_mode = GST_VP9_REFERENCE_MODE_SELECT;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
hdr->reference_mode = GST_VP9_REFERENCE_MODE_SINGLE_REFERENCE;
|
||||||
|
|
||||||
|
return GST_VP9_PARSER_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GstVp9ParserResult
|
||||||
|
parse_is_inter_probs (GstVp9FrameHeader * hdr, Vp9BoolDecoder * bd)
|
||||||
|
{
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
for (i = 0; i < GST_VP9_IS_INTER_CONTEXTS; i++)
|
||||||
|
hdr->delta_probabilities.is_inter[i] = decode_term_subexp (bd);
|
||||||
|
|
||||||
|
return GST_VP9_PARSER_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GstVp9ParserResult
|
||||||
|
parse_interp_filter_probs (GstVp9FrameHeader * hdr, Vp9BoolDecoder * bd)
|
||||||
|
{
|
||||||
|
guint i, j;
|
||||||
|
|
||||||
|
for (i = 0; i < GST_VP9_INTERP_FILTER_CONTEXTS; i++)
|
||||||
|
for (j = 0; j < GST_VP9_SWITCHABLE_FILTERS - 1; j++)
|
||||||
|
hdr->delta_probabilities.interp_filter[i][j] = decode_term_subexp (bd);
|
||||||
|
|
||||||
|
return GST_VP9_PARSER_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GstVp9ParserResult
|
||||||
|
parse_inter_mode_probs (GstVp9FrameHeader * hdr, Vp9BoolDecoder * bd)
|
||||||
|
{
|
||||||
|
guint i, j;
|
||||||
|
|
||||||
|
for (i = 0; i < GST_VP9_INTER_MODE_CONTEXTS; i++)
|
||||||
|
for (j = 0; j < GST_VP9_INTER_MODES - 1; j++)
|
||||||
|
hdr->delta_probabilities.inter_mode[i][j] = decode_term_subexp (bd);
|
||||||
|
|
||||||
|
return GST_VP9_PARSER_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GstVp9ParserResult
|
||||||
|
parse_skip_probs (GstVp9FrameHeader * hdr, Vp9BoolDecoder * bd)
|
||||||
|
{
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
for (i = 0; i < GST_VP9_SKIP_CONTEXTS; i++)
|
||||||
|
hdr->delta_probabilities.skip[i] = decode_term_subexp (bd);
|
||||||
|
|
||||||
|
return GST_VP9_PARSER_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GstVp9ParserResult
|
||||||
|
parse_coef_probs (GstVp9FrameHeader * hdr, Vp9BoolDecoder * bd)
|
||||||
|
{
|
||||||
|
GstVp9TxSize tx_size, max_tx_size;
|
||||||
|
guint8 i, j, k, l, m;
|
||||||
|
guint8 update_probs;
|
||||||
|
|
||||||
|
static const guint8 tx_mode_to_biggest_tx_size[GST_VP9_TX_MODES] = {
|
||||||
|
GST_VP9_TX_4x4,
|
||||||
|
GST_VP9_TX_8x8,
|
||||||
|
GST_VP9_TX_16x16,
|
||||||
|
GST_VP9_TX_32x32,
|
||||||
|
GST_VP9_TX_32x32,
|
||||||
|
};
|
||||||
|
|
||||||
|
max_tx_size = tx_mode_to_biggest_tx_size[hdr->tx_mode];
|
||||||
|
for (tx_size = GST_VP9_TX_4x4; tx_size <= max_tx_size; tx_size++) {
|
||||||
|
update_probs = read_literal (bd, 1);
|
||||||
|
if (update_probs) {
|
||||||
|
for (i = 0; i < 2; i++)
|
||||||
|
for (j = 0; j < 2; j++)
|
||||||
|
for (k = 0; k < 6; k++)
|
||||||
|
for (l = 0; l < ((k == 0) ? 3 : 6); l++)
|
||||||
|
for (m = 0; m < 3; m++)
|
||||||
|
hdr->delta_probabilities.coef[tx_size][i][j][k][l][m] =
|
||||||
|
decode_term_subexp (bd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return GST_VP9_PARSER_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GstVp9ParserResult
|
||||||
|
parse_tx_mode_probs (GstVp9FrameHeader * hdr, Vp9BoolDecoder * bd)
|
||||||
|
{
|
||||||
|
guint i, j;
|
||||||
|
|
||||||
|
for (i = 0; i < GST_VP9_TX_SIZE_CONTEXTS; i++)
|
||||||
|
for (j = 0; j < GST_VP9_TX_SIZES - 3; j++)
|
||||||
|
hdr->delta_probabilities.tx_probs_8x8[i][j] = decode_term_subexp (bd);
|
||||||
|
|
||||||
|
for (i = 0; i < GST_VP9_TX_SIZE_CONTEXTS; i++)
|
||||||
|
for (j = 0; j < GST_VP9_TX_SIZES - 2; j++)
|
||||||
|
hdr->delta_probabilities.tx_probs_16x16[i][j] = decode_term_subexp (bd);
|
||||||
|
|
||||||
|
for (i = 0; i < GST_VP9_TX_SIZE_CONTEXTS; i++)
|
||||||
|
for (j = 0; j < GST_VP9_TX_SIZES - 1; j++)
|
||||||
|
hdr->delta_probabilities.tx_probs_32x32[i][j] = decode_term_subexp (bd);
|
||||||
|
|
||||||
|
return GST_VP9_PARSER_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GstVp9ParserResult
|
||||||
|
parse_tx_mode (GstVp9FrameHeader * hdr, Vp9BoolDecoder * bd)
|
||||||
|
{
|
||||||
|
guint8 tx_mode;
|
||||||
|
guint8 tx_mode_select;
|
||||||
|
|
||||||
|
if (hdr->lossless_flag) {
|
||||||
|
hdr->tx_mode = GST_VP9_TX_MODE_ONLY_4x4;
|
||||||
|
return GST_VP9_PARSER_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
tx_mode = read_literal (bd, 2);
|
||||||
|
if (tx_mode == GST_VP9_TX_MODE_ALLOW_32x32) {
|
||||||
|
tx_mode_select = read_literal (bd, 1);
|
||||||
|
tx_mode += tx_mode_select;
|
||||||
|
}
|
||||||
|
|
||||||
|
hdr->tx_mode = tx_mode;
|
||||||
|
return GST_VP9_PARSER_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GstVp9ParserResult
|
||||||
|
parse_compressed_header (GstVp9StatefulParser * self, GstVp9FrameHeader * hdr,
|
||||||
|
GstBitReader * br)
|
||||||
|
{
|
||||||
|
GstVp9ParserResult rst;
|
||||||
|
gboolean frame_is_intra_only;
|
||||||
|
Vp9BoolDecoder bd;
|
||||||
|
|
||||||
|
/* consume trailing bits */
|
||||||
|
while (gst_bit_reader_get_pos (br) & 0x7)
|
||||||
|
gst_bit_reader_get_bits_uint8_unchecked (br, 1);
|
||||||
|
|
||||||
|
rst = init_bool (&bd, br, hdr->header_size_in_bytes);
|
||||||
|
if (rst != GST_VP9_PARSER_OK) {
|
||||||
|
GST_ERROR ("Failed to init the boolean decoder.");
|
||||||
|
return rst;
|
||||||
|
}
|
||||||
|
|
||||||
|
rst = parse_tx_mode (hdr, &bd);
|
||||||
|
if (rst != GST_VP9_PARSER_OK)
|
||||||
|
return rst;
|
||||||
|
|
||||||
|
if (hdr->tx_mode == GST_VP9_TX_MODE_SELECT) {
|
||||||
|
rst = parse_tx_mode_probs (hdr, &bd);
|
||||||
|
if (rst != GST_VP9_PARSER_OK)
|
||||||
|
return rst;
|
||||||
|
}
|
||||||
|
|
||||||
|
rst = parse_coef_probs (hdr, &bd);
|
||||||
|
if (rst != GST_VP9_PARSER_OK)
|
||||||
|
return rst;
|
||||||
|
|
||||||
|
rst = parse_skip_probs (hdr, &bd);
|
||||||
|
if (rst != GST_VP9_PARSER_OK)
|
||||||
|
return rst;
|
||||||
|
|
||||||
|
frame_is_intra_only = (hdr->frame_type == GST_VP9_KEY_FRAME
|
||||||
|
|| hdr->intra_only);
|
||||||
|
|
||||||
|
if (!frame_is_intra_only) {
|
||||||
|
rst = parse_inter_mode_probs (hdr, &bd);
|
||||||
|
if (rst != GST_VP9_PARSER_OK)
|
||||||
|
return rst;
|
||||||
|
|
||||||
|
if (hdr->interpolation_filter == GST_VP9_INTERPOLATION_FILTER_SWITCHABLE) {
|
||||||
|
rst = parse_interp_filter_probs (hdr, &bd);
|
||||||
|
if (rst != GST_VP9_PARSER_OK)
|
||||||
|
return rst;
|
||||||
|
}
|
||||||
|
|
||||||
|
rst = parse_is_inter_probs (hdr, &bd);
|
||||||
|
if (rst != GST_VP9_PARSER_OK)
|
||||||
|
return rst;
|
||||||
|
|
||||||
|
rst = parse_frame_reference (hdr, &bd);
|
||||||
|
if (rst != GST_VP9_PARSER_OK)
|
||||||
|
return rst;
|
||||||
|
|
||||||
|
rst = parse_frame_reference_mode_probs (hdr, &bd);
|
||||||
|
if (rst != GST_VP9_PARSER_OK)
|
||||||
|
return rst;
|
||||||
|
|
||||||
|
rst = parse_y_mode_probs (hdr, &bd);
|
||||||
|
if (rst != GST_VP9_PARSER_OK)
|
||||||
|
return rst;
|
||||||
|
|
||||||
|
rst = parse_partition_probs (hdr, &bd);
|
||||||
|
if (rst != GST_VP9_PARSER_OK)
|
||||||
|
return rst;
|
||||||
|
|
||||||
|
rst = parse_mv_probs (hdr, &bd);
|
||||||
|
if (rst != GST_VP9_PARSER_OK)
|
||||||
|
return rst;
|
||||||
|
}
|
||||||
|
|
||||||
|
rst = exit_bool (&bd);
|
||||||
|
if (rst != GST_VP9_PARSER_OK) {
|
||||||
|
GST_ERROR ("The boolean decoder did not exit cleanly.");
|
||||||
|
return rst;
|
||||||
|
}
|
||||||
|
|
||||||
|
return GST_VP9_PARSER_OK;
|
||||||
|
}
|
||||||
|
|
||||||
static const gint16 dc_qlookup[256] = {
|
static const gint16 dc_qlookup[256] = {
|
||||||
4, 8, 8, 9, 10, 11, 12, 12,
|
4, 8, 8, 9, 10, 11, 12, 12,
|
||||||
13, 14, 15, 16, 17, 18, 19, 19,
|
13, 14, 15, 16, 17, 18, 19, 19,
|
||||||
|
@ -753,7 +1297,6 @@ parse_segmentation_params (GstBitReader * br, GstVp9SegmentationParams * params)
|
||||||
VP9_READ_BIT (params->feature_enabled[i][GST_VP9_SEG_SEG_LVL_SKIP]);
|
VP9_READ_BIT (params->feature_enabled[i][GST_VP9_SEG_SEG_LVL_SKIP]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return GST_VP9_PARSER_OK;
|
return GST_VP9_PARSER_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -878,7 +1421,42 @@ gst_vp9_stateful_parser_free (GstVp9StatefulParser * parser)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_vp9_stateful_parser_parse_frame_header:
|
* gst_vp9_stateful_parser_parse_compressed_frame_header:
|
||||||
|
* @parser: The #GstVp9StatefulParser
|
||||||
|
* @header: The #GstVp9FrameHeader to fill
|
||||||
|
* @data: The data to parse
|
||||||
|
* @size: The size of the @data to parse
|
||||||
|
*
|
||||||
|
* Parses the compressed information in the VP9 bitstream contained in @data,
|
||||||
|
* and fills in @header with the parsed values.
|
||||||
|
* The @size argument represent the whole frame size.
|
||||||
|
*
|
||||||
|
* Returns: a #GstVp9ParserResult
|
||||||
|
*
|
||||||
|
* Since: 1.20
|
||||||
|
*/
|
||||||
|
|
||||||
|
GstVp9ParserResult
|
||||||
|
gst_vp9_stateful_parser_parse_compressed_frame_header (GstVp9StatefulParser *
|
||||||
|
parser, GstVp9FrameHeader * header, const guint8 * data, gsize size)
|
||||||
|
{
|
||||||
|
GstVp9ParserResult rst = GST_VP9_PARSER_OK;
|
||||||
|
GstBitReader bit_reader;
|
||||||
|
GstBitReader *br = &bit_reader;
|
||||||
|
|
||||||
|
gst_bit_reader_init (br, data, size);
|
||||||
|
|
||||||
|
rst = parse_compressed_header (parser, header, br);
|
||||||
|
if (rst != GST_VP9_PARSER_OK) {
|
||||||
|
GST_ERROR ("Failed to parse the compressed header");
|
||||||
|
return GST_VP9_PARSER_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rst;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_vp9_stateful_parser_parse_uncompressed_frame_header:
|
||||||
* @parser: The #GstVp9StatefulParser
|
* @parser: The #GstVp9StatefulParser
|
||||||
* @header: The #GstVp9FrameHeader to fill
|
* @header: The #GstVp9FrameHeader to fill
|
||||||
* @data: The data to parse
|
* @data: The data to parse
|
||||||
|
@ -892,8 +1470,8 @@ gst_vp9_stateful_parser_free (GstVp9StatefulParser * parser)
|
||||||
* Since: 1.20
|
* Since: 1.20
|
||||||
*/
|
*/
|
||||||
GstVp9ParserResult
|
GstVp9ParserResult
|
||||||
gst_vp9_stateful_parser_parse_frame_header (GstVp9StatefulParser * parser,
|
gst_vp9_stateful_parser_parse_uncompressed_frame_header (GstVp9StatefulParser *
|
||||||
GstVp9FrameHeader * header, const guint8 * data, gsize size)
|
parser, GstVp9FrameHeader * header, const guint8 * data, gsize size)
|
||||||
{
|
{
|
||||||
GstBitReader bit_reader;
|
GstBitReader bit_reader;
|
||||||
GstBitReader *br = &bit_reader;
|
GstBitReader *br = &bit_reader;
|
||||||
|
@ -1089,6 +1667,7 @@ gst_vp9_stateful_parser_parse_frame_header (GstVp9StatefulParser * parser,
|
||||||
|
|
||||||
header->frame_header_length_in_bytes = (gst_bit_reader_get_pos (br) + 7) / 8;
|
header->frame_header_length_in_bytes = (gst_bit_reader_get_pos (br) + 7) / 8;
|
||||||
|
|
||||||
|
|
||||||
return GST_VP9_PARSER_OK;
|
return GST_VP9_PARSER_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,8 @@ typedef struct _GstVp9StatefulParser GstVp9StatefulParser;
|
||||||
typedef struct _GstVp9LoopFilterParams GstVp9LoopFilterParams;
|
typedef struct _GstVp9LoopFilterParams GstVp9LoopFilterParams;
|
||||||
typedef struct _GstVp9QuantizationParams GstVp9QuantizationParams;
|
typedef struct _GstVp9QuantizationParams GstVp9QuantizationParams;
|
||||||
typedef struct _GstVp9SegmentationParams GstVp9SegmentationParams;
|
typedef struct _GstVp9SegmentationParams GstVp9SegmentationParams;
|
||||||
|
typedef struct _GstVp9MvDeltaProbs GstVp9MvDeltaProbs;
|
||||||
|
typedef struct _GstVp9DeltaProbabilities GstVp9DeltaProbabilities;
|
||||||
typedef struct _GstVp9FrameHeader GstVp9FrameHeader;
|
typedef struct _GstVp9FrameHeader GstVp9FrameHeader;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -75,6 +77,263 @@ typedef struct _GstVp9FrameHeader GstVp9FrameHeader;
|
||||||
* Since: 1.20
|
* Since: 1.20
|
||||||
*/
|
*/
|
||||||
#define GST_VP9_SEG_LVL_MAX 4
|
#define GST_VP9_SEG_LVL_MAX 4
|
||||||
|
/**
|
||||||
|
* GST_VP9_TX_SIZE_CONTEXTS:
|
||||||
|
*
|
||||||
|
* Number of contexts for transform size
|
||||||
|
*
|
||||||
|
* Since: 1.20
|
||||||
|
*/
|
||||||
|
#define GST_VP9_TX_SIZE_CONTEXTS 2
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GST_VP9_TX_SIZES:
|
||||||
|
*
|
||||||
|
* Number of values for tx_size
|
||||||
|
*
|
||||||
|
* Since: 1.20
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define GST_VP9_TX_SIZES 4
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GST_VP9_SKIP_CONTEXTS:
|
||||||
|
*
|
||||||
|
* Number of contexts for decoding skip
|
||||||
|
*
|
||||||
|
* Since: 1.20
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define GST_VP9_SKIP_CONTEXTS 3
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GST_VP9_INTER_MODE_CONTEXTS:
|
||||||
|
*
|
||||||
|
* Number of contexts for inter_mode
|
||||||
|
*
|
||||||
|
* Since: 1.20
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define GST_VP9_INTER_MODE_CONTEXTS 7
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GST_VP9_INTER_MODES:
|
||||||
|
*
|
||||||
|
* Number of values for inter_mode
|
||||||
|
*
|
||||||
|
* Since: 1.20
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define GST_VP9_INTER_MODES 4
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GST_VP9_INTERP_FILTER_CONTEXTS:
|
||||||
|
*
|
||||||
|
* Number of contexts for interp_filter
|
||||||
|
*
|
||||||
|
* Since: 1.20
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define GST_VP9_INTERP_FILTER_CONTEXTS 4
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GST_VP9_SWITCHABLE_FILTERS:
|
||||||
|
*
|
||||||
|
* Number of contexts for interp_filter
|
||||||
|
*
|
||||||
|
* Since: 1.20
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define GST_VP9_SWITCHABLE_FILTERS 3
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GST_VP9_IS_INTER_CONTEXTS:
|
||||||
|
*
|
||||||
|
* Number of contexts for interp_filter
|
||||||
|
*
|
||||||
|
* Since: 1.20
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define GST_VP9_IS_INTER_CONTEXTS 4
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GST_VP9_COMP_MODE_CONTEXTS:
|
||||||
|
*
|
||||||
|
* Number of contexts for comp_mode
|
||||||
|
*
|
||||||
|
* Since: 1.20
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define GST_VP9_COMP_MODE_CONTEXTS 5
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GST_VP9_REF_CONTEXTS:
|
||||||
|
*
|
||||||
|
* Number of contexts for single_ref and comp_ref
|
||||||
|
*
|
||||||
|
* Since: 1.20
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define GST_VP9_REF_CONTEXTS 5
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GST_VP9_BLOCK_SIZE_GROUPS:
|
||||||
|
*
|
||||||
|
* Number of contexts when decoding intra_mode
|
||||||
|
*
|
||||||
|
* Since: 1.20
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define GST_VP9_BLOCK_SIZE_GROUPS 4
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GST_VP9_INTRA_MODES:
|
||||||
|
*
|
||||||
|
* Number of values for intra_mode
|
||||||
|
*
|
||||||
|
* Since: 1.20
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define GST_VP9_INTRA_MODES 10
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GST_VP9_PARTITION_CONTEXTS:
|
||||||
|
*
|
||||||
|
* Number of contexts when decoding partition
|
||||||
|
*
|
||||||
|
* Since: 1.20
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define GST_VP9_PARTITION_CONTEXTS 16
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GST_VP9_PARTITION_TYPES:
|
||||||
|
*
|
||||||
|
* Number of values for partition
|
||||||
|
*
|
||||||
|
* Since: 1.20
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define GST_VP9_PARTITION_TYPES 4
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GST_VP9_MV_JOINTS:
|
||||||
|
*
|
||||||
|
* Number of values for partition
|
||||||
|
*
|
||||||
|
* Since: 1.20
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define GST_VP9_MV_JOINTS 4
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GST_VP9_MV_CLASSES:
|
||||||
|
*
|
||||||
|
* Number of values for mv_class
|
||||||
|
*
|
||||||
|
* Since: 1.20
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define GST_VP9_MV_CLASSES 11
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GST_VP9_MV_OFFSET_BITS:
|
||||||
|
*
|
||||||
|
* Maximum number of bits for decoding motion vectors
|
||||||
|
*
|
||||||
|
* Since: 1.20
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define GST_VP9_MV_OFFSET_BITS 10
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GST_VP9_CLASS0_SIZE:
|
||||||
|
*
|
||||||
|
* Number of values for mv_classO_bit
|
||||||
|
*
|
||||||
|
* Since: 1.20
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define GST_VP9_CLASS0_SIZE 2
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GST_VP9_MV_FR_SIZE:
|
||||||
|
*
|
||||||
|
* Number of values that can be decoded for mv_fr
|
||||||
|
*
|
||||||
|
* Since: 1.20
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define GST_VP9_MV_FR_SIZE 4
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GST_VP9_TX_MODES:
|
||||||
|
*
|
||||||
|
* Number of values for tx_mode
|
||||||
|
*
|
||||||
|
* Since: 1.20
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define GST_VP9_TX_MODES 5
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GstVp9TxMode:
|
||||||
|
* @GST_VP9_TX_MODE_ONLY_4x4: Only 4x4
|
||||||
|
* @GST_VP9_TX_MODE_ALLOW_8x8: Allow 8x8
|
||||||
|
* @GST_VP9_TX_MODE_ALLOW_16x16: Allow 16x16
|
||||||
|
* @GST_VP9_TX_MODE_ALLOW_32x32: Allow 32x32
|
||||||
|
* @GST_VP9_TX_MODE_SELECT: The choice is specified explicitly for each block
|
||||||
|
*
|
||||||
|
* TxMode: Specifies how the transform size is determined
|
||||||
|
*
|
||||||
|
* Since: 1.20
|
||||||
|
*/
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
GST_VP9_TX_MODE_ONLY_4x4 = 0,
|
||||||
|
GST_VP9_TX_MODE_ALLOW_8x8 = 1,
|
||||||
|
GST_VP9_TX_MODE_ALLOW_16x16 = 2,
|
||||||
|
GST_VP9_TX_MODE_ALLOW_32x32 = 3,
|
||||||
|
GST_VP9_TX_MODE_SELECT = 4,
|
||||||
|
|
||||||
|
} GstVp9TxMode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GstVp9ReferenceMode:
|
||||||
|
* @GST_VP9_REFERENCE_MODE_SINGLE_REFERENCE: Indicates that all the inter blocks use only a single reference frame
|
||||||
|
* @GST_VP9_REFERENCE_MODE_COMPOUND_REFERENCE: Requires all the inter blocks to use compound mode
|
||||||
|
* @GST_VP9_REFERENCE_MODE_SELECT: Allows each individual inter block to select between single and compound prediction modes
|
||||||
|
*
|
||||||
|
* Reference modes: Specify the type of inter prediction to be used
|
||||||
|
*
|
||||||
|
* Since: 1.20
|
||||||
|
*/
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
GST_VP9_REFERENCE_MODE_SINGLE_REFERENCE = 0,
|
||||||
|
GST_VP9_REFERENCE_MODE_COMPOUND_REFERENCE = 1,
|
||||||
|
GST_VP9_REFERENCE_MODE_SELECT = 2,
|
||||||
|
} GstVp9ReferenceMode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GstVp9TxSize:
|
||||||
|
* @GST_VP9_TX_4x4: 4x4
|
||||||
|
* @GST_VP9_TX_8x8: 8x8
|
||||||
|
* @GST_VP9_TX_16x16: 16x16
|
||||||
|
* @GST_VP9_TX_32x32: 32x32
|
||||||
|
*
|
||||||
|
* TxSize: Specifies the transform size
|
||||||
|
*
|
||||||
|
* Since: 1.20
|
||||||
|
*/
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
GST_VP9_TX_4x4 = 0,
|
||||||
|
GST_VP9_TX_8x8 = 1,
|
||||||
|
GST_VP9_TX_16x16 = 2,
|
||||||
|
GST_VP9_TX_32x32 = 3,
|
||||||
|
} GstVp9TxSize;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GstVp9LoopFilterParams:
|
* GstVp9LoopFilterParams:
|
||||||
|
@ -179,6 +438,59 @@ struct _GstVp9SegmentationParams
|
||||||
gint16 feature_data[GST_VP9_MAX_SEGMENTS][GST_VP9_SEG_LVL_MAX];
|
gint16 feature_data[GST_VP9_MAX_SEGMENTS][GST_VP9_SEG_LVL_MAX];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GstVp9MvDeltaProbs:
|
||||||
|
*
|
||||||
|
* Stores motion vectors probabilities updates. This is from the spec
|
||||||
|
* and can be used as a binary.
|
||||||
|
*
|
||||||
|
* Since: 1.20
|
||||||
|
*/
|
||||||
|
struct _GstVp9MvDeltaProbs
|
||||||
|
{
|
||||||
|
/*< private >*/
|
||||||
|
guint8 joint[GST_VP9_MV_JOINTS - 1];
|
||||||
|
guint8 sign[2];
|
||||||
|
guint8 klass[2][GST_VP9_MV_CLASSES - 1];
|
||||||
|
guint8 class0_bit[2];
|
||||||
|
guint8 bits[2][GST_VP9_MV_OFFSET_BITS];
|
||||||
|
guint8 class0_fr[2][GST_VP9_CLASS0_SIZE][GST_VP9_MV_FR_SIZE - 1];
|
||||||
|
guint8 fr[2][GST_VP9_MV_FR_SIZE - 1];
|
||||||
|
guint8 class0_hp[2];
|
||||||
|
guint8 hp[2];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GstVp9DeltaProbabilities:
|
||||||
|
*
|
||||||
|
* Stores probabilities updates. This is from the spec
|
||||||
|
* and can be used as a binary.
|
||||||
|
*
|
||||||
|
* Since: 1.20
|
||||||
|
*/
|
||||||
|
struct _GstVp9DeltaProbabilities
|
||||||
|
{
|
||||||
|
/*< private >*/
|
||||||
|
guint8 tx_probs_8x8[GST_VP9_TX_SIZE_CONTEXTS][GST_VP9_TX_SIZES - 3];
|
||||||
|
guint8 tx_probs_16x16[GST_VP9_TX_SIZE_CONTEXTS][GST_VP9_TX_SIZES - 2];
|
||||||
|
guint8 tx_probs_32x32[GST_VP9_TX_SIZE_CONTEXTS][GST_VP9_TX_SIZES - 1];
|
||||||
|
guint8 coef[4][2][2][6][6][3];
|
||||||
|
guint8 skip[GST_VP9_SKIP_CONTEXTS];
|
||||||
|
guint8 inter_mode[GST_VP9_INTER_MODE_CONTEXTS][GST_VP9_INTER_MODES - 1];
|
||||||
|
guint8
|
||||||
|
interp_filter[GST_VP9_INTERP_FILTER_CONTEXTS][GST_VP9_SWITCHABLE_FILTERS
|
||||||
|
- 1];
|
||||||
|
guint8 is_inter[GST_VP9_IS_INTER_CONTEXTS];
|
||||||
|
guint8 comp_mode[GST_VP9_COMP_MODE_CONTEXTS];
|
||||||
|
guint8 single_ref[GST_VP9_REF_CONTEXTS][2];
|
||||||
|
guint8 comp_ref[GST_VP9_REF_CONTEXTS];
|
||||||
|
guint8 y_mode[GST_VP9_BLOCK_SIZE_GROUPS][GST_VP9_INTRA_MODES - 1];
|
||||||
|
guint8 partition[GST_VP9_PARTITION_CONTEXTS][GST_VP9_PARTITION_TYPES - 1];
|
||||||
|
GstVp9MvDeltaProbs mv;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GstVp9FrameHeader:
|
* GstVp9FrameHeader:
|
||||||
* @profile: encoded profile
|
* @profile: encoded profile
|
||||||
|
@ -225,11 +537,38 @@ struct _GstVp9SegmentationParams
|
||||||
* @segmentation_params: a #GstVp9SegmentationParams
|
* @segmentation_params: a #GstVp9SegmentationParams
|
||||||
* @tile_cols_log2: specifies the base 2 logarithm of the width of each tile
|
* @tile_cols_log2: specifies the base 2 logarithm of the width of each tile
|
||||||
* @tile_rows_log2: specifies the base 2 logarithm of the height of each tile
|
* @tile_rows_log2: specifies the base 2 logarithm of the height of each tile
|
||||||
|
* @tx_mode: specifies how the transform size is determined
|
||||||
|
* @reference_mode: is a derived syntax element that specifies the type of
|
||||||
|
* inter prediction to be used
|
||||||
|
* @delta_probabilities: modification to the probabilities encoded in the
|
||||||
|
* bitstream
|
||||||
* @lossless_flag: lossless mode decode
|
* @lossless_flag: lossless mode decode
|
||||||
* @frame_header_length_in_bytes: length of uncompressed header
|
* @frame_header_length_in_bytes: length of uncompressed header
|
||||||
*
|
*
|
||||||
* Since: 1.20
|
* Since: 1.20
|
||||||
*/
|
*/
|
||||||
|
/**
|
||||||
|
* GstVp9FrameHeader.tx_mode:
|
||||||
|
*
|
||||||
|
* Specifies how the transform size is determined.
|
||||||
|
*
|
||||||
|
* Since: 1.20
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* GstVp9FrameHeader.reference_mode:
|
||||||
|
*
|
||||||
|
* Is a derived syntax element that specifies the type of
|
||||||
|
* inter prediction to be used.
|
||||||
|
*
|
||||||
|
* Since: 1.20
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* GstVp9FrameHeader.delta_probabilities:
|
||||||
|
*
|
||||||
|
* Modification to the probabilities encoded in the bitstream.
|
||||||
|
*
|
||||||
|
* Since: 1.20
|
||||||
|
*/
|
||||||
struct _GstVp9FrameHeader
|
struct _GstVp9FrameHeader
|
||||||
{
|
{
|
||||||
guint8 profile;
|
guint8 profile;
|
||||||
|
@ -269,6 +608,11 @@ struct _GstVp9FrameHeader
|
||||||
|
|
||||||
guint16 header_size_in_bytes;
|
guint16 header_size_in_bytes;
|
||||||
|
|
||||||
|
/* compressed header */
|
||||||
|
GstVp9TxMode tx_mode;
|
||||||
|
GstVp9ReferenceMode reference_mode;
|
||||||
|
GstVp9DeltaProbabilities delta_probabilities;
|
||||||
|
|
||||||
/* calculated values */
|
/* calculated values */
|
||||||
guint8 lossless_flag;
|
guint8 lossless_flag;
|
||||||
guint32 frame_header_length_in_bytes;
|
guint32 frame_header_length_in_bytes;
|
||||||
|
@ -312,10 +656,16 @@ GST_CODECS_API
|
||||||
void gst_vp9_stateful_parser_free (GstVp9StatefulParser * parser);
|
void gst_vp9_stateful_parser_free (GstVp9StatefulParser * parser);
|
||||||
|
|
||||||
GST_CODECS_API
|
GST_CODECS_API
|
||||||
GstVp9ParserResult gst_vp9_stateful_parser_parse_frame_header (GstVp9StatefulParser * parser,
|
GstVp9ParserResult gst_vp9_stateful_parser_parse_compressed_frame_header (GstVp9StatefulParser * parser,
|
||||||
GstVp9FrameHeader * header,
|
GstVp9FrameHeader * header,
|
||||||
const guint8 * data,
|
const guint8 * data,
|
||||||
gsize size);
|
gsize size);
|
||||||
|
|
||||||
|
GST_CODECS_API
|
||||||
|
GstVp9ParserResult gst_vp9_stateful_parser_parse_uncompressed_frame_header (GstVp9StatefulParser * parser,
|
||||||
|
GstVp9FrameHeader * header,
|
||||||
|
const guint8 * data,
|
||||||
|
gsize size);
|
||||||
|
|
||||||
/* Util methods */
|
/* Util methods */
|
||||||
GST_CODECS_API
|
GST_CODECS_API
|
||||||
|
|
Loading…
Reference in a new issue