diff options
author | Edward Hervey <bilboed@bilboed.com> | 2012-09-20 19:03:11 +0200 |
---|---|---|
committer | Edward Hervey <edward@collabora.com> | 2013-03-31 19:05:31 +0200 |
commit | e3c71c65fe86b9810024980f19a422016eaf0b3c (patch) | |
tree | 52186abdca4d52f464abb15bb4f80fa2ddf7f6c8 | |
parent | 2296296a51450c2db5581a09b9707a95fa149153 (diff) |
vdpau: Port to 1.0
New base class for vdpau decoders
* mpeg2 ported and activated
* h264 ported but deactivated
* Uses GstMpegVideo meta
63 files changed, 1672 insertions, 8688 deletions
diff --git a/configure.ac b/configure.ac index f0bd19240..72d79dcba 100644 --- a/configure.ac +++ b/configure.ac @@ -2401,8 +2401,6 @@ sys/shm/Makefile sys/uvch264/Makefile sys/vcd/Makefile sys/vdpau/Makefile -sys/vdpau/gstvdp/Makefile -sys/vdpau/basevideodecoder/Makefile sys/pvr2d/Makefile sys/wasapi/Makefile sys/wininet/Makefile diff --git a/sys/Makefile.am b/sys/Makefile.am index e61e53ea3..99c3801e9 100644 --- a/sys/Makefile.am +++ b/sys/Makefile.am @@ -142,11 +142,11 @@ else VCD_DIR= endif -#if USE_VDPAU -#VDPAU_DIR=vdpau -#else -#VDPAU_DIR= -#endif +if USE_VDPAU +VDPAU_DIR=vdpau +else +VDPAU_DIR= +endif if USE_DIRECT3D9 WINSCREENCAP_DIR=winscreencap diff --git a/sys/vdpau/Makefile.am b/sys/vdpau/Makefile.am index d507d4a37..afa0c1417 100644 --- a/sys/vdpau/Makefile.am +++ b/sys/vdpau/Makefile.am @@ -1,45 +1,39 @@ -SUBDIRS = basevideodecoder gstvdp - plugin_LTLIBRARIES = libgstvdpau.la libgstvdpau_la_SOURCES = \ gstvdpau.c \ - gstvdpvideopostprocess.c \ - gstvdpsink.c \ - mpeg/gstvdpmpegframe.c \ - mpeg/mpegutil.c \ - mpeg/gstvdpmpegdec.c \ - h264/gstnalreader.c \ - h264/gsth264parser.c \ - h264/gsth264frame.c \ - h264/gsth264dpb.c \ - h264/gstvdph264dec.c \ - mpeg4/mpeg4util.c \ - mpeg4/gstmpeg4frame.c \ - mpeg4/gstvdpmpeg4dec.c + gstvdputils.c \ + gstvdpvideomemory.c \ + gstvdpvideobufferpool.c \ + gstvdpdevice.c \ + gstvdpdecoder.c \ + mpeg/gstvdpmpegdec.c + # \ + # h264/gsth264dpb.c \ + # h264/gstvdph264dec.c + -libgstvdpau_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) $(X11_CFLAGS) $(VDPAU_CFLAGS) +libgstvdpau_la_CFLAGS = $(GST_PLUGINS_BAD_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) \ + $(GST_CFLAGS) $(X11_CFLAGS) $(VDPAU_CFLAGS) -libgstvdpau_la_LIBADD = $(GST_LIBS) $(GST_BASE_LIBS) \ +libgstvdpau_la_LIBADD = \ + $(top_builddir)/gst-libs/gst/codecparsers/libgstcodecparsers-$(GST_API_VERSION).la \ + $(GST_LIBS) $(GST_BASE_LIBS) \ $(GST_PLUGINS_BASE_LIBS) $(X11_LIBS) -lgstvideo-$(GST_API_VERSION) \ - -lgstinterfaces-$(GST_API_VERSION) $(VDPAU_LIBS) \ - gstvdp/libgstvdp-@GST_API_VERSION@.la \ - $(LIBM) - + $(VDPAU_LIBS) $(LIBM) + libgstvdpau_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) libgstvdpau_la_LIBTOOLFLAGS = --tag=disable-static noinst_HEADERS = \ + gstvdputils.h \ + gstvdpvideomemory.h \ + gstvdpvideobufferpool.h \ gstvdpvideopostprocess.h \ gstvdpsink.h \ - mpeg/gstvdpmpegframe.h \ - mpeg/mpegutil.h \ mpeg/gstvdpmpegdec.h \ - h264/gstnalreader.h \ - h264/gsth264parser.h \ - h264/gsth264frame.h \ - h264/gsth264dpb.h \ - h264/gstvdph264dec.h \ + # h264/gsth264dpb.h \ + # h264/gstvdph264dec.h \ mpeg4/mpeg4util.h \ mpeg4/gstmpeg4frame.h \ mpeg4/gstvdpmpeg4dec.h diff --git a/sys/vdpau/basevideodecoder/Makefile.am b/sys/vdpau/basevideodecoder/Makefile.am deleted file mode 100644 index fcd508458..000000000 --- a/sys/vdpau/basevideodecoder/Makefile.am +++ /dev/null @@ -1,19 +0,0 @@ -noinst_LTLIBRARIES = libgstbasevideodecoder.la - -libgstbasevideodecoder_la_SOURCES = \ - gstvideoframe.c \ - gstbasevideodecoder.c - -libgstbasevideodecoder_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) \ - -DGstBaseVideoDecoder=SatBaseVideoDecoder \ - -DGstBaseVideoDecoderClass=SatBaseVideoDecoderClass -libgstbasevideodecoder_la_LIBADD = \ - $(GST_PLUGINS_BASE_LIBS) -lgstinterfaces-$(GST_API_VERSION) \ - $(GST_BASE_LIBS) $(GST_LIBS) - -libgstbasevideodecoder_la_LDFLAGS = $(GST_ALL_LDFLAGS) -module -avoid-version - -noinst_HEADERS = \ - gstvideoframe.h \ - gstbasevideodecoder.h \ - gstbasevideoutils.h
\ No newline at end of file diff --git a/sys/vdpau/basevideodecoder/gstbasevideodecoder.c b/sys/vdpau/basevideodecoder/gstbasevideodecoder.c deleted file mode 100644 index a4ce42b1d..000000000 --- a/sys/vdpau/basevideodecoder/gstbasevideodecoder.c +++ /dev/null @@ -1,1199 +0,0 @@ -/* GStreamer - * Copyright (C) 2008 David Schleef <ds@schleef.org> - * - * 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., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "gstbasevideodecoder.h" - -#include <string.h> - -GST_DEBUG_CATEGORY (basevideodecoder_debug); -#define GST_CAT_DEFAULT basevideodecoder_debug - -enum -{ - PROP_0, - PROP_PACKETIZED, - PROP_SINK_CLIPPING -}; - - -static GstFlowReturn gst_base_video_decoder_drain (GstBaseVideoDecoder * dec, - gboolean at_eos); - - -GST_BOILERPLATE (GstBaseVideoDecoder, gst_base_video_decoder, - GstElement, GST_TYPE_ELEMENT); - - - -typedef struct _Timestamp Timestamp; -struct _Timestamp -{ - guint64 offset; - GstClockTime timestamp; - GstClockTime duration; -}; - -static void -gst_base_video_decoder_clear_timestamps (GstBaseVideoDecoder * - base_video_decoder) -{ - GList *l; - - for (l = base_video_decoder->timestamps; l; - l = base_video_decoder->timestamps) { - g_slice_free (Timestamp, l->data); - base_video_decoder->timestamps = l->next; - g_list_free1 (l); - } -} - -static void -gst_base_video_decoder_add_timestamp (GstBaseVideoDecoder * base_video_decoder, - GstBuffer * buffer) -{ - Timestamp *ts; - - ts = g_slice_new (Timestamp); - - GST_DEBUG ("adding timestamp %" G_GUINT64_FORMAT " %" GST_TIME_FORMAT, - base_video_decoder->input_offset, - GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer))); - - ts->offset = base_video_decoder->input_offset; - ts->timestamp = GST_BUFFER_TIMESTAMP (buffer); - ts->duration = GST_BUFFER_DURATION (buffer); - - base_video_decoder->timestamps = - g_list_append (base_video_decoder->timestamps, ts); -} - -static void -gst_base_video_decoder_get_timestamp_at_offset (GstBaseVideoDecoder * - base_video_decoder, guint64 offset, GstClockTime * timestamp, - GstClockTime * duration) -{ - GList *g; - - *timestamp = GST_CLOCK_TIME_NONE; - *duration = GST_CLOCK_TIME_NONE; - - g = base_video_decoder->timestamps; - while (g) { - Timestamp *ts; - - ts = g->data; - if (ts->offset <= offset) { - *timestamp = ts->timestamp; - *duration = ts->duration; - g_slice_free (Timestamp, ts); - g = g_list_next (g); - base_video_decoder->timestamps = - g_list_remove (base_video_decoder->timestamps, ts); - } else { - break; - } - } - - GST_DEBUG ("got timestamp %" G_GUINT64_FORMAT " %" GST_TIME_FORMAT, - offset, GST_TIME_ARGS (*timestamp)); -} - -static guint64 -gst_base_video_decoder_get_field_timestamp (GstBaseVideoDecoder * - base_video_decoder, gint field_offset) -{ - if (base_video_decoder->state.fps_d == 0) { - return GST_CLOCK_TIME_NONE; - } - if (field_offset < 0) { - GST_WARNING ("field offset < 0"); - return GST_CLOCK_TIME_NONE; - } - return base_video_decoder->timestamp_offset + - gst_util_uint64_scale (field_offset, - base_video_decoder->state.fps_d * GST_SECOND, - base_video_decoder->state.fps_n * 2); -} - -static guint64 -gst_base_video_decoder_get_field_duration (GstBaseVideoDecoder * - base_video_decoder, gint n_fields) -{ - if (base_video_decoder->state.fps_d == 0) { - return GST_CLOCK_TIME_NONE; - } - if (n_fields < 0) { - GST_WARNING ("n_fields < 0"); - return GST_CLOCK_TIME_NONE; - } - return gst_util_uint64_scale (n_fields, - base_video_decoder->state.fps_d * GST_SECOND, - base_video_decoder->state.fps_n * 2); -} - -static GstVideoFrame * -gst_base_video_decoder_new_frame (GstBaseVideoDecoder * base_video_decoder) -{ - GstBaseVideoDecoderClass *base_video_decoder_class = - GST_BASE_VIDEO_DECODER_GET_CLASS (base_video_decoder); - - GstVideoFrame *frame; - - if (base_video_decoder_class->create_frame) - frame = base_video_decoder_class->create_frame (base_video_decoder); - else - frame = gst_video_frame_new (); - - return frame; -} - -static void -gst_base_video_decoder_reset (GstBaseVideoDecoder * base_video_decoder) -{ - GST_DEBUG ("reset"); - - base_video_decoder->discont = TRUE; - base_video_decoder->have_sync = FALSE; - - base_video_decoder->timestamp_offset = GST_CLOCK_TIME_NONE; - base_video_decoder->last_timestamp = GST_CLOCK_TIME_NONE; - - base_video_decoder->input_offset = 0; - base_video_decoder->current_buf_offset = -1; - base_video_decoder->prev_buf_offset = -1; - - gst_adapter_clear (base_video_decoder->input_adapter); - - if (base_video_decoder->current_frame) { - gst_video_frame_unref (base_video_decoder->current_frame); - base_video_decoder->current_frame = NULL; - } - - gst_base_video_decoder_clear_timestamps (base_video_decoder); - - base_video_decoder->have_src_caps = FALSE; - - GST_OBJECT_LOCK (base_video_decoder); - base_video_decoder->earliest_time = GST_CLOCK_TIME_NONE; - base_video_decoder->proportion = 0.5; - GST_OBJECT_UNLOCK (base_video_decoder); -} - -static void -gst_base_video_decoder_flush (GstBaseVideoDecoder * base_video_decoder) -{ - GstBaseVideoDecoderClass *base_video_decoder_class; - - gst_base_video_decoder_reset (base_video_decoder); - - base_video_decoder_class = - GST_BASE_VIDEO_DECODER_GET_CLASS (base_video_decoder); - - if (base_video_decoder_class->flush) - base_video_decoder_class->flush (base_video_decoder); -} - -static void -gst_base_video_decoder_reset_state (GstVideoState * state) -{ - if (state->codec_data) - gst_buffer_unref (state->codec_data); - - memset (state, 0, sizeof (GstVideoState)); - state->par_n = state->par_d = 1; -} - -static gboolean -gst_base_video_decoder_sink_setcaps (GstPad * pad, GstCaps * caps) -{ - GstBaseVideoDecoder *base_video_decoder; - GstBaseVideoDecoderClass *base_video_decoder_class; - GstStructure *structure; - const GValue *codec_data; - GstVideoState *state; - gboolean ret = TRUE; - - base_video_decoder = GST_BASE_VIDEO_DECODER (gst_pad_get_parent (pad)); - base_video_decoder_class = - GST_BASE_VIDEO_DECODER_GET_CLASS (base_video_decoder); - - GST_DEBUG ("setcaps %" GST_PTR_FORMAT, caps); - - state = &base_video_decoder->state; - - gst_base_video_decoder_reset_state (state); - - structure = gst_caps_get_structure (caps, 0); - - gst_video_format_parse_caps (caps, NULL, &state->width, &state->height); - gst_video_parse_caps_framerate (caps, &state->fps_n, &state->fps_d); - gst_video_parse_caps_pixel_aspect_ratio (caps, &state->par_n, &state->par_d); - gst_structure_get_boolean (structure, "interlaced", &state->interlaced); - - codec_data = gst_structure_get_value (structure, "codec_data"); - if (codec_data && G_VALUE_TYPE (codec_data) == GST_TYPE_BUFFER) - state->codec_data = gst_value_get_buffer (codec_data); - - if (base_video_decoder_class->set_sink_caps) - ret = base_video_decoder_class->set_sink_caps (base_video_decoder, caps); - - g_object_unref (base_video_decoder); - - return ret; -} - -static gboolean -gst_base_video_decoder_sink_event (GstPad * pad, GstEvent * event) -{ - GstBaseVideoDecoder *base_video_decoder; - gboolean res = FALSE; - - base_video_decoder = GST_BASE_VIDEO_DECODER (gst_pad_get_parent (pad)); - - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_EOS: - if (!base_video_decoder->packetized) - gst_base_video_decoder_drain (base_video_decoder, TRUE); - - res = - gst_pad_push_event (GST_BASE_VIDEO_DECODER_SRC_PAD - (base_video_decoder), event); - break; - - case GST_EVENT_NEWSEGMENT: - { - gboolean update; - double rate; - double applied_rate; - GstFormat format; - gint64 start; - gint64 stop; - gint64 position; - GstSegment *segment = &base_video_decoder->segment; - - gst_event_parse_new_segment_full (event, &update, &rate, - &applied_rate, &format, &start, &stop, &position); - - if (format != GST_FORMAT_TIME) - goto newseg_wrong_format; - - if (!update) { - gst_base_video_decoder_flush (base_video_decoder); - } - - base_video_decoder->timestamp_offset = start; - - gst_segment_set_newsegment_full (segment, - update, rate, applied_rate, format, start, stop, position); - base_video_decoder->have_segment = TRUE; - - GST_WARNING ("new segment: format %d rate %g start %" GST_TIME_FORMAT - " stop %" GST_TIME_FORMAT - " position %" GST_TIME_FORMAT - " update %d", - format, rate, - GST_TIME_ARGS (segment->start), - GST_TIME_ARGS (segment->stop), GST_TIME_ARGS (segment->time), update); - - res = - gst_pad_push_event (GST_BASE_VIDEO_DECODER_SRC_PAD - (base_video_decoder), event); - break; - } - - case GST_EVENT_FLUSH_STOP: - gst_base_video_decoder_flush (base_video_decoder); - gst_segment_init (&base_video_decoder->segment, GST_FORMAT_TIME); - - res = - gst_pad_push_event (GST_BASE_VIDEO_DECODER_SRC_PAD - (base_video_decoder), event); - break; - - default: - res = gst_pad_event_default (pad, event); - break; - } - -done: - gst_object_unref (base_video_decoder); - return res; - -newseg_wrong_format: - GST_DEBUG_OBJECT (base_video_decoder, "received non TIME newsegment"); - gst_event_unref (event); - goto done; -} - -static gboolean -gst_base_video_decoder_src_event (GstPad * pad, GstEvent * event) -{ - GstBaseVideoDecoder *base_video_decoder; - gboolean res = FALSE; - - base_video_decoder = GST_BASE_VIDEO_DECODER (gst_pad_get_parent (pad)); - - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_SEEK: - - /* FIXME: do seek using bitrate incase upstream doesn't handle it */ - res = - gst_pad_push_event (GST_BASE_VIDEO_DECODER_SINK_PAD - (base_video_decoder), event); - - break; - - case GST_EVENT_QOS: - { - gdouble proportion; - GstClockTimeDiff diff; - GstClockTime timestamp; - GstClockTime duration; - - gst_event_parse_qos (event, &proportion, &diff, ×tamp); - - GST_OBJECT_LOCK (base_video_decoder); - base_video_decoder->proportion = proportion; - if (G_LIKELY (GST_CLOCK_TIME_IS_VALID (timestamp))) { - if (G_UNLIKELY (diff > 0)) { - if (base_video_decoder->state.fps_n > 0) - duration = - gst_util_uint64_scale (GST_SECOND, - base_video_decoder->state.fps_d, - base_video_decoder->state.fps_n); - else - duration = 0; - base_video_decoder->earliest_time = timestamp + 2 * diff + duration; - } else { - base_video_decoder->earliest_time = timestamp + diff; - } - } else { - base_video_decoder->earliest_time = GST_CLOCK_TIME_NONE; - } - GST_OBJECT_UNLOCK (base_video_decoder); - - GST_DEBUG_OBJECT (base_video_decoder, - "got QoS %" GST_TIME_FORMAT ", %" G_GINT64_FORMAT ", %g", - GST_TIME_ARGS (timestamp), diff, proportion); - - res = - gst_pad_push_event (GST_BASE_VIDEO_DECODER_SINK_PAD - (base_video_decoder), event); - break; - } - - default: - res = - gst_pad_push_event (GST_BASE_VIDEO_DECODER_SINK_PAD - (base_video_decoder), event); - break; - } - - gst_object_unref (base_video_decoder); - return res; -} - -static const GstQueryType * -gst_base_video_decoder_get_query_types (GstPad * pad) -{ - static const GstQueryType query_types[] = { - GST_QUERY_POSITION, - GST_QUERY_DURATION, - 0 - }; - - return query_types; -} - -static gboolean -gst_base_video_decoder_src_query (GstPad * pad, GstQuery * query) -{ - GstBaseVideoDecoder *dec; - gboolean res = TRUE; - - dec = GST_BASE_VIDEO_DECODER (gst_pad_get_parent (pad)); - - switch GST_QUERY_TYPE - (query) { - case GST_QUERY_POSITION: - { - GstFormat format; - gint64 time; - - gst_query_parse_position (query, &format, NULL); - GST_DEBUG ("query in format %d", format); - - if (format != GST_FORMAT_TIME) { - goto error; - } - - time = dec->last_timestamp; - time = gst_segment_to_stream_time (&dec->segment, GST_FORMAT_TIME, time); - - gst_query_set_position (query, format, time); - - res = TRUE; - break; - } - - case GST_QUERY_DURATION: - /* FIXME: approximate using bitrate if upstream doesn't answear */ - res = gst_pad_query (dec->sinkpad, query); - break; - - default: - res = gst_pad_query_default (pad, query); - } - - gst_object_unref (dec); - return res; - -error: - GST_ERROR_OBJECT (dec, "query failed"); - gst_object_unref (dec); - return res; -} - -static gboolean -gst_base_video_decoder_sink_query (GstPad * pad, GstQuery * query) -{ - GstBaseVideoDecoder *base_video_decoder; - gboolean res = FALSE; - - base_video_decoder = GST_BASE_VIDEO_DECODER (gst_pad_get_parent (pad)); - - GST_DEBUG_OBJECT (base_video_decoder, "sink query fps=%d/%d", - base_video_decoder->state.fps_n, base_video_decoder->state.fps_d); - switch (GST_QUERY_TYPE (query)) { - - default: - res = gst_pad_query_default (pad, query); - break; - } - - gst_object_unref (base_video_decoder); - - return res; -} - -gboolean -gst_base_video_decoder_set_src_caps (GstBaseVideoDecoder * base_video_decoder) -{ - GstCaps *caps; - GstVideoState *state = &base_video_decoder->state; - - if (base_video_decoder->have_src_caps) - return TRUE; - - caps = gst_pad_get_allowed_caps (base_video_decoder->srcpad); - if (!caps) - goto null_allowed_caps; - if (gst_caps_is_empty (caps)) - goto empty_allowed_caps; - - gst_caps_set_simple (caps, - "width", G_TYPE_INT, state->width, - "height", G_TYPE_INT, state->height, - "pixel-aspect-ratio", GST_TYPE_FRACTION, state->par_n, state->par_d, - "interlaced", G_TYPE_BOOLEAN, state->interlaced, NULL); - - if (state->fps_d != 0) - gst_caps_set_simple (caps, - "framerate", GST_TYPE_FRACTION, state->fps_n, state->fps_d, NULL); - - - gst_pad_fixate_caps (base_video_decoder->srcpad, caps); - GST_DEBUG ("setting caps %" GST_PTR_FORMAT, caps); - - base_video_decoder->have_src_caps = - gst_pad_set_caps (GST_BASE_VIDEO_DECODER_SRC_PAD (base_video_decoder), - caps); - gst_caps_unref (caps); - - return base_video_decoder->have_src_caps; - -null_allowed_caps: - GST_ERROR_OBJECT (base_video_decoder, - "Got null from gst_pad_get_allowed_caps"); - return FALSE; - -empty_allowed_caps: - GST_ERROR_OBJECT (base_video_decoder, - "Got EMPTY caps from gst_pad_get_allowed_caps"); - - gst_caps_unref (caps); - return FALSE; -} - -static GstFlowReturn -gst_base_video_decoder_drain (GstBaseVideoDecoder * dec, gboolean at_eos) -{ - GstBaseVideoDecoderClass *klass; - GstBaseVideoDecoderScanResult res; - guint size; - - klass = GST_BASE_VIDEO_DECODER_GET_CLASS (dec); - - if (gst_adapter_available (dec->input_adapter) == 0) - return GST_FLOW_OK; - -lost_sync: - if (!dec->have_sync) { - gint n, m; - - GST_DEBUG ("no sync, scanning"); - - n = gst_adapter_available (dec->input_adapter); - m = klass->scan_for_sync (dec, dec->input_adapter); - if (m == -1) { - gst_object_unref (dec); - return GST_FLOW_OK; - } - - if (m < 0) { - g_warning ("subclass returned negative scan %d", m); - } - - if (m >= n) { - GST_ERROR ("subclass scanned past end %d >= %d", m, n); - } - - gst_adapter_flush (dec->input_adapter, m); - - if (m < n) { - GST_DEBUG ("found possible sync after %d bytes (of %d)", m, n); - /* this is only "maybe" sync */ - dec->have_sync = TRUE; - } - - if (!dec->have_sync) { - return GST_FLOW_OK; - } - } - - res = klass->scan_for_packet_end (dec, dec->input_adapter, &size, at_eos); - while (res == GST_BASE_VIDEO_DECODER_SCAN_RESULT_OK) { - GstBuffer *buf; - GstFlowReturn ret; - - GST_DEBUG ("Packet size: %u", size); - if (size > gst_adapter_available (dec->input_adapter)) - return GST_FLOW_OK; - - buf = gst_adapter_take_buffer (dec->input_adapter, size); - - dec->prev_buf_offset = dec->current_buf_offset; - dec->current_buf_offset = dec->input_offset - - gst_adapter_available (dec->input_adapter); - - ret = klass->parse_data (dec, buf, at_eos, dec->current_frame); - if (ret != GST_FLOW_OK) - return ret; - - res = klass->scan_for_packet_end (dec, dec->input_adapter, &size, at_eos); - } - - switch (res) { - case GST_BASE_VIDEO_DECODER_SCAN_RESULT_LOST_SYNC: - dec->have_sync = FALSE; - goto lost_sync; - - case GST_BASE_VIDEO_DECODER_SCAN_RESULT_NEED_DATA: - return GST_FLOW_OK; - - default: - GST_ERROR_OBJECT (dec, "Subclass returned invalid scan result"); - return GST_FLOW_ERROR; - } -} - -static GstFlowReturn -gst_base_video_decoder_chain (GstPad * pad, GstBuffer * buf) -{ - GstBaseVideoDecoder *base_video_decoder; - GstFlowReturn ret; - - GST_DEBUG ("chain %" GST_TIME_FORMAT " duration %" GST_TIME_FORMAT, - GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)), - GST_TIME_ARGS (GST_BUFFER_DURATION (buf))); - -#if 0 - /* requiring the pad to be negotiated makes it impossible to use - * oggdemux or filesrc ! decoder */ - if (!gst_pad_is_negotiated (pad)) { - GST_DEBUG ("not negotiated"); - return GST_FLOW_NOT_NEGOTIATED; - } -#endif - - base_video_decoder = GST_BASE_VIDEO_DECODER (gst_pad_get_parent (pad)); - - GST_DEBUG_OBJECT (base_video_decoder, "chain"); - - if (!base_video_decoder->have_segment) { - GstEvent *event; - GstFlowReturn ret; - - GST_WARNING - ("Received buffer without a new-segment. Assuming timestamps start from 0."); - - gst_segment_set_newsegment_full (&base_video_decoder->segment, - FALSE, 1.0, 1.0, GST_FORMAT_TIME, 0, GST_CLOCK_TIME_NONE, 0); - base_video_decoder->have_segment = TRUE; - - event = gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_TIME, 0, - GST_CLOCK_TIME_NONE, 0); - - ret = - gst_pad_push_event (GST_BASE_VIDEO_DECODER_SRC_PAD (base_video_decoder), - event); - if (!ret) { - GST_ERROR ("new segment event ret=%d", ret); - return GST_FLOW_ERROR; - } - } - - if (G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DISCONT))) { - GST_DEBUG_OBJECT (base_video_decoder, "received DISCONT buffer"); - gst_base_video_decoder_flush (base_video_decoder); - } - - base_video_decoder->input_offset += GST_BUFFER_SIZE (buf); - if (GST_BUFFER_TIMESTAMP_IS_VALID (buf)) { - gst_base_video_decoder_add_timestamp (base_video_decoder, buf); - } - - if (!base_video_decoder->current_frame) - base_video_decoder->current_frame = - gst_base_video_decoder_new_frame (base_video_decoder); - - if (base_video_decoder->packetized) { - base_video_decoder->current_frame->sink_buffer = buf; - - ret = gst_base_video_decoder_have_frame (base_video_decoder, TRUE, NULL); - } else { - - gst_adapter_push (base_video_decoder->input_adapter, buf); - - ret = gst_base_video_decoder_drain (base_video_decoder, FALSE); - } - - gst_object_unref (base_video_decoder); - return ret; -} - -static gboolean -gst_base_video_decoder_stop (GstBaseVideoDecoder * base_video_decoder) -{ - GstBaseVideoDecoderClass *base_video_decoder_class; - - GST_DEBUG ("stop"); - - base_video_decoder_class = - GST_BASE_VIDEO_DECODER_GET_CLASS (base_video_decoder); - - gst_base_video_decoder_reset (base_video_decoder); - - if (base_video_decoder_class->stop) - return base_video_decoder_class->stop (base_video_decoder); - - return TRUE; -} - -static gboolean -gst_base_video_decoder_start (GstBaseVideoDecoder * base_video_decoder) -{ - GstBaseVideoDecoderClass *base_video_decoder_class; - - GST_DEBUG ("start"); - - base_video_decoder_class = - GST_BASE_VIDEO_DECODER_GET_CLASS (base_video_decoder); - - gst_base_video_decoder_reset (base_video_decoder); - gst_base_video_decoder_reset_state (&base_video_decoder->state); - - gst_segment_init (&base_video_decoder->segment, GST_FORMAT_TIME); - - if (base_video_decoder_class->start) - return base_video_decoder_class->start (base_video_decoder); - - return TRUE; -} - -static GstStateChangeReturn -gst_base_video_decoder_change_state (GstElement * element, - GstStateChange transition) -{ - GstBaseVideoDecoder *base_video_decoder; - GstStateChangeReturn ret; - - base_video_decoder = GST_BASE_VIDEO_DECODER (element); - - switch (transition) { - case GST_STATE_CHANGE_READY_TO_PAUSED: - if (!gst_base_video_decoder_start (base_video_decoder)) - return GST_STATE_CHANGE_FAILURE; - break; - - default: - break; - } - - ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); - - switch (transition) { - case GST_STATE_CHANGE_PAUSED_TO_READY: - if (!gst_base_video_decoder_stop (base_video_decoder)) - ret = GST_STATE_CHANGE_FAILURE; - break; - - default: - break; - } - - return ret; -} - -static gboolean -gst_base_video_decoder_check_timestamp (GstBaseVideoDecoder * - base_video_decoder, GstClockTime timestamp) -{ - if (timestamp == GST_CLOCK_TIME_NONE) - return FALSE; - - if (GST_CLOCK_TIME_IS_VALID (base_video_decoder->last_timestamp)) - return timestamp > base_video_decoder->last_timestamp; - - return TRUE; -} - -static void -gst_base_video_decoder_calculate_timestamps (GstBaseVideoDecoder * - base_video_decoder, GstVideoFrame * frame, - GstClockTime * presentation_timestamp, GstClockTime * presentation_duration) -{ - GST_DEBUG ("calculate timestamps sync=%d upstream timestamp: %" - GST_TIME_FORMAT " parsed timestamp: %" GST_TIME_FORMAT, - GST_VIDEO_FRAME_FLAG_IS_SET (frame, GST_VIDEO_FRAME_FLAG_SYNC_POINT), - GST_TIME_ARGS (frame->upstream_timestamp), - GST_TIME_ARGS (frame->parsed_timestamp)); - - *presentation_timestamp = GST_CLOCK_TIME_NONE; - *presentation_duration = GST_CLOCK_TIME_NONE; - - if (gst_base_video_decoder_check_timestamp (base_video_decoder, - frame->upstream_timestamp)) { - *presentation_timestamp = frame->upstream_timestamp; - *presentation_duration = frame->upstream_duration; - } - - else if (gst_base_video_decoder_check_timestamp (base_video_decoder, - frame->parsed_timestamp)) - *presentation_timestamp = frame->parsed_timestamp; - - - if (GST_CLOCK_TIME_IS_VALID (*presentation_timestamp)) { - GST_DEBUG ("sync timestamp %" GST_TIME_FORMAT " diff %" GST_TIME_FORMAT, - GST_TIME_ARGS (*presentation_timestamp), - GST_TIME_ARGS (*presentation_timestamp - - base_video_decoder->segment.start)); - base_video_decoder->timestamp_offset = *presentation_timestamp; - base_video_decoder->field_index = 0; - } - - else { - if (GST_VIDEO_FRAME_FLAG_IS_SET (frame, GST_VIDEO_FRAME_FLAG_SYNC_POINT)) { - GST_WARNING ("sync point doesn't have timestamp"); - if (!GST_CLOCK_TIME_IS_VALID (base_video_decoder->timestamp_offset)) { - GST_WARNING - ("No base timestamp. Assuming frames start at segment start"); - base_video_decoder->timestamp_offset = - base_video_decoder->segment.start; - base_video_decoder->field_index = 0; - } - } - - *presentation_timestamp = - gst_base_video_decoder_get_field_timestamp (base_video_decoder, - base_video_decoder->field_index); - } - - if (*presentation_duration == GST_CLOCK_TIME_NONE) { - *presentation_duration = - gst_base_video_decoder_get_field_duration (base_video_decoder, - frame->n_fields); - } - - base_video_decoder->field_index += frame->n_fields; - base_video_decoder->last_timestamp = *presentation_timestamp; -} - -GstFlowReturn -gst_base_video_decoder_finish_frame (GstBaseVideoDecoder * base_video_decoder, - GstVideoFrame * frame) -{ - GstBaseVideoDecoderClass *base_video_decoder_class; - - GstClockTime presentation_timestamp; - GstClockTime presentation_duration; - - GstBuffer *src_buffer; - - GST_DEBUG ("finish frame"); - - base_video_decoder_class = - GST_BASE_VIDEO_DECODER_GET_CLASS (base_video_decoder); - - - if (!gst_base_video_decoder_set_src_caps (base_video_decoder)) - return GST_FLOW_NOT_NEGOTIATED; - - gst_base_video_decoder_calculate_timestamps (base_video_decoder, frame, - &presentation_timestamp, &presentation_duration); - - src_buffer = frame->src_buffer; - - GST_BUFFER_FLAG_UNSET (src_buffer, GST_BUFFER_FLAG_DELTA_UNIT); - if (base_video_decoder->state.interlaced) { -#ifndef GST_VIDEO_BUFFER_TFF -#define GST_VIDEO_BUFFER_TFF (GST_MINI_OBJECT_FLAG_LAST << 5) -#endif -#ifndef GST_VIDEO_BUFFER_RFF -#define GST_VIDEO_BUFFER_RFF (GST_MINI_OBJECT_FLAG_LAST << 6) -#endif -#ifndef GST_VIDEO_BUFFER_ONEFIELD -#define GST_VIDEO_BUFFER_ONEFIELD (GST_MINI_OBJECT_FLAG_LAST << 7) -#endif - - if (GST_VIDEO_FRAME_FLAG_IS_SET (frame, GST_VIDEO_FRAME_FLAG_TFF)) { - GST_BUFFER_FLAG_SET (src_buffer, GST_VIDEO_BUFFER_TFF); - } else { - GST_BUFFER_FLAG_UNSET (src_buffer, GST_VIDEO_BUFFER_TFF); - } - GST_BUFFER_FLAG_UNSET (src_buffer, GST_VIDEO_BUFFER_RFF); - GST_BUFFER_FLAG_UNSET (src_buffer, GST_VIDEO_BUFFER_ONEFIELD); - if (frame->n_fields == 3) { - GST_BUFFER_FLAG_SET (src_buffer, GST_VIDEO_BUFFER_RFF); - } else if (frame->n_fields == 1) { - GST_BUFFER_FLAG_SET (src_buffer, GST_VIDEO_BUFFER_ONEFIELD); - } - } - if (base_video_decoder->discont) { - GST_BUFFER_FLAG_UNSET (src_buffer, GST_BUFFER_FLAG_DISCONT); - base_video_decoder->discont = FALSE; - } - - GST_BUFFER_TIMESTAMP (src_buffer) = presentation_timestamp; - GST_BUFFER_DURATION (src_buffer) = presentation_duration; - GST_BUFFER_OFFSET (src_buffer) = GST_BUFFER_OFFSET_NONE; - GST_BUFFER_OFFSET_END (src_buffer) = GST_BUFFER_OFFSET_NONE; - - GST_DEBUG ("pushing frame %" GST_TIME_FORMAT, - GST_TIME_ARGS (presentation_timestamp)); - - if (base_video_decoder->sink_clipping) { - gint64 start = GST_BUFFER_TIMESTAMP (src_buffer); - gint64 stop = GST_BUFFER_TIMESTAMP (src_buffer) + - GST_BUFFER_DURATION (src_buffer); - - if (gst_segment_clip (&base_video_decoder->segment, GST_FORMAT_TIME, - start, stop, &start, &stop)) { - GST_BUFFER_TIMESTAMP (src_buffer) = start; - GST_BUFFER_DURATION (src_buffer) = stop - start; - GST_DEBUG ("accepting buffer inside segment: %" GST_TIME_FORMAT - " %" GST_TIME_FORMAT - " seg %" GST_TIME_FORMAT " to %" GST_TIME_FORMAT - " time %" GST_TIME_FORMAT, - GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (src_buffer)), - GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (src_buffer) + - GST_BUFFER_DURATION (src_buffer)), - GST_TIME_ARGS (base_video_decoder->segment.start), - GST_TIME_ARGS (base_video_decoder->segment.stop), - GST_TIME_ARGS (base_video_decoder->segment.time)); - } else { - GST_DEBUG ("dropping buffer outside segment: %" GST_TIME_FORMAT - " %" GST_TIME_FORMAT - " seg %" GST_TIME_FORMAT " to %" GST_TIME_FORMAT - " time %" GST_TIME_FORMAT, - GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (src_buffer)), - GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (src_buffer) + - GST_BUFFER_DURATION (src_buffer)), - GST_TIME_ARGS (base_video_decoder->segment.start), - GST_TIME_ARGS (base_video_decoder->segment.stop), - GST_TIME_ARGS (base_video_decoder->segment.time)); - gst_video_frame_unref (frame); - return GST_FLOW_OK; - } - } - - gst_buffer_ref (src_buffer); - gst_video_frame_unref (frame); - - if (base_video_decoder_class->shape_output) - return base_video_decoder_class->shape_output (base_video_decoder, - src_buffer); - - return gst_pad_push (GST_BASE_VIDEO_DECODER_SRC_PAD (base_video_decoder), - src_buffer); -} - -void -gst_base_video_decoder_skip_frame (GstBaseVideoDecoder * base_video_decoder, - GstVideoFrame * frame) -{ - GstClockTime presentation_timestamp; - GstClockTime presentation_duration; - - GST_DEBUG ("skip frame"); - - gst_base_video_decoder_calculate_timestamps (base_video_decoder, frame, - &presentation_timestamp, &presentation_duration); - - GST_DEBUG ("skipping frame %" GST_TIME_FORMAT, - GST_TIME_ARGS (presentation_timestamp)); - - gst_video_frame_unref (frame); -} - -GstFlowReturn -gst_base_video_decoder_have_frame (GstBaseVideoDecoder * base_video_decoder, - gboolean include_current_buf, GstVideoFrame ** new_frame) -{ - GstVideoFrame *frame = base_video_decoder->current_frame; - GstBaseVideoDecoderClass *klass; - - guint64 frame_end_offset; - GstClockTime timestamp, duration; - GstClockTime running_time; - GstClockTimeDiff deadline; - GstFlowReturn ret; - - klass = GST_BASE_VIDEO_DECODER_GET_CLASS (base_video_decoder); - - if (include_current_buf) - frame_end_offset = base_video_decoder->current_buf_offset; - else - frame_end_offset = base_video_decoder->prev_buf_offset; - - gst_base_video_decoder_get_timestamp_at_offset (base_video_decoder, - frame_end_offset, ×tamp, &duration); - - frame->upstream_timestamp = timestamp; - frame->upstream_duration = duration; - - GST_DEBUG ("upstream timestamp %" GST_TIME_FORMAT, - GST_TIME_ARGS (frame->upstream_timestamp)); - - running_time = gst_segment_to_running_time (&base_video_decoder->segment, - GST_FORMAT_TIME, frame->upstream_timestamp); - - if (GST_CLOCK_TIME_IS_VALID (base_video_decoder->earliest_time)) - deadline = GST_CLOCK_DIFF (base_video_decoder->earliest_time, running_time); - else - deadline = G_MAXINT64; - - /* do something with frame */ - ret = klass->handle_frame (base_video_decoder, frame, deadline); - if (ret != GST_FLOW_OK) { - GST_DEBUG ("flow error!"); - } - - /* create new frame */ - base_video_decoder->current_frame = - gst_base_video_decoder_new_frame (base_video_decoder); - - if (new_frame) - *new_frame = base_video_decoder->current_frame; - - return ret; -} - -GstVideoState -gst_base_video_decoder_get_state (GstBaseVideoDecoder * base_video_decoder) -{ - return base_video_decoder->state; -} - -void -gst_base_video_decoder_set_state (GstBaseVideoDecoder * base_video_decoder, - GstVideoState state) -{ - base_video_decoder->state = state; - - base_video_decoder->have_src_caps = FALSE; -} - -void -gst_base_video_decoder_lost_sync (GstBaseVideoDecoder * base_video_decoder) -{ - g_return_if_fail (GST_IS_BASE_VIDEO_DECODER (base_video_decoder)); - - GST_DEBUG ("lost_sync"); - - if (gst_adapter_available (base_video_decoder->input_adapter) >= 1) { - gst_adapter_flush (base_video_decoder->input_adapter, 1); - } - - base_video_decoder->have_sync = FALSE; -} - -/* GObject vmethod implementations */ -static void -gst_base_video_decoder_get_property (GObject * object, guint property_id, - GValue * value, GParamSpec * pspec) -{ - GstBaseVideoDecoder *base_video_decoder = GST_BASE_VIDEO_DECODER (object); - - switch (property_id) { - case PROP_PACKETIZED: - g_value_set_boolean (value, base_video_decoder->packetized); - break; - case PROP_SINK_CLIPPING: - g_value_set_boolean (value, base_video_decoder->sink_clipping); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -gst_base_video_decoder_set_property (GObject * object, guint property_id, - const GValue * value, GParamSpec * pspec) -{ - GstBaseVideoDecoder *base_video_decoder = GST_BASE_VIDEO_DECODER (object); - - switch (property_id) { - case PROP_PACKETIZED: - base_video_decoder->packetized = g_value_get_boolean (value); - break; - case PROP_SINK_CLIPPING: - base_video_decoder->sink_clipping = g_value_get_boolean (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -gst_base_video_decoder_finalize (GObject * object) -{ - GstBaseVideoDecoder *base_video_decoder; - - g_return_if_fail (GST_IS_BASE_VIDEO_DECODER (object)); - base_video_decoder = GST_BASE_VIDEO_DECODER (object); - - g_object_unref (base_video_decoder->input_adapter); - - GST_DEBUG_OBJECT (object, "finalize"); - - G_OBJECT_CLASS (parent_class)->finalize (object); -} - -static void -gst_base_video_decoder_base_init (gpointer g_class) -{ - GST_DEBUG_CATEGORY_INIT (basevideodecoder_debug, "basevideodecoder", 0, - "Base Video Decoder"); -} - -static void -gst_base_video_decoder_class_init (GstBaseVideoDecoderClass * klass) -{ - GObjectClass *gobject_class; - GstElementClass *gstelement_class; - - gobject_class = G_OBJECT_CLASS (klass); - gstelement_class = GST_ELEMENT_CLASS (klass); - - gobject_class->finalize = gst_base_video_decoder_finalize; - gobject_class->get_property = gst_base_video_decoder_get_property; - gobject_class->set_property = gst_base_video_decoder_set_property; - - g_object_class_install_property (gobject_class, PROP_PACKETIZED, - g_param_spec_boolean ("packetized", "Packetized", - "Whether the incoming data is already packetized into suitable " - "packets", FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (gobject_class, PROP_PACKETIZED, - g_param_spec_boolean ("sink-clipping", "Sink Clipping", - "If enabled GstBaseVideoDecoder will clip outgoing frames", FALSE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - gstelement_class->change_state = gst_base_video_decoder_change_state; - - parent_class = g_type_class_peek_parent (klass); -} - -static void -gst_base_video_decoder_init (GstBaseVideoDecoder * base_video_decoder, - GstBaseVideoDecoderClass * base_video_decoder_class) -{ - GstPadTemplate *pad_template; - GstPad *pad; - - GST_DEBUG ("gst_base_video_decoder_init"); - - pad_template = - gst_element_class_get_pad_template (GST_ELEMENT_CLASS - (base_video_decoder_class), "sink"); - g_return_if_fail (pad_template != NULL); - - base_video_decoder->sinkpad = pad = - gst_pad_new_from_template (pad_template, "sink"); - gst_element_add_pad (GST_ELEMENT (base_video_decoder), pad); - - gst_pad_set_chain_function (pad, gst_base_video_decoder_chain); - gst_pad_set_event_function (pad, gst_base_video_decoder_sink_event); - gst_pad_set_setcaps_function (pad, gst_base_video_decoder_sink_setcaps); - gst_pad_set_query_function (pad, gst_base_video_decoder_sink_query); - - if (base_video_decoder_class->create_srcpad) { - base_video_decoder->srcpad = pad = - base_video_decoder_class->create_srcpad (base_video_decoder, - base_video_decoder_class); - } else { - pad_template = - gst_element_class_get_pad_template (GST_ELEMENT_CLASS - (base_video_decoder_class), "src"); - g_return_if_fail (pad_template != NULL); - - base_video_decoder->srcpad = pad = - gst_pad_new_from_template (pad_template, "src"); - } - gst_element_add_pad (GST_ELEMENT (base_video_decoder), pad); - - gst_pad_set_event_function (pad, gst_base_video_decoder_src_event); - gst_pad_set_query_type_function (pad, gst_base_video_decoder_get_query_types); - gst_pad_set_query_function (pad, gst_base_video_decoder_src_query); - gst_pad_use_fixed_caps (pad); - - base_video_decoder->input_adapter = gst_adapter_new (); - memset (&base_video_decoder->state, 0, sizeof (GstVideoState)); - - /* properties */ - base_video_decoder->packetized = FALSE; - base_video_decoder->sink_clipping = TRUE; -} diff --git a/sys/vdpau/basevideodecoder/gstbasevideodecoder.h b/sys/vdpau/basevideodecoder/gstbasevideodecoder.h deleted file mode 100644 index 6cf5c7d47..000000000 --- a/sys/vdpau/basevideodecoder/gstbasevideodecoder.h +++ /dev/null @@ -1,179 +0,0 @@ -/* GStreamer - * Copyright (C) 2008 David Schleef <ds@schleef.org> - * - * 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., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef _GST_BASE_VIDEO_DECODER_H_ -#define _GST_BASE_VIDEO_DECODER_H_ - -#include "gstbasevideoutils.h" -#include "gstvideoframe.h" - -G_BEGIN_DECLS - -#define GST_TYPE_BASE_VIDEO_DECODER (gst_base_video_decoder_get_type()) -#define GST_BASE_VIDEO_DECODER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_BASE_VIDEO_DECODER, GstBaseVideoDecoder)) -#define GST_BASE_VIDEO_DECODER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_BASE_VIDEO_DECODER, GstBaseVideoDecoderClass)) -#define GST_BASE_VIDEO_DECODER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GST_TYPE_BASE_VIDEO_DECODER, GstBaseVideoDecoderClass)) -#define GST_IS_BASE_VIDEO_DECODER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_BASE_VIDEO_DECODER)) -#define GST_IS_BASE_VIDEO_DECODER_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_BASE_VIDEO_DECODER)) - -/** - * GST_BASE_VIDEO_DECODER_SINK_NAME: - * - * The name of the templates for the sink pad. - */ -#define GST_BASE_VIDEO_DECODER_SINK_NAME "sink" -/** - * GST_BASE_VIDEO_DECODER_SRC_NAME: - * - * The name of the templates for the source pad. - */ -#define GST_BASE_VIDEO_DECODER_SRC_NAME "src" - -/** - * GST_BASE_VIDEO_CODEC_SRC_PAD: - * @obj: base video codec instance - * - * Gives the pointer to the source #GstPad object of the element. - */ -#define GST_BASE_VIDEO_DECODER_SRC_PAD(obj) (((GstBaseVideoDecoder *) (obj))->srcpad) - -/** - * GST_BASE_VIDEO_CODEC_SINK_PAD: - * @obj: base video codec instance - * - * Gives the pointer to the sink #GstPad object of the element. - */ -#define GST_BASE_VIDEO_DECODER_SINK_PAD(obj) (((GstBaseVideoDecoder *) (obj))->sinkpad) - -/** - * * GST_BASE_VIDEO_DECODER_FLOW_NEED_DATA: - * * - * */ -#define GST_BASE_VIDEO_DECODER_FLOW_NEED_DATA GST_FLOW_CUSTOM_SUCCESS - - -typedef enum _GstBaseVideoDecoderScanResult GstBaseVideoDecoderScanResult; - -enum _GstBaseVideoDecoderScanResult -{ - GST_BASE_VIDEO_DECODER_SCAN_RESULT_OK, - GST_BASE_VIDEO_DECODER_SCAN_RESULT_LOST_SYNC, - GST_BASE_VIDEO_DECODER_SCAN_RESULT_NEED_DATA -}; - -typedef struct _GstBaseVideoDecoder GstBaseVideoDecoder; -typedef struct _GstBaseVideoDecoderClass GstBaseVideoDecoderClass; - -struct _GstBaseVideoDecoder -{ - GstElement element; - - /*< private >*/ - GstPad *sinkpad; - GstPad *srcpad; - GstAdapter *input_adapter; - - gboolean have_sync; - gboolean discont; - - GstVideoState state; - GstSegment segment; - - GstCaps *caps; - gboolean have_src_caps; - - GstVideoFrame *current_frame; - - GList *timestamps; - guint64 field_index; - GstClockTime timestamp_offset; - GstClockTime last_timestamp; - - gdouble proportion; - GstClockTime earliest_time; - - guint64 input_offset; - guint64 current_buf_offset; - guint64 prev_buf_offset; - - gboolean have_segment; - - /* properties */ - gboolean sink_clipping; - gboolean packetized; -}; - -struct _GstBaseVideoDecoderClass -{ - GstElementClass element_class; - - gboolean (*start) (GstBaseVideoDecoder *coder); - gboolean (*stop) (GstBaseVideoDecoder *coder); - gboolean (*flush) (GstBaseVideoDecoder *coder); - - gboolean (*set_sink_caps) (GstBaseVideoDecoder *base_video_decoder, - GstCaps *caps); - - GstPad *(*create_srcpad) (GstBaseVideoDecoder * base_video_decoder, - GstBaseVideoDecoderClass *base_video_decoder_class); - - - gint (*scan_for_sync) (GstBaseVideoDecoder *coder, GstAdapter *adapter); - - GstBaseVideoDecoderScanResult (*scan_for_packet_end) - (GstBaseVideoDecoder *coder, GstAdapter *adapter, guint *size, gboolean at_eos); - - GstFlowReturn (*parse_data) (GstBaseVideoDecoder *decoder, - GstBuffer *buf, gboolean at_eos, GstVideoFrame *frame); - - - GstVideoFrame *(*create_frame) (GstBaseVideoDecoder *coder); - GstFlowReturn (*handle_frame) (GstBaseVideoDecoder *coder, GstVideoFrame *frame, - GstClockTimeDiff deadline); - GstFlowReturn (*shape_output) (GstBaseVideoDecoder *coder, - GstBuffer *buf); - -}; - -GType gst_base_video_decoder_get_type (void); - -GstVideoFrame *gst_base_video_decoder_get_frame (GstBaseVideoDecoder *coder, - gint frame_number); -GstVideoFrame *gst_base_video_decoder_get_oldest_frame (GstBaseVideoDecoder *coder); - -GstFlowReturn gst_base_video_decoder_finish_frame (GstBaseVideoDecoder *base_video_decoder, - GstVideoFrame *frame); -void gst_base_video_decoder_skip_frame (GstBaseVideoDecoder * base_video_decoder, - GstVideoFrame * frame); - -GstFlowReturn -gst_base_video_decoder_have_frame (GstBaseVideoDecoder *base_video_decoder, - gboolean include_current_buf, GstVideoFrame **new_frame); - -GstVideoState gst_base_video_decoder_get_state (GstBaseVideoDecoder *base_video_decoder); -void gst_base_video_decoder_set_state (GstBaseVideoDecoder *base_video_decoder, - GstVideoState state); -gboolean gst_base_video_decoder_set_src_caps (GstBaseVideoDecoder * base_video_decoder); - -void gst_base_video_decoder_lost_sync (GstBaseVideoDecoder *base_video_decoder); - -G_END_DECLS - -#endif - diff --git a/sys/vdpau/basevideodecoder/gstbasevideoutils.h b/sys/vdpau/basevideodecoder/gstbasevideoutils.h deleted file mode 100644 index f982c601c..000000000 --- a/sys/vdpau/basevideodecoder/gstbasevideoutils.h +++ /dev/null @@ -1,55 +0,0 @@ -/* GStreamer - * Copyright (C) 2008 David Schleef <ds@schleef.org> - * - * 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., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef _GST_BASE_VIDEO_UTILS_H_ -#define _GST_BASE_VIDEO_UTILS_H_ - -#define GST_USE_UNSTABLE_API 1 - -#ifndef GST_USE_UNSTABLE_API -#warning "The base video utils API is unstable and may change in future." -#warning "You can define GST_USE_UNSTABLE_API to avoid this warning." -#endif - -#include <gst/gst.h> -#include <gst/video/video.h> -#include <gst/base/gstadapter.h> - -G_BEGIN_DECLS - -typedef struct _GstVideoState GstVideoState; - -struct _GstVideoState -{ - gint width, height; - gint fps_n, fps_d; - gint par_n, par_d; - - gboolean interlaced; - - gint clean_width, clean_height; - gint clean_offset_left, clean_offset_top; - - gint bytes_per_picture; - - GstBuffer *codec_data; - -}; - -#endif /* _GST_BASE_VIDEO_UTILS_H_ */
\ No newline at end of file diff --git a/sys/vdpau/basevideodecoder/gstvideoframe.c b/sys/vdpau/basevideodecoder/gstvideoframe.c deleted file mode 100644 index b59ac54fa..000000000 --- a/sys/vdpau/basevideodecoder/gstvideoframe.c +++ /dev/null @@ -1,107 +0,0 @@ -/* -* GStreamer -* Copyright (C) 2009 Carl-Anton Ingmarsson <ca.ingmarsson@gmail.com> -* -* 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., 51 Franklin St, Fifth Floor, -* Boston, MA 02110-1301, USA. -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "gstvideoframe.h" - -GST_DEBUG_CATEGORY_STATIC (gst_video_frame_debug); -#define GST_CAT_DEFAULT gst_video_frame_debug - -#define DEBUG_INIT(bla) \ -GST_DEBUG_CATEGORY_INIT (gst_video_frame_debug, "gstvideoframe", 0, "Video Frame"); - -GstVideoFrame * -gst_video_frame_new (void) -{ - GstVideoFrame *frame; - - frame = (GstVideoFrame *) gst_mini_object_new (GST_TYPE_VIDEO_FRAME); - - return frame; -} - -static GObjectClass *gst_video_frame_parent_class; - -static void -gst_video_frame_finalize (GstVideoFrame * frame) -{ - if (frame->sink_buffer) - gst_buffer_unref (frame->sink_buffer); - if (frame->src_buffer) - gst_buffer_unref (frame->src_buffer); - - GST_MINI_OBJECT_CLASS (gst_video_frame_parent_class)->finalize - (GST_MINI_OBJECT (frame)); -} - -static void -gst_video_frame_init (GstVideoFrame * frame, gpointer g_class) -{ - frame->upstream_timestamp = GST_CLOCK_TIME_NONE; - frame->upstream_duration = GST_CLOCK_TIME_NONE; - - frame->parsed_timestamp = GST_CLOCK_TIME_NONE; - - frame->n_fields = 2; - - frame->sink_buffer = NULL; - frame->src_buffer = NULL; -} - -static void -gst_video_frame_class_init (gpointer g_class, gpointer class_data) -{ - GstMiniObjectClass *mini_object_class = GST_MINI_OBJECT_CLASS (g_class); - - gst_video_frame_parent_class = g_type_class_peek_parent (g_class); - - mini_object_class->finalize = (GstMiniObjectFinalizeFunction) - gst_video_frame_finalize; -} - - -GType -gst_video_frame_get_type (void) -{ - static GType _gst_video_frame_type = 0; - - if (G_UNLIKELY (_gst_video_frame_type == 0)) { - static const GTypeInfo info = { - sizeof (GstVideoFrameClass), - NULL, - NULL, - gst_video_frame_class_init, - NULL, - NULL, - sizeof (GstVideoFrame), - 0, - (GInstanceInitFunc) gst_video_frame_init, - NULL - }; - _gst_video_frame_type = g_type_register_static (GST_TYPE_MINI_OBJECT, - "GstVideoFrame", &info, 0); - - DEBUG_INIT (); - } - return _gst_video_frame_type; -} diff --git a/sys/vdpau/basevideodecoder/gstvideoframe.h b/sys/vdpau/basevideodecoder/gstvideoframe.h deleted file mode 100644 index ab293da8d..000000000 --- a/sys/vdpau/basevideodecoder/gstvideoframe.h +++ /dev/null @@ -1,149 +0,0 @@ -/* -* GStreamer -* Copyright (C) 2009 Carl-Anton Ingmarsson <ca.ingmarsson@gmail.com> -* -* 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., 51 Franklin St, Fifth Floor, -* Boston, MA 02110-1301, USA. -*/ - -#ifndef _GST_VIDEO_FRAME_H_ -#define _GST_VIDEO_FRAME_H_ - -#include <gst/gst.h> - -#define GST_TYPE_VIDEO_FRAME (gst_video_frame_get_type()) -#define GST_IS_VIDEO_FRAME(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VIDEO_FRAME)) -#define GST_VIDEO_FRAME(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VIDEO_FRAME, GstVideoFrame)) -#define GST_VIDEO_FRAME_CAST(obj) ((GstVideoFrame *)obj) - -/** - * GstVideoFrameFlag: - * @GST_VIDEO_FRAME_FLAG_PREROLL: the frame is part of a preroll and should not be - * displayed. - * @GST_VIDEO_FRAME_FLAG_DISCONT: the frame marks a discontinuity in the stream. - * This typically occurs after a seek or a dropped buffer from a live or - * network source. - * @GST_VIDEO_FRAME_FLAG_GAP: the frame has been created to fill a gap in the - * stream and contains media neutral data (elements can switch to optimized code - * path that ignores the buffer content). - * @GST_VIDEO_FRAME_FLAG_DELTA_UNIT: the frame is a keyframe. - * @GST_VIDEO_FRAME_FLAG_SYNC_POINT: the frame marks a sync point. - * @GST_VIDEO_FRAME_FLAG_EOS: the frame is the last in the stream. - * @GST_VIDEO_FRAME_FLAG_TFF: If the frame is interlaced, then the first - * field in the video frame is the top field. If unset, the bottom field is first. - * @GST_VIDEO_FRAME_FLAG_LAST: additional flags can be added starting from this flag. - * A set of frame flags used to describe properties of a #GstVideoFrame. - */ -typedef enum -{ - GST_VIDEO_FRAME_FLAG_PREROLL = (GST_MINI_OBJECT_FLAG_LAST << 0), - GST_VIDEO_FRAME_FLAG_DISCONT = (GST_MINI_OBJECT_FLAG_LAST << 1), - GST_VIDEO_FRAME_FLAG_GAP = (GST_MINI_OBJECT_FLAG_LAST << 2), - GST_VIDEO_FRAME_FLAG_KEYFRAME = (GST_MINI_OBJECT_FLAG_LAST << 3), - GST_VIDEO_FRAME_FLAG_SYNC_POINT = (GST_MINI_OBJECT_FLAG_LAST << 4), - GST_VIDEO_FRAME_FLAG_EOS = (GST_MINI_OBJECT_FLAG_LAST << 5), - GST_VIDEO_FRAME_FLAG_TFF = (GST_MINI_OBJECT_FLAG_LAST << 6), - GST_VIDEO_FRAME_FLAG_LAST = (GST_MINI_OBJECT_FLAG_LAST << 7) -} GstVideoFrameFlag; - -typedef struct _GstVideoFrame GstVideoFrame; -typedef struct _GstVideoFrameClass GstVideoFrameClass; - -struct _GstVideoFrame -{ - GstMiniObject mini_object; - - GstClockTime upstream_timestamp; - GstClockTime upstream_duration; - - GstClockTime parsed_timestamp; - - guint n_fields; - - GstBuffer *sink_buffer; - GstBuffer *src_buffer; -}; - -struct _GstVideoFrameClass -{ - GstMiniObjectClass mini_object_class; -}; - -/* refcounting */ -/** - * gst_video_frame_ref: - * @frame: a #GstVideoFrame. - * - * Increases the refcount of the given frame by one. - * - * Returns: @frame - */ -#ifdef _FOOL_GTK_DOC_ -G_INLINE_FUNC GstVideoFrame * gst_buffer_ref (GstVideoFrame * frame); -#endif - -static inline GstVideoFrame * -gst_video_frame_ref (GstVideoFrame *frame) -{ - return (GstVideoFrame *) gst_mini_object_ref (GST_MINI_OBJECT_CAST (frame)); -} - -/** - * gst_video_frame_unref: - * @frame: a #GstVideoFrame. - * - * Decreases the refcount of the frame. If the refcount reaches 0, the frame - * will be freed. - */ -#ifdef _FOOL_GTK_DOC_ -G_INLINE_FUNC void gst_video_frame_unref (GstVideoFrame * frame); -#endif - -static inline void -gst_video_frame_unref (GstVideoFrame * frame) -{ - gst_mini_object_unref (GST_MINI_OBJECT_CAST (frame)); -} - -/** - * GST_VIDEO_FRAME_FLAG_IS_SET: - * @buf: a #GstVideoFrame. - * @flag: the #GstVideoFrameFlag to check. - * - * Gives the status of a specific flag on a video frame. - */ -#define GST_VIDEO_FRAME_FLAG_IS_SET(frame,flag) GST_MINI_OBJECT_FLAG_IS_SET (frame, flag) -/** - * GST_VIDEO_FRAME_FLAG_SET: - * @buf: a #GstVideoFrame. - * @flag: the #GstVideoFrameFlag to set. - * - * Sets a frame flag on a video frame. - */ -#define GST_VIDEO_FRAME_FLAG_SET(frame,flag) GST_MINI_OBJECT_FLAG_SET (frame, flag) -/** - * GST_VIDEO_FRAME_FLAG_UNSET: - * @buf: a #GstVideoFrame. - * @flag: the #GstVideoFrameFlag to clear. - * - * Clears a frame flag. - */ -#define GST_VIDEO_FRAME_FLAG_UNSET(frame,flag) GST_MINI_OBJECT_FLAG_UNSET (frame, flag) - -GstVideoFrame *gst_video_frame_new (void); - -GType gst_video_frame_get_type (void); - -#endif
\ No newline at end of file diff --git a/sys/vdpau/gstvdp/Makefile.am b/sys/vdpau/gstvdp/Makefile.am deleted file mode 100644 index 982b21fd5..000000000 --- a/sys/vdpau/gstvdp/Makefile.am +++ /dev/null @@ -1,40 +0,0 @@ -lib_LTLIBRARIES = libgstvdp-@GST_API_VERSION@.la - -libgstvdp_@GST_API_VERSION@_la_SOURCES = \ - gstvdpdevice.c \ - gstvdputils.c \ - gstvdpbuffer.c \ - gstvdpbufferpool.c \ - gstvdpvideobuffer.c \ - gstvdpvideobufferpool.c \ - gstvdpoutputbuffer.c \ - gstvdpoutputbufferpool.c \ - gstvdpvideosrcpad.c \ - gstvdpoutputsrcpad.c \ - gstvdpdecoder.c \ - gstvdp.c - -libgstvdp_@GST_API_VERSION@includedir = $(includedir)/gstreamer-@GST_API_VERSION@/gst/vdpau -libgstvdp_@GST_API_VERSION@include_HEADERS = \ - gstvdpdevice.h \ - gstvdputils.h \ - gstvdpbuffer.h \ - gstvdpbufferpool.h \ - gstvdpvideobuffer.h \ - gstvdpvideobufferpool.h \ - gstvdpoutputbuffer.h \ - gstvdpoutputbufferpool.h \ - gstvdpvideosrcpad.h \ - gstvdpoutputsrcpad.h \ - gstvdpdecoder.h \ - gstvdp.h - -libgstvdp_@GST_API_VERSION@_la_CFLAGS = $(GST_CFLAGS) $(GST_BASE_CFLAGS) \ - $(GST_PLUGINS_BASE_CFLAGS) $(X11_CFLAGS) $(VDPAU_CFLAGS) - -libgstvdp_@GST_API_VERSION@_la_LIBADD = $(GST_LIBS) $(X11_LIBS) $(VDPAU_LIBS) \ - -lgstvideo-$(GST_API_VERSION) \ - ../basevideodecoder/libgstbasevideodecoder.la - -libgstvdp_@GST_API_VERSION@_la_LDFLAGS = $(GST_LIB_LDFLAGS) $(GST_LT_LDFLAGS) $(GST_ALL_LDFLAGS) -libgstvdp_@GST_API_VERSION@_la_LIBTOOLFLAGS = --tag=disable-static diff --git a/sys/vdpau/gstvdp/gstvdp.c b/sys/vdpau/gstvdp/gstvdp.c deleted file mode 100644 index 3964d5df2..000000000 --- a/sys/vdpau/gstvdp/gstvdp.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * GStreamer - * Copyright (C) 2009 Carl-Anton Ingmarsson <ca.ingmarsson@gmail.com> - * - * 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., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include <gst/gst.h> - -#include "gstvdpdevice.h" -#include "gstvdpvideobuffer.h" -#include "gstvdpvideosrcpad.h" -#include "gstvdpoutputbuffer.h" -#include "gstvdpoutputsrcpad.h" -#include "gstvdpdecoder.h" - -#include "gstvdp.h" - -GST_DEBUG_CATEGORY (gst_vdp_debug); - -void -gst_vdp_init (void) -{ - /* do this so debug categories get created */ - gst_vdp_device_get_type (); - gst_vdp_output_buffer_get_type (); - gst_vdp_video_buffer_get_type (); - gst_vdp_video_src_pad_get_type (); - gst_vdp_output_src_pad_get_type (); - gst_vdp_decoder_get_type (); - - GST_DEBUG_CATEGORY_INIT (gst_vdp_debug, "vdp", 0, "GstVdp debug category"); -} diff --git a/sys/vdpau/gstvdp/gstvdp.h b/sys/vdpau/gstvdp/gstvdp.h deleted file mode 100644 index fe2781ffc..000000000 --- a/sys/vdpau/gstvdp/gstvdp.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * GStreamer - * Copyright (C) 2009 Carl-Anton Ingmarsson <ca.ingmarsson@gmail.com> - * - * 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., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef _GST_VDP_H_ -#define _GST_VDP_H_ - -void gst_vdp_init(void); - -#endif /* _GST_VDP_H_ */ diff --git a/sys/vdpau/gstvdp/gstvdpbuffer.c b/sys/vdpau/gstvdp/gstvdpbuffer.c deleted file mode 100644 index aee98fbc9..000000000 --- a/sys/vdpau/gstvdp/gstvdpbuffer.c +++ /dev/null @@ -1,86 +0,0 @@ -/* - * GStreamer - * Copyright (C) 2009 Carl-Anton Ingmarsson <ca.ingmarsson@gmail.com> - * - * 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., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "gstvdpbuffer.h" - -static GObjectClass *gst_vdp_buffer_parent_class; - -void -gst_vdp_buffer_set_buffer_pool (GstVdpBuffer * buffer, GstVdpBufferPool * bpool) -{ - g_return_if_fail (GST_IS_VDP_BUFFER (buffer)); - - if (bpool) { - g_return_if_fail (GST_IS_VDP_BUFFER_POOL (bpool)); - g_object_add_weak_pointer (G_OBJECT (bpool), (void **) &buffer->bpool); - } - - buffer->bpool = bpool; -} - -gboolean -gst_vdp_buffer_revive (GstVdpBuffer * buffer) -{ - if (buffer->bpool) - return gst_vdp_buffer_pool_put_buffer (buffer->bpool, buffer); - - return FALSE; -} - -static void -gst_vdp_buffer_init (GstVdpBuffer * buffer, gpointer g_class) -{ - buffer->bpool = NULL; -} - -static void -gst_vdp_buffer_class_init (gpointer g_class, gpointer class_data) -{ - gst_vdp_buffer_parent_class = g_type_class_peek_parent (g_class); -} - - -GType -gst_vdp_buffer_get_type (void) -{ - static GType _gst_vdp_buffer_type; - - if (G_UNLIKELY (_gst_vdp_buffer_type == 0)) { - static const GTypeInfo info = { - sizeof (GstBufferClass), - NULL, - NULL, - gst_vdp_buffer_class_init, - NULL, - NULL, - sizeof (GstVdpBuffer), - 0, - (GInstanceInitFunc) gst_vdp_buffer_init, - NULL - }; - _gst_vdp_buffer_type = g_type_register_static (GST_TYPE_BUFFER, - "GstVdpBuffer", &info, 0); - } - return _gst_vdp_buffer_type; -} diff --git a/sys/vdpau/gstvdp/gstvdpbuffer.h b/sys/vdpau/gstvdp/gstvdpbuffer.h deleted file mode 100644 index 7b26cd10b..000000000 --- a/sys/vdpau/gstvdp/gstvdpbuffer.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * GStreamer - * Copyright (C) 2009 Carl-Anton Ingmarsson <ca.ingmarsson@gmail.com> - * - * 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., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef _GST_VDP_BUFFER_H_ -#define _GST_VDP_BUFFER_H_ - -#include <gst/gst.h> - -typedef struct _GstVdpBuffer GstVdpBuffer; - -#include "gstvdpbufferpool.h" - -#define GST_TYPE_VDP_BUFFER (gst_vdp_buffer_get_type()) - -#define GST_IS_VDP_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VDP_BUFFER)) -#define GST_VDP_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VDP_BUFFER, GstVdpBuffer)) -#define GST_VDP_BUFFER_CAST(obj) ((GstVdpBuffer *)obj) - -struct _GstVdpBuffer { - GstBuffer buffer; - - GstVdpBufferPool *bpool; -}; - -void gst_vdp_buffer_set_buffer_pool (GstVdpBuffer *buffer, GstVdpBufferPool *bpool); -gboolean gst_vdp_buffer_revive (GstVdpBuffer * buffer); - -static inline GstVdpBuffer * -gst_vdp_buffer_ref (GstVdpBuffer *buffer) -{ - return (GstVdpBuffer *) gst_mini_object_ref (GST_MINI_OBJECT_CAST (buffer)); -} - -static inline void -gst_vdp_buffer_unref (GstVdpBuffer *buffer) -{ - gst_mini_object_unref (GST_MINI_OBJECT_CAST (buffer)); -} - -GType gst_vdp_buffer_get_type (void); - -#endif
\ No newline at end of file diff --git a/sys/vdpau/gstvdp/gstvdpbufferpool.c b/sys/vdpau/gstvdp/gstvdpbufferpool.c deleted file mode 100644 index 7a1b9c185..000000000 --- a/sys/vdpau/gstvdp/gstvdpbufferpool.c +++ /dev/null @@ -1,361 +0,0 @@ -/* - * GStreamer - * Copyright (C) 2010 Carl-Anton Ingmarsson <ca.ingmarsson@gmail.com> - * - * 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., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -/* FIXME 0.11: suppress warnings for deprecated API such as GStaticRecMutex - * with newer GLib versions (>= 2.31.0) */ -#define GLIB_DISABLE_DEPRECATION_WARNINGS - -#include "gstvdpbufferpool.h" - -struct _GstVdpBufferPoolPrivate -{ - GQueue *buffers; - GMutex *mutex; - - /* properties */ - guint max_buffers; - GstCaps *caps; - GstVdpDevice *device; -}; - -enum -{ - PROP_0, - PROP_DEVICE, - PROP_CAPS, - PROP_MAX_BUFFERS -}; - -G_DEFINE_TYPE (GstVdpBufferPool, gst_vdp_buffer_pool, G_TYPE_OBJECT); - -#define DEFAULT_MAX_BUFFERS 20 - -static void -gst_vdp_buffer_free (GstVdpBuffer * buf) -{ - gst_vdp_buffer_set_buffer_pool (buf, NULL); - gst_vdp_buffer_unref (buf); -} - -static void -gst_vdp_buffer_pool_clear (GstVdpBufferPool * bpool) -{ - GstVdpBufferPoolPrivate *priv = bpool->priv; - - g_queue_foreach (priv->buffers, (GFunc) gst_vdp_buffer_free, NULL); - g_queue_clear (priv->buffers); -} - -gboolean -gst_vdp_buffer_pool_put_buffer (GstVdpBufferPool * bpool, GstVdpBuffer * buf) -{ - GstVdpBufferPoolPrivate *priv; - - gboolean res; - GstVdpBufferPoolClass *bpool_class; - GstCaps *caps; - - g_return_val_if_fail (GST_IS_VDP_BUFFER_POOL (bpool), FALSE); - g_return_val_if_fail (GST_IS_VDP_BUFFER (buf), FALSE); - - priv = bpool->priv; - g_return_val_if_fail (priv->caps, FALSE); - - g_mutex_lock (priv->mutex); - - if (priv->buffers->length == priv->max_buffers) { - res = FALSE; - goto done; - } - - bpool_class = GST_VDP_BUFFER_POOL_GET_CLASS (bpool); - caps = GST_BUFFER_CAPS (buf); - if (!caps) - goto no_caps; - - if (!bpool_class->check_caps (bpool, caps)) { - res = FALSE; - goto done; - } - - gst_vdp_buffer_ref (buf); - g_queue_push_tail (priv->buffers, buf); - res = TRUE; - -done: - g_mutex_unlock (priv->mutex); - - return res; - -no_caps: - GST_WARNING ("Buffer doesn't have any caps"); - res = FALSE; - goto done; -} - -GstVdpBuffer * -gst_vdp_buffer_pool_get_buffer (GstVdpBufferPool * bpool, GError ** error) -{ - GstVdpBufferPoolPrivate *priv; - GstVdpBuffer *buf; - - g_return_val_if_fail (GST_IS_VDP_BUFFER_POOL (bpool), NULL); - - priv = bpool->priv; - g_return_val_if_fail (priv->caps, NULL); - - g_mutex_lock (priv->mutex); - - buf = g_queue_pop_head (priv->buffers); - if (!buf) { - GstVdpBufferPoolClass *bpool_class = GST_VDP_BUFFER_POOL_GET_CLASS (bpool); - - buf = bpool_class->alloc_buffer (bpool, error); - if (!buf) - goto done; - gst_buffer_set_caps (GST_BUFFER_CAST (buf), priv->caps); - gst_vdp_buffer_set_buffer_pool (buf, bpool); - } - -done: - g_mutex_unlock (priv->mutex); - return buf; -} - -void -gst_vdp_buffer_pool_set_max_buffers (GstVdpBufferPool * bpool, - guint max_buffers) -{ - GstVdpBufferPoolPrivate *priv; - - g_return_if_fail (GST_IS_VDP_BUFFER_POOL (bpool)); - g_return_if_fail (max_buffers >= -1); - - priv = bpool->priv; - - g_mutex_lock (priv->mutex); - - if (max_buffers != -1) { - while (max_buffers < priv->buffers->length) { - GstVdpBuffer *buf; - - buf = g_queue_pop_tail (priv->buffers); - gst_vdp_buffer_unref (buf); - } - } - - priv->max_buffers = max_buffers; - - g_mutex_unlock (priv->mutex); -} - -guint -gst_vdp_buffer_pool_get_max_buffers (GstVdpBufferPool * bpool) -{ - g_return_val_if_fail (GST_IS_VDP_BUFFER_POOL (bpool), 0); - - return bpool->priv->max_buffers; -} - -void -gst_vdp_buffer_pool_set_caps (GstVdpBufferPool * bpool, const GstCaps * caps) -{ - GstVdpBufferPoolPrivate *priv; - GstVdpBufferPoolClass *bpool_class; - gboolean clear_bufs; - - g_return_if_fail (GST_IS_VDP_BUFFER_POOL (bpool)); - g_return_if_fail (GST_IS_CAPS (caps)); - - priv = bpool->priv; - bpool_class = GST_VDP_BUFFER_POOL_GET_CLASS (bpool); - - g_mutex_lock (priv->mutex); - - if (!bpool_class->set_caps (bpool, caps, &clear_bufs)) - goto invalid_caps; - - if (clear_bufs) - gst_vdp_buffer_pool_clear (bpool); - - if (priv->caps) - gst_caps_unref (priv->caps); - - priv->caps = gst_caps_copy (caps); - -done: - g_mutex_unlock (priv->mutex); - return; - -invalid_caps: - GST_WARNING ("Subclass didn't accept caps: %" GST_PTR_FORMAT, caps); - goto done; -} - -const GstCaps * -gst_vdp_buffer_pool_get_caps (GstVdpBufferPool * bpool) -{ - g_return_val_if_fail (GST_IS_VDP_BUFFER_POOL (bpool), NULL); - - return bpool->priv->caps; -} - -GstVdpDevice * -gst_vdp_buffer_pool_get_device (GstVdpBufferPool * bpool) -{ - g_return_val_if_fail (GST_IS_VDP_BUFFER_POOL (bpool), NULL); - - return bpool->priv->device; -} - -static void -gst_vdp_buffer_pool_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec) -{ - GstVdpBufferPool *bpool = (GstVdpBufferPool *) object; - GstVdpBufferPoolPrivate *priv = bpool->priv; - - switch (prop_id) { - case PROP_DEVICE: - g_value_set_object (value, priv->device); - break; - - case PROP_CAPS: - g_value_set_pointer (value, priv->caps); - break; - - case PROP_MAX_BUFFERS: - g_value_set_uint (value, priv->max_buffers); - break; - - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_vdp_buffer_pool_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) -{ - GstVdpBufferPool *bpool = (GstVdpBufferPool *) object; - GstVdpBufferPoolPrivate *priv = bpool->priv; - - switch (prop_id) { - case PROP_DEVICE: - priv->device = g_value_get_object (value); - break; - - case PROP_CAPS: - gst_vdp_buffer_pool_set_caps (bpool, g_value_get_pointer (value)); - break; - - case PROP_MAX_BUFFERS: - gst_vdp_buffer_pool_set_max_buffers (bpool, g_value_get_uint (value)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_vdp_buffer_pool_finalize (GObject * object) -{ - GstVdpBufferPool *bpool = GST_VDP_BUFFER_POOL (object); - GstVdpBufferPoolPrivate *priv = bpool->priv; - - g_mutex_free (priv->mutex); - - if (priv->caps) - gst_caps_unref (priv->caps); - - G_OBJECT_CLASS (gst_vdp_buffer_pool_parent_class)->finalize (object); -} - -static void -gst_vdp_buffer_pool_init (GstVdpBufferPool * bpool) -{ - GstVdpBufferPoolPrivate *priv; - - bpool->priv = priv = G_TYPE_INSTANCE_GET_PRIVATE (bpool, - GST_TYPE_VDP_BUFFER_POOL, GstVdpBufferPoolPrivate); - - priv->buffers = g_queue_new (); - priv->mutex = g_mutex_new (); - - /* properties */ - priv->caps = NULL; - priv->max_buffers = DEFAULT_MAX_BUFFERS; -} - -static void -gst_vdp_buffer_pool_class_init (GstVdpBufferPoolClass * bpool_klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (bpool_klass); - - g_type_class_add_private (bpool_klass, sizeof (GstVdpBufferPoolPrivate)); - - object_class->get_property = gst_vdp_buffer_pool_get_property; - object_class->set_property = gst_vdp_buffer_pool_set_property; - - object_class->finalize = gst_vdp_buffer_pool_finalize; - - /** - * GstVdpBufferPool:device: - * - * The #GstVdpDevice this pool is bound to. - */ - g_object_class_install_property - (object_class, - PROP_DEVICE, - g_param_spec_object ("device", - "Device", - "The GstVdpDevice this pool is bound to", - GST_TYPE_VDP_DEVICE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - - /** - * GstVdpBufferPool:caps: - * - * The video object capabilities represented as a #GstCaps. This - * shall hold at least the "width" and "height" properties. - */ - g_object_class_install_property - (object_class, - PROP_CAPS, - g_param_spec_pointer ("caps", - "Caps", "The buffer capabilities", G_PARAM_READWRITE)); - - /** - * GstVdpBufferPool:max-buffers: - * - * The maximum number of buffer in the pool. Or -1, the pool - * will hold as many objects as possible. - */ - g_object_class_install_property - (object_class, - PROP_MAX_BUFFERS, - g_param_spec_int ("max-buffers", - "Max Buffers", - "The maximum number of buffers in the pool, or -1 for unlimited", - -1, G_MAXINT32, DEFAULT_MAX_BUFFERS, G_PARAM_READWRITE)); -} diff --git a/sys/vdpau/gstvdp/gstvdpbufferpool.h b/sys/vdpau/gstvdp/gstvdpbufferpool.h deleted file mode 100644 index af3321e81..000000000 --- a/sys/vdpau/gstvdp/gstvdpbufferpool.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * GStreamer - * Copyright (C) 2009 Carl-Anton Ingmarsson <ca.ingmarsson@gmail.com> - * - * 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., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef _GST_VDP_BUFFER_POOL_H_ -#define _GST_VDP_BUFFER_POOL_H_ - -#include <gst/gst.h> - -typedef struct _GstVdpBufferPool GstVdpBufferPool; - -#include "gstvdpdevice.h" -#include "gstvdpbuffer.h" - -G_BEGIN_DECLS - -#define GST_TYPE_VDP_BUFFER_POOL (gst_vdp_buffer_pool_get_type ()) -#define GST_VDP_BUFFER_POOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VDP_BUFFER_POOL, GstVdpBufferPool)) -#define GST_VDP_BUFFER_POOL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_VDP_BUFFER_POOL, GstVdpBufferPoolClass)) -#define GST_IS_VDP_BUFFER_POOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VDP_BUFFER_POOL)) -#define GST_IS_VDP_BUFFER_POOL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_VDP_BUFFER_POOL)) -#define GST_VDP_BUFFER_POOL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VDP_BUFFER_POOL, GstVdpBufferPoolClass)) - -typedef struct _GstVdpBufferPoolClass GstVdpBufferPoolClass; -typedef struct _GstVdpBufferPoolPrivate GstVdpBufferPoolPrivate; - -struct _GstVdpBufferPool -{ - GObject object; - - GstVdpBufferPoolPrivate *priv; -}; - -struct _GstVdpBufferPoolClass -{ - GObjectClass object_class; - - GstVdpBuffer *(*alloc_buffer) (GstVdpBufferPool *bpool, GError **error); - gboolean (*set_caps) (GstVdpBufferPool *bpool, const GstCaps *caps, gboolean *clear_bufs); - gboolean (*check_caps) (GstVdpBufferPool *bpool, const GstCaps *caps); -}; - -gboolean gst_vdp_buffer_pool_put_buffer (GstVdpBufferPool *bpool, GstVdpBuffer *buf); -GstVdpBuffer *gst_vdp_buffer_pool_get_buffer (GstVdpBufferPool * bpool, GError **error); - -void gst_vdp_buffer_pool_set_max_buffers (GstVdpBufferPool *bpool, guint max_buffers); -guint gst_vdp_buffer_pool_get_max_buffers (GstVdpBufferPool *bpool); - -void gst_vdp_buffer_pool_set_caps (GstVdpBufferPool *bpool, const GstCaps *caps); -const GstCaps *gst_vdp_buffer_pool_get_caps (GstVdpBufferPool * bpool); - -GstVdpDevice *gst_vdp_buffer_pool_get_device (GstVdpBufferPool * bpool); - -GType gst_vdp_buffer_pool_get_type (void) G_GNUC_CONST; - -G_END_DECLS - -#endif /* _GST_VDP_BUFFER_POOL_H_ */ diff --git a/sys/vdpau/gstvdp/gstvdpoutputsrcpad.c b/sys/vdpau/gstvdp/gstvdpoutputsrcpad.c deleted file mode 100644 index 26b83c57c..000000000 --- a/sys/vdpau/gstvdp/gstvdpoutputsrcpad.c +++ /dev/null @@ -1,427 +0,0 @@ -/* - * GStreamer - * Copyright (C) 2009 Carl-Anton Ingmarsson <ca.ingmarsson@gmail.com> - * - * 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., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "gstvdputils.h" -#include "gstvdpvideobuffer.h" -#include "gstvdpoutputbufferpool.h" - -#include "gstvdpoutputsrcpad.h" - -GST_DEBUG_CATEGORY_STATIC (gst_vdp_output_src_pad_debug); -#define GST_CAT_DEFAULT gst_vdp_output_src_pad_debug - -enum -{ - PROP_0, - PROP_DEVICE -}; - -typedef enum _GstVdpOutputSrcPadFormat GstVdpOutputSrcPadFormat; - -enum _GstVdpOutputSrcPadFormat -{ - GST_VDP_OUTPUT_SRC_PAD_FORMAT_RGB, - GST_VDP_OUTPUT_SRC_PAD_FORMAT_VDPAU -}; - -struct _GstVdpOutputSrcPad -{ - GstPad pad; - - GstCaps *caps; - - GstCaps *output_caps; - GstVdpOutputSrcPadFormat output_format; - VdpRGBAFormat rgba_format; - gint width, height; - - GstVdpBufferPool *bpool; - gboolean lock_caps; - - /* properties */ - GstVdpDevice *device; -}; - -struct _GstVdpOutputSrcPadClass -{ - GstPadClass pad_class; -}; - -#define DEBUG_INIT(bla) \ -GST_DEBUG_CATEGORY_INIT (gst_vdp_output_src_pad_debug, "vdpoutputsrcpad", 0, "GstVdpOutputSrcPad"); - -G_DEFINE_TYPE_WITH_CODE (GstVdpOutputSrcPad, gst_vdp_output_src_pad, - GST_TYPE_PAD, DEBUG_INIT ()); - -GstFlowReturn -gst_vdp_output_src_pad_push (GstVdpOutputSrcPad * vdp_pad, - GstVdpOutputBuffer * output_buf, GError ** error) -{ - GstPad *pad; - GstBuffer *outbuf; - - g_return_val_if_fail (GST_IS_VDP_OUTPUT_SRC_PAD (vdp_pad), GST_FLOW_ERROR); - g_return_val_if_fail (GST_IS_VDP_OUTPUT_BUFFER (output_buf), GST_FLOW_ERROR); - - pad = (GstPad *) vdp_pad; - - if (G_UNLIKELY (!GST_PAD_CAPS (pad))) - return GST_FLOW_NOT_NEGOTIATED; - - switch (vdp_pad->output_format) { - case GST_VDP_OUTPUT_SRC_PAD_FORMAT_RGB: - { - GstFlowReturn ret; - guint size; - - gst_vdp_output_buffer_calculate_size (output_buf, &size); - - vdp_pad->lock_caps = TRUE; - ret = gst_pad_alloc_buffer (pad, 0, size, GST_PAD_CAPS (vdp_pad), - &outbuf); - vdp_pad->lock_caps = FALSE; - - if (ret != GST_FLOW_OK) { - gst_buffer_unref (GST_BUFFER_CAST (output_buf)); - return ret; - } - - if (!gst_vdp_output_buffer_download (output_buf, outbuf, error)) { - gst_buffer_unref (GST_BUFFER_CAST (output_buf)); - gst_buffer_unref (outbuf); - return GST_FLOW_ERROR; - } - - gst_buffer_copy_metadata (outbuf, (const GstBuffer *) output_buf, - GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS); - gst_buffer_unref (GST_BUFFER_CAST (output_buf)); - break; - } - case GST_VDP_OUTPUT_SRC_PAD_FORMAT_VDPAU: - { - outbuf = GST_BUFFER_CAST (output_buf); - break; - } - - default: - g_assert_not_reached (); - break; - } - - gst_buffer_set_caps (outbuf, GST_PAD_CAPS (vdp_pad)); - - return gst_pad_push (pad, outbuf); -} - -static GstFlowReturn -gst_vdp_output_src_pad_create_buffer (GstVdpOutputSrcPad * vdp_pad, - GstVdpOutputBuffer ** output_buf, GError ** error) -{ - GstFlowReturn ret; - GstBuffer *neg_buf; - - /* negotiate */ - ret = gst_pad_alloc_buffer_and_set_caps (GST_PAD_CAST (vdp_pad), - GST_BUFFER_OFFSET_NONE, 0, GST_PAD_CAPS (vdp_pad), &neg_buf); - if (ret == GST_FLOW_OK) - gst_buffer_unref (neg_buf); - - *output_buf = - (GstVdpOutputBuffer *) gst_vdp_buffer_pool_get_buffer (vdp_pad->bpool, - error); - if (!*output_buf) - return GST_FLOW_ERROR; - - return GST_FLOW_OK; -} - -static GstFlowReturn -gst_vdp_output_src_pad_alloc_with_caps (GstVdpOutputSrcPad * vdp_pad, - GstCaps * caps, GstVdpOutputBuffer ** output_buf, GError ** error) -{ - GstFlowReturn ret; - - ret = gst_pad_alloc_buffer_and_set_caps ((GstPad *) vdp_pad, 0, 0, caps, - (GstBuffer **) output_buf); - if (ret != GST_FLOW_OK) - return ret; - - if (!GST_IS_VDP_OUTPUT_BUFFER (*output_buf)) - goto invalid_buf; - - return GST_FLOW_OK; - -invalid_buf: - gst_buffer_unref (GST_BUFFER (*output_buf)); - g_set_error (error, GST_STREAM_ERROR, GST_STREAM_ERROR_FAILED, - "Sink element returned buffer of wrong type"); - return GST_FLOW_ERROR; -} - -GstFlowReturn -gst_vdp_output_src_pad_alloc_buffer (GstVdpOutputSrcPad * vdp_pad, - GstVdpOutputBuffer ** output_buf, GError ** error) -{ - GstCaps *caps; - GstFlowReturn ret; - - g_return_val_if_fail (GST_IS_VDP_OUTPUT_SRC_PAD (vdp_pad), GST_FLOW_ERROR); - - caps = GST_PAD_CAPS (vdp_pad); - if (!caps) - return GST_FLOW_NOT_NEGOTIATED; - - switch (vdp_pad->output_format) { - case GST_VDP_OUTPUT_SRC_PAD_FORMAT_RGB: - { - ret = gst_vdp_output_src_pad_create_buffer (vdp_pad, output_buf, error); - if (ret != GST_FLOW_OK) - return ret; - - break; - } - - case GST_VDP_OUTPUT_SRC_PAD_FORMAT_VDPAU: - { - ret = gst_vdp_output_src_pad_alloc_with_caps (vdp_pad, caps, output_buf, - error); - if (ret != GST_FLOW_OK) - return ret; - - break; - } - - default: - g_assert_not_reached (); - break; - } - - return GST_FLOW_OK; - -} - -static gboolean -gst_vdp_output_src_pad_acceptcaps (GstPad * pad, GstCaps * caps) -{ - GstVdpOutputSrcPad *vdp_pad = GST_VDP_OUTPUT_SRC_PAD (pad); - - if (!vdp_pad->lock_caps) - return TRUE; - - return gst_caps_is_equal_fixed (caps, GST_PAD_CAPS (pad)); -} - -static gboolean -gst_vdp_output_src_pad_setcaps (GstPad * pad, GstCaps * caps) -{ - GstVdpOutputSrcPad *vdp_pad = GST_VDP_OUTPUT_SRC_PAD (pad); - const GstStructure *structure; - - structure = gst_caps_get_structure (caps, 0); - - if (!gst_structure_get_int (structure, "width", &vdp_pad->width)) - return FALSE; - if (!gst_structure_get_int (structure, "height", &vdp_pad->height)) - return FALSE; - - if (gst_structure_has_name (structure, "video/x-raw-rgb")) { - if (!gst_vdp_caps_to_rgba_format (caps, &vdp_pad->rgba_format)) - return FALSE; - - /* create buffer pool if we dont't have one */ - if (!vdp_pad->bpool) - vdp_pad->bpool = gst_vdp_output_buffer_pool_new (vdp_pad->device); - - if (vdp_pad->output_caps) - gst_caps_unref (vdp_pad->output_caps); - - vdp_pad->output_caps = gst_caps_new_simple ("video/x-vdpau-output", - "rgba-format", G_TYPE_INT, vdp_pad->rgba_format, - "width", G_TYPE_INT, vdp_pad->width, "height", G_TYPE_INT, - vdp_pad->height, NULL); - gst_vdp_buffer_pool_set_caps (vdp_pad->bpool, vdp_pad->output_caps); - - vdp_pad->output_format = GST_VDP_OUTPUT_SRC_PAD_FORMAT_RGB; - } else if (gst_structure_has_name (structure, "video/x-vdpau-output")) { - if (!gst_structure_get_int (structure, "rgba-format", - (gint *) & vdp_pad->rgba_format)) - return FALSE; - - /* don't need the buffer pool */ - if (vdp_pad->bpool) { - gst_object_unref (vdp_pad->bpool); - vdp_pad->bpool = NULL; - } - - vdp_pad->output_format = GST_VDP_OUTPUT_SRC_PAD_FORMAT_VDPAU; - } else - return FALSE; - - return TRUE; -} - -static GstCaps * -gst_vdp_output_src_pad_getcaps (GstPad * pad) -{ - GstVdpOutputSrcPad *vdp_pad = (GstVdpOutputSrcPad *) pad; - - const GstCaps *templ_caps; - - if (vdp_pad->caps) - return gst_caps_ref (vdp_pad->caps); - - else if ((templ_caps = gst_pad_get_pad_template_caps (pad))) - return gst_caps_copy (templ_caps); - - return NULL; -} - -static gboolean -gst_vdp_output_src_pad_activate_push (GstPad * pad, gboolean active) -{ - GstVdpOutputSrcPad *vdp_pad = GST_VDP_OUTPUT_SRC_PAD (pad); - - if (!active) { - if (vdp_pad->caps) - gst_caps_unref (vdp_pad->caps); - vdp_pad->caps = NULL; - - if (vdp_pad->output_caps) - gst_caps_unref (vdp_pad->output_caps); - vdp_pad->output_caps = NULL; - - if (vdp_pad->bpool) - g_object_unref (vdp_pad->bpool); - vdp_pad->bpool = NULL; - - if (vdp_pad->device) - g_object_unref (vdp_pad->device); - vdp_pad->device = NULL; - } - - return TRUE; -} - -GstVdpOutputSrcPad * -gst_vdp_output_src_pad_new (GstPadTemplate * templ, const gchar * name) -{ - return g_object_new (GST_TYPE_VDP_OUTPUT_SRC_PAD, "name", name, - "template", templ, "direction", GST_PAD_SRC, NULL); -} - -static void -gst_vdp_output_src_pad_update_caps (GstVdpOutputSrcPad * vdp_pad) -{ - GstCaps *caps; - const GstCaps *templ_caps; - - if (vdp_pad->caps) - gst_caps_unref (vdp_pad->caps); - - caps = gst_vdp_output_buffer_get_allowed_caps (vdp_pad->device); - - if ((templ_caps = gst_pad_get_pad_template_caps (GST_PAD (vdp_pad)))) { - vdp_pad->caps = gst_caps_intersect (caps, templ_caps); - gst_caps_unref (caps); - } else - vdp_pad->caps = caps; -} - -static void -gst_vdp_output_src_pad_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec) -{ - GstVdpOutputSrcPad *vdp_pad = (GstVdpOutputSrcPad *) object; - - switch (prop_id) { - case PROP_DEVICE: - g_value_set_object (value, vdp_pad->device); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_vdp_output_src_pad_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) -{ - GstVdpOutputSrcPad *vdp_pad = (GstVdpOutputSrcPad *) object; - - switch (prop_id) { - case PROP_DEVICE: - if (vdp_pad->device) - g_object_unref (vdp_pad->device); - vdp_pad->device = g_value_dup_object (value); - gst_vdp_output_src_pad_update_caps (vdp_pad); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_vdp_output_src_pad_init (GstVdpOutputSrcPad * vdp_pad) -{ - GstPad *pad = GST_PAD (vdp_pad); - - vdp_pad->caps = NULL; - vdp_pad->output_caps = NULL; - vdp_pad->bpool = NULL; - vdp_pad->device = NULL; - - vdp_pad->lock_caps = FALSE; - - gst_pad_set_getcaps_function (pad, - GST_DEBUG_FUNCPTR (gst_vdp_output_src_pad_getcaps)); - gst_pad_set_setcaps_function (pad, - GST_DEBUG_FUNCPTR (gst_vdp_output_src_pad_setcaps)); - gst_pad_set_acceptcaps_function (pad, - GST_DEBUG_FUNCPTR (gst_vdp_output_src_pad_acceptcaps)); - - gst_pad_set_activatepush_function (pad, - GST_DEBUG_FUNCPTR (gst_vdp_output_src_pad_activate_push)); -} - -static void -gst_vdp_output_src_pad_class_init (GstVdpOutputSrcPadClass * klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->get_property = gst_vdp_output_src_pad_get_property; - object_class->set_property = gst_vdp_output_src_pad_set_property; - - /** - * GstVdpVideoSrcPad:device: - * - * The #GstVdpDevice this pool is bound to. - */ - g_object_class_install_property - (object_class, - PROP_DEVICE, - g_param_spec_object ("device", - "Device", - "The GstVdpDevice the pad should use", - GST_TYPE_VDP_DEVICE, G_PARAM_READWRITE)); -} diff --git a/sys/vdpau/gstvdp/gstvdpoutputsrcpad.h b/sys/vdpau/gstvdp/gstvdpoutputsrcpad.h deleted file mode 100644 index d5ed439dd..000000000 --- a/sys/vdpau/gstvdp/gstvdpoutputsrcpad.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * GStreamer - * Copyright (C) 2009 Carl-Anton Ingmarsson <ca.ingmarsson@gmail.com> - * - * 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., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef _GST_VDP_OUTPUT_SRC_PAD_H_ -#define _GST_VDP_OUTPUT_SRC_PAD_H_ - -#include <gst/gst.h> - -#include "gstvdpdevice.h" -#include "gstvdpoutputbuffer.h" - -G_BEGIN_DECLS - -#define GST_TYPE_VDP_OUTPUT_SRC_PAD (gst_vdp_output_src_pad_get_type ()) -#define GST_VDP_OUTPUT_SRC_PAD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VDP_OUTPUT_SRC_PAD, GstVdpOutputSrcPad)) -#define GST_VDP_OUTPUT_SRC_PAD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_VDP_OUTPUT_SRC_PAD, GstVdpOutputSrcPadClass)) -#define GST_IS_VDP_OUTPUT_SRC_PAD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VDP_OUTPUT_SRC_PAD)) -#define GST_IS_VDP_OUTPUT_SRC_PAD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_VDP_OUTPUT_SRC_PAD)) -#define GST_VDP_OUTPUT_SRC_PAD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VDP_OUTPUT_SRC_PAD, GstVdpOutputSrcPadClass)) - -typedef struct _GstVdpOutputSrcPad GstVdpOutputSrcPad; -typedef struct _GstVdpOutputSrcPadClass GstVdpOutputSrcPadClass; - -GstFlowReturn gst_vdp_output_src_pad_push (GstVdpOutputSrcPad *vdp_pad, GstVdpOutputBuffer *output_buf, GError **error); -GstFlowReturn gst_vdp_output_src_pad_alloc_buffer (GstVdpOutputSrcPad *vdp_pad, GstVdpOutputBuffer **output_buf, GError **error); - -GstFlowReturn gst_vdp_output_src_pad_get_device (GstVdpOutputSrcPad *vdp_pad, GstVdpDevice **device, GError **error); - -GstVdpOutputSrcPad *gst_vdp_output_src_pad_new (GstPadTemplate *templ, const gchar *name); -GType gst_vdp_output_src_pad_get_type (void); - -G_END_DECLS - -#endif /* _GST_VDP_OUTPUT_SRC_PAD_H_ */ diff --git a/sys/vdpau/gstvdp/gstvdputils.c b/sys/vdpau/gstvdp/gstvdputils.c deleted file mode 100644 index 9e3f1d22e..000000000 --- a/sys/vdpau/gstvdp/gstvdputils.c +++ /dev/null @@ -1,138 +0,0 @@ -/* - * GStreamer - * Copyright (C) 2009 Carl-Anton Ingmarsson <ca.ingmarsson@gmail.com> - * - * 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., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "gstvdpvideobuffer.h" - -#include "gstvdputils.h" - -static void -gst_vdp_video_remove_pixel_aspect_ratio (GstStructure * structure) -{ - gint par_n, par_d; - - if (gst_structure_get_fraction (structure, "pixel-aspect-ratio", &par_n, - &par_d)) { - gint width; - - gst_structure_get_int (structure, "width", &width); - width = gst_util_uint64_scale_int (width, par_n, par_d); - gst_structure_set (structure, "width", G_TYPE_INT, width, NULL); - - gst_structure_remove_field (structure, "pixel-aspect-ratio"); - } -} - -GstCaps * -gst_vdp_video_to_output_caps (GstCaps * video_caps) -{ - GstCaps *output_caps; - gint i; - - g_return_val_if_fail (GST_IS_CAPS (video_caps), NULL); - - output_caps = gst_caps_copy (video_caps); - for (i = 0; i < gst_caps_get_size (video_caps); i++) { - - GstStructure *structure, *rgb_structure; - - structure = gst_caps_get_structure (output_caps, i); - if (!gst_structure_has_name (structure, "video/x-vdpau-video")) - goto not_video_error; - - rgb_structure = gst_structure_copy (structure); - - gst_structure_set_name (structure, "video/x-vdpau-output"); - gst_structure_remove_field (structure, "chroma-type"); - gst_vdp_video_remove_pixel_aspect_ratio (structure); - - gst_structure_set_name (rgb_structure, "video/x-raw-rgb"); - gst_structure_remove_field (rgb_structure, "chroma-type"); - gst_vdp_video_remove_pixel_aspect_ratio (rgb_structure); - gst_caps_append_structure (output_caps, rgb_structure); - } - - return output_caps; - -error: - gst_caps_unref (output_caps); - return NULL; - -not_video_error: - GST_WARNING ("The caps weren't of type \"video/x-vdpau-video\""); - goto error; -} - -GstCaps * -gst_vdp_yuv_to_video_caps (GstCaps * yuv_caps) -{ - GstCaps *video_caps; - gint i; - - g_return_val_if_fail (GST_IS_CAPS (yuv_caps), NULL); - - video_caps = gst_caps_copy (yuv_caps); - for (i = 0; i < gst_caps_get_size (video_caps); i++) { - GstStructure *structure; - guint32 fourcc; - VdpChromaType chroma_type; - - structure = gst_caps_get_structure (video_caps, i); - if (!gst_structure_has_name (structure, "video/x-raw-yuv")) - goto not_yuv_error; - - if (!gst_structure_get_fourcc (structure, "format", &fourcc)) - goto no_format_error; - - chroma_type = -1; - for (i = 0; i < G_N_ELEMENTS (formats); i++) { - if (formats[i].fourcc == fourcc) { - chroma_type = formats[i].chroma_type; - break; - } - } - - if (chroma_type == -1) - goto no_chroma_error; - - /* now we transform the caps */ - gst_structure_set_name (structure, "video/x-vdpau-video"); - gst_structure_remove_field (structure, "format"); - gst_structure_set (structure, "chroma-type", G_TYPE_INT, chroma_type, NULL); - } - - return video_caps; - -error: - gst_caps_unref (video_caps); - return NULL; - -not_yuv_error: - GST_WARNING ("The caps weren't of type \"video/x-raw-yuv\""); - goto error; - -no_format_error: - GST_WARNING ("The caps didn't have a \"fourcc\" field"); - goto error; - -no_chroma_error: - GST_WARNING ("The caps had an invalid \"fourcc\" field"); - goto error; - -} diff --git a/sys/vdpau/gstvdp/gstvdpvideobuffer.c b/sys/vdpau/gstvdp/gstvdpvideobuffer.c deleted file mode 100644 index 886333b7b..000000000 --- a/sys/vdpau/gstvdp/gstvdpvideobuffer.c +++ /dev/null @@ -1,502 +0,0 @@ -/* - * GStreamer - * Copyright (C) 2009 Carl-Anton Ingmarsson <ca.ingmarsson@gmail.com> - * - * 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., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "gstvdpvideobuffer.h" - -GST_DEBUG_CATEGORY_STATIC (gst_vdp_video_buffer_debug); -#define GST_CAT_DEFAULT gst_vdp_video_buffer_debug - -#define DEBUG_INIT(bla) \ -GST_DEBUG_CATEGORY_INIT (gst_vdp_video_buffer_debug, "vdpvideobuffer", 0, "VDPAU video buffer"); - -GstVdpVideoBuffer * -gst_vdp_video_buffer_new (GstVdpDevice * device, VdpChromaType chroma_type, - gint width, gint height, GError ** error) -{ - GstVdpVideoBuffer *buffer; - VdpStatus status; - VdpVideoSurface surface; - - g_return_val_if_fail (GST_IS_VDP_DEVICE (device), NULL); - - - status = device->vdp_video_surface_create (device->device, chroma_type, width, - height, &surface); - if (status != VDP_STATUS_OK) - goto create_error; - - buffer = - (GstVdpVideoBuffer *) gst_mini_object_new (GST_TYPE_VDP_VIDEO_BUFFER); - - buffer->device = g_object_ref (device); - buffer->surface = surface; - - return buffer; - -create_error: - g_set_error (error, GST_RESOURCE_ERROR, GST_RESOURCE_ERROR_READ, - "Couldn't create a VdpVideoSurface, error returned from vdpau was: %s", - device->vdp_get_error_string (status)); - return NULL; -} - -static GObjectClass *gst_vdp_video_buffer_parent_class; - -static void -gst_vdp_video_buffer_finalize (GstVdpVideoBuffer * buffer) -{ - GstVdpDevice *device; - VdpStatus status; - - if (gst_vdp_buffer_revive (GST_VDP_BUFFER_CAST (buffer))) - return; - - device = buffer->device; - - 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_VDP_BUFFER, - "GstVdpVideoBuffer", &info, 0); - - DEBUG_INIT (); - } - return _gst_vdp_video_buffer_type; -} - -GstCaps * -gst_vdp_video_buffer_get_caps (gboolean filter, VdpChromaType chroma_type) -{ - GstCaps *video_caps, *yuv_caps; - gint i; - - video_caps = gst_caps_new_empty (); - for (i = 0; i < G_N_ELEMENTS (chroma_types); i++) { - GstStructure *structure; - - if (filter) { - if (chroma_types[i] != chroma_type) - continue; - } - - structure = gst_structure_new ("video/x-vdpau-video", - "chroma-type", G_TYPE_INT, chroma_types[i], - "width", GST_TYPE_INT_RANGE, 1, 4096, - "height", GST_TYPE_INT_RANGE, 1, 4096, NULL); - gst_caps_append_structure (video_caps, structure); - } - - yuv_caps = gst_caps_new_empty (); - for (i = 0; i < G_N_ELEMENTS (formats); i++) { - GstStructure *structure; - - if (filter) { - if (formats[i].chroma_type != chroma_type) - continue; - } - - structure = gst_structure_new ("video/x-raw-yuv", - "format", GST_TYPE_FOURCC, formats[i].fourcc, - "width", GST_TYPE_INT_RANGE, 1, 4096, - "height", GST_TYPE_INT_RANGE, 1, 4096, NULL); - gst_caps_append_structure (yuv_caps, structure); - } - - gst_caps_append (video_caps, yuv_caps); - return video_caps; -} - -GstCaps * -gst_vdp_video_buffer_get_allowed_caps (GstVdpDevice * device) -{ - GstCaps *video_caps, *yuv_caps; - gint i; - VdpStatus status; - - video_caps = gst_caps_new_empty (); - yuv_caps = gst_caps_new_empty (); - - for (i = 0; i < G_N_ELEMENTS (chroma_types); i++) { - 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) - goto surface_query_caps_error; - - if (is_supported) { - GstCaps *format_caps; - gint j; - - format_caps = gst_caps_new_simple ("video/x-vdpau-video", - "chroma-type", G_TYPE_INT, chroma_types[i], - "width", GST_TYPE_INT_RANGE, 1, max_w, - "height", GST_TYPE_INT_RANGE, 1, max_h, NULL); - gst_caps_append (video_caps, format_caps); - - for (j = 0; j < G_N_ELEMENTS (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) - goto surface_query_ycbcr_error; - - if (is_supported) { - 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, NULL); - gst_caps_append (yuv_caps, format_caps); - } - } - } - } - -done: - gst_caps_append (video_caps, yuv_caps); - return video_caps; - -surface_query_caps_error: - GST_ERROR_OBJECT (device, - "Could not get query VDPAU video surface capabilites, " - "Error returned from vdpau was: %s", - device->vdp_get_error_string (status)); - goto done; - -surface_query_ycbcr_error: - GST_ERROR_OBJECT (device, "Could not query VDPAU YCbCr capabilites, " - "Error returned from vdpau was: %s", - device->vdp_get_error_string (status)); - goto done; -} - -gboolean -gst_vdp_video_buffer_calculate_size (guint32 fourcc, gint width, gint height, - guint * size) -{ - switch (fourcc) { - case GST_MAKE_FOURCC ('Y', 'V', '1', '2'): - { - *size = gst_video_format_get_size (GST_VIDEO_FORMAT_YV12, width, height); - break; - } - case GST_MAKE_FOURCC ('I', '4', '2', '0'): - { - *size = gst_video_format_get_size (GST_VIDEO_FORMAT_YV12, width, height); - break; - } - case GST_MAKE_FOURCC ('N', 'V', '1', '2'): - { - *size = width * height + width * height / 2; - break; - } - case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'): - { - *size = gst_video_format_get_size (GST_VIDEO_FORMAT_UYVY, width, height); - break; - } - case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'): - { - *size = gst_video_format_get_size (GST_VIDEO_FORMAT_YUY2, width, height); - break; - } - default: - return FALSE; - } - - return TRUE; -} - -gboolean -gst_vdp_video_buffer_download (GstVdpVideoBuffer * video_buf, - GstBuffer * outbuf, guint32 fourcc, gint width, gint height) -{ - - guint8 *data[3]; - guint32 stride[3]; - VdpYCbCrFormat format; - GstVdpDevice *device; - VdpVideoSurface surface; - VdpStatus status; - - g_return_val_if_fail (GST_IS_VDP_VIDEO_BUFFER (video_buf), FALSE); - g_return_val_if_fail (GST_IS_BUFFER (outbuf), FALSE); - - switch (fourcc) { - case GST_MAKE_FOURCC ('Y', 'V', '1', '2'): - { - data[0] = GST_BUFFER_DATA (outbuf) + - gst_video_format_get_component_offset (GST_VIDEO_FORMAT_YV12, - 0, width, height); - data[1] = GST_BUFFER_DATA (outbuf) + - gst_video_format_get_component_offset (GST_VIDEO_FORMAT_YV12, - 2, width, height); - data[2] = GST_BUFFER_DATA (outbuf) + - gst_video_format_get_component_offset (GST_VIDEO_FORMAT_YV12, - 1, width, height); - - stride[0] = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_YV12, - 0, width); - stride[1] = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_YV12, - 2, width); - stride[2] = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_YV12, - 1, width); - - format = VDP_YCBCR_FORMAT_YV12; - break; - } - case GST_MAKE_FOURCC ('I', '4', '2', '0'): - { - data[0] = GST_BUFFER_DATA (outbuf) + - gst_video_format_get_component_offset (GST_VIDEO_FORMAT_I420, - 0, width, height); - data[1] = GST_BUFFER_DATA (outbuf) + - gst_video_format_get_component_offset (GST_VIDEO_FORMAT_I420, - 2, width, height); - data[2] = GST_BUFFER_DATA (outbuf) + - gst_video_format_get_component_offset (GST_VIDEO_FORMAT_I420, - 1, width, height); - - stride[0] = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_I420, - 0, width); - stride[1] = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_I420, - 2, width); - stride[2] = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_I420, - 1, width); - - format = VDP_YCBCR_FORMAT_YV12; - break; - } - case GST_MAKE_FOURCC ('N', 'V', '1', '2'): - { - data[0] = GST_BUFFER_DATA (outbuf); - data[1] = GST_BUFFER_DATA (outbuf) + width * height; - - stride[0] = width; - stride[1] = width; - - format = VDP_YCBCR_FORMAT_NV12; - break; - } - case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'): - { - data[0] = GST_BUFFER_DATA (outbuf); - - stride[0] = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_UYVY, - 0, width); - - format = VDP_YCBCR_FORMAT_UYVY; - break; - } - case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'): - { - data[0] = GST_BUFFER_DATA (outbuf); - - stride[0] = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_YUY2, - 0, width); - - format = VDP_YCBCR_FORMAT_YUYV; - break; - } - default: - return FALSE; - } - - device = video_buf->device; - surface = video_buf->surface; - - GST_LOG_OBJECT (video_buf, "Entering vdp_video_surface_get_bits_ycbcr"); - status = - device->vdp_video_surface_get_bits_ycbcr (surface, - format, (void *) data, stride); - GST_LOG_OBJECT (video_buf, - "Got status %d from vdp_video_surface_get_bits_ycbcr", status); - if (G_UNLIKELY (status != VDP_STATUS_OK)) { - GST_ERROR_OBJECT (video_buf, - "Couldn't get data from vdpau, Error returned from vdpau was: %s", - device->vdp_get_error_string (status)); - return FALSE; - } - - return TRUE; -} - -gboolean -gst_vdp_video_buffer_upload (GstVdpVideoBuffer * video_buf, GstBuffer * src_buf, - guint fourcc, gint width, gint height) -{ - guint8 *data[3]; - guint32 stride[3]; - VdpYCbCrFormat format; - GstVdpDevice *device; - VdpStatus status; - - g_return_val_if_fail (GST_IS_VDP_VIDEO_BUFFER (video_buf), FALSE); - g_return_val_if_fail (GST_IS_BUFFER (src_buf), FALSE); - - switch (fourcc) { - case GST_MAKE_FOURCC ('Y', 'V', '1', '2'): - { - data[0] = GST_BUFFER_DATA (src_buf) + - gst_video_format_get_component_offset (GST_VIDEO_FORMAT_YV12, - 0, width, height); - data[1] = GST_BUFFER_DATA (src_buf) + - gst_video_format_get_component_offset (GST_VIDEO_FORMAT_YV12, - 2, width, height); - data[2] = GST_BUFFER_DATA (src_buf) + - gst_video_format_get_component_offset (GST_VIDEO_FORMAT_YV12, - 1, width, height); - - stride[0] = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_YV12, - 0, width); - stride[1] = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_YV12, - 2, width); - stride[2] = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_YV12, - 1, width); - - format = VDP_YCBCR_FORMAT_YV12; - break; - } - case GST_MAKE_FOURCC ('I', '4', '2', '0'): - { - data[0] = GST_BUFFER_DATA (src_buf) + - gst_video_format_get_component_offset (GST_VIDEO_FORMAT_I420, - 0, width, height); - data[1] = GST_BUFFER_DATA (src_buf) + - gst_video_format_get_component_offset (GST_VIDEO_FORMAT_I420, - 2, width, height); - data[2] = GST_BUFFER_DATA (src_buf) + - gst_video_format_get_component_offset (GST_VIDEO_FORMAT_I420, - 1, width, height); - - stride[0] = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_I420, - 0, width); - stride[1] = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_I420, - 2, width); - stride[2] = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_I420, - 1, width); - - format = VDP_YCBCR_FORMAT_YV12; - break; - } - case GST_MAKE_FOURCC ('N', 'V', '1', '2'): - { - data[0] = GST_BUFFER_DATA (src_buf); - data[1] = GST_BUFFER_DATA (src_buf) + width * height; - - stride[0] = width; - stride[1] = width; - - format = VDP_YCBCR_FORMAT_NV12; - break; - } - case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'): - { - data[0] = GST_BUFFER_DATA (src_buf); - - stride[0] = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_UYVY, - 0, width); - - format = VDP_YCBCR_FORMAT_UYVY; - break; - } - case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'): - { - data[0] = GST_BUFFER_DATA (src_buf); - - stride[0] = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_YUY2, - 0, width); - - format = VDP_YCBCR_FORMAT_YUYV; - break; - } - default: - return FALSE; - } - - device = video_buf->device; - status = device->vdp_video_surface_put_bits_ycbcr (video_buf->surface, format, - (void *) data, stride); - if (G_UNLIKELY (status != VDP_STATUS_OK)) { - GST_ERROR_OBJECT (video_buf, "Couldn't push YUV data to VDPAU, " - "Error returned from vdpau was: %s", - device->vdp_get_error_string (status)); - return FALSE; - } - - return TRUE; -} diff --git a/sys/vdpau/gstvdp/gstvdpvideobuffer.h b/sys/vdpau/gstvdp/gstvdpvideobuffer.h deleted file mode 100644 index 25b61f474..000000000 --- a/sys/vdpau/gstvdp/gstvdpvideobuffer.h +++ /dev/null @@ -1,109 +0,0 @@ -/* - * GStreamer - * Copyright (C) 2009 Carl-Anton Ingmarsson <ca.ingmarsson@gmail.com> - * - * 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., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef _GST_VDP_VIDEO_BUFFER_H_ -#define _GST_VDP_VIDEO_BUFFER_H_ - -#include <gst/gst.h> -#include <gst/video/video.h> - -#include "gstvdpbuffer.h" -#include "gstvdpdevice.h" - -typedef struct _GstVdpVideoBuffer GstVdpVideoBuffer; - -#define GST_TYPE_VDP_VIDEO_BUFFER (gst_vdp_video_buffer_get_type()) - -#define GST_IS_VDP_VIDEO_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VDP_VIDEO_BUFFER)) -#define GST_VDP_VIDEO_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VDP_VIDEO_BUFFER, GstVdpVideoBuffer)) - -struct _GstVdpVideoBuffer { - GstVdpBuffer vdp_buffer; - - GstVdpDevice *device; - VdpVideoSurface surface; -}; - -typedef struct -{ - VdpChromaType chroma_type; - VdpYCbCrFormat format; - guint32 fourcc; -} GstVdpVideoBufferFormats; - -static const VdpChromaType chroma_types[] = - { VDP_CHROMA_TYPE_420, VDP_CHROMA_TYPE_422, VDP_CHROMA_TYPE_444 }; - -static const GstVdpVideoBufferFormats formats[] = { - { - VDP_CHROMA_TYPE_420, - VDP_YCBCR_FORMAT_YV12, - GST_MAKE_FOURCC ('I', '4', '2', '0') - }, - { - VDP_CHROMA_TYPE_420, - VDP_YCBCR_FORMAT_YV12, - GST_MAKE_FOURCC ('Y', 'V', '1', '2') - }, - { - 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', '2') - }, -}; - -GType gst_vdp_video_buffer_get_type (void); - -GstVdpVideoBuffer *gst_vdp_video_buffer_new (GstVdpDevice * device, VdpChromaType chroma_type, gint width, gint height, GError **error); - -GstCaps *gst_vdp_video_buffer_get_caps (gboolean filter, VdpChromaType chroma_type); -GstCaps *gst_vdp_video_buffer_get_allowed_caps (GstVdpDevice * device); - -gboolean gst_vdp_video_buffer_calculate_size (guint32 fourcc, gint width, gint height, guint *size); -gboolean gst_vdp_video_buffer_download (GstVdpVideoBuffer *inbuf, GstBuffer *outbuf, guint32 fourcc, gint width, gint height); -gboolean gst_vdp_video_buffer_upload (GstVdpVideoBuffer *video_buf, GstBuffer *src_buf, guint fourcc, gint width, gint height); - -#define GST_VDP_VIDEO_CAPS \ - "video/x-vdpau-video, " \ - "chroma-type = (int)[0,2], " \ - "width = (int)[1,4096], " \ - "height = (int)[1,4096]" - -#endif diff --git a/sys/vdpau/gstvdp/gstvdpvideobufferpool.c b/sys/vdpau/gstvdp/gstvdpvideobufferpool.c deleted file mode 100644 index f9e4d72da..000000000 --- a/sys/vdpau/gstvdp/gstvdpvideobufferpool.c +++ /dev/null @@ -1,148 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ -/* - * gst-plugins-bad - * Copyright (C) Carl-Anton Ingmarsson 2010 <ca.ingmarsson@gmail.com> - * - * 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., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "gstvdpdevice.h" -#include "gstvdpvideobuffer.h" - -#include "gstvdpvideobufferpool.h" - - -struct _GstVdpVideoBufferPool -{ - GstVdpBufferPool buffer_pool; - - VdpChromaType chroma_type; - guint width, height; -}; - -G_DEFINE_TYPE (GstVdpVideoBufferPool, gst_vdp_video_buffer_pool, - GST_TYPE_VDP_BUFFER_POOL); - -GstVdpBufferPool * -gst_vdp_video_buffer_pool_new (GstVdpDevice * device) -{ - g_return_val_if_fail (GST_IS_VDP_DEVICE (device), NULL); - - return g_object_new (GST_TYPE_VDP_VIDEO_BUFFER_POOL, "device", device, NULL); -} - -static gboolean -parse_caps (const GstCaps * caps, VdpChromaType * chroma_type, gint * width, - gint * height) -{ - GstStructure *structure; - - structure = gst_caps_get_structure (caps, 0); - - if (!gst_structure_get_int (structure, "chroma-type", (gint *) chroma_type)) - return FALSE; - if (!gst_structure_get_int (structure, "width", width)) - return FALSE; - if (!gst_structure_get_int (structure, "height", height)) - return FALSE; - - return TRUE; -} - -static gboolean -gst_vdp_video_buffer_pool_check_caps (GstVdpBufferPool * bpool, - const GstCaps * caps) -{ - GstVdpVideoBufferPool *vpool = GST_VDP_VIDEO_BUFFER_POOL (bpool); - - VdpChromaType chroma_type; - gint width, height; - - if (!parse_caps (caps, &chroma_type, &width, &height)) - return FALSE; - - if (chroma_type != vpool->chroma_type || width != vpool->width || - height != vpool->height) - return FALSE; - - return TRUE; -} - -static gboolean -gst_vdp_video_buffer_pool_set_caps (GstVdpBufferPool * bpool, - const GstCaps * caps, gboolean * clear_bufs) -{ - GstVdpVideoBufferPool *vpool = GST_VDP_VIDEO_BUFFER_POOL (bpool); - - VdpChromaType chroma_type; - gint width, height; - - if (!parse_caps (caps, &chroma_type, &width, &height)) - return FALSE; - - if (chroma_type != vpool->chroma_type || width != vpool->width || - height != vpool->height) - *clear_bufs = TRUE; - else - *clear_bufs = FALSE; - - vpool->chroma_type = chroma_type; - vpool->width = width; - vpool->height = height; - - return TRUE; -} - -static GstVdpBuffer * -gst_vdp_video_buffer_pool_alloc_buffer (GstVdpBufferPool * bpool, - GError ** error) -{ - GstVdpVideoBufferPool *vpool = GST_VDP_VIDEO_BUFFER_POOL (bpool); - GstVdpDevice *device; - - device = gst_vdp_buffer_pool_get_device (bpool); - return GST_VDP_BUFFER_CAST (gst_vdp_video_buffer_new (device, - vpool->chroma_type, vpool->width, vpool->height, error)); -} - -static void -gst_vdp_video_buffer_pool_finalize (GObject * object) -{ - /* TODO: Add deinitalization code here */ - - G_OBJECT_CLASS (gst_vdp_video_buffer_pool_parent_class)->finalize (object); -} - -static void -gst_vdp_video_buffer_pool_init (GstVdpVideoBufferPool * vpool) -{ - vpool->chroma_type = -1; - vpool->width = 0; - vpool->height = 0; -} - -static void -gst_vdp_video_buffer_pool_class_init (GstVdpVideoBufferPoolClass * klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - GstVdpBufferPoolClass *buffer_pool_class = GST_VDP_BUFFER_POOL_CLASS (klass); - - buffer_pool_class->alloc_buffer = gst_vdp_video_buffer_pool_alloc_buffer; - buffer_pool_class->set_caps = gst_vdp_video_buffer_pool_set_caps; - buffer_pool_class->check_caps = gst_vdp_video_buffer_pool_check_caps; - - object_class->finalize = gst_vdp_video_buffer_pool_finalize; -} diff --git a/sys/vdpau/gstvdp/gstvdpvideobufferpool.h b/sys/vdpau/gstvdp/gstvdpvideobufferpool.h deleted file mode 100644 index 3db0acad5..000000000 --- a/sys/vdpau/gstvdp/gstvdpvideobufferpool.h +++ /dev/null @@ -1,52 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ -/* - * gst-plugins-bad - * Copyright (C) Carl-Anton Ingmarsson 2010 <ca.ingmarsson@gmail.com> - * - * 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., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef _GST_VDP_VIDEO_BUFFERPOOL_H_ -#define _GST_VDP_VIDEO_BUFFERPOOL_H_ - -#include <gst/gst.h> - -#include "gstvdpbufferpool.h" - -G_BEGIN_DECLS - -#define GST_TYPE_VDP_VIDEO_BUFFER_POOL (gst_vdp_video_buffer_pool_get_type ()) -#define GST_VDP_VIDEO_BUFFER_POOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VDP_VIDEO_BUFFER_POOL, GstVdpVideoBufferPool)) -#define GST_VDP_VIDEO_BUFFER_POOL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_VDP_VIDEO_BUFFER_POOL, GstVdpVideoBufferPoolClass)) -#define GST_IS_VDP_VIDEO_BUFFER_POOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VDP_VIDEO_BUFFER_POOL)) -#define GST_IS_VDP_VIDEO_BUFFER_POOL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_VDP_VIDEO_BUFFER_POOL)) -#define GST_VDP_VIDEO_BUFFER_POOL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VDP_VIDEO_BUFFER_POOL, GstVdpVideoBufferPoolClass)) - -typedef struct _GstVdpVideoBufferPool GstVdpVideoBufferPool; -typedef struct _GstVdpVideoBufferPoolClass GstVdpVideoBufferPoolClass; - -struct _GstVdpVideoBufferPoolClass -{ - GstVdpBufferPoolClass buffer_pool_class; -}; - -GstVdpBufferPool *gst_vdp_video_buffer_pool_new (GstVdpDevice *device); - -GType gst_vdp_video_buffer_pool_get_type (void) G_GNUC_CONST; - -G_END_DECLS - -#endif /* _GST_VDP_VIDEO_BUFFER_POOL_H_ */ diff --git a/sys/vdpau/gstvdp/gstvdpvideosrcpad.c b/sys/vdpau/gstvdp/gstvdpvideosrcpad.c deleted file mode 100644 index f044599da..000000000 --- a/sys/vdpau/gstvdp/gstvdpvideosrcpad.c +++ /dev/null @@ -1,328 +0,0 @@ -/* - * GStreamer - * Copyright (C) 2009 Carl-Anton Ingmarsson <ca.ingmarsson@gmail.com> - * - * 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., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "gstvdpvideobuffer.h" -#include "gstvdpvideobufferpool.h" -#include "gstvdputils.h" - -#include "gstvdpvideosrcpad.h" - -GST_DEBUG_CATEGORY_STATIC (gst_vdp_video_src_pad_debug); -#define GST_CAT_DEFAULT gst_vdp_video_src_pad_debug - -enum -{ - PROP_0, - PROP_DEVICE -}; - -struct _GstVdpVideoSrcPad -{ - GstPad pad; - - GstVdpBufferPool *bpool; - GstCaps *caps; - - gboolean yuv_output; - gint width, height; - guint32 fourcc; - - /* properties */ - GstVdpDevice *device; -}; - -struct _GstVdpVideoSrcPadClass -{ - GstPadClass pad_class; -}; - -#define DEBUG_INIT(bla) \ -GST_DEBUG_CATEGORY_INIT (gst_vdp_video_src_pad_debug, "vdpvideosrcpad", 0, "GstVdpVideoSrcPad"); - -G_DEFINE_TYPE_WITH_CODE (GstVdpVideoSrcPad, gst_vdp_video_src_pad, GST_TYPE_PAD, - DEBUG_INIT ()); - -GstVdpVideoSrcPad * -gst_vdp_video_src_pad_new (GstPadTemplate * templ, const gchar * name) -{ - g_return_val_if_fail (GST_IS_PAD_TEMPLATE (templ), NULL); - g_return_val_if_fail ((templ->direction == GST_PAD_SRC), NULL); - - return g_object_new (GST_TYPE_VDP_VIDEO_SRC_PAD, - "name", name, "direction", templ->direction, "template", templ, NULL); -} - -GstFlowReturn -gst_vdp_video_src_pad_push (GstVdpVideoSrcPad * vdp_pad, - GstVdpVideoBuffer * video_buf) -{ - GstPad *pad; - GstBuffer *out_buf; - - g_return_val_if_fail (GST_IS_VDP_VIDEO_SRC_PAD (vdp_pad), GST_FLOW_ERROR); - g_return_val_if_fail (GST_IS_VDP_VIDEO_BUFFER (video_buf), GST_FLOW_ERROR); - - pad = (GstPad *) vdp_pad; - - if (G_UNLIKELY (!GST_PAD_CAPS (pad))) - return GST_FLOW_NOT_NEGOTIATED; - - if (vdp_pad->yuv_output) { - guint size; - GstFlowReturn ret; - GstCaps *caps; - - if (!gst_vdp_video_buffer_calculate_size (vdp_pad->fourcc, vdp_pad->width, - vdp_pad->height, &size)) { - GST_ERROR_OBJECT (vdp_pad, "Couldn't calculate buffer size for caps"); - gst_buffer_unref (GST_BUFFER_CAST (video_buf)); - return GST_FLOW_ERROR; - } - - caps = GST_PAD_CAPS (pad); - ret = gst_pad_alloc_buffer (pad, - GST_BUFFER_OFFSET_NONE, size, caps, &out_buf); - if (ret != GST_FLOW_OK) { - gst_buffer_unref (GST_BUFFER_CAST (video_buf)); - return ret; - } - - if (!gst_caps_is_equal_fixed (caps, GST_BUFFER_CAPS (out_buf))) { - GST_ERROR_OBJECT (vdp_pad, - "Sink element allocated buffer with different caps"); - gst_buffer_unref (GST_BUFFER_CAST (video_buf)); - gst_buffer_unref (out_buf); - return GST_FLOW_ERROR; - } - - if (!gst_vdp_video_buffer_download (video_buf, out_buf, vdp_pad->fourcc, - vdp_pad->width, vdp_pad->height)) { - GST_ERROR_OBJECT (vdp_pad, - "Couldn't convert from GstVdpVideoBuffer to the requested format"); - gst_buffer_unref (GST_BUFFER_CAST (video_buf)); - gst_buffer_unref (out_buf); - return GST_FLOW_ERROR; - } - - gst_buffer_copy_metadata (out_buf, (const GstBuffer *) video_buf, - GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS); - gst_buffer_unref (GST_BUFFER_CAST (video_buf)); - } else - out_buf = GST_BUFFER_CAST (video_buf); - - /* FIXME: can't use gst_buffer_set_caps since we may have additional - * references to the bufffer. We can't either use - * gst_buffer_make_metadata_writable since that creates a regular buffer and - * not a GstVdpVideoBuffer */ - gst_caps_replace (&(GST_BUFFER_CAPS (out_buf)), GST_PAD_CAPS (vdp_pad)); - - return gst_pad_push (pad, out_buf); -} - -GstFlowReturn -gst_vdp_video_src_pad_alloc_buffer (GstVdpVideoSrcPad * vdp_pad, - GstVdpVideoBuffer ** video_buf, GError ** error) -{ - GstCaps *caps; - - g_return_val_if_fail (GST_IS_VDP_VIDEO_SRC_PAD (vdp_pad), GST_FLOW_ERROR); - - caps = GST_PAD_CAPS (vdp_pad); - if (!caps) - return GST_FLOW_NOT_NEGOTIATED; - - *video_buf = - (GstVdpVideoBuffer *) gst_vdp_buffer_pool_get_buffer (vdp_pad->bpool, - error); - if (!*video_buf) - return GST_FLOW_ERROR; - - return GST_FLOW_OK; -} - -static gboolean -gst_vdp_video_src_pad_setcaps (GstPad * pad, GstCaps * caps) -{ - GstVdpVideoSrcPad *vdp_pad = GST_VDP_VIDEO_SRC_PAD (pad); - const GstStructure *structure; - - GstCaps *video_caps; - - structure = gst_caps_get_structure (caps, 0); - if (gst_structure_has_name (structure, "video/x-raw-yuv")) { - if (!gst_structure_get_int (structure, "width", &vdp_pad->width)) - return FALSE; - if (!gst_structure_get_int (structure, "height", &vdp_pad->height)) - return FALSE; - if (!gst_structure_get_fourcc (structure, "format", &vdp_pad->fourcc)) - return FALSE; - - video_caps = gst_vdp_yuv_to_video_caps (caps); - vdp_pad->yuv_output = TRUE; - } else if (gst_structure_has_name (structure, "video/x-vdpau-video")) { - if (!gst_structure_get_int (structure, "width", &vdp_pad->width)) - return FALSE; - if (!gst_structure_get_int (structure, "height", &vdp_pad->height)) - return FALSE; - - video_caps = gst_caps_ref (caps); - vdp_pad->yuv_output = FALSE; - } else - return FALSE; - - gst_vdp_buffer_pool_set_caps (vdp_pad->bpool, video_caps); - gst_caps_unref (video_caps); - - return TRUE; -} - -static GstCaps * -gst_vdp_video_src_pad_getcaps (GstPad * pad) -{ - GstVdpVideoSrcPad *vdp_pad = (GstVdpVideoSrcPad *) pad; - - const GstCaps *templ_caps; - - if (vdp_pad->caps) - return gst_caps_ref (vdp_pad->caps); - - else if ((templ_caps = gst_pad_get_pad_template_caps (pad))) - return gst_caps_copy (templ_caps); - - return NULL; -} - -static gboolean -gst_vdp_video_src_pad_activate_push (GstPad * pad, gboolean active) -{ - GstVdpVideoSrcPad *vdp_pad = (GstVdpVideoSrcPad *) pad; - - if (!active) { - if (vdp_pad->caps) - gst_caps_unref (vdp_pad->caps); - vdp_pad->caps = NULL; - - if (vdp_pad->device) - gst_object_unref (vdp_pad->device); - vdp_pad->device = NULL; - } - - return TRUE; -} - -static void -gst_vdp_video_src_pad_set_device (GstVdpVideoSrcPad * vdp_pad, - GstVdpDevice * device) -{ - GstCaps *caps; - const GstCaps *templ_caps; - - if (vdp_pad->bpool) - g_object_unref (vdp_pad->bpool); - if (vdp_pad->device) - g_object_unref (vdp_pad->device); - - vdp_pad->device = device; - vdp_pad->bpool = gst_vdp_video_buffer_pool_new (device); - - /* update caps */ - if (vdp_pad->caps) - gst_caps_unref (vdp_pad->caps); - - caps = gst_vdp_video_buffer_get_allowed_caps (device); - - if ((templ_caps = gst_pad_get_pad_template_caps (GST_PAD (vdp_pad)))) { - vdp_pad->caps = gst_caps_intersect (caps, templ_caps); - gst_caps_unref (caps); - } else - vdp_pad->caps = caps; -} - -static void -gst_vdp_video_src_pad_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec) -{ - GstVdpVideoSrcPad *vdp_pad = (GstVdpVideoSrcPad *) object; - - switch (prop_id) { - case PROP_DEVICE: - g_value_set_object (value, vdp_pad->device); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_vdp_video_src_pad_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) -{ - GstVdpVideoSrcPad *vdp_pad = (GstVdpVideoSrcPad *) object; - - switch (prop_id) { - case PROP_DEVICE: - gst_vdp_video_src_pad_set_device (vdp_pad, g_value_dup_object (value)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_vdp_video_src_pad_init (GstVdpVideoSrcPad * vdp_pad) -{ - GstPad *pad = GST_PAD (vdp_pad); - - vdp_pad->device = NULL; - vdp_pad->caps = NULL; - - gst_pad_set_getcaps_function (pad, - GST_DEBUG_FUNCPTR (gst_vdp_video_src_pad_getcaps)); - gst_pad_set_setcaps_function (pad, - GST_DEBUG_FUNCPTR (gst_vdp_video_src_pad_setcaps)); - gst_pad_set_activatepush_function (pad, - GST_DEBUG_FUNCPTR (gst_vdp_video_src_pad_activate_push)); -} - -static void -gst_vdp_video_src_pad_class_init (GstVdpVideoSrcPadClass * klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->get_property = gst_vdp_video_src_pad_get_property; - object_class->set_property = gst_vdp_video_src_pad_set_property; - - /** - * GstVdpVideoSrcPad:device: - * - * The #GstVdpDevice this pool is bound to. - */ - g_object_class_install_property - (object_class, - PROP_DEVICE, - g_param_spec_object ("device", - "Device", - "The GstVdpDevice the pad should use", - GST_TYPE_VDP_DEVICE, G_PARAM_READWRITE)); -} diff --git a/sys/vdpau/gstvdp/gstvdpvideosrcpad.h b/sys/vdpau/gstvdp/gstvdpvideosrcpad.h deleted file mode 100644 index 2a243b14d..000000000 --- a/sys/vdpau/gstvdp/gstvdpvideosrcpad.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * GStreamer - * Copyright (C) 2009 Carl-Anton Ingmarsson <ca.ingmarsson@gmail.com> - * - * 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., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef _GST_VDP_VIDEO_SRC_PAD_H_ -#define _GST_VDP_VIDEO_SRC_PAD_H_ - -#include <gst/gst.h> - -#include "gstvdpdevice.h" -#include "gstvdpvideobuffer.h" - -G_BEGIN_DECLS - -#define GST_TYPE_VDP_VIDEO_SRC_PAD (gst_vdp_video_src_pad_get_type ()) -#define GST_VDP_VIDEO_SRC_PAD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VDP_VIDEO_SRC_PAD, GstVdpVideoSrcPad)) -#define GST_VDP_VIDEO_SRC_PAD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_VDP_VIDEO_SRC_PAD, GstVdpVideoSrcPadClass)) -#define GST_IS_VDP_VIDEO_SRC_PAD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VDP_VIDEO_SRC_PAD)) -#define GST_IS_VDP_VIDEO_SRC_PAD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_VDP_VIDEO_SRC_PAD)) -#define GST_VDP_VIDEO_SRC_PAD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VDP_VIDEO_SRC_PAD, GstVdpVideoSrcPadClass)) - -typedef struct _GstVdpVideoSrcPad GstVdpVideoSrcPad; -typedef struct _GstVdpVideoSrcPadClass GstVdpVideoSrcPadClass; - -GstFlowReturn gst_vdp_video_src_pad_push (GstVdpVideoSrcPad *vdp_pad, GstVdpVideoBuffer *video_buf); -GstFlowReturn gst_vdp_video_src_pad_alloc_buffer (GstVdpVideoSrcPad *vdp_pad, GstVdpVideoBuffer **video_buf, GError ** error); - -GstCaps *gst_vdp_video_src_pad_get_template_caps (); - -GstVdpVideoSrcPad * gst_vdp_video_src_pad_new (GstPadTemplate * templ, const gchar * name); - -GType gst_vdp_video_src_pad_get_type (void); - -G_END_DECLS - -#endif /* _GST_VDP_VIDEO_SRC_PAD_H_ */ diff --git a/sys/vdpau/gstvdpau.c b/sys/vdpau/gstvdpau.c index 082bdf8ad..64fd4a2ff 100644 --- a/sys/vdpau/gstvdpau.c +++ b/sys/vdpau/gstvdpau.c @@ -5,10 +5,13 @@ #include <gst/gst.h> -#include "gstvdp/gstvdp.h" +#include "gstvdpdevice.h" +#include "gstvdpvideomemory.h" +#include "gstvdpoutputbuffer.h" +#include "gstvdpdecoder.h" #include "mpeg/gstvdpmpegdec.h" -#include "h264/gstvdph264dec.h" +/* #include "h264/gstvdph264dec.h" */ #include "mpeg4/gstvdpmpeg4dec.h" #include "gstvdpvideopostprocess.h" #include "gstvdpsink.h" @@ -16,22 +19,27 @@ static gboolean vdpau_init (GstPlugin * vdpau_plugin) { - gst_vdp_init (); + gboolean ret; + + /* do this so debug categories get created */ + gst_vdp_device_get_type (); + gst_vdp_decoder_get_type (); + gst_vdp_video_memory_init (); /* Before giving these elements a rank again, make sure they pass at * least the generic/states test when there's no device available */ - gst_element_register (vdpau_plugin, "vdpaumpegdec", + ret = gst_element_register (vdpau_plugin, "vdpaumpegdec", GST_RANK_NONE, GST_TYPE_VDP_MPEG_DEC); - gst_element_register (vdpau_plugin, "vdpauh264dec", - GST_RANK_NONE, GST_TYPE_VDP_H264_DEC); - gst_element_register (vdpau_plugin, "vdpaumpeg4dec", - GST_RANK_NONE, GST_TYPE_VDP_MPEG4_DEC); - gst_element_register (vdpau_plugin, "vdpauvideopostprocess", - GST_RANK_NONE, GST_TYPE_VDP_VIDEO_POST_PROCESS); - gst_element_register (vdpau_plugin, "vdpausink", - GST_RANK_NONE, GST_TYPE_VDP_SINK); - - return TRUE; + /* ret &= gst_element_register (vdpau_plugin, "vdpauh264dec", */ + /* GST_RANK_NONE, GST_TYPE_VDP_H264_DEC); */ + /* gst_element_register (vdpau_plugin, "vdpaumpeg4dec", */ + /* GST_RANK_NONE, GST_TYPE_VDP_MPEG4_DEC); */ + /* gst_element_register (vdpau_plugin, "vdpauvideopostprocess", */ + /* GST_RANK_NONE, GST_TYPE_VDP_VIDEO_POST_PROCESS); */ + /* gst_element_register (vdpau_plugin, "vdpausink", */ + /* GST_RANK_NONE, GST_TYPE_VDP_SINK); */ + + return ret; } GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, diff --git a/sys/vdpau/gstvdp/gstvdpdecoder.c b/sys/vdpau/gstvdpdecoder.c index 2ba528d83..264cee1ac 100644 --- a/sys/vdpau/gstvdp/gstvdpdecoder.c +++ b/sys/vdpau/gstvdpdecoder.c @@ -22,19 +22,19 @@ #include "config.h" #endif -#include "gstvdpvideosrcpad.h" - #include "gstvdpdecoder.h" +#include "gstvdpvideomemory.h" +#include "gstvdpvideobufferpool.h" GST_DEBUG_CATEGORY_STATIC (gst_vdp_decoder_debug); #define GST_CAT_DEFAULT gst_vdp_decoder_debug -#define DEBUG_INIT(bla) \ +#define DEBUG_INIT \ GST_DEBUG_CATEGORY_INIT (gst_vdp_decoder_debug, "vdpdecoder", 0, \ "VDPAU decoder base class"); - -GST_BOILERPLATE_FULL (GstVdpDecoder, gst_vdp_decoder, GstBaseVideoDecoder, - GST_TYPE_BASE_VIDEO_DECODER, DEBUG_INIT); +#define gst_vdp_decoder_parent_class parent_class +G_DEFINE_TYPE_WITH_CODE (GstVdpDecoder, gst_vdp_decoder, GST_TYPE_VIDEO_DECODER, + DEBUG_INIT); enum { @@ -42,35 +42,6 @@ enum PROP_DISPLAY }; -static GstFlowReturn -gst_vdp_decoder_shape_output (GstBaseVideoDecoder * base_video_decoder, - GstBuffer * buf) -{ - GstVdpVideoSrcPad *vdp_pad; - - vdp_pad = - (GstVdpVideoSrcPad *) GST_BASE_VIDEO_DECODER_SRC_PAD (base_video_decoder); - - return gst_vdp_video_src_pad_push (vdp_pad, GST_VDP_VIDEO_BUFFER (buf)); -} - -static GstPad * -gst_vdp_decoder_create_srcpad (GstBaseVideoDecoder * base_video_decoder, - GstBaseVideoDecoderClass * base_video_decoder_class) -{ - GstPadTemplate *pad_template; - GstVdpVideoSrcPad *vdp_pad; - - pad_template = gst_element_class_get_pad_template - (GST_ELEMENT_CLASS (base_video_decoder_class), - GST_BASE_VIDEO_DECODER_SRC_NAME); - - vdp_pad = gst_vdp_video_src_pad_new (pad_template, - GST_BASE_VIDEO_DECODER_SRC_NAME); - - return GST_PAD (vdp_pad); -} - void gst_vdp_decoder_post_error (GstVdpDecoder * decoder, GError * error) { @@ -84,67 +55,78 @@ gst_vdp_decoder_post_error (GstVdpDecoder * decoder, GError * error) g_error_free (error); } -static GstFlowReturn -gst_vdp_decoder_alloc_buffer (GstVdpDecoder * vdp_decoder, - GstVdpVideoBuffer ** video_buf) -{ - GstVdpVideoSrcPad *vdp_pad; - - GstFlowReturn ret; - GError *err = NULL; - - vdp_pad = (GstVdpVideoSrcPad *) GST_BASE_VIDEO_DECODER_SRC_PAD (vdp_decoder); - - ret = gst_vdp_video_src_pad_alloc_buffer (vdp_pad, video_buf, &err); - if (ret == GST_FLOW_ERROR) - gst_vdp_decoder_post_error (vdp_decoder, err); - - return ret; -} GstFlowReturn gst_vdp_decoder_render (GstVdpDecoder * vdp_decoder, VdpPictureInfo * info, - guint n_bufs, VdpBitstreamBuffer * bufs, GstVdpVideoBuffer ** video_buf) + guint n_bufs, VdpBitstreamBuffer * bufs, GstVideoCodecFrame * frame) { GstFlowReturn ret; - GstVdpDevice *device; - VdpVideoSurface surface; VdpStatus status; - ret = gst_vdp_decoder_alloc_buffer (vdp_decoder, video_buf); - if (ret != GST_FLOW_OK) - return ret; + GstVdpVideoMemory *vmem; + GstClockTime before, after; - device = (*video_buf)->device; - surface = (*video_buf)->surface; + GST_DEBUG_OBJECT (vdp_decoder, "n_bufs:%d, frame:%d", n_bufs, + frame->system_frame_number); - status = device->vdp_decoder_render (vdp_decoder->decoder, surface, - info, n_bufs, bufs); + ret = + gst_video_decoder_allocate_output_frame (GST_VIDEO_DECODER (vdp_decoder), + frame); + if (ret != GST_FLOW_OK) + goto fail_alloc; + + vmem = (GstVdpVideoMemory *) gst_buffer_get_memory (frame->output_buffer, 0); + if (!vmem + || !gst_memory_is_type ((GstMemory *) vmem, + GST_VDP_VIDEO_MEMORY_ALLOCATOR)) + goto no_mem; + + GST_DEBUG_OBJECT (vdp_decoder, "Calling VdpDecoderRender()"); + before = gst_util_get_timestamp (); + status = + vdp_decoder->device->vdp_decoder_render (vdp_decoder->decoder, + vmem->surface, info, n_bufs, bufs); + after = gst_util_get_timestamp (); if (status != VDP_STATUS_OK) goto decode_error; + GST_DEBUG_OBJECT (vdp_decoder, "VdpDecoderRender() took %" GST_TIME_FORMAT, + GST_TIME_ARGS (after - before)); + return GST_FLOW_OK; decode_error: GST_ELEMENT_ERROR (vdp_decoder, RESOURCE, READ, ("Could not decode"), ("Error returned from vdpau was: %s", - device->vdp_get_error_string (status))); + vdp_decoder->device->vdp_get_error_string (status))); - gst_buffer_unref (GST_BUFFER_CAST (*video_buf)); + gst_video_decoder_drop_frame (GST_VIDEO_DECODER (vdp_decoder), frame); return GST_FLOW_ERROR; + +fail_alloc: + { + GST_WARNING_OBJECT (vdp_decoder, "Failed to get an output frame"); + return ret; + } + +no_mem: + { + GST_ERROR_OBJECT (vdp_decoder, "Didn't get VdpVideoSurface backed buffer"); + return GST_FLOW_ERROR; + } } GstFlowReturn gst_vdp_decoder_init_decoder (GstVdpDecoder * vdp_decoder, - VdpDecoderProfile profile, guint32 max_references) + VdpDecoderProfile profile, guint32 max_references, + GstVideoCodecState * output_state) { GstVdpDevice *device; VdpStatus status; - GstVideoState state; device = vdp_decoder->device; @@ -154,15 +136,14 @@ gst_vdp_decoder_init_decoder (GstVdpDecoder * vdp_decoder, goto destroy_decoder_error; } - if (!gst_base_video_decoder_set_src_caps (GST_BASE_VIDEO_DECODER - (vdp_decoder))) - return GST_FLOW_NOT_NEGOTIATED; - - state = - gst_base_video_decoder_get_state (GST_BASE_VIDEO_DECODER (vdp_decoder)); + GST_DEBUG_OBJECT (vdp_decoder, + "device:%p, profile:%d, width:%d, height:%d, max_references:%d", + device->device, profile, output_state->info.width, + output_state->info.height, max_references); status = device->vdp_decoder_create (device->device, profile, - state.width, state.height, max_references, &vdp_decoder->decoder); + output_state->info.width, output_state->info.height, max_references, + &vdp_decoder->decoder); if (status != VDP_STATUS_OK) goto create_decoder_error; @@ -186,22 +167,74 @@ create_decoder_error: } static gboolean -gst_vdp_decoder_start (GstBaseVideoDecoder * base_video_decoder) +gst_vdp_decoder_decide_allocation (GstVideoDecoder * video_decoder, + GstQuery * query) +{ + GstVdpDecoder *vdp_decoder = GST_VDP_DECODER (video_decoder); + GstCaps *outcaps; + GstBufferPool *pool = NULL; + guint size, min = 0, max = 0; + GstStructure *config; + GstVideoInfo vinfo; + gboolean update_pool; + + gst_query_parse_allocation (query, &outcaps, NULL); + gst_video_info_init (&vinfo); + gst_video_info_from_caps (&vinfo, outcaps); + + if (gst_query_get_n_allocation_pools (query) > 0) { + gst_query_parse_nth_allocation_pool (query, 0, &pool, &size, &min, &max); + size = MAX (size, vinfo.size); + update_pool = TRUE; + } else { + pool = NULL; + size = vinfo.size; + min = max = 0; + + update_pool = FALSE; + } + + if (pool == NULL + || !gst_buffer_pool_has_option (pool, + GST_BUFFER_POOL_OPTION_VDP_VIDEO_META)) { + /* no pool, we can make our own */ + GST_DEBUG_OBJECT (video_decoder, + "no pool or doesn't support GstVdpVideoMeta, making new pool"); + pool = gst_vdp_video_buffer_pool_new (vdp_decoder->device); + } + + /* now configure */ + config = gst_buffer_pool_get_config (pool); + gst_buffer_pool_config_set_params (config, outcaps, size, min, max); + gst_buffer_pool_config_add_option (config, + GST_BUFFER_POOL_OPTION_VDP_VIDEO_META); + gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META); + gst_buffer_pool_set_config (pool, config); + + if (update_pool) + gst_query_set_nth_allocation_pool (query, 0, pool, size, min, max); + else + gst_query_add_allocation_pool (query, pool, size, min, max); + + if (pool) + gst_object_unref (pool); + + return TRUE; + +} + +static gboolean +gst_vdp_decoder_start (GstVideoDecoder * video_decoder) { - GstVdpDecoder *vdp_decoder = GST_VDP_DECODER (base_video_decoder); + GstVdpDecoder *vdp_decoder = GST_VDP_DECODER (video_decoder); + GError *err = NULL; - GError *err; - GstVdpVideoSrcPad *vdp_pad; + GST_DEBUG_OBJECT (video_decoder, "Starting"); - err = NULL; vdp_decoder->device = gst_vdp_get_device (vdp_decoder->display, &err); if (G_UNLIKELY (!vdp_decoder->device)) goto device_error; - vdp_pad = - (GstVdpVideoSrcPad *) GST_BASE_VIDEO_DECODER_SRC_PAD (base_video_decoder); - g_object_set (G_OBJECT (vdp_pad), "device", vdp_decoder->device, NULL); - vdp_decoder->decoder = VDP_INVALID_HANDLE; return TRUE; @@ -212,9 +245,9 @@ device_error: } static gboolean -gst_vdp_decoder_stop (GstBaseVideoDecoder * base_video_decoder) +gst_vdp_decoder_stop (GstVideoDecoder * video_decoder) { - GstVdpDecoder *vdp_decoder = GST_VDP_DECODER (base_video_decoder); + GstVdpDecoder *vdp_decoder = GST_VDP_DECODER (video_decoder); if (vdp_decoder->decoder != VDP_INVALID_HANDLE) { GstVdpDevice *device = vdp_decoder->device; @@ -281,44 +314,39 @@ gst_vdp_decoder_finalize (GObject * object) } static void -gst_vdp_decoder_base_init (gpointer g_class) +gst_vdp_decoder_init (GstVdpDecoder * vdp_decoder) { - GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); - GstCaps *src_caps; - GstPadTemplate *src_template; - - src_caps = gst_vdp_video_buffer_get_caps (TRUE, VDP_CHROMA_TYPE_420); - src_template = gst_pad_template_new (GST_BASE_VIDEO_DECODER_SRC_NAME, - GST_PAD_SRC, GST_PAD_ALWAYS, src_caps); - - gst_element_class_add_pad_template (element_class, src_template); -} - -static void -gst_vdp_decoder_init (GstVdpDecoder * vdp_decoder, GstVdpDecoderClass * klass) -{ - vdp_decoder->display = NULL; } static void gst_vdp_decoder_class_init (GstVdpDecoderClass * klass) { GObjectClass *object_class; - GstBaseVideoDecoderClass *base_video_decoder_class; + GstVideoDecoderClass *video_decoder_class; + GstElementClass *element_class; + + GstCaps *src_caps; + GstPadTemplate *src_template; object_class = G_OBJECT_CLASS (klass); - base_video_decoder_class = GST_BASE_VIDEO_DECODER_CLASS (klass); + element_class = GST_ELEMENT_CLASS (klass); + video_decoder_class = GST_VIDEO_DECODER_CLASS (klass); object_class->get_property = gst_vdp_decoder_get_property; object_class->set_property = gst_vdp_decoder_set_property; object_class->finalize = gst_vdp_decoder_finalize; - base_video_decoder_class->start = gst_vdp_decoder_start; - base_video_decoder_class->stop = gst_vdp_decoder_stop; + video_decoder_class->start = gst_vdp_decoder_start; + video_decoder_class->stop = gst_vdp_decoder_stop; + video_decoder_class->decide_allocation = gst_vdp_decoder_decide_allocation; + + GST_FIXME ("Actually create srcpad template from hw capabilities"); + src_caps = gst_caps_from_string ("video/x-raw,format={ YV12 }"); + src_template = gst_pad_template_new (GST_VIDEO_DECODER_SRC_NAME, + GST_PAD_SRC, GST_PAD_ALWAYS, src_caps); - base_video_decoder_class->create_srcpad = gst_vdp_decoder_create_srcpad; - base_video_decoder_class->shape_output = gst_vdp_decoder_shape_output; + gst_element_class_add_pad_template (element_class, src_template); g_object_class_install_property (object_class, PROP_DISPLAY, g_param_spec_string ("display", "Display", "X Display name", diff --git a/sys/vdpau/gstvdp/gstvdpdecoder.h b/sys/vdpau/gstvdpdecoder.h index 435a2314d..e35e0e71b 100644 --- a/sys/vdpau/gstvdp/gstvdpdecoder.h +++ b/sys/vdpau/gstvdpdecoder.h @@ -24,8 +24,9 @@ #include <gst/gst.h> #include <vdpau/vdpau.h> -#include "../basevideodecoder/gstbasevideodecoder.h" -#include "../gstvdp/gstvdpvideobuffer.h" +#include <gst/video/gstvideodecoder.h> + +#include "gstvdpdevice.h" G_BEGIN_DECLS @@ -41,17 +42,19 @@ typedef struct _GstVdpDecoderClass GstVdpDecoderClass; struct _GstVdpDecoder { - GstBaseVideoDecoder base_video_decoder; + GstVideoDecoder video_decoder; GstVdpDevice *device; VdpDecoder decoder; + GstVideoInfo info; + /* properties */ gchar *display; }; struct _GstVdpDecoderClass { - GstBaseVideoDecoderClass base_video_decoder_class; + GstVideoDecoderClass video_decoder_class; }; void @@ -59,14 +62,15 @@ gst_vdp_decoder_post_error (GstVdpDecoder * decoder, GError * error); GstFlowReturn gst_vdp_decoder_render (GstVdpDecoder * vdp_decoder, VdpPictureInfo *info, - guint n_bufs, VdpBitstreamBuffer *bufs, GstVdpVideoBuffer **video_buf); + guint n_bufs, VdpBitstreamBuffer *bufs, GstVideoCodecFrame *frame); GstFlowReturn gst_vdp_decoder_init_decoder (GstVdpDecoder * vdp_decoder, - VdpDecoderProfile profile, guint32 max_references); + VdpDecoderProfile profile, guint32 max_references, + GstVideoCodecState *output_state); GType gst_vdp_decoder_get_type (void); G_END_DECLS -#endif /* __GST_VDP_DECODER_H__ */
\ No newline at end of file +#endif /* __GST_VDP_DECODER_H__ */ diff --git a/sys/vdpau/gstvdp/gstvdpdevice.c b/sys/vdpau/gstvdpdevice.c index 1b0bc8c2f..18fe586b7 100644 --- a/sys/vdpau/gstvdp/gstvdpdevice.c +++ b/sys/vdpau/gstvdpdevice.c @@ -36,8 +36,6 @@ enum PROP_DISPLAY }; - - G_DEFINE_TYPE_WITH_CODE (GstVdpDevice, gst_vdp_device, G_TYPE_OBJECT, DEBUG_INIT ()); @@ -108,6 +106,9 @@ gst_vdp_device_open (GstVdpDevice * device, GError ** error) &device->vdp_presentation_queue_query_surface_status} }; + GST_DEBUG_OBJECT (device, "Opening the device for display '%s'", + device->display_name); + device->display = XOpenDisplay (device->display_name); if (!device->display) goto create_display_error; @@ -132,6 +133,8 @@ gst_vdp_device_open (GstVdpDevice * device, GError ** error) goto function_error; } + GST_DEBUG_OBJECT (device, "Succesfully opened the device"); + return TRUE; create_display_error: @@ -293,6 +296,8 @@ gst_vdp_get_device (const gchar * display_name, GError ** error) static GstVdpDeviceCache device_cache; GstVdpDevice *device; + GST_DEBUG ("display_name '%s'", display_name); + if (g_once_init_enter (&once)) { device_cache.hash_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); @@ -309,6 +314,7 @@ gst_vdp_get_device (const gchar * display_name, GError ** error) device = g_hash_table_lookup (device_cache.hash_table, ""); if (!device) { + GST_DEBUG ("No cached device, creating a new one"); device = gst_vdp_device_new (display_name, error); if (device) { g_object_weak_ref (G_OBJECT (device), device_destroyed_cb, &device_cache); @@ -317,7 +323,8 @@ gst_vdp_get_device (const gchar * display_name, GError ** error) device); else g_hash_table_insert (device_cache.hash_table, g_strdup (""), device); - } + } else + GST_ERROR ("Could not create GstVdpDevice !"); } else g_object_ref (device); diff --git a/sys/vdpau/gstvdp/gstvdpdevice.h b/sys/vdpau/gstvdpdevice.h index 431435e41..431435e41 100644 --- a/sys/vdpau/gstvdp/gstvdpdevice.h +++ b/sys/vdpau/gstvdpdevice.h diff --git a/sys/vdpau/gstvdp/gstvdpoutputbuffer.c b/sys/vdpau/gstvdpoutputbuffer.c index 11385936e..11385936e 100644 --- a/sys/vdpau/gstvdp/gstvdpoutputbuffer.c +++ b/sys/vdpau/gstvdpoutputbuffer.c diff --git a/sys/vdpau/gstvdp/gstvdpoutputbuffer.h b/sys/vdpau/gstvdpoutputbuffer.h index d60f0f03d..de556f9cb 100644 --- a/sys/vdpau/gstvdp/gstvdpoutputbuffer.h +++ b/sys/vdpau/gstvdpoutputbuffer.h @@ -23,18 +23,19 @@ #include <gst/gst.h> -#include "gstvdpbuffer.h" #include "gstvdpdevice.h" -typedef struct _GstVdpOutputBuffer GstVdpOutputBuffer; +GType gst_vdpau_output_meta_api_get_type (void); -#define GST_TYPE_VDP_OUTPUT_BUFFER (gst_vdp_output_buffer_get_type()) -#define GST_IS_VDP_OUTPUT_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VDP_OUTPUT_BUFFER)) -#define GST_VDP_OUTPUT_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VDP_OUTPUT_BUFFER, GstVdpOutputBuffer)) +const GstMetaInfo * gst_vdpau_output_meta_get_info (void); -struct _GstVdpOutputBuffer { - GstVdpBuffer vdp_buffer; +#define GST_VDPAU_OUTPUT_META_GET(buf) ((GstVdpauMeta *)gst_buffer_get_meta(buf,gst_vdpau_output_meta_api_get_type())) +#define GST_VDPAU_OUTPUT_META_ADD(buf) ((GstVdpauMeta *)gst_buffer_add_meta(buf,gst_vdpau_output_meta_get_info(),NULL)) +struct _GstVdpauOutputMeta { + GstMeta meta; + + /* FIXME : Check we actually need all of this */ GstVdpDevice *device; VdpRGBAFormat rgba_format; gint width, height; @@ -42,15 +43,14 @@ struct _GstVdpOutputBuffer { VdpOutputSurface surface; }; -GType gst_vdp_output_buffer_get_type (void); - -GstVdpOutputBuffer* gst_vdp_output_buffer_new (GstVdpDevice * device, VdpRGBAFormat rgba_format, gint width, gint height, GError **error); - +#if 0 +/* FIXME : Replace with GST_VIDEO_FORMAT... and GST_VIDEO_CHROMA_... */ GstCaps *gst_vdp_output_buffer_get_template_caps (void); GstCaps *gst_vdp_output_buffer_get_allowed_caps (GstVdpDevice *device); gboolean gst_vdp_caps_to_rgba_format (GstCaps *caps, VdpRGBAFormat *rgba_format); gboolean gst_vdp_output_buffer_calculate_size (GstVdpOutputBuffer *output_buf, guint *size); +/* FIXME : Replace with map/unmap */ gboolean gst_vdp_output_buffer_download (GstVdpOutputBuffer *output_buf, GstBuffer *outbuf, GError **error); #define GST_VDP_OUTPUT_CAPS \ @@ -58,5 +58,5 @@ gboolean gst_vdp_output_buffer_download (GstVdpOutputBuffer *output_buf, GstBuff "rgba-format = (int)[0,4], " \ "width = (int)[1,8192], " \ "height = (int)[1,8192]" - +#endif #endif diff --git a/sys/vdpau/gstvdp/gstvdpoutputbufferpool.c b/sys/vdpau/gstvdpoutputbufferpool.c index 8657773ce..8657773ce 100644 --- a/sys/vdpau/gstvdp/gstvdpoutputbufferpool.c +++ b/sys/vdpau/gstvdpoutputbufferpool.c diff --git a/sys/vdpau/gstvdp/gstvdpoutputbufferpool.h b/sys/vdpau/gstvdpoutputbufferpool.h index 65852ad20..1c4e93b2d 100644 --- a/sys/vdpau/gstvdp/gstvdpoutputbufferpool.h +++ b/sys/vdpau/gstvdpoutputbufferpool.h @@ -24,8 +24,6 @@ #include <gst/gst.h> -#include "gstvdpbufferpool.h" - G_BEGIN_DECLS #define GST_TYPE_VDP_OUTPUT_BUFFER_POOL (gst_vdp_output_buffer_pool_get_type ()) diff --git a/sys/vdpau/gstvdpsink.c b/sys/vdpau/gstvdpsink.c index 996c1193f..d694fe064 100644 --- a/sys/vdpau/gstvdpsink.c +++ b/sys/vdpau/gstvdpsink.c @@ -27,16 +27,16 @@ #endif /* Our interfaces */ -#include <gst/interfaces/navigation.h> -#include <gst/interfaces/xoverlay.h> +#include <gst/video/navigation.h> +#include <gst/video/videooverlay.h> #include <X11/XKBlib.h> /* Debugging category */ #include <gst/gstinfo.h> -#include "gstvdp/gstvdpoutputbuffer.h" -#include "gstvdp/gstvdpoutputbufferpool.h" +#include "gstvdpoutputbuffer.h" +#include "gstvdpoutputbufferpool.h" /* Object header */ #include "gstvdpsink.h" @@ -852,8 +852,8 @@ gst_vdp_sink_show_frame (GstBaseSink * bsink, GstBuffer * outbuf) g_mutex_lock (vdp_sink->x_lock); status = - device->vdp_presentation_queue_query_surface_status (vdp_sink->window-> - queue, surface, &queue_status, &pres_time); + device->vdp_presentation_queue_query_surface_status (vdp_sink-> + window->queue, surface, &queue_status, &pres_time); g_mutex_unlock (vdp_sink->x_lock); if (queue_status == VDP_PRESENTATION_QUEUE_STATUS_QUEUED) { diff --git a/sys/vdpau/gstvdpsink.h b/sys/vdpau/gstvdpsink.h index 54e51f5cd..e5e7e9405 100644 --- a/sys/vdpau/gstvdpsink.h +++ b/sys/vdpau/gstvdpsink.h @@ -29,7 +29,7 @@ #include <string.h> #include <math.h> -#include "gstvdp/gstvdpdevice.h" +#include "gstvdpdevice.h" G_BEGIN_DECLS @@ -99,7 +99,7 @@ struct _VdpSink { char *display_name; GstVdpDevice *device; - GstVdpBufferPool *bpool; + GstBufferPool *bpool; GstCaps *caps; GstVdpWindow *window; @@ -135,4 +135,4 @@ GType gst_vdp_sink_get_type(void); G_END_DECLS -#endif /* __GST_VDP_SINK_H__ */
\ No newline at end of file +#endif /* __GST_VDP_SINK_H__ */ diff --git a/sys/vdpau/gstvdputils.c b/sys/vdpau/gstvdputils.c new file mode 100644 index 000000000..009235888 --- /dev/null +++ b/sys/vdpau/gstvdputils.c @@ -0,0 +1,89 @@ +/* + * gst-plugins-bad + * Copyright (C) 2012 Edward Hervey <edward@collabora.com> + * + * 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 "gstvdputils.h" + +typedef struct +{ + VdpChromaType chroma_type; + VdpYCbCrFormat format; + GstVideoFormat vformat; +} GstVdpVideoBufferFormats; + +static const GstVdpVideoBufferFormats yuv_formats[] = { + {VDP_CHROMA_TYPE_420, VDP_YCBCR_FORMAT_YV12, GST_VIDEO_FORMAT_YV12}, + {VDP_CHROMA_TYPE_420, VDP_YCBCR_FORMAT_NV12, GST_VIDEO_FORMAT_NV12}, + {VDP_CHROMA_TYPE_422, VDP_YCBCR_FORMAT_UYVY, GST_VIDEO_FORMAT_UYVY}, + {VDP_CHROMA_TYPE_444, VDP_YCBCR_FORMAT_V8U8Y8A8, GST_VIDEO_FORMAT_AYUV}, + /* { */ + /* VDP_CHROMA_TYPE_444, */ + /* VDP_YCBCR_FORMAT_Y8U8V8A8, */ + /* GST_MAKE_FOURCC ('A', 'V', 'U', 'Y') */ + /* }, */ + {VDP_CHROMA_TYPE_422, VDP_YCBCR_FORMAT_YUYV, GST_VIDEO_FORMAT_YUY2} +}; + +VdpYCbCrFormat +gst_video_format_to_vdp_ycbcr (GstVideoFormat format) +{ + int i; + + for (i = 0; i < G_N_ELEMENTS (yuv_formats); i++) { + if (yuv_formats[i].vformat == format) + return yuv_formats[i].format; + } + + return -1; +} + +VdpChromaType +gst_video_info_to_vdp_chroma_type (GstVideoInfo * info) +{ + const GstVideoFormatInfo *finfo = info->finfo; + VdpChromaType ret = -1; + + /* Check subsampling of second plane (first is always non-subsampled) */ + switch (GST_VIDEO_FORMAT_INFO_W_SUB (finfo, 1)) { + case 0: + /* Not subsampled in width for second plane */ + if (GST_VIDEO_FORMAT_INFO_W_SUB (finfo, 2)) + /* Not subsampled at all (4:4:4) */ + ret = VDP_CHROMA_TYPE_444; + break; + case 1: + /* Subsampled horizontally once */ + if (GST_VIDEO_FORMAT_INFO_H_SUB (finfo, 2) == 0) + /* Not subsampled vertically (4:2:2) */ + ret = VDP_CHROMA_TYPE_422; + else if (GST_VIDEO_FORMAT_INFO_H_SUB (finfo, 2) == 1) + /* Subsampled vertically once (4:2:0) */ + ret = VDP_CHROMA_TYPE_420; + break; + default: + break; + } + + return ret; +} diff --git a/sys/vdpau/gstvdp/gstvdputils.h b/sys/vdpau/gstvdputils.h index 98cffafd7..c7c83af3f 100644 --- a/sys/vdpau/gstvdp/gstvdputils.h +++ b/sys/vdpau/gstvdputils.h @@ -1,7 +1,7 @@ -/* - * GStreamer - * Copyright (C) 2009 Carl-Anton Ingmarsson <ca.ingmarsson@gmail.com> - * +/* + * gst-plugins-bad + * Copyright (C) 2012 Edward Hervey <edward@collabora.com> + * * 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 @@ -22,9 +22,17 @@ #define _GST_VDP_UTILS_H_ #include <gst/gst.h> +#include <gst/video/video.h> +#include <gst/video/gstvideometa.h> +#include <gst/video/gstvideopool.h> #include "gstvdpdevice.h" -GstCaps *gst_vdp_video_to_output_caps (GstCaps *video_caps); -GstCaps *gst_vdp_yuv_to_video_caps (GstCaps * yuv_caps); +G_BEGIN_DECLS + +VdpChromaType gst_video_info_to_vdp_chroma_type (GstVideoInfo *info); + +VdpYCbCrFormat gst_video_format_to_vdp_ycbcr (GstVideoFormat format); + +G_END_DECLS #endif /* _GST_VDP_UTILS_H_ */ diff --git a/sys/vdpau/gstvdpvideobufferpool.c b/sys/vdpau/gstvdpvideobufferpool.c new file mode 100644 index 000000000..039ebdba6 --- /dev/null +++ b/sys/vdpau/gstvdpvideobufferpool.c @@ -0,0 +1,210 @@ +/* + * gst-plugins-bad + * Copyright (C) 2012 Edward Hervey <edward@collabora.com> + * + * 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 "gstvdpvideobufferpool.h" +#include "gstvdpvideomemory.h" + +GST_DEBUG_CATEGORY_STATIC (gst_vdp_vidbufpool_debug); +#define GST_CAT_DEFAULT gst_vdp_vidbufpool_debug + +static void gst_vdp_video_buffer_pool_finalize (GObject * object); + +#define DEBUG_INIT \ + GST_DEBUG_CATEGORY_INIT (gst_vdp_vidbufpool_debug, "vdpvideopool", 0, \ + "VDPAU Video bufferpool"); + +#define gst_vdp_video_buffer_pool_parent_class parent_class +G_DEFINE_TYPE_WITH_CODE (GstVdpVideoBufferPool, gst_vdp_video_buffer_pool, + GST_TYPE_BUFFER_POOL, DEBUG_INIT); + +static const gchar ** +gst_vdp_video_buffer_pool_get_options (GstBufferPool * pool) +{ + static const gchar *options[] = { GST_BUFFER_POOL_OPTION_VIDEO_META, + GST_BUFFER_POOL_OPTION_VDP_VIDEO_META, NULL + }; + + return options; +} + +static gboolean +gst_vdp_video_buffer_pool_set_config (GstBufferPool * pool, + GstStructure * config) +{ + GstVdpVideoBufferPool *vdppool = GST_VDP_VIDEO_BUFFER_POOL_CAST (pool); + GstVideoInfo info; + GstCaps *caps; + + if (!gst_buffer_pool_config_get_params (config, &caps, NULL, NULL, NULL)) + goto wrong_config; + + if (caps == NULL) + goto no_caps; + + /* now parse the caps from the config */ + if (!gst_video_info_from_caps (&info, caps)) + goto wrong_caps; + + GST_LOG_OBJECT (pool, "%dx%d, caps %" GST_PTR_FORMAT, info.width, info.height, + caps); + + if (GST_VIDEO_INFO_FORMAT (&info) == -1) + goto unknown_format; + + vdppool->info = info; + + /* enable metadata based on config of the pool */ + vdppool->add_videometa = + gst_buffer_pool_config_has_option (config, + GST_BUFFER_POOL_OPTION_VIDEO_META); + + /* parse extra alignment info */ + vdppool->add_vdpmeta = gst_buffer_pool_config_has_option (config, + GST_BUFFER_POOL_OPTION_VDP_VIDEO_META); + + return GST_BUFFER_POOL_CLASS (parent_class)->set_config (pool, config); + + /* ERRORS */ +wrong_config: + { + GST_WARNING_OBJECT (pool, "invalid config"); + return FALSE; + } +no_caps: + { + GST_WARNING_OBJECT (pool, "no caps in config"); + return FALSE; + } +wrong_caps: + { + GST_WARNING_OBJECT (pool, + "failed getting geometry from caps %" GST_PTR_FORMAT, caps); + return FALSE; + } +unknown_format: + { + GST_WARNING_OBJECT (vdppool, "failed to get format from caps %" + GST_PTR_FORMAT, caps); + GST_ELEMENT_ERROR (vdppool, RESOURCE, WRITE, + ("Failed to create output image buffer of %dx%d pixels", + info.width, info.height), + ("Invalid input caps %" GST_PTR_FORMAT, caps)); + return FALSE;; + } +} + +/* This function handles GstBuffer creation */ +static GstFlowReturn +gst_vdp_video_buffer_pool_alloc (GstBufferPool * pool, GstBuffer ** buffer, + GstBufferPoolAcquireParams * params) +{ + GstVdpVideoBufferPool *vdppool = GST_VDP_VIDEO_BUFFER_POOL_CAST (pool); + GstVideoInfo *info; + GstBuffer *buf; + GstMemory *vdp_mem; + + info = &vdppool->info; + + if (!(buf = gst_buffer_new ())) + goto no_buffer; + + if (!(vdp_mem = gst_vdp_video_memory_alloc (vdppool->device, info))) + goto mem_create_failed; + + gst_buffer_append_memory (buf, vdp_mem); + + if (vdppool->add_videometa) { + GstVideoMeta *vmeta; + + GST_DEBUG_OBJECT (pool, "adding GstVideoMeta"); + /* these are just the defaults for now */ + vmeta = gst_buffer_add_video_meta (buf, 0, GST_VIDEO_INFO_FORMAT (info), + GST_VIDEO_INFO_WIDTH (info), GST_VIDEO_INFO_HEIGHT (info)); + vmeta->map = gst_vdp_video_memory_map; + vmeta->unmap = gst_vdp_video_memory_unmap; + } + + *buffer = buf; + + return GST_FLOW_OK; + + /* ERROR */ +no_buffer: + { + GST_WARNING_OBJECT (pool, "can't create image"); + return GST_FLOW_ERROR; + } + +mem_create_failed: + { + GST_WARNING_OBJECT (pool, "Could create GstVdpVideo Memory"); + return GST_FLOW_ERROR; + } +} + + +GstBufferPool * +gst_vdp_video_buffer_pool_new (GstVdpDevice * device) +{ + GstVdpVideoBufferPool *pool; + + pool = g_object_new (GST_TYPE_VDP_VIDEO_BUFFER_POOL, NULL); + pool->device = gst_object_ref (device); + + GST_LOG_OBJECT (pool, "new VdpVideo buffer pool %p", pool); + + return GST_BUFFER_POOL_CAST (pool); +} + +static void +gst_vdp_video_buffer_pool_class_init (GstVdpVideoBufferPoolClass * klass) +{ + GObjectClass *gobject_class = (GObjectClass *) klass; + GstBufferPoolClass *gstbufferpool_class = (GstBufferPoolClass *) klass; + + gobject_class->finalize = gst_vdp_video_buffer_pool_finalize; + + gstbufferpool_class->get_options = gst_vdp_video_buffer_pool_get_options; + gstbufferpool_class->set_config = gst_vdp_video_buffer_pool_set_config; + gstbufferpool_class->alloc_buffer = gst_vdp_video_buffer_pool_alloc; +} + +static void +gst_vdp_video_buffer_pool_init (GstVdpVideoBufferPool * pool) +{ + +} + +static void +gst_vdp_video_buffer_pool_finalize (GObject * object) +{ + GstVdpVideoBufferPool *pool = GST_VDP_VIDEO_BUFFER_POOL_CAST (object); + + GST_LOG_OBJECT (pool, "finalize VdpVideo buffer pool %p", pool); + + gst_object_unref (pool->device); + + G_OBJECT_CLASS (gst_vdp_video_buffer_pool_parent_class)->finalize (object); +} diff --git a/sys/vdpau/gstvdpvideobufferpool.h b/sys/vdpau/gstvdpvideobufferpool.h new file mode 100644 index 000000000..c2a180bb7 --- /dev/null +++ b/sys/vdpau/gstvdpvideobufferpool.h @@ -0,0 +1,97 @@ +/* + * gst-plugins-bad + * Copyright (C) Carl-Anton Ingmarsson 2010 <ca.ingmarsson@gmail.com> + * 2012 Edward Hervey <edward@collabora.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _GST_VDP_VIDEO_BUFFERPOOL_H_ +#define _GST_VDP_VIDEO_BUFFERPOOL_H_ + +#include <gst/gst.h> +#include <gst/video/video.h> +#include <gst/video/gstvideometa.h> +#include <gst/video/gstvideopool.h> +#include "gstvdpdevice.h" + +G_BEGIN_DECLS + +#define GST_VDPAU_SURFACE_META_GET(buf) ((GstVdpauMeta *)gst_buffer_get_meta(buf,gst_vdpau_surface_meta_api_get_type())) +#define GST_VDPAU_SURFACE_META_ADD(buf) ((GstVdpauMeta *)gst_buffer_add_meta(buf,gst_vdpau_surface_meta_get_info(),NULL)) + +struct _GstVdpauSurfaceMeta { + GstMeta meta; + + GstVdpDevice *device; + VdpVideoSurface surface; +}; + +GType gst_vdpau_surface_meta_api_get_type (void); + +const GstMetaInfo * gst_vdpau_surface_meta_get_info (void); +/** + * GST_BUFFER_POOL_OPTION_VDP_VIDEO_META: + * + * An option that can be activated on bufferpool to request VdpVideo metadata + * on buffers from the pool. + */ +#define GST_BUFFER_POOL_OPTION_VDP_VIDEO_META "GstBufferPoolOptionVdpVideoMeta" + +typedef struct _GstVdpVideoBufferPool GstVdpVideoBufferPool; +typedef struct _GstVdpVideoBufferPoolClass GstVdpVideoBufferPoolClass; + +/* buffer pool functions */ +#define GST_TYPE_VDP_VIDEO_BUFFER_POOL (gst_vdp_video_buffer_pool_get_type()) +#define GST_IS_VDP_VIDEO_BUFFER_POOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VDP_VIDEO_BUFFER_POOL)) +#define GST_VDP_VIDEO_BUFFER_POOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VDP_VIDEO_BUFFER_POOL, GstVdpVideoBufferPool)) +#define GST_VDP_VIDEO_BUFFER_POOL_CAST(obj) ((GstVdpVideoBufferPool*)(obj)) + +struct _GstVdpVideoBufferPool +{ + GstBufferPool bufferpool; + + GstVdpDevice *device; + + GstVideoInfo info; + VdpChromaType chroma_type; + + gboolean add_videometa; + gboolean add_vdpmeta; +}; + +struct _GstVdpVideoBufferPoolClass +{ + GstBufferPoolClass parent_class; +}; + +GType gst_vdp_video_buffer_pool_get_type (void); +GstBufferPool *gst_vdp_video_buffer_pool_new (GstVdpDevice *device); + +GstCaps *gst_vdp_video_buffer_get_caps (gboolean filter, VdpChromaType chroma_type); +#if 0 +GstCaps *gst_vdp_video_buffer_get_allowed_caps (GstVdpDevice * device); + +gboolean gst_vdp_video_buffer_calculate_size (guint32 fourcc, gint width, gint height, guint *size); +/* FIXME : Replace with map/unmap */ +gboolean gst_vdp_video_buffer_download (GstVdpVideoBuffer *inbuf, GstBuffer *outbuf, guint32 fourcc, gint width, gint height); +gboolean gst_vdp_video_buffer_upload (GstVdpVideoBuffer *video_buf, GstBuffer *src_buf, guint fourcc, gint width, gint height); +#endif + + +G_END_DECLS + +#endif /* _GST_VDP_VIDEO_BUFFER_POOL_H_ */ diff --git a/sys/vdpau/gstvdpvideomemory.c b/sys/vdpau/gstvdpvideomemory.c new file mode 100644 index 000000000..d6e141b78 --- /dev/null +++ b/sys/vdpau/gstvdpvideomemory.c @@ -0,0 +1,327 @@ +/* + * GStreamer + * Copyright (C) 2012 Edward Hervey <edward@collabora.com> + * + * 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 <gst/video/video.h> + +#include "gstvdpvideomemory.h" +#include "gstvdputils.h" + +GST_DEBUG_CATEGORY_STATIC (GST_CAT_PERFORMANCE); +GST_DEBUG_CATEGORY_STATIC (gst_vdp_video_mem_debug); +#define GST_CAT_DEFAULT gst_vdp_video_mem_debug + +static GstAllocator *_vdp_video_allocator; + + +static void +_vdp_video_mem_init (GstVdpVideoMemory * mem, GstAllocator * allocator, + GstMemory * parent, GstVdpDevice * device, GstVideoInfo * info) +{ + gst_memory_init (GST_MEMORY_CAST (mem), GST_MEMORY_FLAG_NO_SHARE, + allocator, parent, GST_VIDEO_INFO_SIZE (info), 0, 0, + GST_VIDEO_INFO_SIZE (info)); + + mem->device = gst_object_ref (device); + mem->info = info; + mem->chroma_type = gst_video_info_to_vdp_chroma_type (info); + mem->ycbcr_format = + gst_video_format_to_vdp_ycbcr (GST_VIDEO_INFO_FORMAT (info)); + mem->refcount = 0; + + GST_DEBUG ("new VdpVideo memory"); +} + + +static GstVdpVideoMemory * +_vdp_video_mem_new (GstAllocator * allocator, GstMemory * parent, + GstVdpDevice * device, GstVideoInfo * info) +{ + VdpStatus status; + GstVdpVideoMemory *mem; + VdpVideoSurface surface; + + mem = g_slice_new0 (GstVdpVideoMemory); + _vdp_video_mem_init (mem, allocator, parent, device, info); + + GST_TRACE + ("Calling VdpVideoSurfaceCreate(chroma_type:%d, width:%d, height:%d)", + mem->chroma_type, mem->info->width, mem->info->height); + + status = + device->vdp_video_surface_create (device->device, mem->chroma_type, + mem->info->width, mem->info->height, &surface); + + if (status != VDP_STATUS_OK) + goto create_error; + + /* device->vdp_video_surface_get_parameters (device->device, &chroma_type, */ + /* &width, &height); */ + + GST_TRACE ("created surface %u", surface); + + mem->surface = surface; + + return mem; + + /* ERRORS */ +create_error: + { + GST_ERROR ("Failed to create video surface: %s", + device->vdp_get_error_string (status)); + g_slice_free (GstVdpVideoMemory, mem); + return NULL; + } +} + +static gboolean +ensure_data (GstVdpVideoMemory * vmem) +{ + VdpStatus vdp_stat; + GstVideoInfo *info = vmem->info; + GstClockTime before, after; + + if (g_atomic_int_add (&vmem->refcount, 1) > 1) + return TRUE; + + /* Allocate enough room to store data */ + vmem->cache = g_malloc (GST_VIDEO_INFO_SIZE (info)); + vmem->cached_data[0] = vmem->cache; + vmem->cached_data[1] = vmem->cache + GST_VIDEO_INFO_PLANE_OFFSET (info, 1); + vmem->cached_data[2] = vmem->cache + GST_VIDEO_INFO_PLANE_OFFSET (info, 2); + vmem->destination_pitches[0] = GST_VIDEO_INFO_PLANE_STRIDE (info, 0); + vmem->destination_pitches[1] = GST_VIDEO_INFO_PLANE_STRIDE (info, 1); + vmem->destination_pitches[2] = GST_VIDEO_INFO_PLANE_STRIDE (info, 2); + + GST_DEBUG ("cached_data %p %p %p", + vmem->cached_data[0], vmem->cached_data[1], vmem->cached_data[2]); + GST_DEBUG ("pitches %d %d %d", + vmem->destination_pitches[0], + vmem->destination_pitches[1], vmem->destination_pitches[2]); + + before = gst_util_get_timestamp (); + vdp_stat = + vmem->device->vdp_video_surface_get_bits_ycbcr (vmem->surface, + vmem->ycbcr_format, vmem->cached_data, vmem->destination_pitches); + after = gst_util_get_timestamp (); + + GST_CAT_WARNING (GST_CAT_PERFORMANCE, "Downloading took %" GST_TIME_FORMAT, + GST_TIME_ARGS (after - before)); + + if (vdp_stat != VDP_STATUS_OK) { + GST_ERROR ("Failed to get bits : %s", + vmem->device->vdp_get_error_string (vdp_stat)); + g_free (vmem->cache); + vmem->cache = NULL; + return FALSE; + } + + return TRUE; +} + +static void +release_data (GstVdpVideoMemory * vmem) +{ + g_return_if_fail (vmem->refcount > 0); + + if (g_atomic_int_dec_and_test (&vmem->refcount)) { + g_free (vmem->cache); + } +} + +static gpointer +_vdp_video_mem_map (GstVdpVideoMemory * vmem, gsize maxsize, GstMapFlags flags) +{ + GST_DEBUG ("surface:%d, maxsize:%d, flags:%d", vmem->surface, maxsize, flags); + + if (!ensure_data (vmem)) + return NULL; + + return vmem->cache; +} + +static void +_vdp_video_mem_unmap (GstVdpVideoMemory * vmem) +{ + GST_DEBUG ("surface:%d", vmem->surface); + + release_data (vmem); +} + + +static GstMemory * +_vdp_video_mem_copy (GstVdpVideoMemory * src, gssize offset, gssize size) +{ + GST_FIXME ("Implement !"); + return NULL; +} + +static GstMemory * +_vdp_video_mem_share (GstVdpVideoMemory * mem, gssize offset, gssize size) +{ + GST_FIXME ("Implement !"); + return NULL; +} + +static gboolean +_vdp_video_mem_is_span (GstVdpVideoMemory * mem1, GstVdpVideoMemory * mem2, + gsize * offset) +{ + return FALSE; +} + +static GstMemory * +_vdp_video_mem_alloc (GstAllocator * allocator, gsize size, + GstAllocationParams * params) +{ + g_warning ("use gst_vdp_video_memory_alloc () to allocate from this " + "GstVdpVideoMemory allocator"); + + return NULL; +} + +static void +_vdp_video_mem_free (GstAllocator * allocator, GstMemory * mem) +{ + GstVdpVideoMemory *vmem = (GstVdpVideoMemory *) mem; + VdpStatus status; + + GST_DEBUG ("Destroying surface %d", vmem->surface); + + status = vmem->device->vdp_video_surface_destroy (vmem->surface); + if (status != VDP_STATUS_OK) + GST_ERROR ("Couldn't destroy the VdpVideoSurface: %s", + vmem->device->vdp_get_error_string (status)); + + gst_object_unref (vmem->device); + + if (vmem->cache) + g_free (vmem->cache); + + g_slice_free (GstVdpVideoMemory, vmem); +} + +/** + * gst_vdp_video_memory_alloc: + * @device: a #GstVdpDevice + * @info: the #GstVideoInfo describing the format to use + * + * Returns: a GstMemory object with a VdpVideoSurface specified by @info + * from @device + */ +GstMemory * +gst_vdp_video_memory_alloc (GstVdpDevice * device, GstVideoInfo * info) +{ + return (GstMemory *) _vdp_video_mem_new (_vdp_video_allocator, NULL, device, + info); +} + +G_DEFINE_TYPE (GstVdpVideoAllocator, gst_vdp_video_allocator, + GST_TYPE_ALLOCATOR); + +static void +gst_vdp_video_allocator_class_init (GstVdpVideoAllocatorClass * klass) +{ + GstAllocatorClass *allocator_class; + + allocator_class = (GstAllocatorClass *) klass; + + allocator_class->alloc = _vdp_video_mem_alloc; + allocator_class->free = _vdp_video_mem_free; +} + +static void +gst_vdp_video_allocator_init (GstVdpVideoAllocator * allocator) +{ + GstAllocator *alloc = GST_ALLOCATOR_CAST (allocator); + + alloc->mem_type = GST_VDP_VIDEO_MEMORY_ALLOCATOR; + alloc->mem_map = (GstMemoryMapFunction) _vdp_video_mem_map; + alloc->mem_unmap = (GstMemoryUnmapFunction) _vdp_video_mem_unmap; + alloc->mem_copy = (GstMemoryCopyFunction) _vdp_video_mem_copy; + alloc->mem_share = (GstMemoryShareFunction) _vdp_video_mem_share; + alloc->mem_is_span = (GstMemoryIsSpanFunction) _vdp_video_mem_is_span; +} + +/** + * gst_vdp_video_memory_init: + * + * Initializes the GL Memory allocator. It is safe to call this function + * multiple times. This must be called before any other GstVdpVideoMemory operation. + */ +void +gst_vdp_video_memory_init (void) +{ + static volatile gsize _init = 0; + + if (g_once_init_enter (&_init)) { + _vdp_video_allocator = + g_object_new (gst_vdp_video_allocator_get_type (), NULL); + + gst_allocator_register (GST_VDP_VIDEO_MEMORY_ALLOCATOR, + gst_object_ref (_vdp_video_allocator)); + GST_DEBUG_CATEGORY_INIT (gst_vdp_video_mem_debug, "vdpvideomem", 0, + "VDPAU VideoSurface Memory/Allocator"); + GST_DEBUG_CATEGORY_GET (GST_CAT_PERFORMANCE, "GST_PERFORMANCE"); + g_once_init_leave (&_init, 1); + } +} + +gboolean +gst_vdp_video_memory_map (GstVideoMeta * meta, guint plane, GstMapInfo * info, + gpointer * data, gint * stride, GstMapFlags flags) +{ + GstBuffer *buffer = meta->buffer; + GstVdpVideoMemory *vmem = + (GstVdpVideoMemory *) gst_buffer_get_memory (buffer, 0); + + /* Only handle GstVdpVideoMemory */ + g_return_val_if_fail (((GstMemory *) vmem)->allocator == _vdp_video_allocator, + FALSE); + + GST_DEBUG ("plane:%d", plane); + + /* download if not already done */ + if (!ensure_data (vmem)) + return FALSE; + + *data = vmem->cached_data[plane]; + *stride = vmem->destination_pitches[plane]; + + return TRUE; +} + +gboolean +gst_vdp_video_memory_unmap (GstVideoMeta * meta, guint plane, GstMapInfo * info) +{ + GstVdpVideoMemory *vmem = + (GstVdpVideoMemory *) gst_buffer_get_memory (meta->buffer, 0); + + GST_DEBUG ("plane:%d", plane); + + GST_FIXME ("implement unmap (and potential upload on last unmap)"); + + release_data (vmem); + + return TRUE; +} diff --git a/sys/vdpau/gstvdpvideomemory.h b/sys/vdpau/gstvdpvideomemory.h new file mode 100644 index 000000000..aaf874454 --- /dev/null +++ b/sys/vdpau/gstvdpvideomemory.h @@ -0,0 +1,101 @@ +/* + * GStreamer + * Copyright (C) 2012 Edward Hervey <edward@collabora.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _GST_VDP_VIDEO_MEMORY_H_ +#define _GST_VDP_VIDEO_MEMORY_H_ + +#include <gst/gst.h> +#include <gst/gstmemory.h> +#include <gst/gstallocator.h> +#include <gst/video/video-info.h> +#include <gst/video/gstvideometa.h> + +#include "gstvdpdevice.h" + +G_BEGIN_DECLS + +#define GST_TYPE_VDP_VIDEO_ALLOCATOR (gst_vdp_video_allocator_get_type()) +GType gst_vdp_video_allocator_get_type(void); + +#define GST_IS_VDP_VIDEO_ALLOCATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VDP_VIDEO_ALLOCATOR)) +#define GST_IS_VDP_VIDEO_ALLOCATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_VDP_VIDEO_ALLOCATOR)) +#define GST_VDP_VIDEO_ALLOCATOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VDP_VIDEO_ALLOCATOR, GstVdpVideoAllocatorClass)) +#define GST_VDP_VIDEO_ALLOCATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VDP_VIDEO_ALLOCATOR, GstVdpVideoAllocator)) +#define GST_VDP_VIDEO_ALLOCATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_VDP_VIDEO_ALLOCATOR, GstVdpVideoAllocatorClass)) +#define GST_VDP_VIDEO_ALLOCATOR_CAST(obj) ((GstVdpVideoAllocator *)(obj)) + +typedef struct _GstVdpVideoMemory GstVdpVideoMemory; +typedef struct _GstVdpVideoAllocator GstVdpVideoAllocator; +typedef struct _GstVdpVideoAllocatorClass GstVdpVideoAllocatorClass; + +/** + * GstVdpVideoMemory: + * @mem: the parent object + * @device: the #GstVdpDevice to use + * @surface: the #VdpVideoSurface + * + * Represents information about a #VdpVideoSurface + */ +struct _GstVdpVideoMemory +{ + GstMemory mem; + + GstVdpDevice *device; + VdpVideoSurface surface; + + GstVideoInfo *info; + VdpChromaType chroma_type; + VdpYCbCrFormat ycbcr_format; + + /* Cached data for mapping */ + volatile gint refcount; + GstMapFlags map_flags; + guint n_planes; + guint8 *cache; + void * cached_data[4]; + uint32_t destination_pitches[4]; +}; + +#define GST_VDP_VIDEO_MEMORY_ALLOCATOR "VdpVideoMemory" + +void gst_vdp_video_memory_init (void); + +GstMemory * +gst_vdp_video_memory_alloc (GstVdpDevice * device, GstVideoInfo *info); + +gboolean gst_vdp_video_memory_map(GstVideoMeta * meta, guint plane, + GstMapInfo * info, gpointer * data, + gint * stride, GstMapFlags flags); +gboolean gst_vdp_video_memory_unmap(GstVideoMeta * meta, guint plane, + GstMapInfo * info); + +struct _GstVdpVideoAllocator +{ + GstAllocator parent; +}; + +struct _GstVdpVideoAllocatorClass +{ + GstAllocatorClass parent_class; +}; + +G_END_DECLS + +#endif /* _GST_VDP_VIDEO_MEMORY_H_ */ diff --git a/sys/vdpau/gstvdpvideopostprocess.c b/sys/vdpau/gstvdpvideopostprocess.c index b4ea05381..483e74a54 100644 --- a/sys/vdpau/gstvdpvideopostprocess.c +++ b/sys/vdpau/gstvdpvideopostprocess.c @@ -43,11 +43,8 @@ #endif #include <gst/gst.h> -#include <gst/video/gstvideosink.h> -#include "gstvdp/gstvdputils.h" -#include "gstvdp/gstvdpoutputbuffer.h" -#include "gstvdp/gstvdpoutputsrcpad.h" +#include "gstvdpoutputbuffer.h" #include "gstvdpvideopostprocess.h" @@ -73,11 +70,7 @@ enum PROP_INVERSE_TELECINE }; -#define DEBUG_INIT(bla) \ -GST_DEBUG_CATEGORY_INIT (gst_vdp_vpp_debug, "vdpauvideopostprocess", 0, "VDPAU video surface to output surface"); - -GST_BOILERPLATE_FULL (GstVdpVideoPostProcess, gst_vdp_vpp, - GstElement, GST_TYPE_ELEMENT, DEBUG_INIT); +G_DEFINE_TYPE (GstVdpVideoPostProcess, gst_vdp_vpp, GST_TYPE_ELEMENT); static void gst_vdp_vpp_finalize (GObject * object); @@ -1172,38 +1165,17 @@ gst_vdp_vpp_set_property (GObject * object, guint property_id, /* GType vmethod implementations */ -static void -gst_vdp_vpp_base_init (gpointer gclass) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS (gclass); - GstCaps *src_caps, *sink_caps; - GstPadTemplate *src_template, *sink_template; - - gst_element_class_set_static_metadata (element_class, - "VdpauVideoPostProcess", - "Filter/Converter/Decoder/Video", - "Post process GstVdpVideoBuffers and output GstVdpOutputBuffers", - "Carl-Anton Ingmarsson <ca.ingmarsson@gmail.com>"); - - /* SRC PAD */ - src_caps = gst_vdp_output_buffer_get_template_caps (); - src_template = gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, - src_caps); - gst_element_class_add_pad_template (element_class, src_template); - - /* SINK PAD */ - sink_caps = gst_vdp_video_buffer_get_caps (FALSE, 0); - sink_template = gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, - sink_caps); - gst_element_class_add_pad_template (element_class, sink_template); -} - /* initialize the vdpaumpegdecoder's class */ static void gst_vdp_vpp_class_init (GstVdpVideoPostProcessClass * klass) { GObjectClass *gobject_class; GstElementClass *gstelement_class; + GstCaps *src_caps, *sink_caps; + GstPadTemplate *src_template, *sink_template; + + GST_DEBUG_CATEGORY_INIT (gst_vdp_vpp_debug, "vdpauvideopostprocess", 0, + "VDPAU video surface to output surface"); gobject_class = (GObjectClass *) klass; gstelement_class = (GstElementClass *) klass; @@ -1249,12 +1221,29 @@ gst_vdp_vpp_class_init (GstVdpVideoPostProcessClass * klass) "Whether inverse telecine should be used", FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + gst_element_class_set_metadata (gstelement_class, + "VdpauVideoPostProcess", + "Filter/Converter/Decoder/Video", + "Post process GstVdpVideoBuffers and output GstVdpOutputBuffers", + "Carl-Anton Ingmarsson <ca.ingmarsson@gmail.com>"); + gstelement_class->change_state = gst_vdp_vpp_change_state; + + /* SRC PAD */ + src_caps = gst_vdp_output_buffer_get_template_caps (); + src_template = gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, + src_caps); + gst_element_class_add_pad_template (gstelement_class, src_template); + + /* SINK PAD */ + sink_caps = gst_vdp_video_buffer_get_caps (FALSE, 0); + sink_template = gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, + sink_caps); + gst_element_class_add_pad_template (gstelement_class, sink_template); } static void -gst_vdp_vpp_init (GstVdpVideoPostProcess * vpp, - GstVdpVideoPostProcessClass * gclass) +gst_vdp_vpp_init (GstVdpVideoPostProcess * vpp) { GstPadTemplate *src_template, *sink_template; diff --git a/sys/vdpau/gstvdpvideopostprocess.h b/sys/vdpau/gstvdpvideopostprocess.h index 8af582c41..40f7c3661 100644 --- a/sys/vdpau/gstvdpvideopostprocess.h +++ b/sys/vdpau/gstvdpvideopostprocess.h @@ -23,9 +23,8 @@ #include <gst/gst.h> -#include "gstvdp/gstvdpdevice.h" -#include "gstvdp/gstvdpvideobuffer.h" -#include "gstvdp/gstvdpvideobufferpool.h" +#include "gstvdpdevice.h" +#include "gstvdpvideobufferpool.h" G_BEGIN_DECLS @@ -35,7 +34,7 @@ typedef struct _GstVdpPicture GstVdpPicture; struct _GstVdpPicture { - GstVdpVideoBuffer *buf; + GstBuffer *buf; VdpVideoMixerPictureStructure structure; GstClockTime timestamp; }; @@ -73,7 +72,7 @@ struct _GstVdpVideoPostProcess VdpChromaType chroma_type; gint width, height; guint32 fourcc; - GstVdpBufferPool *vpool; + GstBufferPool *vpool; gboolean got_par; gint par_n, par_d; @@ -114,4 +113,4 @@ GType gst_vdp_vpp_get_type (void); G_END_DECLS -#endif /* __GST_VDP_VIDEO_POST_PROCESS_H__ */
\ No newline at end of file +#endif /* __GST_VDP_VIDEO_POST_PROCESS_H__ */ diff --git a/sys/vdpau/h264/gsth264dpb.c b/sys/vdpau/h264/gsth264dpb.c index a557673a8..9676315fe 100644 --- a/sys/vdpau/h264/gsth264dpb.c +++ b/sys/vdpau/h264/gsth264dpb.c @@ -19,6 +19,7 @@ */ #include "gsth264dpb.h" +#include "gstvdpvideomemory.h" /* Properties */ enum @@ -32,8 +33,8 @@ GST_DEBUG_CATEGORY_STATIC (h264dpb_debug); #define GST_CAT_DEFAULT h264dpb_debug #define DEBUG_INIT \ - GST_DEBUG_CATEGORY_INIT (h264dpb_debug, "h264dpb", 0, \ - "H264 DPB"); + GST_DEBUG_CATEGORY_INIT (h264dpb_debug, "vdph264dpb", 0, \ + "VDPAU H264 DPB"); G_DEFINE_TYPE_WITH_CODE (GstH264DPB, gst_h264_dpb, G_TYPE_OBJECT, DEBUG_INIT); @@ -47,10 +48,11 @@ gst_h264_dpb_fill_reference_frames (GstH264DPB * dpb, frames = dpb->frames; for (i = 0; i < dpb->n_frames; i++) { GstH264Frame *frame = frames[i]; + GstVdpVideoMemory *vmem = + (GstVdpVideoMemory *) gst_buffer_get_memory (frame->frame-> + output_buffer, 0); - reference_frames[i].surface = - GST_VDP_VIDEO_BUFFER (GST_VIDEO_FRAME_CAST (frame)->src_buffer)-> - surface; + reference_frames[i].surface = vmem->surface; reference_frames[i].is_long_term = frame->is_long_term; reference_frames[i].top_is_reference = frame->is_reference; @@ -62,8 +64,12 @@ gst_h264_dpb_fill_reference_frames (GstH264DPB * dpb, for (i = dpb->n_frames; i < 16; i++) { reference_frames[i].surface = VDP_INVALID_HANDLE; + reference_frames[i].is_long_term = FALSE; reference_frames[i].top_is_reference = VDP_FALSE; reference_frames[i].bottom_is_reference = VDP_FALSE; + reference_frames[i].field_order_cnt[0] = 0; + reference_frames[i].field_order_cnt[1] = 0; + reference_frames[i].frame_idx = 0; } } @@ -74,7 +80,7 @@ gst_h264_dpb_remove (GstH264DPB * dpb, guint idx) guint i; frames = dpb->frames; - gst_video_frame_unref (GST_VIDEO_FRAME_CAST (frames[idx])); + gst_video_codec_frame_unref (frames[idx]->frame); dpb->n_frames--; for (i = idx; i < dpb->n_frames; i++) @@ -87,7 +93,7 @@ gst_h264_dpb_output (GstH264DPB * dpb, guint idx) GstFlowReturn ret; GstH264Frame *frame = dpb->frames[idx]; - gst_video_frame_ref (GST_VIDEO_FRAME_CAST (frame)); + gst_video_codec_frame_ref (frame->frame); ret = dpb->output (dpb, frame, dpb->user_data); frame->output_needed = FALSE; @@ -132,7 +138,7 @@ gst_h264_dpb_bump (GstH264DPB * dpb, guint poc, GstFlowReturn * ret) GstFlowReturn gst_h264_dpb_add (GstH264DPB * dpb, GstH264Frame * h264_frame) { - GstFlowReturn ret; + GstFlowReturn ret = GST_FLOW_OK; GST_DEBUG ("add frame with poc: %d", h264_frame->poc); @@ -141,18 +147,13 @@ gst_h264_dpb_add (GstH264DPB * dpb, GstH264Frame * h264_frame) h264_frame->is_reference = FALSE; if (h264_frame->is_reference) { - - ret = GST_FLOW_OK; while (dpb->n_frames == dpb->max_frames) { - if (!gst_h264_dpb_bump (dpb, G_MAXUINT, &ret)) { - GST_ERROR_OBJECT (dpb, "Couldn't make room in DPB"); - return GST_FLOW_OK; - } + if (!gst_h264_dpb_bump (dpb, G_MAXUINT, &ret)) + goto no_room; } + GST_DEBUG ("Storing frame in slot %d", dpb->n_frames); dpb->frames[dpb->n_frames++] = h264_frame; - } - - else { + } else { while (gst_h264_dpb_bump (dpb, h264_frame->poc, &ret)) { if (ret != GST_FLOW_OK) return ret; @@ -162,13 +163,19 @@ gst_h264_dpb_add (GstH264DPB * dpb, GstH264Frame * h264_frame) } return ret; + + /* ERRORS */ +no_room: + { + GST_ERROR_OBJECT (dpb, "Couldn't make room in DPB"); + return GST_FLOW_OK; + } } void gst_h264_dpb_flush (GstH264DPB * dpb, gboolean output) { GstFlowReturn ret; - GstVideoFrame **frames; guint i; GST_DEBUG ("flush"); @@ -176,9 +183,8 @@ gst_h264_dpb_flush (GstH264DPB * dpb, gboolean output) if (output) while (gst_h264_dpb_bump (dpb, G_MAXUINT, &ret)); - frames = (GstVideoFrame **) dpb->frames; for (i = 0; i < dpb->n_frames; i++) - gst_video_frame_unref (frames[i]); + gst_video_codec_frame_unref (dpb->frames[i]->frame); dpb->n_frames = 0; @@ -383,12 +389,10 @@ static void gst_h264_dpb_finalize (GObject * object) { GstH264DPB *dpb = GST_H264_DPB (object); - GstVideoFrame **frames; guint i; - frames = (GstVideoFrame **) dpb->frames; for (i = 0; i < dpb->n_frames; i++) - gst_video_frame_unref (frames[i]); + gst_video_codec_frame_unref (dpb->frames[i]->frame); G_OBJECT_CLASS (gst_h264_dpb_parent_class)->finalize (object); } diff --git a/sys/vdpau/h264/gsth264dpb.h b/sys/vdpau/h264/gsth264dpb.h index a68904c5a..81956390d 100644 --- a/sys/vdpau/h264/gsth264dpb.h +++ b/sys/vdpau/h264/gsth264dpb.h @@ -22,16 +22,15 @@ #define _GST_H264_DPB_H_ #include <glib-object.h> +#include <vdpau/vdpau.h> -#include "../gstvdp/gstvdpvideobuffer.h" - -#include "gsth264frame.h" +#include <gst/video/video.h> +#include <gst/codecparsers/gsth264meta.h> G_BEGIN_DECLS #define MAX_DPB_SIZE 16 - #define GST_TYPE_H264_DPB (gst_h264_dpb_get_type ()) #define GST_H264_DPB(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_H264_DPB, GstH264DPB)) #define GST_H264_DPB_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_H264_DPB, GstH264DPBClass)) @@ -42,21 +41,33 @@ G_BEGIN_DECLS typedef struct _GstH264DPB GstH264DPB; typedef struct _GstH264DPBClass GstH264DPBClass; +typedef struct _GstH264Frame +{ + GstVideoCodecFrame *frame; + + guint poc; + guint16 frame_idx; + gboolean is_reference; + gboolean is_long_term; + gboolean output_needed; +} GstH264Frame; + + typedef GstFlowReturn (*GstH264DPBOutputFunc) (GstH264DPB *dpb, GstH264Frame *h264_frame, gpointer user_data); struct _GstH264DPB { GObject parent_instance; - /* private */ + /* private */ GstH264Frame *frames[MAX_DPB_SIZE]; guint n_frames; guint max_frames; gint max_longterm_frame_idx; - GstH264DPBOutputFunc output; - gpointer user_data; + GstH264DPBOutputFunc output; + gpointer user_data; }; struct _GstH264DPBClass diff --git a/sys/vdpau/h264/gsth264frame.c b/sys/vdpau/h264/gsth264frame.c deleted file mode 100644 index e13d7c917..000000000 --- a/sys/vdpau/h264/gsth264frame.c +++ /dev/null @@ -1,105 +0,0 @@ -/* -* GStreamer -* Copyright (C) 2009 Carl-Anton Ingmarsson <ca.ingmarsson@gmail.com> -* -* 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., 51 Franklin St, Fifth Floor, -* Boston, MA 02110-1301, USA. -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "gsth264frame.h" - -GST_DEBUG_CATEGORY_STATIC (gst_h264_frame_debug); -#define GST_CAT_DEFAULT gst_h264_frame_debug - -#define DEBUG_INIT(bla) \ -GST_DEBUG_CATEGORY_INIT (gst_h264_frame_debug, "gsth264frame", 0, "H264 Frame"); - -void -gst_h264_frame_add_slice (GstH264Frame * h264_frame, GstBuffer * buf) -{ - gst_buffer_ref (buf); - g_ptr_array_add (h264_frame->slices, buf); -} - -GstH264Frame * -gst_h264_frame_new (void) -{ - GstH264Frame *frame; - - frame = (GstH264Frame *) gst_mini_object_new (GST_TYPE_H264_FRAME); - - return frame; -} - -static GObjectClass *gst_h264_frame_parent_class; - -static void -gst_h264_frame_finalize (GstH264Frame * h264_frame) -{ - g_ptr_array_foreach (h264_frame->slices, (GFunc) gst_buffer_unref, NULL); - - g_ptr_array_unref (h264_frame->slices); - - GST_MINI_OBJECT_CLASS (gst_h264_frame_parent_class)->finalize - (GST_MINI_OBJECT (h264_frame)); -} - -static void -gst_h264_frame_init (GstH264Frame * h264_frame, gpointer g_class) -{ - h264_frame->slices = g_ptr_array_new (); -} - -static void -gst_h264_frame_class_init (gpointer g_class, gpointer class_data) -{ - GstMiniObjectClass *mini_object_class = GST_MINI_OBJECT_CLASS (g_class); - - gst_h264_frame_parent_class = g_type_class_peek_parent (g_class); - - mini_object_class->finalize = (GstMiniObjectFinalizeFunction) - gst_h264_frame_finalize; -} - - -GType -gst_h264_frame_get_type (void) -{ - static GType _gst_h264_frame_type = 0; - - if (G_UNLIKELY (_gst_h264_frame_type == 0)) { - static const GTypeInfo info = { - sizeof (GstH264FrameClass), - NULL, - NULL, - gst_h264_frame_class_init, - NULL, - NULL, - sizeof (GstH264Frame), - 0, - (GInstanceInitFunc) gst_h264_frame_init, - NULL - }; - _gst_h264_frame_type = g_type_register_static (GST_TYPE_VIDEO_FRAME, - "GstH264Frame", &info, 0); - - DEBUG_INIT (); - } - return _gst_h264_frame_type; -} diff --git a/sys/vdpau/h264/gsth264frame.h b/sys/vdpau/h264/gsth264frame.h deleted file mode 100644 index 10c185a5b..000000000 --- a/sys/vdpau/h264/gsth264frame.h +++ /dev/null @@ -1,65 +0,0 @@ -/* -* GStreamer -* Copyright (C) 2009 Carl-Anton Ingmarsson <ca.ingmarsson@gmail.com> -* -* 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., 51 Franklin St, Fifth Floor, -* Boston, MA 02110-1301, USA. -*/ - -#ifndef _GST_H264_FRAME_H_ -#define _GST_H264_FRAME_H_ - -#include <gst/gst.h> - -#include "../basevideodecoder/gstvideoframe.h" - -#include "gsth264parser.h" - -#define GST_TYPE_H264_FRAME (gst_h264_frame_get_type()) -#define GST_IS_H264_FRAME(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_H264_FRAME)) -#define GST_H264_FRAME(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_H264_FRAME, GstH264Frame)) -#define GST_H264_FRAME_CAST(obj) ((GstH264Frame *)obj) - -#define GST_H264_FRAME_GOT_PRIMARY GST_VIDEO_FRAME_FLAG_LAST - -typedef struct _GstH264Frame GstH264Frame; -typedef struct _GstH264FrameClass GstH264FrameClass; - -struct _GstH264Frame -{ - GstVideoFrame video_frame; - - GstH264Slice slice_hdr; - GPtrArray *slices; - - guint poc; - guint16 frame_idx; - gboolean is_reference; - gboolean is_long_term; - gboolean output_needed; -}; - -struct _GstH264FrameClass -{ - GstVideoFrameClass video_frame_class; -}; - -void gst_h264_frame_add_slice (GstH264Frame *h264_frame, GstBuffer *buf); - -GstH264Frame *gst_h264_frame_new (void); - -GType gst_h264_frame_get_type (void); - -#endif
\ No newline at end of file diff --git a/sys/vdpau/h264/gsth264parser.c b/sys/vdpau/h264/gsth264parser.c deleted file mode 100644 index 2b7c73e56..000000000 --- a/sys/vdpau/h264/gsth264parser.c +++ /dev/null @@ -1,1253 +0,0 @@ -/* GStreamer - * - * Copyright (C) 2009 Carl-Anton Ingmarsson <ca.ingmarsson@gmail.com>. - * - * 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., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include <string.h> - -#include "gstnalreader.h" - -#include "gsth264parser.h" - -/* default scaling_lists according to Table 7-2 */ -const guint8 default_4x4_intra[16] = - { 6, 13, 13, 20, 20, 20, 28, 28, 28, 28, 32, 32, - 32, 37, 37, 42 -}; - -const guint8 default_4x4_inter[16] = - { 10, 14, 14, 20, 20, 20, 24, 24, 24, 24, 27, 27, - 27, 30, 30, 34 -}; - -const guint8 default_8x8_intra[64] = - { 6, 10, 10, 13, 11, 13, 16, 16, 16, 16, 18, 18, - 18, 18, 18, 23, 23, 23, 23, 23, 23, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, - 27, 27, 27, 27, 27, 29, 29, 29, 29, 29, 29, 29, 31, 31, 31, 31, 31, 31, 33, - 33, 33, 33, 33, 36, 36, 36, 36, 38, 38, 38, 40, 40, 42 -}; - -const guint8 default_8x8_inter[64] = - { 9, 13, 13, 15, 13, 15, 17, 17, 17, 17, 19, 19, - 19, 19, 19, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 24, 24, 24, - 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27, 27, 27, 28, - 28, 28, 28, 28, 30, 30, 30, 30, 32, 32, 32, 33, 33, 35 -}; - -const guint8 zigzag_8x8[64] = { - 0, 1, 8, 16, 9, 2, 3, 10, - 17, 24, 32, 25, 18, 11, 4, 5, - 12, 19, 26, 33, 40, 48, 41, 34, - 27, 20, 13, 6, 7, 14, 21, 28, - 35, 42, 49, 56, 57, 50, 43, 36, - 29, 22, 15, 23, 30, 37, 44, 51, - 58, 59, 52, 45, 38, 31, 39, 46, - 53, 60, 61, 54, 47, 55, 62, 63 -}; - -const guint8 zigzag_4x4[16] = { - 0, 1, 4, 8, - 5, 2, 3, 6, - 9, 12, 13, 10, - 7, 11, 14, 15, -}; - -#define CHECK_ALLOWED(val, min, max) { \ - if (val < min || val > max) { \ - GST_WARNING ("value not in allowed range. value: %d, range %d-%d", \ - val, min, max); \ - goto error; \ - } \ -} - -#define READ_UINT8(reader, val, nbits) { \ - if (!gst_nal_reader_get_bits_uint8 (reader, &val, nbits)) { \ - GST_WARNING ("failed to read uint8, nbits: %d", nbits); \ - goto error; \ - } \ -} - -#define READ_UINT16(reader, val, nbits) { \ - if (!gst_nal_reader_get_bits_uint16 (reader, &val, nbits)) { \ - GST_WARNING ("failed to read uint16, nbits: %d", nbits); \ - goto error; \ - } \ -} - -#define READ_UINT32(reader, val, nbits) { \ - if (!gst_nal_reader_get_bits_uint32 (reader, &val, nbits)) { \ - GST_WARNING ("failed to read uint32, nbits: %d", nbits); \ - goto error; \ - } \ -} - -#define READ_UINT64(reader, val, nbits) { \ - if (!gst_nal_reader_get_bits_uint64 (reader, &val, nbits)) { \ - GST_WARNING ("failed to read uint32, nbits: %d", nbits); \ - goto error; \ - } \ -} - -#define READ_UE(reader, val) { \ - if (!gst_nal_reader_get_ue (reader, &val)) { \ - GST_WARNING ("failed to read UE"); \ - goto error; \ - } \ -} - -#define READ_UE_ALLOWED(reader, val, min, max) { \ - guint32 tmp; \ - READ_UE (reader, tmp); \ - CHECK_ALLOWED (tmp, min, max); \ - val = tmp; \ -} - -#define READ_SE(reader, val) { \ - if (!gst_nal_reader_get_se (reader, &val)) { \ - GST_WARNING ("failed to read SE"); \ - goto error; \ - } \ -} - -#define READ_SE_ALLOWED(reader, val, min, max) { \ - gint32 tmp; \ - READ_SE (reader, tmp); \ - CHECK_ALLOWED (tmp, min, max); \ - val = tmp; \ -} - -GST_DEBUG_CATEGORY_STATIC (h264parser_debug); -#define GST_CAT_DEFAULT h264parser_debug - -#define _do_init \ - GST_DEBUG_CATEGORY_INIT (h264parser_debug, "h264parser", 0, \ - "H264 parser"); - -G_DEFINE_TYPE_WITH_CODE (GstH264Parser, gst_h264_parser, G_TYPE_OBJECT, - _do_init); - -static void -gst_h264_sequence_free (void *data) -{ - g_slice_free (GstH264Sequence, data); -} - -static gboolean -gst_h264_parse_hrd_parameters (GstH264HRDParameters * hrd, - GstNalReader * reader) -{ - guint SchedSelIdx; - - GST_DEBUG ("parsing \"HRD Parameters\""); - - READ_UE_ALLOWED (reader, hrd->cpb_cnt_minus1, 0, 31); - READ_UINT8 (reader, hrd->bit_rate_scale, 4); - READ_UINT8 (reader, hrd->cpb_size_scale, 4); - - for (SchedSelIdx = 0; SchedSelIdx <= hrd->cpb_cnt_minus1; SchedSelIdx++) { - READ_UE (reader, hrd->bit_rate_value_minus1[SchedSelIdx]); - READ_UE (reader, hrd->cpb_size_value_minus1[SchedSelIdx]); - } - - READ_UINT8 (reader, hrd->initial_cpb_removal_delay_length_minus1, 5); - READ_UINT8 (reader, hrd->cpb_removal_delay_length_minus1, 5); - READ_UINT8 (reader, hrd->dpb_output_delay_length_minus1, 5); - READ_UINT8 (reader, hrd->time_offset_length, 5); - - return TRUE; - -error: - GST_WARNING ("error parsing \"HRD Parameters\""); - return FALSE; - -} - -static gboolean -gst_h264_parse_vui_parameters (GstH264VUIParameters * vui, - GstNalReader * reader) -{ - guint8 aspect_ratio_info_present_flag; - guint8 video_signal_type_present_flag; - guint8 chroma_loc_info_present_flag; - - GST_DEBUG ("parsing \"VUI Parameters\""); - - /* set default values for fields that might not be present in the bitstream - and have valid defaults */ - vui->aspect_ratio_idc = 0; - vui->video_format = 5; - vui->video_full_range_flag = 0; - vui->colour_primaries = 2; - vui->transfer_characteristics = 2; - vui->matrix_coefficients = 2; - vui->chroma_sample_loc_type_top_field = 0; - vui->chroma_sample_loc_type_bottom_field = 0; - vui->low_delay_hrd_flag = 0; - - READ_UINT8 (reader, aspect_ratio_info_present_flag, 1); - if (aspect_ratio_info_present_flag) { - READ_UINT8 (reader, vui->aspect_ratio_idc, 8); - if (vui->aspect_ratio_idc == 255) { - READ_UINT16 (reader, vui->sar_width, 16); - READ_UINT16 (reader, vui->sar_height, 16); - } - } - - READ_UINT8 (reader, vui->overscan_info_present_flag, 1); - if (vui->overscan_info_present_flag) - READ_UINT8 (reader, vui->overscan_appropriate_flag, 1); - - READ_UINT8 (reader, video_signal_type_present_flag, 1); - if (video_signal_type_present_flag) { - guint8 colour_description_present_flag; - - READ_UINT8 (reader, vui->video_format, 3); - READ_UINT8 (reader, vui->video_full_range_flag, 1); - READ_UINT8 (reader, colour_description_present_flag, 1); - if (colour_description_present_flag) { - READ_UINT8 (reader, vui->colour_primaries, 8); - READ_UINT8 (reader, vui->transfer_characteristics, 8); - READ_UINT8 (reader, vui->matrix_coefficients, 8); - } - } - - READ_UINT8 (reader, chroma_loc_info_present_flag, 1); - if (chroma_loc_info_present_flag) { - READ_UE_ALLOWED (reader, vui->chroma_sample_loc_type_top_field, 0, 5); - READ_UE_ALLOWED (reader, vui->chroma_sample_loc_type_bottom_field, 0, 5); - } - - READ_UINT8 (reader, vui->timing_info_present_flag, 1); - if (vui->timing_info_present_flag) { - READ_UINT32 (reader, vui->num_units_in_tick, 32); - if (vui->num_units_in_tick == 0) - GST_WARNING - ("num_units_in_tick = 0 detected in stream (incompliant to H.264 E.2.1)."); - - READ_UINT32 (reader, vui->time_scale, 32); - if (vui->time_scale == 0) - GST_WARNING - ("time_scale = 0 detected in stream (incompliant to H.264 E.2.1)."); - - READ_UINT8 (reader, vui->fixed_frame_rate_flag, 1); - } - - READ_UINT8 (reader, vui->nal_hrd_parameters_present_flag, 1); - if (vui->nal_hrd_parameters_present_flag) { - if (!gst_h264_parse_hrd_parameters (&vui->nal_hrd_parameters, reader)) - goto error; - } - - READ_UINT8 (reader, vui->vcl_hrd_parameters_present_flag, 1); - if (vui->vcl_hrd_parameters_present_flag) { - if (!gst_h264_parse_hrd_parameters (&vui->vcl_hrd_parameters, reader)) - goto error; - } - - if (vui->nal_hrd_parameters_present_flag || - vui->vcl_hrd_parameters_present_flag) - READ_UINT8 (reader, vui->low_delay_hrd_flag, 1); - - READ_UINT8 (reader, vui->pic_struct_present_flag, 1); - - return TRUE; - -error: - GST_WARNING ("error parsing \"VUI Parameters\""); - return FALSE; -} - -static gboolean -gst_h264_parser_parse_scaling_list (GstNalReader * reader, - guint8 scaling_lists_4x4[6][16], guint8 scaling_lists_8x8[6][64], - const guint8 fallback_4x4_inter[16], const guint8 fallback_4x4_intra[16], - const guint8 fallback_8x8_inter[64], const guint8 fallback_8x8_intra[64], - guint8 n_lists) -{ - guint i; - - GST_DEBUG ("parsing scaling lists"); - - for (i = 0; i < 12; i++) { - gboolean use_default = FALSE; - - if (i < n_lists) { - guint8 scaling_list_present_flag; - - READ_UINT8 (reader, scaling_list_present_flag, 1); - if (scaling_list_present_flag) { - guint8 *scaling_list; - const guint8 *scan; - guint size; - guint j; - guint8 last_scale, next_scale; - - if (i < 6) { - scaling_list = scaling_lists_4x4[i]; - scan = zigzag_4x4; - size = 16; - } else { - scaling_list = scaling_lists_8x8[i - 6]; - scan = zigzag_8x8; - size = 64; - } - - last_scale = 8; - next_scale = 8; - for (j = 0; j < size; j++) { - if (next_scale != 0) { - gint32 delta_scale; - - READ_SE (reader, delta_scale); - next_scale = (last_scale + delta_scale) & 0xff; - } - if (j == 0 && next_scale == 0) { - use_default = TRUE; - break; - } - last_scale = scaling_list[scan[j]] = - (next_scale == 0) ? last_scale : next_scale; - } - } else - use_default = TRUE; - } else - use_default = TRUE; - - if (use_default) { - switch (i) { - case 0: - memcpy (scaling_lists_4x4[0], fallback_4x4_intra, 16); - break; - case 1: - memcpy (scaling_lists_4x4[1], scaling_lists_4x4[0], 16); - break; - case 2: - memcpy (scaling_lists_4x4[2], scaling_lists_4x4[1], 16); - break; - case 3: - memcpy (scaling_lists_4x4[3], fallback_4x4_inter, 16); - break; - case 4: - memcpy (scaling_lists_4x4[4], scaling_lists_4x4[3], 16); - break; - case 5: - memcpy (scaling_lists_4x4[5], scaling_lists_4x4[4], 16); - break; - case 6: - memcpy (scaling_lists_8x8[0], fallback_8x8_intra, 64); - break; - case 7: - memcpy (scaling_lists_8x8[1], fallback_8x8_inter, 64); - break; - case 8: - memcpy (scaling_lists_8x8[2], scaling_lists_8x8[0], 64); - break; - case 9: - memcpy (scaling_lists_8x8[3], scaling_lists_8x8[1], 64); - break; - case 10: - memcpy (scaling_lists_8x8[4], scaling_lists_8x8[2], 64); - break; - case 11: - memcpy (scaling_lists_8x8[5], scaling_lists_8x8[3], 64); - break; - - default: - break; - } - } - } - - return TRUE; - -error: - - GST_WARNING ("error parsing scaling lists"); - return FALSE; -} - -GstH264Sequence * -gst_h264_parser_parse_sequence (GstH264Parser * parser, guint8 * data, - guint size) -{ - GstNalReader reader = GST_NAL_READER_INIT (data, size); - GstH264Sequence *seq; - guint8 frame_cropping_flag; - - g_return_val_if_fail (GST_IS_H264_PARSER (parser), NULL); - g_return_val_if_fail (data != NULL, NULL); - g_return_val_if_fail (size > 0, NULL); - - GST_DEBUG ("parsing \"Sequence parameter set\""); - - seq = g_slice_new (GstH264Sequence); - - /* set default values for fields that might not be present in the bitstream - and have valid defaults */ - seq->chroma_format_idc = 1; - seq->separate_colour_plane_flag = 0; - seq->bit_depth_luma_minus8 = 0; - seq->bit_depth_chroma_minus8 = 0; - memset (seq->scaling_lists_4x4, 16, 96); - memset (seq->scaling_lists_8x8, 16, 384); - seq->mb_adaptive_frame_field_flag = 0; - seq->frame_crop_left_offset = 0; - seq->frame_crop_right_offset = 0; - seq->frame_crop_top_offset = 0; - seq->frame_crop_bottom_offset = 0; - - READ_UINT8 (&reader, seq->profile_idc, 8); - READ_UINT8 (&reader, seq->constraint_set0_flag, 1); - READ_UINT8 (&reader, seq->constraint_set1_flag, 1); - READ_UINT8 (&reader, seq->constraint_set2_flag, 1); - READ_UINT8 (&reader, seq->constraint_set3_flag, 1); - - /* skip reserved_zero_4bits */ - if (!gst_nal_reader_skip (&reader, 4)) - goto error; - - READ_UINT8 (&reader, seq->level_idc, 8); - - READ_UE_ALLOWED (&reader, seq->id, 0, 31); - - if (seq->profile_idc == 100 || seq->profile_idc == 110 || - seq->profile_idc == 122 || seq->profile_idc == 244 || - seq->profile_idc == 44 || seq->profile_idc == 83 || - seq->profile_idc == 86) { - READ_UE_ALLOWED (&reader, seq->chroma_format_idc, 0, 3); - if (seq->chroma_format_idc == 3) - READ_UINT8 (&reader, seq->separate_colour_plane_flag, 1); - - READ_UE_ALLOWED (&reader, seq->bit_depth_luma_minus8, 0, 6); - READ_UE_ALLOWED (&reader, seq->bit_depth_chroma_minus8, 0, 6); - READ_UINT8 (&reader, seq->qpprime_y_zero_transform_bypass_flag, 1); - - READ_UINT8 (&reader, seq->scaling_matrix_present_flag, 1); - if (seq->scaling_matrix_present_flag) { - guint8 n_lists; - - n_lists = (seq->chroma_format_idc != 3) ? 8 : 12; - if (!gst_h264_parser_parse_scaling_list (&reader, - seq->scaling_lists_4x4, seq->scaling_lists_8x8, - default_4x4_inter, default_4x4_intra, - default_8x8_inter, default_8x8_intra, n_lists)) - goto error; - } - } - - READ_UE_ALLOWED (&reader, seq->log2_max_frame_num_minus4, 0, 12); - /* calculate MaxFrameNum */ - seq->MaxFrameNum = 1 << (seq->log2_max_frame_num_minus4 + 4); - - READ_UE_ALLOWED (&reader, seq->pic_order_cnt_type, 0, 2); - if (seq->pic_order_cnt_type == 0) { - READ_UE_ALLOWED (&reader, seq->log2_max_pic_order_cnt_lsb_minus4, 0, 12); - } else if (seq->pic_order_cnt_type == 1) { - guint i; - - READ_UINT8 (&reader, seq->delta_pic_order_always_zero_flag, 1); - READ_SE (&reader, seq->offset_for_non_ref_pic); - READ_SE (&reader, seq->offset_for_top_to_bottom_field); - READ_UE_ALLOWED (&reader, seq->num_ref_frames_in_pic_order_cnt_cycle, 0, - 255); - for (i = 0; i < seq->num_ref_frames_in_pic_order_cnt_cycle; i++) - READ_SE (&reader, seq->offset_for_ref_frame[i]); - } - - READ_UE (&reader, seq->num_ref_frames); - READ_UINT8 (&reader, seq->gaps_in_frame_num_value_allowed_flag, 1); - READ_UE (&reader, seq->pic_width_in_mbs_minus1); - READ_UE (&reader, seq->pic_height_in_map_units_minus1); - READ_UINT8 (&reader, seq->frame_mbs_only_flag, 1); - - if (!seq->frame_mbs_only_flag) - READ_UINT8 (&reader, seq->mb_adaptive_frame_field_flag, 1); - - READ_UINT8 (&reader, seq->direct_8x8_inference_flag, 1); - READ_UINT8 (&reader, frame_cropping_flag, 1); - if (frame_cropping_flag) { - READ_UE (&reader, seq->frame_crop_left_offset); - READ_UE (&reader, seq->frame_crop_right_offset); - READ_UE (&reader, seq->frame_crop_top_offset); - READ_UE (&reader, seq->frame_crop_bottom_offset); - } - - READ_UINT8 (&reader, seq->vui_parameters_present_flag, 1); - if (seq->vui_parameters_present_flag) { - if (!gst_h264_parse_vui_parameters (&seq->vui_parameters, &reader)) - goto error; - } - - /* calculate ChromaArrayType */ - if (seq->separate_colour_plane_flag) - seq->ChromaArrayType = 0; - else - seq->ChromaArrayType = seq->chroma_format_idc; - - GST_DEBUG ("adding sequence parameter set with id: %d to hash table", - seq->id); - g_hash_table_replace (parser->sequences, &seq->id, seq); - return seq; - -error: - GST_WARNING ("error parsing \"Sequence parameter set\""); - - gst_h264_sequence_free (seq); - return NULL; -} - -static void -gst_h264_picture_free (void *data) -{ - GstH264Picture *pic = (GstH264Picture *) data; - - if (pic->slice_group_id) - g_free (pic->slice_group_id); - - g_slice_free (GstH264Picture, data); -} - -static gboolean -gst_h264_parser_more_data (GstNalReader * reader) -{ - guint remaining; - - remaining = gst_nal_reader_get_remaining (reader); - if (remaining == 0) - return FALSE; - - if (remaining <= 8) { - guint8 rbsp_stop_one_bit; - - if (!gst_nal_reader_peek_bits_uint8 (reader, &rbsp_stop_one_bit, 1)) - return FALSE; - - if (rbsp_stop_one_bit == 1) { - guint8 zero_bits; - - if (remaining == 1) - return FALSE; - - if (!gst_nal_reader_peek_bits_uint8 (reader, &zero_bits, remaining)) - return FALSE; - - if ((zero_bits - (1 << (remaining - 1))) == 0) - return FALSE; - } - } - - return TRUE; -} - -GstH264Picture * -gst_h264_parser_parse_picture (GstH264Parser * parser, guint8 * data, - guint size) -{ - GstNalReader reader = GST_NAL_READER_INIT (data, size); - GstH264Picture *pic; - gint seq_parameter_set_id; - GstH264Sequence *seq; - guint8 pic_scaling_matrix_present_flag; - - g_return_val_if_fail (GST_IS_H264_PARSER (parser), NULL); - g_return_val_if_fail (data != NULL, NULL); - g_return_val_if_fail (size > 0, NULL); - - GST_DEBUG ("parsing \"Picture parameter set\""); - - pic = g_slice_new (GstH264Picture); - - READ_UE_ALLOWED (&reader, pic->id, 0, 255); - READ_UE_ALLOWED (&reader, seq_parameter_set_id, 0, 31); - seq = g_hash_table_lookup (parser->sequences, &seq_parameter_set_id); - if (!seq) { - GST_WARNING ("couldn't find associated sequence parameter set with id: %d", - seq_parameter_set_id); - goto error; - } - pic->sequence = seq; - - /* set default values for fields that might not be present in the bitstream - and have valid defaults */ - pic->slice_group_id = NULL; - pic->transform_8x8_mode_flag = 0; - memcpy (&pic->scaling_lists_4x4, &seq->scaling_lists_4x4, 96); - memcpy (&pic->scaling_lists_8x8, &seq->scaling_lists_8x8, 384); - - READ_UINT8 (&reader, pic->entropy_coding_mode_flag, 1); - READ_UINT8 (&reader, pic->pic_order_present_flag, 1); - READ_UE_ALLOWED (&reader, pic->num_slice_groups_minus1, 0, 7); - if (pic->num_slice_groups_minus1 > 0) { - READ_UE_ALLOWED (&reader, pic->slice_group_map_type, 0, 6); - if (pic->slice_group_map_type == 0) { - gint i; - - for (i = 0; i <= pic->num_slice_groups_minus1; i++) - READ_UE (&reader, pic->run_length_minus1[i]); - } else if (pic->slice_group_map_type == 2) { - gint i; - - for (i = 0; i <= pic->num_slice_groups_minus1; i++) { - READ_UE (&reader, pic->top_left[i]); - READ_UE (&reader, pic->bottom_right[i]); - } - } else if (pic->slice_group_map_type >= 3 && pic->slice_group_map_type <= 5) { - READ_UINT8 (&reader, pic->slice_group_change_direction_flag, 1); - READ_UE (&reader, pic->slice_group_change_rate_minus1); - } else if (pic->slice_group_map_type == 6) { - gint bits; - gint i; - - READ_UE (&reader, pic->pic_size_in_map_units_minus1); - bits = g_bit_storage (pic->num_slice_groups_minus1); - - pic->slice_group_id = - g_new (guint8, pic->pic_size_in_map_units_minus1 + 1); - for (i = 0; i <= pic->pic_size_in_map_units_minus1; i++) - READ_UINT8 (&reader, pic->slice_group_id[i], bits); - } - } - - READ_UE_ALLOWED (&reader, pic->num_ref_idx_l0_active_minus1, 0, 31); - READ_UE_ALLOWED (&reader, pic->num_ref_idx_l1_active_minus1, 0, 31); - READ_UINT8 (&reader, pic->weighted_pred_flag, 1); - READ_UINT8 (&reader, pic->weighted_bipred_idc, 2); - READ_SE_ALLOWED (&reader, pic->pic_init_qp_minus26, -26, 25); - READ_SE_ALLOWED (&reader, pic->pic_init_qs_minus26, -26, 25); - READ_SE_ALLOWED (&reader, pic->chroma_qp_index_offset, -12, 12); - pic->second_chroma_qp_index_offset = pic->chroma_qp_index_offset; - READ_UINT8 (&reader, pic->deblocking_filter_control_present_flag, 1); - READ_UINT8 (&reader, pic->constrained_intra_pred_flag, 1); - READ_UINT8 (&reader, pic->redundant_pic_cnt_present_flag, 1); - - if (!gst_h264_parser_more_data (&reader)) - goto done; - - READ_UINT8 (&reader, pic->transform_8x8_mode_flag, 1); - - READ_UINT8 (&reader, pic_scaling_matrix_present_flag, 1); - if (pic_scaling_matrix_present_flag) { - guint8 n_lists; - - n_lists = 6 + ((seq->chroma_format_idc != 3) ? 2 : 6) * - pic->transform_8x8_mode_flag; - - if (seq->scaling_matrix_present_flag) { - if (!gst_h264_parser_parse_scaling_list (&reader, - pic->scaling_lists_4x4, pic->scaling_lists_8x8, - seq->scaling_lists_4x4[0], seq->scaling_lists_4x4[3], - seq->scaling_lists_8x8[0], seq->scaling_lists_8x8[3], n_lists)) - goto error; - } else { - if (!gst_h264_parser_parse_scaling_list (&reader, - pic->scaling_lists_4x4, pic->scaling_lists_8x8, - default_4x4_inter, default_4x4_intra, - default_8x8_inter, default_8x8_intra, n_lists)) - goto error; - } - } - - READ_SE_ALLOWED (&reader, pic->second_chroma_qp_index_offset, -12, 12); - -done: - GST_DEBUG ("adding picture parameter set with id: %d to hash table", pic->id); - g_hash_table_replace (parser->pictures, &pic->id, pic); - return pic; - -error: - GST_WARNING ("error parsing \"Picture parameter set\""); - - gst_h264_picture_free (pic); - return NULL; -} - -static gboolean -gst_h264_slice_parse_pred_weight_table (GstH264Slice * slice, - GstNalReader * reader, - const GstH264Sequence * seq, const GstH264Picture * pic) -{ - GstH264PredWeightTable *p; - gint i; - - GST_DEBUG ("parsing \"Prediction weight table\""); - - p = &slice->pred_weight_table; - - READ_UE_ALLOWED (reader, p->luma_log2_weight_denom, 0, 7); - /* set default values */ - memset (p->luma_weight_l0, 1 << p->luma_log2_weight_denom, 32); - memset (p->luma_offset_l0, 0, 32); - - if (seq->ChromaArrayType != 0) { - READ_UE_ALLOWED (reader, p->chroma_log2_weight_denom, 0, 7); - /* set default values */ - memset (p->chroma_weight_l0, 1 << p->chroma_log2_weight_denom, 64); - memset (p->chroma_offset_l0, 0, 64); - } - - for (i = 0; i <= slice->num_ref_idx_l0_active_minus1; i++) { - guint8 luma_weight_l0_flag; - - READ_UINT8 (reader, luma_weight_l0_flag, 1); - if (luma_weight_l0_flag) { - READ_SE_ALLOWED (reader, p->luma_weight_l0[i], -128, 127); - READ_SE_ALLOWED (reader, p->luma_offset_l0[i], -128, 127); - } - if (seq->ChromaArrayType != 0) { - guint8 chroma_weight_l0_flag; - gint j; - - READ_UINT8 (reader, chroma_weight_l0_flag, 1); - if (chroma_weight_l0_flag) { - for (j = 0; j < 2; j++) { - READ_SE_ALLOWED (reader, p->chroma_weight_l0[i][j], -128, 127); - READ_SE_ALLOWED (reader, p->chroma_offset_l0[i][j], -128, 127); - } - } - } - } - - if (GST_H264_IS_B_SLICE (slice->type)) { - for (i = 0; i <= slice->num_ref_idx_l1_active_minus1; i++) { - guint8 luma_weight_l1_flag; - - READ_UINT8 (reader, luma_weight_l1_flag, 1); - if (luma_weight_l1_flag) { - READ_SE_ALLOWED (reader, p->luma_weight_l1[i], -128, 127); - READ_SE_ALLOWED (reader, p->luma_offset_l1[i], -128, 127); - } - if (seq->ChromaArrayType != 0) { - guint8 chroma_weight_l1_flag; - gint j; - - READ_UINT8 (reader, chroma_weight_l1_flag, 1); - if (chroma_weight_l1_flag) { - for (j = 0; j < 2; j++) { - READ_SE_ALLOWED (reader, p->chroma_weight_l1[i][j], -128, 127); - READ_SE_ALLOWED (reader, p->chroma_offset_l1[i][j], -128, 127); - } - } - } - } - } - - return TRUE; - -error: - GST_WARNING ("error parsing \"Prediction weight table\""); - return FALSE; -} - -static gboolean -gst_h264_slice_parse_ref_pic_list_reordering (GstH264Slice * slice, - GstNalReader * reader) -{ - GST_DEBUG ("parsing \"Reference picture list reordering\""); - - if (!GST_H264_IS_I_SLICE (slice->type) && !GST_H264_IS_SI_SLICE (slice->type)) { - guint8 ref_pic_list_reordering_flag_l0; - guint8 reordering_of_pic_nums_idc; - - READ_UINT8 (reader, ref_pic_list_reordering_flag_l0, 1); - if (ref_pic_list_reordering_flag_l0) - do { - READ_UE_ALLOWED (reader, reordering_of_pic_nums_idc, 0, 3); - if (reordering_of_pic_nums_idc == 0 || reordering_of_pic_nums_idc == 1) { - guint32 abs_diff_pic_num_minus1 G_GNUC_UNUSED; - - READ_UE_ALLOWED (reader, abs_diff_pic_num_minus1, 0, - slice->MaxPicNum - 1); - } else if (reordering_of_pic_nums_idc == 2) { - guint32 long_term_pic_num; - - READ_UE (reader, long_term_pic_num); - } - } while (reordering_of_pic_nums_idc != 3); - } - - if (GST_H264_IS_B_SLICE (slice->type)) { - guint8 ref_pic_list_reordering_flag_l1; - guint8 reordering_of_pic_nums_idc; - - READ_UINT8 (reader, ref_pic_list_reordering_flag_l1, 1); - if (ref_pic_list_reordering_flag_l1) - do { - READ_UE_ALLOWED (reader, reordering_of_pic_nums_idc, 0, 3); - if (reordering_of_pic_nums_idc == 0 || reordering_of_pic_nums_idc == 1) { - guint32 abs_diff_num_minus1; - READ_UE (reader, abs_diff_num_minus1); - } else if (reordering_of_pic_nums_idc == 2) { - guint32 long_term_pic_num; - - READ_UE (reader, long_term_pic_num); - } - } while (reordering_of_pic_nums_idc != 3); - } - - return TRUE; - -error: - GST_WARNING ("error parsing \"Reference picture list reordering\""); - return FALSE; -} - -static gboolean -gst_h264_slice_parse_dec_ref_pic_marking (GstH264Slice * slice, - GstNalReader * reader) -{ - GstH264DecRefPicMarking *m; - - GST_DEBUG ("parsing \"Decoded reference picture marking\""); - - m = &slice->dec_ref_pic_marking; - - if (slice->nal_unit.IdrPicFlag) { - READ_UINT8 (reader, m->no_output_of_prior_pics_flag, 1); - READ_UINT8 (reader, m->long_term_reference_flag, 1); - } else { - READ_UINT8 (reader, m->adaptive_ref_pic_marking_mode_flag, 1); - if (m->adaptive_ref_pic_marking_mode_flag) { - guint8 memory_management_control_operation; - - m->n_ref_pic_marking = 0; - while (1) { - READ_UE_ALLOWED (reader, memory_management_control_operation, 0, 6); - if (memory_management_control_operation == 0) - break; - - m->ref_pic_marking[m-> - n_ref_pic_marking].memory_management_control_operation = - memory_management_control_operation; - - if (memory_management_control_operation == 1 || - memory_management_control_operation == 3) - READ_UE (reader, - m->ref_pic_marking[m-> - n_ref_pic_marking].difference_of_pic_nums_minus1); - - if (memory_management_control_operation == 2) - READ_UE (reader, - m->ref_pic_marking[m->n_ref_pic_marking].long_term_pic_num); - - if (memory_management_control_operation == 3 || - memory_management_control_operation == 6) - READ_UE (reader, - m->ref_pic_marking[m->n_ref_pic_marking].long_term_frame_idx); - - if (memory_management_control_operation == 4) - READ_UE (reader, - m->ref_pic_marking[m-> - n_ref_pic_marking].max_long_term_frame_idx_plus1); - - m->n_ref_pic_marking++; - } - } - } - - return TRUE; - -error: - GST_WARNING ("error parsing \"Decoded reference picture marking\""); - return FALSE; -} - -gboolean -gst_h264_parser_parse_slice_header (GstH264Parser * parser, - GstH264Slice * slice, guint8 * data, guint size, GstNalUnit nal_unit) -{ - GstNalReader reader = GST_NAL_READER_INIT (data, size); - gint pic_parameter_set_id; - GstH264Picture *pic; - GstH264Sequence *seq; - - g_return_val_if_fail (GST_IS_H264_PARSER (parser), FALSE); - g_return_val_if_fail (slice != NULL, FALSE); - g_return_val_if_fail (data != NULL, FALSE); - g_return_val_if_fail (size > 0, FALSE); - - GST_DEBUG ("parsing \"Slice header\""); - - memcpy (&slice->nal_unit, &nal_unit, sizeof (GstNalUnit)); - - READ_UE (&reader, slice->first_mb_in_slice); - READ_UE (&reader, slice->type); - - READ_UE_ALLOWED (&reader, pic_parameter_set_id, 0, 255); - pic = g_hash_table_lookup (parser->pictures, &pic_parameter_set_id); - if (!pic) { - GST_WARNING ("couldn't find associated picture parameter set with id: %d", - pic_parameter_set_id); - goto error; - } - slice->picture = pic; - seq = pic->sequence; - - /* set default values for fields that might not be present in the bitstream - and have valid defaults */ - slice->field_pic_flag = 0; - slice->bottom_field_flag = 0; - slice->delta_pic_order_cnt_bottom = 0; - slice->delta_pic_order_cnt[0] = 0; - slice->delta_pic_order_cnt[1] = 0; - slice->redundant_pic_cnt = 0; - slice->num_ref_idx_l0_active_minus1 = pic->num_ref_idx_l0_active_minus1; - slice->num_ref_idx_l1_active_minus1 = pic->num_ref_idx_l1_active_minus1; - - if (seq->separate_colour_plane_flag) - READ_UINT8 (&reader, slice->colour_plane_id, 2); - - READ_UINT16 (&reader, slice->frame_num, seq->log2_max_frame_num_minus4 + 4); - - if (!seq->frame_mbs_only_flag) { - READ_UINT8 (&reader, slice->field_pic_flag, 1); - if (slice->field_pic_flag) - READ_UINT8 (&reader, slice->bottom_field_flag, 1); - } - - /* calculate MaxPicNum */ - if (slice->field_pic_flag) - slice->MaxPicNum = seq->MaxFrameNum; - else - slice->MaxPicNum = 2 * seq->MaxFrameNum; - - if (nal_unit.type == 5) - READ_UE_ALLOWED (&reader, slice->idr_pic_id, 0, 65535); - - if (seq->pic_order_cnt_type == 0) { - READ_UINT16 (&reader, slice->pic_order_cnt_lsb, - seq->log2_max_pic_order_cnt_lsb_minus4 + 4); - if (pic->pic_order_present_flag && !slice->field_pic_flag) - READ_SE (&reader, slice->delta_pic_order_cnt_bottom); - } - - if (seq->pic_order_cnt_type == 1 && !seq->delta_pic_order_always_zero_flag) { - READ_SE (&reader, slice->delta_pic_order_cnt[0]); - if (pic->pic_order_present_flag && !slice->field_pic_flag) - READ_SE (&reader, slice->delta_pic_order_cnt[1]); - } - - if (pic->redundant_pic_cnt_present_flag) - READ_UE_ALLOWED (&reader, slice->redundant_pic_cnt, 0, 127); - - if (GST_H264_IS_B_SLICE (slice->type)) - READ_UINT8 (&reader, slice->direct_spatial_mv_pred_flag, 1); - - if (GST_H264_IS_P_SLICE (slice->type) || - GST_H264_IS_SP_SLICE (slice->type) || GST_H264_IS_B_SLICE (slice->type)) { - guint8 num_ref_idx_active_override_flag; - - READ_UINT8 (&reader, num_ref_idx_active_override_flag, 1); - if (num_ref_idx_active_override_flag) { - READ_UE_ALLOWED (&reader, slice->num_ref_idx_l0_active_minus1, 0, 31); - - if (GST_H264_IS_B_SLICE (slice->type)) - READ_UE_ALLOWED (&reader, slice->num_ref_idx_l1_active_minus1, 0, 31); - } - } - - if (!gst_h264_slice_parse_ref_pic_list_reordering (slice, &reader)) - return FALSE; - - if ((pic->weighted_pred_flag && (GST_H264_IS_P_SLICE (slice->type) || - GST_H264_IS_SP_SLICE (slice->type))) - || (pic->weighted_bipred_idc == 1 && GST_H264_IS_B_SLICE (slice->type))) { - if (!gst_h264_slice_parse_pred_weight_table (slice, &reader, seq, pic)) - return FALSE; - } - - if (nal_unit.ref_idc != 0) { - if (!gst_h264_slice_parse_dec_ref_pic_marking (slice, &reader)) - return FALSE; - } - - return TRUE; - -error: - GST_WARNING ("error parsing \"Slice header\""); - return FALSE; -} - -static gboolean -gst_h264_parser_parse_buffering_period (GstH264Parser * parser, - GstH264BufferingPeriod * per, guint8 * data, guint size) -{ - GstNalReader reader = GST_NAL_READER_INIT (data, size); - - GstH264Sequence *seq; - guint8 seq_parameter_set_id; - - GST_DEBUG ("parsing \"Buffering period\""); - - READ_UE_ALLOWED (&reader, seq_parameter_set_id, 0, 31); - seq = g_hash_table_lookup (parser->sequences, &seq_parameter_set_id); - if (!seq) { - GST_WARNING ("couldn't find associated sequence parameter set with id: %d", - seq_parameter_set_id); - goto error; - } - per->seq = seq; - - if (seq->vui_parameters_present_flag) { - GstH264VUIParameters *vui = &seq->vui_parameters; - - if (vui->nal_hrd_parameters_present_flag) { - GstH264HRDParameters *hrd = &vui->nal_hrd_parameters; - guint8 SchedSelIdx; - - for (SchedSelIdx = 0; SchedSelIdx <= hrd->cpb_cnt_minus1; SchedSelIdx++) { - READ_UINT8 (&reader, per->nal_initial_cpb_removal_delay[SchedSelIdx], - 5); - READ_UINT8 (&reader, - per->nal_initial_cpb_removal_delay_offset[SchedSelIdx], 5); - } - } - - if (vui->vcl_hrd_parameters_present_flag) { - GstH264HRDParameters *hrd = &vui->vcl_hrd_parameters; - guint8 SchedSelIdx; - - for (SchedSelIdx = 0; SchedSelIdx <= hrd->cpb_cnt_minus1; SchedSelIdx++) { - READ_UINT8 (&reader, per->vcl_initial_cpb_removal_delay[SchedSelIdx], - 5); - READ_UINT8 (&reader, - per->vcl_initial_cpb_removal_delay_offset[SchedSelIdx], 5); - } - } - } - - return TRUE; - -error: - GST_WARNING ("error parsing \"Buffering period\""); - return FALSE; -} - -static gboolean -gst_h264_parse_clock_timestamp (GstH264ClockTimestamp * tim, - GstH264VUIParameters * vui, GstNalReader * reader) -{ - guint8 full_timestamp_flag; - guint8 time_offset_length; - - GST_DEBUG ("parsing \"Clock timestamp\""); - - /* defalt values */ - tim->time_offset = 0; - - READ_UINT8 (reader, tim->ct_type, 2); - READ_UINT8 (reader, tim->nuit_field_based_flag, 1); - READ_UINT8 (reader, tim->counting_type, 5); - READ_UINT8 (reader, full_timestamp_flag, 1); - READ_UINT8 (reader, tim->discontinuity_flag, 1); - READ_UINT8 (reader, tim->cnt_dropped_flag, 1); - READ_UINT8 (reader, tim->n_frames, 8); - - if (full_timestamp_flag) { - tim->seconds_flag = TRUE; - READ_UINT8 (reader, tim->seconds_value, 6); - - tim->minutes_flag = TRUE; - READ_UINT8 (reader, tim->minutes_value, 6); - - tim->hours_flag = TRUE; - READ_UINT8 (reader, tim->hours_value, 5); - } else { - READ_UINT8 (reader, tim->seconds_flag, 1); - if (tim->seconds_flag) { - READ_UINT8 (reader, tim->seconds_value, 6); - READ_UINT8 (reader, tim->minutes_flag, 1); - if (tim->minutes_flag) { - READ_UINT8 (reader, tim->minutes_value, 6); - READ_UINT8 (reader, tim->hours_flag, 1); - if (tim->hours_flag) - READ_UINT8 (reader, tim->hours_value, 5); - } - } - } - - time_offset_length = 0; - if (vui->nal_hrd_parameters_present_flag) - time_offset_length = vui->nal_hrd_parameters.time_offset_length; - else if (vui->vcl_hrd_parameters_present_flag) - time_offset_length = vui->vcl_hrd_parameters.time_offset_length; - - if (time_offset_length > 0) - READ_UINT32 (reader, tim->time_offset, time_offset_length); - -error: - GST_WARNING ("error parsing \"Clock timestamp\""); - return FALSE; -} - -static gboolean -gst_h264_parser_parse_pic_timing (GstH264Parser * parser, GstH264Sequence * seq, - GstH264PicTiming * tim, guint8 * data, guint size) -{ - GstNalReader reader = GST_NAL_READER_INIT (data, size); - - GST_DEBUG ("parsing \"Picture timing\""); - - if (!seq) { - GST_WARNING ("didn't get the associated sequence paramater set for the " - "current access unit"); - goto error; - } - - /* default values */ - memset (tim->clock_timestamp_flag, 0, 3); - - if (seq->vui_parameters_present_flag) { - GstH264VUIParameters *vui = &seq->vui_parameters; - - if (vui->nal_hrd_parameters_present_flag) { - READ_UINT8 (&reader, tim->cpb_removal_delay, - vui->nal_hrd_parameters.cpb_removal_delay_length_minus1 + 1); - READ_UINT8 (&reader, tim->dpb_output_delay, - vui->nal_hrd_parameters.dpb_output_delay_length_minus1 + 1); - } else if (vui->nal_hrd_parameters_present_flag) { - READ_UINT8 (&reader, tim->cpb_removal_delay, - vui->vcl_hrd_parameters.cpb_removal_delay_length_minus1 + 1); - READ_UINT8 (&reader, tim->dpb_output_delay, - vui->vcl_hrd_parameters.dpb_output_delay_length_minus1 + 1); - } - - if (vui->pic_struct_present_flag) { - const guint8 num_clock_ts_table[9] = { - 1, 1, 1, 2, 2, 3, 3, 2, 3 - }; - guint8 NumClockTs; - guint i; - - READ_UINT8 (&reader, tim->pic_struct, 4); - CHECK_ALLOWED (tim->pic_struct, 0, 8); - - NumClockTs = num_clock_ts_table[tim->pic_struct]; - for (i = 0; i < NumClockTs; i++) { - READ_UINT8 (&reader, tim->clock_timestamp_flag[i], 1); - if (tim->clock_timestamp_flag[i]) { - if (!gst_h264_parse_clock_timestamp (&tim->clock_timestamp[i], vui, - &reader)) - goto error; - } - } - } - } - - return TRUE; - -error: - GST_WARNING ("error parsing \"Picture timing\""); - return FALSE; -} - -gboolean -gst_h264_parser_parse_sei_message (GstH264Parser * parser, - GstH264Sequence * seq, GstH264SEIMessage * sei, guint8 * data, guint size) -{ - GstNalReader reader; - - guint32 payloadSize; - guint8 payload_type_byte, payload_size_byte; - - guint8 *payload_data; - guint remaining, payload_size; - gboolean res; - - g_return_val_if_fail (GST_IS_H264_PARSER (parser), FALSE); - g_return_val_if_fail (sei != NULL, FALSE); - g_return_val_if_fail (data != NULL, FALSE); - g_return_val_if_fail (size > 0, FALSE); - - GST_DEBUG ("parsing \"Sei message\""); - - gst_nal_reader_init (&reader, data, size); - - sei->payloadType = 0; - do { - READ_UINT8 (&reader, payload_type_byte, 8); - sei->payloadType += payload_type_byte; - } - while (payload_type_byte == 0xff); - - payloadSize = 0; - do { - READ_UINT8 (&reader, payload_size_byte, 8); - payloadSize += payload_size_byte; - } - while (payload_size_byte == 0xff); - - payload_data = data + gst_nal_reader_get_pos (&reader) * 8; - remaining = gst_nal_reader_get_remaining (&reader) * 8; - payload_size = payloadSize < remaining ? payloadSize : remaining; - - if (sei->payloadType == 0) - res = - gst_h264_parser_parse_buffering_period (parser, - &sei->buffering_period, payload_data, payload_size); - else if (sei->payloadType == 1) - res = gst_h264_parser_parse_pic_timing (parser, seq, &sei->pic_timing, - payload_data, payload_size); - else - res = TRUE; - - return res; - -error: - GST_WARNING ("error parsing \"Sei message\""); - return FALSE; -} - -#undef CHECK_ALLOWED -#undef READ_UINT8 -#undef READ_UINT16 -#undef READ_UINT32 -#undef READ_UINT64 -#undef READ_UE -#undef READ_UE_ALLOWED -#undef READ_SE -#undef READ_SE_ALLOWED - -static void -gst_h264_parser_init (GstH264Parser * object) -{ - GstH264Parser *parser = GST_H264_PARSER (object); - - parser->sequences = g_hash_table_new_full (g_int_hash, g_int_equal, NULL, - gst_h264_sequence_free); - parser->pictures = g_hash_table_new_full (g_int_hash, g_int_equal, NULL, - gst_h264_picture_free); -} - -static void -gst_h264_parser_finalize (GObject * object) -{ - GstH264Parser *parser = GST_H264_PARSER (object); - - g_hash_table_destroy (parser->sequences); - g_hash_table_destroy (parser->pictures); - - G_OBJECT_CLASS (gst_h264_parser_parent_class)->finalize (object); -} - -static void -gst_h264_parser_class_init (GstH264ParserClass * klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->finalize = gst_h264_parser_finalize; -} diff --git a/sys/vdpau/h264/gsth264parser.h b/sys/vdpau/h264/gsth264parser.h deleted file mode 100644 index f55c25881..000000000 --- a/sys/vdpau/h264/gsth264parser.h +++ /dev/null @@ -1,420 +0,0 @@ -/* GStreamer - * - * Copyright (C) 2009 Carl-Anton Ingmarsson <ca.ingmarsson@gmail.com>. - * - * 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., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef _GST_H264_PARSER_H_ -#define _GST_H264_PARSER_H_ - -#include <glib-object.h> - -G_BEGIN_DECLS - -typedef enum -{ - GST_NAL_UNKNOWN = 0, - GST_NAL_SLICE = 1, - GST_NAL_SLICE_DPA = 2, - GST_NAL_SLICE_DPB = 3, - GST_NAL_SLICE_DPC = 4, - GST_NAL_SLICE_IDR = 5, - GST_NAL_SEI = 6, - GST_NAL_SPS = 7, - GST_NAL_PPS = 8, - GST_NAL_AU_DELIMITER = 9, - GST_NAL_SEQ_END = 10, - GST_NAL_STREAM_END = 11, - GST_NAL_FILTER_DATA = 12 -} GstNalUnitType; - -typedef enum -{ - GST_H264_P_SLICE, - GST_H264_B_SLICE, - GST_H264_I_SLICE, - GST_H264_SP_SLICE, - GST_H264_SI_SLICE, - GST_H264_S_P_SLICE, - GST_H264_S_B_SLICE, - GST_H264_S_I_SLICE, - GST_H264_S_SP_SLICE, - GST_H264_S_SI_SLICE -} GstH264SliceType; - -#define GST_H264_IS_P_SLICE(type) ((type % 5) == GST_H264_P_SLICE) -#define GST_H264_IS_B_SLICE(type) ((type % 5) == GST_H264_B_SLICE) -#define GST_H264_IS_I_SLICE(type) ((type % 5) == GST_H264_I_SLICE) -#define GST_H264_IS_SP_SLICE(type) ((type % 5) == GST_H264_SP_SLICE) -#define GST_H264_IS_SI_SLICE(type) ((type % 5) == GST_H264_SI_SLICE) - -typedef struct _GstNalUnit GstNalUnit; - -typedef struct _GstH264HRDParameters GstH264HRDParameters; -typedef struct _GstH264VUIParameters GstH264VUIParameters; -typedef struct _GstH264Sequence GstH264Sequence; - -typedef struct _GstH264Picture GstH264Picture; - -typedef struct _GstH264DecRefPicMarking GstH264DecRefPicMarking; -typedef struct _GstH264RefPicMarking GstH264RefPicMarking; -typedef struct _GstH264PredWeightTable GstH264PredWeightTable; -typedef struct _GstH264Slice GstH264Slice; - -typedef struct _GstH264ClockTimestamp GstH264ClockTimestamp; -typedef struct _GstH264PicTiming GstH264PicTiming; -typedef struct _GstH264BufferingPeriod GstH264BufferingPeriod; -typedef struct _GstH264SEIMessage GstH264SEIMessage; - -struct _GstNalUnit -{ - guint16 ref_idc; - guint16 type; - - /* calculated values */ - guint8 IdrPicFlag; -}; - -struct _GstH264HRDParameters -{ - guint8 cpb_cnt_minus1; - guint8 bit_rate_scale; - guint8 cpb_size_scale; - - guint32 bit_rate_value_minus1[32]; - guint32 cpb_size_value_minus1[32]; - guint8 cbr_flag[32]; - - guint8 initial_cpb_removal_delay_length_minus1; - guint8 cpb_removal_delay_length_minus1; - guint8 dpb_output_delay_length_minus1; - guint8 time_offset_length; -}; - -struct _GstH264VUIParameters -{ - guint8 aspect_ratio_idc; - /* if aspect_ratio_idc == 255 */ - guint16 sar_width; - guint16 sar_height; - - guint8 overscan_info_present_flag; - /* if overscan_info_present_flag */ - guint8 overscan_appropriate_flag; - - guint8 video_format; - guint8 video_full_range_flag; - guint8 colour_description_present_flag; - guint8 colour_primaries; - guint8 transfer_characteristics; - guint8 matrix_coefficients; - - guint8 chroma_sample_loc_type_top_field; - guint8 chroma_sample_loc_type_bottom_field; - - guint8 timing_info_present_flag; - /* if timing_info_present_flag */ - guint32 num_units_in_tick; - guint32 time_scale; - guint8 fixed_frame_rate_flag; - - guint8 nal_hrd_parameters_present_flag; - /* if nal_hrd_parameters_present_flag */ - GstH264HRDParameters nal_hrd_parameters; - - guint8 vcl_hrd_parameters_present_flag; - /* if nal_hrd_parameters_present_flag */ - GstH264HRDParameters vcl_hrd_parameters; - - guint8 low_delay_hrd_flag; - guint8 pic_struct_present_flag; -}; - -struct _GstH264Sequence -{ - gint id; - - guint8 profile_idc; - guint8 constraint_set0_flag; - guint8 constraint_set1_flag; - guint8 constraint_set2_flag; - guint8 constraint_set3_flag; - guint8 level_idc; - - guint8 chroma_format_idc; - guint8 separate_colour_plane_flag; - guint8 bit_depth_luma_minus8; - guint8 bit_depth_chroma_minus8; - guint8 qpprime_y_zero_transform_bypass_flag; - - guint8 scaling_matrix_present_flag; - guint8 scaling_lists_4x4[6][16]; - guint8 scaling_lists_8x8[6][64]; - - guint8 log2_max_frame_num_minus4; - guint8 pic_order_cnt_type; - - /* if pic_order_cnt_type == 0 */ - guint8 log2_max_pic_order_cnt_lsb_minus4; - - /* else if pic_order_cnt_type == 1 */ - guint8 delta_pic_order_always_zero_flag; - gint32 offset_for_non_ref_pic; - gint32 offset_for_top_to_bottom_field; - guint8 num_ref_frames_in_pic_order_cnt_cycle; - gint32 offset_for_ref_frame[255]; - - guint32 num_ref_frames; - guint8 gaps_in_frame_num_value_allowed_flag; - guint32 pic_width_in_mbs_minus1; - guint32 pic_height_in_map_units_minus1; - guint8 frame_mbs_only_flag; - - guint8 mb_adaptive_frame_field_flag; - - guint8 direct_8x8_inference_flag; - - guint32 frame_crop_left_offset; - guint32 frame_crop_right_offset; - guint32 frame_crop_top_offset; - guint32 frame_crop_bottom_offset; - - guint8 vui_parameters_present_flag; - /* if vui_parameters_present_flag */ - GstH264VUIParameters vui_parameters; - - /* calculated values */ - guint8 ChromaArrayType; - guint32 MaxFrameNum; -}; - -struct _GstH264Picture -{ - gint id; - - GstH264Sequence *sequence; - - guint8 entropy_coding_mode_flag; - guint8 pic_order_present_flag; - - guint32 num_slice_groups_minus1; - - /* if num_slice_groups_minus1 > 0 */ - guint8 slice_group_map_type; - /* and if slice_group_map_type == 0 */ - guint32 run_length_minus1[8]; - /* or if slice_group_map_type == 2 */ - guint32 top_left[8]; - guint32 bottom_right[8]; - /* or if slice_group_map_type == (3, 4, 5) */ - guint8 slice_group_change_direction_flag; - guint32 slice_group_change_rate_minus1; - /* or if slice_group_map_type == 6 */ - guint32 pic_size_in_map_units_minus1; - guint8 *slice_group_id; - - guint8 num_ref_idx_l0_active_minus1; - guint8 num_ref_idx_l1_active_minus1; - guint8 weighted_pred_flag; - guint8 weighted_bipred_idc; - gint8 pic_init_qp_minus26; - gint8 pic_init_qs_minus26; - gint8 chroma_qp_index_offset; - guint8 deblocking_filter_control_present_flag; - guint8 constrained_intra_pred_flag; - guint8 redundant_pic_cnt_present_flag; - - guint8 transform_8x8_mode_flag; - - guint8 scaling_lists_4x4[6][16]; - guint8 scaling_lists_8x8[6][64]; - - guint8 second_chroma_qp_index_offset; -}; - -struct _GstH264RefPicMarking -{ - guint8 memory_management_control_operation; - - guint32 difference_of_pic_nums_minus1; - guint32 long_term_pic_num; - guint32 long_term_frame_idx; - guint32 max_long_term_frame_idx_plus1; -}; - -struct _GstH264DecRefPicMarking -{ - /* if slice->nal_unit.IdrPicFlag */ - guint8 no_output_of_prior_pics_flag; - guint8 long_term_reference_flag; - - guint8 adaptive_ref_pic_marking_mode_flag; - GstH264RefPicMarking ref_pic_marking[10]; - guint8 n_ref_pic_marking; -}; - -struct _GstH264PredWeightTable -{ - guint8 luma_log2_weight_denom; - guint8 chroma_log2_weight_denom; - - guint8 luma_weight_l0[32]; - guint8 luma_offset_l0[32]; - - /* if seq->ChromaArrayType != 0 */ - guint8 chroma_weight_l0[32][2]; - guint8 chroma_offset_l0[32][2]; - - /* if slice->slice_type % 5 == 1 */ - guint8 luma_weight_l1[32]; - guint8 luma_offset_l1[32]; - /* and if seq->ChromaArrayType != 0 */ - guint8 chroma_weight_l1[32][2]; - guint8 chroma_offset_l1[32][2]; -}; - -struct _GstH264Slice -{ - GstNalUnit nal_unit; - - guint32 first_mb_in_slice; - guint32 type; - - GstH264Picture *picture; - - /* if seq->separate_colour_plane_flag */ - guint8 colour_plane_id; - - guint16 frame_num; - - guint8 field_pic_flag; - guint8 bottom_field_flag; - - /* if nal_unit.type == 5 */ - guint16 idr_pic_id; - - /* if seq->pic_order_cnt_type == 0 */ - guint16 pic_order_cnt_lsb; - gint32 delta_pic_order_cnt_bottom; - - gint32 delta_pic_order_cnt[2]; - guint8 redundant_pic_cnt; - - /* if slice_type == B_SLICE */ - guint8 direct_spatial_mv_pred_flag; - - guint8 num_ref_idx_l0_active_minus1; - guint8 num_ref_idx_l1_active_minus1; - - GstH264PredWeightTable pred_weight_table; - /* if nal_unit.ref_idc != 0 */ - GstH264DecRefPicMarking dec_ref_pic_marking; - - /* calculated values */ - guint32 MaxPicNum; -}; - -struct _GstH264ClockTimestamp -{ - guint8 ct_type; - guint8 nuit_field_based_flag; - guint8 counting_type; - guint8 discontinuity_flag; - guint8 cnt_dropped_flag; - guint8 n_frames; - - guint8 seconds_flag; - guint8 seconds_value; - - guint8 minutes_flag; - guint8 minutes_value; - - guint8 hours_flag; - guint8 hours_value; - - guint32 time_offset; -}; - -struct _GstH264PicTiming -{ - guint8 cpb_removal_delay; - guint8 dpb_output_delay; - - guint8 pic_struct_present_flag; - /* if pic_struct_present_flag */ - guint8 pic_struct; - - guint8 clock_timestamp_flag[3]; - GstH264ClockTimestamp clock_timestamp[3]; -}; - -struct _GstH264BufferingPeriod -{ - GstH264Sequence *seq; - - /* seq->vui_parameters->nal_hrd_parameters_present_flag */ - guint8 nal_initial_cpb_removal_delay[32]; - guint8 nal_initial_cpb_removal_delay_offset[32]; - - /* seq->vui_parameters->vcl_hrd_parameters_present_flag */ - guint8 vcl_initial_cpb_removal_delay[32]; - guint8 vcl_initial_cpb_removal_delay_offset[32]; -}; - -struct _GstH264SEIMessage -{ - guint32 payloadType; - - union { - GstH264BufferingPeriod buffering_period; - GstH264PicTiming pic_timing; - }; -}; - -#define GST_TYPE_H264_PARSER (gst_h264_parser_get_type ()) -#define GST_H264_PARSER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_H264_PARSER, GstH264Parser)) -#define GST_H264_PARSER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_H264_PARSER, GstH264ParserClass)) -#define GST_IS_H264_PARSER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_H264_PARSER)) -#define GST_IS_H264_PARSER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_H264_PARSER)) -#define GST_H264_PARSER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_H264_PARSER, GstH264ParserClass)) - -typedef struct _GstH264ParserClass GstH264ParserClass; -typedef struct _GstH264Parser GstH264Parser; - -struct _GstH264ParserClass -{ - GObjectClass parent_class; -}; - -struct _GstH264Parser -{ - GObject parent_instance; - - GHashTable *sequences; - GHashTable *pictures; -}; - -GType gst_h264_parser_get_type (void) G_GNUC_CONST; - -GstH264Sequence *gst_h264_parser_parse_sequence (GstH264Parser * parser, guint8 * data, guint size); -GstH264Picture *gst_h264_parser_parse_picture (GstH264Parser * parser, guint8 * data, guint size); -gboolean gst_h264_parser_parse_slice_header (GstH264Parser * parser, GstH264Slice * slice, guint8 * data, guint size, GstNalUnit nal_unit); -gboolean gst_h264_parser_parse_sei_message (GstH264Parser * parser, GstH264Sequence *seq, GstH264SEIMessage * sei, guint8 * data, guint size); - -G_END_DECLS - -#endif /* _GST_H264_PARSER_H_ */ diff --git a/sys/vdpau/h264/gstnalreader.c b/sys/vdpau/h264/gstnalreader.c deleted file mode 100644 index b9b9d236d..000000000 --- a/sys/vdpau/h264/gstnalreader.c +++ /dev/null @@ -1,503 +0,0 @@ -/* GStreamer - * - * Copyright (C) 2009 Carl-Anton Ingmarsson <ca.ingmarsson@gmail.com>. - * - * 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., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "gstnalreader.h" - -static gboolean gst_nal_reader_read (GstNalReader * reader, guint nbits); - -/** - * SECTION:gstnalreader - * @short_description: Bit reader which automatically skips - * emulation_prevention bytes - * - * #GstNalReader provides a bit reader which automatically skips - * emulation_prevention bytes. It provides functions for reading any number of bits - * into 8, 16, 32 and 64 bit variables. It also provides functions for reading - * Exp-Golomb values. - */ - -/** - * gst_nal_reader_new: - * @data: Data from which the #GstNalReader should read - * @size: Size of @data in bytes - * - * Create a new #GstNalReader instance, which will read from @data. - * - * Returns: a new #GstNalReader instance - * - * Since: 0.10.22 - */ -GstNalReader * -gst_nal_reader_new (const guint8 * data, guint size) -{ - GstNalReader *ret = g_slice_new0 (GstNalReader); - - ret->data = data; - ret->size = size; - - ret->first_byte = 0xff; - ret->cache = 0xff; - - return ret; -} - -/** - * gst_nal_reader_new_from_buffer: - * @buffer: Buffer from which the #GstNalReader should read - * - * Create a new #GstNalReader instance, which will read from the - * #GstBuffer @buffer. - * - * Returns: a new #GstNalReader instance - * - * Since: 0.10.22 - */ -GstNalReader * -gst_nal_reader_new_from_buffer (const GstBuffer * buffer) -{ - g_return_val_if_fail (GST_IS_BUFFER (buffer), NULL); - - return gst_nal_reader_new (GST_BUFFER_DATA (buffer), - GST_BUFFER_SIZE (buffer)); -} - -/** - * gst_nal_reader_free: - * @reader: a #GstNalReader instance - * - * Frees a #GstNalReader instance, which was previously allocated by - * gst_nal_reader_new() or gst_nal_reader_new_from_buffer(). - * - * Since: 0.10.22 - */ -void -gst_nal_reader_free (GstNalReader * reader) -{ - g_return_if_fail (reader != NULL); - - g_slice_free (GstNalReader, reader); -} - -/** - * gst_nal_reader_init: - * @reader: a #GstNalReader instance - * @data: Data from which the #GstNalReader should read - * @size: Size of @data in bytes - * - * Initializes a #GstNalReader instance to read from @data. This function - * can be called on already initialized instances. - * - * Since: 0.10.22 - */ -void -gst_nal_reader_init (GstNalReader * reader, const guint8 * data, guint size) -{ - g_return_if_fail (reader != NULL); - - reader->data = data; - reader->size = size; - - reader->byte = 0; - reader->bits_in_cache = 0; - /* fill with something other than 0 to detect emulation prevention bytes */ - reader->first_byte = 0xff; - reader->cache = 0xff; -} - -/** - * gst_nal_reader_init_from_buffer: - * @reader: a #GstNalReader instance - * @buffer: Buffer from which the #GstNalReader should read - * - * Initializes a #GstNalReader instance to read from @buffer. This function - * can be called on already initialized instances. - * - * Since: 0.10.22 - */ -void -gst_nal_reader_init_from_buffer (GstNalReader * reader, - const GstBuffer * buffer) -{ - g_return_if_fail (GST_IS_BUFFER (buffer)); - - gst_nal_reader_init (reader, GST_BUFFER_DATA (buffer), - GST_BUFFER_SIZE (buffer)); -} - -/** - * gst_nal_reader_skip: - * @reader: a #GstNalReader instance - * @nbits: the number of bits to skip - * - * Skips @nbits bits of the #GstNalReader instance. - * - * Returns: %TRUE if @nbits bits could be skipped, %FALSE otherwise. - * - * Since: 0.10.22 - */ -gboolean -gst_nal_reader_skip (GstNalReader * reader, guint nbits) -{ - g_return_val_if_fail (reader != NULL, FALSE); - - if (G_UNLIKELY (!gst_nal_reader_read (reader, nbits))) - return FALSE; - - reader->bits_in_cache -= nbits; - - return TRUE; -} - -/** - * gst_nal_reader_skip_to_byte: - * @reader: a #GstNalReader instance - * - * Skips until the next byte. - * - * Returns: %TRUE if successful, %FALSE otherwise. - * - * Since: 0.10.22 - */ -gboolean -gst_nal_reader_skip_to_byte (GstNalReader * reader) -{ - g_return_val_if_fail (reader != NULL, FALSE); - - if (reader->bits_in_cache == 0) { - if (G_LIKELY ((reader->size - reader->byte) > 0)) - reader->byte++; - else - return FALSE; - } - - reader->bits_in_cache = 0; - - return TRUE; -} - -/** - * gst_nal_reader_get_pos: - * @reader: a #GstNalReader instance - * - * Returns the current position of a GstNalReader instance in bits. - * - * Returns: The current position in bits - * - */ -guint -gst_nal_reader_get_pos (const GstNalReader * reader) -{ - return reader->byte * 8 - reader->bits_in_cache; -} - -/** - * gst_nal_reader_get_remaining: - * @reader: a #GstNalReader instance - * - * Returns the remaining number of bits of a GstNalReader instance. - * - * Returns: The remaining number of bits. - * - */ -guint -gst_nal_reader_get_remaining (const GstNalReader * reader) -{ - return (reader->size - reader->byte) * 8 + reader->bits_in_cache; -} - -/** - * gst_nal_reader_get_bits_uint8: - * @reader: a #GstNalReader instance - * @val: Pointer to a #guint8 to store the result - * @nbits: number of bits to read - * - * Read @nbits bits into @val and update the current position. - * - * Returns: %TRUE if successful, %FALSE otherwise. - * - * Since: 0.10.22 - */ - -/** - * gst_nal_reader_get_bits_uint16: - * @reader: a #GstNalReader instance - * @val: Pointer to a #guint16 to store the result - * @nbits: number of bits to read - * - * Read @nbits bits into @val and update the current position. - * - * Returns: %TRUE if successful, %FALSE otherwise. - * - * Since: 0.10.22 - */ - -/** - * gst_nal_reader_get_bits_uint32: - * @reader: a #GstNalReader instance - * @val: Pointer to a #guint32 to store the result - * @nbits: number of bits to read - * - * Read @nbits bits into @val and update the current position. - * - * Returns: %TRUE if successful, %FALSE otherwise. - * - * Since: 0.10.22 - */ - -/** - * gst_nal_reader_get_bits_uint64: - * @reader: a #GstNalReader instance - * @val: Pointer to a #guint64 to store the result - * @nbits: number of bits to read - * - * Read @nbits bits into @val and update the current position. - * - * Returns: %TRUE if successful, %FALSE otherwise. - * - * Since: 0.10.22 - */ - -/** - * gst_nal_reader_peek_bits_uint8: - * @reader: a #GstNalReader instance - * @val: Pointer to a #guint8 to store the result - * @nbits: number of bits to read - * - * Read @nbits bits into @val but keep the current position. - * - * Returns: %TRUE if successful, %FALSE otherwise. - * - * Since: 0.10.22 - */ - -/** - * gst_nal_reader_peek_bits_uint16: - * @reader: a #GstNalReader instance - * @val: Pointer to a #guint16 to store the result - * @nbits: number of bits to read - * - * Read @nbits bits into @val but keep the current position. - * - * Returns: %TRUE if successful, %FALSE otherwise. - * - * Since: 0.10.22 - */ - -/** - * gst_nal_reader_peek_bits_uint32: - * @reader: a #GstNalReader instance - * @val: Pointer to a #guint32 to store the result - * @nbits: number of bits to read - * - * Read @nbits bits into @val but keep the current position. - * - * Returns: %TRUE if successful, %FALSE otherwise. - * - * Since: 0.10.22 - */ - -/** - * gst_nal_reader_peek_bits_uint64: - * @reader: a #GstNalReader instance - * @val: Pointer to a #guint64 to store the result - * @nbits: number of bits to read - * - * Read @nbits bits into @val but keep the current position. - * - * Returns: %TRUE if successful, %FALSE otherwise. - * - * Since: 0.10.22 - */ - -static gboolean -gst_nal_reader_read (GstNalReader * reader, guint nbits) -{ - if (G_UNLIKELY (reader->byte * 8 + (nbits - reader->bits_in_cache) > - reader->size * 8)) - return FALSE; - - while (reader->bits_in_cache < nbits) { - guint8 byte; - gboolean check_three_byte; - - check_three_byte = TRUE; - next_byte: - if (G_UNLIKELY (reader->byte >= reader->size)) - return FALSE; - - byte = reader->data[reader->byte++]; - - /* check if the byte is a emulation_prevention_three_byte */ - if (check_three_byte && byte == 0x03 && reader->first_byte == 0x00 && - ((reader->cache & 0xff) == 0)) { - /* next byte goes unconditionally to the cache, even if it's 0x03 */ - check_three_byte = FALSE; - goto next_byte; - } - reader->cache = (reader->cache << 8) | reader->first_byte; - reader->first_byte = byte; - reader->bits_in_cache += 8; - } - - return TRUE; -} - -#define GST_NAL_READER_READ_BITS(bits) \ -gboolean \ -gst_nal_reader_get_bits_uint##bits (GstNalReader *reader, guint##bits *val, guint nbits) \ -{ \ - guint shift; \ - \ - g_return_val_if_fail (reader != NULL, FALSE); \ - g_return_val_if_fail (val != NULL, FALSE); \ - g_return_val_if_fail (nbits <= bits, FALSE); \ - \ - if (!gst_nal_reader_read (reader, nbits)) \ - return FALSE; \ - \ - /* bring the required bits down and truncate */ \ - shift = reader->bits_in_cache - nbits; \ - *val = reader->first_byte >> shift; \ - \ - *val |= reader->cache << (8 - shift); \ - /* mask out required bits */ \ - if (nbits < bits) \ - *val &= ((guint##bits)1 << nbits) - 1; \ - \ - reader->bits_in_cache = shift; \ - \ - return TRUE; \ -} \ -\ -gboolean \ -gst_nal_reader_peek_bits_uint##bits (const GstNalReader *reader, guint##bits *val, guint nbits) \ -{ \ - GstNalReader tmp; \ - \ - g_return_val_if_fail (reader != NULL, FALSE); \ - tmp = *reader; \ - return gst_nal_reader_get_bits_uint##bits (&tmp, val, nbits); \ -} - -GST_NAL_READER_READ_BITS (8); -GST_NAL_READER_READ_BITS (16); -GST_NAL_READER_READ_BITS (32); -GST_NAL_READER_READ_BITS (64); - -/** - * gst_nal_reader_get_ue: - * @reader: a #GstNalReader instance - * @val: Pointer to a #guint32 to store the result - * - * Reads an unsigned Exp-Golomb value into val - * - * Returns: %TRUE if successful, %FALSE otherwise. - */ -gboolean -gst_nal_reader_get_ue (GstNalReader * reader, guint32 * val) -{ - guint i = 0; - guint8 bit; - guint32 value; - - if (G_UNLIKELY (!gst_nal_reader_get_bits_uint8 (reader, &bit, 1))) - return FALSE; - - while (bit == 0) { - i++; - if G_UNLIKELY - ((!gst_nal_reader_get_bits_uint8 (reader, &bit, 1))) - return FALSE; - } - - g_return_val_if_fail (i <= 32, FALSE); - - if (G_UNLIKELY (!gst_nal_reader_get_bits_uint32 (reader, &value, i))) - return FALSE; - - *val = (1 << i) - 1 + value; - - return TRUE; -} - -/** - * gst_nal_reader_peek_ue: - * @reader: a #GstNalReader instance - * @val: Pointer to a #guint32 to store the result - * - * Read an unsigned Exp-Golomb value into val but keep the current position - * - * Returns: %TRUE if successful, %FALSE otherwise. - */ -gboolean -gst_nal_reader_peek_ue (const GstNalReader * reader, guint32 * val) -{ - GstNalReader tmp; - - g_return_val_if_fail (reader != NULL, FALSE); - - tmp = *reader; - return gst_nal_reader_get_ue (&tmp, val); -} - -/** - * gst_nal_reader_get_se: - * @reader: a #GstNalReader instance - * @val: Pointer to a #gint32 to store the result - * - * Reads a signed Exp-Golomb value into val - * - * Returns: %TRUE if successful, %FALSE otherwise. - */ -gboolean -gst_nal_reader_get_se (GstNalReader * reader, gint32 * val) -{ - guint32 value; - - if (G_UNLIKELY (!gst_nal_reader_get_ue (reader, &value))) - return FALSE; - - if (value % 2) - *val = (value / 2) + 1; - else - *val = -(value / 2); - - return TRUE; -} - -/** - * gst_nal_reader_peek_se: - * @reader: a #GstNalReader instance - * @val: Pointer to a #gint32 to store the result - * - * Read a signed Exp-Golomb value into val but keep the current position - * - * Returns: %TRUE if successful, %FALSE otherwise. - */ -gboolean -gst_nal_reader_peek_se (const GstNalReader * reader, gint32 * val) -{ - GstNalReader tmp; - - g_return_val_if_fail (reader != NULL, FALSE); - - tmp = *reader; - return gst_nal_reader_get_se (&tmp, val); -} diff --git a/sys/vdpau/h264/gstnalreader.h b/sys/vdpau/h264/gstnalreader.h deleted file mode 100644 index 353f65018..000000000 --- a/sys/vdpau/h264/gstnalreader.h +++ /dev/null @@ -1,99 +0,0 @@ -/* GStreamer - * - * Copyright (C) 2009 Carl-Anton Ingmarsson <ca.ingmarsson@gmail.com>. - * - * 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., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef __GST_NAL_READER_H__ -#define __GST_NAL_READER_H__ - -#include <gst/gst.h> - -G_BEGIN_DECLS - -typedef struct _GstNalReader GstNalReader; - -struct _GstNalReader -{ - const guint8 *data; - guint size; - - guint byte; /* Byte position */ - guint bits_in_cache; /* bitpos in the cache of next bit */ - guint8 first_byte; - guint64 cache; /* cached bytes */ -}; - -GstNalReader *gst_nal_reader_new (const guint8 *data, guint size); -GstNalReader *gst_nal_reader_new_from_buffer (const GstBuffer *buffer); -void gst_nal_reader_free (GstNalReader * reader); - -void gst_nal_reader_init (GstNalReader * reader, const guint8 * data, guint size); -void gst_nal_reader_init_from_buffer (GstNalReader * reader, const GstBuffer * buffer); - -gboolean gst_nal_reader_skip (GstNalReader *reader, guint nbits); -gboolean gst_nal_reader_skip_to_byte (GstNalReader *reader); - -guint gst_nal_reader_get_pos (const GstNalReader * reader); -guint gst_nal_reader_get_remaining (const GstNalReader *reader); - -gboolean gst_nal_reader_get_bits_uint8 (GstNalReader *reader, guint8 *val, guint nbits); -gboolean gst_nal_reader_get_bits_uint16 (GstNalReader *reader, guint16 *val, guint nbits); -gboolean gst_nal_reader_get_bits_uint32 (GstNalReader *reader, guint32 *val, guint nbits); -gboolean gst_nal_reader_get_bits_uint64 (GstNalReader *reader, guint64 *val, guint nbits); - -gboolean gst_nal_reader_peek_bits_uint8 (const GstNalReader *reader, guint8 *val, guint nbits); -gboolean gst_nal_reader_peek_bits_uint16 (const GstNalReader *reader, guint16 *val, guint nbits); -gboolean gst_nal_reader_peek_bits_uint32 (const GstNalReader *reader, guint32 *val, guint nbits); -gboolean gst_nal_reader_peek_bits_uint64 (const GstNalReader *reader, guint64 *val, guint nbits); - -gboolean gst_nal_reader_get_ue (GstNalReader *reader, guint32 *val); -gboolean gst_nal_reader_peek_ue (const GstNalReader *reader, guint32 *val); - -gboolean gst_nal_reader_get_se (GstNalReader *reader, gint32 *val); -gboolean gst_nal_reader_peek_se (const GstNalReader *reader, gint32 *val); - -/** - * GST_NAL_READER_INIT: - * @data: Data from which the #GstNalReader should read - * @size: Size of @data in bytes - * - * A #GstNalReader must be initialized with this macro, before it can be - * used. This macro can used be to initialize a variable, but it cannot - * be assigned to a variable. In that case you have to use - * gst_bit_reader_init(). - * - * Since: 0.10.22 - */ -#define GST_NAL_READER_INIT(data, size) {data, size, 0, 0, 0xff, 0xff} - -/** - * GST_NAL_READER_INIT_FROM_BUFFER: - * @buffer: Buffer from which the #GstNalReader should read - * - * A #GstNalReader must be initialized with this macro, before it can be - * used. This macro can used be to initialize a variable, but it cannot - * be assigned to a variable. In that case you have to use - * gst_bit_reader_init(). - * - * Since: 0.10.22 - */ -#define GST_NAL_READER_INIT_FROM_BUFFER(buffer) {GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer), 0, 0, 0xff, 0xff} - -G_END_DECLS - -#endif /* __GST_NAL_READER_H__ */ diff --git a/sys/vdpau/h264/gstvdph264dec.c b/sys/vdpau/h264/gstvdph264dec.c index 08774d60e..e5d26ce5b 100644 --- a/sys/vdpau/h264/gstvdph264dec.c +++ b/sys/vdpau/h264/gstvdph264dec.c @@ -22,156 +22,49 @@ #include "config.h" #endif -#include <gst/base/gstadapter.h> -#include <gst/base/gstbitreader.h> +#include <gst/codecparsers/gsth264parser.h> +#include <gst/codecparsers/gsth264meta.h> #include <string.h> -#include "gsth264frame.h" - #include "gstvdph264dec.h" GST_DEBUG_CATEGORY_STATIC (gst_vdp_h264_dec_debug); #define GST_CAT_DEFAULT gst_vdp_h264_dec_debug static GstStaticPadTemplate sink_template = -GST_STATIC_PAD_TEMPLATE (GST_BASE_VIDEO_DECODER_SINK_NAME, +GST_STATIC_PAD_TEMPLATE (GST_VIDEO_DECODER_SINK_NAME, GST_PAD_SINK, GST_PAD_ALWAYS, - GST_STATIC_CAPS ("video/x-h264, " "interlaced = (boolean) false") + GST_STATIC_CAPS ("video/x-h264,stream-format=byte-stream,alignment=au") ); -#define DEBUG_INIT(bla) \ +#define DEBUG_INIT \ GST_DEBUG_CATEGORY_INIT (gst_vdp_h264_dec_debug, "vdpauh264dec", 0, \ "VDPAU h264 decoder"); -GST_BOILERPLATE_FULL (GstVdpH264Dec, gst_vdp_h264_dec, GstVdpDecoder, - GST_TYPE_VDP_DECODER, DEBUG_INIT); - -#define SYNC_CODE_SIZE 3 - -#define READ_UINT8(reader, val, nbits) { \ - if (!gst_bit_reader_get_bits_uint8 (reader, &val, nbits)) { \ - GST_WARNING ("failed to read uint8, nbits: %d", nbits); \ - return FALSE; \ - } \ -} - -#define READ_UINT16(reader, val, nbits) { \ - if (!gst_bit_reader_get_bits_uint16 (reader, &val, nbits)) { \ - GST_WARNING ("failed to read uint16, nbits: %d", nbits); \ - return FALSE; \ - } \ -} - -#define SKIP(reader, nbits) { \ - if (!gst_bit_reader_skip (reader, nbits)) { \ - GST_WARNING ("failed to skip nbits: %d", nbits); \ - return FALSE; \ - } \ -} - -static gboolean -gst_vdp_h264_dec_set_sink_caps (GstBaseVideoDecoder * base_video_decoder, - GstCaps * caps) -{ - GstVdpH264Dec *h264_dec; - GstStructure *structure; - const GValue *value; - - h264_dec = GST_VDP_H264_DEC (base_video_decoder); - - structure = gst_caps_get_structure (caps, 0); - /* packetized video has a codec_data */ - if ((value = gst_structure_get_value (structure, "codec_data"))) { - GstBuffer *buf; - GstBitReader reader; - guint8 version; - guint8 n_sps, n_pps; - gint i; - - GST_DEBUG_OBJECT (h264_dec, "have packetized h264"); - h264_dec->packetized = TRUE; - - buf = gst_value_get_buffer (value); - GST_MEMDUMP ("avcC:", GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf)); - - /* parse the avcC data */ - if (GST_BUFFER_SIZE (buf) < 7) { - GST_ERROR_OBJECT (h264_dec, "avcC size %u < 7", GST_BUFFER_SIZE (buf)); - return FALSE; - } - - gst_bit_reader_init_from_buffer (&reader, buf); - - READ_UINT8 (&reader, version, 8); - if (version != 1) - return FALSE; - - SKIP (&reader, 30); - - READ_UINT8 (&reader, h264_dec->nal_length_size, 2); - h264_dec->nal_length_size += 1; - GST_DEBUG_OBJECT (h264_dec, "nal length %u", h264_dec->nal_length_size); - - SKIP (&reader, 3); - - READ_UINT8 (&reader, n_sps, 5); - for (i = 0; i < n_sps; i++) { - guint16 sps_length; - guint8 *data; - - READ_UINT16 (&reader, sps_length, 16); - sps_length -= 1; - SKIP (&reader, 8); - - data = GST_BUFFER_DATA (buf) + gst_bit_reader_get_pos (&reader) / 8; - if (!gst_h264_parser_parse_sequence (h264_dec->parser, data, sps_length)) - return FALSE; - - SKIP (&reader, sps_length * 8); - } - - READ_UINT8 (&reader, n_pps, 8); - for (i = 0; i < n_pps; i++) { - guint16 pps_length; - guint8 *data; - - READ_UINT16 (&reader, pps_length, 16); - pps_length -= 1; - SKIP (&reader, 8); - - data = GST_BUFFER_DATA (buf) + gst_bit_reader_get_pos (&reader) / 8; - if (!gst_h264_parser_parse_picture (h264_dec->parser, data, pps_length)) - return FALSE; - - SKIP (&reader, pps_length * 8); - } - } - - return TRUE; -} +#define gst_vdp_h264_dec_parent_class parent_class +G_DEFINE_TYPE_WITH_CODE (GstVdpH264Dec, gst_vdp_h264_dec, GST_TYPE_VDP_DECODER, + DEBUG_INIT); static GstFlowReturn gst_vdp_h264_dec_output (GstH264DPB * dpb, GstH264Frame * h264_frame, gpointer user_data) { - GstBaseVideoDecoder *base_video_decoder = (GstBaseVideoDecoder *) user_data; + GstVideoDecoder *video_decoder = (GstVideoDecoder *) user_data; GST_DEBUG ("poc: %d", h264_frame->poc); - return gst_base_video_decoder_finish_frame (base_video_decoder, - GST_VIDEO_FRAME_CAST (h264_frame)); + return gst_video_decoder_finish_frame (video_decoder, h264_frame->frame); } static guint -gst_vdp_h264_dec_calculate_poc (GstVdpH264Dec * h264_dec, GstH264Slice * slice) +gst_vdp_h264_dec_calculate_poc (GstVdpH264Dec * h264_dec, + GstH264SliceHdr * slice) { - GstH264Picture *pic; - GstH264Sequence *seq; + GstH264SPS *seq; guint poc = 0; - pic = slice->picture; - seq = pic->sequence; + seq = slice->pps->sequence; if (seq->pic_order_cnt_type == 0) { guint32 max_poc_cnt_lsb = 1 << (seq->log2_max_pic_order_cnt_lsb_minus4 + 4); @@ -196,12 +89,8 @@ gst_vdp_h264_dec_calculate_poc (GstVdpH264Dec * h264_dec, GstH264Slice * slice) static void gst_vdp_h264_dec_init_frame_info (GstVdpH264Dec * h264_dec, - GstH264Frame * h264_frame) + GstH264Frame * h264_frame, GstH264SliceHdr * slice) { - GstH264Slice *slice; - - slice = &h264_frame->slice_hdr; - h264_frame->poc = gst_vdp_h264_dec_calculate_poc (h264_dec, slice); h264_frame->output_needed = TRUE; @@ -209,9 +98,9 @@ gst_vdp_h264_dec_init_frame_info (GstVdpH264Dec * h264_dec, h264_frame->frame_idx = slice->frame_num; /* is reference */ - if (slice->nal_unit.ref_idc == 0) + if (slice->nalu_ref_idc == 0) h264_frame->is_reference = FALSE; - else if (slice->nal_unit.IdrPicFlag) { + else if (slice->slice_type == GST_H264_NAL_SLICE_IDR) { h264_frame->is_reference = TRUE; if (slice->dec_ref_pic_marking.long_term_reference_flag) { h264_frame->is_long_term = TRUE; @@ -237,38 +126,17 @@ gst_vdp_h264_dec_init_frame_info (GstVdpH264Dec * h264_dec, } -static gboolean -gst_vdp_h264_dec_calculate_par (GstH264VUIParameters * vui, guint16 * par_n, - guint16 * par_d) -{ - guint16 aspect[16][2] = { {1, 1}, {12, 11}, {10, 11}, {16, 11}, {40, 33}, - {24, 11}, {20, 11}, {32, 11}, {80, 33}, {18, 11}, {15, 11}, {64, 33}, - {160, 99}, {4, 3}, {3, 2}, {2, 1} - }; - - if (vui->aspect_ratio_idc >= 1 && vui->aspect_ratio_idc <= 16) { - *par_n = aspect[vui->aspect_ratio_idc - 1][0]; - *par_d = aspect[vui->aspect_ratio_idc - 1][1]; - return TRUE; - } else if (vui->aspect_ratio_idc == 255) { - *par_n = vui->sar_height; - *par_d = vui->sar_width; - return TRUE; - } - - return FALSE; -} - static GstFlowReturn -gst_vdp_h264_dec_idr (GstVdpH264Dec * h264_dec, GstH264Frame * h264_frame) +gst_vdp_h264_dec_idr (GstVdpH264Dec * h264_dec, GstVideoCodecFrame * frame, + GstH264SliceHdr * slice) { - GstH264Slice *slice; - GstH264Sequence *seq; + GstH264SPS *seq; + + GST_DEBUG_OBJECT (h264_dec, "Handling IDR slice"); h264_dec->poc_msb = 0; h264_dec->prev_poc_lsb = 0; - slice = &h264_frame->slice_hdr; if (slice->dec_ref_pic_marking.no_output_of_prior_pics_flag) gst_h264_dpb_flush (h264_dec->dpb, FALSE); else @@ -279,48 +147,31 @@ gst_vdp_h264_dec_idr (GstVdpH264Dec * h264_dec, GstH264Frame * h264_frame) else g_object_set (h264_dec->dpb, "max-longterm-frame-idx", -1, NULL); - seq = slice->picture->sequence; - if (seq != h264_dec->sequence) { - GstVideoState state; + seq = slice->pps->sequence; + if (seq->id != h264_dec->current_sps) { + GstVideoCodecState *state; VdpDecoderProfile profile; GstFlowReturn ret; - state = - gst_base_video_decoder_get_state (GST_BASE_VIDEO_DECODER (h264_dec)); - - state.width = (seq->pic_width_in_mbs_minus1 + 1) * 16 - - 2 * seq->frame_crop_right_offset; + GST_DEBUG_OBJECT (h264_dec, "Sequence changed !"); - state.height = (2 - seq->frame_mbs_only_flag) * - (seq->pic_height_in_map_units_minus1 + 1) * 16; - if (seq->frame_mbs_only_flag) - state.height -= 2 * seq->frame_crop_bottom_offset; - else - state.height -= 4 * seq->frame_crop_bottom_offset; + state = + gst_video_decoder_set_output_state (GST_VIDEO_DECODER (h264_dec), + GST_VIDEO_FORMAT_YV12, seq->width, seq->height, h264_dec->input_state); /* calculate framerate if we haven't got one */ - if (state.fps_n == 0 && seq->vui_parameters_present_flag) { - GstH264VUIParameters *vui; - guint16 par_n, par_d; - - vui = &seq->vui_parameters; - - if (gst_vdp_h264_dec_calculate_par (vui, &par_n, &par_d)) { - state.par_n = par_n; - state.par_d = par_d; - } - - if (vui->timing_info_present_flag && vui->fixed_frame_rate_flag) { - state.fps_n = vui->time_scale; - state.fps_d = vui->num_units_in_tick; - - if (seq->frame_mbs_only_flag) - state.fps_d *= 2; - } + if (state->info.fps_n == 0) { + state->info.fps_n = seq->fps_num; + state->info.fps_d = seq->fps_den; + } + if (state->info.par_n == 0 && seq->vui_parameters_present_flag) { + state->info.par_n = seq->vui_parameters.par_n; + state->info.par_d = seq->vui_parameters.par_d; } - gst_base_video_decoder_set_state (GST_BASE_VIDEO_DECODER (h264_dec), state); + if (!gst_video_decoder_negotiate (GST_VIDEO_DECODER (h264_dec))) + goto nego_fail; switch (seq->profile_idc) { case 66: @@ -336,197 +187,118 @@ gst_vdp_h264_dec_idr (GstVdpH264Dec * h264_dec, GstH264Frame * h264_frame) break; default: - GST_ELEMENT_ERROR (h264_dec, STREAM, WRONG_TYPE, - ("vdpauh264dec doesn't support this streams profile"), - ("profile_idc: %d", seq->profile_idc)); - return GST_FLOW_ERROR; + goto profile_not_suported; } ret = gst_vdp_decoder_init_decoder (GST_VDP_DECODER (h264_dec), profile, - seq->num_ref_frames); + seq->num_ref_frames, h264_dec->input_state); if (ret != GST_FLOW_OK) return ret; g_object_set (h264_dec->dpb, "num-ref-frames", seq->num_ref_frames, NULL); - h264_dec->sequence = seq; + h264_dec->current_sps = seq->id; } return GST_FLOW_OK; + +profile_not_suported: + { + GST_ELEMENT_ERROR (h264_dec, STREAM, WRONG_TYPE, + ("vdpauh264dec doesn't support this streams profile"), + ("profile_idc: %d", seq->profile_idc)); + return GST_FLOW_ERROR; + } + +nego_fail: + { + GST_ERROR_OBJECT (h264_dec, "Negotiation failed"); + return GST_FLOW_NOT_NEGOTIATED; + } } -static VdpPictureInfoH264 -gst_vdp_h264_dec_fill_info (GstVdpH264Dec * h264_dec, GstH264Frame * h264_frame) +static void +gst_vdp_h264_dec_fill_info (VdpPictureInfoH264 * info, GstVdpH264Dec * h264_dec, + GstH264Frame * h264_frame, GstH264SliceHdr * slice) { - GstH264Slice *slice; - GstH264Picture *pic; - GstH264Sequence *seq; - VdpPictureInfoH264 info; + GstH264PPS *pic; + GstH264SPS *seq; - slice = &h264_frame->slice_hdr; - pic = slice->picture; + pic = slice->pps; seq = pic->sequence; - info.slice_count = h264_frame->slices->len; + GST_DEBUG_OBJECT (h264_dec, "Filling info"); /* FIXME: we only handle frames for now */ - info.field_order_cnt[0] = h264_frame->poc; - info.field_order_cnt[1] = h264_frame->poc; - - info.is_reference = h264_frame->is_reference; - info.frame_num = slice->frame_num; - - info.field_pic_flag = slice->field_pic_flag; - info.bottom_field_flag = slice->bottom_field_flag; - info.num_ref_idx_l0_active_minus1 = slice->num_ref_idx_l0_active_minus1; - info.num_ref_idx_l1_active_minus1 = slice->num_ref_idx_l1_active_minus1; - - info.num_ref_frames = seq->num_ref_frames; - info.frame_mbs_only_flag = seq->frame_mbs_only_flag; - info.mb_adaptive_frame_field_flag = seq->mb_adaptive_frame_field_flag; - info.log2_max_frame_num_minus4 = seq->log2_max_frame_num_minus4; - info.pic_order_cnt_type = seq->pic_order_cnt_type; - info.log2_max_pic_order_cnt_lsb_minus4 = + info->field_order_cnt[0] = h264_frame->poc; + info->field_order_cnt[1] = h264_frame->poc; + + info->is_reference = h264_frame->is_reference; + info->frame_num = slice->frame_num; + + info->field_pic_flag = slice->field_pic_flag; + info->bottom_field_flag = slice->bottom_field_flag; + info->num_ref_idx_l0_active_minus1 = slice->num_ref_idx_l0_active_minus1; + info->num_ref_idx_l1_active_minus1 = slice->num_ref_idx_l1_active_minus1; + + info->num_ref_frames = seq->num_ref_frames; + info->mb_adaptive_frame_field_flag = seq->mb_adaptive_frame_field_flag; + info->frame_mbs_only_flag = seq->frame_mbs_only_flag; + info->log2_max_frame_num_minus4 = seq->log2_max_frame_num_minus4; + info->pic_order_cnt_type = seq->pic_order_cnt_type; + info->log2_max_pic_order_cnt_lsb_minus4 = seq->log2_max_pic_order_cnt_lsb_minus4; - info.delta_pic_order_always_zero_flag = seq->delta_pic_order_always_zero_flag; - info.direct_8x8_inference_flag = seq->direct_8x8_inference_flag; - - - info.constrained_intra_pred_flag = pic->constrained_intra_pred_flag; - info.weighted_pred_flag = pic->weighted_pred_flag; - info.weighted_bipred_idc = pic->weighted_bipred_idc; - info.transform_8x8_mode_flag = pic->transform_8x8_mode_flag; - info.chroma_qp_index_offset = pic->chroma_qp_index_offset; - info.second_chroma_qp_index_offset = pic->second_chroma_qp_index_offset; - info.pic_init_qp_minus26 = pic->pic_init_qp_minus26; - info.entropy_coding_mode_flag = pic->entropy_coding_mode_flag; - info.pic_order_present_flag = pic->pic_order_present_flag; - info.deblocking_filter_control_present_flag = + info->delta_pic_order_always_zero_flag = + seq->delta_pic_order_always_zero_flag; + info->direct_8x8_inference_flag = seq->direct_8x8_inference_flag; + + info->constrained_intra_pred_flag = pic->constrained_intra_pred_flag; + info->weighted_pred_flag = pic->weighted_pred_flag; + info->weighted_bipred_idc = pic->weighted_bipred_idc; + info->transform_8x8_mode_flag = pic->transform_8x8_mode_flag; + info->chroma_qp_index_offset = pic->chroma_qp_index_offset; + info->second_chroma_qp_index_offset = pic->second_chroma_qp_index_offset; + info->pic_init_qp_minus26 = pic->pic_init_qp_minus26; + info->entropy_coding_mode_flag = pic->entropy_coding_mode_flag; + info->pic_order_present_flag = pic->pic_order_present_flag; + info->deblocking_filter_control_present_flag = pic->deblocking_filter_control_present_flag; - info.redundant_pic_cnt_present_flag = pic->redundant_pic_cnt_present_flag; - - memcpy (&info.scaling_lists_4x4, &pic->scaling_lists_4x4, 96); - memcpy (&info.scaling_lists_8x8, &pic->scaling_lists_8x8, 128); + info->redundant_pic_cnt_present_flag = pic->redundant_pic_cnt_present_flag; - gst_h264_dpb_fill_reference_frames (h264_dec->dpb, info.referenceFrames); + memcpy (&info->scaling_lists_4x4, &pic->scaling_lists_4x4, 96); + memcpy (&info->scaling_lists_8x8, &pic->scaling_lists_8x8, 128); - return info; + gst_h264_dpb_fill_reference_frames (h264_dec->dpb, info->referenceFrames); } static VdpBitstreamBuffer * gst_vdp_h264_dec_create_bitstream_buffers (GstVdpH264Dec * h264_dec, - GstH264Frame * h264_frame, guint * n_bufs) + GstH264Meta * meta, GstMapInfo * info) { VdpBitstreamBuffer *bufs; + guint i; + gsize offset = 0; - if (h264_dec->packetized) { - guint i; + bufs = g_new (VdpBitstreamBuffer, meta->num_slices); - bufs = g_new (VdpBitstreamBuffer, h264_frame->slices->len * 2); - *n_bufs = h264_frame->slices->len * 2; - - for (i = 0; i < h264_frame->slices->len; i++) { - static const guint8 start_code[] = { 0x00, 0x00, 0x01 }; - guint idx; - GstBuffer *buf; - - idx = i * 2; - bufs[idx].bitstream = start_code; - bufs[idx].bitstream_bytes = 3; - bufs[idx].struct_version = VDP_BITSTREAM_BUFFER_VERSION; - - idx = idx + 1; - buf = GST_BUFFER_CAST (g_ptr_array_index (h264_frame->slices, i)); - bufs[idx].bitstream = GST_BUFFER_DATA (buf) + h264_dec->nal_length_size; - bufs[idx].bitstream_bytes = GST_BUFFER_SIZE (buf) - - h264_dec->nal_length_size; - bufs[idx].struct_version = VDP_BITSTREAM_BUFFER_VERSION; - } - } - - else { - guint i; - - bufs = g_new (VdpBitstreamBuffer, h264_frame->slices->len); - *n_bufs = h264_frame->slices->len; - - for (i = 0; i < h264_frame->slices->len; i++) { - GstBuffer *buf; - - buf = GST_BUFFER_CAST (g_ptr_array_index (h264_frame->slices, i)); - bufs[i].bitstream = GST_BUFFER_DATA (buf); - bufs[i].bitstream_bytes = GST_BUFFER_SIZE (buf); - bufs[i].struct_version = VDP_BITSTREAM_BUFFER_VERSION; - } + for (i = 0; i < meta->num_slices; i++) { + bufs[i].bitstream = info->data + offset; + if (i == meta->num_slices) + offset = info->size; + else + offset = meta->slice_offsets[i + 1]; + bufs[i].bitstream_bytes = offset - meta->slice_offsets[i]; + bufs[i].struct_version = VDP_BITSTREAM_BUFFER_VERSION; } return bufs; } static GstFlowReturn -gst_vdp_h264_dec_handle_frame (GstBaseVideoDecoder * base_video_decoder, - GstVideoFrame * frame, GstClockTimeDiff deadline) +gst_vdp_h264_dec_handle_dpb (GstVdpH264Dec * h264_dec, + GstH264Frame * h264_frame, GstH264SliceHdr * slice) { - GstVdpH264Dec *h264_dec = GST_VDP_H264_DEC (base_video_decoder); - - GstH264Frame *h264_frame; - GstH264Slice *slice; - GstH264Picture *pic G_GNUC_UNUSED; - GstH264Sequence *seq G_GNUC_UNUSED; - - GstFlowReturn ret; - GstVdpVideoBuffer *outbuf; - VdpPictureInfoH264 info; - VdpBitstreamBuffer *bufs; - guint n_bufs; - - GST_DEBUG ("handle_frame"); - - h264_frame = GST_H264_FRAME_CAST (frame); - - slice = &h264_frame->slice_hdr; - pic = slice->picture; - seq = pic->sequence; - - - if (slice->nal_unit.IdrPicFlag) { - ret = gst_vdp_h264_dec_idr (h264_dec, h264_frame); - - if (ret == GST_FLOW_OK) - h264_dec->got_idr = TRUE; - else { - gst_base_video_decoder_skip_frame (base_video_decoder, frame); - return GST_FLOW_OK; - } - } - - /* check if we've got a IDR frame yet */ - if (!h264_dec->got_idr) { - gst_base_video_decoder_skip_frame (base_video_decoder, frame); - return GST_FLOW_OK; - } - - - gst_vdp_h264_dec_init_frame_info (h264_dec, h264_frame); - - info = gst_vdp_h264_dec_fill_info (h264_dec, h264_frame); - bufs = gst_vdp_h264_dec_create_bitstream_buffers (h264_dec, h264_frame, - &n_bufs); - - ret = gst_vdp_decoder_render (GST_VDP_DECODER (h264_dec), - (VdpPictureInfo *) & info, n_bufs, bufs, &outbuf); - g_free (bufs); - - if (ret != GST_FLOW_OK) { - gst_base_video_decoder_skip_frame (base_video_decoder, frame); - return ret; - } - - frame->src_buffer = GST_BUFFER_CAST (outbuf); - - - /* DPB handling */ - if (slice->nal_unit.ref_idc != 0 && !slice->nal_unit.IdrPicFlag) { + if (slice->nalu_ref_idc != 0 && slice->slice_type != GST_H264_NAL_SLICE_IDR) { if (slice->dec_ref_pic_marking.adaptive_ref_pic_marking_mode_flag) { GstH264RefPicMarking *marking; guint i; @@ -586,242 +358,148 @@ gst_vdp_h264_dec_handle_frame (GstBaseVideoDecoder * base_video_decoder, } return gst_h264_dpb_add (h264_dec->dpb, h264_frame); + } -static gint -gst_vdp_h264_dec_scan_for_sync (GstBaseVideoDecoder * base_video_decoder, - GstAdapter * adapter) +static void +gst_h264_frame_free (GstH264Frame * frame) { - GstVdpH264Dec *h264_dec = GST_VDP_H264_DEC (base_video_decoder); - gint m; - - if (h264_dec->packetized) - return 0; - - m = gst_adapter_masked_scan_uint32 (adapter, 0xffffff00, 0x00000100, - 0, gst_adapter_available (adapter)); - if (m == -1) - return gst_adapter_available (adapter) - SYNC_CODE_SIZE; - - return m; + g_slice_free (GstH264Frame, frame); } -static GstBaseVideoDecoderScanResult -gst_vdp_h264_dec_scan_for_packet_end (GstBaseVideoDecoder * base_video_decoder, - GstAdapter * adapter, guint * size, gboolean at_eos) +static GstFlowReturn +gst_vdp_h264_dec_handle_frame (GstVideoDecoder * video_decoder, + GstVideoCodecFrame * frame) { - GstVdpH264Dec *h264_dec = GST_VDP_H264_DEC (base_video_decoder); - guint avail; - - avail = gst_adapter_available (adapter); - if (avail < h264_dec->nal_length_size) - return GST_BASE_VIDEO_DECODER_SCAN_RESULT_NEED_DATA; - - if (h264_dec->packetized) { - guint8 *data; - gint i; - guint32 nal_length = 0; + GstVdpH264Dec *h264_dec = GST_VDP_H264_DEC (video_decoder); + GstH264Meta *h264_meta; + GstH264Frame *h264_frame; + GList *tmp; + GstFlowReturn ret; + VdpPictureInfoH264 info; + VdpBitstreamBuffer *bufs; + GstH264SliceHdr *first_slice; + guint i; + GstMapInfo map; - data = g_slice_alloc (h264_dec->nal_length_size); - gst_adapter_copy (adapter, data, 0, h264_dec->nal_length_size); - for (i = 0; i < h264_dec->nal_length_size; i++) - nal_length = (nal_length << 8) | data[i]; + GST_DEBUG ("handle_frame"); - g_slice_free1 (h264_dec->nal_length_size, data); + h264_meta = gst_buffer_get_h264_meta (frame->input_buffer); + if (G_UNLIKELY (h264_meta == NULL)) + goto no_h264_meta; - nal_length += h264_dec->nal_length_size; + if (G_UNLIKELY (h264_meta->num_slices == 0)) + goto no_slices; - /* check for invalid NALU sizes, assume the size if the available bytes - * when something is fishy */ - if (nal_length <= 1 || nal_length > avail) { - nal_length = avail - h264_dec->nal_length_size; - GST_DEBUG ("fixing invalid NALU size to %u", nal_length); + /* Handle PPS/SPS/SEI if present */ + if (h264_meta->sps) { + for (tmp = h264_meta->sps; tmp; tmp = tmp->next) { + GstH264SPS *sps = (GstH264SPS *) tmp->data; + GST_LOG_OBJECT (h264_dec, "Storing SPS %d", sps->id); + h264_dec->sps[sps->id] = g_slice_dup (GstH264SPS, sps); } - - *size = nal_length; } - - else { - guint8 *data; - guint32 start_code; - guint n; - - data = g_slice_alloc (SYNC_CODE_SIZE); - gst_adapter_copy (adapter, data, 0, SYNC_CODE_SIZE); - start_code = ((data[0] << 16) && (data[1] << 8) && data[2]); - g_slice_free1 (SYNC_CODE_SIZE, data); - - GST_DEBUG ("start_code: %d", start_code); - if (start_code == 0x000001) - return GST_BASE_VIDEO_DECODER_SCAN_RESULT_LOST_SYNC; - - n = gst_adapter_masked_scan_uint32 (adapter, 0xffffff00, 0x00000100, - SYNC_CODE_SIZE, avail - SYNC_CODE_SIZE); - if (n == -1) - return GST_BASE_VIDEO_DECODER_SCAN_RESULT_NEED_DATA; - - *size = n; + if (h264_meta->pps) { + for (tmp = h264_meta->pps; tmp; tmp = tmp->next) { + GstH264PPS *pps = (GstH264PPS *) tmp->data; + GST_LOG_OBJECT (h264_dec, "Storing PPS %d", pps->id); + h264_dec->pps[pps->id] = g_slice_dup (GstH264PPS, pps); + /* Adjust pps pointer */ + h264_dec->pps[pps->id]->sequence = h264_dec->sps[pps->sps_id]; + } } - GST_DEBUG ("NAL size: %d", *size); - - return GST_BASE_VIDEO_DECODER_SCAN_RESULT_OK; -} - -static GstFlowReturn -gst_vdp_h264_dec_parse_data (GstBaseVideoDecoder * base_video_decoder, - GstBuffer * buf, gboolean at_eos, GstVideoFrame * frame) -{ - GstVdpH264Dec *h264_dec = GST_VDP_H264_DEC (base_video_decoder); - GstBitReader reader; - GstNalUnit nal_unit; - guint8 forbidden_zero_bit; + first_slice = &h264_meta->slices[0]; - guint8 *data; - guint size; - gint i; + if (!h264_dec->got_idr && first_slice->slice_type != GST_H264_NAL_SLICE_IDR) + goto no_idr; - GstFlowReturn ret = GST_FLOW_OK; + /* Handle slices */ + for (i = 0; i < h264_meta->num_slices; i++) { + GstH264SliceHdr *slice = &h264_meta->slices[i]; - GST_MEMDUMP ("data", GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf)); + GST_LOG_OBJECT (h264_dec, "Handling slice #%d", i); + slice->pps = h264_dec->pps[slice->pps_id]; + } - gst_bit_reader_init_from_buffer (&reader, buf); + if (first_slice->slice_type == GST_H264_NAL_SLICE_IDR) { + ret = gst_vdp_h264_dec_idr (h264_dec, frame, first_slice); + if (ret == GST_FLOW_OK) + h264_dec->got_idr = TRUE; + else + goto skip_frame; + } - if (gst_bit_reader_get_remaining (&reader) < - h264_dec->nal_length_size * 8 + 7) - goto invalid_packet; + h264_frame = g_slice_new0 (GstH264Frame); + gst_video_codec_frame_set_user_data (frame, h264_frame, + (GDestroyNotify) gst_h264_frame_free); - /* skip nal_length or sync code */ - gst_bit_reader_skip_unchecked (&reader, h264_dec->nal_length_size * 8); + gst_vdp_h264_dec_init_frame_info (h264_dec, h264_frame, first_slice); + h264_frame->frame = frame; + gst_vdp_h264_dec_fill_info (&info, h264_dec, h264_frame, first_slice); + info.slice_count = h264_meta->num_slices; - forbidden_zero_bit = gst_bit_reader_get_bits_uint8_unchecked (&reader, 1); + if (!gst_buffer_map (frame->input_buffer, &map, GST_MAP_READ)) + goto map_fail; + bufs = gst_vdp_h264_dec_create_bitstream_buffers (h264_dec, h264_meta, &map); - if (forbidden_zero_bit != 0) { - GST_WARNING ("forbidden_zero_bit != 0"); - return GST_FLOW_ERROR; - } + ret = gst_vdp_decoder_render (GST_VDP_DECODER (h264_dec), + (VdpPictureInfo *) & info, h264_meta->num_slices, bufs, frame); + g_free (bufs); + gst_buffer_unmap (frame->input_buffer, &map); - nal_unit.ref_idc = gst_bit_reader_get_bits_uint16_unchecked (&reader, 2); - GST_DEBUG ("nal_ref_idc: %u", nal_unit.ref_idc); + if (ret != GST_FLOW_OK) + goto render_fail; - /* read nal_unit_type */ - nal_unit.type = gst_bit_reader_get_bits_uint16_unchecked (&reader, 5); + /* DPB handling */ + return gst_vdp_h264_dec_handle_dpb (h264_dec, h264_frame, first_slice); - GST_DEBUG ("nal_unit_type: %u", nal_unit.type); - if (nal_unit.type == 14 || nal_unit.type == 20) { - if (!gst_bit_reader_skip (&reader, 24)) - goto invalid_packet; + /* EARLY exit */ +no_idr: + { + GST_DEBUG_OBJECT (video_decoder, "Didn't see a IDR yet, skipping frame"); + return gst_video_decoder_finish_frame (video_decoder, frame); } - nal_unit.IdrPicFlag = (nal_unit.type == 5 ? 1 : 0); - - data = GST_BUFFER_DATA (buf) + gst_bit_reader_get_pos (&reader) / 8; - size = gst_bit_reader_get_remaining (&reader) / 8; - i = size - 1; - while ((gint) size > 0 && data[i] == 0x00) { - size--; - i--; +skip_frame: + { + GST_DEBUG_OBJECT (video_decoder, "Skipping frame"); + return gst_video_decoder_finish_frame (video_decoder, frame); } - if (GST_VIDEO_FRAME_FLAG_IS_SET (frame, GST_H264_FRAME_GOT_PRIMARY)) { - if (nal_unit.type == GST_NAL_SPS || nal_unit.type == GST_NAL_PPS || - nal_unit.type == GST_NAL_SEI || nal_unit.type == GST_NAL_AU_DELIMITER || - (nal_unit.type >= 14 && nal_unit.type <= 18)) - ret = - gst_base_video_decoder_have_frame (base_video_decoder, FALSE, &frame); + /* ERRORS */ +no_h264_meta: + { + GST_ERROR_OBJECT (video_decoder, "Input buffer doesn't have GstH264Meta"); + return GST_FLOW_ERROR; } - if (nal_unit.type >= GST_NAL_SLICE && nal_unit.type <= GST_NAL_SLICE_IDR) { - GstH264Slice slice; - - if (!gst_h264_parser_parse_slice_header (h264_dec->parser, &slice, data, - size, nal_unit)) - goto invalid_packet; - - if (slice.redundant_pic_cnt == 0) { - if (GST_VIDEO_FRAME_FLAG_IS_SET (frame, GST_H264_FRAME_GOT_PRIMARY)) { - GstH264Slice *p_slice; - guint8 pic_order_cnt_type, p_pic_order_cnt_type; - gboolean finish_frame = FALSE; - - p_slice = &(GST_H264_FRAME_CAST (frame)->slice_hdr); - pic_order_cnt_type = slice.picture->sequence->pic_order_cnt_type; - p_pic_order_cnt_type = p_slice->picture->sequence->pic_order_cnt_type; - - if (slice.frame_num != p_slice->frame_num) - finish_frame = TRUE; - - else if (slice.picture != p_slice->picture) - finish_frame = TRUE; - - else if (slice.bottom_field_flag != p_slice->bottom_field_flag) - finish_frame = TRUE; - - else if (nal_unit.ref_idc != p_slice->nal_unit.ref_idc && - (nal_unit.ref_idc == 0 || p_slice->nal_unit.ref_idc == 0)) - finish_frame = TRUE; - - else if ((pic_order_cnt_type == 0 && p_pic_order_cnt_type == 0) && - (slice.pic_order_cnt_lsb != p_slice->pic_order_cnt_lsb || - slice.delta_pic_order_cnt_bottom != - p_slice->delta_pic_order_cnt_bottom)) - finish_frame = TRUE; - - else if ((p_pic_order_cnt_type == 1 && p_pic_order_cnt_type == 1) && - (slice.delta_pic_order_cnt[0] != p_slice->delta_pic_order_cnt[0] || - slice.delta_pic_order_cnt[1] != - p_slice->delta_pic_order_cnt[1])) - finish_frame = TRUE; - - if (finish_frame) - ret = - gst_base_video_decoder_have_frame (base_video_decoder, FALSE, - &frame); - - } - - if (!GST_VIDEO_FRAME_FLAG_IS_SET (frame, GST_H264_FRAME_GOT_PRIMARY)) { - if (GST_H264_IS_I_SLICE (slice.type) - || GST_H264_IS_SI_SLICE (slice.type)) - GST_VIDEO_FRAME_FLAG_SET (frame, GST_VIDEO_FRAME_FLAG_KEYFRAME); - - GST_H264_FRAME_CAST (frame)->slice_hdr = slice; - GST_VIDEO_FRAME_FLAG_SET (frame, GST_H264_FRAME_GOT_PRIMARY); - } - } - gst_h264_frame_add_slice ((GstH264Frame *) frame, buf); +no_slices: + { + GST_ERROR_OBJECT (video_decoder, "Input buffer doesn't have any slices"); + return GST_FLOW_ERROR; } - if (nal_unit.type == GST_NAL_SPS) { - if (!gst_h264_parser_parse_sequence (h264_dec->parser, data, size)) - goto invalid_packet; +map_fail: + { + GST_ERROR_OBJECT (video_decoder, "Failed to map input buffer for READ"); + return GST_FLOW_ERROR; } - if (nal_unit.type == GST_NAL_PPS) { - if (!gst_h264_parser_parse_picture (h264_dec->parser, data, size)) - goto invalid_packet; +render_fail: + { + GST_ERROR_OBJECT (video_decoder, "Failed to render : %s", + gst_flow_get_name (ret)); + gst_video_decoder_drop_frame (video_decoder, frame); + return ret; } - - gst_buffer_unref (buf); - return ret; - -invalid_packet: - GST_WARNING ("Invalid packet size!"); - gst_buffer_unref (buf); - - return GST_FLOW_OK; } -static GstVideoFrame * -gst_vdp_h264_dec_create_frame (GstBaseVideoDecoder * base_video_decoder) -{ - return GST_VIDEO_FRAME_CAST (gst_h264_frame_new ()); -} static gboolean -gst_vdp_h264_dec_flush (GstBaseVideoDecoder * base_video_decoder) +gst_vdp_h264_dec_reset (GstVideoDecoder * video_decoder, gboolean hard) { - GstVdpH264Dec *h264_dec = GST_VDP_H264_DEC (base_video_decoder); + GstVdpH264Dec *h264_dec = GST_VDP_H264_DEC (video_decoder); h264_dec->got_idr = FALSE; gst_h264_dpb_flush (h264_dec->dpb, FALSE); @@ -830,75 +508,75 @@ gst_vdp_h264_dec_flush (GstBaseVideoDecoder * base_video_decoder) } static gboolean -gst_vdp_h264_dec_start (GstBaseVideoDecoder * base_video_decoder) +gst_vdp_h264_dec_start (GstVideoDecoder * video_decoder) { - GstVdpH264Dec *h264_dec = GST_VDP_H264_DEC (base_video_decoder); - - h264_dec->packetized = FALSE; - h264_dec->nal_length_size = SYNC_CODE_SIZE; + GstVdpH264Dec *h264_dec = GST_VDP_H264_DEC (video_decoder); h264_dec->got_idr = FALSE; - h264_dec->sequence = NULL; - - h264_dec->parser = g_object_new (GST_TYPE_H264_PARSER, NULL); + h264_dec->current_sps = -1; + h264_dec->got_idr = FALSE; h264_dec->dpb = g_object_new (GST_TYPE_H264_DPB, NULL); gst_h264_dpb_set_output_func (h264_dec->dpb, gst_vdp_h264_dec_output, h264_dec); - return GST_BASE_VIDEO_DECODER_CLASS - (parent_class)->start (base_video_decoder); + return GST_VIDEO_DECODER_CLASS (parent_class)->start (video_decoder); } static gboolean -gst_vdp_h264_dec_stop (GstBaseVideoDecoder * base_video_decoder) +gst_vdp_h264_dec_stop (GstVideoDecoder * video_decoder) { - GstVdpH264Dec *h264_dec = GST_VDP_H264_DEC (base_video_decoder); + GstVdpH264Dec *h264_dec = GST_VDP_H264_DEC (video_decoder); - g_object_unref (h264_dec->parser); g_object_unref (h264_dec->dpb); - return GST_BASE_VIDEO_DECODER_CLASS (parent_class)->stop (base_video_decoder); + return GST_VIDEO_DECODER_CLASS (parent_class)->stop (video_decoder); } -static void -gst_vdp_h264_dec_base_init (gpointer g_class) +static gboolean +gst_vdp_h264_dec_set_format (GstVideoDecoder * video_decoder, + GstVideoCodecState * state) { - GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); + GstVdpH264Dec *h264_dec = GST_VDP_H264_DEC (video_decoder); - gst_element_class_set_static_metadata (element_class, - "VDPAU H264 Decoder", - "Decoder", - "Decode h264 stream with vdpau", - "Carl-Anton Ingmarsson <ca.ingmarsson@gmail.com>"); + if (h264_dec->input_state) + gst_video_codec_state_unref (h264_dec->input_state); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&sink_template)); + h264_dec->input_state = gst_video_codec_state_ref (state); + + GST_FIXME_OBJECT (video_decoder, "Do something when receiving input state ?"); + + return TRUE; } static void -gst_vdp_h264_dec_init (GstVdpH264Dec * h264_dec, GstVdpH264DecClass * klass) +gst_vdp_h264_dec_init (GstVdpH264Dec * h264_dec) { } static void gst_vdp_h264_dec_class_init (GstVdpH264DecClass * klass) { - GstBaseVideoDecoderClass *base_video_decoder_class; + GstElementClass *element_class; + GstVideoDecoderClass *video_decoder_class; - base_video_decoder_class = GST_BASE_VIDEO_DECODER_CLASS (klass); + element_class = GST_ELEMENT_CLASS (klass); + video_decoder_class = GST_VIDEO_DECODER_CLASS (klass); - base_video_decoder_class->start = gst_vdp_h264_dec_start; - base_video_decoder_class->stop = gst_vdp_h264_dec_stop; - base_video_decoder_class->flush = gst_vdp_h264_dec_flush; + gst_element_class_set_static_metadata (element_class, + "VDPAU H264 Decoder", + "Decoder", + "Decode h264 stream with vdpau", + "Carl-Anton Ingmarsson <ca.ingmarsson@gmail.com>"); + + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&sink_template)); - base_video_decoder_class->set_sink_caps = gst_vdp_h264_dec_set_sink_caps; + video_decoder_class->start = gst_vdp_h264_dec_start; + video_decoder_class->stop = gst_vdp_h264_dec_stop; + video_decoder_class->reset = gst_vdp_h264_dec_reset; - base_video_decoder_class->scan_for_sync = gst_vdp_h264_dec_scan_for_sync; - base_video_decoder_class->scan_for_packet_end = - gst_vdp_h264_dec_scan_for_packet_end; - base_video_decoder_class->parse_data = gst_vdp_h264_dec_parse_data; + video_decoder_class->set_format = gst_vdp_h264_dec_set_format; - base_video_decoder_class->handle_frame = gst_vdp_h264_dec_handle_frame; - base_video_decoder_class->create_frame = gst_vdp_h264_dec_create_frame; + video_decoder_class->handle_frame = gst_vdp_h264_dec_handle_frame; } diff --git a/sys/vdpau/h264/gstvdph264dec.h b/sys/vdpau/h264/gstvdph264dec.h index a067a09f8..07074338c 100644 --- a/sys/vdpau/h264/gstvdph264dec.h +++ b/sys/vdpau/h264/gstvdph264dec.h @@ -22,10 +22,9 @@ #define __GST_VDP_H264_DEC_H__ #include <gst/gst.h> +#include <gst/codecparsers/gsth264parser.h> -#include "../gstvdp/gstvdpdecoder.h" - -#include "gsth264parser.h" +#include "../gstvdpdecoder.h" #include "gsth264dpb.h" G_BEGIN_DECLS @@ -45,16 +44,17 @@ typedef struct _GstVdpH264DecClass GstVdpH264DecClass; struct _GstVdpH264Dec { GstVdpDecoder vdp_decoder; - gboolean packetized; - guint8 nal_length_size; - - GstH264Parser *parser; GstH264DPB *dpb; + GstH264SPS *sps[GST_H264_MAX_SPS_COUNT]; + GstH264PPS *pps[GST_H264_MAX_PPS_COUNT]; + + /* Current SPS being used. Default:-1 */ + gint current_sps; - GstH264Sequence *sequence; gboolean got_idr; - VdpDecoder decoder; + GstVideoCodecState *input_state; + guint poc_msb; guint prev_poc_lsb; }; @@ -67,4 +67,4 @@ GType gst_vdp_h264_dec_get_type (void); G_END_DECLS -#endif /* __GST_VDP_H264_DEC_H__ */
\ No newline at end of file +#endif /* __GST_VDP_H264_DEC_H__ */ diff --git a/sys/vdpau/mpeg/gstvdpmpegdec.c b/sys/vdpau/mpeg/gstvdpmpegdec.c index 8a3a37a8a..68cd48ff8 100644 --- a/sys/vdpau/mpeg/gstvdpmpegdec.c +++ b/sys/vdpau/mpeg/gstvdpmpegdec.c @@ -38,11 +38,12 @@ #include <gst/gst.h> #include <gst/base/gstbytereader.h> #include <gst/base/gstbitreader.h> +#include <gst/codecparsers/gstmpegvideoparser.h> +#include <gst/codecparsers/gstmpegvideometa.h> #include <string.h> -#include "mpegutil.h" - #include "gstvdpmpegdec.h" +#include "gstvdpvideomemory.h" GST_DEBUG_CATEGORY_STATIC (gst_vdp_mpeg_dec_debug); #define GST_CAT_DEFAULT gst_vdp_mpeg_dec_debug @@ -58,24 +59,24 @@ static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink", "systemstream = (boolean) false") ); -#define DEBUG_INIT(bla) \ +#define DEBUG_INIT \ GST_DEBUG_CATEGORY_INIT (gst_vdp_mpeg_dec_debug, "vdpaumpegdec", 0, \ "VDPAU mpeg decoder"); - -GST_BOILERPLATE_FULL (GstVdpMpegDec, gst_vdp_mpeg_dec, - GstVdpDecoder, GST_TYPE_VDP_DECODER, DEBUG_INIT); +#define gst_vdp_mpeg_dec_parent_class parent_class +G_DEFINE_TYPE_WITH_CODE (GstVdpMpegDec, gst_vdp_mpeg_dec, GST_TYPE_VDP_DECODER, + DEBUG_INIT); static void gst_vdp_mpeg_dec_init_info (VdpPictureInfoMPEG1Or2 * vdp_info); #define SYNC_CODE_SIZE 3 static VdpDecoderProfile -gst_vdp_mpeg_dec_get_profile (MPEGSeqExtHdr * hdr) +gst_vdp_mpeg_dec_get_profile (GstMpegVideoSequenceExt * hdr) { VdpDecoderProfile profile; switch (hdr->profile) { - case 5: + case GST_MPEG_VIDEO_PROFILE_SIMPLE: profile = VDP_DECODER_PROFILE_MPEG2_SIMPLE; break; default: @@ -88,86 +89,105 @@ gst_vdp_mpeg_dec_get_profile (MPEGSeqExtHdr * hdr) static gboolean gst_vdp_mpeg_dec_handle_picture_coding (GstVdpMpegDec * mpeg_dec, - GstBuffer * buffer, GstVideoFrame * frame) + GstMpegVideoPictureExt * pic_ext, GstVideoCodecFrame * frame) { - MPEGPictureExt pic_ext; VdpPictureInfoMPEG1Or2 *info; +#if 0 gint fields; +#endif + + GST_DEBUG_OBJECT (mpeg_dec, "Handling GstMpegVideoPictureExt"); info = &mpeg_dec->vdp_info; - if (!mpeg_util_parse_picture_coding_extension (&pic_ext, buffer)) - return FALSE; + /* FIXME : Set defaults when pic_ext isn't present */ - memcpy (&mpeg_dec->vdp_info.f_code, &pic_ext.f_code, 4); + memcpy (&mpeg_dec->vdp_info.f_code, &pic_ext->f_code, 4); - info->intra_dc_precision = pic_ext.intra_dc_precision; - info->picture_structure = pic_ext.picture_structure; - info->top_field_first = pic_ext.top_field_first; - info->frame_pred_frame_dct = pic_ext.frame_pred_frame_dct; - info->concealment_motion_vectors = pic_ext.concealment_motion_vectors; - info->q_scale_type = pic_ext.q_scale_type; - info->intra_vlc_format = pic_ext.intra_vlc_format; - info->alternate_scan = pic_ext.alternate_scan; + info->intra_dc_precision = pic_ext->intra_dc_precision; + info->picture_structure = pic_ext->picture_structure; + info->top_field_first = pic_ext->top_field_first; + info->frame_pred_frame_dct = pic_ext->frame_pred_frame_dct; + info->concealment_motion_vectors = pic_ext->concealment_motion_vectors; + info->q_scale_type = pic_ext->q_scale_type; + info->intra_vlc_format = pic_ext->intra_vlc_format; + info->alternate_scan = pic_ext->alternate_scan; +#if 0 fields = 2; - if (pic_ext.picture_structure == 3) { + if (pic_ext->picture_structure == 3) { if (mpeg_dec->stream_info.interlaced) { - if (pic_ext.progressive_frame == 0) + if (pic_ext->progressive_frame == 0) fields = 2; - if (pic_ext.progressive_frame == 0 && pic_ext.repeat_first_field == 0) + if (pic_ext->progressive_frame == 0 && pic_ext->repeat_first_field == 0) fields = 2; - if (pic_ext.progressive_frame == 1 && pic_ext.repeat_first_field == 1) + if (pic_ext->progressive_frame == 1 && pic_ext->repeat_first_field == 1) fields = 3; } else { - if (pic_ext.repeat_first_field == 0) + if (pic_ext->repeat_first_field == 0) fields = 2; - if (pic_ext.repeat_first_field == 1 && pic_ext.top_field_first == 0) + if (pic_ext->repeat_first_field == 1 && pic_ext->top_field_first == 0) fields = 4; - if (pic_ext.repeat_first_field == 1 && pic_ext.top_field_first == 1) + if (pic_ext->repeat_first_field == 1 && pic_ext->top_field_first == 1) fields = 6; } } else fields = 1; +#endif - frame->n_fields = fields; - - if (pic_ext.top_field_first) - GST_VIDEO_FRAME_FLAG_SET (frame, GST_VIDEO_FRAME_FLAG_TFF); + if (pic_ext->top_field_first) + GST_FIXME ("Set TFF on outgoing buffer"); +#if 0 + GST_VIDEO_FRAME_FLAG_SET (frame, GST_VIDEO_FRAME_FLAG_TFF); +#endif return TRUE; } static gboolean -gst_vdp_mpeg_dec_handle_picture (GstVdpMpegDec * mpeg_dec, GstBuffer * buffer) +gst_vdp_mpeg_dec_handle_picture (GstVdpMpegDec * mpeg_dec, + GstMpegVideoPictureHdr * pic_hdr) { - MPEGPictureHdr pic_hdr; - - if (!mpeg_util_parse_picture_hdr (&pic_hdr, buffer)) - return FALSE; + GST_DEBUG_OBJECT (mpeg_dec, "Handling GstMpegVideoPictureHdr"); - mpeg_dec->vdp_info.picture_coding_type = pic_hdr.pic_type; + mpeg_dec->vdp_info.picture_coding_type = pic_hdr->pic_type; if (mpeg_dec->stream_info.version == 1) { mpeg_dec->vdp_info.full_pel_forward_vector = - pic_hdr.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); + pic_hdr->full_pel_backward_vector; + memcpy (&mpeg_dec->vdp_info.f_code, &pic_hdr->f_code, 4); } - mpeg_dec->frame_nr = mpeg_dec->gop_frame + pic_hdr.tsn; + mpeg_dec->frame_nr = mpeg_dec->gop_frame + pic_hdr->tsn; return TRUE; } static gboolean -gst_vdp_mpeg_dec_handle_gop (GstVdpMpegDec * mpeg_dec, GstBuffer * buffer) +gst_vdp_mpeg_dec_set_format (GstVideoDecoder * decoder, + GstVideoCodecState * state) { - MPEGGop gop; + GstVdpMpegDec *mpeg_dec = (GstVdpMpegDec *) decoder; + + /* FIXME : Check the hardware can handle the level/profile */ + if (mpeg_dec->input_state) + gst_video_codec_state_unref (mpeg_dec->input_state); + mpeg_dec->input_state = gst_video_codec_state_ref (state); + + return TRUE; +} + +#if 0 +static gboolean +gst_vdp_mpeg_dec_handle_gop (GstVdpMpegDec * mpeg_dec, const guint8 * data, + gsize size, guint offset) +{ + GstMpegVideoGop gop; GstClockTime time; - if (!mpeg_util_parse_gop (&gop, buffer)) + if (!gst_mpeg_video_parse_gop (&gop, data, size, offset)) return FALSE; time = GST_SECOND * (gop.hour * 3600 + gop.minute * 60 + gop.second); @@ -183,185 +203,157 @@ gst_vdp_mpeg_dec_handle_gop (GstVdpMpegDec * mpeg_dec, GstBuffer * buffer) return TRUE; } +#endif static gboolean gst_vdp_mpeg_dec_handle_quant_matrix (GstVdpMpegDec * mpeg_dec, - GstBuffer * buffer) + GstMpegVideoQuantMatrixExt * qm) { - MPEGQuantMatrix qm; - - if (!mpeg_util_parse_quant_matrix (&qm, buffer)) - return FALSE; + GST_DEBUG_OBJECT (mpeg_dec, "Handling GstMpegVideoQuantMatrixExt"); memcpy (&mpeg_dec->vdp_info.intra_quantizer_matrix, - &qm.intra_quantizer_matrix, 64); + &qm->intra_quantiser_matrix, 64); memcpy (&mpeg_dec->vdp_info.non_intra_quantizer_matrix, - &qm.non_intra_quantizer_matrix, 64); + &qm->non_intra_quantiser_matrix, 64); + return TRUE; } static GstFlowReturn gst_vdp_mpeg_dec_handle_sequence (GstVdpMpegDec * mpeg_dec, - GstBuffer * seq, GstBuffer * seq_ext) + GstMpegVideoSequenceHdr * hdr, GstMpegVideoSequenceExt * ext) { - GstBaseVideoDecoder *base_video_decoder = GST_BASE_VIDEO_DECODER (mpeg_dec); - - MPEGSeqHdr hdr; + GstFlowReturn ret; + GstVideoDecoder *video_decoder = GST_VIDEO_DECODER (mpeg_dec); GstVdpMpegStreamInfo stream_info; - if (!mpeg_util_parse_sequence_hdr (&hdr, seq)) - return GST_FLOW_CUSTOM_ERROR; + GST_DEBUG_OBJECT (mpeg_dec, "Handling GstMpegVideoSequenceHdr"); memcpy (&mpeg_dec->vdp_info.intra_quantizer_matrix, - &hdr.intra_quantizer_matrix, 64); + &hdr->intra_quantizer_matrix, 64); memcpy (&mpeg_dec->vdp_info.non_intra_quantizer_matrix, - &hdr.non_intra_quantizer_matrix, 64); + &hdr->non_intra_quantizer_matrix, 64); - stream_info.width = hdr.width; - stream_info.height = hdr.height; + stream_info.width = hdr->width; + stream_info.height = hdr->height; - stream_info.fps_n = hdr.fps_n; - stream_info.fps_d = hdr.fps_d; + stream_info.fps_n = hdr->fps_n; + stream_info.fps_d = hdr->fps_d; - stream_info.par_n = hdr.par_w; - stream_info.par_d = hdr.par_h; + stream_info.par_n = hdr->par_w; + stream_info.par_d = hdr->par_h; stream_info.interlaced = FALSE; stream_info.version = 1; stream_info.profile = VDP_DECODER_PROFILE_MPEG1; - if (seq_ext) { - MPEGSeqExtHdr ext; - - if (!mpeg_util_parse_sequence_extension (&ext, seq_ext)) - return GST_FLOW_CUSTOM_ERROR; + if (ext) { + GST_DEBUG_OBJECT (mpeg_dec, "Handling GstMpegVideoSequenceExt"); - stream_info.fps_n *= (ext.fps_n_ext + 1); - stream_info.fps_d *= (ext.fps_d_ext + 1); + /* FIXME : isn't this already processed by mpegvideoparse ? */ + stream_info.fps_n *= (ext->fps_n_ext + 1); + stream_info.fps_d *= (ext->fps_d_ext + 1); - stream_info.width += (ext.horiz_size_ext << 12); - stream_info.height += (ext.vert_size_ext << 12); + stream_info.width += (ext->horiz_size_ext << 12); + stream_info.height += (ext->vert_size_ext << 12); - stream_info.interlaced = !ext.progressive; + stream_info.interlaced = !ext->progressive; stream_info.version = 2; - stream_info.profile = gst_vdp_mpeg_dec_get_profile (&ext); - } - - if (memcmp (&mpeg_dec->stream_info, &stream_info, - sizeof (GstVdpMpegStreamInfo)) != 0) { - GstVideoState state; - GstFlowReturn ret; - - state = gst_base_video_decoder_get_state (base_video_decoder); - - state.width = stream_info.width; - state.height = stream_info.height; - - state.fps_n = stream_info.fps_n; - state.fps_d = stream_info.fps_d; - - state.par_n = stream_info.par_n; - state.par_d = stream_info.par_d; - - state.interlaced = stream_info.interlaced; - - gst_base_video_decoder_set_state (base_video_decoder, state); - - ret = gst_vdp_decoder_init_decoder (GST_VDP_DECODER (mpeg_dec), - stream_info.profile, 2); - if (ret != GST_FLOW_OK) - return ret; - - memcpy (&mpeg_dec->stream_info, &stream_info, - sizeof (GstVdpMpegStreamInfo)); + stream_info.profile = gst_vdp_mpeg_dec_get_profile (ext); } + GST_DEBUG_OBJECT (mpeg_dec, "Setting output state to %dx%d", + stream_info.width, stream_info.height); + mpeg_dec->output_state = + gst_video_decoder_set_output_state (video_decoder, GST_VIDEO_FORMAT_YV12, + stream_info.width, stream_info.height, mpeg_dec->input_state); + if (stream_info.interlaced) + mpeg_dec->output_state->info.interlace_mode = + GST_VIDEO_INTERLACE_MODE_INTERLEAVED; + gst_video_decoder_negotiate (video_decoder); + + ret = gst_vdp_decoder_init_decoder (GST_VDP_DECODER (mpeg_dec), + stream_info.profile, 2, mpeg_dec->output_state); mpeg_dec->state = GST_VDP_MPEG_DEC_STATE_NEED_DATA; - return GST_FLOW_OK; + return ret; } static GstFlowReturn -gst_vdp_mpeg_dec_handle_frame (GstBaseVideoDecoder * base_video_decoder, - GstVideoFrame * frame, GstClockTimeDiff deadline) +gst_vdp_mpeg_dec_handle_frame (GstVideoDecoder * video_decoder, + GstVideoCodecFrame * frame) { - GstVdpMpegDec *mpeg_dec = GST_VDP_MPEG_DEC (base_video_decoder); + GstVdpMpegDec *mpeg_dec = GST_VDP_MPEG_DEC (video_decoder); VdpPictureInfoMPEG1Or2 *info; - GstVdpMpegFrame *mpeg_frame; + GstMpegVideoMeta *mpeg_meta; + GstVdpVideoMemory *vmem; GstFlowReturn ret = GST_FLOW_OK; VdpBitstreamBuffer vbit[1]; - GstVdpVideoBuffer *outbuf; - - /* MPEG_PACKET_SEQUENCE */ - mpeg_frame = GST_VDP_MPEG_FRAME (frame); - if (mpeg_frame->seq) { - ret = gst_vdp_mpeg_dec_handle_sequence (mpeg_dec, mpeg_frame->seq, - mpeg_frame->seq_ext); - if (ret != GST_FLOW_OK) { - gst_base_video_decoder_skip_frame (base_video_decoder, frame); - return ret; - } - } + GstMapInfo mapinfo; - if (mpeg_dec->state == GST_VDP_MPEG_DEC_STATE_NEED_SEQUENCE) { - GST_DEBUG_OBJECT (mpeg_dec, "Drop frame since we haven't found a " - "MPEG_PACKET_SEQUENCE yet"); + /* FIXME : Specify in sink query that we need the mpeg video meta */ - gst_base_video_decoder_skip_frame (base_video_decoder, frame); - return GST_FLOW_OK; + /* Parse all incoming data from the frame */ + mpeg_meta = gst_buffer_get_mpeg_video_meta (frame->input_buffer); + if (!mpeg_meta) + goto no_meta; + + /* GST_MPEG_VIDEO_PACKET_SEQUENCE */ + if (mpeg_meta->sequencehdr) { + ret = + gst_vdp_mpeg_dec_handle_sequence (mpeg_dec, mpeg_meta->sequencehdr, + mpeg_meta->sequenceext); + if (ret != GST_FLOW_OK) + goto sequence_parse_fail; } - /* MPEG_PACKET_PICTURE */ - if (mpeg_frame->pic) - gst_vdp_mpeg_dec_handle_picture (mpeg_dec, mpeg_frame->pic); + if (mpeg_dec->state == GST_VDP_MPEG_DEC_STATE_NEED_SEQUENCE) + goto need_sequence; - /* MPEG_PACKET_EXT_PICTURE_CODING */ - if (mpeg_frame->pic_ext) - gst_vdp_mpeg_dec_handle_picture_coding (mpeg_dec, mpeg_frame->pic_ext, - frame); + /* GST_MPEG_VIDEO_PACKET_PICTURE */ + if (mpeg_meta->pichdr) + gst_vdp_mpeg_dec_handle_picture (mpeg_dec, mpeg_meta->pichdr); - /* MPEG_PACKET_GOP */ - if (mpeg_frame->gop) - gst_vdp_mpeg_dec_handle_gop (mpeg_dec, mpeg_frame->gop); + /* GST_MPEG_VIDEO_PACKET_EXT_PICTURE_CODING */ + if (mpeg_meta->picext) + gst_vdp_mpeg_dec_handle_picture_coding (mpeg_dec, mpeg_meta->picext, frame); - /* MPEG_PACKET_EXT_QUANT_MATRIX */ - if (mpeg_frame->qm_ext) - gst_vdp_mpeg_dec_handle_quant_matrix (mpeg_dec, mpeg_frame->qm_ext); + /* GST_MPEG_VIDEO_PACKET_GOP */ + /* if (mpeg_meta->gop) */ + /* GST_FIXME_OBJECT (mpeg_dec, "Handle GOP !"); */ + /* gst_vdp_mpeg_dec_handle_gop (mpeg_dec, mpeg_frame.gop); */ + /* GST_MPEG_VIDEO_PACKET_EXT_QUANT_MATRIX */ + if (mpeg_meta->quantext) + gst_vdp_mpeg_dec_handle_quant_matrix (mpeg_dec, mpeg_meta->quantext); info = &mpeg_dec->vdp_info; - info->slice_count = mpeg_frame->n_slices; - - /* check if we can decode the frame */ - if (info->picture_coding_type != I_FRAME - && info->backward_reference == VDP_INVALID_HANDLE) { - GST_DEBUG_OBJECT (mpeg_dec, - "Drop frame since we haven't got an I_FRAME yet"); + info->slice_count = mpeg_meta->num_slices; - gst_base_video_decoder_skip_frame (base_video_decoder, frame); - return GST_FLOW_OK; - } - if (info->picture_coding_type == B_FRAME - && info->forward_reference == VDP_INVALID_HANDLE) { - GST_DEBUG_OBJECT (mpeg_dec, - "Drop frame since we haven't got two non B_FRAMES yet"); + GST_DEBUG_OBJECT (mpeg_dec, "picture coding type %d", + info->picture_coding_type); - gst_base_video_decoder_skip_frame (base_video_decoder, frame); - return GST_FLOW_OK; - } + /* check if we can decode the frame */ + if (info->picture_coding_type != GST_MPEG_VIDEO_PICTURE_TYPE_I + && info->backward_reference == VDP_INVALID_HANDLE) + goto need_i_frame; + if (info->picture_coding_type == GST_MPEG_VIDEO_PICTURE_TYPE_B + && info->forward_reference == VDP_INVALID_HANDLE) + goto need_non_b_frame; - if (info->picture_coding_type != B_FRAME) { + if (info->picture_coding_type != GST_MPEG_VIDEO_PICTURE_TYPE_B) { if (info->backward_reference != VDP_INVALID_HANDLE) { - ret = gst_base_video_decoder_finish_frame (base_video_decoder, - mpeg_dec->b_frame); + GST_DEBUG_OBJECT (mpeg_dec, "Pushing B frame"); + ret = gst_video_decoder_finish_frame (video_decoder, mpeg_dec->b_frame); } if (info->forward_reference != VDP_INVALID_HANDLE) { - gst_video_frame_unref (mpeg_dec->f_frame); + GST_DEBUG_OBJECT (mpeg_dec, "Releasing no-longer needed forward frame"); + gst_video_codec_frame_unref (mpeg_dec->f_frame); info->forward_reference = VDP_INVALID_HANDLE; } @@ -371,211 +363,112 @@ gst_vdp_mpeg_dec_handle_frame (GstBaseVideoDecoder * base_video_decoder, info->backward_reference = VDP_INVALID_HANDLE; } - if (ret != GST_FLOW_OK) { - gst_base_video_decoder_skip_frame (base_video_decoder, frame); - return ret; - } + if (ret != GST_FLOW_OK) + goto exit_after_b_frame; /* decode */ + if (!gst_buffer_map (frame->input_buffer, &mapinfo, GST_MAP_READ)) + goto map_fail; + vbit[0].struct_version = VDP_BITSTREAM_BUFFER_VERSION; - vbit[0].bitstream = GST_BUFFER_DATA (mpeg_frame->slices); - vbit[0].bitstream_bytes = GST_BUFFER_SIZE (mpeg_frame->slices); + vbit[0].bitstream = mapinfo.data + mpeg_meta->slice_offset; + vbit[0].bitstream_bytes = mapinfo.size - mpeg_meta->slice_offset; ret = gst_vdp_decoder_render (GST_VDP_DECODER (mpeg_dec), - (VdpPictureInfo *) info, 1, vbit, &outbuf); + (VdpPictureInfo *) info, 1, vbit, frame); + + gst_buffer_unmap (frame->input_buffer, &mapinfo); + if (ret != GST_FLOW_OK) - return ret; + goto render_fail; - frame->src_buffer = GST_BUFFER_CAST (outbuf); + vmem = (GstVdpVideoMemory *) gst_buffer_get_memory (frame->output_buffer, 0); - if (info->picture_coding_type == B_FRAME) { - ret = gst_base_video_decoder_finish_frame (base_video_decoder, frame); + if (info->picture_coding_type == GST_MPEG_VIDEO_PICTURE_TYPE_B) { + ret = gst_video_decoder_finish_frame (video_decoder, frame); } else { - info->backward_reference = GST_VDP_VIDEO_BUFFER (outbuf)->surface; - mpeg_dec->b_frame = gst_video_frame_ref (frame); + info->backward_reference = vmem->surface; + mpeg_dec->b_frame = gst_video_codec_frame_ref (frame); } return ret; -} - -static GstVideoFrame * -gst_vdp_mpeg_dec_create_frame (GstBaseVideoDecoder * base_video_decoder) -{ - return GST_VIDEO_FRAME (gst_vdp_mpeg_frame_new ()); -} - -static GstFlowReturn -gst_vdp_mpeg_dec_parse_data (GstBaseVideoDecoder * base_video_decoder, - GstBuffer * buf, gboolean at_eos, GstVideoFrame * frame) -{ - GstVdpMpegDec *mpeg_dec = GST_VDP_MPEG_DEC (base_video_decoder); - - GstVdpMpegFrame *mpeg_frame; - GstFlowReturn ret = GST_FLOW_OK; - GstBitReader b_reader = GST_BIT_READER_INIT_FROM_BUFFER (buf); - guint8 start_code; - - if (gst_bit_reader_get_remaining (&b_reader) < 8 * 3 + 8) - return GST_FLOW_ERROR; - - /* skip sync_code */ - gst_bit_reader_skip_unchecked (&b_reader, 8 * 3); - /* start_code */ - start_code = gst_bit_reader_get_bits_uint8_unchecked (&b_reader, 8); - - mpeg_frame = GST_VDP_MPEG_FRAME_CAST (frame); - - if (start_code >= MPEG_PACKET_SLICE_MIN - && start_code <= MPEG_PACKET_SLICE_MAX) { - GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_SLICE"); + /* EARLY EXIT */ +need_sequence: + { + GST_DEBUG_OBJECT (mpeg_dec, "Drop frame since we haven't found a " + "GST_MPEG_VIDEO_PACKET_SEQUENCE yet"); - gst_vdp_mpeg_frame_add_slice (mpeg_frame, buf); - goto done; + gst_video_decoder_finish_frame (video_decoder, frame); + return GST_FLOW_OK; } - switch (start_code) { - case MPEG_PACKET_SEQUENCE: - GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_SEQUENCE"); - - if (mpeg_dec->prev_packet != -1) - ret = gst_base_video_decoder_have_frame (base_video_decoder, FALSE, - (GstVideoFrame **) & mpeg_frame); - - mpeg_frame->seq = buf; - break; - - case MPEG_PACKET_PICTURE: - GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_PICTURE"); - - if (mpeg_dec->prev_packet != MPEG_PACKET_SEQUENCE && - mpeg_dec->prev_packet != MPEG_PACKET_GOP) - ret = gst_base_video_decoder_have_frame (base_video_decoder, FALSE, - (GstVideoFrame **) & mpeg_frame); - - mpeg_frame->pic = buf; - break; - - case MPEG_PACKET_GOP: - GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_GOP"); - - if (mpeg_dec->prev_packet != MPEG_PACKET_SEQUENCE) - ret = gst_base_video_decoder_have_frame (base_video_decoder, FALSE, - (GstVideoFrame **) & mpeg_frame); - - mpeg_frame->gop = buf; - break; - - case MPEG_PACKET_EXTENSION: - { - guint8 ext_code; - - /* ext_code */ - if (!gst_bit_reader_get_bits_uint8 (&b_reader, &ext_code, 4)) { - ret = GST_FLOW_ERROR; - gst_buffer_unref (buf); - goto done; - } - - GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_EXTENSION: %d", ext_code); - - switch (ext_code) { - case MPEG_PACKET_EXT_SEQUENCE: - GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_EXT_SEQUENCE"); - - - mpeg_frame->seq_ext = buf; - - /* so that we don't finish the frame if we get a MPEG_PACKET_PICTURE - * or MPEG_PACKET_GOP after this */ - start_code = MPEG_PACKET_SEQUENCE; - break; - - case MPEG_PACKET_EXT_SEQUENCE_DISPLAY: - GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_EXT_SEQUENCE_DISPLAY"); - - /* so that we don't finish the frame if we get a MPEG_PACKET_PICTURE - * or MPEG_PACKET_GOP after this */ - start_code = MPEG_PACKET_SEQUENCE; - break; - - case MPEG_PACKET_EXT_PICTURE_CODING: - GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_EXT_PICTURE_CODING"); - - mpeg_frame->pic_ext = buf; - break; - - case MPEG_PACKET_EXT_QUANT_MATRIX: - GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_EXT_QUANT_MATRIX"); - - mpeg_frame->qm_ext = buf; - break; - - default: - gst_buffer_unref (buf); - } - break; - } +need_i_frame: + { + GST_DEBUG_OBJECT (mpeg_dec, + "Drop frame since we haven't got an I_FRAME yet"); - default: - gst_buffer_unref (buf); + gst_video_decoder_finish_frame (video_decoder, frame); + return GST_FLOW_OK; } - if (at_eos && mpeg_frame->slices) - ret = gst_base_video_decoder_have_frame (base_video_decoder, TRUE, NULL); - -done: - mpeg_dec->prev_packet = start_code; - - return ret; -} - -static gint -gst_vdp_mpeg_dec_scan_for_sync (GstBaseVideoDecoder * base_video_decoder, - GstAdapter * adapter) -{ - gint m; - - m = gst_adapter_masked_scan_uint32 (adapter, 0xffffff00, 0x00000100, 0, - gst_adapter_available (adapter)); - if (m == -1) - return gst_adapter_available (adapter) - SYNC_CODE_SIZE; +need_non_b_frame: + { + GST_DEBUG_OBJECT (mpeg_dec, + "Drop frame since we haven't got two non B_FRAME yet"); - return m; -} + gst_video_decoder_finish_frame (video_decoder, frame); + return GST_FLOW_OK; + } -static GstBaseVideoDecoderScanResult -gst_vdp_mpeg_dec_scan_for_packet_end (GstBaseVideoDecoder * base_video_decoder, - GstAdapter * adapter, guint * size, gboolean at_eos) -{ - guint8 *data; - guint32 sync_code; - data = g_slice_alloc (SYNC_CODE_SIZE); - gst_adapter_copy (adapter, data, 0, SYNC_CODE_SIZE); - sync_code = ((data[0] << 16) | (data[1] << 8) | data[2]); + /* ERRORS */ +no_meta: + { + GST_ERROR_OBJECT (video_decoder, + "Input buffer does not have MpegVideo GstMeta"); + gst_video_decoder_drop_frame (video_decoder, frame); + return GST_FLOW_ERROR; + } - if (sync_code != 0x000001) - return GST_BASE_VIDEO_DECODER_SCAN_RESULT_LOST_SYNC; +sequence_parse_fail: + { + GST_ERROR_OBJECT (video_decoder, "Failed to handle sequence header"); + gst_video_decoder_finish_frame (video_decoder, frame); + return ret; + } - *size = gst_adapter_masked_scan_uint32 (adapter, 0xffffff00, 0x00000100, - SYNC_CODE_SIZE, gst_adapter_available (adapter) - SYNC_CODE_SIZE); +exit_after_b_frame: + { + GST_WARNING_OBJECT (video_decoder, "Leaving after pushing B frame"); + gst_video_decoder_finish_frame (video_decoder, frame); + return ret; + } - if (*size == -1) - return GST_BASE_VIDEO_DECODER_SCAN_RESULT_NEED_DATA; +map_fail: + { + GST_ERROR_OBJECT (video_decoder, "Failed to map input buffer"); + gst_video_decoder_drop_frame (video_decoder, frame); + return GST_FLOW_ERROR; + } - return GST_BASE_VIDEO_DECODER_SCAN_RESULT_OK; +render_fail: + { + GST_ERROR_OBJECT (video_decoder, "Error when rendering the frame"); + gst_video_decoder_drop_frame (video_decoder, frame); + return ret; + } } static gboolean -gst_vdp_mpeg_dec_flush (GstBaseVideoDecoder * base_video_decoder) +gst_vdp_mpeg_dec_reset (GstVideoDecoder * video_decoder, gboolean hard) { - GstVdpMpegDec *mpeg_dec = GST_VDP_MPEG_DEC (base_video_decoder); + GstVdpMpegDec *mpeg_dec = GST_VDP_MPEG_DEC (video_decoder); if (mpeg_dec->vdp_info.forward_reference != VDP_INVALID_HANDLE) - gst_video_frame_unref (mpeg_dec->f_frame); + gst_video_codec_frame_unref (mpeg_dec->f_frame); if (mpeg_dec->vdp_info.backward_reference != VDP_INVALID_HANDLE) - gst_video_frame_unref (mpeg_dec->b_frame); + gst_video_codec_frame_unref (mpeg_dec->b_frame); gst_vdp_mpeg_dec_init_info (&mpeg_dec->vdp_info); @@ -585,9 +478,11 @@ gst_vdp_mpeg_dec_flush (GstBaseVideoDecoder * base_video_decoder) } static gboolean -gst_vdp_mpeg_dec_start (GstBaseVideoDecoder * base_video_decoder) +gst_vdp_mpeg_dec_start (GstVideoDecoder * video_decoder) { - GstVdpMpegDec *mpeg_dec = GST_VDP_MPEG_DEC (base_video_decoder); + GstVdpMpegDec *mpeg_dec = GST_VDP_MPEG_DEC (video_decoder); + + GST_DEBUG_OBJECT (video_decoder, "Starting"); gst_vdp_mpeg_dec_init_info (&mpeg_dec->vdp_info); @@ -596,14 +491,13 @@ gst_vdp_mpeg_dec_start (GstBaseVideoDecoder * base_video_decoder) memset (&mpeg_dec->stream_info, 0, sizeof (GstVdpMpegStreamInfo)); - return GST_BASE_VIDEO_DECODER_CLASS - (parent_class)->start (base_video_decoder); + return GST_VIDEO_DECODER_CLASS (parent_class)->start (video_decoder); } static gboolean -gst_vdp_mpeg_dec_stop (GstBaseVideoDecoder * base_video_decoder) +gst_vdp_mpeg_dec_stop (GstVideoDecoder * video_decoder) { - GstVdpMpegDec *mpeg_dec = GST_VDP_MPEG_DEC (base_video_decoder); + GstVdpMpegDec *mpeg_dec = GST_VDP_MPEG_DEC (video_decoder); if (mpeg_dec->vdp_info.forward_reference != VDP_INVALID_HANDLE) mpeg_dec->vdp_info.forward_reference = VDP_INVALID_HANDLE; @@ -612,13 +506,18 @@ gst_vdp_mpeg_dec_stop (GstBaseVideoDecoder * base_video_decoder) mpeg_dec->state = GST_VDP_MPEG_DEC_STATE_NEED_SEQUENCE; - return GST_BASE_VIDEO_DECODER_CLASS (parent_class)->stop (base_video_decoder); + return GST_VIDEO_DECODER_CLASS (parent_class)->stop (video_decoder); } +/* initialize the vdpaumpegdecoder's class */ static void -gst_vdp_mpeg_dec_base_init (gpointer gclass) +gst_vdp_mpeg_dec_class_init (GstVdpMpegDecClass * klass) { - GstElementClass *element_class = GST_ELEMENT_CLASS (gclass); + GstElementClass *element_class; + GstVideoDecoderClass *video_decoder_class; + + element_class = GST_ELEMENT_CLASS (klass); + video_decoder_class = GST_VIDEO_DECODER_CLASS (klass); gst_element_class_set_static_metadata (element_class, "VDPAU Mpeg Decoder", @@ -628,27 +527,13 @@ gst_vdp_mpeg_dec_base_init (gpointer gclass) gst_element_class_add_pad_template (element_class, gst_static_pad_template_get (&sink_template)); -} - -/* initialize the vdpaumpegdecoder's class */ -static void -gst_vdp_mpeg_dec_class_init (GstVdpMpegDecClass * klass) -{ - GstBaseVideoDecoderClass *base_video_decoder_class; - - base_video_decoder_class = GST_BASE_VIDEO_DECODER_CLASS (klass); - - base_video_decoder_class->start = gst_vdp_mpeg_dec_start; - base_video_decoder_class->stop = gst_vdp_mpeg_dec_stop; - base_video_decoder_class->flush = gst_vdp_mpeg_dec_flush; - base_video_decoder_class->scan_for_sync = gst_vdp_mpeg_dec_scan_for_sync; - base_video_decoder_class->scan_for_packet_end = - gst_vdp_mpeg_dec_scan_for_packet_end; - base_video_decoder_class->parse_data = gst_vdp_mpeg_dec_parse_data; + video_decoder_class->start = gst_vdp_mpeg_dec_start; + video_decoder_class->stop = gst_vdp_mpeg_dec_stop; + video_decoder_class->reset = gst_vdp_mpeg_dec_reset; - base_video_decoder_class->handle_frame = gst_vdp_mpeg_dec_handle_frame; - base_video_decoder_class->create_frame = gst_vdp_mpeg_dec_create_frame; + video_decoder_class->handle_frame = gst_vdp_mpeg_dec_handle_frame; + video_decoder_class->set_format = gst_vdp_mpeg_dec_set_format; } static void @@ -669,6 +554,6 @@ gst_vdp_mpeg_dec_init_info (VdpPictureInfoMPEG1Or2 * vdp_info) } static void -gst_vdp_mpeg_dec_init (GstVdpMpegDec * mpeg_dec, GstVdpMpegDecClass * gclass) +gst_vdp_mpeg_dec_init (GstVdpMpegDec * mpeg_dec) { } diff --git a/sys/vdpau/mpeg/gstvdpmpegdec.h b/sys/vdpau/mpeg/gstvdpmpegdec.h index 660e06996..96f085efb 100644 --- a/sys/vdpau/mpeg/gstvdpmpegdec.h +++ b/sys/vdpau/mpeg/gstvdpmpegdec.h @@ -24,10 +24,20 @@ #include <gst/gst.h> #include <gst/base/gstadapter.h> -#include "../gstvdp/gstvdpdecoder.h" -#include "gstvdpmpegframe.h" +#include "../gstvdpdecoder.h" G_BEGIN_DECLS +typedef struct _GstVdpMpegStreamInfo GstVdpMpegStreamInfo; + +struct _GstVdpMpegStreamInfo +{ + gint width, height; + gint fps_n, fps_d; + gint par_n, par_d; + gboolean interlaced; + gint version; + VdpDecoderProfile profile; +}; #define GST_TYPE_VDP_MPEG_DEC (gst_vdp_mpeg_dec_get_type()) #define GST_VDP_MPEG_DEC(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VDP_MPEG_DEC,GstVdpMpegDec)) @@ -50,11 +60,13 @@ struct _GstVdpMpegDec VdpDecoder decoder; - GstVdpMpegStreamInfo stream_info; + GstVdpMpegStreamInfo stream_info; /* decoder state */ + GstVideoCodecState *input_state; + GstVideoCodecState *output_state; GstVdpMpegDecState state; - gint prev_packet; + gint prev_packet; /* currently decoded frame info */ VdpPictureInfoMPEG1Or2 vdp_info; @@ -64,8 +76,7 @@ struct _GstVdpMpegDec guint64 gop_frame; /* forward and backward reference */ - GstVideoFrame *f_frame, *b_frame; - + GstVideoCodecFrame *f_frame, *b_frame; }; struct _GstVdpMpegDecClass diff --git a/sys/vdpau/mpeg/gstvdpmpegframe.c b/sys/vdpau/mpeg/gstvdpmpegframe.c deleted file mode 100644 index e6b09d6f9..000000000 --- a/sys/vdpau/mpeg/gstvdpmpegframe.c +++ /dev/null @@ -1,134 +0,0 @@ -/* -* GStreamer -* Copyright (C) 2009 Carl-Anton Ingmarsson <ca.ingmarsson@gmail.com> -* -* 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., 51 Franklin St, Fifth Floor, -* Boston, MA 02110-1301, USA. -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "gstvdpmpegframe.h" - -GST_DEBUG_CATEGORY_STATIC (gst_vdp_mpeg_frame_debug); -#define GST_CAT_DEFAULT gst_vdp_mpeg_frame_debug - -#define DEBUG_INIT(bla) \ -GST_DEBUG_CATEGORY_INIT (gst_vdp_mpeg_frame_debug, "gstvdpmpegframe", 0, "Video Frame"); - -void -gst_vdp_mpeg_frame_add_slice (GstVdpMpegFrame * mpeg_frame, GstBuffer * buf) -{ - if (!mpeg_frame->slices) - mpeg_frame->slices = buf; - else - mpeg_frame->slices = gst_buffer_append (mpeg_frame->slices, buf); - mpeg_frame->n_slices++; -} - -GstVdpMpegFrame * -gst_vdp_mpeg_frame_new (void) -{ - GstVdpMpegFrame *frame; - - frame = - GST_VDP_MPEG_FRAME_CAST (gst_mini_object_new (GST_TYPE_VDP_MPEG_FRAME)); - - return frame; -} - -static GObjectClass *gst_vdp_mpeg_frame_parent_class; - -static void -gst_vdp_mpeg_frame_finalize (GstVdpMpegFrame * mpeg_frame) -{ - if (mpeg_frame->seq) - gst_buffer_unref (mpeg_frame->seq); - if (mpeg_frame->seq_ext) - gst_buffer_unref (mpeg_frame->seq_ext); - - if (mpeg_frame->pic) - gst_buffer_unref (mpeg_frame->pic); - if (mpeg_frame->pic_ext) - gst_buffer_unref (mpeg_frame->pic_ext); - - if (mpeg_frame->gop) - gst_buffer_unref (mpeg_frame->gop); - if (mpeg_frame->qm_ext) - gst_buffer_unref (mpeg_frame->qm_ext); - - if (mpeg_frame->slices) - gst_buffer_unref (mpeg_frame->slices); - - - GST_MINI_OBJECT_CLASS (gst_vdp_mpeg_frame_parent_class)->finalize - (GST_MINI_OBJECT (mpeg_frame)); -} - -static void -gst_vdp_mpeg_frame_init (GstVdpMpegFrame * mpeg_frame, gpointer g_class) -{ - mpeg_frame->seq = NULL; - mpeg_frame->seq_ext = NULL; - - mpeg_frame->pic = NULL; - mpeg_frame->pic_ext = NULL; - - mpeg_frame->gop = NULL; - mpeg_frame->qm_ext = NULL; - - mpeg_frame->n_slices = 0; - mpeg_frame->slices = NULL; -} - -static void -gst_vdp_mpeg_frame_class_init (gpointer g_class, gpointer class_data) -{ - GstMiniObjectClass *mini_object_class = GST_MINI_OBJECT_CLASS (g_class); - - gst_vdp_mpeg_frame_parent_class = g_type_class_peek_parent (g_class); - - mini_object_class->finalize = (GstMiniObjectFinalizeFunction) - gst_vdp_mpeg_frame_finalize; -} - - -GType -gst_vdp_mpeg_frame_get_type (void) -{ - static GType _gst_vdp_mpeg_frame_type = 0; - - if (G_UNLIKELY (_gst_vdp_mpeg_frame_type == 0)) { - static const GTypeInfo info = { - sizeof (GstVdpMpegFrameClass), - NULL, - NULL, - gst_vdp_mpeg_frame_class_init, - NULL, - NULL, - sizeof (GstVdpMpegFrame), - 0, - (GInstanceInitFunc) gst_vdp_mpeg_frame_init, - NULL - }; - _gst_vdp_mpeg_frame_type = g_type_register_static (GST_TYPE_VIDEO_FRAME, - "GstVdpMpegFrame", &info, 0); - - DEBUG_INIT (); - } - return _gst_vdp_mpeg_frame_type; -} diff --git a/sys/vdpau/mpeg/gstvdpmpegframe.h b/sys/vdpau/mpeg/gstvdpmpegframe.h deleted file mode 100644 index 5dc96047c..000000000 --- a/sys/vdpau/mpeg/gstvdpmpegframe.h +++ /dev/null @@ -1,78 +0,0 @@ -/* -* GStreamer -* Copyright (C) 2009 Carl-Anton Ingmarsson <ca.ingmarsson@gmail.com> -* -* 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., 51 Franklin St, Fifth Floor, -* Boston, MA 02110-1301, USA. -*/ - -#ifndef _GST_VDP_MPEG_FRAME_H_ -#define _GST_VDP_MPEG_FRAME_H_ - -#include <gst/gst.h> - -#include <vdpau/vdpau.h> - -#include "../basevideodecoder/gstvideoframe.h" - -#define GST_TYPE_VDP_MPEG_FRAME (gst_vdp_mpeg_frame_get_type()) -#define GST_IS_VDP_MPEG_FRAME(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VDP_MPEG_FRAME)) -#define GST_VDP_MPEG_FRAME(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VDP_MPEG_FRAME, GstVdpMpegFrame)) -#define GST_VDP_MPEG_FRAME_CAST(obj) ((GstVdpMpegFrame *)obj) - -typedef struct _GstVdpMpegStreamInfo GstVdpMpegStreamInfo; - -struct _GstVdpMpegStreamInfo -{ - gint width, height; - gint fps_n, fps_d; - gint par_n, par_d; - gboolean interlaced; - gint version; - VdpDecoderProfile profile; -}; - -typedef struct _GstVdpMpegFrame GstVdpMpegFrame; -typedef struct _GstVdpMpegFrameClass GstVdpMpegFrameClass; - -struct _GstVdpMpegFrame -{ - GstVideoFrame video_frame; - - GstBuffer *seq; - GstBuffer *seq_ext; - - GstBuffer *pic; - GstBuffer *pic_ext; - - GstBuffer *gop; - GstBuffer *qm_ext; - - gint n_slices; - GstBuffer *slices; -}; - -struct _GstVdpMpegFrameClass -{ - GstVideoFrameClass video_frame_class; -}; - -void gst_vdp_mpeg_frame_add_slice (GstVdpMpegFrame *mpeg_frame, GstBuffer *buf); - -GstVdpMpegFrame *gst_vdp_mpeg_frame_new (void); - -GType gst_vdp_mpeg_frame_get_type (void); - -#endif
\ No newline at end of file diff --git a/sys/vdpau/mpeg/mpegutil.c b/sys/vdpau/mpeg/mpegutil.c deleted file mode 100644 index 6d30eead1..000000000 --- a/sys/vdpau/mpeg/mpegutil.c +++ /dev/null @@ -1,429 +0,0 @@ -/* GStreamer - * Copyright (C) 2007 Jan Schmidt <thaytan@mad.scientist.com> - * Copyright (C) 2009 Carl-Anton Ingmarsson <ca.ingmarsson@gmail.com> - * - * 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., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include <gst/base/gstbitreader.h> -#include <string.h> - -#include "mpegutil.h" - -/* default intra quant matrix, in zig-zag order */ -const guint8 default_intra_quantizer_matrix[64] = { - 8, - 16, 16, - 19, 16, 19, - 22, 22, 22, 22, - 22, 22, 26, 24, 26, - 27, 27, 27, 26, 26, 26, - 26, 27, 27, 27, 29, 29, 29, - 34, 34, 34, 29, 29, 29, 27, 27, - 29, 29, 32, 32, 34, 34, 37, - 38, 37, 35, 35, 34, 35, - 38, 38, 40, 40, 40, - 48, 48, 46, 46, - 56, 56, 58, - 69, 69, - 83 -}; - -const guint8 mpeg_zigzag_8x8[64] = { - 0, 1, 8, 16, 9, 2, 3, 10, - 17, 24, 32, 25, 18, 11, 4, 5, - 12, 19, 26, 33, 40, 48, 41, 34, - 27, 20, 13, 6, 7, 14, 21, 28, - 35, 42, 49, 56, 57, 50, 43, 36, - 29, 22, 15, 23, 30, 37, 44, 51, - 58, 59, 52, 45, 38, 31, 39, 46, - 53, 60, 61, 54, 47, 55, 62, 63 -}; - -#define READ_UINT8(reader, val, nbits) { \ - if (!gst_bit_reader_get_bits_uint8 (reader, &val, nbits)) { \ - GST_WARNING ("failed to read uint8, nbits: %d", nbits); \ - goto error; \ - } \ -} - -#define READ_UINT16(reader, val, nbits) { \ - if (!gst_bit_reader_get_bits_uint16 (reader, &val, nbits)) { \ - GST_WARNING ("failed to read uint16, nbits: %d", nbits); \ - goto error; \ - } \ -} - -#define READ_UINT32(reader, val, nbits) { \ - if (!gst_bit_reader_get_bits_uint32 (reader, &val, nbits)) { \ - GST_WARNING ("failed to read uint32, nbits: %d", nbits); \ - goto error; \ - } \ -} - -#define READ_UINT64(reader, val, nbits) { \ - if (!gst_bit_reader_get_bits_uint64 (reader, &val, nbits)) { \ - GST_WARNING ("failed to read uint32, nbits: %d", nbits); \ - goto error; \ - } \ -} - -static void -set_fps_from_code (MPEGSeqHdr * hdr, guint8 fps_code) -{ - const gint framerates[][2] = { - {30, 1}, {24000, 1001}, {24, 1}, {25, 1}, - {30000, 1001}, {30, 1}, {50, 1}, {60000, 1001}, - {60, 1}, {30, 1} - }; - - if (fps_code < 10) { - hdr->fps_n = framerates[fps_code][0]; - hdr->fps_d = framerates[fps_code][1]; - } else { - /* Force a valid framerate */ - hdr->fps_n = 30000; - hdr->fps_d = 1001; - } -} - -/* Set the Pixel Aspect Ratio in our hdr from a DAR code in the data */ -static void -set_par_from_dar (MPEGSeqHdr * hdr, guint8 asr_code) -{ - /* Pixel_width = DAR_width * display_vertical_size */ - /* Pixel_height = DAR_height * display_horizontal_size */ - switch (asr_code) { - case 0x02: /* 3:4 DAR = 4:3 pixels */ - hdr->par_w = 4 * hdr->height; - hdr->par_h = 3 * hdr->width; - break; - case 0x03: /* 9:16 DAR */ - hdr->par_w = 16 * hdr->height; - hdr->par_h = 9 * hdr->width; - break; - case 0x04: /* 1:2.21 DAR */ - hdr->par_w = 221 * hdr->height; - hdr->par_h = 100 * hdr->width; - break; - case 0x01: /* Square pixels */ - default: - hdr->par_w = hdr->par_h = 1; - break; - } -} - -gboolean -mpeg_util_parse_sequence_extension (MPEGSeqExtHdr * hdr, GstBuffer * buffer) -{ - GstBitReader reader = GST_BIT_READER_INIT_FROM_BUFFER (buffer);; - - /* skip sync word */ - if (!gst_bit_reader_skip (&reader, 8 * 4)) - return FALSE; - - /* skip extension code */ - if (!gst_bit_reader_skip (&reader, 4)) - return FALSE; - - /* skip profile and level escape bit */ - if (!gst_bit_reader_skip (&reader, 1)) - return FALSE; - - READ_UINT8 (&reader, hdr->profile, 3); - READ_UINT8 (&reader, hdr->level, 4); - - /* progressive */ - READ_UINT8 (&reader, hdr->progressive, 1); - - /* chroma format */ - READ_UINT8 (&reader, hdr->chroma_format, 2); - - /* resolution extension */ - READ_UINT8 (&reader, hdr->horiz_size_ext, 2); - READ_UINT8 (&reader, hdr->vert_size_ext, 2); - - READ_UINT16 (&reader, hdr->bitrate_ext, 12); - - /* skip to framerate extension */ - if (!gst_bit_reader_skip (&reader, 9)) - return FALSE; - - /* framerate extension */ - READ_UINT8 (&reader, hdr->fps_n_ext, 2); - READ_UINT8 (&reader, hdr->fps_d_ext, 2); - - return TRUE; - -error: - GST_WARNING ("error parsing \"Sequence Extension\""); - return FALSE; -} - -gboolean -mpeg_util_parse_sequence_hdr (MPEGSeqHdr * hdr, GstBuffer * buffer) -{ - GstBitReader reader = GST_BIT_READER_INIT_FROM_BUFFER (buffer); - guint8 dar_idx, par_idx; - guint8 load_intra_flag, load_non_intra_flag; - - /* skip sync word */ - if (!gst_bit_reader_skip (&reader, 8 * 4)) - return FALSE; - - /* resolution */ - READ_UINT16 (&reader, hdr->width, 12); - READ_UINT16 (&reader, hdr->height, 12); - - /* aspect ratio */ - READ_UINT8 (&reader, dar_idx, 4); - set_par_from_dar (hdr, dar_idx); - - /* framerate */ - READ_UINT8 (&reader, par_idx, 4); - set_fps_from_code (hdr, par_idx); - - /* bitrate */ - READ_UINT32 (&reader, hdr->bitrate, 18); - - if (!gst_bit_reader_skip (&reader, 1)) - return FALSE; - - /* VBV buffer size */ - READ_UINT16 (&reader, hdr->vbv_buffer, 10); - - /* constrained parameters flag */ - READ_UINT8 (&reader, hdr->constrained_parameters_flag, 1); - - /* intra quantizer matrix */ - READ_UINT8 (&reader, load_intra_flag, 1); - if (load_intra_flag) { - gint i; - for (i = 0; i < 64; i++) - READ_UINT8 (&reader, hdr->intra_quantizer_matrix[mpeg_zigzag_8x8[i]], 8); - } else - memcpy (hdr->intra_quantizer_matrix, default_intra_quantizer_matrix, 64); - - /* non intra quantizer matrix */ - READ_UINT8 (&reader, load_non_intra_flag, 1); - if (load_non_intra_flag) { - gint i; - for (i = 0; i < 64; i++) - READ_UINT8 (&reader, hdr->non_intra_quantizer_matrix[mpeg_zigzag_8x8[i]], - 8); - } else - memset (hdr->non_intra_quantizer_matrix, 16, 64); - - return TRUE; - -error: - GST_WARNING ("error parsing \"Sequence Header\""); - return FALSE; -} - -gboolean -mpeg_util_parse_picture_hdr (MPEGPictureHdr * hdr, GstBuffer * buffer) -{ - GstBitReader reader = GST_BIT_READER_INIT_FROM_BUFFER (buffer); - - /* skip sync word */ - if (!gst_bit_reader_skip (&reader, 8 * 4)) - return FALSE; - - /* temperal sequence number */ - if (!gst_bit_reader_get_bits_uint16 (&reader, &hdr->tsn, 10)) - return FALSE; - - /* frame type */ - if (!gst_bit_reader_get_bits_uint8 (&reader, &hdr->pic_type, 3)) - return FALSE; - - if (hdr->pic_type == 0 || hdr->pic_type > 4) - return FALSE; /* Corrupted picture packet */ - - /* VBV delay */ - if (!gst_bit_reader_get_bits_uint16 (&reader, &hdr->vbv_delay, 16)) - return FALSE; - - if (hdr->pic_type == P_FRAME || hdr->pic_type == B_FRAME) { - - READ_UINT8 (&reader, hdr->full_pel_forward_vector, 1); - - READ_UINT8 (&reader, hdr->f_code[0][0], 3); - hdr->f_code[0][1] = hdr->f_code[0][0]; - } else { - hdr->full_pel_forward_vector = 0; - hdr->f_code[0][0] = hdr->f_code[0][1] = 0; - } - - if (hdr->pic_type == B_FRAME) { - READ_UINT8 (&reader, hdr->full_pel_backward_vector, 1); - - READ_UINT8 (&reader, hdr->f_code[1][0], 3); - hdr->f_code[1][1] = hdr->f_code[1][0]; - } else { - hdr->full_pel_backward_vector = 0; - hdr->f_code[1][0] = hdr->f_code[1][1] = 0; - } - - return TRUE; - -error: - GST_WARNING ("error parsing \"Picture Header\""); - return FALSE; -} - -gboolean -mpeg_util_parse_picture_coding_extension (MPEGPictureExt * ext, - GstBuffer * buffer) -{ - GstBitReader reader = GST_BIT_READER_INIT_FROM_BUFFER (buffer); - - /* skip sync word */ - if (!gst_bit_reader_skip (&reader, 8 * 4)) - return FALSE; - - /* skip extension code */ - if (!gst_bit_reader_skip (&reader, 4)) - return FALSE; - - /* f_code */ - READ_UINT8 (&reader, ext->f_code[0][0], 4); - READ_UINT8 (&reader, ext->f_code[0][1], 4); - READ_UINT8 (&reader, ext->f_code[1][0], 4); - READ_UINT8 (&reader, ext->f_code[1][1], 4); - - /* intra DC precision */ - READ_UINT8 (&reader, ext->intra_dc_precision, 2); - - /* picture structure */ - READ_UINT8 (&reader, ext->picture_structure, 2); - - /* top field first */ - READ_UINT8 (&reader, ext->top_field_first, 1); - - /* frame pred frame dct */ - READ_UINT8 (&reader, ext->frame_pred_frame_dct, 1); - - /* concealment motion vectors */ - READ_UINT8 (&reader, ext->concealment_motion_vectors, 1); - - /* q scale type */ - READ_UINT8 (&reader, ext->q_scale_type, 1); - - /* intra vlc format */ - READ_UINT8 (&reader, ext->intra_vlc_format, 1); - - /* alternate scan */ - READ_UINT8 (&reader, ext->alternate_scan, 1); - - /* repeat first field */ - READ_UINT8 (&reader, ext->repeat_first_field, 1); - - /* chroma_420_type */ - READ_UINT8 (&reader, ext->chroma_420_type, 1); - - /* progressive_frame */ - READ_UINT8 (&reader, ext->progressive_frame, 1); - - return TRUE; - -error: - GST_WARNING ("error parsing \"Picture Coding Extension\""); - return FALSE; -} - -gboolean -mpeg_util_parse_gop (MPEGGop * gop, GstBuffer * buffer) -{ - GstBitReader reader = GST_BIT_READER_INIT_FROM_BUFFER (buffer); - - /* skip sync word */ - if (!gst_bit_reader_skip (&reader, 8 * 4)) - return FALSE; - - READ_UINT8 (&reader, gop->drop_frame_flag, 1); - - READ_UINT8 (&reader, gop->hour, 5); - - READ_UINT8 (&reader, gop->minute, 6); - - /* skip unused bit */ - if (!gst_bit_reader_skip (&reader, 1)) - return FALSE; - - READ_UINT8 (&reader, gop->second, 6); - - READ_UINT8 (&reader, gop->frame, 6); - - READ_UINT8 (&reader, gop->closed_gop, 1); - - READ_UINT8 (&reader, gop->broken_gop, 1); - - return TRUE; - -error: - GST_WARNING ("error parsing \"GOP\""); - return FALSE; -} - -gboolean -mpeg_util_parse_quant_matrix (MPEGQuantMatrix * qm, GstBuffer * buffer) -{ - GstBitReader reader = GST_BIT_READER_INIT_FROM_BUFFER (buffer); - guint8 load_intra_flag, load_non_intra_flag; - - /* skip sync word */ - if (!gst_bit_reader_skip (&reader, 8 * 4)) - return FALSE; - - /* skip extension code */ - if (!gst_bit_reader_skip (&reader, 4)) - return FALSE; - - /* intra quantizer matrix */ - READ_UINT8 (&reader, load_intra_flag, 1); - if (load_intra_flag) { - gint i; - for (i = 0; i < 64; i++) { - READ_UINT8 (&reader, qm->intra_quantizer_matrix[mpeg_zigzag_8x8[i]], 8); - } - } else - memcpy (qm->intra_quantizer_matrix, default_intra_quantizer_matrix, 64); - - /* non intra quantizer matrix */ - READ_UINT8 (&reader, load_non_intra_flag, 1); - if (load_non_intra_flag) { - gint i; - for (i = 0; i < 64; i++) { - READ_UINT8 (&reader, qm->non_intra_quantizer_matrix[mpeg_zigzag_8x8[i]], - 8); - } - } else - memset (qm->non_intra_quantizer_matrix, 16, 64); - - return TRUE; - -error: - GST_WARNING ("error parsing \"Quant Matrix Extension\""); - return FALSE; - -} - -#undef READ_UINT8 -#undef READ_UINT16 -#undef READ_UINT32 -#undef READ_UINT64 diff --git a/sys/vdpau/mpeg/mpegutil.h b/sys/vdpau/mpeg/mpegutil.h deleted file mode 100644 index 38f17d7e7..000000000 --- a/sys/vdpau/mpeg/mpegutil.h +++ /dev/null @@ -1,150 +0,0 @@ -/* GStreamer - * Copyright (C) 2007 Jan Schmidt <thaytan@mad.scientist.com> - * Copyright (C) 2009 Carl-Anton Ingmarsson <ca.ingmarsson@gmail.com> - * - * 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., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef __MPEGUTIL_H__ -#define __MPEGUTIL_H__ - -#include <gst/gst.h> - -typedef struct MPEGSeqHdr MPEGSeqHdr; -typedef struct MPEGSeqExtHdr MPEGSeqExtHdr; -typedef struct MPEGPictureHdr MPEGPictureHdr; -typedef struct MPEGPictureExt MPEGPictureExt; -typedef struct MPEGGop MPEGGop; -typedef struct MPEGQuantMatrix MPEGQuantMatrix; - -/* Packet ID codes for different packet types we - * care about */ -#define MPEG_PACKET_PICTURE 0x00 -#define MPEG_PACKET_SLICE_MIN 0x01 -#define MPEG_PACKET_SLICE_MAX 0xaf -#define MPEG_PACKET_SEQUENCE 0xb3 -#define MPEG_PACKET_EXTENSION 0xb5 -#define MPEG_PACKET_SEQUENCE_END 0xb7 -#define MPEG_PACKET_GOP 0xb8 -#define MPEG_PACKET_NONE 0xff - -/* Extension codes we care about */ -#define MPEG_PACKET_EXT_SEQUENCE 0x01 -#define MPEG_PACKET_EXT_SEQUENCE_DISPLAY 0x02 -#define MPEG_PACKET_EXT_QUANT_MATRIX 0x03 -#define MPEG_PACKET_EXT_PICTURE_CODING 0x08 - -/* frame types */ -#define I_FRAME 1 -#define P_FRAME 2 -#define B_FRAME 3 - -struct MPEGSeqHdr -{ - /* Pixel-Aspect Ratio from DAR code via set_par_from_dar */ - guint par_w, par_h; - /* Width and Height of the video */ - guint16 width, height; - /* Framerate */ - guint fps_n, fps_d; - - guint32 bitrate; - guint16 vbv_buffer; - - guint8 constrained_parameters_flag; - - guint8 intra_quantizer_matrix[64]; - guint8 non_intra_quantizer_matrix[64]; -}; - -struct MPEGSeqExtHdr -{ - - /* mpeg2 decoder profile */ - guint8 profile; - /* mpeg2 decoder level */ - guint8 level; - - guint8 progressive; - guint8 chroma_format; - - guint8 horiz_size_ext, vert_size_ext; - - guint16 bitrate_ext; - guint8 fps_n_ext, fps_d_ext; - -}; - -struct MPEGPictureHdr -{ - guint16 tsn; - guint8 pic_type; - guint16 vbv_delay; - - guint8 full_pel_forward_vector, full_pel_backward_vector; - - guint8 f_code[2][2]; -}; - -struct MPEGPictureExt -{ - guint8 f_code[2][2]; - - guint8 intra_dc_precision; - guint8 picture_structure; - guint8 top_field_first; - guint8 frame_pred_frame_dct; - guint8 concealment_motion_vectors; - guint8 q_scale_type; - guint8 intra_vlc_format; - guint8 alternate_scan; - guint8 repeat_first_field; - guint8 chroma_420_type; - guint8 progressive_frame; -}; - -struct MPEGGop -{ - guint8 drop_frame_flag; - - guint8 hour, minute, second, frame; - - guint8 closed_gop; - guint8 broken_gop; -}; - -struct MPEGQuantMatrix -{ - guint8 intra_quantizer_matrix[64]; - guint8 non_intra_quantizer_matrix[64]; -}; - -gboolean mpeg_util_parse_sequence_hdr (MPEGSeqHdr *hdr, GstBuffer *buffer); - -gboolean mpeg_util_parse_sequence_extension (MPEGSeqExtHdr *hdr, - GstBuffer *buffer); - -gboolean mpeg_util_parse_picture_hdr (MPEGPictureHdr * hdr, GstBuffer *buffer); - -gboolean mpeg_util_parse_picture_coding_extension (MPEGPictureExt *ext, - GstBuffer *buffer); - -gboolean mpeg_util_parse_gop (MPEGGop * gop, GstBuffer *buffer); - -gboolean mpeg_util_parse_quant_matrix (MPEGQuantMatrix * qm, GstBuffer *buffer); - -#endif - diff --git a/sys/vdpau/mpeg4/gstmpeg4frame.h b/sys/vdpau/mpeg4/gstmpeg4frame.h index f089dd555..bf7b5bdbd 100644 --- a/sys/vdpau/mpeg4/gstmpeg4frame.h +++ b/sys/vdpau/mpeg4/gstmpeg4frame.h @@ -23,24 +23,14 @@ #include <gst/gst.h> -#include "../basevideodecoder/gstvideoframe.h" - #include "mpeg4util.h" -#define GST_TYPE_MPEG4_FRAME (gst_mpeg4_frame_get_type()) -#define GST_IS_MPEG4_FRAME(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_MPEG4_FRAME)) -#define GST_MPEG4_FRAME(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_MPEG4_FRAME, GstMpeg4Frame)) -#define GST_MPEG4_FRAME_CAST(obj) ((GstMpeg4Frame *)obj) - #define GST_MPEG4_FRAME_GOT_PRIMARY GST_VIDEO_FRAME_FLAG_LAST typedef struct _GstMpeg4Frame GstMpeg4Frame; -typedef struct _GstMpeg4FrameClass GstMpeg4FrameClass; struct _GstMpeg4Frame { - GstVideoFrame video_frame; - GstBuffer *vos_buf; GstBuffer *vo_buf; GstBuffer *vol_buf; @@ -50,15 +40,6 @@ struct _GstMpeg4Frame guint32 vop_time; }; -struct _GstMpeg4FrameClass -{ - GstVideoFrameClass video_frame_class; -}; - - - GstMpeg4Frame *gst_mpeg4_frame_new (void); -GType gst_mpeg4_frame_get_type (void); - -#endif
\ No newline at end of file +#endif diff --git a/sys/vdpau/mpeg4/gstvdpmpeg4dec.c b/sys/vdpau/mpeg4/gstvdpmpeg4dec.c index 80ffa83db..a3be09f53 100644 --- a/sys/vdpau/mpeg4/gstvdpmpeg4dec.c +++ b/sys/vdpau/mpeg4/gstvdpmpeg4dec.c @@ -61,8 +61,8 @@ static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink", GST_DEBUG_CATEGORY_INIT (gst_vdp_mpeg4_dec_debug, "vdpaumpeg4dec", 0, \ "VDPAU mpeg4 decoder"); -GST_BOILERPLATE_FULL (GstVdpMpeg4Dec, gst_vdp_mpeg4_dec, - GstVdpDecoder, GST_TYPE_VDP_DECODER, DEBUG_INIT); +G_DEFINE_TYPE_FULL (GstVdpMpeg4Dec, gst_vdp_mpeg4_dec, GST_TYPE_VDP_DECODER, + DEBUG_INIT); #define SYNC_CODE_SIZE 3 @@ -81,8 +81,8 @@ gst_vdp_mpeg4_dec_fill_info (GstVdpMpeg4Dec * mpeg4_dec, /* forward reference */ if (vop->coding_type != I_VOP && mpeg4_dec->f_frame) { info.forward_reference = - GST_VDP_VIDEO_BUFFER (GST_VIDEO_FRAME (mpeg4_dec-> - f_frame)->src_buffer)->surface; + GST_VDP_VIDEO_BUFFER (GST_VIDEO_FRAME (mpeg4_dec->f_frame)-> + src_buffer)->surface; } if (vop->coding_type == B_VOP) { @@ -100,8 +100,8 @@ gst_vdp_mpeg4_dec_fill_info (GstVdpMpeg4Dec * mpeg4_dec, /* backward reference */ if (mpeg4_dec->b_frame) { info.backward_reference = - GST_VDP_VIDEO_BUFFER (GST_VIDEO_FRAME (mpeg4_dec-> - b_frame)->src_buffer)->surface; + GST_VDP_VIDEO_BUFFER (GST_VIDEO_FRAME (mpeg4_dec->b_frame)-> + src_buffer)->surface; } } diff --git a/sys/vdpau/mpeg4/gstvdpmpeg4dec.h b/sys/vdpau/mpeg4/gstvdpmpeg4dec.h index d4f92fade..788d832a7 100644 --- a/sys/vdpau/mpeg4/gstvdpmpeg4dec.h +++ b/sys/vdpau/mpeg4/gstvdpmpeg4dec.h @@ -23,7 +23,7 @@ #include <gst/gst.h> -#include "../gstvdp/gstvdpdecoder.h" +#include "../gstvdpdecoder.h" #include "mpeg4util.h" #include "gstmpeg4frame.h" |