mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 06:54:49 +00:00
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.
This commit is contained in:
parent
dbba1f6107
commit
e5d12e8853
10 changed files with 1204 additions and 620 deletions
|
@ -145,8 +145,10 @@ endif
|
||||||
|
|
||||||
if USE_CODEC_PARSERS
|
if USE_CODEC_PARSERS
|
||||||
libgstvaapi_source_c += \
|
libgstvaapi_source_c += \
|
||||||
|
gstvaapicodec_objects.c \
|
||||||
gstvaapidecoder_mpeg2.c \
|
gstvaapidecoder_mpeg2.c \
|
||||||
gstvaapidecoder_mpeg4.c \
|
gstvaapidecoder_mpeg4.c \
|
||||||
|
gstvaapidecoder_objects.c \
|
||||||
gstvaapidecoder_vc1.c \
|
gstvaapidecoder_vc1.c \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
libgstvaapi_source_h += \
|
libgstvaapi_source_h += \
|
||||||
|
@ -154,6 +156,10 @@ libgstvaapi_source_h += \
|
||||||
gstvaapidecoder_mpeg4.h \
|
gstvaapidecoder_mpeg4.h \
|
||||||
gstvaapidecoder_vc1.h \
|
gstvaapidecoder_vc1.h \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
libgstvaapi_source_priv_h += \
|
||||||
|
gstvaapicodec_objects.h \
|
||||||
|
gstvaapidecoder_objects.h \
|
||||||
|
$(NULL)
|
||||||
libgstvaapi_cflags += $(GST_CODEC_PARSERS_CFLAGS)
|
libgstvaapi_cflags += $(GST_CODEC_PARSERS_CFLAGS)
|
||||||
libgstvaapi_libs += $(GST_CODEC_PARSERS_LIBS)
|
libgstvaapi_libs += $(GST_CODEC_PARSERS_LIBS)
|
||||||
endif
|
endif
|
||||||
|
|
250
gst-libs/gst/vaapi/gstvaapicodec_objects.c
Normal file
250
gst-libs/gst/vaapi/gstvaapicodec_objects.c
Normal file
|
@ -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);
|
||||||
|
}
|
323
gst-libs/gst/vaapi/gstvaapicodec_objects.h
Normal file
323
gst-libs/gst/vaapi/gstvaapicodec_objects.h
Normal file
|
@ -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 */
|
|
@ -26,7 +26,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include <string.h>
|
|
||||||
#include "gstvaapicompat.h"
|
#include "gstvaapicompat.h"
|
||||||
#include "gstvaapidecoder.h"
|
#include "gstvaapidecoder.h"
|
||||||
#include "gstvaapidecoder_priv.h"
|
#include "gstvaapidecoder_priv.h"
|
||||||
|
@ -43,7 +42,6 @@ enum {
|
||||||
|
|
||||||
PROP_DISPLAY,
|
PROP_DISPLAY,
|
||||||
PROP_CAPS,
|
PROP_CAPS,
|
||||||
PROP_CODEC_INFO,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -202,20 +200,6 @@ set_caps(GstVaapiDecoder *decoder, GstCaps *caps)
|
||||||
set_codec_data(decoder, gst_value_get_buffer(v_codec_data));
|
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
|
static void
|
||||||
clear_queue(GQueue *q, GDestroyNotify destroy)
|
clear_queue(GQueue *q, GDestroyNotify destroy)
|
||||||
{
|
{
|
||||||
|
@ -285,9 +269,6 @@ gst_vaapi_decoder_set_property(
|
||||||
case PROP_CAPS:
|
case PROP_CAPS:
|
||||||
set_caps(decoder, g_value_get_pointer(value));
|
set_caps(decoder, g_value_get_pointer(value));
|
||||||
break;
|
break;
|
||||||
case PROP_CODEC_INFO:
|
|
||||||
set_codec_info(decoder, g_value_get_pointer(value));
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
@ -349,14 +330,6 @@ gst_vaapi_decoder_class_init(GstVaapiDecoderClass *klass)
|
||||||
"Decoder caps",
|
"Decoder caps",
|
||||||
"The decoder caps",
|
"The decoder caps",
|
||||||
G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
|
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
|
static void
|
||||||
|
@ -611,349 +584,3 @@ gst_vaapi_decoder_push_surface_proxy(
|
||||||
{
|
{
|
||||||
return push_surface(decoder, g_object_ref(proxy), timestamp);
|
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;
|
|
||||||
}
|
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include <gst/base/gstbitreader.h>
|
#include <gst/base/gstbitreader.h>
|
||||||
#include <gst/codecparsers/gstmpegvideoparser.h>
|
#include <gst/codecparsers/gstmpegvideoparser.h>
|
||||||
#include "gstvaapidecoder_mpeg2.h"
|
#include "gstvaapidecoder_mpeg2.h"
|
||||||
|
#include "gstvaapidecoder_objects.h"
|
||||||
#include "gstvaapidecoder_priv.h"
|
#include "gstvaapidecoder_priv.h"
|
||||||
#include "gstvaapidisplay_priv.h"
|
#include "gstvaapidisplay_priv.h"
|
||||||
#include "gstvaapiobject_priv.h"
|
#include "gstvaapiobject_priv.h"
|
||||||
|
@ -91,23 +92,11 @@ struct _GstVaapiDecoderMpeg2Private {
|
||||||
static void
|
static void
|
||||||
gst_vaapi_decoder_mpeg2_close(GstVaapiDecoderMpeg2 *decoder)
|
gst_vaapi_decoder_mpeg2_close(GstVaapiDecoderMpeg2 *decoder)
|
||||||
{
|
{
|
||||||
GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder);
|
|
||||||
GstVaapiDecoderMpeg2Private * const priv = decoder->priv;
|
GstVaapiDecoderMpeg2Private * const priv = decoder->priv;
|
||||||
|
|
||||||
if (priv->current_picture) {
|
gst_vaapi_picture_replace(&priv->current_picture, NULL);
|
||||||
gst_vaapi_decoder_free_picture(base_decoder, priv->current_picture);
|
gst_vaapi_picture_replace(&priv->next_picture, NULL);
|
||||||
priv->current_picture = NULL;
|
gst_vaapi_picture_replace(&priv->prev_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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (priv->sub_buffer) {
|
if (priv->sub_buffer) {
|
||||||
gst_buffer_unref(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;
|
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) {
|
if (!picture->iq_matrix) {
|
||||||
GST_DEBUG("failed to allocate IQ matrix");
|
GST_DEBUG("failed to allocate IQ matrix");
|
||||||
return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
|
return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
|
||||||
|
@ -266,11 +255,7 @@ ensure_quant_matrix(GstVaapiDecoderMpeg2 *decoder, GstVaapiPicture *picture)
|
||||||
static inline GstVaapiDecoderStatus
|
static inline GstVaapiDecoderStatus
|
||||||
render_picture(GstVaapiDecoderMpeg2 *decoder, GstVaapiPicture *picture)
|
render_picture(GstVaapiDecoderMpeg2 *decoder, GstVaapiPicture *picture)
|
||||||
{
|
{
|
||||||
GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder);
|
if (!gst_vaapi_picture_output(picture))
|
||||||
|
|
||||||
if (!gst_vaapi_decoder_push_surface(base_decoder,
|
|
||||||
picture->surface,
|
|
||||||
picture->pts))
|
|
||||||
return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
|
return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
|
||||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -278,19 +263,18 @@ render_picture(GstVaapiDecoderMpeg2 *decoder, GstVaapiPicture *picture)
|
||||||
static GstVaapiDecoderStatus
|
static GstVaapiDecoderStatus
|
||||||
decode_current_picture(GstVaapiDecoderMpeg2 *decoder)
|
decode_current_picture(GstVaapiDecoderMpeg2 *decoder)
|
||||||
{
|
{
|
||||||
GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder);
|
|
||||||
GstVaapiDecoderMpeg2Private * const priv = decoder->priv;
|
GstVaapiDecoderMpeg2Private * const priv = decoder->priv;
|
||||||
GstVaapiPicture * const picture = priv->current_picture;
|
GstVaapiPicture * const picture = priv->current_picture;
|
||||||
GstVaapiDecoderStatus status = GST_VAAPI_DECODER_STATUS_SUCCESS;
|
GstVaapiDecoderStatus status = GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||||
|
|
||||||
if (picture) {
|
if (picture) {
|
||||||
if (!gst_vaapi_decoder_decode_picture(base_decoder, picture))
|
if (!gst_vaapi_picture_decode(picture))
|
||||||
status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
|
status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
|
||||||
if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture)) {
|
if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture)) {
|
||||||
if ((priv->prev_picture && priv->next_picture) ||
|
if ((priv->prev_picture && priv->next_picture) ||
|
||||||
(priv->closed_gop && priv->next_picture))
|
(priv->closed_gop && priv->next_picture))
|
||||||
status = render_picture(decoder, picture);
|
status = render_picture(decoder, picture);
|
||||||
gst_vaapi_decoder_free_picture(base_decoder, picture);
|
gst_vaapi_picture_unref(picture);
|
||||||
}
|
}
|
||||||
priv->current_picture = NULL;
|
priv->current_picture = NULL;
|
||||||
}
|
}
|
||||||
|
@ -448,7 +432,6 @@ decode_gop(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size)
|
||||||
static GstVaapiDecoderStatus
|
static GstVaapiDecoderStatus
|
||||||
decode_picture(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size)
|
decode_picture(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size)
|
||||||
{
|
{
|
||||||
GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder);
|
|
||||||
GstVaapiDecoderMpeg2Private * const priv = decoder->priv;
|
GstVaapiDecoderMpeg2Private * const priv = decoder->priv;
|
||||||
GstMpegVideoPictureHdr * const pic_hdr = &priv->pic_hdr;
|
GstMpegVideoPictureHdr * const pic_hdr = &priv->pic_hdr;
|
||||||
GstVaapiPicture *picture;
|
GstVaapiPicture *picture;
|
||||||
|
@ -467,7 +450,7 @@ decode_picture(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size)
|
||||||
return status;
|
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) {
|
if (!priv->current_picture) {
|
||||||
GST_DEBUG("failed to allocate picture");
|
GST_DEBUG("failed to allocate picture");
|
||||||
return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
|
return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
|
||||||
|
@ -510,9 +493,9 @@ decode_picture(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size)
|
||||||
|
|
||||||
/* Update reference pictures */
|
/* Update reference pictures */
|
||||||
if (pic_hdr->pic_type != GST_MPEG_VIDEO_PICTURE_TYPE_B) {
|
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) {
|
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;
|
priv->prev_picture = NULL;
|
||||||
}
|
}
|
||||||
if (priv->next_picture) {
|
if (priv->next_picture) {
|
||||||
|
@ -626,15 +609,12 @@ decode_slice(
|
||||||
|
|
||||||
priv->mb_y = slice_no;
|
priv->mb_y = slice_no;
|
||||||
|
|
||||||
slice = gst_vaapi_decoder_new_slice(
|
slice = GST_VAAPI_SLICE_NEW(MPEG2, decoder, buf, buf_size);
|
||||||
GST_VAAPI_DECODER(decoder),
|
|
||||||
picture,
|
|
||||||
buf, buf_size
|
|
||||||
);
|
|
||||||
if (!slice) {
|
if (!slice) {
|
||||||
GST_DEBUG("failed to allocate slice");
|
GST_DEBUG("failed to allocate slice");
|
||||||
return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
|
return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
|
||||||
}
|
}
|
||||||
|
gst_vaapi_picture_add_slice(picture, slice);
|
||||||
|
|
||||||
/* Parse slice */
|
/* Parse slice */
|
||||||
gst_bit_reader_init(&br, buf, buf_size);
|
gst_bit_reader_init(&br, buf, buf_size);
|
||||||
|
@ -911,14 +891,6 @@ gst_vaapi_decoder_mpeg2_new(GstVaapiDisplay *display, GstCaps *caps)
|
||||||
{
|
{
|
||||||
GstVaapiDecoderMpeg2 *decoder;
|
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_VAAPI_IS_DISPLAY(display), NULL);
|
||||||
g_return_val_if_fail(GST_IS_CAPS(caps), 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,
|
GST_VAAPI_TYPE_DECODER_MPEG2,
|
||||||
"display", display,
|
"display", display,
|
||||||
"caps", caps,
|
"caps", caps,
|
||||||
"codec-info", &codec_info,
|
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
if (!decoder->priv->is_constructed) {
|
if (!decoder->priv->is_constructed) {
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include <gst/base/gstbitreader.h>
|
#include <gst/base/gstbitreader.h>
|
||||||
#include <gst/codecparsers/gstmpeg4parser.h>
|
#include <gst/codecparsers/gstmpeg4parser.h>
|
||||||
#include "gstvaapidecoder_mpeg4.h"
|
#include "gstvaapidecoder_mpeg4.h"
|
||||||
|
#include "gstvaapidecoder_objects.h"
|
||||||
#include "gstvaapidecoder_priv.h"
|
#include "gstvaapidecoder_priv.h"
|
||||||
#include "gstvaapidisplay_priv.h"
|
#include "gstvaapidisplay_priv.h"
|
||||||
#include "gstvaapiobject_priv.h"
|
#include "gstvaapiobject_priv.h"
|
||||||
|
@ -95,23 +96,11 @@ struct _GstVaapiDecoderMpeg4Private {
|
||||||
static void
|
static void
|
||||||
gst_vaapi_decoder_mpeg4_close(GstVaapiDecoderMpeg4 *decoder)
|
gst_vaapi_decoder_mpeg4_close(GstVaapiDecoderMpeg4 *decoder)
|
||||||
{
|
{
|
||||||
GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder);
|
|
||||||
GstVaapiDecoderMpeg4Private * const priv = decoder->priv;
|
GstVaapiDecoderMpeg4Private * const priv = decoder->priv;
|
||||||
|
|
||||||
if (priv->curr_picture) {
|
gst_vaapi_picture_replace(&priv->curr_picture, NULL);
|
||||||
gst_vaapi_decoder_free_picture(base_decoder, priv->curr_picture);
|
gst_vaapi_picture_replace(&priv->next_picture, NULL);
|
||||||
priv->curr_picture = NULL;
|
gst_vaapi_picture_replace(&priv->prev_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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (priv->sub_buffer) {
|
if (priv->sub_buffer) {
|
||||||
gst_buffer_unref(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;
|
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) {
|
if (!picture->iq_matrix) {
|
||||||
GST_DEBUG("failed to allocate IQ matrix");
|
GST_DEBUG("failed to allocate IQ matrix");
|
||||||
return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
|
return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
|
||||||
|
@ -261,11 +250,7 @@ ensure_quant_matrix(GstVaapiDecoderMpeg4 *decoder, GstVaapiPicture *picture)
|
||||||
static inline GstVaapiDecoderStatus
|
static inline GstVaapiDecoderStatus
|
||||||
render_picture(GstVaapiDecoderMpeg4 *decoder, GstVaapiPicture *picture)
|
render_picture(GstVaapiDecoderMpeg4 *decoder, GstVaapiPicture *picture)
|
||||||
{
|
{
|
||||||
GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder);
|
if (!gst_vaapi_picture_output(picture))
|
||||||
|
|
||||||
if (!gst_vaapi_decoder_push_surface(base_decoder,
|
|
||||||
picture->surface,
|
|
||||||
picture->pts))
|
|
||||||
return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
|
return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
|
||||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -277,19 +262,18 @@ render_picture(GstVaapiDecoderMpeg4 *decoder, GstVaapiPicture *picture)
|
||||||
static GstVaapiDecoderStatus
|
static GstVaapiDecoderStatus
|
||||||
decode_current_picture(GstVaapiDecoderMpeg4 *decoder)
|
decode_current_picture(GstVaapiDecoderMpeg4 *decoder)
|
||||||
{
|
{
|
||||||
GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder);
|
|
||||||
GstVaapiDecoderMpeg4Private * const priv = decoder->priv;
|
GstVaapiDecoderMpeg4Private * const priv = decoder->priv;
|
||||||
GstVaapiPicture * const picture = priv->curr_picture;
|
GstVaapiPicture * const picture = priv->curr_picture;
|
||||||
GstVaapiDecoderStatus status = GST_VAAPI_DECODER_STATUS_SUCCESS;
|
GstVaapiDecoderStatus status = GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||||
|
|
||||||
if (picture) {
|
if (picture) {
|
||||||
if (!gst_vaapi_decoder_decode_picture(base_decoder, picture))
|
if (!gst_vaapi_picture_decode(picture))
|
||||||
status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
|
status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
|
||||||
if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture)) {
|
if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture)) {
|
||||||
if ((priv->prev_picture && priv->next_picture) ||
|
if ((priv->prev_picture && priv->next_picture) ||
|
||||||
(priv->closed_gop && priv->next_picture))
|
(priv->closed_gop && priv->next_picture))
|
||||||
status = render_picture(decoder, picture);
|
status = render_picture(decoder, picture);
|
||||||
gst_vaapi_decoder_free_picture(base_decoder, picture);
|
gst_vaapi_picture_unref(picture);
|
||||||
}
|
}
|
||||||
priv->curr_picture = NULL;
|
priv->curr_picture = NULL;
|
||||||
}
|
}
|
||||||
|
@ -448,7 +432,6 @@ static GstVaapiDecoderStatus
|
||||||
decode_picture(GstVaapiDecoderMpeg4 *decoder, const guint8 *buf, guint buf_size)
|
decode_picture(GstVaapiDecoderMpeg4 *decoder, const guint8 *buf, guint buf_size)
|
||||||
{
|
{
|
||||||
GstMpeg4ParseResult parser_result = GST_MPEG4_PARSER_OK;
|
GstMpeg4ParseResult parser_result = GST_MPEG4_PARSER_OK;
|
||||||
GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder);
|
|
||||||
GstVaapiDecoderMpeg4Private * const priv = decoder->priv;
|
GstVaapiDecoderMpeg4Private * const priv = decoder->priv;
|
||||||
GstMpeg4VideoObjectPlane * const vop_hdr = &priv->vop_hdr;
|
GstMpeg4VideoObjectPlane * const vop_hdr = &priv->vop_hdr;
|
||||||
GstMpeg4VideoObjectLayer * const vol_hdr = &priv->vol_hdr;
|
GstMpeg4VideoObjectLayer * const vol_hdr = &priv->vol_hdr;
|
||||||
|
@ -496,7 +479,7 @@ decode_picture(GstVaapiDecoderMpeg4 *decoder, const guint8 *buf, guint buf_size)
|
||||||
return status;
|
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) {
|
if (!priv->curr_picture) {
|
||||||
GST_DEBUG("failed to allocate picture");
|
GST_DEBUG("failed to allocate picture");
|
||||||
return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
|
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:
|
case GST_MPEG4_I_VOP:
|
||||||
picture->type = GST_VAAPI_PICTURE_TYPE_I;
|
picture->type = GST_VAAPI_PICTURE_TYPE_I;
|
||||||
if (priv->is_svh || vop_hdr->coded)
|
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;
|
break;
|
||||||
case GST_MPEG4_P_VOP:
|
case GST_MPEG4_P_VOP:
|
||||||
picture->type = GST_VAAPI_PICTURE_TYPE_P;
|
picture->type = GST_VAAPI_PICTURE_TYPE_P;
|
||||||
if (priv->is_svh || vop_hdr->coded)
|
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;
|
break;
|
||||||
case GST_MPEG4_B_VOP:
|
case GST_MPEG4_B_VOP:
|
||||||
picture->type = GST_VAAPI_PICTURE_TYPE_B;
|
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;
|
picture->type = GST_VAAPI_PICTURE_TYPE_S;
|
||||||
// see 3.175 reference VOP
|
// see 3.175 reference VOP
|
||||||
if (vop_hdr->coded)
|
if (vop_hdr->coded)
|
||||||
picture->flags |= GST_VAAPI_PICTURE_REFERENCE;
|
GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_REFERENCE);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
GST_DEBUG("unsupported picture type %d", priv->coding_type);
|
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 */
|
/* Update reference pictures */
|
||||||
/* XXX: consider priv->vol_hdr.low_delay, consider packed video frames for DivX/XviD */
|
/* XXX: consider priv->vol_hdr.low_delay, consider packed video frames for DivX/XviD */
|
||||||
if (GST_VAAPI_PICTURE_IS_REFERENCE(picture)) {
|
if (GST_VAAPI_PICTURE_IS_REFERENCE(picture)) {
|
||||||
picture->flags |= GST_VAAPI_PICTURE_REFERENCE;
|
|
||||||
if (priv->prev_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;
|
priv->prev_picture = NULL;
|
||||||
}
|
}
|
||||||
if (priv->next_picture) {
|
if (priv->next_picture) {
|
||||||
|
@ -712,15 +694,12 @@ decode_slice(
|
||||||
if (!has_packet_header && !fill_picture(decoder, picture))
|
if (!has_packet_header && !fill_picture(decoder, picture))
|
||||||
return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
|
return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
|
||||||
|
|
||||||
slice = gst_vaapi_decoder_new_slice(
|
slice = GST_VAAPI_SLICE_NEW(MPEG4, decoder, buf, buf_size);
|
||||||
GST_VAAPI_DECODER(decoder),
|
|
||||||
picture,
|
|
||||||
(guchar*)buf, buf_size
|
|
||||||
);
|
|
||||||
if (!slice) {
|
if (!slice) {
|
||||||
GST_DEBUG("failed to allocate slice");
|
GST_DEBUG("failed to allocate slice");
|
||||||
return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
|
return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
|
||||||
}
|
}
|
||||||
|
gst_vaapi_picture_add_slice(picture, slice);
|
||||||
|
|
||||||
/* Fill in VASliceParameterBufferMPEG4 */
|
/* Fill in VASliceParameterBufferMPEG4 */
|
||||||
slice_param = slice->param;
|
slice_param = slice->param;
|
||||||
|
@ -1085,14 +1064,6 @@ gst_vaapi_decoder_mpeg4_new(GstVaapiDisplay *display, GstCaps *caps)
|
||||||
{
|
{
|
||||||
GstVaapiDecoderMpeg4 *decoder;
|
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_VAAPI_IS_DISPLAY(display), NULL);
|
||||||
g_return_val_if_fail(GST_IS_CAPS(caps), 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,
|
GST_VAAPI_TYPE_DECODER_MPEG4,
|
||||||
"display", display,
|
"display", display,
|
||||||
"caps", caps,
|
"caps", caps,
|
||||||
"codec-info", &codec_info,
|
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
if (!decoder->priv->is_constructed) {
|
if (!decoder->priv->is_constructed) {
|
||||||
|
|
326
gst-libs/gst/vaapi/gstvaapidecoder_objects.c
Normal file
326
gst-libs/gst/vaapi/gstvaapidecoder_objects.c
Normal file
|
@ -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);
|
||||||
|
}
|
253
gst-libs/gst/vaapi/gstvaapidecoder_objects.h
Normal file
253
gst-libs/gst/vaapi/gstvaapidecoder_objects.h
Normal file
|
@ -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 */
|
|
@ -109,73 +109,6 @@ G_BEGIN_DECLS
|
||||||
GST_VAAPI_TYPE_DECODER, \
|
GST_VAAPI_TYPE_DECODER, \
|
||||||
GstVaapiDecoderPrivate))
|
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 {
|
struct _GstVaapiDecoderPrivate {
|
||||||
GstVaapiDisplay *display;
|
GstVaapiDisplay *display;
|
||||||
VADisplay va_display;
|
VADisplay va_display;
|
||||||
|
@ -184,7 +117,6 @@ struct _GstVaapiDecoderPrivate {
|
||||||
GstCaps *caps;
|
GstCaps *caps;
|
||||||
GstVaapiCodec codec;
|
GstVaapiCodec codec;
|
||||||
GstBuffer *codec_data;
|
GstBuffer *codec_data;
|
||||||
GstVaapiCodecInfo codec_info;
|
|
||||||
guint width;
|
guint width;
|
||||||
guint height;
|
guint height;
|
||||||
guint fps_n;
|
guint fps_n;
|
||||||
|
@ -247,54 +179,6 @@ gst_vaapi_decoder_push_surface_proxy(
|
||||||
GstClockTime timestamp
|
GstClockTime timestamp
|
||||||
) attribute_hidden;
|
) 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
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* GST_VAAPI_DECODER_PRIV_H */
|
#endif /* GST_VAAPI_DECODER_PRIV_H */
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <gst/codecparsers/gstvc1parser.h>
|
#include <gst/codecparsers/gstvc1parser.h>
|
||||||
#include "gstvaapidecoder_vc1.h"
|
#include "gstvaapidecoder_vc1.h"
|
||||||
|
#include "gstvaapidecoder_objects.h"
|
||||||
#include "gstvaapidecoder_priv.h"
|
#include "gstvaapidecoder_priv.h"
|
||||||
#include "gstvaapidisplay_priv.h"
|
#include "gstvaapidisplay_priv.h"
|
||||||
#include "gstvaapiobject_priv.h"
|
#include "gstvaapiobject_priv.h"
|
||||||
|
@ -96,23 +97,11 @@ get_status(GstVC1ParserResult result)
|
||||||
static void
|
static void
|
||||||
gst_vaapi_decoder_vc1_close(GstVaapiDecoderVC1 *decoder)
|
gst_vaapi_decoder_vc1_close(GstVaapiDecoderVC1 *decoder)
|
||||||
{
|
{
|
||||||
GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder);
|
|
||||||
GstVaapiDecoderVC1Private * const priv = decoder->priv;
|
GstVaapiDecoderVC1Private * const priv = decoder->priv;
|
||||||
|
|
||||||
if (priv->current_picture) {
|
gst_vaapi_picture_replace(&priv->current_picture, NULL);
|
||||||
gst_vaapi_decoder_free_picture(base_decoder, priv->current_picture);
|
gst_vaapi_picture_replace(&priv->next_picture, NULL);
|
||||||
priv->current_picture = NULL;
|
gst_vaapi_picture_replace(&priv->prev_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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (priv->sub_buffer) {
|
if (priv->sub_buffer) {
|
||||||
gst_buffer_unref(priv->sub_buffer);
|
gst_buffer_unref(priv->sub_buffer);
|
||||||
|
@ -220,11 +209,7 @@ ensure_context(GstVaapiDecoderVC1 *decoder)
|
||||||
static inline GstVaapiDecoderStatus
|
static inline GstVaapiDecoderStatus
|
||||||
render_picture(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture)
|
render_picture(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture)
|
||||||
{
|
{
|
||||||
GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder);
|
if (!gst_vaapi_picture_output(picture))
|
||||||
|
|
||||||
if (!gst_vaapi_decoder_push_surface(base_decoder,
|
|
||||||
picture->surface,
|
|
||||||
picture->pts))
|
|
||||||
return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
|
return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
|
||||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -232,18 +217,17 @@ render_picture(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture)
|
||||||
static GstVaapiDecoderStatus
|
static GstVaapiDecoderStatus
|
||||||
decode_current_picture(GstVaapiDecoderVC1 *decoder)
|
decode_current_picture(GstVaapiDecoderVC1 *decoder)
|
||||||
{
|
{
|
||||||
GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder);
|
|
||||||
GstVaapiDecoderVC1Private * const priv = decoder->priv;
|
GstVaapiDecoderVC1Private * const priv = decoder->priv;
|
||||||
GstVaapiPicture * const picture = priv->current_picture;
|
GstVaapiPicture * const picture = priv->current_picture;
|
||||||
GstVaapiDecoderStatus status = GST_VAAPI_DECODER_STATUS_SUCCESS;
|
GstVaapiDecoderStatus status = GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||||
|
|
||||||
if (picture) {
|
if (picture) {
|
||||||
if (!gst_vaapi_decoder_decode_picture(base_decoder, picture))
|
if (!gst_vaapi_picture_decode(picture))
|
||||||
status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
|
status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
|
||||||
if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture)) {
|
if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture)) {
|
||||||
if (priv->prev_picture && priv->next_picture)
|
if (priv->prev_picture && priv->next_picture)
|
||||||
status = render_picture(decoder, picture);
|
status = render_picture(decoder, picture);
|
||||||
gst_vaapi_decoder_free_picture(base_decoder, picture);
|
gst_vaapi_picture_unref(picture);
|
||||||
}
|
}
|
||||||
priv->current_picture = NULL;
|
priv->current_picture = NULL;
|
||||||
}
|
}
|
||||||
|
@ -788,7 +772,6 @@ fill_picture_advanced(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture)
|
||||||
static gboolean
|
static gboolean
|
||||||
fill_picture(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture)
|
fill_picture(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture)
|
||||||
{
|
{
|
||||||
GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder);
|
|
||||||
GstVaapiDecoderVC1Private * const priv = decoder->priv;
|
GstVaapiDecoderVC1Private * const priv = decoder->priv;
|
||||||
VAPictureParameterBufferVC1 * const pic_param = picture->param;
|
VAPictureParameterBufferVC1 * const pic_param = picture->param;
|
||||||
GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
|
GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
|
||||||
|
@ -878,8 +861,8 @@ fill_picture(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
picture->bitplane = gst_vaapi_decoder_new_bitplane(
|
picture->bitplane = GST_VAAPI_BITPLANE_NEW(
|
||||||
base_decoder,
|
decoder,
|
||||||
(seq_hdr->mb_width * seq_hdr->mb_height + 1) / 2
|
(seq_hdr->mb_width * seq_hdr->mb_height + 1) / 2
|
||||||
);
|
);
|
||||||
if (!picture->bitplane)
|
if (!picture->bitplane)
|
||||||
|
@ -898,7 +881,6 @@ fill_picture(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture)
|
||||||
static GstVaapiDecoderStatus
|
static GstVaapiDecoderStatus
|
||||||
decode_frame(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu)
|
decode_frame(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu)
|
||||||
{
|
{
|
||||||
GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder);
|
|
||||||
GstVaapiDecoderVC1Private * const priv = decoder->priv;
|
GstVaapiDecoderVC1Private * const priv = decoder->priv;
|
||||||
GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
|
GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
|
||||||
GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr;
|
GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr;
|
||||||
|
@ -921,7 +903,7 @@ decode_frame(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu)
|
||||||
return status;
|
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) {
|
if (!priv->current_picture) {
|
||||||
GST_DEBUG("failed to allocate picture");
|
GST_DEBUG("failed to allocate picture");
|
||||||
return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
|
return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
|
||||||
|
@ -949,14 +931,14 @@ decode_frame(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu)
|
||||||
switch (frame_hdr->ptype) {
|
switch (frame_hdr->ptype) {
|
||||||
case GST_VC1_PICTURE_TYPE_I:
|
case GST_VC1_PICTURE_TYPE_I:
|
||||||
picture->type = GST_VAAPI_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;
|
break;
|
||||||
case GST_VC1_PICTURE_TYPE_SKIPPED:
|
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
|
// fall-through
|
||||||
case GST_VC1_PICTURE_TYPE_P:
|
case GST_VC1_PICTURE_TYPE_P:
|
||||||
picture->type = GST_VAAPI_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;
|
break;
|
||||||
case GST_VC1_PICTURE_TYPE_B:
|
case GST_VC1_PICTURE_TYPE_B:
|
||||||
picture->type = GST_VAAPI_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 */
|
/* Update reference pictures */
|
||||||
if (GST_VAAPI_PICTURE_IS_REFERENCE(picture)) {
|
if (GST_VAAPI_PICTURE_IS_REFERENCE(picture)) {
|
||||||
if (priv->prev_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;
|
priv->prev_picture = NULL;
|
||||||
}
|
}
|
||||||
if (priv->next_picture) {
|
if (priv->next_picture) {
|
||||||
|
@ -990,9 +972,9 @@ decode_frame(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu)
|
||||||
if (!fill_picture(decoder, picture))
|
if (!fill_picture(decoder, picture))
|
||||||
return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
|
return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
|
||||||
|
|
||||||
slice = gst_vaapi_decoder_new_slice(
|
slice = GST_VAAPI_SLICE_NEW(
|
||||||
base_decoder,
|
VC1,
|
||||||
picture,
|
decoder,
|
||||||
ebdu->data + ebdu->sc_offset,
|
ebdu->data + ebdu->sc_offset,
|
||||||
ebdu->size + ebdu->offset - 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");
|
GST_DEBUG("failed to allocate slice");
|
||||||
return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
|
return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
|
||||||
}
|
}
|
||||||
|
gst_vaapi_picture_add_slice(picture, slice);
|
||||||
|
|
||||||
/* Fill in VASliceParameterBufferVC1 */
|
/* Fill in VASliceParameterBufferVC1 */
|
||||||
slice_param = slice->param;
|
slice_param = slice->param;
|
||||||
|
@ -1351,14 +1334,6 @@ gst_vaapi_decoder_vc1_new(GstVaapiDisplay *display, GstCaps *caps)
|
||||||
{
|
{
|
||||||
GstVaapiDecoderVC1 *decoder;
|
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_VAAPI_IS_DISPLAY(display), NULL);
|
||||||
g_return_val_if_fail(GST_IS_CAPS(caps), 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,
|
GST_VAAPI_TYPE_DECODER_VC1,
|
||||||
"display", display,
|
"display", display,
|
||||||
"caps", caps,
|
"caps", caps,
|
||||||
"codec-info", &codec_info,
|
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
if (!decoder->priv->is_constructed) {
|
if (!decoder->priv->is_constructed) {
|
||||||
|
|
Loading…
Reference in a new issue