From e0006ee0b9556be2f69e0ac6ac4ef102937f0966 Mon Sep 17 00:00:00 2001 From: Jan Schmidt Date: Thu, 1 Apr 2004 11:48:27 +0000 Subject: [PATCH] a52dec: Use a debug category, Output timestamps correctly Original commit message from CVS: a52dec: Use a debug category, Output timestamps correctly Emit tag info, Handle events, tell liba52dec about cpu capabilities so it can use MMX etc. dvdec: Fix a crasher accessing invalid memory dvdnavsrc:Some support for byte-format seeking. Small fixes for still frames and menu button overlays mpeg2dec: Use a debug category. Adjust the report level of several items to LOG. Call mpeg2_custom_fbuf to mark our buffers as 'custom buffers' so it doesn't lose the GstBuffer pointer navseek: Add the navseek debug element for seeking back and forth in a video stream using arrow keys. mpeg2subt:Pretty much a complete rewrite. Now a loopbased element. May still require work to properly synchronise subtitle buffers. mpegdemux: dvddemux: Don't attempt to create subbuffers of size 0 Reduce a couple of error outputs to warnings. y4mencode:Output the y4m frame header correctly --- ChangeLog | 57 +++++++++++ ext/dv/gstdvdec.c | 18 +++- gst/debug/Makefile.am | 5 +- gst/debug/gstdebug.c | 2 + gst/debug/gstnavseek.c | 270 +++++++++++++++++++++++++++++++++++++++++++++++++ gst/debug/gstnavseek.h | 58 +++++++++++ 6 files changed, 406 insertions(+), 4 deletions(-) create mode 100644 gst/debug/gstnavseek.c create mode 100644 gst/debug/gstnavseek.h diff --git a/ChangeLog b/ChangeLog index 53ff97d..7621d47 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,60 @@ +2004-04-01 Jan Schmidt + + * ext/a52dec/gsta52dec.c: (gst_a52dec_get_type), (gst_a52dec_init), + (gst_a52dec_push), (gst_a52dec_handle_event), + (gst_a52dec_update_streaminfo), (gst_a52dec_loop), + (gst_a52dec_change_state): + * ext/a52dec/gsta52dec.h: + Use a debug category, Output timestamps correctly + Emit tag info, Handle events, tell liba52dec about cpu + capabilities so it can use MMX etc. + * ext/dv/gstdvdec.c: (gst_dvdec_loop), (gst_dvdec_change_state): + Fix a crasher accessing invalid memory + * ext/dvdnav/dvdnavsrc.c: (dvdnavsrc_init), + (dvdnavsrc_update_highlight), (dvdnavsrc_loop), + (dvdnavsrc_get_event_mask), (dvdnav_handle_navigation_event), + (dvdnavsrc_event), (dvdnavsrc_get_formats), (dvdnavsrc_convert), + (dvdnavsrc_query): + Some support for byte-format seeking. + Small fixes for still frames and menu button overlays + * ext/mpeg2dec/gstmpeg2dec.c: (gst_mpeg2dec_get_type), + (gst_mpeg2dec_alloc_buffer): + Use a debug category. Adjust the report level of several items to + LOG. Call mpeg2_custom_fbuf to mark our buffers as 'custom buffers' + so it doesn't lose the GstBuffer pointer + * gst/debug/Makefile.am: + * gst/debug/gstdebug.c: (plugin_init): + * gst/debug/gstnavseek.c: (gst_navseek_get_type), + (gst_navseek_base_init), (gst_navseek_class_init), + (gst_navseek_init), (gst_navseek_seek), + (gst_navseek_handle_src_event), (gst_navseek_set_property), + (gst_navseek_get_property), (gst_navseek_chain), + (gst_navseek_plugin_init): + * gst/debug/gstnavseek.h: + Add the navseek debug element for seeking back and forth in a + video stream using arrow keys. + * gst/mpeg2sub/gstmpeg2subt.c: (gst_mpeg2subt_get_type), + (gst_mpeg2subt_base_init), (gst_mpeg2subt_class_init), + (gst_mpeg2subt_init), (gst_mpeg2subt_finalize), + (gst_mpeg2subt_getcaps_video), (gst_mpeg2subt_link_video), + (gst_mpeg2subt_handle_video), (gst_mpeg2subt_src_event), + (gst_mpeg2subt_parse_header), (gst_get_nibble), + (gst_setup_palette), (gst_get_rle_code), (gst_draw_rle_line), + (gst_merge_uv_data), (gst_mpeg2subt_merge_title), + (gst_update_still_frame), (gst_mpeg2subt_handle_subtitle), + (gst_mpeg2subt_handle_dvd_event), (gst_mpeg2subt_loop): + * gst/mpeg2sub/gstmpeg2subt.h: + Pretty much a complete rewrite. Now a loopbased element. May still + require work to properly synchronise subtitle buffers. + * gst/mpegstream/gstdvddemux.c: (gst_dvd_demux_process_private), + (gst_dvd_demux_send_subbuffer): + * gst/mpegstream/gstmpegdemux.c: (gst_mpeg_demux_send_subbuffer): + Don't attempt to create subbuffers of size 0 + Reduce a couple of error outputs to warnings. + * gst/y4m/gsty4mencode.c: (gst_y4mencode_sinkconnect), + (gst_y4mencode_chain): + Output the y4m frame header correctly. + 2004-04-01 Thomas Vander Stichele * gst/adder/gstadder.c: (gst_adder_get_type), (gst_adder_loop): diff --git a/ext/dv/gstdvdec.c b/ext/dv/gstdvdec.c index 5625237..fc5f162 100644 --- a/ext/dv/gstdvdec.c +++ b/ext/dv/gstdvdec.c @@ -777,9 +777,18 @@ gst_dvdec_loop (GstElement * element) dvdec = GST_DVDEC (element); + /* + * Apparently dv_parse_header can read from the body of the frame + * too, so it needs more than header_size bytes. Wacky! + */ + if (dvdec->found_header) + length = (dvdec->PAL ? PAL_BUFFER : NTSC_BUFFER); + else + length = NTSC_BUFFER; + /* first read enough bytes to parse the header */ - got_bytes = gst_bytestream_peek_bytes (dvdec->bs, &inframe, header_size); - if (got_bytes < header_size) { + got_bytes = gst_bytestream_peek_bytes (dvdec->bs, &inframe, length); + if (got_bytes < length) { gst_dvdec_handle_sink_event (dvdec); return; } @@ -918,6 +927,11 @@ gst_dvdec_change_state (GstElement * element) dvdec->decoder = dv_decoder_new (0, dvdec->clamp_luma, dvdec->clamp_chroma); dvdec->decoder->quality = dvdec->quality; + /* + * Enable this function call when libdv2 0.100 or higher is more + * common + */ + /* dv_set_quality (dvdec->decoder, dvdec->quality); */ break; case GST_STATE_PAUSED_TO_PLAYING: break; diff --git a/gst/debug/Makefile.am b/gst/debug/Makefile.am index 88eef63..f1ca6bb 100644 --- a/gst/debug/Makefile.am +++ b/gst/debug/Makefile.am @@ -1,7 +1,7 @@ plugin_LTLIBRARIES = libgstefence.la libgstnavigationtest.la libgstdebug.la -noinst_HEADERS = efence.h gstnavigationtest.h +noinst_HEADERS = efence.h gstnavigationtest.h gstnavseek.h libgstefence_la_SOURCES = efence.c libgstefence_la_CFLAGS = $(GST_CFLAGS) @@ -13,7 +13,8 @@ libgstnavigationtest_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) libgstdebug_la_SOURCES = gstdebug.c \ breakmydata.c \ - negotiation.c + negotiation.c \ + gstnavseek.c libgstdebug_la_CFLAGS = $(GST_CFLAGS) libgstdebug_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) diff --git a/gst/debug/gstdebug.c b/gst/debug/gstdebug.c index 32db4c5..9ec4aff 100644 --- a/gst/debug/gstdebug.c +++ b/gst/debug/gstdebug.c @@ -26,12 +26,14 @@ gboolean gst_break_my_data_plugin_init (GstPlugin * plugin); gboolean gst_negotiation_plugin_init (GstPlugin * plugin); +gboolean gst_navseek_plugin_init (GstPlugin * plugin); static gboolean plugin_init (GstPlugin * plugin) { gst_break_my_data_plugin_init (plugin); gst_negotiation_plugin_init (plugin); + gst_navseek_plugin_init (plugin); return TRUE; } diff --git a/gst/debug/gstnavseek.c b/gst/debug/gstnavseek.c new file mode 100644 index 0000000..476fa83 --- /dev/null +++ b/gst/debug/gstnavseek.c @@ -0,0 +1,270 @@ +/* GStreamer + * Copyright (C) <1999> Erik Walthinsen + * Copyright (C) <2003> David Schleef + * + * 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. + */ + +/* + * This file was (probably) generated from gstnavseek.c, + * gstnavseek.c,v 1.7 2003/11/08 02:48:59 dschleef Exp + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +/* GstNavSeek signals and args */ +enum +{ + /* FILL ME */ + LAST_SIGNAL +}; + +enum +{ + ARG_0, + ARG_SEEKOFFSET + /* FILL ME */ +}; + +GstStaticPadTemplate navseek_src_template = GST_STATIC_PAD_TEMPLATE ("src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS_ANY); + +GstStaticPadTemplate navseek_sink_template = GST_STATIC_PAD_TEMPLATE ("sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS_ANY); + +static void gst_navseek_base_init (gpointer g_class); +static void gst_navseek_class_init (gpointer g_class, gpointer class_data); +static void gst_navseek_init (GTypeInstance * instance, gpointer g_class); + +static gboolean gst_navseek_handle_src_event (GstPad * pad, GstEvent * event); +static void gst_navseek_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec); +static void gst_navseek_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec); +static void gst_navseek_chain (GstPad * pad, GstData * _data); + +static GType +gst_navseek_get_type (void) +{ + static GType navseek_type = 0; + + if (!navseek_type) { + static const GTypeInfo navseek_info = { + sizeof (GstNavSeekClass), + gst_navseek_base_init, + NULL, + gst_navseek_class_init, + NULL, + NULL, + sizeof (GstNavSeek), + 0, + gst_navseek_init, + }; + + navseek_type = g_type_register_static (GST_TYPE_ELEMENT, + "GstNavSeek", &navseek_info, 0); + } + return navseek_type; +} + +static void +gst_navseek_base_init (gpointer g_class) +{ + static GstElementDetails navseek_details = + GST_ELEMENT_DETAILS ("Seek based on left-right arrows", + "Filter/Video", + "Seek based on navigation keys left-right", + "Jan Schmidt "); + GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); + + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&navseek_sink_template)); + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&navseek_src_template)); + + gst_element_class_set_details (element_class, &navseek_details); +} + +static void +gst_navseek_class_init (gpointer g_class, gpointer class_data) +{ + GObjectClass *gobject_class; + + gobject_class = G_OBJECT_CLASS (g_class); + + g_object_class_install_property (G_OBJECT_CLASS (g_class), + ARG_SEEKOFFSET, g_param_spec_double ("seek-offset", "Seek Offset", + "Time in seconds to seek by", 0.0, G_MAXDOUBLE, 5.0, + G_PARAM_READWRITE)); + + gobject_class->set_property = gst_navseek_set_property; + gobject_class->get_property = gst_navseek_get_property; +} + +static void +gst_navseek_init (GTypeInstance * instance, gpointer g_class) +{ + GstNavSeek *navseek = GST_NAVSEEK (instance); + + navseek->sinkpad = + gst_pad_new_from_template (gst_static_pad_template_get + (&navseek_sink_template), "sink"); + gst_element_add_pad (GST_ELEMENT (navseek), navseek->sinkpad); + gst_pad_set_chain_function (navseek->sinkpad, gst_navseek_chain); + gst_pad_set_link_function (navseek->sinkpad, gst_pad_proxy_pad_link); + gst_pad_set_getcaps_function (navseek->sinkpad, gst_pad_proxy_getcaps); + + navseek->srcpad = + gst_pad_new_from_template (gst_static_pad_template_get + (&navseek_src_template), "src"); + gst_element_add_pad (GST_ELEMENT (navseek), navseek->srcpad); + gst_pad_set_link_function (navseek->srcpad, gst_pad_proxy_pad_link); + gst_pad_set_getcaps_function (navseek->srcpad, gst_pad_proxy_getcaps); + gst_pad_set_event_function (navseek->srcpad, gst_navseek_handle_src_event); + + navseek->seek_offset = 5.0; +} + +static void +gst_navseek_seek (GstNavSeek * navseek, gint64 offset) +{ + /* Query for the current time then attempt to set to time + offset */ + gint64 peer_value; + GstFormat peer_format = GST_FORMAT_TIME; + + if (gst_pad_query (gst_pad_get_peer (navseek->sinkpad), + GST_QUERY_POSITION, &peer_format, &peer_value)) { + if (peer_format != GST_FORMAT_TIME) + return; + + peer_value += offset; + if (peer_value < 0) + peer_value = 0; + + gst_element_seek (GST_ELEMENT (navseek), + GST_SEEK_METHOD_SET | GST_FORMAT_TIME | GST_SEEK_FLAG_ACCURATE | + GST_SEEK_FLAG_FLUSH, peer_value); + } +} + +static gboolean +gst_navseek_handle_src_event (GstPad * pad, GstEvent * event) +{ + GstNavSeek *navseek; + + navseek = GST_NAVSEEK (gst_pad_get_parent (pad)); + + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_NAVIGATION: + /* Check for a keyup and convert left/right to a seek event */ + { + GstStructure *structure; + const gchar *event_type; + + structure = event->event_data.structure.structure; + event_type = gst_structure_get_string (structure, "event"); + + g_return_val_if_fail (event != NULL, FALSE); + + if (strcmp (event_type, "key-press") == 0) { + const char *key = gst_structure_get_string (structure, "key"); + + g_assert (key != NULL); + if (strcmp (key, "Left") == 0) { + /* Seek backward by 5 secs */ + gst_navseek_seek (navseek, -1.0 * navseek->seek_offset * GST_SECOND); + } else if (strcmp (key, "Right") == 0) { + /* Seek forward */ + gst_navseek_seek (navseek, navseek->seek_offset * GST_SECOND); + } + } else { + break; + } + gst_event_unref (event); + event = NULL; + } + break; + default: + break; + } + if (event) { + return gst_pad_send_event (gst_pad_get_peer (navseek->sinkpad), event); + } + return TRUE; +} + +static void +gst_navseek_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GstNavSeek *src; + + g_return_if_fail (GST_IS_NAVSEEK (object)); + src = GST_NAVSEEK (object); + + switch (prop_id) { + case ARG_SEEKOFFSET: + src->seek_offset = g_value_get_double (value); + break; + default: + break; + } +} + +static void +gst_navseek_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) +{ + GstNavSeek *src; + + g_return_if_fail (GST_IS_NAVSEEK (object)); + src = GST_NAVSEEK (object); + + switch (prop_id) { + case ARG_SEEKOFFSET: + g_value_set_double (value, src->seek_offset); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_navseek_chain (GstPad * pad, GstData * _data) +{ + GstNavSeek *navseek; + + navseek = GST_NAVSEEK (gst_pad_get_parent (pad)); + gst_pad_push (navseek->srcpad, _data); +} + +gboolean +gst_navseek_plugin_init (GstPlugin * plugin) +{ + return gst_element_register (plugin, "navseek", GST_RANK_NONE, + GST_TYPE_NAVSEEK); +} diff --git a/gst/debug/gstnavseek.h b/gst/debug/gstnavseek.h new file mode 100644 index 0000000..27a2723 --- /dev/null +++ b/gst/debug/gstnavseek.h @@ -0,0 +1,58 @@ +/* GStreamer + * Copyright (C) <1999> Erik Walthinsen + * + * 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_NAVSEEK_H__ +#define __GST_NAVSEEK_H__ + + +#include + +G_BEGIN_DECLS + +#define GST_TYPE_NAVSEEK \ + (gst_navseek_get_type()) +#define GST_NAVSEEK(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_NAVSEEK,GstNavSeek)) +#define GST_NAVSEEK_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_NAVSEEK,GstNavSeekClass)) +#define GST_IS_NAVSEEK(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_NAVSEEK)) +#define GST_IS_NAVSEEK_CLASS(obj) \ + (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_NAVSEEK)) + +typedef struct _GstNavSeek GstNavSeek; +typedef struct _GstNavSeekClass GstNavSeekClass; + +struct _GstNavSeek { + GstElement element; + GstPad *sinkpad; + GstPad *srcpad; + + gdouble seek_offset; +}; + +struct _GstNavSeekClass { + GstElementClass parent_class; +}; + +G_END_DECLS + +#endif /* __GST_NAVSEEK_H__ */ + -- 2.7.4