From e5d12e885315fc2a5db806ec5a8d92f9ab3ea809 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 26 Jan 2012 09:48:11 +0100 Subject: [PATCH] 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. --- gst-libs/gst/vaapi/Makefile.am | 6 + gst-libs/gst/vaapi/gstvaapicodec_objects.c | 250 +++++++++++++ gst-libs/gst/vaapi/gstvaapicodec_objects.h | 323 ++++++++++++++++ gst-libs/gst/vaapi/gstvaapidecoder.c | 373 ------------------- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 55 +-- gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c | 60 +-- gst-libs/gst/vaapi/gstvaapidecoder_objects.c | 326 ++++++++++++++++ gst-libs/gst/vaapi/gstvaapidecoder_objects.h | 253 +++++++++++++ gst-libs/gst/vaapi/gstvaapidecoder_priv.h | 116 ------ gst-libs/gst/vaapi/gstvaapidecoder_vc1.c | 62 +-- 10 files changed, 1204 insertions(+), 620 deletions(-) create mode 100644 gst-libs/gst/vaapi/gstvaapicodec_objects.c create mode 100644 gst-libs/gst/vaapi/gstvaapicodec_objects.h create mode 100644 gst-libs/gst/vaapi/gstvaapidecoder_objects.c create mode 100644 gst-libs/gst/vaapi/gstvaapidecoder_objects.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index 68c76dbcf9..b2cd2ccc6b 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 0000000000..7af2dd9579 --- /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 +#include +#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 0000000000..7577ba6ac7 --- /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 +#include + +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 b896847dc1..e0d1b7b209 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -26,7 +26,6 @@ */ #include "config.h" -#include #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 e70c6357a0..33edc0f3de 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -29,6 +29,7 @@ #include #include #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 0c4d969fde..a81f19b790 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c @@ -29,6 +29,7 @@ #include #include #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 0000000000..61ff4e6b19 --- /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 +#include +#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 0000000000..2bd1ea9879 --- /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 + +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 2d6d55d6a5..27efee1144 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 0bf52371fe..9f4e6c9e87 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c @@ -28,6 +28,7 @@ #include #include #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) {