summaryrefslogtreecommitdiff
path: root/gst-libs
diff options
context:
space:
mode:
authorGwenole Beauchesne <gwenole.beauchesne@intel.com>2012-01-26 09:48:11 +0100
committerGwenole Beauchesne <gwenole.beauchesne@intel.com>2012-01-27 13:28:11 +0100
commite5d12e885315fc2a5db806ec5a8d92f9ab3ea809 (patch)
treeec48e4f0c199c0fec24beb179e5eb2b80089394f /gst-libs
parentdbba1f6107daaf716f15675e26bfd20ce8e91122 (diff)
decoder: rework the internal VA objects API.
The new API simplifies a lot reference counting and makes it more flexible for future additions/changes. The GstVaapiCodecInfo is also gone. Rather, new helper macros are provided to allocate picture, slice and quantization matrix parameter buffers.
Diffstat (limited to 'gst-libs')
-rw-r--r--gst-libs/gst/vaapi/Makefile.am6
-rw-r--r--gst-libs/gst/vaapi/gstvaapicodec_objects.c250
-rw-r--r--gst-libs/gst/vaapi/gstvaapicodec_objects.h323
-rw-r--r--gst-libs/gst/vaapi/gstvaapidecoder.c373
-rw-r--r--gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c55
-rw-r--r--gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c60
-rw-r--r--gst-libs/gst/vaapi/gstvaapidecoder_objects.c326
-rw-r--r--gst-libs/gst/vaapi/gstvaapidecoder_objects.h253
-rw-r--r--gst-libs/gst/vaapi/gstvaapidecoder_priv.h116
-rw-r--r--gst-libs/gst/vaapi/gstvaapidecoder_vc1.c62
10 files changed, 1204 insertions, 620 deletions
diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am
index 68c76dbc..b2cd2ccc 100644
--- a/gst-libs/gst/vaapi/Makefile.am
+++ b/gst-libs/gst/vaapi/Makefile.am
@@ -145,8 +145,10 @@ endif
if USE_CODEC_PARSERS
libgstvaapi_source_c += \
+ gstvaapicodec_objects.c \
gstvaapidecoder_mpeg2.c \
gstvaapidecoder_mpeg4.c \
+ gstvaapidecoder_objects.c \
gstvaapidecoder_vc1.c \
$(NULL)
libgstvaapi_source_h += \
@@ -154,6 +156,10 @@ libgstvaapi_source_h += \
gstvaapidecoder_mpeg4.h \
gstvaapidecoder_vc1.h \
$(NULL)
+libgstvaapi_source_priv_h += \
+ gstvaapicodec_objects.h \
+ gstvaapidecoder_objects.h \
+ $(NULL)
libgstvaapi_cflags += $(GST_CODEC_PARSERS_CFLAGS)
libgstvaapi_libs += $(GST_CODEC_PARSERS_LIBS)
endif
diff --git a/gst-libs/gst/vaapi/gstvaapicodec_objects.c b/gst-libs/gst/vaapi/gstvaapicodec_objects.c
new file mode 100644
index 00000000..7af2dd95
--- /dev/null
+++ b/gst-libs/gst/vaapi/gstvaapicodec_objects.c
@@ -0,0 +1,250 @@
+/*
+ * gstvaapicodec_objects.c - VA codec objects abstraction
+ *
+ * Copyright (C) 2010-2011 Splitted-Desktop Systems
+ * Copyright (C) 2011-2012 Intel Corporation
+ *
+ * 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
+ */
+
+#include "config.h"
+#include <string.h>
+#include <gst/vaapi/gstvaapicontext.h>
+#include "gstvaapicodec_objects.h"
+#include "gstvaapidecoder_priv.h"
+#include "gstvaapicompat.h"
+#include "gstvaapiutils.h"
+
+#define DEBUG 1
+#include "gstvaapidebug.h"
+
+/* ------------------------------------------------------------------------- */
+/* --- Base Codec Object --- */
+/* ------------------------------------------------------------------------- */
+
+G_DEFINE_TYPE(GstVaapiCodecObject, gst_vaapi_codec_object, GST_TYPE_MINI_OBJECT)
+
+static void
+gst_vaapi_codec_object_finalize(GstMiniObject *object)
+{
+ GstVaapiCodecObject * const obj = GST_VAAPI_CODEC_OBJECT(object);
+
+ obj->codec = NULL;
+}
+
+static void
+gst_vaapi_codec_object_init(GstVaapiCodecObject *obj)
+{
+ obj->codec = NULL;
+}
+
+static gboolean
+gst_vaapi_codec_object_create(
+ GstVaapiCodecObject *obj,
+ const GstVaapiCodecObjectConstructorArgs *args
+)
+{
+ obj->codec = args->codec;
+ return TRUE;
+}
+
+static void
+gst_vaapi_codec_object_class_init(GstVaapiCodecObjectClass *klass)
+{
+ GstMiniObjectClass * const object_class = GST_MINI_OBJECT_CLASS(klass);
+
+ object_class->finalize = gst_vaapi_codec_object_finalize;
+ klass->construct = gst_vaapi_codec_object_create;
+}
+
+GstVaapiCodecObject *
+gst_vaapi_codec_object_new(
+ GType type,
+ GstVaapiCodecBase *codec,
+ gconstpointer param,
+ guint param_size,
+ gconstpointer data,
+ guint data_size
+)
+{
+ GstMiniObject *obj;
+ GstVaapiCodecObject *va_obj;
+ GstVaapiCodecObjectConstructorArgs args;
+
+ obj = gst_mini_object_new(type);
+ if (!obj)
+ return NULL;
+
+ va_obj = GST_VAAPI_CODEC_OBJECT(obj);
+ args.codec = codec;
+ args.param = param;
+ args.param_size = param_size;
+ args.data = data;
+ args.data_size = data_size;
+ if (gst_vaapi_codec_object_construct(va_obj, &args))
+ return va_obj;
+
+ gst_mini_object_unref(obj);
+ return NULL;
+}
+
+gboolean
+gst_vaapi_codec_object_construct(
+ GstVaapiCodecObject *obj,
+ const GstVaapiCodecObjectConstructorArgs *args
+)
+{
+ GstVaapiCodecObjectClass *klass;
+
+ g_return_val_if_fail(GST_VAAPI_CODEC_OBJECT(obj), FALSE);
+ g_return_val_if_fail(args->codec != NULL, FALSE);
+ g_return_val_if_fail(args->param_size > 0, FALSE);
+
+ if (GST_MINI_OBJECT_FLAG_IS_SET(obj, GST_VAAPI_CODEC_OBJECT_FLAG_CONSTRUCTED))
+ return TRUE;
+
+ klass = GST_VAAPI_CODEC_OBJECT_GET_CLASS(obj);
+ if (!klass || !klass->construct || !klass->construct(obj, args))
+ return FALSE;
+
+ GST_MINI_OBJECT_FLAG_SET(obj, GST_VAAPI_CODEC_OBJECT_FLAG_CONSTRUCTED);
+ return TRUE;
+}
+
+#define GET_DECODER(obj) GST_VAAPI_DECODER_CAST((obj)->parent_instance.codec)
+#define GET_CONTEXT(obj) GET_DECODER(obj)->priv->context
+#define GET_VA_DISPLAY(obj) GET_DECODER(obj)->priv->va_display
+#define GET_VA_CONTEXT(obj) GET_DECODER(obj)->priv->va_context
+
+/* ------------------------------------------------------------------------- */
+/* --- Inverse Quantization Matrices --- */
+/* ------------------------------------------------------------------------- */
+
+GST_VAAPI_CODEC_DEFINE_TYPE(GstVaapiIqMatrix,
+ gst_vaapi_iq_matrix,
+ GST_VAAPI_TYPE_CODEC_OBJECT)
+
+static void
+gst_vaapi_iq_matrix_destroy(GstVaapiIqMatrix *iq_matrix)
+{
+ vaapi_destroy_buffer(GET_VA_DISPLAY(iq_matrix), &iq_matrix->param_id);
+ iq_matrix->param = NULL;
+}
+
+static gboolean
+gst_vaapi_iq_matrix_create(
+ GstVaapiIqMatrix *iq_matrix,
+ const GstVaapiCodecObjectConstructorArgs *args
+)
+{
+ iq_matrix->param = vaapi_create_buffer(
+ GET_VA_DISPLAY(iq_matrix),
+ GET_VA_CONTEXT(iq_matrix),
+ VAIQMatrixBufferType,
+ args->param_size,
+ &iq_matrix->param_id
+ );
+ if (!iq_matrix->param)
+ return FALSE;
+ return TRUE;
+}
+
+static void
+gst_vaapi_iq_matrix_init(GstVaapiIqMatrix *iq_matrix)
+{
+ iq_matrix->param = NULL;
+ iq_matrix->param_id = VA_INVALID_ID;
+}
+
+GstVaapiIqMatrix *
+gst_vaapi_iq_matrix_new(
+ GstVaapiDecoder *decoder,
+ gconstpointer param,
+ guint param_size
+)
+{
+ GstVaapiCodecObject *object;
+
+ g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), NULL);
+
+ object = gst_vaapi_codec_object_new(
+ GST_VAAPI_TYPE_IQ_MATRIX,
+ GST_VAAPI_CODEC_BASE(decoder),
+ param, param_size,
+ NULL, 0
+ );
+ if (!object)
+ return NULL;
+ return GST_VAAPI_IQ_MATRIX_CAST(object);
+}
+
+/* ------------------------------------------------------------------------- */
+/* --- VC-1 Bit Planes --- */
+/* ------------------------------------------------------------------------- */
+
+GST_VAAPI_CODEC_DEFINE_TYPE(GstVaapiBitPlane,
+ gst_vaapi_bitplane,
+ GST_VAAPI_TYPE_CODEC_OBJECT)
+
+static void
+gst_vaapi_bitplane_destroy(GstVaapiBitPlane *bitplane)
+{
+ vaapi_destroy_buffer(GET_VA_DISPLAY(bitplane), &bitplane->data_id);
+ bitplane->data = NULL;
+}
+
+static gboolean
+gst_vaapi_bitplane_create(
+ GstVaapiBitPlane *bitplane,
+ const GstVaapiCodecObjectConstructorArgs *args
+)
+{
+ bitplane->data = vaapi_create_buffer(
+ GET_VA_DISPLAY(bitplane),
+ GET_VA_CONTEXT(bitplane),
+ VABitPlaneBufferType,
+ args->param_size,
+ &bitplane->data_id
+ );
+ if (!bitplane->data)
+ return FALSE;
+ return TRUE;
+}
+
+static void
+gst_vaapi_bitplane_init(GstVaapiBitPlane *bitplane)
+{
+ bitplane->data = NULL;
+ bitplane->data_id = VA_INVALID_ID;
+}
+
+GstVaapiBitPlane *
+gst_vaapi_bitplane_new(GstVaapiDecoder *decoder, guint8 *data, guint data_size)
+{
+ GstVaapiCodecObject *object;
+
+ g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), NULL);
+
+ object = gst_vaapi_codec_object_new(
+ GST_VAAPI_TYPE_BITPLANE,
+ GST_VAAPI_CODEC_BASE(decoder),
+ data, data_size,
+ NULL, 0
+ );
+ if (!object)
+ return NULL;
+ return GST_VAAPI_BITPLANE_CAST(object);
+}
diff --git a/gst-libs/gst/vaapi/gstvaapicodec_objects.h b/gst-libs/gst/vaapi/gstvaapicodec_objects.h
new file mode 100644
index 00000000..7577ba6a
--- /dev/null
+++ b/gst-libs/gst/vaapi/gstvaapicodec_objects.h
@@ -0,0 +1,323 @@
+/*
+ * gstvaapicodec_objects.h - VA codec objects abstraction
+ *
+ * Copyright (C) 2010-2011 Splitted-Desktop Systems
+ * Copyright (C) 2011-2012 Intel Corporation
+ *
+ * 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_CODEC_COMMON_H
+#define GST_VAAPI_CODEC_COMMON_H
+
+#include <gst/gstminiobject.h>
+#include <gst/vaapi/gstvaapidecoder.h>
+
+G_BEGIN_DECLS
+
+typedef gpointer GstVaapiCodecBase;
+typedef struct _GstVaapiCodecObject GstVaapiCodecObject;
+typedef struct _GstVaapiCodecObjectClass GstVaapiCodecObjectClass;
+typedef struct _GstVaapiIqMatrix GstVaapiIqMatrix;
+typedef struct _GstVaapiIqMatrixClass GstVaapiIqMatrixClass;
+typedef struct _GstVaapiBitPlane GstVaapiBitPlane;
+typedef struct _GstVaapiBitPlaneClass GstVaapiBitPlaneClass;
+
+/* ------------------------------------------------------------------------- */
+/* --- Base Codec Object --- */
+/* ------------------------------------------------------------------------- */
+
+/* XXX: remove when a common base class for decoder and encoder is available */
+#define GST_VAAPI_CODEC_BASE(obj) \
+ ((GstVaapiCodecBase *)(obj))
+
+#define GST_VAAPI_TYPE_CODEC_OBJECT \
+ (gst_vaapi_codec_object_get_type())
+
+#define GST_VAAPI_CODEC_OBJECT(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj), \
+ GST_VAAPI_TYPE_CODEC_OBJECT, \
+ GstVaapiCodecObject))
+
+#define GST_VAAPI_CODEC_OBJECT_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass), \
+ GST_VAAPI_TYPE_CODEC_OBJECT, \
+ GstVaapiCodecObjectClass))
+
+#define GST_VAAPI_IS_CODEC_OBJECT(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_CODEC_OBJECT))
+
+#define GST_VAAPI_IS_CODEC_OBJECT_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_CODEC_OBJECT))
+
+#define GST_VAAPI_CODEC_OBJECT_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS((obj), \
+ GST_VAAPI_TYPE_CODEC_OBJECT, \
+ GstVaapiCodecObjectClass))
+
+enum {
+ GST_VAAPI_CODEC_OBJECT_FLAG_CONSTRUCTED = (GST_MINI_OBJECT_FLAG_LAST << 0),
+ GST_VAAPI_CODEC_OBJECT_FLAG_LAST = (GST_MINI_OBJECT_FLAG_LAST << 1)
+};
+
+typedef struct {
+ GstVaapiCodecObject *obj;
+ GstVaapiCodecBase *codec;
+ gconstpointer param;
+ guint param_size;
+ gconstpointer data;
+ guint data_size;
+} GstVaapiCodecObjectConstructorArgs;
+
+/**
+ * GstVaapiCodecObject:
+ *
+ * A #GstMiniObject holding the base codec object data
+ */
+struct _GstVaapiCodecObject {
+ /*< private >*/
+ GstMiniObject parent_instance;
+ GstVaapiCodecBase *codec;
+};
+
+/**
+ * GstVaapiCodecObjectClass:
+ *
+ * The #GstVaapiCodecObject base class.
+ */
+struct _GstVaapiCodecObjectClass {
+ /*< private >*/
+ GstMiniObjectClass parent_class;
+
+ gboolean (*construct) (GstVaapiCodecObject *obj,
+ const GstVaapiCodecObjectConstructorArgs *args);
+};
+
+GType
+gst_vaapi_codec_object_get_type(void)
+ attribute_hidden;
+
+GstVaapiCodecObject *
+gst_vaapi_codec_object_new(
+ GType type,
+ GstVaapiCodecBase *codec,
+ gconstpointer param,
+ guint param_size,
+ gconstpointer data,
+ guint data_size
+) attribute_hidden;
+
+gboolean
+gst_vaapi_codec_object_construct(
+ GstVaapiCodecObject *obj,
+ const GstVaapiCodecObjectConstructorArgs *args
+) attribute_hidden;
+
+/* ------------------------------------------------------------------------- */
+/* --- Inverse Quantization Matrices --- */
+/* ------------------------------------------------------------------------- */
+
+#define GST_VAAPI_TYPE_IQ_MATRIX \
+ (gst_vaapi_iq_matrix_get_type())
+
+#define GST_VAAPI_IQ_MATRIX_CAST(obj) \
+ ((GstVaapiIqMatrix *)(obj))
+
+#define GST_VAAPI_IQ_MATRIX(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj), \
+ GST_VAAPI_TYPE_IQ_MATRIX, \
+ GstVaapiIqMatrix))
+
+#define GST_VAAPI_IQ_MATRIX_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass), \
+ GST_VAAPI_TYPE_IQ_MATRIX, \
+ GstVaapiIqMatrixClass))
+
+#define GST_VAAPI_IS_IQ_MATRIX(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_IQ_MATRIX))
+
+#define GST_VAAPI_IS_IQ_MATRIX_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_IQ_MATRIX))
+
+#define GST_VAAPI_IQ_MATRIX_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS((obj), \
+ GST_VAAPI_TYPE_IQ_MATRIX, \
+ GstVaapiIqMatrixClass))
+
+/**
+ * GstVaapiIqMatrix:
+ *
+ * A #GstVaapiCodecObject holding an inverse quantization matrix parameter.
+ */
+struct _GstVaapiIqMatrix {
+ /*< private >*/
+ GstVaapiCodecObject parent_instance;
+ VABufferID param_id;
+
+ /*< public >*/
+ gpointer param;
+};
+
+/**
+ * GstVaapiIqMatrixClass:
+ *
+ * The #GstVaapiIqMatrix base class.
+ */
+struct _GstVaapiIqMatrixClass {
+ /*< private >*/
+ GstVaapiCodecObjectClass parent_class;
+};
+
+GType
+gst_vaapi_iq_matrix_get_type(void)
+ attribute_hidden;
+
+GstVaapiIqMatrix *
+gst_vaapi_iq_matrix_new(
+ GstVaapiDecoder *decoder,
+ gconstpointer param,
+ guint param_size
+) attribute_hidden;
+
+/* ------------------------------------------------------------------------- */
+/* --- VC-1 Bit Planes --- */
+/* ------------------------------------------------------------------------- */
+
+#define GST_VAAPI_TYPE_BITPLANE \
+ (gst_vaapi_bitplane_get_type())
+
+#define GST_VAAPI_BITPLANE_CAST(obj) \
+ ((GstVaapiBitPlane *)(obj))
+
+#define GST_VAAPI_BITPLANE(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj), \
+ GST_VAAPI_TYPE_BITPLANE, \
+ GstVaapiBitPlane))
+
+#define GST_VAAPI_BITPLANE_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass), \
+ GST_VAAPI_TYPE_BITPLANE, \
+ GstVaapiBitPlaneClass))
+
+#define GST_VAAPI_IS_BITPLANE(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_BITPLANE))
+
+#define GST_VAAPI_IS_BITPLANE_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_BITPLANE))
+
+#define GST_VAAPI_BITPLANE_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS((obj), \
+ GST_VAAPI_TYPE_BITPLANE, \
+ GstVaapiBitPlaneClass))
+
+/**
+ * GstVaapiBitPlane:
+ *
+ * A #GstVaapiCodecObject holding a VC-1 bit plane parameter.
+ */
+struct _GstVaapiBitPlane {
+ /*< private >*/
+ GstVaapiCodecObject parent_instance;
+ VABufferID data_id;
+
+ /*< public >*/
+ guint8 *data;
+};
+
+/**
+ * GstVaapiBitPlaneClass:
+ *
+ * The #GstVaapiBitPlane base class.
+ */
+struct _GstVaapiBitPlaneClass {
+ /*< private >*/
+ GstVaapiCodecObjectClass parent_class;
+};
+
+GType
+gst_vaapi_bitplane_get_type(void)
+ attribute_hidden;
+
+GstVaapiBitPlane *
+gst_vaapi_bitplane_new(GstVaapiDecoder *decoder, guint8 *data, guint data_size)
+ attribute_hidden;
+
+/* ------------------------------------------------------------------------- */
+/* --- Helpers to create codec-dependent objects --- */
+/* ------------------------------------------------------------------------- */
+
+#define GST_VAAPI_CODEC_DEFINE_TYPE(type, prefix, base_type) \
+G_DEFINE_TYPE(type, prefix, base_type) \
+ \
+static void \
+prefix##_destroy(type *); \
+ \
+static gboolean \
+prefix##_create( \
+ type *, \
+ const GstVaapiCodecObjectConstructorArgs *args \
+); \
+ \
+static void \
+prefix##_finalize(GstMiniObject *object) \
+{ \
+ GstMiniObjectClass *parent_class; \
+ \
+ prefix##_destroy((type *)object); \
+ \
+ parent_class = GST_MINI_OBJECT_CLASS(prefix##_parent_class); \
+ if (parent_class->finalize) \
+ parent_class->finalize(object); \
+} \
+ \
+static gboolean \
+prefix##_construct( \
+ GstVaapiCodecObject *object, \
+ const GstVaapiCodecObjectConstructorArgs *args \
+) \
+{ \
+ GstVaapiCodecObjectClass *parent_class; \
+ \
+ parent_class = GST_VAAPI_CODEC_OBJECT_CLASS(prefix##_parent_class); \
+ if (parent_class->construct) { \
+ if (!parent_class->construct(object, args)) \
+ return FALSE; \
+ } \
+ return prefix##_create((type *)object, args); \
+} \
+ \
+static void \
+prefix##_class_init(type##Class *klass) \
+{ \
+ GstMiniObjectClass * const object_class = \
+ GST_MINI_OBJECT_CLASS(klass); \
+ GstVaapiCodecObjectClass * const codec_class = \
+ GST_VAAPI_CODEC_OBJECT_CLASS(klass); \
+ \
+ object_class->finalize = prefix##_finalize; \
+ codec_class->construct = prefix##_construct; \
+}
+
+#define GST_VAAPI_IQ_MATRIX_NEW(codec, decoder) \
+ gst_vaapi_iq_matrix_new(GST_VAAPI_DECODER_CAST(decoder), \
+ NULL, sizeof(VAIQMatrixBuffer##codec))
+
+#define GST_VAAPI_BITPLANE_NEW(decoder, size) \
+ gst_vaapi_bitplane_new(GST_VAAPI_DECODER_CAST(decoder), NULL, size)
+
+G_END_DECLS
+
+#endif /* GST_VAAPI_CODEC_OBJECTS_H */
diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c
index b896847d..e0d1b7b2 100644
--- a/gst-libs/gst/vaapi/gstvaapidecoder.c
+++ b/gst-libs/gst/vaapi/gstvaapidecoder.c
@@ -26,7 +26,6 @@
*/
#include "config.h"
-#include <string.h>
#include "gstvaapicompat.h"
#include "gstvaapidecoder.h"
#include "gstvaapidecoder_priv.h"
@@ -43,7 +42,6 @@ enum {
PROP_DISPLAY,
PROP_CAPS,
- PROP_CODEC_INFO,
};
static void
@@ -202,20 +200,6 @@ set_caps(GstVaapiDecoder *decoder, GstCaps *caps)
set_codec_data(decoder, gst_value_get_buffer(v_codec_data));
}
-static inline void
-set_codec_info(GstVaapiDecoder *decoder, GstVaapiCodecInfo *codec_info)
-{
- GstVaapiDecoderPrivate * const priv = decoder->priv;
-
- if (codec_info) {
- priv->codec_info = *codec_info;
- if (!priv->codec_info.pic_size)
- priv->codec_info.pic_size = sizeof(GstVaapiPicture);
- if (!priv->codec_info.slice_size)
- priv->codec_info.slice_size = sizeof(GstVaapiSlice);
- }
-}
-
static void
clear_queue(GQueue *q, GDestroyNotify destroy)
{
@@ -285,9 +269,6 @@ gst_vaapi_decoder_set_property(
case PROP_CAPS:
set_caps(decoder, g_value_get_pointer(value));
break;
- case PROP_CODEC_INFO:
- set_codec_info(decoder, g_value_get_pointer(value));
- break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
@@ -349,14 +330,6 @@ gst_vaapi_decoder_class_init(GstVaapiDecoderClass *klass)
"Decoder caps",
"The decoder caps",
G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
-
- g_object_class_install_property
- (object_class,
- PROP_CODEC_INFO,
- g_param_spec_pointer("codec-info",
- "Codec info",
- "The codec info",
- G_PARAM_WRITABLE|G_PARAM_CONSTRUCT_ONLY));
}
static void
@@ -611,349 +584,3 @@ gst_vaapi_decoder_push_surface_proxy(
{
return push_surface(decoder, g_object_ref(proxy), timestamp);
}
-
-static void
-destroy_iq_matrix(GstVaapiDecoder *decoder, GstVaapiIqMatrix *iq_matrix);
-
-static void
-destroy_bitplane(GstVaapiDecoder *decoder, GstVaapiBitPlane *bitplane);
-
-static void
-destroy_slice(GstVaapiDecoder *decoder, GstVaapiSlice *slice);
-
-static void
-destroy_slice_cb(gpointer data, gpointer user_data)
-{
- GstVaapiDecoder * const decoder = GST_VAAPI_DECODER(user_data);
- GstVaapiSlice * const slice = data;
-
- destroy_slice(decoder, slice);
-}
-
-static void
-destroy_picture(GstVaapiDecoder *decoder, GstVaapiPicture *picture)
-{
- GstVaapiDecoderPrivate * const priv = decoder->priv;
-
- if (picture->slices) {
- g_ptr_array_foreach(picture->slices, destroy_slice_cb, decoder);
- g_ptr_array_free(picture->slices, TRUE);
- picture->slices = NULL;
- }
-
- if (picture->iq_matrix) {
- destroy_iq_matrix(decoder, picture->iq_matrix);
- picture->iq_matrix = NULL;
- }
-
- if (picture->bitplane) {
- destroy_bitplane(decoder, picture->bitplane);
- picture->bitplane = NULL;
- }
-
- picture->surface = NULL;
- picture->surface_id = VA_INVALID_ID;
-
- vaapi_destroy_buffer(priv->va_display, &picture->param_id);
- picture->param = NULL;
- g_slice_free1(priv->codec_info.pic_size, picture);
-}
-
-static GstVaapiPicture *
-create_picture(GstVaapiDecoder *decoder)
-{
- GstVaapiDecoderPrivate * const priv = decoder->priv;
- GstVaapiPicture *picture;
-
- picture = g_slice_alloc(priv->codec_info.pic_size);
- if (!picture)
- return NULL;
-
- picture->type = GST_VAAPI_PICTURE_TYPE_NONE;
- picture->flags = 0;
- picture->ref_count = 1;
- picture->surface_id = VA_INVALID_ID;
- picture->surface = NULL;
- picture->param_id = VA_INVALID_ID;
- picture->param = NULL;
- picture->slices = NULL;
- picture->iq_matrix = NULL;
- picture->bitplane = NULL;
- picture->pts = GST_CLOCK_TIME_NONE;
-
- picture->surface = gst_vaapi_context_get_surface(priv->context);
- if (!picture->surface)
- goto error;
- picture->surface_id = gst_vaapi_surface_get_id(picture->surface);
-
- picture->param = vaapi_create_buffer(
- priv->va_display,
- priv->va_context,
- VAPictureParameterBufferType,
- priv->codec_info.pic_param_size,
- &picture->param_id
- );
- if (!picture->param)
- goto error;
-
- picture->slices = g_ptr_array_new();
- if (!picture->slices)
- goto error;
- return picture;
-
-error:
- destroy_picture(priv->va_display, picture);
- return NULL;
-}
-
-GstVaapiPicture *
-gst_vaapi_decoder_new_picture(GstVaapiDecoder *decoder)
-{
- return create_picture(decoder);
-}
-
-void
-gst_vaapi_decoder_free_picture(GstVaapiDecoder *decoder, GstVaapiPicture *picture)
-{
- destroy_picture(decoder, picture);
-}
-
-static void
-destroy_iq_matrix(GstVaapiDecoder *decoder, GstVaapiIqMatrix *iq_matrix)
-{
- GstVaapiDecoderPrivate * const priv = decoder->priv;
-
- vaapi_destroy_buffer(priv->va_display, &iq_matrix->param_id);
- iq_matrix->param = NULL;
- g_slice_free(GstVaapiIqMatrix, iq_matrix);
-}
-
-static GstVaapiIqMatrix *
-create_iq_matrix(GstVaapiDecoder *decoder)
-{
- GstVaapiDecoderPrivate * const priv = decoder->priv;
- GstVaapiIqMatrix *iq_matrix;
-
- iq_matrix = g_slice_new(GstVaapiIqMatrix);
- if (!iq_matrix)
- return NULL;
-
- iq_matrix->param_id = VA_INVALID_ID;
-
- iq_matrix->param = vaapi_create_buffer(
- priv->va_display,
- priv->va_context,
- VAIQMatrixBufferType,
- priv->codec_info.iq_matrix_size,
- &iq_matrix->param_id
- );
- if (!iq_matrix->param)
- goto error;
- return iq_matrix;
-
-error:
- destroy_iq_matrix(decoder, iq_matrix);
- return NULL;
-}
-
-GstVaapiIqMatrix *
-gst_vaapi_decoder_new_iq_matrix(GstVaapiDecoder *decoder)
-{
- return create_iq_matrix(decoder);
-}
-
-static void
-destroy_bitplane(GstVaapiDecoder *decoder, GstVaapiBitPlane *bitplane)
-{
- GstVaapiDecoderPrivate * const priv = decoder->priv;
-
- vaapi_destroy_buffer(priv->va_display, &bitplane->data_id);
- bitplane->data = NULL;
- g_slice_free(GstVaapiBitPlane, bitplane);
-}
-
-static GstVaapiBitPlane *
-create_bitplane(GstVaapiDecoder *decoder, guint size)
-{
- GstVaapiDecoderPrivate * const priv = decoder->priv;
- GstVaapiBitPlane *bitplane;
-
- bitplane = g_slice_new(GstVaapiBitPlane);
- if (!bitplane)
- return NULL;
-
- bitplane->data_id = VA_INVALID_ID;
-
- bitplane->data = vaapi_create_buffer(
- priv->va_display,
- priv->va_context,
- VABitPlaneBufferType,
- size,
- &bitplane->data_id
- );
- if (!bitplane->data)
- goto error;
- return bitplane;
-
-error:
- destroy_bitplane(decoder, bitplane);
- return NULL;
-}
-
-GstVaapiBitPlane *
-gst_vaapi_decoder_new_bitplane(GstVaapiDecoder *decoder, guint size)
-{
- return create_bitplane(decoder, size);
-}
-
-static void
-destroy_slice(GstVaapiDecoder *decoder, GstVaapiSlice *slice)
-{
- GstVaapiDecoderPrivate * const priv = decoder->priv;
-
- vaapi_destroy_buffer(priv->va_display, &slice->data_id);
- vaapi_destroy_buffer(priv->va_display, &slice->param_id);
- slice->param = NULL;
- g_slice_free1(priv->codec_info.slice_size, slice);
-}
-
-static GstVaapiSlice *
-create_slice(GstVaapiDecoder *decoder, guchar *buf, guint buf_size)
-{
- GstVaapiDecoderPrivate * const priv = decoder->priv;
- GstVaapiSlice *slice;
- VASliceParameterBufferBase *slice_param;
- guchar *data;
-
- slice = g_slice_alloc(priv->codec_info.slice_size);
- if (!slice)
- return NULL;
-
- slice->data_id = VA_INVALID_ID;
- slice->param_id = VA_INVALID_ID;
-
- data = vaapi_create_buffer(
- priv->va_display,
- priv->va_context,
- VASliceDataBufferType,
- buf_size,
- &slice->data_id
- );
- if (!data)
- goto error;
- memcpy(data, buf, buf_size);
- vaapi_unmap_buffer(priv->va_display, slice->data_id, NULL);
-
- slice->param = vaapi_create_buffer(
- priv->va_display,
- priv->va_context,
- VASliceParameterBufferType,
- priv->codec_info.slice_param_size,
- &slice->param_id
- );
- if (!slice->param)
- goto error;
-
- slice_param = slice->param;
- slice_param->slice_data_size = buf_size;
- slice_param->slice_data_offset = 0;
- slice_param->slice_data_flag = VA_SLICE_DATA_FLAG_ALL;
- return slice;
-
-error:
- destroy_slice(decoder, slice);
- return NULL;
-}
-
-GstVaapiSlice *
-gst_vaapi_decoder_new_slice(
- GstVaapiDecoder *decoder,
- GstVaapiPicture *picture,
- guchar *buf,
- guint buf_size
-)
-{
- GstVaapiSlice *slice;
-
- slice = create_slice(decoder, buf, buf_size);
- if (!slice)
- return NULL;
-
- if (picture)
- g_ptr_array_add(picture->slices, slice);
- return slice;
-}
-
-void
-gst_vaapi_decoder_free_slice(GstVaapiDecoder *decoder, GstVaapiSlice *slice)
-{
- destroy_slice(decoder, slice);
-}
-
-gboolean
-gst_vaapi_decoder_decode_picture(
- GstVaapiDecoder *decoder,
- GstVaapiPicture *picture
-)
-{
- GstVaapiDecoderPrivate * const priv = decoder->priv;
- GstVaapiIqMatrix * const iq_matrix = picture->iq_matrix;
- GstVaapiBitPlane * const bitplane = picture->bitplane;
- GstVaapiSlice *slice;
- VABufferID va_buffers[3];
- guint i, n_va_buffers = 0;
- VAStatus status;
-
- GST_DEBUG("decode picture 0x%08x", gst_vaapi_surface_get_id(picture->surface));
-
- vaapi_unmap_buffer(priv->va_display, picture->param_id, &picture->param);
- va_buffers[n_va_buffers++] = picture->param_id;
-
- if (iq_matrix) {
- vaapi_unmap_buffer(priv->va_display, iq_matrix->param_id, &iq_matrix->param);
- va_buffers[n_va_buffers++] = iq_matrix->param_id;
- }
-
- if (bitplane) {
- vaapi_unmap_buffer(priv->va_display, bitplane->data_id, (void **)&bitplane->data);
- va_buffers[n_va_buffers++] = bitplane->data_id;
- }
-
- status = vaBeginPicture(
- priv->va_display,
- priv->va_context,
- picture->surface_id
- );
- if (!vaapi_check_status(status, "vaBeginPicture()"))
- return FALSE;
-
- status = vaRenderPicture(
- priv->va_display,
- priv->va_context,
- va_buffers, n_va_buffers
- );
- if (!vaapi_check_status(status, "vaRenderPicture()"))
- return FALSE;
-
- for (i = 0; i < picture->slices->len; i++) {
- slice = g_ptr_array_index(picture->slices, i);
-
- vaapi_unmap_buffer(priv->va_display, slice->param_id, NULL);
- va_buffers[0] = slice->param_id;
- va_buffers[1] = slice->data_id;
- n_va_buffers = 2;
-
- status = vaRenderPicture(
- priv->va_display,
- priv->va_context,
- va_buffers, n_va_buffers
- );
- if (!vaapi_check_status(status, "vaRenderPicture()"))
- return FALSE;
- }
-
- status = vaEndPicture(priv->va_display, priv->va_context);
- if (!vaapi_check_status(status, "vaEndPicture()"))
- return FALSE;
- return TRUE;
-}
diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c
index e70c6357..33edc0f3 100644
--- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c
+++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c
@@ -29,6 +29,7 @@
#include <gst/base/gstbitreader.h>
#include <gst/codecparsers/gstmpegvideoparser.h>
#include "gstvaapidecoder_mpeg2.h"
+#include "gstvaapidecoder_objects.h"
#include "gstvaapidecoder_priv.h"
#include "gstvaapidisplay_priv.h"
#include "gstvaapiobject_priv.h"
@@ -91,23 +92,11 @@ struct _GstVaapiDecoderMpeg2Private {
static void
gst_vaapi_decoder_mpeg2_close(GstVaapiDecoderMpeg2 *decoder)
{
- GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder);
GstVaapiDecoderMpeg2Private * const priv = decoder->priv;
- if (priv->current_picture) {
- gst_vaapi_decoder_free_picture(base_decoder, priv->current_picture);
- priv->current_picture = NULL;
- }
-
- if (priv->next_picture) {
- gst_vaapi_decoder_free_picture(base_decoder, priv->next_picture);
- priv->next_picture = NULL;
- }
-
- if (priv->prev_picture) {
- gst_vaapi_decoder_free_picture(base_decoder, priv->prev_picture);
- priv->prev_picture = NULL;
- }
+ gst_vaapi_picture_replace(&priv->current_picture, NULL);
+ gst_vaapi_picture_replace(&priv->next_picture, NULL);
+ gst_vaapi_picture_replace(&priv->prev_picture, NULL);
if (priv->sub_buffer) {
gst_buffer_unref(priv->sub_buffer);
@@ -221,7 +210,7 @@ ensure_quant_matrix(GstVaapiDecoderMpeg2 *decoder, GstVaapiPicture *picture)
priv->quant_matrix_changed = FALSE;
- picture->iq_matrix = gst_vaapi_decoder_new_iq_matrix(GST_VAAPI_DECODER(decoder));
+ picture->iq_matrix = GST_VAAPI_IQ_MATRIX_NEW(MPEG2, decoder);
if (!picture->iq_matrix) {
GST_DEBUG("failed to allocate IQ matrix");
return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
@@ -266,11 +255,7 @@ ensure_quant_matrix(GstVaapiDecoderMpeg2 *decoder, GstVaapiPicture *picture)
static inline GstVaapiDecoderStatus
render_picture(GstVaapiDecoderMpeg2 *decoder, GstVaapiPicture *picture)
{
- GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder);
-
- if (!gst_vaapi_decoder_push_surface(base_decoder,
- picture->surface,
- picture->pts))
+ if (!gst_vaapi_picture_output(picture))
return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
return GST_VAAPI_DECODER_STATUS_SUCCESS;
}
@@ -278,19 +263,18 @@ render_picture(GstVaapiDecoderMpeg2 *decoder, GstVaapiPicture *picture)
static GstVaapiDecoderStatus
decode_current_picture(GstVaapiDecoderMpeg2 *decoder)
{
- GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder);
GstVaapiDecoderMpeg2Private * const priv = decoder->priv;
GstVaapiPicture * const picture = priv->current_picture;
GstVaapiDecoderStatus status = GST_VAAPI_DECODER_STATUS_SUCCESS;
if (picture) {
- if (!gst_vaapi_decoder_decode_picture(base_decoder, picture))
+ if (!gst_vaapi_picture_decode(picture))
status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture)) {
if ((priv->prev_picture && priv->next_picture) ||
(priv->closed_gop && priv->next_picture))
status = render_picture(decoder, picture);
- gst_vaapi_decoder_free_picture(base_decoder, picture);
+ gst_vaapi_picture_unref(picture);
}
priv->current_picture = NULL;
}
@@ -448,7 +432,6 @@ decode_gop(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size)
static GstVaapiDecoderStatus
decode_picture(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size)
{
- GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder);
GstVaapiDecoderMpeg2Private * const priv = decoder->priv;
GstMpegVideoPictureHdr * const pic_hdr = &priv->pic_hdr;
GstVaapiPicture *picture;
@@ -467,7 +450,7 @@ decode_picture(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size)
return status;
}
- priv->current_picture = gst_vaapi_decoder_new_picture(base_decoder);
+ priv->current_picture = GST_VAAPI_PICTURE_NEW(MPEG2, decoder);
if (!priv->current_picture) {
GST_DEBUG("failed to allocate picture");
return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
@@ -510,9 +493,9 @@ decode_picture(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size)
/* Update reference pictures */
if (pic_hdr->pic_type != GST_MPEG_VIDEO_PICTURE_TYPE_B) {
- picture->flags |= GST_VAAPI_PICTURE_REFERENCE;
+ GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_REFERENCE);
if (priv->prev_picture) {
- gst_vaapi_decoder_free_picture(base_decoder, priv->prev_picture);
+ gst_vaapi_picture_unref(priv->prev_picture);
priv->prev_picture = NULL;
}
if (priv->next_picture) {
@@ -626,15 +609,12 @@ decode_slice(
priv->mb_y = slice_no;
- slice = gst_vaapi_decoder_new_slice(
- GST_VAAPI_DECODER(decoder),
- picture,
- buf, buf_size
- );
+ slice = GST_VAAPI_SLICE_NEW(MPEG2, decoder, buf, buf_size);
if (!slice) {
GST_DEBUG("failed to allocate slice");
return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
}
+ gst_vaapi_picture_add_slice(picture, slice);
/* Parse slice */
gst_bit_reader_init(&br, buf, buf_size);
@@ -911,14 +891,6 @@ gst_vaapi_decoder_mpeg2_new(GstVaapiDisplay *display, GstCaps *caps)
{
GstVaapiDecoderMpeg2 *decoder;
- static const GstVaapiCodecInfo codec_info = {
- .pic_size = sizeof(GstVaapiPicture),
- .slice_size = sizeof(GstVaapiSlice),
- .pic_param_size = sizeof(VAPictureParameterBufferMPEG2),
- .slice_param_size = sizeof(VASliceParameterBufferMPEG2),
- .iq_matrix_size = sizeof(VAIQMatrixBufferMPEG2),
- };
-
g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL);
g_return_val_if_fail(GST_IS_CAPS(caps), NULL);
@@ -926,7 +898,6 @@ gst_vaapi_decoder_mpeg2_new(GstVaapiDisplay *display, GstCaps *caps)
GST_VAAPI_TYPE_DECODER_MPEG2,
"display", display,
"caps", caps,
- "codec-info", &codec_info,
NULL
);
if (!decoder->priv->is_constructed) {
diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c
index 0c4d969f..a81f19b7 100644
--- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c
+++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c
@@ -29,6 +29,7 @@
#include <gst/base/gstbitreader.h>
#include <gst/codecparsers/gstmpeg4parser.h>
#include "gstvaapidecoder_mpeg4.h"
+#include "gstvaapidecoder_objects.h"
#include "gstvaapidecoder_priv.h"
#include "gstvaapidisplay_priv.h"
#include "gstvaapiobject_priv.h"
@@ -95,23 +96,11 @@ struct _GstVaapiDecoderMpeg4Private {
static void
gst_vaapi_decoder_mpeg4_close(GstVaapiDecoderMpeg4 *decoder)
{
- GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder);
GstVaapiDecoderMpeg4Private * const priv = decoder->priv;
- if (priv->curr_picture) {
- gst_vaapi_decoder_free_picture(base_decoder, priv->curr_picture);
- priv->curr_picture = NULL;
- }
-
- if (priv->next_picture) {
- gst_vaapi_decoder_free_picture(base_decoder, priv->next_picture);
- priv->next_picture = NULL;
- }
-
- if (priv->prev_picture) {
- gst_vaapi_decoder_free_picture(base_decoder, priv->prev_picture);
- priv->prev_picture = NULL;
- }
+ gst_vaapi_picture_replace(&priv->curr_picture, NULL);
+ gst_vaapi_picture_replace(&priv->next_picture, NULL);
+ gst_vaapi_picture_replace(&priv->prev_picture, NULL);
if (priv->sub_buffer) {
gst_buffer_unref(priv->sub_buffer);
@@ -231,7 +220,7 @@ ensure_quant_matrix(GstVaapiDecoderMpeg4 *decoder, GstVaapiPicture *picture)
return GST_VAAPI_DECODER_STATUS_SUCCESS;
}
- picture->iq_matrix = gst_vaapi_decoder_new_iq_matrix(GST_VAAPI_DECODER(decoder));
+ picture->iq_matrix = GST_VAAPI_IQ_MATRIX_NEW(MPEG4, decoder);
if (!picture->iq_matrix) {
GST_DEBUG("failed to allocate IQ matrix");
return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
@@ -261,11 +250,7 @@ ensure_quant_matrix(GstVaapiDecoderMpeg4 *decoder, GstVaapiPicture *picture)
static inline GstVaapiDecoderStatus
render_picture(GstVaapiDecoderMpeg4 *decoder, GstVaapiPicture *picture)
{
- GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder);
-
- if (!gst_vaapi_decoder_push_surface(base_decoder,
- picture->surface,
- picture->pts))
+ if (!gst_vaapi_picture_output(picture))
return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
return GST_VAAPI_DECODER_STATUS_SUCCESS;
}
@@ -277,19 +262,18 @@ render_picture(GstVaapiDecoderMpeg4 *decoder, GstVaapiPicture *picture)
static GstVaapiDecoderStatus
decode_current_picture(GstVaapiDecoderMpeg4 *decoder)
{
- GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder);
GstVaapiDecoderMpeg4Private * const priv = decoder->priv;
GstVaapiPicture * const picture = priv->curr_picture;
GstVaapiDecoderStatus status = GST_VAAPI_DECODER_STATUS_SUCCESS;
if (picture) {
- if (!gst_vaapi_decoder_decode_picture(base_decoder, picture))
+ if (!gst_vaapi_picture_decode(picture))
status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture)) {
if ((priv->prev_picture && priv->next_picture) ||
(priv->closed_gop && priv->next_picture))
status = render_picture(decoder, picture);
- gst_vaapi_decoder_free_picture(base_decoder, picture);
+ gst_vaapi_picture_unref(picture);
}
priv->curr_picture = NULL;
}
@@ -448,7 +432,6 @@ static GstVaapiDecoderStatus
decode_picture(GstVaapiDecoderMpeg4 *decoder, const guint8 *buf, guint buf_size)
{
GstMpeg4ParseResult parser_result = GST_MPEG4_PARSER_OK;
- GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder);
GstVaapiDecoderMpeg4Private * const priv = decoder->priv;
GstMpeg4VideoObjectPlane * const vop_hdr = &priv->vop_hdr;
GstMpeg4VideoObjectLayer * const vol_hdr = &priv->vol_hdr;
@@ -496,7 +479,7 @@ decode_picture(GstVaapiDecoderMpeg4 *decoder, const guint8 *buf, guint buf_size)
return status;
}
- priv->curr_picture = gst_vaapi_decoder_new_picture(base_decoder);
+ priv->curr_picture = GST_VAAPI_PICTURE_NEW(MPEG4, decoder);
if (!priv->curr_picture) {
GST_DEBUG("failed to allocate picture");
return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
@@ -527,12 +510,12 @@ decode_picture(GstVaapiDecoderMpeg4 *decoder, const guint8 *buf, guint buf_size)
case GST_MPEG4_I_VOP:
picture->type = GST_VAAPI_PICTURE_TYPE_I;
if (priv->is_svh || vop_hdr->coded)
- picture->flags |= GST_VAAPI_PICTURE_REFERENCE;
+ GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_REFERENCE);
break;
case GST_MPEG4_P_VOP:
picture->type = GST_VAAPI_PICTURE_TYPE_P;
if (priv->is_svh || vop_hdr->coded)
- picture->flags |= GST_VAAPI_PICTURE_REFERENCE;
+ GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_REFERENCE);
break;
case GST_MPEG4_B_VOP:
picture->type = GST_VAAPI_PICTURE_TYPE_B;
@@ -541,7 +524,7 @@ decode_picture(GstVaapiDecoderMpeg4 *decoder, const guint8 *buf, guint buf_size)
picture->type = GST_VAAPI_PICTURE_TYPE_S;
// see 3.175 reference VOP
if (vop_hdr->coded)
- picture->flags |= GST_VAAPI_PICTURE_REFERENCE;
+ GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_REFERENCE);
break;
default:
GST_DEBUG("unsupported picture type %d", priv->coding_type);
@@ -586,9 +569,8 @@ decode_picture(GstVaapiDecoderMpeg4 *decoder, const guint8 *buf, guint buf_size)
/* Update reference pictures */
/* XXX: consider priv->vol_hdr.low_delay, consider packed video frames for DivX/XviD */
if (GST_VAAPI_PICTURE_IS_REFERENCE(picture)) {
- picture->flags |= GST_VAAPI_PICTURE_REFERENCE;
if (priv->prev_picture) {
- gst_vaapi_decoder_free_picture(base_decoder, priv->prev_picture);
+ gst_vaapi_picture_unref(priv->prev_picture);
priv->prev_picture = NULL;
}
if (priv->next_picture) {
@@ -712,15 +694,12 @@ decode_slice(
if (!has_packet_header && !fill_picture(decoder, picture))
return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
- slice = gst_vaapi_decoder_new_slice(
- GST_VAAPI_DECODER(decoder),
- picture,
- (guchar*)buf, buf_size
- );
+ slice = GST_VAAPI_SLICE_NEW(MPEG4, decoder, buf, buf_size);
if (!slice) {
GST_DEBUG("failed to allocate slice");
return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
}
+ gst_vaapi_picture_add_slice(picture, slice);
/* Fill in VASliceParameterBufferMPEG4 */
slice_param = slice->param;
@@ -1085,14 +1064,6 @@ gst_vaapi_decoder_mpeg4_new(GstVaapiDisplay *display, GstCaps *caps)
{
GstVaapiDecoderMpeg4 *decoder;
- static const GstVaapiCodecInfo codec_info = {
- .pic_size = sizeof(GstVaapiPicture),
- .slice_size = sizeof(GstVaapiSlice),
- .pic_param_size = sizeof(VAPictureParameterBufferMPEG4),
- .slice_param_size = sizeof(VASliceParameterBufferMPEG4),
- .iq_matrix_size = sizeof(VAIQMatrixBufferMPEG4),
- };
-
g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL);
g_return_val_if_fail(GST_IS_CAPS(caps), NULL);
@@ -1100,7 +1071,6 @@ gst_vaapi_decoder_mpeg4_new(GstVaapiDisplay *display, GstCaps *caps)
GST_VAAPI_TYPE_DECODER_MPEG4,
"display", display,
"caps", caps,
- "codec-info", &codec_info,
NULL
);
if (!decoder->priv->is_constructed) {
diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c
new file mode 100644
index 00000000..61ff4e6b
--- /dev/null
+++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c
@@ -0,0 +1,326 @@
+/*
+ * gstvaapidecoder_objects.c - VA decoder objects helpers
+ *
+ * Copyright (C) 2010-2011 Splitted-Desktop Systems
+ * Copyright (C) 2011-2012 Intel Corporation
+ *
+ * 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
+ */
+
+#include "config.h"
+#include <string.h>
+#include <gst/vaapi/gstvaapicontext.h>
+#include "gstvaapidecoder_objects.h"
+#include "gstvaapidecoder_priv.h"
+#include "gstvaapicompat.h"
+#include "gstvaapiutils.h"
+
+#define DEBUG 1
+#include "gstvaapidebug.h"
+
+#define GET_DECODER(obj) GST_VAAPI_DECODER_CAST((obj)->parent_instance.codec)
+#define GET_CONTEXT(obj) GET_DECODER(obj)->priv->context
+#define GET_VA_DISPLAY(obj) GET_DECODER(obj)->priv->va_display
+#define GET_VA_CONTEXT(obj) GET_DECODER(obj)->priv->va_context
+
+/* ------------------------------------------------------------------------- */
+/* --- Pictures --- */
+/* ------------------------------------------------------------------------- */
+
+GST_VAAPI_CODEC_DEFINE_TYPE(GstVaapiPicture,
+ gst_vaapi_picture,
+ GST_VAAPI_TYPE_CODEC_OBJECT)
+
+static void
+destroy_slice_cb(gpointer data, gpointer user_data)
+{
+ GstMiniObject * const object = data;
+
+ gst_mini_object_unref(object);
+}
+
+static void
+gst_vaapi_picture_destroy(GstVaapiPicture *picture)
+{
+ if (picture->slices) {
+ g_ptr_array_foreach(picture->slices, destroy_slice_cb, NULL);
+ g_ptr_array_free(picture->slices, TRUE);
+ picture->slices = NULL;
+ }
+
+ if (picture->iq_matrix) {
+ gst_mini_object_unref(GST_MINI_OBJECT(picture->iq_matrix));
+ picture->iq_matrix = NULL;
+ }
+
+ if (picture->bitplane) {
+ gst_mini_object_unref(GST_MINI_OBJECT(picture->bitplane));
+ picture->bitplane = NULL;
+ }
+
+ picture->surface_id = VA_INVALID_ID;
+ picture->surface = NULL;
+
+ vaapi_destroy_buffer(GET_VA_DISPLAY(picture), &picture->param_id);
+ picture->param = NULL;
+}
+
+static gboolean
+gst_vaapi_picture_create(
+ GstVaapiPicture *picture,
+ const GstVaapiCodecObjectConstructorArgs *args
+)
+{
+ picture->surface = gst_vaapi_context_get_surface(GET_CONTEXT(picture));
+ if (!picture->surface)
+ return FALSE;
+ picture->surface_id = gst_vaapi_surface_get_id(picture->surface);
+
+ picture->param = vaapi_create_buffer(
+ GET_VA_DISPLAY(picture),
+ GET_VA_CONTEXT(picture),
+ VAPictureParameterBufferType,
+ args->param_size,
+ &picture->param_id
+ );
+ if (!picture->param)
+ return FALSE;
+
+ picture->slices = g_ptr_array_new();
+ if (!picture->slices)
+ return FALSE;
+ return TRUE;
+}
+
+static void
+gst_vaapi_picture_init(GstVaapiPicture *picture)
+{
+ picture->type = GST_VAAPI_PICTURE_TYPE_NONE;
+ picture->surface = NULL;
+ picture->surface_id = VA_INVALID_ID;
+ picture->param = NULL;
+ picture->param_id = VA_INVALID_ID;
+ picture->slices = NULL;
+ picture->iq_matrix = NULL;
+ picture->bitplane = NULL;
+ picture->pts = GST_CLOCK_TIME_NONE;
+}
+
+GstVaapiPicture *
+gst_vaapi_picture_new(
+ GstVaapiDecoder *decoder,
+ gconstpointer param,
+ guint param_size
+)
+{
+ GstVaapiCodecObject *object;
+
+ g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), NULL);
+
+ object = gst_vaapi_codec_object_new(
+ GST_VAAPI_TYPE_PICTURE,
+ GST_VAAPI_CODEC_BASE(decoder),
+ param, param_size,
+ NULL, 0
+ );
+ if (!object)
+ return NULL;
+ return GST_VAAPI_PICTURE_CAST(object);
+}
+
+void
+gst_vaapi_picture_add_slice(GstVaapiPicture *picture, GstVaapiSlice *slice)
+{
+ g_return_if_fail(GST_VAAPI_IS_PICTURE(picture));
+ g_return_if_fail(GST_VAAPI_IS_SLICE(slice));
+
+ g_ptr_array_add(picture->slices, slice);
+}
+
+gboolean
+gst_vaapi_picture_decode(GstVaapiPicture *picture)
+{
+ GstVaapiIqMatrix *iq_matrix;
+ GstVaapiBitPlane *bitplane;
+ VADisplay va_display;
+ VAContextID va_context;
+ VABufferID va_buffers[3];
+ guint i, n_va_buffers = 0;
+ VAStatus status;
+
+ g_return_val_if_fail(GST_VAAPI_IS_PICTURE(picture), FALSE);
+
+ va_display = GET_VA_DISPLAY(picture);
+ va_context = GET_VA_CONTEXT(picture);
+
+ GST_DEBUG("decode picture 0x%08x", picture->surface_id);
+
+ vaapi_unmap_buffer(va_display, picture->param_id, &picture->param);
+ va_buffers[n_va_buffers++] = picture->param_id;
+
+ iq_matrix = picture->iq_matrix;
+ if (iq_matrix) {
+ vaapi_unmap_buffer(
+ va_display,
+ iq_matrix->param_id, &iq_matrix->param
+ );
+ va_buffers[n_va_buffers++] = iq_matrix->param_id;
+ }
+
+ bitplane = picture->bitplane;
+ if (bitplane) {
+ vaapi_unmap_buffer(
+ va_display,
+ bitplane->data_id, (void **)&bitplane->data
+ );
+ va_buffers[n_va_buffers++] = bitplane->data_id;
+ }
+
+ status = vaBeginPicture(va_display, va_context, picture->surface_id);
+ if (!vaapi_check_status(status, "vaBeginPicture()"))
+ return FALSE;
+
+ status = vaRenderPicture(va_display, va_context, va_buffers, n_va_buffers);
+ if (!vaapi_check_status(status, "vaRenderPicture()"))
+ return FALSE;
+
+ for (i = 0; i < picture->slices->len; i++) {
+ GstVaapiSlice * const slice = g_ptr_array_index(picture->slices, i);
+
+ vaapi_unmap_buffer(va_display, slice->param_id, NULL);
+ va_buffers[0] = slice->param_id;
+ va_buffers[1] = slice->data_id;
+ n_va_buffers = 2;
+
+ status = vaRenderPicture(
+ va_display,
+ va_context,
+ va_buffers, n_va_buffers
+ );
+ if (!vaapi_check_status(status, "vaRenderPicture()"))
+ return FALSE;
+ }
+
+ status = vaEndPicture(va_display, va_context);
+ if (!vaapi_check_status(status, "vaEndPicture()"))
+ return FALSE;
+ return TRUE;
+}
+
+gboolean
+gst_vaapi_picture_output(GstVaapiPicture *picture)
+{
+ GstVaapiSurfaceProxy *proxy;
+ gboolean success;
+
+ g_return_val_if_fail(GST_VAAPI_IS_PICTURE(picture), FALSE);
+
+ proxy = gst_vaapi_surface_proxy_new(GET_CONTEXT(picture), picture->surface);
+ if (!proxy)
+ return FALSE;
+ success = gst_vaapi_decoder_push_surface_proxy(
+ GET_DECODER(picture),
+ proxy, picture->pts
+ );
+ g_object_unref(proxy); // ref'ed in gst_vaapi_decoder_push_surface_proxy()
+ return success;
+}
+
+/* ------------------------------------------------------------------------- */
+/* --- Slices --- */
+/* ------------------------------------------------------------------------- */
+
+GST_VAAPI_CODEC_DEFINE_TYPE(GstVaapiSlice,
+ gst_vaapi_slice,
+ GST_VAAPI_TYPE_CODEC_OBJECT)
+
+static void
+gst_vaapi_slice_destroy(GstVaapiSlice *slice)
+{
+ VADisplay const va_display = GET_VA_DISPLAY(slice);
+
+ vaapi_destroy_buffer(va_display, &slice->data_id);
+ vaapi_destroy_buffer(va_display, &slice->param_id);
+ slice->param = NULL;
+}
+
+static gboolean
+gst_vaapi_slice_create(
+ GstVaapiSlice *slice,
+ const GstVaapiCodecObjectConstructorArgs *args
+)
+{
+ VASliceParameterBufferBase *slice_param;
+ guint8 *data;
+
+ data = vaapi_create_buffer(
+ GET_VA_DISPLAY(slice),
+ GET_VA_CONTEXT(slice),
+ VASliceDataBufferType,
+ args->data_size,
+ &slice->data_id
+ );
+ if (!data)
+ return FALSE;
+ memcpy(data, args->data, args->data_size);
+ vaapi_unmap_buffer(GET_VA_DISPLAY(slice), slice->data_id, NULL);
+
+ slice->param = vaapi_create_buffer(
+ GET_VA_DISPLAY(slice),
+ GET_VA_CONTEXT(slice),
+ VASliceParameterBufferType,
+ args->param_size,
+ &slice->param_id
+ );
+ if (!slice->param)
+ return FALSE;
+
+ slice_param = slice->param;
+ slice_param->slice_data_size = args->data_size;
+ slice_param->slice_data_offset = 0;
+ slice_param->slice_data_flag = VA_SLICE_DATA_FLAG_ALL;
+ return TRUE;
+}
+
+static void
+gst_vaapi_slice_init(GstVaapiSlice *slice)
+{
+ slice->param = NULL;
+ slice->param_id = VA_INVALID_ID;
+ slice->data_id = VA_INVALID_ID;
+}
+
+GstVaapiSlice *
+gst_vaapi_slice_new(
+ GstVaapiDecoder *decoder,
+ gconstpointer param,
+ guint param_size,
+ const guchar *data,
+ guint data_size
+)
+{
+ GstVaapiCodecObject *object;
+
+ g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), NULL);
+
+ object = gst_vaapi_codec_object_new(
+ GST_VAAPI_TYPE_SLICE,
+ GST_VAAPI_CODEC_BASE(decoder),
+ param, param_size,
+ data, data_size
+ );
+ return GST_VAAPI_SLICE_CAST(object);
+}
diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h
new file mode 100644
index 00000000..2bd1ea98
--- /dev/null
+++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h
@@ -0,0 +1,253 @@
+/*
+ * gstvaapidecoder_objects.h - VA decoder objects
+ *
+ * Copyright (C) 2010-2011 Splitted-Desktop Systems
+ * Copyright (C) 2011-2012 Intel Corporation
+ *
+ * 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_OBJECTS_H
+#define GST_VAAPI_DECODER_OBJECTS_H
+
+#include <gst/vaapi/gstvaapicodec_objects.h>
+
+G_BEGIN_DECLS
+
+typedef enum _GstVaapiPictureType GstVaapiPictureType;
+typedef struct _GstVaapiPicture GstVaapiPicture;
+typedef struct _GstVaapiPictureClass GstVaapiPictureClass;
+typedef struct _GstVaapiSlice GstVaapiSlice;
+typedef struct _GstVaapiSliceClass GstVaapiSliceClass;
+
+/* ------------------------------------------------------------------------- */
+/* --- Pictures --- */
+/* ------------------------------------------------------------------------- */
+
+#define GST_VAAPI_TYPE_PICTURE \
+ (gst_vaapi_picture_get_type())
+
+#define GST_VAAPI_PICTURE_CAST(obj) \
+ ((GstVaapiPicture *)(obj))
+
+#define GST_VAAPI_PICTURE(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj), \
+ GST_VAAPI_TYPE_PICTURE, \
+ GstVaapiPicture))
+
+#define GST_VAAPI_PICTURE_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass), \
+ GST_VAAPI_TYPE_PICTURE, \
+ GstVaapiPictureClass))
+
+#define GST_VAAPI_IS_PICTURE(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_PICTURE))
+
+#define GST_VAAPI_IS_PICTURE_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_PICTURE))
+
+#define GST_VAAPI_PICTURE_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS((obj), \
+ GST_VAAPI_TYPE_PICTURE, \
+ GstVaapiPictureClass))
+
+enum _GstVaapiPictureType {
+ GST_VAAPI_PICTURE_TYPE_NONE = 0, // Undefined
+ GST_VAAPI_PICTURE_TYPE_I, // Intra
+ GST_VAAPI_PICTURE_TYPE_P, // Predicted
+ GST_VAAPI_PICTURE_TYPE_B, // Bi-directional predicted
+ GST_VAAPI_PICTURE_TYPE_S, // S(GMC)-VOP (MPEG-4)
+ GST_VAAPI_PICTURE_TYPE_SI, // Switching Intra
+ GST_VAAPI_PICTURE_TYPE_SP, // Switching Predicted
+ GST_VAAPI_PICTURE_TYPE_BI, // BI type (VC-1)
+};
+
+/**
+ * Picture flags:
+ * @GST_VAAPI_PICTURE_FLAG_SKIPPED: skipped frame
+ * @GST_VAAPI_PICTURE_FLAG_REFERENCE: reference frame
+ * @GST_VAAPI_PICTURE_FLAG_LAST: first flag that can be used by subclasses
+ *
+ * Enum values used for #GstVaapiPicture flags.
+ */
+enum {
+ GST_VAAPI_PICTURE_FLAG_SKIPPED = (GST_VAAPI_CODEC_OBJECT_FLAG_LAST << 0),
+ GST_VAAPI_PICTURE_FLAG_REFERENCE = (GST_VAAPI_CODEC_OBJECT_FLAG_LAST << 1),
+ GST_VAAPI_PICTURE_FLAG_LAST = (GST_VAAPI_CODEC_OBJECT_FLAG_LAST << 2),
+};
+
+#define GST_VAAPI_PICTURE_FLAG_IS_SET GST_MINI_OBJECT_FLAG_IS_SET
+#define GST_VAAPI_PICTURE_FLAG_SET GST_MINI_OBJECT_FLAG_SET
+#define GST_VAAPI_PICTURE_FLAG_UNSET GST_MINI_OBJECT_FLAG_UNSET
+
+#define GST_VAAPI_PICTURE_IS_REFERENCE(picture) \
+ GST_VAAPI_PICTURE_FLAG_IS_SET(picture, GST_VAAPI_PICTURE_FLAG_REFERENCE)
+
+/**
+ * GstVaapiPicture:
+ *
+ * A #GstVaapiCodecObject holding a picture parameter.
+ */
+struct _GstVaapiPicture {
+ /*< private >*/
+ GstVaapiCodecObject parent_instance;
+ GstVaapiSurface *surface;
+ VABufferID param_id;
+
+ /*< public >*/
+ GstVaapiPictureType type;
+ VASurfaceID surface_id;
+ gpointer param;
+ GPtrArray *slices;
+ GstVaapiIqMatrix *iq_matrix;
+ GstVaapiBitPlane *bitplane;
+ GstClockTime pts;
+};
+
+/**
+ * GstVaapiPictureClass:
+ *
+ * The #GstVaapiPicture base class.
+ */
+struct _GstVaapiPictureClass {
+ /*< private >*/
+ GstVaapiCodecObjectClass parent_class;
+};
+
+GType
+gst_vaapi_picture_get_type(void)
+ attribute_hidden;
+
+GstVaapiPicture *
+gst_vaapi_picture_new(
+ GstVaapiDecoder *decoder,
+ gconstpointer param,
+ guint param_size
+) attribute_hidden;
+
+void
+gst_vaapi_picture_add_slice(GstVaapiPicture *picture, GstVaapiSlice *slice)
+ attribute_hidden;
+
+gboolean
+gst_vaapi_picture_decode(GstVaapiPicture *picture)
+ attribute_hidden;
+
+gboolean
+gst_vaapi_picture_output(GstVaapiPicture *picture)
+ attribute_hidden;
+
+static inline gpointer
+gst_vaapi_picture_ref(gpointer ptr)
+{
+ return gst_mini_object_ref(GST_MINI_OBJECT(ptr));
+}
+
+static inline void
+gst_vaapi_picture_unref(gpointer ptr)
+{
+ gst_mini_object_unref(GST_MINI_OBJECT(ptr));
+}
+
+#define gst_vaapi_picture_replace(old_picture_p, new_picture) \
+ gst_mini_object_replace((GstMiniObject **)(old_picture_p), \
+ (GstMiniObject *)(new_picture))
+
+/* ------------------------------------------------------------------------- */
+/* --- Slices --- */
+/* ------------------------------------------------------------------------- */
+
+#define GST_VAAPI_TYPE_SLICE \
+ (gst_vaapi_slice_get_type())
+
+#define GST_VAAPI_SLICE_CAST(obj) \
+ ((GstVaapiSlice *)(obj))
+
+#define GST_VAAPI_SLICE(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj), \
+ GST_VAAPI_TYPE_SLICE, \
+ GstVaapiSlice))
+
+#define GST_VAAPI_SLICE_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass), \
+ GST_VAAPI_TYPE_SLICE, \
+ GstVaapiSliceClass))
+
+#define GST_VAAPI_IS_SLICE(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_SLICE))
+
+#define GST_VAAPI_IS_SLICE_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_SLICE))
+
+#define GST_VAAPI_SLICE_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS((obj), \
+ GST_VAAPI_TYPE_SLICE, \
+ GstVaapiSliceClass))
+
+/**
+ * GstVaapiSlice:
+ *
+ * A #GstVaapiCodecObject holding a slice parameter.
+ */
+struct _GstVaapiSlice {
+ /*< private >*/
+ GstVaapiCodecObject parent_instance;
+
+ /*< public >*/
+ VABufferID param_id;
+ VABufferID data_id;
+ gpointer param;
+};
+
+/**
+ * GstVaapiSliceClass:
+ *
+ * The #GstVaapiSlice base class.
+ */
+struct _GstVaapiSliceClass {
+ /*< private >*/
+ GstVaapiCodecObjectClass parent_class;
+};
+
+GType
+gst_vaapi_slice_get_type(void)
+ attribute_hidden;
+
+GstVaapiSlice *
+gst_vaapi_slice_new(
+ GstVaapiDecoder *decoder,
+ gconstpointer param,
+ guint param_size,
+ const guchar *data,
+ guint data_size
+) attribute_hidden;
+
+/* ------------------------------------------------------------------------- */
+/* --- Helpers to create codec-dependent objects --- */
+/* ------------------------------------------------------------------------- */
+
+#define GST_VAAPI_PICTURE_NEW(codec, decoder) \
+ gst_vaapi_picture_new(GST_VAAPI_DECODER_CAST(decoder), \
+ NULL, sizeof(VAPictureParameterBuffer##codec))
+
+#define GST_VAAPI_SLICE_NEW(codec, decoder, buf, buf_size) \
+ gst_vaapi_slice_new(GST_VAAPI_DECODER_CAST(decoder), \
+ NULL, sizeof(VASliceParameterBuffer##codec), \
+ buf, buf_size)
+
+G_END_DECLS
+
+#endif /* GST_VAAPI_DECODER_OBJECTS_H */
diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h
index 2d6d55d6..27efee11 100644
--- a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h
+++ b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h
@@ -109,73 +109,6 @@ G_BEGIN_DECLS
GST_VAAPI_TYPE_DECODER, \
GstVaapiDecoderPrivate))
-typedef enum _GstVaapiPictureType GstVaapiPictureType;
-typedef struct _GstVaapiCodecInfo GstVaapiCodecInfo;
-typedef struct _GstVaapiPicture GstVaapiPicture;
-typedef struct _GstVaapiSlice GstVaapiSlice;
-typedef struct _GstVaapiIqMatrix GstVaapiIqMatrix;
-typedef struct _GstVaapiBitPlane GstVaapiBitPlane;
-
-enum _GstVaapiPictureType {
- GST_VAAPI_PICTURE_TYPE_NONE = 0, // Undefined
- GST_VAAPI_PICTURE_TYPE_I, // Intra
- GST_VAAPI_PICTURE_TYPE_P, // Predicted
- GST_VAAPI_PICTURE_TYPE_B, // Bi-directional predicted
- GST_VAAPI_PICTURE_TYPE_S, // S(GMC)-VOP (MPEG-4)
- GST_VAAPI_PICTURE_TYPE_SI, // Switching Intra
- GST_VAAPI_PICTURE_TYPE_SP, // Switching Predicted
- GST_VAAPI_PICTURE_TYPE_BI, // BI type (VC-1)
-};
-
-enum {
- GST_VAAPI_PICTURE_SKIPPED = 1 << 0, // Skipped frame
- GST_VAAPI_PICTURE_REFERENCE = 1 << 1, // Reference frame
-};
-
-#define GST_VAAPI_PICTURE(picture) \
- ((GstVaapiPicture *)(picture))
-
-#define GST_VAAPI_PICTURE_IS_REFERENCE(picture) \
- ((GST_VAAPI_PICTURE(picture)->flags & GST_VAAPI_PICTURE_REFERENCE) != 0)
-
-struct _GstVaapiCodecInfo {
- guint pic_size; // GstVaapiPicture size
- guint slice_size; // GstVaapiSlice size
- guint pic_param_size; // VAPictureParameterBuffer size
- guint slice_param_size; // VASliceParameterBuffer size
- guint iq_matrix_size; // VAIQMatrixBuffer size
-};
-
-struct _GstVaapiPicture {
- GstVaapiPictureType type;
- guint flags;
- guint ref_count;
- VASurfaceID surface_id;
- GstVaapiSurface *surface;
- VABufferID param_id;
- void *param;
- GPtrArray *slices;
- GstVaapiIqMatrix *iq_matrix;
- GstVaapiBitPlane *bitplane;
- GstClockTime pts;
-};
-
-struct _GstVaapiSlice {
- VABufferID param_id;
- void *param;
- VABufferID data_id;
-};
-
-struct _GstVaapiIqMatrix {
- VABufferID param_id;
- void *param;
-};
-
-struct _GstVaapiBitPlane {
- VABufferID data_id;
- guint8 *data;
-};
-
struct _GstVaapiDecoderPrivate {
GstVaapiDisplay *display;
VADisplay va_display;
@@ -184,7 +117,6 @@ struct _GstVaapiDecoderPrivate {
GstCaps *caps;
GstVaapiCodec codec;
GstBuffer *codec_data;
- GstVaapiCodecInfo codec_info;
guint width;
guint height;
guint fps_n;
@@ -247,54 +179,6 @@ gst_vaapi_decoder_push_surface_proxy(
GstClockTime timestamp
) attribute_hidden;
-GstVaapiPicture *
-gst_vaapi_decoder_new_picture(GstVaapiDecoder *decoder)
- attribute_hidden;
-
-void
-gst_vaapi_decoder_free_picture(GstVaapiDecoder *decoder, GstVaapiPicture *picture)
- attribute_hidden;
-
-static inline GstVaapiPicture *
-gst_vaapi_decoder_ref_picture(GstVaapiDecoder *decoder, GstVaapiPicture *picture)
-{
- ++picture->ref_count;
- return picture;
-}
-
-static inline void
-gst_vaapi_decoder_unref_picture(GstVaapiDecoder *decoder, GstVaapiPicture *picture)
-{
- if (--picture->ref_count == 0)
- gst_vaapi_decoder_free_picture(decoder, picture);
-}
-
-GstVaapiIqMatrix *
-gst_vaapi_decoder_new_iq_matrix(GstVaapiDecoder *decoder)
- attribute_hidden;
-
-GstVaapiBitPlane *
-gst_vaapi_decoder_new_bitplane(GstVaapiDecoder *decoder, guint size)
- attribute_hidden;
-
-GstVaapiSlice *
-gst_vaapi_decoder_new_slice(
- GstVaapiDecoder *decoder,
- GstVaapiPicture *picture,
- guchar *buf,
- guint buf_size
-) attribute_hidden;
-
-void
-gst_vaapi_decoder_free_slice(GstVaapiDecoder *decoder, GstVaapiSlice *slice)
- attribute_hidden;
-
-gboolean
-gst_vaapi_decoder_decode_picture(
- GstVaapiDecoder *decoder,
- GstVaapiPicture *picture
-) attribute_hidden;
-
G_END_DECLS
#endif /* GST_VAAPI_DECODER_PRIV_H */
diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c
index 0bf52371..9f4e6c9e 100644
--- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c
+++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c
@@ -28,6 +28,7 @@
#include <string.h>
#include <gst/codecparsers/gstvc1parser.h>
#include "gstvaapidecoder_vc1.h"
+#include "gstvaapidecoder_objects.h"
#include "gstvaapidecoder_priv.h"
#include "gstvaapidisplay_priv.h"
#include "gstvaapiobject_priv.h"
@@ -96,23 +97,11 @@ get_status(GstVC1ParserResult result)
static void
gst_vaapi_decoder_vc1_close(GstVaapiDecoderVC1 *decoder)
{
- GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder);
GstVaapiDecoderVC1Private * const priv = decoder->priv;
- if (priv->current_picture) {
- gst_vaapi_decoder_free_picture(base_decoder, priv->current_picture);
- priv->current_picture = NULL;
- }
-
- if (priv->next_picture) {
- gst_vaapi_decoder_free_picture(base_decoder, priv->next_picture);
- priv->next_picture = NULL;
- }
-
- if (priv->prev_picture) {
- gst_vaapi_decoder_free_picture(base_decoder, priv->prev_picture);
- priv->prev_picture = NULL;
- }
+ gst_vaapi_picture_replace(&priv->current_picture, NULL);
+ gst_vaapi_picture_replace(&priv->next_picture, NULL);
+ gst_vaapi_picture_replace(&priv->prev_picture, NULL);
if (priv->sub_buffer) {
gst_buffer_unref(priv->sub_buffer);
@@ -220,11 +209,7 @@ ensure_context(GstVaapiDecoderVC1 *decoder)
static inline GstVaapiDecoderStatus
render_picture(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture)
{
- GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder);
-
- if (!gst_vaapi_decoder_push_surface(base_decoder,
- picture->surface,
- picture->pts))
+ if (!gst_vaapi_picture_output(picture))
return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
return GST_VAAPI_DECODER_STATUS_SUCCESS;
}
@@ -232,18 +217,17 @@ render_picture(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture)
static GstVaapiDecoderStatus
decode_current_picture(GstVaapiDecoderVC1 *decoder)
{
- GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder);
GstVaapiDecoderVC1Private * const priv = decoder->priv;
GstVaapiPicture * const picture = priv->current_picture;
GstVaapiDecoderStatus status = GST_VAAPI_DECODER_STATUS_SUCCESS;
if (picture) {
- if (!gst_vaapi_decoder_decode_picture(base_decoder, picture))
+ if (!gst_vaapi_picture_decode(picture))
status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture)) {
if (priv->prev_picture && priv->next_picture)
status = render_picture(decoder, picture);
- gst_vaapi_decoder_free_picture(base_decoder, picture);
+ gst_vaapi_picture_unref(picture);
}
priv->current_picture = NULL;
}
@@ -788,7 +772,6 @@ fill_picture_advanced(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture)
static gboolean
fill_picture(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture)
{
- GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder);
GstVaapiDecoderVC1Private * const priv = decoder->priv;
VAPictureParameterBufferVC1 * const pic_param = picture->param;
GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
@@ -878,8 +861,8 @@ fill_picture(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture)
break;
}
- picture->bitplane = gst_vaapi_decoder_new_bitplane(
- base_decoder,
+ picture->bitplane = GST_VAAPI_BITPLANE_NEW(
+ decoder,
(seq_hdr->mb_width * seq_hdr->mb_height + 1) / 2
);
if (!picture->bitplane)
@@ -898,7 +881,6 @@ fill_picture(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture)
static GstVaapiDecoderStatus
decode_frame(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu)
{
- GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder);
GstVaapiDecoderVC1Private * const priv = decoder->priv;
GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr;
@@ -921,7 +903,7 @@ decode_frame(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu)
return status;
}
- priv->current_picture = gst_vaapi_decoder_new_picture(base_decoder);
+ priv->current_picture = GST_VAAPI_PICTURE_NEW(VC1, decoder);
if (!priv->current_picture) {
GST_DEBUG("failed to allocate picture");
return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
@@ -949,14 +931,14 @@ decode_frame(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu)
switch (frame_hdr->ptype) {
case GST_VC1_PICTURE_TYPE_I:
picture->type = GST_VAAPI_PICTURE_TYPE_I;
- picture->flags |= GST_VAAPI_PICTURE_REFERENCE;
+ GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_REFERENCE);
break;
case GST_VC1_PICTURE_TYPE_SKIPPED:
- picture->flags |= GST_VAAPI_PICTURE_SKIPPED;
+ GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_SKIPPED);
// fall-through
case GST_VC1_PICTURE_TYPE_P:
picture->type = GST_VAAPI_PICTURE_TYPE_P;
- picture->flags |= GST_VAAPI_PICTURE_REFERENCE;
+ GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_REFERENCE);
break;
case GST_VC1_PICTURE_TYPE_B:
picture->type = GST_VAAPI_PICTURE_TYPE_B;
@@ -976,7 +958,7 @@ decode_frame(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu)
/* Update reference pictures */
if (GST_VAAPI_PICTURE_IS_REFERENCE(picture)) {
if (priv->prev_picture) {
- gst_vaapi_decoder_free_picture(base_decoder, priv->prev_picture);
+ gst_vaapi_picture_unref(priv->prev_picture);
priv->prev_picture = NULL;
}
if (priv->next_picture) {
@@ -990,9 +972,9 @@ decode_frame(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu)
if (!fill_picture(decoder, picture))
return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
- slice = gst_vaapi_decoder_new_slice(
- base_decoder,
- picture,
+ slice = GST_VAAPI_SLICE_NEW(
+ VC1,
+ decoder,
ebdu->data + ebdu->sc_offset,
ebdu->size + ebdu->offset - ebdu->sc_offset
);
@@ -1000,6 +982,7 @@ decode_frame(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu)
GST_DEBUG("failed to allocate slice");
return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
}
+ gst_vaapi_picture_add_slice(picture, slice);
/* Fill in VASliceParameterBufferVC1 */
slice_param = slice->param;
@@ -1351,14 +1334,6 @@ gst_vaapi_decoder_vc1_new(GstVaapiDisplay *display, GstCaps *caps)
{
GstVaapiDecoderVC1 *decoder;
- static const GstVaapiCodecInfo codec_info = {
- .pic_size = sizeof(GstVaapiPicture),
- .slice_size = sizeof(GstVaapiSlice),
- .pic_param_size = sizeof(VAPictureParameterBufferVC1),
- .slice_param_size = sizeof(VASliceParameterBufferVC1),
- .iq_matrix_size = 0,
- };
-
g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL);
g_return_val_if_fail(GST_IS_CAPS(caps), NULL);
@@ -1366,7 +1341,6 @@ gst_vaapi_decoder_vc1_new(GstVaapiDisplay *display, GstCaps *caps)
GST_VAAPI_TYPE_DECODER_VC1,
"display", display,
"caps", caps,
- "codec-info", &codec_info,
NULL
);
if (!decoder->priv->is_constructed) {