mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-24 09:10:36 +00:00
Add initial VP8 decoder.
https://bugzilla.gnome.org/show_bug.cgi?id=722761 [complete overhaul, fixed support for resolution changes] Signed-off-by: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
This commit is contained in:
parent
450092e371
commit
029bae0b6a
13 changed files with 853 additions and 0 deletions
50
configure.ac
50
configure.ac
|
@ -335,6 +335,7 @@ if test "$enable_builtin_codecparsers" = "yes"; then
|
|||
ac_cv_have_gst_mpeg2_parser="no"
|
||||
ac_cv_have_gst_h264_parser="no"
|
||||
ac_cv_have_gst_jpeg_parser="no"
|
||||
ac_cv_have_gst_vp8_parser="no"
|
||||
else
|
||||
PKG_CHECK_MODULES([GST_CODEC_PARSERS],
|
||||
[gstreamer-codecparsers-$GST_PKG_VERSION >= $GST_PLUGINS_BAD_VERSION_REQUIRED])
|
||||
|
@ -413,6 +414,26 @@ AC_CACHE_CHECK([for JPEG parser],
|
|||
AM_CONDITIONAL([USE_LOCAL_CODEC_PARSERS_JPEG],
|
||||
[test "$ac_cv_have_gst_jpeg_parser" != "yes"])
|
||||
|
||||
dnl ... VP8 parser, not upstream yet
|
||||
AC_CACHE_CHECK([for VP8 parser],
|
||||
ac_cv_have_gst_vp8_parser, [
|
||||
saved_CPPFLAGS="$CPPFLAGS"
|
||||
CPPFLAGS="$CPPFLAGS $GST_CFLAGS $GST_CODEC_PARSERS_CFLAGS"
|
||||
saved_LIBS="$LIBS"
|
||||
LIBS="$LIBS $GST_LIBS $GST_CODEC_PARSERS_LIBS"
|
||||
AC_COMPILE_IFELSE(
|
||||
[AC_LANG_PROGRAM(
|
||||
[[#include <gst/codecparsers/gstvp8parser.h>]],
|
||||
[[GstVp8FrameHdr frame_hdr;]])],
|
||||
[ac_cv_have_gst_vp8_parser="yes"],
|
||||
[ac_cv_have_gst_vp8_parser="no"]
|
||||
)
|
||||
CPPFLAGS="$saved_CPPFLAGS"
|
||||
LIBS="$saved_LIBS"
|
||||
])
|
||||
AM_CONDITIONAL([USE_LOCAL_CODEC_PARSERS_VP8],
|
||||
[test "$ac_cv_have_gst_vp8_parser" != "yes"])
|
||||
|
||||
case $GST_API_VERSION in
|
||||
0.10) lt_bias=gst0_vaapi_lt_current_bias;;
|
||||
1.0) lt_bias=gst1_vaapi_lt_current_bias;;
|
||||
|
@ -665,6 +686,31 @@ AC_CACHE_CHECK([for JPEG decoding API],
|
|||
LIBS="$saved_LIBS"
|
||||
])
|
||||
|
||||
dnl Check for VP8 decoding API (0.34+)
|
||||
USE_VP8_DECODER=0
|
||||
AC_CACHE_CHECK([for VP8 decoding API],
|
||||
ac_cv_have_vp8_decoding_api, [
|
||||
saved_CPPFLAGS="$CPPFLAGS"
|
||||
CPPFLAGS="$CPPFLAGS $LIBVA_CFLAGS"
|
||||
saved_LIBS="$LIBS"
|
||||
LIBS="$LIBS $LIBVA_LIBS"
|
||||
AC_COMPILE_IFELSE(
|
||||
[AC_LANG_PROGRAM(
|
||||
[[#include <va/va.h>
|
||||
#include <va/va_dec_vp8.h>
|
||||
]],
|
||||
[[VAPictureParameterBufferVP8 pic_param;
|
||||
VASliceParameterBufferVP8 slice_param;
|
||||
VAProbabilityDataBufferVP8 prob_data;
|
||||
VAIQMatrixBufferVP8 iq_matrix;]])],
|
||||
[ac_cv_have_vp8_decoding_api="yes" USE_VP8_DECODER=1],
|
||||
[ac_cv_have_vp8_decoding_api="no"]
|
||||
)
|
||||
CPPFLAGS="$saved_CPPFLAGS"
|
||||
LIBS="$saved_LIBS"
|
||||
])
|
||||
|
||||
|
||||
dnl Check for vpp (video post-processing) support
|
||||
USE_VA_VPP=0
|
||||
AC_CACHE_CHECK([for video post-postprocessing API],
|
||||
|
@ -737,6 +783,10 @@ AC_DEFINE_UNQUOTED(USE_JPEG_DECODER, $USE_JPEG_DECODER,
|
|||
[Defined to 1 if JPEG decoder is used])
|
||||
AM_CONDITIONAL(USE_JPEG_DECODER, test $USE_JPEG_DECODER -eq 1)
|
||||
|
||||
AC_DEFINE_UNQUOTED(USE_VP8_DECODER, $USE_VP8_DECODER,
|
||||
[Defined to 1 if JPEG decoder is used])
|
||||
AM_CONDITIONAL(USE_VP8_DECODER, test $USE_VP8_DECODER -eq 1)
|
||||
|
||||
AC_DEFINE_UNQUOTED(USE_DRM, $USE_DRM,
|
||||
[Defined to 1 if DRM is enabled])
|
||||
AM_CONDITIONAL(USE_DRM, test $USE_DRM -eq 1)
|
||||
|
|
|
@ -9,6 +9,7 @@ codecparsers_source_c = \
|
|||
gstmpeg4parser.c \
|
||||
gstmpegvideoparser.c \
|
||||
gstvc1parser.c \
|
||||
gstvp8parser.c \
|
||||
parserutils.c \
|
||||
$(NULL)
|
||||
|
||||
|
@ -20,6 +21,7 @@ codecparsers_source_h = \
|
|||
gstmpeg4parser.h \
|
||||
gstmpegvideoparser.h \
|
||||
gstvc1parser.h \
|
||||
gstvp8parser.h \
|
||||
parserutils.h \
|
||||
$(NULL)
|
||||
|
||||
|
|
|
@ -40,6 +40,14 @@ gen_source_c += gsth264parser.c
|
|||
gen_source_h += gsth264parser.h
|
||||
endif
|
||||
|
||||
if USE_LOCAL_CODEC_PARSERS_VP8
|
||||
gen_source_c += gstvp8parser.c
|
||||
gen_source_h += gstvp8parser.h gstvp8rangedecoder.h vp8utils.h
|
||||
|
||||
gen_source_c += dboolhuff.c gstvp8rangedecoder.c vp8utils.c
|
||||
gen_source_h += dboolhuff.h
|
||||
endif
|
||||
|
||||
GENFILES = \
|
||||
$(gen_source_c) \
|
||||
$(gen_source_h) \
|
||||
|
|
|
@ -56,6 +56,7 @@ libgstvaapi_source_c = \
|
|||
gstvaapidecoder_objects.c \
|
||||
gstvaapidecoder_unit.c \
|
||||
gstvaapidecoder_vc1.c \
|
||||
gstvaapidecoder_vp8.c \
|
||||
gstvaapidisplay.c \
|
||||
gstvaapidisplaycache.c \
|
||||
gstvaapifilter.c \
|
||||
|
@ -86,6 +87,7 @@ libgstvaapi_source_h = \
|
|||
gstvaapidecoder_mpeg2.h \
|
||||
gstvaapidecoder_mpeg4.h \
|
||||
gstvaapidecoder_vc1.h \
|
||||
gstvaapidecoder_vp8.h \
|
||||
gstvaapidisplay.h \
|
||||
gstvaapifilter.h \
|
||||
gstvaapiimage.h \
|
||||
|
|
|
@ -212,3 +212,39 @@ gst_vaapi_huffman_table_new (GstVaapiDecoder * decoder,
|
|||
return GST_VAAPI_HUFFMAN_TABLE_CAST (object);
|
||||
}
|
||||
#endif
|
||||
#if USE_VP8_DECODER
|
||||
GST_VAAPI_CODEC_DEFINE_TYPE (GstVaapiProbabilityTable,
|
||||
gst_vaapi_probability_table);
|
||||
|
||||
void
|
||||
gst_vaapi_probability_table_destroy (GstVaapiProbabilityTable * prob_table)
|
||||
{
|
||||
vaapi_destroy_buffer (GET_VA_DISPLAY (prob_table), &prob_table->param_id);
|
||||
prob_table->param = NULL;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_vaapi_probability_table_create (GstVaapiProbabilityTable * prob_table,
|
||||
const GstVaapiCodecObjectConstructorArgs * args)
|
||||
{
|
||||
prob_table->param_id = VA_INVALID_ID;
|
||||
return vaapi_create_buffer (GET_VA_DISPLAY (prob_table),
|
||||
GET_VA_CONTEXT (prob_table),
|
||||
VAProbabilityBufferType,
|
||||
args->param_size, args->param, &prob_table->param_id, &prob_table->param);
|
||||
}
|
||||
|
||||
GstVaapiProbabilityTable *
|
||||
gst_vaapi_probability_table_new (GstVaapiDecoder * decoder,
|
||||
gconstpointer param, guint param_size)
|
||||
{
|
||||
GstVaapiCodecObject *object;
|
||||
|
||||
object = gst_vaapi_codec_object_new (&GstVaapiProbabilityTableClass,
|
||||
GST_VAAPI_CODEC_BASE (decoder), param, param_size, NULL, 0, 0);
|
||||
if (!object)
|
||||
return NULL;
|
||||
return GST_VAAPI_PROBABILITY_TABLE_CAST (object);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -27,6 +27,9 @@
|
|||
|
||||
#include <gst/vaapi/gstvaapiminiobject.h>
|
||||
#include <gst/vaapi/gstvaapidecoder.h>
|
||||
#if USE_VP8_DECODER
|
||||
#include <va/va_dec_vp8.h>
|
||||
#endif
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
@ -36,6 +39,7 @@ typedef struct _GstVaapiCodecObjectClass GstVaapiCodecObjectClass;
|
|||
typedef struct _GstVaapiIqMatrix GstVaapiIqMatrix;
|
||||
typedef struct _GstVaapiBitPlane GstVaapiBitPlane;
|
||||
typedef struct _GstVaapiHuffmanTable GstVaapiHuffmanTable;
|
||||
typedef struct _GstVaapiProbabilityTable GstVaapiProbabilityTable;
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* --- Base Codec Object --- */
|
||||
|
@ -195,6 +199,33 @@ GstVaapiHuffmanTable *
|
|||
gst_vaapi_huffman_table_new (GstVaapiDecoder * decoder, guint8 * data,
|
||||
guint data_size);
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* --- Probability (Update) Table --- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#define GST_VAAPI_PROBABILITY_TABLE_CAST(obj) \
|
||||
((GstVaapiProbabilityTable *)(obj))
|
||||
|
||||
/**
|
||||
* GstVaapiProbabilityTable:
|
||||
*
|
||||
* A #GstVaapiCodecObject holding an Probability (Update) Table for RAC decoding
|
||||
*/
|
||||
struct _GstVaapiProbabilityTable
|
||||
{
|
||||
/*< private > */
|
||||
GstVaapiCodecObject parent_instance;
|
||||
VABufferID param_id;
|
||||
|
||||
/*< public > */
|
||||
gpointer param;
|
||||
};
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
GstVaapiProbabilityTable *
|
||||
gst_vaapi_probability_table_new (GstVaapiDecoder * decoder,
|
||||
gconstpointer param, guint param_size);
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* --- Helpers to create codec-dependent objects --- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
@ -230,6 +261,10 @@ static const GstVaapiCodecObjectClass G_PASTE (type, Class) = { \
|
|||
gst_vaapi_huffman_table_new (GST_VAAPI_DECODER_CAST (decoder), \
|
||||
NULL, sizeof (G_PASTE (VAHuffmanTableBuffer, codec)))
|
||||
|
||||
#define GST_VAAPI_PROBABILITY_TABLE_NEW(codec, decoder) \
|
||||
gst_vaapi_probability_table_new (GST_VAAPI_DECODER_CAST (decoder), \
|
||||
NULL, sizeof (G_PASTE (VAProbabilityDataBuffer, codec)))
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* GST_VAAPI_CODEC_OBJECTS_H */
|
||||
|
|
|
@ -71,6 +71,7 @@ gst_vaapi_picture_destroy (GstVaapiPicture * picture)
|
|||
gst_vaapi_codec_object_replace (&picture->iq_matrix, NULL);
|
||||
gst_vaapi_codec_object_replace (&picture->huf_table, NULL);
|
||||
gst_vaapi_codec_object_replace (&picture->bitplane, NULL);
|
||||
gst_vaapi_codec_object_replace (&picture->prob_table, NULL);
|
||||
|
||||
if (picture->proxy) {
|
||||
gst_vaapi_surface_proxy_unref (picture->proxy);
|
||||
|
@ -223,6 +224,7 @@ gst_vaapi_picture_decode (GstVaapiPicture * picture)
|
|||
GstVaapiIqMatrix *iq_matrix;
|
||||
GstVaapiBitPlane *bitplane;
|
||||
GstVaapiHuffmanTable *huf_table;
|
||||
GstVaapiProbabilityTable *prob_table;
|
||||
VADisplay va_display;
|
||||
VAContextID va_context;
|
||||
VAStatus status;
|
||||
|
@ -257,6 +259,11 @@ gst_vaapi_picture_decode (GstVaapiPicture * picture)
|
|||
&huf_table->param_id, (void **) &huf_table->param))
|
||||
return FALSE;
|
||||
|
||||
prob_table = picture->prob_table;
|
||||
if (prob_table && !do_decode (va_display, va_context,
|
||||
&prob_table->param_id, (void **) &prob_table->param))
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < picture->slices->len; i++) {
|
||||
GstVaapiSlice *const slice = g_ptr_array_index (picture->slices, i);
|
||||
VABufferID va_buffers[2];
|
||||
|
|
|
@ -134,6 +134,7 @@ struct _GstVaapiPicture
|
|||
GstVaapiIqMatrix *iq_matrix;
|
||||
GstVaapiHuffmanTable *huf_table;
|
||||
GstVaapiBitPlane *bitplane;
|
||||
GstVaapiProbabilityTable *prob_table;
|
||||
GstClockTime pts;
|
||||
gint32 poc;
|
||||
guint structure;
|
||||
|
|
664
gst-libs/gst/vaapi/gstvaapidecoder_vp8.c
Normal file
664
gst-libs/gst/vaapi/gstvaapidecoder_vp8.c
Normal file
|
@ -0,0 +1,664 @@
|
|||
/*
|
||||
* gstvaapidecoder_vp8.c - VP8 decoder
|
||||
*
|
||||
* Copyright (C) 2013-2014 Intel Corporation
|
||||
* Author: Halley Zhao <halley.zhao@intel.com>
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
* as published by the Free Software Foundation; either version 2.1
|
||||
* 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:gstvaapidecoder_vp8
|
||||
* @short_description: VP8 decoder
|
||||
*/
|
||||
|
||||
#include "sysdeps.h"
|
||||
#include <gst/codecparsers/gstvp8parser.h>
|
||||
#include "gstvaapidecoder_vp8.h"
|
||||
#include "gstvaapidecoder_objects.h"
|
||||
#include "gstvaapidecoder_priv.h"
|
||||
#include "gstvaapidisplay_priv.h"
|
||||
#include "gstvaapiobject_priv.h"
|
||||
|
||||
#include "gstvaapicompat.h"
|
||||
#include <va/va_dec_vp8.h>
|
||||
|
||||
#define DEBUG 1
|
||||
#include "gstvaapidebug.h"
|
||||
|
||||
#define GST_VAAPI_DECODER_VP8_CAST(decoder) \
|
||||
((GstVaapiDecoderVp8 *)(decoder))
|
||||
|
||||
typedef struct _GstVaapiDecoderVp8Private GstVaapiDecoderVp8Private;
|
||||
typedef struct _GstVaapiDecoderVp8Class GstVaapiDecoderVp8Class;
|
||||
|
||||
struct _GstVaapiDecoderVp8Private
|
||||
{
|
||||
GstVaapiProfile profile;
|
||||
guint width;
|
||||
guint height;
|
||||
GstVp8Parser parser;
|
||||
GstVp8FrameHdr frame_hdr;
|
||||
GstVaapiPicture *last_picture;
|
||||
GstVaapiPicture *golden_ref_picture;
|
||||
GstVaapiPicture *alt_ref_picture;
|
||||
GstVaapiPicture *current_picture;
|
||||
GstClockTime pts;
|
||||
guint size_changed:1;
|
||||
};
|
||||
|
||||
/**
|
||||
* GstVaapiDecoderVp8:
|
||||
*
|
||||
* A decoder based on Vp8.
|
||||
*/
|
||||
struct _GstVaapiDecoderVp8
|
||||
{
|
||||
/*< private >*/
|
||||
GstVaapiDecoder parent_instance;
|
||||
|
||||
GstVaapiDecoderVp8Private priv;
|
||||
};
|
||||
|
||||
/**
|
||||
* GstVaapiDecoderVp8Class:
|
||||
*
|
||||
* A decoder class based on Vp8.
|
||||
*/
|
||||
struct _GstVaapiDecoderVp8Class
|
||||
{
|
||||
/*< private >*/
|
||||
GstVaapiDecoderClass parent_class;
|
||||
};
|
||||
|
||||
static GstVaapiDecoderStatus
|
||||
get_status (GstVp8ParserResult result)
|
||||
{
|
||||
GstVaapiDecoderStatus status;
|
||||
|
||||
switch (result) {
|
||||
case GST_VP8_PARSER_OK:
|
||||
status = GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||
break;
|
||||
case GST_VP8_PARSER_ERROR:
|
||||
status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
|
||||
break;
|
||||
default:
|
||||
status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_decoder_vp8_close (GstVaapiDecoderVp8 * decoder)
|
||||
{
|
||||
GstVaapiDecoderVp8Private *const priv = &decoder->priv;
|
||||
|
||||
gst_vaapi_picture_replace (&priv->last_picture, NULL);
|
||||
gst_vaapi_picture_replace (&priv->golden_ref_picture, NULL);
|
||||
gst_vaapi_picture_replace (&priv->alt_ref_picture, NULL);
|
||||
gst_vaapi_picture_replace (&priv->current_picture, NULL);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_vaapi_decoder_vp8_open (GstVaapiDecoderVp8 * decoder)
|
||||
{
|
||||
GstVaapiDecoderVp8Private *const priv = &decoder->priv;
|
||||
|
||||
gst_vaapi_decoder_vp8_close (decoder);
|
||||
gst_vp8_parser_init (&priv->parser);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_decoder_vp8_destroy (GstVaapiDecoder * base_decoder)
|
||||
{
|
||||
GstVaapiDecoderVp8 *const decoder = GST_VAAPI_DECODER_VP8_CAST (base_decoder);
|
||||
|
||||
gst_vaapi_decoder_vp8_close (decoder);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_vaapi_decoder_vp8_create (GstVaapiDecoder * base_decoder)
|
||||
{
|
||||
GstVaapiDecoderVp8 *const decoder = GST_VAAPI_DECODER_VP8_CAST (base_decoder);
|
||||
GstVaapiDecoderVp8Private *const priv = &decoder->priv;
|
||||
|
||||
if (!gst_vaapi_decoder_vp8_open (decoder))
|
||||
return FALSE;
|
||||
|
||||
priv->profile = GST_VAAPI_PROFILE_UNKNOWN;
|
||||
priv->pts = GST_CLOCK_TIME_NONE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GstVaapiDecoderStatus
|
||||
ensure_context (GstVaapiDecoderVp8 * decoder)
|
||||
{
|
||||
GstVaapiDecoderVp8Private *const priv = &decoder->priv;
|
||||
const GstVaapiProfile profile = GST_VAAPI_PROFILE_VP8;
|
||||
const GstVaapiEntrypoint entrypoint = GST_VAAPI_ENTRYPOINT_VLD;
|
||||
gboolean reset_context = FALSE;
|
||||
|
||||
if (priv->profile != profile) {
|
||||
if (!gst_vaapi_display_has_decoder (GST_VAAPI_DECODER_DISPLAY (decoder),
|
||||
profile, entrypoint))
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
|
||||
|
||||
priv->profile = profile;
|
||||
reset_context = TRUE;
|
||||
}
|
||||
|
||||
if (priv->size_changed) {
|
||||
GST_DEBUG ("size changed");
|
||||
priv->size_changed = FALSE;
|
||||
reset_context = TRUE;
|
||||
}
|
||||
|
||||
if (reset_context) {
|
||||
GstVaapiContextInfo info;
|
||||
|
||||
info.profile = priv->profile;
|
||||
info.entrypoint = entrypoint;
|
||||
info.width = priv->width;
|
||||
info.height = priv->height;
|
||||
info.ref_frames = 3;
|
||||
reset_context =
|
||||
gst_vaapi_decoder_ensure_context (GST_VAAPI_DECODER (decoder), &info);
|
||||
|
||||
if (!reset_context)
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
|
||||
}
|
||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static GstVaapiDecoderStatus
|
||||
ensure_quant_matrix (GstVaapiDecoderVp8 * decoder, GstVaapiPicture * picture)
|
||||
{
|
||||
GstVaapiDecoderVp8Private *const priv = &decoder->priv;
|
||||
GstVp8FrameHdr *const frame_hdr = &priv->frame_hdr;
|
||||
GstVp8Segmentation *const seg = &priv->parser.segmentation;
|
||||
VAIQMatrixBufferVP8 *iq_matrix;
|
||||
const gint8 QI_MAX = 127;
|
||||
gint8 qi, qi_base;
|
||||
gint i;
|
||||
|
||||
picture->iq_matrix = GST_VAAPI_IQ_MATRIX_NEW (VP8, decoder);
|
||||
if (!picture->iq_matrix) {
|
||||
GST_ERROR ("failed to allocate IQ matrix");
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
|
||||
}
|
||||
iq_matrix = picture->iq_matrix->param;
|
||||
|
||||
/* Fill in VAIQMatrixBufferVP8 */
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (seg->segmentation_enabled) {
|
||||
qi_base = seg->quantizer_update_value[i];
|
||||
if (!seg->segment_feature_mode) // 0 means delta update
|
||||
qi_base += frame_hdr->quant_indices.y_ac_qi;
|
||||
} else
|
||||
qi_base = frame_hdr->quant_indices.y_ac_qi;
|
||||
|
||||
qi = qi_base;
|
||||
iq_matrix->quantization_index[i][0] = CLAMP (qi, 0, QI_MAX);
|
||||
qi = qi_base + frame_hdr->quant_indices.y_dc_delta;
|
||||
iq_matrix->quantization_index[i][1] = CLAMP (qi, 0, QI_MAX);
|
||||
qi = qi_base + frame_hdr->quant_indices.y2_dc_delta;
|
||||
iq_matrix->quantization_index[i][2] = CLAMP (qi, 0, QI_MAX);
|
||||
qi = qi_base + frame_hdr->quant_indices.y2_ac_delta;
|
||||
iq_matrix->quantization_index[i][3] = CLAMP (qi, 0, QI_MAX);
|
||||
qi = qi_base + frame_hdr->quant_indices.uv_dc_delta;
|
||||
iq_matrix->quantization_index[i][4] = CLAMP (qi, 0, QI_MAX);
|
||||
qi = qi_base + frame_hdr->quant_indices.uv_ac_delta;
|
||||
iq_matrix->quantization_index[i][5] = CLAMP (qi, 0, QI_MAX);
|
||||
}
|
||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static GstVaapiDecoderStatus
|
||||
ensure_probability_table (GstVaapiDecoderVp8 * decoder,
|
||||
GstVaapiPicture * picture)
|
||||
{
|
||||
GstVaapiDecoderVp8Private *const priv = &decoder->priv;
|
||||
GstVp8FrameHdr *const frame_hdr = &priv->frame_hdr;
|
||||
VAProbabilityDataBufferVP8 *prob_table;
|
||||
|
||||
picture->prob_table = GST_VAAPI_PROBABILITY_TABLE_NEW (VP8, decoder);
|
||||
if (!picture->prob_table) {
|
||||
GST_ERROR ("failed to allocate probality table");
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
|
||||
}
|
||||
prob_table = picture->prob_table->param;
|
||||
|
||||
/* Fill in VAProbabilityDataBufferVP8 */
|
||||
memcpy (prob_table->dct_coeff_probs, frame_hdr->token_probs.prob,
|
||||
sizeof (frame_hdr->token_probs.prob));
|
||||
|
||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
init_picture (GstVaapiDecoderVp8 * decoder, GstVaapiPicture * picture)
|
||||
{
|
||||
GstVaapiDecoderVp8Private *const priv = &decoder->priv;
|
||||
GstVp8FrameHdr *const frame_hdr = &priv->frame_hdr;
|
||||
|
||||
picture->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME;
|
||||
picture->type = frame_hdr->key_frame ? GST_VAAPI_PICTURE_TYPE_I :
|
||||
GST_VAAPI_PICTURE_TYPE_P;
|
||||
picture->pts = priv->pts;
|
||||
|
||||
if (!frame_hdr->show_frame)
|
||||
GST_VAAPI_PICTURE_FLAG_SET (picture, GST_VAAPI_PICTURE_FLAG_SKIPPED);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fill_picture (GstVaapiDecoderVp8 * decoder, GstVaapiPicture * picture)
|
||||
{
|
||||
GstVaapiDecoderVp8Private *const priv = &decoder->priv;
|
||||
VAPictureParameterBufferVP8 *const pic_param = picture->param;
|
||||
GstVp8Parser *const parser = &priv->parser;
|
||||
GstVp8FrameHdr *const frame_hdr = &priv->frame_hdr;
|
||||
GstVp8Segmentation *const seg = &parser->segmentation;
|
||||
gint i;
|
||||
|
||||
/* Fill in VAPictureParameterBufferVP8 */
|
||||
pic_param->frame_width = priv->width;
|
||||
pic_param->frame_height = priv->height;
|
||||
|
||||
pic_param->last_ref_frame = VA_INVALID_SURFACE;
|
||||
pic_param->golden_ref_frame = VA_INVALID_SURFACE;
|
||||
pic_param->alt_ref_frame = VA_INVALID_SURFACE;
|
||||
if (!frame_hdr->key_frame) {
|
||||
if (priv->last_picture)
|
||||
pic_param->last_ref_frame = priv->last_picture->surface_id;
|
||||
if (priv->golden_ref_picture)
|
||||
pic_param->golden_ref_frame = priv->golden_ref_picture->surface_id;
|
||||
if (priv->alt_ref_picture)
|
||||
pic_param->alt_ref_frame = priv->alt_ref_picture->surface_id;
|
||||
}
|
||||
pic_param->out_of_loop_frame = VA_INVALID_SURFACE; // not used currently
|
||||
|
||||
pic_param->pic_fields.value = 0;
|
||||
pic_param->pic_fields.bits.key_frame = !frame_hdr->key_frame;
|
||||
pic_param->pic_fields.bits.version = frame_hdr->version;
|
||||
pic_param->pic_fields.bits.segmentation_enabled = seg->segmentation_enabled;
|
||||
pic_param->pic_fields.bits.update_mb_segmentation_map =
|
||||
seg->update_mb_segmentation_map;
|
||||
pic_param->pic_fields.bits.update_segment_feature_data =
|
||||
seg->update_segment_feature_data;
|
||||
pic_param->pic_fields.bits.filter_type = frame_hdr->filter_type;
|
||||
pic_param->pic_fields.bits.sharpness_level = frame_hdr->sharpness_level;
|
||||
pic_param->pic_fields.bits.loop_filter_adj_enable =
|
||||
parser->mb_lf_adjust.loop_filter_adj_enable;
|
||||
pic_param->pic_fields.bits.mode_ref_lf_delta_update =
|
||||
parser->mb_lf_adjust.mode_ref_lf_delta_update;
|
||||
pic_param->pic_fields.bits.sign_bias_golden = frame_hdr->sign_bias_golden;
|
||||
pic_param->pic_fields.bits.sign_bias_alternate =
|
||||
frame_hdr->sign_bias_alternate;
|
||||
pic_param->pic_fields.bits.mb_no_coeff_skip = frame_hdr->mb_no_skip_coeff;
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
pic_param->mb_segment_tree_probs[i] = seg->segment_prob[i];
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (seg->segmentation_enabled) {
|
||||
pic_param->loop_filter_level[i] = seg->lf_update_value[i];
|
||||
if (!seg->segment_feature_mode)
|
||||
pic_param->loop_filter_level[i] += frame_hdr->loop_filter_level;
|
||||
} else
|
||||
pic_param->loop_filter_level[i] = frame_hdr->loop_filter_level;
|
||||
|
||||
pic_param->loop_filter_deltas_ref_frame[i] =
|
||||
parser->mb_lf_adjust.ref_frame_delta[i];
|
||||
pic_param->loop_filter_deltas_mode[i] =
|
||||
parser->mb_lf_adjust.mb_mode_delta[i];
|
||||
}
|
||||
if ((pic_param->pic_fields.bits.version == 0)
|
||||
|| (pic_param->pic_fields.bits.version == 1)) {
|
||||
pic_param->pic_fields.bits.loop_filter_disable =
|
||||
pic_param->loop_filter_level[0] == 0;
|
||||
}
|
||||
|
||||
pic_param->prob_skip_false = frame_hdr->prob_skip_false;
|
||||
pic_param->prob_intra = frame_hdr->prob_intra;
|
||||
pic_param->prob_last = frame_hdr->prob_last;
|
||||
pic_param->prob_gf = frame_hdr->prob_gf;
|
||||
|
||||
memcpy (pic_param->y_mode_probs, frame_hdr->mode_probs.y_prob,
|
||||
sizeof (frame_hdr->mode_probs.y_prob));
|
||||
memcpy (pic_param->uv_mode_probs, frame_hdr->mode_probs.uv_prob,
|
||||
sizeof (frame_hdr->mode_probs.uv_prob));
|
||||
memcpy (pic_param->mv_probs, frame_hdr->mv_probs.prob,
|
||||
sizeof (frame_hdr->mv_probs));
|
||||
|
||||
pic_param->bool_coder_ctx.range = frame_hdr->rd_range;
|
||||
pic_param->bool_coder_ctx.value = frame_hdr->rd_value;
|
||||
pic_param->bool_coder_ctx.count = frame_hdr->rd_count;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fill_slice (GstVaapiDecoderVp8 * decoder, GstVaapiSlice * slice)
|
||||
{
|
||||
GstVaapiDecoderVp8Private *const priv = &decoder->priv;
|
||||
VASliceParameterBufferVP8 *const slice_param = slice->param;
|
||||
GstVp8FrameHdr *const frame_hdr = &priv->frame_hdr;
|
||||
gint i;
|
||||
|
||||
/* Fill in VASliceParameterBufferVP8 */
|
||||
slice_param->slice_data_offset = frame_hdr->data_chunk_size;
|
||||
slice_param->macroblock_offset = frame_hdr->header_size;
|
||||
slice_param->num_of_partitions =
|
||||
(1 << frame_hdr->log2_nbr_of_dct_partitions) + 1;
|
||||
|
||||
slice_param->partition_size[0] =
|
||||
frame_hdr->first_part_size - ((slice_param->macroblock_offset + 7) >> 3);
|
||||
for (i = 1; i < slice_param->num_of_partitions; i++)
|
||||
slice_param->partition_size[i] = frame_hdr->partition_size[i - 1];
|
||||
for (; i < G_N_ELEMENTS (slice_param->partition_size); i++)
|
||||
slice_param->partition_size[i] = 0;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GstVaapiDecoderStatus
|
||||
decode_slice (GstVaapiDecoderVp8 * decoder, GstVaapiPicture * picture,
|
||||
const guchar * buf, guint buf_size)
|
||||
{
|
||||
GstVaapiSlice *slice;
|
||||
|
||||
slice = GST_VAAPI_SLICE_NEW (VP8, decoder, buf, buf_size);
|
||||
if (!slice) {
|
||||
GST_ERROR ("failed to allocate slice");
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
|
||||
}
|
||||
|
||||
if (!fill_slice (decoder, slice)) {
|
||||
gst_vaapi_mini_object_unref (GST_VAAPI_MINI_OBJECT (slice));
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
|
||||
}
|
||||
|
||||
gst_vaapi_picture_add_slice (GST_VAAPI_PICTURE_CAST (picture), slice);
|
||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static GstVaapiDecoderStatus
|
||||
decode_picture (GstVaapiDecoderVp8 * decoder, const guchar * buf,
|
||||
guint buf_size)
|
||||
{
|
||||
GstVaapiDecoderVp8Private *const priv = &decoder->priv;
|
||||
GstVaapiPicture *picture;
|
||||
GstVaapiDecoderStatus status;
|
||||
|
||||
status = ensure_context (decoder);
|
||||
if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
|
||||
return status;
|
||||
|
||||
/* Create new picture */
|
||||
picture = GST_VAAPI_PICTURE_NEW (VP8, decoder);
|
||||
if (!picture) {
|
||||
GST_ERROR ("failed to allocate picture");
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
|
||||
}
|
||||
gst_vaapi_picture_replace (&priv->current_picture, picture);
|
||||
gst_vaapi_picture_unref (picture);
|
||||
|
||||
status = ensure_quant_matrix (decoder, picture);
|
||||
if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
|
||||
return status;
|
||||
|
||||
status = ensure_probability_table (decoder, picture);
|
||||
if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
|
||||
return status;
|
||||
|
||||
init_picture (decoder, picture);
|
||||
if (!fill_picture (decoder, picture))
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
|
||||
|
||||
return decode_slice (decoder, picture, buf, buf_size);
|
||||
}
|
||||
|
||||
static void
|
||||
update_ref_frames (GstVaapiDecoderVp8 * decoder)
|
||||
{
|
||||
GstVaapiDecoderVp8Private *const priv = &decoder->priv;
|
||||
GstVaapiPicture *picture = priv->current_picture;
|
||||
GstVp8FrameHdr *const frame_hdr = &priv->frame_hdr;
|
||||
|
||||
// update picture reference
|
||||
if (frame_hdr->key_frame) {
|
||||
gst_vaapi_picture_replace (&priv->golden_ref_picture, picture);
|
||||
gst_vaapi_picture_replace (&priv->alt_ref_picture, picture);
|
||||
} else {
|
||||
// process refresh_alternate_frame/copy_buffer_to_alternate first
|
||||
if (frame_hdr->refresh_alternate_frame) {
|
||||
gst_vaapi_picture_replace (&priv->alt_ref_picture, picture);
|
||||
} else {
|
||||
switch (frame_hdr->copy_buffer_to_alternate) {
|
||||
case 0:
|
||||
// do nothing
|
||||
break;
|
||||
case 1:
|
||||
gst_vaapi_picture_replace (&priv->alt_ref_picture,
|
||||
priv->last_picture);
|
||||
break;
|
||||
case 2:
|
||||
gst_vaapi_picture_replace (&priv->alt_ref_picture,
|
||||
priv->golden_ref_picture);
|
||||
break;
|
||||
default:
|
||||
GST_WARNING
|
||||
("WARNING: VP8 decoder: unrecognized copy_buffer_to_alternate");
|
||||
}
|
||||
}
|
||||
|
||||
if (frame_hdr->refresh_golden_frame) {
|
||||
gst_vaapi_picture_replace (&priv->golden_ref_picture, picture);
|
||||
} else {
|
||||
switch (frame_hdr->copy_buffer_to_golden) {
|
||||
case 0:
|
||||
// do nothing
|
||||
break;
|
||||
case 1:
|
||||
gst_vaapi_picture_replace (&priv->golden_ref_picture,
|
||||
priv->last_picture);
|
||||
break;
|
||||
case 2:
|
||||
gst_vaapi_picture_replace (&priv->golden_ref_picture,
|
||||
priv->alt_ref_picture);
|
||||
break;
|
||||
default:
|
||||
GST_WARNING
|
||||
("WARNING: VP8 decoder: unrecognized copy_buffer_to_golden");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (frame_hdr->key_frame || frame_hdr->refresh_last)
|
||||
gst_vaapi_picture_replace (&priv->last_picture, picture);
|
||||
}
|
||||
|
||||
static GstVaapiDecoderStatus
|
||||
decode_current_picture (GstVaapiDecoderVp8 * decoder)
|
||||
{
|
||||
GstVaapiDecoderVp8Private *const priv = &decoder->priv;
|
||||
GstVaapiPicture *const picture = priv->current_picture;
|
||||
|
||||
if (!picture)
|
||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||
|
||||
update_ref_frames (decoder);
|
||||
if (!gst_vaapi_picture_decode (picture))
|
||||
goto error;
|
||||
if (!gst_vaapi_picture_output (picture))
|
||||
goto error;
|
||||
gst_vaapi_picture_replace (&priv->current_picture, NULL);
|
||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||
|
||||
error:
|
||||
/* XXX: fix for cases where first field failed to be decoded */
|
||||
gst_vaapi_picture_replace (&priv->current_picture, NULL);
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
|
||||
}
|
||||
|
||||
static GstVaapiDecoderStatus
|
||||
parse_frame_header (GstVaapiDecoderVp8 * decoder, const guchar * buf,
|
||||
guint buf_size, GstVp8FrameHdr * frame_hdr)
|
||||
{
|
||||
GstVaapiDecoderVp8Private *const priv = &decoder->priv;
|
||||
GstVp8ParserResult result;
|
||||
|
||||
memset (frame_hdr, 0, sizeof (*frame_hdr));
|
||||
result = gst_vp8_parser_parse_frame_header (&priv->parser, frame_hdr,
|
||||
buf, buf_size);
|
||||
if (result != GST_VP8_PARSER_OK)
|
||||
return get_status (result);
|
||||
|
||||
if (frame_hdr->key_frame &&
|
||||
(frame_hdr->width != priv->width || frame_hdr->height != priv->height)) {
|
||||
priv->width = frame_hdr->width;
|
||||
priv->height = frame_hdr->height;
|
||||
priv->size_changed = TRUE;
|
||||
}
|
||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static GstVaapiDecoderStatus
|
||||
gst_vaapi_decoder_vp8_parse (GstVaapiDecoder * base_decoder,
|
||||
GstAdapter * adapter, gboolean at_eos, GstVaapiDecoderUnit * unit)
|
||||
{
|
||||
GstVaapiDecoderVp8 *const decoder = GST_VAAPI_DECODER_VP8_CAST (base_decoder);
|
||||
GstVaapiDecoderVp8Private *const priv = &decoder->priv;
|
||||
guint flags = 0;
|
||||
|
||||
priv->pts = gst_adapter_prev_pts (adapter, NULL);
|
||||
unit->size = gst_adapter_available (adapter);
|
||||
|
||||
/* The whole frame is available */
|
||||
flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START;
|
||||
flags |= GST_VAAPI_DECODER_UNIT_FLAG_SLICE;
|
||||
flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END;
|
||||
GST_VAAPI_DECODER_UNIT_FLAG_SET (unit, flags);
|
||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
static GstVaapiDecoderStatus
|
||||
decode_buffer (GstVaapiDecoderVp8 * decoder, const guchar * buf, guint buf_size)
|
||||
{
|
||||
GstVaapiDecoderVp8Private *const priv = &decoder->priv;
|
||||
GstVaapiDecoderStatus status;
|
||||
|
||||
status = parse_frame_header (decoder, buf, buf_size, &priv->frame_hdr);
|
||||
if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
|
||||
return status;
|
||||
|
||||
return decode_picture (decoder, buf, buf_size);
|
||||
}
|
||||
|
||||
GstVaapiDecoderStatus
|
||||
gst_vaapi_decoder_vp8_decode (GstVaapiDecoder * base_decoder,
|
||||
GstVaapiDecoderUnit * unit)
|
||||
{
|
||||
GstVaapiDecoderVp8 *const decoder = GST_VAAPI_DECODER_VP8_CAST (base_decoder);
|
||||
GstVaapiDecoderStatus status;
|
||||
GstBuffer *const buffer =
|
||||
GST_VAAPI_DECODER_CODEC_FRAME (decoder)->input_buffer;
|
||||
GstMapInfo map_info;
|
||||
|
||||
if (!gst_buffer_map (buffer, &map_info, GST_MAP_READ)) {
|
||||
GST_ERROR ("failed to map buffer");
|
||||
return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
|
||||
}
|
||||
|
||||
status = decode_buffer (decoder, map_info.data + unit->offset, unit->size);
|
||||
gst_buffer_unmap (buffer, &map_info);
|
||||
if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
|
||||
return status;
|
||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static GstVaapiDecoderStatus
|
||||
gst_vaapi_decoder_vp8_start_frame (GstVaapiDecoder * base_decoder,
|
||||
GstVaapiDecoderUnit * base_unit)
|
||||
{
|
||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static GstVaapiDecoderStatus
|
||||
gst_vaapi_decoder_vp8_end_frame (GstVaapiDecoder * base_decoder)
|
||||
{
|
||||
GstVaapiDecoderVp8 *const decoder = GST_VAAPI_DECODER_VP8_CAST (base_decoder);
|
||||
|
||||
return decode_current_picture (decoder);
|
||||
}
|
||||
|
||||
static GstVaapiDecoderStatus
|
||||
gst_vaapi_decoder_vp8_flush (GstVaapiDecoder * base_decoder)
|
||||
{
|
||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_decoder_vp8_class_init (GstVaapiDecoderVp8Class * klass)
|
||||
{
|
||||
GstVaapiMiniObjectClass *const object_class =
|
||||
GST_VAAPI_MINI_OBJECT_CLASS (klass);
|
||||
GstVaapiDecoderClass *const decoder_class = GST_VAAPI_DECODER_CLASS (klass);
|
||||
|
||||
object_class->size = sizeof (GstVaapiDecoderVp8);
|
||||
object_class->finalize = (GDestroyNotify) gst_vaapi_decoder_finalize;
|
||||
|
||||
decoder_class->create = gst_vaapi_decoder_vp8_create;
|
||||
decoder_class->destroy = gst_vaapi_decoder_vp8_destroy;
|
||||
decoder_class->parse = gst_vaapi_decoder_vp8_parse;
|
||||
decoder_class->decode = gst_vaapi_decoder_vp8_decode;
|
||||
decoder_class->start_frame = gst_vaapi_decoder_vp8_start_frame;
|
||||
decoder_class->end_frame = gst_vaapi_decoder_vp8_end_frame;
|
||||
decoder_class->flush = gst_vaapi_decoder_vp8_flush;
|
||||
}
|
||||
|
||||
static inline const GstVaapiDecoderClass *
|
||||
gst_vaapi_decoder_vp8_class (void)
|
||||
{
|
||||
static GstVaapiDecoderVp8Class g_class;
|
||||
static gsize g_class_init = FALSE;
|
||||
|
||||
if (g_once_init_enter (&g_class_init)) {
|
||||
gst_vaapi_decoder_vp8_class_init (&g_class);
|
||||
g_once_init_leave (&g_class_init, TRUE);
|
||||
}
|
||||
return GST_VAAPI_DECODER_CLASS (&g_class);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_decoder_vp8_new:
|
||||
* @display: a #GstVaapiDisplay
|
||||
* @caps: a #GstCaps holding codec information
|
||||
*
|
||||
* Creates a new #GstVaapiDecoder for VP8 decoding. The @caps can
|
||||
* hold extra information like codec-data and pictured coded size.
|
||||
*
|
||||
* Return value: the newly allocated #GstVaapiDecoder object
|
||||
*/
|
||||
GstVaapiDecoder *
|
||||
gst_vaapi_decoder_vp8_new (GstVaapiDisplay * display, GstCaps * caps)
|
||||
{
|
||||
return gst_vaapi_decoder_new (gst_vaapi_decoder_vp8_class (), display, caps);
|
||||
}
|
38
gst-libs/gst/vaapi/gstvaapidecoder_vp8.h
Normal file
38
gst-libs/gst/vaapi/gstvaapidecoder_vp8.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* gstvaapidecoder_vp8.h - VP8 decoder
|
||||
*
|
||||
* Copyright (C) 2013-2014 Intel Corporation
|
||||
* Author: Halley Zhao <halley.zhao@intel.com>
|
||||
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
* as published by the Free Software Foundation; either version 2.1
|
||||
* 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef GST_VAAPI_DECODER_VP8_H
|
||||
#define GST_VAAPI_DECODER_VP8_H
|
||||
|
||||
#include <gst/vaapi/gstvaapidecoder.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GstVaapiDecoderVp8 GstVaapiDecoderVp8;
|
||||
|
||||
GstVaapiDecoder *
|
||||
gst_vaapi_decoder_vp8_new (GstVaapiDisplay * display, GstCaps * caps);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* GST_VAAPI_DECODER_VP8_H */
|
|
@ -65,6 +65,7 @@ static const GstVaapiCodecMap gst_vaapi_codecs[] = {
|
|||
{ GST_VAAPI_CODEC_WMV3, "wmv3" },
|
||||
{ GST_VAAPI_CODEC_VC1, "vc1" },
|
||||
{ GST_VAAPI_CODEC_JPEG, "jpeg" },
|
||||
{ GST_VAAPI_CODEC_VP8, "vp8" },
|
||||
{ 0, }
|
||||
};
|
||||
|
||||
|
@ -125,6 +126,8 @@ static const GstVaapiProfileMap gst_vaapi_profiles[] = {
|
|||
"image/jpeg", "baseline"
|
||||
},
|
||||
#endif
|
||||
{GST_VAAPI_PROFILE_VP8, VAProfileVP8Version0_3,
|
||||
"video/x-vp8", "Version0_3"},
|
||||
{ 0, }
|
||||
};
|
||||
|
||||
|
|
|
@ -51,6 +51,7 @@ typedef enum {
|
|||
GST_VAAPI_CODEC_WMV3 = GST_MAKE_FOURCC('W','M','V',0),
|
||||
GST_VAAPI_CODEC_VC1 = GST_MAKE_FOURCC('V','C','1',0),
|
||||
GST_VAAPI_CODEC_JPEG = GST_MAKE_FOURCC('J','P','G',0),
|
||||
GST_VAAPI_CODEC_VP8 = GST_MAKE_FOURCC('V','P','8',0),
|
||||
} GstVaapiCodec;
|
||||
|
||||
/**
|
||||
|
@ -151,6 +152,7 @@ typedef enum {
|
|||
GST_VAAPI_PROFILE_VC1_MAIN = GST_VAAPI_MAKE_PROFILE(VC1,2),
|
||||
GST_VAAPI_PROFILE_VC1_ADVANCED = GST_VAAPI_MAKE_PROFILE(VC1,3),
|
||||
GST_VAAPI_PROFILE_JPEG_BASELINE = GST_VAAPI_MAKE_PROFILE(JPEG,1),
|
||||
GST_VAAPI_PROFILE_VP8 = GST_VAAPI_MAKE_PROFILE(VP8,1),
|
||||
} GstVaapiProfile;
|
||||
|
||||
/**
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
#include <gst/vaapi/gstvaapidecoder_mpeg2.h>
|
||||
#include <gst/vaapi/gstvaapidecoder_mpeg4.h>
|
||||
#include <gst/vaapi/gstvaapidecoder_vc1.h>
|
||||
#include <gst/vaapi/gstvaapidecoder_vp8.h>
|
||||
|
||||
#define GST_PLUGIN_NAME "vaapidecode"
|
||||
#define GST_PLUGIN_DESC "A VA-API based video decoder"
|
||||
|
@ -67,6 +68,7 @@ static const char gst_vaapidecode_sink_caps_str[] =
|
|||
GST_CAPS_CODEC("video/x-h263")
|
||||
GST_CAPS_CODEC("video/x-h264")
|
||||
GST_CAPS_CODEC("video/x-wmv")
|
||||
GST_CAPS_CODEC("video/x-vp8")
|
||||
GST_CAPS_CODEC("image/jpeg")
|
||||
;
|
||||
|
||||
|
@ -631,6 +633,9 @@ gst_vaapidecode_create(GstVaapiDecode *decode, GstCaps *caps)
|
|||
decode->decoder = gst_vaapi_decoder_jpeg_new(dpy, caps);
|
||||
break;
|
||||
#endif
|
||||
case GST_VAAPI_CODEC_VP8:
|
||||
decode->decoder = gst_vaapi_decoder_vp8_new(dpy, caps);
|
||||
break;
|
||||
default:
|
||||
decode->decoder = NULL;
|
||||
break;
|
||||
|
|
Loading…
Reference in a new issue