From b31ab745a506acb17a3f70119304d43b19a76988 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Sat, 14 Mar 2009 10:43:28 +0100 Subject: add new vdpau directory --- sys/Makefile.am | 10 ++++++++-- sys/vdpau/Makefile.am | 11 +++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 sys/vdpau/Makefile.am (limited to 'sys') diff --git a/sys/Makefile.am b/sys/Makefile.am index 161f3339..15c89e17 100644 --- a/sys/Makefile.am +++ b/sys/Makefile.am @@ -70,8 +70,14 @@ else ACM_DIR= endif -SUBDIRS = $(ACM_DIR) $(DIRECTDRAW_DIR) $(DVB_DIR) $(FBDEV_DIR) $(OSS4_DIR) $(OSX_VIDEO_DIR) $(QT_DIR) $(VCD_DIR) $(WININET_DIR) +if USE_VDPAU +VDPAU_DIR=vdpau +else +VDPAU_DIR= +endif + +SUBDIRS = $(ACM_DIR) $(DIRECTDRAW_DIR) $(DVB_DIR) $(FBDEV_DIR) $(OSS4_DIR) $(OSX_VIDEO_DIR) $(QT_DIR) $(VCD_DIR) $(VDPAU_DIR) $(WININET_DIR) DIST_SUBDIRS = acmenc acmmp3dec directdraw dvb fbdev dshowdecwrapper dshowsrcwrapper dshowvideosink \ - oss4 osxvideo qtwrapper vcd wasapi wininet winks winscreencap + oss4 osxvideo qtwrapper vcd vdpau wasapi wininet winks winscreencap diff --git a/sys/vdpau/Makefile.am b/sys/vdpau/Makefile.am new file mode 100644 index 00000000..03d87758 --- /dev/null +++ b/sys/vdpau/Makefile.am @@ -0,0 +1,11 @@ + +lib_LTLIBRARIES = \ + libgstvdpau.la + +libgstvdpau_la_SOURCES = + +libgstvdpau_la_CFLAGS = $(GST_CFLAGS) +libgstvdpau_la_LIBADD = $(GST_LIBS) +libgstvdpau_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) +libgstvdpau_la_LIBTOOLFLAGS = --tag=disable-static + -- cgit v1.2.1 From b25f035fe5e02a14ae3f52912213ed6357f627f6 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Sun, 15 Mar 2009 21:21:49 +0100 Subject: vdpau: add basic base class for vdpau decoders --- sys/vdpau/Makefile.am | 15 +-- sys/vdpau/gstvdpaudecoder.c | 224 ++++++++++++++++++++++++++++++++++++++++++++ sys/vdpau/gstvdpaudecoder.h | 66 +++++++++++++ 3 files changed, 299 insertions(+), 6 deletions(-) create mode 100644 sys/vdpau/gstvdpaudecoder.c create mode 100644 sys/vdpau/gstvdpaudecoder.h (limited to 'sys') diff --git a/sys/vdpau/Makefile.am b/sys/vdpau/Makefile.am index 03d87758..777a05cb 100644 --- a/sys/vdpau/Makefile.am +++ b/sys/vdpau/Makefile.am @@ -1,11 +1,14 @@ +plugin_LTLIBRARIES = libgstvdpau.la -lib_LTLIBRARIES = \ - libgstvdpau.la +libgstvdpau_la_SOURCES = \ + gstvdpaudecoder.c -libgstvdpau_la_SOURCES = - -libgstvdpau_la_CFLAGS = $(GST_CFLAGS) -libgstvdpau_la_LIBADD = $(GST_LIBS) +libgstvdpau_la_CFLAGS = $(GST_CFLAGS) $(X11_CFLAGS) -Ivdpau +libgstvdpau_la_LIBADD = $(GST_LIBS) $(X11_LIBS) -lvdpau libgstvdpau_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) libgstvdpau_la_LIBTOOLFLAGS = --tag=disable-static +noinst_HEADERS = \ + gstvdpaudecoder.h + + diff --git a/sys/vdpau/gstvdpaudecoder.c b/sys/vdpau/gstvdpaudecoder.c new file mode 100644 index 00000000..f828d2ba --- /dev/null +++ b/sys/vdpau/gstvdpaudecoder.c @@ -0,0 +1,224 @@ +/* + * GStreamer + * Copyright (C) 2006 Stefan Kost + * Copyright (C) 2009 Carl-Anton Ingmarsson + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#include +#include +#include "gstvdpaudecoder.h" + +GST_DEBUG_CATEGORY_STATIC (gst_vdpaudecoder_debug); +#define GST_CAT_DEFAULT gst_vdpaudecoder_debug + +/* Filter signals and args */ +enum +{ + /* FILL ME */ + LAST_SIGNAL +}; + +enum +{ + PROP_0, + PROP_DISPLAY, + PROP_SILENT +}; + +static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS ("video/x-raw-yuv, " + "framerate = (fraction) [ 0, MAX ], " + "width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ]")); + +/* debug category for fltering log messages + * + * FIXME:exchange the string 'Template vdpaudecoder' with your description + */ +#define DEBUG_INIT(bla) \ + GST_DEBUG_CATEGORY_INIT (gst_vdpaudecoder_debug, "vdpaudecoder", 0, "vdpaudecoder base class"); + +GST_BOILERPLATE_FULL (GstVDPAUDecoder, gst_vdpaudecoder, GstElement, + GST_TYPE_ELEMENT, DEBUG_INIT); + +static void gst_vdpaudecoder_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec); +static void gst_vdpaudecoder_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec); + +static GstStateChangeReturn gst_vdpaudecoder_change_state (GstElement * element, + GstStateChange transition); + +/* GObject vmethod implementations */ + +static void +gst_vdpaudecoder_base_init (gpointer klass) +{ + GstElementClass *element_class = GST_ELEMENT_CLASS (klass); + + gst_element_class_set_details_simple (element_class, + "VDPAUDecoder", + "Generic/Filter", + "VDPAU decoder base class", + "Carl-Anton Ingmarsson "); + + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&src_template)); +} + +/* initialize the vdpaudecoder's class */ +static void +gst_vdpaudecoder_class_init (GstVDPAUDecoderClass * klass) +{ + GObjectClass *gobject_class; + GstElementClass *gstelement_class; + + gobject_class = (GObjectClass *) klass; + gstelement_class = (GstElementClass *) klass; + + gobject_class->set_property = gst_vdpaudecoder_set_property; + gobject_class->get_property = gst_vdpaudecoder_get_property; + + g_object_class_install_property (gobject_class, PROP_DISPLAY, + g_param_spec_string ("display", "Display", "X Display name", + NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + + g_object_class_install_property (gobject_class, PROP_SILENT, + g_param_spec_boolean ("silent", "Silent", "Produce verbose output ?", + FALSE, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE)); + + gstelement_class->change_state = + GST_DEBUG_FUNCPTR (gst_vdpaudecoder_change_state); +} + +static void +gst_vdpaudecoder_init (GstVDPAUDecoder * dec, GstVDPAUDecoderClass * klass) +{ + dec->display = NULL; + dec->device = 0; + dec->silent = FALSE; + + dec->src = gst_pad_new_from_static_template (&src_template, "src"); + gst_element_add_pad (GST_ELEMENT (dec), dec->src); + + dec->sink = + gst_pad_new_from_template (gst_element_class_get_pad_template + (GST_ELEMENT_CLASS (klass), "sink"), "sink"); + gst_element_add_pad (GST_ELEMENT (dec), dec->sink); +} + +static GstStateChangeReturn +gst_vdpaudecoder_change_state (GstElement * element, GstStateChange transition) +{ + GstVDPAUDecoder *dec; + + dec = GST_VDPAUDECODER (element); + + switch (transition) { + case GST_STATE_CHANGE_NULL_TO_READY: + { + Display *display; + int screen; + VdpStatus status; + + /* FIXME: We probably want to use the same VdpDevice for every VDPAU element */ + display = XOpenDisplay (dec->display); + if (!display) { + GST_ELEMENT_ERROR (dec, RESOURCE, WRITE, ("Could not initialise VDPAU"), + ("Could not open display")); + return GST_STATE_CHANGE_FAILURE; + } + + screen = DefaultScreen (display); + status = vdp_device_create_x11 (display, screen, &dec->device, NULL); + if (status != VDP_STATUS_OK) { + GST_ELEMENT_ERROR (dec, RESOURCE, WRITE, ("Could not initialise VDPAU"), + ("Could not create VDPAU device")); + XCloseDisplay (display); + + return GST_STATE_CHANGE_FAILURE; + } + XCloseDisplay (display); + break; + } + + default: + break; + } + + return GST_STATE_CHANGE_SUCCESS; +} + +static void +gst_vdpaudecoder_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GstVDPAUDecoder *dec = GST_VDPAUDECODER (object); + + switch (prop_id) { + case PROP_DISPLAY: + g_free (dec->display); + dec->display = g_value_dup_string (value); + break; + case PROP_SILENT: + dec->silent = g_value_get_boolean (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_vdpaudecoder_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) +{ + GstVDPAUDecoder *dec = GST_VDPAUDECODER (object); + + switch (prop_id) { + case PROP_DISPLAY: + g_value_set_string (value, dec->display); + break; + case PROP_SILENT: + g_value_set_boolean (value, dec->silent); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static gboolean +plugin_init (GstPlugin * plugin) +{ + return TRUE; +} + +GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, + GST_VERSION_MINOR, + "vdpau", + "vdpau elements", + plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN) diff --git a/sys/vdpau/gstvdpaudecoder.h b/sys/vdpau/gstvdpaudecoder.h new file mode 100644 index 00000000..83506866 --- /dev/null +++ b/sys/vdpau/gstvdpaudecoder.h @@ -0,0 +1,66 @@ +/* + * GStreamer + * Copyright (C) 2006 Stefan Kost + * Copyright (C) 2009 Carl-Anton Ingmarsson + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GST_VDPAUDECODER_H__ +#define __GST_VDPAUDECODER_H__ + +#include +#include + +#include + +G_BEGIN_DECLS + +#define GST_TYPE_VDPAUDECODER \ + (gst_vdpaudecoder_get_type()) +#define GST_VDPAUDECODER(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VDPAUDECODER,GstVDPAUDecoder)) +#define GST_VDPAUDECODER_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VDPAUDECODER,GstVDPAUDecoderClass)) +#define GST_IS_VDPAUDECODER(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VDPAUDECODER)) +#define GST_IS_VDPAUDECODER_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VDPAUDECODER)) + +typedef struct _GstVDPAUDecoder GstVDPAUDecoder; +typedef struct _GstVDPAUDecoderClass GstVDPAUDecoderClass; + +struct _GstVDPAUDecoder { + GstElement element; + + gchar *display; + VdpDevice device; + + GstPad *src; + GstPad *sink; + + gboolean silent; +}; + +struct _GstVDPAUDecoderClass { + GstBaseTransformClass parent_class; +}; + +GType gst_vdpaudecoder_get_type (void); + +G_END_DECLS + +#endif /* __GST_VDPAUDECODER_H__ */ -- cgit v1.2.1 From 05908cd13001e62bf8416ff0d0856d9f145c415e Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Sun, 15 Mar 2009 21:23:35 +0100 Subject: vdpau: small indentation fix --- sys/vdpau/gstvdpaudecoder.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpaudecoder.c b/sys/vdpau/gstvdpaudecoder.c index f828d2ba..fe4e8796 100644 --- a/sys/vdpau/gstvdpaudecoder.c +++ b/sys/vdpau/gstvdpaudecoder.c @@ -124,8 +124,7 @@ gst_vdpaudecoder_init (GstVDPAUDecoder * dec, GstVDPAUDecoderClass * klass) dec->src = gst_pad_new_from_static_template (&src_template, "src"); gst_element_add_pad (GST_ELEMENT (dec), dec->src); - dec->sink = - gst_pad_new_from_template (gst_element_class_get_pad_template + dec->sink = gst_pad_new_from_template (gst_element_class_get_pad_template (GST_ELEMENT_CLASS (klass), "sink"), "sink"); gst_element_add_pad (GST_ELEMENT (dec), dec->sink); } -- cgit v1.2.1 From f2eea7d0ed8004d4630739b04daf27075d6834e5 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Fri, 20 Mar 2009 21:24:40 +0100 Subject: vdpau: implement downstream caps negotiation --- sys/vdpau/Makefile.am | 7 +- sys/vdpau/gstvdpaudecoder.c | 283 +++++++++++++++++++++++++++++++--------- sys/vdpau/gstvdpaudecoder.h | 34 ++--- sys/vdpau/gstvdpauh264decoder.c | 202 ++++++++++++++++++++++++++++ sys/vdpau/gstvdpauh264decoder.h | 88 +++++++++++++ sys/vdpau/vdpauvariables.h | 45 +++++++ 6 files changed, 577 insertions(+), 82 deletions(-) create mode 100644 sys/vdpau/gstvdpauh264decoder.c create mode 100644 sys/vdpau/gstvdpauh264decoder.h create mode 100644 sys/vdpau/vdpauvariables.h (limited to 'sys') diff --git a/sys/vdpau/Makefile.am b/sys/vdpau/Makefile.am index 777a05cb..3e718abe 100644 --- a/sys/vdpau/Makefile.am +++ b/sys/vdpau/Makefile.am @@ -1,7 +1,8 @@ plugin_LTLIBRARIES = libgstvdpau.la libgstvdpau_la_SOURCES = \ - gstvdpaudecoder.c + gstvdpaudecoder.c\ + gstvdpauh264decoder.c libgstvdpau_la_CFLAGS = $(GST_CFLAGS) $(X11_CFLAGS) -Ivdpau libgstvdpau_la_LIBADD = $(GST_LIBS) $(X11_LIBS) -lvdpau @@ -9,6 +10,8 @@ libgstvdpau_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) libgstvdpau_la_LIBTOOLFLAGS = --tag=disable-static noinst_HEADERS = \ - gstvdpaudecoder.h + gstvdpaudecoder.h\ + vdpauvariables.h \ + gstvdpauh264decoder.h diff --git a/sys/vdpau/gstvdpaudecoder.c b/sys/vdpau/gstvdpaudecoder.c index fe4e8796..230fa80c 100644 --- a/sys/vdpau/gstvdpaudecoder.c +++ b/sys/vdpau/gstvdpaudecoder.c @@ -28,6 +28,8 @@ #include #include + +#include "vdpauvariables.h" #include "gstvdpaudecoder.h" GST_DEBUG_CATEGORY_STATIC (gst_vdpaudecoder_debug); @@ -61,7 +63,7 @@ static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src", #define DEBUG_INIT(bla) \ GST_DEBUG_CATEGORY_INIT (gst_vdpaudecoder_debug, "vdpaudecoder", 0, "vdpaudecoder base class"); -GST_BOILERPLATE_FULL (GstVDPAUDecoder, gst_vdpaudecoder, GstElement, +GST_BOILERPLATE_FULL (GstVdpauDecoder, gst_vdpaudecoder, GstElement, GST_TYPE_ELEMENT, DEBUG_INIT); static void gst_vdpaudecoder_set_property (GObject * object, guint prop_id, @@ -69,8 +71,213 @@ static void gst_vdpaudecoder_set_property (GObject * object, guint prop_id, static void gst_vdpaudecoder_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); -static GstStateChangeReturn gst_vdpaudecoder_change_state (GstElement * element, - GstStateChange transition); +typedef struct +{ + VdpChromaType chroma_type; + VdpYCbCrFormat format; + guint32 fourcc; +} VdpauFormats; + +static VdpChromaType chroma_types[3] = + { VDP_CHROMA_TYPE_420, VDP_CHROMA_TYPE_422, VDP_CHROMA_TYPE_444 }; +static VdpauFormats formats[6] = { + { + VDP_CHROMA_TYPE_420, + VDP_YCBCR_FORMAT_NV12, + GST_MAKE_FOURCC ('N', 'V', '1', '2') + }, + { + VDP_CHROMA_TYPE_422, + VDP_YCBCR_FORMAT_UYVY, + GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y') + }, + { + VDP_CHROMA_TYPE_444, + VDP_YCBCR_FORMAT_V8U8Y8A8, + GST_MAKE_FOURCC ('A', 'Y', 'U', 'V') + }, + { + VDP_CHROMA_TYPE_444, + VDP_YCBCR_FORMAT_Y8U8V8A8, + GST_MAKE_FOURCC ('A', 'V', 'U', 'Y') + }, + { + VDP_CHROMA_TYPE_422, + VDP_YCBCR_FORMAT_YUYV, + GST_MAKE_FOURCC ('Y', 'U', 'Y', 'V') + }, + { + VDP_CHROMA_TYPE_420, + VDP_YCBCR_FORMAT_YV12, + GST_MAKE_FOURCC ('Y', 'V', '1', '2') + } +}; + +static GstCaps * +gst_vdpaudecoder_get_vdpau_support (GstVdpauDecoder * dec) +{ + GstCaps *caps; + gint i; + + caps = gst_caps_new_empty (); + + for (i = 0; i < 3; i++) { + VdpStatus status; + VdpBool is_supported; + guint32 max_w, max_h; + + status = vdp_video_surface_query_capabilities (dec->device, chroma_types[i], + &is_supported, &max_w, &max_h); + + if (status != VDP_STATUS_OK && status != VDP_STATUS_INVALID_CHROMA_TYPE) { + GST_ELEMENT_ERROR (dec, RESOURCE, READ, + ("Could not get VDPAU capabilites"), + ("Could not query video surface capabilities")); + + return NULL; + } + if (is_supported) { + gint j; + + for (j = 0; j < 6; j++) { + if (formats[j].chroma_type != chroma_types[i]) + continue; + + status = + vdp_video_surface_query_ycbcr_capabilities (dec->device, + formats[j].chroma_type, formats[j].format, &is_supported); + if (status != VDP_STATUS_OK + && status != VDP_STATUS_INVALID_Y_CB_CR_FORMAT) { + GST_ELEMENT_ERROR (dec, RESOURCE, READ, + ("Could not get VDPAU capabilites"), + ("Could not query video surface ycbcr capabilities")); + + return NULL; + } + if (is_supported) { + GstCaps *format_caps; + + format_caps = gst_caps_new_simple ("video/x-raw-yuv", + "format", GST_TYPE_FOURCC, formats[j].fourcc, + "width", GST_TYPE_INT_RANGE, 1, max_w, + "height", GST_TYPE_INT_RANGE, 1, max_h, + "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL); + gst_caps_append (caps, format_caps); + GST_DEBUG ("fourcc: %" GST_FOURCC_FORMAT "\n", + GST_FOURCC_ARGS (formats[j].fourcc)); + } + } + } + } + if (gst_caps_is_empty (caps)) { + gst_caps_unref (caps); + return NULL; + } + + return caps; +} + +static gboolean +gst_vdpaudecoder_init_vdpau (GstVdpauDecoder * dec) +{ + Display *display; + int screen; + VdpStatus status; + GstCaps *caps; + + /* FIXME: We probably want to use the same VdpDevice for every VDPAU element */ + display = XOpenDisplay (dec->display); + if (!display) { + GST_ELEMENT_ERROR (dec, RESOURCE, READ, ("Could not initialise VDPAU"), + ("Could not open display")); + return GST_STATE_CHANGE_FAILURE; + } + + screen = DefaultScreen (display); + status = + vdp_device_create_x11 (display, screen, &dec->device, + &vdp_get_proc_address); + if (status != VDP_STATUS_OK) { + GST_ELEMENT_ERROR (dec, RESOURCE, READ, ("Could not initialise VDPAU"), + ("Could not create VDPAU device")); + XCloseDisplay (display); + + return FALSE; + } + XCloseDisplay (display); + + vdp_get_proc_address (dec->device, + VDP_FUNC_ID_VIDEO_SURFACE_QUERY_CAPABILITIES, + (void **) &vdp_video_surface_query_capabilities); + vdp_get_proc_address (dec->device, + VDP_FUNC_ID_VIDEO_SURFACE_QUERY_GET_PUT_BITS_Y_CB_CR_CAPABILITIES, + (void **) &vdp_video_surface_query_ycbcr_capabilities); + + caps = gst_vdpaudecoder_get_vdpau_support (dec); + if (!caps) + return FALSE; + + dec->src_caps = caps; + + return TRUE; +} + +static gboolean +gst_vdpaudecoder_sink_set_caps (GstPad * pad, GstCaps * caps) +{ + GstVdpauDecoder *dec = GST_VDPAU_DECODER (GST_OBJECT_PARENT (pad)); + + GstCaps *src_caps, *new_caps; + GstStructure *structure; + gint width, height; + gint framerate_numerator, framerate_denominator; + gboolean res; + + structure = gst_caps_get_structure (caps, 0); + gst_structure_get_int (structure, "width", &width); + gst_structure_get_int (structure, "height", &height); + gst_structure_get_fraction (structure, "framerate", + &framerate_numerator, &framerate_denominator); + + src_caps = gst_pad_get_allowed_caps (dec->src); + GST_DEBUG ("caps: %s\n\n", gst_caps_to_string (src_caps)); + + structure = gst_caps_get_structure (src_caps, 0); + gst_structure_set (structure, + "width", G_TYPE_INT, width, + "height", G_TYPE_INT, height, + "framerate", GST_TYPE_FRACTION, framerate_numerator, + framerate_denominator, NULL); + + new_caps = gst_caps_copy_nth (src_caps, 0); + gst_caps_unref (src_caps); + gst_pad_fixate_caps (dec->src, new_caps); + res = gst_pad_set_caps (dec->src, new_caps); + + gst_caps_unref (new_caps); + GST_DEBUG ("caps: %s\n\n", gst_caps_to_string (gst_pad_get_caps (dec->src))); + + if (!res) + return FALSE; + + return TRUE; +} + +static GstCaps * +gst_vdpaudecoder_src_getcaps (GstPad * pad) +{ + GstVdpauDecoder *dec; + + dec = GST_VDPAU_DECODER (GST_OBJECT_PARENT (pad)); + + if (GST_PAD_CAPS (dec->src)) + return gst_caps_ref (GST_PAD_CAPS (dec->src)); + + if (dec->src_caps) + return gst_caps_ref (dec->src_caps); + + return gst_caps_copy (gst_pad_get_pad_template_caps (dec->src)); +} /* GObject vmethod implementations */ @@ -80,7 +287,7 @@ gst_vdpaudecoder_base_init (gpointer klass) GstElementClass *element_class = GST_ELEMENT_CLASS (klass); gst_element_class_set_details_simple (element_class, - "VDPAUDecoder", + "VdpauDecoder", "Generic/Filter", "VDPAU decoder base class", "Carl-Anton Ingmarsson "); @@ -91,7 +298,7 @@ gst_vdpaudecoder_base_init (gpointer klass) /* initialize the vdpaudecoder's class */ static void -gst_vdpaudecoder_class_init (GstVDPAUDecoderClass * klass) +gst_vdpaudecoder_class_init (GstVdpauDecoderClass * klass) { GObjectClass *gobject_class; GstElementClass *gstelement_class; @@ -109,73 +316,33 @@ gst_vdpaudecoder_class_init (GstVDPAUDecoderClass * klass) g_object_class_install_property (gobject_class, PROP_SILENT, g_param_spec_boolean ("silent", "Silent", "Produce verbose output ?", FALSE, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE)); - - gstelement_class->change_state = - GST_DEBUG_FUNCPTR (gst_vdpaudecoder_change_state); } static void -gst_vdpaudecoder_init (GstVDPAUDecoder * dec, GstVDPAUDecoderClass * klass) +gst_vdpaudecoder_init (GstVdpauDecoder * dec, GstVdpauDecoderClass * klass) { dec->display = NULL; dec->device = 0; dec->silent = FALSE; + dec->src_caps = NULL; dec->src = gst_pad_new_from_static_template (&src_template, "src"); + gst_pad_set_getcaps_function (dec->src, gst_vdpaudecoder_src_getcaps); gst_element_add_pad (GST_ELEMENT (dec), dec->src); dec->sink = gst_pad_new_from_template (gst_element_class_get_pad_template (GST_ELEMENT_CLASS (klass), "sink"), "sink"); + gst_pad_set_setcaps_function (dec->sink, gst_vdpaudecoder_sink_set_caps); gst_element_add_pad (GST_ELEMENT (dec), dec->sink); -} -static GstStateChangeReturn -gst_vdpaudecoder_change_state (GstElement * element, GstStateChange transition) -{ - GstVDPAUDecoder *dec; - - dec = GST_VDPAUDECODER (element); - - switch (transition) { - case GST_STATE_CHANGE_NULL_TO_READY: - { - Display *display; - int screen; - VdpStatus status; - - /* FIXME: We probably want to use the same VdpDevice for every VDPAU element */ - display = XOpenDisplay (dec->display); - if (!display) { - GST_ELEMENT_ERROR (dec, RESOURCE, WRITE, ("Could not initialise VDPAU"), - ("Could not open display")); - return GST_STATE_CHANGE_FAILURE; - } - - screen = DefaultScreen (display); - status = vdp_device_create_x11 (display, screen, &dec->device, NULL); - if (status != VDP_STATUS_OK) { - GST_ELEMENT_ERROR (dec, RESOURCE, WRITE, ("Could not initialise VDPAU"), - ("Could not create VDPAU device")); - XCloseDisplay (display); - - return GST_STATE_CHANGE_FAILURE; - } - XCloseDisplay (display); - break; - } - - default: - break; - } - - return GST_STATE_CHANGE_SUCCESS; + gst_vdpaudecoder_init_vdpau (dec); } static void gst_vdpaudecoder_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { - GstVDPAUDecoder *dec = GST_VDPAUDECODER (object); + GstVdpauDecoder *dec = GST_VDPAU_DECODER (object); switch (prop_id) { case PROP_DISPLAY: @@ -195,7 +362,7 @@ static void gst_vdpaudecoder_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { - GstVDPAUDecoder *dec = GST_VDPAUDECODER (object); + GstVdpauDecoder *dec = GST_VDPAU_DECODER (object); switch (prop_id) { case PROP_DISPLAY: @@ -209,15 +376,3 @@ gst_vdpaudecoder_get_property (GObject * object, guint prop_id, break; } } - -static gboolean -plugin_init (GstPlugin * plugin) -{ - return TRUE; -} - -GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, - GST_VERSION_MINOR, - "vdpau", - "vdpau elements", - plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN) diff --git a/sys/vdpau/gstvdpaudecoder.h b/sys/vdpau/gstvdpaudecoder.h index 83506866..f713b0dd 100644 --- a/sys/vdpau/gstvdpaudecoder.h +++ b/sys/vdpau/gstvdpaudecoder.h @@ -19,8 +19,8 @@ * Boston, MA 02111-1307, USA. */ -#ifndef __GST_VDPAUDECODER_H__ -#define __GST_VDPAUDECODER_H__ +#ifndef __GST_VDPAU_DECODER_H__ +#define __GST_VDPAU_DECODER_H__ #include #include @@ -29,21 +29,21 @@ G_BEGIN_DECLS -#define GST_TYPE_VDPAUDECODER \ +#define GST_TYPE_VDPAU_DECODER \ (gst_vdpaudecoder_get_type()) -#define GST_VDPAUDECODER(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VDPAUDECODER,GstVDPAUDecoder)) -#define GST_VDPAUDECODER_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VDPAUDECODER,GstVDPAUDecoderClass)) -#define GST_IS_VDPAUDECODER(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VDPAUDECODER)) -#define GST_IS_VDPAUDECODER_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VDPAUDECODER)) +#define GST_VDPAU_DECODER(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VDPAU_DECODER,GstVdpauDecoder)) +#define GST_VDPAU_DECODER_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VDPAU_DECODER,GstVdpauDecoderClass)) +#define GST_IS_VDPAU_DECODER(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VDPAU_DECODER)) +#define GST_IS_VDPAU_DECODER_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VDPAU_DECODER)) -typedef struct _GstVDPAUDecoder GstVDPAUDecoder; -typedef struct _GstVDPAUDecoderClass GstVDPAUDecoderClass; +typedef struct _GstVdpauDecoder GstVdpauDecoder; +typedef struct _GstVdpauDecoderClass GstVdpauDecoderClass; -struct _GstVDPAUDecoder { +struct _GstVdpauDecoder { GstElement element; gchar *display; @@ -52,10 +52,12 @@ struct _GstVDPAUDecoder { GstPad *src; GstPad *sink; + GstCaps *src_caps; + gboolean silent; }; -struct _GstVDPAUDecoderClass { +struct _GstVdpauDecoderClass { GstBaseTransformClass parent_class; }; @@ -63,4 +65,4 @@ GType gst_vdpaudecoder_get_type (void); G_END_DECLS -#endif /* __GST_VDPAUDECODER_H__ */ +#endif /* __GST_VDPAU_DECODER_H__ */ diff --git a/sys/vdpau/gstvdpauh264decoder.c b/sys/vdpau/gstvdpauh264decoder.c new file mode 100644 index 00000000..794f71d1 --- /dev/null +++ b/sys/vdpau/gstvdpauh264decoder.c @@ -0,0 +1,202 @@ +/* + * GStreamer + * Copyright (C) 2005 Thomas Vander Stichele + * Copyright (C) 2005 Ronald S. Bultje + * Copyright (C) 2009 Carl-Anton Ingmarsson + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Alternatively, the contents of this file may be used under the + * GNU Lesser General Public License Version 2.1 (the "LGPL"), in + * which case the following provisions apply instead of the ones + * mentioned above: + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/** + * SECTION:element-vdpauh264decoder + * + * FIXME:Describe vdpauh264decoder here. + * + * + * Example launch line + * |[ + * gst-launch -v -m fakesrc ! vdpauh264decoder ! fakesink silent=TRUE + * ]| + * + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include "gstvdpauh264decoder.h" + +GST_DEBUG_CATEGORY_STATIC (gst_vdpau_h264decoder_debug); +#define GST_CAT_DEFAULT gst_vdpau_h264decoder_debug + +/* Filter signals and args */ +enum +{ + /* FILL ME */ + LAST_SIGNAL +}; + +enum +{ + PROP_0, + PROP_SILENT +}; + +/* the capabilities of the inputs and outputs. + * + * describe the real formats here. + */ +static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS ("video/x-h264") + ); + +GST_BOILERPLATE (GstVdpauH264Decoder, gst_vdpau_h264decoder, GstVdpauDecoder, + GST_TYPE_VDPAU_DECODER); + +static void gst_vdpau_h264decoder_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec); +static void gst_vdpau_h264decoder_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec); + +/* GObject vmethod implementations */ + +static void +gst_vdpau_h264decoder_base_init (gpointer gclass) +{ + GstElementClass *element_class = GST_ELEMENT_CLASS (gclass); + + gst_element_class_set_details_simple (element_class, + "VdpauH264Decoder", + "FIXME:Generic", + "FIXME:Generic Template Element", + "Carl-Anton Ingmarsson "); + + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&sink_factory)); +} + +/* initialize the vdpauh264decoder's class */ +static void +gst_vdpau_h264decoder_class_init (GstVdpauH264DecoderClass * klass) +{ + GObjectClass *gobject_class; + GstElementClass *gstelement_class; + + gobject_class = (GObjectClass *) klass; + gstelement_class = (GstElementClass *) klass; + + gobject_class->set_property = gst_vdpau_h264decoder_set_property; + gobject_class->get_property = gst_vdpau_h264decoder_get_property; + + g_object_class_install_property (gobject_class, PROP_SILENT, + g_param_spec_boolean ("silent", "Silent", "Produce verbose output ?", + FALSE, G_PARAM_READWRITE)); +} + +static void +gst_vdpau_h264decoder_init (GstVdpauH264Decoder * filter, + GstVdpauH264DecoderClass * gclass) +{ + filter->silent = FALSE; +} + +static void +gst_vdpau_h264decoder_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GstVdpauH264Decoder *filter = GST_VDPAU_H264_DECODER (object); + + switch (prop_id) { + case PROP_SILENT: + filter->silent = g_value_get_boolean (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_vdpau_h264decoder_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) +{ + GstVdpauH264Decoder *filter = GST_VDPAU_H264_DECODER (object); + + switch (prop_id) { + case PROP_SILENT: + g_value_set_boolean (value, filter->silent); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +/* entry point to initialize the plug-in + * initialize the plug-in itself + * register the element factories and other features + */ +static gboolean +vdpauh264decoder_init (GstPlugin * vdpauh264decoder) +{ + /* debug category for fltering log messages + * + * exchange the string 'Template vdpauh264decoder' with your description + */ + GST_DEBUG_CATEGORY_INIT (gst_vdpau_h264decoder_debug, "vdpauh264decoder", + 0, "Template vdpauh264decoder"); + + return gst_element_register (vdpauh264decoder, "vdpauh264decoder", + GST_RANK_NONE, GST_TYPE_VDPAU_H264_DECODER); +} + +/* gstreamer looks for this structure to register vdpauh264decoders + * + * exchange the string 'Template vdpauh264decoder' with your vdpauh264decoder description + */ +GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, + GST_VERSION_MINOR, + "vdpauh264decoder", + "Template vdpauh264decoder", + vdpauh264decoder_init, + VERSION, "LGPL", "GStreamer", "http://gstreamer.net/") diff --git a/sys/vdpau/gstvdpauh264decoder.h b/sys/vdpau/gstvdpauh264decoder.h new file mode 100644 index 00000000..c3972047 --- /dev/null +++ b/sys/vdpau/gstvdpauh264decoder.h @@ -0,0 +1,88 @@ +/* + * GStreamer + * Copyright (C) 2005 Thomas Vander Stichele + * Copyright (C) 2005 Ronald S. Bultje + * Copyright (C) 2009 Carl-Anton Ingmarsson + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Alternatively, the contents of this file may be used under the + * GNU Lesser General Public License Version 2.1 (the "LGPL"), in + * which case the following provisions apply instead of the ones + * mentioned above: + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GST_VDPAU_H264_DECODER_H__ +#define __GST_VDPAU_H264_DECODER_H__ + +#include + +#include "gstvdpaudecoder.h" + +G_BEGIN_DECLS + +/* #defines don't like whitespacey bits */ +#define GST_TYPE_VDPAU_H264_DECODER \ + (gst_vdpau_h264decoder_get_type()) +#define GST_VDPAU_H264_DECODER(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VDPAU_H264_DECODER,GstVdpauH264Decoder)) +#define GST_VDPAU_H264_DECODER_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VDPAU_H264_DECODER,GstVdpauH264DecoderClass)) +#define GST_IS_VDPAU_H264_DECODER(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VDPAU_H264_DECODER)) +#define GST_IS_VDPAU_H264_DECODER_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VDPAU_H264_DECODER)) + +typedef struct _GstVdpauH264Decoder GstVdpauH264Decoder; +typedef struct _GstVdpauH264DecoderClass GstVdpauH264DecoderClass; + +struct _GstVdpauH264Decoder +{ + GstVdpauDecoder dec; + + GstPad *sinkpad, *srcpad; + + gboolean silent; +}; + +struct _GstVdpauH264DecoderClass +{ + GstVdpauDecoderClass parent_class; +}; + +GType gst_vdpau_h264decoder_get_type (void); + +G_END_DECLS + +#endif /* __GST_VDPAU_H264_DECODER_H__ */ diff --git a/sys/vdpau/vdpauvariables.h b/sys/vdpau/vdpauvariables.h new file mode 100644 index 00000000..ab274aa8 --- /dev/null +++ b/sys/vdpau/vdpauvariables.h @@ -0,0 +1,45 @@ +#include + +static VdpVideoSurfaceQueryCapabilities *vdp_video_surface_query_capabilities; +static VdpVideoSurfaceQueryGetPutBitsYCbCrCapabilities *vdp_video_surface_query_ycbcr_capabilities; + +static VdpGetProcAddress *vdp_get_proc_address; +#if 0 + +static VdpDeviceDestroy *vdp_device_destroy; +static VdpVideoSurfaceCreate *vdp_video_surface_create; +static VdpVideoSurfaceDestroy *vdp_video_surface_destroy; + +static VdpGetErrorString *vdp_get_error_string; + +static VdpVideoSurfacePutBitsYCbCr *vdp_video_surface_put_bits_y_cb_cr; +static VdpOutputSurfacePutBitsNative *vdp_output_surface_put_bits_native; + +static VdpOutputSurfaceCreate *vdp_output_surface_create; +static VdpOutputSurfaceDestroy *vdp_output_surface_destroy; + +static VdpVideoMixerCreate *vdp_video_mixer_create; +static VdpVideoMixerDestroy *vdp_video_mixer_destroy; +static VdpVideoMixerRender *vdp_video_mixer_render; +static VdpVideoMixerSetFeatureEnables *vdp_video_mixer_set_feature_enables; +static VdpVideoMixerSetAttributeValues *vdp_video_mixer_set_attribute_values; + +static VdpPresentationQueueTargetDestroy *vdp_presentation_queue_target_destroy; +static VdpPresentationQueueCreate *vdp_presentation_queue_create; +static VdpPresentationQueueDestroy *vdp_presentation_queue_destroy; +static VdpPresentationQueueDisplay *vdp_presentation_queue_display; +static VdpPresentationQueueBlockUntilSurfaceIdle *vdp_presentation_queue_block_until_surface_idle; +static VdpPresentationQueueTargetCreateX11 *vdp_presentation_queue_target_create_x11; + +static VdpOutputSurfaceRenderOutputSurface *vdp_output_surface_render_output_surface; +static VdpOutputSurfacePutBitsIndexed *vdp_output_surface_put_bits_indexed; +static VdpOutputSurfaceRenderBitmapSurface *vdp_output_surface_render_bitmap_surface; + +static VdpBitmapSurfaceCreate *vdp_bitmap_surface_create; +static VdpBitmapSurfaceDestroy *vdp_bitmap_surface_destroy; +static VdpBitmapSurfacePutBitsNative *vdp_bitmap_surface_putbits_native; + +static VdpDecoderCreate *vdp_decoder_create; +static VdpDecoderDestroy *vdp_decoder_destroy; +static VdpDecoderRender *vdp_decoder_render; +#endif \ No newline at end of file -- cgit v1.2.1 From c0e4cdeb615238fef871cc5a1dfceed0109e3178 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Fri, 20 Mar 2009 21:26:11 +0100 Subject: vdpau: changle gstvdpaudecoder.c classification --- sys/vdpau/gstvdpaudecoder.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpaudecoder.c b/sys/vdpau/gstvdpaudecoder.c index 230fa80c..0ef69654 100644 --- a/sys/vdpau/gstvdpaudecoder.c +++ b/sys/vdpau/gstvdpaudecoder.c @@ -288,7 +288,7 @@ gst_vdpaudecoder_base_init (gpointer klass) gst_element_class_set_details_simple (element_class, "VdpauDecoder", - "Generic/Filter", + "Codec/Decoder/Video", "VDPAU decoder base class", "Carl-Anton Ingmarsson "); -- cgit v1.2.1 From 46a7e8221ceab7e1a5073aeaf36994af9c29ffa3 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Sat, 21 Mar 2009 22:06:12 +0100 Subject: vdpau: update VdpauH264Decoder element description --- sys/vdpau/gstvdpauh264decoder.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpauh264decoder.c b/sys/vdpau/gstvdpauh264decoder.c index 794f71d1..ce6eec11 100644 --- a/sys/vdpau/gstvdpauh264decoder.c +++ b/sys/vdpau/gstvdpauh264decoder.c @@ -107,8 +107,8 @@ gst_vdpau_h264decoder_base_init (gpointer gclass) gst_element_class_set_details_simple (element_class, "VdpauH264Decoder", - "FIXME:Generic", - "FIXME:Generic Template Element", + "Decoder", + "decode h264 stream with vdpau", "Carl-Anton Ingmarsson "); gst_element_class_add_pad_template (element_class, -- cgit v1.2.1 From 24dfc72e89e73a7b6fa6015a1b9f61038a223c02 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Mon, 23 Mar 2009 20:47:00 +0100 Subject: vdpau: add stubs for pushing VdpVideoSurfaces to the src pad --- sys/vdpau/gstvdpaudecoder.c | 21 +++++++++++++++++---- sys/vdpau/gstvdpaudecoder.h | 2 ++ 2 files changed, 19 insertions(+), 4 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpaudecoder.c b/sys/vdpau/gstvdpaudecoder.c index 0ef69654..bea707f5 100644 --- a/sys/vdpau/gstvdpaudecoder.c +++ b/sys/vdpau/gstvdpaudecoder.c @@ -71,6 +71,19 @@ static void gst_vdpaudecoder_set_property (GObject * object, guint prop_id, static void gst_vdpaudecoder_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); +static gboolean +gst_vdpaudecoder_push_video_surface (GstVdpauDecoder * dec, + VdpVideoSurface * surface) +{ + switch (dec->format) { + case GST_MAKE_FOURCC ('Y', 'V', '1', '2'): + /* YV12 specific code */ + break; + default: + break; + } +} + typedef struct { VdpChromaType chroma_type; @@ -163,8 +176,6 @@ gst_vdpaudecoder_get_vdpau_support (GstVdpauDecoder * dec) "height", GST_TYPE_INT_RANGE, 1, max_h, "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL); gst_caps_append (caps, format_caps); - GST_DEBUG ("fourcc: %" GST_FOURCC_FORMAT "\n", - GST_FOURCC_ARGS (formats[j].fourcc)); } } } @@ -231,6 +242,7 @@ gst_vdpaudecoder_sink_set_caps (GstPad * pad, GstCaps * caps) GstStructure *structure; gint width, height; gint framerate_numerator, framerate_denominator; + guint32 fourcc_format; gboolean res; structure = gst_caps_get_structure (caps, 0); @@ -240,9 +252,9 @@ gst_vdpaudecoder_sink_set_caps (GstPad * pad, GstCaps * caps) &framerate_numerator, &framerate_denominator); src_caps = gst_pad_get_allowed_caps (dec->src); - GST_DEBUG ("caps: %s\n\n", gst_caps_to_string (src_caps)); structure = gst_caps_get_structure (src_caps, 0); + gst_structure_get_fourcc (structure, "format", &fourcc_format); gst_structure_set (structure, "width", G_TYPE_INT, width, "height", G_TYPE_INT, height, @@ -255,11 +267,12 @@ gst_vdpaudecoder_sink_set_caps (GstPad * pad, GstCaps * caps) res = gst_pad_set_caps (dec->src, new_caps); gst_caps_unref (new_caps); - GST_DEBUG ("caps: %s\n\n", gst_caps_to_string (gst_pad_get_caps (dec->src))); if (!res) return FALSE; + dec->format = fourcc_format; + return TRUE; } diff --git a/sys/vdpau/gstvdpaudecoder.h b/sys/vdpau/gstvdpaudecoder.h index f713b0dd..7d59f2e2 100644 --- a/sys/vdpau/gstvdpaudecoder.h +++ b/sys/vdpau/gstvdpaudecoder.h @@ -54,6 +54,8 @@ struct _GstVdpauDecoder { GstCaps *src_caps; + guint32 format; + gboolean silent; }; -- cgit v1.2.1 From 3a48982235b6e97af21986e427dcaffa636acfb8 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Mon, 23 Mar 2009 21:36:55 +0100 Subject: vdpau: init vdpau in GST_STATE_CHANGE_NULL_TO_READY add gst_vdpaudecoder_push_video_surface to vdpaudecoder.h --- sys/vdpau/gstvdpaudecoder.c | 36 +++++++++++++++++++++++++++++++----- sys/vdpau/gstvdpaudecoder.h | 2 ++ sys/vdpau/vdpauvariables.h | 4 ++-- 3 files changed, 35 insertions(+), 7 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpaudecoder.c b/sys/vdpau/gstvdpaudecoder.c index bea707f5..932490b9 100644 --- a/sys/vdpau/gstvdpaudecoder.c +++ b/sys/vdpau/gstvdpaudecoder.c @@ -71,7 +71,7 @@ static void gst_vdpaudecoder_set_property (GObject * object, guint prop_id, static void gst_vdpaudecoder_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); -static gboolean +gboolean gst_vdpaudecoder_push_video_surface (GstVdpauDecoder * dec, VdpVideoSurface * surface) { @@ -82,6 +82,8 @@ gst_vdpaudecoder_push_video_surface (GstVdpauDecoder * dec, default: break; } + + return TRUE; } typedef struct @@ -201,7 +203,7 @@ gst_vdpaudecoder_init_vdpau (GstVdpauDecoder * dec) if (!display) { GST_ELEMENT_ERROR (dec, RESOURCE, READ, ("Could not initialise VDPAU"), ("Could not open display")); - return GST_STATE_CHANGE_FAILURE; + return FALSE; } screen = DefaultScreen (display); @@ -223,16 +225,40 @@ gst_vdpaudecoder_init_vdpau (GstVdpauDecoder * dec) vdp_get_proc_address (dec->device, VDP_FUNC_ID_VIDEO_SURFACE_QUERY_GET_PUT_BITS_Y_CB_CR_CAPABILITIES, (void **) &vdp_video_surface_query_ycbcr_capabilities); + vdp_get_proc_address (dec->device, + VDP_FUNC_ID_DEVICE_DESTROY, (void **) &vdp_device_destroy); caps = gst_vdpaudecoder_get_vdpau_support (dec); - if (!caps) + if (!caps) { + vdp_device_destroy (dec->device); + dec->device = 0; return FALSE; + } dec->src_caps = caps; return TRUE; } +static GstStateChangeReturn +gst_vdpaudecoder_change_state (GstElement * element, GstStateChange transition) +{ + GstVdpauDecoder *dec; + + dec = GST_VDPAU_DECODER (element); + + switch (transition) { + case GST_STATE_CHANGE_NULL_TO_READY: + if (!gst_vdpaudecoder_init_vdpau (dec)) + return GST_STATE_CHANGE_FAILURE; + break; + default: + break; + } + + return GST_STATE_CHANGE_SUCCESS; +} + static gboolean gst_vdpaudecoder_sink_set_caps (GstPad * pad, GstCaps * caps) { @@ -329,6 +355,8 @@ gst_vdpaudecoder_class_init (GstVdpauDecoderClass * klass) g_object_class_install_property (gobject_class, PROP_SILENT, g_param_spec_boolean ("silent", "Silent", "Produce verbose output ?", FALSE, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE)); + + gstelement_class->change_state = gst_vdpaudecoder_change_state; } static void @@ -347,8 +375,6 @@ gst_vdpaudecoder_init (GstVdpauDecoder * dec, GstVdpauDecoderClass * klass) (GST_ELEMENT_CLASS (klass), "sink"), "sink"); gst_pad_set_setcaps_function (dec->sink, gst_vdpaudecoder_sink_set_caps); gst_element_add_pad (GST_ELEMENT (dec), dec->sink); - - gst_vdpaudecoder_init_vdpau (dec); } static void diff --git a/sys/vdpau/gstvdpaudecoder.h b/sys/vdpau/gstvdpaudecoder.h index 7d59f2e2..2c8b11f7 100644 --- a/sys/vdpau/gstvdpaudecoder.h +++ b/sys/vdpau/gstvdpaudecoder.h @@ -65,6 +65,8 @@ struct _GstVdpauDecoderClass { GType gst_vdpaudecoder_get_type (void); +gboolean gst_vdpaudecoder_push_video_surface (GstVdpauDecoder * dec, VdpVideoSurface * surface); + G_END_DECLS #endif /* __GST_VDPAU_DECODER_H__ */ diff --git a/sys/vdpau/vdpauvariables.h b/sys/vdpau/vdpauvariables.h index ab274aa8..b93a75be 100644 --- a/sys/vdpau/vdpauvariables.h +++ b/sys/vdpau/vdpauvariables.h @@ -4,9 +4,9 @@ static VdpVideoSurfaceQueryCapabilities *vdp_video_surface_query_capabilities; static VdpVideoSurfaceQueryGetPutBitsYCbCrCapabilities *vdp_video_surface_query_ycbcr_capabilities; static VdpGetProcAddress *vdp_get_proc_address; -#if 0 - static VdpDeviceDestroy *vdp_device_destroy; + +#if 0 static VdpVideoSurfaceCreate *vdp_video_surface_create; static VdpVideoSurfaceDestroy *vdp_video_surface_destroy; -- cgit v1.2.1 From 2363032b34652ae2db9389620057e24dba1c0750 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Tue, 24 Mar 2009 22:26:56 +0100 Subject: vdpau: remove obsolete comment --- sys/vdpau/gstvdpaudecoder.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpaudecoder.c b/sys/vdpau/gstvdpaudecoder.c index 932490b9..a647a5f9 100644 --- a/sys/vdpau/gstvdpaudecoder.c +++ b/sys/vdpau/gstvdpaudecoder.c @@ -56,10 +56,6 @@ static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src", "framerate = (fraction) [ 0, MAX ], " "width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ]")); -/* debug category for fltering log messages - * - * FIXME:exchange the string 'Template vdpaudecoder' with your description - */ #define DEBUG_INIT(bla) \ GST_DEBUG_CATEGORY_INIT (gst_vdpaudecoder_debug, "vdpaudecoder", 0, "vdpaudecoder base class"); -- cgit v1.2.1 From 62757ca5b494969291b78f2b733891902b70b257 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Wed, 25 Mar 2009 19:59:06 +0100 Subject: vdpau: rough try at implementing pushinf of YV12 buffers --- sys/vdpau/gstvdpaudecoder.c | 37 +++++++++++++++++++++++++++++++++++-- sys/vdpau/gstvdpaudecoder.h | 3 ++- sys/vdpau/vdpauvariables.h | 1 + 3 files changed, 38 insertions(+), 3 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpaudecoder.c b/sys/vdpau/gstvdpaudecoder.c index a647a5f9..36d6eca0 100644 --- a/sys/vdpau/gstvdpaudecoder.c +++ b/sys/vdpau/gstvdpaudecoder.c @@ -69,12 +69,36 @@ static void gst_vdpaudecoder_get_property (GObject * object, guint prop_id, gboolean gst_vdpaudecoder_push_video_surface (GstVdpauDecoder * dec, - VdpVideoSurface * surface) + VdpVideoSurface surface) { switch (dec->format) { case GST_MAKE_FOURCC ('Y', 'V', '1', '2'): - /* YV12 specific code */ + { + gint size; + GstFlowReturn result; + GstBuffer *buffer; + VdpStatus status; + guint8 *data[3]; + + size = dec->height * dec->width + dec->height * dec->width / 2; + result = + gst_pad_alloc_buffer_and_set_caps (dec->src, GST_BUFFER_OFFSET_NONE, + size, GST_PAD_CAPS (dec->src), &buffer); + if (G_UNLIKELY (result != GST_FLOW_OK)) + return FALSE; + + data[0] = GST_BUFFER_DATA (buffer); + data[1] = data[0] + dec->height * dec->width; + data[2] = data[1] + dec->height * dec->width / 4; + + status = + vdp_video_surface_get_bits_ycbcr (surface, VDP_YCBCR_FORMAT_YV12, + (void *) data, NULL); + if (G_UNLIKELY (status != VDP_STATUS_OK)) + return FALSE; + break; + } default: break; } @@ -223,6 +247,9 @@ gst_vdpaudecoder_init_vdpau (GstVdpauDecoder * dec) (void **) &vdp_video_surface_query_ycbcr_capabilities); vdp_get_proc_address (dec->device, VDP_FUNC_ID_DEVICE_DESTROY, (void **) &vdp_device_destroy); + vdp_get_proc_address (dec->device, + VDP_FUNC_ID_VIDEO_SURFACE_GET_BITS_Y_CB_CR, + (void **) &vdp_video_surface_get_bits_ycbcr); caps = gst_vdpaudecoder_get_vdpau_support (dec); if (!caps) { @@ -293,6 +320,8 @@ gst_vdpaudecoder_sink_set_caps (GstPad * pad, GstCaps * caps) if (!res) return FALSE; + dec->width = width; + dec->height = height; dec->format = fourcc_format; return TRUE; @@ -363,6 +392,10 @@ gst_vdpaudecoder_init (GstVdpauDecoder * dec, GstVdpauDecoderClass * klass) dec->silent = FALSE; dec->src_caps = NULL; + dec->height = 0; + dec->width = 0; + dec->format = 0; + dec->src = gst_pad_new_from_static_template (&src_template, "src"); gst_pad_set_getcaps_function (dec->src, gst_vdpaudecoder_src_getcaps); gst_element_add_pad (GST_ELEMENT (dec), dec->src); diff --git a/sys/vdpau/gstvdpaudecoder.h b/sys/vdpau/gstvdpaudecoder.h index 2c8b11f7..336e4b8a 100644 --- a/sys/vdpau/gstvdpaudecoder.h +++ b/sys/vdpau/gstvdpaudecoder.h @@ -54,6 +54,7 @@ struct _GstVdpauDecoder { GstCaps *src_caps; + gint width, height; guint32 format; gboolean silent; @@ -65,7 +66,7 @@ struct _GstVdpauDecoderClass { GType gst_vdpaudecoder_get_type (void); -gboolean gst_vdpaudecoder_push_video_surface (GstVdpauDecoder * dec, VdpVideoSurface * surface); +gboolean gst_vdpaudecoder_push_video_surface (GstVdpauDecoder * dec, VdpVideoSurface surface); G_END_DECLS diff --git a/sys/vdpau/vdpauvariables.h b/sys/vdpau/vdpauvariables.h index b93a75be..c0f7bb4f 100644 --- a/sys/vdpau/vdpauvariables.h +++ b/sys/vdpau/vdpauvariables.h @@ -2,6 +2,7 @@ static VdpVideoSurfaceQueryCapabilities *vdp_video_surface_query_capabilities; static VdpVideoSurfaceQueryGetPutBitsYCbCrCapabilities *vdp_video_surface_query_ycbcr_capabilities; +static VdpVideoSurfaceGetBitsYCbCr *vdp_video_surface_get_bits_ycbcr; static VdpGetProcAddress *vdp_get_proc_address; static VdpDeviceDestroy *vdp_device_destroy; -- cgit v1.2.1 From f6ed342f197ba0d977a1203fb10db0726e7e1858 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Wed, 25 Mar 2009 20:38:27 +0100 Subject: vdpau: focus on mpeg instead of h264 --- sys/vdpau/Makefile.am | 4 +- sys/vdpau/gstvdpaumpegdecoder.c | 202 ++++++++++++++++++++++++++++++++++++++++ sys/vdpau/gstvdpaumpegdecoder.h | 88 +++++++++++++++++ 3 files changed, 292 insertions(+), 2 deletions(-) create mode 100644 sys/vdpau/gstvdpaumpegdecoder.c create mode 100644 sys/vdpau/gstvdpaumpegdecoder.h (limited to 'sys') diff --git a/sys/vdpau/Makefile.am b/sys/vdpau/Makefile.am index 3e718abe..94f7efbc 100644 --- a/sys/vdpau/Makefile.am +++ b/sys/vdpau/Makefile.am @@ -2,7 +2,7 @@ plugin_LTLIBRARIES = libgstvdpau.la libgstvdpau_la_SOURCES = \ gstvdpaudecoder.c\ - gstvdpauh264decoder.c + gstvdpaumpegdecoder.c libgstvdpau_la_CFLAGS = $(GST_CFLAGS) $(X11_CFLAGS) -Ivdpau libgstvdpau_la_LIBADD = $(GST_LIBS) $(X11_LIBS) -lvdpau @@ -12,6 +12,6 @@ libgstvdpau_la_LIBTOOLFLAGS = --tag=disable-static noinst_HEADERS = \ gstvdpaudecoder.h\ vdpauvariables.h \ - gstvdpauh264decoder.h + gstvdpaumpegdecoder.h diff --git a/sys/vdpau/gstvdpaumpegdecoder.c b/sys/vdpau/gstvdpaumpegdecoder.c new file mode 100644 index 00000000..24760474 --- /dev/null +++ b/sys/vdpau/gstvdpaumpegdecoder.c @@ -0,0 +1,202 @@ +/* + * GStreamer + * Copyright (C) 2005 Thomas Vander Stichele + * Copyright (C) 2005 Ronald S. Bultje + * Copyright (C) 2009 Carl-Anton Ingmarsson + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Alternatively, the contents of this file may be used under the + * GNU Lesser General Public License Version 2.1 (the "LGPL"), in + * which case the following provisions apply instead of the ones + * mentioned above: + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/** + * SECTION:element-vdpaumpegdecoder + * + * FIXME:Describe vdpaumpegdecoder here. + * + * + * Example launch line + * |[ + * gst-launch -v -m fakesrc ! vdpaumpegdecoder ! fakesink silent=TRUE + * ]| + * + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include "gstvdpaumpegdecoder.h" + +GST_DEBUG_CATEGORY_STATIC (gst_vdpau_mpeg_decoder_debug); +#define GST_CAT_DEFAULT gst_vdpau_mpeg_decoder_debug + +/* Filter signals and args */ +enum +{ + /* FILL ME */ + LAST_SIGNAL +}; + +enum +{ + PROP_0, + PROP_SILENT +}; + +/* the capabilities of the inputs and outputs. + * + * describe the real formats here. + */ +static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS ("video/x-mpeg") + ); + +GST_BOILERPLATE (GstVdpauMpegDecoder, gst_vdpau_mpeg_decoder, GstVdpauDecoder, + GST_TYPE_VDPAU_DECODER); + +static void gst_vdpau_mpeg_decoder_set_property (GObject * object, + guint prop_id, const GValue * value, GParamSpec * pspec); +static void gst_vdpau_mpeg_decoder_get_property (GObject * object, + guint prop_id, GValue * value, GParamSpec * pspec); + +/* GObject vmethod implementations */ + +static void +gst_vdpau_mpeg_decoder_base_init (gpointer gclass) +{ + GstElementClass *element_class = GST_ELEMENT_CLASS (gclass); + + gst_element_class_set_details_simple (element_class, + "VdpauMpegDecoder", + "Decoder", + "decode mpeg stream with vdpau", + "Carl-Anton Ingmarsson "); + + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&sink_factory)); +} + +/* initialize the vdpaumpegdecoder's class */ +static void +gst_vdpau_mpeg_decoder_class_init (GstVdpauMpegDecoderClass * klass) +{ + GObjectClass *gobject_class; + GstElementClass *gstelement_class; + + gobject_class = (GObjectClass *) klass; + gstelement_class = (GstElementClass *) klass; + + gobject_class->set_property = gst_vdpau_mpeg_decoder_set_property; + gobject_class->get_property = gst_vdpau_mpeg_decoder_get_property; + + g_object_class_install_property (gobject_class, PROP_SILENT, + g_param_spec_boolean ("silent", "Silent", "Produce verbose output ?", + FALSE, G_PARAM_READWRITE)); +} + +static void +gst_vdpau_mpeg_decoder_init (GstVdpauMpegDecoder * filter, + GstVdpauMpegDecoderClass * gclass) +{ + filter->silent = FALSE; +} + +static void +gst_vdpau_mpeg_decoder_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GstVdpauMpegDecoder *filter = GST_VDPAU_MPEG_DECODER (object); + + switch (prop_id) { + case PROP_SILENT: + filter->silent = g_value_get_boolean (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_vdpau_mpeg_decoder_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) +{ + GstVdpauMpegDecoder *filter = GST_VDPAU_MPEG_DECODER (object); + + switch (prop_id) { + case PROP_SILENT: + g_value_set_boolean (value, filter->silent); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +/* entry point to initialize the plug-in + * initialize the plug-in itself + * register the element factories and other features + */ +static gboolean +vdpaumpegdecoder_init (GstPlugin * vdpaumpegdecoder) +{ + /* debug category for fltering log messages + * + * exchange the string 'Template vdpaumpegdecoder' with your description + */ + GST_DEBUG_CATEGORY_INIT (gst_vdpau_mpeg_decoder_debug, "vdpaumpegdecoder", + 0, "Template vdpaumpegdecoder"); + + return gst_element_register (vdpaumpegdecoder, "vdpaumpegdecoder", + GST_RANK_NONE, GST_TYPE_VDPAU_MPEG_DECODER); +} + +/* gstreamer looks for this structure to register vdpaumpegdecoders + * + * exchange the string 'Template vdpaumpegdecoder' with your vdpaumpegdecoder description + */ +GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, + GST_VERSION_MINOR, + "vdpaumpegdecoder", + "Template vdpaumpegdecoder", + vdpaumpegdecoder_init, + VERSION, "LGPL", "GStreamer", "http://gstreamer.net/") diff --git a/sys/vdpau/gstvdpaumpegdecoder.h b/sys/vdpau/gstvdpaumpegdecoder.h new file mode 100644 index 00000000..14c9a3f7 --- /dev/null +++ b/sys/vdpau/gstvdpaumpegdecoder.h @@ -0,0 +1,88 @@ +/* + * GStreamer + * Copyright (C) 2005 Thomas Vander Stichele + * Copyright (C) 2005 Ronald S. Bultje + * Copyright (C) 2009 Carl-Anton Ingmarsson + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Alternatively, the contents of this file may be used under the + * GNU Lesser General Public License Version 2.1 (the "LGPL"), in + * which case the following provisions apply instead of the ones + * mentioned above: + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GST_VDPAU_MPEG_DECODER_H__ +#define __GST_VDPAU_MPEG_DECODER_H__ + +#include + +#include "gstvdpaudecoder.h" + +G_BEGIN_DECLS + +/* #defines don't like whitespacey bits */ +#define GST_TYPE_VDPAU_MPEG_DECODER \ + (gst_vdpau_mpeg_decoder_get_type()) +#define GST_VDPAU_MPEG_DECODER(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VDPAU_MPEG_DECODER,GstVdpauMpegDecoder)) +#define GST_VDPAU_MPEG_DECODER_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VDPAU_MPEG_DECODER,GstVdpauMpegDecoderClass)) +#define GST_IS_VDPAU_MPEG_DECODER(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VDPAU_MPEG_DECODER)) +#define GST_IS_VDPAU_MPEG_DECODER_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VDPAU_MPEG_DECODER)) + +typedef struct _GstVdpauMpegDecoder GstVdpauMpegDecoder; +typedef struct _GstVdpauMpegDecoderClass GstVdpauMpegDecoderClass; + +struct _GstVdpauMpegDecoder +{ + GstVdpauDecoder dec; + + GstPad *sinkpad, *srcpad; + + gboolean silent; +}; + +struct _GstVdpauMpegDecoderClass +{ + GstVdpauDecoderClass parent_class; +}; + +GType gst_vdpau_mpeg_decoder_get_type (void); + +G_END_DECLS + +#endif /* __GST_VDPAU_MPEG_DECODER_H__ */ -- cgit v1.2.1 From 367708e2ae7435fab215fd93b31234e553220c77 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Wed, 25 Mar 2009 20:41:46 +0100 Subject: vdpau: add version specification to mpegdecoder caps --- sys/vdpau/gstvdpauh264decoder.c | 202 ---------------------------------------- sys/vdpau/gstvdpauh264decoder.h | 88 ----------------- sys/vdpau/gstvdpaumpegdecoder.c | 2 +- 3 files changed, 1 insertion(+), 291 deletions(-) delete mode 100644 sys/vdpau/gstvdpauh264decoder.c delete mode 100644 sys/vdpau/gstvdpauh264decoder.h (limited to 'sys') diff --git a/sys/vdpau/gstvdpauh264decoder.c b/sys/vdpau/gstvdpauh264decoder.c deleted file mode 100644 index ce6eec11..00000000 --- a/sys/vdpau/gstvdpauh264decoder.c +++ /dev/null @@ -1,202 +0,0 @@ -/* - * GStreamer - * Copyright (C) 2005 Thomas Vander Stichele - * Copyright (C) 2005 Ronald S. Bultje - * Copyright (C) 2009 Carl-Anton Ingmarsson - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Alternatively, the contents of this file may be used under the - * GNU Lesser General Public License Version 2.1 (the "LGPL"), in - * which case the following provisions apply instead of the ones - * mentioned above: - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/** - * SECTION:element-vdpauh264decoder - * - * FIXME:Describe vdpauh264decoder here. - * - * - * Example launch line - * |[ - * gst-launch -v -m fakesrc ! vdpauh264decoder ! fakesink silent=TRUE - * ]| - * - */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include - -#include "gstvdpauh264decoder.h" - -GST_DEBUG_CATEGORY_STATIC (gst_vdpau_h264decoder_debug); -#define GST_CAT_DEFAULT gst_vdpau_h264decoder_debug - -/* Filter signals and args */ -enum -{ - /* FILL ME */ - LAST_SIGNAL -}; - -enum -{ - PROP_0, - PROP_SILENT -}; - -/* the capabilities of the inputs and outputs. - * - * describe the real formats here. - */ -static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("video/x-h264") - ); - -GST_BOILERPLATE (GstVdpauH264Decoder, gst_vdpau_h264decoder, GstVdpauDecoder, - GST_TYPE_VDPAU_DECODER); - -static void gst_vdpau_h264decoder_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec); -static void gst_vdpau_h264decoder_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec); - -/* GObject vmethod implementations */ - -static void -gst_vdpau_h264decoder_base_init (gpointer gclass) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS (gclass); - - gst_element_class_set_details_simple (element_class, - "VdpauH264Decoder", - "Decoder", - "decode h264 stream with vdpau", - "Carl-Anton Ingmarsson "); - - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&sink_factory)); -} - -/* initialize the vdpauh264decoder's class */ -static void -gst_vdpau_h264decoder_class_init (GstVdpauH264DecoderClass * klass) -{ - GObjectClass *gobject_class; - GstElementClass *gstelement_class; - - gobject_class = (GObjectClass *) klass; - gstelement_class = (GstElementClass *) klass; - - gobject_class->set_property = gst_vdpau_h264decoder_set_property; - gobject_class->get_property = gst_vdpau_h264decoder_get_property; - - g_object_class_install_property (gobject_class, PROP_SILENT, - g_param_spec_boolean ("silent", "Silent", "Produce verbose output ?", - FALSE, G_PARAM_READWRITE)); -} - -static void -gst_vdpau_h264decoder_init (GstVdpauH264Decoder * filter, - GstVdpauH264DecoderClass * gclass) -{ - filter->silent = FALSE; -} - -static void -gst_vdpau_h264decoder_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) -{ - GstVdpauH264Decoder *filter = GST_VDPAU_H264_DECODER (object); - - switch (prop_id) { - case PROP_SILENT: - filter->silent = g_value_get_boolean (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_vdpau_h264decoder_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec) -{ - GstVdpauH264Decoder *filter = GST_VDPAU_H264_DECODER (object); - - switch (prop_id) { - case PROP_SILENT: - g_value_set_boolean (value, filter->silent); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -/* entry point to initialize the plug-in - * initialize the plug-in itself - * register the element factories and other features - */ -static gboolean -vdpauh264decoder_init (GstPlugin * vdpauh264decoder) -{ - /* debug category for fltering log messages - * - * exchange the string 'Template vdpauh264decoder' with your description - */ - GST_DEBUG_CATEGORY_INIT (gst_vdpau_h264decoder_debug, "vdpauh264decoder", - 0, "Template vdpauh264decoder"); - - return gst_element_register (vdpauh264decoder, "vdpauh264decoder", - GST_RANK_NONE, GST_TYPE_VDPAU_H264_DECODER); -} - -/* gstreamer looks for this structure to register vdpauh264decoders - * - * exchange the string 'Template vdpauh264decoder' with your vdpauh264decoder description - */ -GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, - GST_VERSION_MINOR, - "vdpauh264decoder", - "Template vdpauh264decoder", - vdpauh264decoder_init, - VERSION, "LGPL", "GStreamer", "http://gstreamer.net/") diff --git a/sys/vdpau/gstvdpauh264decoder.h b/sys/vdpau/gstvdpauh264decoder.h deleted file mode 100644 index c3972047..00000000 --- a/sys/vdpau/gstvdpauh264decoder.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * GStreamer - * Copyright (C) 2005 Thomas Vander Stichele - * Copyright (C) 2005 Ronald S. Bultje - * Copyright (C) 2009 Carl-Anton Ingmarsson - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Alternatively, the contents of this file may be used under the - * GNU Lesser General Public License Version 2.1 (the "LGPL"), in - * which case the following provisions apply instead of the ones - * mentioned above: - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __GST_VDPAU_H264_DECODER_H__ -#define __GST_VDPAU_H264_DECODER_H__ - -#include - -#include "gstvdpaudecoder.h" - -G_BEGIN_DECLS - -/* #defines don't like whitespacey bits */ -#define GST_TYPE_VDPAU_H264_DECODER \ - (gst_vdpau_h264decoder_get_type()) -#define GST_VDPAU_H264_DECODER(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VDPAU_H264_DECODER,GstVdpauH264Decoder)) -#define GST_VDPAU_H264_DECODER_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VDPAU_H264_DECODER,GstVdpauH264DecoderClass)) -#define GST_IS_VDPAU_H264_DECODER(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VDPAU_H264_DECODER)) -#define GST_IS_VDPAU_H264_DECODER_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VDPAU_H264_DECODER)) - -typedef struct _GstVdpauH264Decoder GstVdpauH264Decoder; -typedef struct _GstVdpauH264DecoderClass GstVdpauH264DecoderClass; - -struct _GstVdpauH264Decoder -{ - GstVdpauDecoder dec; - - GstPad *sinkpad, *srcpad; - - gboolean silent; -}; - -struct _GstVdpauH264DecoderClass -{ - GstVdpauDecoderClass parent_class; -}; - -GType gst_vdpau_h264decoder_get_type (void); - -G_END_DECLS - -#endif /* __GST_VDPAU_H264_DECODER_H__ */ diff --git a/sys/vdpau/gstvdpaumpegdecoder.c b/sys/vdpau/gstvdpaumpegdecoder.c index 24760474..c22c27f3 100644 --- a/sys/vdpau/gstvdpaumpegdecoder.c +++ b/sys/vdpau/gstvdpaumpegdecoder.c @@ -87,7 +87,7 @@ enum static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, - GST_STATIC_CAPS ("video/x-mpeg") + GST_STATIC_CAPS ("video/x-mpeg, mpegversion = (int) [ 1, 2 ]") ); GST_BOILERPLATE (GstVdpauMpegDecoder, gst_vdpau_mpeg_decoder, GstVdpauDecoder, -- cgit v1.2.1 From 090638ccec59cebb11327d12ebcff78015716bed Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Thu, 26 Mar 2009 21:04:48 +0100 Subject: vdpau: extract mpeg version --- sys/vdpau/gstvdpaudecoder.c | 5 +++++ sys/vdpau/gstvdpaudecoder.h | 18 ++++++++---------- sys/vdpau/gstvdpaumpegdecoder.c | 21 ++++++++++++++++++++- sys/vdpau/gstvdpaumpegdecoder.h | 19 +++++++------------ 4 files changed, 40 insertions(+), 23 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpaudecoder.c b/sys/vdpau/gstvdpaudecoder.c index 36d6eca0..36a566e0 100644 --- a/sys/vdpau/gstvdpaudecoder.c +++ b/sys/vdpau/gstvdpaudecoder.c @@ -286,6 +286,7 @@ static gboolean gst_vdpaudecoder_sink_set_caps (GstPad * pad, GstCaps * caps) { GstVdpauDecoder *dec = GST_VDPAU_DECODER (GST_OBJECT_PARENT (pad)); + GstVdpauDecoderClass *dec_class = GST_VDPAU_DECODER_GET_CLASS (dec); GstCaps *src_caps, *new_caps; GstStructure *structure; @@ -324,6 +325,9 @@ gst_vdpaudecoder_sink_set_caps (GstPad * pad, GstCaps * caps) dec->height = height; dec->format = fourcc_format; + if (dec_class->set_caps && !dec_class->set_caps (dec, caps)) + return FALSE; + return TRUE; } @@ -404,6 +408,7 @@ gst_vdpaudecoder_init (GstVdpauDecoder * dec, GstVdpauDecoderClass * klass) (GST_ELEMENT_CLASS (klass), "sink"), "sink"); gst_pad_set_setcaps_function (dec->sink, gst_vdpaudecoder_sink_set_caps); gst_element_add_pad (GST_ELEMENT (dec), dec->sink); + gst_pad_set_active (dec->sink, TRUE); } static void diff --git a/sys/vdpau/gstvdpaudecoder.h b/sys/vdpau/gstvdpaudecoder.h index 336e4b8a..d8b8aa33 100644 --- a/sys/vdpau/gstvdpaudecoder.h +++ b/sys/vdpau/gstvdpaudecoder.h @@ -29,16 +29,12 @@ G_BEGIN_DECLS -#define GST_TYPE_VDPAU_DECODER \ - (gst_vdpaudecoder_get_type()) -#define GST_VDPAU_DECODER(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VDPAU_DECODER,GstVdpauDecoder)) -#define GST_VDPAU_DECODER_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VDPAU_DECODER,GstVdpauDecoderClass)) -#define GST_IS_VDPAU_DECODER(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VDPAU_DECODER)) -#define GST_IS_VDPAU_DECODER_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VDPAU_DECODER)) +#define GST_TYPE_VDPAU_DECODER (gst_vdpaudecoder_get_type()) +#define GST_VDPAU_DECODER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VDPAU_DECODER,GstVdpauDecoder)) +#define GST_VDPAU_DECODER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VDPAU_DECODER,GstVdpauDecoderClass)) +#define GST_VDPAU_DECODER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VDPAU_DECODER, GstVdpauDecoderClass)) +#define GST_IS_VDPAU_DECODER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VDPAU_DECODER)) +#define GST_IS_VDPAU_DECODER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VDPAU_DECODER)) typedef struct _GstVdpauDecoder GstVdpauDecoder; typedef struct _GstVdpauDecoderClass GstVdpauDecoderClass; @@ -62,6 +58,8 @@ struct _GstVdpauDecoder { struct _GstVdpauDecoderClass { GstBaseTransformClass parent_class; + + gboolean (*set_caps) (GstVdpauDecoder *dec, GstCaps *caps); }; GType gst_vdpaudecoder_get_type (void); diff --git a/sys/vdpau/gstvdpaumpegdecoder.c b/sys/vdpau/gstvdpaumpegdecoder.c index c22c27f3..380cf602 100644 --- a/sys/vdpau/gstvdpaumpegdecoder.c +++ b/sys/vdpau/gstvdpaumpegdecoder.c @@ -87,7 +87,8 @@ enum static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, - GST_STATIC_CAPS ("video/x-mpeg, mpegversion = (int) [ 1, 2 ]") + GST_STATIC_CAPS ("video/mpeg, mpegversion = (int) [ 1, 2 ], " + "systemstream = (boolean) false") ); GST_BOILERPLATE (GstVdpauMpegDecoder, gst_vdpau_mpeg_decoder, GstVdpauDecoder, @@ -98,6 +99,20 @@ static void gst_vdpau_mpeg_decoder_set_property (GObject * object, static void gst_vdpau_mpeg_decoder_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); +static gboolean +gst_vdpau_mpeg_decoder_set_caps (GstVdpauDecoder * dec, GstCaps * caps) +{ + GstVdpauMpegDecoder *mpeg_dec; + GstStructure *structure; + + mpeg_dec = GST_VDPAU_MPEG_DECODER (dec); + + structure = gst_caps_get_structure (caps, 0); + gst_structure_get_int (structure, "mpegversion", &mpeg_dec->version); + + return TRUE; +} + /* GObject vmethod implementations */ static void @@ -121,9 +136,11 @@ gst_vdpau_mpeg_decoder_class_init (GstVdpauMpegDecoderClass * klass) { GObjectClass *gobject_class; GstElementClass *gstelement_class; + GstVdpauDecoderClass *vdpaudec_class; gobject_class = (GObjectClass *) klass; gstelement_class = (GstElementClass *) klass; + vdpaudec_class = (GstVdpauDecoderClass *) klass; gobject_class->set_property = gst_vdpau_mpeg_decoder_set_property; gobject_class->get_property = gst_vdpau_mpeg_decoder_get_property; @@ -131,6 +148,8 @@ gst_vdpau_mpeg_decoder_class_init (GstVdpauMpegDecoderClass * klass) g_object_class_install_property (gobject_class, PROP_SILENT, g_param_spec_boolean ("silent", "Silent", "Produce verbose output ?", FALSE, G_PARAM_READWRITE)); + + vdpaudec_class->set_caps = gst_vdpau_mpeg_decoder_set_caps; } static void diff --git a/sys/vdpau/gstvdpaumpegdecoder.h b/sys/vdpau/gstvdpaumpegdecoder.h index 14c9a3f7..97462942 100644 --- a/sys/vdpau/gstvdpaumpegdecoder.h +++ b/sys/vdpau/gstvdpaumpegdecoder.h @@ -53,16 +53,11 @@ G_BEGIN_DECLS /* #defines don't like whitespacey bits */ -#define GST_TYPE_VDPAU_MPEG_DECODER \ - (gst_vdpau_mpeg_decoder_get_type()) -#define GST_VDPAU_MPEG_DECODER(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VDPAU_MPEG_DECODER,GstVdpauMpegDecoder)) -#define GST_VDPAU_MPEG_DECODER_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VDPAU_MPEG_DECODER,GstVdpauMpegDecoderClass)) -#define GST_IS_VDPAU_MPEG_DECODER(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VDPAU_MPEG_DECODER)) -#define GST_IS_VDPAU_MPEG_DECODER_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VDPAU_MPEG_DECODER)) +#define GST_TYPE_VDPAU_MPEG_DECODER (gst_vdpau_mpeg_decoder_get_type()) +#define GST_VDPAU_MPEG_DECODER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VDPAU_MPEG_DECODER,GstVdpauMpegDecoder)) +#define GST_VDPAU_MPEG_DECODER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VDPAU_MPEG_DECODER,GstVdpauMpegDecoderClass)) +#define GST_IS_VDPAU_MPEG_DECODER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VDPAU_MPEG_DECODER)) +#define GST_IS_VDPAU_MPEG_DECODER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VDPAU_MPEG_DECODER)) typedef struct _GstVdpauMpegDecoder GstVdpauMpegDecoder; typedef struct _GstVdpauMpegDecoderClass GstVdpauMpegDecoderClass; @@ -71,9 +66,9 @@ struct _GstVdpauMpegDecoder { GstVdpauDecoder dec; - GstPad *sinkpad, *srcpad; - gboolean silent; + + gint version; }; struct _GstVdpauMpegDecoderClass -- cgit v1.2.1 From 29d0c5bdd8beeb2b1ed25e8bf37eec9a135c5422 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Fri, 27 Mar 2009 16:55:19 +0100 Subject: vdpau: extract mpeg2 profile from codec_data --- sys/vdpau/Makefile.am | 10 +- sys/vdpau/gstvdpaudecoder.c | 4 +- sys/vdpau/gstvdpaumpegdecoder.c | 29 ++++- sys/vdpau/gstvdpaumpegdecoder.h | 4 +- sys/vdpau/mpegutil.c | 227 ++++++++++++++++++++++++++++++++++++++++ sys/vdpau/mpegutil.h | 63 +++++++++++ 6 files changed, 325 insertions(+), 12 deletions(-) create mode 100644 sys/vdpau/mpegutil.c create mode 100644 sys/vdpau/mpegutil.h (limited to 'sys') diff --git a/sys/vdpau/Makefile.am b/sys/vdpau/Makefile.am index 94f7efbc..f66c4aa4 100644 --- a/sys/vdpau/Makefile.am +++ b/sys/vdpau/Makefile.am @@ -1,8 +1,9 @@ plugin_LTLIBRARIES = libgstvdpau.la libgstvdpau_la_SOURCES = \ - gstvdpaudecoder.c\ - gstvdpaumpegdecoder.c + gstvdpaudecoder.c \ + gstvdpaumpegdecoder.c \ + mpegutil.c libgstvdpau_la_CFLAGS = $(GST_CFLAGS) $(X11_CFLAGS) -Ivdpau libgstvdpau_la_LIBADD = $(GST_LIBS) $(X11_LIBS) -lvdpau @@ -10,8 +11,9 @@ libgstvdpau_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) libgstvdpau_la_LIBTOOLFLAGS = --tag=disable-static noinst_HEADERS = \ - gstvdpaudecoder.h\ + gstvdpaudecoder.h \ vdpauvariables.h \ - gstvdpaumpegdecoder.h + gstvdpaumpegdecoder.h \ + mpegutil.h diff --git a/sys/vdpau/gstvdpaudecoder.c b/sys/vdpau/gstvdpaudecoder.c index 36a566e0..7d4ecb39 100644 --- a/sys/vdpau/gstvdpaudecoder.c +++ b/sys/vdpau/gstvdpaudecoder.c @@ -302,6 +302,8 @@ gst_vdpaudecoder_sink_set_caps (GstPad * pad, GstCaps * caps) &framerate_numerator, &framerate_denominator); src_caps = gst_pad_get_allowed_caps (dec->src); + if (G_UNLIKELY (!src_caps)) + return FALSE; structure = gst_caps_get_structure (src_caps, 0); gst_structure_get_fourcc (structure, "format", &fourcc_format); @@ -318,7 +320,7 @@ gst_vdpaudecoder_sink_set_caps (GstPad * pad, GstCaps * caps) gst_caps_unref (new_caps); - if (!res) + if (G_UNLIKELY (!res)) return FALSE; dec->width = width; diff --git a/sys/vdpau/gstvdpaumpegdecoder.c b/sys/vdpau/gstvdpaumpegdecoder.c index 380cf602..e5da459f 100644 --- a/sys/vdpau/gstvdpaumpegdecoder.c +++ b/sys/vdpau/gstvdpaumpegdecoder.c @@ -1,7 +1,5 @@ /* * GStreamer - * Copyright (C) 2005 Thomas Vander Stichele - * Copyright (C) 2005 Ronald S. Bultje * Copyright (C) 2009 Carl-Anton Ingmarsson * * Permission is hereby granted, free of charge, to any person obtaining a @@ -62,6 +60,7 @@ #include +#include "mpegutil.h" #include "gstvdpaumpegdecoder.h" GST_DEBUG_CATEGORY_STATIC (gst_vdpau_mpeg_decoder_debug); @@ -88,7 +87,7 @@ static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, GST_STATIC_CAPS ("video/mpeg, mpegversion = (int) [ 1, 2 ], " - "systemstream = (boolean) false") + "systemstream = (boolean) false, parsed = (boolean) true") ); GST_BOILERPLATE (GstVdpauMpegDecoder, gst_vdpau_mpeg_decoder, GstVdpauDecoder, @@ -104,11 +103,33 @@ gst_vdpau_mpeg_decoder_set_caps (GstVdpauDecoder * dec, GstCaps * caps) { GstVdpauMpegDecoder *mpeg_dec; GstStructure *structure; + gint version; mpeg_dec = GST_VDPAU_MPEG_DECODER (dec); structure = gst_caps_get_structure (caps, 0); - gst_structure_get_int (structure, "mpegversion", &mpeg_dec->version); + gst_structure_get_int (structure, "mpegversion", &version); + if (version == 1) + mpeg_dec->profile = VDP_DECODER_PROFILE_MPEG1; + + else { + const GValue *value; + GstBuffer *codec_data; + MPEGSeqHdr hdr = { 0, }; + + value = gst_structure_get_value (structure, "codec_data"); + codec_data = gst_value_get_buffer (value); + mpeg_util_parse_sequence_hdr (&hdr, GST_BUFFER_DATA (codec_data), + GST_BUFFER_DATA (codec_data) + GST_BUFFER_SIZE (codec_data)); + switch (hdr.profile) { + case 5: + mpeg_dec->profile = VDP_DECODER_PROFILE_MPEG2_SIMPLE; + break; + default: + mpeg_dec->profile = VDP_DECODER_PROFILE_MPEG2_MAIN; + break; + } + } return TRUE; } diff --git a/sys/vdpau/gstvdpaumpegdecoder.h b/sys/vdpau/gstvdpaumpegdecoder.h index 97462942..830cc671 100644 --- a/sys/vdpau/gstvdpaumpegdecoder.h +++ b/sys/vdpau/gstvdpaumpegdecoder.h @@ -1,7 +1,5 @@ /* * GStreamer - * Copyright (C) 2005 Thomas Vander Stichele - * Copyright (C) 2005 Ronald S. Bultje * Copyright (C) 2009 Carl-Anton Ingmarsson * * Permission is hereby granted, free of charge, to any person obtaining a @@ -68,7 +66,7 @@ struct _GstVdpauMpegDecoder gboolean silent; - gint version; + VdpDecoderProfile profile; }; struct _GstVdpauMpegDecoderClass diff --git a/sys/vdpau/mpegutil.c b/sys/vdpau/mpegutil.c new file mode 100644 index 00000000..274fa853 --- /dev/null +++ b/sys/vdpau/mpegutil.c @@ -0,0 +1,227 @@ +/* GStreamer + * Copyright (C) 2007 Jan Schmidt + * Copyright (C) 2009 Carl-Anton Ingmarsson + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "mpegutil.h" + +guint8 bits[] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }; + +guint32 +read_bits (guint8 * buf, gint start_bit, gint n_bits) +{ + gint i; + guint32 ret = 0x00; + + buf += start_bit / 8; + start_bit %= 8; + + for (i = 0; i < n_bits; i++) { + guint32 tmp; + + tmp = ((*buf & bits[start_bit]) >> (7 - start_bit)); + ret = (ret | (tmp << (n_bits - i - 1))); + if (++start_bit == 8) { + buf += 1; + start_bit = 0; + } + } + + return ret; +} + +guint8 * +mpeg_util_find_start_code (guint32 * sync_word, guint8 * cur, guint8 * end) +{ + guint32 code; + + if (G_UNLIKELY (cur == NULL)) + return NULL; + + code = *sync_word; + + while (cur < end) { + code <<= 8; + + if (code == 0x00000100) { + /* Reset the sync word accumulator */ + *sync_word = 0xffffffff; + return cur; + } + + /* Add the next available byte to the collected sync word */ + code |= *cur++; + } + + *sync_word = code; + return NULL; +} + +static void +set_fps_from_code (MPEGSeqHdr * hdr, guint8 fps_code) +{ + const gint framerates[][2] = { + {30, 1}, {24000, 1001}, {24, 1}, {25, 1}, + {30000, 1001}, {30, 1}, {50, 1}, {60000, 1001}, + {60, 1}, {30, 1} + }; + + if (fps_code < 10) { + hdr->fps_n = framerates[fps_code][0]; + hdr->fps_d = framerates[fps_code][1]; + } else { + /* Force a valid framerate */ + hdr->fps_n = 30000; + hdr->fps_d = 1001; + } +} + +/* Set the Pixel Aspect Ratio in our hdr from a DAR code in the data */ +static void +set_par_from_dar (MPEGSeqHdr * hdr, guint8 asr_code) +{ + /* Pixel_width = DAR_width * display_vertical_size */ + /* Pixel_height = DAR_height * display_horizontal_size */ + switch (asr_code) { + case 0x02: /* 3:4 DAR = 4:3 pixels */ + hdr->par_w = 4 * hdr->height; + hdr->par_h = 3 * hdr->width; + break; + case 0x03: /* 9:16 DAR */ + hdr->par_w = 16 * hdr->height; + hdr->par_h = 9 * hdr->width; + break; + case 0x04: /* 1:2.21 DAR */ + hdr->par_w = 221 * hdr->height; + hdr->par_h = 100 * hdr->width; + break; + case 0x01: /* Square pixels */ + default: + hdr->par_w = hdr->par_h = 1; + break; + } +} + +static gboolean +mpeg_util_parse_extension_packet (MPEGSeqHdr * hdr, guint8 * data, guint8 * end) +{ + guint8 ext_code; + + if (G_UNLIKELY (data >= end)) + return FALSE; /* short extension packet */ + + ext_code = data[0] >> 4; + + switch (ext_code) { + case MPEG_PACKET_EXT_SEQUENCE: + { + /* Parse a Sequence Extension */ + guint8 horiz_size_ext, vert_size_ext; + guint8 fps_n_ext, fps_d_ext; + + if (G_UNLIKELY ((end - data) < 6)) + /* need at least 10 bytes, minus 4 for the start code 000001b5 */ + return FALSE; + + horiz_size_ext = ((data[1] << 1) & 0x02) | ((data[2] >> 7) & 0x01); + vert_size_ext = (data[2] >> 5) & 0x03; + hdr->profile = read_bits (data, 7, 3); + fps_n_ext = (data[5] >> 5) & 0x03; + fps_d_ext = data[5] & 0x1f; + + hdr->fps_n *= (fps_n_ext + 1); + hdr->fps_d *= (fps_d_ext + 1); + hdr->width += (horiz_size_ext << 12); + hdr->height += (vert_size_ext << 12); + break; + } + default: + break; + } + + return TRUE; +} + +gboolean +mpeg_util_parse_sequence_hdr (MPEGSeqHdr * hdr, guint8 * data, guint8 * end) +{ + guint32 code; + guint8 dar_idx, fps_idx; + guint32 sync_word = 0xffffffff; + gboolean constrained_flag; + gboolean load_intra_flag; + gboolean load_non_intra_flag; + + if (G_UNLIKELY ((end - data) < 12)) + return FALSE; /* Too small to be a sequence header */ + + code = GST_READ_UINT32_BE (data); + if (G_UNLIKELY (code != (0x00000100 | MPEG_PACKET_SEQUENCE))) + return FALSE; + + /* Skip the sync word */ + data += 4; + + /* Parse the MPEG 1 bits */ + hdr->mpeg_version = 1; + + code = GST_READ_UINT32_BE (data); + hdr->width = (code >> 20) & 0xfff; + hdr->height = (code >> 8) & 0xfff; + + dar_idx = (code >> 4) & 0xf; + set_par_from_dar (hdr, dar_idx); + fps_idx = code & 0xf; + set_fps_from_code (hdr, fps_idx); + + constrained_flag = (data[7] >> 2) & 0x01; + load_intra_flag = (data[7] >> 1) & 0x01; + if (load_intra_flag) { + if (G_UNLIKELY ((end - data) < 64)) + return FALSE; + data += 64; + } + + load_non_intra_flag = data[7] & 0x01; + if (load_non_intra_flag) { + if (G_UNLIKELY ((end - data) < 64)) + return FALSE; + data += 64; + } + + /* Advance past the rest of the MPEG-1 header */ + data += 8; + + /* Read MPEG-2 sequence extensions */ + data = mpeg_util_find_start_code (&sync_word, data, end); + while (data != NULL) { + if (G_UNLIKELY (data >= end)) + return FALSE; + + /* data points at the last byte of the start code */ + if (data[0] == MPEG_PACKET_EXTENSION) { + if (!mpeg_util_parse_extension_packet (hdr, data + 1, end)) + return FALSE; + + hdr->mpeg_version = 2; + } + data = mpeg_util_find_start_code (&sync_word, data, end); + } + + return TRUE; +} diff --git a/sys/vdpau/mpegutil.h b/sys/vdpau/mpegutil.h new file mode 100644 index 00000000..f0f8aca0 --- /dev/null +++ b/sys/vdpau/mpegutil.h @@ -0,0 +1,63 @@ +/* GStreamer + * Copyright (C) 2007 Jan Schmidt + * Copyright (C) 2009 Carl-Anton Ingmarsson + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __MPEGUTIL_H__ +#define __MPEGUTIL_H__ + +#include + +typedef struct MPEGSeqHdr MPEGSeqHdr; + +/* Packet ID codes for different packet types we + * care about */ +#define MPEG_PACKET_PICTURE 0x00 +#define MPEG_PACKET_SLICE_MIN 0x01 +#define MPEG_PACKET_SLICE_MAX 0xaf +#define MPEG_PACKET_SEQUENCE 0xb3 +#define MPEG_PACKET_EXTENSION 0xb5 +#define MPEG_PACKET_SEQUENCE_END 0xb7 +#define MPEG_PACKET_GOP 0xb8 +#define MPEG_PACKET_NONE 0xff + +/* Extension codes we care about */ +#define MPEG_PACKET_EXT_SEQUENCE 0x01 +#define MPEG_PACKET_EXT_SEQUENCE_DISPLAY 0x02 +#define MPEG_PACKET_EXT_QUANT_MATRIX 0x03 + +struct MPEGSeqHdr +{ + /* 0 for unknown, else 1 or 2 */ + guint8 mpeg_version; + + /* Pixel-Aspect Ratio from DAR code via set_par_from_dar */ + gint par_w, par_h; + /* Width and Height of the video */ + gint width, height; + /* Framerate */ + gint fps_n, fps_d; + + /* mpeg2 decoder profile */ + gint profile; +}; + +gboolean mpeg_util_parse_sequence_hdr (MPEGSeqHdr *hdr, + guint8 *data, guint8 *end); + +#endif -- cgit v1.2.1 From 584b000583c7050689d7a93e5d6dc7083bbdfcbd Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Fri, 27 Mar 2009 17:11:04 +0100 Subject: vdpau: store vdpau function pointers in a local structure --- sys/vdpau/Makefile.am | 1 - sys/vdpau/gstvdpaudecoder.c | 40 +++++++++++++++++++++++++-------------- sys/vdpau/gstvdpaudecoder.h | 17 +++++++++++++++++ sys/vdpau/vdpauvariables.h | 46 --------------------------------------------- 4 files changed, 43 insertions(+), 61 deletions(-) delete mode 100644 sys/vdpau/vdpauvariables.h (limited to 'sys') diff --git a/sys/vdpau/Makefile.am b/sys/vdpau/Makefile.am index f66c4aa4..b786be0d 100644 --- a/sys/vdpau/Makefile.am +++ b/sys/vdpau/Makefile.am @@ -12,7 +12,6 @@ libgstvdpau_la_LIBTOOLFLAGS = --tag=disable-static noinst_HEADERS = \ gstvdpaudecoder.h \ - vdpauvariables.h \ gstvdpaumpegdecoder.h \ mpegutil.h diff --git a/sys/vdpau/gstvdpaudecoder.c b/sys/vdpau/gstvdpaudecoder.c index 7d4ecb39..007837f4 100644 --- a/sys/vdpau/gstvdpaudecoder.c +++ b/sys/vdpau/gstvdpaudecoder.c @@ -29,7 +29,6 @@ #include #include -#include "vdpauvariables.h" #include "gstvdpaudecoder.h" GST_DEBUG_CATEGORY_STATIC (gst_vdpaudecoder_debug); @@ -71,6 +70,10 @@ gboolean gst_vdpaudecoder_push_video_surface (GstVdpauDecoder * dec, VdpVideoSurface surface) { + VdpauFunctions *f; + + f = dec->functions; + switch (dec->format) { case GST_MAKE_FOURCC ('Y', 'V', '1', '2'): { @@ -92,7 +95,7 @@ gst_vdpaudecoder_push_video_surface (GstVdpauDecoder * dec, data[2] = data[1] + dec->height * dec->width / 4; status = - vdp_video_surface_get_bits_ycbcr (surface, VDP_YCBCR_FORMAT_YV12, + f->vdp_video_surface_get_bits_ycbcr (surface, VDP_YCBCR_FORMAT_YV12, (void *) data, NULL); if (G_UNLIKELY (status != VDP_STATUS_OK)) return FALSE; @@ -151,9 +154,12 @@ static VdpauFormats formats[6] = { static GstCaps * gst_vdpaudecoder_get_vdpau_support (GstVdpauDecoder * dec) { + VdpauFunctions *f; GstCaps *caps; gint i; + f = dec->functions; + caps = gst_caps_new_empty (); for (i = 0; i < 3; i++) { @@ -161,7 +167,8 @@ gst_vdpaudecoder_get_vdpau_support (GstVdpauDecoder * dec) VdpBool is_supported; guint32 max_w, max_h; - status = vdp_video_surface_query_capabilities (dec->device, chroma_types[i], + status = + f->vdp_video_surface_query_capabilities (dec->device, chroma_types[i], &is_supported, &max_w, &max_h); if (status != VDP_STATUS_OK && status != VDP_STATUS_INVALID_CHROMA_TYPE) { @@ -179,7 +186,7 @@ gst_vdpaudecoder_get_vdpau_support (GstVdpauDecoder * dec) continue; status = - vdp_video_surface_query_ycbcr_capabilities (dec->device, + f->vdp_video_surface_query_ycbcr_capabilities (dec->device, formats[j].chroma_type, formats[j].format, &is_supported); if (status != VDP_STATUS_OK && status != VDP_STATUS_INVALID_Y_CB_CR_FORMAT) { @@ -215,6 +222,7 @@ gst_vdpaudecoder_init_vdpau (GstVdpauDecoder * dec) { Display *display; int screen; + VdpauFunctions *f; VdpStatus status; GstCaps *caps; @@ -226,10 +234,12 @@ gst_vdpaudecoder_init_vdpau (GstVdpauDecoder * dec) return FALSE; } + f = dec->functions; + screen = DefaultScreen (display); status = vdp_device_create_x11 (display, screen, &dec->device, - &vdp_get_proc_address); + &f->vdp_get_proc_address); if (status != VDP_STATUS_OK) { GST_ELEMENT_ERROR (dec, RESOURCE, READ, ("Could not initialise VDPAU"), ("Could not create VDPAU device")); @@ -239,21 +249,21 @@ gst_vdpaudecoder_init_vdpau (GstVdpauDecoder * dec) } XCloseDisplay (display); - vdp_get_proc_address (dec->device, + f->vdp_get_proc_address (dec->device, VDP_FUNC_ID_VIDEO_SURFACE_QUERY_CAPABILITIES, - (void **) &vdp_video_surface_query_capabilities); - vdp_get_proc_address (dec->device, + (void **) &f->vdp_video_surface_query_capabilities); + f->vdp_get_proc_address (dec->device, VDP_FUNC_ID_VIDEO_SURFACE_QUERY_GET_PUT_BITS_Y_CB_CR_CAPABILITIES, - (void **) &vdp_video_surface_query_ycbcr_capabilities); - vdp_get_proc_address (dec->device, - VDP_FUNC_ID_DEVICE_DESTROY, (void **) &vdp_device_destroy); - vdp_get_proc_address (dec->device, + (void **) &f->vdp_video_surface_query_ycbcr_capabilities); + f->vdp_get_proc_address (dec->device, + VDP_FUNC_ID_DEVICE_DESTROY, (void **) &f->vdp_device_destroy); + f->vdp_get_proc_address (dec->device, VDP_FUNC_ID_VIDEO_SURFACE_GET_BITS_Y_CB_CR, - (void **) &vdp_video_surface_get_bits_ycbcr); + (void **) &f->vdp_video_surface_get_bits_ycbcr); caps = gst_vdpaudecoder_get_vdpau_support (dec); if (!caps) { - vdp_device_destroy (dec->device); + f->vdp_device_destroy (dec->device); dec->device = 0; return FALSE; } @@ -402,6 +412,8 @@ gst_vdpaudecoder_init (GstVdpauDecoder * dec, GstVdpauDecoderClass * klass) dec->width = 0; dec->format = 0; + dec->functions = g_slice_new0 (VdpauFunctions); + dec->src = gst_pad_new_from_static_template (&src_template, "src"); gst_pad_set_getcaps_function (dec->src, gst_vdpaudecoder_src_getcaps); gst_element_add_pad (GST_ELEMENT (dec), dec->src); diff --git a/sys/vdpau/gstvdpaudecoder.h b/sys/vdpau/gstvdpaudecoder.h index d8b8aa33..2c1a274f 100644 --- a/sys/vdpau/gstvdpaudecoder.h +++ b/sys/vdpau/gstvdpaudecoder.h @@ -38,6 +38,7 @@ G_BEGIN_DECLS typedef struct _GstVdpauDecoder GstVdpauDecoder; typedef struct _GstVdpauDecoderClass GstVdpauDecoderClass; +typedef struct _VdpauFunctions VdpauFunctions; struct _GstVdpauDecoder { GstElement element; @@ -45,6 +46,8 @@ struct _GstVdpauDecoder { gchar *display; VdpDevice device; + VdpauFunctions *functions; + GstPad *src; GstPad *sink; @@ -62,6 +65,20 @@ struct _GstVdpauDecoderClass { gboolean (*set_caps) (GstVdpauDecoder *dec, GstCaps *caps); }; +struct _VdpauFunctions { + VdpGetProcAddress *vdp_get_proc_address; + + VdpVideoSurfaceQueryCapabilities *vdp_video_surface_query_capabilities; + VdpVideoSurfaceQueryGetPutBitsYCbCrCapabilities *vdp_video_surface_query_ycbcr_capabilities; + VdpVideoSurfaceGetBitsYCbCr *vdp_video_surface_get_bits_ycbcr; + + VdpDeviceDestroy *vdp_device_destroy; + + VdpDecoderCreate *vdp_decoder_create; + VdpDecoderDestroy *vdp_decoder_destroy; + VdpDecoderRender *vdp_decoder_render; +}; + GType gst_vdpaudecoder_get_type (void); gboolean gst_vdpaudecoder_push_video_surface (GstVdpauDecoder * dec, VdpVideoSurface surface); diff --git a/sys/vdpau/vdpauvariables.h b/sys/vdpau/vdpauvariables.h deleted file mode 100644 index c0f7bb4f..00000000 --- a/sys/vdpau/vdpauvariables.h +++ /dev/null @@ -1,46 +0,0 @@ -#include - -static VdpVideoSurfaceQueryCapabilities *vdp_video_surface_query_capabilities; -static VdpVideoSurfaceQueryGetPutBitsYCbCrCapabilities *vdp_video_surface_query_ycbcr_capabilities; -static VdpVideoSurfaceGetBitsYCbCr *vdp_video_surface_get_bits_ycbcr; - -static VdpGetProcAddress *vdp_get_proc_address; -static VdpDeviceDestroy *vdp_device_destroy; - -#if 0 -static VdpVideoSurfaceCreate *vdp_video_surface_create; -static VdpVideoSurfaceDestroy *vdp_video_surface_destroy; - -static VdpGetErrorString *vdp_get_error_string; - -static VdpVideoSurfacePutBitsYCbCr *vdp_video_surface_put_bits_y_cb_cr; -static VdpOutputSurfacePutBitsNative *vdp_output_surface_put_bits_native; - -static VdpOutputSurfaceCreate *vdp_output_surface_create; -static VdpOutputSurfaceDestroy *vdp_output_surface_destroy; - -static VdpVideoMixerCreate *vdp_video_mixer_create; -static VdpVideoMixerDestroy *vdp_video_mixer_destroy; -static VdpVideoMixerRender *vdp_video_mixer_render; -static VdpVideoMixerSetFeatureEnables *vdp_video_mixer_set_feature_enables; -static VdpVideoMixerSetAttributeValues *vdp_video_mixer_set_attribute_values; - -static VdpPresentationQueueTargetDestroy *vdp_presentation_queue_target_destroy; -static VdpPresentationQueueCreate *vdp_presentation_queue_create; -static VdpPresentationQueueDestroy *vdp_presentation_queue_destroy; -static VdpPresentationQueueDisplay *vdp_presentation_queue_display; -static VdpPresentationQueueBlockUntilSurfaceIdle *vdp_presentation_queue_block_until_surface_idle; -static VdpPresentationQueueTargetCreateX11 *vdp_presentation_queue_target_create_x11; - -static VdpOutputSurfaceRenderOutputSurface *vdp_output_surface_render_output_surface; -static VdpOutputSurfacePutBitsIndexed *vdp_output_surface_put_bits_indexed; -static VdpOutputSurfaceRenderBitmapSurface *vdp_output_surface_render_bitmap_surface; - -static VdpBitmapSurfaceCreate *vdp_bitmap_surface_create; -static VdpBitmapSurfaceDestroy *vdp_bitmap_surface_destroy; -static VdpBitmapSurfacePutBitsNative *vdp_bitmap_surface_putbits_native; - -static VdpDecoderCreate *vdp_decoder_create; -static VdpDecoderDestroy *vdp_decoder_destroy; -static VdpDecoderRender *vdp_decoder_render; -#endif \ No newline at end of file -- cgit v1.2.1 From f70ddb66050244bdc0833d7cdc6c1b2e64f425ff Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Sun, 29 Mar 2009 15:28:06 +0200 Subject: vdpau: create VdpDecoder in set_caps add more functions for parsing mpeg --- sys/vdpau/gstvdpaudecoder.c | 128 ++++++++++++++++++++++++++++------------ sys/vdpau/gstvdpaudecoder.h | 15 +++-- sys/vdpau/gstvdpaumpegdecoder.c | 25 ++++++-- sys/vdpau/gstvdpaumpegdecoder.h | 2 +- sys/vdpau/mpegutil.c | 115 ++++++++++++++++++++++++++++++++++++ sys/vdpau/mpegutil.h | 39 +++++++++++- 6 files changed, 276 insertions(+), 48 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpaudecoder.c b/sys/vdpau/gstvdpaudecoder.c index 007837f4..c13b0173 100644 --- a/sys/vdpau/gstvdpaudecoder.c +++ b/sys/vdpau/gstvdpaudecoder.c @@ -26,10 +26,8 @@ #include #include -#include -#include - #include "gstvdpaudecoder.h" +#include GST_DEBUG_CATEGORY_STATIC (gst_vdpaudecoder_debug); #define GST_CAT_DEFAULT gst_vdpaudecoder_debug @@ -173,8 +171,9 @@ gst_vdpaudecoder_get_vdpau_support (GstVdpauDecoder * dec) if (status != VDP_STATUS_OK && status != VDP_STATUS_INVALID_CHROMA_TYPE) { GST_ELEMENT_ERROR (dec, RESOURCE, READ, - ("Could not get VDPAU capabilites"), - ("Could not query video surface capabilities")); + ("Could not get query VDPAU video surface capabilites"), + ("Error returned from vdpau was: %s", + f->vdp_get_error_string (status))); return NULL; } @@ -191,8 +190,9 @@ gst_vdpaudecoder_get_vdpau_support (GstVdpauDecoder * dec) if (status != VDP_STATUS_OK && status != VDP_STATUS_INVALID_Y_CB_CR_FORMAT) { GST_ELEMENT_ERROR (dec, RESOURCE, READ, - ("Could not get VDPAU capabilites"), - ("Could not query video surface ycbcr capabilities")); + ("Could not query VDPAU YCbCr capabilites"), + ("Error returned from vdpau was: %s", + f->vdp_get_error_string (status))); return NULL; } @@ -220,15 +220,45 @@ gst_vdpaudecoder_get_vdpau_support (GstVdpauDecoder * dec) static gboolean gst_vdpaudecoder_init_vdpau (GstVdpauDecoder * dec) { - Display *display; - int screen; - VdpauFunctions *f; + gint screen; VdpStatus status; + gint i; + VdpauFunctions *f; GstCaps *caps; + typedef struct + { + int id; + void *func; + } VdpFunction; + + VdpFunction vdp_function[] = { + {VDP_FUNC_ID_DEVICE_DESTROY, &dec->functions->vdp_device_destroy}, + {VDP_FUNC_ID_VIDEO_SURFACE_CREATE, + &dec->functions->vdp_video_surface_create}, + {VDP_FUNC_ID_VIDEO_SURFACE_DESTROY, + &dec->functions->vdp_video_surface_destroy}, + {VDP_FUNC_ID_VIDEO_SURFACE_QUERY_CAPABILITIES, + &dec->functions->vdp_video_surface_query_capabilities}, + {VDP_FUNC_ID_VIDEO_SURFACE_QUERY_GET_PUT_BITS_Y_CB_CR_CAPABILITIES, + &dec->functions->vdp_video_surface_query_ycbcr_capabilities}, + {VDP_FUNC_ID_VIDEO_SURFACE_GET_BITS_Y_CB_CR, + &dec->functions->vdp_video_surface_get_bits_ycbcr}, + {VDP_FUNC_ID_VIDEO_SURFACE_GET_PARAMETERS, + &dec->functions->vdp_video_surface_get_parameters}, + {VDP_FUNC_ID_DECODER_CREATE, &dec->functions->vdp_decoder_create}, + {VDP_FUNC_ID_DECODER_RENDER, &dec->functions->vdp_decoder_render}, + {VDP_FUNC_ID_DECODER_DESTROY, &dec->functions->vdp_decoder_destroy}, + {VDP_FUNC_ID_DECODER_QUERY_CAPABILITIES, + &dec->functions->vdp_decoder_query_capabilities}, + {VDP_FUNC_ID_DECODER_GET_PARAMETERS, + &dec->functions->vdp_decoder_get_parameters}, + {0, NULL} + }; + /* FIXME: We probably want to use the same VdpDevice for every VDPAU element */ - display = XOpenDisplay (dec->display); - if (!display) { + dec->display = XOpenDisplay (dec->display_name); + if (!dec->display) { GST_ELEMENT_ERROR (dec, RESOURCE, READ, ("Could not initialise VDPAU"), ("Could not open display")); return FALSE; @@ -236,55 +266,78 @@ gst_vdpaudecoder_init_vdpau (GstVdpauDecoder * dec) f = dec->functions; - screen = DefaultScreen (display); + screen = DefaultScreen (dec->display); status = - vdp_device_create_x11 (display, screen, &dec->device, + vdp_device_create_x11 (dec->display, screen, &dec->device, &f->vdp_get_proc_address); if (status != VDP_STATUS_OK) { GST_ELEMENT_ERROR (dec, RESOURCE, READ, ("Could not initialise VDPAU"), ("Could not create VDPAU device")); - XCloseDisplay (display); + XCloseDisplay (dec->display); + dec->display = NULL; return FALSE; } - XCloseDisplay (display); - - f->vdp_get_proc_address (dec->device, - VDP_FUNC_ID_VIDEO_SURFACE_QUERY_CAPABILITIES, - (void **) &f->vdp_video_surface_query_capabilities); - f->vdp_get_proc_address (dec->device, - VDP_FUNC_ID_VIDEO_SURFACE_QUERY_GET_PUT_BITS_Y_CB_CR_CAPABILITIES, - (void **) &f->vdp_video_surface_query_ycbcr_capabilities); - f->vdp_get_proc_address (dec->device, - VDP_FUNC_ID_DEVICE_DESTROY, (void **) &f->vdp_device_destroy); - f->vdp_get_proc_address (dec->device, - VDP_FUNC_ID_VIDEO_SURFACE_GET_BITS_Y_CB_CR, - (void **) &f->vdp_video_surface_get_bits_ycbcr); - caps = gst_vdpaudecoder_get_vdpau_support (dec); - if (!caps) { - f->vdp_device_destroy (dec->device); - dec->device = 0; - return FALSE; + status = f->vdp_get_proc_address (dec->device, + VDP_FUNC_ID_GET_ERROR_STRING, (void **) &f->vdp_get_error_string); + if (status != VDP_STATUS_OK) { + GST_ELEMENT_ERROR (dec, RESOURCE, READ, + ("Could'nt get function pointer from vdpau"), + ("Couldn't get vdp_get_error_string function pointer")); + goto error; } + for (i = 0; vdp_function[i].func != NULL; i++) { + status = f->vdp_get_proc_address (dec->device, + vdp_function[i].id, vdp_function[i].func); + + if (status != VDP_STATUS_OK) { + GST_ELEMENT_ERROR (dec, RESOURCE, READ, + ("Could not get function pointer from vdpau"), + ("Error returned from vdpau was: %s", + f->vdp_get_error_string (status))); + goto error; + } + } + + caps = gst_vdpaudecoder_get_vdpau_support (dec); + if (!caps) + goto error; + dec->src_caps = caps; return TRUE; + +error: + f->vdp_device_destroy (dec->device); + dec->device = VDP_INVALID_HANDLE; + + return FALSE; + } static GstStateChangeReturn gst_vdpaudecoder_change_state (GstElement * element, GstStateChange transition) { GstVdpauDecoder *dec; + VdpauFunctions *f; dec = GST_VDPAU_DECODER (element); + f = dec->functions; switch (transition) { case GST_STATE_CHANGE_NULL_TO_READY: if (!gst_vdpaudecoder_init_vdpau (dec)) return GST_STATE_CHANGE_FAILURE; break; + case GST_STATE_CHANGE_READY_TO_NULL: + f->vdp_device_destroy (dec->device); + XCloseDisplay (dec->display); + + dec->device = VDP_INVALID_HANDLE; + dec->display = NULL; + break; default: break; } @@ -403,8 +456,9 @@ gst_vdpaudecoder_class_init (GstVdpauDecoderClass * klass) static void gst_vdpaudecoder_init (GstVdpauDecoder * dec, GstVdpauDecoderClass * klass) { + dec->display_name = NULL; dec->display = NULL; - dec->device = 0; + dec->device = VDP_INVALID_HANDLE; dec->silent = FALSE; dec->src_caps = NULL; @@ -433,8 +487,8 @@ gst_vdpaudecoder_set_property (GObject * object, guint prop_id, switch (prop_id) { case PROP_DISPLAY: - g_free (dec->display); - dec->display = g_value_dup_string (value); + g_free (dec->display_name); + dec->display_name = g_value_dup_string (value); break; case PROP_SILENT: dec->silent = g_value_get_boolean (value); @@ -453,7 +507,7 @@ gst_vdpaudecoder_get_property (GObject * object, guint prop_id, switch (prop_id) { case PROP_DISPLAY: - g_value_set_string (value, dec->display); + g_value_set_string (value, dec->display_name); break; case PROP_SILENT: g_value_set_boolean (value, dec->silent); diff --git a/sys/vdpau/gstvdpaudecoder.h b/sys/vdpau/gstvdpaudecoder.h index 2c1a274f..5cd83042 100644 --- a/sys/vdpau/gstvdpaudecoder.h +++ b/sys/vdpau/gstvdpaudecoder.h @@ -25,6 +25,7 @@ #include #include +#include #include G_BEGIN_DECLS @@ -43,7 +44,8 @@ typedef struct _VdpauFunctions VdpauFunctions; struct _GstVdpauDecoder { GstElement element; - gchar *display; + gchar *display_name; + Display *display; VdpDevice device; VdpauFunctions *functions; @@ -66,17 +68,22 @@ struct _GstVdpauDecoderClass { }; struct _VdpauFunctions { + VdpDeviceDestroy *vdp_device_destroy; VdpGetProcAddress *vdp_get_proc_address; - + VdpGetErrorString *vdp_get_error_string; + + VdpVideoSurfaceCreate *vdp_video_surface_create; + VdpVideoSurfaceDestroy *vdp_video_surface_destroy; VdpVideoSurfaceQueryCapabilities *vdp_video_surface_query_capabilities; VdpVideoSurfaceQueryGetPutBitsYCbCrCapabilities *vdp_video_surface_query_ycbcr_capabilities; + VdpVideoSurfaceGetParameters *vdp_video_surface_get_parameters; VdpVideoSurfaceGetBitsYCbCr *vdp_video_surface_get_bits_ycbcr; - VdpDeviceDestroy *vdp_device_destroy; - VdpDecoderCreate *vdp_decoder_create; VdpDecoderDestroy *vdp_decoder_destroy; VdpDecoderRender *vdp_decoder_render; + VdpDecoderQueryCapabilities *vdp_decoder_query_capabilities; + VdpDecoderGetParameters *vdp_decoder_get_parameters; }; GType gst_vdpaudecoder_get_type (void); diff --git a/sys/vdpau/gstvdpaumpegdecoder.c b/sys/vdpau/gstvdpaumpegdecoder.c index e5da459f..6ff9b42a 100644 --- a/sys/vdpau/gstvdpaumpegdecoder.c +++ b/sys/vdpau/gstvdpaumpegdecoder.c @@ -104,13 +104,16 @@ gst_vdpau_mpeg_decoder_set_caps (GstVdpauDecoder * dec, GstCaps * caps) GstVdpauMpegDecoder *mpeg_dec; GstStructure *structure; gint version; + VdpDecoderProfile profile; + VdpauFunctions *f; + VdpStatus status; mpeg_dec = GST_VDPAU_MPEG_DECODER (dec); structure = gst_caps_get_structure (caps, 0); gst_structure_get_int (structure, "mpegversion", &version); if (version == 1) - mpeg_dec->profile = VDP_DECODER_PROFILE_MPEG1; + profile = VDP_DECODER_PROFILE_MPEG1; else { const GValue *value; @@ -123,14 +126,24 @@ gst_vdpau_mpeg_decoder_set_caps (GstVdpauDecoder * dec, GstCaps * caps) GST_BUFFER_DATA (codec_data) + GST_BUFFER_SIZE (codec_data)); switch (hdr.profile) { case 5: - mpeg_dec->profile = VDP_DECODER_PROFILE_MPEG2_SIMPLE; + profile = VDP_DECODER_PROFILE_MPEG2_SIMPLE; break; default: - mpeg_dec->profile = VDP_DECODER_PROFILE_MPEG2_MAIN; + profile = VDP_DECODER_PROFILE_MPEG2_MAIN; break; } } + f = dec->functions; + status = f->vdp_decoder_create (dec->device, profile, dec->width, + dec->height, 2, &mpeg_dec->decoder); + if (status != VDP_STATUS_OK) { + GST_ELEMENT_ERROR (mpeg_dec, RESOURCE, READ, + ("Could not create vdpau decoder"), + ("Error returned from vdpau was: %s", + f->vdp_get_error_string (status))); + return FALSE; + } return TRUE; } @@ -174,10 +187,12 @@ gst_vdpau_mpeg_decoder_class_init (GstVdpauMpegDecoderClass * klass) } static void -gst_vdpau_mpeg_decoder_init (GstVdpauMpegDecoder * filter, +gst_vdpau_mpeg_decoder_init (GstVdpauMpegDecoder * mpeg_dec, GstVdpauMpegDecoderClass * gclass) { - filter->silent = FALSE; + mpeg_dec->silent = FALSE; + + mpeg_dec->decoder = VDP_INVALID_HANDLE; } static void diff --git a/sys/vdpau/gstvdpaumpegdecoder.h b/sys/vdpau/gstvdpaumpegdecoder.h index 830cc671..0207ce31 100644 --- a/sys/vdpau/gstvdpaumpegdecoder.h +++ b/sys/vdpau/gstvdpaumpegdecoder.h @@ -66,7 +66,7 @@ struct _GstVdpauMpegDecoder gboolean silent; - VdpDecoderProfile profile; + VdpDecoder decoder; }; struct _GstVdpauMpegDecoderClass diff --git a/sys/vdpau/mpegutil.c b/sys/vdpau/mpegutil.c index 274fa853..aa77a426 100644 --- a/sys/vdpau/mpegutil.c +++ b/sys/vdpau/mpegutil.c @@ -18,8 +18,41 @@ * Boston, MA 02111-1307, USA. */ +#include + #include "mpegutil.h" +/* default intra quant matrix, in zig-zag order */ +static const guint8 default_intra_quantizer_matrix[64] = { + 8, + 16, 16, + 19, 16, 19, + 22, 22, 22, 22, + 22, 22, 26, 24, 26, + 27, 27, 27, 26, 26, 26, + 26, 27, 27, 27, 29, 29, 29, + 34, 34, 34, 29, 29, 29, 27, 27, + 29, 29, 32, 32, 34, 34, 37, + 38, 37, 35, 35, 34, 35, + 38, 38, 40, 40, 40, + 48, 48, 46, 46, + 56, 56, 58, + 69, 69, + 83 +}; + +guint8 mpeg2_scan[64] = { + /* Zig-Zag scan pattern */ + 0, 1, 8, 16, 9, 2, 3, 10, + 17, 24, 32, 25, 18, 11, 4, 5, + 12, 19, 26, 33, 40, 48, 41, 34, + 27, 20, 13, 6, 7, 14, 21, 28, + 35, 42, 49, 56, 57, 50, 43, 36, + 29, 22, 15, 23, 30, 37, 44, 51, + 58, 59, 52, 45, 38, 31, 39, 46, + 53, 60, 61, 54, 47, 55, 62, 63 +}; + guint8 bits[] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }; guint32 @@ -133,6 +166,7 @@ mpeg_util_parse_extension_packet (MPEGSeqHdr * hdr, guint8 * data, guint8 * end) /* Parse a Sequence Extension */ guint8 horiz_size_ext, vert_size_ext; guint8 fps_n_ext, fps_d_ext; + gint i, offset; if (G_UNLIKELY ((end - data) < 6)) /* need at least 10 bytes, minus 4 for the start code 000001b5 */ @@ -148,6 +182,23 @@ mpeg_util_parse_extension_packet (MPEGSeqHdr * hdr, guint8 * data, guint8 * end) hdr->fps_d *= (fps_d_ext + 1); hdr->width += (horiz_size_ext << 12); hdr->height += (vert_size_ext << 12); + + if (read_bits (data + 7, 6, 1)) { + for (i = 0; i < 64; i++) + hdr->intra_quantizer_matrix[mpeg2_scan[i]] = + read_bits (data + 7 + i, 7, 8); + offset = 64; + } else + memcpy (hdr->intra_quantizer_matrix, default_intra_quantizer_matrix, + 64); + + if (read_bits (data + 7 + offset, 7, 1)) { + for (i = 0; i < 64; i++) + hdr->non_intra_quantizer_matrix[mpeg2_scan[i]] = + read_bits (data + 8 + offset + i, 0, 8); + } else + memset (hdr->non_intra_quantizer_matrix, 0, 64); + break; } default: @@ -225,3 +276,67 @@ mpeg_util_parse_sequence_hdr (MPEGSeqHdr * hdr, guint8 * data, guint8 * end) return TRUE; } + +gboolean +mpeg_util_parse_picture_hdr (MPEGPictureHdr * hdr, guint8 * data, guint8 * end) +{ + guint32 code; + + if (G_UNLIKELY ((end - data) < 6)) + return FALSE; /* Packet too small */ + + code = GST_READ_UINT32_BE (data); + if (G_UNLIKELY (code != (0x00000100 | MPEG_PACKET_PICTURE))) + return FALSE; + + /* Skip the start code */ + data += 4; + + hdr->pic_type = (data[1] >> 3) & 0x07; + if (hdr->pic_type == 0 || hdr->pic_type > 4) + return FALSE; /* Corrupted picture packet */ + + if (hdr->pic_type == P_FRAME || hdr->pic_type == B_FRAME) { + if (G_UNLIKELY ((end - data) < 7)) + return FALSE; /* packet too small */ + + hdr->full_pel_forward_vector = read_bits (data + 3, 5, 1); + hdr->f_code[0][0] = hdr->f_code[0][1] = read_bits (data + 3, 6, 3); + + if (hdr->pic_type == B_FRAME) { + hdr->full_pel_backward_vector = read_bits (data + 4, 1, 1); + hdr->f_code[1][0] = hdr->f_code[1][1] = read_bits (data + 4, 2, 3); + } + } else { + hdr->full_pel_forward_vector = 0; + hdr->full_pel_backward_vector = 0; + } + + return TRUE; +} + +gboolean +mpeg_util_parse_picture_coding_extension (MPEGPictureExt * ext, guint8 * data, + guint8 * end) +{ + if (G_UNLIKELY ((end - data) < 7)) + return FALSE; /* Packet too small */ + + if (G_UNLIKELY (read_bits (data, 0, 4) != MPEG_PACKET_EXT_PICTURE_CODING)) + return FALSE; + + ext->f_code[0][0] = read_bits (data, 4, 4); + ext->f_code[0][1] = read_bits (data + 1, 0, 4); + ext->f_code[1][0] = read_bits (data + 1, 4, 4); + ext->f_code[1][1] = read_bits (data + 2, 0, 4); + + ext->intra_dc_precision = read_bits (data + 2, 4, 2); + ext->picture_structure = read_bits (data + 2, 6, 2); + ext->top_field_first = read_bits (data + 3, 0, 1); + ext->frame_pred_frame_dct = read_bits (data + 3, 1, 1); + ext->concealment_motion_vectors = read_bits (data + 3, 2, 1); + ext->q_scale_type = read_bits (data + 3, 3, 1); + ext->intra_vlc_format = read_bits (data + 3, 4, 1); + + return TRUE; +} diff --git a/sys/vdpau/mpegutil.h b/sys/vdpau/mpegutil.h index f0f8aca0..929e4fbb 100644 --- a/sys/vdpau/mpegutil.h +++ b/sys/vdpau/mpegutil.h @@ -24,6 +24,8 @@ #include typedef struct MPEGSeqHdr MPEGSeqHdr; +typedef struct MPEGPictureHdr MPEGPictureHdr; +typedef struct MPEGPictureExt MPEGPictureExt; /* Packet ID codes for different packet types we * care about */ @@ -40,6 +42,12 @@ typedef struct MPEGSeqHdr MPEGSeqHdr; #define MPEG_PACKET_EXT_SEQUENCE 0x01 #define MPEG_PACKET_EXT_SEQUENCE_DISPLAY 0x02 #define MPEG_PACKET_EXT_QUANT_MATRIX 0x03 +#define MPEG_PACKET_EXT_PICTURE_CODING 0x08 + +/* frame types */ +#define I_FRAME 1 +#define P_FRAME 2 +#define B_FRAME 3 struct MPEGSeqHdr { @@ -55,9 +63,38 @@ struct MPEGSeqHdr /* mpeg2 decoder profile */ gint profile; + + guint8 intra_quantizer_matrix[64]; + guint8 non_intra_quantizer_matrix[64]; +}; + +struct MPEGPictureHdr +{ + guint8 pic_type; + + guint8 full_pel_forward_vector, full_pel_backward_vector; + + guint8 f_code[2][2]; +}; + +struct MPEGPictureExt +{ + guint8 f_code[2][2]; + + guint8 intra_dc_precision; + guint8 picture_structure; + guint8 top_field_first; + guint8 frame_pred_frame_dct; + guint8 concealment_motion_vectors; + guint8 q_scale_type; + guint8 intra_vlc_format; }; gboolean mpeg_util_parse_sequence_hdr (MPEGSeqHdr *hdr, - guint8 *data, guint8 *end); + guint8 *data, guint8 *end); + +gboolean mpeg_util_parse_picture_hdr (MPEGPictureHdr * hdr, guint8 * data, guint8 * end); + +gboolean mpeg_util_parse_picture_coding_extension (MPEGPictureExt *ext, guint8 *data, guint8 *end); #endif -- cgit v1.2.1 From a727e6a0229823170a89ca79b9f07b79fbc7a061 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Tue, 31 Mar 2009 22:53:40 +0200 Subject: vdpau: MPEG1 decoding know gives recognizable output --- sys/vdpau/Makefile.am | 3 +- sys/vdpau/gstvdpaudecoder.c | 144 ++++++++++++++++++--- sys/vdpau/gstvdpaudecoder.h | 7 +- sys/vdpau/gstvdpaumpegdecoder.c | 272 ++++++++++++++++++++++++++++++++++++++-- sys/vdpau/gstvdpaumpegdecoder.h | 10 ++ sys/vdpau/mpegutil.c | 131 ++++++++++++++----- sys/vdpau/mpegutil.h | 23 ++++ 7 files changed, 529 insertions(+), 61 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/Makefile.am b/sys/vdpau/Makefile.am index b786be0d..ef43e5fd 100644 --- a/sys/vdpau/Makefile.am +++ b/sys/vdpau/Makefile.am @@ -6,7 +6,8 @@ libgstvdpau_la_SOURCES = \ mpegutil.c libgstvdpau_la_CFLAGS = $(GST_CFLAGS) $(X11_CFLAGS) -Ivdpau -libgstvdpau_la_LIBADD = $(GST_LIBS) $(X11_LIBS) -lvdpau +libgstvdpau_la_LIBADD = $(GST_LIBS) $(GST_BASE_LIBS) \ + $(GST_PLUGINS_BASE) $(X11_LIBS) -lgstvideo-$(GST_MAJORMINOR) -lvdpau libgstvdpau_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) libgstvdpau_la_LIBTOOLFLAGS = --tag=disable-static diff --git a/sys/vdpau/gstvdpaudecoder.c b/sys/vdpau/gstvdpaudecoder.c index c13b0173..fb2ce627 100644 --- a/sys/vdpau/gstvdpaudecoder.c +++ b/sys/vdpau/gstvdpaudecoder.c @@ -24,7 +24,7 @@ #endif #include -#include +#include #include "gstvdpaudecoder.h" #include @@ -64,11 +64,12 @@ static void gst_vdpaudecoder_set_property (GObject * object, guint prop_id, static void gst_vdpaudecoder_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); -gboolean -gst_vdpaudecoder_push_video_surface (GstVdpauDecoder * dec, +GstFlowReturn +gst_vdpau_decoder_push_video_surface (GstVdpauDecoder * dec, VdpVideoSurface surface) { VdpauFunctions *f; + GstBuffer *buffer; f = dec->functions; @@ -77,34 +78,98 @@ gst_vdpaudecoder_push_video_surface (GstVdpauDecoder * dec, { gint size; GstFlowReturn result; - GstBuffer *buffer; VdpStatus status; guint8 *data[3]; + guint32 stride[3]; - size = dec->height * dec->width + dec->height * dec->width / 2; + size = + gst_video_format_get_size (GST_VIDEO_FORMAT_YV12, dec->width, + dec->height); result = gst_pad_alloc_buffer_and_set_caps (dec->src, GST_BUFFER_OFFSET_NONE, size, GST_PAD_CAPS (dec->src), &buffer); if (G_UNLIKELY (result != GST_FLOW_OK)) - return FALSE; - - data[0] = GST_BUFFER_DATA (buffer); - data[1] = data[0] + dec->height * dec->width; - data[2] = data[1] + dec->height * dec->width / 4; + return result; + + + data[0] = GST_BUFFER_DATA (buffer) + + gst_video_format_get_component_offset (GST_VIDEO_FORMAT_YV12, + 0, dec->width, dec->height); + data[1] = data[0] + + gst_video_format_get_component_offset (GST_VIDEO_FORMAT_YV12, + 2, dec->width, dec->height); + data[2] = data[0] + + gst_video_format_get_component_offset (GST_VIDEO_FORMAT_YV12, + 1, dec->width, dec->height); + + stride[0] = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_YV12, + 0, dec->width); + stride[1] = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_YV12, + 2, dec->width); + stride[2] = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_YV12, + 1, dec->width); status = f->vdp_video_surface_get_bits_ycbcr (surface, VDP_YCBCR_FORMAT_YV12, - (void *) data, NULL); - if (G_UNLIKELY (status != VDP_STATUS_OK)) - return FALSE; + (void *) data, stride); + if (G_UNLIKELY (status != VDP_STATUS_OK)) { + GST_ELEMENT_ERROR (dec, RESOURCE, READ, + ("Couldn't get data from vdpau"), + ("Error returned from vdpau was: %s", + f->vdp_get_error_string (status))); + return GST_FLOW_ERROR; + } + break; + } + case GST_MAKE_FOURCC ('N', 'V', '1', '2'): + { + gint size; + GstFlowReturn result; + VdpStatus status; + guint8 *data[2]; + guint32 stride[2]; + + size = dec->width * dec->height + dec->width * dec->height / 2; + result = + gst_pad_alloc_buffer_and_set_caps (dec->src, GST_BUFFER_OFFSET_NONE, + size, GST_PAD_CAPS (dec->src), &buffer); + if (G_UNLIKELY (result != GST_FLOW_OK)) + return result; + + + data[0] = GST_BUFFER_DATA (buffer); + data[1] = data[0] + dec->width * dec->height; + stride[0] = dec->width; + stride[1] = dec->width; + + status = + f->vdp_video_surface_get_bits_ycbcr (surface, VDP_YCBCR_FORMAT_NV12, + (void *) data, stride); + if (G_UNLIKELY (status != VDP_STATUS_OK)) { + GST_ELEMENT_ERROR (dec, RESOURCE, READ, + ("Couldn't get data from vdpau"), + ("Error returned from vdpau was: %s", + f->vdp_get_error_string (status))); + return GST_FLOW_ERROR; + } break; } default: break; } - return TRUE; + GST_BUFFER_TIMESTAMP (buffer) = + gst_util_uint64_scale_int (GST_SECOND * dec->frame_nr, + dec->framerate_denominator, dec->framerate_numerator); + GST_BUFFER_DURATION (buffer) = + gst_util_uint64_scale_int (GST_SECOND, dec->framerate_denominator, + dec->framerate_numerator); + GST_BUFFER_OFFSET (buffer) = dec->frame_nr; + dec->frame_nr++; + GST_BUFFER_OFFSET_END (buffer) = dec->frame_nr; + + return gst_pad_push (dec->src, buffer); } typedef struct @@ -149,6 +214,38 @@ static VdpauFormats formats[6] = { } }; +VdpVideoSurface +gst_vdpau_decoder_create_video_surface (GstVdpauDecoder * dec) +{ + VdpauFunctions *f; + VdpChromaType chroma_type; + gint i; + VdpStatus status; + VdpVideoSurface surface; + + f = dec->functions; + + chroma_type = VDP_CHROMA_TYPE_422; + for (i = 0; i < 6; i++) { + if (formats[i].fourcc == dec->format) { + chroma_type = formats[i].chroma_type; + break; + } + } + + status = f->vdp_video_surface_create (dec->device, chroma_type, dec->width, + dec->height, &surface); + if (status != VDP_STATUS_OK) { + GST_ELEMENT_ERROR (dec, RESOURCE, READ, + ("Couldn't create a VdpVideoSurface"), + ("Error returned from vdpau was: %s", + f->vdp_get_error_string (status))); + return VDP_INVALID_HANDLE; + } + + return surface; +} + static GstCaps * gst_vdpaudecoder_get_vdpau_support (GstVdpauDecoder * dec) { @@ -355,6 +452,7 @@ gst_vdpaudecoder_sink_set_caps (GstPad * pad, GstCaps * caps) GstStructure *structure; gint width, height; gint framerate_numerator, framerate_denominator; + gint par_numerator, par_denominator; guint32 fourcc_format; gboolean res; @@ -363,21 +461,25 @@ gst_vdpaudecoder_sink_set_caps (GstPad * pad, GstCaps * caps) gst_structure_get_int (structure, "height", &height); gst_structure_get_fraction (structure, "framerate", &framerate_numerator, &framerate_denominator); + gst_structure_get_fraction (structure, "pixel-aspect-ratio", + &par_numerator, &par_denominator); src_caps = gst_pad_get_allowed_caps (dec->src); if (G_UNLIKELY (!src_caps)) return FALSE; - structure = gst_caps_get_structure (src_caps, 0); + new_caps = gst_caps_copy_nth (src_caps, 0); + gst_caps_unref (src_caps); + structure = gst_caps_get_structure (new_caps, 0); gst_structure_get_fourcc (structure, "format", &fourcc_format); gst_structure_set (structure, "width", G_TYPE_INT, width, "height", G_TYPE_INT, height, "framerate", GST_TYPE_FRACTION, framerate_numerator, - framerate_denominator, NULL); + framerate_denominator, + "pixel-aspect-ratio", GST_TYPE_FRACTION, par_numerator, + par_denominator, NULL); - new_caps = gst_caps_copy_nth (src_caps, 0); - gst_caps_unref (src_caps); gst_pad_fixate_caps (dec->src, new_caps); res = gst_pad_set_caps (dec->src, new_caps); @@ -388,6 +490,8 @@ gst_vdpaudecoder_sink_set_caps (GstPad * pad, GstCaps * caps) dec->width = width; dec->height = height; + dec->framerate_numerator = framerate_numerator; + dec->framerate_denominator = framerate_denominator; dec->format = fourcc_format; if (dec_class->set_caps && !dec_class->set_caps (dec, caps)) @@ -464,8 +568,12 @@ gst_vdpaudecoder_init (GstVdpauDecoder * dec, GstVdpauDecoderClass * klass) dec->height = 0; dec->width = 0; + dec->framerate_numerator = 0; + dec->framerate_denominator = 0; dec->format = 0; + dec->frame_nr = 0; + dec->functions = g_slice_new0 (VdpauFunctions); dec->src = gst_pad_new_from_static_template (&src_template, "src"); diff --git a/sys/vdpau/gstvdpaudecoder.h b/sys/vdpau/gstvdpaudecoder.h index 5cd83042..3ab3c9f3 100644 --- a/sys/vdpau/gstvdpaudecoder.h +++ b/sys/vdpau/gstvdpaudecoder.h @@ -56,8 +56,11 @@ struct _GstVdpauDecoder { GstCaps *src_caps; gint width, height; + gint framerate_numerator, framerate_denominator; guint32 format; + gint frame_nr; + gboolean silent; }; @@ -88,7 +91,9 @@ struct _VdpauFunctions { GType gst_vdpaudecoder_get_type (void); -gboolean gst_vdpaudecoder_push_video_surface (GstVdpauDecoder * dec, VdpVideoSurface surface); +gboolean gst_vdpau_decoder_push_video_surface (GstVdpauDecoder * dec, + VdpVideoSurface surface); +VdpVideoSurface gst_vdpau_decoder_create_video_surface (GstVdpauDecoder *dec); G_END_DECLS diff --git a/sys/vdpau/gstvdpaumpegdecoder.c b/sys/vdpau/gstvdpaumpegdecoder.c index 6ff9b42a..6f75181b 100644 --- a/sys/vdpau/gstvdpaumpegdecoder.c +++ b/sys/vdpau/gstvdpaumpegdecoder.c @@ -59,6 +59,7 @@ #endif #include +#include #include "mpegutil.h" #include "gstvdpaumpegdecoder.h" @@ -103,7 +104,9 @@ gst_vdpau_mpeg_decoder_set_caps (GstVdpauDecoder * dec, GstCaps * caps) { GstVdpauMpegDecoder *mpeg_dec; GstStructure *structure; - gint version; + const GValue *value; + GstBuffer *codec_data; + MPEGSeqHdr hdr = { 0, }; VdpDecoderProfile profile; VdpauFunctions *f; VdpStatus status; @@ -111,19 +114,15 @@ gst_vdpau_mpeg_decoder_set_caps (GstVdpauDecoder * dec, GstCaps * caps) mpeg_dec = GST_VDPAU_MPEG_DECODER (dec); structure = gst_caps_get_structure (caps, 0); - gst_structure_get_int (structure, "mpegversion", &version); - if (version == 1) + gst_structure_get_int (structure, "mpegversion", &mpeg_dec->version); + if (mpeg_dec->version == 1) profile = VDP_DECODER_PROFILE_MPEG1; - else { - const GValue *value; - GstBuffer *codec_data; - MPEGSeqHdr hdr = { 0, }; - - value = gst_structure_get_value (structure, "codec_data"); - codec_data = gst_value_get_buffer (value); - mpeg_util_parse_sequence_hdr (&hdr, GST_BUFFER_DATA (codec_data), - GST_BUFFER_DATA (codec_data) + GST_BUFFER_SIZE (codec_data)); + value = gst_structure_get_value (structure, "codec_data"); + codec_data = gst_value_get_buffer (value); + mpeg_util_parse_sequence_hdr (&hdr, GST_BUFFER_DATA (codec_data), + GST_BUFFER_DATA (codec_data) + GST_BUFFER_SIZE (codec_data)); + if (mpeg_dec->version != 1) { switch (hdr.profile) { case 5: profile = VDP_DECODER_PROFILE_MPEG2_SIMPLE; @@ -133,6 +132,10 @@ gst_vdpau_mpeg_decoder_set_caps (GstVdpauDecoder * dec, GstCaps * caps) break; } } + memcpy (&mpeg_dec->vdp_info.intra_quantizer_matrix, + &hdr.intra_quantizer_matrix, 64); + memcpy (&mpeg_dec->vdp_info.non_intra_quantizer_matrix, + &hdr.non_intra_quantizer_matrix, 64); f = dec->functions; status = f->vdp_decoder_create (dec->device, profile, dec->width, @@ -147,6 +150,228 @@ gst_vdpau_mpeg_decoder_set_caps (GstVdpauDecoder * dec, GstCaps * caps) return TRUE; } +static GstFlowReturn +gst_vdpau_mpeg_decoder_decode (GstVdpauMpegDecoder * mpeg_dec) +{ + GstVdpauDecoder *dec; + GstBuffer *buffer; + VdpVideoSurface surface; + VdpauFunctions *f; + VdpBitstreamBuffer vbit[1]; + VdpStatus status; + GstFlowReturn ret; + + dec = GST_VDPAU_DECODER (mpeg_dec); + + buffer = gst_adapter_take_buffer (mpeg_dec->adapter, + gst_adapter_available (mpeg_dec->adapter)); + + if (mpeg_dec->vdp_info.picture_coding_type == P_FRAME) { + mpeg_dec->p_buffer = buffer; + } + + surface = + gst_vdpau_decoder_create_video_surface (GST_VDPAU_DECODER (mpeg_dec)); + + f = dec->functions; + + vbit[0].struct_version = VDP_BITSTREAM_BUFFER_VERSION; + vbit[0].bitstream = GST_BUFFER_DATA (buffer); + vbit[0].bitstream_bytes = GST_BUFFER_SIZE (buffer); + + status = f->vdp_decoder_render (mpeg_dec->decoder, surface, + (VdpPictureInfo *) & mpeg_dec->vdp_info, 1, vbit); + gst_buffer_unref (buffer); + mpeg_dec->vdp_info.slice_count = 0; + + if (status != VDP_STATUS_OK) { + GST_ELEMENT_ERROR (mpeg_dec, RESOURCE, READ, + ("Could not decode"), + ("Error returned from vdpau was: %s", + f->vdp_get_error_string (status))); + + if (mpeg_dec->vdp_info.forward_reference != VDP_INVALID_HANDLE) + f->vdp_video_surface_destroy (mpeg_dec->vdp_info.forward_reference); + + f->vdp_video_surface_destroy (surface); + + return GST_FLOW_ERROR; + } + + ret = + gst_vdpau_decoder_push_video_surface (GST_VDPAU_DECODER (mpeg_dec), + surface); + + if (mpeg_dec->vdp_info.forward_reference != VDP_INVALID_HANDLE) + f->vdp_video_surface_destroy (mpeg_dec->vdp_info.forward_reference); + + mpeg_dec->vdp_info.forward_reference = surface; + + return ret; +} + +static gboolean +gst_vdpau_mpeg_decoder_parse_picture_coding (GstVdpauMpegDecoder * mpeg_dec, + guint8 * data, guint8 * end) +{ + GstVdpauDecoder *dec; + MPEGPictureExt pic_ext; + VdpPictureInfoMPEG1Or2 *info; + + dec = GST_VDPAU_DECODER (mpeg_dec); + info = &mpeg_dec->vdp_info; + + if (!mpeg_util_parse_picture_coding_extension (&pic_ext, data, end)) + return FALSE; + + memcpy (&mpeg_dec->vdp_info.f_code, &pic_ext.f_code, 4); + + info->intra_dc_precision = pic_ext.intra_dc_precision; + info->picture_structure = pic_ext.picture_structure; + info->top_field_first = pic_ext.top_field_first; + info->frame_pred_frame_dct = pic_ext.frame_pred_frame_dct; + info->concealment_motion_vectors = pic_ext.concealment_motion_vectors; + info->q_scale_type = pic_ext.q_scale_type; + info->intra_vlc_format = pic_ext.intra_vlc_format; + + return TRUE; +} + +static gboolean +gst_vdpau_mpeg_decoder_parse_picture (GstVdpauMpegDecoder * mpeg_dec, + guint8 * data, guint8 * end) +{ + GstVdpauDecoder *dec; + MPEGPictureHdr pic_hdr; + + dec = GST_VDPAU_DECODER (mpeg_dec); + + if (!mpeg_util_parse_picture_hdr (&pic_hdr, data, end)) + return FALSE; + + mpeg_dec->vdp_info.picture_coding_type = pic_hdr.pic_type; + + + if (pic_hdr.pic_type == I_FRAME && + mpeg_dec->vdp_info.forward_reference != VDP_INVALID_HANDLE) { + dec->functions->vdp_video_surface_destroy (mpeg_dec->vdp_info. + forward_reference); + mpeg_dec->vdp_info.forward_reference = VDP_INVALID_HANDLE; + } + + if (mpeg_dec->version == 1) { + mpeg_dec->vdp_info.full_pel_forward_vector = + pic_hdr.full_pel_forward_vector; + mpeg_dec->vdp_info.full_pel_backward_vector = + pic_hdr.full_pel_backward_vector; + memcpy (&mpeg_dec->vdp_info.f_code, &pic_hdr.f_code, 4); + } + + return TRUE; +} + +static gboolean +gst_vdpau_mpeg_decoder_parse_gop (GstVdpauMpegDecoder * mpeg_dec, guint8 * data, + guint8 * end) +{ + MPEGPictureGOP gop; + + if (!mpeg_util_parse_picture_gop (&gop, data, end)) + return FALSE; + + return TRUE; +} + +static gboolean +gst_vdpau_mpeg_decoder_parse_quant_matrix (GstVdpauMpegDecoder * mpeg_dec, + guint8 * data, guint8 * end) +{ + MPEGQuantMatrix qm; + + if (!mpeg_util_parse_quant_matrix (&qm, data, end)) + return FALSE; + + memcpy (&mpeg_dec->vdp_info.intra_quantizer_matrix, + &qm.intra_quantizer_matrix, 64); + memcpy (&mpeg_dec->vdp_info.non_intra_quantizer_matrix, + &qm.non_intra_quantizer_matrix, 64); + return TRUE; +} + +static GstFlowReturn +gst_vdpau_mpeg_decoder_chain (GstPad * pad, GstBuffer * buffer) +{ + GstVdpauMpegDecoder *mpeg_dec; + guint8 *data, *end; + guint32 sync_word = 0xffffffff; + + mpeg_dec = GST_VDPAU_MPEG_DECODER (GST_OBJECT_PARENT (pad)); + + data = GST_BUFFER_DATA (buffer); + end = GST_BUFFER_DATA (buffer) + GST_BUFFER_SIZE (buffer); + + while ((data = mpeg_util_find_start_code (&sync_word, data, end))) { + guint8 *packet_start; + guint8 *packet_end; + + packet_start = data - 3; + packet_end = mpeg_util_find_start_code (&sync_word, data, end); + if (packet_end) + packet_end -= 3; + else + packet_end = end; + + if (data[0] >= MPEG_PACKET_SLICE_MIN && data[0] <= MPEG_PACKET_SLICE_MAX) { + GstBuffer *subbuf; + + GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_SLICE"); + subbuf = + gst_buffer_create_sub (buffer, + packet_start - GST_BUFFER_DATA (buffer), packet_end - packet_start); + gst_adapter_push (mpeg_dec->adapter, subbuf); + mpeg_dec->vdp_info.slice_count++; + } else if (mpeg_dec->vdp_info.slice_count > 0) { + if (gst_vdpau_mpeg_decoder_decode (mpeg_dec) != GST_FLOW_OK) + return GST_FLOW_ERROR; + } + + switch (data[0]) { + case MPEG_PACKET_PICTURE: + GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_PICTURE"); + gst_vdpau_mpeg_decoder_parse_picture (mpeg_dec, packet_start, + packet_end); + break; + case MPEG_PACKET_SEQUENCE: + GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_SEQUENCE"); + break; + case MPEG_PACKET_EXTENSION: + GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_EXTENSION"); + switch (read_bits (data + 1, 0, 4)) { + case MPEG_PACKET_EXT_PICTURE_CODING: + gst_vdpau_mpeg_decoder_parse_picture_coding (mpeg_dec, packet_start, + packet_end); + break; + default: + break; + } + break; + case MPEG_PACKET_EXT_QUANT_MATRIX: + GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_EXT_QUANT_MATRIX"); + gst_vdpau_mpeg_decoder_parse_quant_matrix (mpeg_dec, packet_start, + packet_end); + break; + case MPEG_PACKET_GOP: + GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_GOP"); + gst_vdpau_mpeg_decoder_parse_gop (mpeg_dec, packet_start, packet_end); + break; + default: + break; + } + } + + return GST_FLOW_OK; +} + /* GObject vmethod implementations */ static void @@ -186,13 +411,34 @@ gst_vdpau_mpeg_decoder_class_init (GstVdpauMpegDecoderClass * klass) vdpaudec_class->set_caps = gst_vdpau_mpeg_decoder_set_caps; } +static void +gst_vdpau_mpeg_decoder_init_info (VdpPictureInfoMPEG1Or2 * vdp_info) +{ + vdp_info->forward_reference = VDP_INVALID_HANDLE; + vdp_info->backward_reference = VDP_INVALID_HANDLE; + vdp_info->slice_count = 0; + vdp_info->picture_structure = 0; + vdp_info->picture_coding_type = 0; + vdp_info->intra_dc_precision = 0; + vdp_info->frame_pred_frame_dct = 0; + vdp_info->concealment_motion_vectors = 0; +} + static void gst_vdpau_mpeg_decoder_init (GstVdpauMpegDecoder * mpeg_dec, GstVdpauMpegDecoderClass * gclass) { - mpeg_dec->silent = FALSE; + GstVdpauDecoder *dec; + + dec = GST_VDPAU_DECODER (mpeg_dec); + mpeg_dec->silent = FALSE; mpeg_dec->decoder = VDP_INVALID_HANDLE; + gst_vdpau_mpeg_decoder_init_info (&mpeg_dec->vdp_info); + + mpeg_dec->adapter = gst_adapter_new (); + + gst_pad_set_chain_function (dec->sink, gst_vdpau_mpeg_decoder_chain); } static void diff --git a/sys/vdpau/gstvdpaumpegdecoder.h b/sys/vdpau/gstvdpaumpegdecoder.h index 0207ce31..36c02534 100644 --- a/sys/vdpau/gstvdpaumpegdecoder.h +++ b/sys/vdpau/gstvdpaumpegdecoder.h @@ -45,6 +45,7 @@ #define __GST_VDPAU_MPEG_DECODER_H__ #include +#include #include "gstvdpaudecoder.h" @@ -66,7 +67,16 @@ struct _GstVdpauMpegDecoder gboolean silent; + gint version; + VdpDecoder decoder; + VdpPictureInfoMPEG1Or2 vdp_info; + + GstAdapter *adapter; + gint slices; + + GstBuffer *p_buffer; + VdpPictureInfoMPEG1Or2 p_vdp_info; }; struct _GstVdpauMpegDecoderClass diff --git a/sys/vdpau/mpegutil.c b/sys/vdpau/mpegutil.c index aa77a426..8bba8d1f 100644 --- a/sys/vdpau/mpegutil.c +++ b/sys/vdpau/mpegutil.c @@ -166,7 +166,6 @@ mpeg_util_parse_extension_packet (MPEGSeqHdr * hdr, guint8 * data, guint8 * end) /* Parse a Sequence Extension */ guint8 horiz_size_ext, vert_size_ext; guint8 fps_n_ext, fps_d_ext; - gint i, offset; if (G_UNLIKELY ((end - data) < 6)) /* need at least 10 bytes, minus 4 for the start code 000001b5 */ @@ -182,23 +181,6 @@ mpeg_util_parse_extension_packet (MPEGSeqHdr * hdr, guint8 * data, guint8 * end) hdr->fps_d *= (fps_d_ext + 1); hdr->width += (horiz_size_ext << 12); hdr->height += (vert_size_ext << 12); - - if (read_bits (data + 7, 6, 1)) { - for (i = 0; i < 64; i++) - hdr->intra_quantizer_matrix[mpeg2_scan[i]] = - read_bits (data + 7 + i, 7, 8); - offset = 64; - } else - memcpy (hdr->intra_quantizer_matrix, default_intra_quantizer_matrix, - 64); - - if (read_bits (data + 7 + offset, 7, 1)) { - for (i = 0; i < 64; i++) - hdr->non_intra_quantizer_matrix[mpeg2_scan[i]] = - read_bits (data + 8 + offset + i, 0, 8); - } else - memset (hdr->non_intra_quantizer_matrix, 0, 64); - break; } default: @@ -217,6 +199,7 @@ mpeg_util_parse_sequence_hdr (MPEGSeqHdr * hdr, guint8 * data, guint8 * end) gboolean constrained_flag; gboolean load_intra_flag; gboolean load_non_intra_flag; + gint i; if (G_UNLIKELY ((end - data) < 12)) return FALSE; /* Too small to be a sequence header */ @@ -241,19 +224,29 @@ mpeg_util_parse_sequence_hdr (MPEGSeqHdr * hdr, guint8 * data, guint8 * end) set_fps_from_code (hdr, fps_idx); constrained_flag = (data[7] >> 2) & 0x01; - load_intra_flag = (data[7] >> 1) & 0x01; + + load_intra_flag = read_bits (data + 7, 6, 1); if (load_intra_flag) { if (G_UNLIKELY ((end - data) < 64)) return FALSE; + for (i = 0; i < 64; i++) { + hdr->intra_quantizer_matrix[mpeg2_scan[i]] = + read_bits (data + 7 + i, 7, 8); + } data += 64; - } - load_non_intra_flag = data[7] & 0x01; + } else + memcpy (hdr->intra_quantizer_matrix, default_intra_quantizer_matrix, 64); + + load_non_intra_flag = read_bits (data + 7, 7 + load_intra_flag, 1); if (load_non_intra_flag) { if (G_UNLIKELY ((end - data) < 64)) return FALSE; - data += 64; - } + for (i = 0; i < 64; i++) + hdr->non_intra_quantizer_matrix[mpeg2_scan[i]] = + read_bits (data + 8 + i, 1 + load_intra_flag, 8); + } else + memset (hdr->non_intra_quantizer_matrix, 16, 64); /* Advance past the rest of the MPEG-1 header */ data += 8; @@ -282,14 +275,14 @@ mpeg_util_parse_picture_hdr (MPEGPictureHdr * hdr, guint8 * data, guint8 * end) { guint32 code; - if (G_UNLIKELY ((end - data) < 6)) + if (G_UNLIKELY ((end - data) < 8)) return FALSE; /* Packet too small */ code = GST_READ_UINT32_BE (data); if (G_UNLIKELY (code != (0x00000100 | MPEG_PACKET_PICTURE))) return FALSE; - /* Skip the start code */ + /* Skip the sync word */ data += 4; hdr->pic_type = (data[1] >> 3) & 0x07; @@ -297,7 +290,7 @@ mpeg_util_parse_picture_hdr (MPEGPictureHdr * hdr, guint8 * data, guint8 * end) return FALSE; /* Corrupted picture packet */ if (hdr->pic_type == P_FRAME || hdr->pic_type == B_FRAME) { - if (G_UNLIKELY ((end - data) < 7)) + if (G_UNLIKELY ((end - data) < 5)) return FALSE; /* packet too small */ hdr->full_pel_forward_vector = read_bits (data + 3, 5, 1); @@ -319,12 +312,19 @@ gboolean mpeg_util_parse_picture_coding_extension (MPEGPictureExt * ext, guint8 * data, guint8 * end) { - if (G_UNLIKELY ((end - data) < 7)) + guint32 code; + + if (G_UNLIKELY ((end - data) < 10)) return FALSE; /* Packet too small */ - if (G_UNLIKELY (read_bits (data, 0, 4) != MPEG_PACKET_EXT_PICTURE_CODING)) + code = GST_READ_UINT32_BE (data); + + if (G_UNLIKELY (G_UNLIKELY (code != (0x00000100 | MPEG_PACKET_EXTENSION)))) return FALSE; + /* Skip the sync word */ + data += 4; + ext->f_code[0][0] = read_bits (data, 4, 4); ext->f_code[0][1] = read_bits (data + 1, 0, 4); ext->f_code[1][0] = read_bits (data + 1, 4, 4); @@ -340,3 +340,78 @@ mpeg_util_parse_picture_coding_extension (MPEGPictureExt * ext, guint8 * data, return TRUE; } + +gboolean +mpeg_util_parse_picture_gop (MPEGPictureGOP * gop, guint8 * data, guint8 * end) +{ + guint32 code; + gint hour, minute, second; + + if (G_UNLIKELY ((end - data) < 8)) + return FALSE; /* Packet too small */ + + code = GST_READ_UINT32_BE (data); + + if (G_UNLIKELY (G_UNLIKELY (code != (0x00000100 | MPEG_PACKET_GOP)))) + return FALSE; + + /* Skip the sync word */ + data += 4; + + gop->drop_frame_flag = read_bits (data, 0, 1); + + hour = read_bits (data, 1, 5); + minute = read_bits (data, 6, 6); + second = read_bits (data + 1, 4, 6); + + gop->timestamp = hour * 3600 * GST_SECOND; + gop->timestamp += minute * 60 * GST_SECOND; + gop->timestamp += second * GST_SECOND; + + gop->frame = read_bits (data + 2, 3, 6); + + return TRUE; +} + +gboolean +mpeg_util_parse_quant_matrix (MPEGQuantMatrix * qm, guint8 * data, guint8 * end) +{ + guint32 code; + gboolean load_intra_flag, load_non_intra_flag; + gint i; + + if (G_UNLIKELY ((end - data) < 5)) + return FALSE; /* Packet too small */ + + code = GST_READ_UINT32_BE (data); + + if (G_UNLIKELY (G_UNLIKELY (code != (0x00000100 | MPEG_PACKET_GOP)))) + return FALSE; + + /* Skip the sync word */ + data += 4; + + load_intra_flag = read_bits (data, 0, 1); + if (load_intra_flag) { + if (G_UNLIKELY ((end - data) < 64)) + return FALSE; + for (i = 0; i < 64; i++) { + qm->intra_quantizer_matrix[mpeg2_scan[i]] = read_bits (data + i, 1, 8); + } + data += 64; + + } else + memcpy (qm->intra_quantizer_matrix, default_intra_quantizer_matrix, 64); + + load_non_intra_flag = read_bits (data, 1 + load_intra_flag, 1); + if (load_non_intra_flag) { + if (G_UNLIKELY ((end - data) < 64)) + return FALSE; + for (i = 0; i < 64; i++) + qm->non_intra_quantizer_matrix[mpeg2_scan[i]] = + read_bits (data + i, 2 + load_intra_flag, 8); + } else + memset (qm->non_intra_quantizer_matrix, 16, 64); + + return TRUE; +} diff --git a/sys/vdpau/mpegutil.h b/sys/vdpau/mpegutil.h index 929e4fbb..5fb47290 100644 --- a/sys/vdpau/mpegutil.h +++ b/sys/vdpau/mpegutil.h @@ -26,6 +26,8 @@ typedef struct MPEGSeqHdr MPEGSeqHdr; typedef struct MPEGPictureHdr MPEGPictureHdr; typedef struct MPEGPictureExt MPEGPictureExt; +typedef struct MPEGPictureGOP MPEGPictureGOP; +typedef struct MPEGQuantMatrix MPEGQuantMatrix; /* Packet ID codes for different packet types we * care about */ @@ -90,6 +92,20 @@ struct MPEGPictureExt guint8 intra_vlc_format; }; +struct MPEGPictureGOP +{ + guint8 drop_frame_flag; + guint8 frame; + + GstClockTime timestamp; +}; + +struct MPEGQuantMatrix +{ + guint8 intra_quantizer_matrix[64]; + guint8 non_intra_quantizer_matrix[64]; +}; + gboolean mpeg_util_parse_sequence_hdr (MPEGSeqHdr *hdr, guint8 *data, guint8 *end); @@ -97,4 +113,11 @@ gboolean mpeg_util_parse_picture_hdr (MPEGPictureHdr * hdr, guint8 * data, guint gboolean mpeg_util_parse_picture_coding_extension (MPEGPictureExt *ext, guint8 *data, guint8 *end); +gboolean mpeg_util_parse_picture_gop (MPEGPictureGOP * gop, guint8 * data, guint8 * end); + +gboolean mpeg_util_parse_quant_matrix (MPEGQuantMatrix * qm, guint8 * data, guint8 * end); + +guint8 *mpeg_util_find_start_code (guint32 * sync_word, guint8 * cur, guint8 * end); +guint32 read_bits (guint8 * buf, gint start_bit, gint n_bits); + #endif -- cgit v1.2.1 From a22a18d1e7da4ceb7f655e9ea468458ae58ad904 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Tue, 31 Mar 2009 22:54:14 +0200 Subject: vdpau: remove comment --- sys/vdpau/gstvdpaumpegdecoder.h | 1 - 1 file changed, 1 deletion(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpaumpegdecoder.h b/sys/vdpau/gstvdpaumpegdecoder.h index 36c02534..b7c293ab 100644 --- a/sys/vdpau/gstvdpaumpegdecoder.h +++ b/sys/vdpau/gstvdpaumpegdecoder.h @@ -51,7 +51,6 @@ G_BEGIN_DECLS -/* #defines don't like whitespacey bits */ #define GST_TYPE_VDPAU_MPEG_DECODER (gst_vdpau_mpeg_decoder_get_type()) #define GST_VDPAU_MPEG_DECODER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VDPAU_MPEG_DECODER,GstVdpauMpegDecoder)) #define GST_VDPAU_MPEG_DECODER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VDPAU_MPEG_DECODER,GstVdpauMpegDecoderClass)) -- cgit v1.2.1 From f74f44c24f97b03163b854516b025fed8e9b29a3 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Wed, 1 Apr 2009 21:19:18 +0200 Subject: vdpau: add gstvdpaudevice for abstracting vdpau initalization --- sys/vdpau/Makefile.am | 6 +- sys/vdpau/gst-vdpau-device.c | 267 ++++++++++++++++++++++++++++++++++++++++ sys/vdpau/gst-vdpau-device.h | 80 ++++++++++++ sys/vdpau/gstvdpaudecoder.c | 143 ++++----------------- sys/vdpau/gstvdpaudecoder.h | 31 +---- sys/vdpau/gstvdpaumpegdecoder.c | 53 ++------ sys/vdpau/gstvdpaumpegdecoder.h | 25 ---- 7 files changed, 392 insertions(+), 213 deletions(-) create mode 100644 sys/vdpau/gst-vdpau-device.c create mode 100644 sys/vdpau/gst-vdpau-device.h (limited to 'sys') diff --git a/sys/vdpau/Makefile.am b/sys/vdpau/Makefile.am index ef43e5fd..f5a5ed1e 100644 --- a/sys/vdpau/Makefile.am +++ b/sys/vdpau/Makefile.am @@ -1,9 +1,10 @@ plugin_LTLIBRARIES = libgstvdpau.la libgstvdpau_la_SOURCES = \ + gst-vdpau-device.c \ gstvdpaudecoder.c \ gstvdpaumpegdecoder.c \ - mpegutil.c + mpegutil.c \ libgstvdpau_la_CFLAGS = $(GST_CFLAGS) $(X11_CFLAGS) -Ivdpau libgstvdpau_la_LIBADD = $(GST_LIBS) $(GST_BASE_LIBS) \ @@ -12,8 +13,9 @@ libgstvdpau_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) libgstvdpau_la_LIBTOOLFLAGS = --tag=disable-static noinst_HEADERS = \ + gst-vdpau-device.h \ gstvdpaudecoder.h \ gstvdpaumpegdecoder.h \ - mpegutil.h + mpegutil.h diff --git a/sys/vdpau/gst-vdpau-device.c b/sys/vdpau/gst-vdpau-device.c new file mode 100644 index 00000000..ec86ca4e --- /dev/null +++ b/sys/vdpau/gst-vdpau-device.c @@ -0,0 +1,267 @@ +/* + * GStreamer + * Copyright (C) 2009 Carl-Anton Ingmarsson + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include +#include + +#include "gst-vdpau-device.h" + +GST_DEBUG_CATEGORY_STATIC (gst_vdpau_device_debug); +#define GST_CAT_DEFAULT gst_vdpau_device_debug + +enum +{ + PROP_0, + + PROP_DISPLAY +}; + + + +G_DEFINE_TYPE (GstVdpauDevice, gst_vdpau_device, G_TYPE_OBJECT); + +static void +gst_vdpau_device_init (GstVdpauDevice * device) +{ + device->display_name = NULL; + device->display = NULL; + device->device = VDP_INVALID_HANDLE; +} + +static void +gst_vdpau_device_finalize (GObject * object) +{ + GstVdpauDevice *device = (GstVdpauDevice *) object; + + device->vdp_device_destroy (device->device); + g_free (device->display_name); + + G_OBJECT_CLASS (gst_vdpau_device_parent_class)->finalize (object); + +} + +static void +gst_vdpau_device_constructed (GObject * object) +{ + GstVdpauDevice *device = (GstVdpauDevice *) object; + gint screen; + VdpStatus status; + gint i; + + typedef struct + { + gint id; + void *func; + } VdpFunction; + + VdpFunction vdp_function[] = { + {VDP_FUNC_ID_DEVICE_DESTROY, &device->vdp_device_destroy}, + {VDP_FUNC_ID_VIDEO_SURFACE_CREATE, + &device->vdp_video_surface_create}, + {VDP_FUNC_ID_VIDEO_SURFACE_DESTROY, + &device->vdp_video_surface_destroy}, + {VDP_FUNC_ID_VIDEO_SURFACE_QUERY_CAPABILITIES, + &device->vdp_video_surface_query_capabilities}, + {VDP_FUNC_ID_VIDEO_SURFACE_QUERY_GET_PUT_BITS_Y_CB_CR_CAPABILITIES, + &device->vdp_video_surface_query_ycbcr_capabilities}, + {VDP_FUNC_ID_VIDEO_SURFACE_GET_BITS_Y_CB_CR, + &device->vdp_video_surface_get_bits_ycbcr}, + {VDP_FUNC_ID_VIDEO_SURFACE_GET_PARAMETERS, + &device->vdp_video_surface_get_parameters}, + {VDP_FUNC_ID_DECODER_CREATE, &device->vdp_decoder_create}, + {VDP_FUNC_ID_DECODER_RENDER, &device->vdp_decoder_render}, + {VDP_FUNC_ID_DECODER_DESTROY, &device->vdp_decoder_destroy}, + {VDP_FUNC_ID_DECODER_QUERY_CAPABILITIES, + &device->vdp_decoder_query_capabilities}, + {VDP_FUNC_ID_DECODER_GET_PARAMETERS, + &device->vdp_decoder_get_parameters}, + {0, NULL} + }; + + /* FIXME: We probably want to use the same VdpDevice for every VDPAU element */ + device->display = XOpenDisplay (device->display_name); + if (!device->display) { + GST_ERROR_OBJECT (device, "Could not open X display with name: %s", + device->display_name); + return; + } + + screen = DefaultScreen (device->display); + status = + vdp_device_create_x11 (device->display, screen, &device->device, + &device->vdp_get_proc_address); + if (status != VDP_STATUS_OK) { + GST_ERROR_OBJECT (device, "Could not create VDPAU device"); + XCloseDisplay (device->display); + device->display = NULL; + + return; + } + + status = device->vdp_get_proc_address (device->device, + VDP_FUNC_ID_GET_ERROR_STRING, (void **) &device->vdp_get_error_string); + if (status != VDP_STATUS_OK) { + GST_ERROR_OBJECT (device, + "Could not get vdp_get_error_string function pointer from VDPAU"); + goto error; + } + + for (i = 0; vdp_function[i].func != NULL; i++) { + status = device->vdp_get_proc_address (device->device, + vdp_function[i].id, vdp_function[i].func); + + if (status != VDP_STATUS_OK) { + GST_ERROR_OBJECT (device, "Could not get function pointer from VDPAU," + " error returned was: %s", device->vdp_get_error_string (status)); + goto error; + } + } + + return; + +error: + XCloseDisplay (device->display); + device->display = NULL; + + if (device->device != VDP_INVALID_HANDLE) { + device->vdp_device_destroy (device->device); + device->device = VDP_INVALID_HANDLE; + } +} + +static void +gst_vdpau_device_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GstVdpauDevice *device; + + g_return_if_fail (GST_IS_VDPAU_DEVICE (object)); + + device = (GstVdpauDevice *) object; + + switch (prop_id) { + case PROP_DISPLAY: + device->display_name = g_value_dup_string (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_vdpau_device_get_property (GObject * object, guint prop_id, GValue * value, + GParamSpec * pspec) +{ + GstVdpauDevice *device; + + g_return_if_fail (GST_IS_VDPAU_DEVICE (object)); + + device = (GstVdpauDevice *) object; + + switch (prop_id) { + case PROP_DISPLAY: + g_value_set_string (value, device->display_name); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_vdpau_device_class_init (GstVdpauDeviceClass * klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->constructed = gst_vdpau_device_constructed; + object_class->finalize = gst_vdpau_device_finalize; + object_class->get_property = gst_vdpau_device_get_property; + object_class->set_property = gst_vdpau_device_set_property; + + + g_object_class_install_property (object_class, + PROP_DISPLAY, + g_param_spec_string ("display", + "Display", + "X Display Name", + "", G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); + + GST_DEBUG_CATEGORY_INIT (gst_vdpau_device_debug, "vdpaudevice", + 0, "vdpaudevice"); +} + +GstVdpauDevice * +gst_vdpau_device_new (const gchar * display_name) +{ + GstVdpauDevice *device; + + device = g_object_new (GST_TYPE_VDPAU_DEVICE, "display", display_name); + + return device; +} + +static void +device_destroyed_cb (gpointer data, GObject * object) +{ + GHashTable *devices_hash = data; + GHashTableIter iter; + gpointer device; + + g_hash_table_iter_init (&iter, devices_hash); + while (g_hash_table_iter_next (&iter, NULL, &device)) { + if (device == object) { + g_hash_table_iter_remove (&iter); + break; + } + } +} + +static gpointer +create_devices_hash (gpointer data) +{ + return g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); +} + +GstVdpauDevice * +gst_vdpau_get_device (const gchar * display_name) +{ + static GOnce my_once = G_ONCE_INIT; + GHashTable *devices_hash; + GstVdpauDevice *device; + + g_once (&my_once, create_devices_hash, NULL); + devices_hash = my_once.retval; + + if (display_name) + device = g_hash_table_lookup (devices_hash, display_name); + else + device = g_hash_table_lookup (devices_hash, ""); + + if (!device) { + g_debug ("asdasd"); + device = gst_vdpau_device_new (display_name); + g_object_weak_ref (G_OBJECT (device), device_destroyed_cb, devices_hash); + } else + g_object_ref (device); + + g_debug ("HMM"); + return device; +} diff --git a/sys/vdpau/gst-vdpau-device.h b/sys/vdpau/gst-vdpau-device.h new file mode 100644 index 00000000..0a5cb5e7 --- /dev/null +++ b/sys/vdpau/gst-vdpau-device.h @@ -0,0 +1,80 @@ +/* + * GStreamer + * Copyright (C) 2009 Carl-Anton Ingmarsson + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _GST_VDPAU_DEVICE_H_ +#define _GST_VDPAU_DEVICE_H_ + +#include +#include + +#include + +G_BEGIN_DECLS + +#define GST_TYPE_VDPAU_DEVICE (gst_vdpau_device_get_type ()) +#define GST_VDPAU_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VDPAU_DEVICE, GstVdpauDevice)) +#define GST_VDPAU_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_VDPAU_DEVICE, GstVdpauDeviceClass)) +#define GST_IS_VDPAU_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VDPAU_DEVICE)) +#define GST_IS_VDPAU_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_VDPAU_DEVICE)) +#define GST_VDPAU_DEVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VDPAU_DEVICE, GstVdpauDeviceClass)) + +typedef struct _GstVdpauDeviceClass GstVdpauDeviceClass; +typedef struct _GstVdpauDevice GstVdpauDevice; + +struct _GstVdpauDeviceClass +{ + GObjectClass parent_class; +}; + +struct _GstVdpauDevice +{ + GObject object; + + gchar *display_name; + Display *display; + VdpDevice device; + + VdpDeviceDestroy *vdp_device_destroy; + VdpGetProcAddress *vdp_get_proc_address; + VdpGetErrorString *vdp_get_error_string; + + VdpVideoSurfaceCreate *vdp_video_surface_create; + VdpVideoSurfaceDestroy *vdp_video_surface_destroy; + VdpVideoSurfaceQueryCapabilities *vdp_video_surface_query_capabilities; + VdpVideoSurfaceQueryGetPutBitsYCbCrCapabilities *vdp_video_surface_query_ycbcr_capabilities; + VdpVideoSurfaceGetParameters *vdp_video_surface_get_parameters; + VdpVideoSurfaceGetBitsYCbCr *vdp_video_surface_get_bits_ycbcr; + + VdpDecoderCreate *vdp_decoder_create; + VdpDecoderDestroy *vdp_decoder_destroy; + VdpDecoderRender *vdp_decoder_render; + VdpDecoderQueryCapabilities *vdp_decoder_query_capabilities; + VdpDecoderGetParameters *vdp_decoder_get_parameters; +}; + +GType gst_vdpau_device_get_type (void) G_GNUC_CONST; + +GstVdpauDevice *gst_vdpau_device_new (const gchar *display_name); + +GstVdpauDevice *gst_vdpau_get_device (const gchar *display_name); + +G_END_DECLS + +#endif /* _GST_VDPAU_DEVICE_H_ */ diff --git a/sys/vdpau/gstvdpaudecoder.c b/sys/vdpau/gstvdpaudecoder.c index fb2ce627..deb93c49 100644 --- a/sys/vdpau/gstvdpaudecoder.c +++ b/sys/vdpau/gstvdpaudecoder.c @@ -1,6 +1,5 @@ /* * GStreamer - * Copyright (C) 2006 Stefan Kost * Copyright (C) 2009 Carl-Anton Ingmarsson * * This library is free software; you can redistribute it and/or @@ -27,7 +26,6 @@ #include #include "gstvdpaudecoder.h" -#include GST_DEBUG_CATEGORY_STATIC (gst_vdpaudecoder_debug); #define GST_CAT_DEFAULT gst_vdpaudecoder_debug @@ -68,10 +66,10 @@ GstFlowReturn gst_vdpau_decoder_push_video_surface (GstVdpauDecoder * dec, VdpVideoSurface surface) { - VdpauFunctions *f; + GstVdpauDevice *device; GstBuffer *buffer; - f = dec->functions; + device = dec->device; switch (dec->format) { case GST_MAKE_FOURCC ('Y', 'V', '1', '2'): @@ -110,13 +108,13 @@ gst_vdpau_decoder_push_video_surface (GstVdpauDecoder * dec, 1, dec->width); status = - f->vdp_video_surface_get_bits_ycbcr (surface, VDP_YCBCR_FORMAT_YV12, - (void *) data, stride); + device->vdp_video_surface_get_bits_ycbcr (surface, + VDP_YCBCR_FORMAT_YV12, (void *) data, stride); if (G_UNLIKELY (status != VDP_STATUS_OK)) { GST_ELEMENT_ERROR (dec, RESOURCE, READ, ("Couldn't get data from vdpau"), ("Error returned from vdpau was: %s", - f->vdp_get_error_string (status))); + device->vdp_get_error_string (status))); return GST_FLOW_ERROR; } break; @@ -144,13 +142,13 @@ gst_vdpau_decoder_push_video_surface (GstVdpauDecoder * dec, stride[1] = dec->width; status = - f->vdp_video_surface_get_bits_ycbcr (surface, VDP_YCBCR_FORMAT_NV12, - (void *) data, stride); + device->vdp_video_surface_get_bits_ycbcr (surface, + VDP_YCBCR_FORMAT_NV12, (void *) data, stride); if (G_UNLIKELY (status != VDP_STATUS_OK)) { GST_ELEMENT_ERROR (dec, RESOURCE, READ, ("Couldn't get data from vdpau"), ("Error returned from vdpau was: %s", - f->vdp_get_error_string (status))); + device->vdp_get_error_string (status))); return GST_FLOW_ERROR; } break; @@ -217,13 +215,13 @@ static VdpauFormats formats[6] = { VdpVideoSurface gst_vdpau_decoder_create_video_surface (GstVdpauDecoder * dec) { - VdpauFunctions *f; + GstVdpauDevice *device; VdpChromaType chroma_type; gint i; VdpStatus status; VdpVideoSurface surface; - f = dec->functions; + device = dec->device; chroma_type = VDP_CHROMA_TYPE_422; for (i = 0; i < 6; i++) { @@ -233,13 +231,14 @@ gst_vdpau_decoder_create_video_surface (GstVdpauDecoder * dec) } } - status = f->vdp_video_surface_create (dec->device, chroma_type, dec->width, + status = + device->vdp_video_surface_create (device->device, chroma_type, dec->width, dec->height, &surface); if (status != VDP_STATUS_OK) { GST_ELEMENT_ERROR (dec, RESOURCE, READ, ("Couldn't create a VdpVideoSurface"), ("Error returned from vdpau was: %s", - f->vdp_get_error_string (status))); + device->vdp_get_error_string (status))); return VDP_INVALID_HANDLE; } @@ -249,11 +248,11 @@ gst_vdpau_decoder_create_video_surface (GstVdpauDecoder * dec) static GstCaps * gst_vdpaudecoder_get_vdpau_support (GstVdpauDecoder * dec) { - VdpauFunctions *f; + GstVdpauDevice *device; GstCaps *caps; gint i; - f = dec->functions; + device = dec->device; caps = gst_caps_new_empty (); @@ -263,14 +262,14 @@ gst_vdpaudecoder_get_vdpau_support (GstVdpauDecoder * dec) guint32 max_w, max_h; status = - f->vdp_video_surface_query_capabilities (dec->device, chroma_types[i], - &is_supported, &max_w, &max_h); + device->vdp_video_surface_query_capabilities (device->device, + chroma_types[i], &is_supported, &max_w, &max_h); if (status != VDP_STATUS_OK && status != VDP_STATUS_INVALID_CHROMA_TYPE) { GST_ELEMENT_ERROR (dec, RESOURCE, READ, ("Could not get query VDPAU video surface capabilites"), ("Error returned from vdpau was: %s", - f->vdp_get_error_string (status))); + device->vdp_get_error_string (status))); return NULL; } @@ -282,14 +281,14 @@ gst_vdpaudecoder_get_vdpau_support (GstVdpauDecoder * dec) continue; status = - f->vdp_video_surface_query_ycbcr_capabilities (dec->device, + device->vdp_video_surface_query_ycbcr_capabilities (device->device, formats[j].chroma_type, formats[j].format, &is_supported); if (status != VDP_STATUS_OK && status != VDP_STATUS_INVALID_Y_CB_CR_FORMAT) { GST_ELEMENT_ERROR (dec, RESOURCE, READ, ("Could not query VDPAU YCbCr capabilites"), ("Error returned from vdpau was: %s", - f->vdp_get_error_string (status))); + device->vdp_get_error_string (status))); return NULL; } @@ -317,111 +316,25 @@ gst_vdpaudecoder_get_vdpau_support (GstVdpauDecoder * dec) static gboolean gst_vdpaudecoder_init_vdpau (GstVdpauDecoder * dec) { - gint screen; - VdpStatus status; - gint i; - VdpauFunctions *f; GstCaps *caps; - typedef struct - { - int id; - void *func; - } VdpFunction; - - VdpFunction vdp_function[] = { - {VDP_FUNC_ID_DEVICE_DESTROY, &dec->functions->vdp_device_destroy}, - {VDP_FUNC_ID_VIDEO_SURFACE_CREATE, - &dec->functions->vdp_video_surface_create}, - {VDP_FUNC_ID_VIDEO_SURFACE_DESTROY, - &dec->functions->vdp_video_surface_destroy}, - {VDP_FUNC_ID_VIDEO_SURFACE_QUERY_CAPABILITIES, - &dec->functions->vdp_video_surface_query_capabilities}, - {VDP_FUNC_ID_VIDEO_SURFACE_QUERY_GET_PUT_BITS_Y_CB_CR_CAPABILITIES, - &dec->functions->vdp_video_surface_query_ycbcr_capabilities}, - {VDP_FUNC_ID_VIDEO_SURFACE_GET_BITS_Y_CB_CR, - &dec->functions->vdp_video_surface_get_bits_ycbcr}, - {VDP_FUNC_ID_VIDEO_SURFACE_GET_PARAMETERS, - &dec->functions->vdp_video_surface_get_parameters}, - {VDP_FUNC_ID_DECODER_CREATE, &dec->functions->vdp_decoder_create}, - {VDP_FUNC_ID_DECODER_RENDER, &dec->functions->vdp_decoder_render}, - {VDP_FUNC_ID_DECODER_DESTROY, &dec->functions->vdp_decoder_destroy}, - {VDP_FUNC_ID_DECODER_QUERY_CAPABILITIES, - &dec->functions->vdp_decoder_query_capabilities}, - {VDP_FUNC_ID_DECODER_GET_PARAMETERS, - &dec->functions->vdp_decoder_get_parameters}, - {0, NULL} - }; - - /* FIXME: We probably want to use the same VdpDevice for every VDPAU element */ - dec->display = XOpenDisplay (dec->display_name); - if (!dec->display) { - GST_ELEMENT_ERROR (dec, RESOURCE, READ, ("Could not initialise VDPAU"), - ("Could not open display")); - return FALSE; - } - - f = dec->functions; - - screen = DefaultScreen (dec->display); - status = - vdp_device_create_x11 (dec->display, screen, &dec->device, - &f->vdp_get_proc_address); - if (status != VDP_STATUS_OK) { - GST_ELEMENT_ERROR (dec, RESOURCE, READ, ("Could not initialise VDPAU"), - ("Could not create VDPAU device")); - XCloseDisplay (dec->display); - dec->display = NULL; - - return FALSE; - } - - status = f->vdp_get_proc_address (dec->device, - VDP_FUNC_ID_GET_ERROR_STRING, (void **) &f->vdp_get_error_string); - if (status != VDP_STATUS_OK) { - GST_ELEMENT_ERROR (dec, RESOURCE, READ, - ("Could'nt get function pointer from vdpau"), - ("Couldn't get vdp_get_error_string function pointer")); - goto error; - } - - for (i = 0; vdp_function[i].func != NULL; i++) { - status = f->vdp_get_proc_address (dec->device, - vdp_function[i].id, vdp_function[i].func); - - if (status != VDP_STATUS_OK) { - GST_ELEMENT_ERROR (dec, RESOURCE, READ, - ("Could not get function pointer from vdpau"), - ("Error returned from vdpau was: %s", - f->vdp_get_error_string (status))); - goto error; - } - } + dec->device = gst_vdpau_get_device (dec->display_name); caps = gst_vdpaudecoder_get_vdpau_support (dec); if (!caps) - goto error; + return FALSE; dec->src_caps = caps; return TRUE; - -error: - f->vdp_device_destroy (dec->device); - dec->device = VDP_INVALID_HANDLE; - - return FALSE; - } static GstStateChangeReturn gst_vdpaudecoder_change_state (GstElement * element, GstStateChange transition) { GstVdpauDecoder *dec; - VdpauFunctions *f; dec = GST_VDPAU_DECODER (element); - f = dec->functions; switch (transition) { case GST_STATE_CHANGE_NULL_TO_READY: @@ -429,11 +342,8 @@ gst_vdpaudecoder_change_state (GstElement * element, GstStateChange transition) return GST_STATE_CHANGE_FAILURE; break; case GST_STATE_CHANGE_READY_TO_NULL: - f->vdp_device_destroy (dec->device); - XCloseDisplay (dec->display); - - dec->device = VDP_INVALID_HANDLE; - dec->display = NULL; + g_object_unref (dec->device); + dec->device = NULL; break; default: break; @@ -561,8 +471,7 @@ static void gst_vdpaudecoder_init (GstVdpauDecoder * dec, GstVdpauDecoderClass * klass) { dec->display_name = NULL; - dec->display = NULL; - dec->device = VDP_INVALID_HANDLE; + dec->device = NULL; dec->silent = FALSE; dec->src_caps = NULL; @@ -574,8 +483,6 @@ gst_vdpaudecoder_init (GstVdpauDecoder * dec, GstVdpauDecoderClass * klass) dec->frame_nr = 0; - dec->functions = g_slice_new0 (VdpauFunctions); - dec->src = gst_pad_new_from_static_template (&src_template, "src"); gst_pad_set_getcaps_function (dec->src, gst_vdpaudecoder_src_getcaps); gst_element_add_pad (GST_ELEMENT (dec), dec->src); diff --git a/sys/vdpau/gstvdpaudecoder.h b/sys/vdpau/gstvdpaudecoder.h index 3ab3c9f3..3fcf9a74 100644 --- a/sys/vdpau/gstvdpaudecoder.h +++ b/sys/vdpau/gstvdpaudecoder.h @@ -1,6 +1,5 @@ /* * GStreamer - * Copyright (C) 2006 Stefan Kost * Copyright (C) 2009 Carl-Anton Ingmarsson * * This library is free software; you can redistribute it and/or @@ -23,10 +22,8 @@ #define __GST_VDPAU_DECODER_H__ #include -#include -#include -#include +#include "gst-vdpau-device.h" G_BEGIN_DECLS @@ -45,10 +42,7 @@ struct _GstVdpauDecoder { GstElement element; gchar *display_name; - Display *display; - VdpDevice device; - - VdpauFunctions *functions; + GstVdpauDevice *device; GstPad *src; GstPad *sink; @@ -65,30 +59,11 @@ struct _GstVdpauDecoder { }; struct _GstVdpauDecoderClass { - GstBaseTransformClass parent_class; + GstElementClass parent_class; gboolean (*set_caps) (GstVdpauDecoder *dec, GstCaps *caps); }; -struct _VdpauFunctions { - VdpDeviceDestroy *vdp_device_destroy; - VdpGetProcAddress *vdp_get_proc_address; - VdpGetErrorString *vdp_get_error_string; - - VdpVideoSurfaceCreate *vdp_video_surface_create; - VdpVideoSurfaceDestroy *vdp_video_surface_destroy; - VdpVideoSurfaceQueryCapabilities *vdp_video_surface_query_capabilities; - VdpVideoSurfaceQueryGetPutBitsYCbCrCapabilities *vdp_video_surface_query_ycbcr_capabilities; - VdpVideoSurfaceGetParameters *vdp_video_surface_get_parameters; - VdpVideoSurfaceGetBitsYCbCr *vdp_video_surface_get_bits_ycbcr; - - VdpDecoderCreate *vdp_decoder_create; - VdpDecoderDestroy *vdp_decoder_destroy; - VdpDecoderRender *vdp_decoder_render; - VdpDecoderQueryCapabilities *vdp_decoder_query_capabilities; - VdpDecoderGetParameters *vdp_decoder_get_parameters; -}; - GType gst_vdpaudecoder_get_type (void); gboolean gst_vdpau_decoder_push_video_surface (GstVdpauDecoder * dec, diff --git a/sys/vdpau/gstvdpaumpegdecoder.c b/sys/vdpau/gstvdpaumpegdecoder.c index 6f75181b..52eec777 100644 --- a/sys/vdpau/gstvdpaumpegdecoder.c +++ b/sys/vdpau/gstvdpaumpegdecoder.c @@ -1,29 +1,6 @@ /* * GStreamer * Copyright (C) 2009 Carl-Anton Ingmarsson - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Alternatively, the contents of this file may be used under the - * GNU Lesser General Public License Version 2.1 (the "LGPL"), in - * which case the following provisions apply instead of the ones - * mentioned above: * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -108,7 +85,7 @@ gst_vdpau_mpeg_decoder_set_caps (GstVdpauDecoder * dec, GstCaps * caps) GstBuffer *codec_data; MPEGSeqHdr hdr = { 0, }; VdpDecoderProfile profile; - VdpauFunctions *f; + GstVdpauDevice *device; VdpStatus status; mpeg_dec = GST_VDPAU_MPEG_DECODER (dec); @@ -137,14 +114,14 @@ gst_vdpau_mpeg_decoder_set_caps (GstVdpauDecoder * dec, GstCaps * caps) memcpy (&mpeg_dec->vdp_info.non_intra_quantizer_matrix, &hdr.non_intra_quantizer_matrix, 64); - f = dec->functions; - status = f->vdp_decoder_create (dec->device, profile, dec->width, + device = dec->device; + status = device->vdp_decoder_create (device->device, profile, dec->width, dec->height, 2, &mpeg_dec->decoder); if (status != VDP_STATUS_OK) { GST_ELEMENT_ERROR (mpeg_dec, RESOURCE, READ, ("Could not create vdpau decoder"), ("Error returned from vdpau was: %s", - f->vdp_get_error_string (status))); + device->vdp_get_error_string (status))); return FALSE; } return TRUE; @@ -156,7 +133,7 @@ gst_vdpau_mpeg_decoder_decode (GstVdpauMpegDecoder * mpeg_dec) GstVdpauDecoder *dec; GstBuffer *buffer; VdpVideoSurface surface; - VdpauFunctions *f; + GstVdpauDevice *device; VdpBitstreamBuffer vbit[1]; VdpStatus status; GstFlowReturn ret; @@ -166,20 +143,16 @@ gst_vdpau_mpeg_decoder_decode (GstVdpauMpegDecoder * mpeg_dec) buffer = gst_adapter_take_buffer (mpeg_dec->adapter, gst_adapter_available (mpeg_dec->adapter)); - if (mpeg_dec->vdp_info.picture_coding_type == P_FRAME) { - mpeg_dec->p_buffer = buffer; - } - surface = gst_vdpau_decoder_create_video_surface (GST_VDPAU_DECODER (mpeg_dec)); - f = dec->functions; + device = dec->device; vbit[0].struct_version = VDP_BITSTREAM_BUFFER_VERSION; vbit[0].bitstream = GST_BUFFER_DATA (buffer); vbit[0].bitstream_bytes = GST_BUFFER_SIZE (buffer); - status = f->vdp_decoder_render (mpeg_dec->decoder, surface, + status = device->vdp_decoder_render (mpeg_dec->decoder, surface, (VdpPictureInfo *) & mpeg_dec->vdp_info, 1, vbit); gst_buffer_unref (buffer); mpeg_dec->vdp_info.slice_count = 0; @@ -188,12 +161,12 @@ gst_vdpau_mpeg_decoder_decode (GstVdpauMpegDecoder * mpeg_dec) GST_ELEMENT_ERROR (mpeg_dec, RESOURCE, READ, ("Could not decode"), ("Error returned from vdpau was: %s", - f->vdp_get_error_string (status))); + device->vdp_get_error_string (status))); if (mpeg_dec->vdp_info.forward_reference != VDP_INVALID_HANDLE) - f->vdp_video_surface_destroy (mpeg_dec->vdp_info.forward_reference); + device->vdp_video_surface_destroy (mpeg_dec->vdp_info.forward_reference); - f->vdp_video_surface_destroy (surface); + device->vdp_video_surface_destroy (surface); return GST_FLOW_ERROR; } @@ -203,7 +176,7 @@ gst_vdpau_mpeg_decoder_decode (GstVdpauMpegDecoder * mpeg_dec) surface); if (mpeg_dec->vdp_info.forward_reference != VDP_INVALID_HANDLE) - f->vdp_video_surface_destroy (mpeg_dec->vdp_info.forward_reference); + device->vdp_video_surface_destroy (mpeg_dec->vdp_info.forward_reference); mpeg_dec->vdp_info.forward_reference = surface; @@ -254,8 +227,8 @@ gst_vdpau_mpeg_decoder_parse_picture (GstVdpauMpegDecoder * mpeg_dec, if (pic_hdr.pic_type == I_FRAME && mpeg_dec->vdp_info.forward_reference != VDP_INVALID_HANDLE) { - dec->functions->vdp_video_surface_destroy (mpeg_dec->vdp_info. - forward_reference); + dec->device->vdp_video_surface_destroy (mpeg_dec-> + vdp_info.forward_reference); mpeg_dec->vdp_info.forward_reference = VDP_INVALID_HANDLE; } diff --git a/sys/vdpau/gstvdpaumpegdecoder.h b/sys/vdpau/gstvdpaumpegdecoder.h index b7c293ab..4b4c6550 100644 --- a/sys/vdpau/gstvdpaumpegdecoder.h +++ b/sys/vdpau/gstvdpaumpegdecoder.h @@ -1,29 +1,6 @@ /* * GStreamer * Copyright (C) 2009 Carl-Anton Ingmarsson - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Alternatively, the contents of this file may be used under the - * GNU Lesser General Public License Version 2.1 (the "LGPL"), in - * which case the following provisions apply instead of the ones - * mentioned above: * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -74,8 +51,6 @@ struct _GstVdpauMpegDecoder GstAdapter *adapter; gint slices; - GstBuffer *p_buffer; - VdpPictureInfoMPEG1Or2 p_vdp_info; }; struct _GstVdpauMpegDecoderClass -- cgit v1.2.1 From 21d774023635ecb3b261c4132a05b194b95b7f35 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Wed, 1 Apr 2009 21:26:45 +0200 Subject: vdpau: remove extra \ from Makefile.am --- sys/vdpau/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sys') diff --git a/sys/vdpau/Makefile.am b/sys/vdpau/Makefile.am index f5a5ed1e..0ee88bf7 100644 --- a/sys/vdpau/Makefile.am +++ b/sys/vdpau/Makefile.am @@ -4,7 +4,7 @@ libgstvdpau_la_SOURCES = \ gst-vdpau-device.c \ gstvdpaudecoder.c \ gstvdpaumpegdecoder.c \ - mpegutil.c \ + mpegutil.c libgstvdpau_la_CFLAGS = $(GST_CFLAGS) $(X11_CFLAGS) -Ivdpau libgstvdpau_la_LIBADD = $(GST_LIBS) $(GST_BASE_LIBS) \ -- cgit v1.2.1 From 6fa5b4ff14b88eff42f36fb74058bdb46c6e92b4 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Wed, 1 Apr 2009 21:40:14 +0200 Subject: vdpau: make the decoder clean up after itself --- sys/vdpau/gstvdpaudecoder.c | 15 +++++++++++++++ sys/vdpau/gstvdpaumpegdecoder.c | 19 +++++++++++++++++-- 2 files changed, 32 insertions(+), 2 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpaudecoder.c b/sys/vdpau/gstvdpaudecoder.c index deb93c49..8d5ed4e5 100644 --- a/sys/vdpau/gstvdpaudecoder.c +++ b/sys/vdpau/gstvdpaudecoder.c @@ -57,6 +57,7 @@ static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src", GST_BOILERPLATE_FULL (GstVdpauDecoder, gst_vdpaudecoder, GstElement, GST_TYPE_ELEMENT, DEBUG_INIT); +static void gst_vdpau_decoder_finalize (GObject * object); static void gst_vdpaudecoder_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec); static void gst_vdpaudecoder_get_property (GObject * object, guint prop_id, @@ -453,6 +454,7 @@ gst_vdpaudecoder_class_init (GstVdpauDecoderClass * klass) gobject_class = (GObjectClass *) klass; gstelement_class = (GstElementClass *) klass; + gobject_class->finalize = gst_vdpau_decoder_finalize; gobject_class->set_property = gst_vdpaudecoder_set_property; gobject_class->get_property = gst_vdpaudecoder_get_property; @@ -494,6 +496,19 @@ gst_vdpaudecoder_init (GstVdpauDecoder * dec, GstVdpauDecoderClass * klass) gst_pad_set_active (dec->sink, TRUE); } +static void +gst_vdpau_decoder_finalize (GObject * object) +{ + GstVdpauDecoder *dec = (GstVdpauDecoder *) object; + + if (dec->src_caps) + g_object_unref (dec->src_caps); + if (dec->device) + g_object_unref (dec->device); + + g_free (dec->display_name); +} + static void gst_vdpaudecoder_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) diff --git a/sys/vdpau/gstvdpaumpegdecoder.c b/sys/vdpau/gstvdpaumpegdecoder.c index 52eec777..f3e510bd 100644 --- a/sys/vdpau/gstvdpaumpegdecoder.c +++ b/sys/vdpau/gstvdpaumpegdecoder.c @@ -71,6 +71,7 @@ static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink", GST_BOILERPLATE (GstVdpauMpegDecoder, gst_vdpau_mpeg_decoder, GstVdpauDecoder, GST_TYPE_VDPAU_DECODER); +static void gst_vdpau_mpeg_decoder_finalize (GObject * object); static void gst_vdpau_mpeg_decoder_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec); static void gst_vdpau_mpeg_decoder_get_property (GObject * object, @@ -227,8 +228,8 @@ gst_vdpau_mpeg_decoder_parse_picture (GstVdpauMpegDecoder * mpeg_dec, if (pic_hdr.pic_type == I_FRAME && mpeg_dec->vdp_info.forward_reference != VDP_INVALID_HANDLE) { - dec->device->vdp_video_surface_destroy (mpeg_dec-> - vdp_info.forward_reference); + dec->device->vdp_video_surface_destroy (mpeg_dec->vdp_info. + forward_reference); mpeg_dec->vdp_info.forward_reference = VDP_INVALID_HANDLE; } @@ -374,6 +375,7 @@ gst_vdpau_mpeg_decoder_class_init (GstVdpauMpegDecoderClass * klass) gstelement_class = (GstElementClass *) klass; vdpaudec_class = (GstVdpauDecoderClass *) klass; + gobject_class->finalize = gst_vdpau_mpeg_decoder_finalize; gobject_class->set_property = gst_vdpau_mpeg_decoder_set_property; gobject_class->get_property = gst_vdpau_mpeg_decoder_get_property; @@ -414,6 +416,19 @@ gst_vdpau_mpeg_decoder_init (GstVdpauMpegDecoder * mpeg_dec, gst_pad_set_chain_function (dec->sink, gst_vdpau_mpeg_decoder_chain); } +static void +gst_vdpau_mpeg_decoder_finalize (GObject * object) +{ + GstVdpauMpegDecoder *mpeg_dec = (GstVdpauMpegDecoder *) object; + +#if 0 /* FIXME: can't free the decoder since the device already has been freed */ + if (mpeg_dec->decoder != VDP_INVALID_HANDLE) + dec->device->vdp_decoder_destroy (mpeg_dec->decoder); +#endif + + g_object_unref (mpeg_dec->adapter); +} + static void gst_vdpau_mpeg_decoder_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) -- cgit v1.2.1 From 5563c933eec3819d00f25588bad4e57c87dcb390 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Wed, 1 Apr 2009 21:42:56 +0200 Subject: vdpau: change all references of "gst_vdpaudecoder*" to "gst_vdpau_decoder" --- sys/vdpau/gstvdpaudecoder.c | 46 ++++++++++++++++++++++----------------------- sys/vdpau/gstvdpaudecoder.h | 4 ++-- 2 files changed, 25 insertions(+), 25 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpaudecoder.c b/sys/vdpau/gstvdpaudecoder.c index 8d5ed4e5..5a8bbacd 100644 --- a/sys/vdpau/gstvdpaudecoder.c +++ b/sys/vdpau/gstvdpaudecoder.c @@ -27,8 +27,8 @@ #include "gstvdpaudecoder.h" -GST_DEBUG_CATEGORY_STATIC (gst_vdpaudecoder_debug); -#define GST_CAT_DEFAULT gst_vdpaudecoder_debug +GST_DEBUG_CATEGORY_STATIC (gst_vdpau_decoder_debug); +#define GST_CAT_DEFAULT gst_vdpau_decoder_debug /* Filter signals and args */ enum @@ -52,15 +52,15 @@ static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src", "width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ]")); #define DEBUG_INIT(bla) \ - GST_DEBUG_CATEGORY_INIT (gst_vdpaudecoder_debug, "vdpaudecoder", 0, "vdpaudecoder base class"); + GST_DEBUG_CATEGORY_INIT (gst_vdpau_decoder_debug, "vdpaudecoder", 0, "vdpaudecoder base class"); -GST_BOILERPLATE_FULL (GstVdpauDecoder, gst_vdpaudecoder, GstElement, +GST_BOILERPLATE_FULL (GstVdpauDecoder, gst_vdpau_decoder, GstElement, GST_TYPE_ELEMENT, DEBUG_INIT); static void gst_vdpau_decoder_finalize (GObject * object); -static void gst_vdpaudecoder_set_property (GObject * object, guint prop_id, +static void gst_vdpau_decoder_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec); -static void gst_vdpaudecoder_get_property (GObject * object, guint prop_id, +static void gst_vdpau_decoder_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); GstFlowReturn @@ -247,7 +247,7 @@ gst_vdpau_decoder_create_video_surface (GstVdpauDecoder * dec) } static GstCaps * -gst_vdpaudecoder_get_vdpau_support (GstVdpauDecoder * dec) +gst_vdpau_decoder_get_vdpau_support (GstVdpauDecoder * dec) { GstVdpauDevice *device; GstCaps *caps; @@ -315,13 +315,13 @@ gst_vdpaudecoder_get_vdpau_support (GstVdpauDecoder * dec) } static gboolean -gst_vdpaudecoder_init_vdpau (GstVdpauDecoder * dec) +gst_vdpau_decoder_init_vdpau (GstVdpauDecoder * dec) { GstCaps *caps; dec->device = gst_vdpau_get_device (dec->display_name); - caps = gst_vdpaudecoder_get_vdpau_support (dec); + caps = gst_vdpau_decoder_get_vdpau_support (dec); if (!caps) return FALSE; @@ -331,7 +331,7 @@ gst_vdpaudecoder_init_vdpau (GstVdpauDecoder * dec) } static GstStateChangeReturn -gst_vdpaudecoder_change_state (GstElement * element, GstStateChange transition) +gst_vdpau_decoder_change_state (GstElement * element, GstStateChange transition) { GstVdpauDecoder *dec; @@ -339,7 +339,7 @@ gst_vdpaudecoder_change_state (GstElement * element, GstStateChange transition) switch (transition) { case GST_STATE_CHANGE_NULL_TO_READY: - if (!gst_vdpaudecoder_init_vdpau (dec)) + if (!gst_vdpau_decoder_init_vdpau (dec)) return GST_STATE_CHANGE_FAILURE; break; case GST_STATE_CHANGE_READY_TO_NULL: @@ -354,7 +354,7 @@ gst_vdpaudecoder_change_state (GstElement * element, GstStateChange transition) } static gboolean -gst_vdpaudecoder_sink_set_caps (GstPad * pad, GstCaps * caps) +gst_vdpau_decoder_sink_set_caps (GstPad * pad, GstCaps * caps) { GstVdpauDecoder *dec = GST_VDPAU_DECODER (GST_OBJECT_PARENT (pad)); GstVdpauDecoderClass *dec_class = GST_VDPAU_DECODER_GET_CLASS (dec); @@ -412,7 +412,7 @@ gst_vdpaudecoder_sink_set_caps (GstPad * pad, GstCaps * caps) } static GstCaps * -gst_vdpaudecoder_src_getcaps (GstPad * pad) +gst_vdpau_decoder_src_getcaps (GstPad * pad) { GstVdpauDecoder *dec; @@ -430,7 +430,7 @@ gst_vdpaudecoder_src_getcaps (GstPad * pad) /* GObject vmethod implementations */ static void -gst_vdpaudecoder_base_init (gpointer klass) +gst_vdpau_decoder_base_init (gpointer klass) { GstElementClass *element_class = GST_ELEMENT_CLASS (klass); @@ -446,7 +446,7 @@ gst_vdpaudecoder_base_init (gpointer klass) /* initialize the vdpaudecoder's class */ static void -gst_vdpaudecoder_class_init (GstVdpauDecoderClass * klass) +gst_vdpau_decoder_class_init (GstVdpauDecoderClass * klass) { GObjectClass *gobject_class; GstElementClass *gstelement_class; @@ -455,8 +455,8 @@ gst_vdpaudecoder_class_init (GstVdpauDecoderClass * klass) gstelement_class = (GstElementClass *) klass; gobject_class->finalize = gst_vdpau_decoder_finalize; - gobject_class->set_property = gst_vdpaudecoder_set_property; - gobject_class->get_property = gst_vdpaudecoder_get_property; + gobject_class->set_property = gst_vdpau_decoder_set_property; + gobject_class->get_property = gst_vdpau_decoder_get_property; g_object_class_install_property (gobject_class, PROP_DISPLAY, g_param_spec_string ("display", "Display", "X Display name", @@ -466,11 +466,11 @@ gst_vdpaudecoder_class_init (GstVdpauDecoderClass * klass) g_param_spec_boolean ("silent", "Silent", "Produce verbose output ?", FALSE, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE)); - gstelement_class->change_state = gst_vdpaudecoder_change_state; + gstelement_class->change_state = gst_vdpau_decoder_change_state; } static void -gst_vdpaudecoder_init (GstVdpauDecoder * dec, GstVdpauDecoderClass * klass) +gst_vdpau_decoder_init (GstVdpauDecoder * dec, GstVdpauDecoderClass * klass) { dec->display_name = NULL; dec->device = NULL; @@ -486,12 +486,12 @@ gst_vdpaudecoder_init (GstVdpauDecoder * dec, GstVdpauDecoderClass * klass) dec->frame_nr = 0; dec->src = gst_pad_new_from_static_template (&src_template, "src"); - gst_pad_set_getcaps_function (dec->src, gst_vdpaudecoder_src_getcaps); + gst_pad_set_getcaps_function (dec->src, gst_vdpau_decoder_src_getcaps); gst_element_add_pad (GST_ELEMENT (dec), dec->src); dec->sink = gst_pad_new_from_template (gst_element_class_get_pad_template (GST_ELEMENT_CLASS (klass), "sink"), "sink"); - gst_pad_set_setcaps_function (dec->sink, gst_vdpaudecoder_sink_set_caps); + gst_pad_set_setcaps_function (dec->sink, gst_vdpau_decoder_sink_set_caps); gst_element_add_pad (GST_ELEMENT (dec), dec->sink); gst_pad_set_active (dec->sink, TRUE); } @@ -510,7 +510,7 @@ gst_vdpau_decoder_finalize (GObject * object) } static void -gst_vdpaudecoder_set_property (GObject * object, guint prop_id, +gst_vdpau_decoder_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { GstVdpauDecoder *dec = GST_VDPAU_DECODER (object); @@ -530,7 +530,7 @@ gst_vdpaudecoder_set_property (GObject * object, guint prop_id, } static void -gst_vdpaudecoder_get_property (GObject * object, guint prop_id, +gst_vdpau_decoder_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { GstVdpauDecoder *dec = GST_VDPAU_DECODER (object); diff --git a/sys/vdpau/gstvdpaudecoder.h b/sys/vdpau/gstvdpaudecoder.h index 3fcf9a74..0a52f2fc 100644 --- a/sys/vdpau/gstvdpaudecoder.h +++ b/sys/vdpau/gstvdpaudecoder.h @@ -27,7 +27,7 @@ G_BEGIN_DECLS -#define GST_TYPE_VDPAU_DECODER (gst_vdpaudecoder_get_type()) +#define GST_TYPE_VDPAU_DECODER (gst_vdpau_decoder_get_type()) #define GST_VDPAU_DECODER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VDPAU_DECODER,GstVdpauDecoder)) #define GST_VDPAU_DECODER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VDPAU_DECODER,GstVdpauDecoderClass)) #define GST_VDPAU_DECODER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VDPAU_DECODER, GstVdpauDecoderClass)) @@ -64,7 +64,7 @@ struct _GstVdpauDecoderClass { gboolean (*set_caps) (GstVdpauDecoder *dec, GstCaps *caps); }; -GType gst_vdpaudecoder_get_type (void); +GType gst_vdpau_decoder_get_type (void); gboolean gst_vdpau_decoder_push_video_surface (GstVdpauDecoder * dec, VdpVideoSurface surface); -- cgit v1.2.1 From 85acf023dff4bc48d9a043e6c8666ac36153c387 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Fri, 3 Apr 2009 17:51:16 +0200 Subject: vdpau: rename gst-vdpau-device.[ch] to gstvdpaudevice.[ch] --- sys/vdpau/Makefile.am | 4 +- sys/vdpau/gstvdpaudecoder.h | 2 +- sys/vdpau/gstvdpaudevice.c | 267 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 270 insertions(+), 3 deletions(-) create mode 100644 sys/vdpau/gstvdpaudevice.c (limited to 'sys') diff --git a/sys/vdpau/Makefile.am b/sys/vdpau/Makefile.am index 0ee88bf7..0e3b578e 100644 --- a/sys/vdpau/Makefile.am +++ b/sys/vdpau/Makefile.am @@ -1,7 +1,7 @@ plugin_LTLIBRARIES = libgstvdpau.la libgstvdpau_la_SOURCES = \ - gst-vdpau-device.c \ + gstvdpaudevice.c \ gstvdpaudecoder.c \ gstvdpaumpegdecoder.c \ mpegutil.c @@ -13,7 +13,7 @@ libgstvdpau_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) libgstvdpau_la_LIBTOOLFLAGS = --tag=disable-static noinst_HEADERS = \ - gst-vdpau-device.h \ + gstvdpaudevice.h \ gstvdpaudecoder.h \ gstvdpaumpegdecoder.h \ mpegutil.h diff --git a/sys/vdpau/gstvdpaudecoder.h b/sys/vdpau/gstvdpaudecoder.h index 0a52f2fc..415d6eca 100644 --- a/sys/vdpau/gstvdpaudecoder.h +++ b/sys/vdpau/gstvdpaudecoder.h @@ -23,7 +23,7 @@ #include -#include "gst-vdpau-device.h" +#include "gstvdpaudevice.h" G_BEGIN_DECLS diff --git a/sys/vdpau/gstvdpaudevice.c b/sys/vdpau/gstvdpaudevice.c new file mode 100644 index 00000000..23a582f3 --- /dev/null +++ b/sys/vdpau/gstvdpaudevice.c @@ -0,0 +1,267 @@ +/* + * GStreamer + * Copyright (C) 2009 Carl-Anton Ingmarsson + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include +#include + +#include "gstvdpaudevice.h" + +GST_DEBUG_CATEGORY_STATIC (gst_vdpau_device_debug); +#define GST_CAT_DEFAULT gst_vdpau_device_debug + +enum +{ + PROP_0, + + PROP_DISPLAY +}; + + + +G_DEFINE_TYPE (GstVdpauDevice, gst_vdpau_device, G_TYPE_OBJECT); + +static void +gst_vdpau_device_init (GstVdpauDevice * device) +{ + device->display_name = NULL; + device->display = NULL; + device->device = VDP_INVALID_HANDLE; +} + +static void +gst_vdpau_device_finalize (GObject * object) +{ + GstVdpauDevice *device = (GstVdpauDevice *) object; + + device->vdp_device_destroy (device->device); + g_free (device->display_name); + + G_OBJECT_CLASS (gst_vdpau_device_parent_class)->finalize (object); + +} + +static void +gst_vdpau_device_constructed (GObject * object) +{ + GstVdpauDevice *device = (GstVdpauDevice *) object; + gint screen; + VdpStatus status; + gint i; + + typedef struct + { + gint id; + void *func; + } VdpFunction; + + VdpFunction vdp_function[] = { + {VDP_FUNC_ID_DEVICE_DESTROY, &device->vdp_device_destroy}, + {VDP_FUNC_ID_VIDEO_SURFACE_CREATE, + &device->vdp_video_surface_create}, + {VDP_FUNC_ID_VIDEO_SURFACE_DESTROY, + &device->vdp_video_surface_destroy}, + {VDP_FUNC_ID_VIDEO_SURFACE_QUERY_CAPABILITIES, + &device->vdp_video_surface_query_capabilities}, + {VDP_FUNC_ID_VIDEO_SURFACE_QUERY_GET_PUT_BITS_Y_CB_CR_CAPABILITIES, + &device->vdp_video_surface_query_ycbcr_capabilities}, + {VDP_FUNC_ID_VIDEO_SURFACE_GET_BITS_Y_CB_CR, + &device->vdp_video_surface_get_bits_ycbcr}, + {VDP_FUNC_ID_VIDEO_SURFACE_GET_PARAMETERS, + &device->vdp_video_surface_get_parameters}, + {VDP_FUNC_ID_DECODER_CREATE, &device->vdp_decoder_create}, + {VDP_FUNC_ID_DECODER_RENDER, &device->vdp_decoder_render}, + {VDP_FUNC_ID_DECODER_DESTROY, &device->vdp_decoder_destroy}, + {VDP_FUNC_ID_DECODER_QUERY_CAPABILITIES, + &device->vdp_decoder_query_capabilities}, + {VDP_FUNC_ID_DECODER_GET_PARAMETERS, + &device->vdp_decoder_get_parameters}, + {0, NULL} + }; + + /* FIXME: We probably want to use the same VdpDevice for every VDPAU element */ + device->display = XOpenDisplay (device->display_name); + if (!device->display) { + GST_ERROR_OBJECT (device, "Could not open X display with name: %s", + device->display_name); + return; + } + + screen = DefaultScreen (device->display); + status = + vdp_device_create_x11 (device->display, screen, &device->device, + &device->vdp_get_proc_address); + if (status != VDP_STATUS_OK) { + GST_ERROR_OBJECT (device, "Could not create VDPAU device"); + XCloseDisplay (device->display); + device->display = NULL; + + return; + } + + status = device->vdp_get_proc_address (device->device, + VDP_FUNC_ID_GET_ERROR_STRING, (void **) &device->vdp_get_error_string); + if (status != VDP_STATUS_OK) { + GST_ERROR_OBJECT (device, + "Could not get vdp_get_error_string function pointer from VDPAU"); + goto error; + } + + for (i = 0; vdp_function[i].func != NULL; i++) { + status = device->vdp_get_proc_address (device->device, + vdp_function[i].id, vdp_function[i].func); + + if (status != VDP_STATUS_OK) { + GST_ERROR_OBJECT (device, "Could not get function pointer from VDPAU," + " error returned was: %s", device->vdp_get_error_string (status)); + goto error; + } + } + + return; + +error: + XCloseDisplay (device->display); + device->display = NULL; + + if (device->device != VDP_INVALID_HANDLE) { + device->vdp_device_destroy (device->device); + device->device = VDP_INVALID_HANDLE; + } +} + +static void +gst_vdpau_device_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GstVdpauDevice *device; + + g_return_if_fail (GST_IS_VDPAU_DEVICE (object)); + + device = (GstVdpauDevice *) object; + + switch (prop_id) { + case PROP_DISPLAY: + device->display_name = g_value_dup_string (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_vdpau_device_get_property (GObject * object, guint prop_id, GValue * value, + GParamSpec * pspec) +{ + GstVdpauDevice *device; + + g_return_if_fail (GST_IS_VDPAU_DEVICE (object)); + + device = (GstVdpauDevice *) object; + + switch (prop_id) { + case PROP_DISPLAY: + g_value_set_string (value, device->display_name); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_vdpau_device_class_init (GstVdpauDeviceClass * klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->constructed = gst_vdpau_device_constructed; + object_class->finalize = gst_vdpau_device_finalize; + object_class->get_property = gst_vdpau_device_get_property; + object_class->set_property = gst_vdpau_device_set_property; + + + g_object_class_install_property (object_class, + PROP_DISPLAY, + g_param_spec_string ("display", + "Display", + "X Display Name", + "", G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); + + GST_DEBUG_CATEGORY_INIT (gst_vdpau_device_debug, "vdpaudevice", + 0, "vdpaudevice"); +} + +GstVdpauDevice * +gst_vdpau_device_new (const gchar * display_name) +{ + GstVdpauDevice *device; + + device = g_object_new (GST_TYPE_VDPAU_DEVICE, "display", display_name); + + return device; +} + +static void +device_destroyed_cb (gpointer data, GObject * object) +{ + GHashTable *devices_hash = data; + GHashTableIter iter; + gpointer device; + + g_hash_table_iter_init (&iter, devices_hash); + while (g_hash_table_iter_next (&iter, NULL, &device)) { + if (device == object) { + g_hash_table_iter_remove (&iter); + break; + } + } +} + +static gpointer +create_devices_hash (gpointer data) +{ + return g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); +} + +GstVdpauDevice * +gst_vdpau_get_device (const gchar * display_name) +{ + static GOnce my_once = G_ONCE_INIT; + GHashTable *devices_hash; + GstVdpauDevice *device; + + g_once (&my_once, create_devices_hash, NULL); + devices_hash = my_once.retval; + + if (display_name) + device = g_hash_table_lookup (devices_hash, display_name); + else + device = g_hash_table_lookup (devices_hash, ""); + + if (!device) { + g_debug ("asdasd"); + device = gst_vdpau_device_new (display_name); + g_object_weak_ref (G_OBJECT (device), device_destroyed_cb, devices_hash); + } else + g_object_ref (device); + + g_debug ("HMM"); + return device; +} -- cgit v1.2.1 From 4cc2a90645172a0e5ec879badffe8b620fbdf74e Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Fri, 3 Apr 2009 17:52:20 +0200 Subject: vdpau: remove gst-vdpau-device.c --- sys/vdpau/gst-vdpau-device.c | 267 ------------------------------------------- 1 file changed, 267 deletions(-) delete mode 100644 sys/vdpau/gst-vdpau-device.c (limited to 'sys') diff --git a/sys/vdpau/gst-vdpau-device.c b/sys/vdpau/gst-vdpau-device.c deleted file mode 100644 index ec86ca4e..00000000 --- a/sys/vdpau/gst-vdpau-device.c +++ /dev/null @@ -1,267 +0,0 @@ -/* - * GStreamer - * Copyright (C) 2009 Carl-Anton Ingmarsson - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#include -#include - -#include "gst-vdpau-device.h" - -GST_DEBUG_CATEGORY_STATIC (gst_vdpau_device_debug); -#define GST_CAT_DEFAULT gst_vdpau_device_debug - -enum -{ - PROP_0, - - PROP_DISPLAY -}; - - - -G_DEFINE_TYPE (GstVdpauDevice, gst_vdpau_device, G_TYPE_OBJECT); - -static void -gst_vdpau_device_init (GstVdpauDevice * device) -{ - device->display_name = NULL; - device->display = NULL; - device->device = VDP_INVALID_HANDLE; -} - -static void -gst_vdpau_device_finalize (GObject * object) -{ - GstVdpauDevice *device = (GstVdpauDevice *) object; - - device->vdp_device_destroy (device->device); - g_free (device->display_name); - - G_OBJECT_CLASS (gst_vdpau_device_parent_class)->finalize (object); - -} - -static void -gst_vdpau_device_constructed (GObject * object) -{ - GstVdpauDevice *device = (GstVdpauDevice *) object; - gint screen; - VdpStatus status; - gint i; - - typedef struct - { - gint id; - void *func; - } VdpFunction; - - VdpFunction vdp_function[] = { - {VDP_FUNC_ID_DEVICE_DESTROY, &device->vdp_device_destroy}, - {VDP_FUNC_ID_VIDEO_SURFACE_CREATE, - &device->vdp_video_surface_create}, - {VDP_FUNC_ID_VIDEO_SURFACE_DESTROY, - &device->vdp_video_surface_destroy}, - {VDP_FUNC_ID_VIDEO_SURFACE_QUERY_CAPABILITIES, - &device->vdp_video_surface_query_capabilities}, - {VDP_FUNC_ID_VIDEO_SURFACE_QUERY_GET_PUT_BITS_Y_CB_CR_CAPABILITIES, - &device->vdp_video_surface_query_ycbcr_capabilities}, - {VDP_FUNC_ID_VIDEO_SURFACE_GET_BITS_Y_CB_CR, - &device->vdp_video_surface_get_bits_ycbcr}, - {VDP_FUNC_ID_VIDEO_SURFACE_GET_PARAMETERS, - &device->vdp_video_surface_get_parameters}, - {VDP_FUNC_ID_DECODER_CREATE, &device->vdp_decoder_create}, - {VDP_FUNC_ID_DECODER_RENDER, &device->vdp_decoder_render}, - {VDP_FUNC_ID_DECODER_DESTROY, &device->vdp_decoder_destroy}, - {VDP_FUNC_ID_DECODER_QUERY_CAPABILITIES, - &device->vdp_decoder_query_capabilities}, - {VDP_FUNC_ID_DECODER_GET_PARAMETERS, - &device->vdp_decoder_get_parameters}, - {0, NULL} - }; - - /* FIXME: We probably want to use the same VdpDevice for every VDPAU element */ - device->display = XOpenDisplay (device->display_name); - if (!device->display) { - GST_ERROR_OBJECT (device, "Could not open X display with name: %s", - device->display_name); - return; - } - - screen = DefaultScreen (device->display); - status = - vdp_device_create_x11 (device->display, screen, &device->device, - &device->vdp_get_proc_address); - if (status != VDP_STATUS_OK) { - GST_ERROR_OBJECT (device, "Could not create VDPAU device"); - XCloseDisplay (device->display); - device->display = NULL; - - return; - } - - status = device->vdp_get_proc_address (device->device, - VDP_FUNC_ID_GET_ERROR_STRING, (void **) &device->vdp_get_error_string); - if (status != VDP_STATUS_OK) { - GST_ERROR_OBJECT (device, - "Could not get vdp_get_error_string function pointer from VDPAU"); - goto error; - } - - for (i = 0; vdp_function[i].func != NULL; i++) { - status = device->vdp_get_proc_address (device->device, - vdp_function[i].id, vdp_function[i].func); - - if (status != VDP_STATUS_OK) { - GST_ERROR_OBJECT (device, "Could not get function pointer from VDPAU," - " error returned was: %s", device->vdp_get_error_string (status)); - goto error; - } - } - - return; - -error: - XCloseDisplay (device->display); - device->display = NULL; - - if (device->device != VDP_INVALID_HANDLE) { - device->vdp_device_destroy (device->device); - device->device = VDP_INVALID_HANDLE; - } -} - -static void -gst_vdpau_device_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) -{ - GstVdpauDevice *device; - - g_return_if_fail (GST_IS_VDPAU_DEVICE (object)); - - device = (GstVdpauDevice *) object; - - switch (prop_id) { - case PROP_DISPLAY: - device->display_name = g_value_dup_string (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_vdpau_device_get_property (GObject * object, guint prop_id, GValue * value, - GParamSpec * pspec) -{ - GstVdpauDevice *device; - - g_return_if_fail (GST_IS_VDPAU_DEVICE (object)); - - device = (GstVdpauDevice *) object; - - switch (prop_id) { - case PROP_DISPLAY: - g_value_set_string (value, device->display_name); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_vdpau_device_class_init (GstVdpauDeviceClass * klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->constructed = gst_vdpau_device_constructed; - object_class->finalize = gst_vdpau_device_finalize; - object_class->get_property = gst_vdpau_device_get_property; - object_class->set_property = gst_vdpau_device_set_property; - - - g_object_class_install_property (object_class, - PROP_DISPLAY, - g_param_spec_string ("display", - "Display", - "X Display Name", - "", G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); - - GST_DEBUG_CATEGORY_INIT (gst_vdpau_device_debug, "vdpaudevice", - 0, "vdpaudevice"); -} - -GstVdpauDevice * -gst_vdpau_device_new (const gchar * display_name) -{ - GstVdpauDevice *device; - - device = g_object_new (GST_TYPE_VDPAU_DEVICE, "display", display_name); - - return device; -} - -static void -device_destroyed_cb (gpointer data, GObject * object) -{ - GHashTable *devices_hash = data; - GHashTableIter iter; - gpointer device; - - g_hash_table_iter_init (&iter, devices_hash); - while (g_hash_table_iter_next (&iter, NULL, &device)) { - if (device == object) { - g_hash_table_iter_remove (&iter); - break; - } - } -} - -static gpointer -create_devices_hash (gpointer data) -{ - return g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); -} - -GstVdpauDevice * -gst_vdpau_get_device (const gchar * display_name) -{ - static GOnce my_once = G_ONCE_INIT; - GHashTable *devices_hash; - GstVdpauDevice *device; - - g_once (&my_once, create_devices_hash, NULL); - devices_hash = my_once.retval; - - if (display_name) - device = g_hash_table_lookup (devices_hash, display_name); - else - device = g_hash_table_lookup (devices_hash, ""); - - if (!device) { - g_debug ("asdasd"); - device = gst_vdpau_device_new (display_name); - g_object_weak_ref (G_OBJECT (device), device_destroyed_cb, devices_hash); - } else - g_object_ref (device); - - g_debug ("HMM"); - return device; -} -- cgit v1.2.1 From 7b6cfb83c821342489bd61e02a5694fa60d2012e Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Fri, 3 Apr 2009 17:53:21 +0200 Subject: vdpau: commit rename of gst-vdpau-device.h to gstvdpaudevice.h --- sys/vdpau/gst-vdpau-device.h | 80 -------------------------------------------- sys/vdpau/gstvdpaudevice.h | 80 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+), 80 deletions(-) delete mode 100644 sys/vdpau/gst-vdpau-device.h create mode 100644 sys/vdpau/gstvdpaudevice.h (limited to 'sys') diff --git a/sys/vdpau/gst-vdpau-device.h b/sys/vdpau/gst-vdpau-device.h deleted file mode 100644 index 0a5cb5e7..00000000 --- a/sys/vdpau/gst-vdpau-device.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * GStreamer - * Copyright (C) 2009 Carl-Anton Ingmarsson - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef _GST_VDPAU_DEVICE_H_ -#define _GST_VDPAU_DEVICE_H_ - -#include -#include - -#include - -G_BEGIN_DECLS - -#define GST_TYPE_VDPAU_DEVICE (gst_vdpau_device_get_type ()) -#define GST_VDPAU_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VDPAU_DEVICE, GstVdpauDevice)) -#define GST_VDPAU_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_VDPAU_DEVICE, GstVdpauDeviceClass)) -#define GST_IS_VDPAU_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VDPAU_DEVICE)) -#define GST_IS_VDPAU_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_VDPAU_DEVICE)) -#define GST_VDPAU_DEVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VDPAU_DEVICE, GstVdpauDeviceClass)) - -typedef struct _GstVdpauDeviceClass GstVdpauDeviceClass; -typedef struct _GstVdpauDevice GstVdpauDevice; - -struct _GstVdpauDeviceClass -{ - GObjectClass parent_class; -}; - -struct _GstVdpauDevice -{ - GObject object; - - gchar *display_name; - Display *display; - VdpDevice device; - - VdpDeviceDestroy *vdp_device_destroy; - VdpGetProcAddress *vdp_get_proc_address; - VdpGetErrorString *vdp_get_error_string; - - VdpVideoSurfaceCreate *vdp_video_surface_create; - VdpVideoSurfaceDestroy *vdp_video_surface_destroy; - VdpVideoSurfaceQueryCapabilities *vdp_video_surface_query_capabilities; - VdpVideoSurfaceQueryGetPutBitsYCbCrCapabilities *vdp_video_surface_query_ycbcr_capabilities; - VdpVideoSurfaceGetParameters *vdp_video_surface_get_parameters; - VdpVideoSurfaceGetBitsYCbCr *vdp_video_surface_get_bits_ycbcr; - - VdpDecoderCreate *vdp_decoder_create; - VdpDecoderDestroy *vdp_decoder_destroy; - VdpDecoderRender *vdp_decoder_render; - VdpDecoderQueryCapabilities *vdp_decoder_query_capabilities; - VdpDecoderGetParameters *vdp_decoder_get_parameters; -}; - -GType gst_vdpau_device_get_type (void) G_GNUC_CONST; - -GstVdpauDevice *gst_vdpau_device_new (const gchar *display_name); - -GstVdpauDevice *gst_vdpau_get_device (const gchar *display_name); - -G_END_DECLS - -#endif /* _GST_VDPAU_DEVICE_H_ */ diff --git a/sys/vdpau/gstvdpaudevice.h b/sys/vdpau/gstvdpaudevice.h new file mode 100644 index 00000000..0a5cb5e7 --- /dev/null +++ b/sys/vdpau/gstvdpaudevice.h @@ -0,0 +1,80 @@ +/* + * GStreamer + * Copyright (C) 2009 Carl-Anton Ingmarsson + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _GST_VDPAU_DEVICE_H_ +#define _GST_VDPAU_DEVICE_H_ + +#include +#include + +#include + +G_BEGIN_DECLS + +#define GST_TYPE_VDPAU_DEVICE (gst_vdpau_device_get_type ()) +#define GST_VDPAU_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VDPAU_DEVICE, GstVdpauDevice)) +#define GST_VDPAU_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_VDPAU_DEVICE, GstVdpauDeviceClass)) +#define GST_IS_VDPAU_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VDPAU_DEVICE)) +#define GST_IS_VDPAU_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_VDPAU_DEVICE)) +#define GST_VDPAU_DEVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VDPAU_DEVICE, GstVdpauDeviceClass)) + +typedef struct _GstVdpauDeviceClass GstVdpauDeviceClass; +typedef struct _GstVdpauDevice GstVdpauDevice; + +struct _GstVdpauDeviceClass +{ + GObjectClass parent_class; +}; + +struct _GstVdpauDevice +{ + GObject object; + + gchar *display_name; + Display *display; + VdpDevice device; + + VdpDeviceDestroy *vdp_device_destroy; + VdpGetProcAddress *vdp_get_proc_address; + VdpGetErrorString *vdp_get_error_string; + + VdpVideoSurfaceCreate *vdp_video_surface_create; + VdpVideoSurfaceDestroy *vdp_video_surface_destroy; + VdpVideoSurfaceQueryCapabilities *vdp_video_surface_query_capabilities; + VdpVideoSurfaceQueryGetPutBitsYCbCrCapabilities *vdp_video_surface_query_ycbcr_capabilities; + VdpVideoSurfaceGetParameters *vdp_video_surface_get_parameters; + VdpVideoSurfaceGetBitsYCbCr *vdp_video_surface_get_bits_ycbcr; + + VdpDecoderCreate *vdp_decoder_create; + VdpDecoderDestroy *vdp_decoder_destroy; + VdpDecoderRender *vdp_decoder_render; + VdpDecoderQueryCapabilities *vdp_decoder_query_capabilities; + VdpDecoderGetParameters *vdp_decoder_get_parameters; +}; + +GType gst_vdpau_device_get_type (void) G_GNUC_CONST; + +GstVdpauDevice *gst_vdpau_device_new (const gchar *display_name); + +GstVdpauDevice *gst_vdpau_get_device (const gchar *display_name); + +G_END_DECLS + +#endif /* _GST_VDPAU_DEVICE_H_ */ -- cgit v1.2.1 From f72dc12373cbb73a68fa1f8951d33472ac0940b2 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Fri, 3 Apr 2009 17:58:25 +0200 Subject: vdpau: remove obosolete FIXME and some debug prints from gstvdpaudevice.c --- sys/vdpau/gstvdpaudevice.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpaudevice.c b/sys/vdpau/gstvdpaudevice.c index 23a582f3..8e314d6d 100644 --- a/sys/vdpau/gstvdpaudevice.c +++ b/sys/vdpau/gstvdpaudevice.c @@ -95,7 +95,6 @@ gst_vdpau_device_constructed (GObject * object) {0, NULL} }; - /* FIXME: We probably want to use the same VdpDevice for every VDPAU element */ device->display = XOpenDisplay (device->display_name); if (!device->display) { GST_ERROR_OBJECT (device, "Could not open X display with name: %s", @@ -256,12 +255,10 @@ gst_vdpau_get_device (const gchar * display_name) device = g_hash_table_lookup (devices_hash, ""); if (!device) { - g_debug ("asdasd"); device = gst_vdpau_device_new (display_name); g_object_weak_ref (G_OBJECT (device), device_destroyed_cb, devices_hash); } else g_object_ref (device); - g_debug ("HMM"); return device; } -- cgit v1.2.1 From 5e73b7272bb210427763b8d2effc68280d9493a0 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Fri, 3 Apr 2009 17:59:02 +0200 Subject: vdpau: small indent fix --- sys/vdpau/gstvdpaumpegdecoder.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpaumpegdecoder.c b/sys/vdpau/gstvdpaumpegdecoder.c index f3e510bd..fba52d39 100644 --- a/sys/vdpau/gstvdpaumpegdecoder.c +++ b/sys/vdpau/gstvdpaumpegdecoder.c @@ -228,8 +228,8 @@ gst_vdpau_mpeg_decoder_parse_picture (GstVdpauMpegDecoder * mpeg_dec, if (pic_hdr.pic_type == I_FRAME && mpeg_dec->vdp_info.forward_reference != VDP_INVALID_HANDLE) { - dec->device->vdp_video_surface_destroy (mpeg_dec->vdp_info. - forward_reference); + dec->device->vdp_video_surface_destroy (mpeg_dec-> + vdp_info.forward_reference); mpeg_dec->vdp_info.forward_reference = VDP_INVALID_HANDLE; } -- cgit v1.2.1 From 85158b07eabb0d8fe7e4f29b06ea447a54505ad8 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Sat, 4 Apr 2009 20:53:35 +0200 Subject: vdpau: add new GstVdpauVideoYUV element GstVdpauDecoder now pushes GstVdpauVideoBuffers instead of doing VdpSurface -> YUV conversion. To get YUV data you now put in a GstVdpauVideoYUV element which takes GstVdpauVideoBuffers and outputs YUV data. --- sys/vdpau/Makefile.am | 6 +- sys/vdpau/gstvdpaudecoder.c | 291 +------------------------ sys/vdpau/gstvdpaudecoder.h | 6 +- sys/vdpau/gstvdpaumpegdecoder.c | 37 ++-- sys/vdpau/gstvdpaumpegdecoder.h | 2 +- sys/vdpau/gstvdpauvideobuffer.c | 114 ++++++++++ sys/vdpau/gstvdpauvideobuffer.h | 55 +++++ sys/vdpau/gstvdpauvideoyuv.c | 454 ++++++++++++++++++++++++++++++++++++++++ sys/vdpau/gstvdpauvideoyuv.h | 62 ++++++ 9 files changed, 721 insertions(+), 306 deletions(-) create mode 100644 sys/vdpau/gstvdpauvideobuffer.c create mode 100644 sys/vdpau/gstvdpauvideobuffer.h create mode 100644 sys/vdpau/gstvdpauvideoyuv.c create mode 100644 sys/vdpau/gstvdpauvideoyuv.h (limited to 'sys') diff --git a/sys/vdpau/Makefile.am b/sys/vdpau/Makefile.am index 0e3b578e..ba286d54 100644 --- a/sys/vdpau/Makefile.am +++ b/sys/vdpau/Makefile.am @@ -4,7 +4,9 @@ libgstvdpau_la_SOURCES = \ gstvdpaudevice.c \ gstvdpaudecoder.c \ gstvdpaumpegdecoder.c \ - mpegutil.c + mpegutil.c \ + gstvdpauvideoyuv.c \ + gstvdpauvideobuffer.c libgstvdpau_la_CFLAGS = $(GST_CFLAGS) $(X11_CFLAGS) -Ivdpau libgstvdpau_la_LIBADD = $(GST_LIBS) $(GST_BASE_LIBS) \ @@ -16,6 +18,8 @@ noinst_HEADERS = \ gstvdpaudevice.h \ gstvdpaudecoder.h \ gstvdpaumpegdecoder.h \ + gstvdpauvideoyuv.h \ + gstvdpauvideobuffer.h \ mpegutil.h diff --git a/sys/vdpau/gstvdpaudecoder.c b/sys/vdpau/gstvdpaudecoder.c index 5a8bbacd..4db93f7e 100644 --- a/sys/vdpau/gstvdpaudecoder.c +++ b/sys/vdpau/gstvdpaudecoder.c @@ -25,6 +25,7 @@ #include #include +#include "gstvdpauvideobuffer.h" #include "gstvdpaudecoder.h" GST_DEBUG_CATEGORY_STATIC (gst_vdpau_decoder_debug); @@ -47,9 +48,7 @@ enum static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS, - GST_STATIC_CAPS ("video/x-raw-yuv, " - "framerate = (fraction) [ 0, MAX ], " - "width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ]")); + GST_STATIC_CAPS ("video/vdpau-video, " "chroma-type = (int) 0")); #define DEBUG_INIT(bla) \ GST_DEBUG_CATEGORY_INIT (gst_vdpau_decoder_debug, "vdpaudecoder", 0, "vdpaudecoder base class"); @@ -64,100 +63,9 @@ static void gst_vdpau_decoder_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); GstFlowReturn -gst_vdpau_decoder_push_video_surface (GstVdpauDecoder * dec, - VdpVideoSurface surface) +gst_vdpau_decoder_push_video_buffer (GstVdpauDecoder * dec, + GstVdpauVideoBuffer * buffer) { - GstVdpauDevice *device; - GstBuffer *buffer; - - device = dec->device; - - switch (dec->format) { - case GST_MAKE_FOURCC ('Y', 'V', '1', '2'): - { - gint size; - GstFlowReturn result; - VdpStatus status; - guint8 *data[3]; - guint32 stride[3]; - - size = - gst_video_format_get_size (GST_VIDEO_FORMAT_YV12, dec->width, - dec->height); - result = - gst_pad_alloc_buffer_and_set_caps (dec->src, GST_BUFFER_OFFSET_NONE, - size, GST_PAD_CAPS (dec->src), &buffer); - if (G_UNLIKELY (result != GST_FLOW_OK)) - return result; - - - data[0] = GST_BUFFER_DATA (buffer) + - gst_video_format_get_component_offset (GST_VIDEO_FORMAT_YV12, - 0, dec->width, dec->height); - data[1] = data[0] + - gst_video_format_get_component_offset (GST_VIDEO_FORMAT_YV12, - 2, dec->width, dec->height); - data[2] = data[0] + - gst_video_format_get_component_offset (GST_VIDEO_FORMAT_YV12, - 1, dec->width, dec->height); - - stride[0] = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_YV12, - 0, dec->width); - stride[1] = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_YV12, - 2, dec->width); - stride[2] = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_YV12, - 1, dec->width); - - status = - device->vdp_video_surface_get_bits_ycbcr (surface, - VDP_YCBCR_FORMAT_YV12, (void *) data, stride); - if (G_UNLIKELY (status != VDP_STATUS_OK)) { - GST_ELEMENT_ERROR (dec, RESOURCE, READ, - ("Couldn't get data from vdpau"), - ("Error returned from vdpau was: %s", - device->vdp_get_error_string (status))); - return GST_FLOW_ERROR; - } - break; - } - case GST_MAKE_FOURCC ('N', 'V', '1', '2'): - { - gint size; - GstFlowReturn result; - VdpStatus status; - guint8 *data[2]; - guint32 stride[2]; - - size = dec->width * dec->height + dec->width * dec->height / 2; - result = - gst_pad_alloc_buffer_and_set_caps (dec->src, GST_BUFFER_OFFSET_NONE, - size, GST_PAD_CAPS (dec->src), &buffer); - if (G_UNLIKELY (result != GST_FLOW_OK)) - return result; - - - data[0] = GST_BUFFER_DATA (buffer); - data[1] = data[0] + dec->width * dec->height; - - stride[0] = dec->width; - stride[1] = dec->width; - - status = - device->vdp_video_surface_get_bits_ycbcr (surface, - VDP_YCBCR_FORMAT_NV12, (void *) data, stride); - if (G_UNLIKELY (status != VDP_STATUS_OK)) { - GST_ELEMENT_ERROR (dec, RESOURCE, READ, - ("Couldn't get data from vdpau"), - ("Error returned from vdpau was: %s", - device->vdp_get_error_string (status))); - return GST_FLOW_ERROR; - } - break; - } - default: - break; - } - GST_BUFFER_TIMESTAMP (buffer) = gst_util_uint64_scale_int (GST_SECOND * dec->frame_nr, dec->framerate_denominator, dec->framerate_numerator); @@ -167,167 +75,9 @@ gst_vdpau_decoder_push_video_surface (GstVdpauDecoder * dec, GST_BUFFER_OFFSET (buffer) = dec->frame_nr; dec->frame_nr++; GST_BUFFER_OFFSET_END (buffer) = dec->frame_nr; + gst_buffer_set_caps (GST_BUFFER (buffer), GST_PAD_CAPS (dec->src)); - return gst_pad_push (dec->src, buffer); -} - -typedef struct -{ - VdpChromaType chroma_type; - VdpYCbCrFormat format; - guint32 fourcc; -} VdpauFormats; - -static VdpChromaType chroma_types[3] = - { VDP_CHROMA_TYPE_420, VDP_CHROMA_TYPE_422, VDP_CHROMA_TYPE_444 }; -static VdpauFormats formats[6] = { - { - VDP_CHROMA_TYPE_420, - VDP_YCBCR_FORMAT_NV12, - GST_MAKE_FOURCC ('N', 'V', '1', '2') - }, - { - VDP_CHROMA_TYPE_422, - VDP_YCBCR_FORMAT_UYVY, - GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y') - }, - { - VDP_CHROMA_TYPE_444, - VDP_YCBCR_FORMAT_V8U8Y8A8, - GST_MAKE_FOURCC ('A', 'Y', 'U', 'V') - }, - { - VDP_CHROMA_TYPE_444, - VDP_YCBCR_FORMAT_Y8U8V8A8, - GST_MAKE_FOURCC ('A', 'V', 'U', 'Y') - }, - { - VDP_CHROMA_TYPE_422, - VDP_YCBCR_FORMAT_YUYV, - GST_MAKE_FOURCC ('Y', 'U', 'Y', 'V') - }, - { - VDP_CHROMA_TYPE_420, - VDP_YCBCR_FORMAT_YV12, - GST_MAKE_FOURCC ('Y', 'V', '1', '2') - } -}; - -VdpVideoSurface -gst_vdpau_decoder_create_video_surface (GstVdpauDecoder * dec) -{ - GstVdpauDevice *device; - VdpChromaType chroma_type; - gint i; - VdpStatus status; - VdpVideoSurface surface; - - device = dec->device; - - chroma_type = VDP_CHROMA_TYPE_422; - for (i = 0; i < 6; i++) { - if (formats[i].fourcc == dec->format) { - chroma_type = formats[i].chroma_type; - break; - } - } - - status = - device->vdp_video_surface_create (device->device, chroma_type, dec->width, - dec->height, &surface); - if (status != VDP_STATUS_OK) { - GST_ELEMENT_ERROR (dec, RESOURCE, READ, - ("Couldn't create a VdpVideoSurface"), - ("Error returned from vdpau was: %s", - device->vdp_get_error_string (status))); - return VDP_INVALID_HANDLE; - } - - return surface; -} - -static GstCaps * -gst_vdpau_decoder_get_vdpau_support (GstVdpauDecoder * dec) -{ - GstVdpauDevice *device; - GstCaps *caps; - gint i; - - device = dec->device; - - caps = gst_caps_new_empty (); - - for (i = 0; i < 3; i++) { - VdpStatus status; - VdpBool is_supported; - guint32 max_w, max_h; - - status = - device->vdp_video_surface_query_capabilities (device->device, - chroma_types[i], &is_supported, &max_w, &max_h); - - if (status != VDP_STATUS_OK && status != VDP_STATUS_INVALID_CHROMA_TYPE) { - GST_ELEMENT_ERROR (dec, RESOURCE, READ, - ("Could not get query VDPAU video surface capabilites"), - ("Error returned from vdpau was: %s", - device->vdp_get_error_string (status))); - - return NULL; - } - if (is_supported) { - gint j; - - for (j = 0; j < 6; j++) { - if (formats[j].chroma_type != chroma_types[i]) - continue; - - status = - device->vdp_video_surface_query_ycbcr_capabilities (device->device, - formats[j].chroma_type, formats[j].format, &is_supported); - if (status != VDP_STATUS_OK - && status != VDP_STATUS_INVALID_Y_CB_CR_FORMAT) { - GST_ELEMENT_ERROR (dec, RESOURCE, READ, - ("Could not query VDPAU YCbCr capabilites"), - ("Error returned from vdpau was: %s", - device->vdp_get_error_string (status))); - - return NULL; - } - if (is_supported) { - GstCaps *format_caps; - - format_caps = gst_caps_new_simple ("video/x-raw-yuv", - "format", GST_TYPE_FOURCC, formats[j].fourcc, - "width", GST_TYPE_INT_RANGE, 1, max_w, - "height", GST_TYPE_INT_RANGE, 1, max_h, - "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL); - gst_caps_append (caps, format_caps); - } - } - } - } - if (gst_caps_is_empty (caps)) { - gst_caps_unref (caps); - return NULL; - } - - return caps; -} - -static gboolean -gst_vdpau_decoder_init_vdpau (GstVdpauDecoder * dec) -{ - GstCaps *caps; - - dec->device = gst_vdpau_get_device (dec->display_name); - - caps = gst_vdpau_decoder_get_vdpau_support (dec); - if (!caps) - return FALSE; - - dec->src_caps = caps; - - return TRUE; + return gst_pad_push (dec->src, GST_BUFFER (buffer)); } static GstStateChangeReturn @@ -339,8 +89,7 @@ gst_vdpau_decoder_change_state (GstElement * element, GstStateChange transition) switch (transition) { case GST_STATE_CHANGE_NULL_TO_READY: - if (!gst_vdpau_decoder_init_vdpau (dec)) - return GST_STATE_CHANGE_FAILURE; + dec->device = gst_vdpau_get_device (dec->display_name); break; case GST_STATE_CHANGE_READY_TO_NULL: g_object_unref (dec->device); @@ -364,7 +113,6 @@ gst_vdpau_decoder_sink_set_caps (GstPad * pad, GstCaps * caps) gint width, height; gint framerate_numerator, framerate_denominator; gint par_numerator, par_denominator; - guint32 fourcc_format; gboolean res; structure = gst_caps_get_structure (caps, 0); @@ -382,8 +130,9 @@ gst_vdpau_decoder_sink_set_caps (GstPad * pad, GstCaps * caps) new_caps = gst_caps_copy_nth (src_caps, 0); gst_caps_unref (src_caps); structure = gst_caps_get_structure (new_caps, 0); - gst_structure_get_fourcc (structure, "format", &fourcc_format); gst_structure_set (structure, + "device", G_TYPE_OBJECT, dec->device, + "chroma-type", G_TYPE_INT, VDP_CHROMA_TYPE_420, "width", G_TYPE_INT, width, "height", G_TYPE_INT, height, "framerate", GST_TYPE_FRACTION, framerate_numerator, @@ -403,7 +152,6 @@ gst_vdpau_decoder_sink_set_caps (GstPad * pad, GstCaps * caps) dec->height = height; dec->framerate_numerator = framerate_numerator; dec->framerate_denominator = framerate_denominator; - dec->format = fourcc_format; if (dec_class->set_caps && !dec_class->set_caps (dec, caps)) return FALSE; @@ -411,22 +159,6 @@ gst_vdpau_decoder_sink_set_caps (GstPad * pad, GstCaps * caps) return TRUE; } -static GstCaps * -gst_vdpau_decoder_src_getcaps (GstPad * pad) -{ - GstVdpauDecoder *dec; - - dec = GST_VDPAU_DECODER (GST_OBJECT_PARENT (pad)); - - if (GST_PAD_CAPS (dec->src)) - return gst_caps_ref (GST_PAD_CAPS (dec->src)); - - if (dec->src_caps) - return gst_caps_ref (dec->src_caps); - - return gst_caps_copy (gst_pad_get_pad_template_caps (dec->src)); -} - /* GObject vmethod implementations */ static void @@ -475,18 +207,15 @@ gst_vdpau_decoder_init (GstVdpauDecoder * dec, GstVdpauDecoderClass * klass) dec->display_name = NULL; dec->device = NULL; dec->silent = FALSE; - dec->src_caps = NULL; dec->height = 0; dec->width = 0; dec->framerate_numerator = 0; dec->framerate_denominator = 0; - dec->format = 0; dec->frame_nr = 0; dec->src = gst_pad_new_from_static_template (&src_template, "src"); - gst_pad_set_getcaps_function (dec->src, gst_vdpau_decoder_src_getcaps); gst_element_add_pad (GST_ELEMENT (dec), dec->src); dec->sink = gst_pad_new_from_template (gst_element_class_get_pad_template @@ -501,8 +230,6 @@ gst_vdpau_decoder_finalize (GObject * object) { GstVdpauDecoder *dec = (GstVdpauDecoder *) object; - if (dec->src_caps) - g_object_unref (dec->src_caps); if (dec->device) g_object_unref (dec->device); diff --git a/sys/vdpau/gstvdpaudecoder.h b/sys/vdpau/gstvdpaudecoder.h index 415d6eca..ef3a6fb9 100644 --- a/sys/vdpau/gstvdpaudecoder.h +++ b/sys/vdpau/gstvdpaudecoder.h @@ -47,8 +47,6 @@ struct _GstVdpauDecoder { GstPad *src; GstPad *sink; - GstCaps *src_caps; - gint width, height; gint framerate_numerator, framerate_denominator; guint32 format; @@ -66,8 +64,8 @@ struct _GstVdpauDecoderClass { GType gst_vdpau_decoder_get_type (void); -gboolean gst_vdpau_decoder_push_video_surface (GstVdpauDecoder * dec, - VdpVideoSurface surface); +gboolean gst_vdpau_decoder_push_video_buffer (GstVdpauDecoder * dec, + GstVdpauVideoBuffer *buffer); VdpVideoSurface gst_vdpau_decoder_create_video_surface (GstVdpauDecoder *dec); G_END_DECLS diff --git a/sys/vdpau/gstvdpaumpegdecoder.c b/sys/vdpau/gstvdpaumpegdecoder.c index fba52d39..80ee13ca 100644 --- a/sys/vdpau/gstvdpaumpegdecoder.c +++ b/sys/vdpau/gstvdpaumpegdecoder.c @@ -38,6 +38,8 @@ #include #include +#include "gstvdpauvideobuffer.h" +#include "gstvdpauvideoyuv.h" #include "mpegutil.h" #include "gstvdpaumpegdecoder.h" @@ -133,19 +135,20 @@ gst_vdpau_mpeg_decoder_decode (GstVdpauMpegDecoder * mpeg_dec) { GstVdpauDecoder *dec; GstBuffer *buffer; + GstVdpauVideoBuffer *outbuf; VdpVideoSurface surface; GstVdpauDevice *device; VdpBitstreamBuffer vbit[1]; VdpStatus status; - GstFlowReturn ret; dec = GST_VDPAU_DECODER (mpeg_dec); buffer = gst_adapter_take_buffer (mpeg_dec->adapter, gst_adapter_available (mpeg_dec->adapter)); - surface = - gst_vdpau_decoder_create_video_surface (GST_VDPAU_DECODER (mpeg_dec)); + outbuf = gst_vdpau_video_buffer_new (dec->device, VDP_CHROMA_TYPE_420, + dec->width, dec->height); + surface = outbuf->surface; device = dec->device; @@ -165,23 +168,23 @@ gst_vdpau_mpeg_decoder_decode (GstVdpauMpegDecoder * mpeg_dec) device->vdp_get_error_string (status))); if (mpeg_dec->vdp_info.forward_reference != VDP_INVALID_HANDLE) - device->vdp_video_surface_destroy (mpeg_dec->vdp_info.forward_reference); + gst_buffer_unref (mpeg_dec->f_buffer); - device->vdp_video_surface_destroy (surface); + gst_buffer_unref (GST_BUFFER (outbuf)); return GST_FLOW_ERROR; } - ret = - gst_vdpau_decoder_push_video_surface (GST_VDPAU_DECODER (mpeg_dec), - surface); + gst_buffer_ref (GST_BUFFER (outbuf)); if (mpeg_dec->vdp_info.forward_reference != VDP_INVALID_HANDLE) - device->vdp_video_surface_destroy (mpeg_dec->vdp_info.forward_reference); + gst_buffer_unref (mpeg_dec->f_buffer); mpeg_dec->vdp_info.forward_reference = surface; + mpeg_dec->f_buffer = GST_BUFFER (outbuf); - return ret; + return gst_vdpau_decoder_push_video_buffer (GST_VDPAU_DECODER (mpeg_dec), + outbuf); } static gboolean @@ -228,8 +231,7 @@ gst_vdpau_mpeg_decoder_parse_picture (GstVdpauMpegDecoder * mpeg_dec, if (pic_hdr.pic_type == I_FRAME && mpeg_dec->vdp_info.forward_reference != VDP_INVALID_HANDLE) { - dec->device->vdp_video_surface_destroy (mpeg_dec-> - vdp_info.forward_reference); + gst_buffer_unref (mpeg_dec->f_buffer); mpeg_dec->vdp_info.forward_reference = VDP_INVALID_HANDLE; } @@ -421,11 +423,6 @@ gst_vdpau_mpeg_decoder_finalize (GObject * object) { GstVdpauMpegDecoder *mpeg_dec = (GstVdpauMpegDecoder *) object; -#if 0 /* FIXME: can't free the decoder since the device already has been freed */ - if (mpeg_dec->decoder != VDP_INVALID_HANDLE) - dec->device->vdp_decoder_destroy (mpeg_dec->decoder); -#endif - g_object_unref (mpeg_dec->adapter); } @@ -475,8 +472,12 @@ vdpaumpegdecoder_init (GstPlugin * vdpaumpegdecoder) GST_DEBUG_CATEGORY_INIT (gst_vdpau_mpeg_decoder_debug, "vdpaumpegdecoder", 0, "Template vdpaumpegdecoder"); - return gst_element_register (vdpaumpegdecoder, "vdpaumpegdecoder", + gst_element_register (vdpaumpegdecoder, "vdpaumpegdecoder", GST_RANK_NONE, GST_TYPE_VDPAU_MPEG_DECODER); + gst_element_register (vdpaumpegdecoder, "vdpauvideoyuv", + GST_RANK_NONE, GST_TYPE_VDPAU_VIDEO_YUV); + + return TRUE; } /* gstreamer looks for this structure to register vdpaumpegdecoders diff --git a/sys/vdpau/gstvdpaumpegdecoder.h b/sys/vdpau/gstvdpaumpegdecoder.h index 4b4c6550..d251480c 100644 --- a/sys/vdpau/gstvdpaumpegdecoder.h +++ b/sys/vdpau/gstvdpaumpegdecoder.h @@ -47,10 +47,10 @@ struct _GstVdpauMpegDecoder VdpDecoder decoder; VdpPictureInfoMPEG1Or2 vdp_info; + GstBuffer *f_buffer; GstAdapter *adapter; gint slices; - }; struct _GstVdpauMpegDecoderClass diff --git a/sys/vdpau/gstvdpauvideobuffer.c b/sys/vdpau/gstvdpauvideobuffer.c new file mode 100644 index 00000000..f7ece0eb --- /dev/null +++ b/sys/vdpau/gstvdpauvideobuffer.c @@ -0,0 +1,114 @@ +/* + * GStreamer + * Copyright (C) 2009 Carl-Anton Ingmarsson + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "gstvdpauvideobuffer.h" + +static GObjectClass *gst_vdpau_video_buffer_parent_class; + +static void +gst_vdpau_video_buffer_finalize (GstVdpauVideoBuffer * buffer) +{ + GstVdpauDevice *device = buffer->device; + VdpStatus status; + + status = device->vdp_video_surface_destroy (buffer->surface); + if (status != VDP_STATUS_OK) + GST_ERROR + ("Couldn't destroy the buffers VdpVideoSurface, error returned was: %s", + device->vdp_get_error_string (status)); + + g_object_unref (buffer->device); + + GST_MINI_OBJECT_CLASS (gst_vdpau_video_buffer_parent_class)->finalize + (GST_MINI_OBJECT (buffer)); +} + +static void +gst_vdpau_video_buffer_init (GstVdpauVideoBuffer * buffer, gpointer g_class) +{ + buffer->device = NULL; + buffer->surface = VDP_INVALID_HANDLE; +} + +static void +gst_vdpau_video_buffer_class_init (gpointer g_class, gpointer class_data) +{ + GstMiniObjectClass *mini_object_class = GST_MINI_OBJECT_CLASS (g_class); + + gst_vdpau_video_buffer_parent_class = g_type_class_peek_parent (g_class); + + mini_object_class->finalize = (GstMiniObjectFinalizeFunction) + gst_vdpau_video_buffer_finalize; +} + + +GType +gst_vdpau_video_buffer_get_type (void) +{ + static GType _gst_vdpau_video_buffer_type; + + if (G_UNLIKELY (_gst_vdpau_video_buffer_type == 0)) { + static const GTypeInfo info = { + sizeof (GstBufferClass), + NULL, + NULL, + gst_vdpau_video_buffer_class_init, + NULL, + NULL, + sizeof (GstVdpauVideoBuffer), + 0, + (GInstanceInitFunc) gst_vdpau_video_buffer_init, + NULL + }; + _gst_vdpau_video_buffer_type = g_type_register_static (GST_TYPE_BUFFER, + "GstVdpauVideoBuffer", &info, 0); + } + return _gst_vdpau_video_buffer_type; +} + + +GstVdpauVideoBuffer * +gst_vdpau_video_buffer_new (GstVdpauDevice * device, VdpChromaType chroma_type, + gint width, gint height) +{ + GstVdpauVideoBuffer *buffer; + VdpStatus status; + VdpVideoSurface surface; + + status = device->vdp_video_surface_create (device->device, chroma_type, width, + height, &surface); + if (status != VDP_STATUS_OK) { + GST_ERROR ("Couldn't create a VdpVideoSurface, error returned was: %s", + device->vdp_get_error_string (status)); + return NULL; + } + + buffer = + (GstVdpauVideoBuffer *) gst_mini_object_new (GST_TYPE_VDPAU_VIDEO_BUFFER); + + buffer->device = g_object_ref (device); + buffer->surface = surface; + + return buffer; +} diff --git a/sys/vdpau/gstvdpauvideobuffer.h b/sys/vdpau/gstvdpauvideobuffer.h new file mode 100644 index 00000000..fe2b4b7f --- /dev/null +++ b/sys/vdpau/gstvdpauvideobuffer.h @@ -0,0 +1,55 @@ +/* + * GStreamer + * Copyright (C) 2009 Carl-Anton Ingmarsson + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _GST_VDPAU_VIDEO_BUFFER_H_ +#define _GST_VDPAU_VIDEO_BUFFER_H_ + +#include +#include + +#include "gstvdpaudevice.h" + +#include "gstvdpauvideobuffer.h" + +typedef struct _GstVdpauVideoBuffer GstVdpauVideoBuffer; + +#define GST_TYPE_VDPAU_VIDEO_BUFFER (gst_vdpau_video_buffer_get_type()) + +#define GST_IS_VDPAU_VIDEO_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VDPAU_VIDEO_BUFFER)) +#define GST_VDPAU_VIDEO_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VDPAU_VIDEO_BUFFER, GstVdpauVideoBuffer)) + +struct _GstVdpauVideoBuffer { + GstBuffer buffer; + + GstVdpauDevice *device; + VdpVideoSurface surface; +}; + +GType gst_vdpau_video_buffer_get_type (void); + +GstVdpauVideoBuffer* gst_vdpau_video_buffer_new (GstVdpauDevice * device, VdpChromaType chroma_type, gint width, gint height); + +#define GST_VDPAU_VIDEO_CAPS \ + "video/vdpau-video, " \ + "chroma-type = (int)[0,2], " \ + "width = (int)[1,4096], " \ + "height = (int)[1,4096]" + +#endif diff --git a/sys/vdpau/gstvdpauvideoyuv.c b/sys/vdpau/gstvdpauvideoyuv.c new file mode 100644 index 00000000..1de17045 --- /dev/null +++ b/sys/vdpau/gstvdpauvideoyuv.c @@ -0,0 +1,454 @@ +/* + * GStreamer + * Copyright (C) 2009 Carl-Anton Ingmarsson + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#include "gstvdpauvideobuffer.h" +#include "gstvdpauvideoyuv.h" + +GST_DEBUG_CATEGORY_STATIC (gst_vdpau_video_yuv_debug); +#define GST_CAT_DEFAULT gst_vdpau_video_yuv_debug + +/* Filter signals and args */ +enum +{ + /* FILL ME */ + LAST_SIGNAL +}; + +enum +{ + PROP_0, + PROP_SILENT +}; + +static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS (GST_VDPAU_VIDEO_CAPS)); + +static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS ("video/x-raw-yuv, " + "framerate = (fraction) [ 0, MAX ], " + "width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ]")); + +#define DEBUG_INIT(bla) \ + GST_DEBUG_CATEGORY_INIT (gst_vdpau_video_yuv_debug, "vdpauvideo_yuv", 0, "vdpauvideo_yuv base class"); + +GST_BOILERPLATE_FULL (GstVdpauVideoYUV, gst_vdpau_video_yuv, GstElement, + GST_TYPE_ELEMENT, DEBUG_INIT); + +static void gst_vdpau_video_yuv_finalize (GObject * object); +static void gst_vdpau_video_yuv_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec); +static void gst_vdpau_video_yuv_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec); + +GstFlowReturn +gst_vdpau_video_yuv_chain (GstPad * pad, GstBuffer * buffer) +{ + GstVdpauVideoYUV *video_yuv; + GstVdpauDevice *device; + VdpVideoSurface surface; + GstBuffer *outbuf = NULL; + + video_yuv = GST_VDPAU_VIDEO_YUV (GST_OBJECT_PARENT (pad)); + device = GST_VDPAU_VIDEO_BUFFER (buffer)->device; + surface = GST_VDPAU_VIDEO_BUFFER (buffer)->surface; + + switch (video_yuv->format) { + case GST_MAKE_FOURCC ('Y', 'V', '1', '2'): + { + gint size; + GstFlowReturn result; + VdpStatus status; + guint8 *data[3]; + guint32 stride[3]; + + size = + gst_video_format_get_size (GST_VIDEO_FORMAT_YV12, video_yuv->width, + video_yuv->height); + result = + gst_pad_alloc_buffer_and_set_caps (video_yuv->src, + GST_BUFFER_OFFSET_NONE, size, GST_PAD_CAPS (video_yuv->src), &outbuf); + if (G_UNLIKELY (result != GST_FLOW_OK)) + return result; + + data[0] = GST_BUFFER_DATA (outbuf) + + gst_video_format_get_component_offset (GST_VIDEO_FORMAT_YV12, + 0, video_yuv->width, video_yuv->height); + data[1] = data[0] + + gst_video_format_get_component_offset (GST_VIDEO_FORMAT_YV12, + 2, video_yuv->width, video_yuv->height); + data[2] = data[0] + + gst_video_format_get_component_offset (GST_VIDEO_FORMAT_YV12, + 1, video_yuv->width, video_yuv->height); + + stride[0] = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_YV12, + 0, video_yuv->width); + stride[1] = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_YV12, + 2, video_yuv->width); + stride[2] = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_YV12, + 1, video_yuv->width); + + status = + device->vdp_video_surface_get_bits_ycbcr (surface, + VDP_YCBCR_FORMAT_YV12, (void *) data, stride); + if (G_UNLIKELY (status != VDP_STATUS_OK)) { + GST_ELEMENT_ERROR (video_yuv, RESOURCE, READ, + ("Couldn't get data from vdpau"), + ("Error returned from vdpau was: %s", + device->vdp_get_error_string (status))); + return GST_FLOW_ERROR; + } + break; + } + case GST_MAKE_FOURCC ('N', 'V', '1', '2'): + { + gint size; + GstFlowReturn result; + VdpStatus status; + guint8 *data[2]; + guint32 stride[2]; + + size = + video_yuv->width * video_yuv->height + + video_yuv->width * video_yuv->height / 2; + result = + gst_pad_alloc_buffer_and_set_caps (video_yuv->src, + GST_BUFFER_OFFSET_NONE, size, GST_PAD_CAPS (video_yuv->src), &outbuf); + if (G_UNLIKELY (result != GST_FLOW_OK)) + return result; + + + data[0] = GST_BUFFER_DATA (outbuf); + data[1] = GST_BUFFER_DATA (outbuf) + video_yuv->width * video_yuv->height; + + stride[0] = video_yuv->width; + stride[1] = video_yuv->width; + + status = + device->vdp_video_surface_get_bits_ycbcr (surface, + VDP_YCBCR_FORMAT_NV12, (void *) data, stride); + if (G_UNLIKELY (status != VDP_STATUS_OK)) { + GST_ELEMENT_ERROR (video_yuv, RESOURCE, READ, + ("Couldn't get data from vdpau"), + ("Error returned from vdpau was: %s", + device->vdp_get_error_string (status))); + return GST_FLOW_ERROR; + } + break; + } + default: + break; + } + + if (outbuf) { + gst_buffer_copy_metadata (outbuf, buffer, GST_BUFFER_COPY_TIMESTAMPS); + + return gst_pad_push (video_yuv->src, outbuf); + } + + return GST_FLOW_ERROR; +} + +typedef struct +{ + VdpChromaType chroma_type; + VdpYCbCrFormat format; + guint32 fourcc; +} VdpauFormats; + +static VdpauFormats formats[6] = { + { + VDP_CHROMA_TYPE_420, + VDP_YCBCR_FORMAT_NV12, + GST_MAKE_FOURCC ('N', 'V', '1', '2') + }, + { + VDP_CHROMA_TYPE_422, + VDP_YCBCR_FORMAT_UYVY, + GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y') + }, + { + VDP_CHROMA_TYPE_444, + VDP_YCBCR_FORMAT_V8U8Y8A8, + GST_MAKE_FOURCC ('A', 'Y', 'U', 'V') + }, + { + VDP_CHROMA_TYPE_444, + VDP_YCBCR_FORMAT_Y8U8V8A8, + GST_MAKE_FOURCC ('A', 'V', 'U', 'Y') + }, + { + VDP_CHROMA_TYPE_422, + VDP_YCBCR_FORMAT_YUYV, + GST_MAKE_FOURCC ('Y', 'U', 'Y', 'V') + }, + { + VDP_CHROMA_TYPE_420, + VDP_YCBCR_FORMAT_YV12, + GST_MAKE_FOURCC ('Y', 'V', '1', '2') + } +}; + +static GstCaps * +gst_vdpau_video_yuv_get_caps (GstVdpauVideoYUV * video_yuv, + GstVdpauDevice * device, gint chroma_type, gint width, gint height, + gint framerate_numerator, gint framerate_denominator, gint par_numerator, + gint par_denominator) +{ + GstCaps *caps; + gint i; + + caps = gst_caps_new_empty (); + + for (i = 0; i < 6; i++) { + VdpStatus status; + VdpBool is_supported; + + if (formats[i].chroma_type != chroma_type) + continue; + + status = + device->vdp_video_surface_query_ycbcr_capabilities (device->device, + chroma_type, formats[i].format, &is_supported); + if (status != VDP_STATUS_OK && status != VDP_STATUS_INVALID_Y_CB_CR_FORMAT) { + GST_ELEMENT_ERROR (video_yuv, RESOURCE, READ, + ("Could not query VDPAU YCbCr capabilites"), + ("Error returned from vdpau was: %s", + device->vdp_get_error_string (status))); + + return NULL; + } + if (is_supported) { + GstCaps *format_caps; + + format_caps = gst_caps_new_simple ("video/x-raw-yuv", + "format", GST_TYPE_FOURCC, formats[i].fourcc, + "width", G_TYPE_INT, width, + "height", G_TYPE_INT, height, + "framerate", GST_TYPE_FRACTION, framerate_numerator, + framerate_denominator, "pixel-aspect-ratio", GST_TYPE_FRACTION, + par_numerator, par_denominator, NULL); + gst_caps_append (caps, format_caps); + } + } + + if (gst_caps_is_empty (caps)) { + gst_caps_unref (caps); + return NULL; + } + + return caps; +} + +static gboolean +gst_vdpau_video_yuv_sink_set_caps (GstPad * pad, GstCaps * caps) +{ + GstVdpauVideoYUV *video_yuv = GST_VDPAU_VIDEO_YUV (GST_OBJECT_PARENT (pad)); + + GstCaps *src_caps, *new_caps; + GstStructure *structure; + const GValue *value; + GstVdpauDevice *device; + gint chroma_type; + gint width, height; + gint framerate_numerator, framerate_denominator; + gint par_numerator, par_denominator; + guint32 fourcc_format; + gboolean res; + + structure = gst_caps_get_structure (caps, 0); + value = gst_structure_get_value (structure, "device"); + device = g_value_get_object (value); + + gst_structure_get_int (structure, "chroma-type", &chroma_type); + gst_structure_get_int (structure, "width", &width); + gst_structure_get_int (structure, "height", &height); + gst_structure_get_fraction (structure, "framerate", + &framerate_numerator, &framerate_denominator); + gst_structure_get_fraction (structure, "pixel-aspect-ratio", + &par_numerator, &par_denominator); + + src_caps = + gst_vdpau_video_yuv_get_caps (video_yuv, device, chroma_type, width, + height, framerate_numerator, framerate_denominator, par_numerator, + par_denominator); + if (G_UNLIKELY (!src_caps)) + return FALSE; + + video_yuv->src_caps = src_caps; + + src_caps = gst_pad_get_allowed_caps (video_yuv->src); + if (G_UNLIKELY (!src_caps || !gst_caps_get_size (src_caps))) + return FALSE; + + new_caps = gst_caps_copy_nth (src_caps, 0); + gst_caps_unref (src_caps); + if (G_UNLIKELY (!new_caps)) + return FALSE; + + structure = gst_caps_get_structure (new_caps, 0); + gst_structure_get_fourcc (structure, "format", &fourcc_format); + + gst_pad_fixate_caps (video_yuv->src, new_caps); + res = gst_pad_set_caps (video_yuv->src, new_caps); + + gst_caps_unref (new_caps); + + if (G_UNLIKELY (!res)) + return FALSE; + + video_yuv->width = width; + video_yuv->height = height; + video_yuv->framerate_numerator = framerate_numerator; + video_yuv->framerate_denominator = framerate_denominator; + video_yuv->format = fourcc_format; + + return TRUE; +} + +static GstCaps * +gst_vdpau_video_yuv_src_getcaps (GstPad * pad) +{ + GstVdpauVideoYUV *video_yuv; + + video_yuv = GST_VDPAU_VIDEO_YUV (GST_OBJECT_PARENT (pad)); + + if (video_yuv->src_caps) + return gst_caps_copy (video_yuv->src_caps); + + if (GST_PAD_CAPS (video_yuv->src)) + return gst_caps_copy (GST_PAD_CAPS (video_yuv->src)); + + return gst_caps_copy (gst_pad_get_pad_template_caps (video_yuv->src)); +} + +/* GObject vmethod implementations */ + +static void +gst_vdpau_video_yuv_base_init (gpointer klass) +{ + GstElementClass *element_class = GST_ELEMENT_CLASS (klass); + + gst_element_class_set_details_simple (element_class, + "VdpauVideoYUV", + "Covideo_yuv/Decoder/Video", + "VDPAU video surface to YUV", + "Carl-Anton Ingmarsson "); + + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&sink_template)); + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&src_template)); +} + +static void +gst_vdpau_video_yuv_class_init (GstVdpauVideoYUVClass * klass) +{ + GObjectClass *gobject_class; + GstElementClass *gstelement_class; + + gobject_class = (GObjectClass *) klass; + gstelement_class = (GstElementClass *) klass; + + gobject_class->finalize = gst_vdpau_video_yuv_finalize; + gobject_class->set_property = gst_vdpau_video_yuv_set_property; + gobject_class->get_property = gst_vdpau_video_yuv_get_property; + + g_object_class_install_property (gobject_class, PROP_SILENT, + g_param_spec_boolean ("silent", "Silent", "Produce verbose output ?", + FALSE, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE)); +} + +static void +gst_vdpau_video_yuv_init (GstVdpauVideoYUV * video_yuv, + GstVdpauVideoYUVClass * klass) +{ + video_yuv->silent = FALSE; + video_yuv->src_caps = NULL; + + video_yuv->height = 0; + video_yuv->width = 0; + video_yuv->framerate_numerator = 0; + video_yuv->framerate_denominator = 0; + video_yuv->par_numerator = 1; + video_yuv->par_denominator = 1; + + video_yuv->src = gst_pad_new_from_static_template (&src_template, "src"); + gst_pad_set_getcaps_function (video_yuv->src, + gst_vdpau_video_yuv_src_getcaps); + gst_element_add_pad (GST_ELEMENT (video_yuv), video_yuv->src); + + video_yuv->sink = gst_pad_new_from_static_template (&sink_template, "sink"); + gst_pad_set_setcaps_function (video_yuv->sink, + gst_vdpau_video_yuv_sink_set_caps); + gst_pad_set_chain_function (video_yuv->sink, gst_vdpau_video_yuv_chain); + gst_element_add_pad (GST_ELEMENT (video_yuv), video_yuv->sink); +} + +static void +gst_vdpau_video_yuv_finalize (GObject * object) +{ + GstVdpauVideoYUV *video_yuv = (GstVdpauVideoYUV *) object; + + if (video_yuv->src_caps) + gst_caps_unref (video_yuv->src_caps); +} + +static void +gst_vdpau_video_yuv_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GstVdpauVideoYUV *video_yuv = GST_VDPAU_VIDEO_YUV (object); + + switch (prop_id) { + case PROP_SILENT: + video_yuv->silent = g_value_get_boolean (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_vdpau_video_yuv_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) +{ + GstVdpauVideoYUV *video_yuv = GST_VDPAU_VIDEO_YUV (object); + + switch (prop_id) { + case PROP_SILENT: + g_value_set_boolean (value, video_yuv->silent); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} diff --git a/sys/vdpau/gstvdpauvideoyuv.h b/sys/vdpau/gstvdpauvideoyuv.h new file mode 100644 index 00000000..dd033df7 --- /dev/null +++ b/sys/vdpau/gstvdpauvideoyuv.h @@ -0,0 +1,62 @@ +/* + * GStreamer + * Copyright (C) 2009 Carl-Anton Ingmarsson + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GST_VDPAU_VIDEO_YUV_H__ +#define __GST_VDPAU_VIDEO_YUV_H__ + +#include + +#include "gstvdpaudevice.h" + +G_BEGIN_DECLS + +#define GST_TYPE_VDPAU_VIDEO_YUV (gst_vdpau_video_yuv_get_type()) +#define GST_VDPAU_VIDEO_YUV(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VDPAU_VIDEO_YUV,GstVdpauVideoYUV)) +#define GST_VDPAU_VIDEO_YUV_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VDPAU_VIDEO_YUV,GstVdpauVideoYUVClass)) +#define GST_VDPAU_VIDEO_YUV_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VDPAU_VIDEO_YUV, GstVdpauVideoYUVClass)) +#define GST_IS_VDPAU_VIDEO_YUV(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VDPAU_VIDEO_YUV)) +#define GST_IS_VDPAU_VIDEO_YUV_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VDPAU_VIDEO_YUV)) + +typedef struct _GstVdpauVideoYUV GstVdpauVideoYUV; +typedef struct _GstVdpauVideoYUVClass GstVdpauVideoYUVClass; + +struct _GstVdpauVideoYUV { + GstElement element; + + GstPad *src, *sink; + GstCaps *src_caps; + + gint width, height; + gint framerate_numerator, framerate_denominator; + gint par_numerator, par_denominator; + guint format; + + gboolean silent; +}; + +struct _GstVdpauVideoYUVClass { + GstElementClass parent_class; +}; + +GType gst_vdpau_video_yuv_get_type (void); + +G_END_DECLS + +#endif /* __GST_VDPAU_VIDEO_YUV_H__ */ -- cgit v1.2.1 From 3d4a340cfa134615164af6a93b7ce9d36b84f191 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Sat, 4 Apr 2009 22:03:23 +0200 Subject: vdpau: move plugin definition to a new gstvdpau.c file fix up debug categories --- sys/vdpau/Makefile.am | 3 ++- sys/vdpau/gstvdpau.c | 25 +++++++++++++++++++++++++ sys/vdpau/gstvdpaudecoder.h | 3 ++- sys/vdpau/gstvdpaumpegdecoder.c | 40 +++++----------------------------------- sys/vdpau/gstvdpauvideoyuv.c | 2 +- 5 files changed, 35 insertions(+), 38 deletions(-) create mode 100644 sys/vdpau/gstvdpau.c (limited to 'sys') diff --git a/sys/vdpau/Makefile.am b/sys/vdpau/Makefile.am index ba286d54..0b7e5e5c 100644 --- a/sys/vdpau/Makefile.am +++ b/sys/vdpau/Makefile.am @@ -6,7 +6,8 @@ libgstvdpau_la_SOURCES = \ gstvdpaumpegdecoder.c \ mpegutil.c \ gstvdpauvideoyuv.c \ - gstvdpauvideobuffer.c + gstvdpauvideobuffer.c \ + gstvdpau.c libgstvdpau_la_CFLAGS = $(GST_CFLAGS) $(X11_CFLAGS) -Ivdpau libgstvdpau_la_LIBADD = $(GST_LIBS) $(GST_BASE_LIBS) \ diff --git a/sys/vdpau/gstvdpau.c b/sys/vdpau/gstvdpau.c new file mode 100644 index 00000000..04a0ef5b --- /dev/null +++ b/sys/vdpau/gstvdpau.c @@ -0,0 +1,25 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + + +#include + +#include "gstvdpaumpegdecoder.h" +#include "gstvdpauvideoyuv.h" +static gboolean +vdpau_init (GstPlugin * vdpaumpegdecoder) +{ + gst_element_register (vdpaumpegdecoder, "vdpaumpegdecoder", + GST_RANK_NONE, GST_TYPE_VDPAU_MPEG_DECODER); + gst_element_register (vdpaumpegdecoder, "vdpauvideoyuv", + GST_RANK_NONE, GST_TYPE_VDPAU_VIDEO_YUV); + + return TRUE; +} + +GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, + GST_VERSION_MINOR, + "vdpau", + "Various elements utilizing VDPAU", + vdpau_init, VERSION, "LGPL", "GStreamer", "http://gstreamer.net/") diff --git a/sys/vdpau/gstvdpaudecoder.h b/sys/vdpau/gstvdpaudecoder.h index ef3a6fb9..3f67da68 100644 --- a/sys/vdpau/gstvdpaudecoder.h +++ b/sys/vdpau/gstvdpaudecoder.h @@ -24,6 +24,7 @@ #include #include "gstvdpaudevice.h" +#include "gstvdpauvideobuffer.h" G_BEGIN_DECLS @@ -65,7 +66,7 @@ struct _GstVdpauDecoderClass { GType gst_vdpau_decoder_get_type (void); gboolean gst_vdpau_decoder_push_video_buffer (GstVdpauDecoder * dec, - GstVdpauVideoBuffer *buffer); + GstVdpauVideoBuffer *buffer); VdpVideoSurface gst_vdpau_decoder_create_video_surface (GstVdpauDecoder *dec); G_END_DECLS diff --git a/sys/vdpau/gstvdpaumpegdecoder.c b/sys/vdpau/gstvdpaumpegdecoder.c index 80ee13ca..1c51389c 100644 --- a/sys/vdpau/gstvdpaumpegdecoder.c +++ b/sys/vdpau/gstvdpaumpegdecoder.c @@ -70,8 +70,11 @@ static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink", "systemstream = (boolean) false, parsed = (boolean) true") ); -GST_BOILERPLATE (GstVdpauMpegDecoder, gst_vdpau_mpeg_decoder, GstVdpauDecoder, - GST_TYPE_VDPAU_DECODER); +#define DEBUG_INIT(bla) \ +GST_DEBUG_CATEGORY_INIT (gst_vdpau_mpeg_decoder_debug, "vdpaumpegdecoder", 0, "VDPAU powered mpeg decoder"); + +GST_BOILERPLATE_FULL (GstVdpauMpegDecoder, gst_vdpau_mpeg_decoder, + GstVdpauDecoder, GST_TYPE_VDPAU_DECODER, DEBUG_INIT); static void gst_vdpau_mpeg_decoder_finalize (GObject * object); static void gst_vdpau_mpeg_decoder_set_property (GObject * object, @@ -457,36 +460,3 @@ gst_vdpau_mpeg_decoder_get_property (GObject * object, guint prop_id, break; } } - -/* entry point to initialize the plug-in - * initialize the plug-in itself - * register the element factories and other features - */ -static gboolean -vdpaumpegdecoder_init (GstPlugin * vdpaumpegdecoder) -{ - /* debug category for fltering log messages - * - * exchange the string 'Template vdpaumpegdecoder' with your description - */ - GST_DEBUG_CATEGORY_INIT (gst_vdpau_mpeg_decoder_debug, "vdpaumpegdecoder", - 0, "Template vdpaumpegdecoder"); - - gst_element_register (vdpaumpegdecoder, "vdpaumpegdecoder", - GST_RANK_NONE, GST_TYPE_VDPAU_MPEG_DECODER); - gst_element_register (vdpaumpegdecoder, "vdpauvideoyuv", - GST_RANK_NONE, GST_TYPE_VDPAU_VIDEO_YUV); - - return TRUE; -} - -/* gstreamer looks for this structure to register vdpaumpegdecoders - * - * exchange the string 'Template vdpaumpegdecoder' with your vdpaumpegdecoder description - */ -GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, - GST_VERSION_MINOR, - "vdpaumpegdecoder", - "Template vdpaumpegdecoder", - vdpaumpegdecoder_init, - VERSION, "LGPL", "GStreamer", "http://gstreamer.net/") diff --git a/sys/vdpau/gstvdpauvideoyuv.c b/sys/vdpau/gstvdpauvideoyuv.c index 1de17045..b9be10c1 100644 --- a/sys/vdpau/gstvdpauvideoyuv.c +++ b/sys/vdpau/gstvdpauvideoyuv.c @@ -57,7 +57,7 @@ static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src", "width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ]")); #define DEBUG_INIT(bla) \ - GST_DEBUG_CATEGORY_INIT (gst_vdpau_video_yuv_debug, "vdpauvideo_yuv", 0, "vdpauvideo_yuv base class"); + GST_DEBUG_CATEGORY_INIT (gst_vdpau_video_yuv_debug, "vdpauvideoyuv", 0, "VDPAU VdpSurface to YUV"); GST_BOILERPLATE_FULL (GstVdpauVideoYUV, gst_vdpau_video_yuv, GstElement, GST_TYPE_ELEMENT, DEBUG_INIT); -- cgit v1.2.1 From 17a758ec7129976fa910b6ca0d8fd3d19c815158 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Sat, 4 Apr 2009 22:05:11 +0200 Subject: vdpau: remove some unneded includes --- sys/vdpau/gstvdpaudecoder.c | 1 - sys/vdpau/gstvdpaumpegdecoder.c | 2 -- 2 files changed, 3 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpaudecoder.c b/sys/vdpau/gstvdpaudecoder.c index 4db93f7e..3d0ced34 100644 --- a/sys/vdpau/gstvdpaudecoder.c +++ b/sys/vdpau/gstvdpaudecoder.c @@ -25,7 +25,6 @@ #include #include -#include "gstvdpauvideobuffer.h" #include "gstvdpaudecoder.h" GST_DEBUG_CATEGORY_STATIC (gst_vdpau_decoder_debug); diff --git a/sys/vdpau/gstvdpaumpegdecoder.c b/sys/vdpau/gstvdpaumpegdecoder.c index 1c51389c..36b546ac 100644 --- a/sys/vdpau/gstvdpaumpegdecoder.c +++ b/sys/vdpau/gstvdpaumpegdecoder.c @@ -38,8 +38,6 @@ #include #include -#include "gstvdpauvideobuffer.h" -#include "gstvdpauvideoyuv.h" #include "mpegutil.h" #include "gstvdpaumpegdecoder.h" -- cgit v1.2.1 From 74485f6fa28ac3413ca5533f7bee695ab7670b47 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Sat, 4 Apr 2009 22:45:09 +0200 Subject: vdpau: VideoYUV unref buffer in chain so that we don't leak them MpegDecoder parse sequence headers --- sys/vdpau/gstvdpaumpegdecoder.c | 28 ++++++++++++++++++++++++++-- sys/vdpau/gstvdpauvideoyuv.c | 6 ++++-- 2 files changed, 30 insertions(+), 4 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpaumpegdecoder.c b/sys/vdpau/gstvdpaumpegdecoder.c index 36b546ac..1910652c 100644 --- a/sys/vdpau/gstvdpaumpegdecoder.c +++ b/sys/vdpau/gstvdpaumpegdecoder.c @@ -141,6 +141,7 @@ gst_vdpau_mpeg_decoder_decode (GstVdpauMpegDecoder * mpeg_dec) GstVdpauDevice *device; VdpBitstreamBuffer vbit[1]; VdpStatus status; + GstFlowReturn ret; dec = GST_VDPAU_DECODER (mpeg_dec); @@ -178,14 +179,16 @@ gst_vdpau_mpeg_decoder_decode (GstVdpauMpegDecoder * mpeg_dec) gst_buffer_ref (GST_BUFFER (outbuf)); + ret = gst_vdpau_decoder_push_video_buffer (GST_VDPAU_DECODER (mpeg_dec), + outbuf); + if (mpeg_dec->vdp_info.forward_reference != VDP_INVALID_HANDLE) gst_buffer_unref (mpeg_dec->f_buffer); mpeg_dec->vdp_info.forward_reference = surface; mpeg_dec->f_buffer = GST_BUFFER (outbuf); - return gst_vdpau_decoder_push_video_buffer (GST_VDPAU_DECODER (mpeg_dec), - outbuf); + return ret; } static gboolean @@ -215,6 +218,26 @@ gst_vdpau_mpeg_decoder_parse_picture_coding (GstVdpauMpegDecoder * mpeg_dec, return TRUE; } +static gboolean +gst_vdpau_mpeg_decoder_parse_sequence (GstVdpauMpegDecoder * mpeg_dec, + guint8 * data, guint8 * end) +{ + GstVdpauDecoder *dec; + MPEGSeqHdr hdr; + + dec = GST_VDPAU_DECODER (mpeg_dec); + + if (!mpeg_util_parse_sequence_hdr (&hdr, data, end)) + return FALSE; + + memcpy (&mpeg_dec->vdp_info.intra_quantizer_matrix, + &hdr.intra_quantizer_matrix, 64); + memcpy (&mpeg_dec->vdp_info.non_intra_quantizer_matrix, + &hdr.non_intra_quantizer_matrix, 64); + + return TRUE; +} + static gboolean gst_vdpau_mpeg_decoder_parse_picture (GstVdpauMpegDecoder * mpeg_dec, guint8 * data, guint8 * end) @@ -320,6 +343,7 @@ gst_vdpau_mpeg_decoder_chain (GstPad * pad, GstBuffer * buffer) break; case MPEG_PACKET_SEQUENCE: GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_SEQUENCE"); + gst_vdpau_mpeg_decoder_parse_sequence (mpeg_dec, data, end); break; case MPEG_PACKET_EXTENSION: GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_EXTENSION"); diff --git a/sys/vdpau/gstvdpauvideoyuv.c b/sys/vdpau/gstvdpauvideoyuv.c index b9be10c1..ca1ec803 100644 --- a/sys/vdpau/gstvdpauvideoyuv.c +++ b/sys/vdpau/gstvdpauvideoyuv.c @@ -123,7 +123,7 @@ gst_vdpau_video_yuv_chain (GstPad * pad, GstBuffer * buffer) ("Couldn't get data from vdpau"), ("Error returned from vdpau was: %s", device->vdp_get_error_string (status))); - return GST_FLOW_ERROR; + break; } break; } @@ -159,7 +159,7 @@ gst_vdpau_video_yuv_chain (GstPad * pad, GstBuffer * buffer) ("Couldn't get data from vdpau"), ("Error returned from vdpau was: %s", device->vdp_get_error_string (status))); - return GST_FLOW_ERROR; + break; } break; } @@ -167,6 +167,8 @@ gst_vdpau_video_yuv_chain (GstPad * pad, GstBuffer * buffer) break; } + gst_buffer_unref (buffer); + if (outbuf) { gst_buffer_copy_metadata (outbuf, buffer, GST_BUFFER_COPY_TIMESTAMPS); -- cgit v1.2.1 From f8e0c0bcc11735e14636c7ea45fd23253e6cef99 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Tue, 7 Apr 2009 20:46:49 +0200 Subject: vdpau: add new GstVdpauYUVVideo element the GstVdpauYUVVideo element takes raw YUV video and outputs GstVdpauVideoBuffers --- sys/vdpau/Makefile.am | 6 +- sys/vdpau/gstvdpau.c | 4 + sys/vdpau/gstvdpaudevice.c | 6 + sys/vdpau/gstvdpaudevice.h | 1 + sys/vdpau/gstvdpauvideoyuv.c | 1 + sys/vdpau/gstvdpauyuvvideo.c | 537 +++++++++++++++++++++++++++++++++++++++++++ sys/vdpau/gstvdpauyuvvideo.h | 64 ++++++ 7 files changed, 617 insertions(+), 2 deletions(-) create mode 100644 sys/vdpau/gstvdpauyuvvideo.c create mode 100644 sys/vdpau/gstvdpauyuvvideo.h (limited to 'sys') diff --git a/sys/vdpau/Makefile.am b/sys/vdpau/Makefile.am index 0b7e5e5c..f10cae89 100644 --- a/sys/vdpau/Makefile.am +++ b/sys/vdpau/Makefile.am @@ -7,7 +7,8 @@ libgstvdpau_la_SOURCES = \ mpegutil.c \ gstvdpauvideoyuv.c \ gstvdpauvideobuffer.c \ - gstvdpau.c + gstvdpau.c \ + gstvdpauyuvvideo.c libgstvdpau_la_CFLAGS = $(GST_CFLAGS) $(X11_CFLAGS) -Ivdpau libgstvdpau_la_LIBADD = $(GST_LIBS) $(GST_BASE_LIBS) \ @@ -19,8 +20,9 @@ noinst_HEADERS = \ gstvdpaudevice.h \ gstvdpaudecoder.h \ gstvdpaumpegdecoder.h \ + mpegutil.h \ gstvdpauvideoyuv.h \ gstvdpauvideobuffer.h \ - mpegutil.h + gstvdpauyuvvideo.h diff --git a/sys/vdpau/gstvdpau.c b/sys/vdpau/gstvdpau.c index 04a0ef5b..24ed3982 100644 --- a/sys/vdpau/gstvdpau.c +++ b/sys/vdpau/gstvdpau.c @@ -7,6 +7,8 @@ #include "gstvdpaumpegdecoder.h" #include "gstvdpauvideoyuv.h" +#include "gstvdpauyuvvideo.h" + static gboolean vdpau_init (GstPlugin * vdpaumpegdecoder) { @@ -14,6 +16,8 @@ vdpau_init (GstPlugin * vdpaumpegdecoder) GST_RANK_NONE, GST_TYPE_VDPAU_MPEG_DECODER); gst_element_register (vdpaumpegdecoder, "vdpauvideoyuv", GST_RANK_NONE, GST_TYPE_VDPAU_VIDEO_YUV); + gst_element_register (vdpaumpegdecoder, "vdpauyuvvideo", + GST_RANK_NONE, GST_TYPE_VDPAU_YUV_VIDEO); return TRUE; } diff --git a/sys/vdpau/gstvdpaudevice.c b/sys/vdpau/gstvdpaudevice.c index 8e314d6d..73929444 100644 --- a/sys/vdpau/gstvdpaudevice.c +++ b/sys/vdpau/gstvdpaudevice.c @@ -83,6 +83,8 @@ gst_vdpau_device_constructed (GObject * object) &device->vdp_video_surface_query_ycbcr_capabilities}, {VDP_FUNC_ID_VIDEO_SURFACE_GET_BITS_Y_CB_CR, &device->vdp_video_surface_get_bits_ycbcr}, + {VDP_FUNC_ID_VIDEO_SURFACE_PUT_BITS_Y_CB_CR, + &device->vdp_video_surface_put_bits_ycbcr}, {VDP_FUNC_ID_VIDEO_SURFACE_GET_PARAMETERS, &device->vdp_video_surface_get_parameters}, {VDP_FUNC_ID_DECODER_CREATE, &device->vdp_decoder_create}, @@ -257,6 +259,10 @@ gst_vdpau_get_device (const gchar * display_name) if (!device) { device = gst_vdpau_device_new (display_name); g_object_weak_ref (G_OBJECT (device), device_destroyed_cb, devices_hash); + if (display_name) + g_hash_table_insert (devices_hash, g_strdup (display_name), device); + else + g_hash_table_insert (devices_hash, g_strdup (""), device); } else g_object_ref (device); diff --git a/sys/vdpau/gstvdpaudevice.h b/sys/vdpau/gstvdpaudevice.h index 0a5cb5e7..a4d147c4 100644 --- a/sys/vdpau/gstvdpaudevice.h +++ b/sys/vdpau/gstvdpaudevice.h @@ -61,6 +61,7 @@ struct _GstVdpauDevice VdpVideoSurfaceQueryGetPutBitsYCbCrCapabilities *vdp_video_surface_query_ycbcr_capabilities; VdpVideoSurfaceGetParameters *vdp_video_surface_get_parameters; VdpVideoSurfaceGetBitsYCbCr *vdp_video_surface_get_bits_ycbcr; + VdpVideoSurfacePutBitsYCbCr *vdp_video_surface_put_bits_ycbcr; VdpDecoderCreate *vdp_decoder_create; VdpDecoderDestroy *vdp_decoder_destroy; diff --git a/sys/vdpau/gstvdpauvideoyuv.c b/sys/vdpau/gstvdpauvideoyuv.c index ca1ec803..7b2e7677 100644 --- a/sys/vdpau/gstvdpauvideoyuv.c +++ b/sys/vdpau/gstvdpauvideoyuv.c @@ -412,6 +412,7 @@ gst_vdpau_video_yuv_init (GstVdpauVideoYUV * video_yuv, gst_vdpau_video_yuv_sink_set_caps); gst_pad_set_chain_function (video_yuv->sink, gst_vdpau_video_yuv_chain); gst_element_add_pad (GST_ELEMENT (video_yuv), video_yuv->sink); + gst_pad_set_active (video_yuv->sink, TRUE); } static void diff --git a/sys/vdpau/gstvdpauyuvvideo.c b/sys/vdpau/gstvdpauyuvvideo.c new file mode 100644 index 00000000..4d78bae2 --- /dev/null +++ b/sys/vdpau/gstvdpauyuvvideo.c @@ -0,0 +1,537 @@ +/* + * GStreamer + * Copyright (C) 2009 Carl-Anton Ingmarsson + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#include "gstvdpauvideobuffer.h" +#include "gstvdpauyuvvideo.h" + +GST_DEBUG_CATEGORY_STATIC (gst_vdpau_yuv_video_debug); +#define GST_CAT_DEFAULT gst_vdpau_yuv_video_debug + +/* Filter signals and args */ +enum +{ + /* FILL ME */ + LAST_SIGNAL +}; + +enum +{ + PROP_0, + PROP_DISPLAY, + PROP_SILENT +}; + +static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS ("video/x-raw-yuv, " + "framerate = (fraction) [ 0, MAX ], " + "width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ]")); + +static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS (GST_VDPAU_VIDEO_CAPS)); + +#define DEBUG_INIT(bla) \ + GST_DEBUG_CATEGORY_INIT (gst_vdpau_yuv_video_debug, "vdpauvideoyuv", 0, "YUV to VDPAU video surface"); + +GST_BOILERPLATE_FULL (GstVdpauYUVVideo, gst_vdpau_yuv_video, GstElement, + GST_TYPE_ELEMENT, DEBUG_INIT); + +static void gst_vdpau_yuv_video_finalize (GObject * object); +static void gst_vdpau_yuv_video_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec); +static void gst_vdpau_yuv_video_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec); + +GstFlowReturn +gst_vdpau_yuv_video_chain (GstPad * pad, GstBuffer * buffer) +{ + GstVdpauYUVVideo *yuv_video; + GstVdpauDevice *device; + VdpVideoSurface surface; + GstBuffer *outbuf = NULL; + + yuv_video = GST_VDPAU_YUV_VIDEO (GST_OBJECT_PARENT (pad)); + device = yuv_video->device; + + outbuf = + GST_BUFFER (gst_vdpau_video_buffer_new (device, yuv_video->chroma_type, + yuv_video->width, yuv_video->height)); + surface = GST_VDPAU_VIDEO_BUFFER (outbuf)->surface; + + switch (yuv_video->format) { + case GST_MAKE_FOURCC ('Y', 'V', '1', '2'): + { + VdpStatus status; + guint8 *data[3]; + guint32 stride[3]; + + data[0] = GST_BUFFER_DATA (buffer) + + gst_video_format_get_component_offset (GST_VIDEO_FORMAT_YV12, + 0, yuv_video->width, yuv_video->height); + data[1] = data[0] + + gst_video_format_get_component_offset (GST_VIDEO_FORMAT_YV12, + 2, yuv_video->width, yuv_video->height); + data[2] = data[0] + + gst_video_format_get_component_offset (GST_VIDEO_FORMAT_YV12, + 1, yuv_video->width, yuv_video->height); + + stride[0] = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_YV12, + 0, yuv_video->width); + stride[1] = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_YV12, + 2, yuv_video->width); + stride[2] = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_YV12, + 1, yuv_video->width); + + status = + device->vdp_video_surface_put_bits_ycbcr (surface, + VDP_YCBCR_FORMAT_YV12, (void *) data, stride); + if (G_UNLIKELY (status != VDP_STATUS_OK)) { + GST_ELEMENT_ERROR (yuv_video, RESOURCE, READ, + ("Couldn't push YV12 data to VDPAU"), + ("Error returned from vdpau was: %s", + device->vdp_get_error_string (status))); + break; + } + break; + } + case GST_MAKE_FOURCC ('I', '4', '2', '0'): + { + VdpStatus status; + guint8 *data[3]; + guint32 stride[3]; + + data[0] = GST_BUFFER_DATA (buffer) + + gst_video_format_get_component_offset (GST_VIDEO_FORMAT_I420, + 0, yuv_video->width, yuv_video->height); + data[1] = GST_BUFFER_DATA (buffer) + + gst_video_format_get_component_offset (GST_VIDEO_FORMAT_I420, + 2, yuv_video->width, yuv_video->height); + data[2] = GST_BUFFER_DATA (buffer) + + gst_video_format_get_component_offset (GST_VIDEO_FORMAT_I420, + 1, yuv_video->width, yuv_video->height); + + stride[0] = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_I420, + 0, yuv_video->width); + stride[1] = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_I420, + 2, yuv_video->width); + stride[2] = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_I420, + 1, yuv_video->width); + + status = + device->vdp_video_surface_put_bits_ycbcr (surface, + VDP_YCBCR_FORMAT_YV12, (void *) data, stride); + if (G_UNLIKELY (status != VDP_STATUS_OK)) { + GST_ELEMENT_ERROR (yuv_video, RESOURCE, READ, + ("Couldn't push YV12 data to VDPAU"), + ("Error returned from vdpau was: %s", + device->vdp_get_error_string (status))); + break; + } + break; + } + case GST_MAKE_FOURCC ('N', 'V', '1', '2'): + { + VdpStatus status; + guint8 *data[2]; + guint32 stride[2]; + + data[0] = GST_BUFFER_DATA (buffer); + data[1] = GST_BUFFER_DATA (buffer) + yuv_video->width * yuv_video->height; + + stride[0] = yuv_video->width; + stride[1] = yuv_video->width; + + status = + device->vdp_video_surface_put_bits_ycbcr (surface, + VDP_YCBCR_FORMAT_NV12, (void *) data, stride); + if (G_UNLIKELY (status != VDP_STATUS_OK)) { + GST_ELEMENT_ERROR (yuv_video, RESOURCE, READ, + ("Couldn't get data from vdpau"), + ("Error returned from vdpau was: %s", + device->vdp_get_error_string (status))); + break; + } + break; + } + default: + break; + } + + gst_buffer_unref (buffer); + + if (outbuf) { + gst_buffer_copy_metadata (outbuf, buffer, GST_BUFFER_COPY_TIMESTAMPS); + gst_buffer_set_caps (outbuf, GST_PAD_CAPS (yuv_video->src)); + + return gst_pad_push (yuv_video->src, outbuf); + } + + return GST_FLOW_ERROR; +} + +typedef struct +{ + VdpChromaType chroma_type; + VdpYCbCrFormat format; + guint32 fourcc; +} VdpauFormats; + +static VdpChromaType chroma_types[3] = + { VDP_CHROMA_TYPE_420, VDP_CHROMA_TYPE_422, VDP_CHROMA_TYPE_444 }; +static VdpauFormats formats[7] = { + { + VDP_CHROMA_TYPE_420, + VDP_YCBCR_FORMAT_NV12, + GST_MAKE_FOURCC ('N', 'V', '1', '2') + }, + { + VDP_CHROMA_TYPE_422, + VDP_YCBCR_FORMAT_UYVY, + GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y') + }, + { + VDP_CHROMA_TYPE_444, + VDP_YCBCR_FORMAT_V8U8Y8A8, + GST_MAKE_FOURCC ('A', 'Y', 'U', 'V') + }, + { + VDP_CHROMA_TYPE_444, + VDP_YCBCR_FORMAT_Y8U8V8A8, + GST_MAKE_FOURCC ('A', 'V', 'U', 'Y') + }, + { + VDP_CHROMA_TYPE_422, + VDP_YCBCR_FORMAT_YUYV, + GST_MAKE_FOURCC ('Y', 'U', 'Y', 'V') + }, + { + VDP_CHROMA_TYPE_420, + VDP_YCBCR_FORMAT_YV12, + GST_MAKE_FOURCC ('Y', 'V', '1', '2') + }, + { + VDP_CHROMA_TYPE_420, + VDP_YCBCR_FORMAT_YV12, + GST_MAKE_FOURCC ('I', '4', '2', '0') + } +}; + +static GstCaps * +gst_vdpau_yuv_video_get_caps (GstVdpauYUVVideo * yuv_video) +{ + GstVdpauDevice *device; + GstCaps *caps; + gint i; + + device = yuv_video->device; + + caps = gst_caps_new_empty (); + + for (i = 0; i < 3; i++) { + VdpStatus status; + VdpBool is_supported; + guint32 max_w, max_h; + + status = + device->vdp_video_surface_query_capabilities (device->device, + chroma_types[i], &is_supported, &max_w, &max_h); + + if (status != VDP_STATUS_OK && status != VDP_STATUS_INVALID_CHROMA_TYPE) { + GST_ELEMENT_ERROR (yuv_video, RESOURCE, READ, + ("Could not get query VDPAU video surface capabilites"), + ("Error returned from vdpau was: %s", + device->vdp_get_error_string (status))); + + goto error; + } + if (is_supported) { + gint j; + + for (j = 0; j < 7; j++) { + if (formats[j].chroma_type != chroma_types[i]) + continue; + + status = + device->vdp_video_surface_query_ycbcr_capabilities (device->device, + formats[j].chroma_type, formats[j].format, &is_supported); + if (status != VDP_STATUS_OK + && status != VDP_STATUS_INVALID_Y_CB_CR_FORMAT) { + GST_ELEMENT_ERROR (yuv_video, RESOURCE, READ, + ("Could not query VDPAU YCbCr capabilites"), + ("Error returned from vdpau was: %s", + device->vdp_get_error_string (status))); + + goto error; + } + if (is_supported) { + GstCaps *format_caps; + + format_caps = gst_caps_new_simple ("video/x-raw-yuv", + "format", GST_TYPE_FOURCC, formats[j].fourcc, + "width", GST_TYPE_INT_RANGE, 1, max_w, + "height", GST_TYPE_INT_RANGE, 1, max_h, + "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL); + gst_caps_append (caps, format_caps); + } + } + } + } +error: + if (gst_caps_is_empty (caps)) { + gst_caps_unref (caps); + return NULL; + } + + return caps; +} + +static gboolean +gst_vdpau_yuv_video_sink_setcaps (GstPad * pad, GstCaps * caps) +{ + GstVdpauYUVVideo *yuv_video = GST_VDPAU_YUV_VIDEO (GST_OBJECT_PARENT (pad)); + + GstStructure *structure; + guint32 fourcc; + gint chroma_type = 0; + gint width, height; + gint framerate_numerator, framerate_denominator; + gint par_numerator, par_denominator; + gint i; + GstCaps *src_caps, *new_caps; + gboolean res; + + structure = gst_caps_get_structure (caps, 0); + + gst_structure_get_fourcc (structure, "format", &fourcc); + gst_structure_get_int (structure, "width", &width); + gst_structure_get_int (structure, "height", &height); + gst_structure_get_fraction (structure, "framerate", + &framerate_numerator, &framerate_denominator); + gst_structure_get_fraction (structure, "pixel-aspect-ratio", + &par_numerator, &par_denominator); + + for (i = 0; i < 7; i++) { + if (formats[i].fourcc == fourcc) { + chroma_type = formats[i].chroma_type; + break; + } + } + + src_caps = gst_pad_get_allowed_caps (yuv_video->src); + if (G_UNLIKELY (!src_caps || !gst_caps_get_size (src_caps))) + return FALSE; + + new_caps = gst_caps_copy_nth (src_caps, 0); + gst_caps_unref (src_caps); + if (G_UNLIKELY (!new_caps)) + return FALSE; + + structure = gst_caps_get_structure (new_caps, 0); + + gst_structure_set (structure, + "device", G_TYPE_OBJECT, yuv_video->device, + "chroma-type", G_TYPE_INT, chroma_type, + "width", G_TYPE_INT, width, + "height", G_TYPE_INT, height, + "framerate", GST_TYPE_FRACTION, framerate_numerator, + framerate_denominator, "pixel-aspect-ratio", GST_TYPE_FRACTION, + par_numerator, par_denominator, NULL); + + gst_pad_fixate_caps (yuv_video->src, new_caps); + res = gst_pad_set_caps (yuv_video->src, new_caps); + + gst_caps_unref (new_caps); + + if (G_UNLIKELY (!res)) + return FALSE; + + yuv_video->width = width; + yuv_video->height = height; + yuv_video->format = fourcc; + yuv_video->chroma_type = chroma_type; + + return TRUE; +} + +static GstCaps * +gst_vdpau_yuv_video_sink_getcaps (GstPad * pad) +{ + GstVdpauYUVVideo *yuv_video; + + yuv_video = GST_VDPAU_YUV_VIDEO (GST_OBJECT_PARENT (pad)); + + if (yuv_video->sink_caps) + return gst_caps_copy (yuv_video->sink_caps); + + return gst_caps_copy (gst_pad_get_pad_template_caps (yuv_video->sink)); +} + +static GstStateChangeReturn +gst_vdpau_yuv_video_change_state (GstElement * element, + GstStateChange transition) +{ + GstVdpauYUVVideo *yuv_video; + + yuv_video = GST_VDPAU_YUV_VIDEO (element); + + switch (transition) { + case GST_STATE_CHANGE_NULL_TO_READY: + yuv_video->device = gst_vdpau_get_device (yuv_video->display); + if (!yuv_video->sink_caps) + yuv_video->sink_caps = gst_vdpau_yuv_video_get_caps (yuv_video); + break; + case GST_STATE_CHANGE_READY_TO_NULL: + g_object_unref (yuv_video->device); + yuv_video->device = NULL; + break; + default: + break; + } + + return GST_STATE_CHANGE_SUCCESS; +} + +/* GObject vmethod implementations */ + +static void +gst_vdpau_yuv_video_base_init (gpointer klass) +{ + GstElementClass *element_class = GST_ELEMENT_CLASS (klass); + + gst_element_class_set_details_simple (element_class, + "VdpauYUVVideo", + "Coyuv_video/Decoder/Video", + "VDPAU video surface to YUV", + "Carl-Anton Ingmarsson "); + + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&sink_template)); + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&src_template)); +} + +static void +gst_vdpau_yuv_video_class_init (GstVdpauYUVVideoClass * klass) +{ + GObjectClass *gobject_class; + GstElementClass *gstelement_class; + + gobject_class = (GObjectClass *) klass; + gstelement_class = (GstElementClass *) klass; + + gobject_class->finalize = gst_vdpau_yuv_video_finalize; + gobject_class->set_property = gst_vdpau_yuv_video_set_property; + gobject_class->get_property = gst_vdpau_yuv_video_get_property; + + g_object_class_install_property (gobject_class, PROP_DISPLAY, + g_param_spec_string ("display", "Display", "X Display name", + NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + + g_object_class_install_property (gobject_class, PROP_SILENT, + g_param_spec_boolean ("silent", "Silent", "Produce verbose output ?", + FALSE, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE)); + + gstelement_class->change_state = gst_vdpau_yuv_video_change_state; +} + +static void +gst_vdpau_yuv_video_init (GstVdpauYUVVideo * yuv_video, + GstVdpauYUVVideoClass * klass) +{ + yuv_video->silent = FALSE; + yuv_video->sink_caps = NULL; + + yuv_video->display = NULL; + yuv_video->device = NULL; + + yuv_video->height = 0; + yuv_video->width = 0; + yuv_video->format = 0; + yuv_video->chroma_type = 0; + + yuv_video->src = gst_pad_new_from_static_template (&src_template, "src"); + gst_element_add_pad (GST_ELEMENT (yuv_video), yuv_video->src); + + yuv_video->sink = gst_pad_new_from_static_template (&sink_template, "sink"); + gst_pad_set_getcaps_function (yuv_video->sink, + gst_vdpau_yuv_video_sink_getcaps); + gst_pad_set_setcaps_function (yuv_video->sink, + gst_vdpau_yuv_video_sink_setcaps); + gst_pad_set_chain_function (yuv_video->sink, gst_vdpau_yuv_video_chain); + gst_element_add_pad (GST_ELEMENT (yuv_video), yuv_video->sink); + gst_pad_set_active (yuv_video->sink, TRUE); +} + +static void +gst_vdpau_yuv_video_finalize (GObject * object) +{ + GstVdpauYUVVideo *yuv_video = (GstVdpauYUVVideo *) object; + + g_free (yuv_video->display); +} + +static void +gst_vdpau_yuv_video_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GstVdpauYUVVideo *yuv_video = GST_VDPAU_YUV_VIDEO (object); + + switch (prop_id) { + case PROP_DISPLAY: + g_free (yuv_video->display); + yuv_video->display = g_value_dup_string (value); + break; + case PROP_SILENT: + yuv_video->silent = g_value_get_boolean (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_vdpau_yuv_video_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) +{ + GstVdpauYUVVideo *yuv_video = GST_VDPAU_YUV_VIDEO (object); + + switch (prop_id) { + case PROP_DISPLAY: + g_value_set_string (value, yuv_video->display); + break; + case PROP_SILENT: + g_value_set_boolean (value, yuv_video->silent); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} diff --git a/sys/vdpau/gstvdpauyuvvideo.h b/sys/vdpau/gstvdpauyuvvideo.h new file mode 100644 index 00000000..118715e6 --- /dev/null +++ b/sys/vdpau/gstvdpauyuvvideo.h @@ -0,0 +1,64 @@ +/* + * GStreamer + * Copyright (C) 2009 Carl-Anton Ingmarsson + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GST_VDPAU_YUV_VIDEO_H__ +#define __GST_VDPAU_YUV_VIDEO_H__ + +#include + +#include "gstvdpaudevice.h" + +G_BEGIN_DECLS + +#define GST_TYPE_VDPAU_YUV_VIDEO (gst_vdpau_yuv_video_get_type()) +#define GST_VDPAU_YUV_VIDEO(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VDPAU_YUV_VIDEO,GstVdpauYUVVideo)) +#define GST_VDPAU_YUV_VIDEO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VDPAU_YUV_VIDEO,GstVdpauYUVVideoClass)) +#define GST_VDPAU_YUV_VIDEO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VDPAU_YUV_VIDEO, GstVdpauYUVVideoClass)) +#define GST_IS_VDPAU_YUV_VIDEO(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VDPAU_YUV_VIDEO)) +#define GST_IS_VDPAU_YUV_VIDEO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VDPAU_YUV_VIDEO)) + +typedef struct _GstVdpauYUVVideo GstVdpauYUVVideo; +typedef struct _GstVdpauYUVVideoClass GstVdpauYUVVideoClass; + +struct _GstVdpauYUVVideo { + GstElement element; + + GstPad *src, *sink; + GstCaps *sink_caps; + + gchar *display; + GstVdpauDevice *device; + + guint32 format; + gint chroma_type; + gint width, height; + + gboolean silent; +}; + +struct _GstVdpauYUVVideoClass { + GstElementClass parent_class; +}; + +GType gst_vdpau_yuv_video_get_type (void); + +G_END_DECLS + +#endif /* __GST_VDPAU_YUV_VIDEO_H__ */ -- cgit v1.2.1 From 072f8695485173d660363c1d8be3e62dacc69175 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Tue, 7 Apr 2009 21:51:48 +0200 Subject: vdpau: small fix set vdp_info.forward_reference to VDP_INVALID handle when unreffing the old buffer --- sys/vdpau/gstvdpaumpegdecoder.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpaumpegdecoder.c b/sys/vdpau/gstvdpaumpegdecoder.c index 1910652c..67af4e3f 100644 --- a/sys/vdpau/gstvdpaumpegdecoder.c +++ b/sys/vdpau/gstvdpaumpegdecoder.c @@ -169,8 +169,10 @@ gst_vdpau_mpeg_decoder_decode (GstVdpauMpegDecoder * mpeg_dec) ("Error returned from vdpau was: %s", device->vdp_get_error_string (status))); - if (mpeg_dec->vdp_info.forward_reference != VDP_INVALID_HANDLE) + if (mpeg_dec->vdp_info.forward_reference != VDP_INVALID_HANDLE) { gst_buffer_unref (mpeg_dec->f_buffer); + mpeg_dec->vdp_info.forward_reference = VDP_INVALID_HANDLE; + } gst_buffer_unref (GST_BUFFER (outbuf)); -- cgit v1.2.1 From 86cd9b20f88b55d753b050838cdd660cda07f8c3 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Thu, 9 Apr 2009 16:54:27 +0200 Subject: vdpau: move definition of the VdpChromaType array and the VdpauFormats to gstdevice.h --- sys/vdpau/gstvdpaudevice.h | 51 ++++++++++++++++++++++++++++++++++++++++++ sys/vdpau/gstvdpauvideoyuv.c | 42 +---------------------------------- sys/vdpau/gstvdpauyuvvideo.c | 53 +++----------------------------------------- 3 files changed, 55 insertions(+), 91 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpaudevice.h b/sys/vdpau/gstvdpaudevice.h index a4d147c4..c1c6608a 100644 --- a/sys/vdpau/gstvdpaudevice.h +++ b/sys/vdpau/gstvdpaudevice.h @@ -70,6 +70,57 @@ struct _GstVdpauDevice VdpDecoderGetParameters *vdp_decoder_get_parameters; }; +typedef struct +{ + VdpChromaType chroma_type; + VdpYCbCrFormat format; + guint32 fourcc; +} VdpauFormats; + +#define N_CHROMA_TYPES 3 +#define N_FORMATS 7 + +static const VdpChromaType chroma_types[N_CHROMA_TYPES] = + { VDP_CHROMA_TYPE_420, VDP_CHROMA_TYPE_422, VDP_CHROMA_TYPE_444 }; + +static const VdpauFormats formats[N_FORMATS] = { + { + VDP_CHROMA_TYPE_420, + VDP_YCBCR_FORMAT_NV12, + GST_MAKE_FOURCC ('N', 'V', '1', '2') + }, + { + VDP_CHROMA_TYPE_422, + VDP_YCBCR_FORMAT_UYVY, + GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y') + }, + { + VDP_CHROMA_TYPE_444, + VDP_YCBCR_FORMAT_V8U8Y8A8, + GST_MAKE_FOURCC ('A', 'Y', 'U', 'V') + }, + { + VDP_CHROMA_TYPE_444, + VDP_YCBCR_FORMAT_Y8U8V8A8, + GST_MAKE_FOURCC ('A', 'V', 'U', 'Y') + }, + { + VDP_CHROMA_TYPE_422, + VDP_YCBCR_FORMAT_YUYV, + GST_MAKE_FOURCC ('Y', 'U', 'Y', 'V') + }, + { + VDP_CHROMA_TYPE_420, + VDP_YCBCR_FORMAT_YV12, + GST_MAKE_FOURCC ('Y', 'V', '1', '2') + }, + { + VDP_CHROMA_TYPE_420, + VDP_YCBCR_FORMAT_YV12, + GST_MAKE_FOURCC ('I', '4', '2', '0') + } +}; + GType gst_vdpau_device_get_type (void) G_GNUC_CONST; GstVdpauDevice *gst_vdpau_device_new (const gchar *display_name); diff --git a/sys/vdpau/gstvdpauvideoyuv.c b/sys/vdpau/gstvdpauvideoyuv.c index 7b2e7677..6855ba88 100644 --- a/sys/vdpau/gstvdpauvideoyuv.c +++ b/sys/vdpau/gstvdpauvideoyuv.c @@ -178,46 +178,6 @@ gst_vdpau_video_yuv_chain (GstPad * pad, GstBuffer * buffer) return GST_FLOW_ERROR; } -typedef struct -{ - VdpChromaType chroma_type; - VdpYCbCrFormat format; - guint32 fourcc; -} VdpauFormats; - -static VdpauFormats formats[6] = { - { - VDP_CHROMA_TYPE_420, - VDP_YCBCR_FORMAT_NV12, - GST_MAKE_FOURCC ('N', 'V', '1', '2') - }, - { - VDP_CHROMA_TYPE_422, - VDP_YCBCR_FORMAT_UYVY, - GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y') - }, - { - VDP_CHROMA_TYPE_444, - VDP_YCBCR_FORMAT_V8U8Y8A8, - GST_MAKE_FOURCC ('A', 'Y', 'U', 'V') - }, - { - VDP_CHROMA_TYPE_444, - VDP_YCBCR_FORMAT_Y8U8V8A8, - GST_MAKE_FOURCC ('A', 'V', 'U', 'Y') - }, - { - VDP_CHROMA_TYPE_422, - VDP_YCBCR_FORMAT_YUYV, - GST_MAKE_FOURCC ('Y', 'U', 'Y', 'V') - }, - { - VDP_CHROMA_TYPE_420, - VDP_YCBCR_FORMAT_YV12, - GST_MAKE_FOURCC ('Y', 'V', '1', '2') - } -}; - static GstCaps * gst_vdpau_video_yuv_get_caps (GstVdpauVideoYUV * video_yuv, GstVdpauDevice * device, gint chroma_type, gint width, gint height, @@ -229,7 +189,7 @@ gst_vdpau_video_yuv_get_caps (GstVdpauVideoYUV * video_yuv, caps = gst_caps_new_empty (); - for (i = 0; i < 6; i++) { + for (i = 0; i < N_FORMATS; i++) { VdpStatus status; VdpBool is_supported; diff --git a/sys/vdpau/gstvdpauyuvvideo.c b/sys/vdpau/gstvdpauyuvvideo.c index 4d78bae2..d5935a8f 100644 --- a/sys/vdpau/gstvdpauyuvvideo.c +++ b/sys/vdpau/gstvdpauyuvvideo.c @@ -196,53 +196,6 @@ gst_vdpau_yuv_video_chain (GstPad * pad, GstBuffer * buffer) return GST_FLOW_ERROR; } -typedef struct -{ - VdpChromaType chroma_type; - VdpYCbCrFormat format; - guint32 fourcc; -} VdpauFormats; - -static VdpChromaType chroma_types[3] = - { VDP_CHROMA_TYPE_420, VDP_CHROMA_TYPE_422, VDP_CHROMA_TYPE_444 }; -static VdpauFormats formats[7] = { - { - VDP_CHROMA_TYPE_420, - VDP_YCBCR_FORMAT_NV12, - GST_MAKE_FOURCC ('N', 'V', '1', '2') - }, - { - VDP_CHROMA_TYPE_422, - VDP_YCBCR_FORMAT_UYVY, - GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y') - }, - { - VDP_CHROMA_TYPE_444, - VDP_YCBCR_FORMAT_V8U8Y8A8, - GST_MAKE_FOURCC ('A', 'Y', 'U', 'V') - }, - { - VDP_CHROMA_TYPE_444, - VDP_YCBCR_FORMAT_Y8U8V8A8, - GST_MAKE_FOURCC ('A', 'V', 'U', 'Y') - }, - { - VDP_CHROMA_TYPE_422, - VDP_YCBCR_FORMAT_YUYV, - GST_MAKE_FOURCC ('Y', 'U', 'Y', 'V') - }, - { - VDP_CHROMA_TYPE_420, - VDP_YCBCR_FORMAT_YV12, - GST_MAKE_FOURCC ('Y', 'V', '1', '2') - }, - { - VDP_CHROMA_TYPE_420, - VDP_YCBCR_FORMAT_YV12, - GST_MAKE_FOURCC ('I', '4', '2', '0') - } -}; - static GstCaps * gst_vdpau_yuv_video_get_caps (GstVdpauYUVVideo * yuv_video) { @@ -254,7 +207,7 @@ gst_vdpau_yuv_video_get_caps (GstVdpauYUVVideo * yuv_video) caps = gst_caps_new_empty (); - for (i = 0; i < 3; i++) { + for (i = 0; i < N_CHROMA_TYPES; i++) { VdpStatus status; VdpBool is_supported; guint32 max_w, max_h; @@ -274,7 +227,7 @@ gst_vdpau_yuv_video_get_caps (GstVdpauYUVVideo * yuv_video) if (is_supported) { gint j; - for (j = 0; j < 7; j++) { + for (j = 0; j < N_FORMATS; j++) { if (formats[j].chroma_type != chroma_types[i]) continue; @@ -337,7 +290,7 @@ gst_vdpau_yuv_video_sink_setcaps (GstPad * pad, GstCaps * caps) gst_structure_get_fraction (structure, "pixel-aspect-ratio", &par_numerator, &par_denominator); - for (i = 0; i < 7; i++) { + for (i = 0; i < N_FORMATS; i++) { if (formats[i].fourcc == fourcc) { chroma_type = formats[i].chroma_type; break; -- cgit v1.2.1 From a7170c6ef7e1dd7d623b5a0d61a654b433b2ec2d Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Mon, 13 Apr 2009 19:36:53 +0200 Subject: vdpau: implement GstVdpauVideoBuffer -> I420 conversion --- sys/vdpau/gstvdpauvideoyuv.c | 63 +++++++++++++++++++++++++++++++++++++------- sys/vdpau/gstvdpauyuvvideo.c | 20 +++++++------- 2 files changed, 64 insertions(+), 19 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpauvideoyuv.c b/sys/vdpau/gstvdpauvideoyuv.c index 6855ba88..f7ebe8a9 100644 --- a/sys/vdpau/gstvdpauvideoyuv.c +++ b/sys/vdpau/gstvdpauvideoyuv.c @@ -101,10 +101,10 @@ gst_vdpau_video_yuv_chain (GstPad * pad, GstBuffer * buffer) data[0] = GST_BUFFER_DATA (outbuf) + gst_video_format_get_component_offset (GST_VIDEO_FORMAT_YV12, 0, video_yuv->width, video_yuv->height); - data[1] = data[0] + + data[1] = GST_BUFFER_DATA (outbuf) + gst_video_format_get_component_offset (GST_VIDEO_FORMAT_YV12, 2, video_yuv->width, video_yuv->height); - data[2] = data[0] + + data[2] = GST_BUFFER_DATA (outbuf) + gst_video_format_get_component_offset (GST_VIDEO_FORMAT_YV12, 1, video_yuv->width, video_yuv->height); @@ -123,7 +123,53 @@ gst_vdpau_video_yuv_chain (GstPad * pad, GstBuffer * buffer) ("Couldn't get data from vdpau"), ("Error returned from vdpau was: %s", device->vdp_get_error_string (status))); - break; + goto error; + } + break; + } + case GST_MAKE_FOURCC ('I', '4', '2', '0'): + { + gint size; + GstFlowReturn result; + VdpStatus status; + guint8 *data[3]; + guint32 stride[3]; + + size = + gst_video_format_get_size (GST_VIDEO_FORMAT_YV12, video_yuv->width, + video_yuv->height); + result = + gst_pad_alloc_buffer_and_set_caps (video_yuv->src, + GST_BUFFER_OFFSET_NONE, size, GST_PAD_CAPS (video_yuv->src), &outbuf); + if (G_UNLIKELY (result != GST_FLOW_OK)) + return result; + + data[0] = GST_BUFFER_DATA (outbuf) + + gst_video_format_get_component_offset (GST_VIDEO_FORMAT_I420, + 0, video_yuv->width, video_yuv->height); + data[1] = GST_BUFFER_DATA (outbuf) + + gst_video_format_get_component_offset (GST_VIDEO_FORMAT_I420, + 2, video_yuv->width, video_yuv->height); + data[2] = GST_BUFFER_DATA (outbuf) + + gst_video_format_get_component_offset (GST_VIDEO_FORMAT_I420, + 1, video_yuv->width, video_yuv->height); + + stride[0] = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_I420, + 0, video_yuv->width); + stride[1] = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_I420, + 2, video_yuv->width); + stride[2] = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_I420, + 1, video_yuv->width); + + status = + device->vdp_video_surface_get_bits_ycbcr (surface, + VDP_YCBCR_FORMAT_YV12, (void *) data, stride); + if (G_UNLIKELY (status != VDP_STATUS_OK)) { + GST_ELEMENT_ERROR (video_yuv, RESOURCE, READ, + ("Couldn't get data from vdpau"), + ("Error returned from vdpau was: %s", + device->vdp_get_error_string (status))); + goto error; } break; } @@ -159,7 +205,7 @@ gst_vdpau_video_yuv_chain (GstPad * pad, GstBuffer * buffer) ("Couldn't get data from vdpau"), ("Error returned from vdpau was: %s", device->vdp_get_error_string (status))); - break; + goto error; } break; } @@ -169,12 +215,11 @@ gst_vdpau_video_yuv_chain (GstPad * pad, GstBuffer * buffer) gst_buffer_unref (buffer); - if (outbuf) { - gst_buffer_copy_metadata (outbuf, buffer, GST_BUFFER_COPY_TIMESTAMPS); - - return gst_pad_push (video_yuv->src, outbuf); - } + gst_buffer_copy_metadata (outbuf, buffer, GST_BUFFER_COPY_TIMESTAMPS); + return gst_pad_push (video_yuv->src, outbuf); +error: + gst_buffer_unref (outbuf); return GST_FLOW_ERROR; } diff --git a/sys/vdpau/gstvdpauyuvvideo.c b/sys/vdpau/gstvdpauyuvvideo.c index d5935a8f..51500c55 100644 --- a/sys/vdpau/gstvdpauyuvvideo.c +++ b/sys/vdpau/gstvdpauyuvvideo.c @@ -95,10 +95,10 @@ gst_vdpau_yuv_video_chain (GstPad * pad, GstBuffer * buffer) data[0] = GST_BUFFER_DATA (buffer) + gst_video_format_get_component_offset (GST_VIDEO_FORMAT_YV12, 0, yuv_video->width, yuv_video->height); - data[1] = data[0] + + data[1] = GST_BUFFER_DATA (buffer) + gst_video_format_get_component_offset (GST_VIDEO_FORMAT_YV12, 2, yuv_video->width, yuv_video->height); - data[2] = data[0] + + data[2] = GST_BUFFER_DATA (buffer) + gst_video_format_get_component_offset (GST_VIDEO_FORMAT_YV12, 1, yuv_video->width, yuv_video->height); @@ -117,7 +117,7 @@ gst_vdpau_yuv_video_chain (GstPad * pad, GstBuffer * buffer) ("Couldn't push YV12 data to VDPAU"), ("Error returned from vdpau was: %s", device->vdp_get_error_string (status))); - break; + goto error; } break; } @@ -152,7 +152,7 @@ gst_vdpau_yuv_video_chain (GstPad * pad, GstBuffer * buffer) ("Couldn't push YV12 data to VDPAU"), ("Error returned from vdpau was: %s", device->vdp_get_error_string (status))); - break; + goto error; } break; } @@ -176,7 +176,7 @@ gst_vdpau_yuv_video_chain (GstPad * pad, GstBuffer * buffer) ("Couldn't get data from vdpau"), ("Error returned from vdpau was: %s", device->vdp_get_error_string (status))); - break; + goto error; } break; } @@ -186,13 +186,13 @@ gst_vdpau_yuv_video_chain (GstPad * pad, GstBuffer * buffer) gst_buffer_unref (buffer); - if (outbuf) { - gst_buffer_copy_metadata (outbuf, buffer, GST_BUFFER_COPY_TIMESTAMPS); - gst_buffer_set_caps (outbuf, GST_PAD_CAPS (yuv_video->src)); + gst_buffer_copy_metadata (outbuf, buffer, GST_BUFFER_COPY_TIMESTAMPS); + gst_buffer_set_caps (outbuf, GST_PAD_CAPS (yuv_video->src)); - return gst_pad_push (yuv_video->src, outbuf); - } + return gst_pad_push (yuv_video->src, outbuf); +error: + gst_buffer_unref (outbuf); return GST_FLOW_ERROR; } -- cgit v1.2.1 From 91ff1579f32a6c0d9769cf44f5065d2811ba01f7 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Mon, 13 Apr 2009 20:04:21 +0200 Subject: vdpau: remove unused "silent" properties --- sys/vdpau/gstvdpaudevice.c | 1 - sys/vdpau/gstvdpaumpegdecoder.c | 18 +----------------- sys/vdpau/gstvdpaumpegdecoder.h | 2 -- sys/vdpau/gstvdpauvideoyuv.c | 18 +----------------- sys/vdpau/gstvdpauvideoyuv.h | 2 -- sys/vdpau/gstvdpauyuvvideo.c | 14 +------------- sys/vdpau/gstvdpauyuvvideo.h | 2 -- 7 files changed, 3 insertions(+), 54 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpaudevice.c b/sys/vdpau/gstvdpaudevice.c index 73929444..c5a5f641 100644 --- a/sys/vdpau/gstvdpaudevice.c +++ b/sys/vdpau/gstvdpaudevice.c @@ -29,7 +29,6 @@ GST_DEBUG_CATEGORY_STATIC (gst_vdpau_device_debug); enum { PROP_0, - PROP_DISPLAY }; diff --git a/sys/vdpau/gstvdpaumpegdecoder.c b/sys/vdpau/gstvdpaumpegdecoder.c index 67af4e3f..ecb801a0 100644 --- a/sys/vdpau/gstvdpaumpegdecoder.c +++ b/sys/vdpau/gstvdpaumpegdecoder.c @@ -53,8 +53,7 @@ enum enum { - PROP_0, - PROP_SILENT + PROP_0 }; /* the capabilities of the inputs and outputs. @@ -408,10 +407,6 @@ gst_vdpau_mpeg_decoder_class_init (GstVdpauMpegDecoderClass * klass) gobject_class->set_property = gst_vdpau_mpeg_decoder_set_property; gobject_class->get_property = gst_vdpau_mpeg_decoder_get_property; - g_object_class_install_property (gobject_class, PROP_SILENT, - g_param_spec_boolean ("silent", "Silent", "Produce verbose output ?", - FALSE, G_PARAM_READWRITE)); - vdpaudec_class->set_caps = gst_vdpau_mpeg_decoder_set_caps; } @@ -436,7 +431,6 @@ gst_vdpau_mpeg_decoder_init (GstVdpauMpegDecoder * mpeg_dec, dec = GST_VDPAU_DECODER (mpeg_dec); - mpeg_dec->silent = FALSE; mpeg_dec->decoder = VDP_INVALID_HANDLE; gst_vdpau_mpeg_decoder_init_info (&mpeg_dec->vdp_info); @@ -457,12 +451,7 @@ static void gst_vdpau_mpeg_decoder_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { - GstVdpauMpegDecoder *filter = GST_VDPAU_MPEG_DECODER (object); - switch (prop_id) { - case PROP_SILENT: - filter->silent = g_value_get_boolean (value); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -473,12 +462,7 @@ static void gst_vdpau_mpeg_decoder_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { - GstVdpauMpegDecoder *filter = GST_VDPAU_MPEG_DECODER (object); - switch (prop_id) { - case PROP_SILENT: - g_value_set_boolean (value, filter->silent); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; diff --git a/sys/vdpau/gstvdpaumpegdecoder.h b/sys/vdpau/gstvdpaumpegdecoder.h index d251480c..1a97c270 100644 --- a/sys/vdpau/gstvdpaumpegdecoder.h +++ b/sys/vdpau/gstvdpaumpegdecoder.h @@ -41,8 +41,6 @@ struct _GstVdpauMpegDecoder { GstVdpauDecoder dec; - gboolean silent; - gint version; VdpDecoder decoder; diff --git a/sys/vdpau/gstvdpauvideoyuv.c b/sys/vdpau/gstvdpauvideoyuv.c index f7ebe8a9..879e4562 100644 --- a/sys/vdpau/gstvdpauvideoyuv.c +++ b/sys/vdpau/gstvdpauvideoyuv.c @@ -40,8 +40,7 @@ enum enum { - PROP_0, - PROP_SILENT + PROP_0 }; static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink", @@ -387,17 +386,12 @@ gst_vdpau_video_yuv_class_init (GstVdpauVideoYUVClass * klass) gobject_class->finalize = gst_vdpau_video_yuv_finalize; gobject_class->set_property = gst_vdpau_video_yuv_set_property; gobject_class->get_property = gst_vdpau_video_yuv_get_property; - - g_object_class_install_property (gobject_class, PROP_SILENT, - g_param_spec_boolean ("silent", "Silent", "Produce verbose output ?", - FALSE, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE)); } static void gst_vdpau_video_yuv_init (GstVdpauVideoYUV * video_yuv, GstVdpauVideoYUVClass * klass) { - video_yuv->silent = FALSE; video_yuv->src_caps = NULL; video_yuv->height = 0; @@ -433,12 +427,7 @@ static void gst_vdpau_video_yuv_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { - GstVdpauVideoYUV *video_yuv = GST_VDPAU_VIDEO_YUV (object); - switch (prop_id) { - case PROP_SILENT: - video_yuv->silent = g_value_get_boolean (value); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -449,12 +438,7 @@ static void gst_vdpau_video_yuv_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { - GstVdpauVideoYUV *video_yuv = GST_VDPAU_VIDEO_YUV (object); - switch (prop_id) { - case PROP_SILENT: - g_value_set_boolean (value, video_yuv->silent); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; diff --git a/sys/vdpau/gstvdpauvideoyuv.h b/sys/vdpau/gstvdpauvideoyuv.h index dd033df7..477b3067 100644 --- a/sys/vdpau/gstvdpauvideoyuv.h +++ b/sys/vdpau/gstvdpauvideoyuv.h @@ -47,8 +47,6 @@ struct _GstVdpauVideoYUV { gint framerate_numerator, framerate_denominator; gint par_numerator, par_denominator; guint format; - - gboolean silent; }; struct _GstVdpauVideoYUVClass { diff --git a/sys/vdpau/gstvdpauyuvvideo.c b/sys/vdpau/gstvdpauyuvvideo.c index 51500c55..a9ccb731 100644 --- a/sys/vdpau/gstvdpauyuvvideo.c +++ b/sys/vdpau/gstvdpauyuvvideo.c @@ -41,8 +41,7 @@ enum enum { PROP_0, - PROP_DISPLAY, - PROP_SILENT + PROP_DISPLAY }; static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink", @@ -407,10 +406,6 @@ gst_vdpau_yuv_video_class_init (GstVdpauYUVVideoClass * klass) g_param_spec_string ("display", "Display", "X Display name", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); - g_object_class_install_property (gobject_class, PROP_SILENT, - g_param_spec_boolean ("silent", "Silent", "Produce verbose output ?", - FALSE, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE)); - gstelement_class->change_state = gst_vdpau_yuv_video_change_state; } @@ -418,7 +413,6 @@ static void gst_vdpau_yuv_video_init (GstVdpauYUVVideo * yuv_video, GstVdpauYUVVideoClass * klass) { - yuv_video->silent = FALSE; yuv_video->sink_caps = NULL; yuv_video->display = NULL; @@ -461,9 +455,6 @@ gst_vdpau_yuv_video_set_property (GObject * object, guint prop_id, g_free (yuv_video->display); yuv_video->display = g_value_dup_string (value); break; - case PROP_SILENT: - yuv_video->silent = g_value_get_boolean (value); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -480,9 +471,6 @@ gst_vdpau_yuv_video_get_property (GObject * object, guint prop_id, case PROP_DISPLAY: g_value_set_string (value, yuv_video->display); break; - case PROP_SILENT: - g_value_set_boolean (value, yuv_video->silent); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; diff --git a/sys/vdpau/gstvdpauyuvvideo.h b/sys/vdpau/gstvdpauyuvvideo.h index 118715e6..e80eacf9 100644 --- a/sys/vdpau/gstvdpauyuvvideo.h +++ b/sys/vdpau/gstvdpauyuvvideo.h @@ -49,8 +49,6 @@ struct _GstVdpauYUVVideo { guint32 format; gint chroma_type; gint width, height; - - gboolean silent; }; struct _GstVdpauYUVVideoClass { -- cgit v1.2.1 From 1234267cb5a66dd2782ac7755ef1f998f6561da4 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Mon, 13 Apr 2009 21:11:54 +0200 Subject: vdpau: small improvement to mpeg decoder --- sys/vdpau/gstvdpaumpegdecoder.c | 28 ++++++++++++++++++++-------- sys/vdpau/gstvdpaumpegdecoder.h | 2 ++ sys/vdpau/mpegutil.c | 2 +- 3 files changed, 23 insertions(+), 9 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpaumpegdecoder.c b/sys/vdpau/gstvdpaumpegdecoder.c index ecb801a0..efa89e36 100644 --- a/sys/vdpau/gstvdpaumpegdecoder.c +++ b/sys/vdpau/gstvdpaumpegdecoder.c @@ -112,6 +112,7 @@ gst_vdpau_mpeg_decoder_set_caps (GstVdpauDecoder * dec, GstCaps * caps) break; } } + memcpy (&mpeg_dec->vdp_info.intra_quantizer_matrix, &hdr.intra_quantizer_matrix, 64); memcpy (&mpeg_dec->vdp_info.non_intra_quantizer_matrix, @@ -210,12 +211,15 @@ gst_vdpau_mpeg_decoder_parse_picture_coding (GstVdpauMpegDecoder * mpeg_dec, info->intra_dc_precision = pic_ext.intra_dc_precision; info->picture_structure = pic_ext.picture_structure; + GST_DEBUG ("Picture structure %d", info->picture_structure); info->top_field_first = pic_ext.top_field_first; info->frame_pred_frame_dct = pic_ext.frame_pred_frame_dct; info->concealment_motion_vectors = pic_ext.concealment_motion_vectors; info->q_scale_type = pic_ext.q_scale_type; info->intra_vlc_format = pic_ext.intra_vlc_format; + mpeg_dec->want_slice = TRUE; + return TRUE; } @@ -266,7 +270,10 @@ gst_vdpau_mpeg_decoder_parse_picture (GstVdpauMpegDecoder * mpeg_dec, mpeg_dec->vdp_info.full_pel_backward_vector = pic_hdr.full_pel_backward_vector; memcpy (&mpeg_dec->vdp_info.f_code, &pic_hdr.f_code, 4); - } + + mpeg_dec->want_slice = TRUE; + } else + mpeg_dec->want_slice = FALSE; return TRUE; } @@ -326,12 +333,14 @@ gst_vdpau_mpeg_decoder_chain (GstPad * pad, GstBuffer * buffer) GstBuffer *subbuf; GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_SLICE"); - subbuf = - gst_buffer_create_sub (buffer, - packet_start - GST_BUFFER_DATA (buffer), packet_end - packet_start); - gst_adapter_push (mpeg_dec->adapter, subbuf); - mpeg_dec->vdp_info.slice_count++; - } else if (mpeg_dec->vdp_info.slice_count > 0) { + if (mpeg_dec->want_slice) { + subbuf = + gst_buffer_create_sub (buffer, + packet_start - GST_BUFFER_DATA (buffer), packet_end - packet_start); + gst_adapter_push (mpeg_dec->adapter, subbuf); + mpeg_dec->vdp_info.slice_count++; + } + } else if (mpeg_dec->vdp_info.slice_count > 0 && mpeg_dec->want_slice) { if (gst_vdpau_mpeg_decoder_decode (mpeg_dec) != GST_FLOW_OK) return GST_FLOW_ERROR; } @@ -344,7 +353,8 @@ gst_vdpau_mpeg_decoder_chain (GstPad * pad, GstBuffer * buffer) break; case MPEG_PACKET_SEQUENCE: GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_SEQUENCE"); - gst_vdpau_mpeg_decoder_parse_sequence (mpeg_dec, data, end); + gst_vdpau_mpeg_decoder_parse_sequence (mpeg_dec, packet_start, + packet_end); break; case MPEG_PACKET_EXTENSION: GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_EXTENSION"); @@ -436,6 +446,8 @@ gst_vdpau_mpeg_decoder_init (GstVdpauMpegDecoder * mpeg_dec, mpeg_dec->adapter = gst_adapter_new (); + mpeg_dec->want_slice = FALSE; + gst_pad_set_chain_function (dec->sink, gst_vdpau_mpeg_decoder_chain); } diff --git a/sys/vdpau/gstvdpaumpegdecoder.h b/sys/vdpau/gstvdpaumpegdecoder.h index 1a97c270..785c0c15 100644 --- a/sys/vdpau/gstvdpaumpegdecoder.h +++ b/sys/vdpau/gstvdpaumpegdecoder.h @@ -46,6 +46,8 @@ struct _GstVdpauMpegDecoder VdpDecoder decoder; VdpPictureInfoMPEG1Or2 vdp_info; GstBuffer *f_buffer; + + gboolean want_slice; GstAdapter *adapter; gint slices; diff --git a/sys/vdpau/mpegutil.c b/sys/vdpau/mpegutil.c index 8bba8d1f..3a4a63de 100644 --- a/sys/vdpau/mpegutil.c +++ b/sys/vdpau/mpegutil.c @@ -314,7 +314,7 @@ mpeg_util_parse_picture_coding_extension (MPEGPictureExt * ext, guint8 * data, { guint32 code; - if (G_UNLIKELY ((end - data) < 10)) + if (G_UNLIKELY ((end - data) < 9)) return FALSE; /* Packet too small */ code = GST_READ_UINT32_BE (data); -- cgit v1.2.1 From d2efd275a4f5c7ed853521ff9cb0e738a563b52e Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Mon, 13 Apr 2009 21:23:38 +0200 Subject: vdpau: decode slices when we get the next picture header. MPEG2 now kindof works. --- sys/vdpau/gstvdpaumpegdecoder.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpaumpegdecoder.c b/sys/vdpau/gstvdpaumpegdecoder.c index efa89e36..e13ec14c 100644 --- a/sys/vdpau/gstvdpaumpegdecoder.c +++ b/sys/vdpau/gstvdpaumpegdecoder.c @@ -211,7 +211,6 @@ gst_vdpau_mpeg_decoder_parse_picture_coding (GstVdpauMpegDecoder * mpeg_dec, info->intra_dc_precision = pic_ext.intra_dc_precision; info->picture_structure = pic_ext.picture_structure; - GST_DEBUG ("Picture structure %d", info->picture_structure); info->top_field_first = pic_ext.top_field_first; info->frame_pred_frame_dct = pic_ext.frame_pred_frame_dct; info->concealment_motion_vectors = pic_ext.concealment_motion_vectors; @@ -340,14 +339,15 @@ gst_vdpau_mpeg_decoder_chain (GstPad * pad, GstBuffer * buffer) gst_adapter_push (mpeg_dec->adapter, subbuf); mpeg_dec->vdp_info.slice_count++; } - } else if (mpeg_dec->vdp_info.slice_count > 0 && mpeg_dec->want_slice) { - if (gst_vdpau_mpeg_decoder_decode (mpeg_dec) != GST_FLOW_OK) - return GST_FLOW_ERROR; } switch (data[0]) { case MPEG_PACKET_PICTURE: GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_PICTURE"); + if (mpeg_dec->vdp_info.slice_count > 0 && mpeg_dec->want_slice) { + if (gst_vdpau_mpeg_decoder_decode (mpeg_dec) != GST_FLOW_OK) + return GST_FLOW_ERROR; + } gst_vdpau_mpeg_decoder_parse_picture (mpeg_dec, packet_start, packet_end); break; -- cgit v1.2.1 From 48143abdab828f6ea475c678bccb5a263c50e657 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Mon, 13 Apr 2009 22:19:20 +0200 Subject: vdpau: rename all files and objects from Vdpau to Vdp --- sys/vdpau/Makefile.am | 26 +-- sys/vdpau/gstvdp.c | 29 +++ sys/vdpau/gstvdpau.c | 29 --- sys/vdpau/gstvdpaudecoder.c | 275 ----------------------- sys/vdpau/gstvdpaudecoder.h | 74 ------ sys/vdpau/gstvdpaudevice.c | 269 ---------------------- sys/vdpau/gstvdpaudevice.h | 132 ----------- sys/vdpau/gstvdpaumpegdecoder.c | 482 ---------------------------------------- sys/vdpau/gstvdpaumpegdecoder.h | 65 ------ sys/vdpau/gstvdpauvideobuffer.c | 114 ---------- sys/vdpau/gstvdpauvideobuffer.h | 55 ----- sys/vdpau/gstvdpauvideoyuv.c | 446 ------------------------------------- sys/vdpau/gstvdpauvideoyuv.h | 60 ----- sys/vdpau/gstvdpauyuvvideo.c | 478 --------------------------------------- sys/vdpau/gstvdpauyuvvideo.h | 62 ------ sys/vdpau/gstvdpdecoder.c | 275 +++++++++++++++++++++++ sys/vdpau/gstvdpdecoder.h | 74 ++++++ sys/vdpau/gstvdpdevice.c | 269 ++++++++++++++++++++++ sys/vdpau/gstvdpdevice.h | 132 +++++++++++ sys/vdpau/gstvdpmpegdecoder.c | 481 +++++++++++++++++++++++++++++++++++++++ sys/vdpau/gstvdpmpegdecoder.h | 65 ++++++ sys/vdpau/gstvdpvideobuffer.c | 114 ++++++++++ sys/vdpau/gstvdpvideobuffer.h | 55 +++++ sys/vdpau/gstvdpvideoyuv.c | 444 ++++++++++++++++++++++++++++++++++++ sys/vdpau/gstvdpvideoyuv.h | 60 +++++ sys/vdpau/gstvdpyuvvideo.c | 476 +++++++++++++++++++++++++++++++++++++++ sys/vdpau/gstvdpyuvvideo.h | 62 ++++++ 27 files changed, 2549 insertions(+), 2554 deletions(-) create mode 100644 sys/vdpau/gstvdp.c delete mode 100644 sys/vdpau/gstvdpau.c delete mode 100644 sys/vdpau/gstvdpaudecoder.c delete mode 100644 sys/vdpau/gstvdpaudecoder.h delete mode 100644 sys/vdpau/gstvdpaudevice.c delete mode 100644 sys/vdpau/gstvdpaudevice.h delete mode 100644 sys/vdpau/gstvdpaumpegdecoder.c delete mode 100644 sys/vdpau/gstvdpaumpegdecoder.h delete mode 100644 sys/vdpau/gstvdpauvideobuffer.c delete mode 100644 sys/vdpau/gstvdpauvideobuffer.h delete mode 100644 sys/vdpau/gstvdpauvideoyuv.c delete mode 100644 sys/vdpau/gstvdpauvideoyuv.h delete mode 100644 sys/vdpau/gstvdpauyuvvideo.c delete mode 100644 sys/vdpau/gstvdpauyuvvideo.h create mode 100644 sys/vdpau/gstvdpdecoder.c create mode 100644 sys/vdpau/gstvdpdecoder.h create mode 100644 sys/vdpau/gstvdpdevice.c create mode 100644 sys/vdpau/gstvdpdevice.h create mode 100644 sys/vdpau/gstvdpmpegdecoder.c create mode 100644 sys/vdpau/gstvdpmpegdecoder.h create mode 100644 sys/vdpau/gstvdpvideobuffer.c create mode 100644 sys/vdpau/gstvdpvideobuffer.h create mode 100644 sys/vdpau/gstvdpvideoyuv.c create mode 100644 sys/vdpau/gstvdpvideoyuv.h create mode 100644 sys/vdpau/gstvdpyuvvideo.c create mode 100644 sys/vdpau/gstvdpyuvvideo.h (limited to 'sys') diff --git a/sys/vdpau/Makefile.am b/sys/vdpau/Makefile.am index f10cae89..a603ec77 100644 --- a/sys/vdpau/Makefile.am +++ b/sys/vdpau/Makefile.am @@ -1,14 +1,14 @@ plugin_LTLIBRARIES = libgstvdpau.la libgstvdpau_la_SOURCES = \ - gstvdpaudevice.c \ - gstvdpaudecoder.c \ - gstvdpaumpegdecoder.c \ + gstvdpdevice.c \ + gstvdpdecoder.c \ + gstvdpmpegdecoder.c \ mpegutil.c \ - gstvdpauvideoyuv.c \ - gstvdpauvideobuffer.c \ - gstvdpau.c \ - gstvdpauyuvvideo.c + gstvdpvideoyuv.c \ + gstvdpvideobuffer.c \ + gstvdp.c \ + gstvdpyuvvideo.c libgstvdpau_la_CFLAGS = $(GST_CFLAGS) $(X11_CFLAGS) -Ivdpau libgstvdpau_la_LIBADD = $(GST_LIBS) $(GST_BASE_LIBS) \ @@ -17,12 +17,12 @@ libgstvdpau_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) libgstvdpau_la_LIBTOOLFLAGS = --tag=disable-static noinst_HEADERS = \ - gstvdpaudevice.h \ - gstvdpaudecoder.h \ - gstvdpaumpegdecoder.h \ + gstvdpdevice.h \ + gstvdpdecoder.h \ + gstvdpmpegdecoder.h \ mpegutil.h \ - gstvdpauvideoyuv.h \ - gstvdpauvideobuffer.h \ - gstvdpauyuvvideo.h + gstvdpvideoyuv.h \ + gstvdpvideobuffer.h \ + gstvdpyuvvideo.h diff --git a/sys/vdpau/gstvdp.c b/sys/vdpau/gstvdp.c new file mode 100644 index 00000000..2da9bdb0 --- /dev/null +++ b/sys/vdpau/gstvdp.c @@ -0,0 +1,29 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + + +#include + +#include "gstvdpmpegdecoder.h" +#include "gstvdpvideoyuv.h" +#include "gstvdpyuvvideo.h" + +static gboolean +vdpau_init (GstPlugin * vdpaumpegdecoder) +{ + gst_element_register (vdpaumpegdecoder, "vdpaumpegdecoder", + GST_RANK_NONE, GST_TYPE_VDPAU_MPEG_DECODER); + gst_element_register (vdpaumpegdecoder, "vdpauvideoyuv", + GST_RANK_NONE, GST_TYPE_VDPAU_VIDEO_YUV); + gst_element_register (vdpaumpegdecoder, "vdpauyuvvideo", + GST_RANK_NONE, GST_TYPE_VDPAU_YUV_VIDEO); + + return TRUE; +} + +GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, + GST_VERSION_MINOR, + "vdpau", + "Various elements utilizing VDPAU", + vdpau_init, VERSION, "LGPL", "GStreamer", "http://gstreamer.net/") diff --git a/sys/vdpau/gstvdpau.c b/sys/vdpau/gstvdpau.c deleted file mode 100644 index 24ed3982..00000000 --- a/sys/vdpau/gstvdpau.c +++ /dev/null @@ -1,29 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - - -#include - -#include "gstvdpaumpegdecoder.h" -#include "gstvdpauvideoyuv.h" -#include "gstvdpauyuvvideo.h" - -static gboolean -vdpau_init (GstPlugin * vdpaumpegdecoder) -{ - gst_element_register (vdpaumpegdecoder, "vdpaumpegdecoder", - GST_RANK_NONE, GST_TYPE_VDPAU_MPEG_DECODER); - gst_element_register (vdpaumpegdecoder, "vdpauvideoyuv", - GST_RANK_NONE, GST_TYPE_VDPAU_VIDEO_YUV); - gst_element_register (vdpaumpegdecoder, "vdpauyuvvideo", - GST_RANK_NONE, GST_TYPE_VDPAU_YUV_VIDEO); - - return TRUE; -} - -GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, - GST_VERSION_MINOR, - "vdpau", - "Various elements utilizing VDPAU", - vdpau_init, VERSION, "LGPL", "GStreamer", "http://gstreamer.net/") diff --git a/sys/vdpau/gstvdpaudecoder.c b/sys/vdpau/gstvdpaudecoder.c deleted file mode 100644 index 3d0ced34..00000000 --- a/sys/vdpau/gstvdpaudecoder.c +++ /dev/null @@ -1,275 +0,0 @@ -/* - * GStreamer - * Copyright (C) 2009 Carl-Anton Ingmarsson - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include - -#include "gstvdpaudecoder.h" - -GST_DEBUG_CATEGORY_STATIC (gst_vdpau_decoder_debug); -#define GST_CAT_DEFAULT gst_vdpau_decoder_debug - -/* Filter signals and args */ -enum -{ - /* FILL ME */ - LAST_SIGNAL -}; - -enum -{ - PROP_0, - PROP_DISPLAY, - PROP_SILENT -}; - -static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("video/vdpau-video, " "chroma-type = (int) 0")); - -#define DEBUG_INIT(bla) \ - GST_DEBUG_CATEGORY_INIT (gst_vdpau_decoder_debug, "vdpaudecoder", 0, "vdpaudecoder base class"); - -GST_BOILERPLATE_FULL (GstVdpauDecoder, gst_vdpau_decoder, GstElement, - GST_TYPE_ELEMENT, DEBUG_INIT); - -static void gst_vdpau_decoder_finalize (GObject * object); -static void gst_vdpau_decoder_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec); -static void gst_vdpau_decoder_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec); - -GstFlowReturn -gst_vdpau_decoder_push_video_buffer (GstVdpauDecoder * dec, - GstVdpauVideoBuffer * buffer) -{ - GST_BUFFER_TIMESTAMP (buffer) = - gst_util_uint64_scale_int (GST_SECOND * dec->frame_nr, - dec->framerate_denominator, dec->framerate_numerator); - GST_BUFFER_DURATION (buffer) = - gst_util_uint64_scale_int (GST_SECOND, dec->framerate_denominator, - dec->framerate_numerator); - GST_BUFFER_OFFSET (buffer) = dec->frame_nr; - dec->frame_nr++; - GST_BUFFER_OFFSET_END (buffer) = dec->frame_nr; - gst_buffer_set_caps (GST_BUFFER (buffer), GST_PAD_CAPS (dec->src)); - - return gst_pad_push (dec->src, GST_BUFFER (buffer)); -} - -static GstStateChangeReturn -gst_vdpau_decoder_change_state (GstElement * element, GstStateChange transition) -{ - GstVdpauDecoder *dec; - - dec = GST_VDPAU_DECODER (element); - - switch (transition) { - case GST_STATE_CHANGE_NULL_TO_READY: - dec->device = gst_vdpau_get_device (dec->display_name); - break; - case GST_STATE_CHANGE_READY_TO_NULL: - g_object_unref (dec->device); - dec->device = NULL; - break; - default: - break; - } - - return GST_STATE_CHANGE_SUCCESS; -} - -static gboolean -gst_vdpau_decoder_sink_set_caps (GstPad * pad, GstCaps * caps) -{ - GstVdpauDecoder *dec = GST_VDPAU_DECODER (GST_OBJECT_PARENT (pad)); - GstVdpauDecoderClass *dec_class = GST_VDPAU_DECODER_GET_CLASS (dec); - - GstCaps *src_caps, *new_caps; - GstStructure *structure; - gint width, height; - gint framerate_numerator, framerate_denominator; - gint par_numerator, par_denominator; - gboolean res; - - structure = gst_caps_get_structure (caps, 0); - gst_structure_get_int (structure, "width", &width); - gst_structure_get_int (structure, "height", &height); - gst_structure_get_fraction (structure, "framerate", - &framerate_numerator, &framerate_denominator); - gst_structure_get_fraction (structure, "pixel-aspect-ratio", - &par_numerator, &par_denominator); - - src_caps = gst_pad_get_allowed_caps (dec->src); - if (G_UNLIKELY (!src_caps)) - return FALSE; - - new_caps = gst_caps_copy_nth (src_caps, 0); - gst_caps_unref (src_caps); - structure = gst_caps_get_structure (new_caps, 0); - gst_structure_set (structure, - "device", G_TYPE_OBJECT, dec->device, - "chroma-type", G_TYPE_INT, VDP_CHROMA_TYPE_420, - "width", G_TYPE_INT, width, - "height", G_TYPE_INT, height, - "framerate", GST_TYPE_FRACTION, framerate_numerator, - framerate_denominator, - "pixel-aspect-ratio", GST_TYPE_FRACTION, par_numerator, - par_denominator, NULL); - - gst_pad_fixate_caps (dec->src, new_caps); - res = gst_pad_set_caps (dec->src, new_caps); - - gst_caps_unref (new_caps); - - if (G_UNLIKELY (!res)) - return FALSE; - - dec->width = width; - dec->height = height; - dec->framerate_numerator = framerate_numerator; - dec->framerate_denominator = framerate_denominator; - - if (dec_class->set_caps && !dec_class->set_caps (dec, caps)) - return FALSE; - - return TRUE; -} - -/* GObject vmethod implementations */ - -static void -gst_vdpau_decoder_base_init (gpointer klass) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS (klass); - - gst_element_class_set_details_simple (element_class, - "VdpauDecoder", - "Codec/Decoder/Video", - "VDPAU decoder base class", - "Carl-Anton Ingmarsson "); - - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&src_template)); -} - -/* initialize the vdpaudecoder's class */ -static void -gst_vdpau_decoder_class_init (GstVdpauDecoderClass * klass) -{ - GObjectClass *gobject_class; - GstElementClass *gstelement_class; - - gobject_class = (GObjectClass *) klass; - gstelement_class = (GstElementClass *) klass; - - gobject_class->finalize = gst_vdpau_decoder_finalize; - gobject_class->set_property = gst_vdpau_decoder_set_property; - gobject_class->get_property = gst_vdpau_decoder_get_property; - - g_object_class_install_property (gobject_class, PROP_DISPLAY, - g_param_spec_string ("display", "Display", "X Display name", - NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); - - g_object_class_install_property (gobject_class, PROP_SILENT, - g_param_spec_boolean ("silent", "Silent", "Produce verbose output ?", - FALSE, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE)); - - gstelement_class->change_state = gst_vdpau_decoder_change_state; -} - -static void -gst_vdpau_decoder_init (GstVdpauDecoder * dec, GstVdpauDecoderClass * klass) -{ - dec->display_name = NULL; - dec->device = NULL; - dec->silent = FALSE; - - dec->height = 0; - dec->width = 0; - dec->framerate_numerator = 0; - dec->framerate_denominator = 0; - - dec->frame_nr = 0; - - dec->src = gst_pad_new_from_static_template (&src_template, "src"); - gst_element_add_pad (GST_ELEMENT (dec), dec->src); - - dec->sink = gst_pad_new_from_template (gst_element_class_get_pad_template - (GST_ELEMENT_CLASS (klass), "sink"), "sink"); - gst_pad_set_setcaps_function (dec->sink, gst_vdpau_decoder_sink_set_caps); - gst_element_add_pad (GST_ELEMENT (dec), dec->sink); - gst_pad_set_active (dec->sink, TRUE); -} - -static void -gst_vdpau_decoder_finalize (GObject * object) -{ - GstVdpauDecoder *dec = (GstVdpauDecoder *) object; - - if (dec->device) - g_object_unref (dec->device); - - g_free (dec->display_name); -} - -static void -gst_vdpau_decoder_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) -{ - GstVdpauDecoder *dec = GST_VDPAU_DECODER (object); - - switch (prop_id) { - case PROP_DISPLAY: - g_free (dec->display_name); - dec->display_name = g_value_dup_string (value); - break; - case PROP_SILENT: - dec->silent = g_value_get_boolean (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_vdpau_decoder_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec) -{ - GstVdpauDecoder *dec = GST_VDPAU_DECODER (object); - - switch (prop_id) { - case PROP_DISPLAY: - g_value_set_string (value, dec->display_name); - break; - case PROP_SILENT: - g_value_set_boolean (value, dec->silent); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} diff --git a/sys/vdpau/gstvdpaudecoder.h b/sys/vdpau/gstvdpaudecoder.h deleted file mode 100644 index 3f67da68..00000000 --- a/sys/vdpau/gstvdpaudecoder.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * GStreamer - * Copyright (C) 2009 Carl-Anton Ingmarsson - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __GST_VDPAU_DECODER_H__ -#define __GST_VDPAU_DECODER_H__ - -#include - -#include "gstvdpaudevice.h" -#include "gstvdpauvideobuffer.h" - -G_BEGIN_DECLS - -#define GST_TYPE_VDPAU_DECODER (gst_vdpau_decoder_get_type()) -#define GST_VDPAU_DECODER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VDPAU_DECODER,GstVdpauDecoder)) -#define GST_VDPAU_DECODER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VDPAU_DECODER,GstVdpauDecoderClass)) -#define GST_VDPAU_DECODER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VDPAU_DECODER, GstVdpauDecoderClass)) -#define GST_IS_VDPAU_DECODER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VDPAU_DECODER)) -#define GST_IS_VDPAU_DECODER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VDPAU_DECODER)) - -typedef struct _GstVdpauDecoder GstVdpauDecoder; -typedef struct _GstVdpauDecoderClass GstVdpauDecoderClass; -typedef struct _VdpauFunctions VdpauFunctions; - -struct _GstVdpauDecoder { - GstElement element; - - gchar *display_name; - GstVdpauDevice *device; - - GstPad *src; - GstPad *sink; - - gint width, height; - gint framerate_numerator, framerate_denominator; - guint32 format; - - gint frame_nr; - - gboolean silent; -}; - -struct _GstVdpauDecoderClass { - GstElementClass parent_class; - - gboolean (*set_caps) (GstVdpauDecoder *dec, GstCaps *caps); -}; - -GType gst_vdpau_decoder_get_type (void); - -gboolean gst_vdpau_decoder_push_video_buffer (GstVdpauDecoder * dec, - GstVdpauVideoBuffer *buffer); -VdpVideoSurface gst_vdpau_decoder_create_video_surface (GstVdpauDecoder *dec); - -G_END_DECLS - -#endif /* __GST_VDPAU_DECODER_H__ */ diff --git a/sys/vdpau/gstvdpaudevice.c b/sys/vdpau/gstvdpaudevice.c deleted file mode 100644 index c5a5f641..00000000 --- a/sys/vdpau/gstvdpaudevice.c +++ /dev/null @@ -1,269 +0,0 @@ -/* - * GStreamer - * Copyright (C) 2009 Carl-Anton Ingmarsson - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#include -#include - -#include "gstvdpaudevice.h" - -GST_DEBUG_CATEGORY_STATIC (gst_vdpau_device_debug); -#define GST_CAT_DEFAULT gst_vdpau_device_debug - -enum -{ - PROP_0, - PROP_DISPLAY -}; - - - -G_DEFINE_TYPE (GstVdpauDevice, gst_vdpau_device, G_TYPE_OBJECT); - -static void -gst_vdpau_device_init (GstVdpauDevice * device) -{ - device->display_name = NULL; - device->display = NULL; - device->device = VDP_INVALID_HANDLE; -} - -static void -gst_vdpau_device_finalize (GObject * object) -{ - GstVdpauDevice *device = (GstVdpauDevice *) object; - - device->vdp_device_destroy (device->device); - g_free (device->display_name); - - G_OBJECT_CLASS (gst_vdpau_device_parent_class)->finalize (object); - -} - -static void -gst_vdpau_device_constructed (GObject * object) -{ - GstVdpauDevice *device = (GstVdpauDevice *) object; - gint screen; - VdpStatus status; - gint i; - - typedef struct - { - gint id; - void *func; - } VdpFunction; - - VdpFunction vdp_function[] = { - {VDP_FUNC_ID_DEVICE_DESTROY, &device->vdp_device_destroy}, - {VDP_FUNC_ID_VIDEO_SURFACE_CREATE, - &device->vdp_video_surface_create}, - {VDP_FUNC_ID_VIDEO_SURFACE_DESTROY, - &device->vdp_video_surface_destroy}, - {VDP_FUNC_ID_VIDEO_SURFACE_QUERY_CAPABILITIES, - &device->vdp_video_surface_query_capabilities}, - {VDP_FUNC_ID_VIDEO_SURFACE_QUERY_GET_PUT_BITS_Y_CB_CR_CAPABILITIES, - &device->vdp_video_surface_query_ycbcr_capabilities}, - {VDP_FUNC_ID_VIDEO_SURFACE_GET_BITS_Y_CB_CR, - &device->vdp_video_surface_get_bits_ycbcr}, - {VDP_FUNC_ID_VIDEO_SURFACE_PUT_BITS_Y_CB_CR, - &device->vdp_video_surface_put_bits_ycbcr}, - {VDP_FUNC_ID_VIDEO_SURFACE_GET_PARAMETERS, - &device->vdp_video_surface_get_parameters}, - {VDP_FUNC_ID_DECODER_CREATE, &device->vdp_decoder_create}, - {VDP_FUNC_ID_DECODER_RENDER, &device->vdp_decoder_render}, - {VDP_FUNC_ID_DECODER_DESTROY, &device->vdp_decoder_destroy}, - {VDP_FUNC_ID_DECODER_QUERY_CAPABILITIES, - &device->vdp_decoder_query_capabilities}, - {VDP_FUNC_ID_DECODER_GET_PARAMETERS, - &device->vdp_decoder_get_parameters}, - {0, NULL} - }; - - device->display = XOpenDisplay (device->display_name); - if (!device->display) { - GST_ERROR_OBJECT (device, "Could not open X display with name: %s", - device->display_name); - return; - } - - screen = DefaultScreen (device->display); - status = - vdp_device_create_x11 (device->display, screen, &device->device, - &device->vdp_get_proc_address); - if (status != VDP_STATUS_OK) { - GST_ERROR_OBJECT (device, "Could not create VDPAU device"); - XCloseDisplay (device->display); - device->display = NULL; - - return; - } - - status = device->vdp_get_proc_address (device->device, - VDP_FUNC_ID_GET_ERROR_STRING, (void **) &device->vdp_get_error_string); - if (status != VDP_STATUS_OK) { - GST_ERROR_OBJECT (device, - "Could not get vdp_get_error_string function pointer from VDPAU"); - goto error; - } - - for (i = 0; vdp_function[i].func != NULL; i++) { - status = device->vdp_get_proc_address (device->device, - vdp_function[i].id, vdp_function[i].func); - - if (status != VDP_STATUS_OK) { - GST_ERROR_OBJECT (device, "Could not get function pointer from VDPAU," - " error returned was: %s", device->vdp_get_error_string (status)); - goto error; - } - } - - return; - -error: - XCloseDisplay (device->display); - device->display = NULL; - - if (device->device != VDP_INVALID_HANDLE) { - device->vdp_device_destroy (device->device); - device->device = VDP_INVALID_HANDLE; - } -} - -static void -gst_vdpau_device_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) -{ - GstVdpauDevice *device; - - g_return_if_fail (GST_IS_VDPAU_DEVICE (object)); - - device = (GstVdpauDevice *) object; - - switch (prop_id) { - case PROP_DISPLAY: - device->display_name = g_value_dup_string (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_vdpau_device_get_property (GObject * object, guint prop_id, GValue * value, - GParamSpec * pspec) -{ - GstVdpauDevice *device; - - g_return_if_fail (GST_IS_VDPAU_DEVICE (object)); - - device = (GstVdpauDevice *) object; - - switch (prop_id) { - case PROP_DISPLAY: - g_value_set_string (value, device->display_name); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_vdpau_device_class_init (GstVdpauDeviceClass * klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->constructed = gst_vdpau_device_constructed; - object_class->finalize = gst_vdpau_device_finalize; - object_class->get_property = gst_vdpau_device_get_property; - object_class->set_property = gst_vdpau_device_set_property; - - - g_object_class_install_property (object_class, - PROP_DISPLAY, - g_param_spec_string ("display", - "Display", - "X Display Name", - "", G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); - - GST_DEBUG_CATEGORY_INIT (gst_vdpau_device_debug, "vdpaudevice", - 0, "vdpaudevice"); -} - -GstVdpauDevice * -gst_vdpau_device_new (const gchar * display_name) -{ - GstVdpauDevice *device; - - device = g_object_new (GST_TYPE_VDPAU_DEVICE, "display", display_name); - - return device; -} - -static void -device_destroyed_cb (gpointer data, GObject * object) -{ - GHashTable *devices_hash = data; - GHashTableIter iter; - gpointer device; - - g_hash_table_iter_init (&iter, devices_hash); - while (g_hash_table_iter_next (&iter, NULL, &device)) { - if (device == object) { - g_hash_table_iter_remove (&iter); - break; - } - } -} - -static gpointer -create_devices_hash (gpointer data) -{ - return g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); -} - -GstVdpauDevice * -gst_vdpau_get_device (const gchar * display_name) -{ - static GOnce my_once = G_ONCE_INIT; - GHashTable *devices_hash; - GstVdpauDevice *device; - - g_once (&my_once, create_devices_hash, NULL); - devices_hash = my_once.retval; - - if (display_name) - device = g_hash_table_lookup (devices_hash, display_name); - else - device = g_hash_table_lookup (devices_hash, ""); - - if (!device) { - device = gst_vdpau_device_new (display_name); - g_object_weak_ref (G_OBJECT (device), device_destroyed_cb, devices_hash); - if (display_name) - g_hash_table_insert (devices_hash, g_strdup (display_name), device); - else - g_hash_table_insert (devices_hash, g_strdup (""), device); - } else - g_object_ref (device); - - return device; -} diff --git a/sys/vdpau/gstvdpaudevice.h b/sys/vdpau/gstvdpaudevice.h deleted file mode 100644 index c1c6608a..00000000 --- a/sys/vdpau/gstvdpaudevice.h +++ /dev/null @@ -1,132 +0,0 @@ -/* - * GStreamer - * Copyright (C) 2009 Carl-Anton Ingmarsson - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef _GST_VDPAU_DEVICE_H_ -#define _GST_VDPAU_DEVICE_H_ - -#include -#include - -#include - -G_BEGIN_DECLS - -#define GST_TYPE_VDPAU_DEVICE (gst_vdpau_device_get_type ()) -#define GST_VDPAU_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VDPAU_DEVICE, GstVdpauDevice)) -#define GST_VDPAU_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_VDPAU_DEVICE, GstVdpauDeviceClass)) -#define GST_IS_VDPAU_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VDPAU_DEVICE)) -#define GST_IS_VDPAU_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_VDPAU_DEVICE)) -#define GST_VDPAU_DEVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VDPAU_DEVICE, GstVdpauDeviceClass)) - -typedef struct _GstVdpauDeviceClass GstVdpauDeviceClass; -typedef struct _GstVdpauDevice GstVdpauDevice; - -struct _GstVdpauDeviceClass -{ - GObjectClass parent_class; -}; - -struct _GstVdpauDevice -{ - GObject object; - - gchar *display_name; - Display *display; - VdpDevice device; - - VdpDeviceDestroy *vdp_device_destroy; - VdpGetProcAddress *vdp_get_proc_address; - VdpGetErrorString *vdp_get_error_string; - - VdpVideoSurfaceCreate *vdp_video_surface_create; - VdpVideoSurfaceDestroy *vdp_video_surface_destroy; - VdpVideoSurfaceQueryCapabilities *vdp_video_surface_query_capabilities; - VdpVideoSurfaceQueryGetPutBitsYCbCrCapabilities *vdp_video_surface_query_ycbcr_capabilities; - VdpVideoSurfaceGetParameters *vdp_video_surface_get_parameters; - VdpVideoSurfaceGetBitsYCbCr *vdp_video_surface_get_bits_ycbcr; - VdpVideoSurfacePutBitsYCbCr *vdp_video_surface_put_bits_ycbcr; - - VdpDecoderCreate *vdp_decoder_create; - VdpDecoderDestroy *vdp_decoder_destroy; - VdpDecoderRender *vdp_decoder_render; - VdpDecoderQueryCapabilities *vdp_decoder_query_capabilities; - VdpDecoderGetParameters *vdp_decoder_get_parameters; -}; - -typedef struct -{ - VdpChromaType chroma_type; - VdpYCbCrFormat format; - guint32 fourcc; -} VdpauFormats; - -#define N_CHROMA_TYPES 3 -#define N_FORMATS 7 - -static const VdpChromaType chroma_types[N_CHROMA_TYPES] = - { VDP_CHROMA_TYPE_420, VDP_CHROMA_TYPE_422, VDP_CHROMA_TYPE_444 }; - -static const VdpauFormats formats[N_FORMATS] = { - { - VDP_CHROMA_TYPE_420, - VDP_YCBCR_FORMAT_NV12, - GST_MAKE_FOURCC ('N', 'V', '1', '2') - }, - { - VDP_CHROMA_TYPE_422, - VDP_YCBCR_FORMAT_UYVY, - GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y') - }, - { - VDP_CHROMA_TYPE_444, - VDP_YCBCR_FORMAT_V8U8Y8A8, - GST_MAKE_FOURCC ('A', 'Y', 'U', 'V') - }, - { - VDP_CHROMA_TYPE_444, - VDP_YCBCR_FORMAT_Y8U8V8A8, - GST_MAKE_FOURCC ('A', 'V', 'U', 'Y') - }, - { - VDP_CHROMA_TYPE_422, - VDP_YCBCR_FORMAT_YUYV, - GST_MAKE_FOURCC ('Y', 'U', 'Y', 'V') - }, - { - VDP_CHROMA_TYPE_420, - VDP_YCBCR_FORMAT_YV12, - GST_MAKE_FOURCC ('Y', 'V', '1', '2') - }, - { - VDP_CHROMA_TYPE_420, - VDP_YCBCR_FORMAT_YV12, - GST_MAKE_FOURCC ('I', '4', '2', '0') - } -}; - -GType gst_vdpau_device_get_type (void) G_GNUC_CONST; - -GstVdpauDevice *gst_vdpau_device_new (const gchar *display_name); - -GstVdpauDevice *gst_vdpau_get_device (const gchar *display_name); - -G_END_DECLS - -#endif /* _GST_VDPAU_DEVICE_H_ */ diff --git a/sys/vdpau/gstvdpaumpegdecoder.c b/sys/vdpau/gstvdpaumpegdecoder.c deleted file mode 100644 index e13ec14c..00000000 --- a/sys/vdpau/gstvdpaumpegdecoder.c +++ /dev/null @@ -1,482 +0,0 @@ -/* - * GStreamer - * Copyright (C) 2009 Carl-Anton Ingmarsson - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/** - * SECTION:element-vdpaumpegdecoder - * - * FIXME:Describe vdpaumpegdecoder here. - * - * - * Example launch line - * |[ - * gst-launch -v -m fakesrc ! vdpaumpegdecoder ! fakesink silent=TRUE - * ]| - * - */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include - -#include "mpegutil.h" -#include "gstvdpaumpegdecoder.h" - -GST_DEBUG_CATEGORY_STATIC (gst_vdpau_mpeg_decoder_debug); -#define GST_CAT_DEFAULT gst_vdpau_mpeg_decoder_debug - -/* Filter signals and args */ -enum -{ - /* FILL ME */ - LAST_SIGNAL -}; - -enum -{ - PROP_0 -}; - -/* the capabilities of the inputs and outputs. - * - * describe the real formats here. - */ -static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("video/mpeg, mpegversion = (int) [ 1, 2 ], " - "systemstream = (boolean) false, parsed = (boolean) true") - ); - -#define DEBUG_INIT(bla) \ -GST_DEBUG_CATEGORY_INIT (gst_vdpau_mpeg_decoder_debug, "vdpaumpegdecoder", 0, "VDPAU powered mpeg decoder"); - -GST_BOILERPLATE_FULL (GstVdpauMpegDecoder, gst_vdpau_mpeg_decoder, - GstVdpauDecoder, GST_TYPE_VDPAU_DECODER, DEBUG_INIT); - -static void gst_vdpau_mpeg_decoder_finalize (GObject * object); -static void gst_vdpau_mpeg_decoder_set_property (GObject * object, - guint prop_id, const GValue * value, GParamSpec * pspec); -static void gst_vdpau_mpeg_decoder_get_property (GObject * object, - guint prop_id, GValue * value, GParamSpec * pspec); - -static gboolean -gst_vdpau_mpeg_decoder_set_caps (GstVdpauDecoder * dec, GstCaps * caps) -{ - GstVdpauMpegDecoder *mpeg_dec; - GstStructure *structure; - const GValue *value; - GstBuffer *codec_data; - MPEGSeqHdr hdr = { 0, }; - VdpDecoderProfile profile; - GstVdpauDevice *device; - VdpStatus status; - - mpeg_dec = GST_VDPAU_MPEG_DECODER (dec); - - structure = gst_caps_get_structure (caps, 0); - gst_structure_get_int (structure, "mpegversion", &mpeg_dec->version); - if (mpeg_dec->version == 1) - profile = VDP_DECODER_PROFILE_MPEG1; - - value = gst_structure_get_value (structure, "codec_data"); - codec_data = gst_value_get_buffer (value); - mpeg_util_parse_sequence_hdr (&hdr, GST_BUFFER_DATA (codec_data), - GST_BUFFER_DATA (codec_data) + GST_BUFFER_SIZE (codec_data)); - if (mpeg_dec->version != 1) { - switch (hdr.profile) { - case 5: - profile = VDP_DECODER_PROFILE_MPEG2_SIMPLE; - break; - default: - profile = VDP_DECODER_PROFILE_MPEG2_MAIN; - break; - } - } - - memcpy (&mpeg_dec->vdp_info.intra_quantizer_matrix, - &hdr.intra_quantizer_matrix, 64); - memcpy (&mpeg_dec->vdp_info.non_intra_quantizer_matrix, - &hdr.non_intra_quantizer_matrix, 64); - - device = dec->device; - status = device->vdp_decoder_create (device->device, profile, dec->width, - dec->height, 2, &mpeg_dec->decoder); - if (status != VDP_STATUS_OK) { - GST_ELEMENT_ERROR (mpeg_dec, RESOURCE, READ, - ("Could not create vdpau decoder"), - ("Error returned from vdpau was: %s", - device->vdp_get_error_string (status))); - return FALSE; - } - return TRUE; -} - -static GstFlowReturn -gst_vdpau_mpeg_decoder_decode (GstVdpauMpegDecoder * mpeg_dec) -{ - GstVdpauDecoder *dec; - GstBuffer *buffer; - GstVdpauVideoBuffer *outbuf; - VdpVideoSurface surface; - GstVdpauDevice *device; - VdpBitstreamBuffer vbit[1]; - VdpStatus status; - GstFlowReturn ret; - - dec = GST_VDPAU_DECODER (mpeg_dec); - - buffer = gst_adapter_take_buffer (mpeg_dec->adapter, - gst_adapter_available (mpeg_dec->adapter)); - - outbuf = gst_vdpau_video_buffer_new (dec->device, VDP_CHROMA_TYPE_420, - dec->width, dec->height); - surface = outbuf->surface; - - device = dec->device; - - vbit[0].struct_version = VDP_BITSTREAM_BUFFER_VERSION; - vbit[0].bitstream = GST_BUFFER_DATA (buffer); - vbit[0].bitstream_bytes = GST_BUFFER_SIZE (buffer); - - status = device->vdp_decoder_render (mpeg_dec->decoder, surface, - (VdpPictureInfo *) & mpeg_dec->vdp_info, 1, vbit); - gst_buffer_unref (buffer); - mpeg_dec->vdp_info.slice_count = 0; - - if (status != VDP_STATUS_OK) { - GST_ELEMENT_ERROR (mpeg_dec, RESOURCE, READ, - ("Could not decode"), - ("Error returned from vdpau was: %s", - device->vdp_get_error_string (status))); - - if (mpeg_dec->vdp_info.forward_reference != VDP_INVALID_HANDLE) { - gst_buffer_unref (mpeg_dec->f_buffer); - mpeg_dec->vdp_info.forward_reference = VDP_INVALID_HANDLE; - } - - gst_buffer_unref (GST_BUFFER (outbuf)); - - return GST_FLOW_ERROR; - } - - gst_buffer_ref (GST_BUFFER (outbuf)); - - ret = gst_vdpau_decoder_push_video_buffer (GST_VDPAU_DECODER (mpeg_dec), - outbuf); - - if (mpeg_dec->vdp_info.forward_reference != VDP_INVALID_HANDLE) - gst_buffer_unref (mpeg_dec->f_buffer); - - mpeg_dec->vdp_info.forward_reference = surface; - mpeg_dec->f_buffer = GST_BUFFER (outbuf); - - return ret; -} - -static gboolean -gst_vdpau_mpeg_decoder_parse_picture_coding (GstVdpauMpegDecoder * mpeg_dec, - guint8 * data, guint8 * end) -{ - GstVdpauDecoder *dec; - MPEGPictureExt pic_ext; - VdpPictureInfoMPEG1Or2 *info; - - dec = GST_VDPAU_DECODER (mpeg_dec); - info = &mpeg_dec->vdp_info; - - if (!mpeg_util_parse_picture_coding_extension (&pic_ext, data, end)) - return FALSE; - - memcpy (&mpeg_dec->vdp_info.f_code, &pic_ext.f_code, 4); - - info->intra_dc_precision = pic_ext.intra_dc_precision; - info->picture_structure = pic_ext.picture_structure; - info->top_field_first = pic_ext.top_field_first; - info->frame_pred_frame_dct = pic_ext.frame_pred_frame_dct; - info->concealment_motion_vectors = pic_ext.concealment_motion_vectors; - info->q_scale_type = pic_ext.q_scale_type; - info->intra_vlc_format = pic_ext.intra_vlc_format; - - mpeg_dec->want_slice = TRUE; - - return TRUE; -} - -static gboolean -gst_vdpau_mpeg_decoder_parse_sequence (GstVdpauMpegDecoder * mpeg_dec, - guint8 * data, guint8 * end) -{ - GstVdpauDecoder *dec; - MPEGSeqHdr hdr; - - dec = GST_VDPAU_DECODER (mpeg_dec); - - if (!mpeg_util_parse_sequence_hdr (&hdr, data, end)) - return FALSE; - - memcpy (&mpeg_dec->vdp_info.intra_quantizer_matrix, - &hdr.intra_quantizer_matrix, 64); - memcpy (&mpeg_dec->vdp_info.non_intra_quantizer_matrix, - &hdr.non_intra_quantizer_matrix, 64); - - return TRUE; -} - -static gboolean -gst_vdpau_mpeg_decoder_parse_picture (GstVdpauMpegDecoder * mpeg_dec, - guint8 * data, guint8 * end) -{ - GstVdpauDecoder *dec; - MPEGPictureHdr pic_hdr; - - dec = GST_VDPAU_DECODER (mpeg_dec); - - if (!mpeg_util_parse_picture_hdr (&pic_hdr, data, end)) - return FALSE; - - mpeg_dec->vdp_info.picture_coding_type = pic_hdr.pic_type; - - - if (pic_hdr.pic_type == I_FRAME && - mpeg_dec->vdp_info.forward_reference != VDP_INVALID_HANDLE) { - gst_buffer_unref (mpeg_dec->f_buffer); - mpeg_dec->vdp_info.forward_reference = VDP_INVALID_HANDLE; - } - - if (mpeg_dec->version == 1) { - mpeg_dec->vdp_info.full_pel_forward_vector = - pic_hdr.full_pel_forward_vector; - mpeg_dec->vdp_info.full_pel_backward_vector = - pic_hdr.full_pel_backward_vector; - memcpy (&mpeg_dec->vdp_info.f_code, &pic_hdr.f_code, 4); - - mpeg_dec->want_slice = TRUE; - } else - mpeg_dec->want_slice = FALSE; - - return TRUE; -} - -static gboolean -gst_vdpau_mpeg_decoder_parse_gop (GstVdpauMpegDecoder * mpeg_dec, guint8 * data, - guint8 * end) -{ - MPEGPictureGOP gop; - - if (!mpeg_util_parse_picture_gop (&gop, data, end)) - return FALSE; - - return TRUE; -} - -static gboolean -gst_vdpau_mpeg_decoder_parse_quant_matrix (GstVdpauMpegDecoder * mpeg_dec, - guint8 * data, guint8 * end) -{ - MPEGQuantMatrix qm; - - if (!mpeg_util_parse_quant_matrix (&qm, data, end)) - return FALSE; - - memcpy (&mpeg_dec->vdp_info.intra_quantizer_matrix, - &qm.intra_quantizer_matrix, 64); - memcpy (&mpeg_dec->vdp_info.non_intra_quantizer_matrix, - &qm.non_intra_quantizer_matrix, 64); - return TRUE; -} - -static GstFlowReturn -gst_vdpau_mpeg_decoder_chain (GstPad * pad, GstBuffer * buffer) -{ - GstVdpauMpegDecoder *mpeg_dec; - guint8 *data, *end; - guint32 sync_word = 0xffffffff; - - mpeg_dec = GST_VDPAU_MPEG_DECODER (GST_OBJECT_PARENT (pad)); - - data = GST_BUFFER_DATA (buffer); - end = GST_BUFFER_DATA (buffer) + GST_BUFFER_SIZE (buffer); - - while ((data = mpeg_util_find_start_code (&sync_word, data, end))) { - guint8 *packet_start; - guint8 *packet_end; - - packet_start = data - 3; - packet_end = mpeg_util_find_start_code (&sync_word, data, end); - if (packet_end) - packet_end -= 3; - else - packet_end = end; - - if (data[0] >= MPEG_PACKET_SLICE_MIN && data[0] <= MPEG_PACKET_SLICE_MAX) { - GstBuffer *subbuf; - - GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_SLICE"); - if (mpeg_dec->want_slice) { - subbuf = - gst_buffer_create_sub (buffer, - packet_start - GST_BUFFER_DATA (buffer), packet_end - packet_start); - gst_adapter_push (mpeg_dec->adapter, subbuf); - mpeg_dec->vdp_info.slice_count++; - } - } - - switch (data[0]) { - case MPEG_PACKET_PICTURE: - GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_PICTURE"); - if (mpeg_dec->vdp_info.slice_count > 0 && mpeg_dec->want_slice) { - if (gst_vdpau_mpeg_decoder_decode (mpeg_dec) != GST_FLOW_OK) - return GST_FLOW_ERROR; - } - gst_vdpau_mpeg_decoder_parse_picture (mpeg_dec, packet_start, - packet_end); - break; - case MPEG_PACKET_SEQUENCE: - GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_SEQUENCE"); - gst_vdpau_mpeg_decoder_parse_sequence (mpeg_dec, packet_start, - packet_end); - break; - case MPEG_PACKET_EXTENSION: - GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_EXTENSION"); - switch (read_bits (data + 1, 0, 4)) { - case MPEG_PACKET_EXT_PICTURE_CODING: - gst_vdpau_mpeg_decoder_parse_picture_coding (mpeg_dec, packet_start, - packet_end); - break; - default: - break; - } - break; - case MPEG_PACKET_EXT_QUANT_MATRIX: - GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_EXT_QUANT_MATRIX"); - gst_vdpau_mpeg_decoder_parse_quant_matrix (mpeg_dec, packet_start, - packet_end); - break; - case MPEG_PACKET_GOP: - GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_GOP"); - gst_vdpau_mpeg_decoder_parse_gop (mpeg_dec, packet_start, packet_end); - break; - default: - break; - } - } - - return GST_FLOW_OK; -} - -/* GObject vmethod implementations */ - -static void -gst_vdpau_mpeg_decoder_base_init (gpointer gclass) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS (gclass); - - gst_element_class_set_details_simple (element_class, - "VdpauMpegDecoder", - "Decoder", - "decode mpeg stream with vdpau", - "Carl-Anton Ingmarsson "); - - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&sink_factory)); -} - -/* initialize the vdpaumpegdecoder's class */ -static void -gst_vdpau_mpeg_decoder_class_init (GstVdpauMpegDecoderClass * klass) -{ - GObjectClass *gobject_class; - GstElementClass *gstelement_class; - GstVdpauDecoderClass *vdpaudec_class; - - gobject_class = (GObjectClass *) klass; - gstelement_class = (GstElementClass *) klass; - vdpaudec_class = (GstVdpauDecoderClass *) klass; - - gobject_class->finalize = gst_vdpau_mpeg_decoder_finalize; - gobject_class->set_property = gst_vdpau_mpeg_decoder_set_property; - gobject_class->get_property = gst_vdpau_mpeg_decoder_get_property; - - vdpaudec_class->set_caps = gst_vdpau_mpeg_decoder_set_caps; -} - -static void -gst_vdpau_mpeg_decoder_init_info (VdpPictureInfoMPEG1Or2 * vdp_info) -{ - vdp_info->forward_reference = VDP_INVALID_HANDLE; - vdp_info->backward_reference = VDP_INVALID_HANDLE; - vdp_info->slice_count = 0; - vdp_info->picture_structure = 0; - vdp_info->picture_coding_type = 0; - vdp_info->intra_dc_precision = 0; - vdp_info->frame_pred_frame_dct = 0; - vdp_info->concealment_motion_vectors = 0; -} - -static void -gst_vdpau_mpeg_decoder_init (GstVdpauMpegDecoder * mpeg_dec, - GstVdpauMpegDecoderClass * gclass) -{ - GstVdpauDecoder *dec; - - dec = GST_VDPAU_DECODER (mpeg_dec); - - mpeg_dec->decoder = VDP_INVALID_HANDLE; - gst_vdpau_mpeg_decoder_init_info (&mpeg_dec->vdp_info); - - mpeg_dec->adapter = gst_adapter_new (); - - mpeg_dec->want_slice = FALSE; - - gst_pad_set_chain_function (dec->sink, gst_vdpau_mpeg_decoder_chain); -} - -static void -gst_vdpau_mpeg_decoder_finalize (GObject * object) -{ - GstVdpauMpegDecoder *mpeg_dec = (GstVdpauMpegDecoder *) object; - - g_object_unref (mpeg_dec->adapter); -} - -static void -gst_vdpau_mpeg_decoder_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) -{ - switch (prop_id) { - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_vdpau_mpeg_decoder_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec) -{ - switch (prop_id) { - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} diff --git a/sys/vdpau/gstvdpaumpegdecoder.h b/sys/vdpau/gstvdpaumpegdecoder.h deleted file mode 100644 index 785c0c15..00000000 --- a/sys/vdpau/gstvdpaumpegdecoder.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * GStreamer - * Copyright (C) 2009 Carl-Anton Ingmarsson - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __GST_VDPAU_MPEG_DECODER_H__ -#define __GST_VDPAU_MPEG_DECODER_H__ - -#include -#include - -#include "gstvdpaudecoder.h" - -G_BEGIN_DECLS - -#define GST_TYPE_VDPAU_MPEG_DECODER (gst_vdpau_mpeg_decoder_get_type()) -#define GST_VDPAU_MPEG_DECODER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VDPAU_MPEG_DECODER,GstVdpauMpegDecoder)) -#define GST_VDPAU_MPEG_DECODER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VDPAU_MPEG_DECODER,GstVdpauMpegDecoderClass)) -#define GST_IS_VDPAU_MPEG_DECODER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VDPAU_MPEG_DECODER)) -#define GST_IS_VDPAU_MPEG_DECODER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VDPAU_MPEG_DECODER)) - -typedef struct _GstVdpauMpegDecoder GstVdpauMpegDecoder; -typedef struct _GstVdpauMpegDecoderClass GstVdpauMpegDecoderClass; - -struct _GstVdpauMpegDecoder -{ - GstVdpauDecoder dec; - - gint version; - - VdpDecoder decoder; - VdpPictureInfoMPEG1Or2 vdp_info; - GstBuffer *f_buffer; - - gboolean want_slice; - - GstAdapter *adapter; - gint slices; -}; - -struct _GstVdpauMpegDecoderClass -{ - GstVdpauDecoderClass parent_class; -}; - -GType gst_vdpau_mpeg_decoder_get_type (void); - -G_END_DECLS - -#endif /* __GST_VDPAU_MPEG_DECODER_H__ */ diff --git a/sys/vdpau/gstvdpauvideobuffer.c b/sys/vdpau/gstvdpauvideobuffer.c deleted file mode 100644 index f7ece0eb..00000000 --- a/sys/vdpau/gstvdpauvideobuffer.c +++ /dev/null @@ -1,114 +0,0 @@ -/* - * GStreamer - * Copyright (C) 2009 Carl-Anton Ingmarsson - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "gstvdpauvideobuffer.h" - -static GObjectClass *gst_vdpau_video_buffer_parent_class; - -static void -gst_vdpau_video_buffer_finalize (GstVdpauVideoBuffer * buffer) -{ - GstVdpauDevice *device = buffer->device; - VdpStatus status; - - status = device->vdp_video_surface_destroy (buffer->surface); - if (status != VDP_STATUS_OK) - GST_ERROR - ("Couldn't destroy the buffers VdpVideoSurface, error returned was: %s", - device->vdp_get_error_string (status)); - - g_object_unref (buffer->device); - - GST_MINI_OBJECT_CLASS (gst_vdpau_video_buffer_parent_class)->finalize - (GST_MINI_OBJECT (buffer)); -} - -static void -gst_vdpau_video_buffer_init (GstVdpauVideoBuffer * buffer, gpointer g_class) -{ - buffer->device = NULL; - buffer->surface = VDP_INVALID_HANDLE; -} - -static void -gst_vdpau_video_buffer_class_init (gpointer g_class, gpointer class_data) -{ - GstMiniObjectClass *mini_object_class = GST_MINI_OBJECT_CLASS (g_class); - - gst_vdpau_video_buffer_parent_class = g_type_class_peek_parent (g_class); - - mini_object_class->finalize = (GstMiniObjectFinalizeFunction) - gst_vdpau_video_buffer_finalize; -} - - -GType -gst_vdpau_video_buffer_get_type (void) -{ - static GType _gst_vdpau_video_buffer_type; - - if (G_UNLIKELY (_gst_vdpau_video_buffer_type == 0)) { - static const GTypeInfo info = { - sizeof (GstBufferClass), - NULL, - NULL, - gst_vdpau_video_buffer_class_init, - NULL, - NULL, - sizeof (GstVdpauVideoBuffer), - 0, - (GInstanceInitFunc) gst_vdpau_video_buffer_init, - NULL - }; - _gst_vdpau_video_buffer_type = g_type_register_static (GST_TYPE_BUFFER, - "GstVdpauVideoBuffer", &info, 0); - } - return _gst_vdpau_video_buffer_type; -} - - -GstVdpauVideoBuffer * -gst_vdpau_video_buffer_new (GstVdpauDevice * device, VdpChromaType chroma_type, - gint width, gint height) -{ - GstVdpauVideoBuffer *buffer; - VdpStatus status; - VdpVideoSurface surface; - - status = device->vdp_video_surface_create (device->device, chroma_type, width, - height, &surface); - if (status != VDP_STATUS_OK) { - GST_ERROR ("Couldn't create a VdpVideoSurface, error returned was: %s", - device->vdp_get_error_string (status)); - return NULL; - } - - buffer = - (GstVdpauVideoBuffer *) gst_mini_object_new (GST_TYPE_VDPAU_VIDEO_BUFFER); - - buffer->device = g_object_ref (device); - buffer->surface = surface; - - return buffer; -} diff --git a/sys/vdpau/gstvdpauvideobuffer.h b/sys/vdpau/gstvdpauvideobuffer.h deleted file mode 100644 index fe2b4b7f..00000000 --- a/sys/vdpau/gstvdpauvideobuffer.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * GStreamer - * Copyright (C) 2009 Carl-Anton Ingmarsson - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef _GST_VDPAU_VIDEO_BUFFER_H_ -#define _GST_VDPAU_VIDEO_BUFFER_H_ - -#include -#include - -#include "gstvdpaudevice.h" - -#include "gstvdpauvideobuffer.h" - -typedef struct _GstVdpauVideoBuffer GstVdpauVideoBuffer; - -#define GST_TYPE_VDPAU_VIDEO_BUFFER (gst_vdpau_video_buffer_get_type()) - -#define GST_IS_VDPAU_VIDEO_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VDPAU_VIDEO_BUFFER)) -#define GST_VDPAU_VIDEO_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VDPAU_VIDEO_BUFFER, GstVdpauVideoBuffer)) - -struct _GstVdpauVideoBuffer { - GstBuffer buffer; - - GstVdpauDevice *device; - VdpVideoSurface surface; -}; - -GType gst_vdpau_video_buffer_get_type (void); - -GstVdpauVideoBuffer* gst_vdpau_video_buffer_new (GstVdpauDevice * device, VdpChromaType chroma_type, gint width, gint height); - -#define GST_VDPAU_VIDEO_CAPS \ - "video/vdpau-video, " \ - "chroma-type = (int)[0,2], " \ - "width = (int)[1,4096], " \ - "height = (int)[1,4096]" - -#endif diff --git a/sys/vdpau/gstvdpauvideoyuv.c b/sys/vdpau/gstvdpauvideoyuv.c deleted file mode 100644 index 879e4562..00000000 --- a/sys/vdpau/gstvdpauvideoyuv.c +++ /dev/null @@ -1,446 +0,0 @@ -/* - * GStreamer - * Copyright (C) 2009 Carl-Anton Ingmarsson - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include - -#include "gstvdpauvideobuffer.h" -#include "gstvdpauvideoyuv.h" - -GST_DEBUG_CATEGORY_STATIC (gst_vdpau_video_yuv_debug); -#define GST_CAT_DEFAULT gst_vdpau_video_yuv_debug - -/* Filter signals and args */ -enum -{ - /* FILL ME */ - LAST_SIGNAL -}; - -enum -{ - PROP_0 -}; - -static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS (GST_VDPAU_VIDEO_CAPS)); - -static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("video/x-raw-yuv, " - "framerate = (fraction) [ 0, MAX ], " - "width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ]")); - -#define DEBUG_INIT(bla) \ - GST_DEBUG_CATEGORY_INIT (gst_vdpau_video_yuv_debug, "vdpauvideoyuv", 0, "VDPAU VdpSurface to YUV"); - -GST_BOILERPLATE_FULL (GstVdpauVideoYUV, gst_vdpau_video_yuv, GstElement, - GST_TYPE_ELEMENT, DEBUG_INIT); - -static void gst_vdpau_video_yuv_finalize (GObject * object); -static void gst_vdpau_video_yuv_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec); -static void gst_vdpau_video_yuv_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec); - -GstFlowReturn -gst_vdpau_video_yuv_chain (GstPad * pad, GstBuffer * buffer) -{ - GstVdpauVideoYUV *video_yuv; - GstVdpauDevice *device; - VdpVideoSurface surface; - GstBuffer *outbuf = NULL; - - video_yuv = GST_VDPAU_VIDEO_YUV (GST_OBJECT_PARENT (pad)); - device = GST_VDPAU_VIDEO_BUFFER (buffer)->device; - surface = GST_VDPAU_VIDEO_BUFFER (buffer)->surface; - - switch (video_yuv->format) { - case GST_MAKE_FOURCC ('Y', 'V', '1', '2'): - { - gint size; - GstFlowReturn result; - VdpStatus status; - guint8 *data[3]; - guint32 stride[3]; - - size = - gst_video_format_get_size (GST_VIDEO_FORMAT_YV12, video_yuv->width, - video_yuv->height); - result = - gst_pad_alloc_buffer_and_set_caps (video_yuv->src, - GST_BUFFER_OFFSET_NONE, size, GST_PAD_CAPS (video_yuv->src), &outbuf); - if (G_UNLIKELY (result != GST_FLOW_OK)) - return result; - - data[0] = GST_BUFFER_DATA (outbuf) + - gst_video_format_get_component_offset (GST_VIDEO_FORMAT_YV12, - 0, video_yuv->width, video_yuv->height); - data[1] = GST_BUFFER_DATA (outbuf) + - gst_video_format_get_component_offset (GST_VIDEO_FORMAT_YV12, - 2, video_yuv->width, video_yuv->height); - data[2] = GST_BUFFER_DATA (outbuf) + - gst_video_format_get_component_offset (GST_VIDEO_FORMAT_YV12, - 1, video_yuv->width, video_yuv->height); - - stride[0] = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_YV12, - 0, video_yuv->width); - stride[1] = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_YV12, - 2, video_yuv->width); - stride[2] = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_YV12, - 1, video_yuv->width); - - status = - device->vdp_video_surface_get_bits_ycbcr (surface, - VDP_YCBCR_FORMAT_YV12, (void *) data, stride); - if (G_UNLIKELY (status != VDP_STATUS_OK)) { - GST_ELEMENT_ERROR (video_yuv, RESOURCE, READ, - ("Couldn't get data from vdpau"), - ("Error returned from vdpau was: %s", - device->vdp_get_error_string (status))); - goto error; - } - break; - } - case GST_MAKE_FOURCC ('I', '4', '2', '0'): - { - gint size; - GstFlowReturn result; - VdpStatus status; - guint8 *data[3]; - guint32 stride[3]; - - size = - gst_video_format_get_size (GST_VIDEO_FORMAT_YV12, video_yuv->width, - video_yuv->height); - result = - gst_pad_alloc_buffer_and_set_caps (video_yuv->src, - GST_BUFFER_OFFSET_NONE, size, GST_PAD_CAPS (video_yuv->src), &outbuf); - if (G_UNLIKELY (result != GST_FLOW_OK)) - return result; - - data[0] = GST_BUFFER_DATA (outbuf) + - gst_video_format_get_component_offset (GST_VIDEO_FORMAT_I420, - 0, video_yuv->width, video_yuv->height); - data[1] = GST_BUFFER_DATA (outbuf) + - gst_video_format_get_component_offset (GST_VIDEO_FORMAT_I420, - 2, video_yuv->width, video_yuv->height); - data[2] = GST_BUFFER_DATA (outbuf) + - gst_video_format_get_component_offset (GST_VIDEO_FORMAT_I420, - 1, video_yuv->width, video_yuv->height); - - stride[0] = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_I420, - 0, video_yuv->width); - stride[1] = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_I420, - 2, video_yuv->width); - stride[2] = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_I420, - 1, video_yuv->width); - - status = - device->vdp_video_surface_get_bits_ycbcr (surface, - VDP_YCBCR_FORMAT_YV12, (void *) data, stride); - if (G_UNLIKELY (status != VDP_STATUS_OK)) { - GST_ELEMENT_ERROR (video_yuv, RESOURCE, READ, - ("Couldn't get data from vdpau"), - ("Error returned from vdpau was: %s", - device->vdp_get_error_string (status))); - goto error; - } - break; - } - case GST_MAKE_FOURCC ('N', 'V', '1', '2'): - { - gint size; - GstFlowReturn result; - VdpStatus status; - guint8 *data[2]; - guint32 stride[2]; - - size = - video_yuv->width * video_yuv->height + - video_yuv->width * video_yuv->height / 2; - result = - gst_pad_alloc_buffer_and_set_caps (video_yuv->src, - GST_BUFFER_OFFSET_NONE, size, GST_PAD_CAPS (video_yuv->src), &outbuf); - if (G_UNLIKELY (result != GST_FLOW_OK)) - return result; - - - data[0] = GST_BUFFER_DATA (outbuf); - data[1] = GST_BUFFER_DATA (outbuf) + video_yuv->width * video_yuv->height; - - stride[0] = video_yuv->width; - stride[1] = video_yuv->width; - - status = - device->vdp_video_surface_get_bits_ycbcr (surface, - VDP_YCBCR_FORMAT_NV12, (void *) data, stride); - if (G_UNLIKELY (status != VDP_STATUS_OK)) { - GST_ELEMENT_ERROR (video_yuv, RESOURCE, READ, - ("Couldn't get data from vdpau"), - ("Error returned from vdpau was: %s", - device->vdp_get_error_string (status))); - goto error; - } - break; - } - default: - break; - } - - gst_buffer_unref (buffer); - - gst_buffer_copy_metadata (outbuf, buffer, GST_BUFFER_COPY_TIMESTAMPS); - return gst_pad_push (video_yuv->src, outbuf); - -error: - gst_buffer_unref (outbuf); - return GST_FLOW_ERROR; -} - -static GstCaps * -gst_vdpau_video_yuv_get_caps (GstVdpauVideoYUV * video_yuv, - GstVdpauDevice * device, gint chroma_type, gint width, gint height, - gint framerate_numerator, gint framerate_denominator, gint par_numerator, - gint par_denominator) -{ - GstCaps *caps; - gint i; - - caps = gst_caps_new_empty (); - - for (i = 0; i < N_FORMATS; i++) { - VdpStatus status; - VdpBool is_supported; - - if (formats[i].chroma_type != chroma_type) - continue; - - status = - device->vdp_video_surface_query_ycbcr_capabilities (device->device, - chroma_type, formats[i].format, &is_supported); - if (status != VDP_STATUS_OK && status != VDP_STATUS_INVALID_Y_CB_CR_FORMAT) { - GST_ELEMENT_ERROR (video_yuv, RESOURCE, READ, - ("Could not query VDPAU YCbCr capabilites"), - ("Error returned from vdpau was: %s", - device->vdp_get_error_string (status))); - - return NULL; - } - if (is_supported) { - GstCaps *format_caps; - - format_caps = gst_caps_new_simple ("video/x-raw-yuv", - "format", GST_TYPE_FOURCC, formats[i].fourcc, - "width", G_TYPE_INT, width, - "height", G_TYPE_INT, height, - "framerate", GST_TYPE_FRACTION, framerate_numerator, - framerate_denominator, "pixel-aspect-ratio", GST_TYPE_FRACTION, - par_numerator, par_denominator, NULL); - gst_caps_append (caps, format_caps); - } - } - - if (gst_caps_is_empty (caps)) { - gst_caps_unref (caps); - return NULL; - } - - return caps; -} - -static gboolean -gst_vdpau_video_yuv_sink_set_caps (GstPad * pad, GstCaps * caps) -{ - GstVdpauVideoYUV *video_yuv = GST_VDPAU_VIDEO_YUV (GST_OBJECT_PARENT (pad)); - - GstCaps *src_caps, *new_caps; - GstStructure *structure; - const GValue *value; - GstVdpauDevice *device; - gint chroma_type; - gint width, height; - gint framerate_numerator, framerate_denominator; - gint par_numerator, par_denominator; - guint32 fourcc_format; - gboolean res; - - structure = gst_caps_get_structure (caps, 0); - value = gst_structure_get_value (structure, "device"); - device = g_value_get_object (value); - - gst_structure_get_int (structure, "chroma-type", &chroma_type); - gst_structure_get_int (structure, "width", &width); - gst_structure_get_int (structure, "height", &height); - gst_structure_get_fraction (structure, "framerate", - &framerate_numerator, &framerate_denominator); - gst_structure_get_fraction (structure, "pixel-aspect-ratio", - &par_numerator, &par_denominator); - - src_caps = - gst_vdpau_video_yuv_get_caps (video_yuv, device, chroma_type, width, - height, framerate_numerator, framerate_denominator, par_numerator, - par_denominator); - if (G_UNLIKELY (!src_caps)) - return FALSE; - - video_yuv->src_caps = src_caps; - - src_caps = gst_pad_get_allowed_caps (video_yuv->src); - if (G_UNLIKELY (!src_caps || !gst_caps_get_size (src_caps))) - return FALSE; - - new_caps = gst_caps_copy_nth (src_caps, 0); - gst_caps_unref (src_caps); - if (G_UNLIKELY (!new_caps)) - return FALSE; - - structure = gst_caps_get_structure (new_caps, 0); - gst_structure_get_fourcc (structure, "format", &fourcc_format); - - gst_pad_fixate_caps (video_yuv->src, new_caps); - res = gst_pad_set_caps (video_yuv->src, new_caps); - - gst_caps_unref (new_caps); - - if (G_UNLIKELY (!res)) - return FALSE; - - video_yuv->width = width; - video_yuv->height = height; - video_yuv->framerate_numerator = framerate_numerator; - video_yuv->framerate_denominator = framerate_denominator; - video_yuv->format = fourcc_format; - - return TRUE; -} - -static GstCaps * -gst_vdpau_video_yuv_src_getcaps (GstPad * pad) -{ - GstVdpauVideoYUV *video_yuv; - - video_yuv = GST_VDPAU_VIDEO_YUV (GST_OBJECT_PARENT (pad)); - - if (video_yuv->src_caps) - return gst_caps_copy (video_yuv->src_caps); - - if (GST_PAD_CAPS (video_yuv->src)) - return gst_caps_copy (GST_PAD_CAPS (video_yuv->src)); - - return gst_caps_copy (gst_pad_get_pad_template_caps (video_yuv->src)); -} - -/* GObject vmethod implementations */ - -static void -gst_vdpau_video_yuv_base_init (gpointer klass) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS (klass); - - gst_element_class_set_details_simple (element_class, - "VdpauVideoYUV", - "Covideo_yuv/Decoder/Video", - "VDPAU video surface to YUV", - "Carl-Anton Ingmarsson "); - - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&sink_template)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&src_template)); -} - -static void -gst_vdpau_video_yuv_class_init (GstVdpauVideoYUVClass * klass) -{ - GObjectClass *gobject_class; - GstElementClass *gstelement_class; - - gobject_class = (GObjectClass *) klass; - gstelement_class = (GstElementClass *) klass; - - gobject_class->finalize = gst_vdpau_video_yuv_finalize; - gobject_class->set_property = gst_vdpau_video_yuv_set_property; - gobject_class->get_property = gst_vdpau_video_yuv_get_property; -} - -static void -gst_vdpau_video_yuv_init (GstVdpauVideoYUV * video_yuv, - GstVdpauVideoYUVClass * klass) -{ - video_yuv->src_caps = NULL; - - video_yuv->height = 0; - video_yuv->width = 0; - video_yuv->framerate_numerator = 0; - video_yuv->framerate_denominator = 0; - video_yuv->par_numerator = 1; - video_yuv->par_denominator = 1; - - video_yuv->src = gst_pad_new_from_static_template (&src_template, "src"); - gst_pad_set_getcaps_function (video_yuv->src, - gst_vdpau_video_yuv_src_getcaps); - gst_element_add_pad (GST_ELEMENT (video_yuv), video_yuv->src); - - video_yuv->sink = gst_pad_new_from_static_template (&sink_template, "sink"); - gst_pad_set_setcaps_function (video_yuv->sink, - gst_vdpau_video_yuv_sink_set_caps); - gst_pad_set_chain_function (video_yuv->sink, gst_vdpau_video_yuv_chain); - gst_element_add_pad (GST_ELEMENT (video_yuv), video_yuv->sink); - gst_pad_set_active (video_yuv->sink, TRUE); -} - -static void -gst_vdpau_video_yuv_finalize (GObject * object) -{ - GstVdpauVideoYUV *video_yuv = (GstVdpauVideoYUV *) object; - - if (video_yuv->src_caps) - gst_caps_unref (video_yuv->src_caps); -} - -static void -gst_vdpau_video_yuv_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) -{ - switch (prop_id) { - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_vdpau_video_yuv_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec) -{ - switch (prop_id) { - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} diff --git a/sys/vdpau/gstvdpauvideoyuv.h b/sys/vdpau/gstvdpauvideoyuv.h deleted file mode 100644 index 477b3067..00000000 --- a/sys/vdpau/gstvdpauvideoyuv.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * GStreamer - * Copyright (C) 2009 Carl-Anton Ingmarsson - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __GST_VDPAU_VIDEO_YUV_H__ -#define __GST_VDPAU_VIDEO_YUV_H__ - -#include - -#include "gstvdpaudevice.h" - -G_BEGIN_DECLS - -#define GST_TYPE_VDPAU_VIDEO_YUV (gst_vdpau_video_yuv_get_type()) -#define GST_VDPAU_VIDEO_YUV(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VDPAU_VIDEO_YUV,GstVdpauVideoYUV)) -#define GST_VDPAU_VIDEO_YUV_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VDPAU_VIDEO_YUV,GstVdpauVideoYUVClass)) -#define GST_VDPAU_VIDEO_YUV_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VDPAU_VIDEO_YUV, GstVdpauVideoYUVClass)) -#define GST_IS_VDPAU_VIDEO_YUV(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VDPAU_VIDEO_YUV)) -#define GST_IS_VDPAU_VIDEO_YUV_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VDPAU_VIDEO_YUV)) - -typedef struct _GstVdpauVideoYUV GstVdpauVideoYUV; -typedef struct _GstVdpauVideoYUVClass GstVdpauVideoYUVClass; - -struct _GstVdpauVideoYUV { - GstElement element; - - GstPad *src, *sink; - GstCaps *src_caps; - - gint width, height; - gint framerate_numerator, framerate_denominator; - gint par_numerator, par_denominator; - guint format; -}; - -struct _GstVdpauVideoYUVClass { - GstElementClass parent_class; -}; - -GType gst_vdpau_video_yuv_get_type (void); - -G_END_DECLS - -#endif /* __GST_VDPAU_VIDEO_YUV_H__ */ diff --git a/sys/vdpau/gstvdpauyuvvideo.c b/sys/vdpau/gstvdpauyuvvideo.c deleted file mode 100644 index a9ccb731..00000000 --- a/sys/vdpau/gstvdpauyuvvideo.c +++ /dev/null @@ -1,478 +0,0 @@ -/* - * GStreamer - * Copyright (C) 2009 Carl-Anton Ingmarsson - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include - -#include "gstvdpauvideobuffer.h" -#include "gstvdpauyuvvideo.h" - -GST_DEBUG_CATEGORY_STATIC (gst_vdpau_yuv_video_debug); -#define GST_CAT_DEFAULT gst_vdpau_yuv_video_debug - -/* Filter signals and args */ -enum -{ - /* FILL ME */ - LAST_SIGNAL -}; - -enum -{ - PROP_0, - PROP_DISPLAY -}; - -static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("video/x-raw-yuv, " - "framerate = (fraction) [ 0, MAX ], " - "width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ]")); - -static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS (GST_VDPAU_VIDEO_CAPS)); - -#define DEBUG_INIT(bla) \ - GST_DEBUG_CATEGORY_INIT (gst_vdpau_yuv_video_debug, "vdpauvideoyuv", 0, "YUV to VDPAU video surface"); - -GST_BOILERPLATE_FULL (GstVdpauYUVVideo, gst_vdpau_yuv_video, GstElement, - GST_TYPE_ELEMENT, DEBUG_INIT); - -static void gst_vdpau_yuv_video_finalize (GObject * object); -static void gst_vdpau_yuv_video_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec); -static void gst_vdpau_yuv_video_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec); - -GstFlowReturn -gst_vdpau_yuv_video_chain (GstPad * pad, GstBuffer * buffer) -{ - GstVdpauYUVVideo *yuv_video; - GstVdpauDevice *device; - VdpVideoSurface surface; - GstBuffer *outbuf = NULL; - - yuv_video = GST_VDPAU_YUV_VIDEO (GST_OBJECT_PARENT (pad)); - device = yuv_video->device; - - outbuf = - GST_BUFFER (gst_vdpau_video_buffer_new (device, yuv_video->chroma_type, - yuv_video->width, yuv_video->height)); - surface = GST_VDPAU_VIDEO_BUFFER (outbuf)->surface; - - switch (yuv_video->format) { - case GST_MAKE_FOURCC ('Y', 'V', '1', '2'): - { - VdpStatus status; - guint8 *data[3]; - guint32 stride[3]; - - data[0] = GST_BUFFER_DATA (buffer) + - gst_video_format_get_component_offset (GST_VIDEO_FORMAT_YV12, - 0, yuv_video->width, yuv_video->height); - data[1] = GST_BUFFER_DATA (buffer) + - gst_video_format_get_component_offset (GST_VIDEO_FORMAT_YV12, - 2, yuv_video->width, yuv_video->height); - data[2] = GST_BUFFER_DATA (buffer) + - gst_video_format_get_component_offset (GST_VIDEO_FORMAT_YV12, - 1, yuv_video->width, yuv_video->height); - - stride[0] = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_YV12, - 0, yuv_video->width); - stride[1] = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_YV12, - 2, yuv_video->width); - stride[2] = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_YV12, - 1, yuv_video->width); - - status = - device->vdp_video_surface_put_bits_ycbcr (surface, - VDP_YCBCR_FORMAT_YV12, (void *) data, stride); - if (G_UNLIKELY (status != VDP_STATUS_OK)) { - GST_ELEMENT_ERROR (yuv_video, RESOURCE, READ, - ("Couldn't push YV12 data to VDPAU"), - ("Error returned from vdpau was: %s", - device->vdp_get_error_string (status))); - goto error; - } - break; - } - case GST_MAKE_FOURCC ('I', '4', '2', '0'): - { - VdpStatus status; - guint8 *data[3]; - guint32 stride[3]; - - data[0] = GST_BUFFER_DATA (buffer) + - gst_video_format_get_component_offset (GST_VIDEO_FORMAT_I420, - 0, yuv_video->width, yuv_video->height); - data[1] = GST_BUFFER_DATA (buffer) + - gst_video_format_get_component_offset (GST_VIDEO_FORMAT_I420, - 2, yuv_video->width, yuv_video->height); - data[2] = GST_BUFFER_DATA (buffer) + - gst_video_format_get_component_offset (GST_VIDEO_FORMAT_I420, - 1, yuv_video->width, yuv_video->height); - - stride[0] = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_I420, - 0, yuv_video->width); - stride[1] = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_I420, - 2, yuv_video->width); - stride[2] = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_I420, - 1, yuv_video->width); - - status = - device->vdp_video_surface_put_bits_ycbcr (surface, - VDP_YCBCR_FORMAT_YV12, (void *) data, stride); - if (G_UNLIKELY (status != VDP_STATUS_OK)) { - GST_ELEMENT_ERROR (yuv_video, RESOURCE, READ, - ("Couldn't push YV12 data to VDPAU"), - ("Error returned from vdpau was: %s", - device->vdp_get_error_string (status))); - goto error; - } - break; - } - case GST_MAKE_FOURCC ('N', 'V', '1', '2'): - { - VdpStatus status; - guint8 *data[2]; - guint32 stride[2]; - - data[0] = GST_BUFFER_DATA (buffer); - data[1] = GST_BUFFER_DATA (buffer) + yuv_video->width * yuv_video->height; - - stride[0] = yuv_video->width; - stride[1] = yuv_video->width; - - status = - device->vdp_video_surface_put_bits_ycbcr (surface, - VDP_YCBCR_FORMAT_NV12, (void *) data, stride); - if (G_UNLIKELY (status != VDP_STATUS_OK)) { - GST_ELEMENT_ERROR (yuv_video, RESOURCE, READ, - ("Couldn't get data from vdpau"), - ("Error returned from vdpau was: %s", - device->vdp_get_error_string (status))); - goto error; - } - break; - } - default: - break; - } - - gst_buffer_unref (buffer); - - gst_buffer_copy_metadata (outbuf, buffer, GST_BUFFER_COPY_TIMESTAMPS); - gst_buffer_set_caps (outbuf, GST_PAD_CAPS (yuv_video->src)); - - return gst_pad_push (yuv_video->src, outbuf); - -error: - gst_buffer_unref (outbuf); - return GST_FLOW_ERROR; -} - -static GstCaps * -gst_vdpau_yuv_video_get_caps (GstVdpauYUVVideo * yuv_video) -{ - GstVdpauDevice *device; - GstCaps *caps; - gint i; - - device = yuv_video->device; - - caps = gst_caps_new_empty (); - - for (i = 0; i < N_CHROMA_TYPES; i++) { - VdpStatus status; - VdpBool is_supported; - guint32 max_w, max_h; - - status = - device->vdp_video_surface_query_capabilities (device->device, - chroma_types[i], &is_supported, &max_w, &max_h); - - if (status != VDP_STATUS_OK && status != VDP_STATUS_INVALID_CHROMA_TYPE) { - GST_ELEMENT_ERROR (yuv_video, RESOURCE, READ, - ("Could not get query VDPAU video surface capabilites"), - ("Error returned from vdpau was: %s", - device->vdp_get_error_string (status))); - - goto error; - } - if (is_supported) { - gint j; - - for (j = 0; j < N_FORMATS; j++) { - if (formats[j].chroma_type != chroma_types[i]) - continue; - - status = - device->vdp_video_surface_query_ycbcr_capabilities (device->device, - formats[j].chroma_type, formats[j].format, &is_supported); - if (status != VDP_STATUS_OK - && status != VDP_STATUS_INVALID_Y_CB_CR_FORMAT) { - GST_ELEMENT_ERROR (yuv_video, RESOURCE, READ, - ("Could not query VDPAU YCbCr capabilites"), - ("Error returned from vdpau was: %s", - device->vdp_get_error_string (status))); - - goto error; - } - if (is_supported) { - GstCaps *format_caps; - - format_caps = gst_caps_new_simple ("video/x-raw-yuv", - "format", GST_TYPE_FOURCC, formats[j].fourcc, - "width", GST_TYPE_INT_RANGE, 1, max_w, - "height", GST_TYPE_INT_RANGE, 1, max_h, - "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL); - gst_caps_append (caps, format_caps); - } - } - } - } -error: - if (gst_caps_is_empty (caps)) { - gst_caps_unref (caps); - return NULL; - } - - return caps; -} - -static gboolean -gst_vdpau_yuv_video_sink_setcaps (GstPad * pad, GstCaps * caps) -{ - GstVdpauYUVVideo *yuv_video = GST_VDPAU_YUV_VIDEO (GST_OBJECT_PARENT (pad)); - - GstStructure *structure; - guint32 fourcc; - gint chroma_type = 0; - gint width, height; - gint framerate_numerator, framerate_denominator; - gint par_numerator, par_denominator; - gint i; - GstCaps *src_caps, *new_caps; - gboolean res; - - structure = gst_caps_get_structure (caps, 0); - - gst_structure_get_fourcc (structure, "format", &fourcc); - gst_structure_get_int (structure, "width", &width); - gst_structure_get_int (structure, "height", &height); - gst_structure_get_fraction (structure, "framerate", - &framerate_numerator, &framerate_denominator); - gst_structure_get_fraction (structure, "pixel-aspect-ratio", - &par_numerator, &par_denominator); - - for (i = 0; i < N_FORMATS; i++) { - if (formats[i].fourcc == fourcc) { - chroma_type = formats[i].chroma_type; - break; - } - } - - src_caps = gst_pad_get_allowed_caps (yuv_video->src); - if (G_UNLIKELY (!src_caps || !gst_caps_get_size (src_caps))) - return FALSE; - - new_caps = gst_caps_copy_nth (src_caps, 0); - gst_caps_unref (src_caps); - if (G_UNLIKELY (!new_caps)) - return FALSE; - - structure = gst_caps_get_structure (new_caps, 0); - - gst_structure_set (structure, - "device", G_TYPE_OBJECT, yuv_video->device, - "chroma-type", G_TYPE_INT, chroma_type, - "width", G_TYPE_INT, width, - "height", G_TYPE_INT, height, - "framerate", GST_TYPE_FRACTION, framerate_numerator, - framerate_denominator, "pixel-aspect-ratio", GST_TYPE_FRACTION, - par_numerator, par_denominator, NULL); - - gst_pad_fixate_caps (yuv_video->src, new_caps); - res = gst_pad_set_caps (yuv_video->src, new_caps); - - gst_caps_unref (new_caps); - - if (G_UNLIKELY (!res)) - return FALSE; - - yuv_video->width = width; - yuv_video->height = height; - yuv_video->format = fourcc; - yuv_video->chroma_type = chroma_type; - - return TRUE; -} - -static GstCaps * -gst_vdpau_yuv_video_sink_getcaps (GstPad * pad) -{ - GstVdpauYUVVideo *yuv_video; - - yuv_video = GST_VDPAU_YUV_VIDEO (GST_OBJECT_PARENT (pad)); - - if (yuv_video->sink_caps) - return gst_caps_copy (yuv_video->sink_caps); - - return gst_caps_copy (gst_pad_get_pad_template_caps (yuv_video->sink)); -} - -static GstStateChangeReturn -gst_vdpau_yuv_video_change_state (GstElement * element, - GstStateChange transition) -{ - GstVdpauYUVVideo *yuv_video; - - yuv_video = GST_VDPAU_YUV_VIDEO (element); - - switch (transition) { - case GST_STATE_CHANGE_NULL_TO_READY: - yuv_video->device = gst_vdpau_get_device (yuv_video->display); - if (!yuv_video->sink_caps) - yuv_video->sink_caps = gst_vdpau_yuv_video_get_caps (yuv_video); - break; - case GST_STATE_CHANGE_READY_TO_NULL: - g_object_unref (yuv_video->device); - yuv_video->device = NULL; - break; - default: - break; - } - - return GST_STATE_CHANGE_SUCCESS; -} - -/* GObject vmethod implementations */ - -static void -gst_vdpau_yuv_video_base_init (gpointer klass) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS (klass); - - gst_element_class_set_details_simple (element_class, - "VdpauYUVVideo", - "Coyuv_video/Decoder/Video", - "VDPAU video surface to YUV", - "Carl-Anton Ingmarsson "); - - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&sink_template)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&src_template)); -} - -static void -gst_vdpau_yuv_video_class_init (GstVdpauYUVVideoClass * klass) -{ - GObjectClass *gobject_class; - GstElementClass *gstelement_class; - - gobject_class = (GObjectClass *) klass; - gstelement_class = (GstElementClass *) klass; - - gobject_class->finalize = gst_vdpau_yuv_video_finalize; - gobject_class->set_property = gst_vdpau_yuv_video_set_property; - gobject_class->get_property = gst_vdpau_yuv_video_get_property; - - g_object_class_install_property (gobject_class, PROP_DISPLAY, - g_param_spec_string ("display", "Display", "X Display name", - NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); - - gstelement_class->change_state = gst_vdpau_yuv_video_change_state; -} - -static void -gst_vdpau_yuv_video_init (GstVdpauYUVVideo * yuv_video, - GstVdpauYUVVideoClass * klass) -{ - yuv_video->sink_caps = NULL; - - yuv_video->display = NULL; - yuv_video->device = NULL; - - yuv_video->height = 0; - yuv_video->width = 0; - yuv_video->format = 0; - yuv_video->chroma_type = 0; - - yuv_video->src = gst_pad_new_from_static_template (&src_template, "src"); - gst_element_add_pad (GST_ELEMENT (yuv_video), yuv_video->src); - - yuv_video->sink = gst_pad_new_from_static_template (&sink_template, "sink"); - gst_pad_set_getcaps_function (yuv_video->sink, - gst_vdpau_yuv_video_sink_getcaps); - gst_pad_set_setcaps_function (yuv_video->sink, - gst_vdpau_yuv_video_sink_setcaps); - gst_pad_set_chain_function (yuv_video->sink, gst_vdpau_yuv_video_chain); - gst_element_add_pad (GST_ELEMENT (yuv_video), yuv_video->sink); - gst_pad_set_active (yuv_video->sink, TRUE); -} - -static void -gst_vdpau_yuv_video_finalize (GObject * object) -{ - GstVdpauYUVVideo *yuv_video = (GstVdpauYUVVideo *) object; - - g_free (yuv_video->display); -} - -static void -gst_vdpau_yuv_video_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) -{ - GstVdpauYUVVideo *yuv_video = GST_VDPAU_YUV_VIDEO (object); - - switch (prop_id) { - case PROP_DISPLAY: - g_free (yuv_video->display); - yuv_video->display = g_value_dup_string (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_vdpau_yuv_video_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec) -{ - GstVdpauYUVVideo *yuv_video = GST_VDPAU_YUV_VIDEO (object); - - switch (prop_id) { - case PROP_DISPLAY: - g_value_set_string (value, yuv_video->display); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} diff --git a/sys/vdpau/gstvdpauyuvvideo.h b/sys/vdpau/gstvdpauyuvvideo.h deleted file mode 100644 index e80eacf9..00000000 --- a/sys/vdpau/gstvdpauyuvvideo.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * GStreamer - * Copyright (C) 2009 Carl-Anton Ingmarsson - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __GST_VDPAU_YUV_VIDEO_H__ -#define __GST_VDPAU_YUV_VIDEO_H__ - -#include - -#include "gstvdpaudevice.h" - -G_BEGIN_DECLS - -#define GST_TYPE_VDPAU_YUV_VIDEO (gst_vdpau_yuv_video_get_type()) -#define GST_VDPAU_YUV_VIDEO(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VDPAU_YUV_VIDEO,GstVdpauYUVVideo)) -#define GST_VDPAU_YUV_VIDEO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VDPAU_YUV_VIDEO,GstVdpauYUVVideoClass)) -#define GST_VDPAU_YUV_VIDEO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VDPAU_YUV_VIDEO, GstVdpauYUVVideoClass)) -#define GST_IS_VDPAU_YUV_VIDEO(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VDPAU_YUV_VIDEO)) -#define GST_IS_VDPAU_YUV_VIDEO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VDPAU_YUV_VIDEO)) - -typedef struct _GstVdpauYUVVideo GstVdpauYUVVideo; -typedef struct _GstVdpauYUVVideoClass GstVdpauYUVVideoClass; - -struct _GstVdpauYUVVideo { - GstElement element; - - GstPad *src, *sink; - GstCaps *sink_caps; - - gchar *display; - GstVdpauDevice *device; - - guint32 format; - gint chroma_type; - gint width, height; -}; - -struct _GstVdpauYUVVideoClass { - GstElementClass parent_class; -}; - -GType gst_vdpau_yuv_video_get_type (void); - -G_END_DECLS - -#endif /* __GST_VDPAU_YUV_VIDEO_H__ */ diff --git a/sys/vdpau/gstvdpdecoder.c b/sys/vdpau/gstvdpdecoder.c new file mode 100644 index 00000000..2e92381f --- /dev/null +++ b/sys/vdpau/gstvdpdecoder.c @@ -0,0 +1,275 @@ +/* + * GStreamer + * Copyright (C) 2009 Carl-Anton Ingmarsson + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#include "gstvdpdecoder.h" + +GST_DEBUG_CATEGORY_STATIC (gst_vdp_decoder_debug); +#define GST_CAT_DEFAULT gst_vdp_decoder_debug + +/* Filter signals and args */ +enum +{ + /* FILL ME */ + LAST_SIGNAL +}; + +enum +{ + PROP_0, + PROP_DISPLAY, + PROP_SILENT +}; + +static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS ("video/vdpau-video, " "chroma-type = (int) 0")); + +#define DEBUG_INIT(bla) \ + GST_DEBUG_CATEGORY_INIT (gst_vdp_decoder_debug, "vdpaudecoder", 0, "vdpaudecoder base class"); + +GST_BOILERPLATE_FULL (GstVdpDecoder, gst_vdp_decoder, GstElement, + GST_TYPE_ELEMENT, DEBUG_INIT); + +static void gst_vdp_decoder_finalize (GObject * object); +static void gst_vdp_decoder_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec); +static void gst_vdp_decoder_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec); + +GstFlowReturn +gst_vdp_decoder_push_video_buffer (GstVdpDecoder * dec, + GstVdpVideoBuffer * buffer) +{ + GST_BUFFER_TIMESTAMP (buffer) = + gst_util_uint64_scale_int (GST_SECOND * dec->frame_nr, + dec->framerate_denominator, dec->framerate_numerator); + GST_BUFFER_DURATION (buffer) = + gst_util_uint64_scale_int (GST_SECOND, dec->framerate_denominator, + dec->framerate_numerator); + GST_BUFFER_OFFSET (buffer) = dec->frame_nr; + dec->frame_nr++; + GST_BUFFER_OFFSET_END (buffer) = dec->frame_nr; + gst_buffer_set_caps (GST_BUFFER (buffer), GST_PAD_CAPS (dec->src)); + + return gst_pad_push (dec->src, GST_BUFFER (buffer)); +} + +static GstStateChangeReturn +gst_vdp_decoder_change_state (GstElement * element, GstStateChange transition) +{ + GstVdpDecoder *dec; + + dec = GST_VDPAU_DECODER (element); + + switch (transition) { + case GST_STATE_CHANGE_NULL_TO_READY: + dec->device = gst_vdp_get_device (dec->display_name); + break; + case GST_STATE_CHANGE_READY_TO_NULL: + g_object_unref (dec->device); + dec->device = NULL; + break; + default: + break; + } + + return GST_STATE_CHANGE_SUCCESS; +} + +static gboolean +gst_vdp_decoder_sink_set_caps (GstPad * pad, GstCaps * caps) +{ + GstVdpDecoder *dec = GST_VDPAU_DECODER (GST_OBJECT_PARENT (pad)); + GstVdpDecoderClass *dec_class = GST_VDPAU_DECODER_GET_CLASS (dec); + + GstCaps *src_caps, *new_caps; + GstStructure *structure; + gint width, height; + gint framerate_numerator, framerate_denominator; + gint par_numerator, par_denominator; + gboolean res; + + structure = gst_caps_get_structure (caps, 0); + gst_structure_get_int (structure, "width", &width); + gst_structure_get_int (structure, "height", &height); + gst_structure_get_fraction (structure, "framerate", + &framerate_numerator, &framerate_denominator); + gst_structure_get_fraction (structure, "pixel-aspect-ratio", + &par_numerator, &par_denominator); + + src_caps = gst_pad_get_allowed_caps (dec->src); + if (G_UNLIKELY (!src_caps)) + return FALSE; + + new_caps = gst_caps_copy_nth (src_caps, 0); + gst_caps_unref (src_caps); + structure = gst_caps_get_structure (new_caps, 0); + gst_structure_set (structure, + "device", G_TYPE_OBJECT, dec->device, + "chroma-type", G_TYPE_INT, VDP_CHROMA_TYPE_420, + "width", G_TYPE_INT, width, + "height", G_TYPE_INT, height, + "framerate", GST_TYPE_FRACTION, framerate_numerator, + framerate_denominator, + "pixel-aspect-ratio", GST_TYPE_FRACTION, par_numerator, + par_denominator, NULL); + + gst_pad_fixate_caps (dec->src, new_caps); + res = gst_pad_set_caps (dec->src, new_caps); + + gst_caps_unref (new_caps); + + if (G_UNLIKELY (!res)) + return FALSE; + + dec->width = width; + dec->height = height; + dec->framerate_numerator = framerate_numerator; + dec->framerate_denominator = framerate_denominator; + + if (dec_class->set_caps && !dec_class->set_caps (dec, caps)) + return FALSE; + + return TRUE; +} + +/* GObject vmethod implementations */ + +static void +gst_vdp_decoder_base_init (gpointer klass) +{ + GstElementClass *element_class = GST_ELEMENT_CLASS (klass); + + gst_element_class_set_details_simple (element_class, + "VdpauDecoder", + "Codec/Decoder/Video", + "VDPAU decoder base class", + "Carl-Anton Ingmarsson "); + + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&src_template)); +} + +/* initialize the vdpaudecoder's class */ +static void +gst_vdp_decoder_class_init (GstVdpDecoderClass * klass) +{ + GObjectClass *gobject_class; + GstElementClass *gstelement_class; + + gobject_class = (GObjectClass *) klass; + gstelement_class = (GstElementClass *) klass; + + gobject_class->finalize = gst_vdp_decoder_finalize; + gobject_class->set_property = gst_vdp_decoder_set_property; + gobject_class->get_property = gst_vdp_decoder_get_property; + + g_object_class_install_property (gobject_class, PROP_DISPLAY, + g_param_spec_string ("display", "Display", "X Display name", + NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + + g_object_class_install_property (gobject_class, PROP_SILENT, + g_param_spec_boolean ("silent", "Silent", "Produce verbose output ?", + FALSE, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE)); + + gstelement_class->change_state = gst_vdp_decoder_change_state; +} + +static void +gst_vdp_decoder_init (GstVdpDecoder * dec, GstVdpDecoderClass * klass) +{ + dec->display_name = NULL; + dec->device = NULL; + dec->silent = FALSE; + + dec->height = 0; + dec->width = 0; + dec->framerate_numerator = 0; + dec->framerate_denominator = 0; + + dec->frame_nr = 0; + + dec->src = gst_pad_new_from_static_template (&src_template, "src"); + gst_element_add_pad (GST_ELEMENT (dec), dec->src); + + dec->sink = gst_pad_new_from_template (gst_element_class_get_pad_template + (GST_ELEMENT_CLASS (klass), "sink"), "sink"); + gst_pad_set_setcaps_function (dec->sink, gst_vdp_decoder_sink_set_caps); + gst_element_add_pad (GST_ELEMENT (dec), dec->sink); + gst_pad_set_active (dec->sink, TRUE); +} + +static void +gst_vdp_decoder_finalize (GObject * object) +{ + GstVdpDecoder *dec = (GstVdpDecoder *) object; + + if (dec->device) + g_object_unref (dec->device); + + g_free (dec->display_name); +} + +static void +gst_vdp_decoder_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GstVdpDecoder *dec = GST_VDPAU_DECODER (object); + + switch (prop_id) { + case PROP_DISPLAY: + g_free (dec->display_name); + dec->display_name = g_value_dup_string (value); + break; + case PROP_SILENT: + dec->silent = g_value_get_boolean (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_vdp_decoder_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) +{ + GstVdpDecoder *dec = GST_VDPAU_DECODER (object); + + switch (prop_id) { + case PROP_DISPLAY: + g_value_set_string (value, dec->display_name); + break; + case PROP_SILENT: + g_value_set_boolean (value, dec->silent); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} diff --git a/sys/vdpau/gstvdpdecoder.h b/sys/vdpau/gstvdpdecoder.h new file mode 100644 index 00000000..f918225e --- /dev/null +++ b/sys/vdpau/gstvdpdecoder.h @@ -0,0 +1,74 @@ +/* + * GStreamer + * Copyright (C) 2009 Carl-Anton Ingmarsson + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GST_VDPAU_DECODER_H__ +#define __GST_VDPAU_DECODER_H__ + +#include + +#include "gstvdpdevice.h" +#include "gstvdpvideobuffer.h" + +G_BEGIN_DECLS + +#define GST_TYPE_VDPAU_DECODER (gst_vdp_decoder_get_type()) +#define GST_VDPAU_DECODER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VDPAU_DECODER,GstVdpDecoder)) +#define GST_VDPAU_DECODER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VDPAU_DECODER,GstVdpDecoderClass)) +#define GST_VDPAU_DECODER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VDPAU_DECODER, GstVdpDecoderClass)) +#define GST_IS_VDPAU_DECODER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VDPAU_DECODER)) +#define GST_IS_VDPAU_DECODER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VDPAU_DECODER)) + +typedef struct _GstVdpDecoder GstVdpDecoder; +typedef struct _GstVdpDecoderClass GstVdpDecoderClass; +typedef struct _VdpauFunctions VdpauFunctions; + +struct _GstVdpDecoder { + GstElement element; + + gchar *display_name; + GstVdpDevice *device; + + GstPad *src; + GstPad *sink; + + gint width, height; + gint framerate_numerator, framerate_denominator; + guint32 format; + + gint frame_nr; + + gboolean silent; +}; + +struct _GstVdpDecoderClass { + GstElementClass parent_class; + + gboolean (*set_caps) (GstVdpDecoder *dec, GstCaps *caps); +}; + +GType gst_vdp_decoder_get_type (void); + +gboolean gst_vdp_decoder_push_video_buffer (GstVdpDecoder * dec, + GstVdpVideoBuffer *buffer); +VdpVideoSurface gst_vdp_decoder_create_video_surface (GstVdpDecoder *dec); + +G_END_DECLS + +#endif /* __GST_VDPAU_DECODER_H__ */ diff --git a/sys/vdpau/gstvdpdevice.c b/sys/vdpau/gstvdpdevice.c new file mode 100644 index 00000000..1dc42d68 --- /dev/null +++ b/sys/vdpau/gstvdpdevice.c @@ -0,0 +1,269 @@ +/* + * GStreamer + * Copyright (C) 2009 Carl-Anton Ingmarsson + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include +#include + +#include "gstvdpdevice.h" + +GST_DEBUG_CATEGORY_STATIC (gst_vdp_device_debug); +#define GST_CAT_DEFAULT gst_vdp_device_debug + +enum +{ + PROP_0, + PROP_DISPLAY +}; + + + +G_DEFINE_TYPE (GstVdpDevice, gst_vdp_device, G_TYPE_OBJECT); + +static void +gst_vdp_device_init (GstVdpDevice * device) +{ + device->display_name = NULL; + device->display = NULL; + device->device = VDP_INVALID_HANDLE; +} + +static void +gst_vdp_device_finalize (GObject * object) +{ + GstVdpDevice *device = (GstVdpDevice *) object; + + device->vdp_device_destroy (device->device); + g_free (device->display_name); + + G_OBJECT_CLASS (gst_vdp_device_parent_class)->finalize (object); + +} + +static void +gst_vdp_device_constructed (GObject * object) +{ + GstVdpDevice *device = (GstVdpDevice *) object; + gint screen; + VdpStatus status; + gint i; + + typedef struct + { + gint id; + void *func; + } VdpFunction; + + VdpFunction vdp_function[] = { + {VDP_FUNC_ID_DEVICE_DESTROY, &device->vdp_device_destroy}, + {VDP_FUNC_ID_VIDEO_SURFACE_CREATE, + &device->vdp_video_surface_create}, + {VDP_FUNC_ID_VIDEO_SURFACE_DESTROY, + &device->vdp_video_surface_destroy}, + {VDP_FUNC_ID_VIDEO_SURFACE_QUERY_CAPABILITIES, + &device->vdp_video_surface_query_capabilities}, + {VDP_FUNC_ID_VIDEO_SURFACE_QUERY_GET_PUT_BITS_Y_CB_CR_CAPABILITIES, + &device->vdp_video_surface_query_ycbcr_capabilities}, + {VDP_FUNC_ID_VIDEO_SURFACE_GET_BITS_Y_CB_CR, + &device->vdp_video_surface_get_bits_ycbcr}, + {VDP_FUNC_ID_VIDEO_SURFACE_PUT_BITS_Y_CB_CR, + &device->vdp_video_surface_put_bits_ycbcr}, + {VDP_FUNC_ID_VIDEO_SURFACE_GET_PARAMETERS, + &device->vdp_video_surface_get_parameters}, + {VDP_FUNC_ID_DECODER_CREATE, &device->vdp_decoder_create}, + {VDP_FUNC_ID_DECODER_RENDER, &device->vdp_decoder_render}, + {VDP_FUNC_ID_DECODER_DESTROY, &device->vdp_decoder_destroy}, + {VDP_FUNC_ID_DECODER_QUERY_CAPABILITIES, + &device->vdp_decoder_query_capabilities}, + {VDP_FUNC_ID_DECODER_GET_PARAMETERS, + &device->vdp_decoder_get_parameters}, + {0, NULL} + }; + + device->display = XOpenDisplay (device->display_name); + if (!device->display) { + GST_ERROR_OBJECT (device, "Could not open X display with name: %s", + device->display_name); + return; + } + + screen = DefaultScreen (device->display); + status = + vdp_device_create_x11 (device->display, screen, &device->device, + &device->vdp_get_proc_address); + if (status != VDP_STATUS_OK) { + GST_ERROR_OBJECT (device, "Could not create VDPAU device"); + XCloseDisplay (device->display); + device->display = NULL; + + return; + } + + status = device->vdp_get_proc_address (device->device, + VDP_FUNC_ID_GET_ERROR_STRING, (void **) &device->vdp_get_error_string); + if (status != VDP_STATUS_OK) { + GST_ERROR_OBJECT (device, + "Could not get vdp_get_error_string function pointer from VDPAU"); + goto error; + } + + for (i = 0; vdp_function[i].func != NULL; i++) { + status = device->vdp_get_proc_address (device->device, + vdp_function[i].id, vdp_function[i].func); + + if (status != VDP_STATUS_OK) { + GST_ERROR_OBJECT (device, "Could not get function pointer from VDPAU," + " error returned was: %s", device->vdp_get_error_string (status)); + goto error; + } + } + + return; + +error: + XCloseDisplay (device->display); + device->display = NULL; + + if (device->device != VDP_INVALID_HANDLE) { + device->vdp_device_destroy (device->device); + device->device = VDP_INVALID_HANDLE; + } +} + +static void +gst_vdp_device_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GstVdpDevice *device; + + g_return_if_fail (GST_IS_VDPAU_DEVICE (object)); + + device = (GstVdpDevice *) object; + + switch (prop_id) { + case PROP_DISPLAY: + device->display_name = g_value_dup_string (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_vdp_device_get_property (GObject * object, guint prop_id, GValue * value, + GParamSpec * pspec) +{ + GstVdpDevice *device; + + g_return_if_fail (GST_IS_VDPAU_DEVICE (object)); + + device = (GstVdpDevice *) object; + + switch (prop_id) { + case PROP_DISPLAY: + g_value_set_string (value, device->display_name); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_vdp_device_class_init (GstVdpDeviceClass * klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->constructed = gst_vdp_device_constructed; + object_class->finalize = gst_vdp_device_finalize; + object_class->get_property = gst_vdp_device_get_property; + object_class->set_property = gst_vdp_device_set_property; + + + g_object_class_install_property (object_class, + PROP_DISPLAY, + g_param_spec_string ("display", + "Display", + "X Display Name", + "", G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); + + GST_DEBUG_CATEGORY_INIT (gst_vdp_device_debug, "vdpaudevice", + 0, "vdpaudevice"); +} + +GstVdpDevice * +gst_vdp_device_new (const gchar * display_name) +{ + GstVdpDevice *device; + + device = g_object_new (GST_TYPE_VDPAU_DEVICE, "display", display_name); + + return device; +} + +static void +device_destroyed_cb (gpointer data, GObject * object) +{ + GHashTable *devices_hash = data; + GHashTableIter iter; + gpointer device; + + g_hash_table_iter_init (&iter, devices_hash); + while (g_hash_table_iter_next (&iter, NULL, &device)) { + if (device == object) { + g_hash_table_iter_remove (&iter); + break; + } + } +} + +static gpointer +create_devices_hash (gpointer data) +{ + return g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); +} + +GstVdpDevice * +gst_vdp_get_device (const gchar * display_name) +{ + static GOnce my_once = G_ONCE_INIT; + GHashTable *devices_hash; + GstVdpDevice *device; + + g_once (&my_once, create_devices_hash, NULL); + devices_hash = my_once.retval; + + if (display_name) + device = g_hash_table_lookup (devices_hash, display_name); + else + device = g_hash_table_lookup (devices_hash, ""); + + if (!device) { + device = gst_vdp_device_new (display_name); + g_object_weak_ref (G_OBJECT (device), device_destroyed_cb, devices_hash); + if (display_name) + g_hash_table_insert (devices_hash, g_strdup (display_name), device); + else + g_hash_table_insert (devices_hash, g_strdup (""), device); + } else + g_object_ref (device); + + return device; +} diff --git a/sys/vdpau/gstvdpdevice.h b/sys/vdpau/gstvdpdevice.h new file mode 100644 index 00000000..8b2f596c --- /dev/null +++ b/sys/vdpau/gstvdpdevice.h @@ -0,0 +1,132 @@ +/* + * GStreamer + * Copyright (C) 2009 Carl-Anton Ingmarsson + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _GST_VDPAU_DEVICE_H_ +#define _GST_VDPAU_DEVICE_H_ + +#include +#include + +#include + +G_BEGIN_DECLS + +#define GST_TYPE_VDPAU_DEVICE (gst_vdp_device_get_type ()) +#define GST_VDPAU_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VDPAU_DEVICE, GstVdpDevice)) +#define GST_VDPAU_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_VDPAU_DEVICE, GstVdpDeviceClass)) +#define GST_IS_VDPAU_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VDPAU_DEVICE)) +#define GST_IS_VDPAU_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_VDPAU_DEVICE)) +#define GST_VDPAU_DEVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VDPAU_DEVICE, GstVdpDeviceClass)) + +typedef struct _GstVdpDeviceClass GstVdpDeviceClass; +typedef struct _GstVdpDevice GstVdpDevice; + +struct _GstVdpDeviceClass +{ + GObjectClass parent_class; +}; + +struct _GstVdpDevice +{ + GObject object; + + gchar *display_name; + Display *display; + VdpDevice device; + + VdpDeviceDestroy *vdp_device_destroy; + VdpGetProcAddress *vdp_get_proc_address; + VdpGetErrorString *vdp_get_error_string; + + VdpVideoSurfaceCreate *vdp_video_surface_create; + VdpVideoSurfaceDestroy *vdp_video_surface_destroy; + VdpVideoSurfaceQueryCapabilities *vdp_video_surface_query_capabilities; + VdpVideoSurfaceQueryGetPutBitsYCbCrCapabilities *vdp_video_surface_query_ycbcr_capabilities; + VdpVideoSurfaceGetParameters *vdp_video_surface_get_parameters; + VdpVideoSurfaceGetBitsYCbCr *vdp_video_surface_get_bits_ycbcr; + VdpVideoSurfacePutBitsYCbCr *vdp_video_surface_put_bits_ycbcr; + + VdpDecoderCreate *vdp_decoder_create; + VdpDecoderDestroy *vdp_decoder_destroy; + VdpDecoderRender *vdp_decoder_render; + VdpDecoderQueryCapabilities *vdp_decoder_query_capabilities; + VdpDecoderGetParameters *vdp_decoder_get_parameters; +}; + +typedef struct +{ + VdpChromaType chroma_type; + VdpYCbCrFormat format; + guint32 fourcc; +} VdpauFormats; + +#define N_CHROMA_TYPES 3 +#define N_FORMATS 7 + +static const VdpChromaType chroma_types[N_CHROMA_TYPES] = + { VDP_CHROMA_TYPE_420, VDP_CHROMA_TYPE_422, VDP_CHROMA_TYPE_444 }; + +static const VdpauFormats formats[N_FORMATS] = { + { + VDP_CHROMA_TYPE_420, + VDP_YCBCR_FORMAT_NV12, + GST_MAKE_FOURCC ('N', 'V', '1', '2') + }, + { + VDP_CHROMA_TYPE_422, + VDP_YCBCR_FORMAT_UYVY, + GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y') + }, + { + VDP_CHROMA_TYPE_444, + VDP_YCBCR_FORMAT_V8U8Y8A8, + GST_MAKE_FOURCC ('A', 'Y', 'U', 'V') + }, + { + VDP_CHROMA_TYPE_444, + VDP_YCBCR_FORMAT_Y8U8V8A8, + GST_MAKE_FOURCC ('A', 'V', 'U', 'Y') + }, + { + VDP_CHROMA_TYPE_422, + VDP_YCBCR_FORMAT_YUYV, + GST_MAKE_FOURCC ('Y', 'U', 'Y', 'V') + }, + { + VDP_CHROMA_TYPE_420, + VDP_YCBCR_FORMAT_YV12, + GST_MAKE_FOURCC ('Y', 'V', '1', '2') + }, + { + VDP_CHROMA_TYPE_420, + VDP_YCBCR_FORMAT_YV12, + GST_MAKE_FOURCC ('I', '4', '2', '0') + } +}; + +GType gst_vdp_device_get_type (void) G_GNUC_CONST; + +GstVdpDevice *gst_vdp_device_new (const gchar *display_name); + +GstVdpDevice *gst_vdp_get_device (const gchar *display_name); + +G_END_DECLS + +#endif /* _GST_VDPAU_DEVICE_H_ */ diff --git a/sys/vdpau/gstvdpmpegdecoder.c b/sys/vdpau/gstvdpmpegdecoder.c new file mode 100644 index 00000000..df8a5b67 --- /dev/null +++ b/sys/vdpau/gstvdpmpegdecoder.c @@ -0,0 +1,481 @@ +/* + * GStreamer + * Copyright (C) 2009 Carl-Anton Ingmarsson + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/** + * SECTION:element-vdpaumpegdecoder + * + * FIXME:Describe vdpaumpegdecoder here. + * + * + * Example launch line + * |[ + * gst-launch -v -m fakesrc ! vdpaumpegdecoder ! fakesink silent=TRUE + * ]| + * + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include "mpegutil.h" +#include "gstvdpmpegdecoder.h" + +GST_DEBUG_CATEGORY_STATIC (gst_vdp_mpeg_decoder_debug); +#define GST_CAT_DEFAULT gst_vdp_mpeg_decoder_debug + +/* Filter signals and args */ +enum +{ + /* FILL ME */ + LAST_SIGNAL +}; + +enum +{ + PROP_0 +}; + +/* the capabilities of the inputs and outputs. + * + * describe the real formats here. + */ +static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS ("video/mpeg, mpegversion = (int) [ 1, 2 ], " + "systemstream = (boolean) false, parsed = (boolean) true") + ); + +#define DEBUG_INIT(bla) \ +GST_DEBUG_CATEGORY_INIT (gst_vdp_mpeg_decoder_debug, "vdpaumpegdecoder", 0, "VDPAU powered mpeg decoder"); + +GST_BOILERPLATE_FULL (GstVdpMpegDecoder, gst_vdp_mpeg_decoder, + GstVdpDecoder, GST_TYPE_VDPAU_DECODER, DEBUG_INIT); + +static void gst_vdp_mpeg_decoder_finalize (GObject * object); +static void gst_vdp_mpeg_decoder_set_property (GObject * object, + guint prop_id, const GValue * value, GParamSpec * pspec); +static void gst_vdp_mpeg_decoder_get_property (GObject * object, + guint prop_id, GValue * value, GParamSpec * pspec); + +static gboolean +gst_vdp_mpeg_decoder_set_caps (GstVdpDecoder * dec, GstCaps * caps) +{ + GstVdpMpegDecoder *mpeg_dec; + GstStructure *structure; + const GValue *value; + GstBuffer *codec_data; + MPEGSeqHdr hdr = { 0, }; + VdpDecoderProfile profile; + GstVdpDevice *device; + VdpStatus status; + + mpeg_dec = GST_VDPAU_MPEG_DECODER (dec); + + structure = gst_caps_get_structure (caps, 0); + gst_structure_get_int (structure, "mpegversion", &mpeg_dec->version); + if (mpeg_dec->version == 1) + profile = VDP_DECODER_PROFILE_MPEG1; + + value = gst_structure_get_value (structure, "codec_data"); + codec_data = gst_value_get_buffer (value); + mpeg_util_parse_sequence_hdr (&hdr, GST_BUFFER_DATA (codec_data), + GST_BUFFER_DATA (codec_data) + GST_BUFFER_SIZE (codec_data)); + if (mpeg_dec->version != 1) { + switch (hdr.profile) { + case 5: + profile = VDP_DECODER_PROFILE_MPEG2_SIMPLE; + break; + default: + profile = VDP_DECODER_PROFILE_MPEG2_MAIN; + break; + } + } + + memcpy (&mpeg_dec->vdp_info.intra_quantizer_matrix, + &hdr.intra_quantizer_matrix, 64); + memcpy (&mpeg_dec->vdp_info.non_intra_quantizer_matrix, + &hdr.non_intra_quantizer_matrix, 64); + + device = dec->device; + status = device->vdp_decoder_create (device->device, profile, dec->width, + dec->height, 2, &mpeg_dec->decoder); + if (status != VDP_STATUS_OK) { + GST_ELEMENT_ERROR (mpeg_dec, RESOURCE, READ, + ("Could not create vdpau decoder"), + ("Error returned from vdpau was: %s", + device->vdp_get_error_string (status))); + return FALSE; + } + return TRUE; +} + +static GstFlowReturn +gst_vdp_mpeg_decoder_decode (GstVdpMpegDecoder * mpeg_dec) +{ + GstVdpDecoder *dec; + GstBuffer *buffer; + GstVdpVideoBuffer *outbuf; + VdpVideoSurface surface; + GstVdpDevice *device; + VdpBitstreamBuffer vbit[1]; + VdpStatus status; + GstFlowReturn ret; + + dec = GST_VDPAU_DECODER (mpeg_dec); + + buffer = gst_adapter_take_buffer (mpeg_dec->adapter, + gst_adapter_available (mpeg_dec->adapter)); + + outbuf = gst_vdp_video_buffer_new (dec->device, VDP_CHROMA_TYPE_420, + dec->width, dec->height); + surface = outbuf->surface; + + device = dec->device; + + vbit[0].struct_version = VDP_BITSTREAM_BUFFER_VERSION; + vbit[0].bitstream = GST_BUFFER_DATA (buffer); + vbit[0].bitstream_bytes = GST_BUFFER_SIZE (buffer); + + status = device->vdp_decoder_render (mpeg_dec->decoder, surface, + (VdpPictureInfo *) & mpeg_dec->vdp_info, 1, vbit); + gst_buffer_unref (buffer); + mpeg_dec->vdp_info.slice_count = 0; + + if (status != VDP_STATUS_OK) { + GST_ELEMENT_ERROR (mpeg_dec, RESOURCE, READ, + ("Could not decode"), + ("Error returned from vdpau was: %s", + device->vdp_get_error_string (status))); + + if (mpeg_dec->vdp_info.forward_reference != VDP_INVALID_HANDLE) { + gst_buffer_unref (mpeg_dec->f_buffer); + mpeg_dec->vdp_info.forward_reference = VDP_INVALID_HANDLE; + } + + gst_buffer_unref (GST_BUFFER (outbuf)); + + return GST_FLOW_ERROR; + } + + gst_buffer_ref (GST_BUFFER (outbuf)); + + ret = gst_vdp_decoder_push_video_buffer (GST_VDPAU_DECODER (mpeg_dec), + outbuf); + + if (mpeg_dec->vdp_info.forward_reference != VDP_INVALID_HANDLE) + gst_buffer_unref (mpeg_dec->f_buffer); + + mpeg_dec->vdp_info.forward_reference = surface; + mpeg_dec->f_buffer = GST_BUFFER (outbuf); + + return ret; +} + +static gboolean +gst_vdp_mpeg_decoder_parse_picture_coding (GstVdpMpegDecoder * mpeg_dec, + guint8 * data, guint8 * end) +{ + GstVdpDecoder *dec; + MPEGPictureExt pic_ext; + VdpPictureInfoMPEG1Or2 *info; + + dec = GST_VDPAU_DECODER (mpeg_dec); + info = &mpeg_dec->vdp_info; + + if (!mpeg_util_parse_picture_coding_extension (&pic_ext, data, end)) + return FALSE; + + memcpy (&mpeg_dec->vdp_info.f_code, &pic_ext.f_code, 4); + + info->intra_dc_precision = pic_ext.intra_dc_precision; + info->picture_structure = pic_ext.picture_structure; + info->top_field_first = pic_ext.top_field_first; + info->frame_pred_frame_dct = pic_ext.frame_pred_frame_dct; + info->concealment_motion_vectors = pic_ext.concealment_motion_vectors; + info->q_scale_type = pic_ext.q_scale_type; + info->intra_vlc_format = pic_ext.intra_vlc_format; + + mpeg_dec->want_slice = TRUE; + + return TRUE; +} + +static gboolean +gst_vdp_mpeg_decoder_parse_sequence (GstVdpMpegDecoder * mpeg_dec, + guint8 * data, guint8 * end) +{ + GstVdpDecoder *dec; + MPEGSeqHdr hdr; + + dec = GST_VDPAU_DECODER (mpeg_dec); + + if (!mpeg_util_parse_sequence_hdr (&hdr, data, end)) + return FALSE; + + memcpy (&mpeg_dec->vdp_info.intra_quantizer_matrix, + &hdr.intra_quantizer_matrix, 64); + memcpy (&mpeg_dec->vdp_info.non_intra_quantizer_matrix, + &hdr.non_intra_quantizer_matrix, 64); + + return TRUE; +} + +static gboolean +gst_vdp_mpeg_decoder_parse_picture (GstVdpMpegDecoder * mpeg_dec, + guint8 * data, guint8 * end) +{ + GstVdpDecoder *dec; + MPEGPictureHdr pic_hdr; + + dec = GST_VDPAU_DECODER (mpeg_dec); + + if (!mpeg_util_parse_picture_hdr (&pic_hdr, data, end)) + return FALSE; + + mpeg_dec->vdp_info.picture_coding_type = pic_hdr.pic_type; + + + if (pic_hdr.pic_type == I_FRAME && + mpeg_dec->vdp_info.forward_reference != VDP_INVALID_HANDLE) { + gst_buffer_unref (mpeg_dec->f_buffer); + mpeg_dec->vdp_info.forward_reference = VDP_INVALID_HANDLE; + } + + if (mpeg_dec->version == 1) { + mpeg_dec->vdp_info.full_pel_forward_vector = + pic_hdr.full_pel_forward_vector; + mpeg_dec->vdp_info.full_pel_backward_vector = + pic_hdr.full_pel_backward_vector; + memcpy (&mpeg_dec->vdp_info.f_code, &pic_hdr.f_code, 4); + + mpeg_dec->want_slice = TRUE; + } else + mpeg_dec->want_slice = FALSE; + + return TRUE; +} + +static gboolean +gst_vdp_mpeg_decoder_parse_gop (GstVdpMpegDecoder * mpeg_dec, guint8 * data, + guint8 * end) +{ + MPEGPictureGOP gop; + + if (!mpeg_util_parse_picture_gop (&gop, data, end)) + return FALSE; + + return TRUE; +} + +static gboolean +gst_vdp_mpeg_decoder_parse_quant_matrix (GstVdpMpegDecoder * mpeg_dec, + guint8 * data, guint8 * end) +{ + MPEGQuantMatrix qm; + + if (!mpeg_util_parse_quant_matrix (&qm, data, end)) + return FALSE; + + memcpy (&mpeg_dec->vdp_info.intra_quantizer_matrix, + &qm.intra_quantizer_matrix, 64); + memcpy (&mpeg_dec->vdp_info.non_intra_quantizer_matrix, + &qm.non_intra_quantizer_matrix, 64); + return TRUE; +} + +static GstFlowReturn +gst_vdp_mpeg_decoder_chain (GstPad * pad, GstBuffer * buffer) +{ + GstVdpMpegDecoder *mpeg_dec; + guint8 *data, *end; + guint32 sync_word = 0xffffffff; + + mpeg_dec = GST_VDPAU_MPEG_DECODER (GST_OBJECT_PARENT (pad)); + + data = GST_BUFFER_DATA (buffer); + end = GST_BUFFER_DATA (buffer) + GST_BUFFER_SIZE (buffer); + + while ((data = mpeg_util_find_start_code (&sync_word, data, end))) { + guint8 *packet_start; + guint8 *packet_end; + + packet_start = data - 3; + packet_end = mpeg_util_find_start_code (&sync_word, data, end); + if (packet_end) + packet_end -= 3; + else + packet_end = end; + + if (data[0] >= MPEG_PACKET_SLICE_MIN && data[0] <= MPEG_PACKET_SLICE_MAX) { + GstBuffer *subbuf; + + GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_SLICE"); + if (mpeg_dec->want_slice) { + subbuf = + gst_buffer_create_sub (buffer, + packet_start - GST_BUFFER_DATA (buffer), packet_end - packet_start); + gst_adapter_push (mpeg_dec->adapter, subbuf); + mpeg_dec->vdp_info.slice_count++; + } + } + + switch (data[0]) { + case MPEG_PACKET_PICTURE: + GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_PICTURE"); + if (mpeg_dec->vdp_info.slice_count > 0 && mpeg_dec->want_slice) { + if (gst_vdp_mpeg_decoder_decode (mpeg_dec) != GST_FLOW_OK) + return GST_FLOW_ERROR; + } + gst_vdp_mpeg_decoder_parse_picture (mpeg_dec, packet_start, packet_end); + break; + case MPEG_PACKET_SEQUENCE: + GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_SEQUENCE"); + gst_vdp_mpeg_decoder_parse_sequence (mpeg_dec, packet_start, + packet_end); + break; + case MPEG_PACKET_EXTENSION: + GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_EXTENSION"); + switch (read_bits (data + 1, 0, 4)) { + case MPEG_PACKET_EXT_PICTURE_CODING: + gst_vdp_mpeg_decoder_parse_picture_coding (mpeg_dec, packet_start, + packet_end); + break; + default: + break; + } + break; + case MPEG_PACKET_EXT_QUANT_MATRIX: + GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_EXT_QUANT_MATRIX"); + gst_vdp_mpeg_decoder_parse_quant_matrix (mpeg_dec, packet_start, + packet_end); + break; + case MPEG_PACKET_GOP: + GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_GOP"); + gst_vdp_mpeg_decoder_parse_gop (mpeg_dec, packet_start, packet_end); + break; + default: + break; + } + } + + return GST_FLOW_OK; +} + +/* GObject vmethod implementations */ + +static void +gst_vdp_mpeg_decoder_base_init (gpointer gclass) +{ + GstElementClass *element_class = GST_ELEMENT_CLASS (gclass); + + gst_element_class_set_details_simple (element_class, + "VdpauMpegDecoder", + "Decoder", + "decode mpeg stream with vdpau", + "Carl-Anton Ingmarsson "); + + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&sink_factory)); +} + +/* initialize the vdpaumpegdecoder's class */ +static void +gst_vdp_mpeg_decoder_class_init (GstVdpMpegDecoderClass * klass) +{ + GObjectClass *gobject_class; + GstElementClass *gstelement_class; + GstVdpDecoderClass *vdpaudec_class; + + gobject_class = (GObjectClass *) klass; + gstelement_class = (GstElementClass *) klass; + vdpaudec_class = (GstVdpDecoderClass *) klass; + + gobject_class->finalize = gst_vdp_mpeg_decoder_finalize; + gobject_class->set_property = gst_vdp_mpeg_decoder_set_property; + gobject_class->get_property = gst_vdp_mpeg_decoder_get_property; + + vdpaudec_class->set_caps = gst_vdp_mpeg_decoder_set_caps; +} + +static void +gst_vdp_mpeg_decoder_init_info (VdpPictureInfoMPEG1Or2 * vdp_info) +{ + vdp_info->forward_reference = VDP_INVALID_HANDLE; + vdp_info->backward_reference = VDP_INVALID_HANDLE; + vdp_info->slice_count = 0; + vdp_info->picture_structure = 0; + vdp_info->picture_coding_type = 0; + vdp_info->intra_dc_precision = 0; + vdp_info->frame_pred_frame_dct = 0; + vdp_info->concealment_motion_vectors = 0; +} + +static void +gst_vdp_mpeg_decoder_init (GstVdpMpegDecoder * mpeg_dec, + GstVdpMpegDecoderClass * gclass) +{ + GstVdpDecoder *dec; + + dec = GST_VDPAU_DECODER (mpeg_dec); + + mpeg_dec->decoder = VDP_INVALID_HANDLE; + gst_vdp_mpeg_decoder_init_info (&mpeg_dec->vdp_info); + + mpeg_dec->adapter = gst_adapter_new (); + + mpeg_dec->want_slice = FALSE; + + gst_pad_set_chain_function (dec->sink, gst_vdp_mpeg_decoder_chain); +} + +static void +gst_vdp_mpeg_decoder_finalize (GObject * object) +{ + GstVdpMpegDecoder *mpeg_dec = (GstVdpMpegDecoder *) object; + + g_object_unref (mpeg_dec->adapter); +} + +static void +gst_vdp_mpeg_decoder_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + switch (prop_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_vdp_mpeg_decoder_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) +{ + switch (prop_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} diff --git a/sys/vdpau/gstvdpmpegdecoder.h b/sys/vdpau/gstvdpmpegdecoder.h new file mode 100644 index 00000000..dc90764b --- /dev/null +++ b/sys/vdpau/gstvdpmpegdecoder.h @@ -0,0 +1,65 @@ +/* + * GStreamer + * Copyright (C) 2009 Carl-Anton Ingmarsson + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GST_VDPAU_MPEG_DECODER_H__ +#define __GST_VDPAU_MPEG_DECODER_H__ + +#include +#include + +#include "gstvdpdecoder.h" + +G_BEGIN_DECLS + +#define GST_TYPE_VDPAU_MPEG_DECODER (gst_vdp_mpeg_decoder_get_type()) +#define GST_VDPAU_MPEG_DECODER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VDPAU_MPEG_DECODER,GstVdpMpegDecoder)) +#define GST_VDPAU_MPEG_DECODER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VDPAU_MPEG_DECODER,GstVdpMpegDecoderClass)) +#define GST_IS_VDPAU_MPEG_DECODER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VDPAU_MPEG_DECODER)) +#define GST_IS_VDPAU_MPEG_DECODER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VDPAU_MPEG_DECODER)) + +typedef struct _GstVdpMpegDecoder GstVdpMpegDecoder; +typedef struct _GstVdpMpegDecoderClass GstVdpMpegDecoderClass; + +struct _GstVdpMpegDecoder +{ + GstVdpDecoder dec; + + gint version; + + VdpDecoder decoder; + VdpPictureInfoMPEG1Or2 vdp_info; + GstBuffer *f_buffer; + + gboolean want_slice; + + GstAdapter *adapter; + gint slices; +}; + +struct _GstVdpMpegDecoderClass +{ + GstVdpDecoderClass parent_class; +}; + +GType gst_vdp_mpeg_decoder_get_type (void); + +G_END_DECLS + +#endif /* __GST_VDPAU_MPEG_DECODER_H__ */ diff --git a/sys/vdpau/gstvdpvideobuffer.c b/sys/vdpau/gstvdpvideobuffer.c new file mode 100644 index 00000000..c62ac771 --- /dev/null +++ b/sys/vdpau/gstvdpvideobuffer.c @@ -0,0 +1,114 @@ +/* + * GStreamer + * Copyright (C) 2009 Carl-Anton Ingmarsson + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "gstvdpvideobuffer.h" + +static GObjectClass *gst_vdp_video_buffer_parent_class; + +static void +gst_vdp_video_buffer_finalize (GstVdpVideoBuffer * buffer) +{ + GstVdpDevice *device = buffer->device; + VdpStatus status; + + status = device->vdp_video_surface_destroy (buffer->surface); + if (status != VDP_STATUS_OK) + GST_ERROR + ("Couldn't destroy the buffers VdpVideoSurface, error returned was: %s", + device->vdp_get_error_string (status)); + + g_object_unref (buffer->device); + + GST_MINI_OBJECT_CLASS (gst_vdp_video_buffer_parent_class)->finalize + (GST_MINI_OBJECT (buffer)); +} + +static void +gst_vdp_video_buffer_init (GstVdpVideoBuffer * buffer, gpointer g_class) +{ + buffer->device = NULL; + buffer->surface = VDP_INVALID_HANDLE; +} + +static void +gst_vdp_video_buffer_class_init (gpointer g_class, gpointer class_data) +{ + GstMiniObjectClass *mini_object_class = GST_MINI_OBJECT_CLASS (g_class); + + gst_vdp_video_buffer_parent_class = g_type_class_peek_parent (g_class); + + mini_object_class->finalize = (GstMiniObjectFinalizeFunction) + gst_vdp_video_buffer_finalize; +} + + +GType +gst_vdp_video_buffer_get_type (void) +{ + static GType _gst_vdp_video_buffer_type; + + if (G_UNLIKELY (_gst_vdp_video_buffer_type == 0)) { + static const GTypeInfo info = { + sizeof (GstBufferClass), + NULL, + NULL, + gst_vdp_video_buffer_class_init, + NULL, + NULL, + sizeof (GstVdpVideoBuffer), + 0, + (GInstanceInitFunc) gst_vdp_video_buffer_init, + NULL + }; + _gst_vdp_video_buffer_type = g_type_register_static (GST_TYPE_BUFFER, + "GstVdpVideoBuffer", &info, 0); + } + return _gst_vdp_video_buffer_type; +} + + +GstVdpVideoBuffer * +gst_vdp_video_buffer_new (GstVdpDevice * device, VdpChromaType chroma_type, + gint width, gint height) +{ + GstVdpVideoBuffer *buffer; + VdpStatus status; + VdpVideoSurface surface; + + status = device->vdp_video_surface_create (device->device, chroma_type, width, + height, &surface); + if (status != VDP_STATUS_OK) { + GST_ERROR ("Couldn't create a VdpVideoSurface, error returned was: %s", + device->vdp_get_error_string (status)); + return NULL; + } + + buffer = + (GstVdpVideoBuffer *) gst_mini_object_new (GST_TYPE_VDPAU_VIDEO_BUFFER); + + buffer->device = g_object_ref (device); + buffer->surface = surface; + + return buffer; +} diff --git a/sys/vdpau/gstvdpvideobuffer.h b/sys/vdpau/gstvdpvideobuffer.h new file mode 100644 index 00000000..ab4fb154 --- /dev/null +++ b/sys/vdpau/gstvdpvideobuffer.h @@ -0,0 +1,55 @@ +/* + * GStreamer + * Copyright (C) 2009 Carl-Anton Ingmarsson + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _GST_VDPAU_VIDEO_BUFFER_H_ +#define _GST_VDPAU_VIDEO_BUFFER_H_ + +#include +#include + +#include "gstvdpdevice.h" + +#include "gstvdpvideobuffer.h" + +typedef struct _GstVdpVideoBuffer GstVdpVideoBuffer; + +#define GST_TYPE_VDPAU_VIDEO_BUFFER (gst_vdp_video_buffer_get_type()) + +#define GST_IS_VDPAU_VIDEO_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VDPAU_VIDEO_BUFFER)) +#define GST_VDPAU_VIDEO_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VDPAU_VIDEO_BUFFER, GstVdpVideoBuffer)) + +struct _GstVdpVideoBuffer { + GstBuffer buffer; + + GstVdpDevice *device; + VdpVideoSurface surface; +}; + +GType gst_vdp_video_buffer_get_type (void); + +GstVdpVideoBuffer* gst_vdp_video_buffer_new (GstVdpDevice * device, VdpChromaType chroma_type, gint width, gint height); + +#define GST_VDPAU_VIDEO_CAPS \ + "video/vdpau-video, " \ + "chroma-type = (int)[0,2], " \ + "width = (int)[1,4096], " \ + "height = (int)[1,4096]" + +#endif diff --git a/sys/vdpau/gstvdpvideoyuv.c b/sys/vdpau/gstvdpvideoyuv.c new file mode 100644 index 00000000..917a4edc --- /dev/null +++ b/sys/vdpau/gstvdpvideoyuv.c @@ -0,0 +1,444 @@ +/* + * GStreamer + * Copyright (C) 2009 Carl-Anton Ingmarsson + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#include "gstvdpvideobuffer.h" +#include "gstvdpvideoyuv.h" + +GST_DEBUG_CATEGORY_STATIC (gst_vdp_video_yuv_debug); +#define GST_CAT_DEFAULT gst_vdp_video_yuv_debug + +/* Filter signals and args */ +enum +{ + /* FILL ME */ + LAST_SIGNAL +}; + +enum +{ + PROP_0 +}; + +static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS (GST_VDPAU_VIDEO_CAPS)); + +static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS ("video/x-raw-yuv, " + "framerate = (fraction) [ 0, MAX ], " + "width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ]")); + +#define DEBUG_INIT(bla) \ + GST_DEBUG_CATEGORY_INIT (gst_vdp_video_yuv_debug, "vdpauvideoyuv", 0, "VDPAU VdpSurface to YUV"); + +GST_BOILERPLATE_FULL (GstVdpVideoYUV, gst_vdp_video_yuv, GstElement, + GST_TYPE_ELEMENT, DEBUG_INIT); + +static void gst_vdp_video_yuv_finalize (GObject * object); +static void gst_vdp_video_yuv_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec); +static void gst_vdp_video_yuv_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec); + +GstFlowReturn +gst_vdp_video_yuv_chain (GstPad * pad, GstBuffer * buffer) +{ + GstVdpVideoYUV *video_yuv; + GstVdpDevice *device; + VdpVideoSurface surface; + GstBuffer *outbuf = NULL; + + video_yuv = GST_VDPAU_VIDEO_YUV (GST_OBJECT_PARENT (pad)); + device = GST_VDPAU_VIDEO_BUFFER (buffer)->device; + surface = GST_VDPAU_VIDEO_BUFFER (buffer)->surface; + + switch (video_yuv->format) { + case GST_MAKE_FOURCC ('Y', 'V', '1', '2'): + { + gint size; + GstFlowReturn result; + VdpStatus status; + guint8 *data[3]; + guint32 stride[3]; + + size = + gst_video_format_get_size (GST_VIDEO_FORMAT_YV12, video_yuv->width, + video_yuv->height); + result = + gst_pad_alloc_buffer_and_set_caps (video_yuv->src, + GST_BUFFER_OFFSET_NONE, size, GST_PAD_CAPS (video_yuv->src), &outbuf); + if (G_UNLIKELY (result != GST_FLOW_OK)) + return result; + + data[0] = GST_BUFFER_DATA (outbuf) + + gst_video_format_get_component_offset (GST_VIDEO_FORMAT_YV12, + 0, video_yuv->width, video_yuv->height); + data[1] = GST_BUFFER_DATA (outbuf) + + gst_video_format_get_component_offset (GST_VIDEO_FORMAT_YV12, + 2, video_yuv->width, video_yuv->height); + data[2] = GST_BUFFER_DATA (outbuf) + + gst_video_format_get_component_offset (GST_VIDEO_FORMAT_YV12, + 1, video_yuv->width, video_yuv->height); + + stride[0] = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_YV12, + 0, video_yuv->width); + stride[1] = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_YV12, + 2, video_yuv->width); + stride[2] = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_YV12, + 1, video_yuv->width); + + status = + device->vdp_video_surface_get_bits_ycbcr (surface, + VDP_YCBCR_FORMAT_YV12, (void *) data, stride); + if (G_UNLIKELY (status != VDP_STATUS_OK)) { + GST_ELEMENT_ERROR (video_yuv, RESOURCE, READ, + ("Couldn't get data from vdpau"), + ("Error returned from vdpau was: %s", + device->vdp_get_error_string (status))); + goto error; + } + break; + } + case GST_MAKE_FOURCC ('I', '4', '2', '0'): + { + gint size; + GstFlowReturn result; + VdpStatus status; + guint8 *data[3]; + guint32 stride[3]; + + size = + gst_video_format_get_size (GST_VIDEO_FORMAT_YV12, video_yuv->width, + video_yuv->height); + result = + gst_pad_alloc_buffer_and_set_caps (video_yuv->src, + GST_BUFFER_OFFSET_NONE, size, GST_PAD_CAPS (video_yuv->src), &outbuf); + if (G_UNLIKELY (result != GST_FLOW_OK)) + return result; + + data[0] = GST_BUFFER_DATA (outbuf) + + gst_video_format_get_component_offset (GST_VIDEO_FORMAT_I420, + 0, video_yuv->width, video_yuv->height); + data[1] = GST_BUFFER_DATA (outbuf) + + gst_video_format_get_component_offset (GST_VIDEO_FORMAT_I420, + 2, video_yuv->width, video_yuv->height); + data[2] = GST_BUFFER_DATA (outbuf) + + gst_video_format_get_component_offset (GST_VIDEO_FORMAT_I420, + 1, video_yuv->width, video_yuv->height); + + stride[0] = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_I420, + 0, video_yuv->width); + stride[1] = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_I420, + 2, video_yuv->width); + stride[2] = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_I420, + 1, video_yuv->width); + + status = + device->vdp_video_surface_get_bits_ycbcr (surface, + VDP_YCBCR_FORMAT_YV12, (void *) data, stride); + if (G_UNLIKELY (status != VDP_STATUS_OK)) { + GST_ELEMENT_ERROR (video_yuv, RESOURCE, READ, + ("Couldn't get data from vdpau"), + ("Error returned from vdpau was: %s", + device->vdp_get_error_string (status))); + goto error; + } + break; + } + case GST_MAKE_FOURCC ('N', 'V', '1', '2'): + { + gint size; + GstFlowReturn result; + VdpStatus status; + guint8 *data[2]; + guint32 stride[2]; + + size = + video_yuv->width * video_yuv->height + + video_yuv->width * video_yuv->height / 2; + result = + gst_pad_alloc_buffer_and_set_caps (video_yuv->src, + GST_BUFFER_OFFSET_NONE, size, GST_PAD_CAPS (video_yuv->src), &outbuf); + if (G_UNLIKELY (result != GST_FLOW_OK)) + return result; + + + data[0] = GST_BUFFER_DATA (outbuf); + data[1] = GST_BUFFER_DATA (outbuf) + video_yuv->width * video_yuv->height; + + stride[0] = video_yuv->width; + stride[1] = video_yuv->width; + + status = + device->vdp_video_surface_get_bits_ycbcr (surface, + VDP_YCBCR_FORMAT_NV12, (void *) data, stride); + if (G_UNLIKELY (status != VDP_STATUS_OK)) { + GST_ELEMENT_ERROR (video_yuv, RESOURCE, READ, + ("Couldn't get data from vdpau"), + ("Error returned from vdpau was: %s", + device->vdp_get_error_string (status))); + goto error; + } + break; + } + default: + break; + } + + gst_buffer_unref (buffer); + + gst_buffer_copy_metadata (outbuf, buffer, GST_BUFFER_COPY_TIMESTAMPS); + return gst_pad_push (video_yuv->src, outbuf); + +error: + gst_buffer_unref (outbuf); + return GST_FLOW_ERROR; +} + +static GstCaps * +gst_vdp_video_yuv_get_caps (GstVdpVideoYUV * video_yuv, + GstVdpDevice * device, gint chroma_type, gint width, gint height, + gint framerate_numerator, gint framerate_denominator, gint par_numerator, + gint par_denominator) +{ + GstCaps *caps; + gint i; + + caps = gst_caps_new_empty (); + + for (i = 0; i < N_FORMATS; i++) { + VdpStatus status; + VdpBool is_supported; + + if (formats[i].chroma_type != chroma_type) + continue; + + status = + device->vdp_video_surface_query_ycbcr_capabilities (device->device, + chroma_type, formats[i].format, &is_supported); + if (status != VDP_STATUS_OK && status != VDP_STATUS_INVALID_Y_CB_CR_FORMAT) { + GST_ELEMENT_ERROR (video_yuv, RESOURCE, READ, + ("Could not query VDPAU YCbCr capabilites"), + ("Error returned from vdpau was: %s", + device->vdp_get_error_string (status))); + + return NULL; + } + if (is_supported) { + GstCaps *format_caps; + + format_caps = gst_caps_new_simple ("video/x-raw-yuv", + "format", GST_TYPE_FOURCC, formats[i].fourcc, + "width", G_TYPE_INT, width, + "height", G_TYPE_INT, height, + "framerate", GST_TYPE_FRACTION, framerate_numerator, + framerate_denominator, "pixel-aspect-ratio", GST_TYPE_FRACTION, + par_numerator, par_denominator, NULL); + gst_caps_append (caps, format_caps); + } + } + + if (gst_caps_is_empty (caps)) { + gst_caps_unref (caps); + return NULL; + } + + return caps; +} + +static gboolean +gst_vdp_video_yuv_sink_set_caps (GstPad * pad, GstCaps * caps) +{ + GstVdpVideoYUV *video_yuv = GST_VDPAU_VIDEO_YUV (GST_OBJECT_PARENT (pad)); + + GstCaps *src_caps, *new_caps; + GstStructure *structure; + const GValue *value; + GstVdpDevice *device; + gint chroma_type; + gint width, height; + gint framerate_numerator, framerate_denominator; + gint par_numerator, par_denominator; + guint32 fourcc_format; + gboolean res; + + structure = gst_caps_get_structure (caps, 0); + value = gst_structure_get_value (structure, "device"); + device = g_value_get_object (value); + + gst_structure_get_int (structure, "chroma-type", &chroma_type); + gst_structure_get_int (structure, "width", &width); + gst_structure_get_int (structure, "height", &height); + gst_structure_get_fraction (structure, "framerate", + &framerate_numerator, &framerate_denominator); + gst_structure_get_fraction (structure, "pixel-aspect-ratio", + &par_numerator, &par_denominator); + + src_caps = + gst_vdp_video_yuv_get_caps (video_yuv, device, chroma_type, width, + height, framerate_numerator, framerate_denominator, par_numerator, + par_denominator); + if (G_UNLIKELY (!src_caps)) + return FALSE; + + video_yuv->src_caps = src_caps; + + src_caps = gst_pad_get_allowed_caps (video_yuv->src); + if (G_UNLIKELY (!src_caps || !gst_caps_get_size (src_caps))) + return FALSE; + + new_caps = gst_caps_copy_nth (src_caps, 0); + gst_caps_unref (src_caps); + if (G_UNLIKELY (!new_caps)) + return FALSE; + + structure = gst_caps_get_structure (new_caps, 0); + gst_structure_get_fourcc (structure, "format", &fourcc_format); + + gst_pad_fixate_caps (video_yuv->src, new_caps); + res = gst_pad_set_caps (video_yuv->src, new_caps); + + gst_caps_unref (new_caps); + + if (G_UNLIKELY (!res)) + return FALSE; + + video_yuv->width = width; + video_yuv->height = height; + video_yuv->framerate_numerator = framerate_numerator; + video_yuv->framerate_denominator = framerate_denominator; + video_yuv->format = fourcc_format; + + return TRUE; +} + +static GstCaps * +gst_vdp_video_yuv_src_getcaps (GstPad * pad) +{ + GstVdpVideoYUV *video_yuv; + + video_yuv = GST_VDPAU_VIDEO_YUV (GST_OBJECT_PARENT (pad)); + + if (video_yuv->src_caps) + return gst_caps_copy (video_yuv->src_caps); + + if (GST_PAD_CAPS (video_yuv->src)) + return gst_caps_copy (GST_PAD_CAPS (video_yuv->src)); + + return gst_caps_copy (gst_pad_get_pad_template_caps (video_yuv->src)); +} + +/* GObject vmethod implementations */ + +static void +gst_vdp_video_yuv_base_init (gpointer klass) +{ + GstElementClass *element_class = GST_ELEMENT_CLASS (klass); + + gst_element_class_set_details_simple (element_class, + "VdpauVideoYUV", + "Covideo_yuv/Decoder/Video", + "VDPAU video surface to YUV", + "Carl-Anton Ingmarsson "); + + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&sink_template)); + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&src_template)); +} + +static void +gst_vdp_video_yuv_class_init (GstVdpVideoYUVClass * klass) +{ + GObjectClass *gobject_class; + GstElementClass *gstelement_class; + + gobject_class = (GObjectClass *) klass; + gstelement_class = (GstElementClass *) klass; + + gobject_class->finalize = gst_vdp_video_yuv_finalize; + gobject_class->set_property = gst_vdp_video_yuv_set_property; + gobject_class->get_property = gst_vdp_video_yuv_get_property; +} + +static void +gst_vdp_video_yuv_init (GstVdpVideoYUV * video_yuv, GstVdpVideoYUVClass * klass) +{ + video_yuv->src_caps = NULL; + + video_yuv->height = 0; + video_yuv->width = 0; + video_yuv->framerate_numerator = 0; + video_yuv->framerate_denominator = 0; + video_yuv->par_numerator = 1; + video_yuv->par_denominator = 1; + + video_yuv->src = gst_pad_new_from_static_template (&src_template, "src"); + gst_pad_set_getcaps_function (video_yuv->src, gst_vdp_video_yuv_src_getcaps); + gst_element_add_pad (GST_ELEMENT (video_yuv), video_yuv->src); + + video_yuv->sink = gst_pad_new_from_static_template (&sink_template, "sink"); + gst_pad_set_setcaps_function (video_yuv->sink, + gst_vdp_video_yuv_sink_set_caps); + gst_pad_set_chain_function (video_yuv->sink, gst_vdp_video_yuv_chain); + gst_element_add_pad (GST_ELEMENT (video_yuv), video_yuv->sink); + gst_pad_set_active (video_yuv->sink, TRUE); +} + +static void +gst_vdp_video_yuv_finalize (GObject * object) +{ + GstVdpVideoYUV *video_yuv = (GstVdpVideoYUV *) object; + + if (video_yuv->src_caps) + gst_caps_unref (video_yuv->src_caps); +} + +static void +gst_vdp_video_yuv_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + switch (prop_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_vdp_video_yuv_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) +{ + switch (prop_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} diff --git a/sys/vdpau/gstvdpvideoyuv.h b/sys/vdpau/gstvdpvideoyuv.h new file mode 100644 index 00000000..f2aa4c82 --- /dev/null +++ b/sys/vdpau/gstvdpvideoyuv.h @@ -0,0 +1,60 @@ +/* + * GStreamer + * Copyright (C) 2009 Carl-Anton Ingmarsson + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GST_VDPAU_VIDEO_YUV_H__ +#define __GST_VDPAU_VIDEO_YUV_H__ + +#include + +#include "gstvdpdevice.h" + +G_BEGIN_DECLS + +#define GST_TYPE_VDPAU_VIDEO_YUV (gst_vdp_video_yuv_get_type()) +#define GST_VDPAU_VIDEO_YUV(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VDPAU_VIDEO_YUV,GstVdpVideoYUV)) +#define GST_VDPAU_VIDEO_YUV_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VDPAU_VIDEO_YUV,GstVdpVideoYUVClass)) +#define GST_VDPAU_VIDEO_YUV_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VDPAU_VIDEO_YUV, GstVdpVideoYUVClass)) +#define GST_IS_VDPAU_VIDEO_YUV(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VDPAU_VIDEO_YUV)) +#define GST_IS_VDPAU_VIDEO_YUV_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VDPAU_VIDEO_YUV)) + +typedef struct _GstVdpVideoYUV GstVdpVideoYUV; +typedef struct _GstVdpVideoYUVClass GstVdpVideoYUVClass; + +struct _GstVdpVideoYUV { + GstElement element; + + GstPad *src, *sink; + GstCaps *src_caps; + + gint width, height; + gint framerate_numerator, framerate_denominator; + gint par_numerator, par_denominator; + guint format; +}; + +struct _GstVdpVideoYUVClass { + GstElementClass parent_class; +}; + +GType gst_vdp_video_yuv_get_type (void); + +G_END_DECLS + +#endif /* __GST_VDPAU_VIDEO_YUV_H__ */ diff --git a/sys/vdpau/gstvdpyuvvideo.c b/sys/vdpau/gstvdpyuvvideo.c new file mode 100644 index 00000000..d5ed01cb --- /dev/null +++ b/sys/vdpau/gstvdpyuvvideo.c @@ -0,0 +1,476 @@ +/* + * GStreamer + * Copyright (C) 2009 Carl-Anton Ingmarsson + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#include "gstvdpvideobuffer.h" +#include "gstvdpyuvvideo.h" + +GST_DEBUG_CATEGORY_STATIC (gst_vdp_yuv_video_debug); +#define GST_CAT_DEFAULT gst_vdp_yuv_video_debug + +/* Filter signals and args */ +enum +{ + /* FILL ME */ + LAST_SIGNAL +}; + +enum +{ + PROP_0, + PROP_DISPLAY +}; + +static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS ("video/x-raw-yuv, " + "framerate = (fraction) [ 0, MAX ], " + "width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ]")); + +static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS (GST_VDPAU_VIDEO_CAPS)); + +#define DEBUG_INIT(bla) \ + GST_DEBUG_CATEGORY_INIT (gst_vdp_yuv_video_debug, "vdpauvideoyuv", 0, "YUV to VDPAU video surface"); + +GST_BOILERPLATE_FULL (GstVdpYUVVideo, gst_vdp_yuv_video, GstElement, + GST_TYPE_ELEMENT, DEBUG_INIT); + +static void gst_vdp_yuv_video_finalize (GObject * object); +static void gst_vdp_yuv_video_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec); +static void gst_vdp_yuv_video_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec); + +GstFlowReturn +gst_vdp_yuv_video_chain (GstPad * pad, GstBuffer * buffer) +{ + GstVdpYUVVideo *yuv_video; + GstVdpDevice *device; + VdpVideoSurface surface; + GstBuffer *outbuf = NULL; + + yuv_video = GST_VDPAU_YUV_VIDEO (GST_OBJECT_PARENT (pad)); + device = yuv_video->device; + + outbuf = + GST_BUFFER (gst_vdp_video_buffer_new (device, yuv_video->chroma_type, + yuv_video->width, yuv_video->height)); + surface = GST_VDPAU_VIDEO_BUFFER (outbuf)->surface; + + switch (yuv_video->format) { + case GST_MAKE_FOURCC ('Y', 'V', '1', '2'): + { + VdpStatus status; + guint8 *data[3]; + guint32 stride[3]; + + data[0] = GST_BUFFER_DATA (buffer) + + gst_video_format_get_component_offset (GST_VIDEO_FORMAT_YV12, + 0, yuv_video->width, yuv_video->height); + data[1] = GST_BUFFER_DATA (buffer) + + gst_video_format_get_component_offset (GST_VIDEO_FORMAT_YV12, + 2, yuv_video->width, yuv_video->height); + data[2] = GST_BUFFER_DATA (buffer) + + gst_video_format_get_component_offset (GST_VIDEO_FORMAT_YV12, + 1, yuv_video->width, yuv_video->height); + + stride[0] = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_YV12, + 0, yuv_video->width); + stride[1] = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_YV12, + 2, yuv_video->width); + stride[2] = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_YV12, + 1, yuv_video->width); + + status = + device->vdp_video_surface_put_bits_ycbcr (surface, + VDP_YCBCR_FORMAT_YV12, (void *) data, stride); + if (G_UNLIKELY (status != VDP_STATUS_OK)) { + GST_ELEMENT_ERROR (yuv_video, RESOURCE, READ, + ("Couldn't push YV12 data to VDPAU"), + ("Error returned from vdpau was: %s", + device->vdp_get_error_string (status))); + goto error; + } + break; + } + case GST_MAKE_FOURCC ('I', '4', '2', '0'): + { + VdpStatus status; + guint8 *data[3]; + guint32 stride[3]; + + data[0] = GST_BUFFER_DATA (buffer) + + gst_video_format_get_component_offset (GST_VIDEO_FORMAT_I420, + 0, yuv_video->width, yuv_video->height); + data[1] = GST_BUFFER_DATA (buffer) + + gst_video_format_get_component_offset (GST_VIDEO_FORMAT_I420, + 2, yuv_video->width, yuv_video->height); + data[2] = GST_BUFFER_DATA (buffer) + + gst_video_format_get_component_offset (GST_VIDEO_FORMAT_I420, + 1, yuv_video->width, yuv_video->height); + + stride[0] = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_I420, + 0, yuv_video->width); + stride[1] = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_I420, + 2, yuv_video->width); + stride[2] = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_I420, + 1, yuv_video->width); + + status = + device->vdp_video_surface_put_bits_ycbcr (surface, + VDP_YCBCR_FORMAT_YV12, (void *) data, stride); + if (G_UNLIKELY (status != VDP_STATUS_OK)) { + GST_ELEMENT_ERROR (yuv_video, RESOURCE, READ, + ("Couldn't push YV12 data to VDPAU"), + ("Error returned from vdpau was: %s", + device->vdp_get_error_string (status))); + goto error; + } + break; + } + case GST_MAKE_FOURCC ('N', 'V', '1', '2'): + { + VdpStatus status; + guint8 *data[2]; + guint32 stride[2]; + + data[0] = GST_BUFFER_DATA (buffer); + data[1] = GST_BUFFER_DATA (buffer) + yuv_video->width * yuv_video->height; + + stride[0] = yuv_video->width; + stride[1] = yuv_video->width; + + status = + device->vdp_video_surface_put_bits_ycbcr (surface, + VDP_YCBCR_FORMAT_NV12, (void *) data, stride); + if (G_UNLIKELY (status != VDP_STATUS_OK)) { + GST_ELEMENT_ERROR (yuv_video, RESOURCE, READ, + ("Couldn't get data from vdpau"), + ("Error returned from vdpau was: %s", + device->vdp_get_error_string (status))); + goto error; + } + break; + } + default: + break; + } + + gst_buffer_unref (buffer); + + gst_buffer_copy_metadata (outbuf, buffer, GST_BUFFER_COPY_TIMESTAMPS); + gst_buffer_set_caps (outbuf, GST_PAD_CAPS (yuv_video->src)); + + return gst_pad_push (yuv_video->src, outbuf); + +error: + gst_buffer_unref (outbuf); + return GST_FLOW_ERROR; +} + +static GstCaps * +gst_vdp_yuv_video_get_caps (GstVdpYUVVideo * yuv_video) +{ + GstVdpDevice *device; + GstCaps *caps; + gint i; + + device = yuv_video->device; + + caps = gst_caps_new_empty (); + + for (i = 0; i < N_CHROMA_TYPES; i++) { + VdpStatus status; + VdpBool is_supported; + guint32 max_w, max_h; + + status = + device->vdp_video_surface_query_capabilities (device->device, + chroma_types[i], &is_supported, &max_w, &max_h); + + if (status != VDP_STATUS_OK && status != VDP_STATUS_INVALID_CHROMA_TYPE) { + GST_ELEMENT_ERROR (yuv_video, RESOURCE, READ, + ("Could not get query VDPAU video surface capabilites"), + ("Error returned from vdpau was: %s", + device->vdp_get_error_string (status))); + + goto error; + } + if (is_supported) { + gint j; + + for (j = 0; j < N_FORMATS; j++) { + if (formats[j].chroma_type != chroma_types[i]) + continue; + + status = + device->vdp_video_surface_query_ycbcr_capabilities (device->device, + formats[j].chroma_type, formats[j].format, &is_supported); + if (status != VDP_STATUS_OK + && status != VDP_STATUS_INVALID_Y_CB_CR_FORMAT) { + GST_ELEMENT_ERROR (yuv_video, RESOURCE, READ, + ("Could not query VDPAU YCbCr capabilites"), + ("Error returned from vdpau was: %s", + device->vdp_get_error_string (status))); + + goto error; + } + if (is_supported) { + GstCaps *format_caps; + + format_caps = gst_caps_new_simple ("video/x-raw-yuv", + "format", GST_TYPE_FOURCC, formats[j].fourcc, + "width", GST_TYPE_INT_RANGE, 1, max_w, + "height", GST_TYPE_INT_RANGE, 1, max_h, + "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL); + gst_caps_append (caps, format_caps); + } + } + } + } +error: + if (gst_caps_is_empty (caps)) { + gst_caps_unref (caps); + return NULL; + } + + return caps; +} + +static gboolean +gst_vdp_yuv_video_sink_setcaps (GstPad * pad, GstCaps * caps) +{ + GstVdpYUVVideo *yuv_video = GST_VDPAU_YUV_VIDEO (GST_OBJECT_PARENT (pad)); + + GstStructure *structure; + guint32 fourcc; + gint chroma_type = 0; + gint width, height; + gint framerate_numerator, framerate_denominator; + gint par_numerator, par_denominator; + gint i; + GstCaps *src_caps, *new_caps; + gboolean res; + + structure = gst_caps_get_structure (caps, 0); + + gst_structure_get_fourcc (structure, "format", &fourcc); + gst_structure_get_int (structure, "width", &width); + gst_structure_get_int (structure, "height", &height); + gst_structure_get_fraction (structure, "framerate", + &framerate_numerator, &framerate_denominator); + gst_structure_get_fraction (structure, "pixel-aspect-ratio", + &par_numerator, &par_denominator); + + for (i = 0; i < N_FORMATS; i++) { + if (formats[i].fourcc == fourcc) { + chroma_type = formats[i].chroma_type; + break; + } + } + + src_caps = gst_pad_get_allowed_caps (yuv_video->src); + if (G_UNLIKELY (!src_caps || !gst_caps_get_size (src_caps))) + return FALSE; + + new_caps = gst_caps_copy_nth (src_caps, 0); + gst_caps_unref (src_caps); + if (G_UNLIKELY (!new_caps)) + return FALSE; + + structure = gst_caps_get_structure (new_caps, 0); + + gst_structure_set (structure, + "device", G_TYPE_OBJECT, yuv_video->device, + "chroma-type", G_TYPE_INT, chroma_type, + "width", G_TYPE_INT, width, + "height", G_TYPE_INT, height, + "framerate", GST_TYPE_FRACTION, framerate_numerator, + framerate_denominator, "pixel-aspect-ratio", GST_TYPE_FRACTION, + par_numerator, par_denominator, NULL); + + gst_pad_fixate_caps (yuv_video->src, new_caps); + res = gst_pad_set_caps (yuv_video->src, new_caps); + + gst_caps_unref (new_caps); + + if (G_UNLIKELY (!res)) + return FALSE; + + yuv_video->width = width; + yuv_video->height = height; + yuv_video->format = fourcc; + yuv_video->chroma_type = chroma_type; + + return TRUE; +} + +static GstCaps * +gst_vdp_yuv_video_sink_getcaps (GstPad * pad) +{ + GstVdpYUVVideo *yuv_video; + + yuv_video = GST_VDPAU_YUV_VIDEO (GST_OBJECT_PARENT (pad)); + + if (yuv_video->sink_caps) + return gst_caps_copy (yuv_video->sink_caps); + + return gst_caps_copy (gst_pad_get_pad_template_caps (yuv_video->sink)); +} + +static GstStateChangeReturn +gst_vdp_yuv_video_change_state (GstElement * element, GstStateChange transition) +{ + GstVdpYUVVideo *yuv_video; + + yuv_video = GST_VDPAU_YUV_VIDEO (element); + + switch (transition) { + case GST_STATE_CHANGE_NULL_TO_READY: + yuv_video->device = gst_vdp_get_device (yuv_video->display); + if (!yuv_video->sink_caps) + yuv_video->sink_caps = gst_vdp_yuv_video_get_caps (yuv_video); + break; + case GST_STATE_CHANGE_READY_TO_NULL: + g_object_unref (yuv_video->device); + yuv_video->device = NULL; + break; + default: + break; + } + + return GST_STATE_CHANGE_SUCCESS; +} + +/* GObject vmethod implementations */ + +static void +gst_vdp_yuv_video_base_init (gpointer klass) +{ + GstElementClass *element_class = GST_ELEMENT_CLASS (klass); + + gst_element_class_set_details_simple (element_class, + "VdpauYUVVideo", + "Coyuv_video/Decoder/Video", + "VDPAU video surface to YUV", + "Carl-Anton Ingmarsson "); + + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&sink_template)); + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&src_template)); +} + +static void +gst_vdp_yuv_video_class_init (GstVdpYUVVideoClass * klass) +{ + GObjectClass *gobject_class; + GstElementClass *gstelement_class; + + gobject_class = (GObjectClass *) klass; + gstelement_class = (GstElementClass *) klass; + + gobject_class->finalize = gst_vdp_yuv_video_finalize; + gobject_class->set_property = gst_vdp_yuv_video_set_property; + gobject_class->get_property = gst_vdp_yuv_video_get_property; + + g_object_class_install_property (gobject_class, PROP_DISPLAY, + g_param_spec_string ("display", "Display", "X Display name", + NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + + gstelement_class->change_state = gst_vdp_yuv_video_change_state; +} + +static void +gst_vdp_yuv_video_init (GstVdpYUVVideo * yuv_video, GstVdpYUVVideoClass * klass) +{ + yuv_video->sink_caps = NULL; + + yuv_video->display = NULL; + yuv_video->device = NULL; + + yuv_video->height = 0; + yuv_video->width = 0; + yuv_video->format = 0; + yuv_video->chroma_type = 0; + + yuv_video->src = gst_pad_new_from_static_template (&src_template, "src"); + gst_element_add_pad (GST_ELEMENT (yuv_video), yuv_video->src); + + yuv_video->sink = gst_pad_new_from_static_template (&sink_template, "sink"); + gst_pad_set_getcaps_function (yuv_video->sink, + gst_vdp_yuv_video_sink_getcaps); + gst_pad_set_setcaps_function (yuv_video->sink, + gst_vdp_yuv_video_sink_setcaps); + gst_pad_set_chain_function (yuv_video->sink, gst_vdp_yuv_video_chain); + gst_element_add_pad (GST_ELEMENT (yuv_video), yuv_video->sink); + gst_pad_set_active (yuv_video->sink, TRUE); +} + +static void +gst_vdp_yuv_video_finalize (GObject * object) +{ + GstVdpYUVVideo *yuv_video = (GstVdpYUVVideo *) object; + + g_free (yuv_video->display); +} + +static void +gst_vdp_yuv_video_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GstVdpYUVVideo *yuv_video = GST_VDPAU_YUV_VIDEO (object); + + switch (prop_id) { + case PROP_DISPLAY: + g_free (yuv_video->display); + yuv_video->display = g_value_dup_string (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_vdp_yuv_video_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) +{ + GstVdpYUVVideo *yuv_video = GST_VDPAU_YUV_VIDEO (object); + + switch (prop_id) { + case PROP_DISPLAY: + g_value_set_string (value, yuv_video->display); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} diff --git a/sys/vdpau/gstvdpyuvvideo.h b/sys/vdpau/gstvdpyuvvideo.h new file mode 100644 index 00000000..fbb7d96d --- /dev/null +++ b/sys/vdpau/gstvdpyuvvideo.h @@ -0,0 +1,62 @@ +/* + * GStreamer + * Copyright (C) 2009 Carl-Anton Ingmarsson + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GST_VDPAU_YUV_VIDEO_H__ +#define __GST_VDPAU_YUV_VIDEO_H__ + +#include + +#include "gstvdpdevice.h" + +G_BEGIN_DECLS + +#define GST_TYPE_VDPAU_YUV_VIDEO (gst_vdp_yuv_video_get_type()) +#define GST_VDPAU_YUV_VIDEO(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VDPAU_YUV_VIDEO,GstVdpYUVVideo)) +#define GST_VDPAU_YUV_VIDEO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VDPAU_YUV_VIDEO,GstVdpYUVVideoClass)) +#define GST_VDPAU_YUV_VIDEO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VDPAU_YUV_VIDEO, GstVdpYUVVideoClass)) +#define GST_IS_VDPAU_YUV_VIDEO(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VDPAU_YUV_VIDEO)) +#define GST_IS_VDPAU_YUV_VIDEO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VDPAU_YUV_VIDEO)) + +typedef struct _GstVdpYUVVideo GstVdpYUVVideo; +typedef struct _GstVdpYUVVideoClass GstVdpYUVVideoClass; + +struct _GstVdpYUVVideo { + GstElement element; + + GstPad *src, *sink; + GstCaps *sink_caps; + + gchar *display; + GstVdpDevice *device; + + guint32 format; + gint chroma_type; + gint width, height; +}; + +struct _GstVdpYUVVideoClass { + GstElementClass parent_class; +}; + +GType gst_vdp_yuv_video_get_type (void); + +G_END_DECLS + +#endif /* __GST_VDPAU_YUV_VIDEO_H__ */ -- cgit v1.2.1 From 1af393a72d675ac59f06c5751fe60ce170f9e545 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Mon, 13 Apr 2009 22:21:03 +0200 Subject: vdpau: small cosmetical fix --- sys/vdpau/gstvdp.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdp.c b/sys/vdpau/gstvdp.c index 2da9bdb0..9ca0114e 100644 --- a/sys/vdpau/gstvdp.c +++ b/sys/vdpau/gstvdp.c @@ -10,13 +10,13 @@ #include "gstvdpyuvvideo.h" static gboolean -vdpau_init (GstPlugin * vdpaumpegdecoder) +vdpau_init (GstPlugin * vdpau_plugin) { - gst_element_register (vdpaumpegdecoder, "vdpaumpegdecoder", + gst_element_register (vdpau_plugin, "vdpaumpegdecoder", GST_RANK_NONE, GST_TYPE_VDPAU_MPEG_DECODER); - gst_element_register (vdpaumpegdecoder, "vdpauvideoyuv", + gst_element_register (vdpau_plugin, "vdpauvideoyuv", GST_RANK_NONE, GST_TYPE_VDPAU_VIDEO_YUV); - gst_element_register (vdpaumpegdecoder, "vdpauyuvvideo", + gst_element_register (vdpau_plugin, "vdpauyuvvideo", GST_RANK_NONE, GST_TYPE_VDPAU_YUV_VIDEO); return TRUE; -- cgit v1.2.1 From 71c398566cf9f434d9a8fd7b98224c0e1f963910 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Tue, 14 Apr 2009 19:08:53 +0200 Subject: vdpaumpegdecoder: remove unnecesary want_slice field --- sys/vdpau/gstvdpmpegdecoder.c | 23 +++++++---------------- sys/vdpau/gstvdpmpegdecoder.h | 2 -- 2 files changed, 7 insertions(+), 18 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpmpegdecoder.c b/sys/vdpau/gstvdpmpegdecoder.c index df8a5b67..350414a7 100644 --- a/sys/vdpau/gstvdpmpegdecoder.c +++ b/sys/vdpau/gstvdpmpegdecoder.c @@ -217,8 +217,6 @@ gst_vdp_mpeg_decoder_parse_picture_coding (GstVdpMpegDecoder * mpeg_dec, info->q_scale_type = pic_ext.q_scale_type; info->intra_vlc_format = pic_ext.intra_vlc_format; - mpeg_dec->want_slice = TRUE; - return TRUE; } @@ -269,10 +267,7 @@ gst_vdp_mpeg_decoder_parse_picture (GstVdpMpegDecoder * mpeg_dec, mpeg_dec->vdp_info.full_pel_backward_vector = pic_hdr.full_pel_backward_vector; memcpy (&mpeg_dec->vdp_info.f_code, &pic_hdr.f_code, 4); - - mpeg_dec->want_slice = TRUE; - } else - mpeg_dec->want_slice = FALSE; + } return TRUE; } @@ -332,19 +327,17 @@ gst_vdp_mpeg_decoder_chain (GstPad * pad, GstBuffer * buffer) GstBuffer *subbuf; GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_SLICE"); - if (mpeg_dec->want_slice) { - subbuf = - gst_buffer_create_sub (buffer, - packet_start - GST_BUFFER_DATA (buffer), packet_end - packet_start); - gst_adapter_push (mpeg_dec->adapter, subbuf); - mpeg_dec->vdp_info.slice_count++; - } + subbuf = + gst_buffer_create_sub (buffer, + packet_start - GST_BUFFER_DATA (buffer), packet_end - packet_start); + gst_adapter_push (mpeg_dec->adapter, subbuf); + mpeg_dec->vdp_info.slice_count++; } switch (data[0]) { case MPEG_PACKET_PICTURE: GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_PICTURE"); - if (mpeg_dec->vdp_info.slice_count > 0 && mpeg_dec->want_slice) { + if (mpeg_dec->vdp_info.slice_count > 0) { if (gst_vdp_mpeg_decoder_decode (mpeg_dec) != GST_FLOW_OK) return GST_FLOW_ERROR; } @@ -445,8 +438,6 @@ gst_vdp_mpeg_decoder_init (GstVdpMpegDecoder * mpeg_dec, mpeg_dec->adapter = gst_adapter_new (); - mpeg_dec->want_slice = FALSE; - gst_pad_set_chain_function (dec->sink, gst_vdp_mpeg_decoder_chain); } diff --git a/sys/vdpau/gstvdpmpegdecoder.h b/sys/vdpau/gstvdpmpegdecoder.h index dc90764b..b8f01bdf 100644 --- a/sys/vdpau/gstvdpmpegdecoder.h +++ b/sys/vdpau/gstvdpmpegdecoder.h @@ -46,8 +46,6 @@ struct _GstVdpMpegDecoder VdpDecoder decoder; VdpPictureInfoMPEG1Or2 vdp_info; GstBuffer *f_buffer; - - gboolean want_slice; GstAdapter *adapter; gint slices; -- cgit v1.2.1 From 4470b61f8064758a2998d8b513304e0854170321 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Tue, 14 Apr 2009 21:04:59 +0200 Subject: vdpaumpegdecoder: rename to "vdpaumpegdec" --- sys/vdpau/gstvdp.c | 2 +- sys/vdpau/gstvdpmpegdecoder.c | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdp.c b/sys/vdpau/gstvdp.c index 9ca0114e..b18c8a02 100644 --- a/sys/vdpau/gstvdp.c +++ b/sys/vdpau/gstvdp.c @@ -12,7 +12,7 @@ static gboolean vdpau_init (GstPlugin * vdpau_plugin) { - gst_element_register (vdpau_plugin, "vdpaumpegdecoder", + gst_element_register (vdpau_plugin, "vdpaumpegdec", GST_RANK_NONE, GST_TYPE_VDPAU_MPEG_DECODER); gst_element_register (vdpau_plugin, "vdpauvideoyuv", GST_RANK_NONE, GST_TYPE_VDPAU_VIDEO_YUV); diff --git a/sys/vdpau/gstvdpmpegdecoder.c b/sys/vdpau/gstvdpmpegdecoder.c index 350414a7..e1f9e56c 100644 --- a/sys/vdpau/gstvdpmpegdecoder.c +++ b/sys/vdpau/gstvdpmpegdecoder.c @@ -19,14 +19,14 @@ */ /** - * SECTION:element-vdpaumpegdecoder + * SECTION:element-vdpaumpegdec * - * FIXME:Describe vdpaumpegdecoder here. + * FIXME:Describe vdpaumpegdec here. * * * Example launch line * |[ - * gst-launch -v -m fakesrc ! vdpaumpegdecoder ! fakesink silent=TRUE + * gst-launch -v -m fakesrc ! vdpaumpegdec ! fakesink silent=TRUE * ]| * */ @@ -68,7 +68,7 @@ static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink", ); #define DEBUG_INIT(bla) \ -GST_DEBUG_CATEGORY_INIT (gst_vdp_mpeg_decoder_debug, "vdpaumpegdecoder", 0, "VDPAU powered mpeg decoder"); +GST_DEBUG_CATEGORY_INIT (gst_vdp_mpeg_decoder_debug, "vdpaumpegdec", 0, "VDPAU powered mpeg decoder"); GST_BOILERPLATE_FULL (GstVdpMpegDecoder, gst_vdp_mpeg_decoder, GstVdpDecoder, GST_TYPE_VDPAU_DECODER, DEBUG_INIT); @@ -384,7 +384,7 @@ gst_vdp_mpeg_decoder_base_init (gpointer gclass) GstElementClass *element_class = GST_ELEMENT_CLASS (gclass); gst_element_class_set_details_simple (element_class, - "VdpauMpegDecoder", + "VDPAU Mpeg Decoder", "Decoder", "decode mpeg stream with vdpau", "Carl-Anton Ingmarsson "); -- cgit v1.2.1 From 500861d5171e3c0811a9c8bdf1b9b5631a77f7fe Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Tue, 14 Apr 2009 21:05:44 +0200 Subject: vdpau: don't set element details in GstVdpDecoder --- sys/vdpau/gstvdpdecoder.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpdecoder.c b/sys/vdpau/gstvdpdecoder.c index 2e92381f..ba1ca7c0 100644 --- a/sys/vdpau/gstvdpdecoder.c +++ b/sys/vdpau/gstvdpdecoder.c @@ -165,12 +165,6 @@ gst_vdp_decoder_base_init (gpointer klass) { GstElementClass *element_class = GST_ELEMENT_CLASS (klass); - gst_element_class_set_details_simple (element_class, - "VdpauDecoder", - "Codec/Decoder/Video", - "VDPAU decoder base class", - "Carl-Anton Ingmarsson "); - gst_element_class_add_pad_template (element_class, gst_static_pad_template_get (&src_template)); } -- cgit v1.2.1 From 4ee4429c1ac2a1927ee71a19427a7cc9498f8cab Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Tue, 14 Apr 2009 21:07:32 +0200 Subject: vdpau: remove "silent" property from GstVdpDecoder --- sys/vdpau/gstvdpdecoder.c | 14 +------------- sys/vdpau/gstvdpdecoder.h | 2 -- 2 files changed, 1 insertion(+), 15 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpdecoder.c b/sys/vdpau/gstvdpdecoder.c index ba1ca7c0..fc8beb1f 100644 --- a/sys/vdpau/gstvdpdecoder.c +++ b/sys/vdpau/gstvdpdecoder.c @@ -40,8 +40,7 @@ enum enum { PROP_0, - PROP_DISPLAY, - PROP_SILENT + PROP_DISPLAY }; static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src", @@ -187,10 +186,6 @@ gst_vdp_decoder_class_init (GstVdpDecoderClass * klass) g_param_spec_string ("display", "Display", "X Display name", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); - g_object_class_install_property (gobject_class, PROP_SILENT, - g_param_spec_boolean ("silent", "Silent", "Produce verbose output ?", - FALSE, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE)); - gstelement_class->change_state = gst_vdp_decoder_change_state; } @@ -199,7 +194,6 @@ gst_vdp_decoder_init (GstVdpDecoder * dec, GstVdpDecoderClass * klass) { dec->display_name = NULL; dec->device = NULL; - dec->silent = FALSE; dec->height = 0; dec->width = 0; @@ -240,9 +234,6 @@ gst_vdp_decoder_set_property (GObject * object, guint prop_id, g_free (dec->display_name); dec->display_name = g_value_dup_string (value); break; - case PROP_SILENT: - dec->silent = g_value_get_boolean (value); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -259,9 +250,6 @@ gst_vdp_decoder_get_property (GObject * object, guint prop_id, case PROP_DISPLAY: g_value_set_string (value, dec->display_name); break; - case PROP_SILENT: - g_value_set_boolean (value, dec->silent); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; diff --git a/sys/vdpau/gstvdpdecoder.h b/sys/vdpau/gstvdpdecoder.h index f918225e..8dc4ad66 100644 --- a/sys/vdpau/gstvdpdecoder.h +++ b/sys/vdpau/gstvdpdecoder.h @@ -53,8 +53,6 @@ struct _GstVdpDecoder { guint32 format; gint frame_nr; - - gboolean silent; }; struct _GstVdpDecoderClass { -- cgit v1.2.1 From 08690f10f81b3a699c4d98a139b46b1fef1971a6 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Tue, 14 Apr 2009 23:47:40 +0200 Subject: vdpau: rename "video/vdpau-video" caps to "video/x-vdpau-video" --- sys/vdpau/gstvdpdecoder.c | 2 +- sys/vdpau/gstvdpvideobuffer.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpdecoder.c b/sys/vdpau/gstvdpdecoder.c index fc8beb1f..dafcec98 100644 --- a/sys/vdpau/gstvdpdecoder.c +++ b/sys/vdpau/gstvdpdecoder.c @@ -46,7 +46,7 @@ enum static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS, - GST_STATIC_CAPS ("video/vdpau-video, " "chroma-type = (int) 0")); + GST_STATIC_CAPS ("video/x-vdpau-video, " "chroma-type = (int) 0")); #define DEBUG_INIT(bla) \ GST_DEBUG_CATEGORY_INIT (gst_vdp_decoder_debug, "vdpaudecoder", 0, "vdpaudecoder base class"); diff --git a/sys/vdpau/gstvdpvideobuffer.h b/sys/vdpau/gstvdpvideobuffer.h index ab4fb154..bbfc7af0 100644 --- a/sys/vdpau/gstvdpvideobuffer.h +++ b/sys/vdpau/gstvdpvideobuffer.h @@ -47,7 +47,7 @@ GType gst_vdp_video_buffer_get_type (void); GstVdpVideoBuffer* gst_vdp_video_buffer_new (GstVdpDevice * device, VdpChromaType chroma_type, gint width, gint height); #define GST_VDPAU_VIDEO_CAPS \ - "video/vdpau-video, " \ + "video/x-vdpau-video, " \ "chroma-type = (int)[0,2], " \ "width = (int)[1,4096], " \ "height = (int)[1,4096]" -- cgit v1.2.1 From 638a35eaccf3115644d3581e3877111c8f8f255e Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Wed, 15 Apr 2009 17:52:27 +0200 Subject: vdpaumpegdecoder: remove unused slice field --- sys/vdpau/gstvdpmpegdecoder.h | 1 - 1 file changed, 1 deletion(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpmpegdecoder.h b/sys/vdpau/gstvdpmpegdecoder.h index b8f01bdf..3ec8244d 100644 --- a/sys/vdpau/gstvdpmpegdecoder.h +++ b/sys/vdpau/gstvdpmpegdecoder.h @@ -48,7 +48,6 @@ struct _GstVdpMpegDecoder GstBuffer *f_buffer; GstAdapter *adapter; - gint slices; }; struct _GstVdpMpegDecoderClass -- cgit v1.2.1 From ee591b9f3d01865389a7a5dc4b8381466d0096e0 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Wed, 15 Apr 2009 18:17:54 +0200 Subject: vdpaumpegdec: correct some default values mpeg1 now give nearly correct output :) --- sys/vdpau/gstvdpmpegdecoder.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpmpegdecoder.c b/sys/vdpau/gstvdpmpegdecoder.c index e1f9e56c..7aefe73c 100644 --- a/sys/vdpau/gstvdpmpegdecoder.c +++ b/sys/vdpau/gstvdpmpegdecoder.c @@ -418,11 +418,15 @@ gst_vdp_mpeg_decoder_init_info (VdpPictureInfoMPEG1Or2 * vdp_info) vdp_info->forward_reference = VDP_INVALID_HANDLE; vdp_info->backward_reference = VDP_INVALID_HANDLE; vdp_info->slice_count = 0; - vdp_info->picture_structure = 0; + vdp_info->picture_structure = 3; vdp_info->picture_coding_type = 0; vdp_info->intra_dc_precision = 0; - vdp_info->frame_pred_frame_dct = 0; + vdp_info->frame_pred_frame_dct = 1; vdp_info->concealment_motion_vectors = 0; + vdp_info->intra_vlc_format = 0; + vdp_info->alternate_scan = 0; + vdp_info->q_scale_type = 0; + vdp_info->top_field_first = 1; } static void -- cgit v1.2.1 From 375935d9c419b90d6b82686c5ddd9be7b5637382 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Wed, 15 Apr 2009 23:31:33 +0200 Subject: vdpaumpegdec: fixup quantmatrix extension parsing --- sys/vdpau/gstvdpmpegdecoder.c | 10 +++++----- sys/vdpau/mpegutil.c | 15 +++++++-------- 2 files changed, 12 insertions(+), 13 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpmpegdecoder.c b/sys/vdpau/gstvdpmpegdecoder.c index 7aefe73c..be432281 100644 --- a/sys/vdpau/gstvdpmpegdecoder.c +++ b/sys/vdpau/gstvdpmpegdecoder.c @@ -355,15 +355,15 @@ gst_vdp_mpeg_decoder_chain (GstPad * pad, GstBuffer * buffer) gst_vdp_mpeg_decoder_parse_picture_coding (mpeg_dec, packet_start, packet_end); break; + case MPEG_PACKET_EXT_QUANT_MATRIX: + GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_EXT_QUANT_MATRIX"); + gst_vdp_mpeg_decoder_parse_quant_matrix (mpeg_dec, packet_start, + packet_end); + break; default: break; } break; - case MPEG_PACKET_EXT_QUANT_MATRIX: - GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_EXT_QUANT_MATRIX"); - gst_vdp_mpeg_decoder_parse_quant_matrix (mpeg_dec, packet_start, - packet_end); - break; case MPEG_PACKET_GOP: GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_GOP"); gst_vdp_mpeg_decoder_parse_gop (mpeg_dec, packet_start, packet_end); diff --git a/sys/vdpau/mpegutil.c b/sys/vdpau/mpegutil.c index 3a4a63de..7ef46fb2 100644 --- a/sys/vdpau/mpegutil.c +++ b/sys/vdpau/mpegutil.c @@ -385,31 +385,30 @@ mpeg_util_parse_quant_matrix (MPEGQuantMatrix * qm, guint8 * data, guint8 * end) code = GST_READ_UINT32_BE (data); - if (G_UNLIKELY (G_UNLIKELY (code != (0x00000100 | MPEG_PACKET_GOP)))) + if (G_UNLIKELY (G_UNLIKELY (code != (0x00000100 | MPEG_PACKET_EXTENSION)))) return FALSE; /* Skip the sync word */ data += 4; - load_intra_flag = read_bits (data, 0, 1); + load_intra_flag = read_bits (data, 4, 1); if (load_intra_flag) { if (G_UNLIKELY ((end - data) < 64)) return FALSE; - for (i = 0; i < 64; i++) { - qm->intra_quantizer_matrix[mpeg2_scan[i]] = read_bits (data + i, 1, 8); - } - data += 64; + for (i = 0; i < 64; i++) + qm->intra_quantizer_matrix[mpeg2_scan[i]] = read_bits (data + i, 5, 8); + data += 64; } else memcpy (qm->intra_quantizer_matrix, default_intra_quantizer_matrix, 64); - load_non_intra_flag = read_bits (data, 1 + load_intra_flag, 1); + load_non_intra_flag = read_bits (data, 5 + load_intra_flag, 1); if (load_non_intra_flag) { if (G_UNLIKELY ((end - data) < 64)) return FALSE; for (i = 0; i < 64; i++) qm->non_intra_quantizer_matrix[mpeg2_scan[i]] = - read_bits (data + i, 2 + load_intra_flag, 8); + read_bits (data + i, 6 + load_intra_flag, 8); } else memset (qm->non_intra_quantizer_matrix, 16, 64); -- cgit v1.2.1 From 000db36020bd6d31160bd0eb38ad27bb9687400a Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Wed, 15 Apr 2009 23:38:53 +0200 Subject: vdpaumpegdec: parse PICTURE_CODING_EXTENSION alternate_scan bit --- sys/vdpau/gstvdpmpegdecoder.c | 1 + sys/vdpau/mpegutil.c | 1 + sys/vdpau/mpegutil.h | 1 + 3 files changed, 3 insertions(+) (limited to 'sys') diff --git a/sys/vdpau/gstvdpmpegdecoder.c b/sys/vdpau/gstvdpmpegdecoder.c index be432281..053cf1c0 100644 --- a/sys/vdpau/gstvdpmpegdecoder.c +++ b/sys/vdpau/gstvdpmpegdecoder.c @@ -216,6 +216,7 @@ gst_vdp_mpeg_decoder_parse_picture_coding (GstVdpMpegDecoder * mpeg_dec, info->concealment_motion_vectors = pic_ext.concealment_motion_vectors; info->q_scale_type = pic_ext.q_scale_type; info->intra_vlc_format = pic_ext.intra_vlc_format; + info->alternate_scan = pic_ext.alternate_scan; return TRUE; } diff --git a/sys/vdpau/mpegutil.c b/sys/vdpau/mpegutil.c index 7ef46fb2..929df4ab 100644 --- a/sys/vdpau/mpegutil.c +++ b/sys/vdpau/mpegutil.c @@ -337,6 +337,7 @@ mpeg_util_parse_picture_coding_extension (MPEGPictureExt * ext, guint8 * data, ext->concealment_motion_vectors = read_bits (data + 3, 2, 1); ext->q_scale_type = read_bits (data + 3, 3, 1); ext->intra_vlc_format = read_bits (data + 3, 4, 1); + ext->alternate_scan = read_bits (data + 3, 5, 1); return TRUE; } diff --git a/sys/vdpau/mpegutil.h b/sys/vdpau/mpegutil.h index 5fb47290..24a29a35 100644 --- a/sys/vdpau/mpegutil.h +++ b/sys/vdpau/mpegutil.h @@ -90,6 +90,7 @@ struct MPEGPictureExt guint8 concealment_motion_vectors; guint8 q_scale_type; guint8 intra_vlc_format; + guint8 alternate_scan; }; struct MPEGPictureGOP -- cgit v1.2.1 From 7ca750c4229e1535deb3817687deefce9d4f9b42 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Wed, 15 Apr 2009 23:49:07 +0200 Subject: vdpaumpegdec: fixup GstFlowReturn propagation a bit --- sys/vdpau/gstvdpmpegdecoder.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpmpegdecoder.c b/sys/vdpau/gstvdpmpegdecoder.c index 053cf1c0..9b4aa99d 100644 --- a/sys/vdpau/gstvdpmpegdecoder.c +++ b/sys/vdpau/gstvdpmpegdecoder.c @@ -307,6 +307,7 @@ gst_vdp_mpeg_decoder_chain (GstPad * pad, GstBuffer * buffer) GstVdpMpegDecoder *mpeg_dec; guint8 *data, *end; guint32 sync_word = 0xffffffff; + GstFlowReturn ret = GST_FLOW_OK; mpeg_dec = GST_VDPAU_MPEG_DECODER (GST_OBJECT_PARENT (pad)); @@ -338,10 +339,9 @@ gst_vdp_mpeg_decoder_chain (GstPad * pad, GstBuffer * buffer) switch (data[0]) { case MPEG_PACKET_PICTURE: GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_PICTURE"); - if (mpeg_dec->vdp_info.slice_count > 0) { - if (gst_vdp_mpeg_decoder_decode (mpeg_dec) != GST_FLOW_OK) - return GST_FLOW_ERROR; - } + if (mpeg_dec->vdp_info.slice_count > 0) + ret = gst_vdp_mpeg_decoder_decode (mpeg_dec); + gst_vdp_mpeg_decoder_parse_picture (mpeg_dec, packet_start, packet_end); break; case MPEG_PACKET_SEQUENCE: @@ -374,7 +374,7 @@ gst_vdp_mpeg_decoder_chain (GstPad * pad, GstBuffer * buffer) } } - return GST_FLOW_OK; + return ret; } /* GObject vmethod implementations */ -- cgit v1.2.1 From da191134a1a66de4b5a591a5dea29dd4c0d8e92c Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Thu, 16 Apr 2009 22:06:50 +0200 Subject: vdpaumpegdec: inital support at handling B_FRAMES --- sys/vdpau/gstvdpmpegdecoder.c | 43 +++++++++++++++++++++++++++++++++++++++++++ sys/vdpau/gstvdpmpegdecoder.h | 4 ++++ 2 files changed, 47 insertions(+) (limited to 'sys') diff --git a/sys/vdpau/gstvdpmpegdecoder.c b/sys/vdpau/gstvdpmpegdecoder.c index 9b4aa99d..d2ec7fd1 100644 --- a/sys/vdpau/gstvdpmpegdecoder.c +++ b/sys/vdpau/gstvdpmpegdecoder.c @@ -148,6 +148,18 @@ gst_vdp_mpeg_decoder_decode (GstVdpMpegDecoder * mpeg_dec) buffer = gst_adapter_take_buffer (mpeg_dec->adapter, gst_adapter_available (mpeg_dec->adapter)); + /* if the frame is a B_FRAME we store it for future decoding */ + if (mpeg_dec->vdp_info.picture_coding_type == B_FRAME) { + mpeg_dec->b_buffer = buffer; + memcpy (&mpeg_dec->b_vdp_info, &mpeg_dec->vdp_info, + sizeof (VdpPictureInfoMPEG1Or2)); + + /* unset forward_reference since next frame must be an I_FRAME */ + mpeg_dec->vdp_info.forward_reference = VDP_INVALID_HANDLE; + + return GST_FLOW_OK; + } + outbuf = gst_vdp_video_buffer_new (dec->device, VDP_CHROMA_TYPE_420, dec->width, dec->height); surface = outbuf->surface; @@ -179,6 +191,35 @@ gst_vdp_mpeg_decoder_decode (GstVdpMpegDecoder * mpeg_dec) return GST_FLOW_ERROR; } + /* if we have stored away a B_FRAME we can now decode it */ + if (mpeg_dec->b_buffer) { + GstVdpVideoBuffer *b_outbuf; + + b_outbuf = gst_vdp_video_buffer_new (dec->device, VDP_CHROMA_TYPE_420, + dec->width, dec->height); + mpeg_dec->b_vdp_info.backward_reference = surface; + vbit[0].struct_version = VDP_BITSTREAM_BUFFER_VERSION; + vbit[0].bitstream = GST_BUFFER_DATA (mpeg_dec->b_buffer); + vbit[0].bitstream_bytes = GST_BUFFER_SIZE (mpeg_dec->b_buffer); + + status = device->vdp_decoder_render (mpeg_dec->decoder, b_outbuf->surface, + (VdpPictureInfo *) & mpeg_dec->b_vdp_info, 1, vbit); + gst_buffer_unref (mpeg_dec->b_buffer); + mpeg_dec->b_buffer = NULL; + + if (status != VDP_STATUS_OK) { + GST_ELEMENT_ERROR (mpeg_dec, RESOURCE, READ, + ("Could not decode B_FRAME"), + ("Error returned from vdpau was: %s", + device->vdp_get_error_string (status))); + + if (mpeg_dec->b_vdp_info.forward_reference != VDP_INVALID_HANDLE) + gst_buffer_unref (mpeg_dec->f_buffer); + } + + gst_vdp_decoder_push_video_buffer (GST_VDPAU_DECODER (mpeg_dec), b_outbuf); + } + gst_buffer_ref (GST_BUFFER (outbuf)); ret = gst_vdp_decoder_push_video_buffer (GST_VDPAU_DECODER (mpeg_dec), @@ -441,6 +482,8 @@ gst_vdp_mpeg_decoder_init (GstVdpMpegDecoder * mpeg_dec, mpeg_dec->decoder = VDP_INVALID_HANDLE; gst_vdp_mpeg_decoder_init_info (&mpeg_dec->vdp_info); + mpeg_dec->b_buffer = NULL; + mpeg_dec->adapter = gst_adapter_new (); gst_pad_set_chain_function (dec->sink, gst_vdp_mpeg_decoder_chain); diff --git a/sys/vdpau/gstvdpmpegdecoder.h b/sys/vdpau/gstvdpmpegdecoder.h index 3ec8244d..3761cff6 100644 --- a/sys/vdpau/gstvdpmpegdecoder.h +++ b/sys/vdpau/gstvdpmpegdecoder.h @@ -46,6 +46,10 @@ struct _GstVdpMpegDecoder VdpDecoder decoder; VdpPictureInfoMPEG1Or2 vdp_info; GstBuffer *f_buffer; + + /* holds B_FRAMES */ + GstBuffer *b_buffer; + VdpPictureInfoMPEG1Or2 b_vdp_info; GstAdapter *adapter; }; -- cgit v1.2.1 From a168fdc1d3dfa013c4b381dbe3914564ac79b444 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Thu, 16 Apr 2009 22:30:27 +0200 Subject: vdpaumpegdec: more B_FRAME work --- sys/vdpau/gstvdpmpegdecoder.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpmpegdecoder.c b/sys/vdpau/gstvdpmpegdecoder.c index d2ec7fd1..7c134afa 100644 --- a/sys/vdpau/gstvdpmpegdecoder.c +++ b/sys/vdpau/gstvdpmpegdecoder.c @@ -157,6 +157,8 @@ gst_vdp_mpeg_decoder_decode (GstVdpMpegDecoder * mpeg_dec) /* unset forward_reference since next frame must be an I_FRAME */ mpeg_dec->vdp_info.forward_reference = VDP_INVALID_HANDLE; + mpeg_dec->vdp_info.slice_count = 0; + return GST_FLOW_OK; } @@ -181,11 +183,6 @@ gst_vdp_mpeg_decoder_decode (GstVdpMpegDecoder * mpeg_dec) ("Error returned from vdpau was: %s", device->vdp_get_error_string (status))); - if (mpeg_dec->vdp_info.forward_reference != VDP_INVALID_HANDLE) { - gst_buffer_unref (mpeg_dec->f_buffer); - mpeg_dec->vdp_info.forward_reference = VDP_INVALID_HANDLE; - } - gst_buffer_unref (GST_BUFFER (outbuf)); return GST_FLOW_ERROR; @@ -197,7 +194,9 @@ gst_vdp_mpeg_decoder_decode (GstVdpMpegDecoder * mpeg_dec) b_outbuf = gst_vdp_video_buffer_new (dec->device, VDP_CHROMA_TYPE_420, dec->width, dec->height); - mpeg_dec->b_vdp_info.backward_reference = surface; + mpeg_dec->b_vdp_info.backward_reference = + mpeg_dec->b_vdp_info.forward_reference; + mpeg_dec->b_vdp_info.forward_reference = surface; vbit[0].struct_version = VDP_BITSTREAM_BUFFER_VERSION; vbit[0].bitstream = GST_BUFFER_DATA (mpeg_dec->b_buffer); vbit[0].bitstream_bytes = GST_BUFFER_SIZE (mpeg_dec->b_buffer); @@ -212,12 +211,12 @@ gst_vdp_mpeg_decoder_decode (GstVdpMpegDecoder * mpeg_dec) ("Could not decode B_FRAME"), ("Error returned from vdpau was: %s", device->vdp_get_error_string (status))); - - if (mpeg_dec->b_vdp_info.forward_reference != VDP_INVALID_HANDLE) - gst_buffer_unref (mpeg_dec->f_buffer); } gst_vdp_decoder_push_video_buffer (GST_VDPAU_DECODER (mpeg_dec), b_outbuf); + + if (mpeg_dec->b_vdp_info.forward_reference != VDP_INVALID_HANDLE) + gst_buffer_unref (mpeg_dec->f_buffer); } gst_buffer_ref (GST_BUFFER (outbuf)); -- cgit v1.2.1 From e0ddcabd7ab63c8060b7259e4075a0e88e5bcf66 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Thu, 16 Apr 2009 23:43:24 +0200 Subject: vdpaumpegdec: handle multiple B_FRAMEs in a row --- sys/vdpau/gstvdpmpegdecoder.c | 81 ++++++++++++++++++++++++++----------------- sys/vdpau/gstvdpmpegdecoder.h | 3 +- sys/vdpau/mpegutil.c | 5 +-- 3 files changed, 51 insertions(+), 38 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpmpegdecoder.c b/sys/vdpau/gstvdpmpegdecoder.c index 7c134afa..c40aee81 100644 --- a/sys/vdpau/gstvdpmpegdecoder.c +++ b/sys/vdpau/gstvdpmpegdecoder.c @@ -131,6 +131,12 @@ gst_vdp_mpeg_decoder_set_caps (GstVdpDecoder * dec, GstCaps * caps) return TRUE; } +typedef struct +{ + GstBuffer *buffer; + VdpPictureInfoMPEG1Or2 vdp_info; +} GstVdpBFrame; + static GstFlowReturn gst_vdp_mpeg_decoder_decode (GstVdpMpegDecoder * mpeg_dec) { @@ -150,13 +156,17 @@ gst_vdp_mpeg_decoder_decode (GstVdpMpegDecoder * mpeg_dec) /* if the frame is a B_FRAME we store it for future decoding */ if (mpeg_dec->vdp_info.picture_coding_type == B_FRAME) { - mpeg_dec->b_buffer = buffer; - memcpy (&mpeg_dec->b_vdp_info, &mpeg_dec->vdp_info, + GstVdpBFrame *b_frame; + + b_frame = g_slice_new (GstVdpBFrame); + + b_frame->buffer = buffer; + memcpy (&b_frame->vdp_info, &mpeg_dec->vdp_info, sizeof (VdpPictureInfoMPEG1Or2)); - /* unset forward_reference since next frame must be an I_FRAME */ - mpeg_dec->vdp_info.forward_reference = VDP_INVALID_HANDLE; + mpeg_dec->b_frames = g_slist_append (mpeg_dec->b_frames, b_frame); + gst_buffer_ref (mpeg_dec->f_buffer); mpeg_dec->vdp_info.slice_count = 0; return GST_FLOW_OK; @@ -188,35 +198,43 @@ gst_vdp_mpeg_decoder_decode (GstVdpMpegDecoder * mpeg_dec) return GST_FLOW_ERROR; } - /* if we have stored away a B_FRAME we can now decode it */ - if (mpeg_dec->b_buffer) { - GstVdpVideoBuffer *b_outbuf; - - b_outbuf = gst_vdp_video_buffer_new (dec->device, VDP_CHROMA_TYPE_420, - dec->width, dec->height); - mpeg_dec->b_vdp_info.backward_reference = - mpeg_dec->b_vdp_info.forward_reference; - mpeg_dec->b_vdp_info.forward_reference = surface; - vbit[0].struct_version = VDP_BITSTREAM_BUFFER_VERSION; - vbit[0].bitstream = GST_BUFFER_DATA (mpeg_dec->b_buffer); - vbit[0].bitstream_bytes = GST_BUFFER_SIZE (mpeg_dec->b_buffer); - - status = device->vdp_decoder_render (mpeg_dec->decoder, b_outbuf->surface, - (VdpPictureInfo *) & mpeg_dec->b_vdp_info, 1, vbit); - gst_buffer_unref (mpeg_dec->b_buffer); - mpeg_dec->b_buffer = NULL; - - if (status != VDP_STATUS_OK) { - GST_ELEMENT_ERROR (mpeg_dec, RESOURCE, READ, - ("Could not decode B_FRAME"), - ("Error returned from vdpau was: %s", - device->vdp_get_error_string (status))); - } + /* if we have stored away some B_FRAMEs we can now decode them */ + if (mpeg_dec->b_frames) { + GSList *iter; + + for (iter = mpeg_dec->b_frames; iter; iter = g_slist_next (iter)) { + GstVdpBFrame *b_frame; + GstVdpVideoBuffer *b_outbuf; - gst_vdp_decoder_push_video_buffer (GST_VDPAU_DECODER (mpeg_dec), b_outbuf); + b_frame = (GstVdpBFrame *) iter->data; + + b_outbuf = gst_vdp_video_buffer_new (dec->device, VDP_CHROMA_TYPE_420, + dec->width, dec->height); + + b_frame->vdp_info.forward_reference = surface; + vbit[0].struct_version = VDP_BITSTREAM_BUFFER_VERSION; + vbit[0].bitstream = GST_BUFFER_DATA (b_frame->buffer); + vbit[0].bitstream_bytes = GST_BUFFER_SIZE (b_frame->buffer); + + status = device->vdp_decoder_render (mpeg_dec->decoder, b_outbuf->surface, + (VdpPictureInfo *) & b_frame->vdp_info, 1, vbit); + gst_buffer_unref (b_frame->buffer); + g_slice_free (GstVdpBFrame, b_frame); + + if (status != VDP_STATUS_OK) { + GST_ELEMENT_ERROR (mpeg_dec, RESOURCE, READ, + ("Could not decode B_FRAME"), + ("Error returned from vdpau was: %s", + device->vdp_get_error_string (status))); + } + + gst_vdp_decoder_push_video_buffer (GST_VDPAU_DECODER (mpeg_dec), + b_outbuf); - if (mpeg_dec->b_vdp_info.forward_reference != VDP_INVALID_HANDLE) gst_buffer_unref (mpeg_dec->f_buffer); + } + g_slist_free (mpeg_dec->b_frames); + mpeg_dec->b_frames = NULL; } gst_buffer_ref (GST_BUFFER (outbuf)); @@ -295,7 +313,6 @@ gst_vdp_mpeg_decoder_parse_picture (GstVdpMpegDecoder * mpeg_dec, mpeg_dec->vdp_info.picture_coding_type = pic_hdr.pic_type; - if (pic_hdr.pic_type == I_FRAME && mpeg_dec->vdp_info.forward_reference != VDP_INVALID_HANDLE) { gst_buffer_unref (mpeg_dec->f_buffer); @@ -481,7 +498,7 @@ gst_vdp_mpeg_decoder_init (GstVdpMpegDecoder * mpeg_dec, mpeg_dec->decoder = VDP_INVALID_HANDLE; gst_vdp_mpeg_decoder_init_info (&mpeg_dec->vdp_info); - mpeg_dec->b_buffer = NULL; + mpeg_dec->b_frames = NULL; mpeg_dec->adapter = gst_adapter_new (); diff --git a/sys/vdpau/gstvdpmpegdecoder.h b/sys/vdpau/gstvdpmpegdecoder.h index 3761cff6..a03c17c2 100644 --- a/sys/vdpau/gstvdpmpegdecoder.h +++ b/sys/vdpau/gstvdpmpegdecoder.h @@ -48,8 +48,7 @@ struct _GstVdpMpegDecoder GstBuffer *f_buffer; /* holds B_FRAMES */ - GstBuffer *b_buffer; - VdpPictureInfoMPEG1Or2 b_vdp_info; + GSList *b_frames; GstAdapter *adapter; }; diff --git a/sys/vdpau/mpegutil.c b/sys/vdpau/mpegutil.c index 929df4ab..4586cd7d 100644 --- a/sys/vdpau/mpegutil.c +++ b/sys/vdpau/mpegutil.c @@ -285,14 +285,11 @@ mpeg_util_parse_picture_hdr (MPEGPictureHdr * hdr, guint8 * data, guint8 * end) /* Skip the sync word */ data += 4; - hdr->pic_type = (data[1] >> 3) & 0x07; + hdr->pic_type = read_bits (data + 1, 2, 3); if (hdr->pic_type == 0 || hdr->pic_type > 4) return FALSE; /* Corrupted picture packet */ if (hdr->pic_type == P_FRAME || hdr->pic_type == B_FRAME) { - if (G_UNLIKELY ((end - data) < 5)) - return FALSE; /* packet too small */ - hdr->full_pel_forward_vector = read_bits (data + 3, 5, 1); hdr->f_code[0][0] = hdr->f_code[0][1] = read_bits (data + 3, 6, 3); -- cgit v1.2.1 From fc3c9dba95e18647ab097edc7f2ba5dfecddb787 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Wed, 22 Apr 2009 20:25:55 +0200 Subject: vdpaumpegdec: fixup error where we set forward_reference instead of backward_reference --- sys/vdpau/gstvdpmpegdecoder.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpmpegdecoder.c b/sys/vdpau/gstvdpmpegdecoder.c index c40aee81..bbd5403f 100644 --- a/sys/vdpau/gstvdpmpegdecoder.c +++ b/sys/vdpau/gstvdpmpegdecoder.c @@ -211,7 +211,7 @@ gst_vdp_mpeg_decoder_decode (GstVdpMpegDecoder * mpeg_dec) b_outbuf = gst_vdp_video_buffer_new (dec->device, VDP_CHROMA_TYPE_420, dec->width, dec->height); - b_frame->vdp_info.forward_reference = surface; + b_frame->vdp_info.backward_reference = surface; vbit[0].struct_version = VDP_BITSTREAM_BUFFER_VERSION; vbit[0].bitstream = GST_BUFFER_DATA (b_frame->buffer); vbit[0].bitstream_bytes = GST_BUFFER_SIZE (b_frame->buffer); -- cgit v1.2.1 From 806d4ced04098470b92c3ff53fe82456f26682bc Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Wed, 22 Apr 2009 20:28:19 +0200 Subject: vdpaumpegdec: remove unneded gst_buffer_ref and the accompanying gst_buffer_unref --- sys/vdpau/gstvdpmpegdecoder.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpmpegdecoder.c b/sys/vdpau/gstvdpmpegdecoder.c index bbd5403f..978d0497 100644 --- a/sys/vdpau/gstvdpmpegdecoder.c +++ b/sys/vdpau/gstvdpmpegdecoder.c @@ -166,7 +166,6 @@ gst_vdp_mpeg_decoder_decode (GstVdpMpegDecoder * mpeg_dec) mpeg_dec->b_frames = g_slist_append (mpeg_dec->b_frames, b_frame); - gst_buffer_ref (mpeg_dec->f_buffer); mpeg_dec->vdp_info.slice_count = 0; return GST_FLOW_OK; @@ -230,8 +229,6 @@ gst_vdp_mpeg_decoder_decode (GstVdpMpegDecoder * mpeg_dec) gst_vdp_decoder_push_video_buffer (GST_VDPAU_DECODER (mpeg_dec), b_outbuf); - - gst_buffer_unref (mpeg_dec->f_buffer); } g_slist_free (mpeg_dec->b_frames); mpeg_dec->b_frames = NULL; -- cgit v1.2.1 From 17102ad0fadef83a0d8b0d807d698a104bc428b5 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Wed, 22 Apr 2009 21:04:58 +0200 Subject: vdpaumpegdec: convert all manual parsing to use read_bits instead --- sys/vdpau/mpegutil.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/mpegutil.c b/sys/vdpau/mpegutil.c index 4586cd7d..a1323f68 100644 --- a/sys/vdpau/mpegutil.c +++ b/sys/vdpau/mpegutil.c @@ -158,7 +158,7 @@ mpeg_util_parse_extension_packet (MPEGSeqHdr * hdr, guint8 * data, guint8 * end) if (G_UNLIKELY (data >= end)) return FALSE; /* short extension packet */ - ext_code = data[0] >> 4; + ext_code = read_bits (data, 0, 4); switch (ext_code) { case MPEG_PACKET_EXT_SEQUENCE: @@ -171,11 +171,13 @@ mpeg_util_parse_extension_packet (MPEGSeqHdr * hdr, guint8 * data, guint8 * end) /* need at least 10 bytes, minus 4 for the start code 000001b5 */ return FALSE; - horiz_size_ext = ((data[1] << 1) & 0x02) | ((data[2] >> 7) & 0x01); - vert_size_ext = (data[2] >> 5) & 0x03; hdr->profile = read_bits (data, 7, 3); - fps_n_ext = (data[5] >> 5) & 0x03; - fps_d_ext = data[5] & 0x1f; + + horiz_size_ext = read_bits (data + 1, 7, 2); + vert_size_ext = read_bits (data + 2, 1, 2); + + fps_n_ext = read_bits (data + 5, 1, 2); + fps_d_ext = read_bits (data + 5, 3, 5); hdr->fps_n *= (fps_n_ext + 1); hdr->fps_d *= (fps_d_ext + 1); @@ -215,15 +217,15 @@ mpeg_util_parse_sequence_hdr (MPEGSeqHdr * hdr, guint8 * data, guint8 * end) hdr->mpeg_version = 1; code = GST_READ_UINT32_BE (data); - hdr->width = (code >> 20) & 0xfff; - hdr->height = (code >> 8) & 0xfff; + hdr->width = read_bits (data, 0, 12); + hdr->height = read_bits (data + 1, 4, 12); - dar_idx = (code >> 4) & 0xf; + dar_idx = read_bits (data + 3, 0, 4); set_par_from_dar (hdr, dar_idx); - fps_idx = code & 0xf; + fps_idx = read_bits (data + 3, 4, 4); set_fps_from_code (hdr, fps_idx); - constrained_flag = (data[7] >> 2) & 0x01; + constrained_flag = read_bits (data + 7, 5, 1); load_intra_flag = read_bits (data + 7, 6, 1); if (load_intra_flag) { @@ -285,11 +287,14 @@ mpeg_util_parse_picture_hdr (MPEGPictureHdr * hdr, guint8 * data, guint8 * end) /* Skip the sync word */ data += 4; - hdr->pic_type = read_bits (data + 1, 2, 3); + hdr->pic_type = (data[1] >> 3) & 0x07; if (hdr->pic_type == 0 || hdr->pic_type > 4) return FALSE; /* Corrupted picture packet */ if (hdr->pic_type == P_FRAME || hdr->pic_type == B_FRAME) { + if (G_UNLIKELY ((end - data) < 5)) + return FALSE; /* packet too small */ + hdr->full_pel_forward_vector = read_bits (data + 3, 5, 1); hdr->f_code[0][0] = hdr->f_code[0][1] = read_bits (data + 3, 6, 3); -- cgit v1.2.1 From 035b5f4efb4d57fccf2a5fa220c0d034f4d777a3 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Wed, 22 Apr 2009 23:35:07 +0200 Subject: vdpaumpegdec: handle broken_gop field --- sys/vdpau/gstvdpmpegdecoder.c | 10 ++++++++++ sys/vdpau/gstvdpmpegdecoder.h | 2 ++ sys/vdpau/mpegutil.c | 15 ++++++--------- sys/vdpau/mpegutil.h | 6 ++++-- 4 files changed, 22 insertions(+), 11 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpmpegdecoder.c b/sys/vdpau/gstvdpmpegdecoder.c index 978d0497..d9b74706 100644 --- a/sys/vdpau/gstvdpmpegdecoder.c +++ b/sys/vdpau/gstvdpmpegdecoder.c @@ -158,6 +158,12 @@ gst_vdp_mpeg_decoder_decode (GstVdpMpegDecoder * mpeg_dec) if (mpeg_dec->vdp_info.picture_coding_type == B_FRAME) { GstVdpBFrame *b_frame; + if (mpeg_dec->broken_gop) { + gst_buffer_unref (buffer); + mpeg_dec->broken_gop = FALSE; + return GST_FLOW_OK; + } + b_frame = g_slice_new (GstVdpBFrame); b_frame->buffer = buffer; @@ -336,6 +342,8 @@ gst_vdp_mpeg_decoder_parse_gop (GstVdpMpegDecoder * mpeg_dec, guint8 * data, if (!mpeg_util_parse_picture_gop (&gop, data, end)) return FALSE; + mpeg_dec->broken_gop = gop.broken_gop; + return TRUE; } @@ -497,6 +505,8 @@ gst_vdp_mpeg_decoder_init (GstVdpMpegDecoder * mpeg_dec, mpeg_dec->b_frames = NULL; + mpeg_dec->broken_gop = FALSE; + mpeg_dec->adapter = gst_adapter_new (); gst_pad_set_chain_function (dec->sink, gst_vdp_mpeg_decoder_chain); diff --git a/sys/vdpau/gstvdpmpegdecoder.h b/sys/vdpau/gstvdpmpegdecoder.h index a03c17c2..aac79f31 100644 --- a/sys/vdpau/gstvdpmpegdecoder.h +++ b/sys/vdpau/gstvdpmpegdecoder.h @@ -49,6 +49,8 @@ struct _GstVdpMpegDecoder /* holds B_FRAMES */ GSList *b_frames; + + gboolean broken_gop; GstAdapter *adapter; }; diff --git a/sys/vdpau/mpegutil.c b/sys/vdpau/mpegutil.c index a1323f68..6f59b841 100644 --- a/sys/vdpau/mpegutil.c +++ b/sys/vdpau/mpegutil.c @@ -348,7 +348,6 @@ gboolean mpeg_util_parse_picture_gop (MPEGPictureGOP * gop, guint8 * data, guint8 * end) { guint32 code; - gint hour, minute, second; if (G_UNLIKELY ((end - data) < 8)) return FALSE; /* Packet too small */ @@ -363,16 +362,14 @@ mpeg_util_parse_picture_gop (MPEGPictureGOP * gop, guint8 * data, guint8 * end) gop->drop_frame_flag = read_bits (data, 0, 1); - hour = read_bits (data, 1, 5); - minute = read_bits (data, 6, 6); - second = read_bits (data + 1, 4, 6); - - gop->timestamp = hour * 3600 * GST_SECOND; - gop->timestamp += minute * 60 * GST_SECOND; - gop->timestamp += second * GST_SECOND; - + gop->hour = read_bits (data, 1, 5); + gop->minute = read_bits (data, 6, 6); + gop->second = read_bits (data + 1, 4, 6); gop->frame = read_bits (data + 2, 3, 6); + gop->closed_gop = read_bits (data + 3, 1, 1); + gop->broken_gop = read_bits (data + 3, 2, 1); + return TRUE; } diff --git a/sys/vdpau/mpegutil.h b/sys/vdpau/mpegutil.h index 24a29a35..43f34a59 100644 --- a/sys/vdpau/mpegutil.h +++ b/sys/vdpau/mpegutil.h @@ -96,9 +96,11 @@ struct MPEGPictureExt struct MPEGPictureGOP { guint8 drop_frame_flag; - guint8 frame; - GstClockTime timestamp; + guint8 hour, minute, second, frame; + + guint8 closed_gop; + guint8 broken_gop; }; struct MPEGQuantMatrix -- cgit v1.2.1 From 8b3261f91ac49530495cb7527eab923fcb59ab91 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Sun, 26 Apr 2009 20:40:45 +0200 Subject: vdpaumpegdec: add "MPEG_PACKET_EXT_PICTURE_CODING" debug statement --- sys/vdpau/gstvdpmpegdecoder.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sys') diff --git a/sys/vdpau/gstvdpmpegdecoder.c b/sys/vdpau/gstvdpmpegdecoder.c index d9b74706..863e3bb3 100644 --- a/sys/vdpau/gstvdpmpegdecoder.c +++ b/sys/vdpau/gstvdpmpegdecoder.c @@ -415,6 +415,7 @@ gst_vdp_mpeg_decoder_chain (GstPad * pad, GstBuffer * buffer) GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_EXTENSION"); switch (read_bits (data + 1, 0, 4)) { case MPEG_PACKET_EXT_PICTURE_CODING: + GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_EXT_PICTURE_CODING"); gst_vdp_mpeg_decoder_parse_picture_coding (mpeg_dec, packet_start, packet_end); break; -- cgit v1.2.1 From 4d69d761d24e5b8320efa680402055ec785417bf Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Sun, 26 Apr 2009 22:05:11 +0200 Subject: vdpaumpegdec: reset decoder when we get a discont buffer --- sys/vdpau/gstvdpmpegdecoder.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'sys') diff --git a/sys/vdpau/gstvdpmpegdecoder.c b/sys/vdpau/gstvdpmpegdecoder.c index 863e3bb3..86f65fee 100644 --- a/sys/vdpau/gstvdpmpegdecoder.c +++ b/sys/vdpau/gstvdpmpegdecoder.c @@ -73,6 +73,7 @@ GST_DEBUG_CATEGORY_INIT (gst_vdp_mpeg_decoder_debug, "vdpaumpegdec", 0, "VDPAU p GST_BOILERPLATE_FULL (GstVdpMpegDecoder, gst_vdp_mpeg_decoder, GstVdpDecoder, GST_TYPE_VDPAU_DECODER, DEBUG_INIT); +static void gst_vdp_mpeg_decoder_init_info (VdpPictureInfoMPEG1Or2 * vdp_info); static void gst_vdp_mpeg_decoder_finalize (GObject * object); static void gst_vdp_mpeg_decoder_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec); @@ -363,6 +364,26 @@ gst_vdp_mpeg_decoder_parse_quant_matrix (GstVdpMpegDecoder * mpeg_dec, return TRUE; } +static void +gst_vdp_mpeg_decoder_reset (GstVdpMpegDecoder * mpeg_dec) +{ + GSList *iter; + + for (iter = mpeg_dec->b_frames; iter; iter = iter->next) { + GstVdpBFrame *b_frame = (GstVdpBFrame *) iter->data; + + gst_buffer_unref (b_frame->buffer); + g_slice_free (GstVdpBFrame, b_frame); + } + g_slist_free (mpeg_dec->b_frames); + mpeg_dec->b_frames = NULL; + + if (mpeg_dec->vdp_info.forward_reference != VDP_INVALID_HANDLE) + gst_buffer_unref (mpeg_dec->f_buffer); + + gst_vdp_mpeg_decoder_init_info (&mpeg_dec->vdp_info); +} + static GstFlowReturn gst_vdp_mpeg_decoder_chain (GstPad * pad, GstBuffer * buffer) { @@ -373,6 +394,12 @@ gst_vdp_mpeg_decoder_chain (GstPad * pad, GstBuffer * buffer) mpeg_dec = GST_VDPAU_MPEG_DECODER (GST_OBJECT_PARENT (pad)); + if (G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT))) { + GST_DEBUG_OBJECT (mpeg_dec, "Received discont buffer"); + gst_vdp_mpeg_decoder_reset (mpeg_dec); + return GST_FLOW_OK; + } + data = GST_BUFFER_DATA (buffer); end = GST_BUFFER_DATA (buffer) + GST_BUFFER_SIZE (buffer); -- cgit v1.2.1 From 8bbd79496187baabe6ad754e493cb167bbc3a8dc Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Sun, 26 Apr 2009 23:20:30 +0200 Subject: vdpaumpegdec: reset decoder on GST_EVENT_FLUSH_STOP --- sys/vdpau/gstvdpmpegdecoder.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'sys') diff --git a/sys/vdpau/gstvdpmpegdecoder.c b/sys/vdpau/gstvdpmpegdecoder.c index 86f65fee..42c89a32 100644 --- a/sys/vdpau/gstvdpmpegdecoder.c +++ b/sys/vdpau/gstvdpmpegdecoder.c @@ -467,6 +467,33 @@ gst_vdp_mpeg_decoder_chain (GstPad * pad, GstBuffer * buffer) return ret; } +static gboolean +gst_vdp_mpeg_decoder_sink_event (GstPad * pad, GstEvent * event) +{ + GstVdpMpegDecoder *mpeg_dec; + GstVdpDecoder *dec; + gboolean res; + + mpeg_dec = GST_VDPAU_MPEG_DECODER (GST_OBJECT_PARENT (pad)); + dec = GST_VDPAU_DECODER (mpeg_dec); + + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_FLUSH_STOP: + { + GST_DEBUG_OBJECT (mpeg_dec, "flush stop"); + + gst_vdp_mpeg_decoder_reset (mpeg_dec); + res = gst_pad_push_event (dec->src, event); + + break; + } + default: + res = gst_pad_event_default (pad, event); + } + + return res; +} + /* GObject vmethod implementations */ static void @@ -538,6 +565,7 @@ gst_vdp_mpeg_decoder_init (GstVdpMpegDecoder * mpeg_dec, mpeg_dec->adapter = gst_adapter_new (); gst_pad_set_chain_function (dec->sink, gst_vdp_mpeg_decoder_chain); + gst_pad_set_event_function (dec->sink, gst_vdp_mpeg_decoder_sink_event); } static void -- cgit v1.2.1 From 8c78a4850fa5bc1323fee6d47e6a9bd31d024f0e Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Sun, 26 Apr 2009 23:25:33 +0200 Subject: vdpau: fixup renaming the rename work done in commit 24cf84d06b2f4b2edec3383b198441a07829618b didn't include typecasts. This commit fixes this. --- sys/vdpau/gstvdpdecoder.c | 10 +++++----- sys/vdpau/gstvdpdecoder.h | 12 ++++++------ sys/vdpau/gstvdpdevice.h | 12 ++++++------ sys/vdpau/gstvdpmpegdecoder.c | 24 +++++++++++------------- sys/vdpau/gstvdpmpegdecoder.h | 10 +++++----- sys/vdpau/gstvdpvideobuffer.h | 8 ++++---- sys/vdpau/gstvdpvideoyuv.c | 12 ++++++------ sys/vdpau/gstvdpvideoyuv.h | 12 ++++++------ sys/vdpau/gstvdpyuvvideo.c | 16 ++++++++-------- sys/vdpau/gstvdpyuvvideo.h | 12 ++++++------ 10 files changed, 63 insertions(+), 65 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpdecoder.c b/sys/vdpau/gstvdpdecoder.c index dafcec98..3f71ab40 100644 --- a/sys/vdpau/gstvdpdecoder.c +++ b/sys/vdpau/gstvdpdecoder.c @@ -83,7 +83,7 @@ gst_vdp_decoder_change_state (GstElement * element, GstStateChange transition) { GstVdpDecoder *dec; - dec = GST_VDPAU_DECODER (element); + dec = GST_VDP_DECODER (element); switch (transition) { case GST_STATE_CHANGE_NULL_TO_READY: @@ -103,8 +103,8 @@ gst_vdp_decoder_change_state (GstElement * element, GstStateChange transition) static gboolean gst_vdp_decoder_sink_set_caps (GstPad * pad, GstCaps * caps) { - GstVdpDecoder *dec = GST_VDPAU_DECODER (GST_OBJECT_PARENT (pad)); - GstVdpDecoderClass *dec_class = GST_VDPAU_DECODER_GET_CLASS (dec); + GstVdpDecoder *dec = GST_VDP_DECODER (GST_OBJECT_PARENT (pad)); + GstVdpDecoderClass *dec_class = GST_VDP_DECODER_GET_CLASS (dec); GstCaps *src_caps, *new_caps; GstStructure *structure; @@ -227,7 +227,7 @@ static void gst_vdp_decoder_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { - GstVdpDecoder *dec = GST_VDPAU_DECODER (object); + GstVdpDecoder *dec = GST_VDP_DECODER (object); switch (prop_id) { case PROP_DISPLAY: @@ -244,7 +244,7 @@ static void gst_vdp_decoder_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { - GstVdpDecoder *dec = GST_VDPAU_DECODER (object); + GstVdpDecoder *dec = GST_VDP_DECODER (object); switch (prop_id) { case PROP_DISPLAY: diff --git a/sys/vdpau/gstvdpdecoder.h b/sys/vdpau/gstvdpdecoder.h index 8dc4ad66..dfc63fd9 100644 --- a/sys/vdpau/gstvdpdecoder.h +++ b/sys/vdpau/gstvdpdecoder.h @@ -18,8 +18,8 @@ * Boston, MA 02111-1307, USA. */ -#ifndef __GST_VDPAU_DECODER_H__ -#define __GST_VDPAU_DECODER_H__ +#ifndef __GST_VDP_DECODER_H__ +#define __GST_VDP_DECODER_H__ #include @@ -29,9 +29,9 @@ G_BEGIN_DECLS #define GST_TYPE_VDPAU_DECODER (gst_vdp_decoder_get_type()) -#define GST_VDPAU_DECODER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VDPAU_DECODER,GstVdpDecoder)) -#define GST_VDPAU_DECODER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VDPAU_DECODER,GstVdpDecoderClass)) -#define GST_VDPAU_DECODER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VDPAU_DECODER, GstVdpDecoderClass)) +#define GST_VDP_DECODER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VDPAU_DECODER,GstVdpDecoder)) +#define GST_VDP_DECODER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VDPAU_DECODER,GstVdpDecoderClass)) +#define GST_VDP_DECODER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VDPAU_DECODER, GstVdpDecoderClass)) #define GST_IS_VDPAU_DECODER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VDPAU_DECODER)) #define GST_IS_VDPAU_DECODER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VDPAU_DECODER)) @@ -69,4 +69,4 @@ VdpVideoSurface gst_vdp_decoder_create_video_surface (GstVdpDecoder *dec); G_END_DECLS -#endif /* __GST_VDPAU_DECODER_H__ */ +#endif /* __GST_VDP_DECODER_H__ */ diff --git a/sys/vdpau/gstvdpdevice.h b/sys/vdpau/gstvdpdevice.h index 8b2f596c..26e7fa72 100644 --- a/sys/vdpau/gstvdpdevice.h +++ b/sys/vdpau/gstvdpdevice.h @@ -18,8 +18,8 @@ * Boston, MA 02111-1307, USA. */ -#ifndef _GST_VDPAU_DEVICE_H_ -#define _GST_VDPAU_DEVICE_H_ +#ifndef _GST_VDP_DEVICE_H_ +#define _GST_VDP_DEVICE_H_ #include #include @@ -29,11 +29,11 @@ G_BEGIN_DECLS #define GST_TYPE_VDPAU_DEVICE (gst_vdp_device_get_type ()) -#define GST_VDPAU_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VDPAU_DEVICE, GstVdpDevice)) -#define GST_VDPAU_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_VDPAU_DEVICE, GstVdpDeviceClass)) +#define GST_VDP_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VDPAU_DEVICE, GstVdpDevice)) +#define GST_VDP_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_VDPAU_DEVICE, GstVdpDeviceClass)) #define GST_IS_VDPAU_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VDPAU_DEVICE)) #define GST_IS_VDPAU_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_VDPAU_DEVICE)) -#define GST_VDPAU_DEVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VDPAU_DEVICE, GstVdpDeviceClass)) +#define GST_VDP_DEVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VDPAU_DEVICE, GstVdpDeviceClass)) typedef struct _GstVdpDeviceClass GstVdpDeviceClass; typedef struct _GstVdpDevice GstVdpDevice; @@ -129,4 +129,4 @@ GstVdpDevice *gst_vdp_get_device (const gchar *display_name); G_END_DECLS -#endif /* _GST_VDPAU_DEVICE_H_ */ +#endif /* _GST_VDP_DEVICE_H_ */ diff --git a/sys/vdpau/gstvdpmpegdecoder.c b/sys/vdpau/gstvdpmpegdecoder.c index 42c89a32..f13db895 100644 --- a/sys/vdpau/gstvdpmpegdecoder.c +++ b/sys/vdpau/gstvdpmpegdecoder.c @@ -92,7 +92,7 @@ gst_vdp_mpeg_decoder_set_caps (GstVdpDecoder * dec, GstCaps * caps) GstVdpDevice *device; VdpStatus status; - mpeg_dec = GST_VDPAU_MPEG_DECODER (dec); + mpeg_dec = GST_VDP_MPEG_DECODER (dec); structure = gst_caps_get_structure (caps, 0); gst_structure_get_int (structure, "mpegversion", &mpeg_dec->version); @@ -150,7 +150,7 @@ gst_vdp_mpeg_decoder_decode (GstVdpMpegDecoder * mpeg_dec) VdpStatus status; GstFlowReturn ret; - dec = GST_VDPAU_DECODER (mpeg_dec); + dec = GST_VDP_DECODER (mpeg_dec); buffer = gst_adapter_take_buffer (mpeg_dec->adapter, gst_adapter_available (mpeg_dec->adapter)); @@ -234,8 +234,7 @@ gst_vdp_mpeg_decoder_decode (GstVdpMpegDecoder * mpeg_dec) device->vdp_get_error_string (status))); } - gst_vdp_decoder_push_video_buffer (GST_VDPAU_DECODER (mpeg_dec), - b_outbuf); + gst_vdp_decoder_push_video_buffer (GST_VDP_DECODER (mpeg_dec), b_outbuf); } g_slist_free (mpeg_dec->b_frames); mpeg_dec->b_frames = NULL; @@ -243,8 +242,7 @@ gst_vdp_mpeg_decoder_decode (GstVdpMpegDecoder * mpeg_dec) gst_buffer_ref (GST_BUFFER (outbuf)); - ret = gst_vdp_decoder_push_video_buffer (GST_VDPAU_DECODER (mpeg_dec), - outbuf); + ret = gst_vdp_decoder_push_video_buffer (GST_VDP_DECODER (mpeg_dec), outbuf); if (mpeg_dec->vdp_info.forward_reference != VDP_INVALID_HANDLE) gst_buffer_unref (mpeg_dec->f_buffer); @@ -263,7 +261,7 @@ gst_vdp_mpeg_decoder_parse_picture_coding (GstVdpMpegDecoder * mpeg_dec, MPEGPictureExt pic_ext; VdpPictureInfoMPEG1Or2 *info; - dec = GST_VDPAU_DECODER (mpeg_dec); + dec = GST_VDP_DECODER (mpeg_dec); info = &mpeg_dec->vdp_info; if (!mpeg_util_parse_picture_coding_extension (&pic_ext, data, end)) @@ -290,7 +288,7 @@ gst_vdp_mpeg_decoder_parse_sequence (GstVdpMpegDecoder * mpeg_dec, GstVdpDecoder *dec; MPEGSeqHdr hdr; - dec = GST_VDPAU_DECODER (mpeg_dec); + dec = GST_VDP_DECODER (mpeg_dec); if (!mpeg_util_parse_sequence_hdr (&hdr, data, end)) return FALSE; @@ -310,7 +308,7 @@ gst_vdp_mpeg_decoder_parse_picture (GstVdpMpegDecoder * mpeg_dec, GstVdpDecoder *dec; MPEGPictureHdr pic_hdr; - dec = GST_VDPAU_DECODER (mpeg_dec); + dec = GST_VDP_DECODER (mpeg_dec); if (!mpeg_util_parse_picture_hdr (&pic_hdr, data, end)) return FALSE; @@ -392,7 +390,7 @@ gst_vdp_mpeg_decoder_chain (GstPad * pad, GstBuffer * buffer) guint32 sync_word = 0xffffffff; GstFlowReturn ret = GST_FLOW_OK; - mpeg_dec = GST_VDPAU_MPEG_DECODER (GST_OBJECT_PARENT (pad)); + mpeg_dec = GST_VDP_MPEG_DECODER (GST_OBJECT_PARENT (pad)); if (G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT))) { GST_DEBUG_OBJECT (mpeg_dec, "Received discont buffer"); @@ -474,8 +472,8 @@ gst_vdp_mpeg_decoder_sink_event (GstPad * pad, GstEvent * event) GstVdpDecoder *dec; gboolean res; - mpeg_dec = GST_VDPAU_MPEG_DECODER (GST_OBJECT_PARENT (pad)); - dec = GST_VDPAU_DECODER (mpeg_dec); + mpeg_dec = GST_VDP_MPEG_DECODER (GST_OBJECT_PARENT (pad)); + dec = GST_VDP_DECODER (mpeg_dec); switch (GST_EVENT_TYPE (event)) { case GST_EVENT_FLUSH_STOP: @@ -553,7 +551,7 @@ gst_vdp_mpeg_decoder_init (GstVdpMpegDecoder * mpeg_dec, { GstVdpDecoder *dec; - dec = GST_VDPAU_DECODER (mpeg_dec); + dec = GST_VDP_DECODER (mpeg_dec); mpeg_dec->decoder = VDP_INVALID_HANDLE; gst_vdp_mpeg_decoder_init_info (&mpeg_dec->vdp_info); diff --git a/sys/vdpau/gstvdpmpegdecoder.h b/sys/vdpau/gstvdpmpegdecoder.h index aac79f31..ee7086c5 100644 --- a/sys/vdpau/gstvdpmpegdecoder.h +++ b/sys/vdpau/gstvdpmpegdecoder.h @@ -18,8 +18,8 @@ * Boston, MA 02111-1307, USA. */ -#ifndef __GST_VDPAU_MPEG_DECODER_H__ -#define __GST_VDPAU_MPEG_DECODER_H__ +#ifndef __GST_VDP_MPEG_DECODER_H__ +#define __GST_VDP_MPEG_DECODER_H__ #include #include @@ -29,8 +29,8 @@ G_BEGIN_DECLS #define GST_TYPE_VDPAU_MPEG_DECODER (gst_vdp_mpeg_decoder_get_type()) -#define GST_VDPAU_MPEG_DECODER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VDPAU_MPEG_DECODER,GstVdpMpegDecoder)) -#define GST_VDPAU_MPEG_DECODER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VDPAU_MPEG_DECODER,GstVdpMpegDecoderClass)) +#define GST_VDP_MPEG_DECODER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VDPAU_MPEG_DECODER,GstVdpMpegDecoder)) +#define GST_VDP_MPEG_DECODER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VDPAU_MPEG_DECODER,GstVdpMpegDecoderClass)) #define GST_IS_VDPAU_MPEG_DECODER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VDPAU_MPEG_DECODER)) #define GST_IS_VDPAU_MPEG_DECODER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VDPAU_MPEG_DECODER)) @@ -64,4 +64,4 @@ GType gst_vdp_mpeg_decoder_get_type (void); G_END_DECLS -#endif /* __GST_VDPAU_MPEG_DECODER_H__ */ +#endif /* __GST_VDP_MPEG_DECODER_H__ */ diff --git a/sys/vdpau/gstvdpvideobuffer.h b/sys/vdpau/gstvdpvideobuffer.h index bbfc7af0..92a077f8 100644 --- a/sys/vdpau/gstvdpvideobuffer.h +++ b/sys/vdpau/gstvdpvideobuffer.h @@ -18,8 +18,8 @@ * Boston, MA 02111-1307, USA. */ -#ifndef _GST_VDPAU_VIDEO_BUFFER_H_ -#define _GST_VDPAU_VIDEO_BUFFER_H_ +#ifndef _GST_VDP_VIDEO_BUFFER_H_ +#define _GST_VDP_VIDEO_BUFFER_H_ #include #include @@ -33,7 +33,7 @@ typedef struct _GstVdpVideoBuffer GstVdpVideoBuffer; #define GST_TYPE_VDPAU_VIDEO_BUFFER (gst_vdp_video_buffer_get_type()) #define GST_IS_VDPAU_VIDEO_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VDPAU_VIDEO_BUFFER)) -#define GST_VDPAU_VIDEO_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VDPAU_VIDEO_BUFFER, GstVdpVideoBuffer)) +#define GST_VDP_VIDEO_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VDPAU_VIDEO_BUFFER, GstVdpVideoBuffer)) struct _GstVdpVideoBuffer { GstBuffer buffer; @@ -46,7 +46,7 @@ GType gst_vdp_video_buffer_get_type (void); GstVdpVideoBuffer* gst_vdp_video_buffer_new (GstVdpDevice * device, VdpChromaType chroma_type, gint width, gint height); -#define GST_VDPAU_VIDEO_CAPS \ +#define GST_VDP_VIDEO_CAPS \ "video/x-vdpau-video, " \ "chroma-type = (int)[0,2], " \ "width = (int)[1,4096], " \ diff --git a/sys/vdpau/gstvdpvideoyuv.c b/sys/vdpau/gstvdpvideoyuv.c index 917a4edc..a1f5b6ed 100644 --- a/sys/vdpau/gstvdpvideoyuv.c +++ b/sys/vdpau/gstvdpvideoyuv.c @@ -46,7 +46,7 @@ enum static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, - GST_STATIC_CAPS (GST_VDPAU_VIDEO_CAPS)); + GST_STATIC_CAPS (GST_VDP_VIDEO_CAPS)); static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, @@ -75,9 +75,9 @@ gst_vdp_video_yuv_chain (GstPad * pad, GstBuffer * buffer) VdpVideoSurface surface; GstBuffer *outbuf = NULL; - video_yuv = GST_VDPAU_VIDEO_YUV (GST_OBJECT_PARENT (pad)); - device = GST_VDPAU_VIDEO_BUFFER (buffer)->device; - surface = GST_VDPAU_VIDEO_BUFFER (buffer)->surface; + video_yuv = GST_VDP_VIDEO_YUV (GST_OBJECT_PARENT (pad)); + device = GST_VDP_VIDEO_BUFFER (buffer)->device; + surface = GST_VDP_VIDEO_BUFFER (buffer)->surface; switch (video_yuv->format) { case GST_MAKE_FOURCC ('Y', 'V', '1', '2'): @@ -276,7 +276,7 @@ gst_vdp_video_yuv_get_caps (GstVdpVideoYUV * video_yuv, static gboolean gst_vdp_video_yuv_sink_set_caps (GstPad * pad, GstCaps * caps) { - GstVdpVideoYUV *video_yuv = GST_VDPAU_VIDEO_YUV (GST_OBJECT_PARENT (pad)); + GstVdpVideoYUV *video_yuv = GST_VDP_VIDEO_YUV (GST_OBJECT_PARENT (pad)); GstCaps *src_caps, *new_caps; GstStructure *structure; @@ -344,7 +344,7 @@ gst_vdp_video_yuv_src_getcaps (GstPad * pad) { GstVdpVideoYUV *video_yuv; - video_yuv = GST_VDPAU_VIDEO_YUV (GST_OBJECT_PARENT (pad)); + video_yuv = GST_VDP_VIDEO_YUV (GST_OBJECT_PARENT (pad)); if (video_yuv->src_caps) return gst_caps_copy (video_yuv->src_caps); diff --git a/sys/vdpau/gstvdpvideoyuv.h b/sys/vdpau/gstvdpvideoyuv.h index f2aa4c82..eb628352 100644 --- a/sys/vdpau/gstvdpvideoyuv.h +++ b/sys/vdpau/gstvdpvideoyuv.h @@ -18,8 +18,8 @@ * Boston, MA 02111-1307, USA. */ -#ifndef __GST_VDPAU_VIDEO_YUV_H__ -#define __GST_VDPAU_VIDEO_YUV_H__ +#ifndef __GST_VDP_VIDEO_YUV_H__ +#define __GST_VDP_VIDEO_YUV_H__ #include @@ -28,9 +28,9 @@ G_BEGIN_DECLS #define GST_TYPE_VDPAU_VIDEO_YUV (gst_vdp_video_yuv_get_type()) -#define GST_VDPAU_VIDEO_YUV(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VDPAU_VIDEO_YUV,GstVdpVideoYUV)) -#define GST_VDPAU_VIDEO_YUV_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VDPAU_VIDEO_YUV,GstVdpVideoYUVClass)) -#define GST_VDPAU_VIDEO_YUV_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VDPAU_VIDEO_YUV, GstVdpVideoYUVClass)) +#define GST_VDP_VIDEO_YUV(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VDPAU_VIDEO_YUV,GstVdpVideoYUV)) +#define GST_VDP_VIDEO_YUV_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VDPAU_VIDEO_YUV,GstVdpVideoYUVClass)) +#define GST_VDP_VIDEO_YUV_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VDPAU_VIDEO_YUV, GstVdpVideoYUVClass)) #define GST_IS_VDPAU_VIDEO_YUV(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VDPAU_VIDEO_YUV)) #define GST_IS_VDPAU_VIDEO_YUV_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VDPAU_VIDEO_YUV)) @@ -57,4 +57,4 @@ GType gst_vdp_video_yuv_get_type (void); G_END_DECLS -#endif /* __GST_VDPAU_VIDEO_YUV_H__ */ +#endif /* __GST_VDP_VIDEO_YUV_H__ */ diff --git a/sys/vdpau/gstvdpyuvvideo.c b/sys/vdpau/gstvdpyuvvideo.c index d5ed01cb..72c053e6 100644 --- a/sys/vdpau/gstvdpyuvvideo.c +++ b/sys/vdpau/gstvdpyuvvideo.c @@ -54,7 +54,7 @@ static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink", static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS, - GST_STATIC_CAPS (GST_VDPAU_VIDEO_CAPS)); + GST_STATIC_CAPS (GST_VDP_VIDEO_CAPS)); #define DEBUG_INIT(bla) \ GST_DEBUG_CATEGORY_INIT (gst_vdp_yuv_video_debug, "vdpauvideoyuv", 0, "YUV to VDPAU video surface"); @@ -76,13 +76,13 @@ gst_vdp_yuv_video_chain (GstPad * pad, GstBuffer * buffer) VdpVideoSurface surface; GstBuffer *outbuf = NULL; - yuv_video = GST_VDPAU_YUV_VIDEO (GST_OBJECT_PARENT (pad)); + yuv_video = GST_VDP_YUV_VIDEO (GST_OBJECT_PARENT (pad)); device = yuv_video->device; outbuf = GST_BUFFER (gst_vdp_video_buffer_new (device, yuv_video->chroma_type, yuv_video->width, yuv_video->height)); - surface = GST_VDPAU_VIDEO_BUFFER (outbuf)->surface; + surface = GST_VDP_VIDEO_BUFFER (outbuf)->surface; switch (yuv_video->format) { case GST_MAKE_FOURCC ('Y', 'V', '1', '2'): @@ -267,7 +267,7 @@ error: static gboolean gst_vdp_yuv_video_sink_setcaps (GstPad * pad, GstCaps * caps) { - GstVdpYUVVideo *yuv_video = GST_VDPAU_YUV_VIDEO (GST_OBJECT_PARENT (pad)); + GstVdpYUVVideo *yuv_video = GST_VDP_YUV_VIDEO (GST_OBJECT_PARENT (pad)); GstStructure *structure; guint32 fourcc; @@ -337,7 +337,7 @@ gst_vdp_yuv_video_sink_getcaps (GstPad * pad) { GstVdpYUVVideo *yuv_video; - yuv_video = GST_VDPAU_YUV_VIDEO (GST_OBJECT_PARENT (pad)); + yuv_video = GST_VDP_YUV_VIDEO (GST_OBJECT_PARENT (pad)); if (yuv_video->sink_caps) return gst_caps_copy (yuv_video->sink_caps); @@ -350,7 +350,7 @@ gst_vdp_yuv_video_change_state (GstElement * element, GstStateChange transition) { GstVdpYUVVideo *yuv_video; - yuv_video = GST_VDPAU_YUV_VIDEO (element); + yuv_video = GST_VDP_YUV_VIDEO (element); switch (transition) { case GST_STATE_CHANGE_NULL_TO_READY: @@ -446,7 +446,7 @@ static void gst_vdp_yuv_video_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { - GstVdpYUVVideo *yuv_video = GST_VDPAU_YUV_VIDEO (object); + GstVdpYUVVideo *yuv_video = GST_VDP_YUV_VIDEO (object); switch (prop_id) { case PROP_DISPLAY: @@ -463,7 +463,7 @@ static void gst_vdp_yuv_video_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { - GstVdpYUVVideo *yuv_video = GST_VDPAU_YUV_VIDEO (object); + GstVdpYUVVideo *yuv_video = GST_VDP_YUV_VIDEO (object); switch (prop_id) { case PROP_DISPLAY: diff --git a/sys/vdpau/gstvdpyuvvideo.h b/sys/vdpau/gstvdpyuvvideo.h index fbb7d96d..0c063929 100644 --- a/sys/vdpau/gstvdpyuvvideo.h +++ b/sys/vdpau/gstvdpyuvvideo.h @@ -18,8 +18,8 @@ * Boston, MA 02111-1307, USA. */ -#ifndef __GST_VDPAU_YUV_VIDEO_H__ -#define __GST_VDPAU_YUV_VIDEO_H__ +#ifndef __GST_VDP_YUV_VIDEO_H__ +#define __GST_VDP_YUV_VIDEO_H__ #include @@ -28,9 +28,9 @@ G_BEGIN_DECLS #define GST_TYPE_VDPAU_YUV_VIDEO (gst_vdp_yuv_video_get_type()) -#define GST_VDPAU_YUV_VIDEO(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VDPAU_YUV_VIDEO,GstVdpYUVVideo)) -#define GST_VDPAU_YUV_VIDEO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VDPAU_YUV_VIDEO,GstVdpYUVVideoClass)) -#define GST_VDPAU_YUV_VIDEO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VDPAU_YUV_VIDEO, GstVdpYUVVideoClass)) +#define GST_VDP_YUV_VIDEO(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VDPAU_YUV_VIDEO,GstVdpYUVVideo)) +#define GST_VDP_YUV_VIDEO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VDPAU_YUV_VIDEO,GstVdpYUVVideoClass)) +#define GST_VDP_YUV_VIDEO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VDPAU_YUV_VIDEO, GstVdpYUVVideoClass)) #define GST_IS_VDPAU_YUV_VIDEO(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VDPAU_YUV_VIDEO)) #define GST_IS_VDPAU_YUV_VIDEO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VDPAU_YUV_VIDEO)) @@ -59,4 +59,4 @@ GType gst_vdp_yuv_video_get_type (void); G_END_DECLS -#endif /* __GST_VDPAU_YUV_VIDEO_H__ */ +#endif /* __GST_VDP_YUV_VIDEO_H__ */ -- cgit v1.2.1 From 2d996a3ff49757e299ec6218604f19e499ac0782 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Mon, 27 Apr 2009 15:12:26 +0200 Subject: vdpaumpegdec: clear the adapter when we reset the decoder --- sys/vdpau/gstvdpmpegdecoder.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'sys') diff --git a/sys/vdpau/gstvdpmpegdecoder.c b/sys/vdpau/gstvdpmpegdecoder.c index f13db895..5cc913b0 100644 --- a/sys/vdpau/gstvdpmpegdecoder.c +++ b/sys/vdpau/gstvdpmpegdecoder.c @@ -380,6 +380,8 @@ gst_vdp_mpeg_decoder_reset (GstVdpMpegDecoder * mpeg_dec) gst_buffer_unref (mpeg_dec->f_buffer); gst_vdp_mpeg_decoder_init_info (&mpeg_dec->vdp_info); + + gst_adapter_clear (mpeg_dec->adapter); } static GstFlowReturn -- cgit v1.2.1 From 2eb479f825c3d1f02f9b91cc3f1964945be5d647 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Mon, 27 Apr 2009 18:34:53 +0200 Subject: vdpaumpegdec: if available use incoming buffer timestamp as output timestamp --- sys/vdpau/gstvdpdecoder.c | 14 +++++--------- sys/vdpau/gstvdpmpegdecoder.c | 11 ++++++++--- 2 files changed, 13 insertions(+), 12 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpdecoder.c b/sys/vdpau/gstvdpdecoder.c index 3f71ab40..b3faf837 100644 --- a/sys/vdpau/gstvdpdecoder.c +++ b/sys/vdpau/gstvdpdecoder.c @@ -64,15 +64,11 @@ GstFlowReturn gst_vdp_decoder_push_video_buffer (GstVdpDecoder * dec, GstVdpVideoBuffer * buffer) { - GST_BUFFER_TIMESTAMP (buffer) = - gst_util_uint64_scale_int (GST_SECOND * dec->frame_nr, - dec->framerate_denominator, dec->framerate_numerator); - GST_BUFFER_DURATION (buffer) = - gst_util_uint64_scale_int (GST_SECOND, dec->framerate_denominator, - dec->framerate_numerator); - GST_BUFFER_OFFSET (buffer) = dec->frame_nr; - dec->frame_nr++; - GST_BUFFER_OFFSET_END (buffer) = dec->frame_nr; + if (GST_BUFFER_TIMESTAMP (buffer) == GST_CLOCK_TIME_NONE) { + GST_BUFFER_TIMESTAMP (buffer) = + gst_util_uint64_scale_int (GST_SECOND * dec->frame_nr, + dec->framerate_denominator, dec->framerate_numerator); + } gst_buffer_set_caps (GST_BUFFER (buffer), GST_PAD_CAPS (dec->src)); return gst_pad_push (dec->src, GST_BUFFER (buffer)); diff --git a/sys/vdpau/gstvdpmpegdecoder.c b/sys/vdpau/gstvdpmpegdecoder.c index 5cc913b0..5b461268 100644 --- a/sys/vdpau/gstvdpmpegdecoder.c +++ b/sys/vdpau/gstvdpmpegdecoder.c @@ -139,7 +139,8 @@ typedef struct } GstVdpBFrame; static GstFlowReturn -gst_vdp_mpeg_decoder_decode (GstVdpMpegDecoder * mpeg_dec) +gst_vdp_mpeg_decoder_decode (GstVdpMpegDecoder * mpeg_dec, + GstClockTime timestamp) { GstVdpDecoder *dec; GstBuffer *buffer; @@ -167,6 +168,7 @@ gst_vdp_mpeg_decoder_decode (GstVdpMpegDecoder * mpeg_dec) b_frame = g_slice_new (GstVdpBFrame); + GST_BUFFER_TIMESTAMP (buffer) = timestamp; b_frame->buffer = buffer; memcpy (&b_frame->vdp_info, &mpeg_dec->vdp_info, sizeof (VdpPictureInfoMPEG1Or2)); @@ -180,6 +182,7 @@ gst_vdp_mpeg_decoder_decode (GstVdpMpegDecoder * mpeg_dec) outbuf = gst_vdp_video_buffer_new (dec->device, VDP_CHROMA_TYPE_420, dec->width, dec->height); + GST_BUFFER_TIMESTAMP (outbuf) = timestamp; surface = outbuf->surface; device = dec->device; @@ -216,6 +219,7 @@ gst_vdp_mpeg_decoder_decode (GstVdpMpegDecoder * mpeg_dec) b_outbuf = gst_vdp_video_buffer_new (dec->device, VDP_CHROMA_TYPE_420, dec->width, dec->height); + GST_BUFFER_TIMESTAMP (b_outbuf) = GST_BUFFER_TIMESTAMP (b_frame->buffer); b_frame->vdp_info.backward_reference = surface; vbit[0].struct_version = VDP_BITSTREAM_BUFFER_VERSION; @@ -428,8 +432,6 @@ gst_vdp_mpeg_decoder_chain (GstPad * pad, GstBuffer * buffer) switch (data[0]) { case MPEG_PACKET_PICTURE: GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_PICTURE"); - if (mpeg_dec->vdp_info.slice_count > 0) - ret = gst_vdp_mpeg_decoder_decode (mpeg_dec); gst_vdp_mpeg_decoder_parse_picture (mpeg_dec, packet_start, packet_end); break; @@ -464,6 +466,9 @@ gst_vdp_mpeg_decoder_chain (GstPad * pad, GstBuffer * buffer) } } + if (mpeg_dec->vdp_info.slice_count > 0) + ret = gst_vdp_mpeg_decoder_decode (mpeg_dec, GST_BUFFER_TIMESTAMP (buffer)); + return ret; } -- cgit v1.2.1 From a94f5fe520260991206850f13bc4df578ccbbc97 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Mon, 27 Apr 2009 20:15:07 +0200 Subject: vdpau: use g_once_init_enter instead of g_once --- sys/vdpau/gstvdpdevice.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpdevice.c b/sys/vdpau/gstvdpdevice.c index 1dc42d68..d7a074a7 100644 --- a/sys/vdpau/gstvdpdevice.c +++ b/sys/vdpau/gstvdpdevice.c @@ -53,7 +53,6 @@ gst_vdp_device_finalize (GObject * object) g_free (device->display_name); G_OBJECT_CLASS (gst_vdp_device_parent_class)->finalize (object); - } static void @@ -234,21 +233,18 @@ device_destroyed_cb (gpointer data, GObject * object) } } -static gpointer -create_devices_hash (gpointer data) -{ - return g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); -} - GstVdpDevice * gst_vdp_get_device (const gchar * display_name) { - static GOnce my_once = G_ONCE_INIT; - GHashTable *devices_hash; + static gsize once = 0; + static GHashTable *devices_hash; GstVdpDevice *device; - g_once (&my_once, create_devices_hash, NULL); - devices_hash = my_once.retval; + if (g_once_init_enter (&once)) { + devices_hash = + g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + g_once_init_leave (&once, 1); + } if (display_name) device = g_hash_table_lookup (devices_hash, display_name); -- cgit v1.2.1 From f16aa7271ef571bd260c2a820d0ee0af09c94d11 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Mon, 27 Apr 2009 20:18:52 +0200 Subject: vdpau: small fixes init create GstVdpDevice on GST_STATE_CHANGE_READY_TO_PAUSED instead of on GST_STATE_CHANGE_NULL_TO READY add back incrementing of frame_nr --- sys/vdpau/gstvdpdecoder.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpdecoder.c b/sys/vdpau/gstvdpdecoder.c index b3faf837..8b79dff0 100644 --- a/sys/vdpau/gstvdpdecoder.c +++ b/sys/vdpau/gstvdpdecoder.c @@ -68,6 +68,7 @@ gst_vdp_decoder_push_video_buffer (GstVdpDecoder * dec, GST_BUFFER_TIMESTAMP (buffer) = gst_util_uint64_scale_int (GST_SECOND * dec->frame_nr, dec->framerate_denominator, dec->framerate_numerator); + dec->frame_nr++; } gst_buffer_set_caps (GST_BUFFER (buffer), GST_PAD_CAPS (dec->src)); @@ -82,10 +83,10 @@ gst_vdp_decoder_change_state (GstElement * element, GstStateChange transition) dec = GST_VDP_DECODER (element); switch (transition) { - case GST_STATE_CHANGE_NULL_TO_READY: + case GST_STATE_CHANGE_READY_TO_PAUSED: dec->device = gst_vdp_get_device (dec->display_name); break; - case GST_STATE_CHANGE_READY_TO_NULL: + case GST_STATE_CHANGE_PAUSED_TO_READY: g_object_unref (dec->device); dec->device = NULL; break; -- cgit v1.2.1 From 612a46a565851760db417d2d1399795d7bcb3193 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Mon, 27 Apr 2009 20:21:44 +0200 Subject: vdpau: close display on finalize --- sys/vdpau/gstvdpdevice.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sys') diff --git a/sys/vdpau/gstvdpdevice.c b/sys/vdpau/gstvdpdevice.c index d7a074a7..84fe8922 100644 --- a/sys/vdpau/gstvdpdevice.c +++ b/sys/vdpau/gstvdpdevice.c @@ -50,6 +50,7 @@ gst_vdp_device_finalize (GObject * object) GstVdpDevice *device = (GstVdpDevice *) object; device->vdp_device_destroy (device->device); + XCloseDisplay (device->display); g_free (device->display_name); G_OBJECT_CLASS (gst_vdp_device_parent_class)->finalize (object); -- cgit v1.2.1 From fb70c1e7b5b187f329261b3a26717e621b39de71 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Mon, 27 Apr 2009 20:45:11 +0200 Subject: vdpau: fix error where we forgot to pass a trailing NULL to g_object_new --- sys/vdpau/gstvdpdevice.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpdevice.c b/sys/vdpau/gstvdpdevice.c index 84fe8922..c80b8ac7 100644 --- a/sys/vdpau/gstvdpdevice.c +++ b/sys/vdpau/gstvdpdevice.c @@ -213,7 +213,7 @@ gst_vdp_device_new (const gchar * display_name) { GstVdpDevice *device; - device = g_object_new (GST_TYPE_VDPAU_DEVICE, "display", display_name); + device = g_object_new (GST_TYPE_VDPAU_DEVICE, "display", display_name, NULL); return device; } -- cgit v1.2.1 From e737b9a916d8641b6ac0cc6ea8fd4f3326b9d004 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Mon, 27 Apr 2009 20:50:11 +0200 Subject: vdpaumpegdec: destroy the VdpDecoder and reset the decoder on state change --- sys/vdpau/gstvdpdecoder.c | 27 --------------------------- sys/vdpau/gstvdpmpegdecoder.c | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 27 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpdecoder.c b/sys/vdpau/gstvdpdecoder.c index 8b79dff0..7aca6c2f 100644 --- a/sys/vdpau/gstvdpdecoder.c +++ b/sys/vdpau/gstvdpdecoder.c @@ -75,28 +75,6 @@ gst_vdp_decoder_push_video_buffer (GstVdpDecoder * dec, return gst_pad_push (dec->src, GST_BUFFER (buffer)); } -static GstStateChangeReturn -gst_vdp_decoder_change_state (GstElement * element, GstStateChange transition) -{ - GstVdpDecoder *dec; - - dec = GST_VDP_DECODER (element); - - switch (transition) { - case GST_STATE_CHANGE_READY_TO_PAUSED: - dec->device = gst_vdp_get_device (dec->display_name); - break; - case GST_STATE_CHANGE_PAUSED_TO_READY: - g_object_unref (dec->device); - dec->device = NULL; - break; - default: - break; - } - - return GST_STATE_CHANGE_SUCCESS; -} - static gboolean gst_vdp_decoder_sink_set_caps (GstPad * pad, GstCaps * caps) { @@ -182,8 +160,6 @@ gst_vdp_decoder_class_init (GstVdpDecoderClass * klass) g_object_class_install_property (gobject_class, PROP_DISPLAY, g_param_spec_string ("display", "Display", "X Display name", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); - - gstelement_class->change_state = gst_vdp_decoder_change_state; } static void @@ -214,9 +190,6 @@ gst_vdp_decoder_finalize (GObject * object) { GstVdpDecoder *dec = (GstVdpDecoder *) object; - if (dec->device) - g_object_unref (dec->device); - g_free (dec->display_name); } diff --git a/sys/vdpau/gstvdpmpegdecoder.c b/sys/vdpau/gstvdpmpegdecoder.c index 5b461268..1f15feaf 100644 --- a/sys/vdpau/gstvdpmpegdecoder.c +++ b/sys/vdpau/gstvdpmpegdecoder.c @@ -120,6 +120,12 @@ gst_vdp_mpeg_decoder_set_caps (GstVdpDecoder * dec, GstCaps * caps) &hdr.non_intra_quantizer_matrix, 64); device = dec->device; + + if (mpeg_dec->decoder != VDP_INVALID_HANDLE) { + device->vdp_decoder_destroy (mpeg_dec->decoder); + mpeg_dec->decoder = VDP_INVALID_HANDLE; + } + status = device->vdp_decoder_create (device->device, profile, dec->width, dec->height, 2, &mpeg_dec->decoder); if (status != VDP_STATUS_OK) { @@ -499,6 +505,36 @@ gst_vdp_mpeg_decoder_sink_event (GstPad * pad, GstEvent * event) return res; } +static GstStateChangeReturn +gst_vdp_mpeg_decoder_change_state (GstElement * element, + GstStateChange transition) +{ + GstVdpMpegDecoder *mpeg_dec; + GstVdpDecoder *dec; + + mpeg_dec = GST_VDP_MPEG_DECODER (element); + dec = GST_VDP_DECODER (mpeg_dec); + + switch (transition) { + case GST_STATE_CHANGE_READY_TO_PAUSED: + dec->device = gst_vdp_get_device (dec->display_name); + break; + case GST_STATE_CHANGE_PAUSED_TO_READY: + gst_vdp_mpeg_decoder_reset (mpeg_dec); + + dec->device->vdp_decoder_destroy (mpeg_dec->decoder); + mpeg_dec->decoder = VDP_INVALID_HANDLE; + + g_object_unref (dec->device); + dec->device = NULL; + break; + default: + break; + } + + return GST_STATE_CHANGE_SUCCESS; +} + /* GObject vmethod implementations */ static void @@ -533,6 +569,8 @@ gst_vdp_mpeg_decoder_class_init (GstVdpMpegDecoderClass * klass) gobject_class->get_property = gst_vdp_mpeg_decoder_get_property; vdpaudec_class->set_caps = gst_vdp_mpeg_decoder_set_caps; + + gstelement_class->change_state = gst_vdp_mpeg_decoder_change_state; } static void -- cgit v1.2.1 From 66231a619a2963551102a66c6afe177b8cd0491f Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Mon, 27 Apr 2009 20:57:12 +0200 Subject: vdpau: set vdpauvideoyuv and vdpauyuvvideo to GST_RANK_PRIMARY --- sys/vdpau/gstvdp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdp.c b/sys/vdpau/gstvdp.c index b18c8a02..27a96a82 100644 --- a/sys/vdpau/gstvdp.c +++ b/sys/vdpau/gstvdp.c @@ -15,9 +15,9 @@ vdpau_init (GstPlugin * vdpau_plugin) gst_element_register (vdpau_plugin, "vdpaumpegdec", GST_RANK_NONE, GST_TYPE_VDPAU_MPEG_DECODER); gst_element_register (vdpau_plugin, "vdpauvideoyuv", - GST_RANK_NONE, GST_TYPE_VDPAU_VIDEO_YUV); + GST_RANK_PRIMARY, GST_TYPE_VDPAU_VIDEO_YUV); gst_element_register (vdpau_plugin, "vdpauyuvvideo", - GST_RANK_NONE, GST_TYPE_VDPAU_YUV_VIDEO); + GST_RANK_PRIMARY, GST_TYPE_VDPAU_YUV_VIDEO); return TRUE; } -- cgit v1.2.1 From 3a7a2af1faf00ec3c2cc47fb03dfc01c9dab9eed Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Mon, 27 Apr 2009 21:30:59 +0200 Subject: vdpaumpegdec: drop frames if we haven't got an I_FRAME yet --- sys/vdpau/gstvdpmpegdecoder.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpmpegdecoder.c b/sys/vdpau/gstvdpmpegdecoder.c index 1f15feaf..1a8402e4 100644 --- a/sys/vdpau/gstvdpmpegdecoder.c +++ b/sys/vdpau/gstvdpmpegdecoder.c @@ -325,10 +325,14 @@ gst_vdp_mpeg_decoder_parse_picture (GstVdpMpegDecoder * mpeg_dec, mpeg_dec->vdp_info.picture_coding_type = pic_hdr.pic_type; - if (pic_hdr.pic_type == I_FRAME && - mpeg_dec->vdp_info.forward_reference != VDP_INVALID_HANDLE) { - gst_buffer_unref (mpeg_dec->f_buffer); - mpeg_dec->vdp_info.forward_reference = VDP_INVALID_HANDLE; + if (pic_hdr.pic_type == I_FRAME) { + if (mpeg_dec->vdp_info.forward_reference != VDP_INVALID_HANDLE) { + gst_buffer_unref (mpeg_dec->f_buffer); + mpeg_dec->vdp_info.forward_reference = VDP_INVALID_HANDLE; + } + } else if (mpeg_dec->vdp_info.forward_reference == VDP_INVALID_HANDLE) { + GST_DEBUG_OBJECT (mpeg_dec, "Drop frame since we've got no I_FRAME yet"); + return FALSE; } if (mpeg_dec->version == 1) { @@ -439,7 +443,9 @@ gst_vdp_mpeg_decoder_chain (GstPad * pad, GstBuffer * buffer) case MPEG_PACKET_PICTURE: GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_PICTURE"); - gst_vdp_mpeg_decoder_parse_picture (mpeg_dec, packet_start, packet_end); + if (!gst_vdp_mpeg_decoder_parse_picture (mpeg_dec, packet_start, + packet_end)) + return GST_FLOW_OK; break; case MPEG_PACKET_SEQUENCE: GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_SEQUENCE"); -- cgit v1.2.1 From b8a79867754e5ac7fcd66b0172db675297554451 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Thu, 30 Apr 2009 21:58:01 +0200 Subject: vdpaumpegdec: set full_pel_forward_vector to 0 when pic_type == P_FRAME --- sys/vdpau/mpegutil.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'sys') diff --git a/sys/vdpau/mpegutil.c b/sys/vdpau/mpegutil.c index 6f59b841..08ae5c53 100644 --- a/sys/vdpau/mpegutil.c +++ b/sys/vdpau/mpegutil.c @@ -301,7 +301,8 @@ mpeg_util_parse_picture_hdr (MPEGPictureHdr * hdr, guint8 * data, guint8 * end) if (hdr->pic_type == B_FRAME) { hdr->full_pel_backward_vector = read_bits (data + 4, 1, 1); hdr->f_code[1][0] = hdr->f_code[1][1] = read_bits (data + 4, 2, 3); - } + } else + hdr->full_pel_backward_vector = 0; } else { hdr->full_pel_forward_vector = 0; hdr->full_pel_backward_vector = 0; -- cgit v1.2.1 From 6b05d01898b44cf4d4081df6be34eb69721967b1 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Sun, 3 May 2009 21:52:49 +0200 Subject: vdpaumpegdec: the B_FRAME decoding was completely wrong, fix it the buffers don't come in output order so fix the decoder to handle this add new gst_vdp_video_buffer_add_reference method to GstVdpVideoBuffer to be able to keep buffers alive. Ie. a B_FRAME need to have both the forward reference and the backward reference alive during it's lifetime. add mutex to protect for threadsafety issues when we reset the decoder in FLUSH_STOP --- sys/vdpau/gstvdpmpegdecoder.c | 143 ++++++++++++++++-------------------------- sys/vdpau/gstvdpmpegdecoder.h | 6 +- sys/vdpau/gstvdpvideobuffer.c | 78 +++++++++++++++-------- sys/vdpau/gstvdpvideobuffer.h | 4 ++ 4 files changed, 113 insertions(+), 118 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpmpegdecoder.c b/sys/vdpau/gstvdpmpegdecoder.c index 1a8402e4..413eefd4 100644 --- a/sys/vdpau/gstvdpmpegdecoder.c +++ b/sys/vdpau/gstvdpmpegdecoder.c @@ -155,40 +155,41 @@ gst_vdp_mpeg_decoder_decode (GstVdpMpegDecoder * mpeg_dec, GstVdpDevice *device; VdpBitstreamBuffer vbit[1]; VdpStatus status; - GstFlowReturn ret; dec = GST_VDP_DECODER (mpeg_dec); buffer = gst_adapter_take_buffer (mpeg_dec->adapter, gst_adapter_available (mpeg_dec->adapter)); - /* if the frame is a B_FRAME we store it for future decoding */ - if (mpeg_dec->vdp_info.picture_coding_type == B_FRAME) { - GstVdpBFrame *b_frame; - - if (mpeg_dec->broken_gop) { - gst_buffer_unref (buffer); - mpeg_dec->broken_gop = FALSE; - return GST_FLOW_OK; + if (mpeg_dec->vdp_info.picture_coding_type != B_FRAME) { + if (mpeg_dec->vdp_info.backward_reference != VDP_INVALID_HANDLE) { + GST_BUFFER_TIMESTAMP (mpeg_dec->b_buffer) = timestamp; + gst_buffer_ref (mpeg_dec->b_buffer); + gst_vdp_decoder_push_video_buffer (dec, + GST_VDP_VIDEO_BUFFER (mpeg_dec->b_buffer)); } - b_frame = g_slice_new (GstVdpBFrame); - - GST_BUFFER_TIMESTAMP (buffer) = timestamp; - b_frame->buffer = buffer; - memcpy (&b_frame->vdp_info, &mpeg_dec->vdp_info, - sizeof (VdpPictureInfoMPEG1Or2)); - - mpeg_dec->b_frames = g_slist_append (mpeg_dec->b_frames, b_frame); + if (mpeg_dec->vdp_info.forward_reference != VDP_INVALID_HANDLE) { + gst_buffer_unref (mpeg_dec->f_buffer); + mpeg_dec->vdp_info.forward_reference = VDP_INVALID_HANDLE; + } - mpeg_dec->vdp_info.slice_count = 0; + mpeg_dec->vdp_info.forward_reference = + mpeg_dec->vdp_info.backward_reference; + mpeg_dec->f_buffer = mpeg_dec->b_buffer; - return GST_FLOW_OK; + mpeg_dec->vdp_info.backward_reference = VDP_INVALID_HANDLE; } outbuf = gst_vdp_video_buffer_new (dec->device, VDP_CHROMA_TYPE_420, dec->width, dec->height); - GST_BUFFER_TIMESTAMP (outbuf) = timestamp; + if (mpeg_dec->vdp_info.forward_reference != VDP_INVALID_HANDLE) + gst_vdp_video_buffer_add_reference (outbuf, + GST_VDP_VIDEO_BUFFER (mpeg_dec->f_buffer)); + if (mpeg_dec->vdp_info.backward_reference != VDP_INVALID_HANDLE) + gst_vdp_video_buffer_add_reference (outbuf, + GST_VDP_VIDEO_BUFFER (mpeg_dec->b_buffer)); + surface = outbuf->surface; device = dec->device; @@ -213,54 +214,15 @@ gst_vdp_mpeg_decoder_decode (GstVdpMpegDecoder * mpeg_dec, return GST_FLOW_ERROR; } - /* if we have stored away some B_FRAMEs we can now decode them */ - if (mpeg_dec->b_frames) { - GSList *iter; - - for (iter = mpeg_dec->b_frames; iter; iter = g_slist_next (iter)) { - GstVdpBFrame *b_frame; - GstVdpVideoBuffer *b_outbuf; - - b_frame = (GstVdpBFrame *) iter->data; - - b_outbuf = gst_vdp_video_buffer_new (dec->device, VDP_CHROMA_TYPE_420, - dec->width, dec->height); - GST_BUFFER_TIMESTAMP (b_outbuf) = GST_BUFFER_TIMESTAMP (b_frame->buffer); - - b_frame->vdp_info.backward_reference = surface; - vbit[0].struct_version = VDP_BITSTREAM_BUFFER_VERSION; - vbit[0].bitstream = GST_BUFFER_DATA (b_frame->buffer); - vbit[0].bitstream_bytes = GST_BUFFER_SIZE (b_frame->buffer); - - status = device->vdp_decoder_render (mpeg_dec->decoder, b_outbuf->surface, - (VdpPictureInfo *) & b_frame->vdp_info, 1, vbit); - gst_buffer_unref (b_frame->buffer); - g_slice_free (GstVdpBFrame, b_frame); - - if (status != VDP_STATUS_OK) { - GST_ELEMENT_ERROR (mpeg_dec, RESOURCE, READ, - ("Could not decode B_FRAME"), - ("Error returned from vdpau was: %s", - device->vdp_get_error_string (status))); - } - - gst_vdp_decoder_push_video_buffer (GST_VDP_DECODER (mpeg_dec), b_outbuf); - } - g_slist_free (mpeg_dec->b_frames); - mpeg_dec->b_frames = NULL; + if (mpeg_dec->vdp_info.picture_coding_type == B_FRAME) { + GST_BUFFER_TIMESTAMP (outbuf) = timestamp; + gst_vdp_decoder_push_video_buffer (dec, GST_VDP_VIDEO_BUFFER (outbuf)); + } else { + mpeg_dec->vdp_info.backward_reference = surface; + mpeg_dec->b_buffer = GST_BUFFER (outbuf); } - gst_buffer_ref (GST_BUFFER (outbuf)); - - ret = gst_vdp_decoder_push_video_buffer (GST_VDP_DECODER (mpeg_dec), outbuf); - - if (mpeg_dec->vdp_info.forward_reference != VDP_INVALID_HANDLE) - gst_buffer_unref (mpeg_dec->f_buffer); - - mpeg_dec->vdp_info.forward_reference = surface; - mpeg_dec->f_buffer = GST_BUFFER (outbuf); - - return ret; + return GST_FLOW_OK; } static gboolean @@ -323,18 +285,21 @@ gst_vdp_mpeg_decoder_parse_picture (GstVdpMpegDecoder * mpeg_dec, if (!mpeg_util_parse_picture_hdr (&pic_hdr, data, end)) return FALSE; - mpeg_dec->vdp_info.picture_coding_type = pic_hdr.pic_type; - - if (pic_hdr.pic_type == I_FRAME) { - if (mpeg_dec->vdp_info.forward_reference != VDP_INVALID_HANDLE) { - gst_buffer_unref (mpeg_dec->f_buffer); - mpeg_dec->vdp_info.forward_reference = VDP_INVALID_HANDLE; - } - } else if (mpeg_dec->vdp_info.forward_reference == VDP_INVALID_HANDLE) { - GST_DEBUG_OBJECT (mpeg_dec, "Drop frame since we've got no I_FRAME yet"); + if (pic_hdr.pic_type != I_FRAME + && mpeg_dec->vdp_info.backward_reference == VDP_INVALID_HANDLE) { + GST_DEBUG_OBJECT (mpeg_dec, + "Drop frame since we haven't got an I_FRAME yet"); + return FALSE; + } + if (pic_hdr.pic_type == B_FRAME + && mpeg_dec->vdp_info.forward_reference == VDP_INVALID_HANDLE) { + GST_DEBUG_OBJECT (mpeg_dec, + "Drop frame since we haven't got two non B_FRAMES yet"); return FALSE; } + mpeg_dec->vdp_info.picture_coding_type = pic_hdr.pic_type; + if (mpeg_dec->version == 1) { mpeg_dec->vdp_info.full_pel_forward_vector = pic_hdr.full_pel_forward_vector; @@ -379,19 +344,10 @@ gst_vdp_mpeg_decoder_parse_quant_matrix (GstVdpMpegDecoder * mpeg_dec, static void gst_vdp_mpeg_decoder_reset (GstVdpMpegDecoder * mpeg_dec) { - GSList *iter; - - for (iter = mpeg_dec->b_frames; iter; iter = iter->next) { - GstVdpBFrame *b_frame = (GstVdpBFrame *) iter->data; - - gst_buffer_unref (b_frame->buffer); - g_slice_free (GstVdpBFrame, b_frame); - } - g_slist_free (mpeg_dec->b_frames); - mpeg_dec->b_frames = NULL; - if (mpeg_dec->vdp_info.forward_reference != VDP_INVALID_HANDLE) gst_buffer_unref (mpeg_dec->f_buffer); + if (mpeg_dec->vdp_info.backward_reference != VDP_INVALID_HANDLE) + gst_buffer_unref (mpeg_dec->b_buffer); gst_vdp_mpeg_decoder_init_info (&mpeg_dec->vdp_info); @@ -408,9 +364,12 @@ gst_vdp_mpeg_decoder_chain (GstPad * pad, GstBuffer * buffer) mpeg_dec = GST_VDP_MPEG_DECODER (GST_OBJECT_PARENT (pad)); + g_mutex_lock (mpeg_dec->mutex); + if (G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT))) { GST_DEBUG_OBJECT (mpeg_dec, "Received discont buffer"); gst_vdp_mpeg_decoder_reset (mpeg_dec); + g_mutex_unlock (mpeg_dec->mutex); return GST_FLOW_OK; } @@ -444,8 +403,10 @@ gst_vdp_mpeg_decoder_chain (GstPad * pad, GstBuffer * buffer) GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_PICTURE"); if (!gst_vdp_mpeg_decoder_parse_picture (mpeg_dec, packet_start, - packet_end)) + packet_end)) { + g_mutex_unlock (mpeg_dec->mutex); return GST_FLOW_OK; + } break; case MPEG_PACKET_SEQUENCE: GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_SEQUENCE"); @@ -481,6 +442,8 @@ gst_vdp_mpeg_decoder_chain (GstPad * pad, GstBuffer * buffer) if (mpeg_dec->vdp_info.slice_count > 0) ret = gst_vdp_mpeg_decoder_decode (mpeg_dec, GST_BUFFER_TIMESTAMP (buffer)); + g_mutex_unlock (mpeg_dec->mutex); + return ret; } @@ -499,7 +462,10 @@ gst_vdp_mpeg_decoder_sink_event (GstPad * pad, GstEvent * event) { GST_DEBUG_OBJECT (mpeg_dec, "flush stop"); + g_mutex_lock (mpeg_dec->mutex); gst_vdp_mpeg_decoder_reset (mpeg_dec); + g_mutex_unlock (mpeg_dec->mutex); + res = gst_pad_push_event (dec->src, event); break; @@ -607,7 +573,7 @@ gst_vdp_mpeg_decoder_init (GstVdpMpegDecoder * mpeg_dec, mpeg_dec->decoder = VDP_INVALID_HANDLE; gst_vdp_mpeg_decoder_init_info (&mpeg_dec->vdp_info); - mpeg_dec->b_frames = NULL; + mpeg_dec->mutex = g_mutex_new (); mpeg_dec->broken_gop = FALSE; @@ -622,6 +588,7 @@ gst_vdp_mpeg_decoder_finalize (GObject * object) { GstVdpMpegDecoder *mpeg_dec = (GstVdpMpegDecoder *) object; + g_mutex_free (mpeg_dec->mutex); g_object_unref (mpeg_dec->adapter); } diff --git a/sys/vdpau/gstvdpmpegdecoder.h b/sys/vdpau/gstvdpmpegdecoder.h index ee7086c5..547b0f94 100644 --- a/sys/vdpau/gstvdpmpegdecoder.h +++ b/sys/vdpau/gstvdpmpegdecoder.h @@ -46,10 +46,10 @@ struct _GstVdpMpegDecoder VdpDecoder decoder; VdpPictureInfoMPEG1Or2 vdp_info; GstBuffer *f_buffer; + GstBuffer *b_buffer; - /* holds B_FRAMES */ - GSList *b_frames; - + GMutex *mutex; + gboolean broken_gop; GstAdapter *adapter; diff --git a/sys/vdpau/gstvdpvideobuffer.c b/sys/vdpau/gstvdpvideobuffer.c index c62ac771..82f7dba7 100644 --- a/sys/vdpau/gstvdpvideobuffer.c +++ b/sys/vdpau/gstvdpvideobuffer.c @@ -24,14 +24,54 @@ #include "gstvdpvideobuffer.h" + +void +gst_vdp_video_buffer_add_reference (GstVdpVideoBuffer * buffer, + GstVdpVideoBuffer * buf) +{ + g_assert (GST_IS_VDPAU_VIDEO_BUFFER (buffer)); + g_assert (GST_IS_VDPAU_VIDEO_BUFFER (buf)); + + gst_buffer_ref (GST_BUFFER (buf)); + buffer->refs = g_slist_prepend (buffer->refs, buf); +} + +GstVdpVideoBuffer * +gst_vdp_video_buffer_new (GstVdpDevice * device, VdpChromaType chroma_type, + gint width, gint height) +{ + GstVdpVideoBuffer *buffer; + VdpStatus status; + VdpVideoSurface surface; + + status = device->vdp_video_surface_create (device->device, chroma_type, width, + height, &surface); + if (status != VDP_STATUS_OK) { + GST_ERROR ("Couldn't create a VdpVideoSurface, error returned was: %s", + device->vdp_get_error_string (status)); + return NULL; + } + + buffer = + (GstVdpVideoBuffer *) gst_mini_object_new (GST_TYPE_VDPAU_VIDEO_BUFFER); + + buffer->device = g_object_ref (device); + buffer->surface = surface; + + return buffer; +} + static GObjectClass *gst_vdp_video_buffer_parent_class; static void gst_vdp_video_buffer_finalize (GstVdpVideoBuffer * buffer) { - GstVdpDevice *device = buffer->device; + GSList *iter; + GstVdpDevice *device; VdpStatus status; + device = buffer->device; + status = device->vdp_video_surface_destroy (buffer->surface); if (status != VDP_STATUS_OK) GST_ERROR @@ -40,6 +80,14 @@ gst_vdp_video_buffer_finalize (GstVdpVideoBuffer * buffer) g_object_unref (buffer->device); + for (iter = buffer->refs; iter; iter = g_slist_next (iter)) { + GstBuffer *buf; + + buf = (GstBuffer *) (iter->data); + gst_buffer_unref (buf); + } + g_slist_free (buffer->refs); + GST_MINI_OBJECT_CLASS (gst_vdp_video_buffer_parent_class)->finalize (GST_MINI_OBJECT (buffer)); } @@ -49,6 +97,8 @@ gst_vdp_video_buffer_init (GstVdpVideoBuffer * buffer, gpointer g_class) { buffer->device = NULL; buffer->surface = VDP_INVALID_HANDLE; + + buffer->refs = NULL; } static void @@ -86,29 +136,3 @@ gst_vdp_video_buffer_get_type (void) } return _gst_vdp_video_buffer_type; } - - -GstVdpVideoBuffer * -gst_vdp_video_buffer_new (GstVdpDevice * device, VdpChromaType chroma_type, - gint width, gint height) -{ - GstVdpVideoBuffer *buffer; - VdpStatus status; - VdpVideoSurface surface; - - status = device->vdp_video_surface_create (device->device, chroma_type, width, - height, &surface); - if (status != VDP_STATUS_OK) { - GST_ERROR ("Couldn't create a VdpVideoSurface, error returned was: %s", - device->vdp_get_error_string (status)); - return NULL; - } - - buffer = - (GstVdpVideoBuffer *) gst_mini_object_new (GST_TYPE_VDPAU_VIDEO_BUFFER); - - buffer->device = g_object_ref (device); - buffer->surface = surface; - - return buffer; -} diff --git a/sys/vdpau/gstvdpvideobuffer.h b/sys/vdpau/gstvdpvideobuffer.h index 92a077f8..abc8c99e 100644 --- a/sys/vdpau/gstvdpvideobuffer.h +++ b/sys/vdpau/gstvdpvideobuffer.h @@ -40,12 +40,16 @@ struct _GstVdpVideoBuffer { GstVdpDevice *device; VdpVideoSurface surface; + + GSList *refs; }; GType gst_vdp_video_buffer_get_type (void); GstVdpVideoBuffer* gst_vdp_video_buffer_new (GstVdpDevice * device, VdpChromaType chroma_type, gint width, gint height); +void gst_vdp_video_buffer_add_reference (GstVdpVideoBuffer *buffer, GstVdpVideoBuffer *buf); + #define GST_VDP_VIDEO_CAPS \ "video/x-vdpau-video, " \ "chroma-type = (int)[0,2], " \ -- cgit v1.2.1 From de7fb2006e6bad7dba369bcd2d2fc89c965bf5f3 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Tue, 5 May 2009 08:11:03 +0200 Subject: vdpaumpegdec: hold the lock in change_state --- sys/vdpau/gstvdpmpegdecoder.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'sys') diff --git a/sys/vdpau/gstvdpmpegdecoder.c b/sys/vdpau/gstvdpmpegdecoder.c index 413eefd4..bf3ea423 100644 --- a/sys/vdpau/gstvdpmpegdecoder.c +++ b/sys/vdpau/gstvdpmpegdecoder.c @@ -489,9 +489,12 @@ gst_vdp_mpeg_decoder_change_state (GstElement * element, switch (transition) { case GST_STATE_CHANGE_READY_TO_PAUSED: + g_mutex_lock (mpeg_dec->mutex); dec->device = gst_vdp_get_device (dec->display_name); + g_mutex_unlock (mpeg_dec->mutex); break; case GST_STATE_CHANGE_PAUSED_TO_READY: + g_mutex_lock (mpeg_dec->mutex); gst_vdp_mpeg_decoder_reset (mpeg_dec); dec->device->vdp_decoder_destroy (mpeg_dec->decoder); @@ -499,6 +502,7 @@ gst_vdp_mpeg_decoder_change_state (GstElement * element, g_object_unref (dec->device); dec->device = NULL; + g_mutex_unlock (mpeg_dec->mutex); break; default: break; -- cgit v1.2.1 From e417b2eea0256d5a4a8355f2472e3af3777a2d0c Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Tue, 5 May 2009 16:29:24 +0200 Subject: vdpau: init "vdpaudevice" debug catoegory in gst_vdp_get_device --- sys/vdpau/gstvdpdevice.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpdevice.c b/sys/vdpau/gstvdpdevice.c index c80b8ac7..ff8b6510 100644 --- a/sys/vdpau/gstvdpdevice.c +++ b/sys/vdpau/gstvdpdevice.c @@ -196,16 +196,12 @@ gst_vdp_device_class_init (GstVdpDeviceClass * klass) object_class->get_property = gst_vdp_device_get_property; object_class->set_property = gst_vdp_device_set_property; - g_object_class_install_property (object_class, PROP_DISPLAY, g_param_spec_string ("display", "Display", "X Display Name", "", G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); - - GST_DEBUG_CATEGORY_INIT (gst_vdp_device_debug, "vdpaudevice", - 0, "vdpaudevice"); } GstVdpDevice * @@ -242,6 +238,8 @@ gst_vdp_get_device (const gchar * display_name) GstVdpDevice *device; if (g_once_init_enter (&once)) { + GST_DEBUG_CATEGORY_INIT (gst_vdp_device_debug, "vdpaudevice", + 0, "vdpaudevice"); devices_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); g_once_init_leave (&once, 1); -- cgit v1.2.1 From 323b563c24027d8f657c998c56458014ac97da46 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Tue, 5 May 2009 17:15:33 +0200 Subject: vdpaumpegdec: fixup state change --- sys/vdpau/gstvdpdecoder.c | 1 - sys/vdpau/gstvdpmpegdecoder.c | 14 +++++++++----- 2 files changed, 9 insertions(+), 6 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpdecoder.c b/sys/vdpau/gstvdpdecoder.c index 7aca6c2f..2b0c888e 100644 --- a/sys/vdpau/gstvdpdecoder.c +++ b/sys/vdpau/gstvdpdecoder.c @@ -182,7 +182,6 @@ gst_vdp_decoder_init (GstVdpDecoder * dec, GstVdpDecoderClass * klass) (GST_ELEMENT_CLASS (klass), "sink"), "sink"); gst_pad_set_setcaps_function (dec->sink, gst_vdp_decoder_sink_set_caps); gst_element_add_pad (GST_ELEMENT (dec), dec->sink); - gst_pad_set_active (dec->sink, TRUE); } static void diff --git a/sys/vdpau/gstvdpmpegdecoder.c b/sys/vdpau/gstvdpmpegdecoder.c index bf3ea423..c63b6c0d 100644 --- a/sys/vdpau/gstvdpmpegdecoder.c +++ b/sys/vdpau/gstvdpmpegdecoder.c @@ -483,18 +483,23 @@ gst_vdp_mpeg_decoder_change_state (GstElement * element, { GstVdpMpegDecoder *mpeg_dec; GstVdpDecoder *dec; + GstStateChangeReturn ret; mpeg_dec = GST_VDP_MPEG_DECODER (element); dec = GST_VDP_DECODER (mpeg_dec); switch (transition) { case GST_STATE_CHANGE_READY_TO_PAUSED: - g_mutex_lock (mpeg_dec->mutex); dec->device = gst_vdp_get_device (dec->display_name); - g_mutex_unlock (mpeg_dec->mutex); break; + default: + break; + } + + ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); + + switch (transition) { case GST_STATE_CHANGE_PAUSED_TO_READY: - g_mutex_lock (mpeg_dec->mutex); gst_vdp_mpeg_decoder_reset (mpeg_dec); dec->device->vdp_decoder_destroy (mpeg_dec->decoder); @@ -502,13 +507,12 @@ gst_vdp_mpeg_decoder_change_state (GstElement * element, g_object_unref (dec->device); dec->device = NULL; - g_mutex_unlock (mpeg_dec->mutex); break; default: break; } - return GST_STATE_CHANGE_SUCCESS; + return ret; } /* GObject vmethod implementations */ -- cgit v1.2.1 From 824cf29cdc9399d72ce5f9ad88040cde7ce7de12 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Tue, 5 May 2009 17:20:16 +0200 Subject: vdpau: s/GST_TYPE_VDPAU/GST_TYPE_VDP/g --- sys/vdpau/gstvdpdevice.h | 12 ++++++------ sys/vdpau/gstvdpvideoyuv.h | 12 ++++++------ sys/vdpau/gstvdpyuvvideo.h | 12 ++++++------ 3 files changed, 18 insertions(+), 18 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpdevice.h b/sys/vdpau/gstvdpdevice.h index 26e7fa72..70758a2d 100644 --- a/sys/vdpau/gstvdpdevice.h +++ b/sys/vdpau/gstvdpdevice.h @@ -28,12 +28,12 @@ G_BEGIN_DECLS -#define GST_TYPE_VDPAU_DEVICE (gst_vdp_device_get_type ()) -#define GST_VDP_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VDPAU_DEVICE, GstVdpDevice)) -#define GST_VDP_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_VDPAU_DEVICE, GstVdpDeviceClass)) -#define GST_IS_VDPAU_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VDPAU_DEVICE)) -#define GST_IS_VDPAU_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_VDPAU_DEVICE)) -#define GST_VDP_DEVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VDPAU_DEVICE, GstVdpDeviceClass)) +#define GST_TYPE_VDP_DEVICE (gst_vdp_device_get_type ()) +#define GST_VDP_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VDP_DEVICE, GstVdpDevice)) +#define GST_VDP_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_VDP_DEVICE, GstVdpDeviceClass)) +#define GST_IS_VDPAU_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VDP_DEVICE)) +#define GST_IS_VDPAU_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_VDP_DEVICE)) +#define GST_VDP_DEVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VDP_DEVICE, GstVdpDeviceClass)) typedef struct _GstVdpDeviceClass GstVdpDeviceClass; typedef struct _GstVdpDevice GstVdpDevice; diff --git a/sys/vdpau/gstvdpvideoyuv.h b/sys/vdpau/gstvdpvideoyuv.h index eb628352..07955ed8 100644 --- a/sys/vdpau/gstvdpvideoyuv.h +++ b/sys/vdpau/gstvdpvideoyuv.h @@ -27,12 +27,12 @@ G_BEGIN_DECLS -#define GST_TYPE_VDPAU_VIDEO_YUV (gst_vdp_video_yuv_get_type()) -#define GST_VDP_VIDEO_YUV(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VDPAU_VIDEO_YUV,GstVdpVideoYUV)) -#define GST_VDP_VIDEO_YUV_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VDPAU_VIDEO_YUV,GstVdpVideoYUVClass)) -#define GST_VDP_VIDEO_YUV_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VDPAU_VIDEO_YUV, GstVdpVideoYUVClass)) -#define GST_IS_VDPAU_VIDEO_YUV(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VDPAU_VIDEO_YUV)) -#define GST_IS_VDPAU_VIDEO_YUV_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VDPAU_VIDEO_YUV)) +#define GST_TYPE_VDP_VIDEO_YUV (gst_vdp_video_yuv_get_type()) +#define GST_VDP_VIDEO_YUV(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VDP_VIDEO_YUV,GstVdpVideoYUV)) +#define GST_VDP_VIDEO_YUV_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VDP_VIDEO_YUV,GstVdpVideoYUVClass)) +#define GST_VDP_VIDEO_YUV_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VDP_VIDEO_YUV, GstVdpVideoYUVClass)) +#define GST_IS_VDPAU_VIDEO_YUV(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VDP_VIDEO_YUV)) +#define GST_IS_VDPAU_VIDEO_YUV_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VDP_VIDEO_YUV)) typedef struct _GstVdpVideoYUV GstVdpVideoYUV; typedef struct _GstVdpVideoYUVClass GstVdpVideoYUVClass; diff --git a/sys/vdpau/gstvdpyuvvideo.h b/sys/vdpau/gstvdpyuvvideo.h index 0c063929..ba3a3b01 100644 --- a/sys/vdpau/gstvdpyuvvideo.h +++ b/sys/vdpau/gstvdpyuvvideo.h @@ -27,12 +27,12 @@ G_BEGIN_DECLS -#define GST_TYPE_VDPAU_YUV_VIDEO (gst_vdp_yuv_video_get_type()) -#define GST_VDP_YUV_VIDEO(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VDPAU_YUV_VIDEO,GstVdpYUVVideo)) -#define GST_VDP_YUV_VIDEO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VDPAU_YUV_VIDEO,GstVdpYUVVideoClass)) -#define GST_VDP_YUV_VIDEO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VDPAU_YUV_VIDEO, GstVdpYUVVideoClass)) -#define GST_IS_VDPAU_YUV_VIDEO(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VDPAU_YUV_VIDEO)) -#define GST_IS_VDPAU_YUV_VIDEO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VDPAU_YUV_VIDEO)) +#define GST_TYPE_VDP_YUV_VIDEO (gst_vdp_yuv_video_get_type()) +#define GST_VDP_YUV_VIDEO(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VDP_YUV_VIDEO,GstVdpYUVVideo)) +#define GST_VDP_YUV_VIDEO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VDP_YUV_VIDEO,GstVdpYUVVideoClass)) +#define GST_VDP_YUV_VIDEO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VDP_YUV_VIDEO, GstVdpYUVVideoClass)) +#define GST_IS_VDPAU_YUV_VIDEO(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VDP_YUV_VIDEO)) +#define GST_IS_VDPAU_YUV_VIDEO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VDP_YUV_VIDEO)) typedef struct _GstVdpYUVVideo GstVdpYUVVideo; typedef struct _GstVdpYUVVideoClass GstVdpYUVVideoClass; -- cgit v1.2.1 From 02884b0356edfef0db34d7acc11530673fb41db1 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Tue, 5 May 2009 17:28:19 +0200 Subject: s/GST_TYPE_VDPAU/GST_TYPE_VDP/g --- sys/vdpau/gstvdp.c | 6 +++--- sys/vdpau/gstvdpdecoder.h | 12 ++++++------ sys/vdpau/gstvdpdevice.c | 2 +- sys/vdpau/gstvdpmpegdecoder.c | 2 +- sys/vdpau/gstvdpmpegdecoder.h | 10 +++++----- sys/vdpau/gstvdpvideobuffer.c | 2 +- sys/vdpau/gstvdpvideobuffer.h | 6 +++--- 7 files changed, 20 insertions(+), 20 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdp.c b/sys/vdpau/gstvdp.c index 27a96a82..64ebf37e 100644 --- a/sys/vdpau/gstvdp.c +++ b/sys/vdpau/gstvdp.c @@ -13,11 +13,11 @@ static gboolean vdpau_init (GstPlugin * vdpau_plugin) { gst_element_register (vdpau_plugin, "vdpaumpegdec", - GST_RANK_NONE, GST_TYPE_VDPAU_MPEG_DECODER); + GST_RANK_NONE, GST_TYPE_VDP_MPEG_DECODER); gst_element_register (vdpau_plugin, "vdpauvideoyuv", - GST_RANK_PRIMARY, GST_TYPE_VDPAU_VIDEO_YUV); + GST_RANK_PRIMARY, GST_TYPE_VDP_VIDEO_YUV); gst_element_register (vdpau_plugin, "vdpauyuvvideo", - GST_RANK_PRIMARY, GST_TYPE_VDPAU_YUV_VIDEO); + GST_RANK_PRIMARY, GST_TYPE_VDP_YUV_VIDEO); return TRUE; } diff --git a/sys/vdpau/gstvdpdecoder.h b/sys/vdpau/gstvdpdecoder.h index dfc63fd9..ae53657c 100644 --- a/sys/vdpau/gstvdpdecoder.h +++ b/sys/vdpau/gstvdpdecoder.h @@ -28,12 +28,12 @@ G_BEGIN_DECLS -#define GST_TYPE_VDPAU_DECODER (gst_vdp_decoder_get_type()) -#define GST_VDP_DECODER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VDPAU_DECODER,GstVdpDecoder)) -#define GST_VDP_DECODER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VDPAU_DECODER,GstVdpDecoderClass)) -#define GST_VDP_DECODER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VDPAU_DECODER, GstVdpDecoderClass)) -#define GST_IS_VDPAU_DECODER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VDPAU_DECODER)) -#define GST_IS_VDPAU_DECODER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VDPAU_DECODER)) +#define GST_TYPE_VDP_DECODER (gst_vdp_decoder_get_type()) +#define GST_VDP_DECODER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VDP_DECODER,GstVdpDecoder)) +#define GST_VDP_DECODER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VDP_DECODER,GstVdpDecoderClass)) +#define GST_VDP_DECODER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VDP_DECODER, GstVdpDecoderClass)) +#define GST_IS_VDPAU_DECODER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VDP_DECODER)) +#define GST_IS_VDPAU_DECODER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VDP_DECODER)) typedef struct _GstVdpDecoder GstVdpDecoder; typedef struct _GstVdpDecoderClass GstVdpDecoderClass; diff --git a/sys/vdpau/gstvdpdevice.c b/sys/vdpau/gstvdpdevice.c index ff8b6510..ad771906 100644 --- a/sys/vdpau/gstvdpdevice.c +++ b/sys/vdpau/gstvdpdevice.c @@ -209,7 +209,7 @@ gst_vdp_device_new (const gchar * display_name) { GstVdpDevice *device; - device = g_object_new (GST_TYPE_VDPAU_DEVICE, "display", display_name, NULL); + device = g_object_new (GST_TYPE_VDP_DEVICE, "display", display_name, NULL); return device; } diff --git a/sys/vdpau/gstvdpmpegdecoder.c b/sys/vdpau/gstvdpmpegdecoder.c index c63b6c0d..4bcbf534 100644 --- a/sys/vdpau/gstvdpmpegdecoder.c +++ b/sys/vdpau/gstvdpmpegdecoder.c @@ -71,7 +71,7 @@ static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink", GST_DEBUG_CATEGORY_INIT (gst_vdp_mpeg_decoder_debug, "vdpaumpegdec", 0, "VDPAU powered mpeg decoder"); GST_BOILERPLATE_FULL (GstVdpMpegDecoder, gst_vdp_mpeg_decoder, - GstVdpDecoder, GST_TYPE_VDPAU_DECODER, DEBUG_INIT); + GstVdpDecoder, GST_TYPE_VDP_DECODER, DEBUG_INIT); static void gst_vdp_mpeg_decoder_init_info (VdpPictureInfoMPEG1Or2 * vdp_info); static void gst_vdp_mpeg_decoder_finalize (GObject * object); diff --git a/sys/vdpau/gstvdpmpegdecoder.h b/sys/vdpau/gstvdpmpegdecoder.h index 547b0f94..57ab66ab 100644 --- a/sys/vdpau/gstvdpmpegdecoder.h +++ b/sys/vdpau/gstvdpmpegdecoder.h @@ -28,11 +28,11 @@ G_BEGIN_DECLS -#define GST_TYPE_VDPAU_MPEG_DECODER (gst_vdp_mpeg_decoder_get_type()) -#define GST_VDP_MPEG_DECODER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VDPAU_MPEG_DECODER,GstVdpMpegDecoder)) -#define GST_VDP_MPEG_DECODER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VDPAU_MPEG_DECODER,GstVdpMpegDecoderClass)) -#define GST_IS_VDPAU_MPEG_DECODER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VDPAU_MPEG_DECODER)) -#define GST_IS_VDPAU_MPEG_DECODER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VDPAU_MPEG_DECODER)) +#define GST_TYPE_VDP_MPEG_DECODER (gst_vdp_mpeg_decoder_get_type()) +#define GST_VDP_MPEG_DECODER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VDP_MPEG_DECODER,GstVdpMpegDecoder)) +#define GST_VDP_MPEG_DECODER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VDP_MPEG_DECODER,GstVdpMpegDecoderClass)) +#define GST_IS_VDPAU_MPEG_DECODER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VDP_MPEG_DECODER)) +#define GST_IS_VDPAU_MPEG_DECODER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VDP_MPEG_DECODER)) typedef struct _GstVdpMpegDecoder GstVdpMpegDecoder; typedef struct _GstVdpMpegDecoderClass GstVdpMpegDecoderClass; diff --git a/sys/vdpau/gstvdpvideobuffer.c b/sys/vdpau/gstvdpvideobuffer.c index 82f7dba7..dac62c1b 100644 --- a/sys/vdpau/gstvdpvideobuffer.c +++ b/sys/vdpau/gstvdpvideobuffer.c @@ -53,7 +53,7 @@ gst_vdp_video_buffer_new (GstVdpDevice * device, VdpChromaType chroma_type, } buffer = - (GstVdpVideoBuffer *) gst_mini_object_new (GST_TYPE_VDPAU_VIDEO_BUFFER); + (GstVdpVideoBuffer *) gst_mini_object_new (GST_TYPE_VDP_VIDEO_BUFFER); buffer->device = g_object_ref (device); buffer->surface = surface; diff --git a/sys/vdpau/gstvdpvideobuffer.h b/sys/vdpau/gstvdpvideobuffer.h index abc8c99e..77ccf8ed 100644 --- a/sys/vdpau/gstvdpvideobuffer.h +++ b/sys/vdpau/gstvdpvideobuffer.h @@ -30,10 +30,10 @@ typedef struct _GstVdpVideoBuffer GstVdpVideoBuffer; -#define GST_TYPE_VDPAU_VIDEO_BUFFER (gst_vdp_video_buffer_get_type()) +#define GST_TYPE_VDP_VIDEO_BUFFER (gst_vdp_video_buffer_get_type()) -#define GST_IS_VDPAU_VIDEO_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VDPAU_VIDEO_BUFFER)) -#define GST_VDP_VIDEO_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VDPAU_VIDEO_BUFFER, GstVdpVideoBuffer)) +#define GST_IS_VDPAU_VIDEO_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VDP_VIDEO_BUFFER)) +#define GST_VDP_VIDEO_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VDP_VIDEO_BUFFER, GstVdpVideoBuffer)) struct _GstVdpVideoBuffer { GstBuffer buffer; -- cgit v1.2.1 From fda9c56a590659323c0e503933dea946a42bf8f6 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Tue, 5 May 2009 17:30:33 +0200 Subject: vdpaumpegdec: remove unneeded locking since we know do StateChange correctly --- sys/vdpau/gstvdpmpegdecoder.c | 12 ------------ sys/vdpau/gstvdpmpegdecoder.h | 2 -- 2 files changed, 14 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpmpegdecoder.c b/sys/vdpau/gstvdpmpegdecoder.c index 4bcbf534..eda32c60 100644 --- a/sys/vdpau/gstvdpmpegdecoder.c +++ b/sys/vdpau/gstvdpmpegdecoder.c @@ -364,12 +364,9 @@ gst_vdp_mpeg_decoder_chain (GstPad * pad, GstBuffer * buffer) mpeg_dec = GST_VDP_MPEG_DECODER (GST_OBJECT_PARENT (pad)); - g_mutex_lock (mpeg_dec->mutex); - if (G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT))) { GST_DEBUG_OBJECT (mpeg_dec, "Received discont buffer"); gst_vdp_mpeg_decoder_reset (mpeg_dec); - g_mutex_unlock (mpeg_dec->mutex); return GST_FLOW_OK; } @@ -404,7 +401,6 @@ gst_vdp_mpeg_decoder_chain (GstPad * pad, GstBuffer * buffer) if (!gst_vdp_mpeg_decoder_parse_picture (mpeg_dec, packet_start, packet_end)) { - g_mutex_unlock (mpeg_dec->mutex); return GST_FLOW_OK; } break; @@ -442,8 +438,6 @@ gst_vdp_mpeg_decoder_chain (GstPad * pad, GstBuffer * buffer) if (mpeg_dec->vdp_info.slice_count > 0) ret = gst_vdp_mpeg_decoder_decode (mpeg_dec, GST_BUFFER_TIMESTAMP (buffer)); - g_mutex_unlock (mpeg_dec->mutex); - return ret; } @@ -462,10 +456,7 @@ gst_vdp_mpeg_decoder_sink_event (GstPad * pad, GstEvent * event) { GST_DEBUG_OBJECT (mpeg_dec, "flush stop"); - g_mutex_lock (mpeg_dec->mutex); gst_vdp_mpeg_decoder_reset (mpeg_dec); - g_mutex_unlock (mpeg_dec->mutex); - res = gst_pad_push_event (dec->src, event); break; @@ -581,8 +572,6 @@ gst_vdp_mpeg_decoder_init (GstVdpMpegDecoder * mpeg_dec, mpeg_dec->decoder = VDP_INVALID_HANDLE; gst_vdp_mpeg_decoder_init_info (&mpeg_dec->vdp_info); - mpeg_dec->mutex = g_mutex_new (); - mpeg_dec->broken_gop = FALSE; mpeg_dec->adapter = gst_adapter_new (); @@ -596,7 +585,6 @@ gst_vdp_mpeg_decoder_finalize (GObject * object) { GstVdpMpegDecoder *mpeg_dec = (GstVdpMpegDecoder *) object; - g_mutex_free (mpeg_dec->mutex); g_object_unref (mpeg_dec->adapter); } diff --git a/sys/vdpau/gstvdpmpegdecoder.h b/sys/vdpau/gstvdpmpegdecoder.h index 57ab66ab..06bed84b 100644 --- a/sys/vdpau/gstvdpmpegdecoder.h +++ b/sys/vdpau/gstvdpmpegdecoder.h @@ -47,8 +47,6 @@ struct _GstVdpMpegDecoder VdpPictureInfoMPEG1Or2 vdp_info; GstBuffer *f_buffer; GstBuffer *b_buffer; - - GMutex *mutex; gboolean broken_gop; -- cgit v1.2.1 From e416f5f5e095300d41d7bd22cdc517df29924bf4 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Tue, 5 May 2009 18:37:50 +0200 Subject: vdpaumpegdec: set correct timestamps --- sys/vdpau/gstvdpmpegdecoder.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpmpegdecoder.c b/sys/vdpau/gstvdpmpegdecoder.c index eda32c60..838b4e5a 100644 --- a/sys/vdpau/gstvdpmpegdecoder.c +++ b/sys/vdpau/gstvdpmpegdecoder.c @@ -163,7 +163,6 @@ gst_vdp_mpeg_decoder_decode (GstVdpMpegDecoder * mpeg_dec, if (mpeg_dec->vdp_info.picture_coding_type != B_FRAME) { if (mpeg_dec->vdp_info.backward_reference != VDP_INVALID_HANDLE) { - GST_BUFFER_TIMESTAMP (mpeg_dec->b_buffer) = timestamp; gst_buffer_ref (mpeg_dec->b_buffer); gst_vdp_decoder_push_video_buffer (dec, GST_VDP_VIDEO_BUFFER (mpeg_dec->b_buffer)); @@ -183,6 +182,7 @@ gst_vdp_mpeg_decoder_decode (GstVdpMpegDecoder * mpeg_dec, outbuf = gst_vdp_video_buffer_new (dec->device, VDP_CHROMA_TYPE_420, dec->width, dec->height); + GST_BUFFER_TIMESTAMP (outbuf) = timestamp; if (mpeg_dec->vdp_info.forward_reference != VDP_INVALID_HANDLE) gst_vdp_video_buffer_add_reference (outbuf, GST_VDP_VIDEO_BUFFER (mpeg_dec->f_buffer)); @@ -215,7 +215,6 @@ gst_vdp_mpeg_decoder_decode (GstVdpMpegDecoder * mpeg_dec, } if (mpeg_dec->vdp_info.picture_coding_type == B_FRAME) { - GST_BUFFER_TIMESTAMP (outbuf) = timestamp; gst_vdp_decoder_push_video_buffer (dec, GST_VDP_VIDEO_BUFFER (outbuf)); } else { mpeg_dec->vdp_info.backward_reference = surface; -- cgit v1.2.1 From 42d90ddfa3b25222ed9b37d7e0ba2030715ee8be Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Tue, 5 May 2009 18:45:07 +0200 Subject: vdpaumpegdec: don't add forward_reference if the frame is an I_FRAME --- sys/vdpau/gstvdpmpegdecoder.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpmpegdecoder.c b/sys/vdpau/gstvdpmpegdecoder.c index 838b4e5a..cf8bfe54 100644 --- a/sys/vdpau/gstvdpmpegdecoder.c +++ b/sys/vdpau/gstvdpmpegdecoder.c @@ -183,7 +183,8 @@ gst_vdp_mpeg_decoder_decode (GstVdpMpegDecoder * mpeg_dec, outbuf = gst_vdp_video_buffer_new (dec->device, VDP_CHROMA_TYPE_420, dec->width, dec->height); GST_BUFFER_TIMESTAMP (outbuf) = timestamp; - if (mpeg_dec->vdp_info.forward_reference != VDP_INVALID_HANDLE) + if (mpeg_dec->vdp_info.forward_reference != VDP_INVALID_HANDLE && + mpeg_dec->vdp_info.picture_coding_type != I_FRAME) gst_vdp_video_buffer_add_reference (outbuf, GST_VDP_VIDEO_BUFFER (mpeg_dec->f_buffer)); if (mpeg_dec->vdp_info.backward_reference != VDP_INVALID_HANDLE) -- cgit v1.2.1 From 616038423f2a43091fd9e889435751860b009599 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Tue, 5 May 2009 18:54:31 +0200 Subject: vdpaumpegdec: fixup timestamping of outgoing buffers --- sys/vdpau/gstvdpdecoder.c | 11 +++++++---- sys/vdpau/gstvdpdecoder.h | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpdecoder.c b/sys/vdpau/gstvdpdecoder.c index 2b0c888e..12ab6cfc 100644 --- a/sys/vdpau/gstvdpdecoder.c +++ b/sys/vdpau/gstvdpdecoder.c @@ -65,13 +65,16 @@ gst_vdp_decoder_push_video_buffer (GstVdpDecoder * dec, GstVdpVideoBuffer * buffer) { if (GST_BUFFER_TIMESTAMP (buffer) == GST_CLOCK_TIME_NONE) { - GST_BUFFER_TIMESTAMP (buffer) = - gst_util_uint64_scale_int (GST_SECOND * dec->frame_nr, + GST_BUFFER_TIMESTAMP (buffer) = dec->time + + gst_util_uint64_scale_int (GST_SECOND, dec->framerate_denominator, dec->framerate_numerator); - dec->frame_nr++; } gst_buffer_set_caps (GST_BUFFER (buffer), GST_PAD_CAPS (dec->src)); + GST_DEBUG_OBJECT (dec, "Pushin buffer with timestamp: %" GST_TIME_FORMAT, + GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer))); + dec->time = GST_BUFFER_TIMESTAMP (buffer); + return gst_pad_push (dec->src, GST_BUFFER (buffer)); } @@ -173,7 +176,7 @@ gst_vdp_decoder_init (GstVdpDecoder * dec, GstVdpDecoderClass * klass) dec->framerate_numerator = 0; dec->framerate_denominator = 0; - dec->frame_nr = 0; + dec->time = 0; dec->src = gst_pad_new_from_static_template (&src_template, "src"); gst_element_add_pad (GST_ELEMENT (dec), dec->src); diff --git a/sys/vdpau/gstvdpdecoder.h b/sys/vdpau/gstvdpdecoder.h index ae53657c..f20db20c 100644 --- a/sys/vdpau/gstvdpdecoder.h +++ b/sys/vdpau/gstvdpdecoder.h @@ -52,7 +52,7 @@ struct _GstVdpDecoder { gint framerate_numerator, framerate_denominator; guint32 format; - gint frame_nr; + GstClockTime time; }; struct _GstVdpDecoderClass { -- cgit v1.2.1 From f4fda3f617fad6e09d3ca66a25ebb9f67ab302f5 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Tue, 5 May 2009 23:07:06 +0200 Subject: vdpaumpegdec: fix small typo in debug print --- sys/vdpau/gstvdpdecoder.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpdecoder.c b/sys/vdpau/gstvdpdecoder.c index 12ab6cfc..b6a28cc7 100644 --- a/sys/vdpau/gstvdpdecoder.c +++ b/sys/vdpau/gstvdpdecoder.c @@ -71,7 +71,7 @@ gst_vdp_decoder_push_video_buffer (GstVdpDecoder * dec, } gst_buffer_set_caps (GST_BUFFER (buffer), GST_PAD_CAPS (dec->src)); - GST_DEBUG_OBJECT (dec, "Pushin buffer with timestamp: %" GST_TIME_FORMAT, + GST_DEBUG_OBJECT (dec, "Pushing buffer with timestamp: %" GST_TIME_FORMAT, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer))); dec->time = GST_BUFFER_TIMESTAMP (buffer); -- cgit v1.2.1 From c7c60ad02931019bd5d50f2a01852f63364868b2 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Tue, 5 May 2009 23:08:51 +0200 Subject: vdpaumpegdec: remove unnused GstVdpBFrame struct --- sys/vdpau/gstvdpmpegdecoder.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpmpegdecoder.c b/sys/vdpau/gstvdpmpegdecoder.c index cf8bfe54..680a5496 100644 --- a/sys/vdpau/gstvdpmpegdecoder.c +++ b/sys/vdpau/gstvdpmpegdecoder.c @@ -138,12 +138,6 @@ gst_vdp_mpeg_decoder_set_caps (GstVdpDecoder * dec, GstCaps * caps) return TRUE; } -typedef struct -{ - GstBuffer *buffer; - VdpPictureInfoMPEG1Or2 vdp_info; -} GstVdpBFrame; - static GstFlowReturn gst_vdp_mpeg_decoder_decode (GstVdpMpegDecoder * mpeg_dec, GstClockTime timestamp) -- cgit v1.2.1 From 0ffaf06a9ab7dd780a85f0072e3d3571a5e8639e Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Tue, 5 May 2009 23:13:25 +0200 Subject: vdpaumpegdec: small code cleanup --- sys/vdpau/gstvdpmpegdecoder.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpmpegdecoder.c b/sys/vdpau/gstvdpmpegdecoder.c index 680a5496..fe9b3e7c 100644 --- a/sys/vdpau/gstvdpmpegdecoder.c +++ b/sys/vdpau/gstvdpmpegdecoder.c @@ -143,6 +143,7 @@ gst_vdp_mpeg_decoder_decode (GstVdpMpegDecoder * mpeg_dec, GstClockTime timestamp) { GstVdpDecoder *dec; + VdpPictureInfoMPEG1Or2 *info; GstBuffer *buffer; GstVdpVideoBuffer *outbuf; VdpVideoSurface surface; @@ -151,37 +152,37 @@ gst_vdp_mpeg_decoder_decode (GstVdpMpegDecoder * mpeg_dec, VdpStatus status; dec = GST_VDP_DECODER (mpeg_dec); + info = &mpeg_dec->vdp_info; buffer = gst_adapter_take_buffer (mpeg_dec->adapter, gst_adapter_available (mpeg_dec->adapter)); - if (mpeg_dec->vdp_info.picture_coding_type != B_FRAME) { - if (mpeg_dec->vdp_info.backward_reference != VDP_INVALID_HANDLE) { + if (info->picture_coding_type != B_FRAME) { + if (info->backward_reference != VDP_INVALID_HANDLE) { gst_buffer_ref (mpeg_dec->b_buffer); gst_vdp_decoder_push_video_buffer (dec, GST_VDP_VIDEO_BUFFER (mpeg_dec->b_buffer)); } - if (mpeg_dec->vdp_info.forward_reference != VDP_INVALID_HANDLE) { + if (info->forward_reference != VDP_INVALID_HANDLE) { gst_buffer_unref (mpeg_dec->f_buffer); - mpeg_dec->vdp_info.forward_reference = VDP_INVALID_HANDLE; + info->forward_reference = VDP_INVALID_HANDLE; } - mpeg_dec->vdp_info.forward_reference = - mpeg_dec->vdp_info.backward_reference; + info->forward_reference = info->backward_reference; mpeg_dec->f_buffer = mpeg_dec->b_buffer; - mpeg_dec->vdp_info.backward_reference = VDP_INVALID_HANDLE; + info->backward_reference = VDP_INVALID_HANDLE; } outbuf = gst_vdp_video_buffer_new (dec->device, VDP_CHROMA_TYPE_420, dec->width, dec->height); GST_BUFFER_TIMESTAMP (outbuf) = timestamp; - if (mpeg_dec->vdp_info.forward_reference != VDP_INVALID_HANDLE && - mpeg_dec->vdp_info.picture_coding_type != I_FRAME) + if (info->forward_reference != VDP_INVALID_HANDLE && + info->picture_coding_type != I_FRAME) gst_vdp_video_buffer_add_reference (outbuf, GST_VDP_VIDEO_BUFFER (mpeg_dec->f_buffer)); - if (mpeg_dec->vdp_info.backward_reference != VDP_INVALID_HANDLE) + if (info->backward_reference != VDP_INVALID_HANDLE) gst_vdp_video_buffer_add_reference (outbuf, GST_VDP_VIDEO_BUFFER (mpeg_dec->b_buffer)); @@ -194,9 +195,9 @@ gst_vdp_mpeg_decoder_decode (GstVdpMpegDecoder * mpeg_dec, vbit[0].bitstream_bytes = GST_BUFFER_SIZE (buffer); status = device->vdp_decoder_render (mpeg_dec->decoder, surface, - (VdpPictureInfo *) & mpeg_dec->vdp_info, 1, vbit); + (VdpPictureInfo *) info, 1, vbit); gst_buffer_unref (buffer); - mpeg_dec->vdp_info.slice_count = 0; + info->slice_count = 0; if (status != VDP_STATUS_OK) { GST_ELEMENT_ERROR (mpeg_dec, RESOURCE, READ, @@ -209,10 +210,10 @@ gst_vdp_mpeg_decoder_decode (GstVdpMpegDecoder * mpeg_dec, return GST_FLOW_ERROR; } - if (mpeg_dec->vdp_info.picture_coding_type == B_FRAME) { + if (info->picture_coding_type == B_FRAME) { gst_vdp_decoder_push_video_buffer (dec, GST_VDP_VIDEO_BUFFER (outbuf)); } else { - mpeg_dec->vdp_info.backward_reference = surface; + info->backward_reference = surface; mpeg_dec->b_buffer = GST_BUFFER (outbuf); } -- cgit v1.2.1 From 8e66a1783092da8c171b1d10273eda91e590e732 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Tue, 5 May 2009 23:19:56 +0200 Subject: vdpau: add debug on GstVdpDevice destroy --- sys/vdpau/gstvdpdevice.c | 2 ++ sys/vdpau/gstvdpmpegdecoder.c | 2 ++ 2 files changed, 4 insertions(+) (limited to 'sys') diff --git a/sys/vdpau/gstvdpdevice.c b/sys/vdpau/gstvdpdevice.c index ad771906..f920f973 100644 --- a/sys/vdpau/gstvdpdevice.c +++ b/sys/vdpau/gstvdpdevice.c @@ -221,6 +221,8 @@ device_destroyed_cb (gpointer data, GObject * object) GHashTableIter iter; gpointer device; + GST_DEBUG ("Removing object from hash table"); + g_hash_table_iter_init (&iter, devices_hash); while (g_hash_table_iter_next (&iter, NULL, &device)) { if (device == object) { diff --git a/sys/vdpau/gstvdpmpegdecoder.c b/sys/vdpau/gstvdpmpegdecoder.c index fe9b3e7c..006e6d41 100644 --- a/sys/vdpau/gstvdpmpegdecoder.c +++ b/sys/vdpau/gstvdpmpegdecoder.c @@ -178,10 +178,12 @@ gst_vdp_mpeg_decoder_decode (GstVdpMpegDecoder * mpeg_dec, outbuf = gst_vdp_video_buffer_new (dec->device, VDP_CHROMA_TYPE_420, dec->width, dec->height); GST_BUFFER_TIMESTAMP (outbuf) = timestamp; + if (info->forward_reference != VDP_INVALID_HANDLE && info->picture_coding_type != I_FRAME) gst_vdp_video_buffer_add_reference (outbuf, GST_VDP_VIDEO_BUFFER (mpeg_dec->f_buffer)); + if (info->backward_reference != VDP_INVALID_HANDLE) gst_vdp_video_buffer_add_reference (outbuf, GST_VDP_VIDEO_BUFFER (mpeg_dec->b_buffer)); -- cgit v1.2.1 From 426a6eaba9776157f43da280d37b81ac49cccd72 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Wed, 6 May 2009 23:07:00 +0200 Subject: vdpau: change element rank for testing purposes set mpegvideoparse rank to primary and vdpaumpegdec to primary - 1 to get vdpaumpegdec correctly plugged into playbin --- sys/vdpau/gstvdp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdp.c b/sys/vdpau/gstvdp.c index 64ebf37e..8d5be3dc 100644 --- a/sys/vdpau/gstvdp.c +++ b/sys/vdpau/gstvdp.c @@ -13,7 +13,7 @@ static gboolean vdpau_init (GstPlugin * vdpau_plugin) { gst_element_register (vdpau_plugin, "vdpaumpegdec", - GST_RANK_NONE, GST_TYPE_VDP_MPEG_DECODER); + GST_RANK_PRIMARY - 1, GST_TYPE_VDP_MPEG_DECODER); gst_element_register (vdpau_plugin, "vdpauvideoyuv", GST_RANK_PRIMARY, GST_TYPE_VDP_VIDEO_YUV); gst_element_register (vdpau_plugin, "vdpauyuvvideo", -- cgit v1.2.1 From 127765d19c268724de21ea97038e380acdefd2a2 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Thu, 4 Jun 2009 18:11:06 +0200 Subject: vdpaumpegdec: use GstBitReader to parse bitstream --- sys/vdpau/gstvdpmpegdecoder.c | 213 +++++++++++++++------ sys/vdpau/mpegutil.c | 426 +++++++++++++++++++++--------------------- sys/vdpau/mpegutil.h | 59 ++++-- 3 files changed, 405 insertions(+), 293 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpmpegdecoder.c b/sys/vdpau/gstvdpmpegdecoder.c index 006e6d41..fc7aa5a6 100644 --- a/sys/vdpau/gstvdpmpegdecoder.c +++ b/sys/vdpau/gstvdpmpegdecoder.c @@ -36,6 +36,8 @@ #endif #include +#include +#include #include #include "mpegutil.h" @@ -80,14 +82,82 @@ static void gst_vdp_mpeg_decoder_set_property (GObject * object, static void gst_vdp_mpeg_decoder_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); +guint8 * +mpeg_util_find_start_code (guint32 * sync_word, guint8 * cur, guint8 * end) +{ + guint32 code; + + if (G_UNLIKELY (cur == NULL)) + return NULL; + + code = *sync_word; + + while (cur < end) { + code <<= 8; + + if (code == 0x00000100) { + /* Reset the sync word accumulator */ + *sync_word = 0xffffffff; + return cur; + } + + /* Add the next available byte to the collected sync word */ + code |= *cur++; + } + + *sync_word = code; + return NULL; +} + +typedef struct +{ + GstBuffer *buffer; + guint8 *cur; + guint8 *end; +} GstVdpMpegPacketizer; + +static GstBuffer * +gst_vdp_mpeg_packetizer_get_next_packet (GstVdpMpegPacketizer * packetizer) +{ + guint32 sync_word = 0xffffff; + guint8 *packet_start; + guint8 *packet_end; + + if (!packetizer->cur) + return NULL; + + packet_start = packetizer->cur - 3; + packetizer->cur = packet_end = mpeg_util_find_start_code (&sync_word, + packetizer->cur, packetizer->end); + + if (packet_end) + packet_end -= 3; + else + packet_end = packetizer->end; + + return gst_buffer_create_sub (packetizer->buffer, + packet_start - GST_BUFFER_DATA (packetizer->buffer), + packet_end - packet_start); +} + +static void +gst_vdp_mpeg_packetizer_init (GstVdpMpegPacketizer * packetizer, + GstBuffer * buffer) +{ + guint32 sync_word = 0xffffffff; + + packetizer->buffer = buffer; + packetizer->end = GST_BUFFER_DATA (buffer) + GST_BUFFER_SIZE (buffer); + packetizer->cur = mpeg_util_find_start_code (&sync_word, + GST_BUFFER_DATA (buffer), packetizer->end); +} + static gboolean gst_vdp_mpeg_decoder_set_caps (GstVdpDecoder * dec, GstCaps * caps) { GstVdpMpegDecoder *mpeg_dec; GstStructure *structure; const GValue *value; - GstBuffer *codec_data; - MPEGSeqHdr hdr = { 0, }; VdpDecoderProfile profile; GstVdpDevice *device; VdpStatus status; @@ -100,25 +170,44 @@ gst_vdp_mpeg_decoder_set_caps (GstVdpDecoder * dec, GstCaps * caps) profile = VDP_DECODER_PROFILE_MPEG1; value = gst_structure_get_value (structure, "codec_data"); - codec_data = gst_value_get_buffer (value); - mpeg_util_parse_sequence_hdr (&hdr, GST_BUFFER_DATA (codec_data), - GST_BUFFER_DATA (codec_data) + GST_BUFFER_SIZE (codec_data)); - if (mpeg_dec->version != 1) { - switch (hdr.profile) { - case 5: - profile = VDP_DECODER_PROFILE_MPEG2_SIMPLE; - break; - default: - profile = VDP_DECODER_PROFILE_MPEG2_MAIN; - break; + if (value) { + GstBuffer *codec_data, *buf; + GstVdpMpegPacketizer packetizer; + + codec_data = gst_value_get_buffer (value); + gst_vdp_mpeg_packetizer_init (&packetizer, codec_data); + if ((buf = gst_vdp_mpeg_packetizer_get_next_packet (&packetizer))) { + MPEGSeqHdr hdr; + + mpeg_util_parse_sequence_hdr (&hdr, buf); + + memcpy (&mpeg_dec->vdp_info.intra_quantizer_matrix, + &hdr.intra_quantizer_matrix, 64); + memcpy (&mpeg_dec->vdp_info.non_intra_quantizer_matrix, + &hdr.non_intra_quantizer_matrix, 64); + + gst_buffer_unref (buf); + + if ((buf = gst_vdp_mpeg_packetizer_get_next_packet (&packetizer))) { + MPEGSeqExtHdr ext; + + mpeg_util_parse_sequence_extension (&ext, buf); + if (mpeg_dec->version != 1) { + switch (ext.profile) { + case 5: + profile = VDP_DECODER_PROFILE_MPEG2_SIMPLE; + break; + default: + profile = VDP_DECODER_PROFILE_MPEG2_MAIN; + break; + } + } + + gst_buffer_unref (buf); + } } } - memcpy (&mpeg_dec->vdp_info.intra_quantizer_matrix, - &hdr.intra_quantizer_matrix, 64); - memcpy (&mpeg_dec->vdp_info.non_intra_quantizer_matrix, - &hdr.non_intra_quantizer_matrix, 64); - device = dec->device; if (mpeg_dec->decoder != VDP_INVALID_HANDLE) { @@ -224,7 +313,7 @@ gst_vdp_mpeg_decoder_decode (GstVdpMpegDecoder * mpeg_dec, static gboolean gst_vdp_mpeg_decoder_parse_picture_coding (GstVdpMpegDecoder * mpeg_dec, - guint8 * data, guint8 * end) + GstBuffer * buffer) { GstVdpDecoder *dec; MPEGPictureExt pic_ext; @@ -233,7 +322,7 @@ gst_vdp_mpeg_decoder_parse_picture_coding (GstVdpMpegDecoder * mpeg_dec, dec = GST_VDP_DECODER (mpeg_dec); info = &mpeg_dec->vdp_info; - if (!mpeg_util_parse_picture_coding_extension (&pic_ext, data, end)) + if (!mpeg_util_parse_picture_coding_extension (&pic_ext, buffer)) return FALSE; memcpy (&mpeg_dec->vdp_info.f_code, &pic_ext.f_code, 4); @@ -252,16 +341,17 @@ gst_vdp_mpeg_decoder_parse_picture_coding (GstVdpMpegDecoder * mpeg_dec, static gboolean gst_vdp_mpeg_decoder_parse_sequence (GstVdpMpegDecoder * mpeg_dec, - guint8 * data, guint8 * end) + GstBuffer * buffer) { GstVdpDecoder *dec; MPEGSeqHdr hdr; dec = GST_VDP_DECODER (mpeg_dec); - if (!mpeg_util_parse_sequence_hdr (&hdr, data, end)) + if (!mpeg_util_parse_sequence_hdr (&hdr, buffer)) return FALSE; + g_debug ("här"); memcpy (&mpeg_dec->vdp_info.intra_quantizer_matrix, &hdr.intra_quantizer_matrix, 64); memcpy (&mpeg_dec->vdp_info.non_intra_quantizer_matrix, @@ -272,14 +362,14 @@ gst_vdp_mpeg_decoder_parse_sequence (GstVdpMpegDecoder * mpeg_dec, static gboolean gst_vdp_mpeg_decoder_parse_picture (GstVdpMpegDecoder * mpeg_dec, - guint8 * data, guint8 * end) + GstBuffer * buffer) { GstVdpDecoder *dec; MPEGPictureHdr pic_hdr; dec = GST_VDP_DECODER (mpeg_dec); - if (!mpeg_util_parse_picture_hdr (&pic_hdr, data, end)) + if (!mpeg_util_parse_picture_hdr (&pic_hdr, buffer)) return FALSE; if (pic_hdr.pic_type != I_FRAME @@ -309,12 +399,12 @@ gst_vdp_mpeg_decoder_parse_picture (GstVdpMpegDecoder * mpeg_dec, } static gboolean -gst_vdp_mpeg_decoder_parse_gop (GstVdpMpegDecoder * mpeg_dec, guint8 * data, - guint8 * end) +gst_vdp_mpeg_decoder_parse_gop (GstVdpMpegDecoder * mpeg_dec, + GstBuffer * buffer) { - MPEGPictureGOP gop; + MPEGGop gop; - if (!mpeg_util_parse_picture_gop (&gop, data, end)) + if (!mpeg_util_parse_gop (&gop, buffer)) return FALSE; mpeg_dec->broken_gop = gop.broken_gop; @@ -324,11 +414,11 @@ gst_vdp_mpeg_decoder_parse_gop (GstVdpMpegDecoder * mpeg_dec, guint8 * data, static gboolean gst_vdp_mpeg_decoder_parse_quant_matrix (GstVdpMpegDecoder * mpeg_dec, - guint8 * data, guint8 * end) + GstBuffer * buffer) { MPEGQuantMatrix qm; - if (!mpeg_util_parse_quant_matrix (&qm, data, end)) + if (!mpeg_util_parse_quant_matrix (&qm, buffer)) return FALSE; memcpy (&mpeg_dec->vdp_info.intra_quantizer_matrix, @@ -355,8 +445,8 @@ static GstFlowReturn gst_vdp_mpeg_decoder_chain (GstPad * pad, GstBuffer * buffer) { GstVdpMpegDecoder *mpeg_dec; - guint8 *data, *end; - guint32 sync_word = 0xffffffff; + GstVdpMpegPacketizer packetizer; + GstBuffer *buf; GstFlowReturn ret = GST_FLOW_OK; mpeg_dec = GST_VDP_MPEG_DECODER (GST_OBJECT_PARENT (pad)); @@ -367,69 +457,70 @@ gst_vdp_mpeg_decoder_chain (GstPad * pad, GstBuffer * buffer) return GST_FLOW_OK; } - data = GST_BUFFER_DATA (buffer); - end = GST_BUFFER_DATA (buffer) + GST_BUFFER_SIZE (buffer); + gst_vdp_mpeg_packetizer_init (&packetizer, buffer); + while ((buf = gst_vdp_mpeg_packetizer_get_next_packet (&packetizer))) { + GstBitReader b_reader = GST_BIT_READER_INIT_FROM_BUFFER (buf); + guint32 sync_code; + guint8 start_code; - while ((data = mpeg_util_find_start_code (&sync_word, data, end))) { - guint8 *packet_start; - guint8 *packet_end; + /* skip sync_code */ + gst_bit_reader_get_bits_uint32 (&b_reader, &sync_code, 8 * 3); - packet_start = data - 3; - packet_end = mpeg_util_find_start_code (&sync_word, data, end); - if (packet_end) - packet_end -= 3; - else - packet_end = end; - - if (data[0] >= MPEG_PACKET_SLICE_MIN && data[0] <= MPEG_PACKET_SLICE_MAX) { - GstBuffer *subbuf; + /* start_code */ + gst_bit_reader_get_bits_uint8 (&b_reader, &start_code, 8); + if (start_code >= MPEG_PACKET_SLICE_MIN + && start_code <= MPEG_PACKET_SLICE_MAX) { GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_SLICE"); - subbuf = - gst_buffer_create_sub (buffer, - packet_start - GST_BUFFER_DATA (buffer), packet_end - packet_start); - gst_adapter_push (mpeg_dec->adapter, subbuf); + + gst_buffer_ref (buf); + gst_adapter_push (mpeg_dec->adapter, buf); mpeg_dec->vdp_info.slice_count++; } - switch (data[0]) { + switch (start_code) { case MPEG_PACKET_PICTURE: GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_PICTURE"); - if (!gst_vdp_mpeg_decoder_parse_picture (mpeg_dec, packet_start, - packet_end)) { + if (!gst_vdp_mpeg_decoder_parse_picture (mpeg_dec, buf)) { return GST_FLOW_OK; } break; case MPEG_PACKET_SEQUENCE: GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_SEQUENCE"); - gst_vdp_mpeg_decoder_parse_sequence (mpeg_dec, packet_start, - packet_end); + gst_vdp_mpeg_decoder_parse_sequence (mpeg_dec, buf); break; case MPEG_PACKET_EXTENSION: + { + guint8 ext_code; + GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_EXTENSION"); - switch (read_bits (data + 1, 0, 4)) { + + /* ext_code */ + gst_bit_reader_get_bits_uint8 (&b_reader, &ext_code, 4); + switch (ext_code) { case MPEG_PACKET_EXT_PICTURE_CODING: GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_EXT_PICTURE_CODING"); - gst_vdp_mpeg_decoder_parse_picture_coding (mpeg_dec, packet_start, - packet_end); + gst_vdp_mpeg_decoder_parse_picture_coding (mpeg_dec, buf); break; case MPEG_PACKET_EXT_QUANT_MATRIX: GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_EXT_QUANT_MATRIX"); - gst_vdp_mpeg_decoder_parse_quant_matrix (mpeg_dec, packet_start, - packet_end); + gst_vdp_mpeg_decoder_parse_quant_matrix (mpeg_dec, buf); break; default: break; } break; + } case MPEG_PACKET_GOP: GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_GOP"); - gst_vdp_mpeg_decoder_parse_gop (mpeg_dec, packet_start, packet_end); + gst_vdp_mpeg_decoder_parse_gop (mpeg_dec, buf); break; default: break; } + + gst_buffer_unref (buf); } if (mpeg_dec->vdp_info.slice_count > 0) diff --git a/sys/vdpau/mpegutil.c b/sys/vdpau/mpegutil.c index 08ae5c53..c35ad9fb 100644 --- a/sys/vdpau/mpegutil.c +++ b/sys/vdpau/mpegutil.c @@ -18,6 +18,7 @@ * Boston, MA 02111-1307, USA. */ +#include #include #include "mpegutil.h" @@ -53,58 +54,6 @@ guint8 mpeg2_scan[64] = { 53, 60, 61, 54, 47, 55, 62, 63 }; -guint8 bits[] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }; - -guint32 -read_bits (guint8 * buf, gint start_bit, gint n_bits) -{ - gint i; - guint32 ret = 0x00; - - buf += start_bit / 8; - start_bit %= 8; - - for (i = 0; i < n_bits; i++) { - guint32 tmp; - - tmp = ((*buf & bits[start_bit]) >> (7 - start_bit)); - ret = (ret | (tmp << (n_bits - i - 1))); - if (++start_bit == 8) { - buf += 1; - start_bit = 0; - } - } - - return ret; -} - -guint8 * -mpeg_util_find_start_code (guint32 * sync_word, guint8 * cur, guint8 * end) -{ - guint32 code; - - if (G_UNLIKELY (cur == NULL)) - return NULL; - - code = *sync_word; - - while (cur < end) { - code <<= 8; - - if (code == 0x00000100) { - /* Reset the sync word accumulator */ - *sync_word = 0xffffffff; - return cur; - } - - /* Add the next available byte to the collected sync word */ - code |= *cur++; - } - - *sync_word = code; - return NULL; -} - static void set_fps_from_code (MPEGSeqHdr * hdr, guint8 fps_code) { @@ -150,157 +99,169 @@ set_par_from_dar (MPEGSeqHdr * hdr, guint8 asr_code) } } -static gboolean -mpeg_util_parse_extension_packet (MPEGSeqHdr * hdr, guint8 * data, guint8 * end) +gboolean +mpeg_util_parse_sequence_extension (MPEGSeqExtHdr * hdr, GstBuffer * buffer) { - guint8 ext_code; + GstBitReader reader = GST_BIT_READER_INIT_FROM_BUFFER (buffer);; - if (G_UNLIKELY (data >= end)) - return FALSE; /* short extension packet */ + /* skip sync word */ + if (!gst_bit_reader_skip (&reader, 8 * 4)) + return FALSE; - ext_code = read_bits (data, 0, 4); + /* skip extension code */ + if (!gst_bit_reader_skip (&reader, 4)) + return FALSE; - switch (ext_code) { - case MPEG_PACKET_EXT_SEQUENCE: - { - /* Parse a Sequence Extension */ - guint8 horiz_size_ext, vert_size_ext; - guint8 fps_n_ext, fps_d_ext; + /* skip profile and level escape bit */ + if (!gst_bit_reader_skip (&reader, 1)) + return FALSE; - if (G_UNLIKELY ((end - data) < 6)) - /* need at least 10 bytes, minus 4 for the start code 000001b5 */ - return FALSE; + if (!gst_bit_reader_get_bits_uint8 (&reader, &hdr->profile, 3)) + return FALSE; + if (!gst_bit_reader_get_bits_uint8 (&reader, &hdr->level, 4)) + return FALSE; - hdr->profile = read_bits (data, 7, 3); + /* progressive */ + if (!gst_bit_reader_get_bits_uint8 (&reader, &hdr->progressive, 1)) + return FALSE; + + /* chroma format */ + if (!gst_bit_reader_get_bits_uint8 (&reader, &hdr->chroma_format, 2)) + return FALSE; - horiz_size_ext = read_bits (data + 1, 7, 2); - vert_size_ext = read_bits (data + 2, 1, 2); + /* resolution extension */ + if (!gst_bit_reader_get_bits_uint8 (&reader, &hdr->horiz_size_ext, 2)) + return FALSE; + if (!gst_bit_reader_get_bits_uint8 (&reader, &hdr->vert_size_ext, 2)) + return FALSE; - fps_n_ext = read_bits (data + 5, 1, 2); - fps_d_ext = read_bits (data + 5, 3, 5); + /* skip to framerate extension */ + if (!gst_bit_reader_skip (&reader, 22)) + return FALSE; - hdr->fps_n *= (fps_n_ext + 1); - hdr->fps_d *= (fps_d_ext + 1); - hdr->width += (horiz_size_ext << 12); - hdr->height += (vert_size_ext << 12); - break; - } - default: - break; - } + /* framerate extension */ + if (!gst_bit_reader_get_bits_uint8 (&reader, &hdr->fps_n_ext, 2)) + return FALSE; + if (!gst_bit_reader_get_bits_uint8 (&reader, &hdr->fps_d_ext, 2)) + return FALSE; return TRUE; } gboolean -mpeg_util_parse_sequence_hdr (MPEGSeqHdr * hdr, guint8 * data, guint8 * end) +mpeg_util_parse_sequence_hdr (MPEGSeqHdr * hdr, GstBuffer * buffer) { - guint32 code; - guint8 dar_idx, fps_idx; - guint32 sync_word = 0xffffffff; - gboolean constrained_flag; - gboolean load_intra_flag; - gboolean load_non_intra_flag; - gint i; + GstBitReader reader = GST_BIT_READER_INIT_FROM_BUFFER (buffer); + guint8 dar_idx, par_idx; + guint8 load_intra_flag, load_non_intra_flag; - if (G_UNLIKELY ((end - data) < 12)) - return FALSE; /* Too small to be a sequence header */ + /* skip sync word */ + if (!gst_bit_reader_skip (&reader, 8 * 4)) + return FALSE; - code = GST_READ_UINT32_BE (data); - if (G_UNLIKELY (code != (0x00000100 | MPEG_PACKET_SEQUENCE))) + /* resolution */ + if (!gst_bit_reader_get_bits_uint16 (&reader, &hdr->width, 12)) + return FALSE; + if (!gst_bit_reader_get_bits_uint16 (&reader, &hdr->height, 12)) return FALSE; - /* Skip the sync word */ - data += 4; + /* aspect ratio */ + if (!gst_bit_reader_get_bits_uint8 (&reader, &dar_idx, 4)) + return FALSE; + set_par_from_dar (hdr, dar_idx); - /* Parse the MPEG 1 bits */ - hdr->mpeg_version = 1; + /* framerate */ + if (!gst_bit_reader_get_bits_uint8 (&reader, &par_idx, 4)) + return FALSE; + set_fps_from_code (hdr, par_idx); - code = GST_READ_UINT32_BE (data); - hdr->width = read_bits (data, 0, 12); - hdr->height = read_bits (data + 1, 4, 12); + /* bitrate */ + if (!gst_bit_reader_get_bits_uint32 (&reader, &hdr->bitrate, 18)) + return FALSE; - dar_idx = read_bits (data + 3, 0, 4); - set_par_from_dar (hdr, dar_idx); - fps_idx = read_bits (data + 3, 4, 4); - set_fps_from_code (hdr, fps_idx); + if (!gst_bit_reader_skip (&reader, 1)) + return FALSE; + + /* VBV buffer size */ + if (!gst_bit_reader_get_bits_uint16 (&reader, &hdr->vbv_buffer, 10)) + return FALSE; - constrained_flag = read_bits (data + 7, 5, 1); + /* constrained parameters flag */ + if (!gst_bit_reader_get_bits_uint8 (&reader, + &hdr->constrained_parameters_flag, 1)) + return FALSE; - load_intra_flag = read_bits (data + 7, 6, 1); + /* intra quantizer matrix */ + if (!gst_bit_reader_get_bits_uint8 (&reader, &load_intra_flag, 1)) + return FALSE; if (load_intra_flag) { - if (G_UNLIKELY ((end - data) < 64)) - return FALSE; + gint i; for (i = 0; i < 64; i++) { - hdr->intra_quantizer_matrix[mpeg2_scan[i]] = - read_bits (data + 7 + i, 7, 8); + if (!gst_bit_reader_get_bits_uint8 (&reader, + &hdr->intra_quantizer_matrix[mpeg2_scan[i]], 8)) + return FALSE; } - data += 64; - } else memcpy (hdr->intra_quantizer_matrix, default_intra_quantizer_matrix, 64); - load_non_intra_flag = read_bits (data + 7, 7 + load_intra_flag, 1); + /* non intra quantizer matrix */ + if (!gst_bit_reader_get_bits_uint8 (&reader, &load_non_intra_flag, 1)) + return FALSE; if (load_non_intra_flag) { - if (G_UNLIKELY ((end - data) < 64)) - return FALSE; - for (i = 0; i < 64; i++) - hdr->non_intra_quantizer_matrix[mpeg2_scan[i]] = - read_bits (data + 8 + i, 1 + load_intra_flag, 8); - } else - memset (hdr->non_intra_quantizer_matrix, 16, 64); - - /* Advance past the rest of the MPEG-1 header */ - data += 8; - - /* Read MPEG-2 sequence extensions */ - data = mpeg_util_find_start_code (&sync_word, data, end); - while (data != NULL) { - if (G_UNLIKELY (data >= end)) - return FALSE; - - /* data points at the last byte of the start code */ - if (data[0] == MPEG_PACKET_EXTENSION) { - if (!mpeg_util_parse_extension_packet (hdr, data + 1, end)) + gint i; + for (i = 0; i < 64; i++) { + if (!gst_bit_reader_get_bits_uint8 (&reader, + &hdr->non_intra_quantizer_matrix[mpeg2_scan[i]], 8)) return FALSE; - - hdr->mpeg_version = 2; } - data = mpeg_util_find_start_code (&sync_word, data, end); - } + } else + memset (hdr->non_intra_quantizer_matrix, 16, 64); return TRUE; } gboolean -mpeg_util_parse_picture_hdr (MPEGPictureHdr * hdr, guint8 * data, guint8 * end) +mpeg_util_parse_picture_hdr (MPEGPictureHdr * hdr, GstBuffer * buffer) { - guint32 code; + GstBitReader reader = GST_BIT_READER_INIT_FROM_BUFFER (buffer); - if (G_UNLIKELY ((end - data) < 8)) - return FALSE; /* Packet too small */ + /* skip sync word */ + if (!gst_bit_reader_skip (&reader, 8 * 4)) + return FALSE; - code = GST_READ_UINT32_BE (data); - if (G_UNLIKELY (code != (0x00000100 | MPEG_PACKET_PICTURE))) + /* temperal sequence number */ + if (!gst_bit_reader_get_bits_uint16 (&reader, &hdr->tsn, 10)) return FALSE; - /* Skip the sync word */ - data += 4; + /* frame type */ + if (!gst_bit_reader_get_bits_uint8 (&reader, &hdr->pic_type, 3)) + return FALSE; - hdr->pic_type = (data[1] >> 3) & 0x07; if (hdr->pic_type == 0 || hdr->pic_type > 4) return FALSE; /* Corrupted picture packet */ + /* VBV delay */ + if (!gst_bit_reader_get_bits_uint16 (&reader, &hdr->vbv_delay, 16)) + return FALSE; + if (hdr->pic_type == P_FRAME || hdr->pic_type == B_FRAME) { - if (G_UNLIKELY ((end - data) < 5)) - return FALSE; /* packet too small */ - hdr->full_pel_forward_vector = read_bits (data + 3, 5, 1); - hdr->f_code[0][0] = hdr->f_code[0][1] = read_bits (data + 3, 6, 3); + if (!gst_bit_reader_get_bits_uint8 (&reader, &hdr->full_pel_forward_vector, + 1)) + return FALSE; + + if (!gst_bit_reader_get_bits_uint8 (&reader, &hdr->f_code[0][0], 3)) + return FALSE; + hdr->f_code[0][1] = hdr->f_code[0][0]; if (hdr->pic_type == B_FRAME) { - hdr->full_pel_backward_vector = read_bits (data + 4, 1, 1); - hdr->f_code[1][0] = hdr->f_code[1][1] = read_bits (data + 4, 2, 3); + if (!gst_bit_reader_get_bits_uint8 (&reader, + &hdr->full_pel_backward_vector, 1)) + return FALSE; + + if (!gst_bit_reader_get_bits_uint8 (&reader, &hdr->f_code[1][0], 3)) + return FALSE; + hdr->f_code[1][1] = hdr->f_code[1][0]; } else hdr->full_pel_backward_vector = 0; } else { @@ -312,104 +273,143 @@ mpeg_util_parse_picture_hdr (MPEGPictureHdr * hdr, guint8 * data, guint8 * end) } gboolean -mpeg_util_parse_picture_coding_extension (MPEGPictureExt * ext, guint8 * data, - guint8 * end) +mpeg_util_parse_picture_coding_extension (MPEGPictureExt * ext, + GstBuffer * buffer) { - guint32 code; + GstBitReader reader = GST_BIT_READER_INIT_FROM_BUFFER (buffer); - if (G_UNLIKELY ((end - data) < 9)) - return FALSE; /* Packet too small */ + /* skip sync word */ + if (!gst_bit_reader_skip (&reader, 8 * 4)) + return FALSE; - code = GST_READ_UINT32_BE (data); + /* skip extension code */ + if (!gst_bit_reader_skip (&reader, 4)) + return FALSE; - if (G_UNLIKELY (G_UNLIKELY (code != (0x00000100 | MPEG_PACKET_EXTENSION)))) + /* f_code */ + if (!gst_bit_reader_get_bits_uint8 (&reader, &ext->f_code[0][0], 4)) + return FALSE; + if (!gst_bit_reader_get_bits_uint8 (&reader, &ext->f_code[0][1], 4)) + return FALSE; + if (!gst_bit_reader_get_bits_uint8 (&reader, &ext->f_code[1][0], 4)) + return FALSE; + if (!gst_bit_reader_get_bits_uint8 (&reader, &ext->f_code[1][1], 4)) return FALSE; - /* Skip the sync word */ - data += 4; + /* intra DC precision */ + if (!gst_bit_reader_get_bits_uint8 (&reader, &ext->intra_dc_precision, 2)) + return FALSE; - ext->f_code[0][0] = read_bits (data, 4, 4); - ext->f_code[0][1] = read_bits (data + 1, 0, 4); - ext->f_code[1][0] = read_bits (data + 1, 4, 4); - ext->f_code[1][1] = read_bits (data + 2, 0, 4); + /* picture structure */ + if (!gst_bit_reader_get_bits_uint8 (&reader, &ext->picture_structure, 2)) + return FALSE; - ext->intra_dc_precision = read_bits (data + 2, 4, 2); - ext->picture_structure = read_bits (data + 2, 6, 2); - ext->top_field_first = read_bits (data + 3, 0, 1); - ext->frame_pred_frame_dct = read_bits (data + 3, 1, 1); - ext->concealment_motion_vectors = read_bits (data + 3, 2, 1); - ext->q_scale_type = read_bits (data + 3, 3, 1); - ext->intra_vlc_format = read_bits (data + 3, 4, 1); - ext->alternate_scan = read_bits (data + 3, 5, 1); + /* top field first */ + if (!gst_bit_reader_get_bits_uint8 (&reader, &ext->top_field_first, 1)) + return FALSE; + + /* frame pred frame dct */ + if (!gst_bit_reader_get_bits_uint8 (&reader, &ext->frame_pred_frame_dct, 1)) + return FALSE; + + /* concealment motion vectors */ + if (!gst_bit_reader_get_bits_uint8 (&reader, &ext->concealment_motion_vectors, + 1)) + return FALSE; + + /* q scale type */ + if (!gst_bit_reader_get_bits_uint8 (&reader, &ext->q_scale_type, 1)) + return FALSE; + + /* intra vlc format */ + if (!gst_bit_reader_get_bits_uint8 (&reader, &ext->intra_vlc_format, 1)) + return FALSE; + + /* alternate scan */ + if (!gst_bit_reader_get_bits_uint8 (&reader, &ext->alternate_scan, 1)) + return FALSE; + + /* repeat first field */ + if (!gst_bit_reader_get_bits_uint8 (&reader, &ext->repeat_first_field, 1)) + return FALSE; return TRUE; } gboolean -mpeg_util_parse_picture_gop (MPEGPictureGOP * gop, guint8 * data, guint8 * end) +mpeg_util_parse_gop (MPEGGop * gop, GstBuffer * buffer) { - guint32 code; + GstBitReader reader = GST_BIT_READER_INIT_FROM_BUFFER (buffer); - if (G_UNLIKELY ((end - data) < 8)) - return FALSE; /* Packet too small */ + /* skip sync word */ + if (!gst_bit_reader_skip (&reader, 8 * 4)) + return FALSE; - code = GST_READ_UINT32_BE (data); + if (!gst_bit_reader_get_bits_uint8 (&reader, &gop->drop_frame_flag, 1)) + return FALSE; - if (G_UNLIKELY (G_UNLIKELY (code != (0x00000100 | MPEG_PACKET_GOP)))) + if (!gst_bit_reader_get_bits_uint8 (&reader, &gop->hour, 5)) return FALSE; - /* Skip the sync word */ - data += 4; + if (!gst_bit_reader_get_bits_uint8 (&reader, &gop->minute, 6)) + return FALSE; + + /* skip unused bit */ + if (!gst_bit_reader_skip (&reader, 1)) + return FALSE; - gop->drop_frame_flag = read_bits (data, 0, 1); + if (!gst_bit_reader_get_bits_uint8 (&reader, &gop->second, 6)) + return FALSE; - gop->hour = read_bits (data, 1, 5); - gop->minute = read_bits (data, 6, 6); - gop->second = read_bits (data + 1, 4, 6); - gop->frame = read_bits (data + 2, 3, 6); + if (!gst_bit_reader_get_bits_uint8 (&reader, &gop->frame, 6)) + return FALSE; + + if (!gst_bit_reader_get_bits_uint8 (&reader, &gop->closed_gop, 1)) + return FALSE; - gop->closed_gop = read_bits (data + 3, 1, 1); - gop->broken_gop = read_bits (data + 3, 2, 1); + if (!gst_bit_reader_get_bits_uint8 (&reader, &gop->broken_gop, 1)) + return FALSE; return TRUE; } gboolean -mpeg_util_parse_quant_matrix (MPEGQuantMatrix * qm, guint8 * data, guint8 * end) +mpeg_util_parse_quant_matrix (MPEGQuantMatrix * qm, GstBuffer * buffer) { - guint32 code; - gboolean load_intra_flag, load_non_intra_flag; - gint i; - - if (G_UNLIKELY ((end - data) < 5)) - return FALSE; /* Packet too small */ + GstBitReader reader = GST_BIT_READER_INIT_FROM_BUFFER (buffer); + guint8 load_intra_flag, load_non_intra_flag; - code = GST_READ_UINT32_BE (data); - - if (G_UNLIKELY (G_UNLIKELY (code != (0x00000100 | MPEG_PACKET_EXTENSION)))) + /* skip sync word */ + if (!gst_bit_reader_skip (&reader, 8 * 4)) return FALSE; - /* Skip the sync word */ - data += 4; + /* skip extension code */ + if (!gst_bit_reader_skip (&reader, 4)) + return FALSE; - load_intra_flag = read_bits (data, 4, 1); + /* intra quantizer matrix */ + if (!gst_bit_reader_get_bits_uint8 (&reader, &load_intra_flag, 1)) + return FALSE; if (load_intra_flag) { - if (G_UNLIKELY ((end - data) < 64)) - return FALSE; - for (i = 0; i < 64; i++) - qm->intra_quantizer_matrix[mpeg2_scan[i]] = read_bits (data + i, 5, 8); - - data += 64; + gint i; + for (i = 0; i < 64; i++) { + if (!gst_bit_reader_get_bits_uint8 (&reader, + &qm->intra_quantizer_matrix[mpeg2_scan[i]], 8)) + return FALSE; + } } else memcpy (qm->intra_quantizer_matrix, default_intra_quantizer_matrix, 64); - load_non_intra_flag = read_bits (data, 5 + load_intra_flag, 1); + /* non intra quantizer matrix */ + if (!gst_bit_reader_get_bits_uint8 (&reader, &load_non_intra_flag, 1)) + return FALSE; if (load_non_intra_flag) { - if (G_UNLIKELY ((end - data) < 64)) - return FALSE; - for (i = 0; i < 64; i++) - qm->non_intra_quantizer_matrix[mpeg2_scan[i]] = - read_bits (data + i, 6 + load_intra_flag, 8); + gint i; + for (i = 0; i < 64; i++) { + if (!gst_bit_reader_get_bits_uint8 (&reader, + &qm->non_intra_quantizer_matrix[mpeg2_scan[i]], 8)) + return FALSE; + } } else memset (qm->non_intra_quantizer_matrix, 16, 64); diff --git a/sys/vdpau/mpegutil.h b/sys/vdpau/mpegutil.h index 43f34a59..4e5a656a 100644 --- a/sys/vdpau/mpegutil.h +++ b/sys/vdpau/mpegutil.h @@ -24,9 +24,10 @@ #include typedef struct MPEGSeqHdr MPEGSeqHdr; +typedef struct MPEGSeqExtHdr MPEGSeqExtHdr; typedef struct MPEGPictureHdr MPEGPictureHdr; typedef struct MPEGPictureExt MPEGPictureExt; -typedef struct MPEGPictureGOP MPEGPictureGOP; +typedef struct MPEGGop MPEGGop; typedef struct MPEGQuantMatrix MPEGQuantMatrix; /* Packet ID codes for different packet types we @@ -53,27 +54,45 @@ typedef struct MPEGQuantMatrix MPEGQuantMatrix; struct MPEGSeqHdr { - /* 0 for unknown, else 1 or 2 */ - guint8 mpeg_version; - /* Pixel-Aspect Ratio from DAR code via set_par_from_dar */ - gint par_w, par_h; + guint par_w, par_h; /* Width and Height of the video */ - gint width, height; + guint16 width, height; /* Framerate */ - gint fps_n, fps_d; + guint fps_n, fps_d; - /* mpeg2 decoder profile */ - gint profile; + guint32 bitrate; + guint16 vbv_buffer; + guint8 constrained_parameters_flag; + guint8 intra_quantizer_matrix[64]; guint8 non_intra_quantizer_matrix[64]; }; +struct MPEGSeqExtHdr +{ + + /* mpeg2 decoder profile */ + guint8 profile; + /* mpeg2 decoder level */ + guint8 level; + + guint8 progressive; + guint8 chroma_format; + + guint8 horiz_size_ext, vert_size_ext; + + guint8 fps_n_ext, fps_d_ext; + +}; + struct MPEGPictureHdr { + guint16 tsn; guint8 pic_type; - + guint16 vbv_delay; + guint8 full_pel_forward_vector, full_pel_backward_vector; guint8 f_code[2][2]; @@ -91,9 +110,10 @@ struct MPEGPictureExt guint8 q_scale_type; guint8 intra_vlc_format; guint8 alternate_scan; + guint8 repeat_first_field; }; -struct MPEGPictureGOP +struct MPEGGop { guint8 drop_frame_flag; @@ -109,18 +129,19 @@ struct MPEGQuantMatrix guint8 non_intra_quantizer_matrix[64]; }; -gboolean mpeg_util_parse_sequence_hdr (MPEGSeqHdr *hdr, - guint8 *data, guint8 *end); +gboolean mpeg_util_parse_sequence_hdr (MPEGSeqHdr *hdr, GstBuffer *buffer); -gboolean mpeg_util_parse_picture_hdr (MPEGPictureHdr * hdr, guint8 * data, guint8 * end); +gboolean mpeg_util_parse_sequence_extension (MPEGSeqExtHdr *hdr, + GstBuffer *buffer); -gboolean mpeg_util_parse_picture_coding_extension (MPEGPictureExt *ext, guint8 *data, guint8 *end); +gboolean mpeg_util_parse_picture_hdr (MPEGPictureHdr * hdr, GstBuffer *buffer); -gboolean mpeg_util_parse_picture_gop (MPEGPictureGOP * gop, guint8 * data, guint8 * end); +gboolean mpeg_util_parse_picture_coding_extension (MPEGPictureExt *ext, + GstBuffer *buffer); -gboolean mpeg_util_parse_quant_matrix (MPEGQuantMatrix * qm, guint8 * data, guint8 * end); +gboolean mpeg_util_parse_gop (MPEGGop * gop, GstBuffer *buffer); -guint8 *mpeg_util_find_start_code (guint32 * sync_word, guint8 * cur, guint8 * end); -guint32 read_bits (guint8 * buf, gint start_bit, gint n_bits); +gboolean mpeg_util_parse_quant_matrix (MPEGQuantMatrix * qm, GstBuffer *buffer); #endif + -- cgit v1.2.1 From 27606d4e104ec0f78f8ef3c4171d68f5069c7c91 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Thu, 4 Jun 2009 19:17:14 +0200 Subject: vpdaumpegdec: remove useless GstVdpDecoder baseclass --- sys/vdpau/Makefile.am | 2 - sys/vdpau/gstvdpdecoder.c | 229 ------------------------------------------ sys/vdpau/gstvdpdecoder.h | 72 ------------- sys/vdpau/gstvdpmpegdecoder.c | 159 ++++++++++++++++++++--------- sys/vdpau/gstvdpmpegdecoder.h | 18 +++- 5 files changed, 127 insertions(+), 353 deletions(-) delete mode 100644 sys/vdpau/gstvdpdecoder.c delete mode 100644 sys/vdpau/gstvdpdecoder.h (limited to 'sys') diff --git a/sys/vdpau/Makefile.am b/sys/vdpau/Makefile.am index a603ec77..053332b0 100644 --- a/sys/vdpau/Makefile.am +++ b/sys/vdpau/Makefile.am @@ -2,7 +2,6 @@ plugin_LTLIBRARIES = libgstvdpau.la libgstvdpau_la_SOURCES = \ gstvdpdevice.c \ - gstvdpdecoder.c \ gstvdpmpegdecoder.c \ mpegutil.c \ gstvdpvideoyuv.c \ @@ -18,7 +17,6 @@ libgstvdpau_la_LIBTOOLFLAGS = --tag=disable-static noinst_HEADERS = \ gstvdpdevice.h \ - gstvdpdecoder.h \ gstvdpmpegdecoder.h \ mpegutil.h \ gstvdpvideoyuv.h \ diff --git a/sys/vdpau/gstvdpdecoder.c b/sys/vdpau/gstvdpdecoder.c deleted file mode 100644 index b6a28cc7..00000000 --- a/sys/vdpau/gstvdpdecoder.c +++ /dev/null @@ -1,229 +0,0 @@ -/* - * GStreamer - * Copyright (C) 2009 Carl-Anton Ingmarsson - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include - -#include "gstvdpdecoder.h" - -GST_DEBUG_CATEGORY_STATIC (gst_vdp_decoder_debug); -#define GST_CAT_DEFAULT gst_vdp_decoder_debug - -/* Filter signals and args */ -enum -{ - /* FILL ME */ - LAST_SIGNAL -}; - -enum -{ - PROP_0, - PROP_DISPLAY -}; - -static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("video/x-vdpau-video, " "chroma-type = (int) 0")); - -#define DEBUG_INIT(bla) \ - GST_DEBUG_CATEGORY_INIT (gst_vdp_decoder_debug, "vdpaudecoder", 0, "vdpaudecoder base class"); - -GST_BOILERPLATE_FULL (GstVdpDecoder, gst_vdp_decoder, GstElement, - GST_TYPE_ELEMENT, DEBUG_INIT); - -static void gst_vdp_decoder_finalize (GObject * object); -static void gst_vdp_decoder_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec); -static void gst_vdp_decoder_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec); - -GstFlowReturn -gst_vdp_decoder_push_video_buffer (GstVdpDecoder * dec, - GstVdpVideoBuffer * buffer) -{ - if (GST_BUFFER_TIMESTAMP (buffer) == GST_CLOCK_TIME_NONE) { - GST_BUFFER_TIMESTAMP (buffer) = dec->time + - gst_util_uint64_scale_int (GST_SECOND, - dec->framerate_denominator, dec->framerate_numerator); - } - gst_buffer_set_caps (GST_BUFFER (buffer), GST_PAD_CAPS (dec->src)); - - GST_DEBUG_OBJECT (dec, "Pushing buffer with timestamp: %" GST_TIME_FORMAT, - GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer))); - dec->time = GST_BUFFER_TIMESTAMP (buffer); - - return gst_pad_push (dec->src, GST_BUFFER (buffer)); -} - -static gboolean -gst_vdp_decoder_sink_set_caps (GstPad * pad, GstCaps * caps) -{ - GstVdpDecoder *dec = GST_VDP_DECODER (GST_OBJECT_PARENT (pad)); - GstVdpDecoderClass *dec_class = GST_VDP_DECODER_GET_CLASS (dec); - - GstCaps *src_caps, *new_caps; - GstStructure *structure; - gint width, height; - gint framerate_numerator, framerate_denominator; - gint par_numerator, par_denominator; - gboolean res; - - structure = gst_caps_get_structure (caps, 0); - gst_structure_get_int (structure, "width", &width); - gst_structure_get_int (structure, "height", &height); - gst_structure_get_fraction (structure, "framerate", - &framerate_numerator, &framerate_denominator); - gst_structure_get_fraction (structure, "pixel-aspect-ratio", - &par_numerator, &par_denominator); - - src_caps = gst_pad_get_allowed_caps (dec->src); - if (G_UNLIKELY (!src_caps)) - return FALSE; - - new_caps = gst_caps_copy_nth (src_caps, 0); - gst_caps_unref (src_caps); - structure = gst_caps_get_structure (new_caps, 0); - gst_structure_set (structure, - "device", G_TYPE_OBJECT, dec->device, - "chroma-type", G_TYPE_INT, VDP_CHROMA_TYPE_420, - "width", G_TYPE_INT, width, - "height", G_TYPE_INT, height, - "framerate", GST_TYPE_FRACTION, framerate_numerator, - framerate_denominator, - "pixel-aspect-ratio", GST_TYPE_FRACTION, par_numerator, - par_denominator, NULL); - - gst_pad_fixate_caps (dec->src, new_caps); - res = gst_pad_set_caps (dec->src, new_caps); - - gst_caps_unref (new_caps); - - if (G_UNLIKELY (!res)) - return FALSE; - - dec->width = width; - dec->height = height; - dec->framerate_numerator = framerate_numerator; - dec->framerate_denominator = framerate_denominator; - - if (dec_class->set_caps && !dec_class->set_caps (dec, caps)) - return FALSE; - - return TRUE; -} - -/* GObject vmethod implementations */ - -static void -gst_vdp_decoder_base_init (gpointer klass) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS (klass); - - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&src_template)); -} - -/* initialize the vdpaudecoder's class */ -static void -gst_vdp_decoder_class_init (GstVdpDecoderClass * klass) -{ - GObjectClass *gobject_class; - GstElementClass *gstelement_class; - - gobject_class = (GObjectClass *) klass; - gstelement_class = (GstElementClass *) klass; - - gobject_class->finalize = gst_vdp_decoder_finalize; - gobject_class->set_property = gst_vdp_decoder_set_property; - gobject_class->get_property = gst_vdp_decoder_get_property; - - g_object_class_install_property (gobject_class, PROP_DISPLAY, - g_param_spec_string ("display", "Display", "X Display name", - NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); -} - -static void -gst_vdp_decoder_init (GstVdpDecoder * dec, GstVdpDecoderClass * klass) -{ - dec->display_name = NULL; - dec->device = NULL; - - dec->height = 0; - dec->width = 0; - dec->framerate_numerator = 0; - dec->framerate_denominator = 0; - - dec->time = 0; - - dec->src = gst_pad_new_from_static_template (&src_template, "src"); - gst_element_add_pad (GST_ELEMENT (dec), dec->src); - - dec->sink = gst_pad_new_from_template (gst_element_class_get_pad_template - (GST_ELEMENT_CLASS (klass), "sink"), "sink"); - gst_pad_set_setcaps_function (dec->sink, gst_vdp_decoder_sink_set_caps); - gst_element_add_pad (GST_ELEMENT (dec), dec->sink); -} - -static void -gst_vdp_decoder_finalize (GObject * object) -{ - GstVdpDecoder *dec = (GstVdpDecoder *) object; - - g_free (dec->display_name); -} - -static void -gst_vdp_decoder_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) -{ - GstVdpDecoder *dec = GST_VDP_DECODER (object); - - switch (prop_id) { - case PROP_DISPLAY: - g_free (dec->display_name); - dec->display_name = g_value_dup_string (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_vdp_decoder_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec) -{ - GstVdpDecoder *dec = GST_VDP_DECODER (object); - - switch (prop_id) { - case PROP_DISPLAY: - g_value_set_string (value, dec->display_name); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} diff --git a/sys/vdpau/gstvdpdecoder.h b/sys/vdpau/gstvdpdecoder.h deleted file mode 100644 index f20db20c..00000000 --- a/sys/vdpau/gstvdpdecoder.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * GStreamer - * Copyright (C) 2009 Carl-Anton Ingmarsson - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __GST_VDP_DECODER_H__ -#define __GST_VDP_DECODER_H__ - -#include - -#include "gstvdpdevice.h" -#include "gstvdpvideobuffer.h" - -G_BEGIN_DECLS - -#define GST_TYPE_VDP_DECODER (gst_vdp_decoder_get_type()) -#define GST_VDP_DECODER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VDP_DECODER,GstVdpDecoder)) -#define GST_VDP_DECODER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VDP_DECODER,GstVdpDecoderClass)) -#define GST_VDP_DECODER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VDP_DECODER, GstVdpDecoderClass)) -#define GST_IS_VDPAU_DECODER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VDP_DECODER)) -#define GST_IS_VDPAU_DECODER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VDP_DECODER)) - -typedef struct _GstVdpDecoder GstVdpDecoder; -typedef struct _GstVdpDecoderClass GstVdpDecoderClass; -typedef struct _VdpauFunctions VdpauFunctions; - -struct _GstVdpDecoder { - GstElement element; - - gchar *display_name; - GstVdpDevice *device; - - GstPad *src; - GstPad *sink; - - gint width, height; - gint framerate_numerator, framerate_denominator; - guint32 format; - - GstClockTime time; -}; - -struct _GstVdpDecoderClass { - GstElementClass parent_class; - - gboolean (*set_caps) (GstVdpDecoder *dec, GstCaps *caps); -}; - -GType gst_vdp_decoder_get_type (void); - -gboolean gst_vdp_decoder_push_video_buffer (GstVdpDecoder * dec, - GstVdpVideoBuffer *buffer); -VdpVideoSurface gst_vdp_decoder_create_video_surface (GstVdpDecoder *dec); - -G_END_DECLS - -#endif /* __GST_VDP_DECODER_H__ */ diff --git a/sys/vdpau/gstvdpmpegdecoder.c b/sys/vdpau/gstvdpmpegdecoder.c index fc7aa5a6..a501d533 100644 --- a/sys/vdpau/gstvdpmpegdecoder.c +++ b/sys/vdpau/gstvdpmpegdecoder.c @@ -55,25 +55,31 @@ enum enum { - PROP_0 + PROP_0, + PROP_DISPLAY }; /* the capabilities of the inputs and outputs. * * describe the real formats here. */ -static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink", +static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, GST_STATIC_CAPS ("video/mpeg, mpegversion = (int) [ 1, 2 ], " "systemstream = (boolean) false, parsed = (boolean) true") ); +static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS ("video/x-vdpau-video, " "chroma-type = (int) 0") + ); #define DEBUG_INIT(bla) \ GST_DEBUG_CATEGORY_INIT (gst_vdp_mpeg_decoder_debug, "vdpaumpegdec", 0, "VDPAU powered mpeg decoder"); GST_BOILERPLATE_FULL (GstVdpMpegDecoder, gst_vdp_mpeg_decoder, - GstVdpDecoder, GST_TYPE_VDP_DECODER, DEBUG_INIT); + GstElement, GST_TYPE_ELEMENT, DEBUG_INIT); static void gst_vdp_mpeg_decoder_init_info (VdpPictureInfoMPEG1Or2 * vdp_info); static void gst_vdp_mpeg_decoder_finalize (GObject * object); @@ -153,18 +159,54 @@ gst_vdp_mpeg_packetizer_init (GstVdpMpegPacketizer * packetizer, } static gboolean -gst_vdp_mpeg_decoder_set_caps (GstVdpDecoder * dec, GstCaps * caps) +gst_vdp_mpeg_decoder_set_caps (GstPad * pad, GstCaps * caps) { - GstVdpMpegDecoder *mpeg_dec; + GstVdpMpegDecoder *mpeg_dec = GST_VDP_MPEG_DECODER (GST_OBJECT_PARENT (pad)); GstStructure *structure; + + gint width, height; + gint fps_n, fps_d; + gint par_n, par_d; + gboolean interlaced; + + GstCaps *src_caps; + gboolean res; + const GValue *value; VdpDecoderProfile profile; GstVdpDevice *device; VdpStatus status; - mpeg_dec = GST_VDP_MPEG_DECODER (dec); - structure = gst_caps_get_structure (caps, 0); + + /* create src_pad caps */ + gst_structure_get_int (structure, "width", &width); + gst_structure_get_int (structure, "height", &height); + gst_structure_get_fraction (structure, "framerate", &fps_d, &fps_d); + gst_structure_get_fraction (structure, "pixel-aspect-ratio", &par_n, &par_d); + gst_structure_get_boolean (structure, "interlaced", &interlaced); + + src_caps = gst_caps_new_simple ("video/x-vdpau-video", + "device", G_TYPE_OBJECT, mpeg_dec->device, + "chroma_type", G_TYPE_INT, VDP_CHROMA_TYPE_420, + "width", G_TYPE_INT, width, + "height", G_TYPE_INT, height, + "framerate", GST_TYPE_FRACTION, fps_n, fps_d, + "pixel-aspect-ratio", GST_TYPE_FRACTION, par_n, par_d, + "interlaced", G_TYPE_BOOLEAN, interlaced, NULL); + + res = gst_pad_set_caps (mpeg_dec->src, src_caps); + gst_caps_unref (src_caps); + if (!res) + return FALSE; + + mpeg_dec->width = width; + mpeg_dec->height = height; + mpeg_dec->fps_n = fps_n; + mpeg_dec->fps_d = fps_d; + mpeg_dec->interlaced = interlaced; + + /* parse caps to setup decoder */ gst_structure_get_int (structure, "mpegversion", &mpeg_dec->version); if (mpeg_dec->version == 1) profile = VDP_DECODER_PROFILE_MPEG1; @@ -208,15 +250,15 @@ gst_vdp_mpeg_decoder_set_caps (GstVdpDecoder * dec, GstCaps * caps) } } - device = dec->device; + device = mpeg_dec->device; if (mpeg_dec->decoder != VDP_INVALID_HANDLE) { device->vdp_decoder_destroy (mpeg_dec->decoder); mpeg_dec->decoder = VDP_INVALID_HANDLE; } - status = device->vdp_decoder_create (device->device, profile, dec->width, - dec->height, 2, &mpeg_dec->decoder); + status = device->vdp_decoder_create (device->device, profile, mpeg_dec->width, + mpeg_dec->height, 2, &mpeg_dec->decoder); if (status != VDP_STATUS_OK) { GST_ELEMENT_ERROR (mpeg_dec, RESOURCE, READ, ("Could not create vdpau decoder"), @@ -227,11 +269,29 @@ gst_vdp_mpeg_decoder_set_caps (GstVdpDecoder * dec, GstCaps * caps) return TRUE; } +GstFlowReturn +gst_vdp_mpeg_decoder_push_video_buffer (GstVdpMpegDecoder * mpeg_dec, + GstVdpVideoBuffer * buffer) +{ + if (GST_BUFFER_TIMESTAMP (buffer) == GST_CLOCK_TIME_NONE) { + GST_BUFFER_TIMESTAMP (buffer) = mpeg_dec->time + + gst_util_uint64_scale_int (GST_SECOND, + mpeg_dec->fps_d, mpeg_dec->fps_n); + } + gst_buffer_set_caps (GST_BUFFER (buffer), GST_PAD_CAPS (mpeg_dec->src)); + + GST_DEBUG_OBJECT (mpeg_dec, + "Pushing buffer with timestamp: %" GST_TIME_FORMAT, + GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer))); + mpeg_dec->time = GST_BUFFER_TIMESTAMP (buffer); + + return gst_pad_push (mpeg_dec->src, GST_BUFFER (buffer)); +} + static GstFlowReturn gst_vdp_mpeg_decoder_decode (GstVdpMpegDecoder * mpeg_dec, GstClockTime timestamp) { - GstVdpDecoder *dec; VdpPictureInfoMPEG1Or2 *info; GstBuffer *buffer; GstVdpVideoBuffer *outbuf; @@ -240,7 +300,6 @@ gst_vdp_mpeg_decoder_decode (GstVdpMpegDecoder * mpeg_dec, VdpBitstreamBuffer vbit[1]; VdpStatus status; - dec = GST_VDP_DECODER (mpeg_dec); info = &mpeg_dec->vdp_info; buffer = gst_adapter_take_buffer (mpeg_dec->adapter, @@ -249,7 +308,7 @@ gst_vdp_mpeg_decoder_decode (GstVdpMpegDecoder * mpeg_dec, if (info->picture_coding_type != B_FRAME) { if (info->backward_reference != VDP_INVALID_HANDLE) { gst_buffer_ref (mpeg_dec->b_buffer); - gst_vdp_decoder_push_video_buffer (dec, + gst_vdp_mpeg_decoder_push_video_buffer (mpeg_dec, GST_VDP_VIDEO_BUFFER (mpeg_dec->b_buffer)); } @@ -264,8 +323,8 @@ gst_vdp_mpeg_decoder_decode (GstVdpMpegDecoder * mpeg_dec, info->backward_reference = VDP_INVALID_HANDLE; } - outbuf = gst_vdp_video_buffer_new (dec->device, VDP_CHROMA_TYPE_420, - dec->width, dec->height); + outbuf = gst_vdp_video_buffer_new (mpeg_dec->device, VDP_CHROMA_TYPE_420, + mpeg_dec->width, mpeg_dec->height); GST_BUFFER_TIMESTAMP (outbuf) = timestamp; if (info->forward_reference != VDP_INVALID_HANDLE && @@ -279,7 +338,7 @@ gst_vdp_mpeg_decoder_decode (GstVdpMpegDecoder * mpeg_dec, surface = outbuf->surface; - device = dec->device; + device = mpeg_dec->device; vbit[0].struct_version = VDP_BITSTREAM_BUFFER_VERSION; vbit[0].bitstream = GST_BUFFER_DATA (buffer); @@ -302,7 +361,8 @@ gst_vdp_mpeg_decoder_decode (GstVdpMpegDecoder * mpeg_dec, } if (info->picture_coding_type == B_FRAME) { - gst_vdp_decoder_push_video_buffer (dec, GST_VDP_VIDEO_BUFFER (outbuf)); + gst_vdp_mpeg_decoder_push_video_buffer (mpeg_dec, + GST_VDP_VIDEO_BUFFER (outbuf)); } else { info->backward_reference = surface; mpeg_dec->b_buffer = GST_BUFFER (outbuf); @@ -315,11 +375,9 @@ static gboolean gst_vdp_mpeg_decoder_parse_picture_coding (GstVdpMpegDecoder * mpeg_dec, GstBuffer * buffer) { - GstVdpDecoder *dec; MPEGPictureExt pic_ext; VdpPictureInfoMPEG1Or2 *info; - dec = GST_VDP_DECODER (mpeg_dec); info = &mpeg_dec->vdp_info; if (!mpeg_util_parse_picture_coding_extension (&pic_ext, buffer)) @@ -343,11 +401,8 @@ static gboolean gst_vdp_mpeg_decoder_parse_sequence (GstVdpMpegDecoder * mpeg_dec, GstBuffer * buffer) { - GstVdpDecoder *dec; MPEGSeqHdr hdr; - dec = GST_VDP_DECODER (mpeg_dec); - if (!mpeg_util_parse_sequence_hdr (&hdr, buffer)) return FALSE; @@ -364,11 +419,8 @@ static gboolean gst_vdp_mpeg_decoder_parse_picture (GstVdpMpegDecoder * mpeg_dec, GstBuffer * buffer) { - GstVdpDecoder *dec; MPEGPictureHdr pic_hdr; - dec = GST_VDP_DECODER (mpeg_dec); - if (!mpeg_util_parse_picture_hdr (&pic_hdr, buffer)) return FALSE; @@ -532,20 +584,16 @@ gst_vdp_mpeg_decoder_chain (GstPad * pad, GstBuffer * buffer) static gboolean gst_vdp_mpeg_decoder_sink_event (GstPad * pad, GstEvent * event) { - GstVdpMpegDecoder *mpeg_dec; - GstVdpDecoder *dec; + GstVdpMpegDecoder *mpeg_dec = GST_VDP_MPEG_DECODER (GST_OBJECT_PARENT (pad)); gboolean res; - mpeg_dec = GST_VDP_MPEG_DECODER (GST_OBJECT_PARENT (pad)); - dec = GST_VDP_DECODER (mpeg_dec); - switch (GST_EVENT_TYPE (event)) { case GST_EVENT_FLUSH_STOP: { GST_DEBUG_OBJECT (mpeg_dec, "flush stop"); gst_vdp_mpeg_decoder_reset (mpeg_dec); - res = gst_pad_push_event (dec->src, event); + res = gst_pad_push_event (mpeg_dec->src, event); break; } @@ -561,15 +609,13 @@ gst_vdp_mpeg_decoder_change_state (GstElement * element, GstStateChange transition) { GstVdpMpegDecoder *mpeg_dec; - GstVdpDecoder *dec; GstStateChangeReturn ret; mpeg_dec = GST_VDP_MPEG_DECODER (element); - dec = GST_VDP_DECODER (mpeg_dec); switch (transition) { case GST_STATE_CHANGE_READY_TO_PAUSED: - dec->device = gst_vdp_get_device (dec->display_name); + mpeg_dec->device = gst_vdp_get_device (mpeg_dec->display_name); break; default: break; @@ -581,11 +627,11 @@ gst_vdp_mpeg_decoder_change_state (GstElement * element, case GST_STATE_CHANGE_PAUSED_TO_READY: gst_vdp_mpeg_decoder_reset (mpeg_dec); - dec->device->vdp_decoder_destroy (mpeg_dec->decoder); + mpeg_dec->device->vdp_decoder_destroy (mpeg_dec->decoder); mpeg_dec->decoder = VDP_INVALID_HANDLE; - g_object_unref (dec->device); - dec->device = NULL; + g_object_unref (mpeg_dec->device); + mpeg_dec->device = NULL; break; default: break; @@ -608,7 +654,9 @@ gst_vdp_mpeg_decoder_base_init (gpointer gclass) "Carl-Anton Ingmarsson "); gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&sink_factory)); + gst_static_pad_template_get (&sink_template)); + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&src_template)); } /* initialize the vdpaumpegdecoder's class */ @@ -617,19 +665,19 @@ gst_vdp_mpeg_decoder_class_init (GstVdpMpegDecoderClass * klass) { GObjectClass *gobject_class; GstElementClass *gstelement_class; - GstVdpDecoderClass *vdpaudec_class; gobject_class = (GObjectClass *) klass; gstelement_class = (GstElementClass *) klass; - vdpaudec_class = (GstVdpDecoderClass *) klass; gobject_class->finalize = gst_vdp_mpeg_decoder_finalize; gobject_class->set_property = gst_vdp_mpeg_decoder_set_property; gobject_class->get_property = gst_vdp_mpeg_decoder_get_property; - vdpaudec_class->set_caps = gst_vdp_mpeg_decoder_set_caps; - gstelement_class->change_state = gst_vdp_mpeg_decoder_change_state; + + g_object_class_install_property (gobject_class, PROP_DISPLAY, + g_param_spec_string ("display", "Display", "X Display name", + NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); } static void @@ -653,19 +701,25 @@ static void gst_vdp_mpeg_decoder_init (GstVdpMpegDecoder * mpeg_dec, GstVdpMpegDecoderClass * gclass) { - GstVdpDecoder *dec; + mpeg_dec->src = gst_pad_new_from_static_template (&src_template, "src"); + gst_element_add_pad (GST_ELEMENT (mpeg_dec), mpeg_dec->src); - dec = GST_VDP_DECODER (mpeg_dec); + mpeg_dec->sink = gst_pad_new_from_static_template (&sink_template, "sink"); + gst_pad_set_setcaps_function (mpeg_dec->sink, gst_vdp_mpeg_decoder_set_caps); + gst_pad_set_chain_function (mpeg_dec->sink, gst_vdp_mpeg_decoder_chain); + gst_pad_set_event_function (mpeg_dec->sink, gst_vdp_mpeg_decoder_sink_event); + gst_element_add_pad (GST_ELEMENT (mpeg_dec), mpeg_dec->sink); + + mpeg_dec->display_name = NULL; + mpeg_dec->device = NULL; mpeg_dec->decoder = VDP_INVALID_HANDLE; gst_vdp_mpeg_decoder_init_info (&mpeg_dec->vdp_info); mpeg_dec->broken_gop = FALSE; + mpeg_dec->time = 0; mpeg_dec->adapter = gst_adapter_new (); - - gst_pad_set_chain_function (dec->sink, gst_vdp_mpeg_decoder_chain); - gst_pad_set_event_function (dec->sink, gst_vdp_mpeg_decoder_sink_event); } static void @@ -680,7 +734,13 @@ static void gst_vdp_mpeg_decoder_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { + GstVdpMpegDecoder *mpeg_dec = GST_VDP_MPEG_DECODER (object); + switch (prop_id) { + case PROP_DISPLAY: + g_free (mpeg_dec->display_name); + mpeg_dec->display_name = g_value_dup_string (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -691,7 +751,12 @@ static void gst_vdp_mpeg_decoder_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { + GstVdpMpegDecoder *mpeg_dec = GST_VDP_MPEG_DECODER (object); + switch (prop_id) { + case PROP_DISPLAY: + g_value_set_string (value, mpeg_dec->display_name); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; diff --git a/sys/vdpau/gstvdpmpegdecoder.h b/sys/vdpau/gstvdpmpegdecoder.h index 06bed84b..a48e0c97 100644 --- a/sys/vdpau/gstvdpmpegdecoder.h +++ b/sys/vdpau/gstvdpmpegdecoder.h @@ -24,7 +24,8 @@ #include #include -#include "gstvdpdecoder.h" +#include "gstvdpdevice.h" +#include "gstvdpvideobuffer.h" G_BEGIN_DECLS @@ -39,8 +40,18 @@ typedef struct _GstVdpMpegDecoderClass GstVdpMpegDecoderClass; struct _GstVdpMpegDecoder { - GstVdpDecoder dec; + GstElement element; + gchar *display_name; + GstVdpDevice *device; + + GstPad *src; + GstPad *sink; + + gint width, height; + gint fps_n, fps_d; + gboolean interlaced; + gint version; VdpDecoder decoder; @@ -49,13 +60,14 @@ struct _GstVdpMpegDecoder GstBuffer *b_buffer; gboolean broken_gop; + GstClockTime time; GstAdapter *adapter; }; struct _GstVdpMpegDecoderClass { - GstVdpDecoderClass parent_class; + GstElementClass element_class; }; GType gst_vdp_mpeg_decoder_get_type (void); -- cgit v1.2.1 From aee19375793395486b07679f30e3bed5e85119ea Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Thu, 4 Jun 2009 19:30:02 +0200 Subject: vdpaumpegdec: fix so that the first frame in a raw mpegvideo stream get timestamp 0 --- sys/vdpau/gstvdpmpegdecoder.c | 11 ++++++----- sys/vdpau/gstvdpmpegdecoder.h | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpmpegdecoder.c b/sys/vdpau/gstvdpmpegdecoder.c index a501d533..dbb87c38 100644 --- a/sys/vdpau/gstvdpmpegdecoder.c +++ b/sys/vdpau/gstvdpmpegdecoder.c @@ -274,16 +274,17 @@ gst_vdp_mpeg_decoder_push_video_buffer (GstVdpMpegDecoder * mpeg_dec, GstVdpVideoBuffer * buffer) { if (GST_BUFFER_TIMESTAMP (buffer) == GST_CLOCK_TIME_NONE) { - GST_BUFFER_TIMESTAMP (buffer) = mpeg_dec->time + - gst_util_uint64_scale_int (GST_SECOND, - mpeg_dec->fps_d, mpeg_dec->fps_n); + GST_BUFFER_TIMESTAMP (buffer) = mpeg_dec->next_timestamp; } + + mpeg_dec->next_timestamp = GST_BUFFER_TIMESTAMP (buffer) + + gst_util_uint64_scale_int (GST_SECOND, mpeg_dec->fps_d, mpeg_dec->fps_n); + gst_buffer_set_caps (GST_BUFFER (buffer), GST_PAD_CAPS (mpeg_dec->src)); GST_DEBUG_OBJECT (mpeg_dec, "Pushing buffer with timestamp: %" GST_TIME_FORMAT, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer))); - mpeg_dec->time = GST_BUFFER_TIMESTAMP (buffer); return gst_pad_push (mpeg_dec->src, GST_BUFFER (buffer)); } @@ -717,7 +718,7 @@ gst_vdp_mpeg_decoder_init (GstVdpMpegDecoder * mpeg_dec, gst_vdp_mpeg_decoder_init_info (&mpeg_dec->vdp_info); mpeg_dec->broken_gop = FALSE; - mpeg_dec->time = 0; + mpeg_dec->next_timestamp = 0; mpeg_dec->adapter = gst_adapter_new (); } diff --git a/sys/vdpau/gstvdpmpegdecoder.h b/sys/vdpau/gstvdpmpegdecoder.h index a48e0c97..3e1bc731 100644 --- a/sys/vdpau/gstvdpmpegdecoder.h +++ b/sys/vdpau/gstvdpmpegdecoder.h @@ -60,7 +60,7 @@ struct _GstVdpMpegDecoder GstBuffer *b_buffer; gboolean broken_gop; - GstClockTime time; + GstClockTime next_timestamp; GstAdapter *adapter; }; -- cgit v1.2.1 From df3c59a48286f242649aa3279b1c522b2b1fb1c7 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Thu, 4 Jun 2009 21:17:40 +0200 Subject: vdpaumpegdec: calculate correct duration from data in MPEG_PACKET_EXT_PICTURE_CODING --- sys/vdpau/gstvdpmpegdecoder.c | 40 +++++++++++++++++++++++++++++++++++++--- sys/vdpau/gstvdpmpegdecoder.h | 1 + sys/vdpau/mpegutil.c | 8 ++++++++ sys/vdpau/mpegutil.h | 2 ++ 4 files changed, 48 insertions(+), 3 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpmpegdecoder.c b/sys/vdpau/gstvdpmpegdecoder.c index dbb87c38..008a2428 100644 --- a/sys/vdpau/gstvdpmpegdecoder.c +++ b/sys/vdpau/gstvdpmpegdecoder.c @@ -182,7 +182,7 @@ gst_vdp_mpeg_decoder_set_caps (GstPad * pad, GstCaps * caps) /* create src_pad caps */ gst_structure_get_int (structure, "width", &width); gst_structure_get_int (structure, "height", &height); - gst_structure_get_fraction (structure, "framerate", &fps_d, &fps_d); + gst_structure_get_fraction (structure, "framerate", &fps_n, &fps_d); gst_structure_get_fraction (structure, "pixel-aspect-ratio", &par_n, &par_d); gst_structure_get_boolean (structure, "interlaced", &interlaced); @@ -278,7 +278,7 @@ gst_vdp_mpeg_decoder_push_video_buffer (GstVdpMpegDecoder * mpeg_dec, } mpeg_dec->next_timestamp = GST_BUFFER_TIMESTAMP (buffer) + - gst_util_uint64_scale_int (GST_SECOND, mpeg_dec->fps_d, mpeg_dec->fps_n); + GST_BUFFER_DURATION (buffer); gst_buffer_set_caps (GST_BUFFER (buffer), GST_PAD_CAPS (mpeg_dec->src)); @@ -327,6 +327,7 @@ gst_vdp_mpeg_decoder_decode (GstVdpMpegDecoder * mpeg_dec, outbuf = gst_vdp_video_buffer_new (mpeg_dec->device, VDP_CHROMA_TYPE_420, mpeg_dec->width, mpeg_dec->height); GST_BUFFER_TIMESTAMP (outbuf) = timestamp; + GST_BUFFER_DURATION (outbuf) = mpeg_dec->duration; if (info->forward_reference != VDP_INVALID_HANDLE && info->picture_coding_type != I_FRAME) @@ -378,6 +379,7 @@ gst_vdp_mpeg_decoder_parse_picture_coding (GstVdpMpegDecoder * mpeg_dec, { MPEGPictureExt pic_ext; VdpPictureInfoMPEG1Or2 *info; + gint fields; info = &mpeg_dec->vdp_info; @@ -395,6 +397,36 @@ gst_vdp_mpeg_decoder_parse_picture_coding (GstVdpMpegDecoder * mpeg_dec, info->intra_vlc_format = pic_ext.intra_vlc_format; info->alternate_scan = pic_ext.alternate_scan; + fields = 0; + if (pic_ext.picture_structure == 3) { + if (mpeg_dec->interlaced) { + if (pic_ext.progressive_frame == 0) + fields = 2; + if (pic_ext.progressive_frame == 0 && pic_ext.repeat_first_field == 0) + fields = 2; + if (pic_ext.progressive_frame == 1 && pic_ext.repeat_first_field == 1) + fields = 3; + } else { + if (pic_ext.repeat_first_field == 0) + fields = 2; + if (pic_ext.repeat_first_field == 1 && pic_ext.top_field_first == 0) + fields = 4; + if (pic_ext.repeat_first_field == 1 && pic_ext.top_field_first == 1) + fields = 6; + } + } else + fields = 1; + + GST_DEBUG ("fields: %d", fields); + + if (!fields) { + GST_DEBUG ("Invalid Picture Extension packet"); + return FALSE; + } + + mpeg_dec->duration = gst_util_uint64_scale (fields, + GST_SECOND * mpeg_dec->fps_d, 2 * mpeg_dec->fps_n); + return TRUE; } @@ -407,7 +439,6 @@ gst_vdp_mpeg_decoder_parse_sequence (GstVdpMpegDecoder * mpeg_dec, if (!mpeg_util_parse_sequence_hdr (&hdr, buffer)) return FALSE; - g_debug ("här"); memcpy (&mpeg_dec->vdp_info.intra_quantizer_matrix, &hdr.intra_quantizer_matrix, 64); memcpy (&mpeg_dec->vdp_info.non_intra_quantizer_matrix, @@ -448,6 +479,9 @@ gst_vdp_mpeg_decoder_parse_picture (GstVdpMpegDecoder * mpeg_dec, memcpy (&mpeg_dec->vdp_info.f_code, &pic_hdr.f_code, 4); } + mpeg_dec->duration = gst_util_uint64_scale (1, GST_SECOND * mpeg_dec->fps_d, + mpeg_dec->fps_n); + return TRUE; } diff --git a/sys/vdpau/gstvdpmpegdecoder.h b/sys/vdpau/gstvdpmpegdecoder.h index 3e1bc731..facc791b 100644 --- a/sys/vdpau/gstvdpmpegdecoder.h +++ b/sys/vdpau/gstvdpmpegdecoder.h @@ -60,6 +60,7 @@ struct _GstVdpMpegDecoder GstBuffer *b_buffer; gboolean broken_gop; + GstClockTime duration; GstClockTime next_timestamp; GstAdapter *adapter; diff --git a/sys/vdpau/mpegutil.c b/sys/vdpau/mpegutil.c index c35ad9fb..bba84f2b 100644 --- a/sys/vdpau/mpegutil.c +++ b/sys/vdpau/mpegutil.c @@ -333,6 +333,14 @@ mpeg_util_parse_picture_coding_extension (MPEGPictureExt * ext, if (!gst_bit_reader_get_bits_uint8 (&reader, &ext->repeat_first_field, 1)) return FALSE; + /* chroma_420_type */ + if (!gst_bit_reader_get_bits_uint8 (&reader, &ext->chroma_420_type, 1)) + return FALSE; + + /* progressive_frame */ + if (!gst_bit_reader_get_bits_uint8 (&reader, &ext->progressive_frame, 1)) + return FALSE; + return TRUE; } diff --git a/sys/vdpau/mpegutil.h b/sys/vdpau/mpegutil.h index 4e5a656a..08f6cc2f 100644 --- a/sys/vdpau/mpegutil.h +++ b/sys/vdpau/mpegutil.h @@ -111,6 +111,8 @@ struct MPEGPictureExt guint8 intra_vlc_format; guint8 alternate_scan; guint8 repeat_first_field; + guint8 chroma_420_type; + guint8 progressive_frame; }; struct MPEGGop -- cgit v1.2.1 From adeddd0118cf4506247d9589cca8c14cd35df4a5 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Fri, 5 Jun 2009 11:17:16 +0200 Subject: vdpaumpegdec: handle GST_QUERY_POSITION and GST_QUERY_DURATION --- sys/vdpau/gstvdpmpegdecoder.c | 110 ++++++++++++++++++++++++++++++++++++++++++ sys/vdpau/gstvdpmpegdecoder.h | 2 + sys/vdpau/mpegutil.c | 5 +- sys/vdpau/mpegutil.h | 1 + 4 files changed, 117 insertions(+), 1 deletion(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpmpegdecoder.c b/sys/vdpau/gstvdpmpegdecoder.c index 008a2428..19c096f6 100644 --- a/sys/vdpau/gstvdpmpegdecoder.c +++ b/sys/vdpau/gstvdpmpegdecoder.c @@ -220,6 +220,7 @@ gst_vdp_mpeg_decoder_set_caps (GstPad * pad, GstCaps * caps) gst_vdp_mpeg_packetizer_init (&packetizer, codec_data); if ((buf = gst_vdp_mpeg_packetizer_get_next_packet (&packetizer))) { MPEGSeqHdr hdr; + guint32 bitrate; mpeg_util_parse_sequence_hdr (&hdr, buf); @@ -228,6 +229,7 @@ gst_vdp_mpeg_decoder_set_caps (GstPad * pad, GstCaps * caps) memcpy (&mpeg_dec->vdp_info.non_intra_quantizer_matrix, &hdr.non_intra_quantizer_matrix, 64); + bitrate = hdr.bitrate; gst_buffer_unref (buf); if ((buf = gst_vdp_mpeg_packetizer_get_next_packet (&packetizer))) { @@ -245,8 +247,12 @@ gst_vdp_mpeg_decoder_set_caps (GstPad * pad, GstCaps * caps) } } + bitrate += (ext.bitrate_ext << 18);; gst_buffer_unref (buf); } + + mpeg_dec->byterate = bitrate * 50; + GST_DEBUG ("byterate: %" G_GINT64_FORMAT, mpeg_dec->byterate); } } @@ -526,6 +532,8 @@ gst_vdp_mpeg_decoder_reset (GstVdpMpegDecoder * mpeg_dec) gst_vdp_mpeg_decoder_init_info (&mpeg_dec->vdp_info); gst_adapter_clear (mpeg_dec->adapter); + + //mpeg_dec->byterate = -1; } static GstFlowReturn @@ -616,6 +624,105 @@ gst_vdp_mpeg_decoder_chain (GstPad * pad, GstBuffer * buffer) return ret; } +static gboolean +gst_vdp_mpeg_decoder_convert (GstVdpMpegDecoder * mpeg_dec, + GstFormat src_format, gint64 src_value, + GstFormat dest_format, gint64 * dest_value) +{ + + if (src_format == dest_format) { + *dest_value = src_value; + return TRUE; + } + + if (mpeg_dec->byterate == -1) + return FALSE; + + if (src_format == GST_FORMAT_BYTES && dest_format == GST_FORMAT_TIME) { + *dest_value = gst_util_uint64_scale (GST_SECOND, src_value, + mpeg_dec->byterate); + return TRUE; + } + + if (src_format == GST_FORMAT_TIME && dest_format == GST_FORMAT_BYTES) { + *dest_value = + gst_util_uint64_scale_int (src_value, mpeg_dec->byterate, GST_SECOND); + return TRUE; + } + + return FALSE; +} + +static const GstQueryType * +gst_mpeg_decoder_get_querytypes (GstPad * pad) +{ + static const GstQueryType list[] = { + GST_QUERY_POSITION, + GST_QUERY_DURATION, + 0 + }; + + return list; +} + +static gboolean +gst_vdp_mpeg_decoder_src_query (GstPad * pad, GstQuery * query) +{ + GstVdpMpegDecoder *mpeg_dec = GST_VDP_MPEG_DECODER (GST_OBJECT_PARENT (pad)); + gboolean res = FALSE; + + switch (GST_QUERY_TYPE (query)) { + case GST_QUERY_POSITION: + { + GstFormat format; + + if (gst_pad_query_default (pad, query)) + return TRUE; + + gst_query_parse_position (query, &format, NULL); + if (format == GST_FORMAT_TIME && + GST_CLOCK_TIME_IS_VALID (mpeg_dec->next_timestamp)) { + gst_query_set_position (query, GST_FORMAT_TIME, + mpeg_dec->next_timestamp); + res = TRUE; + } + break; + } + + case GST_QUERY_DURATION: + { + GstFormat format; + + if (gst_pad_query_default (pad, query)) + return TRUE; + + gst_query_parse_duration (query, &format, NULL); + if (format == GST_FORMAT_TIME) { + gint64 bytes; + + format = GST_FORMAT_BYTES; + if (gst_pad_query_duration (pad, &format, &bytes) + && format == GST_FORMAT_BYTES) { + gint64 duration; + + if (gst_vdp_mpeg_decoder_convert (mpeg_dec, GST_FORMAT_BYTES, + bytes, GST_FORMAT_TIME, &duration)) { + GST_DEBUG ("duration: %" GST_TIME_FORMAT, GST_TIME_ARGS (duration)); + gst_query_set_duration (query, GST_FORMAT_TIME, duration); + res = TRUE; + } + } + } + break; + } + + default: + res = gst_pad_query_default (pad, query); + } + + return res; +} + static gboolean gst_vdp_mpeg_decoder_sink_event (GstPad * pad, GstEvent * event) { @@ -737,6 +844,9 @@ gst_vdp_mpeg_decoder_init (GstVdpMpegDecoder * mpeg_dec, GstVdpMpegDecoderClass * gclass) { mpeg_dec->src = gst_pad_new_from_static_template (&src_template, "src"); + gst_pad_set_query_function (mpeg_dec->src, gst_vdp_mpeg_decoder_src_query); + gst_pad_set_query_type_function (mpeg_dec->src, + gst_mpeg_decoder_get_querytypes); gst_element_add_pad (GST_ELEMENT (mpeg_dec), mpeg_dec->src); mpeg_dec->sink = gst_pad_new_from_static_template (&sink_template, "sink"); diff --git a/sys/vdpau/gstvdpmpegdecoder.h b/sys/vdpau/gstvdpmpegdecoder.h index facc791b..597101f8 100644 --- a/sys/vdpau/gstvdpmpegdecoder.h +++ b/sys/vdpau/gstvdpmpegdecoder.h @@ -62,6 +62,8 @@ struct _GstVdpMpegDecoder gboolean broken_gop; GstClockTime duration; GstClockTime next_timestamp; + + gint64 byterate; GstAdapter *adapter; }; diff --git a/sys/vdpau/mpegutil.c b/sys/vdpau/mpegutil.c index bba84f2b..5348bd6a 100644 --- a/sys/vdpau/mpegutil.c +++ b/sys/vdpau/mpegutil.c @@ -135,8 +135,11 @@ mpeg_util_parse_sequence_extension (MPEGSeqExtHdr * hdr, GstBuffer * buffer) if (!gst_bit_reader_get_bits_uint8 (&reader, &hdr->vert_size_ext, 2)) return FALSE; + if (!gst_bit_reader_get_bits_uint16 (&reader, &hdr->bitrate_ext, 12)) + return FALSE; + /* skip to framerate extension */ - if (!gst_bit_reader_skip (&reader, 22)) + if (!gst_bit_reader_skip (&reader, 9)) return FALSE; /* framerate extension */ diff --git a/sys/vdpau/mpegutil.h b/sys/vdpau/mpegutil.h index 08f6cc2f..aaaa15f8 100644 --- a/sys/vdpau/mpegutil.h +++ b/sys/vdpau/mpegutil.h @@ -83,6 +83,7 @@ struct MPEGSeqExtHdr guint8 horiz_size_ext, vert_size_ext; + guint16 bitrate_ext; guint8 fps_n_ext, fps_d_ext; }; -- cgit v1.2.1 From 92335b1a12ff49f9da5050bd8a842a11dd94907e Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Fri, 5 Jun 2009 11:20:56 +0200 Subject: vdpaumpegdec: don't drop discont buffers --- sys/vdpau/gstvdpmpegdecoder.c | 1 - 1 file changed, 1 deletion(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpmpegdecoder.c b/sys/vdpau/gstvdpmpegdecoder.c index 19c096f6..c4c5c54f 100644 --- a/sys/vdpau/gstvdpmpegdecoder.c +++ b/sys/vdpau/gstvdpmpegdecoder.c @@ -549,7 +549,6 @@ gst_vdp_mpeg_decoder_chain (GstPad * pad, GstBuffer * buffer) if (G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT))) { GST_DEBUG_OBJECT (mpeg_dec, "Received discont buffer"); gst_vdp_mpeg_decoder_reset (mpeg_dec); - return GST_FLOW_OK; } gst_vdp_mpeg_packetizer_init (&packetizer, buffer); -- cgit v1.2.1 From f80a7279579850ec2e8ceb0d1e5f56ccb7110f66 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Fri, 5 Jun 2009 11:24:34 +0200 Subject: vdpaumpegdec: use GSE_DEBUG_FUNCPTR --- sys/vdpau/gstvdpmpegdecoder.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpmpegdecoder.c b/sys/vdpau/gstvdpmpegdecoder.c index c4c5c54f..3a161c3a 100644 --- a/sys/vdpau/gstvdpmpegdecoder.c +++ b/sys/vdpau/gstvdpmpegdecoder.c @@ -814,7 +814,8 @@ gst_vdp_mpeg_decoder_class_init (GstVdpMpegDecoderClass * klass) gobject_class->set_property = gst_vdp_mpeg_decoder_set_property; gobject_class->get_property = gst_vdp_mpeg_decoder_get_property; - gstelement_class->change_state = gst_vdp_mpeg_decoder_change_state; + gstelement_class->change_state = + GST_DEBUG_FUNCPTR (gst_vdp_mpeg_decoder_change_state); g_object_class_install_property (gobject_class, PROP_DISPLAY, g_param_spec_string ("display", "Display", "X Display name", @@ -843,15 +844,19 @@ gst_vdp_mpeg_decoder_init (GstVdpMpegDecoder * mpeg_dec, GstVdpMpegDecoderClass * gclass) { mpeg_dec->src = gst_pad_new_from_static_template (&src_template, "src"); - gst_pad_set_query_function (mpeg_dec->src, gst_vdp_mpeg_decoder_src_query); + gst_pad_set_query_function (mpeg_dec->src, + GST_DEBUG_FUNCPTR (gst_vdp_mpeg_decoder_src_query)); gst_pad_set_query_type_function (mpeg_dec->src, - gst_mpeg_decoder_get_querytypes); + GST_DEBUG_FUNCPTR (gst_mpeg_decoder_get_querytypes)); gst_element_add_pad (GST_ELEMENT (mpeg_dec), mpeg_dec->src); mpeg_dec->sink = gst_pad_new_from_static_template (&sink_template, "sink"); - gst_pad_set_setcaps_function (mpeg_dec->sink, gst_vdp_mpeg_decoder_set_caps); - gst_pad_set_chain_function (mpeg_dec->sink, gst_vdp_mpeg_decoder_chain); - gst_pad_set_event_function (mpeg_dec->sink, gst_vdp_mpeg_decoder_sink_event); + gst_pad_set_setcaps_function (mpeg_dec->sink, + GST_DEBUG_FUNCPTR (gst_vdp_mpeg_decoder_set_caps)); + gst_pad_set_chain_function (mpeg_dec->sink, + GST_DEBUG_FUNCPTR (gst_vdp_mpeg_decoder_chain)); + gst_pad_set_event_function (mpeg_dec->sink, + GST_DEBUG_FUNCPTR (gst_vdp_mpeg_decoder_sink_event)); gst_element_add_pad (GST_ELEMENT (mpeg_dec), mpeg_dec->sink); mpeg_dec->display_name = NULL; -- cgit v1.2.1 From e2d8cc99b0436adba5503e3679e4ba21877aee23 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Fri, 5 Jun 2009 11:51:41 +0200 Subject: vdpaumpegdec: add new gst_vdp_mpeg_decoder_flush for flushing the decoder --- sys/vdpau/gstvdpmpegdecoder.c | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpmpegdecoder.c b/sys/vdpau/gstvdpmpegdecoder.c index 3a161c3a..bee76f1f 100644 --- a/sys/vdpau/gstvdpmpegdecoder.c +++ b/sys/vdpau/gstvdpmpegdecoder.c @@ -522,7 +522,7 @@ gst_vdp_mpeg_decoder_parse_quant_matrix (GstVdpMpegDecoder * mpeg_dec, } static void -gst_vdp_mpeg_decoder_reset (GstVdpMpegDecoder * mpeg_dec) +gst_vdp_mpeg_decoder_flush (GstVdpMpegDecoder * mpeg_dec) { if (mpeg_dec->vdp_info.forward_reference != VDP_INVALID_HANDLE) gst_buffer_unref (mpeg_dec->f_buffer); @@ -532,8 +532,22 @@ gst_vdp_mpeg_decoder_reset (GstVdpMpegDecoder * mpeg_dec) gst_vdp_mpeg_decoder_init_info (&mpeg_dec->vdp_info); gst_adapter_clear (mpeg_dec->adapter); +} + +static void +gst_vdp_mpeg_decoder_reset (GstVdpMpegDecoder * mpeg_dec) +{ + gst_vdp_mpeg_decoder_flush (mpeg_dec); - //mpeg_dec->byterate = -1; + if (mpeg_dec->decoder != VDP_INVALID_HANDLE) + mpeg_dec->device->vdp_decoder_destroy (mpeg_dec->decoder); + mpeg_dec->decoder = VDP_INVALID_HANDLE; + if (mpeg_dec->device) + g_object_unref (mpeg_dec->device); + mpeg_dec->device = NULL; + + mpeg_dec->broken_gop = FALSE; + mpeg_dec->next_timestamp = 0; } static GstFlowReturn @@ -548,7 +562,7 @@ gst_vdp_mpeg_decoder_chain (GstPad * pad, GstBuffer * buffer) if (G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT))) { GST_DEBUG_OBJECT (mpeg_dec, "Received discont buffer"); - gst_vdp_mpeg_decoder_reset (mpeg_dec); + gst_vdp_mpeg_decoder_flush (mpeg_dec); } gst_vdp_mpeg_packetizer_init (&packetizer, buffer); @@ -733,7 +747,7 @@ gst_vdp_mpeg_decoder_sink_event (GstPad * pad, GstEvent * event) { GST_DEBUG_OBJECT (mpeg_dec, "flush stop"); - gst_vdp_mpeg_decoder_reset (mpeg_dec); + gst_vdp_mpeg_decoder_flush (mpeg_dec); res = gst_pad_push_event (mpeg_dec->src, event); break; @@ -767,12 +781,6 @@ gst_vdp_mpeg_decoder_change_state (GstElement * element, switch (transition) { case GST_STATE_CHANGE_PAUSED_TO_READY: gst_vdp_mpeg_decoder_reset (mpeg_dec); - - mpeg_dec->device->vdp_decoder_destroy (mpeg_dec->decoder); - mpeg_dec->decoder = VDP_INVALID_HANDLE; - - g_object_unref (mpeg_dec->device); - mpeg_dec->device = NULL; break; default: break; @@ -860,15 +868,14 @@ gst_vdp_mpeg_decoder_init (GstVdpMpegDecoder * mpeg_dec, gst_element_add_pad (GST_ELEMENT (mpeg_dec), mpeg_dec->sink); mpeg_dec->display_name = NULL; - mpeg_dec->device = NULL; - - mpeg_dec->decoder = VDP_INVALID_HANDLE; - gst_vdp_mpeg_decoder_init_info (&mpeg_dec->vdp_info); + mpeg_dec->adapter = gst_adapter_new (); mpeg_dec->broken_gop = FALSE; mpeg_dec->next_timestamp = 0; - mpeg_dec->adapter = gst_adapter_new (); + mpeg_dec->device = NULL; + mpeg_dec->decoder = VDP_INVALID_HANDLE; + gst_vdp_mpeg_decoder_init_info (&mpeg_dec->vdp_info); } static void -- cgit v1.2.1 From f4c0de5a678a7d81c7caf963b8b67a0a102c5f3a Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Fri, 5 Jun 2009 11:52:32 +0200 Subject: vdpaumpegdec: remove unused broken_gop field --- sys/vdpau/gstvdpmpegdecoder.c | 4 ---- sys/vdpau/gstvdpmpegdecoder.h | 1 - 2 files changed, 5 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpmpegdecoder.c b/sys/vdpau/gstvdpmpegdecoder.c index bee76f1f..b2c59344 100644 --- a/sys/vdpau/gstvdpmpegdecoder.c +++ b/sys/vdpau/gstvdpmpegdecoder.c @@ -500,8 +500,6 @@ gst_vdp_mpeg_decoder_parse_gop (GstVdpMpegDecoder * mpeg_dec, if (!mpeg_util_parse_gop (&gop, buffer)) return FALSE; - mpeg_dec->broken_gop = gop.broken_gop; - return TRUE; } @@ -546,7 +544,6 @@ gst_vdp_mpeg_decoder_reset (GstVdpMpegDecoder * mpeg_dec) g_object_unref (mpeg_dec->device); mpeg_dec->device = NULL; - mpeg_dec->broken_gop = FALSE; mpeg_dec->next_timestamp = 0; } @@ -870,7 +867,6 @@ gst_vdp_mpeg_decoder_init (GstVdpMpegDecoder * mpeg_dec, mpeg_dec->display_name = NULL; mpeg_dec->adapter = gst_adapter_new (); - mpeg_dec->broken_gop = FALSE; mpeg_dec->next_timestamp = 0; mpeg_dec->device = NULL; diff --git a/sys/vdpau/gstvdpmpegdecoder.h b/sys/vdpau/gstvdpmpegdecoder.h index 597101f8..37b7ead3 100644 --- a/sys/vdpau/gstvdpmpegdecoder.h +++ b/sys/vdpau/gstvdpmpegdecoder.h @@ -59,7 +59,6 @@ struct _GstVdpMpegDecoder GstBuffer *f_buffer; GstBuffer *b_buffer; - gboolean broken_gop; GstClockTime duration; GstClockTime next_timestamp; -- cgit v1.2.1 From 016f24f8be5a441e070a8e0c941ab050079f3ec9 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Fri, 5 Jun 2009 11:54:17 +0200 Subject: vdpaumpegdec: change a GST_DEBUG to GST_WARNING --- sys/vdpau/gstvdpmpegdecoder.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpmpegdecoder.c b/sys/vdpau/gstvdpmpegdecoder.c index b2c59344..3e817185 100644 --- a/sys/vdpau/gstvdpmpegdecoder.c +++ b/sys/vdpau/gstvdpmpegdecoder.c @@ -426,7 +426,7 @@ gst_vdp_mpeg_decoder_parse_picture_coding (GstVdpMpegDecoder * mpeg_dec, GST_DEBUG ("fields: %d", fields); if (!fields) { - GST_DEBUG ("Invalid Picture Extension packet"); + GST_WARNING ("Invalid Picture Extension packet"); return FALSE; } -- cgit v1.2.1 From 7316cfa186322a4b3c2e6df558a41e1ecc8c6e91 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Fri, 5 Jun 2009 17:43:49 +0200 Subject: vdpaumpegdec: implement seeking --- sys/vdpau/gstvdpmpegdecoder.c | 169 ++++++++++++++++++++++++++++++++++++++++-- sys/vdpau/gstvdpmpegdecoder.h | 5 ++ 2 files changed, 166 insertions(+), 8 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpmpegdecoder.c b/sys/vdpau/gstvdpmpegdecoder.c index 3e817185..b6964175 100644 --- a/sys/vdpau/gstvdpmpegdecoder.c +++ b/sys/vdpau/gstvdpmpegdecoder.c @@ -279,10 +279,25 @@ GstFlowReturn gst_vdp_mpeg_decoder_push_video_buffer (GstVdpMpegDecoder * mpeg_dec, GstVdpVideoBuffer * buffer) { - if (GST_BUFFER_TIMESTAMP (buffer) == GST_CLOCK_TIME_NONE) { + if (GST_BUFFER_TIMESTAMP (buffer) == GST_CLOCK_TIME_NONE + && GST_CLOCK_TIME_IS_VALID (mpeg_dec->next_timestamp)) { GST_BUFFER_TIMESTAMP (buffer) = mpeg_dec->next_timestamp; + } else if (GST_BUFFER_TIMESTAMP (buffer) == GST_CLOCK_TIME_NONE) { + GST_BUFFER_TIMESTAMP (buffer) = gst_util_uint64_scale (mpeg_dec->frame_nr, + GST_SECOND * mpeg_dec->fps_d, mpeg_dec->fps_n); } + if (mpeg_dec->seeking) { + GstEvent *event; + + event = gst_event_new_new_segment (FALSE, + mpeg_dec->segment.rate, GST_FORMAT_TIME, GST_BUFFER_TIMESTAMP (buffer), + mpeg_dec->segment.stop, GST_BUFFER_TIMESTAMP (buffer)); + + gst_pad_push_event (mpeg_dec->src, event); + } + mpeg_dec->seeking = FALSE; + mpeg_dec->next_timestamp = GST_BUFFER_TIMESTAMP (buffer) + GST_BUFFER_DURATION (buffer); @@ -334,6 +349,7 @@ gst_vdp_mpeg_decoder_decode (GstVdpMpegDecoder * mpeg_dec, mpeg_dec->width, mpeg_dec->height); GST_BUFFER_TIMESTAMP (outbuf) = timestamp; GST_BUFFER_DURATION (outbuf) = mpeg_dec->duration; + GST_BUFFER_OFFSET (outbuf) = mpeg_dec->frame_nr; if (info->forward_reference != VDP_INVALID_HANDLE && info->picture_coding_type != I_FRAME) @@ -403,7 +419,7 @@ gst_vdp_mpeg_decoder_parse_picture_coding (GstVdpMpegDecoder * mpeg_dec, info->intra_vlc_format = pic_ext.intra_vlc_format; info->alternate_scan = pic_ext.alternate_scan; - fields = 0; + fields = 2; if (pic_ext.picture_structure == 3) { if (mpeg_dec->interlaced) { if (pic_ext.progressive_frame == 0) @@ -425,11 +441,6 @@ gst_vdp_mpeg_decoder_parse_picture_coding (GstVdpMpegDecoder * mpeg_dec, GST_DEBUG ("fields: %d", fields); - if (!fields) { - GST_WARNING ("Invalid Picture Extension packet"); - return FALSE; - } - mpeg_dec->duration = gst_util_uint64_scale (fields, GST_SECOND * mpeg_dec->fps_d, 2 * mpeg_dec->fps_n); @@ -488,6 +499,8 @@ gst_vdp_mpeg_decoder_parse_picture (GstVdpMpegDecoder * mpeg_dec, mpeg_dec->duration = gst_util_uint64_scale (1, GST_SECOND * mpeg_dec->fps_d, mpeg_dec->fps_n); + mpeg_dec->frame_nr = mpeg_dec->gop_frame + pic_hdr.tsn; + return TRUE; } @@ -496,10 +509,19 @@ gst_vdp_mpeg_decoder_parse_gop (GstVdpMpegDecoder * mpeg_dec, GstBuffer * buffer) { MPEGGop gop; + GstClockTime time; if (!mpeg_util_parse_gop (&gop, buffer)) return FALSE; + time = GST_SECOND * (gop.hour * 3600 + gop.minute * 60 + gop.second); + + GST_DEBUG ("gop timestamp: %" GST_TIME_FORMAT, GST_TIME_ARGS (time)); + + mpeg_dec->gop_frame = + gst_util_uint64_scale (time, mpeg_dec->fps_n, + mpeg_dec->fps_d * GST_SECOND) + gop.frame; + return TRUE; } @@ -530,6 +552,8 @@ gst_vdp_mpeg_decoder_flush (GstVdpMpegDecoder * mpeg_dec) gst_vdp_mpeg_decoder_init_info (&mpeg_dec->vdp_info); gst_adapter_clear (mpeg_dec->adapter); + + mpeg_dec->next_timestamp = GST_CLOCK_TIME_NONE; } static void @@ -544,7 +568,8 @@ gst_vdp_mpeg_decoder_reset (GstVdpMpegDecoder * mpeg_dec) g_object_unref (mpeg_dec->device); mpeg_dec->device = NULL; - mpeg_dec->next_timestamp = 0; + gst_segment_init (&mpeg_dec->segment, GST_FORMAT_TIME); + mpeg_dec->seeking = FALSE; } static GstFlowReturn @@ -733,6 +758,94 @@ gst_vdp_mpeg_decoder_src_query (GstPad * pad, GstQuery * query) return res; } +static gboolean +normal_seek (GstPad * pad, GstEvent * event) +{ + GstVdpMpegDecoder *mpeg_dec = GST_VDP_MPEG_DECODER (GST_OBJECT_PARENT (pad)); + gdouble rate; + GstFormat format, conv; + GstSeekFlags flags; + GstSeekType cur_type, stop_type; + gint64 cur, stop; + gint64 time_cur, bytes_cur; + gint64 time_stop, bytes_stop; + gboolean res; + GstEvent *peer_event; + + GST_DEBUG ("normal seek"); + + gst_event_parse_seek (event, &rate, &format, &flags, + &cur_type, &cur, &stop_type, &stop); + + conv = GST_FORMAT_TIME; + if (!gst_vdp_mpeg_decoder_convert (mpeg_dec, format, cur, conv, &time_cur)) + goto convert_failed; + if (!gst_vdp_mpeg_decoder_convert (mpeg_dec, format, stop, conv, &time_stop)) + goto convert_failed; + + GST_DEBUG ("seek to time %" GST_TIME_FORMAT "-%" GST_TIME_FORMAT, + GST_TIME_ARGS (time_cur), GST_TIME_ARGS (time_stop)); + + peer_event = gst_event_new_seek (rate, GST_FORMAT_TIME, flags, + cur_type, time_cur, stop_type, time_stop); + + /* try seek on time then */ + if ((res = gst_pad_push_event (mpeg_dec->sink, peer_event))) + goto done; + + /* else we try to seek on bytes */ + conv = GST_FORMAT_BYTES; + if (!gst_vdp_mpeg_decoder_convert (mpeg_dec, GST_FORMAT_TIME, time_cur, + conv, &bytes_cur)) + goto convert_failed; + if (!gst_vdp_mpeg_decoder_convert (mpeg_dec, GST_FORMAT_TIME, time_stop, + conv, &bytes_stop)) + goto convert_failed; + + /* conversion succeeded, create the seek */ + peer_event = + gst_event_new_seek (rate, GST_FORMAT_BYTES, flags, + cur_type, bytes_cur, stop_type, bytes_stop); + + /* do the seek */ + res = gst_pad_push_event (mpeg_dec->sink, peer_event); + + mpeg_dec->seeking = TRUE; + +done: + return res; + + /* ERRORS */ +convert_failed: + { + /* probably unsupported seek format */ + GST_DEBUG_OBJECT (mpeg_dec, + "failed to convert format %u into GST_FORMAT_TIME", format); + return FALSE; + } +} + +static gboolean +gst_vdp_mpeg_decoder_src_event (GstPad * pad, GstEvent * event) +{ + gboolean res; + + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_SEEK: + { + if (gst_pad_event_default (pad, event)) + return TRUE; + + res = normal_seek (pad, event); + break; + } + default: + res = gst_pad_event_default (pad, event); + } + + return res; +} + static gboolean gst_vdp_mpeg_decoder_sink_event (GstPad * pad, GstEvent * event) { @@ -749,6 +862,42 @@ gst_vdp_mpeg_decoder_sink_event (GstPad * pad, GstEvent * event) break; } + case GST_EVENT_NEWSEGMENT: + { + gboolean update; + gdouble rate; + GstFormat format; + gint64 start; + gint64 stop; + gint64 position; + + gst_event_parse_new_segment (event, &update, &rate, &format, + &start, &stop, &position); + + if (format != GST_FORMAT_TIME) { + if (!gst_vdp_mpeg_decoder_convert (mpeg_dec, format, start, + GST_FORMAT_TIME, &start)) + goto convert_error; + if (!gst_vdp_mpeg_decoder_convert (mpeg_dec, format, stop, + GST_FORMAT_TIME, &stop)) + goto convert_error; + if (!gst_vdp_mpeg_decoder_convert (mpeg_dec, format, position, + GST_FORMAT_TIME, &position)) + goto convert_error; + + gst_segment_set_newsegment (&mpeg_dec->segment, update, rate, + GST_FORMAT_TIME, start, stop, position); + + gst_event_unref (event); + event = gst_event_new_new_segment (update, rate, GST_FORMAT_TIME, start, + stop, position); + } + + convert_error: + gst_pad_push_event (mpeg_dec->src, event); + + break; + } default: res = gst_pad_event_default (pad, event); } @@ -849,6 +998,8 @@ gst_vdp_mpeg_decoder_init (GstVdpMpegDecoder * mpeg_dec, GstVdpMpegDecoderClass * gclass) { mpeg_dec->src = gst_pad_new_from_static_template (&src_template, "src"); + gst_pad_set_event_function (mpeg_dec->src, + GST_DEBUG_FUNCPTR (gst_vdp_mpeg_decoder_src_event)); gst_pad_set_query_function (mpeg_dec->src, GST_DEBUG_FUNCPTR (gst_vdp_mpeg_decoder_src_query)); gst_pad_set_query_type_function (mpeg_dec->src, @@ -872,6 +1023,8 @@ gst_vdp_mpeg_decoder_init (GstVdpMpegDecoder * mpeg_dec, mpeg_dec->device = NULL; mpeg_dec->decoder = VDP_INVALID_HANDLE; gst_vdp_mpeg_decoder_init_info (&mpeg_dec->vdp_info); + + gst_segment_init (&mpeg_dec->segment, GST_FORMAT_TIME); } static void diff --git a/sys/vdpau/gstvdpmpegdecoder.h b/sys/vdpau/gstvdpmpegdecoder.h index 37b7ead3..9a57e283 100644 --- a/sys/vdpau/gstvdpmpegdecoder.h +++ b/sys/vdpau/gstvdpmpegdecoder.h @@ -62,6 +62,11 @@ struct _GstVdpMpegDecoder GstClockTime duration; GstClockTime next_timestamp; + guint64 gop_frame; + guint64 frame_nr; + + GstSegment segment; + gboolean seeking; gint64 byterate; GstAdapter *adapter; -- cgit v1.2.1 From 3864e0349bb29a7a5bb4ff5961c2e72a14500811 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Fri, 5 Jun 2009 17:53:16 +0200 Subject: vdpaumpegdec: don't send the EVENT_NEWSEGMENT downstream if we're seeking --- sys/vdpau/gstvdpmpegdecoder.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpmpegdecoder.c b/sys/vdpau/gstvdpmpegdecoder.c index b6964175..db01527d 100644 --- a/sys/vdpau/gstvdpmpegdecoder.c +++ b/sys/vdpau/gstvdpmpegdecoder.c @@ -893,8 +893,15 @@ gst_vdp_mpeg_decoder_sink_event (GstPad * pad, GstEvent * event) stop, position); } + /* if we seek ourselves we don't push out a newsegment now since we + * use the calculated timestamp of the first frame for this */ + if (mpeg_dec->seeking) { + gst_event_unref (event); + return TRUE; + } + convert_error: - gst_pad_push_event (mpeg_dec->src, event); + res = gst_pad_push_event (mpeg_dec->src, event); break; } -- cgit v1.2.1 From 757086e3fa0b034b1b9b145f65a0512acc21f4d2 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Fri, 5 Jun 2009 18:18:38 +0200 Subject: vdpaumpegdec: only set base duration once --- sys/vdpau/gstvdpmpegdecoder.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpmpegdecoder.c b/sys/vdpau/gstvdpmpegdecoder.c index db01527d..9475a948 100644 --- a/sys/vdpau/gstvdpmpegdecoder.c +++ b/sys/vdpau/gstvdpmpegdecoder.c @@ -251,6 +251,10 @@ gst_vdp_mpeg_decoder_set_caps (GstPad * pad, GstCaps * caps) gst_buffer_unref (buf); } + mpeg_dec->duration = + gst_util_uint64_scale (1, GST_SECOND * mpeg_dec->fps_d, + mpeg_dec->fps_n); + mpeg_dec->byterate = bitrate * 50; GST_DEBUG ("byterate: %" G_GINT64_FORMAT, mpeg_dec->byterate); } @@ -496,9 +500,6 @@ gst_vdp_mpeg_decoder_parse_picture (GstVdpMpegDecoder * mpeg_dec, memcpy (&mpeg_dec->vdp_info.f_code, &pic_hdr.f_code, 4); } - mpeg_dec->duration = gst_util_uint64_scale (1, GST_SECOND * mpeg_dec->fps_d, - mpeg_dec->fps_n); - mpeg_dec->frame_nr = mpeg_dec->gop_frame + pic_hdr.tsn; return TRUE; @@ -1025,13 +1026,12 @@ gst_vdp_mpeg_decoder_init (GstVdpMpegDecoder * mpeg_dec, mpeg_dec->display_name = NULL; mpeg_dec->adapter = gst_adapter_new (); - mpeg_dec->next_timestamp = 0; - mpeg_dec->device = NULL; mpeg_dec->decoder = VDP_INVALID_HANDLE; - gst_vdp_mpeg_decoder_init_info (&mpeg_dec->vdp_info); + mpeg_dec->vdp_info.forward_reference = VDP_INVALID_HANDLE; + mpeg_dec->vdp_info.backward_reference = VDP_INVALID_HANDLE; - gst_segment_init (&mpeg_dec->segment, GST_FORMAT_TIME); + gst_vdp_mpeg_decoder_reset (mpeg_dec); } static void -- cgit v1.2.1 From b2aa8ae9454cf0b57c98b11c3909759e1968490e Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Fri, 5 Jun 2009 18:28:17 +0200 Subject: vdpaumpegdec: interlaced fixes --- sys/vdpau/gstvdpmpegdecoder.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpmpegdecoder.c b/sys/vdpau/gstvdpmpegdecoder.c index 9475a948..fd06ea3b 100644 --- a/sys/vdpau/gstvdpmpegdecoder.c +++ b/sys/vdpau/gstvdpmpegdecoder.c @@ -167,7 +167,7 @@ gst_vdp_mpeg_decoder_set_caps (GstPad * pad, GstCaps * caps) gint width, height; gint fps_n, fps_d; gint par_n, par_d; - gboolean interlaced; + gboolean interlaced = FALSE; GstCaps *src_caps; gboolean res; @@ -354,6 +354,8 @@ gst_vdp_mpeg_decoder_decode (GstVdpMpegDecoder * mpeg_dec, GST_BUFFER_TIMESTAMP (outbuf) = timestamp; GST_BUFFER_DURATION (outbuf) = mpeg_dec->duration; GST_BUFFER_OFFSET (outbuf) = mpeg_dec->frame_nr; + if (info->top_field_first) + GST_BUFFER_FLAG_SET (outbuf, GST_VIDEO_BUFFER_TFF); if (info->forward_reference != VDP_INVALID_HANDLE && info->picture_coding_type != I_FRAME) -- cgit v1.2.1 From c9464b98604dd6023f5985f4d29e1bb4051d58ee Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Fri, 5 Jun 2009 19:08:24 +0200 Subject: vdpaumpegdec: print frame_nr in debug print --- sys/vdpau/gstvdpmpegdecoder.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpmpegdecoder.c b/sys/vdpau/gstvdpmpegdecoder.c index fd06ea3b..04bebb8a 100644 --- a/sys/vdpau/gstvdpmpegdecoder.c +++ b/sys/vdpau/gstvdpmpegdecoder.c @@ -308,8 +308,10 @@ gst_vdp_mpeg_decoder_push_video_buffer (GstVdpMpegDecoder * mpeg_dec, gst_buffer_set_caps (GST_BUFFER (buffer), GST_PAD_CAPS (mpeg_dec->src)); GST_DEBUG_OBJECT (mpeg_dec, - "Pushing buffer with timestamp: %" GST_TIME_FORMAT, - GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer))); + "Pushing buffer with timestamp: %" GST_TIME_FORMAT + " frame_nr: %" G_GINT64_FORMAT, + GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)), + GST_BUFFER_OFFSET (buffer)); return gst_pad_push (mpeg_dec->src, GST_BUFFER (buffer)); } -- cgit v1.2.1 From c4276ae568934f5f14beab02199849f6aeb757ac Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Fri, 5 Jun 2009 21:16:48 +0200 Subject: vdpaumpegdec: calculate byterate from the size of the incoming data --- sys/vdpau/gstvdpmpegdecoder.c | 16 ++++++++++++++++ sys/vdpau/gstvdpmpegdecoder.h | 34 ++++++++++++++++++++++------------ 2 files changed, 38 insertions(+), 12 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpmpegdecoder.c b/sys/vdpau/gstvdpmpegdecoder.c index 04bebb8a..53e99a5f 100644 --- a/sys/vdpau/gstvdpmpegdecoder.c +++ b/sys/vdpau/gstvdpmpegdecoder.c @@ -283,6 +283,8 @@ GstFlowReturn gst_vdp_mpeg_decoder_push_video_buffer (GstVdpMpegDecoder * mpeg_dec, GstVdpVideoBuffer * buffer) { + gint64 byterate; + if (GST_BUFFER_TIMESTAMP (buffer) == GST_CLOCK_TIME_NONE && GST_CLOCK_TIME_IS_VALID (mpeg_dec->next_timestamp)) { GST_BUFFER_TIMESTAMP (buffer) = mpeg_dec->next_timestamp; @@ -305,6 +307,14 @@ gst_vdp_mpeg_decoder_push_video_buffer (GstVdpMpegDecoder * mpeg_dec, mpeg_dec->next_timestamp = GST_BUFFER_TIMESTAMP (buffer) + GST_BUFFER_DURATION (buffer); + mpeg_dec->accumulated_duration += GST_BUFFER_DURATION (buffer); + mpeg_dec->accumulated_size += GST_BUFFER_SIZE (buffer); + byterate = gst_util_uint64_scale (mpeg_dec->accumulated_size, GST_SECOND, + mpeg_dec->accumulated_duration); + GST_DEBUG ("byterate: %" G_GINT64_FORMAT, mpeg_dec->byterate); + + mpeg_dec->byterate = (mpeg_dec->byterate + byterate) / 2; + gst_buffer_set_caps (GST_BUFFER (buffer), GST_PAD_CAPS (mpeg_dec->src)); GST_DEBUG_OBJECT (mpeg_dec, @@ -356,6 +366,8 @@ gst_vdp_mpeg_decoder_decode (GstVdpMpegDecoder * mpeg_dec, GST_BUFFER_TIMESTAMP (outbuf) = timestamp; GST_BUFFER_DURATION (outbuf) = mpeg_dec->duration; GST_BUFFER_OFFSET (outbuf) = mpeg_dec->frame_nr; + GST_BUFFER_SIZE (outbuf) = mpeg_dec->size; + if (info->top_field_first) GST_BUFFER_FLAG_SET (outbuf, GST_VIDEO_BUFFER_TFF); @@ -575,6 +587,9 @@ gst_vdp_mpeg_decoder_reset (GstVdpMpegDecoder * mpeg_dec) gst_segment_init (&mpeg_dec->segment, GST_FORMAT_TIME); mpeg_dec->seeking = FALSE; + + mpeg_dec->accumulated_size = 0; + mpeg_dec->accumulated_duration = 0; } static GstFlowReturn @@ -592,6 +607,7 @@ gst_vdp_mpeg_decoder_chain (GstPad * pad, GstBuffer * buffer) gst_vdp_mpeg_decoder_flush (mpeg_dec); } + mpeg_dec->size = GST_BUFFER_SIZE (buffer); gst_vdp_mpeg_packetizer_init (&packetizer, buffer); while ((buf = gst_vdp_mpeg_packetizer_get_next_packet (&packetizer))) { GstBitReader b_reader = GST_BIT_READER_INIT_FROM_BUFFER (buf); diff --git a/sys/vdpau/gstvdpmpegdecoder.h b/sys/vdpau/gstvdpmpegdecoder.h index 9a57e283..3cd521ba 100644 --- a/sys/vdpau/gstvdpmpegdecoder.h +++ b/sys/vdpau/gstvdpmpegdecoder.h @@ -42,34 +42,44 @@ struct _GstVdpMpegDecoder { GstElement element; - gchar *display_name; - GstVdpDevice *device; - + /* pads */ GstPad *src; GstPad *sink; + + gchar *display_name; + GstVdpDevice *device; + VdpDecoder decoder; + /* stream info */ gint width, height; gint fps_n, fps_d; gboolean interlaced; - gint version; - - VdpDecoder decoder; + + /* currently decoded frame info */ + GstAdapter *adapter; VdpPictureInfoMPEG1Or2 vdp_info; - GstBuffer *f_buffer; - GstBuffer *b_buffer; - + guint64 size; + guint64 frame_nr; GstClockTime duration; - GstClockTime next_timestamp; + /* frame_nr from GOP */ guint64 gop_frame; - guint64 frame_nr; + + /* forward and backward reference */ + GstBuffer *f_buffer; + GstBuffer *b_buffer; + /* calculated timestamp, size and duration */ + GstClockTime next_timestamp; + guint64 accumulated_size; + guint64 accumulated_duration; + + /* seek data */ GstSegment segment; gboolean seeking; gint64 byterate; - GstAdapter *adapter; }; struct _GstVdpMpegDecoderClass -- cgit v1.2.1 From 7c0e5b5c22e0556567978d13b2c00b9c758d3513 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Fri, 5 Jun 2009 21:18:47 +0200 Subject: vdpaumpegdec: small cleanup --- sys/vdpau/gstvdpmpegdecoder.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpmpegdecoder.c b/sys/vdpau/gstvdpmpegdecoder.c index 53e99a5f..da4f63ec 100644 --- a/sys/vdpau/gstvdpmpegdecoder.c +++ b/sys/vdpau/gstvdpmpegdecoder.c @@ -301,8 +301,9 @@ gst_vdp_mpeg_decoder_push_video_buffer (GstVdpMpegDecoder * mpeg_dec, mpeg_dec->segment.stop, GST_BUFFER_TIMESTAMP (buffer)); gst_pad_push_event (mpeg_dec->src, event); + + mpeg_dec->seeking = FALSE; } - mpeg_dec->seeking = FALSE; mpeg_dec->next_timestamp = GST_BUFFER_TIMESTAMP (buffer) + GST_BUFFER_DURATION (buffer); -- cgit v1.2.1 From 5956df5338d0f3f3763bd8aa9e0e4b7b501a8469 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Fri, 5 Jun 2009 21:42:30 +0200 Subject: vdpaumpegdec: pass buffer size directly to gst_vdp_mpeg_decoder_decode --- sys/vdpau/gstvdpmpegdecoder.c | 8 ++++---- sys/vdpau/gstvdpmpegdecoder.h | 1 - 2 files changed, 4 insertions(+), 5 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpmpegdecoder.c b/sys/vdpau/gstvdpmpegdecoder.c index da4f63ec..6968c347 100644 --- a/sys/vdpau/gstvdpmpegdecoder.c +++ b/sys/vdpau/gstvdpmpegdecoder.c @@ -329,7 +329,7 @@ gst_vdp_mpeg_decoder_push_video_buffer (GstVdpMpegDecoder * mpeg_dec, static GstFlowReturn gst_vdp_mpeg_decoder_decode (GstVdpMpegDecoder * mpeg_dec, - GstClockTime timestamp) + GstClockTime timestamp, gint64 size) { VdpPictureInfoMPEG1Or2 *info; GstBuffer *buffer; @@ -367,7 +367,7 @@ gst_vdp_mpeg_decoder_decode (GstVdpMpegDecoder * mpeg_dec, GST_BUFFER_TIMESTAMP (outbuf) = timestamp; GST_BUFFER_DURATION (outbuf) = mpeg_dec->duration; GST_BUFFER_OFFSET (outbuf) = mpeg_dec->frame_nr; - GST_BUFFER_SIZE (outbuf) = mpeg_dec->size; + GST_BUFFER_SIZE (outbuf) = size; if (info->top_field_first) GST_BUFFER_FLAG_SET (outbuf, GST_VIDEO_BUFFER_TFF); @@ -608,7 +608,6 @@ gst_vdp_mpeg_decoder_chain (GstPad * pad, GstBuffer * buffer) gst_vdp_mpeg_decoder_flush (mpeg_dec); } - mpeg_dec->size = GST_BUFFER_SIZE (buffer); gst_vdp_mpeg_packetizer_init (&packetizer, buffer); while ((buf = gst_vdp_mpeg_packetizer_get_next_packet (&packetizer))) { GstBitReader b_reader = GST_BIT_READER_INIT_FROM_BUFFER (buf); @@ -676,7 +675,8 @@ gst_vdp_mpeg_decoder_chain (GstPad * pad, GstBuffer * buffer) } if (mpeg_dec->vdp_info.slice_count > 0) - ret = gst_vdp_mpeg_decoder_decode (mpeg_dec, GST_BUFFER_TIMESTAMP (buffer)); + ret = gst_vdp_mpeg_decoder_decode (mpeg_dec, GST_BUFFER_TIMESTAMP (buffer), + GST_BUFFER_SIZE (buffer)); return ret; } diff --git a/sys/vdpau/gstvdpmpegdecoder.h b/sys/vdpau/gstvdpmpegdecoder.h index 3cd521ba..e1300862 100644 --- a/sys/vdpau/gstvdpmpegdecoder.h +++ b/sys/vdpau/gstvdpmpegdecoder.h @@ -59,7 +59,6 @@ struct _GstVdpMpegDecoder /* currently decoded frame info */ GstAdapter *adapter; VdpPictureInfoMPEG1Or2 vdp_info; - guint64 size; guint64 frame_nr; GstClockTime duration; -- cgit v1.2.1 From f0134f18472a55581383f15a32d692cb5adf0e53 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Fri, 5 Jun 2009 21:46:08 +0200 Subject: vdpaumpegdec: rename GstVdpMpegDecoder to GstVdpMpegDec --- sys/vdpau/gstvdp.c | 2 +- sys/vdpau/gstvdpmpegdecoder.c | 156 ++++++++++++++++++++---------------------- sys/vdpau/gstvdpmpegdecoder.h | 26 +++---- 3 files changed, 90 insertions(+), 94 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdp.c b/sys/vdpau/gstvdp.c index 8d5be3dc..43360483 100644 --- a/sys/vdpau/gstvdp.c +++ b/sys/vdpau/gstvdp.c @@ -13,7 +13,7 @@ static gboolean vdpau_init (GstPlugin * vdpau_plugin) { gst_element_register (vdpau_plugin, "vdpaumpegdec", - GST_RANK_PRIMARY - 1, GST_TYPE_VDP_MPEG_DECODER); + GST_RANK_PRIMARY - 1, GST_TYPE_VDP_MPEG_DEC); gst_element_register (vdpau_plugin, "vdpauvideoyuv", GST_RANK_PRIMARY, GST_TYPE_VDP_VIDEO_YUV); gst_element_register (vdpau_plugin, "vdpauyuvvideo", diff --git a/sys/vdpau/gstvdpmpegdecoder.c b/sys/vdpau/gstvdpmpegdecoder.c index 6968c347..3c4d7480 100644 --- a/sys/vdpau/gstvdpmpegdecoder.c +++ b/sys/vdpau/gstvdpmpegdecoder.c @@ -43,8 +43,8 @@ #include "mpegutil.h" #include "gstvdpmpegdecoder.h" -GST_DEBUG_CATEGORY_STATIC (gst_vdp_mpeg_decoder_debug); -#define GST_CAT_DEFAULT gst_vdp_mpeg_decoder_debug +GST_DEBUG_CATEGORY_STATIC (gst_vdp_mpeg_dec_debug); +#define GST_CAT_DEFAULT gst_vdp_mpeg_dec_debug /* Filter signals and args */ enum @@ -76,16 +76,16 @@ static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src", ); #define DEBUG_INIT(bla) \ -GST_DEBUG_CATEGORY_INIT (gst_vdp_mpeg_decoder_debug, "vdpaumpegdec", 0, "VDPAU powered mpeg decoder"); +GST_DEBUG_CATEGORY_INIT (gst_vdp_mpeg_dec_debug, "vdpaumpegdec", 0, "VDPAU powered mpeg decoder"); -GST_BOILERPLATE_FULL (GstVdpMpegDecoder, gst_vdp_mpeg_decoder, +GST_BOILERPLATE_FULL (GstVdpMpegDec, gst_vdp_mpeg_dec, GstElement, GST_TYPE_ELEMENT, DEBUG_INIT); -static void gst_vdp_mpeg_decoder_init_info (VdpPictureInfoMPEG1Or2 * vdp_info); -static void gst_vdp_mpeg_decoder_finalize (GObject * object); -static void gst_vdp_mpeg_decoder_set_property (GObject * object, +static void gst_vdp_mpeg_dec_init_info (VdpPictureInfoMPEG1Or2 * vdp_info); +static void gst_vdp_mpeg_dec_finalize (GObject * object); +static void gst_vdp_mpeg_dec_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec); -static void gst_vdp_mpeg_decoder_get_property (GObject * object, +static void gst_vdp_mpeg_dec_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); guint8 * @@ -159,9 +159,9 @@ gst_vdp_mpeg_packetizer_init (GstVdpMpegPacketizer * packetizer, } static gboolean -gst_vdp_mpeg_decoder_set_caps (GstPad * pad, GstCaps * caps) +gst_vdp_mpeg_dec_set_caps (GstPad * pad, GstCaps * caps) { - GstVdpMpegDecoder *mpeg_dec = GST_VDP_MPEG_DECODER (GST_OBJECT_PARENT (pad)); + GstVdpMpegDec *mpeg_dec = GST_VDP_MPEG_DEC (GST_OBJECT_PARENT (pad)); GstStructure *structure; gint width, height; @@ -280,7 +280,7 @@ gst_vdp_mpeg_decoder_set_caps (GstPad * pad, GstCaps * caps) } GstFlowReturn -gst_vdp_mpeg_decoder_push_video_buffer (GstVdpMpegDecoder * mpeg_dec, +gst_vdp_mpeg_dec_push_video_buffer (GstVdpMpegDec * mpeg_dec, GstVdpVideoBuffer * buffer) { gint64 byterate; @@ -328,7 +328,7 @@ gst_vdp_mpeg_decoder_push_video_buffer (GstVdpMpegDecoder * mpeg_dec, } static GstFlowReturn -gst_vdp_mpeg_decoder_decode (GstVdpMpegDecoder * mpeg_dec, +gst_vdp_mpeg_dec_decode (GstVdpMpegDec * mpeg_dec, GstClockTime timestamp, gint64 size) { VdpPictureInfoMPEG1Or2 *info; @@ -347,7 +347,7 @@ gst_vdp_mpeg_decoder_decode (GstVdpMpegDecoder * mpeg_dec, if (info->picture_coding_type != B_FRAME) { if (info->backward_reference != VDP_INVALID_HANDLE) { gst_buffer_ref (mpeg_dec->b_buffer); - gst_vdp_mpeg_decoder_push_video_buffer (mpeg_dec, + gst_vdp_mpeg_dec_push_video_buffer (mpeg_dec, GST_VDP_VIDEO_BUFFER (mpeg_dec->b_buffer)); } @@ -406,7 +406,7 @@ gst_vdp_mpeg_decoder_decode (GstVdpMpegDecoder * mpeg_dec, } if (info->picture_coding_type == B_FRAME) { - gst_vdp_mpeg_decoder_push_video_buffer (mpeg_dec, + gst_vdp_mpeg_dec_push_video_buffer (mpeg_dec, GST_VDP_VIDEO_BUFFER (outbuf)); } else { info->backward_reference = surface; @@ -417,7 +417,7 @@ gst_vdp_mpeg_decoder_decode (GstVdpMpegDecoder * mpeg_dec, } static gboolean -gst_vdp_mpeg_decoder_parse_picture_coding (GstVdpMpegDecoder * mpeg_dec, +gst_vdp_mpeg_dec_parse_picture_coding (GstVdpMpegDec * mpeg_dec, GstBuffer * buffer) { MPEGPictureExt pic_ext; @@ -469,8 +469,7 @@ gst_vdp_mpeg_decoder_parse_picture_coding (GstVdpMpegDecoder * mpeg_dec, } static gboolean -gst_vdp_mpeg_decoder_parse_sequence (GstVdpMpegDecoder * mpeg_dec, - GstBuffer * buffer) +gst_vdp_mpeg_dec_parse_sequence (GstVdpMpegDec * mpeg_dec, GstBuffer * buffer) { MPEGSeqHdr hdr; @@ -486,8 +485,7 @@ gst_vdp_mpeg_decoder_parse_sequence (GstVdpMpegDecoder * mpeg_dec, } static gboolean -gst_vdp_mpeg_decoder_parse_picture (GstVdpMpegDecoder * mpeg_dec, - GstBuffer * buffer) +gst_vdp_mpeg_dec_parse_picture (GstVdpMpegDec * mpeg_dec, GstBuffer * buffer) { MPEGPictureHdr pic_hdr; @@ -523,8 +521,7 @@ gst_vdp_mpeg_decoder_parse_picture (GstVdpMpegDecoder * mpeg_dec, } static gboolean -gst_vdp_mpeg_decoder_parse_gop (GstVdpMpegDecoder * mpeg_dec, - GstBuffer * buffer) +gst_vdp_mpeg_dec_parse_gop (GstVdpMpegDec * mpeg_dec, GstBuffer * buffer) { MPEGGop gop; GstClockTime time; @@ -544,7 +541,7 @@ gst_vdp_mpeg_decoder_parse_gop (GstVdpMpegDecoder * mpeg_dec, } static gboolean -gst_vdp_mpeg_decoder_parse_quant_matrix (GstVdpMpegDecoder * mpeg_dec, +gst_vdp_mpeg_dec_parse_quant_matrix (GstVdpMpegDec * mpeg_dec, GstBuffer * buffer) { MPEGQuantMatrix qm; @@ -560,14 +557,14 @@ gst_vdp_mpeg_decoder_parse_quant_matrix (GstVdpMpegDecoder * mpeg_dec, } static void -gst_vdp_mpeg_decoder_flush (GstVdpMpegDecoder * mpeg_dec) +gst_vdp_mpeg_dec_flush (GstVdpMpegDec * mpeg_dec) { if (mpeg_dec->vdp_info.forward_reference != VDP_INVALID_HANDLE) gst_buffer_unref (mpeg_dec->f_buffer); if (mpeg_dec->vdp_info.backward_reference != VDP_INVALID_HANDLE) gst_buffer_unref (mpeg_dec->b_buffer); - gst_vdp_mpeg_decoder_init_info (&mpeg_dec->vdp_info); + gst_vdp_mpeg_dec_init_info (&mpeg_dec->vdp_info); gst_adapter_clear (mpeg_dec->adapter); @@ -575,9 +572,9 @@ gst_vdp_mpeg_decoder_flush (GstVdpMpegDecoder * mpeg_dec) } static void -gst_vdp_mpeg_decoder_reset (GstVdpMpegDecoder * mpeg_dec) +gst_vdp_mpeg_dec_reset (GstVdpMpegDec * mpeg_dec) { - gst_vdp_mpeg_decoder_flush (mpeg_dec); + gst_vdp_mpeg_dec_flush (mpeg_dec); if (mpeg_dec->decoder != VDP_INVALID_HANDLE) mpeg_dec->device->vdp_decoder_destroy (mpeg_dec->decoder); @@ -594,20 +591,21 @@ gst_vdp_mpeg_decoder_reset (GstVdpMpegDecoder * mpeg_dec) } static GstFlowReturn -gst_vdp_mpeg_decoder_chain (GstPad * pad, GstBuffer * buffer) +gst_vdp_mpeg_dec_chain (GstPad * pad, GstBuffer * buffer) { - GstVdpMpegDecoder *mpeg_dec; + GstVdpMpegDec *mpeg_dec; GstVdpMpegPacketizer packetizer; GstBuffer *buf; GstFlowReturn ret = GST_FLOW_OK; - mpeg_dec = GST_VDP_MPEG_DECODER (GST_OBJECT_PARENT (pad)); + mpeg_dec = GST_VDP_MPEG_DEC (GST_OBJECT_PARENT (pad)); if (G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT))) { GST_DEBUG_OBJECT (mpeg_dec, "Received discont buffer"); - gst_vdp_mpeg_decoder_flush (mpeg_dec); + gst_vdp_mpeg_dec_flush (mpeg_dec); } + gst_vdp_mpeg_packetizer_init (&packetizer, buffer); while ((buf = gst_vdp_mpeg_packetizer_get_next_packet (&packetizer))) { GstBitReader b_reader = GST_BIT_READER_INIT_FROM_BUFFER (buf); @@ -633,13 +631,13 @@ gst_vdp_mpeg_decoder_chain (GstPad * pad, GstBuffer * buffer) case MPEG_PACKET_PICTURE: GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_PICTURE"); - if (!gst_vdp_mpeg_decoder_parse_picture (mpeg_dec, buf)) { + if (!gst_vdp_mpeg_dec_parse_picture (mpeg_dec, buf)) { return GST_FLOW_OK; } break; case MPEG_PACKET_SEQUENCE: GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_SEQUENCE"); - gst_vdp_mpeg_decoder_parse_sequence (mpeg_dec, buf); + gst_vdp_mpeg_dec_parse_sequence (mpeg_dec, buf); break; case MPEG_PACKET_EXTENSION: { @@ -652,11 +650,11 @@ gst_vdp_mpeg_decoder_chain (GstPad * pad, GstBuffer * buffer) switch (ext_code) { case MPEG_PACKET_EXT_PICTURE_CODING: GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_EXT_PICTURE_CODING"); - gst_vdp_mpeg_decoder_parse_picture_coding (mpeg_dec, buf); + gst_vdp_mpeg_dec_parse_picture_coding (mpeg_dec, buf); break; case MPEG_PACKET_EXT_QUANT_MATRIX: GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_EXT_QUANT_MATRIX"); - gst_vdp_mpeg_decoder_parse_quant_matrix (mpeg_dec, buf); + gst_vdp_mpeg_dec_parse_quant_matrix (mpeg_dec, buf); break; default: break; @@ -665,7 +663,7 @@ gst_vdp_mpeg_decoder_chain (GstPad * pad, GstBuffer * buffer) } case MPEG_PACKET_GOP: GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_GOP"); - gst_vdp_mpeg_decoder_parse_gop (mpeg_dec, buf); + gst_vdp_mpeg_dec_parse_gop (mpeg_dec, buf); break; default: break; @@ -675,14 +673,14 @@ gst_vdp_mpeg_decoder_chain (GstPad * pad, GstBuffer * buffer) } if (mpeg_dec->vdp_info.slice_count > 0) - ret = gst_vdp_mpeg_decoder_decode (mpeg_dec, GST_BUFFER_TIMESTAMP (buffer), + ret = gst_vdp_mpeg_dec_decode (mpeg_dec, GST_BUFFER_TIMESTAMP (buffer), GST_BUFFER_SIZE (buffer)); return ret; } static gboolean -gst_vdp_mpeg_decoder_convert (GstVdpMpegDecoder * mpeg_dec, +gst_vdp_mpeg_dec_convert (GstVdpMpegDec * mpeg_dec, GstFormat src_format, gint64 src_value, GstFormat dest_format, gint64 * dest_value) { @@ -711,7 +709,7 @@ gst_vdp_mpeg_decoder_convert (GstVdpMpegDecoder * mpeg_dec, } static const GstQueryType * -gst_mpeg_decoder_get_querytypes (GstPad * pad) +gst_mpeg_dec_get_querytypes (GstPad * pad) { static const GstQueryType list[] = { GST_QUERY_POSITION, @@ -723,9 +721,9 @@ gst_mpeg_decoder_get_querytypes (GstPad * pad) } static gboolean -gst_vdp_mpeg_decoder_src_query (GstPad * pad, GstQuery * query) +gst_vdp_mpeg_dec_src_query (GstPad * pad, GstQuery * query) { - GstVdpMpegDecoder *mpeg_dec = GST_VDP_MPEG_DECODER (GST_OBJECT_PARENT (pad)); + GstVdpMpegDec *mpeg_dec = GST_VDP_MPEG_DEC (GST_OBJECT_PARENT (pad)); gboolean res = FALSE; switch (GST_QUERY_TYPE (query)) { @@ -762,7 +760,7 @@ gst_vdp_mpeg_decoder_src_query (GstPad * pad, GstQuery * query) && format == GST_FORMAT_BYTES) { gint64 duration; - if (gst_vdp_mpeg_decoder_convert (mpeg_dec, GST_FORMAT_BYTES, + if (gst_vdp_mpeg_dec_convert (mpeg_dec, GST_FORMAT_BYTES, bytes, GST_FORMAT_TIME, &duration)) { GST_DEBUG ("duration: %" GST_TIME_FORMAT, GST_TIME_ARGS (duration)); gst_query_set_duration (query, GST_FORMAT_TIME, duration); @@ -783,7 +781,7 @@ gst_vdp_mpeg_decoder_src_query (GstPad * pad, GstQuery * query) static gboolean normal_seek (GstPad * pad, GstEvent * event) { - GstVdpMpegDecoder *mpeg_dec = GST_VDP_MPEG_DECODER (GST_OBJECT_PARENT (pad)); + GstVdpMpegDec *mpeg_dec = GST_VDP_MPEG_DEC (GST_OBJECT_PARENT (pad)); gdouble rate; GstFormat format, conv; GstSeekFlags flags; @@ -800,9 +798,9 @@ normal_seek (GstPad * pad, GstEvent * event) &cur_type, &cur, &stop_type, &stop); conv = GST_FORMAT_TIME; - if (!gst_vdp_mpeg_decoder_convert (mpeg_dec, format, cur, conv, &time_cur)) + if (!gst_vdp_mpeg_dec_convert (mpeg_dec, format, cur, conv, &time_cur)) goto convert_failed; - if (!gst_vdp_mpeg_decoder_convert (mpeg_dec, format, stop, conv, &time_stop)) + if (!gst_vdp_mpeg_dec_convert (mpeg_dec, format, stop, conv, &time_stop)) goto convert_failed; GST_DEBUG ("seek to time %" GST_TIME_FORMAT "-%" GST_TIME_FORMAT, @@ -817,10 +815,10 @@ normal_seek (GstPad * pad, GstEvent * event) /* else we try to seek on bytes */ conv = GST_FORMAT_BYTES; - if (!gst_vdp_mpeg_decoder_convert (mpeg_dec, GST_FORMAT_TIME, time_cur, + if (!gst_vdp_mpeg_dec_convert (mpeg_dec, GST_FORMAT_TIME, time_cur, conv, &bytes_cur)) goto convert_failed; - if (!gst_vdp_mpeg_decoder_convert (mpeg_dec, GST_FORMAT_TIME, time_stop, + if (!gst_vdp_mpeg_dec_convert (mpeg_dec, GST_FORMAT_TIME, time_stop, conv, &bytes_stop)) goto convert_failed; @@ -848,7 +846,7 @@ convert_failed: } static gboolean -gst_vdp_mpeg_decoder_src_event (GstPad * pad, GstEvent * event) +gst_vdp_mpeg_dec_src_event (GstPad * pad, GstEvent * event) { gboolean res; @@ -869,9 +867,9 @@ gst_vdp_mpeg_decoder_src_event (GstPad * pad, GstEvent * event) } static gboolean -gst_vdp_mpeg_decoder_sink_event (GstPad * pad, GstEvent * event) +gst_vdp_mpeg_dec_sink_event (GstPad * pad, GstEvent * event) { - GstVdpMpegDecoder *mpeg_dec = GST_VDP_MPEG_DECODER (GST_OBJECT_PARENT (pad)); + GstVdpMpegDec *mpeg_dec = GST_VDP_MPEG_DEC (GST_OBJECT_PARENT (pad)); gboolean res; switch (GST_EVENT_TYPE (event)) { @@ -879,7 +877,7 @@ gst_vdp_mpeg_decoder_sink_event (GstPad * pad, GstEvent * event) { GST_DEBUG_OBJECT (mpeg_dec, "flush stop"); - gst_vdp_mpeg_decoder_flush (mpeg_dec); + gst_vdp_mpeg_dec_flush (mpeg_dec); res = gst_pad_push_event (mpeg_dec->src, event); break; @@ -897,13 +895,13 @@ gst_vdp_mpeg_decoder_sink_event (GstPad * pad, GstEvent * event) &start, &stop, &position); if (format != GST_FORMAT_TIME) { - if (!gst_vdp_mpeg_decoder_convert (mpeg_dec, format, start, + if (!gst_vdp_mpeg_dec_convert (mpeg_dec, format, start, GST_FORMAT_TIME, &start)) goto convert_error; - if (!gst_vdp_mpeg_decoder_convert (mpeg_dec, format, stop, + if (!gst_vdp_mpeg_dec_convert (mpeg_dec, format, stop, GST_FORMAT_TIME, &stop)) goto convert_error; - if (!gst_vdp_mpeg_decoder_convert (mpeg_dec, format, position, + if (!gst_vdp_mpeg_dec_convert (mpeg_dec, format, position, GST_FORMAT_TIME, &position)) goto convert_error; @@ -935,13 +933,12 @@ gst_vdp_mpeg_decoder_sink_event (GstPad * pad, GstEvent * event) } static GstStateChangeReturn -gst_vdp_mpeg_decoder_change_state (GstElement * element, - GstStateChange transition) +gst_vdp_mpeg_dec_change_state (GstElement * element, GstStateChange transition) { - GstVdpMpegDecoder *mpeg_dec; + GstVdpMpegDec *mpeg_dec; GstStateChangeReturn ret; - mpeg_dec = GST_VDP_MPEG_DECODER (element); + mpeg_dec = GST_VDP_MPEG_DEC (element); switch (transition) { case GST_STATE_CHANGE_READY_TO_PAUSED: @@ -955,7 +952,7 @@ gst_vdp_mpeg_decoder_change_state (GstElement * element, switch (transition) { case GST_STATE_CHANGE_PAUSED_TO_READY: - gst_vdp_mpeg_decoder_reset (mpeg_dec); + gst_vdp_mpeg_dec_reset (mpeg_dec); break; default: break; @@ -967,7 +964,7 @@ gst_vdp_mpeg_decoder_change_state (GstElement * element, /* GObject vmethod implementations */ static void -gst_vdp_mpeg_decoder_base_init (gpointer gclass) +gst_vdp_mpeg_dec_base_init (gpointer gclass) { GstElementClass *element_class = GST_ELEMENT_CLASS (gclass); @@ -985,7 +982,7 @@ gst_vdp_mpeg_decoder_base_init (gpointer gclass) /* initialize the vdpaumpegdecoder's class */ static void -gst_vdp_mpeg_decoder_class_init (GstVdpMpegDecoderClass * klass) +gst_vdp_mpeg_dec_class_init (GstVdpMpegDecClass * klass) { GObjectClass *gobject_class; GstElementClass *gstelement_class; @@ -993,12 +990,12 @@ gst_vdp_mpeg_decoder_class_init (GstVdpMpegDecoderClass * klass) gobject_class = (GObjectClass *) klass; gstelement_class = (GstElementClass *) klass; - gobject_class->finalize = gst_vdp_mpeg_decoder_finalize; - gobject_class->set_property = gst_vdp_mpeg_decoder_set_property; - gobject_class->get_property = gst_vdp_mpeg_decoder_get_property; + gobject_class->finalize = gst_vdp_mpeg_dec_finalize; + gobject_class->set_property = gst_vdp_mpeg_dec_set_property; + gobject_class->get_property = gst_vdp_mpeg_dec_get_property; gstelement_class->change_state = - GST_DEBUG_FUNCPTR (gst_vdp_mpeg_decoder_change_state); + GST_DEBUG_FUNCPTR (gst_vdp_mpeg_dec_change_state); g_object_class_install_property (gobject_class, PROP_DISPLAY, g_param_spec_string ("display", "Display", "X Display name", @@ -1006,7 +1003,7 @@ gst_vdp_mpeg_decoder_class_init (GstVdpMpegDecoderClass * klass) } static void -gst_vdp_mpeg_decoder_init_info (VdpPictureInfoMPEG1Or2 * vdp_info) +gst_vdp_mpeg_dec_init_info (VdpPictureInfoMPEG1Or2 * vdp_info) { vdp_info->forward_reference = VDP_INVALID_HANDLE; vdp_info->backward_reference = VDP_INVALID_HANDLE; @@ -1023,25 +1020,24 @@ gst_vdp_mpeg_decoder_init_info (VdpPictureInfoMPEG1Or2 * vdp_info) } static void -gst_vdp_mpeg_decoder_init (GstVdpMpegDecoder * mpeg_dec, - GstVdpMpegDecoderClass * gclass) +gst_vdp_mpeg_dec_init (GstVdpMpegDec * mpeg_dec, GstVdpMpegDecClass * gclass) { mpeg_dec->src = gst_pad_new_from_static_template (&src_template, "src"); gst_pad_set_event_function (mpeg_dec->src, - GST_DEBUG_FUNCPTR (gst_vdp_mpeg_decoder_src_event)); + GST_DEBUG_FUNCPTR (gst_vdp_mpeg_dec_src_event)); gst_pad_set_query_function (mpeg_dec->src, - GST_DEBUG_FUNCPTR (gst_vdp_mpeg_decoder_src_query)); + GST_DEBUG_FUNCPTR (gst_vdp_mpeg_dec_src_query)); gst_pad_set_query_type_function (mpeg_dec->src, - GST_DEBUG_FUNCPTR (gst_mpeg_decoder_get_querytypes)); + GST_DEBUG_FUNCPTR (gst_mpeg_dec_get_querytypes)); gst_element_add_pad (GST_ELEMENT (mpeg_dec), mpeg_dec->src); mpeg_dec->sink = gst_pad_new_from_static_template (&sink_template, "sink"); gst_pad_set_setcaps_function (mpeg_dec->sink, - GST_DEBUG_FUNCPTR (gst_vdp_mpeg_decoder_set_caps)); + GST_DEBUG_FUNCPTR (gst_vdp_mpeg_dec_set_caps)); gst_pad_set_chain_function (mpeg_dec->sink, - GST_DEBUG_FUNCPTR (gst_vdp_mpeg_decoder_chain)); + GST_DEBUG_FUNCPTR (gst_vdp_mpeg_dec_chain)); gst_pad_set_event_function (mpeg_dec->sink, - GST_DEBUG_FUNCPTR (gst_vdp_mpeg_decoder_sink_event)); + GST_DEBUG_FUNCPTR (gst_vdp_mpeg_dec_sink_event)); gst_element_add_pad (GST_ELEMENT (mpeg_dec), mpeg_dec->sink); mpeg_dec->display_name = NULL; @@ -1052,22 +1048,22 @@ gst_vdp_mpeg_decoder_init (GstVdpMpegDecoder * mpeg_dec, mpeg_dec->vdp_info.forward_reference = VDP_INVALID_HANDLE; mpeg_dec->vdp_info.backward_reference = VDP_INVALID_HANDLE; - gst_vdp_mpeg_decoder_reset (mpeg_dec); + gst_vdp_mpeg_dec_reset (mpeg_dec); } static void -gst_vdp_mpeg_decoder_finalize (GObject * object) +gst_vdp_mpeg_dec_finalize (GObject * object) { - GstVdpMpegDecoder *mpeg_dec = (GstVdpMpegDecoder *) object; + GstVdpMpegDec *mpeg_dec = (GstVdpMpegDec *) object; g_object_unref (mpeg_dec->adapter); } static void -gst_vdp_mpeg_decoder_set_property (GObject * object, guint prop_id, +gst_vdp_mpeg_dec_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { - GstVdpMpegDecoder *mpeg_dec = GST_VDP_MPEG_DECODER (object); + GstVdpMpegDec *mpeg_dec = GST_VDP_MPEG_DEC (object); switch (prop_id) { case PROP_DISPLAY: @@ -1081,10 +1077,10 @@ gst_vdp_mpeg_decoder_set_property (GObject * object, guint prop_id, } static void -gst_vdp_mpeg_decoder_get_property (GObject * object, guint prop_id, +gst_vdp_mpeg_dec_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { - GstVdpMpegDecoder *mpeg_dec = GST_VDP_MPEG_DECODER (object); + GstVdpMpegDec *mpeg_dec = GST_VDP_MPEG_DEC (object); switch (prop_id) { case PROP_DISPLAY: diff --git a/sys/vdpau/gstvdpmpegdecoder.h b/sys/vdpau/gstvdpmpegdecoder.h index e1300862..b60c9f59 100644 --- a/sys/vdpau/gstvdpmpegdecoder.h +++ b/sys/vdpau/gstvdpmpegdecoder.h @@ -18,8 +18,8 @@ * Boston, MA 02111-1307, USA. */ -#ifndef __GST_VDP_MPEG_DECODER_H__ -#define __GST_VDP_MPEG_DECODER_H__ +#ifndef __GST_VDP_MPEG_DEC_H__ +#define __GST_VDP_MPEG_DEC_H__ #include #include @@ -29,16 +29,16 @@ G_BEGIN_DECLS -#define GST_TYPE_VDP_MPEG_DECODER (gst_vdp_mpeg_decoder_get_type()) -#define GST_VDP_MPEG_DECODER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VDP_MPEG_DECODER,GstVdpMpegDecoder)) -#define GST_VDP_MPEG_DECODER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VDP_MPEG_DECODER,GstVdpMpegDecoderClass)) -#define GST_IS_VDPAU_MPEG_DECODER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VDP_MPEG_DECODER)) -#define GST_IS_VDPAU_MPEG_DECODER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VDP_MPEG_DECODER)) +#define GST_TYPE_VDP_MPEG_DEC (gst_vdp_mpeg_dec_get_type()) +#define GST_VDP_MPEG_DEC(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VDP_MPEG_DEC,GstVdpMpegDec)) +#define GST_VDP_MPEG_DEC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VDP_MPEG_DEC,GstVdpMpegDecClass)) +#define GST_IS_VDPAU_MPEG_DEC(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VDP_MPEG_DEC)) +#define GST_IS_VDPAU_MPEG_DEC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VDP_MPEG_DEC)) -typedef struct _GstVdpMpegDecoder GstVdpMpegDecoder; -typedef struct _GstVdpMpegDecoderClass GstVdpMpegDecoderClass; +typedef struct _GstVdpMpegDec GstVdpMpegDec; +typedef struct _GstVdpMpegDecClass GstVdpMpegDecClass; -struct _GstVdpMpegDecoder +struct _GstVdpMpegDec { GstElement element; @@ -81,13 +81,13 @@ struct _GstVdpMpegDecoder }; -struct _GstVdpMpegDecoderClass +struct _GstVdpMpegDecClass { GstElementClass element_class; }; -GType gst_vdp_mpeg_decoder_get_type (void); +GType gst_vdp_mpeg_dec_get_type (void); G_END_DECLS -#endif /* __GST_VDP_MPEG_DECODER_H__ */ +#endif /* __GST_VDP_MPEG_DEC_H__ */ -- cgit v1.2.1 From 8619160ec89ac7c8aed300f1f644fc0f50a294e8 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Fri, 5 Jun 2009 21:48:28 +0200 Subject: vdpaumpegdec: rename gstvdpmpegdecoder.[ch] to gstvdpmpegdec.[ch] --- sys/vdpau/Makefile.am | 4 +- sys/vdpau/gstvdp.c | 2 +- sys/vdpau/gstvdpmpegdec.c | 1093 +++++++++++++++++++++++++++++++++++++++++ sys/vdpau/gstvdpmpegdec.h | 93 ++++ sys/vdpau/gstvdpmpegdecoder.c | 1093 ----------------------------------------- sys/vdpau/gstvdpmpegdecoder.h | 93 ---- 6 files changed, 1189 insertions(+), 1189 deletions(-) create mode 100644 sys/vdpau/gstvdpmpegdec.c create mode 100644 sys/vdpau/gstvdpmpegdec.h delete mode 100644 sys/vdpau/gstvdpmpegdecoder.c delete mode 100644 sys/vdpau/gstvdpmpegdecoder.h (limited to 'sys') diff --git a/sys/vdpau/Makefile.am b/sys/vdpau/Makefile.am index 053332b0..f4380aff 100644 --- a/sys/vdpau/Makefile.am +++ b/sys/vdpau/Makefile.am @@ -2,7 +2,7 @@ plugin_LTLIBRARIES = libgstvdpau.la libgstvdpau_la_SOURCES = \ gstvdpdevice.c \ - gstvdpmpegdecoder.c \ + gstvdpmpegdec.c \ mpegutil.c \ gstvdpvideoyuv.c \ gstvdpvideobuffer.c \ @@ -17,7 +17,7 @@ libgstvdpau_la_LIBTOOLFLAGS = --tag=disable-static noinst_HEADERS = \ gstvdpdevice.h \ - gstvdpmpegdecoder.h \ + gstvdpmpegdec.h \ mpegutil.h \ gstvdpvideoyuv.h \ gstvdpvideobuffer.h \ diff --git a/sys/vdpau/gstvdp.c b/sys/vdpau/gstvdp.c index 43360483..5c524968 100644 --- a/sys/vdpau/gstvdp.c +++ b/sys/vdpau/gstvdp.c @@ -5,7 +5,7 @@ #include -#include "gstvdpmpegdecoder.h" +#include "gstvdpmpegdec.h" #include "gstvdpvideoyuv.h" #include "gstvdpyuvvideo.h" diff --git a/sys/vdpau/gstvdpmpegdec.c b/sys/vdpau/gstvdpmpegdec.c new file mode 100644 index 00000000..b011833e --- /dev/null +++ b/sys/vdpau/gstvdpmpegdec.c @@ -0,0 +1,1093 @@ +/* + * GStreamer + * Copyright (C) 2009 Carl-Anton Ingmarsson + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/** + * SECTION:element-vdpaumpegdec + * + * FIXME:Describe vdpaumpegdec here. + * + * + * Example launch line + * |[ + * gst-launch -v -m fakesrc ! vdpaumpegdec ! fakesink silent=TRUE + * ]| + * + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include + +#include "mpegutil.h" +#include "gstvdpmpegdec.h" + +GST_DEBUG_CATEGORY_STATIC (gst_vdp_mpeg_dec_debug); +#define GST_CAT_DEFAULT gst_vdp_mpeg_dec_debug + +/* Filter signals and args */ +enum +{ + /* FILL ME */ + LAST_SIGNAL +}; + +enum +{ + PROP_0, + PROP_DISPLAY +}; + +/* the capabilities of the inputs and outputs. + * + * describe the real formats here. + */ +static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS ("video/mpeg, mpegversion = (int) [ 1, 2 ], " + "systemstream = (boolean) false, parsed = (boolean) true") + ); +static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS ("video/x-vdpau-video, " "chroma-type = (int) 0") + ); + +#define DEBUG_INIT(bla) \ +GST_DEBUG_CATEGORY_INIT (gst_vdp_mpeg_dec_debug, "vdpaumpegdec", 0, "VDPAU powered mpeg decoder"); + +GST_BOILERPLATE_FULL (GstVdpMpegDec, gst_vdp_mpeg_dec, + GstElement, GST_TYPE_ELEMENT, DEBUG_INIT); + +static void gst_vdp_mpeg_dec_init_info (VdpPictureInfoMPEG1Or2 * vdp_info); +static void gst_vdp_mpeg_dec_finalize (GObject * object); +static void gst_vdp_mpeg_dec_set_property (GObject * object, + guint prop_id, const GValue * value, GParamSpec * pspec); +static void gst_vdp_mpeg_dec_get_property (GObject * object, + guint prop_id, GValue * value, GParamSpec * pspec); + +guint8 * +mpeg_util_find_start_code (guint32 * sync_word, guint8 * cur, guint8 * end) +{ + guint32 code; + + if (G_UNLIKELY (cur == NULL)) + return NULL; + + code = *sync_word; + + while (cur < end) { + code <<= 8; + + if (code == 0x00000100) { + /* Reset the sync word accumulator */ + *sync_word = 0xffffffff; + return cur; + } + + /* Add the next available byte to the collected sync word */ + code |= *cur++; + } + + *sync_word = code; + return NULL; +} + +typedef struct +{ + GstBuffer *buffer; + guint8 *cur; + guint8 *end; +} GstVdpMpegPacketizer; + +static GstBuffer * +gst_vdp_mpeg_packetizer_get_next_packet (GstVdpMpegPacketizer * packetizer) +{ + guint32 sync_word = 0xffffff; + guint8 *packet_start; + guint8 *packet_end; + + if (!packetizer->cur) + return NULL; + + packet_start = packetizer->cur - 3; + packetizer->cur = packet_end = mpeg_util_find_start_code (&sync_word, + packetizer->cur, packetizer->end); + + if (packet_end) + packet_end -= 3; + else + packet_end = packetizer->end; + + return gst_buffer_create_sub (packetizer->buffer, + packet_start - GST_BUFFER_DATA (packetizer->buffer), + packet_end - packet_start); +} + +static void +gst_vdp_mpeg_packetizer_init (GstVdpMpegPacketizer * packetizer, + GstBuffer * buffer) +{ + guint32 sync_word = 0xffffffff; + + packetizer->buffer = buffer; + packetizer->end = GST_BUFFER_DATA (buffer) + GST_BUFFER_SIZE (buffer); + packetizer->cur = mpeg_util_find_start_code (&sync_word, + GST_BUFFER_DATA (buffer), packetizer->end); +} + +static gboolean +gst_vdp_mpeg_dec_set_caps (GstPad * pad, GstCaps * caps) +{ + GstVdpMpegDec *mpeg_dec = GST_VDP_MPEG_DEC (GST_OBJECT_PARENT (pad)); + GstStructure *structure; + + gint width, height; + gint fps_n, fps_d; + gint par_n, par_d; + gboolean interlaced = FALSE; + + GstCaps *src_caps; + gboolean res; + + const GValue *value; + VdpDecoderProfile profile; + GstVdpDevice *device; + VdpStatus status; + + structure = gst_caps_get_structure (caps, 0); + + /* create src_pad caps */ + gst_structure_get_int (structure, "width", &width); + gst_structure_get_int (structure, "height", &height); + gst_structure_get_fraction (structure, "framerate", &fps_n, &fps_d); + gst_structure_get_fraction (structure, "pixel-aspect-ratio", &par_n, &par_d); + gst_structure_get_boolean (structure, "interlaced", &interlaced); + + src_caps = gst_caps_new_simple ("video/x-vdpau-video", + "device", G_TYPE_OBJECT, mpeg_dec->device, + "chroma_type", G_TYPE_INT, VDP_CHROMA_TYPE_420, + "width", G_TYPE_INT, width, + "height", G_TYPE_INT, height, + "framerate", GST_TYPE_FRACTION, fps_n, fps_d, + "pixel-aspect-ratio", GST_TYPE_FRACTION, par_n, par_d, + "interlaced", G_TYPE_BOOLEAN, interlaced, NULL); + + res = gst_pad_set_caps (mpeg_dec->src, src_caps); + gst_caps_unref (src_caps); + if (!res) + return FALSE; + + mpeg_dec->width = width; + mpeg_dec->height = height; + mpeg_dec->fps_n = fps_n; + mpeg_dec->fps_d = fps_d; + mpeg_dec->interlaced = interlaced; + + /* parse caps to setup decoder */ + gst_structure_get_int (structure, "mpegversion", &mpeg_dec->version); + if (mpeg_dec->version == 1) + profile = VDP_DECODER_PROFILE_MPEG1; + + value = gst_structure_get_value (structure, "codec_data"); + if (value) { + GstBuffer *codec_data, *buf; + GstVdpMpegPacketizer packetizer; + + codec_data = gst_value_get_buffer (value); + gst_vdp_mpeg_packetizer_init (&packetizer, codec_data); + if ((buf = gst_vdp_mpeg_packetizer_get_next_packet (&packetizer))) { + MPEGSeqHdr hdr; + guint32 bitrate; + + mpeg_util_parse_sequence_hdr (&hdr, buf); + + memcpy (&mpeg_dec->vdp_info.intra_quantizer_matrix, + &hdr.intra_quantizer_matrix, 64); + memcpy (&mpeg_dec->vdp_info.non_intra_quantizer_matrix, + &hdr.non_intra_quantizer_matrix, 64); + + bitrate = hdr.bitrate; + gst_buffer_unref (buf); + + if ((buf = gst_vdp_mpeg_packetizer_get_next_packet (&packetizer))) { + MPEGSeqExtHdr ext; + + mpeg_util_parse_sequence_extension (&ext, buf); + if (mpeg_dec->version != 1) { + switch (ext.profile) { + case 5: + profile = VDP_DECODER_PROFILE_MPEG2_SIMPLE; + break; + default: + profile = VDP_DECODER_PROFILE_MPEG2_MAIN; + break; + } + } + + bitrate += (ext.bitrate_ext << 18);; + gst_buffer_unref (buf); + } + + mpeg_dec->duration = + gst_util_uint64_scale (1, GST_SECOND * mpeg_dec->fps_d, + mpeg_dec->fps_n); + + mpeg_dec->byterate = bitrate * 50; + GST_DEBUG ("byterate: %" G_GINT64_FORMAT, mpeg_dec->byterate); + } + } + + device = mpeg_dec->device; + + if (mpeg_dec->decoder != VDP_INVALID_HANDLE) { + device->vdp_decoder_destroy (mpeg_dec->decoder); + mpeg_dec->decoder = VDP_INVALID_HANDLE; + } + + status = device->vdp_decoder_create (device->device, profile, mpeg_dec->width, + mpeg_dec->height, 2, &mpeg_dec->decoder); + if (status != VDP_STATUS_OK) { + GST_ELEMENT_ERROR (mpeg_dec, RESOURCE, READ, + ("Could not create vdpau decoder"), + ("Error returned from vdpau was: %s", + device->vdp_get_error_string (status))); + return FALSE; + } + return TRUE; +} + +GstFlowReturn +gst_vdp_mpeg_dec_push_video_buffer (GstVdpMpegDec * mpeg_dec, + GstVdpVideoBuffer * buffer) +{ + gint64 byterate; + + if (GST_BUFFER_TIMESTAMP (buffer) == GST_CLOCK_TIME_NONE + && GST_CLOCK_TIME_IS_VALID (mpeg_dec->next_timestamp)) { + GST_BUFFER_TIMESTAMP (buffer) = mpeg_dec->next_timestamp; + } else if (GST_BUFFER_TIMESTAMP (buffer) == GST_CLOCK_TIME_NONE) { + GST_BUFFER_TIMESTAMP (buffer) = gst_util_uint64_scale (mpeg_dec->frame_nr, + GST_SECOND * mpeg_dec->fps_d, mpeg_dec->fps_n); + } + + if (mpeg_dec->seeking) { + GstEvent *event; + + event = gst_event_new_new_segment (FALSE, + mpeg_dec->segment.rate, GST_FORMAT_TIME, GST_BUFFER_TIMESTAMP (buffer), + mpeg_dec->segment.stop, GST_BUFFER_TIMESTAMP (buffer)); + + gst_pad_push_event (mpeg_dec->src, event); + + mpeg_dec->seeking = FALSE; + } + + mpeg_dec->next_timestamp = GST_BUFFER_TIMESTAMP (buffer) + + GST_BUFFER_DURATION (buffer); + + mpeg_dec->accumulated_duration += GST_BUFFER_DURATION (buffer); + mpeg_dec->accumulated_size += GST_BUFFER_SIZE (buffer); + byterate = gst_util_uint64_scale (mpeg_dec->accumulated_size, GST_SECOND, + mpeg_dec->accumulated_duration); + GST_DEBUG ("byterate: %" G_GINT64_FORMAT, mpeg_dec->byterate); + + mpeg_dec->byterate = (mpeg_dec->byterate + byterate) / 2; + + gst_buffer_set_caps (GST_BUFFER (buffer), GST_PAD_CAPS (mpeg_dec->src)); + + GST_DEBUG_OBJECT (mpeg_dec, + "Pushing buffer with timestamp: %" GST_TIME_FORMAT + " frame_nr: %" G_GINT64_FORMAT, + GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)), + GST_BUFFER_OFFSET (buffer)); + + return gst_pad_push (mpeg_dec->src, GST_BUFFER (buffer)); +} + +static GstFlowReturn +gst_vdp_mpeg_dec_decode (GstVdpMpegDec * mpeg_dec, + GstClockTime timestamp, gint64 size) +{ + VdpPictureInfoMPEG1Or2 *info; + GstBuffer *buffer; + GstVdpVideoBuffer *outbuf; + VdpVideoSurface surface; + GstVdpDevice *device; + VdpBitstreamBuffer vbit[1]; + VdpStatus status; + + info = &mpeg_dec->vdp_info; + + buffer = gst_adapter_take_buffer (mpeg_dec->adapter, + gst_adapter_available (mpeg_dec->adapter)); + + if (info->picture_coding_type != B_FRAME) { + if (info->backward_reference != VDP_INVALID_HANDLE) { + gst_buffer_ref (mpeg_dec->b_buffer); + gst_vdp_mpeg_dec_push_video_buffer (mpeg_dec, + GST_VDP_VIDEO_BUFFER (mpeg_dec->b_buffer)); + } + + if (info->forward_reference != VDP_INVALID_HANDLE) { + gst_buffer_unref (mpeg_dec->f_buffer); + info->forward_reference = VDP_INVALID_HANDLE; + } + + info->forward_reference = info->backward_reference; + mpeg_dec->f_buffer = mpeg_dec->b_buffer; + + info->backward_reference = VDP_INVALID_HANDLE; + } + + outbuf = gst_vdp_video_buffer_new (mpeg_dec->device, VDP_CHROMA_TYPE_420, + mpeg_dec->width, mpeg_dec->height); + GST_BUFFER_TIMESTAMP (outbuf) = timestamp; + GST_BUFFER_DURATION (outbuf) = mpeg_dec->duration; + GST_BUFFER_OFFSET (outbuf) = mpeg_dec->frame_nr; + GST_BUFFER_SIZE (outbuf) = size; + + if (info->top_field_first) + GST_BUFFER_FLAG_SET (outbuf, GST_VIDEO_BUFFER_TFF); + + if (info->forward_reference != VDP_INVALID_HANDLE && + info->picture_coding_type != I_FRAME) + gst_vdp_video_buffer_add_reference (outbuf, + GST_VDP_VIDEO_BUFFER (mpeg_dec->f_buffer)); + + if (info->backward_reference != VDP_INVALID_HANDLE) + gst_vdp_video_buffer_add_reference (outbuf, + GST_VDP_VIDEO_BUFFER (mpeg_dec->b_buffer)); + + surface = outbuf->surface; + + device = mpeg_dec->device; + + vbit[0].struct_version = VDP_BITSTREAM_BUFFER_VERSION; + vbit[0].bitstream = GST_BUFFER_DATA (buffer); + vbit[0].bitstream_bytes = GST_BUFFER_SIZE (buffer); + + status = device->vdp_decoder_render (mpeg_dec->decoder, surface, + (VdpPictureInfo *) info, 1, vbit); + gst_buffer_unref (buffer); + info->slice_count = 0; + + if (status != VDP_STATUS_OK) { + GST_ELEMENT_ERROR (mpeg_dec, RESOURCE, READ, + ("Could not decode"), + ("Error returned from vdpau was: %s", + device->vdp_get_error_string (status))); + + gst_buffer_unref (GST_BUFFER (outbuf)); + + return GST_FLOW_ERROR; + } + + if (info->picture_coding_type == B_FRAME) { + gst_vdp_mpeg_dec_push_video_buffer (mpeg_dec, + GST_VDP_VIDEO_BUFFER (outbuf)); + } else { + info->backward_reference = surface; + mpeg_dec->b_buffer = GST_BUFFER (outbuf); + } + + return GST_FLOW_OK; +} + +static gboolean +gst_vdp_mpeg_dec_parse_picture_coding (GstVdpMpegDec * mpeg_dec, + GstBuffer * buffer) +{ + MPEGPictureExt pic_ext; + VdpPictureInfoMPEG1Or2 *info; + gint fields; + + info = &mpeg_dec->vdp_info; + + if (!mpeg_util_parse_picture_coding_extension (&pic_ext, buffer)) + return FALSE; + + memcpy (&mpeg_dec->vdp_info.f_code, &pic_ext.f_code, 4); + + info->intra_dc_precision = pic_ext.intra_dc_precision; + info->picture_structure = pic_ext.picture_structure; + info->top_field_first = pic_ext.top_field_first; + info->frame_pred_frame_dct = pic_ext.frame_pred_frame_dct; + info->concealment_motion_vectors = pic_ext.concealment_motion_vectors; + info->q_scale_type = pic_ext.q_scale_type; + info->intra_vlc_format = pic_ext.intra_vlc_format; + info->alternate_scan = pic_ext.alternate_scan; + + fields = 2; + if (pic_ext.picture_structure == 3) { + if (mpeg_dec->interlaced) { + if (pic_ext.progressive_frame == 0) + fields = 2; + if (pic_ext.progressive_frame == 0 && pic_ext.repeat_first_field == 0) + fields = 2; + if (pic_ext.progressive_frame == 1 && pic_ext.repeat_first_field == 1) + fields = 3; + } else { + if (pic_ext.repeat_first_field == 0) + fields = 2; + if (pic_ext.repeat_first_field == 1 && pic_ext.top_field_first == 0) + fields = 4; + if (pic_ext.repeat_first_field == 1 && pic_ext.top_field_first == 1) + fields = 6; + } + } else + fields = 1; + + GST_DEBUG ("fields: %d", fields); + + mpeg_dec->duration = gst_util_uint64_scale (fields, + GST_SECOND * mpeg_dec->fps_d, 2 * mpeg_dec->fps_n); + + return TRUE; +} + +static gboolean +gst_vdp_mpeg_dec_parse_sequence (GstVdpMpegDec * mpeg_dec, GstBuffer * buffer) +{ + MPEGSeqHdr hdr; + + if (!mpeg_util_parse_sequence_hdr (&hdr, buffer)) + return FALSE; + + memcpy (&mpeg_dec->vdp_info.intra_quantizer_matrix, + &hdr.intra_quantizer_matrix, 64); + memcpy (&mpeg_dec->vdp_info.non_intra_quantizer_matrix, + &hdr.non_intra_quantizer_matrix, 64); + + return TRUE; +} + +static gboolean +gst_vdp_mpeg_dec_parse_picture (GstVdpMpegDec * mpeg_dec, GstBuffer * buffer) +{ + MPEGPictureHdr pic_hdr; + + if (!mpeg_util_parse_picture_hdr (&pic_hdr, buffer)) + return FALSE; + + if (pic_hdr.pic_type != I_FRAME + && mpeg_dec->vdp_info.backward_reference == VDP_INVALID_HANDLE) { + GST_DEBUG_OBJECT (mpeg_dec, + "Drop frame since we haven't got an I_FRAME yet"); + return FALSE; + } + if (pic_hdr.pic_type == B_FRAME + && mpeg_dec->vdp_info.forward_reference == VDP_INVALID_HANDLE) { + GST_DEBUG_OBJECT (mpeg_dec, + "Drop frame since we haven't got two non B_FRAMES yet"); + return FALSE; + } + + mpeg_dec->vdp_info.picture_coding_type = pic_hdr.pic_type; + + if (mpeg_dec->version == 1) { + mpeg_dec->vdp_info.full_pel_forward_vector = + pic_hdr.full_pel_forward_vector; + mpeg_dec->vdp_info.full_pel_backward_vector = + pic_hdr.full_pel_backward_vector; + memcpy (&mpeg_dec->vdp_info.f_code, &pic_hdr.f_code, 4); + } + + mpeg_dec->frame_nr = mpeg_dec->gop_frame + pic_hdr.tsn; + + return TRUE; +} + +static gboolean +gst_vdp_mpeg_dec_parse_gop (GstVdpMpegDec * mpeg_dec, GstBuffer * buffer) +{ + MPEGGop gop; + GstClockTime time; + + if (!mpeg_util_parse_gop (&gop, buffer)) + return FALSE; + + time = GST_SECOND * (gop.hour * 3600 + gop.minute * 60 + gop.second); + + GST_DEBUG ("gop timestamp: %" GST_TIME_FORMAT, GST_TIME_ARGS (time)); + + mpeg_dec->gop_frame = + gst_util_uint64_scale (time, mpeg_dec->fps_n, + mpeg_dec->fps_d * GST_SECOND) + gop.frame; + + return TRUE; +} + +static gboolean +gst_vdp_mpeg_dec_parse_quant_matrix (GstVdpMpegDec * mpeg_dec, + GstBuffer * buffer) +{ + MPEGQuantMatrix qm; + + if (!mpeg_util_parse_quant_matrix (&qm, buffer)) + return FALSE; + + memcpy (&mpeg_dec->vdp_info.intra_quantizer_matrix, + &qm.intra_quantizer_matrix, 64); + memcpy (&mpeg_dec->vdp_info.non_intra_quantizer_matrix, + &qm.non_intra_quantizer_matrix, 64); + return TRUE; +} + +static void +gst_vdp_mpeg_dec_flush (GstVdpMpegDec * mpeg_dec) +{ + if (mpeg_dec->vdp_info.forward_reference != VDP_INVALID_HANDLE) + gst_buffer_unref (mpeg_dec->f_buffer); + if (mpeg_dec->vdp_info.backward_reference != VDP_INVALID_HANDLE) + gst_buffer_unref (mpeg_dec->b_buffer); + + gst_vdp_mpeg_dec_init_info (&mpeg_dec->vdp_info); + + gst_adapter_clear (mpeg_dec->adapter); + + mpeg_dec->next_timestamp = GST_CLOCK_TIME_NONE; +} + +static void +gst_vdp_mpeg_dec_reset (GstVdpMpegDec * mpeg_dec) +{ + gst_vdp_mpeg_dec_flush (mpeg_dec); + + if (mpeg_dec->decoder != VDP_INVALID_HANDLE) + mpeg_dec->device->vdp_decoder_destroy (mpeg_dec->decoder); + mpeg_dec->decoder = VDP_INVALID_HANDLE; + if (mpeg_dec->device) + g_object_unref (mpeg_dec->device); + mpeg_dec->device = NULL; + + gst_segment_init (&mpeg_dec->segment, GST_FORMAT_TIME); + mpeg_dec->seeking = FALSE; + + mpeg_dec->accumulated_size = 0; + mpeg_dec->accumulated_duration = 0; +} + +static GstFlowReturn +gst_vdp_mpeg_dec_chain (GstPad * pad, GstBuffer * buffer) +{ + GstVdpMpegDec *mpeg_dec; + GstVdpMpegPacketizer packetizer; + GstBuffer *buf; + GstFlowReturn ret = GST_FLOW_OK; + + mpeg_dec = GST_VDP_MPEG_DEC (GST_OBJECT_PARENT (pad)); + + if (G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT))) { + GST_DEBUG_OBJECT (mpeg_dec, "Received discont buffer"); + gst_vdp_mpeg_dec_flush (mpeg_dec); + } + + + gst_vdp_mpeg_packetizer_init (&packetizer, buffer); + while ((buf = gst_vdp_mpeg_packetizer_get_next_packet (&packetizer))) { + GstBitReader b_reader = GST_BIT_READER_INIT_FROM_BUFFER (buf); + guint32 sync_code; + guint8 start_code; + + /* skip sync_code */ + gst_bit_reader_get_bits_uint32 (&b_reader, &sync_code, 8 * 3); + + /* start_code */ + gst_bit_reader_get_bits_uint8 (&b_reader, &start_code, 8); + + if (start_code >= MPEG_PACKET_SLICE_MIN + && start_code <= MPEG_PACKET_SLICE_MAX) { + GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_SLICE"); + + gst_buffer_ref (buf); + gst_adapter_push (mpeg_dec->adapter, buf); + mpeg_dec->vdp_info.slice_count++; + } + + switch (start_code) { + case MPEG_PACKET_PICTURE: + GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_PICTURE"); + + if (!gst_vdp_mpeg_dec_parse_picture (mpeg_dec, buf)) { + return GST_FLOW_OK; + } + break; + case MPEG_PACKET_SEQUENCE: + GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_SEQUENCE"); + gst_vdp_mpeg_dec_parse_sequence (mpeg_dec, buf); + break; + case MPEG_PACKET_EXTENSION: + { + guint8 ext_code; + + GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_EXTENSION"); + + /* ext_code */ + gst_bit_reader_get_bits_uint8 (&b_reader, &ext_code, 4); + switch (ext_code) { + case MPEG_PACKET_EXT_PICTURE_CODING: + GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_EXT_PICTURE_CODING"); + gst_vdp_mpeg_dec_parse_picture_coding (mpeg_dec, buf); + break; + case MPEG_PACKET_EXT_QUANT_MATRIX: + GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_EXT_QUANT_MATRIX"); + gst_vdp_mpeg_dec_parse_quant_matrix (mpeg_dec, buf); + break; + default: + break; + } + break; + } + case MPEG_PACKET_GOP: + GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_GOP"); + gst_vdp_mpeg_dec_parse_gop (mpeg_dec, buf); + break; + default: + break; + } + + gst_buffer_unref (buf); + } + + if (mpeg_dec->vdp_info.slice_count > 0) + ret = gst_vdp_mpeg_dec_decode (mpeg_dec, GST_BUFFER_TIMESTAMP (buffer), + GST_BUFFER_SIZE (buffer)); + + return ret; +} + +static gboolean +gst_vdp_mpeg_dec_convert (GstVdpMpegDec * mpeg_dec, + GstFormat src_format, gint64 src_value, + GstFormat dest_format, gint64 * dest_value) +{ + + if (src_format == dest_format) { + *dest_value = src_value; + return TRUE; + } + + if (mpeg_dec->byterate == -1) + return FALSE; + + if (src_format == GST_FORMAT_BYTES && dest_format == GST_FORMAT_TIME) { + *dest_value = gst_util_uint64_scale (GST_SECOND, src_value, + mpeg_dec->byterate); + return TRUE; + } + + if (src_format == GST_FORMAT_TIME && dest_format == GST_FORMAT_BYTES) { + *dest_value = + gst_util_uint64_scale_int (src_value, mpeg_dec->byterate, GST_SECOND); + return TRUE; + } + + return FALSE; +} + +static const GstQueryType * +gst_mpeg_dec_get_querytypes (GstPad * pad) +{ + static const GstQueryType list[] = { + GST_QUERY_POSITION, + GST_QUERY_DURATION, + 0 + }; + + return list; +} + +static gboolean +gst_vdp_mpeg_dec_src_query (GstPad * pad, GstQuery * query) +{ + GstVdpMpegDec *mpeg_dec = GST_VDP_MPEG_DEC (GST_OBJECT_PARENT (pad)); + gboolean res = FALSE; + + switch (GST_QUERY_TYPE (query)) { + case GST_QUERY_POSITION: + { + GstFormat format; + + if (gst_pad_query_default (pad, query)) + return TRUE; + + gst_query_parse_position (query, &format, NULL); + if (format == GST_FORMAT_TIME && + GST_CLOCK_TIME_IS_VALID (mpeg_dec->next_timestamp)) { + gst_query_set_position (query, GST_FORMAT_TIME, + mpeg_dec->next_timestamp); + res = TRUE; + } + break; + } + + case GST_QUERY_DURATION: + { + GstFormat format; + + if (gst_pad_query_default (pad, query)) + return TRUE; + + gst_query_parse_duration (query, &format, NULL); + if (format == GST_FORMAT_TIME) { + gint64 bytes; + + format = GST_FORMAT_BYTES; + if (gst_pad_query_duration (pad, &format, &bytes) + && format == GST_FORMAT_BYTES) { + gint64 duration; + + if (gst_vdp_mpeg_dec_convert (mpeg_dec, GST_FORMAT_BYTES, + bytes, GST_FORMAT_TIME, &duration)) { + GST_DEBUG ("duration: %" GST_TIME_FORMAT, GST_TIME_ARGS (duration)); + gst_query_set_duration (query, GST_FORMAT_TIME, duration); + res = TRUE; + } + } + } + break; + } + + default: + res = gst_pad_query_default (pad, query); + } + + return res; +} + +static gboolean +normal_seek (GstPad * pad, GstEvent * event) +{ + GstVdpMpegDec *mpeg_dec = GST_VDP_MPEG_DEC (GST_OBJECT_PARENT (pad)); + gdouble rate; + GstFormat format, conv; + GstSeekFlags flags; + GstSeekType cur_type, stop_type; + gint64 cur, stop; + gint64 time_cur, bytes_cur; + gint64 time_stop, bytes_stop; + gboolean res; + GstEvent *peer_event; + + GST_DEBUG ("normal seek"); + + gst_event_parse_seek (event, &rate, &format, &flags, + &cur_type, &cur, &stop_type, &stop); + + conv = GST_FORMAT_TIME; + if (!gst_vdp_mpeg_dec_convert (mpeg_dec, format, cur, conv, &time_cur)) + goto convert_failed; + if (!gst_vdp_mpeg_dec_convert (mpeg_dec, format, stop, conv, &time_stop)) + goto convert_failed; + + GST_DEBUG ("seek to time %" GST_TIME_FORMAT "-%" GST_TIME_FORMAT, + GST_TIME_ARGS (time_cur), GST_TIME_ARGS (time_stop)); + + peer_event = gst_event_new_seek (rate, GST_FORMAT_TIME, flags, + cur_type, time_cur, stop_type, time_stop); + + /* try seek on time then */ + if ((res = gst_pad_push_event (mpeg_dec->sink, peer_event))) + goto done; + + /* else we try to seek on bytes */ + conv = GST_FORMAT_BYTES; + if (!gst_vdp_mpeg_dec_convert (mpeg_dec, GST_FORMAT_TIME, time_cur, + conv, &bytes_cur)) + goto convert_failed; + if (!gst_vdp_mpeg_dec_convert (mpeg_dec, GST_FORMAT_TIME, time_stop, + conv, &bytes_stop)) + goto convert_failed; + + /* conversion succeeded, create the seek */ + peer_event = + gst_event_new_seek (rate, GST_FORMAT_BYTES, flags, + cur_type, bytes_cur, stop_type, bytes_stop); + + /* do the seek */ + res = gst_pad_push_event (mpeg_dec->sink, peer_event); + + mpeg_dec->seeking = TRUE; + +done: + return res; + + /* ERRORS */ +convert_failed: + { + /* probably unsupported seek format */ + GST_DEBUG_OBJECT (mpeg_dec, + "failed to convert format %u into GST_FORMAT_TIME", format); + return FALSE; + } +} + +static gboolean +gst_vdp_mpeg_dec_src_event (GstPad * pad, GstEvent * event) +{ + gboolean res; + + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_SEEK: + { + if (gst_pad_event_default (pad, event)) + return TRUE; + + res = normal_seek (pad, event); + break; + } + default: + res = gst_pad_event_default (pad, event); + } + + return res; +} + +static gboolean +gst_vdp_mpeg_dec_sink_event (GstPad * pad, GstEvent * event) +{ + GstVdpMpegDec *mpeg_dec = GST_VDP_MPEG_DEC (GST_OBJECT_PARENT (pad)); + gboolean res; + + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_FLUSH_STOP: + { + GST_DEBUG_OBJECT (mpeg_dec, "flush stop"); + + gst_vdp_mpeg_dec_flush (mpeg_dec); + res = gst_pad_push_event (mpeg_dec->src, event); + + break; + } + case GST_EVENT_NEWSEGMENT: + { + gboolean update; + gdouble rate; + GstFormat format; + gint64 start; + gint64 stop; + gint64 position; + + gst_event_parse_new_segment (event, &update, &rate, &format, + &start, &stop, &position); + + if (format != GST_FORMAT_TIME) { + if (!gst_vdp_mpeg_dec_convert (mpeg_dec, format, start, + GST_FORMAT_TIME, &start)) + goto convert_error; + if (!gst_vdp_mpeg_dec_convert (mpeg_dec, format, stop, + GST_FORMAT_TIME, &stop)) + goto convert_error; + if (!gst_vdp_mpeg_dec_convert (mpeg_dec, format, position, + GST_FORMAT_TIME, &position)) + goto convert_error; + + gst_segment_set_newsegment (&mpeg_dec->segment, update, rate, + GST_FORMAT_TIME, start, stop, position); + + gst_event_unref (event); + event = gst_event_new_new_segment (update, rate, GST_FORMAT_TIME, start, + stop, position); + } + + /* if we seek ourselves we don't push out a newsegment now since we + * use the calculated timestamp of the first frame for this */ + if (mpeg_dec->seeking) { + gst_event_unref (event); + return TRUE; + } + + convert_error: + res = gst_pad_push_event (mpeg_dec->src, event); + + break; + } + default: + res = gst_pad_event_default (pad, event); + } + + return res; +} + +static GstStateChangeReturn +gst_vdp_mpeg_dec_change_state (GstElement * element, GstStateChange transition) +{ + GstVdpMpegDec *mpeg_dec; + GstStateChangeReturn ret; + + mpeg_dec = GST_VDP_MPEG_DEC (element); + + switch (transition) { + case GST_STATE_CHANGE_READY_TO_PAUSED: + mpeg_dec->device = gst_vdp_get_device (mpeg_dec->display_name); + break; + default: + break; + } + + ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); + + switch (transition) { + case GST_STATE_CHANGE_PAUSED_TO_READY: + gst_vdp_mpeg_dec_reset (mpeg_dec); + break; + default: + break; + } + + return ret; +} + +/* GObject vmethod implementations */ + +static void +gst_vdp_mpeg_dec_base_init (gpointer gclass) +{ + GstElementClass *element_class = GST_ELEMENT_CLASS (gclass); + + gst_element_class_set_details_simple (element_class, + "VDPAU Mpeg Decoder", + "Decoder", + "decode mpeg stream with vdpau", + "Carl-Anton Ingmarsson "); + + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&sink_template)); + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&src_template)); +} + +/* initialize the vdpaumpegdecoder's class */ +static void +gst_vdp_mpeg_dec_class_init (GstVdpMpegDecClass * klass) +{ + GObjectClass *gobject_class; + GstElementClass *gstelement_class; + + gobject_class = (GObjectClass *) klass; + gstelement_class = (GstElementClass *) klass; + + gobject_class->finalize = gst_vdp_mpeg_dec_finalize; + gobject_class->set_property = gst_vdp_mpeg_dec_set_property; + gobject_class->get_property = gst_vdp_mpeg_dec_get_property; + + gstelement_class->change_state = + GST_DEBUG_FUNCPTR (gst_vdp_mpeg_dec_change_state); + + g_object_class_install_property (gobject_class, PROP_DISPLAY, + g_param_spec_string ("display", "Display", "X Display name", + NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); +} + +static void +gst_vdp_mpeg_dec_init_info (VdpPictureInfoMPEG1Or2 * vdp_info) +{ + vdp_info->forward_reference = VDP_INVALID_HANDLE; + vdp_info->backward_reference = VDP_INVALID_HANDLE; + vdp_info->slice_count = 0; + vdp_info->picture_structure = 3; + vdp_info->picture_coding_type = 0; + vdp_info->intra_dc_precision = 0; + vdp_info->frame_pred_frame_dct = 1; + vdp_info->concealment_motion_vectors = 0; + vdp_info->intra_vlc_format = 0; + vdp_info->alternate_scan = 0; + vdp_info->q_scale_type = 0; + vdp_info->top_field_first = 1; +} + +static void +gst_vdp_mpeg_dec_init (GstVdpMpegDec * mpeg_dec, GstVdpMpegDecClass * gclass) +{ + mpeg_dec->src = gst_pad_new_from_static_template (&src_template, "src"); + gst_pad_set_event_function (mpeg_dec->src, + GST_DEBUG_FUNCPTR (gst_vdp_mpeg_dec_src_event)); + gst_pad_set_query_function (mpeg_dec->src, + GST_DEBUG_FUNCPTR (gst_vdp_mpeg_dec_src_query)); + gst_pad_set_query_type_function (mpeg_dec->src, + GST_DEBUG_FUNCPTR (gst_mpeg_dec_get_querytypes)); + gst_element_add_pad (GST_ELEMENT (mpeg_dec), mpeg_dec->src); + + mpeg_dec->sink = gst_pad_new_from_static_template (&sink_template, "sink"); + gst_pad_set_setcaps_function (mpeg_dec->sink, + GST_DEBUG_FUNCPTR (gst_vdp_mpeg_dec_set_caps)); + gst_pad_set_chain_function (mpeg_dec->sink, + GST_DEBUG_FUNCPTR (gst_vdp_mpeg_dec_chain)); + gst_pad_set_event_function (mpeg_dec->sink, + GST_DEBUG_FUNCPTR (gst_vdp_mpeg_dec_sink_event)); + gst_element_add_pad (GST_ELEMENT (mpeg_dec), mpeg_dec->sink); + + mpeg_dec->display_name = NULL; + mpeg_dec->adapter = gst_adapter_new (); + + mpeg_dec->device = NULL; + mpeg_dec->decoder = VDP_INVALID_HANDLE; + mpeg_dec->vdp_info.forward_reference = VDP_INVALID_HANDLE; + mpeg_dec->vdp_info.backward_reference = VDP_INVALID_HANDLE; + + gst_vdp_mpeg_dec_reset (mpeg_dec); +} + +static void +gst_vdp_mpeg_dec_finalize (GObject * object) +{ + GstVdpMpegDec *mpeg_dec = (GstVdpMpegDec *) object; + + g_object_unref (mpeg_dec->adapter); +} + +static void +gst_vdp_mpeg_dec_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GstVdpMpegDec *mpeg_dec = GST_VDP_MPEG_DEC (object); + + switch (prop_id) { + case PROP_DISPLAY: + g_free (mpeg_dec->display_name); + mpeg_dec->display_name = g_value_dup_string (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_vdp_mpeg_dec_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) +{ + GstVdpMpegDec *mpeg_dec = GST_VDP_MPEG_DEC (object); + + switch (prop_id) { + case PROP_DISPLAY: + g_value_set_string (value, mpeg_dec->display_name); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} diff --git a/sys/vdpau/gstvdpmpegdec.h b/sys/vdpau/gstvdpmpegdec.h new file mode 100644 index 00000000..b60c9f59 --- /dev/null +++ b/sys/vdpau/gstvdpmpegdec.h @@ -0,0 +1,93 @@ +/* + * GStreamer + * Copyright (C) 2009 Carl-Anton Ingmarsson + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GST_VDP_MPEG_DEC_H__ +#define __GST_VDP_MPEG_DEC_H__ + +#include +#include + +#include "gstvdpdevice.h" +#include "gstvdpvideobuffer.h" + +G_BEGIN_DECLS + +#define GST_TYPE_VDP_MPEG_DEC (gst_vdp_mpeg_dec_get_type()) +#define GST_VDP_MPEG_DEC(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VDP_MPEG_DEC,GstVdpMpegDec)) +#define GST_VDP_MPEG_DEC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VDP_MPEG_DEC,GstVdpMpegDecClass)) +#define GST_IS_VDPAU_MPEG_DEC(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VDP_MPEG_DEC)) +#define GST_IS_VDPAU_MPEG_DEC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VDP_MPEG_DEC)) + +typedef struct _GstVdpMpegDec GstVdpMpegDec; +typedef struct _GstVdpMpegDecClass GstVdpMpegDecClass; + +struct _GstVdpMpegDec +{ + GstElement element; + + /* pads */ + GstPad *src; + GstPad *sink; + + gchar *display_name; + GstVdpDevice *device; + VdpDecoder decoder; + + /* stream info */ + gint width, height; + gint fps_n, fps_d; + gboolean interlaced; + gint version; + + /* currently decoded frame info */ + GstAdapter *adapter; + VdpPictureInfoMPEG1Or2 vdp_info; + guint64 frame_nr; + GstClockTime duration; + + /* frame_nr from GOP */ + guint64 gop_frame; + + /* forward and backward reference */ + GstBuffer *f_buffer; + GstBuffer *b_buffer; + + /* calculated timestamp, size and duration */ + GstClockTime next_timestamp; + guint64 accumulated_size; + guint64 accumulated_duration; + + /* seek data */ + GstSegment segment; + gboolean seeking; + gint64 byterate; + +}; + +struct _GstVdpMpegDecClass +{ + GstElementClass element_class; +}; + +GType gst_vdp_mpeg_dec_get_type (void); + +G_END_DECLS + +#endif /* __GST_VDP_MPEG_DEC_H__ */ diff --git a/sys/vdpau/gstvdpmpegdecoder.c b/sys/vdpau/gstvdpmpegdecoder.c deleted file mode 100644 index 3c4d7480..00000000 --- a/sys/vdpau/gstvdpmpegdecoder.c +++ /dev/null @@ -1,1093 +0,0 @@ -/* - * GStreamer - * Copyright (C) 2009 Carl-Anton Ingmarsson - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/** - * SECTION:element-vdpaumpegdec - * - * FIXME:Describe vdpaumpegdec here. - * - * - * Example launch line - * |[ - * gst-launch -v -m fakesrc ! vdpaumpegdec ! fakesink silent=TRUE - * ]| - * - */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include -#include -#include - -#include "mpegutil.h" -#include "gstvdpmpegdecoder.h" - -GST_DEBUG_CATEGORY_STATIC (gst_vdp_mpeg_dec_debug); -#define GST_CAT_DEFAULT gst_vdp_mpeg_dec_debug - -/* Filter signals and args */ -enum -{ - /* FILL ME */ - LAST_SIGNAL -}; - -enum -{ - PROP_0, - PROP_DISPLAY -}; - -/* the capabilities of the inputs and outputs. - * - * describe the real formats here. - */ -static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("video/mpeg, mpegversion = (int) [ 1, 2 ], " - "systemstream = (boolean) false, parsed = (boolean) true") - ); -static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("video/x-vdpau-video, " "chroma-type = (int) 0") - ); - -#define DEBUG_INIT(bla) \ -GST_DEBUG_CATEGORY_INIT (gst_vdp_mpeg_dec_debug, "vdpaumpegdec", 0, "VDPAU powered mpeg decoder"); - -GST_BOILERPLATE_FULL (GstVdpMpegDec, gst_vdp_mpeg_dec, - GstElement, GST_TYPE_ELEMENT, DEBUG_INIT); - -static void gst_vdp_mpeg_dec_init_info (VdpPictureInfoMPEG1Or2 * vdp_info); -static void gst_vdp_mpeg_dec_finalize (GObject * object); -static void gst_vdp_mpeg_dec_set_property (GObject * object, - guint prop_id, const GValue * value, GParamSpec * pspec); -static void gst_vdp_mpeg_dec_get_property (GObject * object, - guint prop_id, GValue * value, GParamSpec * pspec); - -guint8 * -mpeg_util_find_start_code (guint32 * sync_word, guint8 * cur, guint8 * end) -{ - guint32 code; - - if (G_UNLIKELY (cur == NULL)) - return NULL; - - code = *sync_word; - - while (cur < end) { - code <<= 8; - - if (code == 0x00000100) { - /* Reset the sync word accumulator */ - *sync_word = 0xffffffff; - return cur; - } - - /* Add the next available byte to the collected sync word */ - code |= *cur++; - } - - *sync_word = code; - return NULL; -} - -typedef struct -{ - GstBuffer *buffer; - guint8 *cur; - guint8 *end; -} GstVdpMpegPacketizer; - -static GstBuffer * -gst_vdp_mpeg_packetizer_get_next_packet (GstVdpMpegPacketizer * packetizer) -{ - guint32 sync_word = 0xffffff; - guint8 *packet_start; - guint8 *packet_end; - - if (!packetizer->cur) - return NULL; - - packet_start = packetizer->cur - 3; - packetizer->cur = packet_end = mpeg_util_find_start_code (&sync_word, - packetizer->cur, packetizer->end); - - if (packet_end) - packet_end -= 3; - else - packet_end = packetizer->end; - - return gst_buffer_create_sub (packetizer->buffer, - packet_start - GST_BUFFER_DATA (packetizer->buffer), - packet_end - packet_start); -} - -static void -gst_vdp_mpeg_packetizer_init (GstVdpMpegPacketizer * packetizer, - GstBuffer * buffer) -{ - guint32 sync_word = 0xffffffff; - - packetizer->buffer = buffer; - packetizer->end = GST_BUFFER_DATA (buffer) + GST_BUFFER_SIZE (buffer); - packetizer->cur = mpeg_util_find_start_code (&sync_word, - GST_BUFFER_DATA (buffer), packetizer->end); -} - -static gboolean -gst_vdp_mpeg_dec_set_caps (GstPad * pad, GstCaps * caps) -{ - GstVdpMpegDec *mpeg_dec = GST_VDP_MPEG_DEC (GST_OBJECT_PARENT (pad)); - GstStructure *structure; - - gint width, height; - gint fps_n, fps_d; - gint par_n, par_d; - gboolean interlaced = FALSE; - - GstCaps *src_caps; - gboolean res; - - const GValue *value; - VdpDecoderProfile profile; - GstVdpDevice *device; - VdpStatus status; - - structure = gst_caps_get_structure (caps, 0); - - /* create src_pad caps */ - gst_structure_get_int (structure, "width", &width); - gst_structure_get_int (structure, "height", &height); - gst_structure_get_fraction (structure, "framerate", &fps_n, &fps_d); - gst_structure_get_fraction (structure, "pixel-aspect-ratio", &par_n, &par_d); - gst_structure_get_boolean (structure, "interlaced", &interlaced); - - src_caps = gst_caps_new_simple ("video/x-vdpau-video", - "device", G_TYPE_OBJECT, mpeg_dec->device, - "chroma_type", G_TYPE_INT, VDP_CHROMA_TYPE_420, - "width", G_TYPE_INT, width, - "height", G_TYPE_INT, height, - "framerate", GST_TYPE_FRACTION, fps_n, fps_d, - "pixel-aspect-ratio", GST_TYPE_FRACTION, par_n, par_d, - "interlaced", G_TYPE_BOOLEAN, interlaced, NULL); - - res = gst_pad_set_caps (mpeg_dec->src, src_caps); - gst_caps_unref (src_caps); - if (!res) - return FALSE; - - mpeg_dec->width = width; - mpeg_dec->height = height; - mpeg_dec->fps_n = fps_n; - mpeg_dec->fps_d = fps_d; - mpeg_dec->interlaced = interlaced; - - /* parse caps to setup decoder */ - gst_structure_get_int (structure, "mpegversion", &mpeg_dec->version); - if (mpeg_dec->version == 1) - profile = VDP_DECODER_PROFILE_MPEG1; - - value = gst_structure_get_value (structure, "codec_data"); - if (value) { - GstBuffer *codec_data, *buf; - GstVdpMpegPacketizer packetizer; - - codec_data = gst_value_get_buffer (value); - gst_vdp_mpeg_packetizer_init (&packetizer, codec_data); - if ((buf = gst_vdp_mpeg_packetizer_get_next_packet (&packetizer))) { - MPEGSeqHdr hdr; - guint32 bitrate; - - mpeg_util_parse_sequence_hdr (&hdr, buf); - - memcpy (&mpeg_dec->vdp_info.intra_quantizer_matrix, - &hdr.intra_quantizer_matrix, 64); - memcpy (&mpeg_dec->vdp_info.non_intra_quantizer_matrix, - &hdr.non_intra_quantizer_matrix, 64); - - bitrate = hdr.bitrate; - gst_buffer_unref (buf); - - if ((buf = gst_vdp_mpeg_packetizer_get_next_packet (&packetizer))) { - MPEGSeqExtHdr ext; - - mpeg_util_parse_sequence_extension (&ext, buf); - if (mpeg_dec->version != 1) { - switch (ext.profile) { - case 5: - profile = VDP_DECODER_PROFILE_MPEG2_SIMPLE; - break; - default: - profile = VDP_DECODER_PROFILE_MPEG2_MAIN; - break; - } - } - - bitrate += (ext.bitrate_ext << 18);; - gst_buffer_unref (buf); - } - - mpeg_dec->duration = - gst_util_uint64_scale (1, GST_SECOND * mpeg_dec->fps_d, - mpeg_dec->fps_n); - - mpeg_dec->byterate = bitrate * 50; - GST_DEBUG ("byterate: %" G_GINT64_FORMAT, mpeg_dec->byterate); - } - } - - device = mpeg_dec->device; - - if (mpeg_dec->decoder != VDP_INVALID_HANDLE) { - device->vdp_decoder_destroy (mpeg_dec->decoder); - mpeg_dec->decoder = VDP_INVALID_HANDLE; - } - - status = device->vdp_decoder_create (device->device, profile, mpeg_dec->width, - mpeg_dec->height, 2, &mpeg_dec->decoder); - if (status != VDP_STATUS_OK) { - GST_ELEMENT_ERROR (mpeg_dec, RESOURCE, READ, - ("Could not create vdpau decoder"), - ("Error returned from vdpau was: %s", - device->vdp_get_error_string (status))); - return FALSE; - } - return TRUE; -} - -GstFlowReturn -gst_vdp_mpeg_dec_push_video_buffer (GstVdpMpegDec * mpeg_dec, - GstVdpVideoBuffer * buffer) -{ - gint64 byterate; - - if (GST_BUFFER_TIMESTAMP (buffer) == GST_CLOCK_TIME_NONE - && GST_CLOCK_TIME_IS_VALID (mpeg_dec->next_timestamp)) { - GST_BUFFER_TIMESTAMP (buffer) = mpeg_dec->next_timestamp; - } else if (GST_BUFFER_TIMESTAMP (buffer) == GST_CLOCK_TIME_NONE) { - GST_BUFFER_TIMESTAMP (buffer) = gst_util_uint64_scale (mpeg_dec->frame_nr, - GST_SECOND * mpeg_dec->fps_d, mpeg_dec->fps_n); - } - - if (mpeg_dec->seeking) { - GstEvent *event; - - event = gst_event_new_new_segment (FALSE, - mpeg_dec->segment.rate, GST_FORMAT_TIME, GST_BUFFER_TIMESTAMP (buffer), - mpeg_dec->segment.stop, GST_BUFFER_TIMESTAMP (buffer)); - - gst_pad_push_event (mpeg_dec->src, event); - - mpeg_dec->seeking = FALSE; - } - - mpeg_dec->next_timestamp = GST_BUFFER_TIMESTAMP (buffer) + - GST_BUFFER_DURATION (buffer); - - mpeg_dec->accumulated_duration += GST_BUFFER_DURATION (buffer); - mpeg_dec->accumulated_size += GST_BUFFER_SIZE (buffer); - byterate = gst_util_uint64_scale (mpeg_dec->accumulated_size, GST_SECOND, - mpeg_dec->accumulated_duration); - GST_DEBUG ("byterate: %" G_GINT64_FORMAT, mpeg_dec->byterate); - - mpeg_dec->byterate = (mpeg_dec->byterate + byterate) / 2; - - gst_buffer_set_caps (GST_BUFFER (buffer), GST_PAD_CAPS (mpeg_dec->src)); - - GST_DEBUG_OBJECT (mpeg_dec, - "Pushing buffer with timestamp: %" GST_TIME_FORMAT - " frame_nr: %" G_GINT64_FORMAT, - GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)), - GST_BUFFER_OFFSET (buffer)); - - return gst_pad_push (mpeg_dec->src, GST_BUFFER (buffer)); -} - -static GstFlowReturn -gst_vdp_mpeg_dec_decode (GstVdpMpegDec * mpeg_dec, - GstClockTime timestamp, gint64 size) -{ - VdpPictureInfoMPEG1Or2 *info; - GstBuffer *buffer; - GstVdpVideoBuffer *outbuf; - VdpVideoSurface surface; - GstVdpDevice *device; - VdpBitstreamBuffer vbit[1]; - VdpStatus status; - - info = &mpeg_dec->vdp_info; - - buffer = gst_adapter_take_buffer (mpeg_dec->adapter, - gst_adapter_available (mpeg_dec->adapter)); - - if (info->picture_coding_type != B_FRAME) { - if (info->backward_reference != VDP_INVALID_HANDLE) { - gst_buffer_ref (mpeg_dec->b_buffer); - gst_vdp_mpeg_dec_push_video_buffer (mpeg_dec, - GST_VDP_VIDEO_BUFFER (mpeg_dec->b_buffer)); - } - - if (info->forward_reference != VDP_INVALID_HANDLE) { - gst_buffer_unref (mpeg_dec->f_buffer); - info->forward_reference = VDP_INVALID_HANDLE; - } - - info->forward_reference = info->backward_reference; - mpeg_dec->f_buffer = mpeg_dec->b_buffer; - - info->backward_reference = VDP_INVALID_HANDLE; - } - - outbuf = gst_vdp_video_buffer_new (mpeg_dec->device, VDP_CHROMA_TYPE_420, - mpeg_dec->width, mpeg_dec->height); - GST_BUFFER_TIMESTAMP (outbuf) = timestamp; - GST_BUFFER_DURATION (outbuf) = mpeg_dec->duration; - GST_BUFFER_OFFSET (outbuf) = mpeg_dec->frame_nr; - GST_BUFFER_SIZE (outbuf) = size; - - if (info->top_field_first) - GST_BUFFER_FLAG_SET (outbuf, GST_VIDEO_BUFFER_TFF); - - if (info->forward_reference != VDP_INVALID_HANDLE && - info->picture_coding_type != I_FRAME) - gst_vdp_video_buffer_add_reference (outbuf, - GST_VDP_VIDEO_BUFFER (mpeg_dec->f_buffer)); - - if (info->backward_reference != VDP_INVALID_HANDLE) - gst_vdp_video_buffer_add_reference (outbuf, - GST_VDP_VIDEO_BUFFER (mpeg_dec->b_buffer)); - - surface = outbuf->surface; - - device = mpeg_dec->device; - - vbit[0].struct_version = VDP_BITSTREAM_BUFFER_VERSION; - vbit[0].bitstream = GST_BUFFER_DATA (buffer); - vbit[0].bitstream_bytes = GST_BUFFER_SIZE (buffer); - - status = device->vdp_decoder_render (mpeg_dec->decoder, surface, - (VdpPictureInfo *) info, 1, vbit); - gst_buffer_unref (buffer); - info->slice_count = 0; - - if (status != VDP_STATUS_OK) { - GST_ELEMENT_ERROR (mpeg_dec, RESOURCE, READ, - ("Could not decode"), - ("Error returned from vdpau was: %s", - device->vdp_get_error_string (status))); - - gst_buffer_unref (GST_BUFFER (outbuf)); - - return GST_FLOW_ERROR; - } - - if (info->picture_coding_type == B_FRAME) { - gst_vdp_mpeg_dec_push_video_buffer (mpeg_dec, - GST_VDP_VIDEO_BUFFER (outbuf)); - } else { - info->backward_reference = surface; - mpeg_dec->b_buffer = GST_BUFFER (outbuf); - } - - return GST_FLOW_OK; -} - -static gboolean -gst_vdp_mpeg_dec_parse_picture_coding (GstVdpMpegDec * mpeg_dec, - GstBuffer * buffer) -{ - MPEGPictureExt pic_ext; - VdpPictureInfoMPEG1Or2 *info; - gint fields; - - info = &mpeg_dec->vdp_info; - - if (!mpeg_util_parse_picture_coding_extension (&pic_ext, buffer)) - return FALSE; - - memcpy (&mpeg_dec->vdp_info.f_code, &pic_ext.f_code, 4); - - info->intra_dc_precision = pic_ext.intra_dc_precision; - info->picture_structure = pic_ext.picture_structure; - info->top_field_first = pic_ext.top_field_first; - info->frame_pred_frame_dct = pic_ext.frame_pred_frame_dct; - info->concealment_motion_vectors = pic_ext.concealment_motion_vectors; - info->q_scale_type = pic_ext.q_scale_type; - info->intra_vlc_format = pic_ext.intra_vlc_format; - info->alternate_scan = pic_ext.alternate_scan; - - fields = 2; - if (pic_ext.picture_structure == 3) { - if (mpeg_dec->interlaced) { - if (pic_ext.progressive_frame == 0) - fields = 2; - if (pic_ext.progressive_frame == 0 && pic_ext.repeat_first_field == 0) - fields = 2; - if (pic_ext.progressive_frame == 1 && pic_ext.repeat_first_field == 1) - fields = 3; - } else { - if (pic_ext.repeat_first_field == 0) - fields = 2; - if (pic_ext.repeat_first_field == 1 && pic_ext.top_field_first == 0) - fields = 4; - if (pic_ext.repeat_first_field == 1 && pic_ext.top_field_first == 1) - fields = 6; - } - } else - fields = 1; - - GST_DEBUG ("fields: %d", fields); - - mpeg_dec->duration = gst_util_uint64_scale (fields, - GST_SECOND * mpeg_dec->fps_d, 2 * mpeg_dec->fps_n); - - return TRUE; -} - -static gboolean -gst_vdp_mpeg_dec_parse_sequence (GstVdpMpegDec * mpeg_dec, GstBuffer * buffer) -{ - MPEGSeqHdr hdr; - - if (!mpeg_util_parse_sequence_hdr (&hdr, buffer)) - return FALSE; - - memcpy (&mpeg_dec->vdp_info.intra_quantizer_matrix, - &hdr.intra_quantizer_matrix, 64); - memcpy (&mpeg_dec->vdp_info.non_intra_quantizer_matrix, - &hdr.non_intra_quantizer_matrix, 64); - - return TRUE; -} - -static gboolean -gst_vdp_mpeg_dec_parse_picture (GstVdpMpegDec * mpeg_dec, GstBuffer * buffer) -{ - MPEGPictureHdr pic_hdr; - - if (!mpeg_util_parse_picture_hdr (&pic_hdr, buffer)) - return FALSE; - - if (pic_hdr.pic_type != I_FRAME - && mpeg_dec->vdp_info.backward_reference == VDP_INVALID_HANDLE) { - GST_DEBUG_OBJECT (mpeg_dec, - "Drop frame since we haven't got an I_FRAME yet"); - return FALSE; - } - if (pic_hdr.pic_type == B_FRAME - && mpeg_dec->vdp_info.forward_reference == VDP_INVALID_HANDLE) { - GST_DEBUG_OBJECT (mpeg_dec, - "Drop frame since we haven't got two non B_FRAMES yet"); - return FALSE; - } - - mpeg_dec->vdp_info.picture_coding_type = pic_hdr.pic_type; - - if (mpeg_dec->version == 1) { - mpeg_dec->vdp_info.full_pel_forward_vector = - pic_hdr.full_pel_forward_vector; - mpeg_dec->vdp_info.full_pel_backward_vector = - pic_hdr.full_pel_backward_vector; - memcpy (&mpeg_dec->vdp_info.f_code, &pic_hdr.f_code, 4); - } - - mpeg_dec->frame_nr = mpeg_dec->gop_frame + pic_hdr.tsn; - - return TRUE; -} - -static gboolean -gst_vdp_mpeg_dec_parse_gop (GstVdpMpegDec * mpeg_dec, GstBuffer * buffer) -{ - MPEGGop gop; - GstClockTime time; - - if (!mpeg_util_parse_gop (&gop, buffer)) - return FALSE; - - time = GST_SECOND * (gop.hour * 3600 + gop.minute * 60 + gop.second); - - GST_DEBUG ("gop timestamp: %" GST_TIME_FORMAT, GST_TIME_ARGS (time)); - - mpeg_dec->gop_frame = - gst_util_uint64_scale (time, mpeg_dec->fps_n, - mpeg_dec->fps_d * GST_SECOND) + gop.frame; - - return TRUE; -} - -static gboolean -gst_vdp_mpeg_dec_parse_quant_matrix (GstVdpMpegDec * mpeg_dec, - GstBuffer * buffer) -{ - MPEGQuantMatrix qm; - - if (!mpeg_util_parse_quant_matrix (&qm, buffer)) - return FALSE; - - memcpy (&mpeg_dec->vdp_info.intra_quantizer_matrix, - &qm.intra_quantizer_matrix, 64); - memcpy (&mpeg_dec->vdp_info.non_intra_quantizer_matrix, - &qm.non_intra_quantizer_matrix, 64); - return TRUE; -} - -static void -gst_vdp_mpeg_dec_flush (GstVdpMpegDec * mpeg_dec) -{ - if (mpeg_dec->vdp_info.forward_reference != VDP_INVALID_HANDLE) - gst_buffer_unref (mpeg_dec->f_buffer); - if (mpeg_dec->vdp_info.backward_reference != VDP_INVALID_HANDLE) - gst_buffer_unref (mpeg_dec->b_buffer); - - gst_vdp_mpeg_dec_init_info (&mpeg_dec->vdp_info); - - gst_adapter_clear (mpeg_dec->adapter); - - mpeg_dec->next_timestamp = GST_CLOCK_TIME_NONE; -} - -static void -gst_vdp_mpeg_dec_reset (GstVdpMpegDec * mpeg_dec) -{ - gst_vdp_mpeg_dec_flush (mpeg_dec); - - if (mpeg_dec->decoder != VDP_INVALID_HANDLE) - mpeg_dec->device->vdp_decoder_destroy (mpeg_dec->decoder); - mpeg_dec->decoder = VDP_INVALID_HANDLE; - if (mpeg_dec->device) - g_object_unref (mpeg_dec->device); - mpeg_dec->device = NULL; - - gst_segment_init (&mpeg_dec->segment, GST_FORMAT_TIME); - mpeg_dec->seeking = FALSE; - - mpeg_dec->accumulated_size = 0; - mpeg_dec->accumulated_duration = 0; -} - -static GstFlowReturn -gst_vdp_mpeg_dec_chain (GstPad * pad, GstBuffer * buffer) -{ - GstVdpMpegDec *mpeg_dec; - GstVdpMpegPacketizer packetizer; - GstBuffer *buf; - GstFlowReturn ret = GST_FLOW_OK; - - mpeg_dec = GST_VDP_MPEG_DEC (GST_OBJECT_PARENT (pad)); - - if (G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT))) { - GST_DEBUG_OBJECT (mpeg_dec, "Received discont buffer"); - gst_vdp_mpeg_dec_flush (mpeg_dec); - } - - - gst_vdp_mpeg_packetizer_init (&packetizer, buffer); - while ((buf = gst_vdp_mpeg_packetizer_get_next_packet (&packetizer))) { - GstBitReader b_reader = GST_BIT_READER_INIT_FROM_BUFFER (buf); - guint32 sync_code; - guint8 start_code; - - /* skip sync_code */ - gst_bit_reader_get_bits_uint32 (&b_reader, &sync_code, 8 * 3); - - /* start_code */ - gst_bit_reader_get_bits_uint8 (&b_reader, &start_code, 8); - - if (start_code >= MPEG_PACKET_SLICE_MIN - && start_code <= MPEG_PACKET_SLICE_MAX) { - GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_SLICE"); - - gst_buffer_ref (buf); - gst_adapter_push (mpeg_dec->adapter, buf); - mpeg_dec->vdp_info.slice_count++; - } - - switch (start_code) { - case MPEG_PACKET_PICTURE: - GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_PICTURE"); - - if (!gst_vdp_mpeg_dec_parse_picture (mpeg_dec, buf)) { - return GST_FLOW_OK; - } - break; - case MPEG_PACKET_SEQUENCE: - GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_SEQUENCE"); - gst_vdp_mpeg_dec_parse_sequence (mpeg_dec, buf); - break; - case MPEG_PACKET_EXTENSION: - { - guint8 ext_code; - - GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_EXTENSION"); - - /* ext_code */ - gst_bit_reader_get_bits_uint8 (&b_reader, &ext_code, 4); - switch (ext_code) { - case MPEG_PACKET_EXT_PICTURE_CODING: - GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_EXT_PICTURE_CODING"); - gst_vdp_mpeg_dec_parse_picture_coding (mpeg_dec, buf); - break; - case MPEG_PACKET_EXT_QUANT_MATRIX: - GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_EXT_QUANT_MATRIX"); - gst_vdp_mpeg_dec_parse_quant_matrix (mpeg_dec, buf); - break; - default: - break; - } - break; - } - case MPEG_PACKET_GOP: - GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_GOP"); - gst_vdp_mpeg_dec_parse_gop (mpeg_dec, buf); - break; - default: - break; - } - - gst_buffer_unref (buf); - } - - if (mpeg_dec->vdp_info.slice_count > 0) - ret = gst_vdp_mpeg_dec_decode (mpeg_dec, GST_BUFFER_TIMESTAMP (buffer), - GST_BUFFER_SIZE (buffer)); - - return ret; -} - -static gboolean -gst_vdp_mpeg_dec_convert (GstVdpMpegDec * mpeg_dec, - GstFormat src_format, gint64 src_value, - GstFormat dest_format, gint64 * dest_value) -{ - - if (src_format == dest_format) { - *dest_value = src_value; - return TRUE; - } - - if (mpeg_dec->byterate == -1) - return FALSE; - - if (src_format == GST_FORMAT_BYTES && dest_format == GST_FORMAT_TIME) { - *dest_value = gst_util_uint64_scale (GST_SECOND, src_value, - mpeg_dec->byterate); - return TRUE; - } - - if (src_format == GST_FORMAT_TIME && dest_format == GST_FORMAT_BYTES) { - *dest_value = - gst_util_uint64_scale_int (src_value, mpeg_dec->byterate, GST_SECOND); - return TRUE; - } - - return FALSE; -} - -static const GstQueryType * -gst_mpeg_dec_get_querytypes (GstPad * pad) -{ - static const GstQueryType list[] = { - GST_QUERY_POSITION, - GST_QUERY_DURATION, - 0 - }; - - return list; -} - -static gboolean -gst_vdp_mpeg_dec_src_query (GstPad * pad, GstQuery * query) -{ - GstVdpMpegDec *mpeg_dec = GST_VDP_MPEG_DEC (GST_OBJECT_PARENT (pad)); - gboolean res = FALSE; - - switch (GST_QUERY_TYPE (query)) { - case GST_QUERY_POSITION: - { - GstFormat format; - - if (gst_pad_query_default (pad, query)) - return TRUE; - - gst_query_parse_position (query, &format, NULL); - if (format == GST_FORMAT_TIME && - GST_CLOCK_TIME_IS_VALID (mpeg_dec->next_timestamp)) { - gst_query_set_position (query, GST_FORMAT_TIME, - mpeg_dec->next_timestamp); - res = TRUE; - } - break; - } - - case GST_QUERY_DURATION: - { - GstFormat format; - - if (gst_pad_query_default (pad, query)) - return TRUE; - - gst_query_parse_duration (query, &format, NULL); - if (format == GST_FORMAT_TIME) { - gint64 bytes; - - format = GST_FORMAT_BYTES; - if (gst_pad_query_duration (pad, &format, &bytes) - && format == GST_FORMAT_BYTES) { - gint64 duration; - - if (gst_vdp_mpeg_dec_convert (mpeg_dec, GST_FORMAT_BYTES, - bytes, GST_FORMAT_TIME, &duration)) { - GST_DEBUG ("duration: %" GST_TIME_FORMAT, GST_TIME_ARGS (duration)); - gst_query_set_duration (query, GST_FORMAT_TIME, duration); - res = TRUE; - } - } - } - break; - } - - default: - res = gst_pad_query_default (pad, query); - } - - return res; -} - -static gboolean -normal_seek (GstPad * pad, GstEvent * event) -{ - GstVdpMpegDec *mpeg_dec = GST_VDP_MPEG_DEC (GST_OBJECT_PARENT (pad)); - gdouble rate; - GstFormat format, conv; - GstSeekFlags flags; - GstSeekType cur_type, stop_type; - gint64 cur, stop; - gint64 time_cur, bytes_cur; - gint64 time_stop, bytes_stop; - gboolean res; - GstEvent *peer_event; - - GST_DEBUG ("normal seek"); - - gst_event_parse_seek (event, &rate, &format, &flags, - &cur_type, &cur, &stop_type, &stop); - - conv = GST_FORMAT_TIME; - if (!gst_vdp_mpeg_dec_convert (mpeg_dec, format, cur, conv, &time_cur)) - goto convert_failed; - if (!gst_vdp_mpeg_dec_convert (mpeg_dec, format, stop, conv, &time_stop)) - goto convert_failed; - - GST_DEBUG ("seek to time %" GST_TIME_FORMAT "-%" GST_TIME_FORMAT, - GST_TIME_ARGS (time_cur), GST_TIME_ARGS (time_stop)); - - peer_event = gst_event_new_seek (rate, GST_FORMAT_TIME, flags, - cur_type, time_cur, stop_type, time_stop); - - /* try seek on time then */ - if ((res = gst_pad_push_event (mpeg_dec->sink, peer_event))) - goto done; - - /* else we try to seek on bytes */ - conv = GST_FORMAT_BYTES; - if (!gst_vdp_mpeg_dec_convert (mpeg_dec, GST_FORMAT_TIME, time_cur, - conv, &bytes_cur)) - goto convert_failed; - if (!gst_vdp_mpeg_dec_convert (mpeg_dec, GST_FORMAT_TIME, time_stop, - conv, &bytes_stop)) - goto convert_failed; - - /* conversion succeeded, create the seek */ - peer_event = - gst_event_new_seek (rate, GST_FORMAT_BYTES, flags, - cur_type, bytes_cur, stop_type, bytes_stop); - - /* do the seek */ - res = gst_pad_push_event (mpeg_dec->sink, peer_event); - - mpeg_dec->seeking = TRUE; - -done: - return res; - - /* ERRORS */ -convert_failed: - { - /* probably unsupported seek format */ - GST_DEBUG_OBJECT (mpeg_dec, - "failed to convert format %u into GST_FORMAT_TIME", format); - return FALSE; - } -} - -static gboolean -gst_vdp_mpeg_dec_src_event (GstPad * pad, GstEvent * event) -{ - gboolean res; - - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_SEEK: - { - if (gst_pad_event_default (pad, event)) - return TRUE; - - res = normal_seek (pad, event); - break; - } - default: - res = gst_pad_event_default (pad, event); - } - - return res; -} - -static gboolean -gst_vdp_mpeg_dec_sink_event (GstPad * pad, GstEvent * event) -{ - GstVdpMpegDec *mpeg_dec = GST_VDP_MPEG_DEC (GST_OBJECT_PARENT (pad)); - gboolean res; - - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_FLUSH_STOP: - { - GST_DEBUG_OBJECT (mpeg_dec, "flush stop"); - - gst_vdp_mpeg_dec_flush (mpeg_dec); - res = gst_pad_push_event (mpeg_dec->src, event); - - break; - } - case GST_EVENT_NEWSEGMENT: - { - gboolean update; - gdouble rate; - GstFormat format; - gint64 start; - gint64 stop; - gint64 position; - - gst_event_parse_new_segment (event, &update, &rate, &format, - &start, &stop, &position); - - if (format != GST_FORMAT_TIME) { - if (!gst_vdp_mpeg_dec_convert (mpeg_dec, format, start, - GST_FORMAT_TIME, &start)) - goto convert_error; - if (!gst_vdp_mpeg_dec_convert (mpeg_dec, format, stop, - GST_FORMAT_TIME, &stop)) - goto convert_error; - if (!gst_vdp_mpeg_dec_convert (mpeg_dec, format, position, - GST_FORMAT_TIME, &position)) - goto convert_error; - - gst_segment_set_newsegment (&mpeg_dec->segment, update, rate, - GST_FORMAT_TIME, start, stop, position); - - gst_event_unref (event); - event = gst_event_new_new_segment (update, rate, GST_FORMAT_TIME, start, - stop, position); - } - - /* if we seek ourselves we don't push out a newsegment now since we - * use the calculated timestamp of the first frame for this */ - if (mpeg_dec->seeking) { - gst_event_unref (event); - return TRUE; - } - - convert_error: - res = gst_pad_push_event (mpeg_dec->src, event); - - break; - } - default: - res = gst_pad_event_default (pad, event); - } - - return res; -} - -static GstStateChangeReturn -gst_vdp_mpeg_dec_change_state (GstElement * element, GstStateChange transition) -{ - GstVdpMpegDec *mpeg_dec; - GstStateChangeReturn ret; - - mpeg_dec = GST_VDP_MPEG_DEC (element); - - switch (transition) { - case GST_STATE_CHANGE_READY_TO_PAUSED: - mpeg_dec->device = gst_vdp_get_device (mpeg_dec->display_name); - break; - default: - break; - } - - ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); - - switch (transition) { - case GST_STATE_CHANGE_PAUSED_TO_READY: - gst_vdp_mpeg_dec_reset (mpeg_dec); - break; - default: - break; - } - - return ret; -} - -/* GObject vmethod implementations */ - -static void -gst_vdp_mpeg_dec_base_init (gpointer gclass) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS (gclass); - - gst_element_class_set_details_simple (element_class, - "VDPAU Mpeg Decoder", - "Decoder", - "decode mpeg stream with vdpau", - "Carl-Anton Ingmarsson "); - - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&sink_template)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&src_template)); -} - -/* initialize the vdpaumpegdecoder's class */ -static void -gst_vdp_mpeg_dec_class_init (GstVdpMpegDecClass * klass) -{ - GObjectClass *gobject_class; - GstElementClass *gstelement_class; - - gobject_class = (GObjectClass *) klass; - gstelement_class = (GstElementClass *) klass; - - gobject_class->finalize = gst_vdp_mpeg_dec_finalize; - gobject_class->set_property = gst_vdp_mpeg_dec_set_property; - gobject_class->get_property = gst_vdp_mpeg_dec_get_property; - - gstelement_class->change_state = - GST_DEBUG_FUNCPTR (gst_vdp_mpeg_dec_change_state); - - g_object_class_install_property (gobject_class, PROP_DISPLAY, - g_param_spec_string ("display", "Display", "X Display name", - NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); -} - -static void -gst_vdp_mpeg_dec_init_info (VdpPictureInfoMPEG1Or2 * vdp_info) -{ - vdp_info->forward_reference = VDP_INVALID_HANDLE; - vdp_info->backward_reference = VDP_INVALID_HANDLE; - vdp_info->slice_count = 0; - vdp_info->picture_structure = 3; - vdp_info->picture_coding_type = 0; - vdp_info->intra_dc_precision = 0; - vdp_info->frame_pred_frame_dct = 1; - vdp_info->concealment_motion_vectors = 0; - vdp_info->intra_vlc_format = 0; - vdp_info->alternate_scan = 0; - vdp_info->q_scale_type = 0; - vdp_info->top_field_first = 1; -} - -static void -gst_vdp_mpeg_dec_init (GstVdpMpegDec * mpeg_dec, GstVdpMpegDecClass * gclass) -{ - mpeg_dec->src = gst_pad_new_from_static_template (&src_template, "src"); - gst_pad_set_event_function (mpeg_dec->src, - GST_DEBUG_FUNCPTR (gst_vdp_mpeg_dec_src_event)); - gst_pad_set_query_function (mpeg_dec->src, - GST_DEBUG_FUNCPTR (gst_vdp_mpeg_dec_src_query)); - gst_pad_set_query_type_function (mpeg_dec->src, - GST_DEBUG_FUNCPTR (gst_mpeg_dec_get_querytypes)); - gst_element_add_pad (GST_ELEMENT (mpeg_dec), mpeg_dec->src); - - mpeg_dec->sink = gst_pad_new_from_static_template (&sink_template, "sink"); - gst_pad_set_setcaps_function (mpeg_dec->sink, - GST_DEBUG_FUNCPTR (gst_vdp_mpeg_dec_set_caps)); - gst_pad_set_chain_function (mpeg_dec->sink, - GST_DEBUG_FUNCPTR (gst_vdp_mpeg_dec_chain)); - gst_pad_set_event_function (mpeg_dec->sink, - GST_DEBUG_FUNCPTR (gst_vdp_mpeg_dec_sink_event)); - gst_element_add_pad (GST_ELEMENT (mpeg_dec), mpeg_dec->sink); - - mpeg_dec->display_name = NULL; - mpeg_dec->adapter = gst_adapter_new (); - - mpeg_dec->device = NULL; - mpeg_dec->decoder = VDP_INVALID_HANDLE; - mpeg_dec->vdp_info.forward_reference = VDP_INVALID_HANDLE; - mpeg_dec->vdp_info.backward_reference = VDP_INVALID_HANDLE; - - gst_vdp_mpeg_dec_reset (mpeg_dec); -} - -static void -gst_vdp_mpeg_dec_finalize (GObject * object) -{ - GstVdpMpegDec *mpeg_dec = (GstVdpMpegDec *) object; - - g_object_unref (mpeg_dec->adapter); -} - -static void -gst_vdp_mpeg_dec_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) -{ - GstVdpMpegDec *mpeg_dec = GST_VDP_MPEG_DEC (object); - - switch (prop_id) { - case PROP_DISPLAY: - g_free (mpeg_dec->display_name); - mpeg_dec->display_name = g_value_dup_string (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_vdp_mpeg_dec_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec) -{ - GstVdpMpegDec *mpeg_dec = GST_VDP_MPEG_DEC (object); - - switch (prop_id) { - case PROP_DISPLAY: - g_value_set_string (value, mpeg_dec->display_name); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} diff --git a/sys/vdpau/gstvdpmpegdecoder.h b/sys/vdpau/gstvdpmpegdecoder.h deleted file mode 100644 index b60c9f59..00000000 --- a/sys/vdpau/gstvdpmpegdecoder.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * GStreamer - * Copyright (C) 2009 Carl-Anton Ingmarsson - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __GST_VDP_MPEG_DEC_H__ -#define __GST_VDP_MPEG_DEC_H__ - -#include -#include - -#include "gstvdpdevice.h" -#include "gstvdpvideobuffer.h" - -G_BEGIN_DECLS - -#define GST_TYPE_VDP_MPEG_DEC (gst_vdp_mpeg_dec_get_type()) -#define GST_VDP_MPEG_DEC(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VDP_MPEG_DEC,GstVdpMpegDec)) -#define GST_VDP_MPEG_DEC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VDP_MPEG_DEC,GstVdpMpegDecClass)) -#define GST_IS_VDPAU_MPEG_DEC(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VDP_MPEG_DEC)) -#define GST_IS_VDPAU_MPEG_DEC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VDP_MPEG_DEC)) - -typedef struct _GstVdpMpegDec GstVdpMpegDec; -typedef struct _GstVdpMpegDecClass GstVdpMpegDecClass; - -struct _GstVdpMpegDec -{ - GstElement element; - - /* pads */ - GstPad *src; - GstPad *sink; - - gchar *display_name; - GstVdpDevice *device; - VdpDecoder decoder; - - /* stream info */ - gint width, height; - gint fps_n, fps_d; - gboolean interlaced; - gint version; - - /* currently decoded frame info */ - GstAdapter *adapter; - VdpPictureInfoMPEG1Or2 vdp_info; - guint64 frame_nr; - GstClockTime duration; - - /* frame_nr from GOP */ - guint64 gop_frame; - - /* forward and backward reference */ - GstBuffer *f_buffer; - GstBuffer *b_buffer; - - /* calculated timestamp, size and duration */ - GstClockTime next_timestamp; - guint64 accumulated_size; - guint64 accumulated_duration; - - /* seek data */ - GstSegment segment; - gboolean seeking; - gint64 byterate; - -}; - -struct _GstVdpMpegDecClass -{ - GstElementClass element_class; -}; - -GType gst_vdp_mpeg_dec_get_type (void); - -G_END_DECLS - -#endif /* __GST_VDP_MPEG_DEC_H__ */ -- cgit v1.2.1 From e9f028957d6036c5fc51f6111340e917554d3eff Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Fri, 5 Jun 2009 22:28:02 +0200 Subject: vdpaumpegdec: set GST_BUFFER_FLAG_DELTA_UNIT on non I_FRAME's --- sys/vdpau/gstvdpmpegdec.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'sys') diff --git a/sys/vdpau/gstvdpmpegdec.c b/sys/vdpau/gstvdpmpegdec.c index b011833e..7eb05afa 100644 --- a/sys/vdpau/gstvdpmpegdec.c +++ b/sys/vdpau/gstvdpmpegdec.c @@ -369,8 +369,16 @@ gst_vdp_mpeg_dec_decode (GstVdpMpegDec * mpeg_dec, GST_BUFFER_OFFSET (outbuf) = mpeg_dec->frame_nr; GST_BUFFER_SIZE (outbuf) = size; + if (info->picture_coding_type == I_FRAME) + GST_BUFFER_FLAG_UNSET (outbuf, GST_BUFFER_FLAG_DELTA_UNIT); + else + GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DELTA_UNIT); + if (info->top_field_first) GST_BUFFER_FLAG_SET (outbuf, GST_VIDEO_BUFFER_TFF); + else + GST_BUFFER_FLAG_UNSET (outbuf, GST_VIDEO_BUFFER_TFF); + if (info->forward_reference != VDP_INVALID_HANDLE && info->picture_coding_type != I_FRAME) -- cgit v1.2.1 From d65d4c40f5bc3d883ac934284b07f564eadebd71 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Fri, 5 Jun 2009 23:11:18 +0200 Subject: vdpaumpegdec: small cleanups --- sys/vdpau/gstvdpmpegdec.c | 39 ++++++++++++++++++++------------------- sys/vdpau/mpegutil.c | 22 ++++++++++++---------- 2 files changed, 32 insertions(+), 29 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpmpegdec.c b/sys/vdpau/gstvdpmpegdec.c index 7eb05afa..e85b1ec3 100644 --- a/sys/vdpau/gstvdpmpegdec.c +++ b/sys/vdpau/gstvdpmpegdec.c @@ -344,24 +344,6 @@ gst_vdp_mpeg_dec_decode (GstVdpMpegDec * mpeg_dec, buffer = gst_adapter_take_buffer (mpeg_dec->adapter, gst_adapter_available (mpeg_dec->adapter)); - if (info->picture_coding_type != B_FRAME) { - if (info->backward_reference != VDP_INVALID_HANDLE) { - gst_buffer_ref (mpeg_dec->b_buffer); - gst_vdp_mpeg_dec_push_video_buffer (mpeg_dec, - GST_VDP_VIDEO_BUFFER (mpeg_dec->b_buffer)); - } - - if (info->forward_reference != VDP_INVALID_HANDLE) { - gst_buffer_unref (mpeg_dec->f_buffer); - info->forward_reference = VDP_INVALID_HANDLE; - } - - info->forward_reference = info->backward_reference; - mpeg_dec->f_buffer = mpeg_dec->b_buffer; - - info->backward_reference = VDP_INVALID_HANDLE; - } - outbuf = gst_vdp_video_buffer_new (mpeg_dec->device, VDP_CHROMA_TYPE_420, mpeg_dec->width, mpeg_dec->height); GST_BUFFER_TIMESTAMP (outbuf) = timestamp; @@ -380,12 +362,31 @@ gst_vdp_mpeg_dec_decode (GstVdpMpegDec * mpeg_dec, GST_BUFFER_FLAG_UNSET (outbuf, GST_VIDEO_BUFFER_TFF); + if (info->picture_coding_type != B_FRAME) { + if (info->backward_reference != VDP_INVALID_HANDLE) { + gst_buffer_ref (mpeg_dec->b_buffer); + gst_vdp_mpeg_dec_push_video_buffer (mpeg_dec, + GST_VDP_VIDEO_BUFFER (mpeg_dec->b_buffer)); + } + + if (info->forward_reference != VDP_INVALID_HANDLE) { + gst_buffer_unref (mpeg_dec->f_buffer); + info->forward_reference = VDP_INVALID_HANDLE; + } + + info->forward_reference = info->backward_reference; + mpeg_dec->f_buffer = mpeg_dec->b_buffer; + + info->backward_reference = VDP_INVALID_HANDLE; + } + if (info->forward_reference != VDP_INVALID_HANDLE && info->picture_coding_type != I_FRAME) gst_vdp_video_buffer_add_reference (outbuf, GST_VDP_VIDEO_BUFFER (mpeg_dec->f_buffer)); - if (info->backward_reference != VDP_INVALID_HANDLE) + if (info->backward_reference != VDP_INVALID_HANDLE + && info->picture_coding_type == B_FRAME) gst_vdp_video_buffer_add_reference (outbuf, GST_VDP_VIDEO_BUFFER (mpeg_dec->b_buffer)); diff --git a/sys/vdpau/mpegutil.c b/sys/vdpau/mpegutil.c index 5348bd6a..b52ab6f8 100644 --- a/sys/vdpau/mpegutil.c +++ b/sys/vdpau/mpegutil.c @@ -256,20 +256,22 @@ mpeg_util_parse_picture_hdr (MPEGPictureHdr * hdr, GstBuffer * buffer) if (!gst_bit_reader_get_bits_uint8 (&reader, &hdr->f_code[0][0], 3)) return FALSE; hdr->f_code[0][1] = hdr->f_code[0][0]; + } else { + hdr->full_pel_forward_vector = 0; + hdr->f_code[0][0] = hdr->f_code[0][1] = 0; + } - if (hdr->pic_type == B_FRAME) { - if (!gst_bit_reader_get_bits_uint8 (&reader, - &hdr->full_pel_backward_vector, 1)) - return FALSE; + if (hdr->pic_type == B_FRAME) { + if (!gst_bit_reader_get_bits_uint8 (&reader, + &hdr->full_pel_backward_vector, 1)) + return FALSE; - if (!gst_bit_reader_get_bits_uint8 (&reader, &hdr->f_code[1][0], 3)) - return FALSE; - hdr->f_code[1][1] = hdr->f_code[1][0]; - } else - hdr->full_pel_backward_vector = 0; + if (!gst_bit_reader_get_bits_uint8 (&reader, &hdr->f_code[1][0], 3)) + return FALSE; + hdr->f_code[1][1] = hdr->f_code[1][0]; } else { - hdr->full_pel_forward_vector = 0; hdr->full_pel_backward_vector = 0; + hdr->f_code[1][0] = hdr->f_code[1][1] = 0; } return TRUE; -- cgit v1.2.1 From 702cc4a03f26267b562eade5fb2b4f1889015b95 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Sat, 6 Jun 2009 21:27:52 +0200 Subject: vdpaumpegdec: further work on seeking --- sys/vdpau/gstvdpmpegdec.c | 61 +++++++++++++++++++++-------------------------- 1 file changed, 27 insertions(+), 34 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpmpegdec.c b/sys/vdpau/gstvdpmpegdec.c index e85b1ec3..c5d6fde5 100644 --- a/sys/vdpau/gstvdpmpegdec.c +++ b/sys/vdpau/gstvdpmpegdec.c @@ -308,6 +308,9 @@ gst_vdp_mpeg_dec_push_video_buffer (GstVdpMpegDec * mpeg_dec, mpeg_dec->next_timestamp = GST_BUFFER_TIMESTAMP (buffer) + GST_BUFFER_DURATION (buffer); + gst_segment_set_last_stop (&mpeg_dec->segment, GST_FORMAT_TIME, + GST_BUFFER_TIMESTAMP (buffer)); + mpeg_dec->accumulated_duration += GST_BUFFER_DURATION (buffer); mpeg_dec->accumulated_size += GST_BUFFER_SIZE (buffer); byterate = gst_util_uint64_scale (mpeg_dec->accumulated_size, GST_SECOND, @@ -795,53 +798,46 @@ normal_seek (GstPad * pad, GstEvent * event) GstFormat format, conv; GstSeekFlags flags; GstSeekType cur_type, stop_type; - gint64 cur, stop; gint64 time_cur, bytes_cur; gint64 time_stop, bytes_stop; gboolean res; + gboolean update; GstEvent *peer_event; GST_DEBUG ("normal seek"); gst_event_parse_seek (event, &rate, &format, &flags, - &cur_type, &cur, &stop_type, &stop); - - conv = GST_FORMAT_TIME; - if (!gst_vdp_mpeg_dec_convert (mpeg_dec, format, cur, conv, &time_cur)) - goto convert_failed; - if (!gst_vdp_mpeg_dec_convert (mpeg_dec, format, stop, conv, &time_stop)) - goto convert_failed; + &cur_type, &time_cur, &stop_type, &time_stop); - GST_DEBUG ("seek to time %" GST_TIME_FORMAT "-%" GST_TIME_FORMAT, - GST_TIME_ARGS (time_cur), GST_TIME_ARGS (time_stop)); + if (format != GST_FORMAT_TIME) + return FALSE; - peer_event = gst_event_new_seek (rate, GST_FORMAT_TIME, flags, - cur_type, time_cur, stop_type, time_stop); + gst_segment_set_seek (&mpeg_dec->segment, rate, GST_FORMAT_TIME, flags, + cur_type, time_cur, stop_type, time_stop, &update); - /* try seek on time then */ - if ((res = gst_pad_push_event (mpeg_dec->sink, peer_event))) - goto done; + if (update) { - /* else we try to seek on bytes */ - conv = GST_FORMAT_BYTES; - if (!gst_vdp_mpeg_dec_convert (mpeg_dec, GST_FORMAT_TIME, time_cur, - conv, &bytes_cur)) - goto convert_failed; - if (!gst_vdp_mpeg_dec_convert (mpeg_dec, GST_FORMAT_TIME, time_stop, - conv, &bytes_stop)) - goto convert_failed; + /* seek on bytes */ + conv = GST_FORMAT_BYTES; + if (!gst_vdp_mpeg_dec_convert (mpeg_dec, GST_FORMAT_TIME, time_cur, + conv, &bytes_cur)) + goto convert_failed; + if (!gst_vdp_mpeg_dec_convert (mpeg_dec, GST_FORMAT_TIME, time_stop, + conv, &bytes_stop)) + goto convert_failed; - /* conversion succeeded, create the seek */ - peer_event = - gst_event_new_seek (rate, GST_FORMAT_BYTES, flags, - cur_type, bytes_cur, stop_type, bytes_stop); + /* conversion succeeded, create the seek */ + peer_event = + gst_event_new_seek (rate, GST_FORMAT_BYTES, flags, + cur_type, bytes_cur, stop_type, bytes_stop); - /* do the seek */ - res = gst_pad_push_event (mpeg_dec->sink, peer_event); + mpeg_dec->seeking = TRUE; - mpeg_dec->seeking = TRUE; + /* do the seek */ + res = gst_pad_push_event (mpeg_dec->sink, peer_event); + } else + res = FALSE; -done: return res; /* ERRORS */ @@ -914,9 +910,6 @@ gst_vdp_mpeg_dec_sink_event (GstPad * pad, GstEvent * event) GST_FORMAT_TIME, &position)) goto convert_error; - gst_segment_set_newsegment (&mpeg_dec->segment, update, rate, - GST_FORMAT_TIME, start, stop, position); - gst_event_unref (event); event = gst_event_new_new_segment (update, rate, GST_FORMAT_TIME, start, stop, position); -- cgit v1.2.1 From 3fa60712f2f86591d7ab7b0c454e1676ad72b751 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Sun, 7 Jun 2009 00:55:55 +0200 Subject: vdpaumpegdec: use gst_pad_get_parent for threadsafety --- sys/vdpau/gstvdpmpegdec.c | 64 ++++++++++++++++++++++++++++++----------------- 1 file changed, 41 insertions(+), 23 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpmpegdec.c b/sys/vdpau/gstvdpmpegdec.c index c5d6fde5..bcff055f 100644 --- a/sys/vdpau/gstvdpmpegdec.c +++ b/sys/vdpau/gstvdpmpegdec.c @@ -161,7 +161,7 @@ gst_vdp_mpeg_packetizer_init (GstVdpMpegPacketizer * packetizer, static gboolean gst_vdp_mpeg_dec_set_caps (GstPad * pad, GstCaps * caps) { - GstVdpMpegDec *mpeg_dec = GST_VDP_MPEG_DEC (GST_OBJECT_PARENT (pad)); + GstVdpMpegDec *mpeg_dec = GST_VDP_MPEG_DEC (gst_pad_get_parent (pad)); GstStructure *structure; gint width, height; @@ -198,7 +198,7 @@ gst_vdp_mpeg_dec_set_caps (GstPad * pad, GstCaps * caps) res = gst_pad_set_caps (mpeg_dec->src, src_caps); gst_caps_unref (src_caps); if (!res) - return FALSE; + goto done; mpeg_dec->width = width; mpeg_dec->height = height; @@ -274,9 +274,15 @@ gst_vdp_mpeg_dec_set_caps (GstPad * pad, GstCaps * caps) ("Could not create vdpau decoder"), ("Error returned from vdpau was: %s", device->vdp_get_error_string (status))); - return FALSE; + res = FALSE; + goto done; } - return TRUE; + res = TRUE; + +done: + gst_object_unref (mpeg_dec); + + return res; } GstFlowReturn @@ -605,13 +611,11 @@ gst_vdp_mpeg_dec_reset (GstVdpMpegDec * mpeg_dec) static GstFlowReturn gst_vdp_mpeg_dec_chain (GstPad * pad, GstBuffer * buffer) { - GstVdpMpegDec *mpeg_dec; + GstVdpMpegDec *mpeg_dec = GST_VDP_MPEG_DEC (gst_pad_get_parent (pad)); GstVdpMpegPacketizer packetizer; GstBuffer *buf; GstFlowReturn ret = GST_FLOW_OK; - mpeg_dec = GST_VDP_MPEG_DEC (GST_OBJECT_PARENT (pad)); - if (G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT))) { GST_DEBUG_OBJECT (mpeg_dec, "Received discont buffer"); gst_vdp_mpeg_dec_flush (mpeg_dec); @@ -643,9 +647,9 @@ gst_vdp_mpeg_dec_chain (GstPad * pad, GstBuffer * buffer) case MPEG_PACKET_PICTURE: GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_PICTURE"); - if (!gst_vdp_mpeg_dec_parse_picture (mpeg_dec, buf)) { - return GST_FLOW_OK; - } + if (!gst_vdp_mpeg_dec_parse_picture (mpeg_dec, buf)) + goto done; + break; case MPEG_PACKET_SEQUENCE: GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_SEQUENCE"); @@ -688,6 +692,9 @@ gst_vdp_mpeg_dec_chain (GstPad * pad, GstBuffer * buffer) ret = gst_vdp_mpeg_dec_decode (mpeg_dec, GST_BUFFER_TIMESTAMP (buffer), GST_BUFFER_SIZE (buffer)); +done: + gst_object_unref (mpeg_dec); + return ret; } @@ -735,16 +742,16 @@ gst_mpeg_dec_get_querytypes (GstPad * pad) static gboolean gst_vdp_mpeg_dec_src_query (GstPad * pad, GstQuery * query) { - GstVdpMpegDec *mpeg_dec = GST_VDP_MPEG_DEC (GST_OBJECT_PARENT (pad)); - gboolean res = FALSE; + GstVdpMpegDec *mpeg_dec = GST_VDP_MPEG_DEC (gst_pad_get_parent (pad)); + gboolean res; switch (GST_QUERY_TYPE (query)) { case GST_QUERY_POSITION: { GstFormat format; - if (gst_pad_query_default (pad, query)) - return TRUE; + if ((res = gst_pad_query_default (pad, query))) + goto done; gst_query_parse_position (query, &format, NULL); if (format == GST_FORMAT_TIME && @@ -760,8 +767,8 @@ gst_vdp_mpeg_dec_src_query (GstPad * pad, GstQuery * query) { GstFormat format; - if (gst_pad_query_default (pad, query)) - return TRUE; + if ((res = gst_pad_query_default (pad, query))) + goto done; gst_query_parse_duration (query, &format, NULL); if (format == GST_FORMAT_TIME) { @@ -787,13 +794,15 @@ gst_vdp_mpeg_dec_src_query (GstPad * pad, GstQuery * query) res = gst_pad_query_default (pad, query); } +done: + gst_object_unref (mpeg_dec); + return res; } static gboolean -normal_seek (GstPad * pad, GstEvent * event) +normal_seek (GstVdpMpegDec * mpeg_dec, GstEvent * event) { - GstVdpMpegDec *mpeg_dec = GST_VDP_MPEG_DEC (GST_OBJECT_PARENT (pad)); gdouble rate; GstFormat format, conv; GstSeekFlags flags; @@ -853,28 +862,33 @@ convert_failed: static gboolean gst_vdp_mpeg_dec_src_event (GstPad * pad, GstEvent * event) { + GstVdpMpegDec *mpeg_dec = GST_VDP_MPEG_DEC (gst_pad_get_parent (pad)); gboolean res; switch (GST_EVENT_TYPE (event)) { case GST_EVENT_SEEK: { - if (gst_pad_event_default (pad, event)) - return TRUE; + if ((res = gst_pad_event_default (pad, event))) + goto done; + + res = normal_seek (mpeg_dec, event); - res = normal_seek (pad, event); break; } default: res = gst_pad_event_default (pad, event); } +done: + gst_object_unref (mpeg_dec); + return res; } static gboolean gst_vdp_mpeg_dec_sink_event (GstPad * pad, GstEvent * event) { - GstVdpMpegDec *mpeg_dec = GST_VDP_MPEG_DEC (GST_OBJECT_PARENT (pad)); + GstVdpMpegDec *mpeg_dec = GST_VDP_MPEG_DEC (gst_pad_get_parent (pad)); gboolean res; switch (GST_EVENT_TYPE (event)) { @@ -919,7 +933,8 @@ gst_vdp_mpeg_dec_sink_event (GstPad * pad, GstEvent * event) * use the calculated timestamp of the first frame for this */ if (mpeg_dec->seeking) { gst_event_unref (event); - return TRUE; + res = TRUE; + goto done; } convert_error: @@ -931,6 +946,9 @@ gst_vdp_mpeg_dec_sink_event (GstPad * pad, GstEvent * event) res = gst_pad_event_default (pad, event); } +done: + gst_object_unref (mpeg_dec); + return res; } -- cgit v1.2.1 From 636ae49bee677ee56f6c480c78f6f4eda8eeab51 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Sun, 7 Jun 2009 01:12:50 +0200 Subject: vdpaumpegdec: use mutex to protect mpeg_dec->seeking from concurrent access --- sys/vdpau/gstvdpmpegdec.c | 14 +++++++++++++- sys/vdpau/gstvdpmpegdec.h | 3 +++ 2 files changed, 16 insertions(+), 1 deletion(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpmpegdec.c b/sys/vdpau/gstvdpmpegdec.c index bcff055f..759eb7f9 100644 --- a/sys/vdpau/gstvdpmpegdec.c +++ b/sys/vdpau/gstvdpmpegdec.c @@ -840,10 +840,16 @@ normal_seek (GstVdpMpegDec * mpeg_dec, GstEvent * event) gst_event_new_seek (rate, GST_FORMAT_BYTES, flags, cur_type, bytes_cur, stop_type, bytes_stop); - mpeg_dec->seeking = TRUE; + g_mutex_lock (mpeg_dec->mutex); /* do the seek */ res = gst_pad_push_event (mpeg_dec->sink, peer_event); + + if (res) + mpeg_dec->seeking = TRUE; + + g_mutex_unlock (mpeg_dec->mutex); + } else res = FALSE; @@ -929,13 +935,16 @@ gst_vdp_mpeg_dec_sink_event (GstPad * pad, GstEvent * event) stop, position); } + g_mutex_lock (mpeg_dec->mutex); /* if we seek ourselves we don't push out a newsegment now since we * use the calculated timestamp of the first frame for this */ if (mpeg_dec->seeking) { gst_event_unref (event); res = TRUE; + g_mutex_unlock (mpeg_dec->mutex); goto done; } + g_mutex_unlock (mpeg_dec->mutex); convert_error: res = gst_pad_push_event (mpeg_dec->src, event); @@ -1069,6 +1078,8 @@ gst_vdp_mpeg_dec_init (GstVdpMpegDec * mpeg_dec, GstVdpMpegDecClass * gclass) mpeg_dec->vdp_info.backward_reference = VDP_INVALID_HANDLE; gst_vdp_mpeg_dec_reset (mpeg_dec); + + mpeg_dec->mutex = g_mutex_new (); } static void @@ -1077,6 +1088,7 @@ gst_vdp_mpeg_dec_finalize (GObject * object) GstVdpMpegDec *mpeg_dec = (GstVdpMpegDec *) object; g_object_unref (mpeg_dec->adapter); + g_mutex_free (mpeg_dec->mutex); } static void diff --git a/sys/vdpau/gstvdpmpegdec.h b/sys/vdpau/gstvdpmpegdec.h index b60c9f59..66a41805 100644 --- a/sys/vdpau/gstvdpmpegdec.h +++ b/sys/vdpau/gstvdpmpegdec.h @@ -78,6 +78,9 @@ struct _GstVdpMpegDec GstSegment segment; gboolean seeking; gint64 byterate; + + /* mutex */ + GMutex *mutex; }; -- cgit v1.2.1 From 64100e473754c70cfba76f1ba1ff7eb297c954db Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Sun, 7 Jun 2009 01:25:01 +0200 Subject: vdpaumpegdec: send newsegment event if only the rate has been updated --- sys/vdpau/gstvdpmpegdec.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpmpegdec.c b/sys/vdpau/gstvdpmpegdec.c index 759eb7f9..931de5a4 100644 --- a/sys/vdpau/gstvdpmpegdec.c +++ b/sys/vdpau/gstvdpmpegdec.c @@ -825,7 +825,6 @@ normal_seek (GstVdpMpegDec * mpeg_dec, GstEvent * event) cur_type, time_cur, stop_type, time_stop, &update); if (update) { - /* seek on bytes */ conv = GST_FORMAT_BYTES; if (!gst_vdp_mpeg_dec_convert (mpeg_dec, GST_FORMAT_TIME, time_cur, @@ -850,8 +849,17 @@ normal_seek (GstVdpMpegDec * mpeg_dec, GstEvent * event) g_mutex_unlock (mpeg_dec->mutex); - } else - res = FALSE; + } else { + GstEvent *event; + + /* send segment with new rate */ + event = gst_event_new_new_segment (TRUE, + mpeg_dec->segment.rate, GST_FORMAT_TIME, mpeg_dec->segment.start, + mpeg_dec->segment.stop, mpeg_dec->segment.time); + + gst_pad_push_event (mpeg_dec->src, event); + res = TRUE; + } return res; -- cgit v1.2.1 From cee2394a0d60857ff0015a62bb8888ec18e40755 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Sun, 7 Jun 2009 23:46:38 +0200 Subject: vdpau: s/IS_VDPAU/IS_VDP --- sys/vdpau/gstvdpdevice.c | 4 ++-- sys/vdpau/gstvdpdevice.h | 4 ++-- sys/vdpau/gstvdpmpegdec.h | 4 ++-- sys/vdpau/gstvdpvideobuffer.c | 4 ++-- sys/vdpau/gstvdpvideobuffer.h | 2 +- sys/vdpau/gstvdpvideoyuv.h | 4 ++-- sys/vdpau/gstvdpyuvvideo.h | 4 ++-- 7 files changed, 13 insertions(+), 13 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpdevice.c b/sys/vdpau/gstvdpdevice.c index f920f973..4ed1b177 100644 --- a/sys/vdpau/gstvdpdevice.c +++ b/sys/vdpau/gstvdpdevice.c @@ -152,7 +152,7 @@ gst_vdp_device_set_property (GObject * object, guint prop_id, { GstVdpDevice *device; - g_return_if_fail (GST_IS_VDPAU_DEVICE (object)); + g_return_if_fail (GST_IS_VDP_DEVICE (object)); device = (GstVdpDevice *) object; @@ -172,7 +172,7 @@ gst_vdp_device_get_property (GObject * object, guint prop_id, GValue * value, { GstVdpDevice *device; - g_return_if_fail (GST_IS_VDPAU_DEVICE (object)); + g_return_if_fail (GST_IS_VDP_DEVICE (object)); device = (GstVdpDevice *) object; diff --git a/sys/vdpau/gstvdpdevice.h b/sys/vdpau/gstvdpdevice.h index 70758a2d..ac036d73 100644 --- a/sys/vdpau/gstvdpdevice.h +++ b/sys/vdpau/gstvdpdevice.h @@ -31,8 +31,8 @@ G_BEGIN_DECLS #define GST_TYPE_VDP_DEVICE (gst_vdp_device_get_type ()) #define GST_VDP_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VDP_DEVICE, GstVdpDevice)) #define GST_VDP_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_VDP_DEVICE, GstVdpDeviceClass)) -#define GST_IS_VDPAU_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VDP_DEVICE)) -#define GST_IS_VDPAU_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_VDP_DEVICE)) +#define GST_IS_VDP_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VDP_DEVICE)) +#define GST_IS_VDP_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_VDP_DEVICE)) #define GST_VDP_DEVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VDP_DEVICE, GstVdpDeviceClass)) typedef struct _GstVdpDeviceClass GstVdpDeviceClass; diff --git a/sys/vdpau/gstvdpmpegdec.h b/sys/vdpau/gstvdpmpegdec.h index 66a41805..9d4c791f 100644 --- a/sys/vdpau/gstvdpmpegdec.h +++ b/sys/vdpau/gstvdpmpegdec.h @@ -32,8 +32,8 @@ G_BEGIN_DECLS #define GST_TYPE_VDP_MPEG_DEC (gst_vdp_mpeg_dec_get_type()) #define GST_VDP_MPEG_DEC(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VDP_MPEG_DEC,GstVdpMpegDec)) #define GST_VDP_MPEG_DEC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VDP_MPEG_DEC,GstVdpMpegDecClass)) -#define GST_IS_VDPAU_MPEG_DEC(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VDP_MPEG_DEC)) -#define GST_IS_VDPAU_MPEG_DEC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VDP_MPEG_DEC)) +#define GST_IS_VDP_MPEG_DEC(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VDP_MPEG_DEC)) +#define GST_IS_VDP_MPEG_DEC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VDP_MPEG_DEC)) typedef struct _GstVdpMpegDec GstVdpMpegDec; typedef struct _GstVdpMpegDecClass GstVdpMpegDecClass; diff --git a/sys/vdpau/gstvdpvideobuffer.c b/sys/vdpau/gstvdpvideobuffer.c index dac62c1b..8ae14e98 100644 --- a/sys/vdpau/gstvdpvideobuffer.c +++ b/sys/vdpau/gstvdpvideobuffer.c @@ -29,8 +29,8 @@ void gst_vdp_video_buffer_add_reference (GstVdpVideoBuffer * buffer, GstVdpVideoBuffer * buf) { - g_assert (GST_IS_VDPAU_VIDEO_BUFFER (buffer)); - g_assert (GST_IS_VDPAU_VIDEO_BUFFER (buf)); + g_assert (GST_IS_VDP_VIDEO_BUFFER (buffer)); + g_assert (GST_IS_VDP_VIDEO_BUFFER (buf)); gst_buffer_ref (GST_BUFFER (buf)); buffer->refs = g_slist_prepend (buffer->refs, buf); diff --git a/sys/vdpau/gstvdpvideobuffer.h b/sys/vdpau/gstvdpvideobuffer.h index 77ccf8ed..36eddcbd 100644 --- a/sys/vdpau/gstvdpvideobuffer.h +++ b/sys/vdpau/gstvdpvideobuffer.h @@ -32,7 +32,7 @@ typedef struct _GstVdpVideoBuffer GstVdpVideoBuffer; #define GST_TYPE_VDP_VIDEO_BUFFER (gst_vdp_video_buffer_get_type()) -#define GST_IS_VDPAU_VIDEO_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VDP_VIDEO_BUFFER)) +#define GST_IS_VDP_VIDEO_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VDP_VIDEO_BUFFER)) #define GST_VDP_VIDEO_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VDP_VIDEO_BUFFER, GstVdpVideoBuffer)) struct _GstVdpVideoBuffer { diff --git a/sys/vdpau/gstvdpvideoyuv.h b/sys/vdpau/gstvdpvideoyuv.h index 07955ed8..935fe700 100644 --- a/sys/vdpau/gstvdpvideoyuv.h +++ b/sys/vdpau/gstvdpvideoyuv.h @@ -31,8 +31,8 @@ G_BEGIN_DECLS #define GST_VDP_VIDEO_YUV(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VDP_VIDEO_YUV,GstVdpVideoYUV)) #define GST_VDP_VIDEO_YUV_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VDP_VIDEO_YUV,GstVdpVideoYUVClass)) #define GST_VDP_VIDEO_YUV_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VDP_VIDEO_YUV, GstVdpVideoYUVClass)) -#define GST_IS_VDPAU_VIDEO_YUV(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VDP_VIDEO_YUV)) -#define GST_IS_VDPAU_VIDEO_YUV_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VDP_VIDEO_YUV)) +#define GST_IS_VDP_VIDEO_YUV(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VDP_VIDEO_YUV)) +#define GST_IS_VDP_VIDEO_YUV_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VDP_VIDEO_YUV)) typedef struct _GstVdpVideoYUV GstVdpVideoYUV; typedef struct _GstVdpVideoYUVClass GstVdpVideoYUVClass; diff --git a/sys/vdpau/gstvdpyuvvideo.h b/sys/vdpau/gstvdpyuvvideo.h index ba3a3b01..2349e1ba 100644 --- a/sys/vdpau/gstvdpyuvvideo.h +++ b/sys/vdpau/gstvdpyuvvideo.h @@ -31,8 +31,8 @@ G_BEGIN_DECLS #define GST_VDP_YUV_VIDEO(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VDP_YUV_VIDEO,GstVdpYUVVideo)) #define GST_VDP_YUV_VIDEO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VDP_YUV_VIDEO,GstVdpYUVVideoClass)) #define GST_VDP_YUV_VIDEO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VDP_YUV_VIDEO, GstVdpYUVVideoClass)) -#define GST_IS_VDPAU_YUV_VIDEO(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VDP_YUV_VIDEO)) -#define GST_IS_VDPAU_YUV_VIDEO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VDP_YUV_VIDEO)) +#define GST_IS_VDP_YUV_VIDEO(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VDP_YUV_VIDEO)) +#define GST_IS_VDP_YUV_VIDEO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VDP_YUV_VIDEO)) typedef struct _GstVdpYUVVideo GstVdpYUVVideo; typedef struct _GstVdpYUVVideoClass GstVdpYUVVideoClass; -- cgit v1.2.1 From aff91bb89acaa2528ad2ed8f696cc93eb254325a Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Mon, 8 Jun 2009 14:15:03 +0200 Subject: vdpaumpegdec: small cleanup --- sys/vdpau/gstvdpmpegdec.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpmpegdec.c b/sys/vdpau/gstvdpmpegdec.c index 931de5a4..fbd53ae9 100644 --- a/sys/vdpau/gstvdpmpegdec.c +++ b/sys/vdpau/gstvdpmpegdec.c @@ -804,7 +804,7 @@ static gboolean normal_seek (GstVdpMpegDec * mpeg_dec, GstEvent * event) { gdouble rate; - GstFormat format, conv; + GstFormat format; GstSeekFlags flags; GstSeekType cur_type, stop_type; gint64 time_cur, bytes_cur; @@ -826,12 +826,11 @@ normal_seek (GstVdpMpegDec * mpeg_dec, GstEvent * event) if (update) { /* seek on bytes */ - conv = GST_FORMAT_BYTES; if (!gst_vdp_mpeg_dec_convert (mpeg_dec, GST_FORMAT_TIME, time_cur, - conv, &bytes_cur)) + GST_FORMAT_BYTES, &bytes_cur)) goto convert_failed; if (!gst_vdp_mpeg_dec_convert (mpeg_dec, GST_FORMAT_TIME, time_stop, - conv, &bytes_stop)) + GST_FORMAT_BYTES, &bytes_stop)) goto convert_failed; /* conversion succeeded, create the seek */ -- cgit v1.2.1 From 53a5272f73beaf87d33f99dc4a0d0dd0770934cc Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Mon, 8 Jun 2009 14:35:29 +0200 Subject: vdpaumpegdec: drop all frames before a GOP when we seek --- sys/vdpau/gstvdpmpegdec.c | 18 +++++++++++++++++- sys/vdpau/gstvdpmpegdec.h | 9 +++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpmpegdec.c b/sys/vdpau/gstvdpmpegdec.c index fbd53ae9..a4c2f687 100644 --- a/sys/vdpau/gstvdpmpegdec.c +++ b/sys/vdpau/gstvdpmpegdec.c @@ -499,6 +499,9 @@ gst_vdp_mpeg_dec_parse_sequence (GstVdpMpegDec * mpeg_dec, GstBuffer * buffer) memcpy (&mpeg_dec->vdp_info.non_intra_quantizer_matrix, &hdr.non_intra_quantizer_matrix, 64); + if (mpeg_dec->state == GST_VDP_MPEG_DEC_NEED_SEQUENCE) + mpeg_dec->state = GST_VDP_MPEG_DEC_NEED_DATA; + return TRUE; } @@ -555,6 +558,9 @@ gst_vdp_mpeg_dec_parse_gop (GstVdpMpegDec * mpeg_dec, GstBuffer * buffer) gst_util_uint64_scale (time, mpeg_dec->fps_n, mpeg_dec->fps_d * GST_SECOND) + gop.frame; + if (mpeg_dec->state == GST_VDP_MPEG_DEC_NEED_GOP) + mpeg_dec->state = GST_VDP_MPEG_DEC_NEED_DATA; + return TRUE; } @@ -601,6 +607,8 @@ gst_vdp_mpeg_dec_reset (GstVdpMpegDec * mpeg_dec) g_object_unref (mpeg_dec->device); mpeg_dec->device = NULL; + mpeg_dec->state = GST_VDP_MPEG_DEC_NEED_SEQUENCE; + gst_segment_init (&mpeg_dec->segment, GST_FORMAT_TIME); mpeg_dec->seeking = FALSE; @@ -688,6 +696,12 @@ gst_vdp_mpeg_dec_chain (GstPad * pad, GstBuffer * buffer) gst_buffer_unref (buf); } + if (mpeg_dec->state == GST_VDP_MPEG_DEC_NEED_SEQUENCE || + mpeg_dec->state == GST_VDP_MPEG_DEC_NEED_GOP) { + gst_adapter_clear (mpeg_dec->adapter); + goto done; + } + if (mpeg_dec->vdp_info.slice_count > 0) ret = gst_vdp_mpeg_dec_decode (mpeg_dec, GST_BUFFER_TIMESTAMP (buffer), GST_BUFFER_SIZE (buffer)); @@ -843,8 +857,10 @@ normal_seek (GstVdpMpegDec * mpeg_dec, GstEvent * event) /* do the seek */ res = gst_pad_push_event (mpeg_dec->sink, peer_event); - if (res) + if (res) { + mpeg_dec->state = GST_VDP_MPEG_DEC_NEED_GOP; mpeg_dec->seeking = TRUE; + } g_mutex_unlock (mpeg_dec->mutex); diff --git a/sys/vdpau/gstvdpmpegdec.h b/sys/vdpau/gstvdpmpegdec.h index 9d4c791f..fc36df5b 100644 --- a/sys/vdpau/gstvdpmpegdec.h +++ b/sys/vdpau/gstvdpmpegdec.h @@ -35,6 +35,12 @@ G_BEGIN_DECLS #define GST_IS_VDP_MPEG_DEC(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VDP_MPEG_DEC)) #define GST_IS_VDP_MPEG_DEC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VDP_MPEG_DEC)) +typedef enum { + GST_VDP_MPEG_DEC_NEED_SEQUENCE, + GST_VDP_MPEG_DEC_NEED_GOP, + GST_VDP_MPEG_DEC_NEED_DATA +} GstVdpMpegDecState; + typedef struct _GstVdpMpegDec GstVdpMpegDec; typedef struct _GstVdpMpegDecClass GstVdpMpegDecClass; @@ -56,6 +62,9 @@ struct _GstVdpMpegDec gboolean interlaced; gint version; + /* decoder state */ + GstVdpMpegDecState state; + /* currently decoded frame info */ GstAdapter *adapter; VdpPictureInfoMPEG1Or2 vdp_info; -- cgit v1.2.1 From b4fa8a4ef01a78638f5bc16a14802acfa1c11106 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Tue, 9 Jun 2009 23:14:26 +0200 Subject: vdpaumpegdec: use fixed src caps --- sys/vdpau/gstvdpmpegdec.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sys') diff --git a/sys/vdpau/gstvdpmpegdec.c b/sys/vdpau/gstvdpmpegdec.c index a4c2f687..b720217d 100644 --- a/sys/vdpau/gstvdpmpegdec.c +++ b/sys/vdpau/gstvdpmpegdec.c @@ -1075,6 +1075,7 @@ static void gst_vdp_mpeg_dec_init (GstVdpMpegDec * mpeg_dec, GstVdpMpegDecClass * gclass) { mpeg_dec->src = gst_pad_new_from_static_template (&src_template, "src"); + gst_pad_use_fixed_caps (mpeg_dec->src); gst_pad_set_event_function (mpeg_dec->src, GST_DEBUG_FUNCPTR (gst_vdp_mpeg_dec_src_event)); gst_pad_set_query_function (mpeg_dec->src, -- cgit v1.2.1 From f45f87709c7da9105024b0ceedda0e3155526240 Mon Sep 17 00:00:00 2001 From: Jan Schmidt Date: Fri, 12 Jun 2009 16:39:39 +0100 Subject: VDPAU: Enhance the configure tests Check for the VDPAU headers in /usr/include/nvidia as they are on some platforms (Fedora/rpmfusion). Also check that the libvdpau library is available. --- sys/vdpau/Makefile.am | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/Makefile.am b/sys/vdpau/Makefile.am index f4380aff..f62ee0b4 100644 --- a/sys/vdpau/Makefile.am +++ b/sys/vdpau/Makefile.am @@ -9,9 +9,10 @@ libgstvdpau_la_SOURCES = \ gstvdp.c \ gstvdpyuvvideo.c -libgstvdpau_la_CFLAGS = $(GST_CFLAGS) $(X11_CFLAGS) -Ivdpau +libgstvdpau_la_CFLAGS = $(GST_CFLAGS) $(X11_CFLAGS) $(VDPAU_CFLAGS) libgstvdpau_la_LIBADD = $(GST_LIBS) $(GST_BASE_LIBS) \ - $(GST_PLUGINS_BASE) $(X11_LIBS) -lgstvideo-$(GST_MAJORMINOR) -lvdpau + $(GST_PLUGINS_BASE) $(X11_LIBS) -lgstvideo-$(GST_MAJORMINOR) \ + $(VDPAU_LIBS) libgstvdpau_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) libgstvdpau_la_LIBTOOLFLAGS = --tag=disable-static -- cgit v1.2.1 From 8ded28b1260c6cf956f6029f74bccca51ce7fd73 Mon Sep 17 00:00:00 2001 From: Jan Schmidt Date: Mon, 15 Jun 2009 18:29:56 +0100 Subject: VDPAU: Fix up caps in vdpaumpegdec. Remove extra semicolon Fix a typo in the caps for the VDPAU mpeg decoder (chroma_type->chroma-type) and use the GST_VDP_VIDEO_CAPS for the pad template. Remove a stray semicolon. --- sys/vdpau/gstvdpmpegdec.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpmpegdec.c b/sys/vdpau/gstvdpmpegdec.c index b720217d..872348c6 100644 --- a/sys/vdpau/gstvdpmpegdec.c +++ b/sys/vdpau/gstvdpmpegdec.c @@ -72,8 +72,7 @@ static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink", static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS, - GST_STATIC_CAPS ("video/x-vdpau-video, " "chroma-type = (int) 0") - ); + GST_STATIC_CAPS (GST_VDP_VIDEO_CAPS)); #define DEBUG_INIT(bla) \ GST_DEBUG_CATEGORY_INIT (gst_vdp_mpeg_dec_debug, "vdpaumpegdec", 0, "VDPAU powered mpeg decoder"); @@ -188,7 +187,7 @@ gst_vdp_mpeg_dec_set_caps (GstPad * pad, GstCaps * caps) src_caps = gst_caps_new_simple ("video/x-vdpau-video", "device", G_TYPE_OBJECT, mpeg_dec->device, - "chroma_type", G_TYPE_INT, VDP_CHROMA_TYPE_420, + "chroma-type", G_TYPE_INT, VDP_CHROMA_TYPE_420, "width", G_TYPE_INT, width, "height", G_TYPE_INT, height, "framerate", GST_TYPE_FRACTION, fps_n, fps_d, @@ -247,7 +246,7 @@ gst_vdp_mpeg_dec_set_caps (GstPad * pad, GstCaps * caps) } } - bitrate += (ext.bitrate_ext << 18);; + bitrate += (ext.bitrate_ext << 18); gst_buffer_unref (buf); } -- cgit v1.2.1 From 0d94e5a656e971f0aab2713d02e9b191d013e831 Mon Sep 17 00:00:00 2001 From: Jan Schmidt Date: Mon, 15 Jun 2009 18:33:06 +0100 Subject: VDPAU: Refactor the error path to a common output, and fix a leak. Don't leak the input buffer on errors. Add some debug statements. --- sys/vdpau/gstvdpvideoyuv.c | 40 ++++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/gstvdpvideoyuv.c b/sys/vdpau/gstvdpvideoyuv.c index a1f5b6ed..8f98f12e 100644 --- a/sys/vdpau/gstvdpvideoyuv.c +++ b/sys/vdpau/gstvdpvideoyuv.c @@ -74,16 +74,19 @@ gst_vdp_video_yuv_chain (GstPad * pad, GstBuffer * buffer) GstVdpDevice *device; VdpVideoSurface surface; GstBuffer *outbuf = NULL; + GstFlowReturn result = GST_FLOW_ERROR; video_yuv = GST_VDP_VIDEO_YUV (GST_OBJECT_PARENT (pad)); device = GST_VDP_VIDEO_BUFFER (buffer)->device; surface = GST_VDP_VIDEO_BUFFER (buffer)->surface; + GST_LOG_OBJECT (video_yuv, "Received buffer format %" GST_FOURCC_FORMAT, + GST_FOURCC_ARGS (video_yuv->format)); + switch (video_yuv->format) { case GST_MAKE_FOURCC ('Y', 'V', '1', '2'): { gint size; - GstFlowReturn result; VdpStatus status; guint8 *data[3]; guint32 stride[3]; @@ -94,8 +97,10 @@ gst_vdp_video_yuv_chain (GstPad * pad, GstBuffer * buffer) result = gst_pad_alloc_buffer_and_set_caps (video_yuv->src, GST_BUFFER_OFFSET_NONE, size, GST_PAD_CAPS (video_yuv->src), &outbuf); - if (G_UNLIKELY (result != GST_FLOW_OK)) - return result; + if (G_UNLIKELY (result != GST_FLOW_OK)) { + GST_DEBUG_OBJECT (video_yuv, "Pad alloc_buffer returned %d", result); + goto done; + } data[0] = GST_BUFFER_DATA (outbuf) + gst_video_format_get_component_offset (GST_VIDEO_FORMAT_YV12, @@ -122,14 +127,13 @@ gst_vdp_video_yuv_chain (GstPad * pad, GstBuffer * buffer) ("Couldn't get data from vdpau"), ("Error returned from vdpau was: %s", device->vdp_get_error_string (status))); - goto error; + goto done; } break; } case GST_MAKE_FOURCC ('I', '4', '2', '0'): { gint size; - GstFlowReturn result; VdpStatus status; guint8 *data[3]; guint32 stride[3]; @@ -140,8 +144,10 @@ gst_vdp_video_yuv_chain (GstPad * pad, GstBuffer * buffer) result = gst_pad_alloc_buffer_and_set_caps (video_yuv->src, GST_BUFFER_OFFSET_NONE, size, GST_PAD_CAPS (video_yuv->src), &outbuf); - if (G_UNLIKELY (result != GST_FLOW_OK)) - return result; + if (G_UNLIKELY (result != GST_FLOW_OK)) { + GST_DEBUG_OBJECT (video_yuv, "Pad alloc_buffer returned %d", result); + goto done; + } data[0] = GST_BUFFER_DATA (outbuf) + gst_video_format_get_component_offset (GST_VIDEO_FORMAT_I420, @@ -168,14 +174,13 @@ gst_vdp_video_yuv_chain (GstPad * pad, GstBuffer * buffer) ("Couldn't get data from vdpau"), ("Error returned from vdpau was: %s", device->vdp_get_error_string (status))); - goto error; + goto done; } break; } case GST_MAKE_FOURCC ('N', 'V', '1', '2'): { gint size; - GstFlowReturn result; VdpStatus status; guint8 *data[2]; guint32 stride[2]; @@ -186,9 +191,10 @@ gst_vdp_video_yuv_chain (GstPad * pad, GstBuffer * buffer) result = gst_pad_alloc_buffer_and_set_caps (video_yuv->src, GST_BUFFER_OFFSET_NONE, size, GST_PAD_CAPS (video_yuv->src), &outbuf); - if (G_UNLIKELY (result != GST_FLOW_OK)) - return result; - + if (G_UNLIKELY (result != GST_FLOW_OK)) { + GST_DEBUG_OBJECT (video_yuv, "Pad alloc_buffer returned %d", result); + goto done; + } data[0] = GST_BUFFER_DATA (outbuf); data[1] = GST_BUFFER_DATA (outbuf) + video_yuv->width * video_yuv->height; @@ -204,7 +210,7 @@ gst_vdp_video_yuv_chain (GstPad * pad, GstBuffer * buffer) ("Couldn't get data from vdpau"), ("Error returned from vdpau was: %s", device->vdp_get_error_string (status))); - goto error; + goto done; } break; } @@ -217,9 +223,11 @@ gst_vdp_video_yuv_chain (GstPad * pad, GstBuffer * buffer) gst_buffer_copy_metadata (outbuf, buffer, GST_BUFFER_COPY_TIMESTAMPS); return gst_pad_push (video_yuv->src, outbuf); -error: - gst_buffer_unref (outbuf); - return GST_FLOW_ERROR; +done: + if (outbuf) + gst_buffer_unref (outbuf); + gst_buffer_unref (buffer); + return result; } static GstCaps * -- cgit v1.2.1 From 8c89eb9a5be9307867c836f9072ecaf0cdee2e42 Mon Sep 17 00:00:00 2001 From: Jan Schmidt Date: Thu, 18 Jun 2009 17:06:23 +0100 Subject: VDPAU: Fix build flags to pull in gst-plugins-base libs --- sys/vdpau/Makefile.am | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sys') diff --git a/sys/vdpau/Makefile.am b/sys/vdpau/Makefile.am index f62ee0b4..93a7513a 100644 --- a/sys/vdpau/Makefile.am +++ b/sys/vdpau/Makefile.am @@ -9,9 +9,9 @@ libgstvdpau_la_SOURCES = \ gstvdp.c \ gstvdpyuvvideo.c -libgstvdpau_la_CFLAGS = $(GST_CFLAGS) $(X11_CFLAGS) $(VDPAU_CFLAGS) +libgstvdpau_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) $(X11_CFLAGS) $(VDPAU_CFLAGS) libgstvdpau_la_LIBADD = $(GST_LIBS) $(GST_BASE_LIBS) \ - $(GST_PLUGINS_BASE) $(X11_LIBS) -lgstvideo-$(GST_MAJORMINOR) \ + $(GST_PLUGINS_BASE_LIBS) $(X11_LIBS) -lgstvideo-$(GST_MAJORMINOR) \ $(VDPAU_LIBS) libgstvdpau_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) libgstvdpau_la_LIBTOOLFLAGS = --tag=disable-static -- cgit v1.2.1 From deb03ee2ca1b50cc7d5010625def11b057d693cf Mon Sep 17 00:00:00 2001 From: Jan Schmidt Date: Fri, 19 Jun 2009 21:20:26 +0100 Subject: VDPAU: Add some debug statements --- sys/vdpau/gstvdpmpegdec.c | 8 ++++++++ sys/vdpau/gstvdpvideoyuv.c | 10 ++++++++++ 2 files changed, 18 insertions(+) (limited to 'sys') diff --git a/sys/vdpau/gstvdpmpegdec.c b/sys/vdpau/gstvdpmpegdec.c index 872348c6..674146c4 100644 --- a/sys/vdpau/gstvdpmpegdec.c +++ b/sys/vdpau/gstvdpmpegdec.c @@ -194,6 +194,9 @@ gst_vdp_mpeg_dec_set_caps (GstPad * pad, GstCaps * caps) "pixel-aspect-ratio", GST_TYPE_FRACTION, par_n, par_d, "interlaced", G_TYPE_BOOLEAN, interlaced, NULL); + GST_DEBUG_OBJECT (mpeg_dec, "Setting source caps to %" GST_PTR_FORMAT, + src_caps); + res = gst_pad_set_caps (mpeg_dec->src, src_caps); gst_caps_unref (src_caps); if (!res) @@ -968,6 +971,11 @@ gst_vdp_mpeg_dec_sink_event (GstPad * pad, GstEvent * event) } g_mutex_unlock (mpeg_dec->mutex); + GST_DEBUG_OBJECT (mpeg_dec, + "Pushing new segment update %d format %d start %" + GST_TIME_FORMAT " stop %" GST_TIME_FORMAT " position %" + GST_TIME_FORMAT, update, format, GST_TIME_ARGS (start), + GST_TIME_ARGS (stop), GST_TIME_ARGS (position)); convert_error: res = gst_pad_push_event (mpeg_dec->src, event); diff --git a/sys/vdpau/gstvdpvideoyuv.c b/sys/vdpau/gstvdpvideoyuv.c index 8f98f12e..2318cd40 100644 --- a/sys/vdpau/gstvdpvideoyuv.c +++ b/sys/vdpau/gstvdpvideoyuv.c @@ -122,6 +122,8 @@ gst_vdp_video_yuv_chain (GstPad * pad, GstBuffer * buffer) status = device->vdp_video_surface_get_bits_ycbcr (surface, VDP_YCBCR_FORMAT_YV12, (void *) data, stride); + GST_LOG_OBJECT (video_yuv, + "Got status %d from vdp_video_surface_get_bits_ycbcr", status); if (G_UNLIKELY (status != VDP_STATUS_OK)) { GST_ELEMENT_ERROR (video_yuv, RESOURCE, READ, ("Couldn't get data from vdpau"), @@ -169,6 +171,8 @@ gst_vdp_video_yuv_chain (GstPad * pad, GstBuffer * buffer) status = device->vdp_video_surface_get_bits_ycbcr (surface, VDP_YCBCR_FORMAT_YV12, (void *) data, stride); + GST_LOG_OBJECT (video_yuv, + "Got status %d from vdp_video_surface_get_bits_ycbcr", status); if (G_UNLIKELY (status != VDP_STATUS_OK)) { GST_ELEMENT_ERROR (video_yuv, RESOURCE, READ, ("Couldn't get data from vdpau"), @@ -188,6 +192,7 @@ gst_vdp_video_yuv_chain (GstPad * pad, GstBuffer * buffer) size = video_yuv->width * video_yuv->height + video_yuv->width * video_yuv->height / 2; + GST_LOG_OBJECT (video_yuv, "Entering buffer_alloc"); result = gst_pad_alloc_buffer_and_set_caps (video_yuv->src, GST_BUFFER_OFFSET_NONE, size, GST_PAD_CAPS (video_yuv->src), &outbuf); @@ -202,9 +207,12 @@ gst_vdp_video_yuv_chain (GstPad * pad, GstBuffer * buffer) stride[0] = video_yuv->width; stride[1] = video_yuv->width; + GST_LOG_OBJECT (video_yuv, "Entering vdp_video_surface_get_bits_ycbcr"); status = device->vdp_video_surface_get_bits_ycbcr (surface, VDP_YCBCR_FORMAT_NV12, (void *) data, stride); + GST_LOG_OBJECT (video_yuv, + "Got status %d from vdp_video_surface_get_bits_ycbcr", status); if (G_UNLIKELY (status != VDP_STATUS_OK)) { GST_ELEMENT_ERROR (video_yuv, RESOURCE, READ, ("Couldn't get data from vdpau"), @@ -221,6 +229,8 @@ gst_vdp_video_yuv_chain (GstPad * pad, GstBuffer * buffer) gst_buffer_unref (buffer); gst_buffer_copy_metadata (outbuf, buffer, GST_BUFFER_COPY_TIMESTAMPS); + GST_LOG_OBJECT (video_yuv, "Pushing buffer with ts %" GST_TIME_FORMAT, + GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf))); return gst_pad_push (video_yuv->src, outbuf); done: -- cgit v1.2.1