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 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