mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-11 01:45:33 +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;
|
||||
}
|
||||
|
||||
pres = gst_vp9_stateful_parser_parse_frame_header (priv->parser, &frame_hdr,
|
||||
map.data, map.size);
|
||||
pres =
|
||||
gst_vp9_stateful_parser_parse_uncompressed_frame_header (priv->parser,
|
||||
&frame_hdr, map.data, map.size);
|
||||
|
||||
if (pres != GST_VP9_PARSER_OK) {
|
||||
GST_ERROR_OBJECT (self, "Failed to parsing frame header");
|
||||
|
@ -348,6 +349,18 @@ gst_vp9_decoder_handle_frame (GstVideoDecoder * decoder,
|
|||
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) {
|
||||
/* This is a non-intra, dummy frame */
|
||||
intra_only = FALSE;
|
||||
|
|
|
@ -51,6 +51,7 @@ struct _GstVp9Decoder
|
|||
|
||||
/*< protected >*/
|
||||
GstVideoCodecState * input_state;
|
||||
gboolean parse_compressed_headers;
|
||||
|
||||
/*< private >*/
|
||||
GstVp9DecoderPrivate *priv;
|
||||
|
|
|
@ -149,6 +149,550 @@ ensure_debug_category (void)
|
|||
#define CHECK_ALLOWED(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] = {
|
||||
4, 8, 8, 9, 10, 11, 12, 12,
|
||||
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]);
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
* @header: The #GstVp9FrameHeader to fill
|
||||
* @data: The data to parse
|
||||
|
@ -892,8 +1470,8 @@ gst_vp9_stateful_parser_free (GstVp9StatefulParser * parser)
|
|||
* Since: 1.20
|
||||
*/
|
||||
GstVp9ParserResult
|
||||
gst_vp9_stateful_parser_parse_frame_header (GstVp9StatefulParser * parser,
|
||||
GstVp9FrameHeader * header, const guint8 * data, gsize size)
|
||||
gst_vp9_stateful_parser_parse_uncompressed_frame_header (GstVp9StatefulParser *
|
||||
parser, GstVp9FrameHeader * header, const guint8 * data, gsize size)
|
||||
{
|
||||
GstBitReader 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;
|
||||
|
||||
|
||||
return GST_VP9_PARSER_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -29,6 +29,8 @@ typedef struct _GstVp9StatefulParser GstVp9StatefulParser;
|
|||
typedef struct _GstVp9LoopFilterParams GstVp9LoopFilterParams;
|
||||
typedef struct _GstVp9QuantizationParams GstVp9QuantizationParams;
|
||||
typedef struct _GstVp9SegmentationParams GstVp9SegmentationParams;
|
||||
typedef struct _GstVp9MvDeltaProbs GstVp9MvDeltaProbs;
|
||||
typedef struct _GstVp9DeltaProbabilities GstVp9DeltaProbabilities;
|
||||
typedef struct _GstVp9FrameHeader GstVp9FrameHeader;
|
||||
|
||||
/**
|
||||
|
@ -75,6 +77,263 @@ typedef struct _GstVp9FrameHeader GstVp9FrameHeader;
|
|||
* Since: 1.20
|
||||
*/
|
||||
#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:
|
||||
|
@ -179,6 +438,59 @@ struct _GstVp9SegmentationParams
|
|||
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:
|
||||
* @profile: encoded profile
|
||||
|
@ -225,11 +537,38 @@ struct _GstVp9SegmentationParams
|
|||
* @segmentation_params: a #GstVp9SegmentationParams
|
||||
* @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
|
||||
* @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
|
||||
* @frame_header_length_in_bytes: length of uncompressed header
|
||||
*
|
||||
* 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
|
||||
{
|
||||
guint8 profile;
|
||||
|
@ -269,6 +608,11 @@ struct _GstVp9FrameHeader
|
|||
|
||||
guint16 header_size_in_bytes;
|
||||
|
||||
/* compressed header */
|
||||
GstVp9TxMode tx_mode;
|
||||
GstVp9ReferenceMode reference_mode;
|
||||
GstVp9DeltaProbabilities delta_probabilities;
|
||||
|
||||
/* calculated values */
|
||||
guint8 lossless_flag;
|
||||
guint32 frame_header_length_in_bytes;
|
||||
|
@ -312,10 +656,16 @@ GST_CODECS_API
|
|||
void gst_vp9_stateful_parser_free (GstVp9StatefulParser * parser);
|
||||
|
||||
GST_CODECS_API
|
||||
GstVp9ParserResult gst_vp9_stateful_parser_parse_frame_header (GstVp9StatefulParser * parser,
|
||||
GstVp9FrameHeader * header,
|
||||
const guint8 * data,
|
||||
gsize size);
|
||||
GstVp9ParserResult gst_vp9_stateful_parser_parse_compressed_frame_header (GstVp9StatefulParser * parser,
|
||||
GstVp9FrameHeader * header,
|
||||
const guint8 * data,
|
||||
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 */
|
||||
GST_CODECS_API
|
||||
|
|
Loading…
Reference in a new issue