mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-26 00:58:12 +00:00
codecparsers: Add VP9 codec parser
https://bugzilla.gnome.org/show_bug.cgi?id=757597
This commit is contained in:
parent
4717b48a03
commit
b245e0f16c
8 changed files with 1726 additions and 3 deletions
|
@ -5,7 +5,8 @@ libgstcodecparsers_@GST_API_VERSION@_la_SOURCES = \
|
|||
gsth265parser.c gstvp8parser.c gstvp8rangedecoder.c \
|
||||
parserutils.c nalutils.c dboolhuff.c vp8utils.c \
|
||||
gstjpegparser.c \
|
||||
gstmpegvideometa.c
|
||||
gstmpegvideometa.c \
|
||||
gstvp9parser.c vp9utils.c
|
||||
|
||||
libgstcodecparsers_@GST_API_VERSION@includedir = \
|
||||
$(includedir)/gstreamer-@GST_API_VERSION@/gst/codecparsers
|
||||
|
@ -16,7 +17,8 @@ libgstcodecparsers_@GST_API_VERSION@include_HEADERS = \
|
|||
gstmpegvideoparser.h gsth264parser.h gstvc1parser.h gstmpeg4parser.h \
|
||||
gsth265parser.h gstvp8parser.h gstvp8rangedecoder.h \
|
||||
gstjpegparser.h \
|
||||
gstmpegvideometa.h
|
||||
gstmpegvideometa.h \
|
||||
gstvp9parser.h vp9utils.h
|
||||
|
||||
libgstcodecparsers_@GST_API_VERSION@_la_CFLAGS = \
|
||||
$(GST_PLUGINS_BAD_CFLAGS) \
|
||||
|
@ -36,4 +38,5 @@ libgstcodecparsers_@GST_API_VERSION@_la_LDFLAGS = \
|
|||
$(GST_ALL_LDFLAGS) \
|
||||
$(GST_LT_LDFLAGS)
|
||||
|
||||
EXTRA_DIST = dboolhuff.LICENSE dboolhuff.PATENTS dboolhuff.AUTHORS
|
||||
EXTRA_DIST = dboolhuff.LICENSE dboolhuff.PATENTS dboolhuff.AUTHORS \
|
||||
vp9utils.LICENSE vp9utils.PATENTS vp9utils.AUTHORS
|
||||
|
|
815
gst-libs/gst/codecparsers/gstvp9parser.c
Normal file
815
gst-libs/gst/codecparsers/gstvp9parser.c
Normal file
|
@ -0,0 +1,815 @@
|
|||
/* gstvp9parser.c
|
||||
*
|
||||
* Copyright (C) 2013-2014 Intel Corporation
|
||||
* Copyright (C) 2015 Intel Corporation
|
||||
* Author: XuGuangxin<Guangxin.Xu@intel.com>
|
||||
* Author: Sreerenj Balachandran<sreerenj.balachandran@intel.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
/**
|
||||
* SECTION:gstvp9parser
|
||||
* @short_description: Convenience library for parsing vp9 video bitstream.
|
||||
*
|
||||
* For more details about the structures, you can refer to the
|
||||
* specifications:
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <gst/base/gstbitreader.h>
|
||||
#include "vp9utils.h"
|
||||
#include "gstvp9parser.h"
|
||||
|
||||
#define MIN_TILE_WIDTH_B64 4
|
||||
#define MAX_TILE_WIDTH_B64 64
|
||||
|
||||
/* order of sb64, where sb64 = 64x64 */
|
||||
#define ALIGN_SB64(w) ((w + 63) >> 6)
|
||||
|
||||
GST_DEBUG_CATEGORY (gst_vp9_parser_debug);
|
||||
#define GST_CAT_DEFAULT gst_vp9_parser_debug
|
||||
|
||||
static gboolean initialized = FALSE;
|
||||
#define INITIALIZE_DEBUG_CATEGORY \
|
||||
if (!initialized) { \
|
||||
GST_DEBUG_CATEGORY_INIT (gst_vp9_parser_debug, "codecparsers_vp9", 0, \
|
||||
"vp9 parser library"); \
|
||||
initialized = TRUE; \
|
||||
}
|
||||
|
||||
#define gst_vp9_read_bit(br) gst_bit_reader_get_bits_uint8_unchecked(br, 1)
|
||||
#define gst_vp9_read_bits(br, bits) gst_bit_reader_get_bits_uint32_unchecked(br, bits)
|
||||
|
||||
#define GST_VP9_PARSER_GET_PRIVATE(parser) ((GstVp9ParserPrivate *)(parser->priv))
|
||||
|
||||
typedef struct _ReferenceSize
|
||||
{
|
||||
guint32 width;
|
||||
guint32 height;
|
||||
} ReferenceSize;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* for loop filters */
|
||||
gint8 ref_deltas[GST_VP9_MAX_REF_LF_DELTAS];
|
||||
gint8 mode_deltas[GST_VP9_MAX_MODE_LF_DELTAS];
|
||||
|
||||
guint8 segmentation_abs_delta;
|
||||
GstVp9SegmentationInfoData segmentation[GST_VP9_MAX_SEGMENTS];
|
||||
|
||||
ReferenceSize reference[GST_VP9_REF_FRAMES];
|
||||
} GstVp9ParserPrivate;
|
||||
|
||||
static gint32
|
||||
gst_vp9_read_signed_bits (GstBitReader * br, int bits)
|
||||
{
|
||||
const gint32 value = gst_vp9_read_bits (br, bits);
|
||||
return gst_vp9_read_bit (br) ? -value : value;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
verify_frame_marker (GstBitReader * br)
|
||||
{
|
||||
guint8 frame_marker = gst_vp9_read_bits (br, 2);
|
||||
if (frame_marker != GST_VP9_FRAME_MARKER) {
|
||||
GST_ERROR ("Invalid VP9 Frame Marker !");
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
verify_sync_code (GstBitReader * const br)
|
||||
{
|
||||
return (gst_vp9_read_bits (br, 24) == GST_VP9_SYNC_CODE);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
parse_bitdepth_colorspace_sampling (GstBitReader * const br,
|
||||
GstVp9FrameHdr * frame_hdr)
|
||||
{
|
||||
if (frame_hdr->profile > GST_VP9_PROFILE_1)
|
||||
frame_hdr->bit_depth =
|
||||
gst_vp9_read_bit (br) ? GST_VP9_BIT_DEPTH_12 : GST_VP9_BIT_DEPTH_10;
|
||||
else
|
||||
frame_hdr->bit_depth = GST_VP9_BIT_DEPTH_8;
|
||||
|
||||
frame_hdr->color_space = gst_vp9_read_bits (br, 3);
|
||||
if (frame_hdr->color_space != GST_VP9_CS_SRGB) {
|
||||
frame_hdr->color_range = gst_vp9_read_bit (br);
|
||||
|
||||
if (frame_hdr->profile == GST_VP9_PROFILE_1
|
||||
|| frame_hdr->profile == GST_VP9_PROFILE_3) {
|
||||
|
||||
frame_hdr->subsampling_x = gst_vp9_read_bit (br);
|
||||
frame_hdr->subsampling_y = gst_vp9_read_bit (br);
|
||||
|
||||
if (frame_hdr->subsampling_x == 1 && frame_hdr->subsampling_y == 1) {
|
||||
GST_ERROR
|
||||
("4:2:0 subsampling is not supported in profile_1 or profile_3");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (gst_vp9_read_bit (br)) {
|
||||
GST_ERROR ("Reserved bit set!");
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
frame_hdr->subsampling_y = frame_hdr->subsampling_x = 1;
|
||||
}
|
||||
} else {
|
||||
frame_hdr->color_range = GST_VP9_CR_FULL;
|
||||
|
||||
if (frame_hdr->profile == GST_VP9_PROFILE_1
|
||||
|| frame_hdr->profile == GST_VP9_PROFILE_3) {
|
||||
if (gst_vp9_read_bit (br)) {
|
||||
GST_ERROR ("Reserved bit set!");
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
GST_ERROR
|
||||
("4:4:4 subsampling is not supported in profile_0 and profile_2");
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
|
||||
error:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static guint
|
||||
parse_profile (GstBitReader * br)
|
||||
{
|
||||
guint8 profile = gst_vp9_read_bit (br);
|
||||
profile |= gst_vp9_read_bit (br) << 1;
|
||||
if (profile > 2)
|
||||
profile += gst_vp9_read_bit (br);
|
||||
return profile;
|
||||
}
|
||||
|
||||
static void
|
||||
parse_frame_size (GstBitReader * br, guint32 * width, guint32 * height)
|
||||
{
|
||||
const guint32 w = gst_vp9_read_bits (br, 16) + 1;
|
||||
const guint32 h = gst_vp9_read_bits (br, 16) + 1;
|
||||
*width = w;
|
||||
*height = h;
|
||||
}
|
||||
|
||||
static void
|
||||
parse_display_frame_size (GstBitReader * br, GstVp9FrameHdr * frame_hdr)
|
||||
{
|
||||
frame_hdr->display_size_enabled = gst_vp9_read_bit (br);
|
||||
if (frame_hdr->display_size_enabled)
|
||||
parse_frame_size (br, &frame_hdr->display_width,
|
||||
&frame_hdr->display_height);
|
||||
}
|
||||
|
||||
static void
|
||||
parse_frame_size_from_refs (const GstVp9Parser * parser,
|
||||
GstVp9FrameHdr * frame_hdr, GstBitReader * br)
|
||||
{
|
||||
gboolean found = FALSE;
|
||||
int i;
|
||||
GstVp9ParserPrivate *priv = GST_VP9_PARSER_GET_PRIVATE (parser);
|
||||
|
||||
for (i = 0; i < GST_VP9_REFS_PER_FRAME; i++) {
|
||||
found = gst_vp9_read_bit (br);
|
||||
|
||||
if (found) {
|
||||
guint8 idx = frame_hdr->ref_frame_indices[i];
|
||||
frame_hdr->width = priv->reference[idx].width;
|
||||
frame_hdr->height = priv->reference[idx].height;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
parse_frame_size (br, &frame_hdr->width, &frame_hdr->height);
|
||||
}
|
||||
|
||||
static GstVp9InterpFilter
|
||||
parse_interp_filter (GstBitReader * br)
|
||||
{
|
||||
const GstVp9InterpFilter filter_map[] = {
|
||||
GST_VP9_INTERP_FILTER_EIGHTTAP_SMOOTH,
|
||||
GST_VP9_INTERP_FILTER_EIGHTTAP,
|
||||
GST_VP9_INTERP_FILTER_EIGHTTAP_SHARP,
|
||||
GST_VP9_INTERP_FILTER_BILINEAR
|
||||
};
|
||||
|
||||
return gst_vp9_read_bit (br) ? GST_VP9_INTERP_FILTER_SWITCHABLE :
|
||||
filter_map[gst_vp9_read_bits (br, 2)];
|
||||
}
|
||||
|
||||
static void
|
||||
parse_loopfilter (GstVp9LoopFilter * lf, GstBitReader * br)
|
||||
{
|
||||
lf->filter_level = gst_vp9_read_bits (br, 6);
|
||||
lf->sharpness_level = gst_vp9_read_bits (br, 3);
|
||||
|
||||
lf->mode_ref_delta_update = 0;
|
||||
|
||||
lf->mode_ref_delta_enabled = gst_vp9_read_bit (br);
|
||||
if (lf->mode_ref_delta_enabled) {
|
||||
lf->mode_ref_delta_update = gst_vp9_read_bit (br);
|
||||
if (lf->mode_ref_delta_update) {
|
||||
int i;
|
||||
for (i = 0; i < GST_VP9_MAX_REF_LF_DELTAS; i++) {
|
||||
lf->update_ref_deltas[i] = gst_vp9_read_bit (br);
|
||||
if (lf->update_ref_deltas[i])
|
||||
lf->ref_deltas[i] = gst_vp9_read_signed_bits (br, 6);
|
||||
}
|
||||
|
||||
for (i = 0; i < GST_VP9_MAX_MODE_LF_DELTAS; i++) {
|
||||
lf->update_mode_deltas[i] = gst_vp9_read_bit (br);
|
||||
if (lf->update_mode_deltas[i])
|
||||
lf->mode_deltas[i] = gst_vp9_read_signed_bits (br, 6);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static gint8
|
||||
parse_delta_q (GstBitReader * br)
|
||||
{
|
||||
return gst_vp9_read_bit (br) ? gst_vp9_read_signed_bits (br, 4) : 0;
|
||||
}
|
||||
|
||||
static void
|
||||
parse_quantization (GstVp9QuantIndices * quant_indices, GstBitReader * br)
|
||||
{
|
||||
quant_indices->y_ac_qi = gst_vp9_read_bits (br, QINDEX_BITS);
|
||||
quant_indices->y_dc_delta = parse_delta_q (br);
|
||||
quant_indices->uv_dc_delta = parse_delta_q (br);
|
||||
quant_indices->uv_ac_delta = parse_delta_q (br);
|
||||
}
|
||||
|
||||
static void
|
||||
parse_segmentation (GstVp9SegmentationInfo * seg, GstBitReader * br)
|
||||
{
|
||||
int i;
|
||||
|
||||
seg->update_map = FALSE;
|
||||
seg->update_data = FALSE;
|
||||
|
||||
seg->enabled = gst_vp9_read_bit (br);
|
||||
if (!seg->enabled)
|
||||
return;
|
||||
|
||||
/* Segmentation map update */
|
||||
seg->update_map = gst_vp9_read_bit (br);
|
||||
if (seg->update_map) {
|
||||
for (i = 0; i < GST_VP9_SEG_TREE_PROBS; i++) {
|
||||
seg->update_tree_probs[i] = gst_vp9_read_bit (br);
|
||||
seg->tree_probs[i] = seg->update_tree_probs[i] ?
|
||||
gst_vp9_read_bits (br, 8) : GST_VP9_MAX_PROB;
|
||||
}
|
||||
|
||||
seg->temporal_update = gst_vp9_read_bit (br);
|
||||
if (seg->temporal_update) {
|
||||
for (i = 0; i < GST_VP9_PREDICTION_PROBS; i++) {
|
||||
seg->update_pred_probs[i] = gst_vp9_read_bit (br);
|
||||
seg->pred_probs[i] = seg->update_pred_probs[i] ?
|
||||
gst_vp9_read_bits (br, 8) : GST_VP9_MAX_PROB;
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < GST_VP9_PREDICTION_PROBS; i++)
|
||||
seg->pred_probs[i] = GST_VP9_MAX_PROB;
|
||||
}
|
||||
}
|
||||
|
||||
/* Segmentation data update */
|
||||
seg->update_data = gst_vp9_read_bit (br);
|
||||
|
||||
if (seg->update_data) {
|
||||
/* clear all features */
|
||||
memset (seg->data, 0, sizeof (seg->data));
|
||||
|
||||
seg->abs_delta = gst_vp9_read_bit (br);
|
||||
|
||||
for (i = 0; i < GST_VP9_MAX_SEGMENTS; i++) {
|
||||
GstVp9SegmentationInfoData *seg_data = seg->data + i;
|
||||
guint8 data;
|
||||
|
||||
/* SEG_LVL_ALT_Q */
|
||||
seg_data->alternate_quantizer_enabled = gst_vp9_read_bit (br);
|
||||
if (seg_data->alternate_quantizer_enabled) {
|
||||
data = gst_vp9_read_bits (br, 8);
|
||||
seg_data->alternate_quantizer = gst_vp9_read_bit (br) ? -data : data;
|
||||
}
|
||||
|
||||
/* SEG_LVL_ALT_LF */
|
||||
seg_data->alternate_loop_filter_enabled = gst_vp9_read_bit (br);
|
||||
if (seg_data->alternate_loop_filter_enabled) {
|
||||
data = gst_vp9_read_bits (br, 6);
|
||||
seg_data->alternate_loop_filter = gst_vp9_read_bit (br) ? -data : data;
|
||||
}
|
||||
|
||||
/* SEG_LVL_REF_FRAME */
|
||||
seg_data->reference_frame_enabled = gst_vp9_read_bit (br);
|
||||
if (seg_data->reference_frame_enabled) {
|
||||
seg_data->reference_frame = gst_vp9_read_bits (br, 2);
|
||||
}
|
||||
|
||||
seg_data->reference_skip = gst_vp9_read_bit (br);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static guint32
|
||||
get_max_lb_tile_cols (guint32 sb_cols)
|
||||
{
|
||||
gint max_log2 = 1;
|
||||
while ((sb_cols >> max_log2) >= MIN_TILE_WIDTH_B64)
|
||||
++max_log2;
|
||||
return max_log2 - 1;
|
||||
}
|
||||
|
||||
static guint32
|
||||
get_min_lb_tile_cols (guint32 sb_cols)
|
||||
{
|
||||
gint min_log2 = 0;
|
||||
while ((MAX_TILE_WIDTH_B64 << min_log2) < sb_cols)
|
||||
++min_log2;
|
||||
return min_log2;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
parse_tile_info (GstVp9FrameHdr * frame_hdr, GstBitReader * br)
|
||||
{
|
||||
guint32 max_ones;
|
||||
const guint32 sb_cols = ALIGN_SB64 (frame_hdr->width);
|
||||
guint32 min_lb_tile_cols = get_min_lb_tile_cols (sb_cols);
|
||||
guint32 max_lb_tile_cols = get_max_lb_tile_cols (sb_cols);
|
||||
|
||||
g_assert (min_lb_tile_cols <= max_lb_tile_cols);
|
||||
max_ones = max_lb_tile_cols - min_lb_tile_cols;
|
||||
|
||||
/* columns */
|
||||
frame_hdr->log2_tile_columns = min_lb_tile_cols;
|
||||
while (max_ones-- && gst_vp9_read_bit (br))
|
||||
frame_hdr->log2_tile_columns++;
|
||||
|
||||
if (frame_hdr->log2_tile_columns > 6) {
|
||||
GST_ERROR ("Invalid number of tile columns..!");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* row */
|
||||
frame_hdr->log2_tile_rows = gst_vp9_read_bit (br);
|
||||
if (frame_hdr->log2_tile_rows)
|
||||
frame_hdr->log2_tile_rows += gst_vp9_read_bit (br);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
loop_filter_update (GstVp9Parser * parser, const GstVp9LoopFilter * lf)
|
||||
{
|
||||
GstVp9ParserPrivate *priv = GST_VP9_PARSER_GET_PRIVATE (parser);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < GST_VP9_MAX_REF_LF_DELTAS; i++) {
|
||||
if (lf->update_ref_deltas[i])
|
||||
priv->ref_deltas[i] = lf->ref_deltas[i];
|
||||
}
|
||||
|
||||
for (i = 0; i < GST_VP9_MAX_MODE_LF_DELTAS; i++) {
|
||||
if (lf->update_mode_deltas[i])
|
||||
priv->mode_deltas[i] = lf->mode_deltas[i];
|
||||
}
|
||||
}
|
||||
|
||||
static guint8
|
||||
seg_get_base_qindex (const GstVp9Parser * parser,
|
||||
const GstVp9FrameHdr * frame_hdr, int segid)
|
||||
{
|
||||
int seg_base = frame_hdr->quant_indices.y_ac_qi;
|
||||
GstVp9ParserPrivate *priv = GST_VP9_PARSER_GET_PRIVATE (parser);
|
||||
const GstVp9SegmentationInfoData *seg = priv->segmentation + segid;
|
||||
/* DEBUG("id = %d, seg_base = %d, seg enable = %d, alt eanble = %d, abs = %d, alt= %d\n",segid,
|
||||
seg_base, frame_hdr->segmentation.enabled, seg->alternate_quantizer_enabled, priv->segmentation_abs_delta, seg->alternate_quantizer);
|
||||
*/
|
||||
if (frame_hdr->segmentation.enabled && seg->alternate_quantizer_enabled) {
|
||||
if (priv->segmentation_abs_delta)
|
||||
seg_base = seg->alternate_quantizer;
|
||||
else
|
||||
seg_base += seg->alternate_quantizer;
|
||||
}
|
||||
return clamp (seg_base, 0, MAXQ);
|
||||
}
|
||||
|
||||
static guint8
|
||||
seg_get_filter_level (const GstVp9Parser * parser,
|
||||
const GstVp9FrameHdr * frame_hdr, int segid)
|
||||
{
|
||||
int seg_filter = frame_hdr->loopfilter.filter_level;
|
||||
GstVp9ParserPrivate *priv = GST_VP9_PARSER_GET_PRIVATE (parser);
|
||||
const GstVp9SegmentationInfoData *seg = priv->segmentation + segid;
|
||||
|
||||
if (frame_hdr->segmentation.enabled && seg->alternate_loop_filter_enabled) {
|
||||
if (priv->segmentation_abs_delta)
|
||||
seg_filter = seg->alternate_loop_filter;
|
||||
else
|
||||
seg_filter += seg->alternate_loop_filter;
|
||||
}
|
||||
return clamp (seg_filter, 0, GST_VP9_MAX_LOOP_FILTER);
|
||||
}
|
||||
|
||||
/*save segmentation info from frame header to parser*/
|
||||
static void
|
||||
segmentation_save (GstVp9Parser * parser, const GstVp9FrameHdr * frame_hdr)
|
||||
{
|
||||
const GstVp9SegmentationInfo *info = &frame_hdr->segmentation;
|
||||
if (!info->enabled)
|
||||
return;
|
||||
|
||||
if (info->update_map) {
|
||||
g_assert (G_N_ELEMENTS (parser->mb_segment_tree_probs) ==
|
||||
G_N_ELEMENTS (info->tree_probs));
|
||||
g_assert (G_N_ELEMENTS (parser->segment_pred_probs) ==
|
||||
G_N_ELEMENTS (info->pred_probs));
|
||||
memcpy (parser->mb_segment_tree_probs, info->tree_probs,
|
||||
sizeof (info->tree_probs));
|
||||
memcpy (parser->segment_pred_probs, info->pred_probs,
|
||||
sizeof (info->pred_probs));
|
||||
}
|
||||
|
||||
if (info->update_data) {
|
||||
GstVp9ParserPrivate *priv = GST_VP9_PARSER_GET_PRIVATE (parser);
|
||||
priv->segmentation_abs_delta = info->abs_delta;
|
||||
g_assert (G_N_ELEMENTS (priv->segmentation) == G_N_ELEMENTS (info->data));
|
||||
memcpy (priv->segmentation, info->data, sizeof (info->data));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
segmentation_update (GstVp9Parser * parser, const GstVp9FrameHdr * frame_hdr)
|
||||
{
|
||||
int i = 0;
|
||||
const GstVp9ParserPrivate *priv = GST_VP9_PARSER_GET_PRIVATE (parser);
|
||||
const GstVp9LoopFilter *lf = &frame_hdr->loopfilter;
|
||||
const GstVp9QuantIndices *quant_indices = &frame_hdr->quant_indices;
|
||||
int default_filter = lf->filter_level;
|
||||
const int scale = 1 << (default_filter >> 5);
|
||||
|
||||
segmentation_save (parser, frame_hdr);
|
||||
|
||||
for (i = 0; i < GST_VP9_MAX_SEGMENTS; i++) {
|
||||
guint8 q = seg_get_base_qindex (parser, frame_hdr, i);
|
||||
|
||||
GstVp9Segmentation *seg = parser->segmentation + i;
|
||||
const GstVp9SegmentationInfoData *info = priv->segmentation + i;
|
||||
|
||||
seg->luma_dc_quant_scale =
|
||||
vp9_dc_quant (q, quant_indices->y_dc_delta, frame_hdr->bit_depth);
|
||||
seg->luma_ac_quant_scale = vp9_ac_quant (q, 0, frame_hdr->bit_depth);
|
||||
seg->chroma_dc_quant_scale =
|
||||
vp9_dc_quant (q, quant_indices->uv_dc_delta, frame_hdr->bit_depth);
|
||||
seg->chroma_ac_quant_scale =
|
||||
vp9_ac_quant (q, quant_indices->uv_ac_delta, frame_hdr->bit_depth);
|
||||
|
||||
if (lf->filter_level) {
|
||||
guint8 filter = seg_get_filter_level (parser, frame_hdr, i);
|
||||
|
||||
if (!lf->mode_ref_delta_enabled) {
|
||||
memset (seg->filter_level, filter, sizeof (seg->filter_level));
|
||||
} else {
|
||||
int ref, mode;
|
||||
const int intra_filter =
|
||||
filter + priv->ref_deltas[GST_VP9_REF_FRAME_INTRA] * scale;
|
||||
seg->filter_level[GST_VP9_REF_FRAME_INTRA][0] =
|
||||
clamp (intra_filter, 0, GST_VP9_MAX_LOOP_FILTER);
|
||||
for (ref = GST_VP9_REF_FRAME_LAST; ref < GST_VP9_REF_FRAME_MAX; ++ref) {
|
||||
for (mode = 0; mode < GST_VP9_MAX_MODE_LF_DELTAS; ++mode) {
|
||||
const int inter_filter = filter + priv->ref_deltas[ref] * scale
|
||||
+ priv->mode_deltas[mode] * scale;
|
||||
seg->filter_level[ref][mode] =
|
||||
clamp (inter_filter, 0, GST_VP9_MAX_LOOP_FILTER);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
seg->reference_frame_enabled = info->reference_frame_enabled;;
|
||||
seg->reference_frame = info->reference_frame;
|
||||
seg->reference_skip = info->reference_skip;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
reference_update (GstVp9Parser * parser, const GstVp9FrameHdr * const frame_hdr)
|
||||
{
|
||||
guint8 flag = 1;
|
||||
guint8 refresh_frame_flags;
|
||||
int i;
|
||||
GstVp9ParserPrivate *priv = GST_VP9_PARSER_GET_PRIVATE (parser);
|
||||
ReferenceSize *reference = priv->reference;
|
||||
if (frame_hdr->frame_type == GST_VP9_KEY_FRAME) {
|
||||
refresh_frame_flags = 0xff;
|
||||
} else {
|
||||
refresh_frame_flags = frame_hdr->refresh_frame_flags;
|
||||
}
|
||||
for (i = 0; i < GST_VP9_REF_FRAMES; i++) {
|
||||
if (refresh_frame_flags & flag) {
|
||||
reference[i].width = frame_hdr->width;
|
||||
reference[i].height = frame_hdr->height;
|
||||
}
|
||||
flag <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int
|
||||
frame_is_intra_only (const GstVp9FrameHdr * frame_hdr)
|
||||
{
|
||||
return frame_hdr->frame_type == GST_VP9_KEY_FRAME || frame_hdr->intra_only;
|
||||
}
|
||||
|
||||
static void
|
||||
set_default_lf_deltas (GstVp9Parser * parser)
|
||||
{
|
||||
GstVp9ParserPrivate *priv = GST_VP9_PARSER_GET_PRIVATE (parser);
|
||||
priv->ref_deltas[GST_VP9_REF_FRAME_INTRA] = 1;
|
||||
priv->ref_deltas[GST_VP9_REF_FRAME_LAST] = 0;
|
||||
priv->ref_deltas[GST_VP9_REF_FRAME_GOLDEN] = -1;
|
||||
priv->ref_deltas[GST_VP9_REF_FRAME_ALTREF] = -1;
|
||||
|
||||
priv->mode_deltas[0] = 0;
|
||||
priv->mode_deltas[1] = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
set_default_segmentation_info (GstVp9Parser * parser)
|
||||
{
|
||||
GstVp9ParserPrivate *priv = GST_VP9_PARSER_GET_PRIVATE (parser);
|
||||
|
||||
memset (priv->segmentation, 0, sizeof (priv->segmentation));
|
||||
|
||||
priv->segmentation_abs_delta = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
setup_past_independence (GstVp9Parser * parser,
|
||||
GstVp9FrameHdr * const frame_hdr)
|
||||
{
|
||||
set_default_lf_deltas (parser);
|
||||
set_default_segmentation_info (parser);
|
||||
|
||||
memset (frame_hdr->ref_frame_sign_bias, 0,
|
||||
sizeof (frame_hdr->ref_frame_sign_bias));
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vp9_parser_init (GstVp9Parser * parser)
|
||||
{
|
||||
GstVp9ParserPrivate *priv = parser->priv;
|
||||
|
||||
memset (parser, 0, sizeof (GstVp9Parser));
|
||||
memset (priv, 0, sizeof (GstVp9ParserPrivate));
|
||||
|
||||
parser->priv = priv;
|
||||
}
|
||||
|
||||
static GstVp9ParserResult
|
||||
gst_vp9_parser_update (GstVp9Parser * parser, GstVp9FrameHdr * const frame_hdr)
|
||||
{
|
||||
if (frame_hdr->frame_type == GST_VP9_KEY_FRAME)
|
||||
gst_vp9_parser_init (parser);
|
||||
|
||||
if (frame_is_intra_only (frame_hdr) || frame_hdr->error_resilient_mode)
|
||||
setup_past_independence (parser, frame_hdr);
|
||||
|
||||
loop_filter_update (parser, &frame_hdr->loopfilter);
|
||||
segmentation_update (parser, frame_hdr);
|
||||
reference_update (parser, frame_hdr);
|
||||
|
||||
return GST_VP9_PARSER_OK;
|
||||
}
|
||||
|
||||
|
||||
/******** API *************/
|
||||
|
||||
/**
|
||||
* gst_vp9_parser_new:
|
||||
*
|
||||
* Creates a new #GstVp9Parser. It should be freed with
|
||||
* gst_vp9_parser_free after use.
|
||||
*
|
||||
* Returns: a new #GstVp9Parser
|
||||
*/
|
||||
GstVp9Parser *
|
||||
gst_vp9_parser_new (void)
|
||||
{
|
||||
GstVp9Parser *parser;
|
||||
GstVp9ParserPrivate *priv;
|
||||
|
||||
INITIALIZE_DEBUG_CATEGORY;
|
||||
GST_DEBUG ("Create VP9 Parser");
|
||||
|
||||
parser = g_slice_new (GstVp9Parser);
|
||||
if (!parser)
|
||||
return NULL;
|
||||
|
||||
priv = g_slice_new (GstVp9ParserPrivate);
|
||||
if (!priv)
|
||||
return NULL;
|
||||
|
||||
parser->priv = priv;
|
||||
gst_vp9_parser_init (parser);
|
||||
|
||||
return parser;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vp9_parser_free:
|
||||
* @parser: the #GstVp9Parser to free
|
||||
*
|
||||
* Frees @parser and sets it to %NULL
|
||||
*/
|
||||
void
|
||||
gst_vp9_parser_free (GstVp9Parser * parser)
|
||||
{
|
||||
if (parser) {
|
||||
if (parser->priv) {
|
||||
g_slice_free (GstVp9ParserPrivate, parser->priv);
|
||||
parser->priv = NULL;
|
||||
}
|
||||
g_slice_free (GstVp9Parser, parser);
|
||||
parser = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vp9_parser_parse_frame_header:
|
||||
* @parser: The #GstVp9Parser
|
||||
* @frame_hdr: The #GstVp9FrameHdr to fill
|
||||
* @data: The data to parse
|
||||
* @size: The size of the @data to parse
|
||||
*
|
||||
* Parses the VP9 bitstream contained in @data, and fills in @frame_hdr
|
||||
* with the information. The @size argument represent the whole frame size.
|
||||
*
|
||||
* Returns: a #GstVp9ParserResult
|
||||
*
|
||||
*/
|
||||
GstVp9ParserResult
|
||||
gst_vp9_parser_parse_frame_header (GstVp9Parser * parser,
|
||||
GstVp9FrameHdr * frame_hdr, const guint8 * data, gsize size)
|
||||
{
|
||||
GstBitReader bit_reader;
|
||||
GstBitReader *br = &bit_reader;
|
||||
|
||||
gst_bit_reader_init (br, data, size);
|
||||
memset (frame_hdr, 0, sizeof (*frame_hdr));
|
||||
|
||||
/* Parsing Uncompressed Data Chunk */
|
||||
|
||||
if (!verify_frame_marker (br))
|
||||
goto error;
|
||||
|
||||
frame_hdr->profile = parse_profile (br);
|
||||
if (frame_hdr->profile > GST_VP9_PROFILE_UNDEFINED) {
|
||||
GST_ERROR ("Stream has undefined VP9 profile !");
|
||||
goto error;
|
||||
}
|
||||
|
||||
frame_hdr->show_existing_frame = gst_vp9_read_bit (br);
|
||||
if (frame_hdr->show_existing_frame) {
|
||||
frame_hdr->frame_to_show = gst_vp9_read_bits (br, GST_VP9_REF_FRAMES_LOG2);
|
||||
return GST_VP9_PARSER_OK;
|
||||
}
|
||||
|
||||
frame_hdr->frame_type = gst_vp9_read_bit (br);
|
||||
frame_hdr->show_frame = gst_vp9_read_bit (br);
|
||||
frame_hdr->error_resilient_mode = gst_vp9_read_bit (br);
|
||||
|
||||
if (frame_hdr->frame_type == GST_VP9_KEY_FRAME) {
|
||||
|
||||
if (!verify_sync_code (br)) {
|
||||
GST_ERROR ("Invalid VP9 Key-frame sync code !");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!parse_bitdepth_colorspace_sampling (br, frame_hdr)) {
|
||||
GST_ERROR ("Failed to parse color_space/bit_depth info !");
|
||||
goto error;
|
||||
}
|
||||
|
||||
parse_frame_size (br, &frame_hdr->width, &frame_hdr->height);
|
||||
|
||||
parse_display_frame_size (br, frame_hdr);
|
||||
|
||||
} else {
|
||||
frame_hdr->intra_only = frame_hdr->show_frame ? 0 : gst_vp9_read_bit (br);
|
||||
frame_hdr->reset_frame_context = frame_hdr->error_resilient_mode ?
|
||||
0 : gst_vp9_read_bits (br, 2);
|
||||
|
||||
if (frame_hdr->intra_only) {
|
||||
|
||||
if (!verify_sync_code (br)) {
|
||||
GST_ERROR ("Invalid VP9 sync code in intra-only frame !");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (frame_hdr->profile > GST_VP9_PROFILE_0) {
|
||||
if (!parse_bitdepth_colorspace_sampling (br, frame_hdr)) {
|
||||
GST_ERROR ("Failed to parse color_space/bit_depth info !");
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
frame_hdr->color_space = GST_VP9_CS_BT_601;
|
||||
frame_hdr->color_range = GST_VP9_CR_LIMITED;
|
||||
frame_hdr->subsampling_y = frame_hdr->subsampling_x = 1;
|
||||
frame_hdr->bit_depth = GST_VP9_BIT_DEPTH_8;
|
||||
}
|
||||
|
||||
frame_hdr->refresh_frame_flags =
|
||||
gst_vp9_read_bits (br, GST_VP9_REF_FRAMES);
|
||||
parse_frame_size (br, &frame_hdr->width, &frame_hdr->height);
|
||||
parse_display_frame_size (br, frame_hdr);
|
||||
|
||||
} else {
|
||||
int i;
|
||||
frame_hdr->refresh_frame_flags =
|
||||
gst_vp9_read_bits (br, GST_VP9_REF_FRAMES);
|
||||
|
||||
for (i = 0; i < GST_VP9_REFS_PER_FRAME; i++) {
|
||||
frame_hdr->ref_frame_indices[i] =
|
||||
gst_vp9_read_bits (br, GST_VP9_REF_FRAMES_LOG2);
|
||||
frame_hdr->ref_frame_sign_bias[i] = gst_vp9_read_bit (br);
|
||||
}
|
||||
|
||||
parse_frame_size_from_refs (parser, frame_hdr, br);
|
||||
parse_display_frame_size (br, frame_hdr);
|
||||
|
||||
frame_hdr->allow_high_precision_mv = gst_vp9_read_bit (br);
|
||||
frame_hdr->mcomp_filter_type = parse_interp_filter (br);
|
||||
|
||||
/* Assing defalut values */
|
||||
frame_hdr->color_space = GST_VP9_CS_BT_601;
|
||||
frame_hdr->color_range = GST_VP9_CR_LIMITED;
|
||||
frame_hdr->subsampling_y = frame_hdr->subsampling_x = 1;
|
||||
frame_hdr->bit_depth = GST_VP9_BIT_DEPTH_8;
|
||||
}
|
||||
}
|
||||
|
||||
frame_hdr->refresh_frame_context =
|
||||
frame_hdr->error_resilient_mode ? 0 : gst_vp9_read_bit (br);
|
||||
frame_hdr->frame_parallel_decoding_mode =
|
||||
frame_hdr->error_resilient_mode ? 1 : gst_vp9_read_bit (br);
|
||||
frame_hdr->frame_context_idx =
|
||||
gst_vp9_read_bits (br, GST_FRAME_CONTEXTS_LOG2);
|
||||
|
||||
/* loopfilter header */
|
||||
parse_loopfilter (&frame_hdr->loopfilter, br);
|
||||
|
||||
/* quantization header */
|
||||
parse_quantization (&frame_hdr->quant_indices, br);
|
||||
/* set lossless_flag */
|
||||
frame_hdr->lossless_flag = frame_hdr->quant_indices.y_ac_qi == 0 &&
|
||||
frame_hdr->quant_indices.y_dc_delta == 0 &&
|
||||
frame_hdr->quant_indices.uv_dc_delta == 0
|
||||
&& frame_hdr->quant_indices.uv_ac_delta == 0;
|
||||
|
||||
/* segmentation header */
|
||||
parse_segmentation (&frame_hdr->segmentation, br);
|
||||
|
||||
/* tile header */
|
||||
if (!parse_tile_info (frame_hdr, br)) {
|
||||
GST_ERROR ("Failed to parse tile info...!");
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* size of the rest of the header */
|
||||
frame_hdr->first_partition_size = gst_vp9_read_bits (br, 16);
|
||||
if (!frame_hdr->first_partition_size) {
|
||||
GST_ERROR ("Failed to parse the first partition size...!");
|
||||
goto error;
|
||||
}
|
||||
|
||||
frame_hdr->frame_header_length_in_bytes =
|
||||
(gst_bit_reader_get_pos (br) + 7) / 8;
|
||||
|
||||
return gst_vp9_parser_update (parser, frame_hdr);
|
||||
|
||||
error:
|
||||
return GST_VP9_PARSER_ERROR;
|
||||
}
|
464
gst-libs/gst/codecparsers/gstvp9parser.h
Normal file
464
gst-libs/gst/codecparsers/gstvp9parser.h
Normal file
|
@ -0,0 +1,464 @@
|
|||
/*
|
||||
* gstvp9parser.h
|
||||
*
|
||||
* Copyright (C) 2013-2014 Intel Corporation
|
||||
* Copyright (C) 2015 Intel Corporation
|
||||
* Author: XuGuangxin<Guangxin.Xu@intel.com>
|
||||
* Author: Sreerenj Balachandran<sreerenj.balachandran@intel.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef GST_VP9_PARSER_H
|
||||
#define GST_VP9_PARSER_H
|
||||
|
||||
#ifndef GST_USE_UNSTABLE_API
|
||||
#warning "The VP9 parsing library is unstable API and may change in future."
|
||||
#warning "You can define GST_USE_UNSTABLE_API to avoid this warning."
|
||||
#endif
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_VP9_FRAME_MARKER 0x02
|
||||
#define GST_VP9_SYNC_CODE 0x498342
|
||||
|
||||
#define GST_VP9_MAX_LOOP_FILTER 63
|
||||
#define GST_VP9_MAX_PROB 255
|
||||
|
||||
#define GST_VP9_REFS_PER_FRAME 3
|
||||
#define GST_VP9_REF_FRAMES_LOG2 3
|
||||
#define GST_VP9_REF_FRAMES (1 << GST_VP9_REF_FRAMES_LOG2)
|
||||
|
||||
#define GST_FRAME_CONTEXTS_LOG2 2
|
||||
|
||||
#define GST_VP9_MAX_LOOP_FILTER 63
|
||||
#define GST_VP9_MAX_SHARPNESS 7
|
||||
|
||||
#define GST_VP9_MAX_REF_LF_DELTAS 4
|
||||
#define GST_VP9_MAX_MODE_LF_DELTAS 2
|
||||
|
||||
#define GST_VP9_SEGMENT_DELTADATA 0
|
||||
#define GST_VP9_SEGMENT_ABSDATA 1
|
||||
|
||||
#define GST_VP9_MAX_SEGMENTS 8
|
||||
#define GST_VP9_SEG_TREE_PROBS (GST_VP9_MAX_SEGMENTS-1)
|
||||
|
||||
#define GST_VP9_PREDICTION_PROBS 3
|
||||
|
||||
typedef struct _GstVp9Parser GstVp9Parser;
|
||||
typedef struct _GstVp9FrameHdr GstVp9FrameHdr;
|
||||
typedef struct _GstVp9LoopFilter GstVp9LoopFilter;
|
||||
typedef struct _GstVp9QuantIndices GstVp9QuantIndices;
|
||||
typedef struct _GstVp9Segmentation GstVp9Segmentation;
|
||||
typedef struct _GstVp9SegmentationInfo GstVp9SegmentationInfo;
|
||||
typedef struct _GstVp9SegmentationInfoData GstVp9SegmentationInfoData;
|
||||
|
||||
/**
|
||||
* GstVp9ParseResult:
|
||||
* @GST_VP9_PARSER_OK: The parsing went well
|
||||
* @GST_VP9_PARSER_BROKEN_DATA: The data to parse is broken
|
||||
* @GST_VP9_PARSER_NO_PACKET_ERROR: An error accured durint the parsing
|
||||
*
|
||||
* Result type of any parsing function.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
GST_VP9_PARSER_OK,
|
||||
GST_VP9_PARSER_BROKEN_DATA,
|
||||
GST_VP9_PARSER_ERROR,
|
||||
} GstVp9ParserResult;
|
||||
|
||||
/**
|
||||
* GstVp9Profile: Bitstream profiles indicated by 2-3 bits in the uncompressed header
|
||||
* @GST_VP9_PROFILE_0: Profile 0, 8-bit 4:2:0 only.
|
||||
* @GST_VP9_PROFILE_1: Profile 1, 8-bit 4:4:4, 4:2:2, and 4:4:0.
|
||||
* @GST_VP9_PROFILE_2: Profile 2, 10-bit and 12-bit color only, with 4:2:0 sampling.
|
||||
* @GST_VP9_PROFILE_3: Profile 3, 10-bit and 12-bit color only, with 4:2:2/4:4:4/4:4:0 sampling.
|
||||
* @GST_VP9_PROFILE_UNDEFINED: Undefined profile
|
||||
*
|
||||
* VP9 Profiles
|
||||
*/
|
||||
typedef enum {
|
||||
GST_VP9_PROFILE_0,
|
||||
GST_VP9_PROFILE_1,
|
||||
GST_VP9_PROFILE_2,
|
||||
GST_VP9_PROFILE_3,
|
||||
GST_VP9_PROFILE_UNDEFINED
|
||||
} GstVP9Profile;
|
||||
|
||||
/**
|
||||
* GstVp9FrameType:
|
||||
* @GST_VP9_KEY_FRAME: Key frame, only have intra blocks
|
||||
* @GST_VP9_INTER_FRAME: Inter frame, both intra and inter blocks
|
||||
*
|
||||
* VP9 frame types
|
||||
*/
|
||||
typedef enum {
|
||||
GST_VP9_KEY_FRAME = 0,
|
||||
GST_VP9_INTER_FRAME = 1
|
||||
} GstVp9FrameType;
|
||||
|
||||
/**
|
||||
* GstVp9BitDepth:
|
||||
* @GST_VP9_BIT_DEPTH_8: Bit depth is 8
|
||||
* @GST_VP9_BIT_DEPTH_10 Bit depth is 10
|
||||
* @GST_VP9_BIT_DEPTH_12:Bit depth is 12
|
||||
*
|
||||
* Bit depths of encoded frames
|
||||
*/
|
||||
typedef enum {
|
||||
GST_VP9_BIT_DEPTH_8 = 8,
|
||||
GST_VP9_BIT_DEPTH_10 = 10,
|
||||
GST_VP9_BIT_DEPTH_12 = 12
|
||||
} GstVp9BitDepth;
|
||||
|
||||
/**
|
||||
* GstVp9ColorSpace:
|
||||
* @GST_VP9_CS_UNKNOWN: Unknown color space
|
||||
* @GST_VP9_CS_BT_601: BT.601
|
||||
* @GST_VP9_CS_BT_709: BT.709
|
||||
* @GST_VP9_CS_SMPTE_170: SMPTE.170
|
||||
* @GST_VP9_CS_SMPTE_240: SMPTE.240
|
||||
* @GST_VP9_CS_BT_2020: BT.2020
|
||||
* @GST_VP9_CS_RESERVED: Reserved
|
||||
* @GST_VP9_CS_SRGB: sRGB
|
||||
*
|
||||
* Supported ColorSpace standards
|
||||
*/
|
||||
typedef enum {
|
||||
GST_VP9_CS_UNKNOWN = 0,
|
||||
GST_VP9_CS_BT_601 = 1,
|
||||
GST_VP9_CS_BT_709 = 2,
|
||||
GST_VP9_CS_SMPTE_170 = 3,
|
||||
GST_VP9_CS_SMPTE_240 = 4,
|
||||
GST_VP9_CS_BT_2020 = 5,
|
||||
GST_VP9_CS_RESERVED_2 = 6,
|
||||
GST_VP9_CS_SRGB = 7
|
||||
} GstVp9ColorSpace;
|
||||
|
||||
/**
|
||||
* GstVp9ColorRange:
|
||||
* @GST_VP9_CR_LIMITED: Y range is [16-235], UV range is [16-240]
|
||||
* @GST_VP9_CR_FULL: Full range for Y,U and V [0-255]
|
||||
*
|
||||
* Possible color value ranges
|
||||
*/
|
||||
typedef enum {
|
||||
GST_VP9_CR_LIMITED,
|
||||
GST_VP9_CR_FULL
|
||||
} GstVp9ColorRange;
|
||||
|
||||
/**
|
||||
* GstVp9InterpFilter:
|
||||
* @GST_VP9_INTERP_FILTER_EIGHTTAP: EightTap interpolation filter
|
||||
* @GST_VP9_INTERP_FILTER_EIGHTTAP_SMOOTH: Smooth interpolation filter
|
||||
* @GST_VP9_INTERP_FILTER_EIGHTTAP_SHARP: Shart interpolation filter
|
||||
* @GST_VP9_INTERP_FILTER_BILINEAR: Bilinear interpolation filter
|
||||
* @GST_VP9_INTERP_FILTER_SWITCHABLE: Selectable interpolation filter
|
||||
*
|
||||
* Interpolation Filters Types
|
||||
*/
|
||||
typedef enum {
|
||||
GST_VP9_INTERP_FILTER_EIGHTTAP = 0,
|
||||
GST_VP9_INTERP_FILTER_EIGHTTAP_SMOOTH = 1,
|
||||
GST_VP9_INTERP_FILTER_EIGHTTAP_SHARP = 2,
|
||||
GST_VP9_INTERP_FILTER_BILINEAR = 3,
|
||||
GST_VP9_INTERP_FILTER_SWITCHABLE = 4
|
||||
} GstVp9InterpFilter;
|
||||
|
||||
/**
|
||||
* GstVp9RefFrameType:
|
||||
* @GST_VP9_REF_FRAME_INTRA: Intra reference frame
|
||||
* @GST_VP9_REF_FRAME_LAST: Last Reference frame
|
||||
* @GST_VP9_REF_FRAME_GOLDEN: Golden Reference frame
|
||||
* @GST_VP9_REF_FRAME_ALTREF: Alternate Reference frame
|
||||
* @GST_VP9_REF_FRAME_MAX:
|
||||
*
|
||||
* Reference Frame types
|
||||
*/
|
||||
typedef enum {
|
||||
GST_VP9_REF_FRAME_INTRA = 0,
|
||||
GST_VP9_REF_FRAME_LAST = 1,
|
||||
GST_VP9_REF_FRAME_GOLDEN = 2,
|
||||
GST_VP9_REF_FRAME_ALTREF = 3,
|
||||
GST_VP9_REF_FRAME_MAX = 4
|
||||
} GstVp9RefFrameType;
|
||||
|
||||
/**
|
||||
* GstVp9QuantIndices:
|
||||
* @y_ac_qi: indicates the dequantization table index used for the
|
||||
* luma AC coefficients
|
||||
* @y_dc_delta: indicates the delta value that is added to the
|
||||
* baseline index to obtain the luma DC coefficient dequantization
|
||||
* index
|
||||
* @uv_dc_delta: indicates the delta value that is added to the
|
||||
* baseline index to obtain the chroma DC coefficient dequantization
|
||||
* index
|
||||
* @uv_ac_delta: indicates the delta value that is added to the
|
||||
* baseline index to obtain the chroma AC coefficient dequantization
|
||||
* index
|
||||
*
|
||||
* Dequantization indices.
|
||||
*/
|
||||
struct _GstVp9QuantIndices
|
||||
{
|
||||
guint8 y_ac_qi;
|
||||
gint8 y_dc_delta;
|
||||
gint8 uv_dc_delta;
|
||||
gint8 uv_ac_delta;
|
||||
};
|
||||
|
||||
/**
|
||||
* GstVp9MbLoofFilter:
|
||||
* @filter_level: indicates loop filter level for the current frame
|
||||
* @sharpness_level: indicates sharpness level for thecurrent frame
|
||||
* @mode_ref_delta_enabled: indicate if filter adjust is on
|
||||
* @mode_ref_delta_update: indicates if the delta values used in an
|
||||
* adjustment are updated in the current frame
|
||||
* @update_ref_deltas: indicate which ref deltas are updated
|
||||
* @ref_deltas: Loop filter strength adjustments based on
|
||||
* frame type (intra, inter)
|
||||
* @update_mode_deltas: indicate with mode deltas are updated
|
||||
* @mode_deltas: Loop filter strength adjustments based on
|
||||
* mode (zero, new mv)
|
||||
*
|
||||
* Loop filter values
|
||||
*/
|
||||
struct _GstVp9LoopFilter {
|
||||
gint filter_level;
|
||||
gint sharpness_level;
|
||||
|
||||
guint8 mode_ref_delta_enabled;
|
||||
guint8 mode_ref_delta_update;
|
||||
guint8 update_ref_deltas[GST_VP9_MAX_REF_LF_DELTAS];
|
||||
gint8 ref_deltas[GST_VP9_MAX_REF_LF_DELTAS];
|
||||
guint8 update_mode_deltas[GST_VP9_MAX_MODE_LF_DELTAS];
|
||||
gint8 mode_deltas[GST_VP9_MAX_MODE_LF_DELTAS];
|
||||
};
|
||||
|
||||
/**
|
||||
* GstVp9SegmentationInfoData:
|
||||
* @alternate_quantizer_enabled: indicate alternate quantizer enabled at segment level
|
||||
* @alternate_quantizer: alternate quantizer value
|
||||
* @alternate_loop_filter_enabled: indicate alternate loop filter enabled at segment level
|
||||
* @alternate_loop_filter: alternate loop filter
|
||||
* @reference_frame_enabled: indicate alternate reference frame at segment level
|
||||
* @reference_frame: alternate reference frame
|
||||
* @reference_skip: a block skip mode that implies both the use of a (0,0)
|
||||
* motion vector and that no residual will be coded.
|
||||
*
|
||||
* Segemtnation info for each segment
|
||||
*
|
||||
*/
|
||||
struct _GstVp9SegmentationInfoData {
|
||||
/* SEG_LVL_ALT_Q */
|
||||
guint8 alternate_quantizer_enabled;
|
||||
gint16 alternate_quantizer;
|
||||
|
||||
/* SEG_LVL_ALT_LF */
|
||||
guint8 alternate_loop_filter_enabled;
|
||||
gint8 alternate_loop_filter;
|
||||
|
||||
/* SEG_LVL_REF_FRAME */
|
||||
guint8 reference_frame_enabled;
|
||||
gint reference_frame;
|
||||
|
||||
guint8 reference_skip;
|
||||
};
|
||||
|
||||
/**
|
||||
* GstVp9SegmentationInfo:
|
||||
* @enabled: enables the segmentation feature for the current frame
|
||||
* @update_map: determines if segmentation is updated in the current frame
|
||||
* @update_tree_probs: determines if tree probabilities updated or not
|
||||
* @tree_probs: segment tree probabilities
|
||||
* @update_pred_probs:determines if prediction probabilities updated or not
|
||||
* @pred_probs: prediction probabilities
|
||||
* @abs_delta: interpretation of segment data values
|
||||
* @temporal_update: type of map update
|
||||
* @update_data: indicates if the segment feature data
|
||||
* is updated in the current frame
|
||||
* @data: segment feature data
|
||||
*
|
||||
* Segmentation info
|
||||
*/
|
||||
struct _GstVp9SegmentationInfo {
|
||||
/* enable in setup_segmentation*/
|
||||
guint8 enabled;
|
||||
/* update_map in setup_segmentation*/
|
||||
guint8 update_map;
|
||||
/* tree_probs exist or not*/
|
||||
guint8 update_tree_probs[GST_VP9_SEG_TREE_PROBS];
|
||||
guint8 tree_probs[GST_VP9_SEG_TREE_PROBS];
|
||||
/* pred_probs exist or not*/
|
||||
guint8 update_pred_probs[GST_VP9_PREDICTION_PROBS];
|
||||
guint8 pred_probs[GST_VP9_PREDICTION_PROBS];
|
||||
|
||||
/* abs_delta in setup_segmentation */
|
||||
guint8 abs_delta;
|
||||
/* temporal_update in setup_segmentation */
|
||||
guint8 temporal_update;
|
||||
|
||||
/* update_data in setup_segmentation*/
|
||||
guint8 update_data;
|
||||
GstVp9SegmentationInfoData data[GST_VP9_MAX_SEGMENTS];
|
||||
};
|
||||
|
||||
/**
|
||||
* GstVp9FrameHdr:
|
||||
* @profile: encoded profile
|
||||
* @show_existing_frame: display already decoded frame instead of doing the decoding
|
||||
* @frame_to_show: which frame to show if show_existing_frame is true
|
||||
* @frame_type: frame type
|
||||
* @show_frame: indicate whether is it displayable frame or not
|
||||
* @error_resilient_mode: error resilent mode
|
||||
* @subsampling_x: horizontal subsampling
|
||||
* @subsampling_y: vertical subsampling
|
||||
* @width: frame width
|
||||
* @height: frame height
|
||||
* @display_size_enabled: display size enabled (cropping)
|
||||
* @display_width: display width
|
||||
* @display_height: display height
|
||||
* @frame_context_idx: frame context index
|
||||
* @bit_depth: bit depth of the stream
|
||||
* @color_space: color space standard
|
||||
* @color_range: color range standard
|
||||
* @intra_only: intra only frame
|
||||
* @reset_frame_context: reset frame context
|
||||
* @refresh_frame_flags: refresh reference frame flags
|
||||
* @ref_frame_indices: reference frame index
|
||||
* @ref_frame_sign_bias: sign bias for selecting altref,last and golden frames
|
||||
* @allow_high_precision_mv: allow hight precision motion vector
|
||||
* @mcomp_filter_type: interpolation filter type
|
||||
* @refresh_frame_context: refresh frame context indicator
|
||||
* @frame_parallel_decoding_mode: enable or disable parallel decoding support.
|
||||
* @loopfilter: loopfilter values
|
||||
* @quant_indices: quantization indeces
|
||||
* @segmentation: segmentation info
|
||||
* @log2_tile_rows: tile row indicator
|
||||
* @log2_tile_columns: tile column indicator
|
||||
* @first_partition_size: first partition size (after the uncompressed header)
|
||||
* @lossless_flag: lossless mode decode
|
||||
* @frame_header_length_in_bytes: length of uncompressed header
|
||||
*
|
||||
* Frame header
|
||||
*/
|
||||
struct _GstVp9FrameHdr
|
||||
{
|
||||
guint profile;
|
||||
guint8 show_existing_frame;
|
||||
gint frame_to_show;
|
||||
guint frame_type;
|
||||
guint8 show_frame;
|
||||
guint8 error_resilient_mode;
|
||||
gint subsampling_x;
|
||||
gint subsampling_y;
|
||||
guint32 width;
|
||||
guint32 height;
|
||||
guint8 display_size_enabled;
|
||||
guint32 display_width;
|
||||
guint32 display_height;
|
||||
guint frame_context_idx;
|
||||
|
||||
guint bit_depth;
|
||||
guint color_space;
|
||||
guint color_range;
|
||||
|
||||
guint8 intra_only;
|
||||
gint reset_frame_context;
|
||||
gint refresh_frame_flags;
|
||||
|
||||
gint ref_frame_indices[GST_VP9_REFS_PER_FRAME];
|
||||
gint ref_frame_sign_bias[GST_VP9_REFS_PER_FRAME];
|
||||
gint allow_high_precision_mv;
|
||||
guint8 mcomp_filter_type;
|
||||
|
||||
gint refresh_frame_context;
|
||||
/* frame_parallel_decoding_mode in vp9 code*/
|
||||
gint frame_parallel_decoding_mode;
|
||||
|
||||
GstVp9LoopFilter loopfilter;
|
||||
GstVp9QuantIndices quant_indices;
|
||||
GstVp9SegmentationInfo segmentation;
|
||||
|
||||
gint log2_tile_rows;
|
||||
gint log2_tile_columns;
|
||||
|
||||
guint32 first_partition_size;
|
||||
|
||||
/* calculated values */
|
||||
guint lossless_flag;
|
||||
guint32 frame_header_length_in_bytes;
|
||||
};
|
||||
|
||||
/**
|
||||
* GstVp9Segmentation:
|
||||
* @filter_level: loop filter level
|
||||
* @luma_ac_quant_scale: AC quant scale for luma(Y) component
|
||||
* @luma_dc_quant_scale: DC quant scale for luma(Y) component
|
||||
* @chroma_ac_quant_scale AC quant scale for chroma(U/V) component
|
||||
* @chroma_dc_quant_scale: DC quant scale for chroma (U/V) component
|
||||
* @reference_frame_enabled: alternate reference frame enablement
|
||||
* @reference_frame: alternate reference frame
|
||||
* @reference_skip: a block skip mode that implies both the use of a (0,0)
|
||||
* motion vector and that no residual will be coded
|
||||
*
|
||||
* Segmentation info kept across multipe frames
|
||||
*/
|
||||
struct _GstVp9Segmentation
|
||||
{
|
||||
guint8 filter_level[4][2];
|
||||
gint16 luma_ac_quant_scale;
|
||||
gint16 luma_dc_quant_scale;
|
||||
gint16 chroma_ac_quant_scale;
|
||||
gint16 chroma_dc_quant_scale;
|
||||
|
||||
guint8 reference_frame_enabled;
|
||||
gint reference_frame;
|
||||
|
||||
guint8 reference_skip;
|
||||
};
|
||||
|
||||
/**
|
||||
* GstVp9Parser:
|
||||
* @priv: GstVp9ParserPrivate struct to keep track of state variables
|
||||
* @mb_segment_tree_probs: decoding tree probabilities
|
||||
* @segment_pred_probs: segement prediction probabiilties
|
||||
* @segmentation: Segemenation info
|
||||
*
|
||||
* Parser context that needs to be live across frames
|
||||
*/
|
||||
struct _GstVp9Parser
|
||||
{
|
||||
/* private stuct for tracking state variables across frames */
|
||||
void *priv;
|
||||
|
||||
guint8 mb_segment_tree_probs[GST_VP9_SEG_TREE_PROBS];
|
||||
guint8 segment_pred_probs[GST_VP9_PREDICTION_PROBS];
|
||||
GstVp9Segmentation segmentation[GST_VP9_MAX_SEGMENTS];
|
||||
};
|
||||
|
||||
GstVp9Parser * gst_vp9_parser_new (void);
|
||||
|
||||
GstVp9ParserResult gst_vp9_parser_parse_frame_header (GstVp9Parser* parser, GstVp9FrameHdr * frame_hdr, const guint8 * data, gsize size);
|
||||
|
||||
void gst_vp9_parser_free (GstVp9Parser * parser);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* GST_VP9_PARSER_H */
|
100
gst-libs/gst/codecparsers/vp9utils.AUTHORS
Normal file
100
gst-libs/gst/codecparsers/vp9utils.AUTHORS
Normal file
|
@ -0,0 +1,100 @@
|
|||
# This file is automatically generated from the git commit history
|
||||
# by tools/gen_authors.sh.
|
||||
|
||||
Aaron Watry <awatry@gmail.com>
|
||||
Abo Talib Mahfoodh <ab.mahfoodh@gmail.com>
|
||||
Adrian Grange <agrange@google.com>
|
||||
Ahmad Sharif <asharif@google.com>
|
||||
Alexander Voronov <avoronov@graphics.cs.msu.ru>
|
||||
Alex Converse <alex.converse@gmail.com>
|
||||
Alexis Ballier <aballier@gentoo.org>
|
||||
Alok Ahuja <waveletcoeff@gmail.com>
|
||||
Alpha Lam <hclam@google.com>
|
||||
A.Mahfoodh <ab.mahfoodh@gmail.com>
|
||||
Ami Fischman <fischman@chromium.org>
|
||||
Andoni Morales Alastruey <ylatuya@gmail.com>
|
||||
Andres Mejia <mcitadel@gmail.com>
|
||||
Aron Rosenberg <arosenberg@logitech.com>
|
||||
Attila Nagy <attilanagy@google.com>
|
||||
changjun.yang <changjun.yang@intel.com>
|
||||
chm <chm@rock-chips.com>
|
||||
Christian Duvivier <cduvivier@google.com>
|
||||
Daniel Kang <ddkang@google.com>
|
||||
Deb Mukherjee <debargha@google.com>
|
||||
Dmitry Kovalev <dkovalev@google.com>
|
||||
Dragan Mrdjan <dmrdjan@mips.com>
|
||||
Erik Niemeyer <erik.a.niemeyer@gmail.com>
|
||||
Fabio Pedretti <fabio.ped@libero.it>
|
||||
Frank Galligan <fgalligan@google.com>
|
||||
Fredrik Söderquist <fs@opera.com>
|
||||
Fritz Koenig <frkoenig@google.com>
|
||||
Gaute Strokkenes <gaute.strokkenes@broadcom.com>
|
||||
Giuseppe Scrivano <gscrivano@gnu.org>
|
||||
Guillaume Martres <gmartres@google.com>
|
||||
Guillermo Ballester Valor <gbvalor@gmail.com>
|
||||
Hangyu Kuang <hkuang@google.com>
|
||||
Henrik Lundin <hlundin@google.com>
|
||||
Hui Su <huisu@google.com>
|
||||
Ivan Maltz <ivanmaltz@google.com>
|
||||
James Berry <jamesberry@google.com>
|
||||
James Zern <jzern@google.com>
|
||||
Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||
Janne Salonen <jsalonen@google.com>
|
||||
Jeff Faust <jfaust@google.com>
|
||||
Jeff Muizelaar <jmuizelaar@mozilla.com>
|
||||
Jeff Petkau <jpet@chromium.org>
|
||||
Jim Bankoski <jimbankoski@google.com>
|
||||
Jingning Han <jingning@google.com>
|
||||
Johann Koenig <johannkoenig@google.com>
|
||||
John Koleszar <jkoleszar@google.com>
|
||||
Joshua Bleecher Snyder <josh@treelinelabs.com>
|
||||
Joshua Litt <joshualitt@google.com>
|
||||
Justin Clift <justin@salasaga.org>
|
||||
Justin Lebar <justin.lebar@gmail.com>
|
||||
KO Myung-Hun <komh@chollian.net>
|
||||
Lou Quillio <louquillio@google.com>
|
||||
Luca Barbato <lu_zero@gentoo.org>
|
||||
Makoto Kato <makoto.kt@gmail.com>
|
||||
Mans Rullgard <mans@mansr.com>
|
||||
Marco Paniconi <marpan@google.com>
|
||||
Mark Mentovai <mark@chromium.org>
|
||||
Martin Ettl <ettl.martin78@googlemail.com>
|
||||
Martin Storsjo <martin@martin.st>
|
||||
Matthew Heaney <matthewjheaney@chromium.org>
|
||||
Michael Kohler <michaelkohler@live.com>
|
||||
Mike Frysinger <vapier@chromium.org>
|
||||
Mike Hommey <mhommey@mozilla.com>
|
||||
Mikhal Shemer <mikhal@google.com>
|
||||
Morton Jonuschat <yabawock@gmail.com>
|
||||
Parag Salasakar <img.mips1@gmail.com>
|
||||
Pascal Massimino <pascal.massimino@gmail.com>
|
||||
Patrik Westin <patrik.westin@gmail.com>
|
||||
Paul Wilkins <paulwilkins@google.com>
|
||||
Pavol Rusnak <stick@gk2.sk>
|
||||
Paweł Hajdan <phajdan@google.com>
|
||||
Philip Jägenstedt <philipj@opera.com>
|
||||
Priit Laes <plaes@plaes.org>
|
||||
Rafael Ávila de Espíndola <rafael.espindola@gmail.com>
|
||||
Rafaël Carré <funman@videolan.org>
|
||||
Ralph Giles <giles@xiph.org>
|
||||
Rob Bradford <rob@linux.intel.com>
|
||||
Ronald S. Bultje <rbultje@google.com>
|
||||
Sami Pietilä <samipietila@google.com>
|
||||
Scott Graham <scottmg@chromium.org>
|
||||
Scott LaVarnway <slavarnway@google.com>
|
||||
Shimon Doodkin <helpmepro1@gmail.com>
|
||||
Stefan Holmer <holmer@google.com>
|
||||
Suman Sunkara <sunkaras@google.com>
|
||||
Taekhyun Kim <takim@nvidia.com>
|
||||
Takanori MATSUURA <t.matsuu@gmail.com>
|
||||
Tamar Levy <tamar.levy@intel.com>
|
||||
Tero Rintaluoma <teror@google.com>
|
||||
Thijs Vermeir <thijsvermeir@gmail.com>
|
||||
Timothy B. Terriberry <tterribe@xiph.org>
|
||||
Tom Finegan <tomfinegan@google.com>
|
||||
Vignesh Venkatasubramanian <vigneshv@google.com>
|
||||
Yaowu Xu <yaowu@google.com>
|
||||
Yunqing Wang <yunqingwang@google.com>
|
||||
Google Inc.
|
||||
The Mozilla Foundation
|
||||
The Xiph.Org Foundation
|
30
gst-libs/gst/codecparsers/vp9utils.LICENSE
Normal file
30
gst-libs/gst/codecparsers/vp9utils.LICENSE
Normal file
|
@ -0,0 +1,30 @@
|
|||
Copyright (c) 2010, The WebM Project authors. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
* Neither the name of Google, nor the WebM Project, nor the names
|
||||
of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
22
gst-libs/gst/codecparsers/vp9utils.PATENTS
Normal file
22
gst-libs/gst/codecparsers/vp9utils.PATENTS
Normal file
|
@ -0,0 +1,22 @@
|
|||
Additional IP Rights Grant (Patents)
|
||||
|
||||
"This implementation" means the copyrightable works distributed by
|
||||
Google as part of the WebM Project.
|
||||
|
||||
Google hereby grants to you a perpetual, worldwide, non-exclusive,
|
||||
no-charge, royalty-free, irrevocable (except as stated in this section)
|
||||
patent license to make, have made, use, offer to sell, sell, import,
|
||||
transfer, and otherwise run, modify and propagate the contents of this
|
||||
implementation of VP8, where such license applies only to those patent
|
||||
claims, both currently owned by Google and acquired in the future,
|
||||
licensable by Google that are necessarily infringed by this
|
||||
implementation of VP8. This grant does not include claims that would be
|
||||
infringed only as a consequence of further modification of this
|
||||
implementation. If you or your agent or exclusive licensee institute or
|
||||
order or agree to the institution of patent litigation against any
|
||||
entity (including a cross-claim or counterclaim in a lawsuit) alleging
|
||||
that this implementation of VP8 or any code incorporated within this
|
||||
implementation of VP8 constitutes direct or contributory patent
|
||||
infringement, or inducement of patent infringement, then any patent
|
||||
rights granted to you under this License for this implementation of VP8
|
||||
shall terminate as of the date such litigation is filed.
|
263
gst-libs/gst/codecparsers/vp9utils.c
Normal file
263
gst-libs/gst/codecparsers/vp9utils.c
Normal file
|
@ -0,0 +1,263 @@
|
|||
/*
|
||||
* Copyright (c) 2010 The WebM project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "vp9utils.h"
|
||||
|
||||
static const int16_t dc_qlookup[QINDEX_RANGE] = {
|
||||
4, 8, 8, 9, 10, 11, 12, 12,
|
||||
13, 14, 15, 16, 17, 18, 19, 19,
|
||||
20, 21, 22, 23, 24, 25, 26, 26,
|
||||
27, 28, 29, 30, 31, 32, 32, 33,
|
||||
34, 35, 36, 37, 38, 38, 39, 40,
|
||||
41, 42, 43, 43, 44, 45, 46, 47,
|
||||
48, 48, 49, 50, 51, 52, 53, 53,
|
||||
54, 55, 56, 57, 57, 58, 59, 60,
|
||||
61, 62, 62, 63, 64, 65, 66, 66,
|
||||
67, 68, 69, 70, 70, 71, 72, 73,
|
||||
74, 74, 75, 76, 77, 78, 78, 79,
|
||||
80, 81, 81, 82, 83, 84, 85, 85,
|
||||
87, 88, 90, 92, 93, 95, 96, 98,
|
||||
99, 101, 102, 104, 105, 107, 108, 110,
|
||||
111, 113, 114, 116, 117, 118, 120, 121,
|
||||
123, 125, 127, 129, 131, 134, 136, 138,
|
||||
140, 142, 144, 146, 148, 150, 152, 154,
|
||||
156, 158, 161, 164, 166, 169, 172, 174,
|
||||
177, 180, 182, 185, 187, 190, 192, 195,
|
||||
199, 202, 205, 208, 211, 214, 217, 220,
|
||||
223, 226, 230, 233, 237, 240, 243, 247,
|
||||
250, 253, 257, 261, 265, 269, 272, 276,
|
||||
280, 284, 288, 292, 296, 300, 304, 309,
|
||||
313, 317, 322, 326, 330, 335, 340, 344,
|
||||
349, 354, 359, 364, 369, 374, 379, 384,
|
||||
389, 395, 400, 406, 411, 417, 423, 429,
|
||||
435, 441, 447, 454, 461, 467, 475, 482,
|
||||
489, 497, 505, 513, 522, 530, 539, 549,
|
||||
559, 569, 579, 590, 602, 614, 626, 640,
|
||||
654, 668, 684, 700, 717, 736, 755, 775,
|
||||
796, 819, 843, 869, 896, 925, 955, 988,
|
||||
1022, 1058, 1098, 1139, 1184, 1232, 1282, 1336,
|
||||
};
|
||||
|
||||
static const int16_t dc_qlookup_10[QINDEX_RANGE] = {
|
||||
4, 9, 10, 13, 15, 17, 20, 22,
|
||||
25, 28, 31, 34, 37, 40, 43, 47,
|
||||
50, 53, 57, 60, 64, 68, 71, 75,
|
||||
78, 82, 86, 90, 93, 97, 101, 105,
|
||||
109, 113, 116, 120, 124, 128, 132, 136,
|
||||
140, 143, 147, 151, 155, 159, 163, 166,
|
||||
170, 174, 178, 182, 185, 189, 193, 197,
|
||||
200, 204, 208, 212, 215, 219, 223, 226,
|
||||
230, 233, 237, 241, 244, 248, 251, 255,
|
||||
259, 262, 266, 269, 273, 276, 280, 283,
|
||||
287, 290, 293, 297, 300, 304, 307, 310,
|
||||
314, 317, 321, 324, 327, 331, 334, 337,
|
||||
343, 350, 356, 362, 369, 375, 381, 387,
|
||||
394, 400, 406, 412, 418, 424, 430, 436,
|
||||
442, 448, 454, 460, 466, 472, 478, 484,
|
||||
490, 499, 507, 516, 525, 533, 542, 550,
|
||||
559, 567, 576, 584, 592, 601, 609, 617,
|
||||
625, 634, 644, 655, 666, 676, 687, 698,
|
||||
708, 718, 729, 739, 749, 759, 770, 782,
|
||||
795, 807, 819, 831, 844, 856, 868, 880,
|
||||
891, 906, 920, 933, 947, 961, 975, 988,
|
||||
1001, 1015, 1030, 1045, 1061, 1076, 1090, 1105,
|
||||
1120, 1137, 1153, 1170, 1186, 1202, 1218, 1236,
|
||||
1253, 1271, 1288, 1306, 1323, 1342, 1361, 1379,
|
||||
1398, 1416, 1436, 1456, 1476, 1496, 1516, 1537,
|
||||
1559, 1580, 1601, 1624, 1647, 1670, 1692, 1717,
|
||||
1741, 1766, 1791, 1817, 1844, 1871, 1900, 1929,
|
||||
1958, 1990, 2021, 2054, 2088, 2123, 2159, 2197,
|
||||
2236, 2276, 2319, 2363, 2410, 2458, 2508, 2561,
|
||||
2616, 2675, 2737, 2802, 2871, 2944, 3020, 3102,
|
||||
3188, 3280, 3375, 3478, 3586, 3702, 3823, 3953,
|
||||
4089, 4236, 4394, 4559, 4737, 4929, 5130, 5347,
|
||||
};
|
||||
|
||||
static const int16_t dc_qlookup_12[QINDEX_RANGE] = {
|
||||
4, 12, 18, 25, 33, 41, 50, 60,
|
||||
70, 80, 91, 103, 115, 127, 140, 153,
|
||||
166, 180, 194, 208, 222, 237, 251, 266,
|
||||
281, 296, 312, 327, 343, 358, 374, 390,
|
||||
405, 421, 437, 453, 469, 484, 500, 516,
|
||||
532, 548, 564, 580, 596, 611, 627, 643,
|
||||
659, 674, 690, 706, 721, 737, 752, 768,
|
||||
783, 798, 814, 829, 844, 859, 874, 889,
|
||||
904, 919, 934, 949, 964, 978, 993, 1008,
|
||||
1022, 1037, 1051, 1065, 1080, 1094, 1108, 1122,
|
||||
1136, 1151, 1165, 1179, 1192, 1206, 1220, 1234,
|
||||
1248, 1261, 1275, 1288, 1302, 1315, 1329, 1342,
|
||||
1368, 1393, 1419, 1444, 1469, 1494, 1519, 1544,
|
||||
1569, 1594, 1618, 1643, 1668, 1692, 1717, 1741,
|
||||
1765, 1789, 1814, 1838, 1862, 1885, 1909, 1933,
|
||||
1957, 1992, 2027, 2061, 2096, 2130, 2165, 2199,
|
||||
2233, 2267, 2300, 2334, 2367, 2400, 2434, 2467,
|
||||
2499, 2532, 2575, 2618, 2661, 2704, 2746, 2788,
|
||||
2830, 2872, 2913, 2954, 2995, 3036, 3076, 3127,
|
||||
3177, 3226, 3275, 3324, 3373, 3421, 3469, 3517,
|
||||
3565, 3621, 3677, 3733, 3788, 3843, 3897, 3951,
|
||||
4005, 4058, 4119, 4181, 4241, 4301, 4361, 4420,
|
||||
4479, 4546, 4612, 4677, 4742, 4807, 4871, 4942,
|
||||
5013, 5083, 5153, 5222, 5291, 5367, 5442, 5517,
|
||||
5591, 5665, 5745, 5825, 5905, 5984, 6063, 6149,
|
||||
6234, 6319, 6404, 6495, 6587, 6678, 6769, 6867,
|
||||
6966, 7064, 7163, 7269, 7376, 7483, 7599, 7715,
|
||||
7832, 7958, 8085, 8214, 8352, 8492, 8635, 8788,
|
||||
8945, 9104, 9275, 9450, 9639, 9832, 10031, 10245,
|
||||
10465, 10702, 10946, 11210, 11482, 11776, 12081, 12409,
|
||||
12750, 13118, 13501, 13913, 14343, 14807, 15290, 15812,
|
||||
16356, 16943, 17575, 18237, 18949, 19718, 20521, 21387,
|
||||
};
|
||||
|
||||
static const int16_t ac_qlookup[QINDEX_RANGE] = {
|
||||
4, 8, 9, 10, 11, 12, 13, 14,
|
||||
15, 16, 17, 18, 19, 20, 21, 22,
|
||||
23, 24, 25, 26, 27, 28, 29, 30,
|
||||
31, 32, 33, 34, 35, 36, 37, 38,
|
||||
39, 40, 41, 42, 43, 44, 45, 46,
|
||||
47, 48, 49, 50, 51, 52, 53, 54,
|
||||
55, 56, 57, 58, 59, 60, 61, 62,
|
||||
63, 64, 65, 66, 67, 68, 69, 70,
|
||||
71, 72, 73, 74, 75, 76, 77, 78,
|
||||
79, 80, 81, 82, 83, 84, 85, 86,
|
||||
87, 88, 89, 90, 91, 92, 93, 94,
|
||||
95, 96, 97, 98, 99, 100, 101, 102,
|
||||
104, 106, 108, 110, 112, 114, 116, 118,
|
||||
120, 122, 124, 126, 128, 130, 132, 134,
|
||||
136, 138, 140, 142, 144, 146, 148, 150,
|
||||
152, 155, 158, 161, 164, 167, 170, 173,
|
||||
176, 179, 182, 185, 188, 191, 194, 197,
|
||||
200, 203, 207, 211, 215, 219, 223, 227,
|
||||
231, 235, 239, 243, 247, 251, 255, 260,
|
||||
265, 270, 275, 280, 285, 290, 295, 300,
|
||||
305, 311, 317, 323, 329, 335, 341, 347,
|
||||
353, 359, 366, 373, 380, 387, 394, 401,
|
||||
408, 416, 424, 432, 440, 448, 456, 465,
|
||||
474, 483, 492, 501, 510, 520, 530, 540,
|
||||
550, 560, 571, 582, 593, 604, 615, 627,
|
||||
639, 651, 663, 676, 689, 702, 715, 729,
|
||||
743, 757, 771, 786, 801, 816, 832, 848,
|
||||
864, 881, 898, 915, 933, 951, 969, 988,
|
||||
1007, 1026, 1046, 1066, 1087, 1108, 1129, 1151,
|
||||
1173, 1196, 1219, 1243, 1267, 1292, 1317, 1343,
|
||||
1369, 1396, 1423, 1451, 1479, 1508, 1537, 1567,
|
||||
1597, 1628, 1660, 1692, 1725, 1759, 1793, 1828,
|
||||
};
|
||||
|
||||
static const int16_t ac_qlookup_10[QINDEX_RANGE] = {
|
||||
4, 9, 11, 13, 16, 18, 21, 24,
|
||||
27, 30, 33, 37, 40, 44, 48, 51,
|
||||
55, 59, 63, 67, 71, 75, 79, 83,
|
||||
88, 92, 96, 100, 105, 109, 114, 118,
|
||||
122, 127, 131, 136, 140, 145, 149, 154,
|
||||
158, 163, 168, 172, 177, 181, 186, 190,
|
||||
195, 199, 204, 208, 213, 217, 222, 226,
|
||||
231, 235, 240, 244, 249, 253, 258, 262,
|
||||
267, 271, 275, 280, 284, 289, 293, 297,
|
||||
302, 306, 311, 315, 319, 324, 328, 332,
|
||||
337, 341, 345, 349, 354, 358, 362, 367,
|
||||
371, 375, 379, 384, 388, 392, 396, 401,
|
||||
409, 417, 425, 433, 441, 449, 458, 466,
|
||||
474, 482, 490, 498, 506, 514, 523, 531,
|
||||
539, 547, 555, 563, 571, 579, 588, 596,
|
||||
604, 616, 628, 640, 652, 664, 676, 688,
|
||||
700, 713, 725, 737, 749, 761, 773, 785,
|
||||
797, 809, 825, 841, 857, 873, 889, 905,
|
||||
922, 938, 954, 970, 986, 1002, 1018, 1038,
|
||||
1058, 1078, 1098, 1118, 1138, 1158, 1178, 1198,
|
||||
1218, 1242, 1266, 1290, 1314, 1338, 1362, 1386,
|
||||
1411, 1435, 1463, 1491, 1519, 1547, 1575, 1603,
|
||||
1631, 1663, 1695, 1727, 1759, 1791, 1823, 1859,
|
||||
1895, 1931, 1967, 2003, 2039, 2079, 2119, 2159,
|
||||
2199, 2239, 2283, 2327, 2371, 2415, 2459, 2507,
|
||||
2555, 2603, 2651, 2703, 2755, 2807, 2859, 2915,
|
||||
2971, 3027, 3083, 3143, 3203, 3263, 3327, 3391,
|
||||
3455, 3523, 3591, 3659, 3731, 3803, 3876, 3952,
|
||||
4028, 4104, 4184, 4264, 4348, 4432, 4516, 4604,
|
||||
4692, 4784, 4876, 4972, 5068, 5168, 5268, 5372,
|
||||
5476, 5584, 5692, 5804, 5916, 6032, 6148, 6268,
|
||||
6388, 6512, 6640, 6768, 6900, 7036, 7172, 7312,
|
||||
};
|
||||
|
||||
static const int16_t ac_qlookup_12[QINDEX_RANGE] = {
|
||||
4, 13, 19, 27, 35, 44, 54, 64,
|
||||
75, 87, 99, 112, 126, 139, 154, 168,
|
||||
183, 199, 214, 230, 247, 263, 280, 297,
|
||||
314, 331, 349, 366, 384, 402, 420, 438,
|
||||
456, 475, 493, 511, 530, 548, 567, 586,
|
||||
604, 623, 642, 660, 679, 698, 716, 735,
|
||||
753, 772, 791, 809, 828, 846, 865, 884,
|
||||
902, 920, 939, 957, 976, 994, 1012, 1030,
|
||||
1049, 1067, 1085, 1103, 1121, 1139, 1157, 1175,
|
||||
1193, 1211, 1229, 1246, 1264, 1282, 1299, 1317,
|
||||
1335, 1352, 1370, 1387, 1405, 1422, 1440, 1457,
|
||||
1474, 1491, 1509, 1526, 1543, 1560, 1577, 1595,
|
||||
1627, 1660, 1693, 1725, 1758, 1791, 1824, 1856,
|
||||
1889, 1922, 1954, 1987, 2020, 2052, 2085, 2118,
|
||||
2150, 2183, 2216, 2248, 2281, 2313, 2346, 2378,
|
||||
2411, 2459, 2508, 2556, 2605, 2653, 2701, 2750,
|
||||
2798, 2847, 2895, 2943, 2992, 3040, 3088, 3137,
|
||||
3185, 3234, 3298, 3362, 3426, 3491, 3555, 3619,
|
||||
3684, 3748, 3812, 3876, 3941, 4005, 4069, 4149,
|
||||
4230, 4310, 4390, 4470, 4550, 4631, 4711, 4791,
|
||||
4871, 4967, 5064, 5160, 5256, 5352, 5448, 5544,
|
||||
5641, 5737, 5849, 5961, 6073, 6185, 6297, 6410,
|
||||
6522, 6650, 6778, 6906, 7034, 7162, 7290, 7435,
|
||||
7579, 7723, 7867, 8011, 8155, 8315, 8475, 8635,
|
||||
8795, 8956, 9132, 9308, 9484, 9660, 9836, 10028,
|
||||
10220, 10412, 10604, 10812, 11020, 11228, 11437, 11661,
|
||||
11885, 12109, 12333, 12573, 12813, 13053, 13309, 13565,
|
||||
13821, 14093, 14365, 14637, 14925, 15213, 15502, 15806,
|
||||
16110, 16414, 16734, 17054, 17390, 17726, 18062, 18414,
|
||||
18766, 19134, 19502, 19886, 20270, 20670, 21070, 21486,
|
||||
21902, 22334, 22766, 23214, 23662, 24126, 24590, 25070,
|
||||
25551, 26047, 26559, 27071, 27599, 28143, 28687, 29247,
|
||||
};
|
||||
|
||||
int clamp(int value, int low, int high)
|
||||
{
|
||||
return value < low ? low : (value > high ? high : value);
|
||||
}
|
||||
|
||||
int16_t vp9_dc_quant(int qindex, int delta, int bit_depth)
|
||||
{
|
||||
const uint8_t q_table_idx = clamp(qindex + delta, 0, MAXQ);
|
||||
|
||||
switch (bit_depth) {
|
||||
case 8:
|
||||
return dc_qlookup[q_table_idx];
|
||||
case 10:
|
||||
return dc_qlookup_10[q_table_idx];
|
||||
case 12:
|
||||
return dc_qlookup_12[q_table_idx];
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int16_t vp9_ac_quant(int qindex, int delta, int bit_depth)
|
||||
{
|
||||
const uint8_t q_table_idx = clamp(qindex + delta, 0, MAXQ);
|
||||
|
||||
switch (bit_depth) {
|
||||
case 8:
|
||||
return ac_qlookup[q_table_idx];
|
||||
case 10:
|
||||
return ac_qlookup_10[q_table_idx];
|
||||
case 12:
|
||||
return ac_qlookup_12[q_table_idx];
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
return -1;
|
||||
}
|
26
gst-libs/gst/codecparsers/vp9utils.h
Normal file
26
gst-libs/gst/codecparsers/vp9utils.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright (c) 2010 The WebM project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#ifndef __VP9_QUANT_H__
|
||||
#define __VP9_QUANT_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define MAXQ 255
|
||||
#define QINDEX_RANGE 256
|
||||
#define QINDEX_BITS 8
|
||||
|
||||
int clamp(int value, int low, int high);
|
||||
|
||||
int16_t vp9_dc_quant(int qindex, int delta, int bit_depth);
|
||||
|
||||
int16_t vp9_ac_quant(int qindex, int delta, int bit_depth);
|
||||
|
||||
|
||||
#endif //__VP9_QUANT_H__
|
Loading…
Reference in a new issue