libs: use GstVaapiMiniObject for video decoders.

Port GstVaapiDecoder and GstVaapiDecoder{MPEG2,MPEG4,JPEG,H264,VC1} to
GstVaapiMiniObject. Add gst_vaapi_decoder_set_codec_state_changed_func()
helper function to let the user add a callback to a function triggered
whenever the codec state (e.g. caps) changes.
This commit is contained in:
Gwenole Beauchesne 2013-05-06 14:07:17 +02:00
parent 2e6ff64a34
commit 3cc7b26961
15 changed files with 709 additions and 1023 deletions

View file

@ -96,8 +96,8 @@ gst_vaapi_codec_object_new(const GstVaapiCodecObjectClass *object_class,
}
#define GET_DECODER(obj) GST_VAAPI_DECODER_CAST((obj)->parent_instance.codec)
#define GET_VA_DISPLAY(obj) GET_DECODER(obj)->priv->va_display
#define GET_VA_CONTEXT(obj) GET_DECODER(obj)->priv->va_context
#define GET_VA_DISPLAY(obj) GET_DECODER(obj)->va_display
#define GET_VA_CONTEXT(obj) GET_DECODER(obj)->va_context
/* ------------------------------------------------------------------------- */
/* --- Inverse Quantization Matrices --- */

View file

@ -32,24 +32,10 @@
#include "gstvaapiparser_frame.h"
#include "gstvaapisurfaceproxy_priv.h"
#include "gstvaapiutils.h"
#include "gstvaapi_priv.h"
#define DEBUG 1
#include "gstvaapidebug.h"
G_DEFINE_TYPE(GstVaapiDecoder, gst_vaapi_decoder, G_TYPE_OBJECT)
enum {
PROP_0,
PROP_DISPLAY,
PROP_CAPS,
N_PROPERTIES
};
static GParamSpec *g_properties[N_PROPERTIES] = { NULL, };
static void
drop_frame(GstVaapiDecoder *decoder, GstVideoCodecFrame *frame);
@ -77,6 +63,8 @@ parser_state_finalize(GstVaapiParserState *ps)
static gboolean
parser_state_init(GstVaapiParserState *ps)
{
memset(ps, 0, sizeof(*ps));
ps->input_adapter = gst_adapter_new();
if (!ps->input_adapter)
return FALSE;
@ -103,8 +91,6 @@ reset:
static gboolean
push_buffer(GstVaapiDecoder *decoder, GstBuffer *buffer)
{
GstVaapiDecoderPrivate * const priv = decoder->priv;
if (!buffer) {
buffer = gst_buffer_new();
if (!buffer)
@ -115,17 +101,16 @@ push_buffer(GstVaapiDecoder *decoder, GstBuffer *buffer)
GST_DEBUG("queue encoded data buffer %p (%d bytes)",
buffer, gst_buffer_get_size(buffer));
g_async_queue_push(priv->buffers, buffer);
g_async_queue_push(decoder->buffers, buffer);
return TRUE;
}
static GstBuffer *
pop_buffer(GstVaapiDecoder *decoder)
{
GstVaapiDecoderPrivate * const priv = decoder->priv;
GstBuffer *buffer;
buffer = g_async_queue_try_pop(priv->buffers);
buffer = g_async_queue_try_pop(decoder->buffers);
if (!buffer)
return NULL;
@ -140,8 +125,7 @@ do_parse(GstVaapiDecoder *decoder,
GstVideoCodecFrame *base_frame, GstAdapter *adapter, gboolean at_eos,
guint *got_unit_size_ptr, gboolean *got_frame_ptr)
{
GstVaapiDecoderPrivate * const priv = decoder->priv;
GstVaapiParserState * const ps = &priv->parser_state;
GstVaapiParserState * const ps = &decoder->parser_state;
GstVaapiParserFrame *frame;
GstVaapiDecoderUnit *unit;
GstVaapiDecoderStatus status;
@ -151,7 +135,7 @@ do_parse(GstVaapiDecoder *decoder,
frame = gst_video_codec_frame_get_user_data(base_frame);
if (!frame) {
GstVideoCodecState * const codec_state = priv->codec_state;
GstVideoCodecState * const codec_state = decoder->codec_state;
frame = gst_vaapi_parser_frame_new(codec_state->info.width,
codec_state->info.height);
if (!frame)
@ -261,7 +245,7 @@ do_decode_1(GstVaapiDecoder *decoder, GstVaapiParserFrame *frame)
static inline GstVaapiDecoderStatus
do_decode(GstVaapiDecoder *decoder, GstVideoCodecFrame *base_frame)
{
GstVaapiParserState * const ps = &decoder->priv->parser_state;
GstVaapiParserState * const ps = &decoder->parser_state;
GstVaapiParserFrame * const frame = base_frame->user_data;
GstVaapiDecoderStatus status;
@ -293,8 +277,7 @@ do_flush(GstVaapiDecoder *decoder)
static GstVaapiDecoderStatus
decode_step(GstVaapiDecoder *decoder)
{
GstVaapiDecoderPrivate * const priv = decoder->priv;
GstVaapiParserState * const ps = &priv->parser_state;
GstVaapiParserState * const ps = &decoder->parser_state;
GstVaapiDecoderStatus status;
GstBuffer *buffer;
gboolean got_frame;
@ -370,8 +353,6 @@ decode_step(GstVaapiDecoder *decoder)
static void
drop_frame(GstVaapiDecoder *decoder, GstVideoCodecFrame *frame)
{
GstVaapiDecoderPrivate * const priv = decoder->priv;
GST_DEBUG("drop frame %d", frame->system_frame_number);
/* no surface proxy */
@ -381,32 +362,30 @@ drop_frame(GstVaapiDecoder *decoder, GstVideoCodecFrame *frame)
GST_VIDEO_CODEC_FRAME_FLAG_SET(frame,
GST_VIDEO_CODEC_FRAME_FLAG_DECODE_ONLY);
g_async_queue_push(priv->frames, gst_video_codec_frame_ref(frame));
g_async_queue_push(decoder->frames, gst_video_codec_frame_ref(frame));
}
static inline void
push_frame(GstVaapiDecoder *decoder, GstVideoCodecFrame *frame)
{
GstVaapiDecoderPrivate * const priv = decoder->priv;
GstVaapiSurfaceProxy * const proxy = frame->user_data;
GST_DEBUG("queue decoded surface %" GST_VAAPI_ID_FORMAT,
GST_VAAPI_ID_ARGS(GST_VAAPI_SURFACE_PROXY_SURFACE_ID(proxy)));
g_async_queue_push(priv->frames, gst_video_codec_frame_ref(frame));
g_async_queue_push(decoder->frames, gst_video_codec_frame_ref(frame));
}
static inline GstVideoCodecFrame *
pop_frame(GstVaapiDecoder *decoder, guint64 timeout)
{
GstVaapiDecoderPrivate * const priv = decoder->priv;
GstVideoCodecFrame *frame;
GstVaapiSurfaceProxy *proxy;
if (G_LIKELY(timeout > 0))
frame = g_async_queue_timeout_pop(priv->frames, timeout);
frame = g_async_queue_timeout_pop(decoder->frames, timeout);
else
frame = g_async_queue_try_pop(priv->frames);
frame = g_async_queue_try_pop(decoder->frames);
if (!frame)
return NULL;
@ -417,25 +396,24 @@ pop_frame(GstVaapiDecoder *decoder, guint64 timeout)
return frame;
}
static void
static gboolean
set_caps(GstVaapiDecoder *decoder, const GstCaps *caps)
{
GstVaapiDecoderPrivate * const priv = decoder->priv;
GstVideoCodecState * const codec_state = priv->codec_state;
GstVideoCodecState * const codec_state = decoder->codec_state;
GstStructure * const structure = gst_caps_get_structure(caps, 0);
GstVaapiProfile profile;
const GValue *v_codec_data;
profile = gst_vaapi_profile_from_caps(caps);
if (!profile)
return;
return FALSE;
priv->codec = gst_vaapi_profile_get_codec(profile);
if (!priv->codec)
return;
decoder->codec = gst_vaapi_profile_get_codec(profile);
if (!decoder->codec)
return FALSE;
if (!gst_video_info_from_caps(&codec_state->info, caps))
return;
return FALSE;
codec_state->caps = gst_caps_copy(caps);
@ -443,6 +421,7 @@ set_caps(GstVaapiDecoder *decoder, const GstCaps *caps)
if (v_codec_data)
gst_buffer_replace(&codec_state->codec_data,
gst_value_get_buffer(v_codec_data));
return TRUE;
}
static inline GstCaps *
@ -452,142 +431,181 @@ get_caps(GstVaapiDecoder *decoder)
}
static void
gst_vaapi_decoder_finalize(GObject *object)
notify_codec_state_changed(GstVaapiDecoder *decoder)
{
GstVaapiDecoder * const decoder = GST_VAAPI_DECODER(object);
GstVaapiDecoderPrivate * const priv = decoder->priv;
if (decoder->codec_state_changed_func)
decoder->codec_state_changed_func(decoder, decoder->codec_state,
decoder->codec_state_changed_data);
}
gst_video_codec_state_unref(priv->codec_state);
priv->codec_state = NULL;
void
gst_vaapi_decoder_finalize(GstVaapiDecoder *decoder)
{
const GstVaapiDecoderClass * const klass =
GST_VAAPI_DECODER_GET_CLASS(decoder);
parser_state_finalize(&priv->parser_state);
if (klass->destroy)
klass->destroy(decoder);
gst_video_codec_state_unref(decoder->codec_state);
decoder->codec_state = NULL;
parser_state_finalize(&decoder->parser_state);
if (priv->buffers) {
g_async_queue_unref(priv->buffers);
priv->buffers = NULL;
if (decoder->buffers) {
g_async_queue_unref(decoder->buffers);
decoder->buffers = NULL;
}
if (priv->frames) {
g_async_queue_unref(priv->frames);
priv->frames = NULL;
if (decoder->frames) {
g_async_queue_unref(decoder->frames);
decoder->frames = NULL;
}
gst_vaapi_object_replace(&priv->context, NULL);
priv->va_context = VA_INVALID_ID;
gst_vaapi_object_replace(&decoder->context, NULL);
decoder->va_context = VA_INVALID_ID;
g_clear_object(&priv->display);
priv->va_display = NULL;
G_OBJECT_CLASS(gst_vaapi_decoder_parent_class)->finalize(object);
g_clear_object(&decoder->display);
decoder->va_display = NULL;
}
static void
gst_vaapi_decoder_set_property(
GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec
)
static gboolean
gst_vaapi_decoder_init(GstVaapiDecoder *decoder, GstVaapiDisplay *display,
GstCaps *caps)
{
GstVaapiDecoder * const decoder = GST_VAAPI_DECODER(object);
GstVaapiDecoderPrivate * const priv = decoder->priv;
switch (prop_id) {
case PROP_DISPLAY:
priv->display = g_object_ref(g_value_get_object(value));
if (priv->display)
priv->va_display = gst_vaapi_display_get_display(priv->display);
else
priv->va_display = NULL;
break;
case PROP_CAPS:
set_caps(decoder, g_value_get_pointer(value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
}
}
static void
gst_vaapi_decoder_get_property(
GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec
)
{
GstVaapiDecoder * const decoder = GST_VAAPI_DECODER_CAST(object);
GstVaapiDecoderPrivate * const priv = decoder->priv;
switch (prop_id) {
case PROP_DISPLAY:
g_value_set_object(value, priv->display);
break;
case PROP_CAPS:
gst_value_set_caps(value, get_caps(decoder));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
}
}
static void
gst_vaapi_decoder_class_init(GstVaapiDecoderClass *klass)
{
GObjectClass * const object_class = G_OBJECT_CLASS(klass);
g_type_class_add_private(klass, sizeof(GstVaapiDecoderPrivate));
object_class->finalize = gst_vaapi_decoder_finalize;
object_class->set_property = gst_vaapi_decoder_set_property;
object_class->get_property = gst_vaapi_decoder_get_property;
/**
* GstVaapiDecoder:display:
*
* The #GstVaapiDisplay this decoder is bound to.
*/
g_properties[PROP_DISPLAY] =
g_param_spec_object("display",
"Display",
"The GstVaapiDisplay this decoder is bound to",
GST_VAAPI_TYPE_DISPLAY,
G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY);
g_properties[PROP_CAPS] =
g_param_spec_pointer("caps",
"Decoder caps",
"The decoder caps",
G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY);
g_object_class_install_properties(object_class, N_PROPERTIES, g_properties);
}
static void
gst_vaapi_decoder_init(GstVaapiDecoder *decoder)
{
GstVaapiDecoderPrivate *priv = GST_VAAPI_DECODER_GET_PRIVATE(decoder);
const GstVaapiDecoderClass * const klass =
GST_VAAPI_DECODER_GET_CLASS(decoder);
GstVideoCodecState *codec_state;
guint sub_size;
parser_state_init(&priv->parser_state);
parser_state_init(&decoder->parser_state);
codec_state = g_slice_new0(GstVideoCodecState);
codec_state->ref_count = 1;
gst_video_info_init(&codec_state->info);
decoder->priv = priv;
priv->display = NULL;
priv->va_display = NULL;
priv->context = NULL;
priv->va_context = VA_INVALID_ID;
priv->codec = 0;
priv->codec_state = codec_state;
decoder->user_data = NULL;
decoder->display = g_object_ref(display);
decoder->va_display = GST_VAAPI_DISPLAY_VADISPLAY(display);
decoder->context = NULL;
decoder->va_context = VA_INVALID_ID;
decoder->codec = 0;
decoder->codec_state = codec_state;
decoder->codec_state_changed_func = NULL;
decoder->codec_state_changed_data = NULL;
priv->buffers = g_async_queue_new_full((GDestroyNotify)gst_buffer_unref);
priv->frames = g_async_queue_new_full((GDestroyNotify)
decoder->buffers = g_async_queue_new_full((GDestroyNotify)gst_buffer_unref);
decoder->frames = g_async_queue_new_full((GDestroyNotify)
gst_video_codec_frame_unref);
if (!set_caps(decoder, caps))
return FALSE;
sub_size = GST_VAAPI_MINI_OBJECT_CLASS(klass)->size - sizeof(*decoder);
if (sub_size > 0)
memset(((guchar *)decoder) + sizeof(*decoder), 0, sub_size);
if (klass->create && !klass->create(decoder))
return FALSE;
return TRUE;
}
GstVaapiDecoder *
gst_vaapi_decoder_new(const GstVaapiDecoderClass *klass,
GstVaapiDisplay *display, GstCaps *caps)
{
GstVaapiDecoder *decoder;
g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL);
g_return_val_if_fail(GST_IS_CAPS(caps), NULL);
decoder = (GstVaapiDecoder *)
gst_vaapi_mini_object_new(GST_VAAPI_MINI_OBJECT_CLASS(klass));
if (!decoder)
return NULL;
if (!gst_vaapi_decoder_init(decoder, display, caps))
goto error;
return decoder;
error:
gst_vaapi_decoder_unref(decoder);
return NULL;
}
/**
* gst_vaapi_decoder_ref:
* @decoder: a #GstVaapiDecoder
*
* Atomically increases the reference count of the given @decoder by one.
*
* Returns: The same @decoder argument
*/
GstVaapiDecoder *
gst_vaapi_decoder_ref(GstVaapiDecoder *decoder)
{
return gst_vaapi_object_ref(decoder);
}
/**
* gst_vaapi_decoder_unref:
* @decoder: a #GstVaapiDecoder
*
* Atomically decreases the reference count of the @decoder by one. If
* the reference count reaches zero, the decoder will be free'd.
*/
void
gst_vaapi_decoder_unref(GstVaapiDecoder *decoder)
{
gst_vaapi_object_unref(decoder);
}
/**
* gst_vaapi_decoder_replace:
* @old_decoder_ptr: a pointer to a #GstVaapiDecoder
* @new_decoder: a #GstVaapiDecoder
*
* Atomically replaces the decoder decoder held in @old_decoder_ptr
* with @new_decoder. This means that @old_decoder_ptr shall reference
* a valid decoder. However, @new_decoder can be NULL.
*/
void
gst_vaapi_decoder_replace(GstVaapiDecoder **old_decoder_ptr,
GstVaapiDecoder *new_decoder)
{
gst_vaapi_object_replace(old_decoder_ptr, new_decoder);
}
/**
* gst_vaapi_decoder_get_user_data:
* @decoder: a #GstVaapiDecoder
*
* Retrieves the user-defined data associated with the @decoder, if any.
*
* Return value: the user-defined data associated with the @decoder
*/
gpointer
gst_vaapi_decoder_get_user_data(GstVaapiDecoder *decoder)
{
g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), NULL);
return decoder->user_data;
}
/**
* gst_vaapi_decoder_set_user_data:
* @decoder: a #GstVaapiDecoder
* @user_data: the pointer to user-defined data
*
* Associates user-defined @user_data to the @decoder. Retrieve the
* attached value with gst_vaapi_decoder_get_user_data() function.
*/
void
gst_vaapi_decoder_set_user_data(GstVaapiDecoder *decoder, gpointer user_data)
{
g_return_if_fail(GST_VAAPI_IS_DECODER(decoder));
decoder->user_data = user_data;
}
/**
@ -603,7 +621,7 @@ gst_vaapi_decoder_get_codec(GstVaapiDecoder *decoder)
{
g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), (GstVaapiCodec)0);
return decoder->priv->codec;
return decoder->codec;
}
/**
@ -624,6 +642,25 @@ gst_vaapi_decoder_get_codec_state(GstVaapiDecoder *decoder)
return GST_VAAPI_DECODER_CODEC_STATE(decoder);
}
/**
* gst_vaapi_decoder_set_codec_state_changed_func:
* @decoder: a #GstVaapiDecoder
* @func: the function to call when codec state changed
* @user_data: a pointer to user-defined data
*
* Sets @func as the function to call whenever the @decoder codec
* state changes.
*/
void
gst_vaapi_decoder_set_codec_state_changed_func(GstVaapiDecoder *decoder,
GstVaapiDecoderStateChangedFunc func, gpointer user_data)
{
g_return_if_fail(GST_VAAPI_IS_DECODER(decoder));
decoder->codec_state_changed_func = func;
decoder->codec_state_changed_data = user_data;
}
/**
* gst_vaapi_decoder_get_caps:
* @decoder: a #GstVaapiDecoder
@ -800,7 +837,7 @@ gst_vaapi_decoder_set_picture_size(
guint height
)
{
GstVideoCodecState * const codec_state = decoder->priv->codec_state;
GstVideoCodecState * const codec_state = decoder->codec_state;
gboolean size_changed = FALSE;
if (codec_state->info.width != width) {
@ -820,7 +857,7 @@ gst_vaapi_decoder_set_picture_size(
}
if (size_changed)
g_object_notify_by_pspec(G_OBJECT(decoder), g_properties[PROP_CAPS]);
notify_codec_state_changed(decoder);
}
void
@ -830,7 +867,7 @@ gst_vaapi_decoder_set_framerate(
guint fps_d
)
{
GstVideoCodecState * const codec_state = decoder->priv->codec_state;
GstVideoCodecState * const codec_state = decoder->codec_state;
if (!fps_n || !fps_d)
return;
@ -841,7 +878,7 @@ gst_vaapi_decoder_set_framerate(
codec_state->info.fps_d = fps_d;
gst_caps_set_simple(codec_state->caps,
"framerate", GST_TYPE_FRACTION, fps_n, fps_d, NULL);
g_object_notify_by_pspec(G_OBJECT(decoder), g_properties[PROP_CAPS]);
notify_codec_state_changed(decoder);
}
}
@ -852,7 +889,7 @@ gst_vaapi_decoder_set_pixel_aspect_ratio(
guint par_d
)
{
GstVideoCodecState * const codec_state = decoder->priv->codec_state;
GstVideoCodecState * const codec_state = decoder->codec_state;
if (!par_n || !par_d)
return;
@ -863,7 +900,7 @@ gst_vaapi_decoder_set_pixel_aspect_ratio(
codec_state->info.par_d = par_d;
gst_caps_set_simple(codec_state->caps,
"pixel-aspect-ratio", GST_TYPE_FRACTION, par_n, par_d, NULL);
g_object_notify_by_pspec(G_OBJECT(decoder), g_properties[PROP_CAPS]);
notify_codec_state_changed(decoder);
}
}
@ -882,7 +919,7 @@ void
gst_vaapi_decoder_set_interlace_mode(GstVaapiDecoder *decoder,
GstVideoInterlaceMode mode)
{
GstVideoCodecState * const codec_state = decoder->priv->codec_state;
GstVideoCodecState * const codec_state = decoder->codec_state;
if (codec_state->info.interlace_mode != mode) {
GST_DEBUG("interlace mode changed to %s",
@ -890,7 +927,7 @@ gst_vaapi_decoder_set_interlace_mode(GstVaapiDecoder *decoder,
codec_state->info.interlace_mode = mode;
gst_caps_set_simple(codec_state->caps, "interlaced",
G_TYPE_BOOLEAN, mode != GST_VIDEO_INTERLACE_MODE_PROGRESSIVE, NULL);
g_object_notify_by_pspec(G_OBJECT(decoder), g_properties[PROP_CAPS]);
notify_codec_state_changed(decoder);
}
}
@ -909,20 +946,18 @@ gst_vaapi_decoder_ensure_context(
GstVaapiContextInfo *cip
)
{
GstVaapiDecoderPrivate * const priv = decoder->priv;
gst_vaapi_decoder_set_picture_size(decoder, cip->width, cip->height);
if (priv->context) {
if (!gst_vaapi_context_reset_full(priv->context, cip))
if (decoder->context) {
if (!gst_vaapi_context_reset_full(decoder->context, cip))
return FALSE;
}
else {
priv->context = gst_vaapi_context_new_full(priv->display, cip);
if (!priv->context)
decoder->context = gst_vaapi_context_new_full(decoder->display, cip);
if (!decoder->context)
return FALSE;
}
priv->va_context = gst_vaapi_context_get_id(priv->context);
decoder->va_context = gst_vaapi_context_get_id(decoder->context);
return TRUE;
}
@ -936,9 +971,8 @@ gst_vaapi_decoder_push_frame(GstVaapiDecoder *decoder,
GstVaapiDecoderStatus
gst_vaapi_decoder_check_status(GstVaapiDecoder *decoder)
{
GstVaapiDecoderPrivate * const priv = decoder->priv;
if (priv->context && gst_vaapi_context_get_surface_count(priv->context) < 1)
if (decoder->context &&
gst_vaapi_context_get_surface_count(decoder->context) < 1)
return GST_VAAPI_DECODER_STATUS_ERROR_NO_SURFACE;
return GST_VAAPI_DECODER_STATUS_SUCCESS;
}

View file

@ -31,34 +31,15 @@
G_BEGIN_DECLS
#define GST_VAAPI_TYPE_DECODER \
(gst_vaapi_decoder_get_type())
#define GST_VAAPI_DECODER(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj), \
GST_VAAPI_TYPE_DECODER, \
GstVaapiDecoder))
#define GST_VAAPI_DECODER_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass), \
GST_VAAPI_TYPE_DECODER, \
GstVaapiDecoderClass))
#define GST_VAAPI_DECODER(obj) \
((GstVaapiDecoder *)(obj))
#define GST_VAAPI_IS_DECODER(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_DECODER))
#define GST_VAAPI_IS_DECODER_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_DECODER))
#define GST_VAAPI_DECODER_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS((obj), \
GST_VAAPI_TYPE_DECODER, \
GstVaapiDecoderClass))
((obj) != NULL)
typedef struct _GstVaapiDecoder GstVaapiDecoder;
typedef struct _GstVaapiDecoderPrivate GstVaapiDecoderPrivate;
typedef struct _GstVaapiDecoderClass GstVaapiDecoderClass;
struct _GstVaapiDecoderUnit;
typedef void (*GstVaapiDecoderStateChangedFunc)(GstVaapiDecoder *decoder,
const GstVideoCodecState *codec_state, gpointer user_data);
/**
* GstVaapiDecoderStatus:
@ -94,42 +75,21 @@ typedef enum {
GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN = -1
} GstVaapiDecoderStatus;
/**
* GstVaapiDecoder:
*
* A VA decoder base instance.
*/
struct _GstVaapiDecoder {
/*< private >*/
GObject parent_instance;
GstVaapiDecoder *
gst_vaapi_decoder_ref(GstVaapiDecoder *decoder);
GstVaapiDecoderPrivate *priv;
};
void
gst_vaapi_decoder_unref(GstVaapiDecoder *decoder);
/**
* GstVaapiDecoderClass:
*
* A VA decoder base class.
*/
struct _GstVaapiDecoderClass {
/*< private >*/
GObjectClass parent_class;
void
gst_vaapi_decoder_replace(GstVaapiDecoder **old_decoder_ptr,
GstVaapiDecoder *new_decoder);
GstVaapiDecoderStatus (*parse)(GstVaapiDecoder *decoder,
GstAdapter *adapter, gboolean at_eos,
struct _GstVaapiDecoderUnit *unit);
GstVaapiDecoderStatus (*decode)(GstVaapiDecoder *decoder,
struct _GstVaapiDecoderUnit *unit);
GstVaapiDecoderStatus (*start_frame)(GstVaapiDecoder *decoder,
struct _GstVaapiDecoderUnit *unit);
GstVaapiDecoderStatus (*end_frame)(GstVaapiDecoder *decoder);
GstVaapiDecoderStatus (*flush)(GstVaapiDecoder *decoder);
GstVaapiDecoderStatus (*decode_codec_data)(GstVaapiDecoder *decoder,
const guchar *buf, guint buf_size);
};
gpointer
gst_vaapi_decoder_get_user_data(GstVaapiDecoder *decoder);
GType
gst_vaapi_decoder_get_type(void) G_GNUC_CONST;
void
gst_vaapi_decoder_set_user_data(GstVaapiDecoder *decoder, gpointer user_data);
GstVaapiCodec
gst_vaapi_decoder_get_codec(GstVaapiDecoder *decoder);
@ -137,6 +97,10 @@ gst_vaapi_decoder_get_codec(GstVaapiDecoder *decoder);
GstVideoCodecState *
gst_vaapi_decoder_get_codec_state(GstVaapiDecoder *decoder);
void
gst_vaapi_decoder_set_codec_state_changed_func(GstVaapiDecoder *decoder,
GstVaapiDecoderStateChangedFunc func, gpointer user_data);
GstCaps *
gst_vaapi_decoder_get_caps(GstVaapiDecoder *decoder);

View file

@ -40,6 +40,8 @@
/* Defined to 1 if strict ordering of DPB is needed. Only useful for debug */
#define USE_STRICT_DPB_ORDERING 0
typedef struct _GstVaapiDecoderH264Private GstVaapiDecoderH264Private;
typedef struct _GstVaapiDecoderH264Class GstVaapiDecoderH264Class;
typedef struct _GstVaapiFrameStore GstVaapiFrameStore;
typedef struct _GstVaapiFrameStoreClass GstVaapiFrameStoreClass;
typedef struct _GstVaapiParserInfoH264 GstVaapiParserInfoH264;
@ -342,18 +344,9 @@ gst_vaapi_frame_store_has_reference(GstVaapiFrameStore *fs)
/* --- H.264 Decoder --- */
/* ------------------------------------------------------------------------- */
G_DEFINE_TYPE(GstVaapiDecoderH264,
gst_vaapi_decoder_h264,
GST_VAAPI_TYPE_DECODER)
#define GST_VAAPI_DECODER_H264_CAST(decoder) \
((GstVaapiDecoderH264 *)(decoder))
#define GST_VAAPI_DECODER_H264_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE((obj), \
GST_VAAPI_TYPE_DECODER_H264, \
GstVaapiDecoderH264Private))
struct _GstVaapiDecoderH264Private {
GstH264NalParser *parser;
GstVaapiPictureH264 *current_picture;
@ -386,7 +379,6 @@ struct _GstVaapiDecoderH264Private {
gint32 prev_frame_num; // prevFrameNum
gboolean prev_pic_has_mmco5; // prevMmco5Pic
gboolean prev_pic_structure; // previous picture structure
guint is_constructed : 1;
guint is_opened : 1;
guint is_avcC : 1;
guint got_sps : 1;
@ -395,6 +387,27 @@ struct _GstVaapiDecoderH264Private {
guint progressive_sequence : 1;
};
/**
* GstVaapiDecoderH264:
*
* A decoder based on H264.
*/
struct _GstVaapiDecoderH264 {
/*< private >*/
GstVaapiDecoder parent_instance;
GstVaapiDecoderH264Private priv;
};
/**
* GstVaapiDecoderH264Class:
*
* A decoder class based on H264.
*/
struct _GstVaapiDecoderH264Class {
/*< private >*/
GstVaapiDecoderClass parent_class;
};
static gboolean
exec_ref_pic_marking(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture);
@ -501,7 +514,7 @@ array_remove_index(void *array, guint *array_length_ptr, guint index)
static void
dpb_remove_index(GstVaapiDecoderH264 *decoder, guint index)
{
GstVaapiDecoderH264Private * const priv = decoder->priv;
GstVaapiDecoderH264Private * const priv = &decoder->priv;
guint i, num_frames = --priv->dpb_count;
if (USE_STRICT_DPB_ORDERING) {
@ -535,7 +548,8 @@ dpb_output(
static inline void
dpb_evict(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture, guint i)
{
GstVaapiFrameStore * const fs = decoder->priv->dpb[i];
GstVaapiDecoderH264Private * const priv = &decoder->priv;
GstVaapiFrameStore * const fs = priv->dpb[i];
if (!fs->output_needed && !gst_vaapi_frame_store_has_reference(fs))
dpb_remove_index(decoder, i);
@ -544,7 +558,7 @@ dpb_evict(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture, guint i)
static gboolean
dpb_bump(GstVaapiDecoderH264 *decoder)
{
GstVaapiDecoderH264Private * const priv = decoder->priv;
GstVaapiDecoderH264Private * const priv = &decoder->priv;
GstVaapiPictureH264 *found_picture = NULL;
guint i, j, found_index;
gboolean success;
@ -572,7 +586,7 @@ dpb_bump(GstVaapiDecoderH264 *decoder)
static void
dpb_clear(GstVaapiDecoderH264 *decoder)
{
GstVaapiDecoderH264Private * const priv = decoder->priv;
GstVaapiDecoderH264Private * const priv = &decoder->priv;
guint i;
for (i = 0; i < priv->dpb_count; i++)
@ -593,7 +607,7 @@ dpb_flush(GstVaapiDecoderH264 *decoder)
static gboolean
dpb_add(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture)
{
GstVaapiDecoderH264Private * const priv = decoder->priv;
GstVaapiDecoderH264Private * const priv = &decoder->priv;
GstVaapiFrameStore *fs;
guint i, j;
@ -668,7 +682,7 @@ dpb_add(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture)
static inline void
dpb_reset(GstVaapiDecoderH264 *decoder, GstH264SPS *sps)
{
GstVaapiDecoderH264Private * const priv = decoder->priv;
GstVaapiDecoderH264Private * const priv = &decoder->priv;
priv->dpb_size = get_max_dec_frame_buffering(sps);
GST_DEBUG("DPB size %u", priv->dpb_size);
@ -699,7 +713,7 @@ get_status(GstH264ParserResult result)
static void
gst_vaapi_decoder_h264_close(GstVaapiDecoderH264 *decoder)
{
GstVaapiDecoderH264Private * const priv = decoder->priv;
GstVaapiDecoderH264Private * const priv = &decoder->priv;
gst_vaapi_picture_replace(&priv->current_picture, NULL);
gst_vaapi_parser_info_h264_replace(&priv->prev_slice_pi, NULL);
@ -715,7 +729,7 @@ gst_vaapi_decoder_h264_close(GstVaapiDecoderH264 *decoder)
static gboolean
gst_vaapi_decoder_h264_open(GstVaapiDecoderH264 *decoder)
{
GstVaapiDecoderH264Private * const priv = decoder->priv;
GstVaapiDecoderH264Private * const priv = &decoder->priv;
gst_vaapi_decoder_h264_close(decoder);
@ -726,16 +740,26 @@ gst_vaapi_decoder_h264_open(GstVaapiDecoderH264 *decoder)
}
static void
gst_vaapi_decoder_h264_destroy(GstVaapiDecoderH264 *decoder)
gst_vaapi_decoder_h264_destroy(GstVaapiDecoder *base_decoder)
{
GstVaapiDecoderH264 * const decoder =
GST_VAAPI_DECODER_H264_CAST(base_decoder);
gst_vaapi_decoder_h264_close(decoder);
}
static gboolean
gst_vaapi_decoder_h264_create(GstVaapiDecoderH264 *decoder)
gst_vaapi_decoder_h264_create(GstVaapiDecoder *base_decoder)
{
if (!GST_VAAPI_DECODER_CODEC(decoder))
return FALSE;
GstVaapiDecoderH264 * const decoder =
GST_VAAPI_DECODER_H264_CAST(base_decoder);
GstVaapiDecoderH264Private * const priv = &decoder->priv;
priv->profile = GST_VAAPI_PROFILE_UNKNOWN;
priv->entrypoint = GST_VAAPI_ENTRYPOINT_VLD;
priv->chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420;
priv->prev_pic_structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME;
priv->progressive_sequence = TRUE;
return TRUE;
}
@ -781,7 +805,7 @@ h264_get_chroma_type(GstH264SPS *sps)
static GstVaapiProfile
get_profile(GstVaapiDecoderH264 *decoder, GstH264SPS *sps)
{
GstVaapiDecoderH264Private * const priv = decoder->priv;
GstVaapiDecoderH264Private * const priv = &decoder->priv;
GstVaapiDisplay * const display = GST_VAAPI_DECODER_DISPLAY(decoder);
GstVaapiProfile profile, profiles[2];
guint i, n_profiles = 0;
@ -815,7 +839,7 @@ static GstVaapiDecoderStatus
ensure_context(GstVaapiDecoderH264 *decoder, GstH264SPS *sps)
{
GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER_CAST(decoder);
GstVaapiDecoderH264Private * const priv = decoder->priv;
GstVaapiDecoderH264Private * const priv = &decoder->priv;
GstVaapiContextInfo info;
GstVaapiProfile profile;
GstVaapiChromaType chroma_type;
@ -963,7 +987,7 @@ ensure_quant_matrix(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture)
static GstVaapiDecoderStatus
decode_current_picture(GstVaapiDecoderH264 *decoder)
{
GstVaapiDecoderH264Private * const priv = decoder->priv;
GstVaapiDecoderH264Private * const priv = &decoder->priv;
GstVaapiPictureH264 * const picture = priv->current_picture;
if (!picture)
@ -988,7 +1012,7 @@ error:
static GstVaapiDecoderStatus
parse_sps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
{
GstVaapiDecoderH264Private * const priv = decoder->priv;
GstVaapiDecoderH264Private * const priv = &decoder->priv;
GstVaapiParserInfoH264 * const pi = unit->parsed_info;
GstH264SPS * const sps = &pi->data.sps;
GstH264ParserResult result;
@ -1010,7 +1034,7 @@ parse_sps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
static GstVaapiDecoderStatus
parse_pps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
{
GstVaapiDecoderH264Private * const priv = decoder->priv;
GstVaapiDecoderH264Private * const priv = &decoder->priv;
GstVaapiParserInfoH264 * const pi = unit->parsed_info;
GstH264PPS * const pps = &pi->data.pps;
GstH264ParserResult result;
@ -1033,7 +1057,7 @@ parse_pps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
static GstVaapiDecoderStatus
parse_sei(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
{
GstVaapiDecoderH264Private * const priv = decoder->priv;
GstVaapiDecoderH264Private * const priv = &decoder->priv;
GstVaapiParserInfoH264 * const pi = unit->parsed_info;
GstH264SEIMessage sei;
GstH264ParserResult result;
@ -1053,7 +1077,7 @@ parse_sei(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
static GstVaapiDecoderStatus
parse_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
{
GstVaapiDecoderH264Private * const priv = decoder->priv;
GstVaapiDecoderH264Private * const priv = &decoder->priv;
GstVaapiParserInfoH264 * const pi = unit->parsed_info;
GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr;
GstH264ParserResult result;
@ -1096,7 +1120,7 @@ init_picture_poc_0(
GstH264SliceHdr *slice_hdr
)
{
GstVaapiDecoderH264Private * const priv = decoder->priv;
GstVaapiDecoderH264Private * const priv = &decoder->priv;
GstH264PPS * const pps = slice_hdr->pps;
GstH264SPS * const sps = pps->sequence;
const gint32 MaxPicOrderCntLsb = 1 << (sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
@ -1157,7 +1181,7 @@ init_picture_poc_1(
GstH264SliceHdr *slice_hdr
)
{
GstVaapiDecoderH264Private * const priv = decoder->priv;
GstVaapiDecoderH264Private * const priv = &decoder->priv;
GstH264PPS * const pps = slice_hdr->pps;
GstH264SPS * const sps = pps->sequence;
const gint32 MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4);
@ -1240,7 +1264,7 @@ init_picture_poc_2(
GstH264SliceHdr *slice_hdr
)
{
GstVaapiDecoderH264Private * const priv = decoder->priv;
GstVaapiDecoderH264Private * const priv = &decoder->priv;
GstH264PPS * const pps = slice_hdr->pps;
GstH264SPS * const sps = pps->sequence;
const gint32 MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4);
@ -1284,7 +1308,7 @@ init_picture_poc(
GstH264SliceHdr *slice_hdr
)
{
GstVaapiDecoderH264Private * const priv = decoder->priv;
GstVaapiDecoderH264Private * const priv = &decoder->priv;
GstH264PPS * const pps = slice_hdr->pps;
GstH264SPS * const sps = pps->sequence;
@ -1369,7 +1393,7 @@ init_picture_refs_pic_num(
GstH264SliceHdr *slice_hdr
)
{
GstVaapiDecoderH264Private * const priv = decoder->priv;
GstVaapiDecoderH264Private * const priv = &decoder->priv;
GstH264PPS * const pps = slice_hdr->pps;
GstH264SPS * const sps = pps->sequence;
const gint32 MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4);
@ -1475,7 +1499,7 @@ init_picture_refs_p_slice(
GstH264SliceHdr *slice_hdr
)
{
GstVaapiDecoderH264Private * const priv = decoder->priv;
GstVaapiDecoderH264Private * const priv = &decoder->priv;
GstVaapiPictureH264 **ref_list;
guint i;
@ -1536,7 +1560,7 @@ init_picture_refs_b_slice(
GstH264SliceHdr *slice_hdr
)
{
GstVaapiDecoderH264Private * const priv = decoder->priv;
GstVaapiDecoderH264Private * const priv = &decoder->priv;
GstVaapiPictureH264 **ref_list;
guint i, n;
@ -1690,7 +1714,7 @@ init_picture_refs_b_slice(
static gint
find_short_term_reference(GstVaapiDecoderH264 *decoder, gint32 pic_num)
{
GstVaapiDecoderH264Private * const priv = decoder->priv;
GstVaapiDecoderH264Private * const priv = &decoder->priv;
guint i;
for (i = 0; i < priv->short_ref_count; i++) {
@ -1705,7 +1729,7 @@ find_short_term_reference(GstVaapiDecoderH264 *decoder, gint32 pic_num)
static gint
find_long_term_reference(GstVaapiDecoderH264 *decoder, gint32 long_term_pic_num)
{
GstVaapiDecoderH264Private * const priv = decoder->priv;
GstVaapiDecoderH264Private * const priv = &decoder->priv;
guint i;
for (i = 0; i < priv->long_ref_count; i++) {
@ -1725,7 +1749,7 @@ exec_picture_refs_modification_1(
guint list
)
{
GstVaapiDecoderH264Private * const priv = decoder->priv;
GstVaapiDecoderH264Private * const priv = &decoder->priv;
GstH264PPS * const pps = slice_hdr->pps;
GstH264SPS * const sps = pps->sequence;
GstH264RefPicListModification *ref_pic_list_modification;
@ -1869,7 +1893,7 @@ exec_picture_refs_modification(
static void
init_picture_ref_lists(GstVaapiDecoderH264 *decoder)
{
GstVaapiDecoderH264Private * const priv = decoder->priv;
GstVaapiDecoderH264Private * const priv = &decoder->priv;
guint i, j, short_ref_count, long_ref_count;
short_ref_count = 0;
@ -1920,7 +1944,7 @@ init_picture_refs(
GstH264SliceHdr *slice_hdr
)
{
GstVaapiDecoderH264Private * const priv = decoder->priv;
GstVaapiDecoderH264Private * const priv = &decoder->priv;
GstVaapiPicture * const base_picture = &picture->base;
guint i, num_refs;
@ -1969,7 +1993,7 @@ init_picture(
GstVaapiDecoderH264 *decoder,
GstVaapiPictureH264 *picture, GstVaapiParserInfoH264 *pi)
{
GstVaapiDecoderH264Private * const priv = decoder->priv;
GstVaapiDecoderH264Private * const priv = &decoder->priv;
GstVaapiPicture * const base_picture = &picture->base;
GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr;
@ -2041,7 +2065,7 @@ init_picture(
static gboolean
exec_ref_pic_marking_sliding_window(GstVaapiDecoderH264 *decoder)
{
GstVaapiDecoderH264Private * const priv = decoder->priv;
GstVaapiDecoderH264Private * const priv = &decoder->priv;
GstH264PPS * const pps = priv->current_picture->pps;
GstH264SPS * const sps = pps->sequence;
GstVaapiPictureH264 *ref_picture;
@ -2107,7 +2131,7 @@ exec_ref_pic_marking_adaptive_mmco_1(
GstH264RefPicMarking *ref_pic_marking
)
{
GstVaapiDecoderH264Private * const priv = decoder->priv;
GstVaapiDecoderH264Private * const priv = &decoder->priv;
gint32 i, picNumX;
picNumX = get_picNumX(picture, ref_pic_marking);
@ -2128,7 +2152,7 @@ exec_ref_pic_marking_adaptive_mmco_2(
GstH264RefPicMarking *ref_pic_marking
)
{
GstVaapiDecoderH264Private * const priv = decoder->priv;
GstVaapiDecoderH264Private * const priv = &decoder->priv;
gint32 i;
i = find_long_term_reference(decoder, ref_pic_marking->long_term_pic_num);
@ -2148,7 +2172,7 @@ exec_ref_pic_marking_adaptive_mmco_3(
GstH264RefPicMarking *ref_pic_marking
)
{
GstVaapiDecoderH264Private * const priv = decoder->priv;
GstVaapiDecoderH264Private * const priv = &decoder->priv;
GstVaapiPictureH264 *ref_picture;
gint32 i, picNumX;
@ -2185,7 +2209,7 @@ exec_ref_pic_marking_adaptive_mmco_4(
GstH264RefPicMarking *ref_pic_marking
)
{
GstVaapiDecoderH264Private * const priv = decoder->priv;
GstVaapiDecoderH264Private * const priv = &decoder->priv;
gint32 i, long_term_frame_idx;
long_term_frame_idx = ref_pic_marking->max_long_term_frame_idx_plus1 - 1;
@ -2207,7 +2231,7 @@ exec_ref_pic_marking_adaptive_mmco_5(
GstH264RefPicMarking *ref_pic_marking
)
{
GstVaapiDecoderH264Private * const priv = decoder->priv;
GstVaapiDecoderH264Private * const priv = &decoder->priv;
dpb_flush(decoder);
@ -2286,7 +2310,7 @@ exec_ref_pic_marking_adaptive(
static gboolean
exec_ref_pic_marking(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture)
{
GstVaapiDecoderH264Private * const priv = decoder->priv;
GstVaapiDecoderH264Private * const priv = &decoder->priv;
priv->prev_pic_has_mmco5 = FALSE;
priv->prev_pic_structure = picture->structure;
@ -2361,7 +2385,7 @@ static gboolean
fill_picture(GstVaapiDecoderH264 *decoder,
GstVaapiPictureH264 *picture, GstVaapiParserInfoH264 *pi)
{
GstVaapiDecoderH264Private * const priv = decoder->priv;
GstVaapiDecoderH264Private * const priv = &decoder->priv;
GstVaapiPicture * const base_picture = &picture->base;
GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr;
GstH264PPS * const pps = picture->pps;
@ -2501,7 +2525,7 @@ is_new_picture(GstVaapiParserInfoH264 *pi, GstVaapiParserInfoH264 *prev_pi)
static GstVaapiDecoderStatus
decode_picture(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
{
GstVaapiDecoderH264Private * const priv = decoder->priv;
GstVaapiDecoderH264Private * const priv = &decoder->priv;
GstVaapiParserInfoH264 * const pi = unit->parsed_info;
GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr;
GstH264PPS * const pps = slice_hdr->pps;
@ -2629,7 +2653,7 @@ static gboolean
fill_RefPicList(GstVaapiDecoderH264 *decoder,
GstVaapiSlice *slice, GstH264SliceHdr *slice_hdr)
{
GstVaapiDecoderH264Private * const priv = decoder->priv;
GstVaapiDecoderH264Private * const priv = &decoder->priv;
VASliceParameterBufferH264 * const slice_param = slice->param;
guint i, num_ref_lists = 0;
@ -2694,7 +2718,7 @@ fill_slice(GstVaapiDecoderH264 *decoder,
static GstVaapiDecoderStatus
decode_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
{
GstVaapiDecoderH264Private * const priv = decoder->priv;
GstVaapiDecoderH264Private * const priv = &decoder->priv;
GstVaapiParserInfoH264 * const pi = unit->parsed_info;
GstVaapiPictureH264 * const picture = priv->current_picture;
GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr;
@ -2775,7 +2799,7 @@ gst_vaapi_decoder_h264_decode_codec_data(GstVaapiDecoder *base_decoder,
{
GstVaapiDecoderH264 * const decoder =
GST_VAAPI_DECODER_H264_CAST(base_decoder);
GstVaapiDecoderH264Private * const priv = decoder->priv;
GstVaapiDecoderH264Private * const priv = &decoder->priv;
GstVaapiDecoderStatus status;
GstVaapiDecoderUnit unit;
GstVaapiParserInfoH264 pi;
@ -2837,12 +2861,9 @@ gst_vaapi_decoder_h264_decode_codec_data(GstVaapiDecoder *base_decoder,
static GstVaapiDecoderStatus
ensure_decoder(GstVaapiDecoderH264 *decoder)
{
GstVaapiDecoderH264Private * const priv = decoder->priv;
GstVaapiDecoderH264Private * const priv = &decoder->priv;
GstVaapiDecoderStatus status;
g_return_val_if_fail(priv->is_constructed,
GST_VAAPI_DECODER_STATUS_ERROR_INIT_FAILED);
if (!priv->is_opened) {
priv->is_opened = gst_vaapi_decoder_h264_open(decoder);
if (!priv->is_opened)
@ -2862,7 +2883,7 @@ gst_vaapi_decoder_h264_parse(GstVaapiDecoder *base_decoder,
{
GstVaapiDecoderH264 * const decoder =
GST_VAAPI_DECODER_H264_CAST(base_decoder);
GstVaapiDecoderH264Private * const priv = decoder->priv;
GstVaapiDecoderH264Private * const priv = &decoder->priv;
GstVaapiParserState * const ps = GST_VAAPI_PARSER_STATE(base_decoder);
GstVaapiParserInfoH264 *pi;
GstVaapiDecoderStatus status;
@ -3051,41 +3072,18 @@ gst_vaapi_decoder_h264_flush(GstVaapiDecoder *base_decoder)
return GST_VAAPI_DECODER_STATUS_SUCCESS;
}
static void
gst_vaapi_decoder_h264_finalize(GObject *object)
{
GstVaapiDecoderH264 * const decoder = GST_VAAPI_DECODER_H264_CAST(object);
gst_vaapi_decoder_h264_destroy(decoder);
G_OBJECT_CLASS(gst_vaapi_decoder_h264_parent_class)->finalize(object);
}
static void
gst_vaapi_decoder_h264_constructed(GObject *object)
{
GstVaapiDecoderH264 * const decoder = GST_VAAPI_DECODER_H264_CAST(object);
GstVaapiDecoderH264Private * const priv = decoder->priv;
GObjectClass *parent_class;
parent_class = G_OBJECT_CLASS(gst_vaapi_decoder_h264_parent_class);
if (parent_class->constructed)
parent_class->constructed(object);
priv->is_constructed = gst_vaapi_decoder_h264_create(decoder);
}
static void
gst_vaapi_decoder_h264_class_init(GstVaapiDecoderH264Class *klass)
{
GObjectClass * const object_class = G_OBJECT_CLASS(klass);
GstVaapiMiniObjectClass * const object_class =
GST_VAAPI_MINI_OBJECT_CLASS(klass);
GstVaapiDecoderClass * const decoder_class = GST_VAAPI_DECODER_CLASS(klass);
g_type_class_add_private(klass, sizeof(GstVaapiDecoderH264Private));
object_class->finalize = gst_vaapi_decoder_h264_finalize;
object_class->constructed = gst_vaapi_decoder_h264_constructed;
object_class->size = sizeof(GstVaapiDecoderH264);
object_class->finalize = (GDestroyNotify)gst_vaapi_decoder_finalize;
decoder_class->create = gst_vaapi_decoder_h264_create;
decoder_class->destroy = gst_vaapi_decoder_h264_destroy;
decoder_class->parse = gst_vaapi_decoder_h264_parse;
decoder_class->decode = gst_vaapi_decoder_h264_decode;
decoder_class->start_frame = gst_vaapi_decoder_h264_start_frame;
@ -3096,18 +3094,17 @@ gst_vaapi_decoder_h264_class_init(GstVaapiDecoderH264Class *klass)
gst_vaapi_decoder_h264_decode_codec_data;
}
static void
gst_vaapi_decoder_h264_init(GstVaapiDecoderH264 *decoder)
static inline const GstVaapiDecoderClass *
gst_vaapi_decoder_h264_class(void)
{
GstVaapiDecoderH264Private *priv;
static GstVaapiDecoderH264Class g_class;
static gsize g_class_init = FALSE;
priv = GST_VAAPI_DECODER_H264_GET_PRIVATE(decoder);
decoder->priv = priv;
priv->profile = GST_VAAPI_PROFILE_UNKNOWN;
priv->entrypoint = GST_VAAPI_ENTRYPOINT_VLD;
priv->chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420;
priv->prev_pic_structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME;
priv->progressive_sequence = TRUE;
if (g_once_init_enter(&g_class_init)) {
gst_vaapi_decoder_h264_class_init(&g_class);
g_once_init_leave(&g_class_init, TRUE);
}
return GST_VAAPI_DECODER_CLASS(&g_class);
}
/**
@ -3123,20 +3120,5 @@ gst_vaapi_decoder_h264_init(GstVaapiDecoderH264 *decoder)
GstVaapiDecoder *
gst_vaapi_decoder_h264_new(GstVaapiDisplay *display, GstCaps *caps)
{
GstVaapiDecoderH264 *decoder;
g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL);
g_return_val_if_fail(GST_IS_CAPS(caps), NULL);
decoder = g_object_new(
GST_VAAPI_TYPE_DECODER_H264,
"display", display,
"caps", caps,
NULL
);
if (!decoder->priv->is_constructed) {
g_object_unref(decoder);
return NULL;
}
return GST_VAAPI_DECODER_CAST(decoder);
return gst_vaapi_decoder_new(gst_vaapi_decoder_h264_class(), display, caps);
}

View file

@ -26,58 +26,7 @@
G_BEGIN_DECLS
#define GST_VAAPI_TYPE_DECODER_H264 \
(gst_vaapi_decoder_h264_get_type())
#define GST_VAAPI_DECODER_H264(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj), \
GST_VAAPI_TYPE_DECODER_H264, \
GstVaapiDecoderH264))
#define GST_VAAPI_DECODER_H264_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass), \
GST_VAAPI_TYPE_DECODER_H264, \
GstVaapiDecoderH264Class))
#define GST_VAAPI_IS_DECODER_H264(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_DECODER_H264))
#define GST_VAAPI_IS_DECODER_H264_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_DECODER_H264))
#define GST_VAAPI_DECODER_H264_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS((obj), \
GST_VAAPI_TYPE_DECODER_H264, \
GstVaapiDecoderH264Class))
typedef struct _GstVaapiDecoderH264 GstVaapiDecoderH264;
typedef struct _GstVaapiDecoderH264Private GstVaapiDecoderH264Private;
typedef struct _GstVaapiDecoderH264Class GstVaapiDecoderH264Class;
/**
* GstVaapiDecoderH264:
*
* A decoder based on H264.
*/
struct _GstVaapiDecoderH264 {
/*< private >*/
GstVaapiDecoder parent_instance;
GstVaapiDecoderH264Private *priv;
};
/**
* GstVaapiDecoderH264Class:
*
* A decoder class based on H264.
*/
struct _GstVaapiDecoderH264Class {
/*< private >*/
GstVaapiDecoderClass parent_class;
};
GType
gst_vaapi_decoder_h264_get_type(void) G_GNUC_CONST;
GstVaapiDecoder *
gst_vaapi_decoder_h264_new(GstVaapiDisplay *display, GstCaps *caps);

View file

@ -37,14 +37,11 @@
#define DEBUG 1
#include "gstvaapidebug.h"
G_DEFINE_TYPE(GstVaapiDecoderJpeg,
gst_vaapi_decoder_jpeg,
GST_VAAPI_TYPE_DECODER)
#define GST_VAAPI_DECODER_JPEG_CAST(decoder) \
((GstVaapiDecoderJpeg *)(decoder))
#define GST_VAAPI_DECODER_JPEG_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE((obj), \
GST_VAAPI_TYPE_DECODER_JPEG, \
GstVaapiDecoderJpegPrivate))
typedef struct _GstVaapiDecoderJpegPrivate GstVaapiDecoderJpegPrivate;
typedef struct _GstVaapiDecoderJpegClass GstVaapiDecoderJpegClass;
struct _GstVaapiDecoderJpegPrivate {
GstVaapiProfile profile;
@ -59,7 +56,27 @@ struct _GstVaapiDecoderJpegPrivate {
guint mcu_restart;
guint is_opened : 1;
guint profile_changed : 1;
guint is_constructed : 1;
};
/**
* GstVaapiDecoderJpeg:
*
* A decoder based on Jpeg.
*/
struct _GstVaapiDecoderJpeg {
/*< private >*/
GstVaapiDecoder parent_instance;
GstVaapiDecoderJpegPrivate priv;
};
/**
* GstVaapiDecoderJpegClass:
*
* A decoder class based on Jpeg.
*/
struct _GstVaapiDecoderJpegClass {
/*< private >*/
GstVaapiDecoderClass parent_class;
};
typedef struct _GstJpegScanSegment GstJpegScanSegment;
@ -74,7 +91,7 @@ struct _GstJpegScanSegment {
static void
gst_vaapi_decoder_jpeg_close(GstVaapiDecoderJpeg *decoder)
{
GstVaapiDecoderJpegPrivate * const priv = decoder->priv;
GstVaapiDecoderJpegPrivate * const priv = &decoder->priv;
gst_vaapi_picture_replace(&priv->current_picture, NULL);
@ -95,23 +112,30 @@ gst_vaapi_decoder_jpeg_open(GstVaapiDecoderJpeg *decoder)
}
static void
gst_vaapi_decoder_jpeg_destroy(GstVaapiDecoderJpeg *decoder)
gst_vaapi_decoder_jpeg_destroy(GstVaapiDecoder *base_decoder)
{
GstVaapiDecoderJpeg * const decoder =
GST_VAAPI_DECODER_JPEG_CAST(base_decoder);
gst_vaapi_decoder_jpeg_close(decoder);
}
static gboolean
gst_vaapi_decoder_jpeg_create(GstVaapiDecoderJpeg *decoder)
gst_vaapi_decoder_jpeg_create(GstVaapiDecoder *base_decoder)
{
if (!GST_VAAPI_DECODER_CODEC(decoder))
return FALSE;
GstVaapiDecoderJpeg * const decoder =
GST_VAAPI_DECODER_JPEG_CAST(base_decoder);
GstVaapiDecoderJpegPrivate * const priv = &decoder->priv;
priv->profile = GST_VAAPI_PROFILE_JPEG_BASELINE;
priv->profile_changed = TRUE;
return TRUE;
}
static GstVaapiDecoderStatus
ensure_context(GstVaapiDecoderJpeg *decoder)
{
GstVaapiDecoderJpegPrivate * const priv = decoder->priv;
GstVaapiDecoderJpegPrivate * const priv = &decoder->priv;
GstVaapiProfile profiles[2];
GstVaapiEntrypoint entrypoint = GST_VAAPI_ENTRYPOINT_VLD;
guint i, n_profiles = 0;
@ -157,7 +181,7 @@ ensure_context(GstVaapiDecoderJpeg *decoder)
static gboolean
decode_current_picture(GstVaapiDecoderJpeg *decoder)
{
GstVaapiDecoderJpegPrivate * const priv = decoder->priv;
GstVaapiDecoderJpegPrivate * const priv = &decoder->priv;
GstVaapiPicture * const picture = priv->current_picture;
gboolean success = TRUE;
@ -209,7 +233,7 @@ fill_quantization_table(
GstVaapiPicture *picture
)
{
GstVaapiDecoderJpegPrivate * const priv = decoder->priv;
GstVaapiDecoderJpegPrivate * const priv = &decoder->priv;
VAIQMatrixBufferJPEGBaseline *iq_matrix;
guint i, j, num_tables;
@ -246,7 +270,7 @@ fill_huffman_table(
GstVaapiPicture *picture
)
{
GstVaapiDecoderJpegPrivate * const priv = decoder->priv;
GstVaapiDecoderJpegPrivate * const priv = &decoder->priv;
GstJpegHuffmanTables * const huf_tables = &priv->huf_tables;
VAHuffmanTableBufferJPEGBaseline *huffman_table;
guint i, num_tables;
@ -318,7 +342,7 @@ decode_picture(
guint buf_size
)
{
GstVaapiDecoderJpegPrivate * const priv = decoder->priv;
GstVaapiDecoderJpegPrivate * const priv = &decoder->priv;
GstJpegFrameHdr * const frame_hdr = &priv->frame_hdr;
GstVaapiPicture *picture;
GstVaapiDecoderStatus status;
@ -372,7 +396,7 @@ decode_huffman_table(
guint buf_size
)
{
GstVaapiDecoderJpegPrivate * const priv = decoder->priv;
GstVaapiDecoderJpegPrivate * const priv = &decoder->priv;
if (!gst_jpeg_parse_huffman_table(&priv->huf_tables, buf, buf_size, 0)) {
GST_DEBUG("failed to parse Huffman table");
@ -389,7 +413,7 @@ decode_quant_table(
guint buf_size
)
{
GstVaapiDecoderJpegPrivate * const priv = decoder->priv;
GstVaapiDecoderJpegPrivate * const priv = &decoder->priv;
if (!gst_jpeg_parse_quant_table(&priv->quant_tables, buf, buf_size, 0)) {
GST_DEBUG("failed to parse quantization table");
@ -406,7 +430,7 @@ decode_restart_interval(
guint buf_size
)
{
GstVaapiDecoderJpegPrivate * const priv = decoder->priv;
GstVaapiDecoderJpegPrivate * const priv = &decoder->priv;
if (!gst_jpeg_parse_restart_interval(&priv->mcu_restart, buf, buf_size, 0)) {
GST_DEBUG("failed to parse restart interval");
@ -424,7 +448,7 @@ decode_scan(
guint scan_data_size
)
{
GstVaapiDecoderJpegPrivate * const priv = decoder->priv;
GstVaapiDecoderJpegPrivate * const priv = &decoder->priv;
GstVaapiPicture *picture = priv->current_picture;
VASliceParameterBufferJPEGBaseline *slice_param;
GstVaapiSlice *gst_slice;
@ -493,7 +517,7 @@ decode_scan(
static GstVaapiDecoderStatus
decode_buffer(GstVaapiDecoderJpeg *decoder, const guchar *buf, guint buf_size)
{
GstVaapiDecoderJpegPrivate * const priv = decoder->priv;
GstVaapiDecoderJpegPrivate * const priv = &decoder->priv;
GstVaapiDecoderStatus status = GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
GstJpegMarkerSegment seg;
GstJpegScanSegment scan_seg;
@ -609,10 +633,7 @@ end:
static GstVaapiDecoderStatus
ensure_decoder(GstVaapiDecoderJpeg *decoder)
{
GstVaapiDecoderJpegPrivate * const priv = decoder->priv;
g_return_val_if_fail(priv->is_constructed,
GST_VAAPI_DECODER_STATUS_ERROR_INIT_FAILED);
GstVaapiDecoderJpegPrivate * const priv = &decoder->priv;
if (!priv->is_opened) {
priv->is_opened = gst_vaapi_decoder_jpeg_open(decoder);
@ -633,7 +654,8 @@ static GstVaapiDecoderStatus
gst_vaapi_decoder_jpeg_parse(GstVaapiDecoder *base_decoder,
GstAdapter *adapter, gboolean at_eos, GstVaapiDecoderUnit *unit)
{
GstVaapiDecoderJpeg * const decoder = GST_VAAPI_DECODER_JPEG(base_decoder);
GstVaapiDecoderJpeg * const decoder =
GST_VAAPI_DECODER_JPEG_CAST(base_decoder);
GstVaapiDecoderStatus status;
guint size, buf_size, flags = 0;
gint ofs;
@ -676,7 +698,8 @@ static GstVaapiDecoderStatus
gst_vaapi_decoder_jpeg_decode(GstVaapiDecoder *base_decoder,
GstVaapiDecoderUnit *unit)
{
GstVaapiDecoderJpeg * const decoder = GST_VAAPI_DECODER_JPEG(base_decoder);
GstVaapiDecoderJpeg * const decoder =
GST_VAAPI_DECODER_JPEG_CAST(base_decoder);
GstVaapiDecoderStatus status;
GstBuffer * const buffer =
GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer;
@ -698,65 +721,33 @@ gst_vaapi_decoder_jpeg_decode(GstVaapiDecoder *base_decoder,
return GST_VAAPI_DECODER_STATUS_SUCCESS;
}
static void
gst_vaapi_decoder_jpeg_finalize(GObject *object)
{
GstVaapiDecoderJpeg * const decoder = GST_VAAPI_DECODER_JPEG(object);
gst_vaapi_decoder_jpeg_destroy(decoder);
G_OBJECT_CLASS(gst_vaapi_decoder_jpeg_parent_class)->finalize(object);
}
static void
gst_vaapi_decoder_jpeg_constructed(GObject *object)
{
GstVaapiDecoderJpeg * const decoder = GST_VAAPI_DECODER_JPEG(object);
GstVaapiDecoderJpegPrivate * const priv = decoder->priv;
GObjectClass *parent_class;
parent_class = G_OBJECT_CLASS(gst_vaapi_decoder_jpeg_parent_class);
if (parent_class->constructed)
parent_class->constructed(object);
priv->is_constructed = gst_vaapi_decoder_jpeg_create(decoder);
}
static void
gst_vaapi_decoder_jpeg_class_init(GstVaapiDecoderJpegClass *klass)
{
GObjectClass * const object_class = G_OBJECT_CLASS(klass);
GstVaapiMiniObjectClass * const object_class =
GST_VAAPI_MINI_OBJECT_CLASS(klass);
GstVaapiDecoderClass * const decoder_class = GST_VAAPI_DECODER_CLASS(klass);
g_type_class_add_private(klass, sizeof(GstVaapiDecoderJpegPrivate));
object_class->finalize = gst_vaapi_decoder_jpeg_finalize;
object_class->constructed = gst_vaapi_decoder_jpeg_constructed;
object_class->size = sizeof(GstVaapiDecoderJpeg);
object_class->finalize = (GDestroyNotify)gst_vaapi_decoder_finalize;
decoder_class->create = gst_vaapi_decoder_jpeg_create;
decoder_class->destroy = gst_vaapi_decoder_jpeg_destroy;
decoder_class->parse = gst_vaapi_decoder_jpeg_parse;
decoder_class->decode = gst_vaapi_decoder_jpeg_decode;
}
static void
gst_vaapi_decoder_jpeg_init(GstVaapiDecoderJpeg *decoder)
static inline const GstVaapiDecoderClass *
gst_vaapi_decoder_jpeg_class(void)
{
GstVaapiDecoderJpegPrivate *priv;
static GstVaapiDecoderJpegClass g_class;
static gsize g_class_init = FALSE;
priv = GST_VAAPI_DECODER_JPEG_GET_PRIVATE(decoder);
decoder->priv = priv;
priv->profile = GST_VAAPI_PROFILE_JPEG_BASELINE;
priv->width = 0;
priv->height = 0;
priv->current_picture = NULL;
priv->has_huf_table = FALSE;
priv->has_quant_table = FALSE;
priv->mcu_restart = 0;
priv->is_opened = FALSE;
priv->profile_changed = TRUE;
priv->is_constructed = FALSE;
memset(&priv->frame_hdr, 0, sizeof(priv->frame_hdr));
memset(&priv->huf_tables, 0, sizeof(priv->huf_tables));
memset(&priv->quant_tables, 0, sizeof(priv->quant_tables));
if (g_once_init_enter(&g_class_init)) {
gst_vaapi_decoder_jpeg_class_init(&g_class);
g_once_init_leave(&g_class_init, TRUE);
}
return GST_VAAPI_DECODER_CLASS(&g_class);
}
/**
@ -772,20 +763,5 @@ gst_vaapi_decoder_jpeg_init(GstVaapiDecoderJpeg *decoder)
GstVaapiDecoder *
gst_vaapi_decoder_jpeg_new(GstVaapiDisplay *display, GstCaps *caps)
{
GstVaapiDecoderJpeg *decoder;
g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL);
g_return_val_if_fail(GST_IS_CAPS(caps), NULL);
decoder = g_object_new(
GST_VAAPI_TYPE_DECODER_JPEG,
"display", display,
"caps", caps,
NULL
);
if (!decoder->priv->is_constructed) {
g_object_unref(decoder);
return NULL;
}
return GST_VAAPI_DECODER_CAST(decoder);
return gst_vaapi_decoder_new(gst_vaapi_decoder_jpeg_class(), display, caps);
}

View file

@ -26,58 +26,7 @@
G_BEGIN_DECLS
#define GST_VAAPI_TYPE_DECODER_JPEG \
(gst_vaapi_decoder_jpeg_get_type())
#define GST_VAAPI_DECODER_JPEG(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj), \
GST_VAAPI_TYPE_DECODER_JPEG, \
GstVaapiDecoderJpeg))
#define GST_VAAPI_DECODER_JPEG_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass), \
GST_VAAPI_TYPE_DECODER_JPEG, \
GstVaapiDecoderJpegClass))
#define GST_VAAPI_IS_DECODER_JPEG(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_DECODER_JPEG))
#define GST_VAAPI_IS_DECODER_JPEG_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_DECODER_JPEG))
#define GST_VAAPI_DECODER_JPEG_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS((obj), \
GST_VAAPI_TYPE_DECODER_JPEG, \
GstVaapiDecoderJpegClass))
typedef struct _GstVaapiDecoderJpeg GstVaapiDecoderJpeg;
typedef struct _GstVaapiDecoderJpegPrivate GstVaapiDecoderJpegPrivate;
typedef struct _GstVaapiDecoderJpegClass GstVaapiDecoderJpegClass;
/**
* GstVaapiDecoderJpeg:
*
* A decoder based on Jpeg.
*/
struct _GstVaapiDecoderJpeg {
/*< private >*/
GstVaapiDecoder parent_instance;
GstVaapiDecoderJpegPrivate *priv;
};
/**
* GstVaapiDecoderJpegClass:
*
* A decoder class based on Jpeg.
*/
struct _GstVaapiDecoderJpegClass {
/*< private >*/
GstVaapiDecoderClass parent_class;
};
GType
gst_vaapi_decoder_jpeg_get_type(void) G_GNUC_CONST;
GstVaapiDecoder *
gst_vaapi_decoder_jpeg_new(GstVaapiDisplay *display, GstCaps *caps);

View file

@ -316,17 +316,11 @@ gst_vaapi_parser_info_mpeg2_ensure(GstVaapiParserInfoMpeg2 **pi_ptr)
/* --- MPEG-2 Decoder --- */
/* ------------------------------------------------------------------------- */
G_DEFINE_TYPE(GstVaapiDecoderMpeg2,
gst_vaapi_decoder_mpeg2,
GST_VAAPI_TYPE_DECODER)
#define GST_VAAPI_DECODER_MPEG2_CAST(decoder) \
((GstVaapiDecoderMpeg2 *)(decoder))
#define GST_VAAPI_DECODER_MPEG2_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE((obj), \
GST_VAAPI_TYPE_DECODER_MPEG2, \
GstVaapiDecoderMpeg2Private))
typedef struct _GstVaapiDecoderMpeg2Private GstVaapiDecoderMpeg2Private;
typedef struct _GstVaapiDecoderMpeg2Class GstVaapiDecoderMpeg2Class;
typedef enum {
GST_MPEG_VIDEO_STATE_GOT_SEQ_HDR = 1 << 0,
@ -367,7 +361,6 @@ struct _GstVaapiDecoderMpeg2Private {
GstVaapiPicture *current_picture;
GstVaapiDpb *dpb;
PTSGenerator tsg;
guint is_constructed : 1;
guint is_opened : 1;
guint size_changed : 1;
guint profile_changed : 1;
@ -377,10 +370,31 @@ struct _GstVaapiDecoderMpeg2Private {
guint broken_link : 1;
};
/**
* GstVaapiDecoderMpeg2:
*
* A decoder based on Mpeg2.
*/
struct _GstVaapiDecoderMpeg2 {
/*< private >*/
GstVaapiDecoder parent_instance;
GstVaapiDecoderMpeg2Private priv;
};
/**
* GstVaapiDecoderMpeg2Class:
*
* A decoder class based on Mpeg2.
*/
struct _GstVaapiDecoderMpeg2Class {
/*< private >*/
GstVaapiDecoderClass parent_class;
};
static void
gst_vaapi_decoder_mpeg2_close(GstVaapiDecoderMpeg2 *decoder)
{
GstVaapiDecoderMpeg2Private * const priv = decoder->priv;
GstVaapiDecoderMpeg2Private * const priv = &decoder->priv;
gst_vaapi_picture_replace(&priv->current_picture, NULL);
@ -400,7 +414,7 @@ gst_vaapi_decoder_mpeg2_close(GstVaapiDecoderMpeg2 *decoder)
static gboolean
gst_vaapi_decoder_mpeg2_open(GstVaapiDecoderMpeg2 *decoder)
{
GstVaapiDecoderMpeg2Private * const priv = decoder->priv;
GstVaapiDecoderMpeg2Private * const priv = &decoder->priv;
gst_vaapi_decoder_mpeg2_close(decoder);
@ -413,16 +427,24 @@ gst_vaapi_decoder_mpeg2_open(GstVaapiDecoderMpeg2 *decoder)
}
static void
gst_vaapi_decoder_mpeg2_destroy(GstVaapiDecoderMpeg2 *decoder)
gst_vaapi_decoder_mpeg2_destroy(GstVaapiDecoder *base_decoder)
{
GstVaapiDecoderMpeg2 * const decoder =
GST_VAAPI_DECODER_MPEG2_CAST(base_decoder);
gst_vaapi_decoder_mpeg2_close(decoder);
}
static gboolean
gst_vaapi_decoder_mpeg2_create(GstVaapiDecoderMpeg2 *decoder)
gst_vaapi_decoder_mpeg2_create(GstVaapiDecoder *base_decoder)
{
if (!GST_VAAPI_DECODER_CODEC(decoder))
return FALSE;
GstVaapiDecoderMpeg2 * const decoder =
GST_VAAPI_DECODER_MPEG2_CAST(base_decoder);
GstVaapiDecoderMpeg2Private * const priv = &decoder->priv;
priv->hw_profile = GST_VAAPI_PROFILE_UNKNOWN;
priv->profile = GST_VAAPI_PROFILE_MPEG2_SIMPLE;
priv->profile_changed = TRUE; /* Allow fallbacks to work */
return TRUE;
}
@ -450,7 +472,7 @@ static GstVaapiProfile
get_profile(GstVaapiDecoderMpeg2 *decoder, GstVaapiEntrypoint entrypoint)
{
GstVaapiDisplay * const va_display = GST_VAAPI_DECODER_DISPLAY(decoder);
GstVaapiDecoderMpeg2Private * const priv = decoder->priv;
GstVaapiDecoderMpeg2Private * const priv = &decoder->priv;
GstVaapiProfile profile = priv->profile;
do {
@ -491,7 +513,7 @@ get_profile(GstVaapiDecoderMpeg2 *decoder, GstVaapiEntrypoint entrypoint)
static GstVaapiDecoderStatus
ensure_context(GstVaapiDecoderMpeg2 *decoder)
{
GstVaapiDecoderMpeg2Private * const priv = decoder->priv;
GstVaapiDecoderMpeg2Private * const priv = &decoder->priv;
GstVaapiEntrypoint entrypoint = GST_VAAPI_ENTRYPOINT_VLD;
gboolean reset_context = FALSE;
@ -532,7 +554,7 @@ ensure_context(GstVaapiDecoderMpeg2 *decoder)
static GstVaapiDecoderStatus
ensure_quant_matrix(GstVaapiDecoderMpeg2 *decoder, GstVaapiPicture *picture)
{
GstVaapiDecoderMpeg2Private * const priv = decoder->priv;
GstVaapiDecoderMpeg2Private * const priv = &decoder->priv;
GstMpegVideoSequenceHdr * const seq_hdr = &priv->seq_hdr->data.seq_hdr;
VAIQMatrixBufferMPEG2 *iq_matrix;
guint8 *intra_quant_matrix = NULL;
@ -593,7 +615,7 @@ ensure_quant_matrix(GstVaapiDecoderMpeg2 *decoder, GstVaapiPicture *picture)
static inline gboolean
is_valid_state(GstVaapiDecoderMpeg2 *decoder, guint state)
{
GstVaapiDecoderMpeg2Private * const priv = decoder->priv;
GstVaapiDecoderMpeg2Private * const priv = &decoder->priv;
return (priv->state & state) == state;
}
@ -601,7 +623,7 @@ is_valid_state(GstVaapiDecoderMpeg2 *decoder, guint state)
static GstVaapiDecoderStatus
decode_current_picture(GstVaapiDecoderMpeg2 *decoder)
{
GstVaapiDecoderMpeg2Private * const priv = decoder->priv;
GstVaapiDecoderMpeg2Private * const priv = &decoder->priv;
GstVaapiPicture * const picture = priv->current_picture;
if (!is_valid_state(decoder, GST_MPEG_VIDEO_STATE_VALID_PICTURE))
@ -634,7 +656,7 @@ static GstVaapiDecoderStatus
parse_sequence(GstVaapiDecoderMpeg2 *decoder,
GstVaapiDecoderUnit *unit, GstMpegVideoPacket *packet)
{
GstVaapiDecoderMpeg2Private * const priv = decoder->priv;
GstVaapiDecoderMpeg2Private * const priv = &decoder->priv;
GstMpegVideoSequenceHdr *seq_hdr;
priv->state = 0;
@ -660,7 +682,7 @@ static GstVaapiDecoderStatus
decode_sequence(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit)
{
GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER_CAST(decoder);
GstVaapiDecoderMpeg2Private * const priv = decoder->priv;
GstVaapiDecoderMpeg2Private * const priv = &decoder->priv;
GstMpegVideoSequenceHdr * const seq_hdr = unit->parsed_info;
gst_vaapi_parser_info_mpeg2_replace(&priv->seq_ext, NULL);
@ -685,7 +707,7 @@ static GstVaapiDecoderStatus
parse_sequence_ext(GstVaapiDecoderMpeg2 *decoder,
GstVaapiDecoderUnit *unit, GstMpegVideoPacket *packet)
{
GstVaapiDecoderMpeg2Private * const priv = decoder->priv;
GstVaapiDecoderMpeg2Private * const priv = &decoder->priv;
GstMpegVideoSequenceExt *seq_ext;
priv->state &= GST_MPEG_VIDEO_STATE_GOT_SEQ_HDR;
@ -711,7 +733,7 @@ static GstVaapiDecoderStatus
decode_sequence_ext(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit)
{
GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER_CAST(decoder);
GstVaapiDecoderMpeg2Private * const priv = decoder->priv;
GstVaapiDecoderMpeg2Private * const priv = &decoder->priv;
GstMpegVideoSequenceExt * const seq_ext = unit->parsed_info;
GstVaapiProfile profile;
guint width, height;
@ -770,7 +792,7 @@ static GstVaapiDecoderStatus
parse_sequence_display_ext(GstVaapiDecoderMpeg2 *decoder,
GstVaapiDecoderUnit *unit, GstMpegVideoPacket *packet)
{
GstVaapiDecoderMpeg2Private * const priv = decoder->priv;
GstVaapiDecoderMpeg2Private * const priv = &decoder->priv;
GstMpegVideoSequenceDisplayExt *seq_display_ext;
if (!gst_vaapi_parser_info_mpeg2_ensure(&priv->seq_display_ext)) {
@ -801,7 +823,7 @@ decode_sequence_display_ext(GstVaapiDecoderMpeg2 *decoder,
static GstVaapiDecoderStatus
decode_sequence_end(GstVaapiDecoderMpeg2 *decoder)
{
GstVaapiDecoderMpeg2Private * const priv = decoder->priv;
GstVaapiDecoderMpeg2Private * const priv = &decoder->priv;
gst_vaapi_dpb_flush(priv->dpb);
return GST_VAAPI_DECODER_STATUS_SUCCESS;
@ -811,7 +833,7 @@ static GstVaapiDecoderStatus
parse_quant_matrix_ext(GstVaapiDecoderMpeg2 *decoder,
GstVaapiDecoderUnit *unit, GstMpegVideoPacket *packet)
{
GstVaapiDecoderMpeg2Private * const priv = decoder->priv;
GstVaapiDecoderMpeg2Private * const priv = &decoder->priv;
GstMpegVideoQuantMatrixExt *quant_matrix;
if (!gst_vaapi_parser_info_mpeg2_ensure(&priv->quant_matrix)) {
@ -835,7 +857,7 @@ static GstVaapiDecoderStatus
decode_quant_matrix_ext(GstVaapiDecoderMpeg2 *decoder,
GstVaapiDecoderUnit *unit)
{
GstVaapiDecoderMpeg2Private * const priv = decoder->priv;
GstVaapiDecoderMpeg2Private * const priv = &decoder->priv;
priv->quant_matrix_changed = TRUE;
return GST_VAAPI_DECODER_STATUS_SUCCESS;
@ -845,7 +867,7 @@ static GstVaapiDecoderStatus
parse_gop(GstVaapiDecoderMpeg2 *decoder,
GstVaapiDecoderUnit *unit, GstMpegVideoPacket *packet)
{
GstVaapiDecoderMpeg2Private * const priv = decoder->priv;
GstVaapiDecoderMpeg2Private * const priv = &decoder->priv;
GstMpegVideoGop *gop;
if (!gst_vaapi_parser_info_mpeg2_ensure(&priv->gop)) {
@ -868,7 +890,7 @@ parse_gop(GstVaapiDecoderMpeg2 *decoder,
static GstVaapiDecoderStatus
decode_gop(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit)
{
GstVaapiDecoderMpeg2Private * const priv = decoder->priv;
GstVaapiDecoderMpeg2Private * const priv = &decoder->priv;
GstMpegVideoGop * const gop = unit->parsed_info;
priv->closed_gop = gop->closed_gop;
@ -886,7 +908,7 @@ static GstVaapiDecoderStatus
parse_picture(GstVaapiDecoderMpeg2 *decoder,
GstVaapiDecoderUnit *unit, GstMpegVideoPacket *packet)
{
GstVaapiDecoderMpeg2Private * const priv = decoder->priv;
GstVaapiDecoderMpeg2Private * const priv = &decoder->priv;
GstMpegVideoPictureHdr *pic_hdr;
priv->state &= (GST_MPEG_VIDEO_STATE_GOT_SEQ_HDR|
@ -912,7 +934,7 @@ parse_picture(GstVaapiDecoderMpeg2 *decoder,
static GstVaapiDecoderStatus
decode_picture(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit)
{
GstVaapiDecoderMpeg2Private * const priv = decoder->priv;
GstVaapiDecoderMpeg2Private * const priv = &decoder->priv;
if (!is_valid_state(decoder, GST_MPEG_VIDEO_STATE_VALID_SEQ_HEADERS))
return GST_VAAPI_DECODER_STATUS_SUCCESS;
@ -927,7 +949,7 @@ static GstVaapiDecoderStatus
parse_picture_ext(GstVaapiDecoderMpeg2 *decoder,
GstVaapiDecoderUnit *unit, GstMpegVideoPacket *packet)
{
GstVaapiDecoderMpeg2Private * const priv = decoder->priv;
GstVaapiDecoderMpeg2Private * const priv = &decoder->priv;
GstMpegVideoPictureExt *pic_ext;
priv->state &= (GST_MPEG_VIDEO_STATE_GOT_SEQ_HDR|
@ -954,7 +976,7 @@ parse_picture_ext(GstVaapiDecoderMpeg2 *decoder,
static GstVaapiDecoderStatus
decode_picture_ext(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit)
{
GstVaapiDecoderMpeg2Private * const priv = decoder->priv;
GstVaapiDecoderMpeg2Private * const priv = &decoder->priv;
GstMpegVideoPictureExt * const pic_ext = unit->parsed_info;
if (!is_valid_state(decoder, GST_MPEG_VIDEO_STATE_GOT_PIC_HDR))
@ -989,7 +1011,7 @@ pack_f_code(guint8 f_code[2][2])
static GstVaapiDecoderStatus
init_picture(GstVaapiDecoderMpeg2 *decoder, GstVaapiPicture *picture)
{
GstVaapiDecoderMpeg2Private * const priv = decoder->priv;
GstVaapiDecoderMpeg2Private * const priv = &decoder->priv;
GstMpegVideoPictureHdr * const pic_hdr = &priv->pic_hdr->data.pic_hdr;
GstMpegVideoPictureExt * const pic_ext = &priv->pic_ext->data.pic_ext;
@ -1071,7 +1093,7 @@ init_picture(GstVaapiDecoderMpeg2 *decoder, GstVaapiPicture *picture)
static void
fill_picture(GstVaapiDecoderMpeg2 *decoder, GstVaapiPicture *picture)
{
GstVaapiDecoderMpeg2Private * const priv = decoder->priv;
GstVaapiDecoderMpeg2Private * const priv = &decoder->priv;
VAPictureParameterBufferMPEG2 * const pic_param = picture->param;
GstMpegVideoPictureHdr * const pic_hdr = &priv->pic_hdr->data.pic_hdr;
GstMpegVideoPictureExt * const pic_ext = &priv->pic_ext->data.pic_ext;
@ -1124,7 +1146,7 @@ static GstVaapiDecoderStatus
parse_slice(GstVaapiDecoderMpeg2 *decoder,
GstVaapiDecoderUnit *unit, GstMpegVideoPacket *packet)
{
GstVaapiDecoderMpeg2Private * const priv = decoder->priv;
GstVaapiDecoderMpeg2Private * const priv = &decoder->priv;
GstMpegVideoSliceHdr *slice_hdr;
GstBitReader br;
gint mb_x, mb_y, mb_inc;
@ -1190,7 +1212,7 @@ failed:
static GstVaapiDecoderStatus
decode_slice(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit)
{
GstVaapiDecoderMpeg2Private * const priv = decoder->priv;
GstVaapiDecoderMpeg2Private * const priv = &decoder->priv;
GstVaapiPicture * const picture = priv->current_picture;
GstVaapiSlice *slice;
VASliceParameterBufferMPEG2 *slice_param;
@ -1367,10 +1389,7 @@ decode_unit(GstVaapiDecoderMpeg2 *decoder, GstVaapiDecoderUnit *unit,
static GstVaapiDecoderStatus
ensure_decoder(GstVaapiDecoderMpeg2 *decoder)
{
GstVaapiDecoderMpeg2Private * const priv = decoder->priv;
g_return_val_if_fail(priv->is_constructed,
GST_VAAPI_DECODER_STATUS_ERROR_INIT_FAILED);
GstVaapiDecoderMpeg2Private * const priv = &decoder->priv;
if (!priv->is_opened) {
priv->is_opened = gst_vaapi_decoder_mpeg2_open(decoder);
@ -1513,7 +1532,7 @@ gst_vaapi_decoder_mpeg2_start_frame(GstVaapiDecoder *base_decoder,
{
GstVaapiDecoderMpeg2 * const decoder =
GST_VAAPI_DECODER_MPEG2_CAST(base_decoder);
GstVaapiDecoderMpeg2Private * const priv = decoder->priv;
GstVaapiDecoderMpeg2Private * const priv = &decoder->priv;
GstMpegVideoSequenceHdr *seq_hdr;
GstMpegVideoSequenceExt *seq_ext;
GstMpegVideoSequenceDisplayExt *seq_display_ext;
@ -1588,47 +1607,24 @@ gst_vaapi_decoder_mpeg2_flush(GstVaapiDecoder *base_decoder)
{
GstVaapiDecoderMpeg2 * const decoder =
GST_VAAPI_DECODER_MPEG2_CAST(base_decoder);
GstVaapiDecoderMpeg2Private * const priv = decoder->priv;
GstVaapiDecoderMpeg2Private * const priv = &decoder->priv;
gst_vaapi_dpb_flush(priv->dpb);
return GST_VAAPI_DECODER_STATUS_SUCCESS;
}
static void
gst_vaapi_decoder_mpeg2_finalize(GObject *object)
{
GstVaapiDecoderMpeg2 * const decoder = GST_VAAPI_DECODER_MPEG2_CAST(object);
gst_vaapi_decoder_mpeg2_destroy(decoder);
G_OBJECT_CLASS(gst_vaapi_decoder_mpeg2_parent_class)->finalize(object);
}
static void
gst_vaapi_decoder_mpeg2_constructed(GObject *object)
{
GstVaapiDecoderMpeg2 * const decoder = GST_VAAPI_DECODER_MPEG2_CAST(object);
GstVaapiDecoderMpeg2Private * const priv = decoder->priv;
GObjectClass *parent_class;
parent_class = G_OBJECT_CLASS(gst_vaapi_decoder_mpeg2_parent_class);
if (parent_class->constructed)
parent_class->constructed(object);
priv->is_constructed = gst_vaapi_decoder_mpeg2_create(decoder);
}
static void
gst_vaapi_decoder_mpeg2_class_init(GstVaapiDecoderMpeg2Class *klass)
{
GObjectClass * const object_class = G_OBJECT_CLASS(klass);
GstVaapiMiniObjectClass * const object_class =
GST_VAAPI_MINI_OBJECT_CLASS(klass);
GstVaapiDecoderClass * const decoder_class = GST_VAAPI_DECODER_CLASS(klass);
g_type_class_add_private(klass, sizeof(GstVaapiDecoderMpeg2Private));
object_class->finalize = gst_vaapi_decoder_mpeg2_finalize;
object_class->constructed = gst_vaapi_decoder_mpeg2_constructed;
object_class->size = sizeof(GstVaapiDecoderMpeg2);
object_class->finalize = (GDestroyNotify)gst_vaapi_decoder_finalize;
decoder_class->create = gst_vaapi_decoder_mpeg2_create;
decoder_class->destroy = gst_vaapi_decoder_mpeg2_destroy;
decoder_class->parse = gst_vaapi_decoder_mpeg2_parse;
decoder_class->decode = gst_vaapi_decoder_mpeg2_decode;
decoder_class->start_frame = gst_vaapi_decoder_mpeg2_start_frame;
@ -1636,16 +1632,17 @@ gst_vaapi_decoder_mpeg2_class_init(GstVaapiDecoderMpeg2Class *klass)
decoder_class->flush = gst_vaapi_decoder_mpeg2_flush;
}
static void
gst_vaapi_decoder_mpeg2_init(GstVaapiDecoderMpeg2 *decoder)
static inline const GstVaapiDecoderClass *
gst_vaapi_decoder_mpeg2_class(void)
{
GstVaapiDecoderMpeg2Private *priv;
static GstVaapiDecoderMpeg2Class g_class;
static gsize g_class_init = FALSE;
priv = GST_VAAPI_DECODER_MPEG2_GET_PRIVATE(decoder);
decoder->priv = priv;
priv->hw_profile = GST_VAAPI_PROFILE_UNKNOWN;
priv->profile = GST_VAAPI_PROFILE_MPEG2_SIMPLE;
priv->profile_changed = TRUE; /* Allow fallbacks to work */
if (g_once_init_enter(&g_class_init)) {
gst_vaapi_decoder_mpeg2_class_init(&g_class);
g_once_init_leave(&g_class_init, TRUE);
}
return GST_VAAPI_DECODER_CLASS(&g_class);
}
/**
@ -1661,20 +1658,6 @@ gst_vaapi_decoder_mpeg2_init(GstVaapiDecoderMpeg2 *decoder)
GstVaapiDecoder *
gst_vaapi_decoder_mpeg2_new(GstVaapiDisplay *display, GstCaps *caps)
{
GstVaapiDecoderMpeg2 *decoder;
g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL);
g_return_val_if_fail(GST_IS_CAPS(caps), NULL);
decoder = g_object_new(
GST_VAAPI_TYPE_DECODER_MPEG2,
"display", display,
"caps", caps,
NULL
);
if (!decoder->priv->is_constructed) {
g_object_unref(decoder);
return NULL;
}
return GST_VAAPI_DECODER_CAST(decoder);
return gst_vaapi_decoder_new(gst_vaapi_decoder_mpeg2_class(),
display, caps);
}

View file

@ -27,58 +27,7 @@
G_BEGIN_DECLS
#define GST_VAAPI_TYPE_DECODER_MPEG2 \
(gst_vaapi_decoder_mpeg2_get_type())
#define GST_VAAPI_DECODER_MPEG2(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj), \
GST_VAAPI_TYPE_DECODER_MPEG2, \
GstVaapiDecoderMpeg2))
#define GST_VAAPI_DECODER_MPEG2_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass), \
GST_VAAPI_TYPE_DECODER_MPEG2, \
GstVaapiDecoderMpeg2Class))
#define GST_VAAPI_IS_DECODER_MPEG2(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_DECODER_MPEG2))
#define GST_VAAPI_IS_DECODER_MPEG2_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_DECODER_MPEG2))
#define GST_VAAPI_DECODER_MPEG2_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS((obj), \
GST_VAAPI_TYPE_DECODER_MPEG2, \
GstVaapiDecoderMpeg2Class))
typedef struct _GstVaapiDecoderMpeg2 GstVaapiDecoderMpeg2;
typedef struct _GstVaapiDecoderMpeg2Private GstVaapiDecoderMpeg2Private;
typedef struct _GstVaapiDecoderMpeg2Class GstVaapiDecoderMpeg2Class;
/**
* GstVaapiDecoderMpeg2:
*
* A decoder based on Mpeg2.
*/
struct _GstVaapiDecoderMpeg2 {
/*< private >*/
GstVaapiDecoder parent_instance;
GstVaapiDecoderMpeg2Private *priv;
};
/**
* GstVaapiDecoderMpeg2Class:
*
* A decoder class based on Mpeg2.
*/
struct _GstVaapiDecoderMpeg2Class {
/*< private >*/
GstVaapiDecoderClass parent_class;
};
GType
gst_vaapi_decoder_mpeg2_get_type(void) G_GNUC_CONST;
GstVaapiDecoder *
gst_vaapi_decoder_mpeg2_new(GstVaapiDisplay *display, GstCaps *caps);

View file

@ -37,17 +37,11 @@
#define DEBUG 1
#include "gstvaapidebug.h"
G_DEFINE_TYPE(GstVaapiDecoderMpeg4,
gst_vaapi_decoder_mpeg4,
GST_VAAPI_TYPE_DECODER)
#define GST_VAAPI_DECODER_MPEG4_CAST(decoder) \
((GstVaapiDecoderMpeg4 *)(decoder))
#define GST_VAAPI_DECODER_MPEG4_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE((obj), \
GST_VAAPI_TYPE_DECODER_MPEG4, \
GstVaapiDecoderMpeg4Private))
typedef struct _GstVaapiDecoderMpeg4Private GstVaapiDecoderMpeg4Private;
typedef struct _GstVaapiDecoderMpeg4Class GstVaapiDecoderMpeg4Class;
struct _GstVaapiDecoderMpeg4Private {
GstVaapiProfile profile;
@ -89,7 +83,6 @@ struct _GstVaapiDecoderMpeg4Private {
GstClockTime trd;
// temporal_reference of previous frame of svh
guint8 prev_t_ref;
guint is_constructed : 1;
guint is_opened : 1;
guint is_first_field : 1;
guint size_changed : 1;
@ -101,10 +94,32 @@ struct _GstVaapiDecoderMpeg4Private {
guint is_svh : 1;
};
/**
* GstVaapiDecoderMpeg4:
*
* A decoder based on Mpeg4.
*/
struct _GstVaapiDecoderMpeg4 {
/*< private >*/
GstVaapiDecoder parent_instance;
GstVaapiDecoderMpeg4Private priv;
};
/**
* GstVaapiDecoderMpeg4Class:
*
* A decoder class based on Mpeg4.
*/
typedef struct _GstVaapiDecoderMpeg4Class GstVaapiDecoderMpeg4Class;
struct _GstVaapiDecoderMpeg4Class {
/*< private >*/
GstVaapiDecoderClass parent_class;
};
static void
gst_vaapi_decoder_mpeg4_close(GstVaapiDecoderMpeg4 *decoder)
{
GstVaapiDecoderMpeg4Private * const priv = decoder->priv;
GstVaapiDecoderMpeg4Private * const priv = &decoder->priv;
gst_vaapi_picture_replace(&priv->curr_picture, NULL);
gst_vaapi_picture_replace(&priv->next_picture, NULL);
@ -115,7 +130,7 @@ static gboolean
gst_vaapi_decoder_mpeg4_open(GstVaapiDecoderMpeg4 *decoder)
{
GstVaapiDecoder *const base_decoder = GST_VAAPI_DECODER(decoder);
GstVaapiDecoderMpeg4Private * const priv = decoder->priv;
GstVaapiDecoderMpeg4Private * const priv = &decoder->priv;
GstCaps *caps = NULL;
GstStructure *structure = NULL;
@ -137,16 +152,28 @@ gst_vaapi_decoder_mpeg4_open(GstVaapiDecoderMpeg4 *decoder)
}
static void
gst_vaapi_decoder_mpeg4_destroy(GstVaapiDecoderMpeg4 *decoder)
gst_vaapi_decoder_mpeg4_destroy(GstVaapiDecoder *base_decoder)
{
GstVaapiDecoderMpeg4 * const decoder =
GST_VAAPI_DECODER_MPEG4_CAST(base_decoder);
gst_vaapi_decoder_mpeg4_close(decoder);
}
static gboolean
gst_vaapi_decoder_mpeg4_create(GstVaapiDecoderMpeg4 *decoder)
gst_vaapi_decoder_mpeg4_create(GstVaapiDecoder *base_decoder)
{
if (!GST_VAAPI_DECODER_CODEC(decoder))
return FALSE;
GstVaapiDecoderMpeg4 * const decoder =
GST_VAAPI_DECODER_MPEG4_CAST(base_decoder);
GstVaapiDecoderMpeg4Private * const priv = &decoder->priv;
priv->profile = GST_VAAPI_PROFILE_MPEG4_SIMPLE;
priv->seq_pts = GST_CLOCK_TIME_NONE;
priv->gop_pts = GST_CLOCK_TIME_NONE;
priv->max_pts = GST_CLOCK_TIME_NONE;
priv->calculate_pts_diff = TRUE;
priv->size_changed = TRUE;
priv->profile_changed = TRUE;
return TRUE;
}
@ -159,7 +186,7 @@ copy_quant_matrix(guint8 dst[64], const guint8 src[64])
static GstVaapiDecoderStatus
ensure_context(GstVaapiDecoderMpeg4 *decoder)
{
GstVaapiDecoderMpeg4Private * const priv = decoder->priv;
GstVaapiDecoderMpeg4Private * const priv = &decoder->priv;
GstVaapiProfile profiles[2];
GstVaapiEntrypoint entrypoint = GST_VAAPI_ENTRYPOINT_VLD;
guint i, n_profiles = 0;
@ -211,7 +238,7 @@ ensure_context(GstVaapiDecoderMpeg4 *decoder)
static GstVaapiDecoderStatus
ensure_quant_matrix(GstVaapiDecoderMpeg4 *decoder, GstVaapiPicture *picture)
{
GstVaapiDecoderMpeg4Private * const priv = decoder->priv;
GstVaapiDecoderMpeg4Private * const priv = &decoder->priv;
VAIQMatrixBufferMPEG4 *iq_matrix;
if (!priv->vol_hdr.load_intra_quant_mat && !priv->vol_hdr.load_non_intra_quant_mat) {
@ -260,7 +287,7 @@ render_picture(GstVaapiDecoderMpeg4 *decoder, GstVaapiPicture *picture)
static GstVaapiDecoderStatus
decode_current_picture(GstVaapiDecoderMpeg4 *decoder)
{
GstVaapiDecoderMpeg4Private * const priv = decoder->priv;
GstVaapiDecoderMpeg4Private * const priv = &decoder->priv;
GstVaapiPicture * const picture = priv->curr_picture;
GstVaapiDecoderStatus status = GST_VAAPI_DECODER_STATUS_SUCCESS;
@ -280,7 +307,7 @@ decode_current_picture(GstVaapiDecoderMpeg4 *decoder)
static GstVaapiDecoderStatus
decode_sequence(GstVaapiDecoderMpeg4 *decoder, const guint8 *buf, guint buf_size)
{
GstVaapiDecoderMpeg4Private * const priv = decoder->priv;
GstVaapiDecoderMpeg4Private * const priv = &decoder->priv;
GstMpeg4VisualObjectSequence * const vos_hdr = &priv->vos_hdr;
GstVaapiProfile profile;
@ -315,7 +342,7 @@ decode_sequence(GstVaapiDecoderMpeg4 *decoder, const guint8 *buf, guint buf_size
static GstVaapiDecoderStatus
decode_sequence_end(GstVaapiDecoderMpeg4 *decoder)
{
GstVaapiDecoderMpeg4Private * const priv = decoder->priv;
GstVaapiDecoderMpeg4Private * const priv = &decoder->priv;
GstVaapiDecoderStatus status;
if (priv->curr_picture) {
@ -338,7 +365,7 @@ decode_sequence_end(GstVaapiDecoderMpeg4 *decoder)
static GstVaapiDecoderStatus
decode_visual_object(GstVaapiDecoderMpeg4 *decoder, const guint8 *buf, guint buf_size)
{
GstVaapiDecoderMpeg4Private * const priv = decoder->priv;
GstVaapiDecoderMpeg4Private * const priv = &decoder->priv;
GstMpeg4VisualObject * vo_hdr = &priv->vo_hdr;
GstMpeg4VideoSignalType * signal_type = &priv->signal_type;
@ -355,7 +382,7 @@ static GstVaapiDecoderStatus
decode_video_object_layer(GstVaapiDecoderMpeg4 *decoder, const guint8 *buf, guint buf_size)
{
GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder);
GstVaapiDecoderMpeg4Private * const priv = decoder->priv;
GstVaapiDecoderMpeg4Private * const priv = &decoder->priv;
GstMpeg4VisualObject * vo_hdr = &priv->vo_hdr;
GstMpeg4VideoObjectLayer * vol_hdr = &priv->vol_hdr;
@ -384,7 +411,7 @@ decode_video_object_layer(GstVaapiDecoderMpeg4 *decoder, const guint8 *buf, guin
static GstVaapiDecoderStatus
decode_gop(GstVaapiDecoderMpeg4 *decoder, const guint8 *buf, guint buf_size)
{
GstVaapiDecoderMpeg4Private * const priv = decoder->priv;
GstVaapiDecoderMpeg4Private * const priv = &decoder->priv;
GstMpeg4GroupOfVOP gop;
GstClockTime gop_time;
@ -427,7 +454,7 @@ calculate_pts_diff(GstVaapiDecoderMpeg4 *decoder,
GstMpeg4VideoObjectLayer *vol_hdr,
GstMpeg4VideoObjectPlane *vop_hdr)
{
GstVaapiDecoderMpeg4Private * const priv = decoder->priv;
GstVaapiDecoderMpeg4Private * const priv = &decoder->priv;
GstClockTime frame_timestamp;
frame_timestamp = GST_VAAPI_DECODER_CODEC_FRAME(decoder)->pts;
@ -473,7 +500,7 @@ static GstVaapiDecoderStatus
decode_picture(GstVaapiDecoderMpeg4 *decoder, const guint8 *buf, guint buf_size)
{
GstMpeg4ParseResult parser_result = GST_MPEG4_PARSER_OK;
GstVaapiDecoderMpeg4Private * const priv = decoder->priv;
GstVaapiDecoderMpeg4Private * const priv = &decoder->priv;
GstMpeg4VideoObjectPlane * const vop_hdr = &priv->vop_hdr;
GstMpeg4VideoObjectLayer * const vol_hdr = &priv->vol_hdr;
GstMpeg4SpriteTrajectory * const sprite_trajectory = &priv->sprite_trajectory;
@ -643,7 +670,7 @@ get_vop_coding_type(GstVaapiPicture *picture)
static gboolean
fill_picture(GstVaapiDecoderMpeg4 *decoder, GstVaapiPicture *picture)
{
GstVaapiDecoderMpeg4Private * const priv = decoder->priv;
GstVaapiDecoderMpeg4Private * const priv = &decoder->priv;
VAPictureParameterBufferMPEG4 * const pic_param = picture->param;
GstMpeg4VideoObjectPlane * const vop_hdr = &priv->vop_hdr;
@ -742,7 +769,7 @@ decode_slice(
gboolean has_packet_header
)
{
GstVaapiDecoderMpeg4Private * const priv = decoder->priv;
GstVaapiDecoderMpeg4Private * const priv = &decoder->priv;
GstVaapiPicture * const picture = priv->curr_picture;
GstVaapiSlice *slice;
VASliceParameterBufferMPEG4 *slice_param;
@ -786,7 +813,7 @@ decode_slice(
static GstVaapiDecoderStatus
decode_packet(GstVaapiDecoderMpeg4 *decoder, GstMpeg4Packet packet)
{
GstVaapiDecoderMpeg4Private * const priv = decoder->priv;
GstVaapiDecoderMpeg4Private * const priv = &decoder->priv;
GstMpeg4Packet *tos = &packet;
GstVaapiDecoderStatus status;
@ -895,7 +922,7 @@ decode_packet(GstVaapiDecoderMpeg4 *decoder, GstMpeg4Packet packet)
static GstVaapiDecoderStatus
decode_buffer(GstVaapiDecoderMpeg4 *decoder, const guchar *buf, guint buf_size)
{
GstVaapiDecoderMpeg4Private * const priv = decoder->priv;
GstVaapiDecoderMpeg4Private * const priv = &decoder->priv;
GstVaapiDecoderStatus status;
GstMpeg4Packet packet;
guint ofs;
@ -967,12 +994,9 @@ gst_vaapi_decoder_mpeg4_decode_codec_data(GstVaapiDecoder *base_decoder,
static GstVaapiDecoderStatus
ensure_decoder(GstVaapiDecoderMpeg4 *decoder)
{
GstVaapiDecoderMpeg4Private * const priv = decoder->priv;
GstVaapiDecoderMpeg4Private * const priv = &decoder->priv;
GstVaapiDecoderStatus status;
g_return_val_if_fail(priv->is_constructed,
GST_VAAPI_DECODER_STATUS_ERROR_INIT_FAILED);
if (!priv->is_opened) {
priv->is_opened = gst_vaapi_decoder_mpeg4_open(decoder);
if (!priv->is_opened)
@ -991,8 +1015,8 @@ gst_vaapi_decoder_mpeg4_parse(GstVaapiDecoder *base_decoder,
GstAdapter *adapter, gboolean at_eos, GstVaapiDecoderUnit *unit)
{
GstVaapiDecoderMpeg4 * const decoder =
GST_VAAPI_DECODER_MPEG4(base_decoder);
GstVaapiDecoderMpeg4Private * const priv = decoder->priv;
GST_VAAPI_DECODER_MPEG4_CAST(base_decoder);
GstVaapiDecoderMpeg4Private * const priv = &decoder->priv;
GstVaapiDecoderStatus status;
GstMpeg4Packet packet;
GstMpeg4ParseResult result;
@ -1081,7 +1105,7 @@ gst_vaapi_decoder_mpeg4_decode(GstVaapiDecoder *base_decoder,
GstVaapiDecoderUnit *unit)
{
GstVaapiDecoderMpeg4 * const decoder =
GST_VAAPI_DECODER_MPEG4(base_decoder);
GST_VAAPI_DECODER_MPEG4_CAST(base_decoder);
GstVaapiDecoderStatus status;
GstBuffer * const buffer =
GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer;
@ -1103,41 +1127,18 @@ gst_vaapi_decoder_mpeg4_decode(GstVaapiDecoder *base_decoder,
return GST_VAAPI_DECODER_STATUS_SUCCESS;
}
static void
gst_vaapi_decoder_mpeg4_finalize(GObject *object)
{
GstVaapiDecoderMpeg4 * const decoder = GST_VAAPI_DECODER_MPEG4(object);
gst_vaapi_decoder_mpeg4_destroy(decoder);
G_OBJECT_CLASS(gst_vaapi_decoder_mpeg4_parent_class)->finalize(object);
}
static void
gst_vaapi_decoder_mpeg4_constructed(GObject *object)
{
GstVaapiDecoderMpeg4 * const decoder = GST_VAAPI_DECODER_MPEG4(object);
GstVaapiDecoderMpeg4Private * const priv = decoder->priv;
GObjectClass *parent_class;
parent_class = G_OBJECT_CLASS(gst_vaapi_decoder_mpeg4_parent_class);
if (parent_class->constructed)
parent_class->constructed(object);
priv->is_constructed = gst_vaapi_decoder_mpeg4_create(decoder);
}
static void
gst_vaapi_decoder_mpeg4_class_init(GstVaapiDecoderMpeg4Class *klass)
{
GObjectClass * const object_class = G_OBJECT_CLASS(klass);
GstVaapiMiniObjectClass * const object_class =
GST_VAAPI_MINI_OBJECT_CLASS(klass);
GstVaapiDecoderClass * const decoder_class = GST_VAAPI_DECODER_CLASS(klass);
g_type_class_add_private(klass, sizeof(GstVaapiDecoderMpeg4Private));
object_class->finalize = gst_vaapi_decoder_mpeg4_finalize;
object_class->constructed = gst_vaapi_decoder_mpeg4_constructed;
object_class->size = sizeof(GstVaapiDecoderMpeg4);
object_class->finalize = (GDestroyNotify)gst_vaapi_decoder_finalize;
decoder_class->create = gst_vaapi_decoder_mpeg4_create;
decoder_class->destroy = gst_vaapi_decoder_mpeg4_destroy;
decoder_class->parse = gst_vaapi_decoder_mpeg4_parse;
decoder_class->decode = gst_vaapi_decoder_mpeg4_decode;
@ -1145,38 +1146,17 @@ gst_vaapi_decoder_mpeg4_class_init(GstVaapiDecoderMpeg4Class *klass)
gst_vaapi_decoder_mpeg4_decode_codec_data;
}
static void
gst_vaapi_decoder_mpeg4_init(GstVaapiDecoderMpeg4 *decoder)
static inline const GstVaapiDecoderClass *
gst_vaapi_decoder_mpeg4_class(void)
{
GstVaapiDecoderMpeg4Private *priv;
static GstVaapiDecoderMpeg4Class g_class;
static gsize g_class_init = FALSE;
priv = GST_VAAPI_DECODER_MPEG4_GET_PRIVATE(decoder);
decoder->priv = priv;
priv->width = 0;
priv->height = 0;
priv->fps_n = 0;
priv->fps_d = 0;
priv->profile = GST_VAAPI_PROFILE_MPEG4_SIMPLE;
priv->curr_picture = NULL;
priv->next_picture = NULL;
priv->prev_picture = NULL;
priv->seq_pts = GST_CLOCK_TIME_NONE;
priv->gop_pts = GST_CLOCK_TIME_NONE;
priv->max_pts = GST_CLOCK_TIME_NONE;
priv->pts_diff = 0;
priv->calculate_pts_diff = TRUE;
priv->is_constructed = FALSE;
priv->is_opened = FALSE;
priv->is_first_field = FALSE;
priv->size_changed = TRUE;
priv->profile_changed = TRUE;
priv->progressive_sequence = FALSE;
priv->closed_gop = FALSE;
priv->broken_link = FALSE;
priv->last_non_b_scale_time = 0;
priv->non_b_scale_time = 0;
priv->trb = 0;
priv->trd = 0;
if (g_once_init_enter(&g_class_init)) {
gst_vaapi_decoder_mpeg4_class_init(&g_class);
g_once_init_leave(&g_class_init, TRUE);
}
return GST_VAAPI_DECODER_CLASS(&g_class);
}
/**
@ -1192,20 +1172,6 @@ gst_vaapi_decoder_mpeg4_init(GstVaapiDecoderMpeg4 *decoder)
GstVaapiDecoder *
gst_vaapi_decoder_mpeg4_new(GstVaapiDisplay *display, GstCaps *caps)
{
GstVaapiDecoderMpeg4 *decoder;
g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL);
g_return_val_if_fail(GST_IS_CAPS(caps), NULL);
decoder = g_object_new(
GST_VAAPI_TYPE_DECODER_MPEG4,
"display", display,
"caps", caps,
NULL
);
if (!decoder->priv->is_constructed) {
g_object_unref(decoder);
return NULL;
}
return GST_VAAPI_DECODER_CAST(decoder);
return gst_vaapi_decoder_new(gst_vaapi_decoder_mpeg4_class(),
display, caps);
}

View file

@ -27,58 +27,7 @@
G_BEGIN_DECLS
#define GST_VAAPI_TYPE_DECODER_MPEG4 \
(gst_vaapi_decoder_mpeg4_get_type())
#define GST_VAAPI_DECODER_MPEG4(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj), \
GST_VAAPI_TYPE_DECODER_MPEG4, \
GstVaapiDecoderMpeg4))
#define GST_VAAPI_DECODER_MPEG4_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass), \
GST_VAAPI_TYPE_DECODER_MPEG4, \
GstVaapiDecoderMpeg4Class))
#define GST_VAAPI_IS_DECODER_MPEG4(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_DECODER_MPEG4))
#define GST_VAAPI_IS_DECODER_MPEG4_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_DECODER_MPEG4))
#define GST_VAAPI_DECODER_MPEG4_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS((obj), \
GST_VAAPI_TYPE_DECODER_MPEG4, \
GstVaapiDecoderMpeg4Class))
typedef struct _GstVaapiDecoderMpeg4 GstVaapiDecoderMpeg4;
typedef struct _GstVaapiDecoderMpeg4Private GstVaapiDecoderMpeg4Private;
typedef struct _GstVaapiDecoderMpeg4Class GstVaapiDecoderMpeg4Class;
/**
* GstVaapiDecoderMpeg4:
*
* A decoder based on Mpeg4.
*/
struct _GstVaapiDecoderMpeg4 {
/*< private >*/
GstVaapiDecoder parent_instance;
GstVaapiDecoderMpeg4Private *priv;
};
/**
* GstVaapiDecoderMpeg4Class:
*
* A decoder class based on Mpeg4.
*/
struct _GstVaapiDecoderMpeg4Class {
/*< private >*/
GstVaapiDecoderClass parent_class;
};
GType
gst_vaapi_decoder_mpeg4_get_type(void) G_GNUC_CONST;
GstVaapiDecoder *
gst_vaapi_decoder_mpeg4_new(GstVaapiDisplay *display, GstCaps *caps);

View file

@ -33,9 +33,9 @@
#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
#define GET_CONTEXT(obj) GET_DECODER(obj)->context
#define GET_VA_DISPLAY(obj) GET_DECODER(obj)->va_display
#define GET_VA_CONTEXT(obj) GET_DECODER(obj)->va_context
/* ------------------------------------------------------------------------- */
/* --- Pictures --- */

View file

@ -27,10 +27,24 @@
#include <gst/vaapi/gstvaapidecoder.h>
#include <gst/vaapi/gstvaapidecoder_unit.h>
#include <gst/vaapi/gstvaapicontext.h>
#include "gstvaapiminiobject.h"
G_BEGIN_DECLS
#define GST_VAAPI_DECODER_CAST(decoder) ((GstVaapiDecoder *)(decoder))
#define GST_VAAPI_DECODER_CAST(decoder) \
((GstVaapiDecoder *)(decoder))
#define GST_VAAPI_DECODER_CLASS(klass) \
((GstVaapiDecoderClass *)(klass))
#define GST_VAAPI_IS_DECODER_CLASS(klass) \
((klass) != NULL))
#define GST_VAAPI_DECODER_GET_CLASS(obj) \
GST_VAAPI_DECODER_CLASS(GST_VAAPI_MINI_OBJECT_GET_CLASS(obj))
typedef struct _GstVaapiDecoderClass GstVaapiDecoderClass;
struct _GstVaapiDecoderUnit;
/**
* GST_VAAPI_PARSER_STATE:
@ -41,7 +55,7 @@ G_BEGIN_DECLS
*/
#undef GST_VAAPI_PARSER_STATE
#define GST_VAAPI_PARSER_STATE(decoder) \
(&GST_VAAPI_DECODER_CAST(decoder)->priv->parser_state)
(&GST_VAAPI_DECODER_CAST(decoder)->parser_state)
/**
* GST_VAAPI_DECODER_DISPLAY:
@ -52,7 +66,7 @@ G_BEGIN_DECLS
*/
#undef GST_VAAPI_DECODER_DISPLAY
#define GST_VAAPI_DECODER_DISPLAY(decoder) \
GST_VAAPI_DECODER_CAST(decoder)->priv->display
GST_VAAPI_DECODER_CAST(decoder)->display
/**
* GST_VAAPI_DECODER_CONTEXT:
@ -63,7 +77,7 @@ G_BEGIN_DECLS
*/
#undef GST_VAAPI_DECODER_CONTEXT
#define GST_VAAPI_DECODER_CONTEXT(decoder) \
GST_VAAPI_DECODER_CAST(decoder)->priv->context
GST_VAAPI_DECODER_CAST(decoder)->context
/**
* GST_VAAPI_DECODER_CODEC:
@ -74,7 +88,7 @@ G_BEGIN_DECLS
*/
#undef GST_VAAPI_DECODER_CODEC
#define GST_VAAPI_DECODER_CODEC(decoder) \
GST_VAAPI_DECODER_CAST(decoder)->priv->codec
GST_VAAPI_DECODER_CAST(decoder)->codec
/**
* GST_VAAPI_DECODER_CODEC_STATE:
@ -86,7 +100,7 @@ G_BEGIN_DECLS
*/
#undef GST_VAAPI_DECODER_CODEC_STATE
#define GST_VAAPI_DECODER_CODEC_STATE(decoder) \
GST_VAAPI_DECODER_CAST(decoder)->priv->codec_state
GST_VAAPI_DECODER_CAST(decoder)->codec_state
/**
* GST_VAAPI_DECODER_CODEC_DATA:
@ -161,7 +175,16 @@ struct _GstVaapiParserState {
guint at_eos : 1;
};
struct _GstVaapiDecoderPrivate {
/**
* GstVaapiDecoder:
*
* A VA decoder base instance.
*/
struct _GstVaapiDecoder {
/*< private >*/
GstVaapiMiniObject parent_instance;
gpointer user_data;
GstVaapiDisplay *display;
VADisplay va_display;
GstVaapiContext *context;
@ -171,8 +194,43 @@ struct _GstVaapiDecoderPrivate {
GAsyncQueue *buffers;
GAsyncQueue *frames;
GstVaapiParserState parser_state;
GstVaapiDecoderStateChangedFunc codec_state_changed_func;
gpointer codec_state_changed_data;
};
/**
* GstVaapiDecoderClass:
*
* A VA decoder base class.
*/
struct _GstVaapiDecoderClass {
/*< private >*/
GstVaapiMiniObjectClass parent_class;
gboolean (*create)(GstVaapiDecoder *decoder);
void (*destroy)(GstVaapiDecoder *decoder);
GstVaapiDecoderStatus (*parse)(GstVaapiDecoder *decoder,
GstAdapter *adapter, gboolean at_eos,
struct _GstVaapiDecoderUnit *unit);
GstVaapiDecoderStatus (*decode)(GstVaapiDecoder *decoder,
struct _GstVaapiDecoderUnit *unit);
GstVaapiDecoderStatus (*start_frame)(GstVaapiDecoder *decoder,
struct _GstVaapiDecoderUnit *unit);
GstVaapiDecoderStatus (*end_frame)(GstVaapiDecoder *decoder);
GstVaapiDecoderStatus (*flush)(GstVaapiDecoder *decoder);
GstVaapiDecoderStatus (*decode_codec_data)(GstVaapiDecoder *decoder,
const guchar *buf, guint buf_size);
};
G_GNUC_INTERNAL
GstVaapiDecoder *
gst_vaapi_decoder_new(const GstVaapiDecoderClass *klass,
GstVaapiDisplay *display, GstCaps *caps);
G_GNUC_INTERNAL
void
gst_vaapi_decoder_finalize(GstVaapiDecoder *decoder);
G_GNUC_INTERNAL
void
gst_vaapi_decoder_set_picture_size(

View file

@ -38,18 +38,17 @@
#define DEBUG 1
#include "gstvaapidebug.h"
G_DEFINE_TYPE(GstVaapiDecoderVC1,
gst_vaapi_decoder_vc1,
GST_VAAPI_TYPE_DECODER)
#define GST_VAAPI_DECODER_VC1_CAST(decoder) \
((GstVaapiDecoderVC1 *)(decoder))
#define GST_VAAPI_DECODER_VC1_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE((obj), \
GST_VAAPI_TYPE_DECODER_VC1, \
GstVaapiDecoderVC1Private))
typedef struct _GstVaapiDecoderVC1Private GstVaapiDecoderVC1Private;
typedef struct _GstVaapiDecoderVC1Class GstVaapiDecoderVC1Class;
/**
* GstVaapiDecoderVC1:
*
* A decoder based on VC1.
*/
struct _GstVaapiDecoderVC1Private {
GstVaapiProfile profile;
guint width;
@ -64,7 +63,6 @@ struct _GstVaapiDecoderVC1Private {
gint32 next_poc;
guint8 *rbdu_buffer;
guint rbdu_buffer_size;
guint is_constructed : 1;
guint is_opened : 1;
guint is_first_field : 1;
guint has_codec_data : 1;
@ -75,6 +73,27 @@ struct _GstVaapiDecoderVC1Private {
guint broken_link : 1;
};
/**
* GstVaapiDecoderVC1:
*
* A decoder based on VC1.
*/
struct _GstVaapiDecoderVC1 {
/*< private >*/
GstVaapiDecoder parent_instance;
GstVaapiDecoderVC1Private priv;
};
/**
* GstVaapiDecoderVC1Class:
*
* A decoder class based on VC1.
*/
struct _GstVaapiDecoderVC1Class {
/*< private >*/
GstVaapiDecoderClass parent_class;
};
static GstVaapiDecoderStatus
get_status(GstVC1ParserResult result)
{
@ -100,7 +119,7 @@ get_status(GstVC1ParserResult result)
static void
gst_vaapi_decoder_vc1_close(GstVaapiDecoderVC1 *decoder)
{
GstVaapiDecoderVC1Private * const priv = decoder->priv;
GstVaapiDecoderVC1Private * const priv = &decoder->priv;
gst_vaapi_picture_replace(&priv->last_non_b_picture, NULL);
gst_vaapi_picture_replace(&priv->current_picture, NULL);
@ -115,7 +134,7 @@ gst_vaapi_decoder_vc1_close(GstVaapiDecoderVC1 *decoder)
static gboolean
gst_vaapi_decoder_vc1_open(GstVaapiDecoderVC1 *decoder)
{
GstVaapiDecoderVC1Private * const priv = decoder->priv;
GstVaapiDecoderVC1Private * const priv = &decoder->priv;
gst_vaapi_decoder_vc1_close(decoder);
@ -130,9 +149,11 @@ gst_vaapi_decoder_vc1_open(GstVaapiDecoderVC1 *decoder)
}
static void
gst_vaapi_decoder_vc1_destroy(GstVaapiDecoderVC1 *decoder)
gst_vaapi_decoder_vc1_destroy(GstVaapiDecoder *base_decoder)
{
GstVaapiDecoderVC1Private * const priv = decoder->priv;
GstVaapiDecoderVC1 * const decoder =
GST_VAAPI_DECODER_VC1_CAST(base_decoder);
GstVaapiDecoderVC1Private * const priv = &decoder->priv;
gst_vaapi_decoder_vc1_close(decoder);
@ -144,17 +165,20 @@ gst_vaapi_decoder_vc1_destroy(GstVaapiDecoderVC1 *decoder)
}
static gboolean
gst_vaapi_decoder_vc1_create(GstVaapiDecoderVC1 *decoder)
gst_vaapi_decoder_vc1_create(GstVaapiDecoder *base_decoder)
{
if (!GST_VAAPI_DECODER_CODEC(decoder))
return FALSE;
GstVaapiDecoderVC1 * const decoder =
GST_VAAPI_DECODER_VC1_CAST(base_decoder);
GstVaapiDecoderVC1Private * const priv = &decoder->priv;
priv->profile = (GstVaapiProfile)0;
return TRUE;
}
static GstVaapiDecoderStatus
ensure_context(GstVaapiDecoderVC1 *decoder)
{
GstVaapiDecoderVC1Private * const priv = decoder->priv;
GstVaapiDecoderVC1Private * const priv = &decoder->priv;
GstVaapiProfile profiles[2];
GstVaapiEntrypoint entrypoint = GST_VAAPI_ENTRYPOINT_VLD;
guint i, n_profiles = 0;
@ -206,7 +230,7 @@ ensure_context(GstVaapiDecoderVC1 *decoder)
static GstVaapiDecoderStatus
decode_current_picture(GstVaapiDecoderVC1 *decoder)
{
GstVaapiDecoderVC1Private * const priv = decoder->priv;
GstVaapiDecoderVC1Private * const priv = &decoder->priv;
GstVaapiPicture * const picture = priv->current_picture;
if (!picture)
@ -231,7 +255,7 @@ static GstVaapiDecoderStatus
decode_sequence(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;
GstVC1AdvancedSeqHdr * const adv_hdr = &seq_hdr->advanced;
GstVC1SeqStructC * const structc = &seq_hdr->struct_c;
@ -347,7 +371,7 @@ decode_sequence(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu)
static GstVaapiDecoderStatus
decode_sequence_end(GstVaapiDecoderVC1 *decoder)
{
GstVaapiDecoderVC1Private * const priv = decoder->priv;
GstVaapiDecoderVC1Private * const priv = &decoder->priv;
GstVaapiDecoderStatus status;
status = decode_current_picture(decoder);
@ -361,7 +385,7 @@ decode_sequence_end(GstVaapiDecoderVC1 *decoder)
static GstVaapiDecoderStatus
decode_entry_point(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu)
{
GstVaapiDecoderVC1Private * const priv = decoder->priv;
GstVaapiDecoderVC1Private * const priv = &decoder->priv;
GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
GstVC1EntryPointHdr * const entrypoint_hdr = &priv->entrypoint_hdr;
GstVC1ParserResult result;
@ -503,7 +527,7 @@ get_MVMODE2(GstVC1FrameHdr *frame_hdr)
static inline int
has_MVTYPEMB_bitplane(GstVaapiDecoderVC1 *decoder)
{
GstVaapiDecoderVC1Private * const priv = decoder->priv;
GstVaapiDecoderVC1Private * const priv = &decoder->priv;
GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr;
guint mvmode, mvmode2;
@ -531,7 +555,7 @@ has_MVTYPEMB_bitplane(GstVaapiDecoderVC1 *decoder)
static inline int
has_SKIPMB_bitplane(GstVaapiDecoderVC1 *decoder)
{
GstVaapiDecoderVC1Private * const priv = decoder->priv;
GstVaapiDecoderVC1Private * const priv = &decoder->priv;
GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr;
@ -552,7 +576,7 @@ has_SKIPMB_bitplane(GstVaapiDecoderVC1 *decoder)
static inline int
has_DIRECTMB_bitplane(GstVaapiDecoderVC1 *decoder)
{
GstVaapiDecoderVC1Private * const priv = decoder->priv;
GstVaapiDecoderVC1Private * const priv = &decoder->priv;
GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr;
@ -572,7 +596,7 @@ has_DIRECTMB_bitplane(GstVaapiDecoderVC1 *decoder)
static inline int
has_ACPRED_bitplane(GstVaapiDecoderVC1 *decoder)
{
GstVaapiDecoderVC1Private * const priv = decoder->priv;
GstVaapiDecoderVC1Private * const priv = &decoder->priv;
GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr;
GstVC1PicAdvanced * const pic = &frame_hdr->pic.advanced;
@ -588,7 +612,7 @@ has_ACPRED_bitplane(GstVaapiDecoderVC1 *decoder)
static inline int
has_OVERFLAGS_bitplane(GstVaapiDecoderVC1 *decoder)
{
GstVaapiDecoderVC1Private * const priv = decoder->priv;
GstVaapiDecoderVC1Private * const priv = &decoder->priv;
GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
GstVC1EntryPointHdr * const entrypoint_hdr = &priv->entrypoint_hdr;
GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr;
@ -623,7 +647,7 @@ pack_bitplanes(GstVaapiBitPlane *bitplane, guint n, const guint8 *bitplanes[3],
static gboolean
fill_picture_structc(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture)
{
GstVaapiDecoderVC1Private * const priv = decoder->priv;
GstVaapiDecoderVC1Private * const priv = &decoder->priv;
VAPictureParameterBufferVC1 * const pic_param = picture->param;
GstVC1SeqStructC * const structc = &priv->seq_hdr.struct_c;
GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr;
@ -666,7 +690,7 @@ fill_picture_structc(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture)
static gboolean
fill_picture_advanced(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture)
{
GstVaapiDecoderVC1Private * const priv = decoder->priv;
GstVaapiDecoderVC1Private * const priv = &decoder->priv;
VAPictureParameterBufferVC1 * const pic_param = picture->param;
GstVC1AdvancedSeqHdr * const adv_hdr = &priv->seq_hdr.advanced;
GstVC1EntryPointHdr * const entrypoint_hdr = &priv->entrypoint_hdr;
@ -733,7 +757,7 @@ fill_picture_advanced(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture)
static gboolean
fill_picture(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture)
{
GstVaapiDecoderVC1Private * const priv = decoder->priv;
GstVaapiDecoderVC1Private * const priv = &decoder->priv;
VAPictureParameterBufferVC1 * const pic_param = picture->param;
GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr;
@ -852,7 +876,7 @@ static GstVaapiDecoderStatus
decode_slice_chunk(GstVaapiDecoderVC1 *decoder, GstVC1BDU *ebdu,
guint slice_addr, guint header_size)
{
GstVaapiDecoderVC1Private * const priv = decoder->priv;
GstVaapiDecoderVC1Private * const priv = &decoder->priv;
GstVaapiPicture * const picture = priv->current_picture;
GstVaapiSlice *slice;
VASliceParameterBufferVC1 *slice_param;
@ -877,7 +901,7 @@ decode_slice_chunk(GstVaapiDecoderVC1 *decoder, GstVC1BDU *ebdu,
static GstVaapiDecoderStatus
decode_frame(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu)
{
GstVaapiDecoderVC1Private * const priv = decoder->priv;
GstVaapiDecoderVC1Private * const priv = &decoder->priv;
GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr;
GstVC1ParserResult result;
GstVaapiPicture * const picture = priv->current_picture;
@ -939,7 +963,7 @@ decode_frame(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu)
static GstVaapiDecoderStatus
decode_slice(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu)
{
GstVaapiDecoderVC1Private * const priv = decoder->priv;
GstVaapiDecoderVC1Private * const priv = &decoder->priv;
GstVC1SliceHdr slice_hdr;
GstVC1ParserResult result;
@ -961,7 +985,7 @@ decode_slice(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu)
static gboolean
decode_rbdu(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu)
{
GstVaapiDecoderVC1Private * const priv = decoder->priv;
GstVaapiDecoderVC1Private * const priv = &decoder->priv;
guint8 *rbdu_buffer;
guint i, j, rbdu_buffer_size;
@ -1045,7 +1069,7 @@ decode_ebdu(GstVaapiDecoderVC1 *decoder, GstVC1BDU *ebdu)
static GstVaapiDecoderStatus
decode_buffer(GstVaapiDecoderVC1 *decoder, guchar *buf, guint buf_size)
{
GstVaapiDecoderVC1Private * const priv = decoder->priv;
GstVaapiDecoderVC1Private * const priv = &decoder->priv;
GstVC1BDU ebdu;
if (priv->has_codec_data) {
@ -1069,7 +1093,7 @@ gst_vaapi_decoder_vc1_decode_codec_data(GstVaapiDecoder *base_decoder,
{
GstVaapiDecoderVC1 * const decoder =
GST_VAAPI_DECODER_VC1_CAST(base_decoder);
GstVaapiDecoderVC1Private * const priv = decoder->priv;
GstVaapiDecoderVC1Private * const priv = &decoder->priv;
GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
GstVaapiDecoderStatus status;
GstVC1ParserResult result;
@ -1151,12 +1175,9 @@ gst_vaapi_decoder_vc1_decode_codec_data(GstVaapiDecoder *base_decoder,
static GstVaapiDecoderStatus
ensure_decoder(GstVaapiDecoderVC1 *decoder)
{
GstVaapiDecoderVC1Private * const priv = decoder->priv;
GstVaapiDecoderVC1Private * const priv = &decoder->priv;
GstVaapiDecoderStatus status;
g_return_val_if_fail(priv->is_constructed,
GST_VAAPI_DECODER_STATUS_ERROR_INIT_FAILED);
if (!priv->is_opened) {
priv->is_opened = gst_vaapi_decoder_vc1_open(decoder);
if (!priv->is_opened)
@ -1181,8 +1202,9 @@ static GstVaapiDecoderStatus
gst_vaapi_decoder_vc1_parse(GstVaapiDecoder *base_decoder,
GstAdapter *adapter, gboolean at_eos, GstVaapiDecoderUnit *unit)
{
GstVaapiDecoderVC1 * const decoder = GST_VAAPI_DECODER_VC1(base_decoder);
GstVaapiDecoderVC1Private * const priv = decoder->priv;
GstVaapiDecoderVC1 * const decoder =
GST_VAAPI_DECODER_VC1_CAST(base_decoder);
GstVaapiDecoderVC1Private * const priv = &decoder->priv;
GstVaapiDecoderStatus status;
guint8 bdu_type;
guint size, buf_size, flags = 0;
@ -1251,7 +1273,8 @@ static GstVaapiDecoderStatus
gst_vaapi_decoder_vc1_decode(GstVaapiDecoder *base_decoder,
GstVaapiDecoderUnit *unit)
{
GstVaapiDecoderVC1 * const decoder = GST_VAAPI_DECODER_VC1(base_decoder);
GstVaapiDecoderVC1 * const decoder =
GST_VAAPI_DECODER_VC1_CAST(base_decoder);
GstVaapiDecoderStatus status;
GstBuffer * const buffer =
GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer;
@ -1277,8 +1300,9 @@ static GstVaapiDecoderStatus
gst_vaapi_decoder_vc1_start_frame(GstVaapiDecoder *base_decoder,
GstVaapiDecoderUnit *unit)
{
GstVaapiDecoderVC1 * const decoder = GST_VAAPI_DECODER_VC1(base_decoder);
GstVaapiDecoderVC1Private * const priv = decoder->priv;
GstVaapiDecoderVC1 * const decoder =
GST_VAAPI_DECODER_VC1_CAST(base_decoder);
GstVaapiDecoderVC1Private * const priv = &decoder->priv;
GstVaapiDecoderStatus status;
GstVaapiPicture *picture;
@ -1306,7 +1330,8 @@ gst_vaapi_decoder_vc1_start_frame(GstVaapiDecoder *base_decoder,
static GstVaapiDecoderStatus
gst_vaapi_decoder_vc1_end_frame(GstVaapiDecoder *base_decoder)
{
GstVaapiDecoderVC1 * const decoder = GST_VAAPI_DECODER_VC1(base_decoder);
GstVaapiDecoderVC1 * const decoder =
GST_VAAPI_DECODER_VC1_CAST(base_decoder);
return decode_current_picture(decoder);
}
@ -1314,48 +1339,26 @@ gst_vaapi_decoder_vc1_end_frame(GstVaapiDecoder *base_decoder)
static GstVaapiDecoderStatus
gst_vaapi_decoder_vc1_flush(GstVaapiDecoder *base_decoder)
{
GstVaapiDecoderVC1 * const decoder = GST_VAAPI_DECODER_VC1(base_decoder);
GstVaapiDecoderVC1Private * const priv = decoder->priv;
GstVaapiDecoderVC1 * const decoder =
GST_VAAPI_DECODER_VC1_CAST(base_decoder);
GstVaapiDecoderVC1Private * const priv = &decoder->priv;
gst_vaapi_dpb_flush(priv->dpb);
return GST_VAAPI_DECODER_STATUS_SUCCESS;
}
static void
gst_vaapi_decoder_vc1_finalize(GObject *object)
{
GstVaapiDecoderVC1 * const decoder = GST_VAAPI_DECODER_VC1(object);
gst_vaapi_decoder_vc1_destroy(decoder);
G_OBJECT_CLASS(gst_vaapi_decoder_vc1_parent_class)->finalize(object);
}
static void
gst_vaapi_decoder_vc1_constructed(GObject *object)
{
GstVaapiDecoderVC1 * const decoder = GST_VAAPI_DECODER_VC1(object);
GstVaapiDecoderVC1Private * const priv = decoder->priv;
GObjectClass *parent_class;
parent_class = G_OBJECT_CLASS(gst_vaapi_decoder_vc1_parent_class);
if (parent_class->constructed)
parent_class->constructed(object);
priv->is_constructed = gst_vaapi_decoder_vc1_create(decoder);
}
static void
gst_vaapi_decoder_vc1_class_init(GstVaapiDecoderVC1Class *klass)
{
GObjectClass * const object_class = G_OBJECT_CLASS(klass);
GstVaapiMiniObjectClass * const object_class =
GST_VAAPI_MINI_OBJECT_CLASS(klass);
GstVaapiDecoderClass * const decoder_class = GST_VAAPI_DECODER_CLASS(klass);
g_type_class_add_private(klass, sizeof(GstVaapiDecoderVC1Private));
object_class->finalize = gst_vaapi_decoder_vc1_finalize;
object_class->constructed = gst_vaapi_decoder_vc1_constructed;
object_class->size = sizeof(GstVaapiDecoderVC1);
object_class->finalize = (GDestroyNotify)gst_vaapi_decoder_finalize;
decoder_class->create = gst_vaapi_decoder_vc1_create;
decoder_class->destroy = gst_vaapi_decoder_vc1_destroy;
decoder_class->parse = gst_vaapi_decoder_vc1_parse;
decoder_class->decode = gst_vaapi_decoder_vc1_decode;
decoder_class->start_frame = gst_vaapi_decoder_vc1_start_frame;
@ -1366,27 +1369,17 @@ gst_vaapi_decoder_vc1_class_init(GstVaapiDecoderVC1Class *klass)
gst_vaapi_decoder_vc1_decode_codec_data;
}
static void
gst_vaapi_decoder_vc1_init(GstVaapiDecoderVC1 *decoder)
static inline const GstVaapiDecoderClass *
gst_vaapi_decoder_vc1_class(void)
{
GstVaapiDecoderVC1Private *priv;
static GstVaapiDecoderVC1Class g_class;
static gsize g_class_init = FALSE;
priv = GST_VAAPI_DECODER_VC1_GET_PRIVATE(decoder);
decoder->priv = priv;
priv->width = 0;
priv->height = 0;
priv->profile = (GstVaapiProfile)0;
priv->current_picture = NULL;
priv->rbdu_buffer = NULL;
priv->rbdu_buffer_size = 0;
priv->is_constructed = FALSE;
priv->is_opened = FALSE;
priv->is_first_field = FALSE;
priv->has_entrypoint = FALSE;
priv->size_changed = FALSE;
priv->profile_changed = FALSE;
priv->closed_entry = FALSE;
priv->broken_link = FALSE;
if (g_once_init_enter(&g_class_init)) {
gst_vaapi_decoder_vc1_class_init(&g_class);
g_once_init_leave(&g_class_init, TRUE);
}
return GST_VAAPI_DECODER_CLASS(&g_class);
}
/**
@ -1402,20 +1395,5 @@ gst_vaapi_decoder_vc1_init(GstVaapiDecoderVC1 *decoder)
GstVaapiDecoder *
gst_vaapi_decoder_vc1_new(GstVaapiDisplay *display, GstCaps *caps)
{
GstVaapiDecoderVC1 *decoder;
g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL);
g_return_val_if_fail(GST_IS_CAPS(caps), NULL);
decoder = g_object_new(
GST_VAAPI_TYPE_DECODER_VC1,
"display", display,
"caps", caps,
NULL
);
if (!decoder->priv->is_constructed) {
g_object_unref(decoder);
return NULL;
}
return GST_VAAPI_DECODER_CAST(decoder);
return gst_vaapi_decoder_new(gst_vaapi_decoder_vc1_class(), display, caps);
}

View file

@ -27,58 +27,7 @@
G_BEGIN_DECLS
#define GST_VAAPI_TYPE_DECODER_VC1 \
(gst_vaapi_decoder_vc1_get_type())
#define GST_VAAPI_DECODER_VC1(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj), \
GST_VAAPI_TYPE_DECODER_VC1, \
GstVaapiDecoderVC1))
#define GST_VAAPI_DECODER_VC1_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass), \
GST_VAAPI_TYPE_DECODER_VC1, \
GstVaapiDecoderVC1Class))
#define GST_VAAPI_IS_DECODER_VC1(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_DECODER_VC1))
#define GST_VAAPI_IS_DECODER_VC1_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_DECODER_VC1))
#define GST_VAAPI_DECODER_VC1_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS((obj), \
GST_VAAPI_TYPE_DECODER_VC1, \
GstVaapiDecoderVC1Class))
typedef struct _GstVaapiDecoderVC1 GstVaapiDecoderVC1;
typedef struct _GstVaapiDecoderVC1Private GstVaapiDecoderVC1Private;
typedef struct _GstVaapiDecoderVC1Class GstVaapiDecoderVC1Class;
/**
* GstVaapiDecoderVC1:
*
* A decoder based on VC1.
*/
struct _GstVaapiDecoderVC1 {
/*< private >*/
GstVaapiDecoder parent_instance;
GstVaapiDecoderVC1Private *priv;
};
/**
* GstVaapiDecoderVC1Class:
*
* A decoder class based on VC1.
*/
struct _GstVaapiDecoderVC1Class {
/*< private >*/
GstVaapiDecoderClass parent_class;
};
GType
gst_vaapi_decoder_vc1_get_type(void) G_GNUC_CONST;
GstVaapiDecoder *
gst_vaapi_decoder_vc1_new(GstVaapiDisplay *display, GstCaps *caps);