...
 
Commits (21)
  • Wim Taymans's avatar
    Various plugin updates to have something to play with. · 1a293825
    Wim Taymans authored
    Original commit message from CVS:
    Various plugin updates to have something to play with.
    1a293825
  • Wim Taymans's avatar
    Added new dir · c092010f
    Wim Taymans authored
    Original commit message from CVS:
    Added new dir
    c092010f
  • Wim Taymans's avatar
    Various plugin updates. · c6449163
    Wim Taymans authored
    Original commit message from CVS:
    Various plugin updates.
    c6449163
  • Wim Taymans's avatar
    Ogg demuxer updates, uses decoder plugin internally to convert granulepos to timestamps. · 56e76376
    Wim Taymans authored
    Original commit message from CVS:
    Ogg demuxer updates, uses decoder plugin internally to convert
    granulepos to timestamps.
    Various other plugin updates.
    56e76376
  • Wim Taymans's avatar
    First attempt at seeking in ogg vorbis. · 2e80494f
    Wim Taymans authored
    Original commit message from CVS:
    First attempt at seeking in ogg vorbis.
    Fix some plugins with new DISCONT values.
    2e80494f
  • Wim Taymans's avatar
    Implement flushing. · 0630e84e
    Wim Taymans authored
    Original commit message from CVS:
    * examples/seeking/seek.c: (dynamic_link), (make_vorbis_pipeline),
    (make_theora_pipeline), (do_seek), (start_seek), (stop_seek):
    * ext/ogg/gstoggdemux.c: (gst_ogg_pad_get_type),
    (gst_ogg_pad_init), (gst_ogg_pad_src_query), (gst_ogg_pad_event),
    (gst_ogg_demux_factory_filter), (compare_ranks),
    (gst_ogg_pad_internal_chain), (gst_ogg_pad_typefind),
    (gst_ogg_pad_submit_packet), (gst_ogg_pad_submit_page),
    (gst_ogg_chain_new), (gst_ogg_chain_free),
    (gst_ogg_chain_new_stream), (gst_ogg_chain_get_stream),
    (gst_ogg_chain_has_stream), (gst_ogg_demux_base_init),
    (gst_ogg_demux_init), (gst_ogg_demux_submit_buffer),
    (gst_ogg_demux_seek), (gst_ogg_demux_get_data),
    (gst_ogg_demux_get_next_page), (gst_ogg_demux_get_prev_page),
    (gst_ogg_demux_perform_seek),
    (gst_ogg_demux_bisect_forward_serialno),
    (gst_ogg_demux_read_chain), (gst_ogg_demux_read_end_chain),
    (gst_ogg_demux_find_pad), (gst_ogg_demux_find_chains),
    (gst_ogg_demux_chain_unlocked), (gst_ogg_demux_chain),
    (gst_ogg_demux_loop), (gst_ogg_demux_sink_activate),
    (gst_ogg_print):
    * sys/xvimage/xvimagesink.c: (gst_xvimagesink_sink_link),
    (gst_xvimagesink_event), (gst_xvimagesink_show_frame),
    (gst_xvimagesink_finish_preroll), (gst_xvimagesink_chain),
    (gst_xvimagesink_buffer_alloc):
    * sys/xvimage/xvimagesink.h:
    Implement flushing.
    Improved seeking in ogg.
    0630e84e
  • Wim Taymans's avatar
    Ogg fixes. xvimagesink clock unscheduling for faster state changes. · bb2efcfa
    Wim Taymans authored
    Original commit message from CVS:
    Ogg fixes.
    xvimagesink clock unscheduling for faster state changes.
    Small updates for plugins that use GstTask.
    bb2efcfa
  • Wim Taymans's avatar
    Handle EOS in oggdemux. Activate chains on BOS pages. · d669afe8
    Wim Taymans authored
    Original commit message from CVS:
    * examples/seeking/seek.c: (dynamic_link), (make_vorbis_pipeline),
    (make_theora_pipeline), (do_seek), (start_seek), (stop_seek):
    * ext/ogg/gstoggdemux.c: (gst_ogg_pad_get_type),
    (gst_ogg_pad_class_init), (gst_ogg_pad_init),
    (gst_ogg_pad_dispose), (gst_ogg_pad_finalize),
    (gst_ogg_pad_getcaps), (gst_ogg_pad_src_query),
    (gst_ogg_pad_event), (gst_ogg_demux_factory_filter),
    (compare_ranks), (gst_ogg_pad_internal_chain),
    (gst_ogg_pad_typefind), (gst_ogg_pad_submit_packet),
    (gst_ogg_pad_submit_page), (gst_ogg_chain_new),
    (gst_ogg_chain_free), (gst_ogg_chain_new_stream),
    (gst_ogg_chain_get_stream), (gst_ogg_chain_has_stream),
    (gst_ogg_demux_base_init), (gst_ogg_demux_init),
    (gst_ogg_demux_finalize), (gst_ogg_demux_submit_buffer),
    (gst_ogg_demux_seek), (gst_ogg_demux_get_data),
    (gst_ogg_demux_get_next_page), (gst_ogg_demux_get_prev_page),
    (gst_ogg_demux_deactivate_current_chain),
    (gst_ogg_demux_activate_chain), (gst_ogg_demux_perform_seek),
    (gst_ogg_demux_bisect_forward_serialno),
    (gst_ogg_demux_read_chain), (gst_ogg_demux_read_end_chain),
    (gst_ogg_demux_find_pad), (gst_ogg_demux_find_chain),
    (gst_ogg_demux_find_chains), (gst_ogg_demux_chain_unlocked),
    (gst_ogg_demux_chain), (gst_ogg_demux_send_eos),
    (gst_ogg_demux_loop), (gst_ogg_demux_sink_activate),
    (gst_ogg_print):
    * sys/xvimage/xvimagesink.c: (gst_xvimagesink_sink_link),
    (gst_xvimagesink_change_state), (gst_xvimagesink_event),
    (gst_xvimagesink_show_frame), (gst_xvimagesink_finish_preroll),
    (gst_xvimagesink_chain), (gst_xvimagesink_buffer_alloc),
    (gst_xvimagesink_init):
    * sys/xvimage/xvimagesink.h:
    Handle EOS in oggdemux. Activate chains on BOS pages.
    Do not wait for preroll when xvimagesink is in EOS.
    d669afe8
  • Wim Taymans's avatar
    Fix osssink state changes. · a6b6f8a5
    Wim Taymans authored
    Original commit message from CVS:
    Fix osssink state changes.
    Reset the ogg stream when seeking.
    a6b6f8a5
  • Wim Taymans's avatar
    Clock fixes. · f3fd919f
    Wim Taymans authored
    Original commit message from CVS:
    Clock fixes.
    Added seeking in theora/vorbis ogg files.
    Make playbin compile.
    f3fd919f
  • Wim Taymans's avatar
    No more bytestream. · f7c6d3e4
    Wim Taymans authored
    Original commit message from CVS:
    No more bytestream.
    f7c6d3e4
  • Wim Taymans's avatar
    Some small fixes. · 9eea8dce
    Wim Taymans authored
    Original commit message from CVS:
    Some small fixes.
    9eea8dce
  • Wim Taymans's avatar
    Fix the demuxer again. · 8d5ea80c
    Wim Taymans authored
    Original commit message from CVS:
    Fix the demuxer again.
    8d5ea80c
  • Ronald S. Bultje's avatar
    gst/playback/NOTE: Add note on autoplugging in 0.9 (basically duplicate of... · 77f9d457
    Ronald S. Bultje authored
    gst/playback/NOTE: Add note on autoplugging in 0.9 (basically duplicate of Dave´s 0.9-suggested-changes, but in a se...
    
    Original commit message from CVS:
    * gst/playback/NOTE:
    Add note on autoplugging in 0.9 (basically duplicate of Dave´s
    0.9-suggested-changes, but in a separate document so people
    specifically looking at porting decodebin don´t miss it).
    77f9d457
  • Ronald S. Bultje's avatar
    ext/gnomevfs/: Disable gnomevfssink for now, make gnomevfssrc work. · 204e36d8
    Ronald S. Bultje authored
    Original commit message from CVS:
    * ext/gnomevfs/Makefile.am:
    * ext/gnomevfs/gstgnomevfs.c: (plugin_init):
    * ext/gnomevfs/gstgnomevfssrc.c: (gst_gnomevfssrc_base_init),
    (gst_gnomevfssrc_class_init), (gst_gnomevfssrc_init),
    (gst_gnomevfssrc_get_property), (gst_gnomevfssrc_get),
    (gst_gnomevfssrc_open_file), (gst_gnomevfssrc_close_file),
    (gst_gnomevfssrc_getrange), (gst_gnomevfssrc_loop),
    (gst_gnomevfssrc_activate), (gst_gnomevfssrc_change_state),
    (gst_gnomevfssrc_srcpad_query), (gst_gnomevfssrc_srcpad_event):
    Disable gnomevfssink for now, make gnomevfssrc work.
    204e36d8
  • Ronald S. Bultje's avatar
    examples/seeking/seek.c: Add AVI pipeline. · 4a1a8872
    Ronald S. Bultje authored
    Original commit message from CVS:
    * examples/seeking/seek.c: (make_avi_msmpeg4v3_mp3_pipeline):
    Add AVI pipeline.
    * gst-libs/gst/riff/riff-media.c: (gst_riff_create_video_caps),
    (gst_riff_create_audio_caps), (gst_riff_create_iavs_caps),
    (gst_riff_create_video_template_caps),
    (gst_riff_create_audio_template_caps),
    (gst_riff_create_iavs_template_caps):
    * gst-libs/gst/riff/riff-media.h:
    Remove obsolete non-data functions, make data functions the
    default.
    * gst-libs/gst/riff/riff-read.c: (gst_riff_read_chunk),
    (gst_riff_parse_chunk), (gst_riff_parse_file_header),
    (gst_riff_parse_strh), (gst_riff_parse_strf_vids),
    (gst_riff_parse_strf_auds), (gst_riff_parse_strf_iavs),
    (gst_riff_parse_info):
    * gst-libs/gst/riff/riff-read.h:
    * gst-libs/gst/riff/riff.c: (plugin_init):
    Change from bytestream-wrapping to pure RIFF parsing (can be used
    chain-based if someone would want that). Add gtk-doc comments.
    * gst/avi/Makefile.am:
    * gst/avi/gstavi.c: (plugin_init):
    Disable mux for now.
    * gst/avi/gstavidemux.c: (gst_avi_demux_get_type),
    (gst_avi_demux_class_init), (gst_avi_demux_init),
    (gst_avi_demux_reset), (gst_avi_demux_src_convert),
    (gst_avi_demux_handle_src_query), (gst_avi_demux_handle_src_event),
    (gst_avi_demux_parse_file_header), (gst_avi_demux_stream_init),
    (gst_avi_demux_parse_avih), (gst_avi_demux_parse_superindex),
    (gst_avi_demux_parse_subindex), (gst_avi_demux_read_subindexes),
    (gst_avi_demux_parse_stream), (gst_avi_demux_parse_odml),
    (gst_avi_demux_parse_index), (gst_avi_demux_stream_index),
    (gst_avi_demux_stream_scan), (gst_avi_demux_massage_index),
    (gst_avi_demux_stream_header), (gst_avi_demux_handle_seek),
    (gst_avi_demux_process_next_entry), (gst_avi_demux_stream_data),
    (gst_avi_demux_loop), (gst_avi_demux_sink_activate):
    * gst/avi/gstavidemux.h:
    Port to changed RIFF API, port to 0.9, add locking. Add gtk-doc
    comments to some relevant functions. Seeking is weird, works
    otherwise. Some parts are still disabled.
    4a1a8872
  • Thomas Vander Stichele's avatar
    remove buffer_join · 7565ce2d
    Thomas Vander Stichele authored
    Original commit message from CVS:
    remove buffer_join
    7565ce2d
  • Wim Taymans's avatar
    Fix compilation again. · 9a9ee1ab
    Wim Taymans authored
    Original commit message from CVS:
    Fix compilation again.
    9a9ee1ab
  • Jan Schmidt's avatar
    examples/seeking/seek.c: Add realtime scrubbing to the seek example. · 6f2922af
    Jan Schmidt authored
    Original commit message from CVS:
    * examples/seeking/seek.c: (end_scrub), (do_seek), (seek_cb),
    (start_seek), (stop_seek):
    Add realtime scrubbing to the seek example.
    * ext/ogg/gstoggdemux.c: (gst_ogg_demux_perform_seek):
    Avoid overflowing 64-bits on large files when estimating
    the new position during a seek.
    6f2922af
  • Ronald S. Bultje's avatar
    gst/avi/gstavidemux.c: Implement accurate seeking, fix keyframe seeking. · e1975c59
    Ronald S. Bultje authored
    Original commit message from CVS:
    * gst/avi/gstavidemux.c: (gst_avi_demux_index_next),
    (gst_avi_demux_index_entry_for_time),
    (gst_avi_demux_index_entry_for_byte),
    (gst_avi_demux_index_entry_for_frame),
    (gst_avi_demux_handle_src_event),
    (gst_avi_demux_process_next_entry):
    Implement accurate seeking, fix keyframe seeking.
    e1975c59
  • Wim Taymans's avatar
    More work on subclassing the sinks from the basesink. · 3a4d09d9
    Wim Taymans authored
    Original commit message from CVS:
    More work on subclassing the sinks from the basesink.
    First attempt at generic audiosink base objects.
    Make oss DMA audiosink.
    3a4d09d9
This diff is collapsed.
common @ b2638c10
Subproject commit ded6dc5186cb7f8c64cb06a8591b9f787122c6f1
Subproject commit b2638c100721f67b280c3b43b21f1ce1c9b5e316
......@@ -12,7 +12,7 @@ AM_MAINTAINER_MODE
dnl when going to/from release please set the nano (fourth number) right !
dnl releases only do Wall, cvs and prerelease does Werror too
AS_VERSION(gst-plugins, GST_PLUGINS_VERSION, 0, 8, 6, 1, GST_CVS="no", GST_CVS="yes")
AS_VERSION(gst-plugins-threaded, GST_PLUGINS_VERSION, 0, 9, 0, 0, GST_CVS="no", GST_CVS="yes")
AM_INIT_AUTOMAKE($PACKAGE,$VERSION)
......@@ -2032,6 +2032,7 @@ gst-libs/gst/xwindowlistener/Makefile
gst-libs/ext/Makefile
examples/dynparams/Makefile
examples/capsfilter/Makefile
examples/negotiation/Makefile
examples/seeking/Makefile
examples/indexing/Makefile
examples/gstplay/Makefile
......
examples = queue colorspace
noinst_PROGRAMS = $(examples)
# we have nothing but apps here, we can do this safely
LIBS = $(GST_LIBS) $(GTK_LIBS) $(GST_CONTROL_LIBS)
AM_CFLAGS = $(GST_CFLAGS) $(GTK_CFLAGS)
/*
* colorspace.c
*
* demo application for negotiation of a simple plugin.
*/
#include <string.h>
#include <gst/gst.h>
static GstElement *pipeline;
static GstElement *space;
static GstPad *src;
static GstPad *sink;
static GstPad *test;
static gboolean caught_error = FALSE;
static GMainLoop *loop;
static gboolean
message_received (GstBus * bus, GstMessage * message, gpointer data)
{
switch (GST_MESSAGE_TYPE (message)) {
case GST_MESSAGE_EOS:
if (g_main_loop_is_running (loop))
g_main_loop_quit (loop);
break;
case GST_MESSAGE_ERROR:
gst_object_default_error (GST_MESSAGE_SRC (message),
GST_MESSAGE_ERROR_GERROR (message),
GST_MESSAGE_ERROR_DEBUG (message));
caught_error = TRUE;
if (g_main_loop_is_running (loop))
g_main_loop_quit (loop);
break;
default:
break;
}
gst_message_unref (message);
return TRUE;
}
static GstFlowReturn
my_chain (GstPad * pad, GstBuffer * buffer)
{
g_print ("got buffer\n");
return GST_FLOW_OK;
}
int
main (int argc, char *argv[])
{
GstBus *bus;
GstBuffer *buffer;
gst_init (&argc, &argv);
pipeline = gst_pipeline_new ("pipeline");
bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
loop = g_main_loop_new (NULL, FALSE);
gst_bus_add_watch (bus, message_received, pipeline);
space = gst_element_factory_make ("ffmpegcolorspace", "space");
gst_bin_add (GST_BIN (pipeline), space);
sink = gst_element_get_pad (space, "sink");
src = gst_element_get_pad (space, "src");
gst_element_set_state (pipeline, GST_STATE_PLAYING);
test = gst_pad_new ("test", GST_PAD_SINK);
gst_pad_set_chain_function (test, my_chain);
gst_pad_link (src, test);
gst_pad_set_active (test, TRUE);
gst_pad_set_caps (sink,
gst_caps_new_simple ("video/x-raw-yuv",
"format", GST_TYPE_FOURCC, GST_STR_FOURCC ("YUY2"),
"width", G_TYPE_INT, 240,
"height", G_TYPE_INT, 120, "framerate", G_TYPE_DOUBLE, 30.0, NULL));
while (g_main_context_iteration (NULL, FALSE));
buffer = gst_buffer_new ();
GST_REAL_PAD (sink)->chainfunc (sink, buffer);
while (g_main_context_iteration (NULL, FALSE));
gst_element_set_state (pipeline, GST_STATE_NULL);
gst_object_unref (GST_OBJECT (pipeline));
return 0;
}
/*
* queue.c
*
* demo application for negotiation over queues.
*/
#include <string.h>
#include <gtk/gtk.h>
#include <gst/gst.h>
static GstElement *pipeline;
static GstElement *src;
static GstElement *queue;
static GstElement *sink;
static GstPad *pad1, *peer1;
static GstPad *pad2, *peer2;
static gboolean caught_error = FALSE;
static GMainLoop *loop;
static gboolean
message_received (GstBus * bus, GstMessage * message, gpointer data)
{
switch (GST_MESSAGE_TYPE (message)) {
case GST_MESSAGE_EOS:
if (g_main_loop_is_running (loop))
g_main_loop_quit (loop);
break;
case GST_MESSAGE_ERROR:
gst_object_default_error (GST_MESSAGE_SRC (message),
GST_MESSAGE_ERROR_GERROR (message),
GST_MESSAGE_ERROR_DEBUG (message));
caught_error = TRUE;
if (g_main_loop_is_running (loop))
g_main_loop_quit (loop);
break;
default:
break;
}
gst_message_unref (message);
return TRUE;
}
static void
block_done (GstPad * pad, gboolean blocked, gpointer data)
{
if (blocked) {
g_print ("pad blocked\n");
/* let's unlink to be cool too */
gst_pad_unlink (pad2, peer2);
} else {
g_print ("pad unblocked\n");
}
}
static gboolean
do_block (GstPipeline * pipeline)
{
static gint iter = 0;
if (iter++ % 2) {
g_print ("blocking pad..");
if (!gst_pad_set_blocked_async (pad2, TRUE, block_done, NULL))
g_print ("was blocked\n");
} else {
/* and relink */
gst_pad_link (pad2, peer2);
g_print ("unblocking pad..");
if (!gst_pad_set_blocked_async (pad2, FALSE, block_done, NULL))
g_print ("was unblocked\n");
}
return TRUE;
}
static gboolean
do_renegotiate (GstPipeline * pipeline)
{
GstCaps *caps;
static gint iter = 0;
g_print ("reneg\n");
if (iter++ % 2) {
caps = gst_caps_new_simple ("video/x-raw-yuv",
"format", GST_TYPE_FOURCC, GST_STR_FOURCC ("I420"),
"width", G_TYPE_INT, 320,
"height", G_TYPE_INT, 240, "framerate", G_TYPE_DOUBLE, 5.0, NULL);
} else {
caps = gst_caps_new_simple ("video/x-raw-yuv",
"format", GST_TYPE_FOURCC, GST_STR_FOURCC ("YUY2"),
"width", G_TYPE_INT, 240,
"height", G_TYPE_INT, 120, "framerate", G_TYPE_DOUBLE, 30.0, NULL);
}
gst_pad_relink_filtered (pad1, peer1, caps);
gst_caps_unref (caps);
return TRUE;
}
int
main (int argc, char *argv[])
{
GstBus *bus;
gtk_init (&argc, &argv);
gst_init (&argc, &argv);
pipeline = gst_pipeline_new ("pipeline");
bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
loop = g_main_loop_new (NULL, FALSE);
gst_bus_add_watch (bus, message_received, pipeline);
src = gst_element_factory_make ("videotestsrc", "src");
queue = gst_element_factory_make ("queue", "queue");
sink = gst_element_factory_make ("xvimagesink", "sink");
gst_bin_add (GST_BIN (pipeline), src);
gst_bin_add (GST_BIN (pipeline), queue);
gst_bin_add (GST_BIN (pipeline), sink);
pad1 = gst_element_get_pad (src, "src");
peer1 = gst_element_get_pad (queue, "sink");
pad2 = gst_element_get_pad (queue, "src");
peer2 = gst_element_get_pad (sink, "sink");
gst_pad_link (pad1, peer1);
gst_pad_link (pad2, peer2);
gst_element_set_state (pipeline, GST_STATE_PLAYING);
g_timeout_add (1000, (GSourceFunc) do_block, pipeline);
g_main_loop_run (loop);
g_timeout_add (200, (GSourceFunc) do_renegotiate, pipeline);
gst_element_set_state (pipeline, GST_STATE_NULL);
gst_object_unref (GST_OBJECT (pipeline));
return 0;
}
This diff is collapsed.
......@@ -571,8 +571,13 @@ gst_faad_chain (GstPad * pad, GstData * data)
buf = GST_BUFFER (data);
next_ts = GST_BUFFER_TIMESTAMP (buf);
if (faad->tempbuf) {
buf = gst_buffer_join (faad->tempbuf, buf);
GstBuffer *new = NULL;
new = gst_buffer_join (faad->tempbuf, buf);
gst_buffer_unref (faad->tempbuf);
faad->tempbuf = NULL;
gst_buffer_unref (buf);
buf = new;
}
/* init if not already done during capsnego */
......
......@@ -27,8 +27,7 @@ SUBDIRS = \
video \
xoverlay \
$(X_DIR) \
. \
play
.
DIST_SUBDIRS = \
audio \
......
......@@ -17,7 +17,9 @@ CLEANFILES = gstaudiofilterexample.c \
$(BUILT_SOURCES)
libgstaudio_la_SOURCES = audio.c audioclock.c \
multichannel.c
multichannel.c \
gstbaseaudiosink.c \
gstringbuffer.c
nodist_libgstaudio_la_SOURCES = $(built_sources)
libgstaudioincludedir = $(includedir)/gstreamer-@GST_MAJORMINOR@/gst/audio
......@@ -25,6 +27,8 @@ libgstaudioinclude_HEADERS = \
audio.h \
audioclock.h \
gstaudiofilter.h \
gstbaseaudiosink.h \
gstringbuffer.h \
multichannel.h \
multichannel-enumtypes.h
......
......@@ -30,10 +30,11 @@ static void gst_audio_clock_class_init (GstAudioClockClass * klass);
static void gst_audio_clock_init (GstAudioClock * clock);
static GstClockTime gst_audio_clock_get_internal_time (GstClock * clock);
static GstClockEntryStatus gst_audio_clock_id_wait_async (GstClock * clock,
GstClockEntry * entry);
static void gst_audio_clock_id_unschedule (GstClock * clock,
GstClockEntry * entry);
//static GstClockEntryStatus gst_audio_clock_id_wait_async (GstClock * clock,
// GstClockEntry * entry);
//static void gst_audio_clock_id_unschedule (GstClock * clock,
// GstClockEntry * entry);
static GstSystemClockClass *parent_class = NULL;
......@@ -79,8 +80,8 @@ gst_audio_clock_class_init (GstAudioClockClass * klass)
parent_class = g_type_class_ref (GST_TYPE_SYSTEM_CLOCK);
gstclock_class->get_internal_time = gst_audio_clock_get_internal_time;
gstclock_class->wait_async = gst_audio_clock_id_wait_async;
gstclock_class->unschedule = gst_audio_clock_id_unschedule;
//gstclock_class->wait_async = gst_audio_clock_id_wait_async;
//gstclock_class->unschedule = gst_audio_clock_id_unschedule;
}
static void
......@@ -178,6 +179,7 @@ gst_audio_clock_update_time (GstAudioClock * aclock, GstClockTime time)
}
}
#if 0
static gint
compare_clock_entries (GstClockEntry * entry1, GstClockEntry * entry2)
{
......@@ -203,3 +205,4 @@ gst_audio_clock_id_unschedule (GstClock * clock, GstClockEntry * entry)
aclock->async_entries = g_slist_remove (aclock->async_entries, entry);
}
#endif
......@@ -51,7 +51,7 @@ static void gst_audiofilter_set_property (GObject * object, guint prop_id,
static void gst_audiofilter_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
static void gst_audiofilter_chain (GstPad * pad, GstData * _data);
static GstFlowReturn gst_audiofilter_chain (GstPad * pad, GstBuffer * buffer);
GstCaps *gst_audiofilter_class_get_capslist (GstAudiofilterClass * klass);
static GstElementClass *parent_class = NULL;
......@@ -113,18 +113,20 @@ gst_audiofilter_class_init (gpointer g_class, gpointer class_data)
}
static GstPadLinkReturn
gst_audiofilter_link (GstPad * pad, const GstCaps * caps)
gst_audiofilter_link (GstPad * pad, GstPad * peer)
{
GstAudiofilter *audiofilter;
GstPadLinkReturn ret;
GstPadLinkReturn link_ret;
GstStructure *structure;
//GstPadLinkReturn ret;
//GstPadLinkReturn link_ret;
//GstStructure *structure;
GstAudiofilterClass *audiofilter_class;
GST_DEBUG ("gst_audiofilter_link");
audiofilter = GST_AUDIOFILTER (gst_pad_get_parent (pad));
audiofilter_class = GST_AUDIOFILTER_CLASS (G_OBJECT_GET_CLASS (audiofilter));
#if 0
ret = GST_PAD_LINK_DELAYED; /* intialise with dummy value */
if (pad == audiofilter->srcpad) {
link_ret = gst_pad_try_set_caps (audiofilter->sinkpad, caps);
......@@ -158,6 +160,7 @@ gst_audiofilter_link (GstPad * pad, const GstCaps * caps)
if (audiofilter_class->setup)
(audiofilter_class->setup) (audiofilter);
#endif
return GST_PAD_LINK_OK;
}
......@@ -177,7 +180,7 @@ gst_audiofilter_init (GTypeInstance * instance, gpointer g_class)
gst_element_add_pad (GST_ELEMENT (audiofilter), audiofilter->sinkpad);
gst_pad_set_chain_function (audiofilter->sinkpad, gst_audiofilter_chain);
gst_pad_set_link_function (audiofilter->sinkpad, gst_audiofilter_link);
gst_pad_set_getcaps_function (audiofilter->sinkpad, gst_pad_proxy_getcaps);
//gst_pad_set_getcaps_function (audiofilter->sinkpad, gst_pad_proxy_getcaps);
pad_template =
gst_element_class_get_pad_template (GST_ELEMENT_CLASS (g_class), "src");
......@@ -185,24 +188,24 @@ gst_audiofilter_init (GTypeInstance * instance, gpointer g_class)
audiofilter->srcpad = gst_pad_new_from_template (pad_template, "src");
gst_element_add_pad (GST_ELEMENT (audiofilter), audiofilter->srcpad);
gst_pad_set_link_function (audiofilter->srcpad, gst_audiofilter_link);
gst_pad_set_getcaps_function (audiofilter->srcpad, gst_pad_proxy_getcaps);
//gst_pad_set_getcaps_function (audiofilter->srcpad, gst_pad_proxy_getcaps);
audiofilter->inited = FALSE;
}
static void
gst_audiofilter_chain (GstPad * pad, GstData * data)
static GstFlowReturn
gst_audiofilter_chain (GstPad * pad, GstBuffer * buffer)
{
GstBuffer *inbuf = GST_BUFFER (data);
GstBuffer *inbuf = GST_BUFFER (buffer);
GstAudiofilter *audiofilter;
GstBuffer *outbuf;
GstAudiofilterClass *audiofilter_class;
GST_DEBUG ("gst_audiofilter_chain");
g_return_if_fail (pad != NULL);
g_return_if_fail (GST_IS_PAD (pad));
g_return_if_fail (inbuf != NULL);
g_return_val_if_fail (pad != NULL, GST_FLOW_ERROR);
g_return_val_if_fail (GST_IS_PAD (pad), GST_FLOW_ERROR);
g_return_val_if_fail (inbuf != NULL, GST_FLOW_ERROR);
audiofilter = GST_AUDIOFILTER (gst_pad_get_parent (pad));
//g_return_if_fail (audiofilter->inited);
......@@ -212,14 +215,14 @@ gst_audiofilter_chain (GstPad * pad, GstData * data)
GST_BUFFER_SIZE (inbuf), GST_OBJECT_NAME (audiofilter));
if (audiofilter->passthru) {
gst_pad_push (audiofilter->srcpad, data);
return;
gst_pad_push (audiofilter->srcpad, buffer);
return GST_FLOW_OK;
}
audiofilter->size = GST_BUFFER_SIZE (inbuf);
audiofilter->n_samples = audiofilter->size / audiofilter->bytes_per_sample;
if (gst_data_is_writable (data)) {
if (gst_data_is_writable (GST_DATA (buffer))) {
if (audiofilter_class->filter_inplace) {
(audiofilter_class->filter_inplace) (audiofilter, inbuf);
outbuf = inbuf;
......@@ -246,7 +249,9 @@ gst_audiofilter_chain (GstPad * pad, GstData * data)
gst_buffer_unref (inbuf);
}
gst_pad_push (audiofilter->srcpad, GST_DATA (outbuf));
gst_pad_push (audiofilter->srcpad, outbuf);
return GST_FLOW_OK;
}
static void
......
/* GStreamer
* Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
* 2005 Wim Taymans <wim@fluendo.com>
*
* gstbaseaudiosink.c:
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include "gstbaseaudiosink.h"
GST_DEBUG_CATEGORY_STATIC (gst_baseaudiosink_debug);
#define GST_CAT_DEFAULT gst_baseaudiosink_debug
/* BaseAudioSink signals and args */
enum
{
/* FILL ME */
LAST_SIGNAL
};
enum
{
ARG_0,
};
#define _do_init(bla) \
GST_DEBUG_CATEGORY_INIT (gst_baseaudiosink_debug, "baseaudiosink", 0, "baseaudiosink element");
GST_BOILERPLATE_FULL (GstBaseAudioSink, gst_baseaudiosink, GstBaseSink,
GST_TYPE_BASESINK, _do_init);
static void gst_baseaudiosink_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec);
static void gst_baseaudiosink_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
static GstElementStateReturn gst_baseaudiosink_change_state (GstElement *
element);
static GstFlowReturn gst_baseaudiosink_preroll (GstBaseSink * bsink,
GstBuffer * buffer);
static GstFlowReturn gst_baseaudiosink_render (GstBaseSink * bsink,
GstBuffer * buffer);
static void gst_baseaudiosink_event (GstBaseSink * bsink, GstEvent * event);
static void gst_baseaudiosink_get_times (GstBaseSink * bsink,
GstBuffer * buffer, GstClockTime * start, GstClockTime * end);
static gboolean gst_baseaudiosink_setcaps (GstBaseSink * bsink, GstCaps * caps);
//static guint gst_baseaudiosink_signals[LAST_SIGNAL] = { 0 };
static void
gst_baseaudiosink_base_init (gpointer g_class)
{
}
static void
gst_baseaudiosink_class_init (GstBaseAudioSinkClass * klass)
{
GObjectClass *gobject_class;
GstElementClass *gstelement_class;
GstBaseSinkClass *gstbasesink_class;
gobject_class = (GObjectClass *) klass;
gstelement_class = (GstElementClass *) klass;
gstbasesink_class = (GstBaseSinkClass *) klass;
gobject_class->set_property =
GST_DEBUG_FUNCPTR (gst_baseaudiosink_set_property);
gobject_class->get_property =
GST_DEBUG_FUNCPTR (gst_baseaudiosink_get_property);
gstelement_class->change_state =
GST_DEBUG_FUNCPTR (gst_baseaudiosink_change_state);
gstbasesink_class->event = GST_DEBUG_FUNCPTR (gst_baseaudiosink_event);
gstbasesink_class->preroll = GST_DEBUG_FUNCPTR (gst_baseaudiosink_preroll);
gstbasesink_class->render = GST_DEBUG_FUNCPTR (gst_baseaudiosink_render);
gstbasesink_class->get_times =
GST_DEBUG_FUNCPTR (gst_baseaudiosink_get_times);
gstbasesink_class->set_caps = GST_DEBUG_FUNCPTR (gst_baseaudiosink_setcaps);
}
static void
gst_baseaudiosink_init (GstBaseAudioSink * baseaudiosink)
{
}
static void
gst_baseaudiosink_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
GstBaseAudioSink *sink;
sink = GST_BASEAUDIOSINK (object);
switch (prop_id) {
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gst_baseaudiosink_get_property (GObject * object, guint prop_id, GValue * value,
GParamSpec * pspec)
{
GstBaseAudioSink *sink;
sink = GST_BASEAUDIOSINK (object);
switch (prop_id) {
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static gboolean
gst_baseaudiosink_setcaps (GstBaseSink * bsink, GstCaps * caps)
{
GstBaseAudioSink *sink = GST_BASEAUDIOSINK (bsink);
GstRingBufferSpec spec;
spec.caps = caps;
spec.segsize = 64;
spec.segtotal = 64;
gst_ringbuffer_release (sink->ringbuffer);
gst_ringbuffer_acquire (sink->ringbuffer, &spec);
return TRUE;
}
static void
gst_baseaudiosink_get_times (GstBaseSink * bsink, GstBuffer * buffer,
GstClockTime * start, GstClockTime * end)
{
*start = GST_CLOCK_TIME_NONE;
*end = GST_CLOCK_TIME_NONE;
}
static void
gst_baseaudiosink_event (GstBaseSink * bsink, GstEvent * event)
{
}
static GstFlowReturn
gst_baseaudiosink_preroll (GstBaseSink * bsink, GstBuffer * buffer)
{
return GST_FLOW_OK;
}
static GstFlowReturn
gst_baseaudiosink_render (GstBaseSink * bsink, GstBuffer * buf)
{
GstBaseAudioSink *sink = GST_BASEAUDIOSINK (bsink);
gst_ringbuffer_write (sink->ringbuffer, GST_CLOCK_TIME_NONE,
GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
return GST_FLOW_OK;
}
GstRingBuffer *
gst_baseaudiosink_create_ringbuffer (GstBaseAudioSink * sink)
{
GstBaseAudioSinkClass *bclass;
GstRingBuffer *buffer = NULL;
bclass = GST_BASEAUDIOSINK_GET_CLASS (sink);
if (bclass->create_ringbuffer)
buffer = bclass->create_ringbuffer (sink);
return buffer;
}
void
gst_baseaudiosink_callback (GstRingBuffer * rbuf, guint advance, gpointer data)
{
//GstBaseAudioSink *sink = GST_BASEAUDIOSINK (data);
}
static GstElementStateReturn
gst_baseaudiosink_change_state (GstElement * element)
{
GstElementStateReturn ret = GST_STATE_SUCCESS;
GstBaseAudioSink *sink = GST_BASEAUDIOSINK (element);
GstElementState transition = GST_STATE_TRANSITION (element);
switch (transition) {
case GST_STATE_NULL_TO_READY:
break;
case GST_STATE_READY_TO_PAUSED:
sink->ringbuffer = gst_baseaudiosink_create_ringbuffer (sink);
gst_ringbuffer_set_callback (sink->ringbuffer, gst_baseaudiosink_callback,
sink);
break;
case GST_STATE_PAUSED_TO_PLAYING:
gst_ringbuffer_play (sink->ringbuffer);
break;
default:
break;
}
ret = GST_ELEMENT_CLASS (parent_class)->change_state (element);
switch (transition) {
case GST_STATE_PLAYING_TO_PAUSED:
gst_ringbuffer_stop (sink->ringbuffer);
break;
case GST_STATE_PAUSED_TO_READY:
gst_object_unref (GST_OBJECT (sink->ringbuffer));
break;
case GST_STATE_READY_TO_NULL:
break;
default:
break;
}
return ret;
}
/* GStreamer
* Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
* 2005 Wim Taymans <wim@fluendo.com>
*
* gstbaseaudosink.h:
*
* 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.
*/
/* a base class for audio sinks.
*
* It uses a ringbuffer to schedule playback of samples. This makes
* it very easy to drop or insert samples to align incomming
* buffers to the exact playback timestamp.
*
* Subclasses must provide a ringbuffer pointing to either DMA
* memory or regular memory. A subclass should also call a callback
* function when it has processed N samples in the buffer. The subclass
* is free to use a thread to signal this callback, use EIO or any
* other mechanism.
*
* The base class is able to operate in push or pull mode. The chain
* mode will queue the samples in the ringbuffer as much as possible.
* The available space is calculated in the callback function.
*
* The pull mode will pull_range() a new buffer of N samples with a
* configurable latency. This allows for high-end real time
* audio processing pipelines driven by the audiosink. The callback
* function will be used to perform a pull_range() on the sinkpad.
* The thread scheduling the callback can be a real-time thread.
*/
#ifndef __GST_BASEAUDIOSINK_H__
#define __GST_BASEAUDIOSINK_H__
#include <gst/gst.h>
#include <gst/base/gstbasesink.h>
#include "gstringbuffer.h"
G_BEGIN_DECLS
#define GST_TYPE_BASEAUDIOSINK (gst_baseaudiosink_get_type())
#define GST_BASEAUDIOSINK(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_BASEAUDIOSINK,GstBaseAudioSink))
#define GST_BASEAUDIOSINK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_BASEAUDIOSINK,GstBaseAudioSinkClass))
#define GST_BASEAUDIOSINK_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_BASEAUDIOSINK, GstBaseAudioSinkClass))
#define GST_IS_BASEAUDIOSINK(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_BASEAUDIOSINK))
#define GST_IS_BASEAUDIOSINK_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_BASEAUDIOSINK))
#define GST_BASEAUDIOSINK_CLOCK(obj) (GST_BASEAUDIOSINK (obj)->clock)
#define GST_BASEAUDIOSINK_PAD(obj) (GST_BASEAUDIOSINK (obj)->sinkpad)
typedef struct _GstBaseAudioSink GstBaseAudioSink;
typedef struct _GstBaseAudioSinkClass GstBaseAudioSinkClass;
struct _GstBaseAudioSink {
GstBaseSink element;
GstRingBuffer *ringbuffer;
};
struct _GstBaseAudioSinkClass {
GstBaseSinkClass parent_class;
/* subclass ringbuffer allocation */
GstRingBuffer* (*create_ringbuffer) (GstBaseAudioSink *sink);
};
GType gst_baseaudiosink_get_type(void);
GstRingBuffer *gst_baseaudiosink_create_ringbuffer (GstBaseAudioSink *sink);
G_END_DECLS
#endif /* __GST_BASEAUDIOSINK_H__ */
/* GStreamer
* Copyright (C) 2005 Wim Taymans <wim@fluendo.com>
*
* gstringbuffer.c:
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include <string.h>
#include "gstringbuffer.h"
static void gst_ringbuffer_class_init (GstRingBufferClass * klass);
static void gst_ringbuffer_init (GstRingBuffer * ringbuffer);
static void gst_ringbuffer_dispose (GObject * object);
static void gst_ringbuffer_finalize (GObject * object);
static GstObjectClass *parent_class = NULL;
/* ringbuffer abstract base class */
GType
gst_ringbuffer_get_type (void)
{
static GType ringbuffer_type = 0;
if (!ringbuffer_type) {
static const GTypeInfo ringbuffer_info = {
sizeof (GstRingBufferClass),
NULL,
NULL,
(GClassInitFunc) gst_ringbuffer_class_init,
NULL,
NULL,
sizeof (GstRingBuffer),
0,
(GInstanceInitFunc) gst_ringbuffer_init,
NULL
};
ringbuffer_type = g_type_register_static (GST_TYPE_OBJECT, "GstRingBuffer",
&ringbuffer_info, G_TYPE_FLAG_ABSTRACT);
}
return ringbuffer_type;
}
static void
gst_ringbuffer_class_init (GstRingBufferClass * klass)
{
GObjectClass *gobject_class;
GstObjectClass *gstobject_class;
gobject_class = (GObjectClass *) klass;
gstobject_class = (GstObjectClass *) klass;
parent_class = g_type_class_ref (GST_TYPE_OBJECT);
gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_ringbuffer_dispose);
gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_ringbuffer_finalize);
}
static void
gst_ringbuffer_init (GstRingBuffer * ringbuffer)
{
ringbuffer->acquired = FALSE;
ringbuffer->state = GST_RINGBUFFER_STATE_STOPPED;
ringbuffer->playseg = 0;
ringbuffer->writeseg = 1;
ringbuffer->segfilled = 0;
ringbuffer->waiters = FALSE;
ringbuffer->cond = g_cond_new ();
}
static void
gst_ringbuffer_dispose (GObject * object)
{
GstRingBuffer *ringbuffer = GST_RINGBUFFER (object);
G_OBJECT_CLASS (parent_class)->dispose (G_OBJECT (ringbuffer));
}
static void
gst_ringbuffer_finalize (GObject * object)
{
GstRingBuffer *ringbuffer = GST_RINGBUFFER (object);
g_cond_free (ringbuffer->cond);
G_OBJECT_CLASS (parent_class)->finalize (G_OBJECT (ringbuffer));
}
void
gst_ringbuffer_set_callback (GstRingBuffer * buf, GstRingBufferCallback cb,
gpointer data)
{
GST_LOCK (buf);
buf->callback = cb;
buf->cb_data = data;
GST_UNLOCK (buf);
}
gboolean
gst_ringbuffer_acquire (GstRingBuffer * buf, GstRingBufferSpec * spec)
{
gboolean res = FALSE;
GstRingBufferClass *rclass;
GST_LOCK (buf);
if (buf->acquired) {
res = TRUE;
goto done;
}
buf->acquired = TRUE;
GST_UNLOCK (buf);
rclass = GST_RINGBUFFER_GET_CLASS (buf);
if (rclass->acquire)
res = rclass->acquire (buf, spec);
GST_LOCK (buf);
if (!res) {
buf->acquired = FALSE;
}
done:
GST_UNLOCK (buf);
return res;
}
gboolean
gst_ringbuffer_release (GstRingBuffer * buf)
{
gboolean res = FALSE;
GstRingBufferClass *rclass;
GST_LOCK (buf);
if (!buf->acquired) {
res = TRUE;
goto done;
}
buf->acquired = FALSE;
GST_UNLOCK (buf);
rclass = GST_RINGBUFFER_GET_CLASS (buf);
if (rclass->release)
res = rclass->release (buf);
GST_LOCK (buf);
if (!res) {
buf->acquired = TRUE;
}
done:
GST_UNLOCK (buf);
return res;
}
gboolean
gst_ringbuffer_play (GstRingBuffer * buf)
{
gboolean res = FALSE;
GstRingBufferClass *rclass;
GST_LOCK (buf);
if (buf->state == GST_RINGBUFFER_STATE_PLAYING) {
res = TRUE;
goto done;
}
buf->state = GST_RINGBUFFER_STATE_PLAYING;
rclass = GST_RINGBUFFER_GET_CLASS (buf);
if (rclass->play)
res = rclass->play (buf);
if (!res) {
buf->state = GST_RINGBUFFER_STATE_STOPPED;
}
done:
GST_UNLOCK (buf);
return res;
}
gboolean
gst_ringbuffer_stop (GstRingBuffer * buf)
{
gboolean res = FALSE;
GstRingBufferClass *rclass;
GST_LOCK (buf);
if (buf->state == GST_RINGBUFFER_STATE_STOPPED) {
res = TRUE;
goto done;
}
buf->state = GST_RINGBUFFER_STATE_STOPPED;
rclass = GST_RINGBUFFER_GET_CLASS (buf);
if (rclass->stop)
res = rclass->stop (buf);
if (!res) {
buf->state = GST_RINGBUFFER_STATE_PLAYING;
}
done:
GST_UNLOCK (buf);
return res;
}
void
gst_ringbuffer_callback (GstRingBuffer * buf, guint advance)
{
GST_LOCK (buf);
buf->playseg = (buf->playseg + advance) % buf->spec.segtotal;
if (buf->playseg == buf->writeseg) {
g_print ("underrun!! read %d, write %d\n", buf->playseg, buf->writeseg);
buf->writeseg = (buf->playseg + 1) % buf->spec.segtotal;
buf->segfilled = 0;
}
if (buf->waiters)
GST_RINGBUFFER_SIGNAL (buf);
GST_UNLOCK (buf);
if (buf->callback)
buf->callback (buf, advance, buf->cb_data);
}
guint
gst_ringbuffer_write (GstRingBuffer * buf, GstClockTime time, guchar * data,
guint len)
{
guint towrite = len;
guint written = 0;
GST_LOCK (buf);
/* we write the complete buffer */
while (towrite > 0) {
guint segavail;
guint segwrite;
/* we cannot write anymore since the buffer is filled, wait for
* some space to become available */
while (buf->writeseg == buf->playseg) {
buf->waiters = TRUE;
GST_RINGBUFFER_WAIT (buf);
buf->waiters = FALSE;
}
/* this is the available size now in the current segment */
segavail = buf->spec.segsize - buf->segfilled;
/* we write up to the available space */
segwrite = MIN (segavail, towrite);
memcpy (GST_BUFFER_DATA (buf->data) + buf->writeseg * buf->spec.segsize +
buf->segfilled, data, segwrite);
towrite -= segwrite;
data += segwrite;
buf->segfilled += segwrite;
written += segwrite;
/* we wrote a complete segment, advance the write pointer */
if (buf->segfilled == buf->spec.segsize) {
buf->writeseg = (buf->writeseg + 1) % buf->spec.segtotal;
buf->segfilled = 0;
}
}
GST_UNLOCK (buf);
return written;
}
/* GStreamer
* Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
* 2005 Wim Taymans <wim@fluendo.com>
*
* gstrinbuffer.h:
*
* 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_RINGBUFFER_H__
#define __GST_RINGBUFFER_H__
#include <gst/gst.h>
G_BEGIN_DECLS
#define GST_TYPE_RINGBUFFER (gst_ringbuffer_get_type())
#define GST_RINGBUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RINGBUFFER,GstRingBuffer))
#define GST_RINGBUFFER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RINGBUFFER,GstRingBufferClass))
#define GST_RINGBUFFER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_RINGBUFFER, GstRingBufferClass))
#define GST_IS_RINGBUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RINGBUFFER))
#define GST_IS_RINGBUFFER_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RINGBUFFER))
typedef struct _GstRingBuffer GstRingBuffer;
typedef struct _GstRingBufferClass GstRingBufferClass;
typedef struct _GstRingBufferSpec GstRingBufferSpec;
typedef void (*GstRingBufferCallback) (GstRingBuffer *rbuf, guint advance, gpointer data);
typedef enum {
GST_RINGBUFFER_STATE_STOPPED,
GST_RINGBUFFER_STATE_PLAYING,
} GstRingBufferState;
typedef enum {
GST_SEGSTATE_INVALID,
GST_SEGSTATE_EMPTY,
GST_SEGSTATE_FILLED,
} GstRingBufferSegState;
struct _GstRingBufferSpec
{
GstCaps *caps;
guint segsize;
guint segtotal;
};
#define GST_RINGBUFFER_GET_COND(buf) (((GstRingBuffer *)buf)->cond)
#define GST_RINGBUFFER_WAIT(buf) (g_cond_wait (GST_RINGBUFFER_GET_COND (buf), GST_GET_LOCK (buf)))
#define GST_RINGBUFFER_SIGNAL(buf) (g_cond_signal (GST_RINGBUFFER_GET_COND (buf)))
struct _GstRingBuffer {
GstObject object;
/*< public >*/ /* with LOCK */
GCond *cond;
gboolean acquired;
GstRingBufferState state;
GstBuffer *data;
GstRingBufferSpec spec;
GstRingBufferSegState *segstate;
gboolean waiters;
gint playseg;
gint writeseg;
gint segfilled;
GstRingBufferCallback callback;
gpointer cb_data;
};
struct _GstRingBufferClass {
GstObjectClass parent_class;
/*< public >*/
gboolean (*acquire) (GstRingBuffer *buf, GstRingBufferSpec *spec);
gboolean (*release) (GstRingBuffer *buf);
gboolean (*play) (GstRingBuffer *buf);
gboolean (*stop) (GstRingBuffer *buf);
};
GType gst_ringbuffer_get_type(void);
void gst_ringbuffer_set_callback (GstRingBuffer *buf, GstRingBufferCallback cb,
gpointer data);
gboolean gst_ringbuffer_acquire (GstRingBuffer *buf, GstRingBufferSpec *spec);
gboolean gst_ringbuffer_release (GstRingBuffer *buf);
gboolean gst_ringbuffer_play (GstRingBuffer *buf);
gboolean gst_ringbuffer_stop (GstRingBuffer *buf);
guint gst_ringbuffer_write (GstRingBuffer *buf, GstClockTime time,
guchar *data, guint len);
void gst_ringbuffer_callback (GstRingBuffer *buf, guint advance);
G_END_DECLS
#endif /* __GST_RINGBUFFER_H__ */
......@@ -49,7 +49,7 @@ main (gint argc, gchar * argv[])
str = gst_caps_to_string (caps);
g_print ("Test caps #2: %s\n", str);
g_free (str);
gst_caps_free (caps);
gst_caps_unref (caps);
return 0;
}
......@@ -55,25 +55,34 @@ gst_bin_find_unconnected_pad (GstBin * bin, GstPadDirection direction)
const GList *pads = NULL;
GstElement *element = NULL;
elements = (GList *) gst_bin_get_list (bin);
GST_LOCK (bin);
elements = bin->children;
/* traverse all elements looking for unconnected pads */
while (elements && pad == NULL) {
element = GST_ELEMENT (elements->data);
pads = gst_element_get_pad_list (element);
GST_LOCK (element);
pads = element->pads;
while (pads) {
GstPad *testpad = GST_PAD (pads->data);
/* check if the direction matches */
if (GST_PAD_DIRECTION (GST_PAD (pads->data)) == direction) {
if (GST_PAD_PEER (GST_PAD (pads->data)) == NULL) {
if (GST_PAD_DIRECTION (testpad) == direction) {
GST_LOCK (pad);
if (GST_PAD_PEER (testpad) == NULL) {
GST_UNLOCK (pad);
/* found it ! */
pad = GST_PAD (pads->data);
pad = testpad;
break;
}
GST_UNLOCK (pad);
}
if (pad)
break; /* found one already */
pads = g_list_next (pads);
}
GST_UNLOCK (element);
elements = g_list_next (elements);
}
GST_UNLOCK (bin);
return pad;
}
......@@ -147,7 +156,7 @@ gst_gconf_render_bin_from_description (const gchar * description)
/* parse the pipeline to a bin */
desc = g_strdup_printf ("bin.( %s )", description);
bin = GST_ELEMENT (gst_parse_launch (desc, &error));
//bin = GST_ELEMENT (gst_parse_launch (desc, &error));
g_free (desc);
if (error) {
g_print ("DEBUG: gstgconf: error parsing pipeline %s\n%s\n",
......
......@@ -273,7 +273,7 @@ G_STMT_START { \
#define CAPS_RESET(target) \
G_STMT_START { \
if (target) gst_caps_free (target); \
if (target) gst_caps_unref (target); \
target = NULL; \
} G_STMT_END
CAPS_RESET (priv->type);
......@@ -509,7 +509,9 @@ gmip_find_type (GstMediaInfoPriv * priv, GError ** error)
if (!gmip_find_type_pre (priv, error))
return FALSE;
GST_DEBUG ("gmip_find_type: iterating");
while ((priv->type == NULL) && gst_bin_iterate (GST_BIN (priv->pipeline)))
while ((priv->type == NULL)
// && gst_bin_iterate (GST_BIN (priv->pipeline))
)
GMI_DEBUG ("+");
GMI_DEBUG ("\n");
return gmip_find_type_post (priv);
......@@ -616,7 +618,7 @@ gmip_find_stream (GstMediaInfoPriv * priv)
/* iterate until caps are found */
/* FIXME: this should be done through the plugin sending some signal
* that it is ready for queries */
while (gst_bin_iterate (GST_BIN (priv->pipeline)) && priv->format == NULL);
//while (gst_bin_iterate (GST_BIN (priv->pipeline)) && priv->format == NULL);
if (gst_element_set_state (priv->pipeline, GST_STATE_PAUSED)
== GST_STATE_FAILURE)
g_warning ("Couldn't set to paused");
......@@ -659,7 +661,9 @@ gmip_find_track_metadata (GstMediaInfoPriv * priv)
{
gmip_find_track_metadata_pre (priv);
GST_DEBUG ("gmip_find_metadata: iterating");
while ((priv->metadata == NULL) && gst_bin_iterate (GST_BIN (priv->pipeline)))
while ((priv->metadata == NULL)
//&& gst_bin_iterate (GST_BIN (priv->pipeline))
)
GMI_DEBUG ("+");
GMI_DEBUG ("\n");
gmip_find_track_metadata_post (priv);
......@@ -729,8 +733,9 @@ gmip_find_track_streaminfo (GstMediaInfoPriv * priv)
{
gmip_find_track_streaminfo_pre (priv);
GST_DEBUG ("DEBUG: gmip_find_streaminfo: iterating");
while ((priv->streaminfo == NULL) &&
gst_bin_iterate (GST_BIN (priv->pipeline)))
while ((priv->streaminfo == NULL)
// && gst_bin_iterate (GST_BIN (priv->pipeline))
)
GMI_DEBUG ("+");
GMI_DEBUG ("\n");
gmip_find_track_streaminfo_post (priv);
......@@ -766,7 +771,9 @@ gmip_find_track_format (GstMediaInfoPriv * priv)
{
gmip_find_track_format_pre (priv);
GST_DEBUG ("DEBUG: gmip_find_format: iterating");
while ((priv->format == NULL) && gst_bin_iterate (GST_BIN (priv->pipeline)))
while ((priv->format == NULL)
//&& gst_bin_iterate (GST_BIN (priv->pipeline))
)
GMI_DEBUG ("+");
GMI_DEBUG ("\n");
gmip_find_track_format_post (priv);
......
......@@ -266,7 +266,8 @@ gst_media_info_read_idler (GstMediaInfo * info, GstMediaInfoStream ** streamp,
gchar *mime;
GST_LOG ("STATE_TYPEFIND");
if ((priv->type == NULL) && gst_bin_iterate (GST_BIN (priv->pipeline))) {
//if ((priv->type == NULL) && gst_bin_iterate (GST_BIN (priv->pipeline))) {
if ((priv->type == NULL)) {
GST_DEBUG ("iterating while in STATE_TYPEFIND");
GMI_DEBUG ("?");
return TRUE;
......@@ -298,7 +299,8 @@ gst_media_info_read_idler (GstMediaInfo * info, GstMediaInfoStream ** streamp,
case GST_MEDIA_INFO_STATE_STREAM:
{
GST_LOG ("STATE_STREAM");
if ((priv->format == NULL) && gst_bin_iterate (GST_BIN (priv->pipeline))) {
//if ((priv->format == NULL) && gst_bin_iterate (GST_BIN (priv->pipeline))) {
if ((priv->format == NULL)) {
GMI_DEBUG ("?");
return TRUE;
}
......@@ -317,7 +319,7 @@ gst_media_info_read_idler (GstMediaInfo * info, GstMediaInfoStream ** streamp,
case GST_MEDIA_INFO_STATE_METADATA:
{
if ((priv->metadata == NULL) &&
gst_bin_iterate (GST_BIN (priv->pipeline)) &&
//gst_bin_iterate (GST_BIN (priv->pipeline)) &&
priv->metadata_iters < MAX_METADATA_ITERS) {
GMI_DEBUG ("?");
priv->metadata_iters++;
......@@ -338,8 +340,9 @@ gst_media_info_read_idler (GstMediaInfo * info, GstMediaInfoStream ** streamp,
}
case GST_MEDIA_INFO_STATE_STREAMINFO:
{
if ((priv->streaminfo == NULL) &&
gst_bin_iterate (GST_BIN (priv->pipeline))) {
if ((priv->streaminfo == NULL)
//&& gst_bin_iterate (GST_BIN (priv->pipeline))
) {
GMI_DEBUG ("?");
return TRUE;
}
......@@ -355,7 +358,9 @@ gst_media_info_read_idler (GstMediaInfo * info, GstMediaInfoStream ** streamp,
}
case GST_MEDIA_INFO_STATE_FORMAT:
{
if ((priv->format == NULL) && gst_bin_iterate (GST_BIN (priv->pipeline))) {
if ((priv->format == NULL)
// && gst_bin_iterate (GST_BIN (priv->pipeline))
) {
GMI_DEBUG ("?");
return TRUE;
}
......
......@@ -41,7 +41,7 @@
*/
GstCaps *
gst_riff_create_video_caps_with_data (guint32 codec_fcc,
gst_riff_create_video_caps (guint32 codec_fcc,
gst_riff_strh * strh, gst_riff_strf_vids * strf,
GstBuffer * strf_data, GstBuffer * strd_data, char **codec_name)
{
......@@ -355,15 +355,7 @@ gst_riff_create_video_caps_with_data (guint32 codec_fcc,
}
GstCaps *
gst_riff_create_video_caps (guint32 codec_fcc,
gst_riff_strh * strh, gst_riff_strf_vids * strf, char **codec_name)
{
return gst_riff_create_video_caps_with_data (codec_fcc,
strh, strf, NULL, NULL, codec_name);
}
GstCaps *
gst_riff_create_audio_caps_with_data (guint16 codec_id,
gst_riff_create_audio_caps (guint16 codec_id,
gst_riff_strh * strh, gst_riff_strf_auds * strf,
GstBuffer * strf_data, GstBuffer * strd_data, char **codec_name)
{
......@@ -527,17 +519,10 @@ gst_riff_create_audio_caps_with_data (guint16 codec_id,
return caps;
}
GstCaps *
gst_riff_create_audio_caps (guint16 codec_id,
gst_riff_strh * strh, gst_riff_strf_auds * strf, char **codec_name)
{
return gst_riff_create_audio_caps_with_data (codec_id,
strh, strf, NULL, NULL, codec_name);
}
GstCaps *
gst_riff_create_iavs_caps (guint32 codec_fcc,
gst_riff_strh * strh, gst_riff_strf_iavs * strf, char **codec_name)
gst_riff_strh * strh, gst_riff_strf_iavs * strf,
GstBuffer * init_data, GstBuffer * extra_data, char **codec_name)
{
GstCaps *caps = NULL;
......@@ -600,7 +585,7 @@ gst_riff_create_video_template_caps (void)
caps = gst_caps_new_empty ();
for (i = 0; tags[i] != 0; i++) {
one = gst_riff_create_video_caps (tags[i], NULL, NULL, NULL);
one = gst_riff_create_video_caps (tags[i], NULL, NULL, NULL, NULL, NULL);
if (one)
gst_caps_append (caps, one);
}
......@@ -632,7 +617,7 @@ gst_riff_create_audio_template_caps (void)
caps = gst_caps_new_empty ();
for (i = 0; tags[i] != 0; i++) {
one = gst_riff_create_audio_caps (tags[i], NULL, NULL, NULL);
one = gst_riff_create_audio_caps (tags[i], NULL, NULL, NULL, NULL, NULL);
if (one)
gst_caps_append (caps, one);
}
......@@ -653,7 +638,7 @@ gst_riff_create_iavs_template_caps (void)
caps = gst_caps_new_empty ();
for (i = 0; tags[i] != 0; i++) {
one = gst_riff_create_iavs_caps (tags[i], NULL, NULL, NULL);
one = gst_riff_create_iavs_caps (tags[i], NULL, NULL, NULL, NULL, NULL);
if (one)
gst_caps_append (caps, one);
}
......
......@@ -29,48 +29,36 @@
G_BEGIN_DECLS
/*
* Create one caps. strh/strf can be NULL (for non-fixed caps).
* Create caos. strh/strf, strf/strd_data and codec_name can be NULL.
*/
GstCaps *gst_riff_create_video_caps (guint32 codec_fcc,
gst_riff_strh *strh,
gst_riff_strf_vids *strf,
char **codec_name);
GstCaps *gst_riff_create_audio_caps (guint16 codec_id,
gst_riff_strh *strh,
gst_riff_strf_auds *strf,
char **codec_name);
GstCaps *gst_riff_create_iavs_caps (guint32 codec_fcc,
gst_riff_strh *strh,
gst_riff_strf_iavs *strf,
char **codec_name);
/*
* Extended...
*/
GstCaps *
gst_riff_create_video_caps_with_data (guint32 codec_fcc,
GstCaps * gst_riff_create_video_caps (guint32 codec_fcc,
gst_riff_strh * strh,
gst_riff_strf_vids * strf,
GstBuffer * strf_data,
GstBuffer * strd_data,
char ** codec_name);
GstCaps *
gst_riff_create_audio_caps_with_data (guint16 codec_id,
GstCaps * gst_riff_create_audio_caps (guint16 codec_id,
gst_riff_strh * strh,
gst_riff_strf_auds * strf,
GstBuffer * strf_data,
GstBuffer * strd_data,
char ** codec_name);
GstCaps * gst_riff_create_iavs_caps (guint32 codec_fcc,
gst_riff_strh * strh,
gst_riff_strf_iavs * strf,
GstBuffer * strf_data,
GstBuffer * strd_data,
char ** codec_name);
/*
* Create template caps (includes all known types).
*/
GstCaps *gst_riff_create_video_template_caps (void);
GstCaps *gst_riff_create_audio_template_caps (void);
GstCaps *gst_riff_create_iavs_template_caps (void);
GstCaps * gst_riff_create_video_template_caps (void);
GstCaps * gst_riff_create_audio_template_caps (void);
GstCaps * gst_riff_create_iavs_template_caps (void);
G_END_DECLS
......
This diff is collapsed.
......@@ -24,87 +24,58 @@
#include <glib.h>
#include <gst/gst.h>
#include <gst/bytestream/bytestream.h>
G_BEGIN_DECLS
#include "riff-ids.h"
#define GST_TYPE_RIFF_READ \