diff options
91 files changed, 10959 insertions, 19713 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index a9f98ce1..0295fb97 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3,8 +3,9 @@ of people, including, but not limited to: David Schleef <ds@schleef.org> Jan Schmidt <thaytan@noraisin.net> - Wim Taymans <wim@fluendo.com> + Wim Taymans <wim.taymans@gmail.com> Thomas Vander Stichele <thomas@apestaart.org> + Tim-Philipp Müller <tim centricular net> Maintainer-related issues should be addressed to: diff --git a/configure.ac b/configure.ac index 5f5a4bc8..667d7d36 100644 --- a/configure.ac +++ b/configure.ac @@ -3,7 +3,7 @@ AC_PREREQ(2.52) dnl initialize autoconf dnl when going to/from release please set the nano (fourth number) right ! dnl releases only do Wall, cvs and prerelease does Werror too -AC_INIT(GStreamer Bad Plug-ins, 0.10.13.1, +AC_INIT(GStreamer Bad Plug-ins, 0.10.13.2, http://bugzilla.gnome.org/enter_bug.cgi?product=GStreamer, gst-plugins-bad) @@ -45,8 +45,8 @@ AC_LIBTOOL_WIN32_DLL AM_PROG_LIBTOOL dnl *** required versions of GStreamer stuff *** -GST_REQ=0.10.23.1 -GSTPB_REQ=0.10.23.1 +GST_REQ=0.10.24 +GSTPB_REQ=0.10.24 dnl *** autotools stuff **** @@ -172,7 +172,7 @@ AC_CHECK_FUNC(socket,,[AC_CHECK_LIB(socket,socket)]) AC_CHECK_FUNC(gethostbyname,,[AC_CHECK_LIB(nsl,gethostbyname)]) dnl GLib is required -AG_GST_GLIB_CHECK([2.6]) +AG_GST_GLIB_CHECK([2.16]) dnl liboil is required PKG_CHECK_MODULES(LIBOIL, liboil-0.3 >= 0.3.8, HAVE_LIBOIL=yes, HAVE_LIBOIL=no) @@ -284,7 +284,6 @@ AG_GST_CHECK_PLUGIN(pcapparse) AG_GST_CHECK_PLUGIN(qtmux) AG_GST_CHECK_PLUGIN(rawparse) AG_GST_CHECK_PLUGIN(real) -AG_GST_CHECK_PLUGIN(rtpmanager) AG_GST_CHECK_PLUGIN(rtpmux) AG_GST_CHECK_PLUGIN(scaletempo) AG_GST_CHECK_PLUGIN(sdp) @@ -1696,7 +1695,6 @@ gst/pcapparse/Makefile gst/qtmux/Makefile gst/rawparse/Makefile gst/real/Makefile -gst/rtpmanager/Makefile gst/rtpmux/Makefile gst/scaletempo/Makefile gst/sdp/Makefile diff --git a/docs/plugins/Makefile.am b/docs/plugins/Makefile.am index 7ac083ae..dc581fc1 100644 --- a/docs/plugins/Makefile.am +++ b/docs/plugins/Makefile.am @@ -142,11 +142,6 @@ EXTRA_HFILES = \ $(top_srcdir)/gst/pcapparse/gstpcapparse.h \ $(top_srcdir)/gst/rawparse/gstaudioparse.h \ $(top_srcdir)/gst/rawparse/gstvideoparse.h \ - $(top_srcdir)/gst/rtpmanager/gstrtpbin.h \ - $(top_srcdir)/gst/rtpmanager/gstrtpjitterbuffer.h \ - $(top_srcdir)/gst/rtpmanager/gstrtpptdemux.h \ - $(top_srcdir)/gst/rtpmanager/gstrtpsession.h \ - $(top_srcdir)/gst/rtpmanager/gstrtpssrcdemux.h \ $(top_srcdir)/gst/rtpmux/gstrtpmux.h \ $(top_srcdir)/gst/rtpmux/gstrtpdtmfmux.h \ $(top_srcdir)/gst/scaletempo/gstscaletempo.h \ diff --git a/docs/plugins/gst-plugins-bad-plugins-docs.sgml b/docs/plugins/gst-plugins-bad-plugins-docs.sgml index ef8eb36b..cf6fed4b 100644 --- a/docs/plugins/gst-plugins-bad-plugins-docs.sgml +++ b/docs/plugins/gst-plugins-bad-plugins-docs.sgml @@ -38,11 +38,6 @@ <xi:include href="xml/element-dvdspu.xml" /> <xi:include href="xml/element-festival.xml" /> <xi:include href="xml/element-fpsdisplaysink.xml" /> - <xi:include href="xml/element-gstrtpbin.xml" /> - <xi:include href="xml/element-gstrtpjitterbuffer.xml" /> - <xi:include href="xml/element-gstrtpptdemux.xml" /> - <xi:include href="xml/element-gstrtpsession.xml" /> - <xi:include href="xml/element-gstrtpssrcdemux.xml" /> <xi:include href="xml/element-input-selector.xml" /> <xi:include href="xml/element-ivorbisdec.xml" /> <xi:include href="xml/element-jackaudiosrc.xml" /> @@ -122,7 +117,6 @@ <xi:include href="xml/plugin-freeze.xml" /> <xi:include href="xml/plugin-frei0r.xml" /> <xi:include href="xml/plugin-gsm.xml" /> - <xi:include href="xml/plugin-gstrtpmanager.xml" /> <xi:include href="xml/plugin-h264parse.xml" /> <xi:include href="xml/plugin-jack.xml" /> <xi:include href="xml/plugin-kate.xml" /> diff --git a/docs/plugins/gst-plugins-bad-plugins-sections.txt b/docs/plugins/gst-plugins-bad-plugins-sections.txt index c60e127c..45edb369 100644 --- a/docs/plugins/gst-plugins-bad-plugins-sections.txt +++ b/docs/plugins/gst-plugins-bad-plugins-sections.txt @@ -781,82 +781,6 @@ gst_rtp_session_set_ssrc </SECTION> <SECTION> -<FILE>element-gstrtpbin</FILE> -<TITLE>gstrtpbin</TITLE> -GstRtpBin -<SUBSECTION Standard> -GstRtpBinPrivate -GstRtpBinClass -GST_RTP_BIN -GST_IS_RTP_BIN -GST_TYPE_RTP_BIN -gst_rtp_bin_get_type -GST_RTP_BIN_CLASS -GST_IS_RTP_BIN_CLASS -</SECTION> - -<SECTION> -<FILE>element-gstrtpjitterbuffer</FILE> -<TITLE>gstrtpjitterbuffer</TITLE> -GstRtpJitterBuffer -<SUBSECTION Standard> -GstRtpJitterBufferClass -GstRtpJitterBufferPrivate -GST_RTP_JITTER_BUFFER -GST_IS_RTP_JITTER_BUFFER -GST_TYPE_RTP_JITTER_BUFFER -gst_rtp_jitter_buffer_get_type -GST_RTP_JITTER_BUFFER_CLASS -GST_IS_RTP_JITTER_BUFFER_CLASS -</SECTION> - -<SECTION> -<FILE>element-gstrtpptdemux</FILE> -<TITLE>gstrtpptdemux</TITLE> -GstRtpPtDemux -<SUBSECTION Standard> -GstRtpPtDemuxClass -GstRtpPtDemuxPad -GST_RTP_PT_DEMUX -GST_IS_RTP_PT_DEMUX -GST_TYPE_RTP_PT_DEMUX -gst_rtp_pt_demux_get_type -GST_RTP_PT_DEMUX_CLASS -GST_IS_RTP_PT_DEMUX_CLASS -</SECTION> - -<SECTION> -<FILE>element-gstrtpsession</FILE> -<TITLE>gstrtpsession</TITLE> -GstRtpSession -<SUBSECTION Standard> -GstRtpSessionClass -GstRtpSessionPrivate -GST_RTP_SESSION -GST_IS_RTP_SESSION -GST_TYPE_RTP_SESSION -gst_rtp_session_get_type -GST_RTP_SESSION_CLASS -GST_IS_RTP_SESSION_CLASS -GST_RTP_SESSION_CAST -</SECTION> - -<SECTION> -<FILE>element-gstrtpssrcdemux</FILE> -<TITLE>gstrtpssrcdemux</TITLE> -GstRtpSsrcDemux -<SUBSECTION Standard> -GstRtpSsrcDemuxClass -GstRtpSsrcDemuxPad -GST_RTP_SSRC_DEMUX -GST_IS_RTP_SSRC_DEMUX -GST_TYPE_RTP_SSRC_DEMUX -gst_rtp_ssrc_demux_get_type -GST_RTP_SSRC_DEMUX_CLASS -GST_IS_RTP_SSRC_DEMUX_CLASS -</SECTION> - -<SECTION> <FILE>element-scaletempo</FILE> <TITLE>scaletempo</TITLE> GstScaletempo diff --git a/docs/plugins/gst-plugins-bad-plugins.args b/docs/plugins/gst-plugins-bad-plugins.args index f25241fe..4b259eab 100644 --- a/docs/plugins/gst-plugins-bad-plugins.args +++ b/docs/plugins/gst-plugins-bad-plugins.args @@ -17559,36 +17559,6 @@ </ARG> <ARG> -<NAME>GstRTPJitterBuffer::drop-on-latency</NAME> -<TYPE>gboolean</TYPE> -<RANGE></RANGE> -<FLAGS>rw</FLAGS> -<NICK>Drop buffers when maximum latency is reached</NICK> -<BLURB>Tells the jitterbuffer to never exceed the given latency in size.</BLURB> -<DEFAULT>FALSE</DEFAULT> -</ARG> - -<ARG> -<NAME>GstRTPJitterBuffer::latency</NAME> -<TYPE>guint</TYPE> -<RANGE></RANGE> -<FLAGS>rw</FLAGS> -<NICK>Buffer latency in ms</NICK> -<BLURB>Amount of ms to buffer.</BLURB> -<DEFAULT>200</DEFAULT> -</ARG> - -<ARG> -<NAME>GstRTPBin::latency</NAME> -<TYPE>guint</TYPE> -<RANGE></RANGE> -<FLAGS>rw</FLAGS> -<NICK>Buffer latency in ms</NICK> -<BLURB>Default amount of ms to buffer in the jitterbuffers.</BLURB> -<DEFAULT>200</DEFAULT> -</ARG> - -<ARG> <NAME>GstOSXVideoSink::embed</NAME> <TYPE>gboolean</TYPE> <RANGE></RANGE> @@ -18109,286 +18079,6 @@ </ARG> <ARG> -<NAME>GstRtpSession::ntp-ns-base</NAME> -<TYPE>guint64</TYPE> -<RANGE></RANGE> -<FLAGS>rw</FLAGS> -<NICK>NTP base time</NICK> -<BLURB>The NTP base time corresponding to running_time 0.</BLURB> -<DEFAULT>0</DEFAULT> -</ARG> - -<ARG> -<NAME>GstRtpSession::bandwidth</NAME> -<TYPE>gdouble</TYPE> -<RANGE>>= 0</RANGE> -<FLAGS>rw</FLAGS> -<NICK>Bandwidth</NICK> -<BLURB>The bandwidth of the session.</BLURB> -<DEFAULT>64000</DEFAULT> -</ARG> - -<ARG> -<NAME>GstRtpSession::num-active-sources</NAME> -<TYPE>guint</TYPE> -<RANGE></RANGE> -<FLAGS>r</FLAGS> -<NICK>Num Active Sources</NICK> -<BLURB>The number of active sources in the session.</BLURB> -<DEFAULT>0</DEFAULT> -</ARG> - -<ARG> -<NAME>GstRtpSession::num-sources</NAME> -<TYPE>guint</TYPE> -<RANGE></RANGE> -<FLAGS>r</FLAGS> -<NICK>Num Sources</NICK> -<BLURB>The number of sources in the session.</BLURB> -<DEFAULT>0</DEFAULT> -</ARG> - -<ARG> -<NAME>GstRtpSession::rtcp-fraction</NAME> -<TYPE>gdouble</TYPE> -<RANGE>>= 0</RANGE> -<FLAGS>rw</FLAGS> -<NICK>RTCP Fraction</NICK> -<BLURB>The fraction of the bandwidth used for RTCP.</BLURB> -<DEFAULT>3000</DEFAULT> -</ARG> - -<ARG> -<NAME>GstRtpSession::sdes-cname</NAME> -<TYPE>gchar*</TYPE> -<RANGE></RANGE> -<FLAGS>rw</FLAGS> -<NICK>SDES CNAME</NICK> -<BLURB>The CNAME to put in SDES messages of this session.</BLURB> -<DEFAULT>NULL</DEFAULT> -</ARG> - -<ARG> -<NAME>GstRtpSession::sdes-email</NAME> -<TYPE>gchar*</TYPE> -<RANGE></RANGE> -<FLAGS>rw</FLAGS> -<NICK>SDES EMAIL</NICK> -<BLURB>The EMAIL to put in SDES messages of this session.</BLURB> -<DEFAULT>NULL</DEFAULT> -</ARG> - -<ARG> -<NAME>GstRtpSession::sdes-location</NAME> -<TYPE>gchar*</TYPE> -<RANGE></RANGE> -<FLAGS>rw</FLAGS> -<NICK>SDES LOCATION</NICK> -<BLURB>The LOCATION to put in SDES messages of this session.</BLURB> -<DEFAULT>NULL</DEFAULT> -</ARG> - -<ARG> -<NAME>GstRtpSession::sdes-name</NAME> -<TYPE>gchar*</TYPE> -<RANGE></RANGE> -<FLAGS>rw</FLAGS> -<NICK>SDES NAME</NICK> -<BLURB>The NAME to put in SDES messages of this session.</BLURB> -<DEFAULT>NULL</DEFAULT> -</ARG> - -<ARG> -<NAME>GstRtpSession::sdes-note</NAME> -<TYPE>gchar*</TYPE> -<RANGE></RANGE> -<FLAGS>rw</FLAGS> -<NICK>SDES NOTE</NICK> -<BLURB>The NOTE to put in SDES messages of this session.</BLURB> -<DEFAULT>NULL</DEFAULT> -</ARG> - -<ARG> -<NAME>GstRtpSession::sdes-phone</NAME> -<TYPE>gchar*</TYPE> -<RANGE></RANGE> -<FLAGS>rw</FLAGS> -<NICK>SDES PHONE</NICK> -<BLURB>The PHONE to put in SDES messages of this session.</BLURB> -<DEFAULT>NULL</DEFAULT> -</ARG> - -<ARG> -<NAME>GstRtpSession::sdes-tool</NAME> -<TYPE>gchar*</TYPE> -<RANGE></RANGE> -<FLAGS>rw</FLAGS> -<NICK>SDES TOOL</NICK> -<BLURB>The TOOL to put in SDES messages of this session.</BLURB> -<DEFAULT>NULL</DEFAULT> -</ARG> - -<ARG> -<NAME>GstRtpSession::internal-session</NAME> -<TYPE>RTPSession*</TYPE> -<RANGE></RANGE> -<FLAGS>r</FLAGS> -<NICK>Internal Session</NICK> -<BLURB>The internal RTPSession object.</BLURB> -<DEFAULT></DEFAULT> -</ARG> - -<ARG> -<NAME>GstRtpSession::sdes</NAME> -<TYPE>GstStructure*</TYPE> -<RANGE></RANGE> -<FLAGS>rw</FLAGS> -<NICK>SDES</NICK> -<BLURB>The SDES items of this session.</BLURB> -<DEFAULT></DEFAULT> -</ARG> - -<ARG> -<NAME>GstRtpJitterBuffer::drop-on-latency</NAME> -<TYPE>gboolean</TYPE> -<RANGE></RANGE> -<FLAGS>rw</FLAGS> -<NICK>Drop buffers when maximum latency is reached</NICK> -<BLURB>Tells the jitterbuffer to never exceed the given latency in size.</BLURB> -<DEFAULT>FALSE</DEFAULT> -</ARG> - -<ARG> -<NAME>GstRtpJitterBuffer::latency</NAME> -<TYPE>guint</TYPE> -<RANGE></RANGE> -<FLAGS>rw</FLAGS> -<NICK>Buffer latency in ms</NICK> -<BLURB>Amount of ms to buffer.</BLURB> -<DEFAULT>200</DEFAULT> -</ARG> - -<ARG> -<NAME>GstRtpJitterBuffer::ts-offset</NAME> -<TYPE>gint64</TYPE> -<RANGE></RANGE> -<FLAGS>rw</FLAGS> -<NICK>Timestamp Offset</NICK> -<BLURB>Adjust buffer timestamps with offset in nanoseconds.</BLURB> -<DEFAULT>0</DEFAULT> -</ARG> - -<ARG> -<NAME>GstRtpJitterBuffer::do-lost</NAME> -<TYPE>gboolean</TYPE> -<RANGE></RANGE> -<FLAGS>rw</FLAGS> -<NICK>Do Lost</NICK> -<BLURB>Send an event downstream when a packet is lost.</BLURB> -<DEFAULT>FALSE</DEFAULT> -</ARG> - -<ARG> -<NAME>GstRtpBin::latency</NAME> -<TYPE>guint</TYPE> -<RANGE></RANGE> -<FLAGS>rw</FLAGS> -<NICK>Buffer latency in ms</NICK> -<BLURB>Default amount of ms to buffer in the jitterbuffers.</BLURB> -<DEFAULT>200</DEFAULT> -</ARG> - -<ARG> -<NAME>GstRtpBin::sdes-cname</NAME> -<TYPE>gchar*</TYPE> -<RANGE></RANGE> -<FLAGS>rw</FLAGS> -<NICK>SDES CNAME</NICK> -<BLURB>The CNAME to put in SDES messages of this session.</BLURB> -<DEFAULT>NULL</DEFAULT> -</ARG> - -<ARG> -<NAME>GstRtpBin::sdes-email</NAME> -<TYPE>gchar*</TYPE> -<RANGE></RANGE> -<FLAGS>rw</FLAGS> -<NICK>SDES EMAIL</NICK> -<BLURB>The EMAIL to put in SDES messages of this session.</BLURB> -<DEFAULT>NULL</DEFAULT> -</ARG> - -<ARG> -<NAME>GstRtpBin::sdes-location</NAME> -<TYPE>gchar*</TYPE> -<RANGE></RANGE> -<FLAGS>rw</FLAGS> -<NICK>SDES LOCATION</NICK> -<BLURB>The LOCATION to put in SDES messages of this session.</BLURB> -<DEFAULT>NULL</DEFAULT> -</ARG> - -<ARG> -<NAME>GstRtpBin::sdes-name</NAME> -<TYPE>gchar*</TYPE> -<RANGE></RANGE> -<FLAGS>rw</FLAGS> -<NICK>SDES NAME</NICK> -<BLURB>The NAME to put in SDES messages of this session.</BLURB> -<DEFAULT>NULL</DEFAULT> -</ARG> - -<ARG> -<NAME>GstRtpBin::sdes-note</NAME> -<TYPE>gchar*</TYPE> -<RANGE></RANGE> -<FLAGS>rw</FLAGS> -<NICK>SDES NOTE</NICK> -<BLURB>The NOTE to put in SDES messages of this session.</BLURB> -<DEFAULT>NULL</DEFAULT> -</ARG> - -<ARG> -<NAME>GstRtpBin::sdes-phone</NAME> -<TYPE>gchar*</TYPE> -<RANGE></RANGE> -<FLAGS>rw</FLAGS> -<NICK>SDES PHONE</NICK> -<BLURB>The PHONE to put in SDES messages of this session.</BLURB> -<DEFAULT>NULL</DEFAULT> -</ARG> - -<ARG> -<NAME>GstRtpBin::sdes-tool</NAME> -<TYPE>gchar*</TYPE> -<RANGE></RANGE> -<FLAGS>rw</FLAGS> -<NICK>SDES TOOL</NICK> -<BLURB>The TOOL to put in SDES messages of this session.</BLURB> -<DEFAULT>NULL</DEFAULT> -</ARG> - -<ARG> -<NAME>GstRtpBin::do-lost</NAME> -<TYPE>gboolean</TYPE> -<RANGE></RANGE> -<FLAGS>rw</FLAGS> -<NICK>Do Lost</NICK> -<BLURB>Send an event downstream when a packet is lost.</BLURB> -<DEFAULT>FALSE</DEFAULT> -</ARG> - -<ARG> -<NAME>GstRtpBin::sdes</NAME> -<TYPE>GstStructure*</TYPE> -<RANGE></RANGE> -<FLAGS>rw</FLAGS> -<NICK>SDES</NICK> -<BLURB>The SDES items of this session.</BLURB> -<DEFAULT></DEFAULT> -</ARG> - -<ARG> <NAME>GstGioSrc::location</NAME> <TYPE>gchar*</TYPE> <RANGE></RANGE> diff --git a/docs/plugins/gst-plugins-bad-plugins.hierarchy b/docs/plugins/gst-plugins-bad-plugins.hierarchy index 2c755d23..10a65892 100644 --- a/docs/plugins/gst-plugins-bad-plugins.hierarchy +++ b/docs/plugins/gst-plugins-bad-plugins.hierarchy @@ -16,7 +16,6 @@ GObject GstFPSDisplaySink GstAutoConvert GstSDPDemux - GstRtpBin GstSignalProcessor http---calf-sourceforge-net-plugins-Compressor http---calf-sourceforge-net-plugins-Filter @@ -466,10 +465,6 @@ GObject GstSpeed GstInputSelector GstOutputSelector - GstRtpJitterBuffer - GstRtpPtDemux - GstRtpSession - GstRtpSsrcDemux GstRealVideoDec GstRealAudioDec GstRawParse diff --git a/docs/plugins/gst-plugins-bad-plugins.signals b/docs/plugins/gst-plugins-bad-plugins.signals index 73f6b85e..0550d9b1 100644 --- a/docs/plugins/gst-plugins-bad-plugins.signals +++ b/docs/plugins/gst-plugins-bad-plugins.signals @@ -51,302 +51,6 @@ gint64 arg3 </SIGNAL> <SIGNAL> -<NAME>GstRtpBin::clear-pt-map</NAME> -<RETURNS>void</RETURNS> -<FLAGS>la</FLAGS> -GstRtpBin *gstrtpbin -</SIGNAL> - -<SIGNAL> -<NAME>GstRtpBin::on-bye-ssrc</NAME> -<RETURNS>void</RETURNS> -<FLAGS>l</FLAGS> -GstRtpBin *gstrtpbin -guint arg1 -guint arg2 -</SIGNAL> - -<SIGNAL> -<NAME>GstRtpBin::on-bye-timeout</NAME> -<RETURNS>void</RETURNS> -<FLAGS>l</FLAGS> -GstRtpBin *gstrtpbin -guint arg1 -guint arg2 -</SIGNAL> - -<SIGNAL> -<NAME>GstRtpBin::on-new-ssrc</NAME> -<RETURNS>void</RETURNS> -<FLAGS>l</FLAGS> -GstRtpBin *gstrtpbin -guint arg1 -guint arg2 -</SIGNAL> - -<SIGNAL> -<NAME>GstRtpBin::on-ssrc-active</NAME> -<RETURNS>void</RETURNS> -<FLAGS>l</FLAGS> -GstRtpBin *gstrtpbin -guint arg1 -guint arg2 -</SIGNAL> - -<SIGNAL> -<NAME>GstRtpBin::on-ssrc-collision</NAME> -<RETURNS>void</RETURNS> -<FLAGS>l</FLAGS> -GstRtpBin *gstrtpbin -guint arg1 -guint arg2 -</SIGNAL> - -<SIGNAL> -<NAME>GstRtpBin::on-ssrc-sdes</NAME> -<RETURNS>void</RETURNS> -<FLAGS>l</FLAGS> -GstRtpBin *gstrtpbin -guint arg1 -guint arg2 -</SIGNAL> - -<SIGNAL> -<NAME>GstRtpBin::on-ssrc-validated</NAME> -<RETURNS>void</RETURNS> -<FLAGS>l</FLAGS> -GstRtpBin *gstrtpbin -guint arg1 -guint arg2 -</SIGNAL> - -<SIGNAL> -<NAME>GstRtpBin::on-timeout</NAME> -<RETURNS>void</RETURNS> -<FLAGS>l</FLAGS> -GstRtpBin *gstrtpbin -guint arg1 -guint arg2 -</SIGNAL> - -<SIGNAL> -<NAME>GstRtpBin::request-pt-map</NAME> -<RETURNS>GstCaps*</RETURNS> -<FLAGS>l</FLAGS> -GstRtpBin *gstrtpbin -guint arg1 -guint arg2 -</SIGNAL> - -<SIGNAL> -<NAME>GstRtpBin::get-internal-session</NAME> -<RETURNS>RTPSession*</RETURNS> -<FLAGS>la</FLAGS> -GstRtpBin *gstrtpbin -guint arg1 -</SIGNAL> - -<SIGNAL> -<NAME>GstRtpBin::on-sender-timeout</NAME> -<RETURNS>void</RETURNS> -<FLAGS>l</FLAGS> -GstRtpBin *gstrtpbin -guint arg1 -guint arg2 -</SIGNAL> - -<SIGNAL> -<NAME>GstRtpBin::reset-sync</NAME> -<RETURNS>void</RETURNS> -<FLAGS>la</FLAGS> -GstRtpBin *gstrtpbin -</SIGNAL> - -<SIGNAL> -<NAME>GstRtpBin::on-npt-stop</NAME> -<RETURNS>void</RETURNS> -<FLAGS>l</FLAGS> -GstRtpBin *gstrtpbin -guint arg1 -guint arg2 -</SIGNAL> - -<SIGNAL> -<NAME>GstRtpJitterBuffer::clear-pt-map</NAME> -<RETURNS>void</RETURNS> -<FLAGS>la</FLAGS> -GstRtpJitterBuffer *gstrtpjitterbuffer -</SIGNAL> - -<SIGNAL> -<NAME>GstRtpJitterBuffer::request-pt-map</NAME> -<RETURNS>GstCaps*</RETURNS> -<FLAGS>l</FLAGS> -GstRtpJitterBuffer *gstrtpjitterbuffer -guint arg1 -</SIGNAL> - -<SIGNAL> -<NAME>GstRtpJitterBuffer::handle-sync</NAME> -<RETURNS>void</RETURNS> -<FLAGS>l</FLAGS> -GstRtpJitterBuffer *gstrtpjitterbuffer -GstStructure *arg1 -</SIGNAL> - -<SIGNAL> -<NAME>GstRtpJitterBuffer::on-npt-stop</NAME> -<RETURNS>void</RETURNS> -<FLAGS>l</FLAGS> -GstRtpJitterBuffer *gstrtpjitterbuffer -</SIGNAL> - -<SIGNAL> -<NAME>GstRtpPtDemux::clear-pt-map</NAME> -<RETURNS>void</RETURNS> -<FLAGS>la</FLAGS> -GstRtpPtDemux *gstrtpptdemux -</SIGNAL> - -<SIGNAL> -<NAME>GstRtpPtDemux::new-payload-type</NAME> -<RETURNS>void</RETURNS> -<FLAGS>l</FLAGS> -GstRtpPtDemux *gstrtpptdemux -guint arg1 -GstPad *arg2 -</SIGNAL> - -<SIGNAL> -<NAME>GstRtpPtDemux::payload-type-change</NAME> -<RETURNS>void</RETURNS> -<FLAGS>l</FLAGS> -GstRtpPtDemux *gstrtpptdemux -guint arg1 -</SIGNAL> - -<SIGNAL> -<NAME>GstRtpPtDemux::request-pt-map</NAME> -<RETURNS>GstCaps*</RETURNS> -<FLAGS>l</FLAGS> -GstRtpPtDemux *gstrtpptdemux -guint arg1 -</SIGNAL> - -<SIGNAL> -<NAME>GstRtpSession::clear-pt-map</NAME> -<RETURNS>void</RETURNS> -<FLAGS>a</FLAGS> -GstRtpSession *gstrtpsession -</SIGNAL> - -<SIGNAL> -<NAME>GstRtpSession::on-bye-ssrc</NAME> -<RETURNS>void</RETURNS> -<FLAGS>l</FLAGS> -GstRtpSession *gstrtpsession -guint arg1 -</SIGNAL> - -<SIGNAL> -<NAME>GstRtpSession::on-bye-timeout</NAME> -<RETURNS>void</RETURNS> -<FLAGS>l</FLAGS> -GstRtpSession *gstrtpsession -guint arg1 -</SIGNAL> - -<SIGNAL> -<NAME>GstRtpSession::on-new-ssrc</NAME> -<RETURNS>void</RETURNS> -<FLAGS>l</FLAGS> -GstRtpSession *gstrtpsession -guint arg1 -</SIGNAL> - -<SIGNAL> -<NAME>GstRtpSession::on-ssrc-active</NAME> -<RETURNS>void</RETURNS> -<FLAGS>l</FLAGS> -GstRtpSession *gstrtpsession -guint arg1 -</SIGNAL> - -<SIGNAL> -<NAME>GstRtpSession::on-ssrc-collision</NAME> -<RETURNS>void</RETURNS> -<FLAGS>l</FLAGS> -GstRtpSession *gstrtpsession -guint arg1 -</SIGNAL> - -<SIGNAL> -<NAME>GstRtpSession::on-ssrc-sdes</NAME> -<RETURNS>void</RETURNS> -<FLAGS>l</FLAGS> -GstRtpSession *gstrtpsession -guint arg1 -</SIGNAL> - -<SIGNAL> -<NAME>GstRtpSession::on-ssrc-validated</NAME> -<RETURNS>void</RETURNS> -<FLAGS>l</FLAGS> -GstRtpSession *gstrtpsession -guint arg1 -</SIGNAL> - -<SIGNAL> -<NAME>GstRtpSession::on-timeout</NAME> -<RETURNS>void</RETURNS> -<FLAGS>l</FLAGS> -GstRtpSession *gstrtpsession -guint arg1 -</SIGNAL> - -<SIGNAL> -<NAME>GstRtpSession::request-pt-map</NAME> -<RETURNS>GstCaps*</RETURNS> -<FLAGS>l</FLAGS> -GstRtpSession *gstrtpsession -guint arg1 -</SIGNAL> - -<SIGNAL> -<NAME>GstRtpSession::on-sender-timeout</NAME> -<RETURNS>void</RETURNS> -<FLAGS>l</FLAGS> -GstRtpSession *gstrtpsession -guint arg1 -</SIGNAL> - -<SIGNAL> -<NAME>GstRtpSsrcDemux::new-ssrc-pad</NAME> -<RETURNS>void</RETURNS> -<FLAGS>l</FLAGS> -GstRtpSsrcDemux *gstrtpssrcdemux -guint arg1 -GstPad *arg2 -</SIGNAL> - -<SIGNAL> -<NAME>GstRtpSsrcDemux::clear-ssrc</NAME> -<RETURNS>void</RETURNS> -<FLAGS>la</FLAGS> -GstRtpSsrcDemux *gstrtpssrcdemux -guint arg1 -</SIGNAL> - -<SIGNAL> -<NAME>GstRtpSsrcDemux::removed-ssrc-pad</NAME> -<RETURNS>void</RETURNS> -<FLAGS>l</FLAGS> -GstRtpSsrcDemux *gstrtpssrcdemux -guint arg1 -GstPad *arg2 -</SIGNAL> - -<SIGNAL> <NAME>GstCDAudio::track-change</NAME> <RETURNS>void</RETURNS> <FLAGS>l</FLAGS> diff --git a/docs/plugins/inspect/plugin-gstrtpmanager.xml b/docs/plugins/inspect/plugin-gstrtpmanager.xml deleted file mode 100644 index 82e96115..00000000 --- a/docs/plugins/inspect/plugin-gstrtpmanager.xml +++ /dev/null @@ -1,190 +0,0 @@ -<plugin> - <name>gstrtpmanager</name> - <description>RTP session management plugin library</description> - <filename>../../gst/rtpmanager/.libs/libgstrtpmanager.so</filename> - <basename>libgstrtpmanager.so</basename> - <version>0.10.13.1</version> - <license>LGPL</license> - <source>gst-plugins-bad</source> - <package>GStreamer Bad Plug-ins git/prerelease</package> - <origin>http://gstreamer.freedesktop.org</origin> - <elements> - <element> - <name>gstrtpbin</name> - <longname>RTP Bin</longname> - <class>Filter/Network/RTP</class> - <description>Implement an RTP bin</description> - <author>Wim Taymans <wim.taymans@gmail.com></author> - <pads> - <caps> - <name>send_rtp_src_%d</name> - <direction>source</direction> - <presence>sometimes</presence> - <details>application/x-rtp</details> - </caps> - <caps> - <name>send_rtcp_src_%d</name> - <direction>source</direction> - <presence>request</presence> - <details>application/x-rtcp</details> - </caps> - <caps> - <name>recv_rtp_src_%d_%d_%d</name> - <direction>source</direction> - <presence>sometimes</presence> - <details>application/x-rtp</details> - </caps> - <caps> - <name>send_rtp_sink_%d</name> - <direction>sink</direction> - <presence>request</presence> - <details>application/x-rtp</details> - </caps> - <caps> - <name>recv_rtcp_sink_%d</name> - <direction>sink</direction> - <presence>request</presence> - <details>application/x-rtcp</details> - </caps> - <caps> - <name>recv_rtp_sink_%d</name> - <direction>sink</direction> - <presence>request</presence> - <details>application/x-rtp</details> - </caps> - </pads> - </element> - <element> - <name>gstrtpjitterbuffer</name> - <longname>RTP packet jitter-buffer</longname> - <class>Filter/Network/RTP</class> - <description>A buffer that deals with network jitter and other transmission faults</description> - <author>Philippe Kalaf <philippe.kalaf@collabora.co.uk>, Wim Taymans <wim.taymans@gmail.com></author> - <pads> - <caps> - <name>sink_rtcp</name> - <direction>sink</direction> - <presence>request</presence> - <details>application/x-rtcp</details> - </caps> - <caps> - <name>sink</name> - <direction>sink</direction> - <presence>always</presence> - <details>application/x-rtp, clock-rate=(int)[ 1, 2147483647 ]</details> - </caps> - <caps> - <name>src</name> - <direction>source</direction> - <presence>always</presence> - <details>application/x-rtp</details> - </caps> - </pads> - </element> - <element> - <name>gstrtpptdemux</name> - <longname>RTP Demux</longname> - <class>Demux/Network/RTP</class> - <description>Parses codec streams transmitted in the same RTP session</description> - <author>Kai Vehmanen <kai.vehmanen@nokia.com></author> - <pads> - <caps> - <name>src_%d</name> - <direction>source</direction> - <presence>sometimes</presence> - <details>application/x-rtp, payload=(int)[ 0, 255 ]</details> - </caps> - <caps> - <name>sink</name> - <direction>sink</direction> - <presence>always</presence> - <details>application/x-rtp</details> - </caps> - </pads> - </element> - <element> - <name>gstrtpsession</name> - <longname>RTP Session</longname> - <class>Filter/Network/RTP</class> - <description>Implement an RTP session</description> - <author>Wim Taymans <wim.taymans@gmail.com></author> - <pads> - <caps> - <name>send_rtcp_src</name> - <direction>source</direction> - <presence>request</presence> - <details>application/x-rtcp</details> - </caps> - <caps> - <name>send_rtp_src</name> - <direction>source</direction> - <presence>sometimes</presence> - <details>application/x-rtp</details> - </caps> - <caps> - <name>sync_src</name> - <direction>source</direction> - <presence>sometimes</presence> - <details>application/x-rtcp</details> - </caps> - <caps> - <name>recv_rtp_src</name> - <direction>source</direction> - <presence>sometimes</presence> - <details>application/x-rtp</details> - </caps> - <caps> - <name>send_rtp_sink</name> - <direction>sink</direction> - <presence>request</presence> - <details>application/x-rtp</details> - </caps> - <caps> - <name>recv_rtcp_sink</name> - <direction>sink</direction> - <presence>request</presence> - <details>application/x-rtcp</details> - </caps> - <caps> - <name>recv_rtp_sink</name> - <direction>sink</direction> - <presence>request</presence> - <details>application/x-rtp</details> - </caps> - </pads> - </element> - <element> - <name>gstrtpssrcdemux</name> - <longname>RTP SSRC Demux</longname> - <class>Demux/Network/RTP</class> - <description>Splits RTP streams based on the SSRC</description> - <author>Wim Taymans <wim.taymans@gmail.com></author> - <pads> - <caps> - <name>rtcp_src_%d</name> - <direction>source</direction> - <presence>sometimes</presence> - <details>application/x-rtcp</details> - </caps> - <caps> - <name>src_%d</name> - <direction>source</direction> - <presence>sometimes</presence> - <details>application/x-rtp</details> - </caps> - <caps> - <name>rtcp_sink</name> - <direction>sink</direction> - <presence>always</presence> - <details>application/x-rtcp</details> - </caps> - <caps> - <name>sink</name> - <direction>sink</direction> - <presence>always</presence> - <details>application/x-rtp</details> - </caps> - </pads> - </element> - </elements> -</plugin>
\ No newline at end of file diff --git a/ext/Makefile.am b/ext/Makefile.am index 31dd00a4..da5085e4 100644 --- a/ext/Makefile.am +++ b/ext/Makefile.am @@ -307,7 +307,7 @@ SOUNDTOUCH_DIR= endif if USE_SPC -SPC_DIR=gme +SPC_DIR=spc else SPC_DIR= endif diff --git a/ext/kate/gstkateenc.c b/ext/kate/gstkateenc.c index 42333509..d4e8835b 100644 --- a/ext/kate/gstkateenc.c +++ b/ext/kate/gstkateenc.c @@ -62,14 +62,18 @@ * <para> * This encodes a DVD SPU track to a Kate stream: * <programlisting> - * gst-launch dvdreadsrc ! dvddemux ! dvdsubparse ! kateenc ! oggmux ! filesink location=test.ogg + * gst-launch dvdreadsrc ! dvddemux ! dvdsubparse ! kateenc category=spu-subtitles ! oggmux ! filesink location=test.ogg * </programlisting> * </para> * </refsect2> */ -/* FIXME: should we automatically pick up the language code from the - * upstream event tags if none was set via the property? */ +/* FIXME: + * - should we automatically pick up the language code from the + * upstream event tags if none was set via the property? + * - turn category property into an enum (freestyle text property in + * combination with supposedly strictly defined known values that + * aren't even particularly human-readable is just not very nice)? */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -131,6 +135,7 @@ static void gst_kate_enc_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); static void gst_kate_enc_dispose (GObject * object); +static gboolean gst_kate_enc_setcaps (GstPad * pad, GstCaps * caps); static GstFlowReturn gst_kate_enc_chain (GstPad * pad, GstBuffer * buf); static GstStateChangeReturn gst_kate_enc_change_state (GstElement * element, GstStateChange transition); @@ -246,6 +251,8 @@ gst_kate_enc_init (GstKateEnc * ke, GstKateEncClass * gclass) GST_DEBUG_FUNCPTR (gst_kate_enc_chain)); gst_pad_set_event_function (ke->sinkpad, GST_DEBUG_FUNCPTR (gst_kate_enc_sink_event)); + gst_pad_set_setcaps_function (ke->sinkpad, + GST_DEBUG_FUNCPTR (gst_kate_enc_setcaps)); gst_element_add_pad (GST_ELEMENT (ke), ke->sinkpad); ke->srcpad = gst_pad_new_from_static_template (&src_factory, "src"); @@ -515,6 +522,47 @@ gst_kate_enc_set_metadata (GstKateEnc * ke) } static gboolean +gst_kate_enc_setcaps (GstPad * pad, GstCaps * caps) +{ + GstKateEnc *ke; + + ke = GST_KATE_ENC (GST_PAD_PARENT (pad)); + + GST_LOG_OBJECT (ke, "input caps: %" GST_PTR_FORMAT, caps); + + /* One day we could try to automatically set the category based on the + * input format, assuming that the input is subtitles. Currently that + * doesn't work yet though, because we send the header packets already from + * the sink event handler when receiving the newsegment event, so before + * the first buffer (might be tricky to change too, given that there could + * be no data at the beginning for a long time). So for now we just try to + * make sure people didn't set the category to something obviously wrong. */ + if (ke->category != NULL) { + GstStructure *s = gst_caps_get_structure (caps, 0); + + if (gst_structure_has_name (s, "text/plain") || + gst_structure_has_name (s, "text/x-pango-markup")) { + if (strcmp (ke->category, "K-SPU") == 0 || + strcmp (ke->category, "spu-subtitles") == 0) { + GST_ELEMENT_WARNING (ke, LIBRARY, SETTINGS, (NULL), + ("Category set to '%s', but input is text-based.", ke->category)); + } + } else if (gst_structure_has_name (s, "video/x-dvd-subpicture")) { + if (strcmp (ke->category, "SUB") == 0 || + strcmp (ke->category, "subtitles") == 0) { + GST_ELEMENT_WARNING (ke, LIBRARY, SETTINGS, (NULL), + ("Category set to '%s', but input is subpictures.", ke->category)); + } + } else { + GST_ERROR_OBJECT (ke, "unexpected input caps %" GST_PTR_FORMAT, caps); + return FALSE; + } + } + + return TRUE; +} + +static gboolean gst_kate_enc_is_simple_subtitle_category (GstKateEnc * ke, const char *category) { static const char *const simple[] = { @@ -541,6 +589,14 @@ gst_kate_enc_send_headers (GstKateEnc * ke) GstCaps *caps; GList *headers = NULL, *item; + if (G_UNLIKELY (ke->category == NULL || *ke->category == '\0')) { + /* The error code is a bit of a lie, but seems most appropriate. */ + GST_ELEMENT_ERROR (ke, LIBRARY, SETTINGS, (NULL), + ("The 'category' property must be set. For subtitles, set it to " + "either 'SUB' (text subtitles) or 'K-SPU' (dvd-style subtitles)")); + return GST_FLOW_ERROR; + } + gst_kate_enc_set_metadata (ke); /* encode headers and store them in a list */ diff --git a/gst-plugins-bad.spec.in b/gst-plugins-bad.spec.in index ea4a5d82..66fa5d46 100644 --- a/gst-plugins-bad.spec.in +++ b/gst-plugins-bad.spec.in @@ -70,6 +70,8 @@ rm -rf $RPM_BUILD_ROOT %files -f gst-plugins-bad-%{majorminor}.lang %defattr(-, root, root) %doc AUTHORS COPYING README REQUIREMENTS gst-plugins-bad.doap +%{_bindir}/gst-camera +%{_bindir}/gst-camera-perf # non-core plugins without external dependencies %{_libdir}/gstreamer-%{majorminor}/libgsttta.so @@ -83,7 +85,6 @@ rm -rf $RPM_BUILD_ROOT %{_libdir}/gstreamer-%{majorminor}/libgstreal.so %{_libdir}/gstreamer-%{majorminor}/libgstmve.so %{_libdir}/gstreamer-%{majorminor}/libgstmpegvideoparse.so -%{_libdir}/gstreamer-%{majorminor}/libgstrtpmanager.so %{_libdir}/gstreamer-%{majorminor}/libgstbayer.so %{_libdir}/gstreamer-%{majorminor}/libgstdvdspu.so %{_libdir}/gstreamer-%{majorminor}/libgstfestival.so @@ -126,12 +127,23 @@ rm -rf $RPM_BUILD_ROOT %{_libdir}/gstreamer-%{majorminor}/libgsthdvparse.so %{_libdir}/gstreamer-%{majorminor}/libgstshapewipe.so %{_libdir}/gstreamer-%{majorminor}/libgstdebugutilsbad.so +%{_libdir}/gstreamer-%{majorminor}/libgstasfmux.so +%{_libdir}/gstreamer-%{majorminor}/libgstofa.so +%{_includedir}/gstreamer-%{majorminor}/gst/video/gstbasevideocodec.h +%{_includedir}/gstreamer-%{majorminor}/gst/video/gstbasevideodecoder.h +%{_includedir}/gstreamer-%{majorminor}/gst/video/gstbasevideoencoder.h +%{_includedir}/gstreamer-%{majorminor}/gst/video/gstbasevideoparse.h +%{_includedir}/gstreamer-%{majorminor}/gst/video/gstbasevideoutils.h +%{_datadir}/gstreamer-%{majorminor}/camera-apps/gst-camera.glade + %{_includedir}/gstreamer-%{majorminor}/gst/interfaces/photography-enumtypes.h %{_includedir}/gstreamer-%{majorminor}/gst/interfaces/photography.h %{_libdir}/libgstphotography-0.10.so %{_libdir}/gstreamer-%{majorminor}/libgstcamerabin.so %{_libdir}/libgstphotography-%{majorminor}.so.0 %{_libdir}/libgstphotography-%{majorminor}.so.0.0.0 +%{_libdir}/libgstbasevideo* +%{_libdir}/libgstsignalprocessor* # %{_datadir}/gstreamer-%{majorminor}/presets/GstFAAC.prs # gstreamer-plugins with external dependencies but in the main package @USE_FAAD_TRUE@%{_libdir}/gstreamer-%{majorminor}/libgstfaad.so @@ -159,6 +171,9 @@ rm -rf $RPM_BUILD_ROOT @USE_MPEG2ENC_TRUE@%{_libdir}/gstreamer-%{majorminor}/libgstmpeg2enc.so @USE_MPLEX_TRUE@%{_libdir}/gstreamer-%{majorminor}/libgstmplex.so @USE_KATE_TRUE@%{_libdir}/gstreamer-%{majorminor}/libgstkate.so +@USE_ASSRENDER_TRUE@%{_libdir}/gstreamer-%{majorminor}/libgstassrender.so +@USE_PLUGIN_FREI0R_TRUE@%{_libdir}/gstreamer-%{majorminor}/libgstfrei0r.so +@USE_SCHRO_TRUE@%{_libdir}/gstreamer-%{majorminor}/libgstschro.so %changelog * Thu Mar 12 2009 Christian Schaller <chrisian.schaller at collabora dot co uk> diff --git a/gst/autoconvert/gstautoconvert.c b/gst/autoconvert/gstautoconvert.c index 43110030..39b9c784 100644 --- a/gst/autoconvert/gstautoconvert.c +++ b/gst/autoconvert/gstautoconvert.c @@ -46,13 +46,6 @@ GST_DEBUG_CATEGORY (autoconvert_debug); #define GST_CAT_DEFAULT (autoconvert_debug) /* elementfactory information */ -static const GstElementDetails gst_auto_convert_details = -GST_ELEMENT_DETAILS ("Select convertor based on caps", - "Generic/Bin", - "Selects the right transform element based on the caps", - "Olivier Crete <olivier.crete@collabora.co.uk>"); - - static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, @@ -63,7 +56,6 @@ static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_ALWAYS, GST_STATIC_CAPS_ANY); - static GstStaticPadTemplate sink_internal_template = GST_STATIC_PAD_TEMPLATE ("sink_internal", GST_PAD_SINK, @@ -86,16 +78,18 @@ enum enum { PROP_0, - PROP_FACTORIES, + PROP_FACTORIES }; - static void gst_auto_convert_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec); static void gst_auto_convert_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); static void gst_auto_convert_dispose (GObject * object); +static GstStateChangeReturn gst_auto_convert_change_state (GstElement * element, + GstStateChange transition); + static GstElement *gst_auto_convert_get_subelement (GstAutoConvert * autoconvert); static GstPad *gst_auto_convert_get_internal_sinkpad (GstAutoConvert * @@ -118,7 +112,6 @@ static gboolean gst_auto_convert_src_event (GstPad * pad, GstEvent * event); static gboolean gst_auto_convert_src_query (GstPad * pad, GstQuery * query); static const GstQueryType *gst_auto_convert_src_query_type (GstPad * pad); - static GstFlowReturn gst_auto_convert_internal_sink_chain (GstPad * pad, GstBuffer * buffer); static gboolean gst_auto_convert_internal_sink_event (GstPad * pad, @@ -140,18 +133,21 @@ static gboolean gst_auto_convert_internal_src_query (GstPad * pad, static const GstQueryType *gst_auto_convert_internal_src_query_type (GstPad * pad); - static void gst_auto_convert_load_factories (GstAutoConvert * autoconvert); -GQuark internal_srcpad_quark = 0; -GQuark internal_sinkpad_quark = 0; -GQuark parent_quark = 0; +static GQuark internal_srcpad_quark = 0; +static GQuark internal_sinkpad_quark = 0; +static GQuark parent_quark = 0; static void gst_auto_convert_do_init (GType type) { GST_DEBUG_CATEGORY_INIT (autoconvert_debug, "autoconvert", 0, "Auto convert based on caps"); + + internal_srcpad_quark = g_quark_from_static_string ("internal_srcpad"); + internal_sinkpad_quark = g_quark_from_static_string ("internal_sinkpad"); + parent_quark = g_quark_from_static_string ("parent"); } GST_BOILERPLATE_FULL (GstAutoConvert, gst_auto_convert, GstBin, @@ -167,53 +163,43 @@ gst_auto_convert_base_init (gpointer klass) gst_element_class_add_pad_template (element_class, gst_static_pad_template_get (&sinktemplate)); - gst_element_class_set_details (element_class, &gst_auto_convert_details); + gst_element_class_set_details_simple (element_class, + "Select convertor based on caps", "Generic/Bin", + "Selects the right transform element based on the caps", + "Olivier Crete <olivier.crete@collabora.co.uk>"); } static void gst_auto_convert_class_init (GstAutoConvertClass * klass) { - GObjectClass *gobject_class; - GstElementClass *gstelement_class; - GstBinClass *gstbin_class; - - gobject_class = (GObjectClass *) klass; - gstelement_class = (GstElementClass *) klass; - gstbin_class = (GstBinClass *) klass; + GObjectClass *gobject_class = (GObjectClass *) klass; + GstElementClass *gstelement_class = (GstElementClass *) klass; - gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_auto_convert_dispose); + gobject_class->dispose = gst_auto_convert_dispose; - gobject_class->set_property = - GST_DEBUG_FUNCPTR (gst_auto_convert_set_property); - gobject_class->get_property = - GST_DEBUG_FUNCPTR (gst_auto_convert_get_property); + gobject_class->set_property = gst_auto_convert_set_property; + gobject_class->get_property = gst_auto_convert_get_property; g_object_class_install_property (gobject_class, PROP_FACTORIES, g_param_spec_pointer ("factories", "GList of GstElementFactory", "GList of GstElementFactory objects to pick from (the element takes" " ownership of the list (NULL means it will go through all possible" - " elements), can only be set once", G_PARAM_READWRITE)); - - parent_class = g_type_class_peek_parent (klass); + " elements), can only be set once", + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - internal_srcpad_quark = g_quark_from_static_string ("internal_srcpad"); - internal_sinkpad_quark = g_quark_from_static_string ("internal_sinkpad"); - parent_quark = g_quark_from_static_string ("parent"); + gstelement_class->change_state = + GST_DEBUG_FUNCPTR (gst_auto_convert_change_state); } static void gst_auto_convert_init (GstAutoConvert * autoconvert, GstAutoConvertClass * klass) { - autoconvert->sinkpad = gst_pad_new_from_static_template (&sinktemplate, "sink"); autoconvert->srcpad = gst_pad_new_from_static_template (&srctemplate, "src"); - gst_element_add_pad (GST_ELEMENT (autoconvert), autoconvert->sinkpad); - gst_element_add_pad (GST_ELEMENT (autoconvert), autoconvert->srcpad); - gst_pad_set_setcaps_function (autoconvert->sinkpad, GST_DEBUG_FUNCPTR (gst_auto_convert_sink_setcaps)); gst_pad_set_getcaps_function (autoconvert->sinkpad, @@ -235,6 +221,9 @@ gst_auto_convert_init (GstAutoConvert * autoconvert, GST_DEBUG_FUNCPTR (gst_auto_convert_src_query)); gst_pad_set_query_type_function (autoconvert->srcpad, GST_DEBUG_FUNCPTR (gst_auto_convert_src_query_type)); + + gst_element_add_pad (GST_ELEMENT (autoconvert), autoconvert->sinkpad); + gst_element_add_pad (GST_ELEMENT (autoconvert), autoconvert->srcpad); } static void @@ -251,6 +240,11 @@ gst_auto_convert_dispose (GObject * object) autoconvert->current_internal_sinkpad = NULL; autoconvert->current_internal_srcpad = NULL; } + + g_list_foreach (autoconvert->cached_events, (GFunc) gst_mini_object_unref, + NULL); + g_list_free (autoconvert->cached_events); + autoconvert->cached_events = NULL; GST_OBJECT_UNLOCK (object); G_OBJECT_CLASS (parent_class)->dispose (object); @@ -297,6 +291,35 @@ gst_auto_convert_get_property (GObject * object, } } +static GstStateChangeReturn +gst_auto_convert_change_state (GstElement * element, GstStateChange transition) +{ + GstAutoConvert *autoconvert = GST_AUTO_CONVERT (element); + GstStateChangeReturn ret; + + switch (transition) { + default: + break; + } + + ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); + if (ret == GST_STATE_CHANGE_FAILURE) + return ret; + + switch (transition) { + case GST_STATE_CHANGE_PAUSED_TO_READY: + g_list_foreach (autoconvert->cached_events, (GFunc) gst_mini_object_unref, + NULL); + g_list_free (autoconvert->cached_events); + autoconvert->cached_events = NULL; + break; + default: + break; + } + + return ret; +} + static GstElement * gst_auto_convert_get_element_by_type (GstAutoConvert * autoconvert, GType type) { @@ -908,6 +931,20 @@ gst_auto_convert_sink_chain (GstPad * pad, GstBuffer * buffer) internal_srcpad = gst_auto_convert_get_internal_srcpad (autoconvert); if (internal_srcpad) { + GST_OBJECT_LOCK (autoconvert); + if (autoconvert->cached_events) { + GList *l; + + GST_DEBUG_OBJECT (autoconvert, "Sending cached events downstream"); + + autoconvert->cached_events = g_list_reverse (autoconvert->cached_events); + + for (l = autoconvert->cached_events; l; l = l->next) + gst_pad_push_event (internal_srcpad, l->data); + g_list_free (autoconvert->cached_events); + autoconvert->cached_events = NULL; + } + GST_OBJECT_UNLOCK (autoconvert); ret = gst_pad_push (internal_srcpad, buffer); gst_object_unref (internal_srcpad); } else { @@ -932,9 +969,26 @@ gst_auto_convert_sink_event (GstPad * pad, GstEvent * event) ret = gst_pad_push_event (internal_srcpad, event); gst_object_unref (internal_srcpad); } else { - GST_WARNING_OBJECT (autoconvert, "Got event while no element was selected," - "letting through"); - ret = gst_pad_push_event (autoconvert->srcpad, event); + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_FLUSH_STOP: + GST_OBJECT_LOCK (autoconvert); + g_list_foreach (autoconvert->cached_events, + (GFunc) gst_mini_object_unref, NULL); + g_list_free (autoconvert->cached_events); + autoconvert->cached_events = NULL; + GST_OBJECT_UNLOCK (autoconvert); + /* fall through */ + case GST_EVENT_FLUSH_START: + ret = gst_pad_push_event (autoconvert->srcpad, event); + break; + default: + GST_OBJECT_LOCK (autoconvert); + autoconvert->cached_events = + g_list_prepend (autoconvert->cached_events, event); + ret = TRUE; + GST_OBJECT_UNLOCK (autoconvert); + break; + } } gst_object_unref (autoconvert); @@ -961,7 +1015,7 @@ gst_auto_convert_sink_query (GstPad * pad, GstQuery * query) } else { GST_WARNING_OBJECT (autoconvert, "Got query while no element was selected," "letting through"); - ret = gst_pad_query_default (pad, query); + ret = gst_pad_peer_query (autoconvert->srcpad, query); } gst_object_unref (autoconvert); @@ -1199,7 +1253,7 @@ gst_auto_convert_src_query (GstPad * pad, GstQuery * query) } else { GST_WARNING_OBJECT (autoconvert, "Got query while not element was selected," "letting through"); - ret = gst_pad_query_default (pad, query); + ret = gst_pad_peer_query (autoconvert->sinkpad, query); } gst_object_unref (autoconvert); diff --git a/gst/autoconvert/gstautoconvert.h b/gst/autoconvert/gstautoconvert.h index 4a3c8df0..af463f4b 100644 --- a/gst/autoconvert/gstautoconvert.h +++ b/gst/autoconvert/gstautoconvert.h @@ -52,6 +52,8 @@ struct _GstAutoConvert GstElement *current_subelement; GstPad *current_internal_srcpad; GstPad *current_internal_sinkpad; + + GList *cached_events; }; struct _GstAutoConvertClass diff --git a/gst/mixmatrix/Makefile.am b/gst/mixmatrix/Makefile.am index e4f37ef9..e4f37ef9 100755..100644 --- a/gst/mixmatrix/Makefile.am +++ b/gst/mixmatrix/Makefile.am diff --git a/gst/rtpmanager/.gitignore b/gst/rtpmanager/.gitignore deleted file mode 100644 index 0962d997..00000000 --- a/gst/rtpmanager/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -gstrtpbin-marshal.h -gstrtpbin-marshal.c diff --git a/gst/rtpmanager/Makefile.am b/gst/rtpmanager/Makefile.am deleted file mode 100644 index 8080f303..00000000 --- a/gst/rtpmanager/Makefile.am +++ /dev/null @@ -1,49 +0,0 @@ -plugin_LTLIBRARIES = libgstrtpmanager.la - -glib_enum_define = GST_RTP_BIN -glib_enum_prefix = gst_rtp_bin - -include $(top_srcdir)/common/glib-gen.mak - -built_sources = gstrtpbin-marshal.c -built_headers = gstrtpbin-marshal.h - -BUILT_SOURCES = $(built_sources) $(built_headers) - -libgstrtpmanager_la_SOURCES = gstrtpmanager.c \ - gstrtpbin.c \ - gstrtpjitterbuffer.c \ - gstrtpptdemux.c \ - gstrtpssrcdemux.c \ - rtpjitterbuffer.c \ - rtpsession.c \ - rtpsource.c \ - rtpstats.c \ - gstrtpsession.c - -nodist_libgstrtpmanager_la_SOURCES = \ - $(built_sources) - -noinst_HEADERS = gstrtpbin.h \ - gstrtpjitterbuffer.h \ - gstrtpptdemux.h \ - gstrtpssrcdemux.h \ - rtpjitterbuffer.h \ - rtpsession.h \ - rtpsource.h \ - rtpstats.h \ - gstrtpsession.h - -libgstrtpmanager_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) \ - $(ERROR_CFLAGS) -libgstrtpmanager_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) \ - -lgstnetbuffer-@GST_MAJORMINOR@ -lgstrtp-@GST_MAJORMINOR@ \ - $(GST_BASE_LIBS) $(GST_LIBS_LIBS) -libgstrtpmanager_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) -libgstrtpmanager_la_LIBTOOLFLAGS = --tag=disable-static - -CLEANFILES = $(BUILT_SOURCES) - -EXTRA_DIST = gstrtpbin-marshal.list - - diff --git a/gst/rtpmanager/gstrtpbin-marshal.list b/gst/rtpmanager/gstrtpbin-marshal.list deleted file mode 100644 index ed73e43b..00000000 --- a/gst/rtpmanager/gstrtpbin-marshal.list +++ /dev/null @@ -1,8 +0,0 @@ -UINT:UINT -BOXED:UINT -BOXED:UINT,UINT -OBJECT:UINT -VOID:UINT,OBJECT -VOID:UINT -VOID:UINT,UINT -VOID:OBJECT,OBJECT diff --git a/gst/rtpmanager/gstrtpbin.c b/gst/rtpmanager/gstrtpbin.c deleted file mode 100644 index c09b0ab9..00000000 --- a/gst/rtpmanager/gstrtpbin.c +++ /dev/null @@ -1,2458 +0,0 @@ -/* GStreamer - * Copyright (C) <2007> Wim Taymans <wim.taymans@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., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/** - * SECTION:element-gstrtpbin - * @see_also: gstrtpjitterbuffer, gstrtpsession, gstrtpptdemux, gstrtpssrcdemux - * - * RTP bin combines the functions of #GstRtpSession, #GstRtpsSrcDemux, - * #GstRtpJitterBuffer and #GstRtpPtDemux in one element. It allows for multiple - * RTP sessions that will be synchronized together using RTCP SR packets. - * - * #GstRtpBin is configured with a number of request pads that define the - * functionality that is activated, similar to the #GstRtpSession element. - * - * To use #GstRtpBin as an RTP receiver, request a recv_rtp_sink_%%d pad. The session - * number must be specified in the pad name. - * Data received on the recv_rtp_sink_%%d pad will be processed in the gstrtpsession - * manager and after being validated forwarded on #GstRtpsSrcDemux element. Each - * RTP stream is demuxed based on the SSRC and send to a #GstRtpJitterBuffer. After - * the packets are released from the jitterbuffer, they will be forwarded to a - * #GstRtpsSrcDemux element. The #GstRtpsSrcDemux element will demux the packets based - * on the payload type and will create a unique pad recv_rtp_src_%%d_%%d_%%d on - * gstrtpbin with the session number, SSRC and payload type respectively as the pad - * name. - * - * To also use #GstRtpBin as an RTCP receiver, request a recv_rtcp_sink_%%d pad. The - * session number must be specified in the pad name. - * - * If you want the session manager to generate and send RTCP packets, request - * the send_rtcp_src_%%d pad with the session number in the pad name. Packet pushed - * on this pad contain SR/RR RTCP reports that should be sent to all participants - * in the session. - * - * To use #GstRtpBin as a sender, request a send_rtp_sink_%%d pad, which will - * automatically create a send_rtp_src_%%d pad. If the session number is not provided, - * the pad from the lowest available session will be returned. The session manager will modify the - * SSRC in the RTP packets to its own SSRC and wil forward the packets on the - * send_rtp_src_%%d pad after updating its internal state. - * - * The session manager needs the clock-rate of the payload types it is handling - * and will signal the #GstRtpSession::request-pt-map signal when it needs such a - * mapping. One can clear the cached values with the #GstRtpSession::clear-pt-map - * signal. - * - * <refsect2> - * <title>Example pipelines</title> - * |[ - * gst-launch udpsrc port=5000 caps="application/x-rtp, ..." ! .recv_rtp_sink_0 \ - * gstrtpbin ! rtptheoradepay ! theoradec ! xvimagesink - * ]| Receive RTP data from port 5000 and send to the session 0 in gstrtpbin. - * |[ - * gst-launch gstrtpbin name=rtpbin \ - * v4l2src ! ffmpegcolorspace ! ffenc_h263 ! rtph263ppay ! rtpbin.send_rtp_sink_0 \ - * rtpbin.send_rtp_src_0 ! udpsink port=5000 \ - * rtpbin.send_rtcp_src_0 ! udpsink port=5001 sync=false async=false \ - * udpsrc port=5005 ! rtpbin.recv_rtcp_sink_0 \ - * audiotestsrc ! amrnbenc ! rtpamrpay ! rtpbin.send_rtp_sink_1 \ - * rtpbin.send_rtp_src_1 ! udpsink port=5002 \ - * rtpbin.send_rtcp_src_1 ! udpsink port=5003 sync=false async=false \ - * udpsrc port=5007 ! rtpbin.recv_rtcp_sink_1 - * ]| Encode and payload H263 video captured from a v4l2src. Encode and payload AMR - * audio generated from audiotestsrc. The video is sent to session 0 in rtpbin - * and the audio is sent to session 1. Video packets are sent on UDP port 5000 - * and audio packets on port 5002. The video RTCP packets for session 0 are sent - * on port 5001 and the audio RTCP packets for session 0 are sent on port 5003. - * RTCP packets for session 0 are received on port 5005 and RTCP for session 1 - * is received on port 5007. Since RTCP packets from the sender should be sent - * as soon as possible and do not participate in preroll, sync=false and - * async=false is configured on udpsink - * |[ - * gst-launch -v gstrtpbin name=rtpbin \ - * udpsrc caps="application/x-rtp,media=(string)video,clock-rate=(int)90000,encoding-name=(string)H263-1998" \ - * port=5000 ! rtpbin.recv_rtp_sink_0 \ - * rtpbin. ! rtph263pdepay ! ffdec_h263 ! xvimagesink \ - * udpsrc port=5001 ! rtpbin.recv_rtcp_sink_0 \ - * rtpbin.send_rtcp_src_0 ! udpsink port=5005 sync=false async=false \ - * udpsrc caps="application/x-rtp,media=(string)audio,clock-rate=(int)8000,encoding-name=(string)AMR,encoding-params=(string)1,octet-align=(string)1" \ - * port=5002 ! rtpbin.recv_rtp_sink_1 \ - * rtpbin. ! rtpamrdepay ! amrnbdec ! alsasink \ - * udpsrc port=5003 ! rtpbin.recv_rtcp_sink_1 \ - * rtpbin.send_rtcp_src_1 ! udpsink port=5007 sync=false async=false - * ]| Receive H263 on port 5000, send it through rtpbin in session 0, depayload, - * decode and display the video. - * Receive AMR on port 5002, send it through rtpbin in session 1, depayload, - * decode and play the audio. - * Receive server RTCP packets for session 0 on port 5001 and RTCP packets for - * session 1 on port 5003. These packets will be used for session management and - * synchronisation. - * Send RTCP reports for session 0 on port 5005 and RTCP reports for session 1 - * on port 5007. - * </refsect2> - * - * Last reviewed on 2007-08-30 (0.10.6) - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif -#include <string.h> - -#include <gst/rtp/gstrtpbuffer.h> -#include <gst/rtp/gstrtcpbuffer.h> - -#include "gstrtpbin-marshal.h" -#include "gstrtpbin.h" -#include "rtpsession.h" -#include "gstrtpsession.h" -#include "gstrtpjitterbuffer.h" - -GST_DEBUG_CATEGORY_STATIC (gst_rtp_bin_debug); -#define GST_CAT_DEFAULT gst_rtp_bin_debug - -/* elementfactory information */ -static const GstElementDetails rtpbin_details = GST_ELEMENT_DETAILS ("RTP Bin", - "Filter/Network/RTP", - "Implement an RTP bin", - "Wim Taymans <wim.taymans@gmail.com>"); - -/* sink pads */ -static GstStaticPadTemplate rtpbin_recv_rtp_sink_template = -GST_STATIC_PAD_TEMPLATE ("recv_rtp_sink_%d", - GST_PAD_SINK, - GST_PAD_REQUEST, - GST_STATIC_CAPS ("application/x-rtp") - ); - -static GstStaticPadTemplate rtpbin_recv_rtcp_sink_template = -GST_STATIC_PAD_TEMPLATE ("recv_rtcp_sink_%d", - GST_PAD_SINK, - GST_PAD_REQUEST, - GST_STATIC_CAPS ("application/x-rtcp") - ); - -static GstStaticPadTemplate rtpbin_send_rtp_sink_template = -GST_STATIC_PAD_TEMPLATE ("send_rtp_sink_%d", - GST_PAD_SINK, - GST_PAD_REQUEST, - GST_STATIC_CAPS ("application/x-rtp") - ); - -/* src pads */ -static GstStaticPadTemplate rtpbin_recv_rtp_src_template = -GST_STATIC_PAD_TEMPLATE ("recv_rtp_src_%d_%d_%d", - GST_PAD_SRC, - GST_PAD_SOMETIMES, - GST_STATIC_CAPS ("application/x-rtp") - ); - -static GstStaticPadTemplate rtpbin_send_rtcp_src_template = -GST_STATIC_PAD_TEMPLATE ("send_rtcp_src_%d", - GST_PAD_SRC, - GST_PAD_REQUEST, - GST_STATIC_CAPS ("application/x-rtcp") - ); - -static GstStaticPadTemplate rtpbin_send_rtp_src_template = -GST_STATIC_PAD_TEMPLATE ("send_rtp_src_%d", - GST_PAD_SRC, - GST_PAD_SOMETIMES, - GST_STATIC_CAPS ("application/x-rtp") - ); - -#define GST_RTP_BIN_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_RTP_BIN, GstRtpBinPrivate)) - -#define GST_RTP_BIN_LOCK(bin) g_mutex_lock ((bin)->priv->bin_lock) -#define GST_RTP_BIN_UNLOCK(bin) g_mutex_unlock ((bin)->priv->bin_lock) - -/* lock to protect dynamic callbacks, like pad-added and new ssrc. */ -#define GST_RTP_BIN_DYN_LOCK(bin) g_mutex_lock ((bin)->priv->dyn_lock) -#define GST_RTP_BIN_DYN_UNLOCK(bin) g_mutex_unlock ((bin)->priv->dyn_lock) - -/* lock for shutdown */ -#define GST_RTP_BIN_SHUTDOWN_LOCK(bin,label) \ -G_STMT_START { \ - if (g_atomic_int_get (&bin->priv->shutdown)) \ - goto label; \ - GST_RTP_BIN_DYN_LOCK (bin); \ - if (g_atomic_int_get (&bin->priv->shutdown)) { \ - GST_RTP_BIN_DYN_UNLOCK (bin); \ - goto label; \ - } \ -} G_STMT_END - -/* unlock for shutdown */ -#define GST_RTP_BIN_SHUTDOWN_UNLOCK(bin) \ - GST_RTP_BIN_DYN_UNLOCK (bin); \ - -struct _GstRtpBinPrivate -{ - GMutex *bin_lock; - - /* lock protecting dynamic adding/removing */ - GMutex *dyn_lock; - - /* the time when we went to playing */ - GstClockTime ntp_ns_base; - - /* if we are shutting down or not */ - gint shutdown; -}; - -/* signals and args */ -enum -{ - SIGNAL_REQUEST_PT_MAP, - SIGNAL_CLEAR_PT_MAP, - SIGNAL_RESET_SYNC, - SIGNAL_GET_INTERNAL_SESSION, - - SIGNAL_ON_NEW_SSRC, - SIGNAL_ON_SSRC_COLLISION, - SIGNAL_ON_SSRC_VALIDATED, - SIGNAL_ON_SSRC_ACTIVE, - SIGNAL_ON_SSRC_SDES, - SIGNAL_ON_BYE_SSRC, - SIGNAL_ON_BYE_TIMEOUT, - SIGNAL_ON_TIMEOUT, - SIGNAL_ON_SENDER_TIMEOUT, - SIGNAL_ON_NPT_STOP, - LAST_SIGNAL -}; - -#define DEFAULT_LATENCY_MS 200 -#define DEFAULT_SDES NULL -#define DEFAULT_DO_LOST FALSE - -enum -{ - PROP_0, - PROP_LATENCY, - PROP_SDES, - PROP_DO_LOST, - PROP_LAST -}; - -/* helper objects */ -typedef struct _GstRtpBinSession GstRtpBinSession; -typedef struct _GstRtpBinStream GstRtpBinStream; -typedef struct _GstRtpBinClient GstRtpBinClient; - -static guint gst_rtp_bin_signals[LAST_SIGNAL] = { 0 }; - -static GstCaps *pt_map_requested (GstElement * element, guint pt, - GstRtpBinSession * session); -static void free_stream (GstRtpBinStream * stream); - -/* Manages the RTP stream for one SSRC. - * - * We pipe the stream (comming from the SSRC demuxer) into a jitterbuffer. - * If we see an SDES RTCP packet that links multiple SSRCs together based on a - * common CNAME, we create a GstRtpBinClient structure to group the SSRCs - * together (see below). - */ -struct _GstRtpBinStream -{ - /* the SSRC of this stream */ - guint32 ssrc; - - /* parent bin */ - GstRtpBin *bin; - - /* the session this SSRC belongs to */ - GstRtpBinSession *session; - - /* the jitterbuffer of the SSRC */ - GstElement *buffer; - gulong buffer_handlesync_sig; - gulong buffer_ptreq_sig; - gulong buffer_ntpstop_sig; - - /* the PT demuxer of the SSRC */ - GstElement *demux; - gulong demux_newpad_sig; - gulong demux_padremoved_sig; - gulong demux_ptreq_sig; - gulong demux_pt_change_sig; - - /* if we have calculated a valid unix_delta for this stream */ - gboolean have_sync; - /* mapping to local RTP and NTP time */ - gint64 unix_delta; -}; - -#define GST_RTP_SESSION_LOCK(sess) g_mutex_lock ((sess)->lock) -#define GST_RTP_SESSION_UNLOCK(sess) g_mutex_unlock ((sess)->lock) - -/* Manages the receiving end of the packets. - * - * There is one such structure for each RTP session (audio/video/...). - * We get the RTP/RTCP packets and stuff them into the session manager. From - * there they are pushed into an SSRC demuxer that splits the stream based on - * SSRC. Each of the SSRC streams go into their own jitterbuffer (managed with - * the GstRtpBinStream above). - */ -struct _GstRtpBinSession -{ - /* session id */ - gint id; - /* the parent bin */ - GstRtpBin *bin; - /* the session element */ - GstElement *session; - /* the SSRC demuxer */ - GstElement *demux; - gulong demux_newpad_sig; - gulong demux_padremoved_sig; - - GMutex *lock; - - /* list of GstRtpBinStream */ - GSList *streams; - - /* mapping of payload type to caps */ - GHashTable *ptmap; - - /* the pads of the session */ - GstPad *recv_rtp_sink; - GstPad *recv_rtp_sink_ghost; - GstPad *recv_rtp_src; - GstPad *recv_rtcp_sink; - GstPad *recv_rtcp_sink_ghost; - GstPad *sync_src; - GstPad *send_rtp_sink; - GstPad *send_rtp_sink_ghost; - GstPad *send_rtp_src; - GstPad *send_rtp_src_ghost; - GstPad *send_rtcp_src; - GstPad *send_rtcp_src_ghost; -}; - -/* Manages the RTP streams that come from one client and should therefore be - * synchronized. - */ -struct _GstRtpBinClient -{ - /* the common CNAME for the streams */ - gchar *cname; - guint cname_len; - - /* the streams */ - guint nstreams; - GSList *streams; -}; - -/* find a session with the given id. Must be called with RTP_BIN_LOCK */ -static GstRtpBinSession * -find_session_by_id (GstRtpBin * rtpbin, gint id) -{ - GSList *walk; - - for (walk = rtpbin->sessions; walk; walk = g_slist_next (walk)) { - GstRtpBinSession *sess = (GstRtpBinSession *) walk->data; - - if (sess->id == id) - return sess; - } - return NULL; -} - -/* find a session with the given request pad. Must be called with RTP_BIN_LOCK */ -static GstRtpBinSession * -find_session_by_pad (GstRtpBin * rtpbin, GstPad * pad) -{ - GSList *walk; - - for (walk = rtpbin->sessions; walk; walk = g_slist_next (walk)) { - GstRtpBinSession *sess = (GstRtpBinSession *) walk->data; - - if ((sess->recv_rtp_sink_ghost == pad) || - (sess->recv_rtcp_sink_ghost == pad) || - (sess->send_rtp_sink_ghost == pad) - || (sess->send_rtcp_src_ghost == pad)) - return sess; - } - return NULL; -} - -static void -on_new_ssrc (GstElement * session, guint32 ssrc, GstRtpBinSession * sess) -{ - g_signal_emit (sess->bin, gst_rtp_bin_signals[SIGNAL_ON_NEW_SSRC], 0, - sess->id, ssrc); -} - -static void -on_ssrc_collision (GstElement * session, guint32 ssrc, GstRtpBinSession * sess) -{ - g_signal_emit (sess->bin, gst_rtp_bin_signals[SIGNAL_ON_SSRC_COLLISION], 0, - sess->id, ssrc); -} - -static void -on_ssrc_validated (GstElement * session, guint32 ssrc, GstRtpBinSession * sess) -{ - g_signal_emit (sess->bin, gst_rtp_bin_signals[SIGNAL_ON_SSRC_VALIDATED], 0, - sess->id, ssrc); -} - -static void -on_ssrc_active (GstElement * session, guint32 ssrc, GstRtpBinSession * sess) -{ - g_signal_emit (sess->bin, gst_rtp_bin_signals[SIGNAL_ON_SSRC_ACTIVE], 0, - sess->id, ssrc); -} - -static void -on_ssrc_sdes (GstElement * session, guint32 ssrc, GstRtpBinSession * sess) -{ - g_signal_emit (sess->bin, gst_rtp_bin_signals[SIGNAL_ON_SSRC_SDES], 0, - sess->id, ssrc); -} - -static void -on_bye_ssrc (GstElement * session, guint32 ssrc, GstRtpBinSession * sess) -{ - g_signal_emit (sess->bin, gst_rtp_bin_signals[SIGNAL_ON_BYE_SSRC], 0, - sess->id, ssrc); -} - -static void -on_bye_timeout (GstElement * session, guint32 ssrc, GstRtpBinSession * sess) -{ - g_signal_emit (sess->bin, gst_rtp_bin_signals[SIGNAL_ON_BYE_TIMEOUT], 0, - sess->id, ssrc); -} - -static void -on_timeout (GstElement * session, guint32 ssrc, GstRtpBinSession * sess) -{ - g_signal_emit (sess->bin, gst_rtp_bin_signals[SIGNAL_ON_TIMEOUT], 0, - sess->id, ssrc); -} - -static void -on_sender_timeout (GstElement * session, guint32 ssrc, GstRtpBinSession * sess) -{ - g_signal_emit (sess->bin, gst_rtp_bin_signals[SIGNAL_ON_SENDER_TIMEOUT], 0, - sess->id, ssrc); -} - -static void -on_npt_stop (GstElement * jbuf, GstRtpBinStream * stream) -{ - g_signal_emit (stream->bin, gst_rtp_bin_signals[SIGNAL_ON_NPT_STOP], 0, - stream->session->id, stream->ssrc); -} - -/* must be called with the SESSION lock */ -static GstRtpBinStream * -find_stream_by_ssrc (GstRtpBinSession * session, guint32 ssrc) -{ - GSList *walk; - - for (walk = session->streams; walk; walk = g_slist_next (walk)) { - GstRtpBinStream *stream = (GstRtpBinStream *) walk->data; - - if (stream->ssrc == ssrc) - return stream; - } - return NULL; -} - -static void -ssrc_demux_pad_removed (GstElement * element, guint ssrc, GstPad * pad, - GstRtpBinSession * session) -{ - GstRtpBinStream *stream = NULL; - - GST_RTP_SESSION_LOCK (session); - if ((stream = find_stream_by_ssrc (session, ssrc))) - session->streams = g_slist_remove (session->streams, stream); - GST_RTP_SESSION_UNLOCK (session); - - if (stream) - free_stream (stream); -} - -/* create a session with the given id. Must be called with RTP_BIN_LOCK */ -static GstRtpBinSession * -create_session (GstRtpBin * rtpbin, gint id) -{ - GstRtpBinSession *sess; - GstElement *session, *demux; - GstState target; - - if (!(session = gst_element_factory_make ("gstrtpsession", NULL))) - goto no_session; - - if (!(demux = gst_element_factory_make ("gstrtpssrcdemux", NULL))) - goto no_demux; - - sess = g_new0 (GstRtpBinSession, 1); - sess->lock = g_mutex_new (); - sess->id = id; - sess->bin = rtpbin; - sess->session = session; - sess->demux = demux; - sess->ptmap = g_hash_table_new_full (NULL, NULL, NULL, - (GDestroyNotify) gst_caps_unref); - rtpbin->sessions = g_slist_prepend (rtpbin->sessions, sess); - - /* set NTP base or new session */ - g_object_set (session, "ntp-ns-base", rtpbin->priv->ntp_ns_base, NULL); - /* configure SDES items */ - GST_OBJECT_LOCK (rtpbin); - g_object_set (session, "sdes", rtpbin->sdes, NULL); - GST_OBJECT_UNLOCK (rtpbin); - - /* provide clock_rate to the session manager when needed */ - g_signal_connect (session, "request-pt-map", - (GCallback) pt_map_requested, sess); - - g_signal_connect (sess->session, "on-new-ssrc", - (GCallback) on_new_ssrc, sess); - g_signal_connect (sess->session, "on-ssrc-collision", - (GCallback) on_ssrc_collision, sess); - g_signal_connect (sess->session, "on-ssrc-validated", - (GCallback) on_ssrc_validated, sess); - g_signal_connect (sess->session, "on-ssrc-active", - (GCallback) on_ssrc_active, sess); - g_signal_connect (sess->session, "on-ssrc-sdes", - (GCallback) on_ssrc_sdes, sess); - g_signal_connect (sess->session, "on-bye-ssrc", - (GCallback) on_bye_ssrc, sess); - g_signal_connect (sess->session, "on-bye-timeout", - (GCallback) on_bye_timeout, sess); - g_signal_connect (sess->session, "on-timeout", (GCallback) on_timeout, sess); - g_signal_connect (sess->session, "on-sender-timeout", - (GCallback) on_sender_timeout, sess); - - gst_bin_add (GST_BIN_CAST (rtpbin), session); - gst_bin_add (GST_BIN_CAST (rtpbin), demux); - - GST_OBJECT_LOCK (rtpbin); - target = GST_STATE_TARGET (rtpbin); - GST_OBJECT_UNLOCK (rtpbin); - - /* change state only to what's needed */ - gst_element_set_state (demux, target); - gst_element_set_state (session, target); - - return sess; - - /* ERRORS */ -no_session: - { - g_warning ("gstrtpbin: could not create gstrtpsession element"); - return NULL; - } -no_demux: - { - gst_object_unref (session); - g_warning ("gstrtpbin: could not create gstrtpssrcdemux element"); - return NULL; - } -} - -static void -free_session (GstRtpBinSession * sess, GstRtpBin * bin) -{ - GST_DEBUG_OBJECT (bin, "freeing session %p", sess); - - gst_element_set_state (sess->demux, GST_STATE_NULL); - gst_element_set_state (sess->session, GST_STATE_NULL); - - if (sess->recv_rtp_sink != NULL) { - gst_element_release_request_pad (sess->session, sess->recv_rtp_sink); - gst_object_unref (sess->recv_rtp_sink); - } - if (sess->recv_rtp_src != NULL) - gst_object_unref (sess->recv_rtp_src); - if (sess->recv_rtcp_sink != NULL) { - gst_element_release_request_pad (sess->session, sess->recv_rtcp_sink); - gst_object_unref (sess->recv_rtcp_sink); - } - if (sess->sync_src != NULL) - gst_object_unref (sess->sync_src); - if (sess->send_rtp_sink != NULL) { - gst_element_release_request_pad (sess->session, sess->send_rtp_sink); - gst_object_unref (sess->send_rtp_sink); - } - if (sess->send_rtp_src != NULL) - gst_object_unref (sess->send_rtp_src); - if (sess->send_rtcp_src != NULL) { - gst_element_release_request_pad (sess->session, sess->send_rtcp_src); - gst_object_unref (sess->send_rtcp_src); - } - - gst_bin_remove (GST_BIN_CAST (bin), sess->session); - gst_bin_remove (GST_BIN_CAST (bin), sess->demux); - - g_slist_foreach (sess->streams, (GFunc) free_stream, NULL); - g_slist_free (sess->streams); - - g_mutex_free (sess->lock); - g_hash_table_destroy (sess->ptmap); - - g_free (sess); -} - -/* get the payload type caps for the specific payload @pt in @session */ -static GstCaps * -get_pt_map (GstRtpBinSession * session, guint pt) -{ - GstCaps *caps = NULL; - GstRtpBin *bin; - GValue ret = { 0 }; - GValue args[3] = { {0}, {0}, {0} }; - - GST_DEBUG ("searching pt %d in cache", pt); - - GST_RTP_SESSION_LOCK (session); - - /* first look in the cache */ - caps = g_hash_table_lookup (session->ptmap, GINT_TO_POINTER (pt)); - if (caps) { - gst_caps_ref (caps); - goto done; - } - - bin = session->bin; - - GST_DEBUG ("emiting signal for pt %d in session %d", pt, session->id); - - /* not in cache, send signal to request caps */ - g_value_init (&args[0], GST_TYPE_ELEMENT); - g_value_set_object (&args[0], bin); - g_value_init (&args[1], G_TYPE_UINT); - g_value_set_uint (&args[1], session->id); - g_value_init (&args[2], G_TYPE_UINT); - g_value_set_uint (&args[2], pt); - - g_value_init (&ret, GST_TYPE_CAPS); - g_value_set_boxed (&ret, NULL); - - GST_RTP_SESSION_UNLOCK (session); - - g_signal_emitv (args, gst_rtp_bin_signals[SIGNAL_REQUEST_PT_MAP], 0, &ret); - - GST_RTP_SESSION_LOCK (session); - - g_value_unset (&args[0]); - g_value_unset (&args[1]); - g_value_unset (&args[2]); - - /* look in the cache again because we let the lock go */ - caps = g_hash_table_lookup (session->ptmap, GINT_TO_POINTER (pt)); - if (caps) { - gst_caps_ref (caps); - g_value_unset (&ret); - goto done; - } - - caps = (GstCaps *) g_value_dup_boxed (&ret); - g_value_unset (&ret); - if (!caps) - goto no_caps; - - GST_DEBUG ("caching pt %d as %" GST_PTR_FORMAT, pt, caps); - - /* store in cache, take additional ref */ - g_hash_table_insert (session->ptmap, GINT_TO_POINTER (pt), - gst_caps_ref (caps)); - -done: - GST_RTP_SESSION_UNLOCK (session); - - return caps; - - /* ERRORS */ -no_caps: - { - GST_RTP_SESSION_UNLOCK (session); - GST_DEBUG ("no pt map could be obtained"); - return NULL; - } -} - -static gboolean -return_true (gpointer key, gpointer value, gpointer user_data) -{ - return TRUE; -} - -static void -gst_rtp_bin_reset_sync (GstRtpBin * rtpbin) -{ - GSList *clients, *streams; - - GST_DEBUG_OBJECT (rtpbin, "Reset sync on all clients"); - - GST_RTP_BIN_LOCK (rtpbin); - for (clients = rtpbin->clients; clients; clients = g_slist_next (clients)) { - GstRtpBinClient *client = (GstRtpBinClient *) clients->data; - - /* reset sync on all streams for this client */ - for (streams = client->streams; streams; streams = g_slist_next (streams)) { - GstRtpBinStream *stream = (GstRtpBinStream *) streams->data; - - /* make use require a new SR packet for this stream before we attempt new - * lip-sync */ - stream->have_sync = FALSE; - stream->unix_delta = 0; - } - } - GST_RTP_BIN_UNLOCK (rtpbin); -} - -static void -gst_rtp_bin_clear_pt_map (GstRtpBin * bin) -{ - GSList *sessions, *streams; - - GST_RTP_BIN_LOCK (bin); - GST_DEBUG_OBJECT (bin, "clearing pt map"); - for (sessions = bin->sessions; sessions; sessions = g_slist_next (sessions)) { - GstRtpBinSession *session = (GstRtpBinSession *) sessions->data; - - GST_DEBUG_OBJECT (bin, "clearing session %p", session); - g_signal_emit_by_name (session->session, "clear-pt-map", NULL); - - GST_RTP_SESSION_LOCK (session); - g_hash_table_foreach_remove (session->ptmap, return_true, NULL); - - for (streams = session->streams; streams; streams = g_slist_next (streams)) { - GstRtpBinStream *stream = (GstRtpBinStream *) streams->data; - - GST_DEBUG_OBJECT (bin, "clearing stream %p", stream); - g_signal_emit_by_name (stream->buffer, "clear-pt-map", NULL); - g_signal_emit_by_name (stream->demux, "clear-pt-map", NULL); - } - GST_RTP_SESSION_UNLOCK (session); - } - GST_RTP_BIN_UNLOCK (bin); - - /* reset sync too */ - gst_rtp_bin_reset_sync (bin); -} - -static RTPSession * -gst_rtp_bin_get_internal_session (GstRtpBin * bin, guint session_id) -{ - RTPSession *internal_session = NULL; - GstRtpBinSession *session; - - GST_RTP_BIN_LOCK (bin); - GST_DEBUG_OBJECT (bin, "retrieving internal RTPSession object, index: %d", - session_id); - session = find_session_by_id (bin, (gint) session_id); - if (session) { - g_object_get (session->session, "internal-session", &internal_session, - NULL); - } - GST_RTP_BIN_UNLOCK (bin); - - return internal_session; -} - -static void -gst_rtp_bin_propagate_property_to_jitterbuffer (GstRtpBin * bin, - const gchar * name, const GValue * value) -{ - GSList *sessions, *streams; - - GST_RTP_BIN_LOCK (bin); - for (sessions = bin->sessions; sessions; sessions = g_slist_next (sessions)) { - GstRtpBinSession *session = (GstRtpBinSession *) sessions->data; - - GST_RTP_SESSION_LOCK (session); - for (streams = session->streams; streams; streams = g_slist_next (streams)) { - GstRtpBinStream *stream = (GstRtpBinStream *) streams->data; - - g_object_set_property (G_OBJECT (stream->buffer), name, value); - } - GST_RTP_SESSION_UNLOCK (session); - } - GST_RTP_BIN_UNLOCK (bin); -} - -/* get a client with the given SDES name. Must be called with RTP_BIN_LOCK */ -static GstRtpBinClient * -get_client (GstRtpBin * bin, guint8 len, guint8 * data, gboolean * created) -{ - GstRtpBinClient *result = NULL; - GSList *walk; - - for (walk = bin->clients; walk; walk = g_slist_next (walk)) { - GstRtpBinClient *client = (GstRtpBinClient *) walk->data; - - if (len != client->cname_len) - continue; - - if (!strncmp ((gchar *) data, client->cname, client->cname_len)) { - GST_DEBUG_OBJECT (bin, "found existing client %p with CNAME %s", client, - client->cname); - result = client; - break; - } - } - - /* nothing found, create one */ - if (result == NULL) { - result = g_new0 (GstRtpBinClient, 1); - result->cname = g_strndup ((gchar *) data, len); - result->cname_len = len; - bin->clients = g_slist_prepend (bin->clients, result); - GST_DEBUG_OBJECT (bin, "created new client %p with CNAME %s", result, - result->cname); - } - return result; -} - -static void -free_client (GstRtpBinClient * client, GstRtpBin * bin) -{ - GST_DEBUG_OBJECT (bin, "freeing client %p", client); - g_slist_free (client->streams); - g_free (client->cname); - g_free (client); -} - -/* associate a stream to the given CNAME. This will make sure all streams for - * that CNAME are synchronized together. - * Must be called with GST_RTP_BIN_LOCK */ -static void -gst_rtp_bin_associate (GstRtpBin * bin, GstRtpBinStream * stream, guint8 len, - guint8 * data, guint64 last_unix, guint64 last_extrtptime, - guint64 clock_base, guint64 clock_base_time, guint clock_rate) -{ - GstRtpBinClient *client; - gboolean created; - GSList *walk; - guint64 local_unix; - guint64 local_rtp; - - /* first find or create the CNAME */ - client = get_client (bin, len, data, &created); - - /* find stream in the client */ - for (walk = client->streams; walk; walk = g_slist_next (walk)) { - GstRtpBinStream *ostream = (GstRtpBinStream *) walk->data; - - if (ostream == stream) - break; - } - /* not found, add it to the list */ - if (walk == NULL) { - GST_DEBUG_OBJECT (bin, - "new association of SSRC %08x with client %p with CNAME %s", - stream->ssrc, client, client->cname); - client->streams = g_slist_prepend (client->streams, stream); - client->nstreams++; - } else { - GST_DEBUG_OBJECT (bin, - "found association of SSRC %08x with client %p with CNAME %s", - stream->ssrc, client, client->cname); - } - - /* take the extended rtptime we found in the SR packet and map it to the - * local rtptime. The local rtp time is used to construct timestamps on the - * buffers. */ - local_rtp = last_extrtptime - clock_base; - - GST_DEBUG_OBJECT (bin, - "base %" G_GUINT64_FORMAT ", extrtptime %" G_GUINT64_FORMAT - ", local RTP %" G_GUINT64_FORMAT ", clock-rate %d", clock_base, - last_extrtptime, local_rtp, clock_rate); - - /* calculate local NTP time in gstreamer timestamp, we essentially perform the - * same conversion that a jitterbuffer would use to convert an rtp timestamp - * into a corresponding gstreamer timestamp. */ - local_unix = gst_util_uint64_scale_int (local_rtp, GST_SECOND, clock_rate); - local_unix += clock_base_time; - - /* calculate delta between server and receiver. last_unix is created by - * converting the ntptime in the last SR packet to a gstreamer timestamp. This - * delta expresses the difference to our timeline and the server timeline. */ - stream->unix_delta = last_unix - local_unix; - stream->have_sync = TRUE; - - GST_DEBUG_OBJECT (bin, - "local UNIX %" G_GUINT64_FORMAT ", remote UNIX %" G_GUINT64_FORMAT - ", delta %" G_GINT64_FORMAT, local_unix, last_unix, stream->unix_delta); - - /* recalc inter stream playout offset, but only if there is more than one - * stream. */ - if (client->nstreams > 1) { - gint64 min; - - /* calculate the min of all deltas, ignoring streams that did not yet have a - * valid unix_delta because we did not yet receive an SR packet for those - * streams. - * We calculate the mininum because we would like to only apply positive - * offsets to streams, delaying their playback instead of trying to speed up - * other streams (which might be imposible when we have to create negative - * latencies). - * The stream that has the smallest diff is selected as the reference stream, - * all other streams will have a positive offset to this difference. */ - min = G_MAXINT64; - for (walk = client->streams; walk; walk = g_slist_next (walk)) { - GstRtpBinStream *ostream = (GstRtpBinStream *) walk->data; - - if (!ostream->have_sync) - continue; - - if (ostream->unix_delta < min) - min = ostream->unix_delta; - } - - GST_DEBUG_OBJECT (bin, "client %p min delta %" G_GINT64_FORMAT, client, - min); - - /* calculate offsets for each stream */ - for (walk = client->streams; walk; walk = g_slist_next (walk)) { - GstRtpBinStream *ostream = (GstRtpBinStream *) walk->data; - gint64 ts_offset, prev_ts_offset; - - /* ignore streams for which we didn't receive an SR packet yet, we - * can't synchronize them yet. We can however sync other streams just - * fine. */ - if (!ostream->have_sync) - continue; - - /* calculate offset to our reference stream, this should always give a - * positive number. */ - ts_offset = ostream->unix_delta - min; - - g_object_get (ostream->buffer, "ts-offset", &prev_ts_offset, NULL); - - /* delta changed, see how much */ - if (prev_ts_offset != ts_offset) { - gint64 diff; - - if (prev_ts_offset > ts_offset) - diff = prev_ts_offset - ts_offset; - else - diff = ts_offset - prev_ts_offset; - - GST_DEBUG_OBJECT (bin, - "ts-offset %" G_GUINT64_FORMAT ", prev %" G_GUINT64_FORMAT - ", diff: %" G_GINT64_FORMAT, ts_offset, prev_ts_offset, diff); - - /* only change diff when it changed more than 4 milliseconds. This - * compensates for rounding errors in NTP to RTP timestamp - * conversions */ - if (diff > 4 * GST_MSECOND && diff < (3 * GST_SECOND)) { - g_object_set (ostream->buffer, "ts-offset", ts_offset, NULL); - } - } - GST_DEBUG_OBJECT (bin, "stream SSRC %08x, delta %" G_GINT64_FORMAT, - ostream->ssrc, ts_offset); - } - } - return; -} - -#define GST_RTCP_BUFFER_FOR_PACKETS(b,buffer,packet) \ - for ((b) = gst_rtcp_buffer_get_first_packet ((buffer), (packet)); (b); \ - (b) = gst_rtcp_packet_move_to_next ((packet))) - -#define GST_RTCP_SDES_FOR_ITEMS(b,packet) \ - for ((b) = gst_rtcp_packet_sdes_first_item ((packet)); (b); \ - (b) = gst_rtcp_packet_sdes_next_item ((packet))) - -#define GST_RTCP_SDES_FOR_ENTRIES(b,packet) \ - for ((b) = gst_rtcp_packet_sdes_first_entry ((packet)); (b); \ - (b) = gst_rtcp_packet_sdes_next_entry ((packet))) - -static void -gst_rtp_bin_handle_sync (GstElement * jitterbuffer, GstStructure * s, - GstRtpBinStream * stream) -{ - GstRtpBin *bin; - GstRTCPPacket packet; - guint32 ssrc; - guint64 ntptime; - gboolean have_sr, have_sdes; - gboolean more; - guint64 clock_base; - guint64 clock_base_time; - guint clock_rate; - guint64 extrtptime; - GstBuffer *buffer; - - bin = stream->bin; - - GST_DEBUG_OBJECT (bin, "sync handler called"); - - /* get the last relation between the rtp timestamps and the gstreamer - * timestamps. We get this info directly from the jitterbuffer which - * constructs gstreamer timestamps from rtp timestamps and so it know exactly - * what the current situation is. */ - clock_base = g_value_get_uint64 (gst_structure_get_value (s, "base-rtptime")); - clock_base_time = - g_value_get_uint64 (gst_structure_get_value (s, "base-time")); - clock_rate = g_value_get_uint (gst_structure_get_value (s, "clock-rate")); - extrtptime = - g_value_get_uint64 (gst_structure_get_value (s, "sr-ext-rtptime")); - buffer = gst_value_get_buffer (gst_structure_get_value (s, "sr-buffer")); - - have_sr = FALSE; - have_sdes = FALSE; - GST_RTCP_BUFFER_FOR_PACKETS (more, buffer, &packet) { - /* first packet must be SR or RR or else the validate would have failed */ - switch (gst_rtcp_packet_get_type (&packet)) { - case GST_RTCP_TYPE_SR: - /* only parse first. There is only supposed to be one SR in the packet - * but we will deal with malformed packets gracefully */ - if (have_sr) - break; - /* get NTP and RTP times */ - gst_rtcp_packet_sr_get_sender_info (&packet, &ssrc, &ntptime, NULL, - NULL, NULL); - - GST_DEBUG_OBJECT (bin, "received sync packet from SSRC %08x", ssrc); - /* ignore SR that is not ours */ - if (ssrc != stream->ssrc) - continue; - - have_sr = TRUE; - break; - case GST_RTCP_TYPE_SDES: - { - gboolean more_items, more_entries; - - /* only deal with first SDES, there is only supposed to be one SDES in - * the RTCP packet but we deal with bad packets gracefully. Also bail - * out if we have not seen an SR item yet. */ - if (have_sdes || !have_sr) - break; - - GST_RTCP_SDES_FOR_ITEMS (more_items, &packet) { - /* skip items that are not about the SSRC of the sender */ - if (gst_rtcp_packet_sdes_get_ssrc (&packet) != ssrc) - continue; - - /* find the CNAME entry */ - GST_RTCP_SDES_FOR_ENTRIES (more_entries, &packet) { - GstRTCPSDESType type; - guint8 len; - guint8 *data; - - gst_rtcp_packet_sdes_get_entry (&packet, &type, &len, &data); - - if (type == GST_RTCP_SDES_CNAME) { - GST_RTP_BIN_LOCK (bin); - /* associate the stream to CNAME */ - gst_rtp_bin_associate (bin, stream, len, data, - gst_rtcp_ntp_to_unix (ntptime), extrtptime, - clock_base, clock_base_time, clock_rate); - GST_RTP_BIN_UNLOCK (bin); - } - } - } - have_sdes = TRUE; - break; - } - default: - /* we can ignore these packets */ - break; - } - } -} - -/* create a new stream with @ssrc in @session. Must be called with - * RTP_SESSION_LOCK. */ -static GstRtpBinStream * -create_stream (GstRtpBinSession * session, guint32 ssrc) -{ - GstElement *buffer, *demux; - GstRtpBinStream *stream; - GstRtpBin *rtpbin; - GstState target; - - if (!(buffer = gst_element_factory_make ("gstrtpjitterbuffer", NULL))) - goto no_jitterbuffer; - - if (!(demux = gst_element_factory_make ("gstrtpptdemux", NULL))) - goto no_demux; - - rtpbin = session->bin; - - stream = g_new0 (GstRtpBinStream, 1); - stream->ssrc = ssrc; - stream->bin = rtpbin; - stream->session = session; - stream->buffer = buffer; - stream->demux = demux; - stream->have_sync = FALSE; - stream->unix_delta = 0; - session->streams = g_slist_prepend (session->streams, stream); - - /* provide clock_rate to the jitterbuffer when needed */ - stream->buffer_ptreq_sig = g_signal_connect (buffer, "request-pt-map", - (GCallback) pt_map_requested, session); - stream->buffer_ntpstop_sig = g_signal_connect (buffer, "on-npt-stop", - (GCallback) on_npt_stop, stream); - - /* configure latency and packet lost */ - g_object_set (buffer, "latency", rtpbin->latency, NULL); - g_object_set (buffer, "do-lost", rtpbin->do_lost, NULL); - - gst_bin_add (GST_BIN_CAST (rtpbin), demux); - gst_bin_add (GST_BIN_CAST (rtpbin), buffer); - - /* link stuff */ - gst_element_link (buffer, demux); - - GST_OBJECT_LOCK (rtpbin); - target = GST_STATE_TARGET (rtpbin); - GST_OBJECT_UNLOCK (rtpbin); - - /* from sink to source */ - gst_element_set_state (demux, target); - gst_element_set_state (buffer, target); - - return stream; - - /* ERRORS */ -no_jitterbuffer: - { - g_warning ("gstrtpbin: could not create gstrtpjitterbuffer element"); - return NULL; - } -no_demux: - { - gst_object_unref (buffer); - g_warning ("gstrtpbin: could not create gstrtpptdemux element"); - return NULL; - } -} - -static void -free_stream (GstRtpBinStream * stream) -{ - GstRtpBinSession *session; - - session = stream->session; - - g_signal_handler_disconnect (stream->demux, stream->demux_newpad_sig); - g_signal_handler_disconnect (stream->demux, stream->demux_ptreq_sig); - g_signal_handler_disconnect (stream->buffer, stream->buffer_handlesync_sig); - g_signal_handler_disconnect (stream->buffer, stream->buffer_ptreq_sig); - g_signal_handler_disconnect (stream->buffer, stream->buffer_ntpstop_sig); - - gst_element_set_state (stream->demux, GST_STATE_NULL); - gst_element_set_state (stream->buffer, GST_STATE_NULL); - - /* now remove this signal, we need this while going to NULL because it to - * do some cleanups */ - g_signal_handler_disconnect (stream->demux, stream->demux_padremoved_sig); - - gst_bin_remove (GST_BIN_CAST (session->bin), stream->buffer); - gst_bin_remove (GST_BIN_CAST (session->bin), stream->demux); - - g_free (stream); -} - -/* GObject vmethods */ -static void gst_rtp_bin_dispose (GObject * object); -static void gst_rtp_bin_finalize (GObject * object); -static void gst_rtp_bin_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec); -static void gst_rtp_bin_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec); - -/* GstElement vmethods */ -static GstStateChangeReturn gst_rtp_bin_change_state (GstElement * element, - GstStateChange transition); -static GstPad *gst_rtp_bin_request_new_pad (GstElement * element, - GstPadTemplate * templ, const gchar * name); -static void gst_rtp_bin_release_pad (GstElement * element, GstPad * pad); -static void gst_rtp_bin_handle_message (GstBin * bin, GstMessage * message); -static void gst_rtp_bin_clear_pt_map (GstRtpBin * bin); - -GST_BOILERPLATE (GstRtpBin, gst_rtp_bin, GstBin, GST_TYPE_BIN); - -static void -gst_rtp_bin_base_init (gpointer klass) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS (klass); - - /* sink pads */ - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&rtpbin_recv_rtp_sink_template)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&rtpbin_recv_rtcp_sink_template)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&rtpbin_send_rtp_sink_template)); - - /* src pads */ - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&rtpbin_recv_rtp_src_template)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&rtpbin_send_rtcp_src_template)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&rtpbin_send_rtp_src_template)); - - gst_element_class_set_details (element_class, &rtpbin_details); -} - -static void -gst_rtp_bin_class_init (GstRtpBinClass * klass) -{ - GObjectClass *gobject_class; - GstElementClass *gstelement_class; - GstBinClass *gstbin_class; - - gobject_class = (GObjectClass *) klass; - gstelement_class = (GstElementClass *) klass; - gstbin_class = (GstBinClass *) klass; - - g_type_class_add_private (klass, sizeof (GstRtpBinPrivate)); - - gobject_class->dispose = gst_rtp_bin_dispose; - gobject_class->finalize = gst_rtp_bin_finalize; - gobject_class->set_property = gst_rtp_bin_set_property; - gobject_class->get_property = gst_rtp_bin_get_property; - - g_object_class_install_property (gobject_class, PROP_LATENCY, - g_param_spec_uint ("latency", "Buffer latency in ms", - "Default amount of ms to buffer in the jitterbuffers", 0, - G_MAXUINT, DEFAULT_LATENCY_MS, G_PARAM_READWRITE)); - - /** - * GstRtpBin::request-pt-map: - * @rtpbin: the object which received the signal - * @session: the session - * @pt: the pt - * - * Request the payload type as #GstCaps for @pt in @session. - */ - gst_rtp_bin_signals[SIGNAL_REQUEST_PT_MAP] = - g_signal_new ("request-pt-map", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass, request_pt_map), - NULL, NULL, gst_rtp_bin_marshal_BOXED__UINT_UINT, GST_TYPE_CAPS, 2, - G_TYPE_UINT, G_TYPE_UINT); - /** - * GstRtpBin::clear-pt-map: - * @rtpbin: the object which received the signal - * - * Clear all previously cached pt-mapping obtained with - * #GstRtpBin::request-pt-map. - */ - gst_rtp_bin_signals[SIGNAL_CLEAR_PT_MAP] = - g_signal_new ("clear-pt-map", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (GstRtpBinClass, - clear_pt_map), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, - 0, G_TYPE_NONE); - /** - * GstRtpBin::reset-sync: - * @rtpbin: the object which received the signal - * - * Reset all currently configured lip-sync parameters and require new SR - * packets for all streams before lip-sync is attempted again. - */ - gst_rtp_bin_signals[SIGNAL_RESET_SYNC] = - g_signal_new ("reset-sync", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (GstRtpBinClass, - reset_sync), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, - 0, G_TYPE_NONE); - - /** - * GstRtpBin::get-internal-session: - * @rtpbin: the object which received the signal - * @id: the session id - * - * Request the internal RTPSession object as #GObject in session @id. - */ - gst_rtp_bin_signals[SIGNAL_GET_INTERNAL_SESSION] = - g_signal_new ("get-internal-session", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (GstRtpBinClass, - get_internal_session), NULL, NULL, gst_rtp_bin_marshal_OBJECT__UINT, - RTP_TYPE_SESSION, 1, G_TYPE_UINT); - - /** - * GstRtpBin::on-new-ssrc: - * @rtpbin: the object which received the signal - * @session: the session - * @ssrc: the SSRC - * - * Notify of a new SSRC that entered @session. - */ - gst_rtp_bin_signals[SIGNAL_ON_NEW_SSRC] = - g_signal_new ("on-new-ssrc", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass, on_new_ssrc), - NULL, NULL, gst_rtp_bin_marshal_VOID__UINT_UINT, G_TYPE_NONE, 2, - G_TYPE_UINT, G_TYPE_UINT); - /** - * GstRtpBin::on-ssrc-collision: - * @rtpbin: the object which received the signal - * @session: the session - * @ssrc: the SSRC - * - * Notify when we have an SSRC collision - */ - gst_rtp_bin_signals[SIGNAL_ON_SSRC_COLLISION] = - g_signal_new ("on-ssrc-collision", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass, on_ssrc_collision), - NULL, NULL, gst_rtp_bin_marshal_VOID__UINT_UINT, G_TYPE_NONE, 2, - G_TYPE_UINT, G_TYPE_UINT); - /** - * GstRtpBin::on-ssrc-validated: - * @rtpbin: the object which received the signal - * @session: the session - * @ssrc: the SSRC - * - * Notify of a new SSRC that became validated. - */ - gst_rtp_bin_signals[SIGNAL_ON_SSRC_VALIDATED] = - g_signal_new ("on-ssrc-validated", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass, on_ssrc_validated), - NULL, NULL, gst_rtp_bin_marshal_VOID__UINT_UINT, G_TYPE_NONE, 2, - G_TYPE_UINT, G_TYPE_UINT); - /** - * GstRtpBin::on-ssrc-active: - * @rtpbin: the object which received the signal - * @session: the session - * @ssrc: the SSRC - * - * Notify of a SSRC that is active, i.e., sending RTCP. - */ - gst_rtp_bin_signals[SIGNAL_ON_SSRC_ACTIVE] = - g_signal_new ("on-ssrc-active", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass, on_ssrc_active), - NULL, NULL, gst_rtp_bin_marshal_VOID__UINT_UINT, G_TYPE_NONE, 2, - G_TYPE_UINT, G_TYPE_UINT); - /** - * GstRtpBin::on-ssrc-sdes: - * @rtpbin: the object which received the signal - * @session: the session - * @ssrc: the SSRC - * - * Notify of a SSRC that is active, i.e., sending RTCP. - */ - gst_rtp_bin_signals[SIGNAL_ON_SSRC_SDES] = - g_signal_new ("on-ssrc-sdes", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass, on_ssrc_sdes), - NULL, NULL, gst_rtp_bin_marshal_VOID__UINT_UINT, G_TYPE_NONE, 2, - G_TYPE_UINT, G_TYPE_UINT); - - /** - * GstRtpBin::on-bye-ssrc: - * @rtpbin: the object which received the signal - * @session: the session - * @ssrc: the SSRC - * - * Notify of an SSRC that became inactive because of a BYE packet. - */ - gst_rtp_bin_signals[SIGNAL_ON_BYE_SSRC] = - g_signal_new ("on-bye-ssrc", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass, on_bye_ssrc), - NULL, NULL, gst_rtp_bin_marshal_VOID__UINT_UINT, G_TYPE_NONE, 2, - G_TYPE_UINT, G_TYPE_UINT); - /** - * GstRtpBin::on-bye-timeout: - * @rtpbin: the object which received the signal - * @session: the session - * @ssrc: the SSRC - * - * Notify of an SSRC that has timed out because of BYE - */ - gst_rtp_bin_signals[SIGNAL_ON_BYE_TIMEOUT] = - g_signal_new ("on-bye-timeout", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass, on_bye_timeout), - NULL, NULL, gst_rtp_bin_marshal_VOID__UINT_UINT, G_TYPE_NONE, 2, - G_TYPE_UINT, G_TYPE_UINT); - /** - * GstRtpBin::on-timeout: - * @rtpbin: the object which received the signal - * @session: the session - * @ssrc: the SSRC - * - * Notify of an SSRC that has timed out - */ - gst_rtp_bin_signals[SIGNAL_ON_TIMEOUT] = - g_signal_new ("on-timeout", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass, on_timeout), - NULL, NULL, gst_rtp_bin_marshal_VOID__UINT_UINT, G_TYPE_NONE, 2, - G_TYPE_UINT, G_TYPE_UINT); - /** - * GstRtpBin::on-sender-timeout: - * @rtpbin: the object which received the signal - * @session: the session - * @ssrc: the SSRC - * - * Notify of a sender SSRC that has timed out and became a receiver - */ - gst_rtp_bin_signals[SIGNAL_ON_SENDER_TIMEOUT] = - g_signal_new ("on-sender-timeout", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass, on_sender_timeout), - NULL, NULL, gst_rtp_bin_marshal_VOID__UINT_UINT, G_TYPE_NONE, 2, - G_TYPE_UINT, G_TYPE_UINT); - - /** - * GstRtpBin::on-npt-stop: - * @rtpbin: the object which received the signal - * @session: the session - * @ssrc: the SSRC - * - * Notify that SSRC sender has sent data up to the configured NPT stop time. - */ - gst_rtp_bin_signals[SIGNAL_ON_NPT_STOP] = - g_signal_new ("on-npt-stop", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass, on_npt_stop), - NULL, NULL, gst_rtp_bin_marshal_VOID__UINT_UINT, G_TYPE_NONE, 2, - G_TYPE_UINT, G_TYPE_UINT); - - g_object_class_install_property (gobject_class, PROP_SDES, - g_param_spec_boxed ("sdes", "SDES", - "The SDES items of this session", - GST_TYPE_STRUCTURE, G_PARAM_READWRITE)); - - g_object_class_install_property (gobject_class, PROP_DO_LOST, - g_param_spec_boolean ("do-lost", "Do Lost", - "Send an event downstream when a packet is lost", DEFAULT_DO_LOST, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_rtp_bin_change_state); - gstelement_class->request_new_pad = - GST_DEBUG_FUNCPTR (gst_rtp_bin_request_new_pad); - gstelement_class->release_pad = GST_DEBUG_FUNCPTR (gst_rtp_bin_release_pad); - - gstbin_class->handle_message = GST_DEBUG_FUNCPTR (gst_rtp_bin_handle_message); - - klass->clear_pt_map = GST_DEBUG_FUNCPTR (gst_rtp_bin_clear_pt_map); - klass->reset_sync = GST_DEBUG_FUNCPTR (gst_rtp_bin_reset_sync); - klass->get_internal_session = - GST_DEBUG_FUNCPTR (gst_rtp_bin_get_internal_session); - - GST_DEBUG_CATEGORY_INIT (gst_rtp_bin_debug, "rtpbin", 0, "RTP bin"); -} - -static void -gst_rtp_bin_init (GstRtpBin * rtpbin, GstRtpBinClass * klass) -{ - gchar *str; - - rtpbin->priv = GST_RTP_BIN_GET_PRIVATE (rtpbin); - rtpbin->priv->bin_lock = g_mutex_new (); - rtpbin->priv->dyn_lock = g_mutex_new (); - - rtpbin->latency = DEFAULT_LATENCY_MS; - rtpbin->do_lost = DEFAULT_DO_LOST; - - /* some default SDES entries */ - str = g_strdup_printf ("%s@%s", g_get_user_name (), g_get_host_name ()); - rtpbin->sdes = gst_structure_new ("application/x-rtp-source-sdes", - "cname", G_TYPE_STRING, str, - "name", G_TYPE_STRING, g_get_real_name (), - "tool", G_TYPE_STRING, "GStreamer", NULL); - g_free (str); -} - -static void -gst_rtp_bin_dispose (GObject * object) -{ - GstRtpBin *rtpbin; - - rtpbin = GST_RTP_BIN (object); - - GST_DEBUG_OBJECT (object, "freeing sessions"); - g_slist_foreach (rtpbin->sessions, (GFunc) free_session, rtpbin); - g_slist_free (rtpbin->sessions); - rtpbin->sessions = NULL; - GST_DEBUG_OBJECT (object, "freeing clients"); - g_slist_foreach (rtpbin->clients, (GFunc) free_client, rtpbin); - g_slist_free (rtpbin->clients); - rtpbin->clients = NULL; - - G_OBJECT_CLASS (parent_class)->dispose (object); -} - -static void -gst_rtp_bin_finalize (GObject * object) -{ - GstRtpBin *rtpbin; - - rtpbin = GST_RTP_BIN (object); - - if (rtpbin->sdes) - gst_structure_free (rtpbin->sdes); - - g_mutex_free (rtpbin->priv->bin_lock); - g_mutex_free (rtpbin->priv->dyn_lock); - - G_OBJECT_CLASS (parent_class)->finalize (object); -} - - -static void -gst_rtp_bin_set_sdes_struct (GstRtpBin * bin, const GstStructure * sdes) -{ - GSList *item; - - if (sdes == NULL) - return; - - GST_RTP_BIN_LOCK (bin); - - GST_OBJECT_LOCK (bin); - if (bin->sdes) - gst_structure_free (bin->sdes); - bin->sdes = gst_structure_copy (sdes); - - /* store in all sessions */ - for (item = bin->sessions; item; item = g_slist_next (item)) - g_object_set (item->data, "sdes", sdes, NULL); - GST_OBJECT_UNLOCK (bin); - - GST_RTP_BIN_UNLOCK (bin); -} - -static GstStructure * -gst_rtp_bin_get_sdes_struct (GstRtpBin * bin) -{ - GstStructure *result; - - GST_OBJECT_LOCK (bin); - result = gst_structure_copy (bin->sdes); - GST_OBJECT_UNLOCK (bin); - - return result; -} - -static void -gst_rtp_bin_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) -{ - GstRtpBin *rtpbin; - - rtpbin = GST_RTP_BIN (object); - - switch (prop_id) { - case PROP_LATENCY: - GST_RTP_BIN_LOCK (rtpbin); - rtpbin->latency = g_value_get_uint (value); - GST_RTP_BIN_UNLOCK (rtpbin); - /* propegate the property down to the jitterbuffer */ - gst_rtp_bin_propagate_property_to_jitterbuffer (rtpbin, "latency", value); - break; - case PROP_SDES: - gst_rtp_bin_set_sdes_struct (rtpbin, g_value_get_boxed (value)); - break; - case PROP_DO_LOST: - GST_RTP_BIN_LOCK (rtpbin); - rtpbin->do_lost = g_value_get_boolean (value); - GST_RTP_BIN_UNLOCK (rtpbin); - gst_rtp_bin_propagate_property_to_jitterbuffer (rtpbin, "do-lost", value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_rtp_bin_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec) -{ - GstRtpBin *rtpbin; - - rtpbin = GST_RTP_BIN (object); - - switch (prop_id) { - case PROP_LATENCY: - GST_RTP_BIN_LOCK (rtpbin); - g_value_set_uint (value, rtpbin->latency); - GST_RTP_BIN_UNLOCK (rtpbin); - break; - case PROP_SDES: - g_value_take_boxed (value, gst_rtp_bin_get_sdes_struct (rtpbin)); - break; - case PROP_DO_LOST: - GST_RTP_BIN_LOCK (rtpbin); - g_value_set_boolean (value, rtpbin->do_lost); - GST_RTP_BIN_UNLOCK (rtpbin); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_rtp_bin_handle_message (GstBin * bin, GstMessage * message) -{ - GstRtpBin *rtpbin; - - rtpbin = GST_RTP_BIN (bin); - - switch (GST_MESSAGE_TYPE (message)) { - case GST_MESSAGE_ELEMENT: - { - const GstStructure *s = gst_message_get_structure (message); - - /* we change the structure name and add the session ID to it */ - if (gst_structure_has_name (s, "application/x-rtp-source-sdes")) { - GSList *walk; - - /* find the session, the message source has it */ - for (walk = rtpbin->sessions; walk; walk = g_slist_next (walk)) { - GstRtpBinSession *sess = (GstRtpBinSession *) walk->data; - - /* if we found the session, change message. else we exit the loop and - * leave the message unchanged */ - if (GST_OBJECT_CAST (sess->session) == GST_MESSAGE_SRC (message)) { - message = gst_message_make_writable (message); - s = gst_message_get_structure (message); - - gst_structure_set ((GstStructure *) s, "session", G_TYPE_UINT, - sess->id, NULL); - break; - } - } - } - /* fallthrough to forward the modified message to the parent */ - } - default: - { - GST_BIN_CLASS (parent_class)->handle_message (bin, message); - break; - } - } -} - -static void -calc_ntp_ns_base (GstRtpBin * bin) -{ - GstClockTime now; - GTimeVal current; - GSList *walk; - - /* get the current time and convert it to NTP time in nanoseconds */ - g_get_current_time (¤t); - now = GST_TIMEVAL_TO_TIME (current); - now += (2208988800LL * GST_SECOND); - - GST_RTP_BIN_LOCK (bin); - bin->priv->ntp_ns_base = now; - for (walk = bin->sessions; walk; walk = g_slist_next (walk)) { - GstRtpBinSession *session = (GstRtpBinSession *) walk->data; - - g_object_set (session->session, "ntp-ns-base", now, NULL); - } - GST_RTP_BIN_UNLOCK (bin); - - return; -} - -static GstStateChangeReturn -gst_rtp_bin_change_state (GstElement * element, GstStateChange transition) -{ - GstStateChangeReturn res; - GstRtpBin *rtpbin; - GstRtpBinPrivate *priv; - - rtpbin = GST_RTP_BIN (element); - priv = rtpbin->priv; - - switch (transition) { - case GST_STATE_CHANGE_NULL_TO_READY: - break; - case GST_STATE_CHANGE_READY_TO_PAUSED: - GST_LOG_OBJECT (rtpbin, "clearing shutdown flag"); - g_atomic_int_set (&priv->shutdown, 0); - break; - case GST_STATE_CHANGE_PAUSED_TO_PLAYING: - calc_ntp_ns_base (rtpbin); - break; - case GST_STATE_CHANGE_PAUSED_TO_READY: - GST_LOG_OBJECT (rtpbin, "setting shutdown flag"); - g_atomic_int_set (&priv->shutdown, 1); - /* wait for all callbacks to end by taking the lock. No new callbacks will - * be able to happen as we set the shutdown flag. */ - GST_RTP_BIN_DYN_LOCK (rtpbin); - GST_LOG_OBJECT (rtpbin, "dynamic lock taken, we can continue shutdown"); - GST_RTP_BIN_DYN_UNLOCK (rtpbin); - break; - default: - break; - } - - res = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); - - switch (transition) { - case GST_STATE_CHANGE_PLAYING_TO_PAUSED: - break; - case GST_STATE_CHANGE_PAUSED_TO_READY: - break; - case GST_STATE_CHANGE_READY_TO_NULL: - break; - default: - break; - } - return res; -} - -/* a new pad (SSRC) was created in @session. This signal is emited from the - * payload demuxer. */ -static void -new_payload_found (GstElement * element, guint pt, GstPad * pad, - GstRtpBinStream * stream) -{ - GstRtpBin *rtpbin; - GstElementClass *klass; - GstPadTemplate *templ; - gchar *padname; - GstPad *gpad; - - rtpbin = stream->bin; - - GST_DEBUG ("new payload pad %d", pt); - - GST_RTP_BIN_SHUTDOWN_LOCK (rtpbin, shutdown); - - /* ghost the pad to the parent */ - klass = GST_ELEMENT_GET_CLASS (rtpbin); - templ = gst_element_class_get_pad_template (klass, "recv_rtp_src_%d_%d_%d"); - padname = g_strdup_printf ("recv_rtp_src_%d_%u_%d", - stream->session->id, stream->ssrc, pt); - gpad = gst_ghost_pad_new_from_template (padname, pad, templ); - g_free (padname); - g_object_set_data (G_OBJECT (pad), "GstRTPBin.ghostpad", gpad); - - gst_pad_set_caps (gpad, GST_PAD_CAPS (pad)); - gst_pad_set_active (gpad, TRUE); - gst_element_add_pad (GST_ELEMENT_CAST (rtpbin), gpad); - GST_RTP_BIN_SHUTDOWN_UNLOCK (rtpbin); - - return; - -shutdown: - { - GST_DEBUG ("ignoring, we are shutting down"); - return; - } -} - -static void -payload_pad_removed (GstElement * element, GstPad * pad, - GstRtpBinStream * stream) -{ - GstRtpBin *rtpbin; - GstPad *gpad; - - rtpbin = stream->bin; - - GST_DEBUG ("payload pad removed"); - - GST_RTP_BIN_DYN_LOCK (rtpbin); - if ((gpad = g_object_get_data (G_OBJECT (pad), "GstRTPBin.ghostpad"))) { - g_object_set_data (G_OBJECT (pad), "GstRTPBin.ghostpad", NULL); - - gst_pad_set_active (gpad, FALSE); - gst_element_remove_pad (GST_ELEMENT_CAST (rtpbin), gpad); - } - GST_RTP_BIN_DYN_UNLOCK (rtpbin); -} - -static GstCaps * -pt_map_requested (GstElement * element, guint pt, GstRtpBinSession * session) -{ - GstRtpBin *rtpbin; - GstCaps *caps; - - rtpbin = session->bin; - - GST_DEBUG_OBJECT (rtpbin, "payload map requested for pt %d in session %d", pt, - session->id); - - caps = get_pt_map (session, pt); - if (!caps) - goto no_caps; - - return caps; - - /* ERRORS */ -no_caps: - { - GST_DEBUG_OBJECT (rtpbin, "could not get caps"); - return NULL; - } -} - -/* emited when caps changed for the session */ -static void -caps_changed (GstPad * pad, GParamSpec * pspec, GstRtpBinSession * session) -{ - GstRtpBin *bin; - GstCaps *caps; - gint payload; - const GstStructure *s; - - bin = session->bin; - - g_object_get (pad, "caps", &caps, NULL); - - if (caps == NULL) - return; - - GST_DEBUG_OBJECT (bin, "got caps %" GST_PTR_FORMAT, caps); - - s = gst_caps_get_structure (caps, 0); - - /* get payload, finish when it's not there */ - if (!gst_structure_get_int (s, "payload", &payload)) - return; - - GST_RTP_SESSION_LOCK (session); - GST_DEBUG_OBJECT (bin, "insert caps for payload %d", payload); - g_hash_table_insert (session->ptmap, GINT_TO_POINTER (payload), caps); - GST_RTP_SESSION_UNLOCK (session); -} - -/* a new pad (SSRC) was created in @session */ -static void -new_ssrc_pad_found (GstElement * element, guint ssrc, GstPad * pad, - GstRtpBinSession * session) -{ - GstRtpBin *rtpbin; - GstRtpBinStream *stream; - GstPad *sinkpad, *srcpad; - gchar *padname; - - rtpbin = session->bin; - - GST_DEBUG_OBJECT (rtpbin, "new SSRC pad %08x, %s:%s", ssrc, - GST_DEBUG_PAD_NAME (pad)); - - GST_RTP_BIN_SHUTDOWN_LOCK (rtpbin, shutdown); - - GST_RTP_SESSION_LOCK (session); - - /* create new stream */ - stream = create_stream (session, ssrc); - if (!stream) - goto no_stream; - - /* get pad and link */ - GST_DEBUG_OBJECT (rtpbin, "linking jitterbuffer RTP"); - padname = g_strdup_printf ("src_%d", ssrc); - srcpad = gst_element_get_static_pad (element, padname); - g_free (padname); - sinkpad = gst_element_get_static_pad (stream->buffer, "sink"); - gst_pad_link (srcpad, sinkpad); - gst_object_unref (sinkpad); - gst_object_unref (srcpad); - - GST_DEBUG_OBJECT (rtpbin, "linking jitterbuffer RTCP"); - padname = g_strdup_printf ("rtcp_src_%d", ssrc); - srcpad = gst_element_get_static_pad (element, padname); - g_free (padname); - sinkpad = gst_element_get_request_pad (stream->buffer, "sink_rtcp"); - gst_pad_link (srcpad, sinkpad); - gst_object_unref (sinkpad); - gst_object_unref (srcpad); - - /* connect to the RTCP sync signal from the jitterbuffer */ - GST_DEBUG_OBJECT (rtpbin, "connecting sync signal"); - stream->buffer_handlesync_sig = g_signal_connect (stream->buffer, - "handle-sync", (GCallback) gst_rtp_bin_handle_sync, stream); - - /* connect to the new-pad signal of the payload demuxer, this will expose the - * new pad by ghosting it. */ - stream->demux_newpad_sig = g_signal_connect (stream->demux, - "new-payload-type", (GCallback) new_payload_found, stream); - stream->demux_padremoved_sig = g_signal_connect (stream->demux, - "pad-removed", (GCallback) payload_pad_removed, stream); - - /* connect to the request-pt-map signal. This signal will be emited by the - * demuxer so that it can apply a proper caps on the buffers for the - * depayloaders. */ - stream->demux_ptreq_sig = g_signal_connect (stream->demux, - "request-pt-map", (GCallback) pt_map_requested, session); - - GST_RTP_SESSION_UNLOCK (session); - GST_RTP_BIN_SHUTDOWN_UNLOCK (rtpbin); - - return; - - /* ERRORS */ -shutdown: - { - GST_DEBUG_OBJECT (rtpbin, "we are shutting down"); - return; - } -no_stream: - { - GST_RTP_SESSION_UNLOCK (session); - GST_RTP_BIN_SHUTDOWN_UNLOCK (rtpbin); - GST_DEBUG_OBJECT (rtpbin, "could not create stream"); - return; - } -} - -/* Create a pad for receiving RTP for the session in @name. Must be called with - * RTP_BIN_LOCK. - */ -static GstPad * -create_recv_rtp (GstRtpBin * rtpbin, GstPadTemplate * templ, const gchar * name) -{ - GstPad *sinkdpad; - guint sessid; - GstRtpBinSession *session; - GstPadLinkReturn lres; - - /* first get the session number */ - if (name == NULL || sscanf (name, "recv_rtp_sink_%d", &sessid) != 1) - goto no_name; - - GST_DEBUG_OBJECT (rtpbin, "finding session %d", sessid); - - /* get or create session */ - session = find_session_by_id (rtpbin, sessid); - if (!session) { - GST_DEBUG_OBJECT (rtpbin, "creating session %d", sessid); - /* create session now */ - session = create_session (rtpbin, sessid); - if (session == NULL) - goto create_error; - } - - /* check if pad was requested */ - if (session->recv_rtp_sink_ghost != NULL) - return session->recv_rtp_sink_ghost; - - GST_DEBUG_OBJECT (rtpbin, "getting RTP sink pad"); - /* get recv_rtp pad and store */ - session->recv_rtp_sink = - gst_element_get_request_pad (session->session, "recv_rtp_sink"); - if (session->recv_rtp_sink == NULL) - goto pad_failed; - - g_signal_connect (session->recv_rtp_sink, "notify::caps", - (GCallback) caps_changed, session); - - GST_DEBUG_OBJECT (rtpbin, "getting RTP src pad"); - /* get srcpad, link to SSRCDemux */ - session->recv_rtp_src = - gst_element_get_static_pad (session->session, "recv_rtp_src"); - if (session->recv_rtp_src == NULL) - goto pad_failed; - - GST_DEBUG_OBJECT (rtpbin, "getting demuxer RTP sink pad"); - sinkdpad = gst_element_get_static_pad (session->demux, "sink"); - GST_DEBUG_OBJECT (rtpbin, "linking demuxer RTP sink pad"); - lres = gst_pad_link (session->recv_rtp_src, sinkdpad); - gst_object_unref (sinkdpad); - if (lres != GST_PAD_LINK_OK) - goto link_failed; - - /* connect to the new-ssrc-pad signal of the SSRC demuxer */ - session->demux_newpad_sig = g_signal_connect (session->demux, - "new-ssrc-pad", (GCallback) new_ssrc_pad_found, session); - session->demux_padremoved_sig = g_signal_connect (session->demux, - "removed-ssrc-pad", (GCallback) ssrc_demux_pad_removed, session); - - GST_DEBUG_OBJECT (rtpbin, "ghosting session sink pad"); - session->recv_rtp_sink_ghost = - gst_ghost_pad_new_from_template (name, session->recv_rtp_sink, templ); - gst_pad_set_active (session->recv_rtp_sink_ghost, TRUE); - gst_element_add_pad (GST_ELEMENT_CAST (rtpbin), session->recv_rtp_sink_ghost); - - return session->recv_rtp_sink_ghost; - - /* ERRORS */ -no_name: - { - g_warning ("gstrtpbin: invalid name given"); - return NULL; - } -create_error: - { - /* create_session already warned */ - return NULL; - } -pad_failed: - { - g_warning ("gstrtpbin: failed to get session pad"); - return NULL; - } -link_failed: - { - g_warning ("gstrtpbin: failed to link pads"); - return NULL; - } -} - -static void -remove_recv_rtp (GstRtpBin * rtpbin, GstRtpBinSession * session) -{ - if (session->demux_newpad_sig) { - g_signal_handler_disconnect (session->demux, session->demux_newpad_sig); - session->demux_newpad_sig = 0; - } - if (session->demux_padremoved_sig) { - g_signal_handler_disconnect (session->demux, session->demux_padremoved_sig); - session->demux_padremoved_sig = 0; - } - if (session->recv_rtp_src) { - gst_object_unref (session->recv_rtp_src); - session->recv_rtp_src = NULL; - } - if (session->recv_rtp_sink) { - gst_element_release_request_pad (session->session, session->recv_rtp_sink); - gst_object_unref (session->recv_rtp_sink); - session->recv_rtp_sink = NULL; - } - if (session->recv_rtp_sink_ghost) { - gst_pad_set_active (session->recv_rtp_sink_ghost, FALSE); - gst_element_remove_pad (GST_ELEMENT_CAST (rtpbin), - session->recv_rtp_sink_ghost); - session->recv_rtp_sink_ghost = NULL; - } -} - -/* Create a pad for receiving RTCP for the session in @name. Must be called with - * RTP_BIN_LOCK. - */ -static GstPad * -create_recv_rtcp (GstRtpBin * rtpbin, GstPadTemplate * templ, - const gchar * name) -{ - guint sessid; - GstRtpBinSession *session; - GstPad *sinkdpad; - GstPadLinkReturn lres; - - /* first get the session number */ - if (name == NULL || sscanf (name, "recv_rtcp_sink_%d", &sessid) != 1) - goto no_name; - - GST_DEBUG_OBJECT (rtpbin, "finding session %d", sessid); - - /* get or create the session */ - session = find_session_by_id (rtpbin, sessid); - if (!session) { - GST_DEBUG_OBJECT (rtpbin, "creating session %d", sessid); - /* create session now */ - session = create_session (rtpbin, sessid); - if (session == NULL) - goto create_error; - } - - /* check if pad was requested */ - if (session->recv_rtcp_sink_ghost != NULL) - return session->recv_rtcp_sink_ghost; - - /* get recv_rtp pad and store */ - GST_DEBUG_OBJECT (rtpbin, "getting RTCP sink pad"); - session->recv_rtcp_sink = - gst_element_get_request_pad (session->session, "recv_rtcp_sink"); - if (session->recv_rtcp_sink == NULL) - goto pad_failed; - - /* get srcpad, link to SSRCDemux */ - GST_DEBUG_OBJECT (rtpbin, "getting sync src pad"); - session->sync_src = gst_element_get_static_pad (session->session, "sync_src"); - if (session->sync_src == NULL) - goto pad_failed; - - GST_DEBUG_OBJECT (rtpbin, "getting demuxer RTCP sink pad"); - sinkdpad = gst_element_get_static_pad (session->demux, "rtcp_sink"); - lres = gst_pad_link (session->sync_src, sinkdpad); - gst_object_unref (sinkdpad); - if (lres != GST_PAD_LINK_OK) - goto link_failed; - - session->recv_rtcp_sink_ghost = - gst_ghost_pad_new_from_template (name, session->recv_rtcp_sink, templ); - gst_pad_set_active (session->recv_rtcp_sink_ghost, TRUE); - gst_element_add_pad (GST_ELEMENT_CAST (rtpbin), - session->recv_rtcp_sink_ghost); - - return session->recv_rtcp_sink_ghost; - - /* ERRORS */ -no_name: - { - g_warning ("gstrtpbin: invalid name given"); - return NULL; - } -create_error: - { - /* create_session already warned */ - return NULL; - } -pad_failed: - { - g_warning ("gstrtpbin: failed to get session pad"); - return NULL; - } -link_failed: - { - g_warning ("gstrtpbin: failed to link pads"); - return NULL; - } -} - -static void -remove_recv_rtcp (GstRtpBin * rtpbin, GstRtpBinSession * session) -{ - if (session->recv_rtcp_sink_ghost) { - gst_pad_set_active (session->recv_rtcp_sink_ghost, FALSE); - gst_element_remove_pad (GST_ELEMENT_CAST (rtpbin), - session->recv_rtcp_sink_ghost); - session->recv_rtcp_sink_ghost = NULL; - } - if (session->sync_src) { - /* releasing the request pad should also unref the sync pad */ - gst_object_unref (session->sync_src); - session->sync_src = NULL; - } - if (session->recv_rtcp_sink) { - gst_element_release_request_pad (session->session, session->recv_rtcp_sink); - gst_object_unref (session->recv_rtcp_sink); - session->recv_rtcp_sink = NULL; - } -} - -/* Create a pad for sending RTP for the session in @name. Must be called with - * RTP_BIN_LOCK. - */ -static GstPad * -create_send_rtp (GstRtpBin * rtpbin, GstPadTemplate * templ, const gchar * name) -{ - gchar *gname; - guint sessid; - GstRtpBinSession *session; - GstElementClass *klass; - - /* first get the session number */ - if (name == NULL || sscanf (name, "send_rtp_sink_%d", &sessid) != 1) - goto no_name; - - /* get or create session */ - session = find_session_by_id (rtpbin, sessid); - if (!session) { - /* create session now */ - session = create_session (rtpbin, sessid); - if (session == NULL) - goto create_error; - } - - /* check if pad was requested */ - if (session->send_rtp_sink_ghost != NULL) - return session->send_rtp_sink_ghost; - - /* get send_rtp pad and store */ - session->send_rtp_sink = - gst_element_get_request_pad (session->session, "send_rtp_sink"); - if (session->send_rtp_sink == NULL) - goto pad_failed; - - session->send_rtp_sink_ghost = - gst_ghost_pad_new_from_template (name, session->send_rtp_sink, templ); - gst_pad_set_active (session->send_rtp_sink_ghost, TRUE); - gst_element_add_pad (GST_ELEMENT_CAST (rtpbin), session->send_rtp_sink_ghost); - - /* get srcpad */ - session->send_rtp_src = - gst_element_get_static_pad (session->session, "send_rtp_src"); - if (session->send_rtp_src == NULL) - goto no_srcpad; - - /* ghost the new source pad */ - klass = GST_ELEMENT_GET_CLASS (rtpbin); - gname = g_strdup_printf ("send_rtp_src_%d", sessid); - templ = gst_element_class_get_pad_template (klass, "send_rtp_src_%d"); - session->send_rtp_src_ghost = - gst_ghost_pad_new_from_template (gname, session->send_rtp_src, templ); - gst_pad_set_active (session->send_rtp_src_ghost, TRUE); - gst_element_add_pad (GST_ELEMENT_CAST (rtpbin), session->send_rtp_src_ghost); - g_free (gname); - - return session->send_rtp_sink_ghost; - - /* ERRORS */ -no_name: - { - g_warning ("gstrtpbin: invalid name given"); - return NULL; - } -create_error: - { - /* create_session already warned */ - return NULL; - } -pad_failed: - { - g_warning ("gstrtpbin: failed to get session pad for session %d", sessid); - return NULL; - } -no_srcpad: - { - g_warning ("gstrtpbin: failed to get rtp source pad for session %d", - sessid); - return NULL; - } -} - -static void -remove_send_rtp (GstRtpBin * rtpbin, GstRtpBinSession * session) -{ - if (session->send_rtp_src_ghost) { - gst_pad_set_active (session->send_rtp_src_ghost, FALSE); - gst_element_remove_pad (GST_ELEMENT_CAST (rtpbin), - session->send_rtp_src_ghost); - session->send_rtp_src_ghost = NULL; - } - if (session->send_rtp_src) { - gst_object_unref (session->send_rtp_src); - session->send_rtp_src = NULL; - } - if (session->send_rtp_sink) { - gst_element_release_request_pad (GST_ELEMENT_CAST (session->session), - session->send_rtp_sink); - gst_object_unref (session->send_rtp_sink); - session->send_rtp_sink = NULL; - } - if (session->send_rtp_sink_ghost) { - gst_pad_set_active (session->send_rtp_sink_ghost, FALSE); - gst_element_remove_pad (GST_ELEMENT_CAST (rtpbin), - session->send_rtp_sink_ghost); - session->send_rtp_sink_ghost = NULL; - } -} - -/* Create a pad for sending RTCP for the session in @name. Must be called with - * RTP_BIN_LOCK. - */ -static GstPad * -create_rtcp (GstRtpBin * rtpbin, GstPadTemplate * templ, const gchar * name) -{ - guint sessid; - GstRtpBinSession *session; - - /* first get the session number */ - if (name == NULL || sscanf (name, "send_rtcp_src_%d", &sessid) != 1) - goto no_name; - - /* get or create session */ - session = find_session_by_id (rtpbin, sessid); - if (!session) - goto no_session; - - /* check if pad was requested */ - if (session->send_rtcp_src_ghost != NULL) - return session->send_rtcp_src_ghost; - - /* get rtcp_src pad and store */ - session->send_rtcp_src = - gst_element_get_request_pad (session->session, "send_rtcp_src"); - if (session->send_rtcp_src == NULL) - goto pad_failed; - - session->send_rtcp_src_ghost = - gst_ghost_pad_new_from_template (name, session->send_rtcp_src, templ); - gst_pad_set_active (session->send_rtcp_src_ghost, TRUE); - gst_element_add_pad (GST_ELEMENT_CAST (rtpbin), session->send_rtcp_src_ghost); - - return session->send_rtcp_src_ghost; - - /* ERRORS */ -no_name: - { - g_warning ("gstrtpbin: invalid name given"); - return NULL; - } -no_session: - { - g_warning ("gstrtpbin: session with id %d does not exist", sessid); - return NULL; - } -pad_failed: - { - g_warning ("gstrtpbin: failed to get rtcp pad for session %d", sessid); - return NULL; - } -} - -static void -remove_rtcp (GstRtpBin * rtpbin, GstRtpBinSession * session) -{ - if (session->send_rtcp_src_ghost) { - gst_pad_set_active (session->send_rtcp_src_ghost, FALSE); - gst_element_remove_pad (GST_ELEMENT_CAST (rtpbin), - session->send_rtcp_src_ghost); - session->send_rtcp_src_ghost = NULL; - } - if (session->send_rtcp_src) { - gst_element_release_request_pad (session->session, session->send_rtcp_src); - gst_object_unref (session->send_rtcp_src); - session->send_rtcp_src = NULL; - } -} - -/* If the requested name is NULL we should create a name with - * the session number assuming we want the lowest posible session - * with a free pad like the template */ -static gchar * -gst_rtp_bin_get_free_pad_name (GstElement * element, GstPadTemplate * templ) -{ - gboolean name_found = FALSE; - gint session = 0; - GstPad *pad = NULL; - GstIterator *pad_it = NULL; - gchar *pad_name = NULL; - - GST_DEBUG_OBJECT (element, "find a free pad name for template"); - while (!name_found) { - g_free (pad_name); - pad_name = g_strdup_printf (templ->name_template, session++); - pad_it = gst_element_iterate_pads (GST_ELEMENT (element)); - name_found = TRUE; - while (gst_iterator_next (pad_it, (gpointer) & pad) == GST_ITERATOR_OK) { - gchar *name; - - name = gst_pad_get_name (pad); - if (strcmp (name, pad_name) == 0) - name_found = FALSE; - g_free (name); - } - gst_iterator_free (pad_it); - } - - GST_DEBUG_OBJECT (element, "free pad name found: '%s'", pad_name); - return pad_name; -} - -/* - */ -static GstPad * -gst_rtp_bin_request_new_pad (GstElement * element, - GstPadTemplate * templ, const gchar * name) -{ - GstRtpBin *rtpbin; - GstElementClass *klass; - GstPad *result; - - gchar *pad_name = NULL; - - g_return_val_if_fail (templ != NULL, NULL); - g_return_val_if_fail (GST_IS_RTP_BIN (element), NULL); - - rtpbin = GST_RTP_BIN (element); - klass = GST_ELEMENT_GET_CLASS (element); - - GST_RTP_BIN_LOCK (rtpbin); - - if (name == NULL) { - /* use a free pad name */ - pad_name = gst_rtp_bin_get_free_pad_name (element, templ); - } else { - /* use the provided name */ - pad_name = g_strdup (name); - } - - GST_DEBUG_OBJECT (rtpbin, "Trying to request a pad with name %s", pad_name); - - /* figure out the template */ - if (templ == gst_element_class_get_pad_template (klass, "recv_rtp_sink_%d")) { - result = create_recv_rtp (rtpbin, templ, pad_name); - } else if (templ == gst_element_class_get_pad_template (klass, - "recv_rtcp_sink_%d")) { - result = create_recv_rtcp (rtpbin, templ, pad_name); - } else if (templ == gst_element_class_get_pad_template (klass, - "send_rtp_sink_%d")) { - result = create_send_rtp (rtpbin, templ, pad_name); - } else if (templ == gst_element_class_get_pad_template (klass, - "send_rtcp_src_%d")) { - result = create_rtcp (rtpbin, templ, pad_name); - } else - goto wrong_template; - - g_free (pad_name); - GST_RTP_BIN_UNLOCK (rtpbin); - - return result; - - /* ERRORS */ -wrong_template: - { - g_free (pad_name); - GST_RTP_BIN_UNLOCK (rtpbin); - g_warning ("gstrtpbin: this is not our template"); - return NULL; - } -} - -static void -gst_rtp_bin_release_pad (GstElement * element, GstPad * pad) -{ - GstRtpBinSession *session; - GstRtpBin *rtpbin; - - g_return_if_fail (GST_IS_GHOST_PAD (pad)); - g_return_if_fail (GST_IS_RTP_BIN (element)); - - rtpbin = GST_RTP_BIN (element); - - GST_RTP_BIN_LOCK (rtpbin); - GST_DEBUG_OBJECT (rtpbin, "Trying to release pad %s:%s", - GST_DEBUG_PAD_NAME (pad)); - - if (!(session = find_session_by_pad (rtpbin, pad))) - goto unknown_pad; - - if (session->recv_rtp_sink_ghost == pad) { - remove_recv_rtp (rtpbin, session); - } else if (session->recv_rtcp_sink_ghost == pad) { - remove_recv_rtcp (rtpbin, session); - } else if (session->send_rtp_sink_ghost == pad) { - remove_send_rtp (rtpbin, session); - } else if (session->send_rtcp_src_ghost == pad) { - remove_rtcp (rtpbin, session); - } - - /* no more request pads, free the complete session */ - if (session->recv_rtp_sink_ghost == NULL - && session->recv_rtcp_sink_ghost == NULL - && session->send_rtp_sink_ghost == NULL - && session->send_rtcp_src_ghost == NULL) { - GST_DEBUG_OBJECT (rtpbin, "no more pads for session %p", session); - rtpbin->sessions = g_slist_remove (rtpbin->sessions, session); - free_session (session, rtpbin); - } - GST_RTP_BIN_UNLOCK (rtpbin); - - return; - - /* ERROR */ -unknown_pad: - { - GST_RTP_BIN_UNLOCK (rtpbin); - g_warning ("gstrtpbin: %s:%s is not one of our request pads", - GST_DEBUG_PAD_NAME (pad)); - return; - } -} diff --git a/gst/rtpmanager/gstrtpbin.h b/gst/rtpmanager/gstrtpbin.h deleted file mode 100644 index bed6ad02..00000000 --- a/gst/rtpmanager/gstrtpbin.h +++ /dev/null @@ -1,88 +0,0 @@ -/* GStreamer - * Copyright (C) <2007> Wim Taymans <wim.taymans@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., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __GST_RTP_BIN_H__ -#define __GST_RTP_BIN_H__ - -#include <gst/gst.h> - -#include "rtpsession.h" - -#define GST_TYPE_RTP_BIN \ - (gst_rtp_bin_get_type()) -#define GST_RTP_BIN(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_BIN,GstRtpBin)) -#define GST_RTP_BIN_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_BIN,GstRtpBinClass)) -#define GST_IS_RTP_BIN(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_BIN)) -#define GST_IS_RTP_BIN_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_BIN)) - -typedef struct _GstRtpBin GstRtpBin; -typedef struct _GstRtpBinClass GstRtpBinClass; -typedef struct _GstRtpBinPrivate GstRtpBinPrivate; - -struct _GstRtpBin { - GstBin bin; - - /*< private >*/ - /* default latency for sessions */ - guint latency; - gboolean do_lost; - /* a list of session */ - GSList *sessions; - - /* a list of clients, these are streams with the same CNAME */ - GSList *clients; - - /* the default SDES items for sessions */ - GstStructure *sdes; - - /*< private >*/ - GstRtpBinPrivate *priv; -}; - -struct _GstRtpBinClass { - GstBinClass parent_class; - - /* get the caps for pt */ - GstCaps* (*request_pt_map) (GstRtpBin *rtpbin, guint session, guint pt); - - /* action signals */ - void (*clear_pt_map) (GstRtpBin *rtpbin); - void (*reset_sync) (GstRtpBin *rtpbin); - RTPSession* (*get_internal_session) (GstRtpBin *rtpbin, guint session_id); - - /* session manager signals */ - void (*on_new_ssrc) (GstRtpBin *rtpbin, guint session, guint32 ssrc); - void (*on_ssrc_collision) (GstRtpBin *rtpbin, guint session, guint32 ssrc); - void (*on_ssrc_validated) (GstRtpBin *rtpbin, guint session, guint32 ssrc); - void (*on_ssrc_active) (GstRtpBin *rtpbin, guint session, guint32 ssrc); - void (*on_ssrc_sdes) (GstRtpBin *rtpbin, guint session, guint32 ssrc); - void (*on_bye_ssrc) (GstRtpBin *rtpbin, guint session, guint32 ssrc); - void (*on_bye_timeout) (GstRtpBin *rtpbin, guint session, guint32 ssrc); - void (*on_timeout) (GstRtpBin *rtpbin, guint session, guint32 ssrc); - void (*on_sender_timeout) (GstRtpBin *rtpbin, guint session, guint32 ssrc); - void (*on_npt_stop) (GstRtpBin *rtpbin, guint session, guint32 ssrc); -}; - -GType gst_rtp_bin_get_type (void); - -#endif /* __GST_RTP_BIN_H__ */ diff --git a/gst/rtpmanager/gstrtpjitterbuffer.c b/gst/rtpmanager/gstrtpjitterbuffer.c deleted file mode 100644 index 55126054..00000000 --- a/gst/rtpmanager/gstrtpjitterbuffer.c +++ /dev/null @@ -1,1972 +0,0 @@ -/* - * Farsight Voice+Video library - * - * Copyright 2007 Collabora Ltd, - * Copyright 2007 Nokia Corporation - * @author: Philippe Kalaf <philippe.kalaf@collabora.co.uk>. - * Copyright 2007 Wim Taymans <wim.taymans@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., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - */ - -/** - * SECTION:element-gstrtpjitterbuffer - * - * This element reorders and removes duplicate RTP packets as they are received - * from a network source. It will also wait for missing packets up to a - * configurable time limit using the #GstRtpJitterBuffer:latency property. - * Packets arriving too late are considered to be lost packets. - * - * This element acts as a live element and so adds #GstRtpJitterBuffer:latency - * to the pipeline. - * - * The element needs the clock-rate of the RTP payload in order to estimate the - * delay. This information is obtained either from the caps on the sink pad or, - * when no caps are present, from the #GstRtpJitterBuffer::request-pt-map signal. - * To clear the previous pt-map use the #GstRtpJitterBuffer::clear-pt-map signal. - * - * This element will automatically be used inside gstrtpbin. - * - * <refsect2> - * <title>Example pipelines</title> - * |[ - * gst-launch rtspsrc location=rtsp://192.168.1.133:8554/mpeg1or2AudioVideoTest ! gstrtpjitterbuffer ! rtpmpvdepay ! mpeg2dec ! xvimagesink - * ]| Connect to a streaming server and decode the MPEG video. The jitterbuffer is - * inserted into the pipeline to smooth out network jitter and to reorder the - * out-of-order RTP packets. - * </refsect2> - * - * Last reviewed on 2007-05-28 (0.10.5) - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <stdlib.h> -#include <string.h> -#include <gst/rtp/gstrtpbuffer.h> - -#include "gstrtpbin-marshal.h" - -#include "gstrtpjitterbuffer.h" -#include "rtpjitterbuffer.h" -#include "rtpstats.h" - -GST_DEBUG_CATEGORY (rtpjitterbuffer_debug); -#define GST_CAT_DEFAULT (rtpjitterbuffer_debug) - -/* low and high threshold tell the queue when to start and stop buffering */ -#define LOW_THRESHOLD 0.2 -#define HIGH_THRESHOLD 0.8 - -/* elementfactory information */ -static const GstElementDetails gst_rtp_jitter_buffer_details = -GST_ELEMENT_DETAILS ("RTP packet jitter-buffer", - "Filter/Network/RTP", - "A buffer that deals with network jitter and other transmission faults", - "Philippe Kalaf <philippe.kalaf@collabora.co.uk>, " - "Wim Taymans <wim.taymans@gmail.com>"); - -/* RTPJitterBuffer signals and args */ -enum -{ - SIGNAL_REQUEST_PT_MAP, - SIGNAL_CLEAR_PT_MAP, - SIGNAL_HANDLE_SYNC, - SIGNAL_ON_NPT_STOP, - LAST_SIGNAL -}; - -#define DEFAULT_LATENCY_MS 200 -#define DEFAULT_DROP_ON_LATENCY FALSE -#define DEFAULT_TS_OFFSET 0 -#define DEFAULT_DO_LOST FALSE - -enum -{ - PROP_0, - PROP_LATENCY, - PROP_DROP_ON_LATENCY, - PROP_TS_OFFSET, - PROP_DO_LOST, - PROP_LAST -}; - -#define JBUF_LOCK(priv) (g_mutex_lock ((priv)->jbuf_lock)) - -#define JBUF_LOCK_CHECK(priv,label) G_STMT_START { \ - JBUF_LOCK (priv); \ - if (G_UNLIKELY (priv->srcresult != GST_FLOW_OK)) \ - goto label; \ -} G_STMT_END - -#define JBUF_UNLOCK(priv) (g_mutex_unlock ((priv)->jbuf_lock)) -#define JBUF_WAIT(priv) (g_cond_wait ((priv)->jbuf_cond, (priv)->jbuf_lock)) - -#define JBUF_WAIT_CHECK(priv,label) G_STMT_START { \ - JBUF_WAIT(priv); \ - if (G_UNLIKELY (priv->srcresult != GST_FLOW_OK)) \ - goto label; \ -} G_STMT_END - -#define JBUF_SIGNAL(priv) (g_cond_signal ((priv)->jbuf_cond)) - -struct _GstRtpJitterBufferPrivate -{ - GstPad *sinkpad, *srcpad; - GstPad *rtcpsinkpad; - - RTPJitterBuffer *jbuf; - GMutex *jbuf_lock; - GCond *jbuf_cond; - gboolean waiting; - gboolean discont; - - /* properties */ - guint latency_ms; - gboolean drop_on_latency; - gint64 ts_offset; - gboolean do_lost; - - /* the last seqnum we pushed out */ - guint32 last_popped_seqnum; - /* the next expected seqnum we push */ - guint32 next_seqnum; - /* last output time */ - GstClockTime last_out_time; - /* the next expected seqnum we receive */ - guint32 next_in_seqnum; - - /* start and stop ranges */ - GstClockTime npt_start; - GstClockTime npt_stop; - guint64 ext_timestamp; - guint64 last_elapsed; - guint64 estimated_eos; - GstClockID eos_id; - gboolean reached_npt_stop; - - /* state */ - gboolean eos; - - /* clock rate and rtp timestamp offset */ - gint last_pt; - gint32 clock_rate; - gint64 clock_base; - gint64 prev_ts_offset; - - /* when we are shutting down */ - GstFlowReturn srcresult; - gboolean blocked; - - /* for sync */ - GstSegment segment; - GstClockID clock_id; - gboolean unscheduled; - /* the latency of the upstream peer, we have to take this into account when - * synchronizing the buffers. */ - GstClockTime peer_latency; - - /* some accounting */ - guint64 num_late; - guint64 num_duplicates; -}; - -#define GST_RTP_JITTER_BUFFER_GET_PRIVATE(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((o), GST_TYPE_RTP_JITTER_BUFFER, \ - GstRtpJitterBufferPrivate)) - -static GstStaticPadTemplate gst_rtp_jitter_buffer_sink_template = -GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("application/x-rtp, " - "clock-rate = (int) [ 1, 2147483647 ]" - /* "payload = (int) , " - * "encoding-name = (string) " - */ ) - ); - -static GstStaticPadTemplate gst_rtp_jitter_buffer_sink_rtcp_template = -GST_STATIC_PAD_TEMPLATE ("sink_rtcp", - GST_PAD_SINK, - GST_PAD_REQUEST, - GST_STATIC_CAPS ("application/x-rtcp") - ); - -static GstStaticPadTemplate gst_rtp_jitter_buffer_src_template = -GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("application/x-rtp" - /* "payload = (int) , " - * "clock-rate = (int) , " - * "encoding-name = (string) " - */ ) - ); - -static guint gst_rtp_jitter_buffer_signals[LAST_SIGNAL] = { 0 }; - -GST_BOILERPLATE (GstRtpJitterBuffer, gst_rtp_jitter_buffer, GstElement, - GST_TYPE_ELEMENT); - -/* object overrides */ -static void gst_rtp_jitter_buffer_set_property (GObject * object, - guint prop_id, const GValue * value, GParamSpec * pspec); -static void gst_rtp_jitter_buffer_get_property (GObject * object, - guint prop_id, GValue * value, GParamSpec * pspec); -static void gst_rtp_jitter_buffer_finalize (GObject * object); - -/* element overrides */ -static GstStateChangeReturn gst_rtp_jitter_buffer_change_state (GstElement - * element, GstStateChange transition); -static GstPad *gst_rtp_jitter_buffer_request_new_pad (GstElement * element, - GstPadTemplate * templ, const gchar * name); -static void gst_rtp_jitter_buffer_release_pad (GstElement * element, - GstPad * pad); - -/* pad overrides */ -static GstCaps *gst_rtp_jitter_buffer_getcaps (GstPad * pad); -static GList *gst_rtp_jitter_buffer_internal_links (GstPad * pad); - -/* sinkpad overrides */ -static gboolean gst_jitter_buffer_sink_setcaps (GstPad * pad, GstCaps * caps); -static gboolean gst_rtp_jitter_buffer_sink_event (GstPad * pad, - GstEvent * event); -static GstFlowReturn gst_rtp_jitter_buffer_chain (GstPad * pad, - GstBuffer * buffer); - -static gboolean gst_rtp_jitter_buffer_sink_rtcp_event (GstPad * pad, - GstEvent * event); -static GstFlowReturn gst_rtp_jitter_buffer_chain_rtcp (GstPad * pad, - GstBuffer * buffer); - -/* srcpad overrides */ -static gboolean gst_rtp_jitter_buffer_src_event (GstPad * pad, - GstEvent * event); -static gboolean -gst_rtp_jitter_buffer_src_activate_push (GstPad * pad, gboolean active); -static void gst_rtp_jitter_buffer_loop (GstRtpJitterBuffer * jitterbuffer); -static gboolean gst_rtp_jitter_buffer_query (GstPad * pad, GstQuery * query); - -static void -gst_rtp_jitter_buffer_clear_pt_map (GstRtpJitterBuffer * jitterbuffer); - -static void -gst_rtp_jitter_buffer_base_init (gpointer klass) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS (klass); - - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&gst_rtp_jitter_buffer_src_template)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&gst_rtp_jitter_buffer_sink_template)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&gst_rtp_jitter_buffer_sink_rtcp_template)); - - gst_element_class_set_details (element_class, &gst_rtp_jitter_buffer_details); -} - -static void -gst_rtp_jitter_buffer_class_init (GstRtpJitterBufferClass * klass) -{ - GObjectClass *gobject_class; - GstElementClass *gstelement_class; - - gobject_class = (GObjectClass *) klass; - gstelement_class = (GstElementClass *) klass; - - g_type_class_add_private (klass, sizeof (GstRtpJitterBufferPrivate)); - - gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_rtp_jitter_buffer_finalize); - - gobject_class->set_property = gst_rtp_jitter_buffer_set_property; - gobject_class->get_property = gst_rtp_jitter_buffer_get_property; - - /** - * GstRtpJitterBuffer::latency: - * - * The maximum latency of the jitterbuffer. Packets will be kept in the buffer - * for at most this time. - */ - g_object_class_install_property (gobject_class, PROP_LATENCY, - g_param_spec_uint ("latency", "Buffer latency in ms", - "Amount of ms to buffer", 0, G_MAXUINT, DEFAULT_LATENCY_MS, - G_PARAM_READWRITE)); - /** - * GstRtpJitterBuffer::drop-on-latency: - * - * Drop oldest buffers when the queue is completely filled. - */ - g_object_class_install_property (gobject_class, PROP_DROP_ON_LATENCY, - g_param_spec_boolean ("drop-on-latency", - "Drop buffers when maximum latency is reached", - "Tells the jitterbuffer to never exceed the given latency in size", - DEFAULT_DROP_ON_LATENCY, G_PARAM_READWRITE)); - /** - * GstRtpJitterBuffer::ts-offset: - * - * Adjust GStreamer output buffer timestamps in the jitterbuffer with offset. - * This is mainly used to ensure interstream synchronisation. - */ - g_object_class_install_property (gobject_class, PROP_TS_OFFSET, - g_param_spec_int64 ("ts-offset", "Timestamp Offset", - "Adjust buffer timestamps with offset in nanoseconds", G_MININT64, - G_MAXINT64, DEFAULT_TS_OFFSET, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstRtpJitterBuffer::do-lost: - * - * Send out a GstRTPPacketLost event downstream when a packet is considered - * lost. - */ - g_object_class_install_property (gobject_class, PROP_DO_LOST, - g_param_spec_boolean ("do-lost", "Do Lost", - "Send an event downstream when a packet is lost", DEFAULT_DO_LOST, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - /** - * GstRtpJitterBuffer::request-pt-map: - * @buffer: the object which received the signal - * @pt: the pt - * - * Request the payload type as #GstCaps for @pt. - */ - gst_rtp_jitter_buffer_signals[SIGNAL_REQUEST_PT_MAP] = - g_signal_new ("request-pt-map", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpJitterBufferClass, - request_pt_map), NULL, NULL, gst_rtp_bin_marshal_BOXED__UINT, - GST_TYPE_CAPS, 1, G_TYPE_UINT); - /** - * GstRtpJitterBuffer::handle-sync: - * @buffer: the object which received the signal - * @struct: a GstStructure containing sync values. - * - * Be notified of new sync values. - */ - gst_rtp_jitter_buffer_signals[SIGNAL_HANDLE_SYNC] = - g_signal_new ("handle-sync", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpJitterBufferClass, - handle_sync), NULL, NULL, g_cclosure_marshal_VOID__BOXED, - G_TYPE_NONE, 1, GST_TYPE_STRUCTURE | G_SIGNAL_TYPE_STATIC_SCOPE); - - /** - * GstRtpJitterBuffer::on-npt-stop - * @buffer: the object which received the signal - * - * Signal that the jitterbufer has pushed the RTP packet that corresponds to - * the npt-stop position. - */ - gst_rtp_jitter_buffer_signals[SIGNAL_ON_NPT_STOP] = - g_signal_new ("on-npt-stop", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpJitterBufferClass, - on_npt_stop), NULL, NULL, g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0, G_TYPE_NONE); - - /** - * GstRtpJitterBuffer::clear-pt-map: - * @buffer: the object which received the signal - * - * Invalidate the clock-rate as obtained with the - * #GstRtpJitterBuffer::request-pt-map signal. - */ - gst_rtp_jitter_buffer_signals[SIGNAL_CLEAR_PT_MAP] = - g_signal_new ("clear-pt-map", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, - G_STRUCT_OFFSET (GstRtpJitterBufferClass, clear_pt_map), NULL, NULL, - g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0, G_TYPE_NONE); - - gstelement_class->change_state = - GST_DEBUG_FUNCPTR (gst_rtp_jitter_buffer_change_state); - gstelement_class->request_new_pad = - GST_DEBUG_FUNCPTR (gst_rtp_jitter_buffer_request_new_pad); - gstelement_class->release_pad = - GST_DEBUG_FUNCPTR (gst_rtp_jitter_buffer_release_pad); - - klass->clear_pt_map = GST_DEBUG_FUNCPTR (gst_rtp_jitter_buffer_clear_pt_map); - - GST_DEBUG_CATEGORY_INIT - (rtpjitterbuffer_debug, "gstrtpjitterbuffer", 0, "RTP Jitter Buffer"); -} - -static void -gst_rtp_jitter_buffer_init (GstRtpJitterBuffer * jitterbuffer, - GstRtpJitterBufferClass * klass) -{ - GstRtpJitterBufferPrivate *priv; - - priv = GST_RTP_JITTER_BUFFER_GET_PRIVATE (jitterbuffer); - jitterbuffer->priv = priv; - - priv->latency_ms = DEFAULT_LATENCY_MS; - priv->drop_on_latency = DEFAULT_DROP_ON_LATENCY; - priv->do_lost = DEFAULT_DO_LOST; - - priv->jbuf = rtp_jitter_buffer_new (); - priv->jbuf_lock = g_mutex_new (); - priv->jbuf_cond = g_cond_new (); - - priv->srcpad = - gst_pad_new_from_static_template (&gst_rtp_jitter_buffer_src_template, - "src"); - - gst_pad_set_activatepush_function (priv->srcpad, - GST_DEBUG_FUNCPTR (gst_rtp_jitter_buffer_src_activate_push)); - gst_pad_set_query_function (priv->srcpad, - GST_DEBUG_FUNCPTR (gst_rtp_jitter_buffer_query)); - gst_pad_set_getcaps_function (priv->srcpad, - GST_DEBUG_FUNCPTR (gst_rtp_jitter_buffer_getcaps)); - gst_pad_set_event_function (priv->srcpad, - GST_DEBUG_FUNCPTR (gst_rtp_jitter_buffer_src_event)); - - priv->sinkpad = - gst_pad_new_from_static_template (&gst_rtp_jitter_buffer_sink_template, - "sink"); - - gst_pad_set_chain_function (priv->sinkpad, - GST_DEBUG_FUNCPTR (gst_rtp_jitter_buffer_chain)); - gst_pad_set_event_function (priv->sinkpad, - GST_DEBUG_FUNCPTR (gst_rtp_jitter_buffer_sink_event)); - gst_pad_set_setcaps_function (priv->sinkpad, - GST_DEBUG_FUNCPTR (gst_jitter_buffer_sink_setcaps)); - gst_pad_set_getcaps_function (priv->sinkpad, - GST_DEBUG_FUNCPTR (gst_rtp_jitter_buffer_getcaps)); - - gst_element_add_pad (GST_ELEMENT (jitterbuffer), priv->srcpad); - gst_element_add_pad (GST_ELEMENT (jitterbuffer), priv->sinkpad); -} - -static void -gst_rtp_jitter_buffer_finalize (GObject * object) -{ - GstRtpJitterBuffer *jitterbuffer; - - jitterbuffer = GST_RTP_JITTER_BUFFER (object); - - g_mutex_free (jitterbuffer->priv->jbuf_lock); - g_cond_free (jitterbuffer->priv->jbuf_cond); - - g_object_unref (jitterbuffer->priv->jbuf); - - G_OBJECT_CLASS (parent_class)->finalize (object); -} - -static GList * -gst_rtp_jitter_buffer_internal_links (GstPad * pad) -{ - GstRtpJitterBuffer *jitterbuffer; - GstRtpJitterBufferPrivate *priv; - GList *res = NULL; - - jitterbuffer = GST_RTP_JITTER_BUFFER (gst_pad_get_parent (pad)); - priv = jitterbuffer->priv; - - if (pad == priv->sinkpad) { - res = g_list_prepend (res, priv->srcpad); - } else if (pad == priv->srcpad) { - res = g_list_prepend (res, priv->sinkpad); - } else if (pad == priv->rtcpsinkpad) { - res = NULL; - } - - gst_object_unref (jitterbuffer); - - return res; -} - -static GstPad * -create_rtcp_sink (GstRtpJitterBuffer * jitterbuffer) -{ - GstRtpJitterBufferPrivate *priv; - - priv = jitterbuffer->priv; - - GST_DEBUG_OBJECT (jitterbuffer, "creating RTCP sink pad"); - - priv->rtcpsinkpad = - gst_pad_new_from_static_template - (&gst_rtp_jitter_buffer_sink_rtcp_template, "sink_rtcp"); - gst_pad_set_chain_function (priv->rtcpsinkpad, - gst_rtp_jitter_buffer_chain_rtcp); - gst_pad_set_event_function (priv->rtcpsinkpad, - (GstPadEventFunction) gst_rtp_jitter_buffer_sink_rtcp_event); - gst_pad_set_internal_link_function (priv->rtcpsinkpad, - gst_rtp_jitter_buffer_internal_links); - gst_pad_set_active (priv->rtcpsinkpad, TRUE); - gst_element_add_pad (GST_ELEMENT_CAST (jitterbuffer), priv->rtcpsinkpad); - - return priv->rtcpsinkpad; -} - -static void -remove_rtcp_sink (GstRtpJitterBuffer * jitterbuffer) -{ - GstRtpJitterBufferPrivate *priv; - - priv = jitterbuffer->priv; - - GST_DEBUG_OBJECT (jitterbuffer, "removing RTCP sink pad"); - - gst_pad_set_active (priv->rtcpsinkpad, FALSE); - - gst_element_remove_pad (GST_ELEMENT_CAST (jitterbuffer), priv->rtcpsinkpad); - priv->rtcpsinkpad = NULL; -} - -static GstPad * -gst_rtp_jitter_buffer_request_new_pad (GstElement * element, - GstPadTemplate * templ, const gchar * name) -{ - GstRtpJitterBuffer *jitterbuffer; - GstElementClass *klass; - GstPad *result; - GstRtpJitterBufferPrivate *priv; - - g_return_val_if_fail (templ != NULL, NULL); - g_return_val_if_fail (GST_IS_RTP_JITTER_BUFFER (element), NULL); - - jitterbuffer = GST_RTP_JITTER_BUFFER (element); - priv = jitterbuffer->priv; - klass = GST_ELEMENT_GET_CLASS (element); - - GST_DEBUG_OBJECT (element, "requesting pad %s", GST_STR_NULL (name)); - - /* figure out the template */ - if (templ == gst_element_class_get_pad_template (klass, "sink_rtcp")) { - if (priv->rtcpsinkpad != NULL) - goto exists; - - result = create_rtcp_sink (jitterbuffer); - } else - goto wrong_template; - - return result; - - /* ERRORS */ -wrong_template: - { - g_warning ("gstrtpjitterbuffer: this is not our template"); - return NULL; - } -exists: - { - g_warning ("gstrtpjitterbuffer: pad already requested"); - return NULL; - } -} - -static void -gst_rtp_jitter_buffer_release_pad (GstElement * element, GstPad * pad) -{ - GstRtpJitterBuffer *jitterbuffer; - GstRtpJitterBufferPrivate *priv; - - g_return_if_fail (GST_IS_RTP_JITTER_BUFFER (element)); - g_return_if_fail (GST_IS_PAD (pad)); - - jitterbuffer = GST_RTP_JITTER_BUFFER (element); - priv = jitterbuffer->priv; - - GST_DEBUG_OBJECT (element, "releasing pad %s:%s", GST_DEBUG_PAD_NAME (pad)); - - if (priv->rtcpsinkpad == pad) { - remove_rtcp_sink (jitterbuffer); - } else - goto wrong_pad; - - return; - - /* ERRORS */ -wrong_pad: - { - g_warning ("gstjitterbuffer: asked to release an unknown pad"); - return; - } -} - -static void -gst_rtp_jitter_buffer_clear_pt_map (GstRtpJitterBuffer * jitterbuffer) -{ - GstRtpJitterBufferPrivate *priv; - - priv = jitterbuffer->priv; - - /* this will trigger a new pt-map request signal, FIXME, do something better. */ - priv->clock_rate = -1; -} - -static GstCaps * -gst_rtp_jitter_buffer_getcaps (GstPad * pad) -{ - GstRtpJitterBuffer *jitterbuffer; - GstRtpJitterBufferPrivate *priv; - GstPad *other; - GstCaps *caps; - const GstCaps *templ; - - jitterbuffer = GST_RTP_JITTER_BUFFER (gst_pad_get_parent (pad)); - priv = jitterbuffer->priv; - - other = (pad == priv->srcpad ? priv->sinkpad : priv->srcpad); - - caps = gst_pad_peer_get_caps (other); - - templ = gst_pad_get_pad_template_caps (pad); - if (caps == NULL) { - GST_DEBUG_OBJECT (jitterbuffer, "copy template"); - caps = gst_caps_copy (templ); - } else { - GstCaps *intersect; - - GST_DEBUG_OBJECT (jitterbuffer, "intersect with template"); - - intersect = gst_caps_intersect (caps, templ); - gst_caps_unref (caps); - - caps = intersect; - } - gst_object_unref (jitterbuffer); - - return caps; -} - -static gboolean -gst_jitter_buffer_sink_parse_caps (GstRtpJitterBuffer * jitterbuffer, - GstCaps * caps) -{ - GstRtpJitterBufferPrivate *priv; - GstStructure *caps_struct; - guint val; - GstClockTime tval; - - priv = jitterbuffer->priv; - - /* first parse the caps */ - caps_struct = gst_caps_get_structure (caps, 0); - - GST_DEBUG_OBJECT (jitterbuffer, "got caps"); - - /* we need a clock-rate to convert the rtp timestamps to GStreamer time and to - * measure the amount of data in the buffer */ - if (!gst_structure_get_int (caps_struct, "clock-rate", &priv->clock_rate)) - goto error; - - if (priv->clock_rate <= 0) - goto wrong_rate; - - GST_DEBUG_OBJECT (jitterbuffer, "got clock-rate %d", priv->clock_rate); - - /* The clock base is the RTP timestamp corrsponding to the npt-start value. We - * can use this to track the amount of time elapsed on the sender. */ - if (gst_structure_get_uint (caps_struct, "clock-base", &val)) - priv->clock_base = val; - else - priv->clock_base = -1; - - priv->ext_timestamp = priv->clock_base; - - GST_DEBUG_OBJECT (jitterbuffer, "got clock-base %" G_GINT64_FORMAT, - priv->clock_base); - - if (gst_structure_get_uint (caps_struct, "seqnum-base", &val)) { - /* first expected seqnum, only update when we didn't have a previous base. */ - if (priv->next_in_seqnum == -1) - priv->next_in_seqnum = val; - if (priv->next_seqnum == -1) - priv->next_seqnum = val; - } - - GST_DEBUG_OBJECT (jitterbuffer, "got seqnum-base %d", priv->next_in_seqnum); - - /* the start and stop times. The seqnum-base corresponds to the start time. We - * will keep track of the seqnums on the output and when we reach the one - * corresponding to npt-stop, we emit the npt-stop-reached signal */ - if (gst_structure_get_clock_time (caps_struct, "npt-start", &tval)) - priv->npt_start = tval; - else - priv->npt_start = 0; - - if (gst_structure_get_clock_time (caps_struct, "npt-stop", &tval)) - priv->npt_stop = tval; - else - priv->npt_stop = -1; - - GST_DEBUG_OBJECT (jitterbuffer, - "npt start/stop: %" GST_TIME_FORMAT "-%" GST_TIME_FORMAT, - GST_TIME_ARGS (priv->npt_start), GST_TIME_ARGS (priv->npt_stop)); - - return TRUE; - - /* ERRORS */ -error: - { - GST_DEBUG_OBJECT (jitterbuffer, "No clock-rate in caps!"); - return FALSE; - } -wrong_rate: - { - GST_DEBUG_OBJECT (jitterbuffer, "Invalid clock-rate %d", priv->clock_rate); - return FALSE; - } -} - -static gboolean -gst_jitter_buffer_sink_setcaps (GstPad * pad, GstCaps * caps) -{ - GstRtpJitterBuffer *jitterbuffer; - GstRtpJitterBufferPrivate *priv; - gboolean res; - - jitterbuffer = GST_RTP_JITTER_BUFFER (gst_pad_get_parent (pad)); - priv = jitterbuffer->priv; - - res = gst_jitter_buffer_sink_parse_caps (jitterbuffer, caps); - - /* set same caps on srcpad on success */ - if (res) - gst_pad_set_caps (priv->srcpad, caps); - - gst_object_unref (jitterbuffer); - - return res; -} - -static void -gst_rtp_jitter_buffer_flush_start (GstRtpJitterBuffer * jitterbuffer) -{ - GstRtpJitterBufferPrivate *priv; - - priv = jitterbuffer->priv; - - JBUF_LOCK (priv); - /* mark ourselves as flushing */ - priv->srcresult = GST_FLOW_WRONG_STATE; - GST_DEBUG_OBJECT (jitterbuffer, "Disabling pop on queue"); - /* this unblocks any waiting pops on the src pad task */ - JBUF_SIGNAL (priv); - /* unlock clock, we just unschedule, the entry will be released by the - * locking streaming thread. */ - if (priv->clock_id) { - gst_clock_id_unschedule (priv->clock_id); - priv->unscheduled = TRUE; - } - JBUF_UNLOCK (priv); -} - -static void -gst_rtp_jitter_buffer_flush_stop (GstRtpJitterBuffer * jitterbuffer) -{ - GstRtpJitterBufferPrivate *priv; - - priv = jitterbuffer->priv; - - JBUF_LOCK (priv); - GST_DEBUG_OBJECT (jitterbuffer, "Enabling pop on queue"); - /* Mark as non flushing */ - priv->srcresult = GST_FLOW_OK; - gst_segment_init (&priv->segment, GST_FORMAT_TIME); - priv->last_popped_seqnum = -1; - priv->last_out_time = -1; - priv->next_seqnum = -1; - priv->next_in_seqnum = -1; - priv->clock_rate = -1; - priv->eos = FALSE; - priv->estimated_eos = -1; - priv->last_elapsed = 0; - priv->reached_npt_stop = FALSE; - priv->ext_timestamp = -1; - GST_DEBUG_OBJECT (jitterbuffer, "flush and reset jitterbuffer"); - rtp_jitter_buffer_flush (priv->jbuf); - rtp_jitter_buffer_reset_skew (priv->jbuf); - JBUF_UNLOCK (priv); -} - -static gboolean -gst_rtp_jitter_buffer_src_activate_push (GstPad * pad, gboolean active) -{ - gboolean result = TRUE; - GstRtpJitterBuffer *jitterbuffer = NULL; - - jitterbuffer = GST_RTP_JITTER_BUFFER (gst_pad_get_parent (pad)); - - if (active) { - /* allow data processing */ - gst_rtp_jitter_buffer_flush_stop (jitterbuffer); - - /* start pushing out buffers */ - GST_DEBUG_OBJECT (jitterbuffer, "Starting task on srcpad"); - gst_pad_start_task (jitterbuffer->priv->srcpad, - (GstTaskFunction) gst_rtp_jitter_buffer_loop, jitterbuffer); - } else { - /* make sure all data processing stops ASAP */ - gst_rtp_jitter_buffer_flush_start (jitterbuffer); - - /* NOTE this will hardlock if the state change is called from the src pad - * task thread because we will _join() the thread. */ - GST_DEBUG_OBJECT (jitterbuffer, "Stopping task on srcpad"); - result = gst_pad_stop_task (pad); - } - - gst_object_unref (jitterbuffer); - - return result; -} - -static GstStateChangeReturn -gst_rtp_jitter_buffer_change_state (GstElement * element, - GstStateChange transition) -{ - GstRtpJitterBuffer *jitterbuffer; - GstRtpJitterBufferPrivate *priv; - GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS; - - jitterbuffer = GST_RTP_JITTER_BUFFER (element); - priv = jitterbuffer->priv; - - switch (transition) { - case GST_STATE_CHANGE_NULL_TO_READY: - break; - case GST_STATE_CHANGE_READY_TO_PAUSED: - JBUF_LOCK (priv); - /* reset negotiated values */ - priv->clock_rate = -1; - priv->clock_base = -1; - priv->peer_latency = 0; - priv->last_pt = -1; - /* block until we go to PLAYING */ - priv->blocked = TRUE; - /* reset skew detection initialy */ - rtp_jitter_buffer_reset_skew (priv->jbuf); - JBUF_UNLOCK (priv); - break; - case GST_STATE_CHANGE_PAUSED_TO_PLAYING: - JBUF_LOCK (priv); - /* unblock to allow streaming in PLAYING */ - priv->blocked = FALSE; - JBUF_SIGNAL (priv); - JBUF_UNLOCK (priv); - break; - default: - break; - } - - ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); - - switch (transition) { - case GST_STATE_CHANGE_READY_TO_PAUSED: - /* we are a live element because we sync to the clock, which we can only - * do in the PLAYING state */ - if (ret != GST_STATE_CHANGE_FAILURE) - ret = GST_STATE_CHANGE_NO_PREROLL; - break; - case GST_STATE_CHANGE_PLAYING_TO_PAUSED: - JBUF_LOCK (priv); - /* block to stop streaming when PAUSED */ - priv->blocked = TRUE; - JBUF_UNLOCK (priv); - if (ret != GST_STATE_CHANGE_FAILURE) - ret = GST_STATE_CHANGE_NO_PREROLL; - break; - case GST_STATE_CHANGE_PAUSED_TO_READY: - break; - case GST_STATE_CHANGE_READY_TO_NULL: - break; - default: - break; - } - - return ret; -} - -static gboolean -gst_rtp_jitter_buffer_src_event (GstPad * pad, GstEvent * event) -{ - gboolean ret = TRUE; - GstRtpJitterBuffer *jitterbuffer; - GstRtpJitterBufferPrivate *priv; - - jitterbuffer = GST_RTP_JITTER_BUFFER (gst_pad_get_parent (pad)); - priv = jitterbuffer->priv; - - GST_DEBUG_OBJECT (jitterbuffer, "received %s", GST_EVENT_TYPE_NAME (event)); - - switch (GST_EVENT_TYPE (event)) { - default: - ret = gst_pad_push_event (priv->sinkpad, event); - break; - } - gst_object_unref (jitterbuffer); - - return ret; -} - -static gboolean -gst_rtp_jitter_buffer_sink_event (GstPad * pad, GstEvent * event) -{ - gboolean ret = TRUE; - GstRtpJitterBuffer *jitterbuffer; - GstRtpJitterBufferPrivate *priv; - - jitterbuffer = GST_RTP_JITTER_BUFFER (gst_pad_get_parent (pad)); - priv = jitterbuffer->priv; - - GST_DEBUG_OBJECT (jitterbuffer, "received %s", GST_EVENT_TYPE_NAME (event)); - - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_NEWSEGMENT: - { - GstFormat format; - gdouble rate, arate; - gint64 start, stop, time; - gboolean update; - - gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format, - &start, &stop, &time); - - /* we need time for now */ - if (format != GST_FORMAT_TIME) - goto newseg_wrong_format; - - GST_DEBUG_OBJECT (jitterbuffer, - "newsegment: update %d, rate %g, arate %g, start %" GST_TIME_FORMAT - ", stop %" GST_TIME_FORMAT ", time %" GST_TIME_FORMAT, - update, rate, arate, GST_TIME_ARGS (start), GST_TIME_ARGS (stop), - GST_TIME_ARGS (time)); - - /* now configure the values, we need these to time the release of the - * buffers on the srcpad. */ - gst_segment_set_newsegment_full (&priv->segment, update, - rate, arate, format, start, stop, time); - - /* FIXME, push SEGMENT in the queue. Sorting order might be difficult. */ - ret = gst_pad_push_event (priv->srcpad, event); - break; - } - case GST_EVENT_FLUSH_START: - gst_rtp_jitter_buffer_flush_start (jitterbuffer); - ret = gst_pad_push_event (priv->srcpad, event); - break; - case GST_EVENT_FLUSH_STOP: - ret = gst_pad_push_event (priv->srcpad, event); - ret = gst_rtp_jitter_buffer_src_activate_push (priv->srcpad, TRUE); - break; - case GST_EVENT_EOS: - { - /* push EOS in queue. We always push it at the head */ - JBUF_LOCK (priv); - /* check for flushing, we need to discard the event and return FALSE when - * we are flushing */ - ret = priv->srcresult == GST_FLOW_OK; - if (ret && !priv->eos) { - GST_DEBUG_OBJECT (jitterbuffer, "queuing EOS"); - priv->eos = TRUE; - JBUF_SIGNAL (priv); - } else if (priv->eos) { - GST_DEBUG_OBJECT (jitterbuffer, "dropping EOS, we are already EOS"); - } else { - GST_DEBUG_OBJECT (jitterbuffer, "dropping EOS, reason %s", - gst_flow_get_name (priv->srcresult)); - } - JBUF_UNLOCK (priv); - gst_event_unref (event); - break; - } - default: - ret = gst_pad_push_event (priv->srcpad, event); - break; - } - -done: - gst_object_unref (jitterbuffer); - - return ret; - - /* ERRORS */ -newseg_wrong_format: - { - GST_DEBUG_OBJECT (jitterbuffer, "received non TIME newsegment"); - ret = FALSE; - goto done; - } -} - -static gboolean -gst_rtp_jitter_buffer_sink_rtcp_event (GstPad * pad, GstEvent * event) -{ - GstRtpJitterBuffer *jitterbuffer; - GstRtpJitterBufferPrivate *priv; - - jitterbuffer = GST_RTP_JITTER_BUFFER (gst_pad_get_parent (pad)); - priv = jitterbuffer->priv; - - GST_DEBUG_OBJECT (jitterbuffer, "received %s", GST_EVENT_TYPE_NAME (event)); - - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_FLUSH_START: - break; - case GST_EVENT_FLUSH_STOP: - break; - default: - break; - } - gst_event_unref (event); - gst_object_unref (jitterbuffer); - - return TRUE; -} - -static gboolean -gst_rtp_jitter_buffer_get_clock_rate (GstRtpJitterBuffer * jitterbuffer, - guint8 pt) -{ - GValue ret = { 0 }; - GValue args[2] = { {0}, {0} }; - GstCaps *caps; - gboolean res; - - g_value_init (&args[0], GST_TYPE_ELEMENT); - g_value_set_object (&args[0], jitterbuffer); - g_value_init (&args[1], G_TYPE_UINT); - g_value_set_uint (&args[1], pt); - - g_value_init (&ret, GST_TYPE_CAPS); - g_value_set_boxed (&ret, NULL); - - g_signal_emitv (args, gst_rtp_jitter_buffer_signals[SIGNAL_REQUEST_PT_MAP], 0, - &ret); - - g_value_unset (&args[0]); - g_value_unset (&args[1]); - caps = (GstCaps *) g_value_dup_boxed (&ret); - g_value_unset (&ret); - if (!caps) - goto no_caps; - - res = gst_jitter_buffer_sink_parse_caps (jitterbuffer, caps); - - gst_caps_unref (caps); - - return res; - - /* ERRORS */ -no_caps: - { - GST_DEBUG_OBJECT (jitterbuffer, "could not get caps"); - return FALSE; - } -} - -static GstFlowReturn -gst_rtp_jitter_buffer_chain (GstPad * pad, GstBuffer * buffer) -{ - GstRtpJitterBuffer *jitterbuffer; - GstRtpJitterBufferPrivate *priv; - guint16 seqnum; - GstFlowReturn ret = GST_FLOW_OK; - GstClockTime timestamp; - guint64 latency_ts; - gboolean tail; - guint8 pt; - - jitterbuffer = GST_RTP_JITTER_BUFFER (gst_pad_get_parent (pad)); - - if (G_UNLIKELY (!gst_rtp_buffer_validate (buffer))) - goto invalid_buffer; - - priv = jitterbuffer->priv; - - pt = gst_rtp_buffer_get_payload_type (buffer); - - if (G_UNLIKELY (priv->last_pt != pt)) { - GstCaps *caps; - - GST_DEBUG_OBJECT (jitterbuffer, "pt changed from %u to %u", priv->last_pt, - pt); - - priv->last_pt = pt; - /* reset clock-rate so that we get a new one */ - priv->clock_rate = -1; - /* Try to get the clock-rate from the caps first if we can. If there are no - * caps we must fire the signal to get the clock-rate. */ - if ((caps = GST_BUFFER_CAPS (buffer))) { - gst_jitter_buffer_sink_parse_caps (jitterbuffer, caps); - } - } - - if (G_UNLIKELY (priv->clock_rate == -1)) { - /* no clock rate given on the caps, try to get one with the signal */ - gst_rtp_jitter_buffer_get_clock_rate (jitterbuffer, pt); - if (G_UNLIKELY (priv->clock_rate == -1)) - goto no_clock_rate; - } - - /* take the timestamp of the buffer. This is the time when the packet was - * received and is used to calculate jitter and clock skew. We will adjust - * this timestamp with the smoothed value after processing it in the - * jitterbuffer. */ - timestamp = GST_BUFFER_TIMESTAMP (buffer); - /* bring to running time */ - timestamp = gst_segment_to_running_time (&priv->segment, GST_FORMAT_TIME, - timestamp); - - seqnum = gst_rtp_buffer_get_seq (buffer); - - GST_DEBUG_OBJECT (jitterbuffer, - "Received packet #%d at time %" GST_TIME_FORMAT, seqnum, - GST_TIME_ARGS (timestamp)); - - JBUF_LOCK_CHECK (priv, out_flushing); - /* don't accept more data on EOS */ - if (G_UNLIKELY (priv->eos)) - goto have_eos; - - /* now check against our expected seqnum */ - if (G_LIKELY (priv->next_in_seqnum != -1)) { - gint gap; - gboolean reset = FALSE; - - gap = gst_rtp_buffer_compare_seqnum (priv->next_in_seqnum, seqnum); - if (G_UNLIKELY (gap != 0)) { - GST_DEBUG_OBJECT (jitterbuffer, "expected #%d, got #%d, gap of %d", - priv->next_in_seqnum, seqnum, gap); - /* priv->next_in_seqnum >= seqnum, this packet is too late or the - * sender might have been restarted with different seqnum. */ - if (gap < -RTP_MAX_MISORDER) { - GST_DEBUG_OBJECT (jitterbuffer, "reset: buffer too old %d", gap); - reset = TRUE; - } - /* priv->next_in_seqnum < seqnum, this is a new packet */ - else if (G_UNLIKELY (gap > RTP_MAX_DROPOUT)) { - GST_DEBUG_OBJECT (jitterbuffer, "reset: too many dropped packets %d", - gap); - reset = TRUE; - } else { - GST_DEBUG_OBJECT (jitterbuffer, "tolerable gap"); - } - } - if (G_UNLIKELY (reset)) { - GST_DEBUG_OBJECT (jitterbuffer, "flush and reset jitterbuffer"); - rtp_jitter_buffer_flush (priv->jbuf); - rtp_jitter_buffer_reset_skew (priv->jbuf); - priv->last_popped_seqnum = -1; - priv->next_seqnum = seqnum; - } - } - priv->next_in_seqnum = (seqnum + 1) & 0xffff; - - /* let's check if this buffer is too late, we can only accept packets with - * bigger seqnum than the one we last pushed. */ - if (G_LIKELY (priv->last_popped_seqnum != -1)) { - gint gap; - - gap = gst_rtp_buffer_compare_seqnum (priv->last_popped_seqnum, seqnum); - - /* priv->last_popped_seqnum >= seqnum, we're too late. */ - if (G_UNLIKELY (gap <= 0)) - goto too_late; - } - - /* let's drop oldest packet if the queue is already full and drop-on-latency - * is set. We can only do this when there actually is a latency. When no - * latency is set, we just pump it in the queue and let the other end push it - * out as fast as possible. */ - if (priv->latency_ms && priv->drop_on_latency) { - latency_ts = - gst_util_uint64_scale_int (priv->latency_ms, priv->clock_rate, 1000); - - if (G_UNLIKELY (rtp_jitter_buffer_get_ts_diff (priv->jbuf) >= latency_ts)) { - GstBuffer *old_buf; - - old_buf = rtp_jitter_buffer_pop (priv->jbuf); - - GST_DEBUG_OBJECT (jitterbuffer, "Queue full, dropping old packet #%d", - gst_rtp_buffer_get_seq (old_buf)); - - gst_buffer_unref (old_buf); - } - } - - /* we need to make the metadata writable before pushing it in the jitterbuffer - * because the jitterbuffer will update the timestamp */ - buffer = gst_buffer_make_metadata_writable (buffer); - - /* now insert the packet into the queue in sorted order. This function returns - * FALSE if a packet with the same seqnum was already in the queue, meaning we - * have a duplicate. */ - if (G_UNLIKELY (!rtp_jitter_buffer_insert (priv->jbuf, buffer, timestamp, - priv->clock_rate, &tail))) - goto duplicate; - - /* signal addition of new buffer when the _loop is waiting. */ - if (priv->waiting) - JBUF_SIGNAL (priv); - - /* let's unschedule and unblock any waiting buffers. We only want to do this - * when the tail buffer changed */ - if (G_UNLIKELY (priv->clock_id && tail)) { - GST_DEBUG_OBJECT (jitterbuffer, - "Unscheduling waiting buffer, new tail buffer"); - gst_clock_id_unschedule (priv->clock_id); - priv->unscheduled = TRUE; - } - - GST_DEBUG_OBJECT (jitterbuffer, "Pushed packet #%d, now %d packets, tail: %d", - seqnum, rtp_jitter_buffer_num_packets (priv->jbuf), tail); - -finished: - JBUF_UNLOCK (priv); - - gst_object_unref (jitterbuffer); - - return ret; - - /* ERRORS */ -invalid_buffer: - { - /* this is not fatal but should be filtered earlier */ - GST_ELEMENT_WARNING (jitterbuffer, STREAM, DECODE, (NULL), - ("Received invalid RTP payload, dropping")); - gst_buffer_unref (buffer); - gst_object_unref (jitterbuffer); - return GST_FLOW_OK; - } -no_clock_rate: - { - GST_WARNING_OBJECT (jitterbuffer, - "No clock-rate in caps!, dropping buffer"); - gst_buffer_unref (buffer); - gst_object_unref (jitterbuffer); - return GST_FLOW_OK; - } -out_flushing: - { - ret = priv->srcresult; - GST_DEBUG_OBJECT (jitterbuffer, "flushing %s", gst_flow_get_name (ret)); - gst_buffer_unref (buffer); - goto finished; - } -have_eos: - { - ret = GST_FLOW_UNEXPECTED; - GST_WARNING_OBJECT (jitterbuffer, "we are EOS, refusing buffer"); - gst_buffer_unref (buffer); - goto finished; - } -too_late: - { - GST_WARNING_OBJECT (jitterbuffer, "Packet #%d too late as #%d was already" - " popped, dropping", seqnum, priv->last_popped_seqnum); - priv->num_late++; - gst_buffer_unref (buffer); - goto finished; - } -duplicate: - { - GST_WARNING_OBJECT (jitterbuffer, "Duplicate packet #%d detected, dropping", - seqnum); - priv->num_duplicates++; - gst_buffer_unref (buffer); - goto finished; - } -} - -static GstClockTime -apply_offset (GstRtpJitterBuffer * jitterbuffer, GstClockTime timestamp) -{ - GstRtpJitterBufferPrivate *priv; - - priv = jitterbuffer->priv; - - if (timestamp == -1) - return -1; - - /* apply the timestamp offset */ - timestamp += priv->ts_offset; - - return timestamp; -} - -static GstClockTime -get_sync_time (GstRtpJitterBuffer * jitterbuffer, GstClockTime timestamp) -{ - GstClockTime result; - GstRtpJitterBufferPrivate *priv; - - priv = jitterbuffer->priv; - - result = timestamp + GST_ELEMENT_CAST (jitterbuffer)->base_time; - /* add latency, this includes our own latency and the peer latency. */ - result += (priv->latency_ms * GST_MSECOND); - result += priv->peer_latency; - - return result; -} - -static gboolean -eos_reached (GstClock * clock, GstClockTime time, GstClockID id, - GstRtpJitterBuffer * jitterbuffer) -{ - GstRtpJitterBufferPrivate *priv; - - priv = jitterbuffer->priv; - - JBUF_LOCK_CHECK (priv, flushing); - if (priv->waiting) { - GST_DEBUG_OBJECT (jitterbuffer, "got the NPT timeout"); - priv->reached_npt_stop = TRUE; - JBUF_SIGNAL (priv); - } - JBUF_UNLOCK (priv); - - return TRUE; - - /* ERRORS */ -flushing: - { - JBUF_UNLOCK (priv); - return FALSE; - } -} - -/** - * This funcion will push out buffers on the source pad. - * - * For each pushed buffer, the seqnum is recorded, if the next buffer B has a - * different seqnum (missing packets before B), this function will wait for the - * missing packet to arrive up to the timestamp of buffer B. - */ -static void -gst_rtp_jitter_buffer_loop (GstRtpJitterBuffer * jitterbuffer) -{ - GstRtpJitterBufferPrivate *priv; - GstBuffer *outbuf; - GstFlowReturn result; - guint16 seqnum; - guint32 next_seqnum; - GstClockTime timestamp, out_time; - gboolean discont = FALSE; - gint gap; - GstClock *clock; - GstClockID id; - GstClockTime sync_time; - - priv = jitterbuffer->priv; - - JBUF_LOCK_CHECK (priv, flushing); -again: - GST_DEBUG_OBJECT (jitterbuffer, "Peeking item"); - while (TRUE) { - id = NULL; - /* always wait if we are blocked */ - if (G_LIKELY (!priv->blocked)) { - /* if we have a packet, we can exit the loop and grab it */ - if (rtp_jitter_buffer_num_packets (priv->jbuf) > 0) - break; - /* no packets but we are EOS, do eos logic */ - if (G_UNLIKELY (priv->eos)) - goto do_eos; - /* underrun, wait for packets or flushing now if we are expecting an EOS - * timeout, set the async timer for it too */ - if (priv->estimated_eos != -1 && !priv->reached_npt_stop) { - sync_time = get_sync_time (jitterbuffer, priv->estimated_eos); - - GST_OBJECT_LOCK (jitterbuffer); - clock = GST_ELEMENT_CLOCK (jitterbuffer); - if (clock) { - GST_DEBUG_OBJECT (jitterbuffer, "scheduling timeout"); - id = gst_clock_new_single_shot_id (clock, sync_time); - gst_clock_id_wait_async (id, (GstClockCallback) eos_reached, - jitterbuffer); - } - GST_OBJECT_UNLOCK (jitterbuffer); - } - } - /* now we wait */ - priv->waiting = TRUE; - JBUF_WAIT (priv); - priv->waiting = FALSE; - - if (id) { - /* unschedule any pending async notifications we might have */ - gst_clock_id_unschedule (id); - gst_clock_id_unref (id); - } - if (G_UNLIKELY (priv->srcresult != GST_FLOW_OK)) - goto flushing; - - if (id && priv->reached_npt_stop) { - goto do_npt_stop; - } - } - - /* peek a buffer, we're just looking at the timestamp and the sequence number. - * If all is fine, we'll pop and push it. If the sequence number is wrong we - * wait on the timestamp. In the chain function we will unlock the wait when a - * new buffer is available. The peeked buffer is valid for as long as we hold - * the jitterbuffer lock. */ - outbuf = rtp_jitter_buffer_peek (priv->jbuf); - - /* get the seqnum and the next expected seqnum */ - seqnum = gst_rtp_buffer_get_seq (outbuf); - next_seqnum = priv->next_seqnum; - - /* get the timestamp, this is already corrected for clock skew by the - * jitterbuffer */ - timestamp = GST_BUFFER_TIMESTAMP (outbuf); - - GST_DEBUG_OBJECT (jitterbuffer, - "Peeked buffer #%d, expect #%d, timestamp %" GST_TIME_FORMAT - ", now %d left", seqnum, next_seqnum, GST_TIME_ARGS (timestamp), - rtp_jitter_buffer_num_packets (priv->jbuf)); - - /* apply our timestamp offset to the incomming buffer, this will be our output - * timestamp. */ - out_time = apply_offset (jitterbuffer, timestamp); - - /* get the gap between this and the previous packet. If we don't know the - * previous packet seqnum assume no gap. */ - if (G_LIKELY (next_seqnum != -1)) { - gap = gst_rtp_buffer_compare_seqnum (next_seqnum, seqnum); - - /* if we have a packet that we already pushed or considered dropped, pop it - * off and get the next packet */ - if (G_UNLIKELY (gap < 0)) { - GST_DEBUG_OBJECT (jitterbuffer, "Old packet #%d, next #%d dropping", - seqnum, next_seqnum); - outbuf = rtp_jitter_buffer_pop (priv->jbuf); - gst_buffer_unref (outbuf); - goto again; - } - } else { - GST_DEBUG_OBJECT (jitterbuffer, "no next seqnum known, first packet"); - gap = -1; - } - - /* If we don't know what the next seqnum should be (== -1) we have to wait - * because it might be possible that we are not receiving this buffer in-order, - * a buffer with a lower seqnum could arrive later and we want to push that - * earlier buffer before this buffer then. - * If we know the expected seqnum, we can compare it to the current seqnum to - * determine if we have missing a packet. If we have a missing packet (which - * must be before this packet) we can wait for it until the deadline for this - * packet expires. */ - if (G_UNLIKELY (gap != 0 && out_time != -1)) { - GstClockReturn ret; - GstClockTime duration = GST_CLOCK_TIME_NONE; - - if (gap > 0) { - /* we have a gap */ - GST_WARNING_OBJECT (jitterbuffer, - "Sequence number GAP detected: expected %d instead of %d (%d missing)", - next_seqnum, seqnum, gap); - - if (priv->last_out_time != -1) { - GST_DEBUG_OBJECT (jitterbuffer, - "out_time %" GST_TIME_FORMAT ", last %" GST_TIME_FORMAT, - GST_TIME_ARGS (out_time), GST_TIME_ARGS (priv->last_out_time)); - /* interpolate between the current time and the last time based on - * number of packets we are missing, this is the estimated duration - * for the missing packet based on equidistant packet spacing. Also make - * sure we never go negative. */ - if (out_time > priv->last_out_time) - duration = (out_time - priv->last_out_time) / (gap + 1); - else - goto lost; - - GST_DEBUG_OBJECT (jitterbuffer, "duration %" GST_TIME_FORMAT, - GST_TIME_ARGS (duration)); - /* add this duration to the timestamp of the last packet we pushed */ - out_time = (priv->last_out_time + duration); - } - } else { - /* we don't know what the next_seqnum should be, wait for the last - * possible moment to push this buffer, maybe we get an earlier seqnum - * while we wait */ - GST_DEBUG_OBJECT (jitterbuffer, "First buffer %d, do sync", seqnum); - } - - GST_OBJECT_LOCK (jitterbuffer); - clock = GST_ELEMENT_CLOCK (jitterbuffer); - if (!clock) { - GST_OBJECT_UNLOCK (jitterbuffer); - /* let's just push if there is no clock */ - goto push_buffer; - } - - GST_DEBUG_OBJECT (jitterbuffer, "sync to timestamp %" GST_TIME_FORMAT, - GST_TIME_ARGS (out_time)); - - /* prepare for sync against clock */ - sync_time = get_sync_time (jitterbuffer, out_time); - - /* create an entry for the clock */ - id = priv->clock_id = gst_clock_new_single_shot_id (clock, sync_time); - priv->unscheduled = FALSE; - GST_OBJECT_UNLOCK (jitterbuffer); - - /* release the lock so that the other end can push stuff or unlock */ - JBUF_UNLOCK (priv); - - ret = gst_clock_id_wait (id, NULL); - - JBUF_LOCK (priv); - /* and free the entry */ - gst_clock_id_unref (id); - priv->clock_id = NULL; - - /* at this point, the clock could have been unlocked by a timeout, a new - * tail element was added to the queue or because we are shutting down. Check - * for shutdown first. */ - if G_UNLIKELY - ((priv->srcresult != GST_FLOW_OK)) - goto flushing; - - /* if we got unscheduled and we are not flushing, it's because a new tail - * element became available in the queue or we flushed the queue. - * Grab it and try to push or sync. */ - if (ret == GST_CLOCK_UNSCHEDULED || priv->unscheduled) { - GST_DEBUG_OBJECT (jitterbuffer, - "Wait got unscheduled, will retry to push with new buffer"); - goto again; - } - - lost: - /* we now timed out, this means we lost a packet or finished synchronizing - * on the first buffer. */ - if (gap > 0) { - GstEvent *event; - - /* we had a gap and thus we lost a packet. Create an event for this. */ - GST_DEBUG_OBJECT (jitterbuffer, "Packet #%d lost", next_seqnum); - priv->num_late++; - discont = TRUE; - - /* update our expected next packet */ - priv->last_popped_seqnum = next_seqnum; - priv->last_out_time = out_time; - priv->next_seqnum = (next_seqnum + 1) & 0xffff; - - if (priv->do_lost) { - /* create paket lost event */ - event = gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, - gst_structure_new ("GstRTPPacketLost", - "seqnum", G_TYPE_UINT, (guint) next_seqnum, - "timestamp", G_TYPE_UINT64, out_time, - "duration", G_TYPE_UINT64, duration, NULL)); - - JBUF_UNLOCK (priv); - gst_pad_push_event (priv->srcpad, event); - JBUF_LOCK_CHECK (priv, flushing); - } - /* look for next packet */ - goto again; - } - - /* there was no known gap,just the first packet, exit the loop and push */ - GST_DEBUG_OBJECT (jitterbuffer, "First packet #%d synced", seqnum); - - /* get new timestamp, latency might have changed */ - out_time = apply_offset (jitterbuffer, timestamp); - } -push_buffer: - - /* when we get here we are ready to pop and push the buffer */ - outbuf = rtp_jitter_buffer_pop (priv->jbuf); - - if (G_UNLIKELY (discont || priv->discont)) { - /* set DISCONT flag when we missed a packet. We pushed the buffer writable - * into the jitterbuffer so we can modify now. */ - GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DISCONT); - priv->discont = FALSE; - } - - /* apply timestamp with offset to buffer now */ - GST_BUFFER_TIMESTAMP (outbuf) = out_time; - - /* update the elapsed time when we need to check against the npt stop time. */ - if (priv->npt_stop != -1 && priv->ext_timestamp != -1 - && priv->clock_base != -1) { - guint64 ext_time, elapsed, estimated; - guint32 rtp_time; - - rtp_time = gst_rtp_buffer_get_timestamp (outbuf); - - GST_LOG_OBJECT (jitterbuffer, "rtp %" G_GUINT32_FORMAT ", ext %" - G_GUINT64_FORMAT, rtp_time, priv->ext_timestamp); - - if (rtp_time < priv->ext_timestamp) { - ext_time = priv->ext_timestamp; - } else { - ext_time = gst_rtp_buffer_ext_timestamp (&priv->ext_timestamp, rtp_time); - } - - if (ext_time > priv->clock_base) - elapsed = ext_time - priv->clock_base; - else - elapsed = 0; - - elapsed = gst_util_uint64_scale_int (elapsed, GST_SECOND, priv->clock_rate); - - if (elapsed > priv->last_elapsed) { - guint64 left; - - priv->last_elapsed = elapsed; - - left = priv->npt_stop - priv->npt_start; - - if (elapsed > 0) - estimated = gst_util_uint64_scale (out_time, left, elapsed); - else - estimated = -1; - - GST_LOG_OBJECT (jitterbuffer, "elapsed %" GST_TIME_FORMAT ", estimated %" - GST_TIME_FORMAT, GST_TIME_ARGS (elapsed), GST_TIME_ARGS (estimated)); - - priv->estimated_eos = estimated; - } - } - - /* now we are ready to push the buffer. Save the seqnum and release the lock - * so the other end can push stuff in the queue again. */ - priv->last_popped_seqnum = seqnum; - priv->last_out_time = out_time; - priv->next_seqnum = (seqnum + 1) & 0xffff; - JBUF_UNLOCK (priv); - - /* push buffer */ - GST_DEBUG_OBJECT (jitterbuffer, - "Pushing buffer %d, timestamp %" GST_TIME_FORMAT, seqnum, - GST_TIME_ARGS (out_time)); - result = gst_pad_push (priv->srcpad, outbuf); - if (G_UNLIKELY (result != GST_FLOW_OK)) - goto pause; - - return; - - /* ERRORS */ -do_eos: - { - /* store result, we are flushing now */ - GST_DEBUG_OBJECT (jitterbuffer, "We are EOS, pushing EOS downstream"); - priv->srcresult = GST_FLOW_UNEXPECTED; - gst_pad_pause_task (priv->srcpad); - JBUF_UNLOCK (priv); - gst_pad_push_event (priv->srcpad, gst_event_new_eos ()); - return; - } -do_npt_stop: - { - /* store result, we are flushing now */ - GST_DEBUG_OBJECT (jitterbuffer, "We reached the NPT stop"); - JBUF_UNLOCK (priv); - - g_signal_emit (jitterbuffer, - gst_rtp_jitter_buffer_signals[SIGNAL_ON_NPT_STOP], 0, NULL); - return; - } -flushing: - { - GST_DEBUG_OBJECT (jitterbuffer, "we are flushing"); - gst_pad_pause_task (priv->srcpad); - JBUF_UNLOCK (priv); - return; - } -pause: - { - GST_DEBUG_OBJECT (jitterbuffer, "pausing task, reason %s", - gst_flow_get_name (result)); - - JBUF_LOCK (priv); - /* store result */ - priv->srcresult = result; - /* we don't post errors or anything because upstream will do that for us - * when we pass the return value upstream. */ - gst_pad_pause_task (priv->srcpad); - JBUF_UNLOCK (priv); - return; - } -} - -static GstFlowReturn -gst_rtp_jitter_buffer_chain_rtcp (GstPad * pad, GstBuffer * buffer) -{ - GstRtpJitterBuffer *jitterbuffer; - GstRtpJitterBufferPrivate *priv; - GstFlowReturn ret = GST_FLOW_OK; - guint64 base_rtptime, timestamp; - guint32 clock_rate; - guint64 last_rtptime; - guint32 ssrc; - GstRTCPPacket packet; - guint64 ext_rtptime, diff; - guint32 rtptime; - gboolean drop = FALSE; - - jitterbuffer = GST_RTP_JITTER_BUFFER (gst_pad_get_parent (pad)); - - if (G_UNLIKELY (!gst_rtcp_buffer_validate (buffer))) - goto invalid_buffer; - - priv = jitterbuffer->priv; - - if (!gst_rtcp_buffer_get_first_packet (buffer, &packet)) - goto invalid_buffer; - - /* first packet must be SR or RR or else the validate would have failed */ - switch (gst_rtcp_packet_get_type (&packet)) { - case GST_RTCP_TYPE_SR: - gst_rtcp_packet_sr_get_sender_info (&packet, &ssrc, NULL, &rtptime, - NULL, NULL); - break; - default: - goto ignore_buffer; - } - - GST_DEBUG_OBJECT (jitterbuffer, "received RTCP of SSRC %08x", ssrc); - - JBUF_LOCK (priv); - /* convert the RTP timestamp to our extended timestamp, using the same offset - * we used in the jitterbuffer */ - ext_rtptime = priv->jbuf->ext_rtptime; - ext_rtptime = gst_rtp_buffer_ext_timestamp (&ext_rtptime, rtptime); - - /* get the last values from the jitterbuffer */ - rtp_jitter_buffer_get_sync (priv->jbuf, &base_rtptime, ×tamp, - &clock_rate, &last_rtptime); - - GST_DEBUG_OBJECT (jitterbuffer, "ext SR %" G_GUINT64_FORMAT ", base %" - G_GUINT64_FORMAT ", clock-rate %" G_GUINT32_FORMAT, - ext_rtptime, base_rtptime, clock_rate); - - if (base_rtptime == -1 || clock_rate == -1 || timestamp == -1) { - GST_DEBUG_OBJECT (jitterbuffer, "dropping, no RTP values"); - drop = TRUE; - } else { - /* we can't accept anything that happened before we did the last resync */ - if (base_rtptime > ext_rtptime) { - GST_DEBUG_OBJECT (jitterbuffer, "dropping, older than base time"); - drop = TRUE; - } else { - /* the SR RTP timestamp must be something close to what we last observed - * in the jitterbuffer */ - if (ext_rtptime > last_rtptime) { - /* check how far ahead it is to our RTP timestamps */ - diff = ext_rtptime - last_rtptime; - /* if bigger than 1 second, we drop it */ - if (diff > clock_rate) { - GST_DEBUG_OBJECT (jitterbuffer, "dropping, too far ahead"); - drop = TRUE; - } - GST_DEBUG_OBJECT (jitterbuffer, "ext last %" G_GUINT64_FORMAT ", diff %" - G_GUINT64_FORMAT, last_rtptime, diff); - } - } - } - JBUF_UNLOCK (priv); - - if (!drop) { - GstStructure *s; - - s = gst_structure_new ("application/x-rtp-sync", - "base-rtptime", G_TYPE_UINT64, base_rtptime, - "base-time", G_TYPE_UINT64, timestamp, - "clock-rate", G_TYPE_UINT, clock_rate, - "sr-ext-rtptime", G_TYPE_UINT64, ext_rtptime, - "sr-buffer", GST_TYPE_BUFFER, buffer, NULL); - - GST_DEBUG_OBJECT (jitterbuffer, "signaling sync"); - g_signal_emit (jitterbuffer, - gst_rtp_jitter_buffer_signals[SIGNAL_HANDLE_SYNC], 0, s); - gst_structure_free (s); - } else { - GST_DEBUG_OBJECT (jitterbuffer, "dropping RTCP packet"); - ret = GST_FLOW_OK; - } - -done: - gst_buffer_unref (buffer); - gst_object_unref (jitterbuffer); - - return ret; - -invalid_buffer: - { - /* this is not fatal but should be filtered earlier */ - GST_ELEMENT_WARNING (jitterbuffer, STREAM, DECODE, (NULL), - ("Received invalid RTCP payload, dropping")); - ret = GST_FLOW_OK; - goto done; - } -ignore_buffer: - { - GST_DEBUG_OBJECT (jitterbuffer, "ignoring RTCP packet"); - ret = GST_FLOW_OK; - goto done; - } -} - -static gboolean -gst_rtp_jitter_buffer_query (GstPad * pad, GstQuery * query) -{ - GstRtpJitterBuffer *jitterbuffer; - GstRtpJitterBufferPrivate *priv; - gboolean res = FALSE; - - jitterbuffer = GST_RTP_JITTER_BUFFER (gst_pad_get_parent (pad)); - priv = jitterbuffer->priv; - - switch (GST_QUERY_TYPE (query)) { - case GST_QUERY_LATENCY: - { - /* We need to send the query upstream and add the returned latency to our - * own */ - GstClockTime min_latency, max_latency; - gboolean us_live; - GstClockTime our_latency; - - if ((res = gst_pad_peer_query (priv->sinkpad, query))) { - gst_query_parse_latency (query, &us_live, &min_latency, &max_latency); - - GST_DEBUG_OBJECT (jitterbuffer, "Peer latency: min %" - GST_TIME_FORMAT " max %" GST_TIME_FORMAT, - GST_TIME_ARGS (min_latency), GST_TIME_ARGS (max_latency)); - - /* store this so that we can safely sync on the peer buffers. */ - JBUF_LOCK (priv); - priv->peer_latency = min_latency; - our_latency = ((guint64) priv->latency_ms) * GST_MSECOND; - JBUF_UNLOCK (priv); - - GST_DEBUG_OBJECT (jitterbuffer, "Our latency: %" GST_TIME_FORMAT, - GST_TIME_ARGS (our_latency)); - - /* we add some latency but can buffer an infinite amount of time */ - min_latency += our_latency; - max_latency = -1; - - GST_DEBUG_OBJECT (jitterbuffer, "Calculated total latency : min %" - GST_TIME_FORMAT " max %" GST_TIME_FORMAT, - GST_TIME_ARGS (min_latency), GST_TIME_ARGS (max_latency)); - - gst_query_set_latency (query, TRUE, min_latency, max_latency); - } - break; - } - default: - res = gst_pad_query_default (pad, query); - break; - } - - gst_object_unref (jitterbuffer); - - return res; -} - -static void -gst_rtp_jitter_buffer_set_property (GObject * object, - guint prop_id, const GValue * value, GParamSpec * pspec) -{ - GstRtpJitterBuffer *jitterbuffer; - GstRtpJitterBufferPrivate *priv; - - jitterbuffer = GST_RTP_JITTER_BUFFER (object); - priv = jitterbuffer->priv; - - switch (prop_id) { - case PROP_LATENCY: - { - guint new_latency, old_latency; - - new_latency = g_value_get_uint (value); - - JBUF_LOCK (priv); - old_latency = priv->latency_ms; - priv->latency_ms = new_latency; - JBUF_UNLOCK (priv); - - /* post message if latency changed, this will inform the parent pipeline - * that a latency reconfiguration is possible/needed. */ - if (new_latency != old_latency) { - GST_DEBUG_OBJECT (jitterbuffer, "latency changed to: %" GST_TIME_FORMAT, - GST_TIME_ARGS (new_latency * GST_MSECOND)); - - gst_element_post_message (GST_ELEMENT_CAST (jitterbuffer), - gst_message_new_latency (GST_OBJECT_CAST (jitterbuffer))); - } - break; - } - case PROP_DROP_ON_LATENCY: - JBUF_LOCK (priv); - priv->drop_on_latency = g_value_get_boolean (value); - JBUF_UNLOCK (priv); - break; - case PROP_TS_OFFSET: - JBUF_LOCK (priv); - priv->ts_offset = g_value_get_int64 (value); - /* FIXME, we don't really have a method for signaling a timestamp - * DISCONT without also making this a data discont. */ - /* priv->discont = TRUE; */ - JBUF_UNLOCK (priv); - break; - case PROP_DO_LOST: - JBUF_LOCK (priv); - priv->do_lost = g_value_get_boolean (value); - JBUF_UNLOCK (priv); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_rtp_jitter_buffer_get_property (GObject * object, - guint prop_id, GValue * value, GParamSpec * pspec) -{ - GstRtpJitterBuffer *jitterbuffer; - GstRtpJitterBufferPrivate *priv; - - jitterbuffer = GST_RTP_JITTER_BUFFER (object); - priv = jitterbuffer->priv; - - switch (prop_id) { - case PROP_LATENCY: - JBUF_LOCK (priv); - g_value_set_uint (value, priv->latency_ms); - JBUF_UNLOCK (priv); - break; - case PROP_DROP_ON_LATENCY: - JBUF_LOCK (priv); - g_value_set_boolean (value, priv->drop_on_latency); - JBUF_UNLOCK (priv); - break; - case PROP_TS_OFFSET: - JBUF_LOCK (priv); - g_value_set_int64 (value, priv->ts_offset); - JBUF_UNLOCK (priv); - break; - case PROP_DO_LOST: - JBUF_LOCK (priv); - g_value_set_boolean (value, priv->do_lost); - JBUF_UNLOCK (priv); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} diff --git a/gst/rtpmanager/gstrtpjitterbuffer.h b/gst/rtpmanager/gstrtpjitterbuffer.h deleted file mode 100644 index 6d7610e5..00000000 --- a/gst/rtpmanager/gstrtpjitterbuffer.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Farsight Voice+Video library - * - * Copyright 2007 Collabora Ltd, - * Copyright 2007 Nokia Corporation - * @author: Philippe Kalaf <philippe.kalaf@collabora.co.uk>. - * Copyright 2007 Wim Taymans <wim.taymans@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., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - */ - -#ifndef __GST_RTP_JITTER_BUFFER_H__ -#define __GST_RTP_JITTER_BUFFER_H__ - -#include <gst/gst.h> -#include <gst/rtp/gstrtpbuffer.h> - -G_BEGIN_DECLS - -/* #define's don't like whitespacey bits */ -#define GST_TYPE_RTP_JITTER_BUFFER \ - (gst_rtp_jitter_buffer_get_type()) -#define GST_RTP_JITTER_BUFFER(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_TYPE_RTP_JITTER_BUFFER,GstRtpJitterBuffer)) -#define GST_RTP_JITTER_BUFFER_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_TYPE_RTP_JITTER_BUFFER,GstRtpJitterBufferClass)) -#define GST_IS_RTP_JITTER_BUFFER(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_JITTER_BUFFER)) -#define GST_IS_RTP_JITTER_BUFFER_CLASS(obj) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_JITTER_BUFFER)) - -typedef struct _GstRtpJitterBuffer GstRtpJitterBuffer; -typedef struct _GstRtpJitterBufferClass GstRtpJitterBufferClass; -typedef struct _GstRtpJitterBufferPrivate GstRtpJitterBufferPrivate; - -/** - * GstRtpJitterBuffer: - * - * Opaque jitterbuffer structure. - */ -struct _GstRtpJitterBuffer -{ - GstElement parent; - - /*< private >*/ - GstRtpJitterBufferPrivate *priv; - - gpointer _gst_reserved[GST_PADDING]; -}; - -struct _GstRtpJitterBufferClass -{ - GstElementClass parent_class; - - /* signals */ - GstCaps* (*request_pt_map) (GstRtpJitterBuffer *buffer, guint pt); - - void (*handle_sync) (GstRtpJitterBuffer *buffer, GstStructure *s); - void (*on_npt_stop) (GstRtpJitterBuffer *buffer); - - /* actions */ - void (*clear_pt_map) (GstRtpJitterBuffer *buffer); - - /*< private > */ - gpointer _gst_reserved[GST_PADDING]; -}; - -GType gst_rtp_jitter_buffer_get_type (void); - -G_END_DECLS - -#endif /* __GST_RTP_JITTER_BUFFER_H__ */ diff --git a/gst/rtpmanager/gstrtpmanager.c b/gst/rtpmanager/gstrtpmanager.c deleted file mode 100644 index f38a77a8..00000000 --- a/gst/rtpmanager/gstrtpmanager.c +++ /dev/null @@ -1,60 +0,0 @@ -/* GStreamer - * Copyright (C) <2007> Wim Taymans <wim.taymans@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., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "gstrtpbin.h" -#include "gstrtpjitterbuffer.h" -#include "gstrtpptdemux.h" -#include "gstrtpsession.h" -#include "gstrtpssrcdemux.h" - -static gboolean -plugin_init (GstPlugin * plugin) -{ - if (!gst_element_register (plugin, "gstrtpbin", GST_RANK_NONE, - GST_TYPE_RTP_BIN)) - return FALSE; - - if (!gst_element_register (plugin, "gstrtpjitterbuffer", GST_RANK_NONE, - GST_TYPE_RTP_JITTER_BUFFER)) - return FALSE; - - if (!gst_element_register (plugin, "gstrtpptdemux", GST_RANK_NONE, - GST_TYPE_RTP_PT_DEMUX)) - return FALSE; - - if (!gst_element_register (plugin, "gstrtpsession", GST_RANK_NONE, - GST_TYPE_RTP_SESSION)) - return FALSE; - - if (!gst_element_register (plugin, "gstrtpssrcdemux", GST_RANK_NONE, - GST_TYPE_RTP_SSRC_DEMUX)) - return FALSE; - - return TRUE; -} - -GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, - GST_VERSION_MINOR, - "gstrtpmanager", - "RTP session management plugin library", - plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN) diff --git a/gst/rtpmanager/gstrtpptdemux.c b/gst/rtpmanager/gstrtpptdemux.c deleted file mode 100644 index 6e34705e..00000000 --- a/gst/rtpmanager/gstrtpptdemux.c +++ /dev/null @@ -1,492 +0,0 @@ -/* - * RTP Demux element - * - * Copyright (C) 2005 Nokia Corporation. - * @author Kai Vehmanen <kai.vehmanen@nokia.com> - * - * Loosely based on GStreamer gstdecodebin - * Copyright (C) <2004> Wim Taymans <wim.taymans@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., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/** - * SECTION:element-gstrtpptdemux - * - * gstrtpptdemux acts as a demuxer for RTP packets based on the payload type of - * the packets. Its main purpose is to allow an application to easily receive - * and decode an RTP stream with multiple payload types. - * - * For each payload type that is detected, a new pad will be created and the - * #GstRtpPtDemux::new-payload-type signal will be emitted. When the payload for - * the RTP stream changes, the #GstRtpPtDemux::payload-type-change signal will be - * emitted. - * - * The element will try to set complete and unique application/x-rtp caps on the - * outgoing buffers and pads based on the result of the - * #GstRtpPtDemux::request-pt-map signal. - * - * <refsect2> - * <title>Example pipelines</title> - * |[ - * gst-launch udpsrc caps="application/x-rtp" ! gstrtpptdemux ! fakesink - * ]| Takes an RTP stream and send the RTP packets with the first detected - * payload type to fakesink, discarding the other payload types. - * </refsect2> - * - * Last reviewed on 2007-05-28 (0.10.5) - */ - -/* - * Contributors: - * Andre Moreira Magalhaes <andre.magalhaes@indt.org.br> - */ -/* - * Status: - * - works with the test_rtpdemux.c tool - * - * Check: - * - is emitting a signal enough, or should we - * use GstEvent to notify downstream elements - * of the new packet... no? - * - * Notes: - * - emits event both for new PTs, and whenever - * a PT is changed - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <string.h> -#include <gst/gst.h> -#include <gst/rtp/gstrtpbuffer.h> - -#include "gstrtpbin-marshal.h" -#include "gstrtpptdemux.h" - -/* generic templates */ -static GstStaticPadTemplate rtp_pt_demux_sink_template = -GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("application/x-rtp") - ); - -static GstStaticPadTemplate rtp_pt_demux_src_template = -GST_STATIC_PAD_TEMPLATE ("src_%d", - GST_PAD_SRC, - GST_PAD_SOMETIMES, - GST_STATIC_CAPS ("application/x-rtp, " "payload = (int) [ 0, 255 ]") - ); - -GST_DEBUG_CATEGORY_STATIC (gst_rtp_pt_demux_debug); -#define GST_CAT_DEFAULT gst_rtp_pt_demux_debug - -/** - * Item for storing GstPad<->pt pairs. - */ -struct _GstRtpPtDemuxPad -{ - GstPad *pad; /**< pointer to the actual pad */ - gint pt; /**< RTP payload-type attached to pad */ - gboolean newcaps; -}; - -/* signals */ -enum -{ - SIGNAL_REQUEST_PT_MAP, - SIGNAL_NEW_PAYLOAD_TYPE, - SIGNAL_PAYLOAD_TYPE_CHANGE, - SIGNAL_CLEAR_PT_MAP, - LAST_SIGNAL -}; - -GST_BOILERPLATE (GstRtpPtDemux, gst_rtp_pt_demux, GstElement, GST_TYPE_ELEMENT); - -static void gst_rtp_pt_demux_finalize (GObject * object); - -static void gst_rtp_pt_demux_release (GstRtpPtDemux * ptdemux); -static gboolean gst_rtp_pt_demux_setup (GstRtpPtDemux * ptdemux); - -static GstFlowReturn gst_rtp_pt_demux_chain (GstPad * pad, GstBuffer * buf); -static GstStateChangeReturn gst_rtp_pt_demux_change_state (GstElement * element, - GstStateChange transition); -static void gst_rtp_pt_demux_clear_pt_map (GstRtpPtDemux * rtpdemux); - -static GstRtpPtDemuxPad *find_pad_for_pt (GstRtpPtDemux * rtpdemux, guint8 pt); - -static guint gst_rtp_pt_demux_signals[LAST_SIGNAL] = { 0 }; - -static GstElementDetails gst_rtp_pt_demux_details = { - "RTP Demux", - "Demux/Network/RTP", - "Parses codec streams transmitted in the same RTP session", - "Kai Vehmanen <kai.vehmanen@nokia.com>" -}; - -static void -gst_rtp_pt_demux_base_init (gpointer g_class) -{ - GstElementClass *gstelement_klass = GST_ELEMENT_CLASS (g_class); - - gst_element_class_add_pad_template (gstelement_klass, - gst_static_pad_template_get (&rtp_pt_demux_sink_template)); - gst_element_class_add_pad_template (gstelement_klass, - gst_static_pad_template_get (&rtp_pt_demux_src_template)); - - gst_element_class_set_details (gstelement_klass, &gst_rtp_pt_demux_details); -} - -static void -gst_rtp_pt_demux_class_init (GstRtpPtDemuxClass * klass) -{ - GObjectClass *gobject_klass; - GstElementClass *gstelement_klass; - - gobject_klass = (GObjectClass *) klass; - gstelement_klass = (GstElementClass *) klass; - - /** - * GstRtpPtDemux::request-pt-map: - * @demux: the object which received the signal - * @pt: the payload type - * - * Request the payload type as #GstCaps for @pt. - */ - gst_rtp_pt_demux_signals[SIGNAL_REQUEST_PT_MAP] = - g_signal_new ("request-pt-map", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpPtDemuxClass, request_pt_map), - NULL, NULL, gst_rtp_bin_marshal_BOXED__UINT, GST_TYPE_CAPS, 1, - G_TYPE_UINT); - - /** - * GstRtpPtDemux::new-payload-type: - * @demux: the object which received the signal - * @pt: the payload type - * @pad: the pad with the new payload - * - * Emited when a new payload type pad has been created in @demux. - */ - gst_rtp_pt_demux_signals[SIGNAL_NEW_PAYLOAD_TYPE] = - g_signal_new ("new-payload-type", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpPtDemuxClass, new_payload_type), - NULL, NULL, gst_rtp_bin_marshal_VOID__UINT_OBJECT, G_TYPE_NONE, 2, - G_TYPE_UINT, GST_TYPE_PAD); - - /** - * GstRtpPtDemux::payload-type-change: - * @demux: the object which received the signal - * @pt: the new payload type - * - * Emited when the payload type changed. - */ - gst_rtp_pt_demux_signals[SIGNAL_PAYLOAD_TYPE_CHANGE] = - g_signal_new ("payload-type-change", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpPtDemuxClass, - payload_type_change), NULL, NULL, g_cclosure_marshal_VOID__UINT, - G_TYPE_NONE, 1, G_TYPE_UINT); - - /** - * GstRtpPtDemux::clear-pt-map: - * @demux: the object which received the signal - * - * The application can call this signal to instruct the element to discard the - * currently cached payload type map. - */ - gst_rtp_pt_demux_signals[SIGNAL_CLEAR_PT_MAP] = - g_signal_new ("clear-pt-map", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_ACTION | G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpPtDemuxClass, - clear_pt_map), NULL, NULL, g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0, G_TYPE_NONE); - - gobject_klass->finalize = GST_DEBUG_FUNCPTR (gst_rtp_pt_demux_finalize); - - gstelement_klass->change_state = - GST_DEBUG_FUNCPTR (gst_rtp_pt_demux_change_state); - - klass->clear_pt_map = GST_DEBUG_FUNCPTR (gst_rtp_pt_demux_clear_pt_map); - - GST_DEBUG_CATEGORY_INIT (gst_rtp_pt_demux_debug, - "rtpptdemux", 0, "RTP codec demuxer"); -} - -static void -gst_rtp_pt_demux_init (GstRtpPtDemux * ptdemux, GstRtpPtDemuxClass * g_class) -{ - GstElementClass *klass = GST_ELEMENT_GET_CLASS (ptdemux); - - ptdemux->sink = - gst_pad_new_from_template (gst_element_class_get_pad_template (klass, - "sink"), "sink"); - g_assert (ptdemux->sink != NULL); - - gst_pad_set_chain_function (ptdemux->sink, gst_rtp_pt_demux_chain); - - gst_element_add_pad (GST_ELEMENT (ptdemux), ptdemux->sink); -} - -static void -gst_rtp_pt_demux_finalize (GObject * object) -{ - gst_rtp_pt_demux_release (GST_RTP_PT_DEMUX (object)); - - G_OBJECT_CLASS (parent_class)->finalize (object); -} - -static GstCaps * -gst_rtp_pt_demux_get_caps (GstRtpPtDemux * rtpdemux, guint pt) -{ - GstCaps *caps; - GValue ret = { 0 }; - GValue args[2] = { {0}, {0} }; - - /* figure out the caps */ - g_value_init (&args[0], GST_TYPE_ELEMENT); - g_value_set_object (&args[0], rtpdemux); - g_value_init (&args[1], G_TYPE_UINT); - g_value_set_uint (&args[1], pt); - - g_value_init (&ret, GST_TYPE_CAPS); - g_value_set_boxed (&ret, NULL); - - g_signal_emitv (args, gst_rtp_pt_demux_signals[SIGNAL_REQUEST_PT_MAP], 0, - &ret); - - g_value_unset (&args[0]); - g_value_unset (&args[1]); - caps = g_value_dup_boxed (&ret); - g_value_unset (&ret); - if (caps == NULL) { - caps = GST_PAD_CAPS (rtpdemux->sink); - if (caps) - gst_caps_ref (caps); - } - - GST_DEBUG ("pt %d, got caps %" GST_PTR_FORMAT, pt, caps); - - return caps; -} - -static void -gst_rtp_pt_demux_clear_pt_map (GstRtpPtDemux * rtpdemux) -{ - GSList *walk; - - GST_OBJECT_LOCK (rtpdemux); - GST_DEBUG ("clearing pt map"); - for (walk = rtpdemux->srcpads; walk; walk = g_slist_next (walk)) { - GstRtpPtDemuxPad *pad = walk->data; - - pad->newcaps = TRUE; - } - GST_OBJECT_UNLOCK (rtpdemux); -} - -static GstFlowReturn -gst_rtp_pt_demux_chain (GstPad * pad, GstBuffer * buf) -{ - GstFlowReturn ret = GST_FLOW_OK; - GstRtpPtDemux *rtpdemux; - GstElement *element = GST_ELEMENT (GST_OBJECT_PARENT (pad)); - guint8 pt; - GstPad *srcpad; - GstRtpPtDemuxPad *rtpdemuxpad; - GstCaps *caps; - - rtpdemux = GST_RTP_PT_DEMUX (GST_OBJECT_PARENT (pad)); - - if (!gst_rtp_buffer_validate (buf)) - goto invalid_buffer; - - pt = gst_rtp_buffer_get_payload_type (buf); - - GST_DEBUG_OBJECT (rtpdemux, "received buffer for pt %d", pt); - - rtpdemuxpad = find_pad_for_pt (rtpdemux, pt); - if (rtpdemuxpad == NULL) { - /* new PT, create a src pad */ - GstElementClass *klass; - GstPadTemplate *templ; - gchar *padname; - - klass = GST_ELEMENT_GET_CLASS (rtpdemux); - templ = gst_element_class_get_pad_template (klass, "src_%d"); - padname = g_strdup_printf ("src_%d", pt); - srcpad = gst_pad_new_from_template (templ, padname); - gst_pad_use_fixed_caps (srcpad); - g_free (padname); - - caps = gst_rtp_pt_demux_get_caps (rtpdemux, pt); - if (!caps) - goto no_caps; - - caps = gst_caps_make_writable (caps); - gst_caps_set_simple (caps, "payload", G_TYPE_INT, pt, NULL); - gst_pad_set_caps (srcpad, caps); - gst_caps_unref (caps); - - GST_DEBUG ("Adding pt=%d to the list.", pt); - rtpdemuxpad = g_new0 (GstRtpPtDemuxPad, 1); - rtpdemuxpad->pt = pt; - rtpdemuxpad->newcaps = FALSE; - rtpdemuxpad->pad = srcpad; - GST_OBJECT_LOCK (rtpdemux); - rtpdemux->srcpads = g_slist_append (rtpdemux->srcpads, rtpdemuxpad); - GST_OBJECT_UNLOCK (rtpdemux); - - gst_pad_set_active (srcpad, TRUE); - gst_element_add_pad (element, srcpad); - - GST_DEBUG ("emitting new-payload-type for pt %d", pt); - g_signal_emit (G_OBJECT (rtpdemux), - gst_rtp_pt_demux_signals[SIGNAL_NEW_PAYLOAD_TYPE], 0, pt, srcpad); - } - - srcpad = rtpdemuxpad->pad; - - if (pt != rtpdemux->last_pt) { - gint emit_pt = pt; - - /* our own signal with an extra flag that this is the only pad */ - rtpdemux->last_pt = pt; - GST_DEBUG ("emitting payload-type-changed for pt %d", emit_pt); - g_signal_emit (G_OBJECT (rtpdemux), - gst_rtp_pt_demux_signals[SIGNAL_PAYLOAD_TYPE_CHANGE], 0, emit_pt); - } - - if (rtpdemuxpad->newcaps) { - GST_DEBUG ("need new caps"); - caps = gst_rtp_pt_demux_get_caps (rtpdemux, pt); - if (!caps) - goto no_caps; - - caps = gst_caps_make_writable (caps); - gst_caps_set_simple (caps, "payload", G_TYPE_INT, pt, NULL); - gst_pad_set_caps (srcpad, caps); - gst_caps_unref (caps); - rtpdemuxpad->newcaps = FALSE; - } - - gst_buffer_set_caps (buf, GST_PAD_CAPS (srcpad)); - - /* push to srcpad */ - ret = gst_pad_push (srcpad, buf); - - return ret; - - /* ERRORS */ -invalid_buffer: - { - /* this is fatal and should be filtered earlier */ - GST_ELEMENT_ERROR (rtpdemux, STREAM, DECODE, (NULL), - ("Dropping invalid RTP payload")); - gst_buffer_unref (buf); - return GST_FLOW_ERROR; - } -no_caps: - { - GST_ELEMENT_ERROR (rtpdemux, STREAM, DECODE, (NULL), - ("Could not get caps for payload")); - gst_buffer_unref (buf); - return GST_FLOW_ERROR; - } -} - -static GstRtpPtDemuxPad * -find_pad_for_pt (GstRtpPtDemux * rtpdemux, guint8 pt) -{ - GstRtpPtDemuxPad *respad = NULL; - GSList *walk; - - for (walk = rtpdemux->srcpads; walk; walk = g_slist_next (walk)) { - GstRtpPtDemuxPad *pad = walk->data; - - if (pad->pt == pt) { - respad = pad; - break; - } - } - return respad; -} - -/** - * Reserves resources for the object. - */ -static gboolean -gst_rtp_pt_demux_setup (GstRtpPtDemux * ptdemux) -{ - ptdemux->srcpads = NULL; - ptdemux->last_pt = 0xFFFF; - - return TRUE; -} - -/** - * Free resources for the object. - */ -static void -gst_rtp_pt_demux_release (GstRtpPtDemux * ptdemux) -{ - GSList *walk; - - for (walk = ptdemux->srcpads; walk; walk = g_slist_next (walk)) { - GstRtpPtDemuxPad *pad = walk->data; - - gst_pad_set_active (pad->pad, FALSE); - gst_element_remove_pad (GST_ELEMENT_CAST (ptdemux), pad->pad); - g_free (pad); - } - g_slist_free (ptdemux->srcpads); - ptdemux->srcpads = NULL; -} - -static GstStateChangeReturn -gst_rtp_pt_demux_change_state (GstElement * element, GstStateChange transition) -{ - GstStateChangeReturn ret; - GstRtpPtDemux *ptdemux; - - ptdemux = GST_RTP_PT_DEMUX (element); - - switch (transition) { - case GST_STATE_CHANGE_NULL_TO_READY: - if (gst_rtp_pt_demux_setup (ptdemux) != TRUE) - ret = GST_STATE_CHANGE_FAILURE; - break; - case GST_STATE_CHANGE_READY_TO_PAUSED: - case GST_STATE_CHANGE_PAUSED_TO_PLAYING: - default: - break; - } - - ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); - - switch (transition) { - case GST_STATE_CHANGE_PLAYING_TO_PAUSED: - case GST_STATE_CHANGE_PAUSED_TO_READY: - break; - case GST_STATE_CHANGE_READY_TO_NULL: - gst_rtp_pt_demux_release (ptdemux); - break; - default: - break; - } - - return ret; -} diff --git a/gst/rtpmanager/gstrtpptdemux.h b/gst/rtpmanager/gstrtpptdemux.h deleted file mode 100644 index 028c97d4..00000000 --- a/gst/rtpmanager/gstrtpptdemux.h +++ /dev/null @@ -1,62 +0,0 @@ -/* GStreamer - * Copyright (C) <2007> Wim Taymans <wim.taymans@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., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __GST_RTP_PT_DEMUX_H__ -#define __GST_RTP_PT_DEMUX_H__ - -#include <gst/gst.h> - -#define GST_TYPE_RTP_PT_DEMUX (gst_rtp_pt_demux_get_type()) -#define GST_RTP_PT_DEMUX(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_PT_DEMUX,GstRtpPtDemux)) -#define GST_RTP_PT_DEMUX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_PT_DEMUX,GstRtpPtDemuxClass)) -#define GST_IS_RTP_PT_DEMUX(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_PT_DEMUX)) -#define GST_IS_RTP_PT_DEMUX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_PT_DEMUX)) - -typedef struct _GstRtpPtDemux GstRtpPtDemux; -typedef struct _GstRtpPtDemuxClass GstRtpPtDemuxClass; -typedef struct _GstRtpPtDemuxPad GstRtpPtDemuxPad; - -struct _GstRtpPtDemux -{ - GstElement parent; /**< parent class */ - - GstPad *sink; /**< the sink pad */ - guint16 last_pt; /**< pt of the last packet 0xFFFF if none */ - GSList *srcpads; /**< a linked list of GstRtpPtDemuxPad objects */ -}; - -struct _GstRtpPtDemuxClass -{ - GstElementClass parent_class; - - /* get the caps for pt */ - GstCaps* (*request_pt_map) (GstRtpPtDemux *demux, guint pt); - - /* signal emmited when a new PT is found from the incoming stream */ - void (*new_payload_type) (GstRtpPtDemux *demux, guint pt, GstPad * pad); - - /* signal emitted when the payload type changes */ - void (*payload_type_change) (GstRtpPtDemux *demux, guint pt); - - void (*clear_pt_map) (GstRtpPtDemux *demux); -}; - -GType gst_rtp_pt_demux_get_type (void); - -#endif /* __GST_RTP_PT_DEMUX_H__ */ diff --git a/gst/rtpmanager/gstrtpsession.c b/gst/rtpmanager/gstrtpsession.c deleted file mode 100644 index dcddb689..00000000 --- a/gst/rtpmanager/gstrtpsession.c +++ /dev/null @@ -1,1940 +0,0 @@ -/* GStreamer - * Copyright (C) <2007> Wim Taymans <wim.taymans@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., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/** - * SECTION:element-gstrtpsession - * @see_also: gstrtpjitterbuffer, gstrtpbin, gstrtpptdemux, gstrtpssrcdemux - * - * The RTP session manager models one participant with a unique SSRC in an RTP - * session. This session can be used to send and receive RTP and RTCP packets. - * Based on what REQUEST pads are requested from the session manager, specific - * functionality can be activated. - * - * The session manager currently implements RFC 3550 including: - * <itemizedlist> - * <listitem> - * <para>RTP packet validation based on consecutive sequence numbers.</para> - * </listitem> - * <listitem> - * <para>Maintainance of the SSRC participant database.</para> - * </listitem> - * <listitem> - * <para>Keeping per participant statistics based on received RTCP packets.</para> - * </listitem> - * <listitem> - * <para>Scheduling of RR/SR RTCP packets.</para> - * </listitem> - * </itemizedlist> - * - * The gstrtpsession will not demux packets based on SSRC or payload type, nor will - * it correct for packet reordering and jitter. Use #GstRtpsSrcDemux, - * #GstRtpPtDemux and GstRtpJitterBuffer in addition to #GstRtpSession to - * perform these tasks. It is usually a good idea to use #GstRtpBin, which - * combines all these features in one element. - * - * To use #GstRtpSession as an RTP receiver, request a recv_rtp_sink pad, which will - * automatically create recv_rtp_src pad. Data received on the recv_rtp_sink pad - * will be processed in the session and after being validated forwarded on the - * recv_rtp_src pad. - * - * To also use #GstRtpSession as an RTCP receiver, request a recv_rtcp_sink pad, - * which will automatically create a sync_src pad. Packets received on the RTCP - * pad will be used by the session manager to update the stats and database of - * the other participants. SR packets will be forwarded on the sync_src pad - * so that they can be used to perform inter-stream synchronisation when needed. - * - * If you want the session manager to generate and send RTCP packets, request - * the send_rtcp_src pad. Packet pushed on this pad contain SR/RR RTCP reports - * that should be sent to all participants in the session. - * - * To use #GstRtpSession as a sender, request a send_rtp_sink pad, which will - * automatically create a send_rtp_src pad. The session manager will modify the - * SSRC in the RTP packets to its own SSRC and wil forward the packets on the - * send_rtp_src pad after updating its internal state. - * - * The session manager needs the clock-rate of the payload types it is handling - * and will signal the #GstRtpSession::request-pt-map signal when it needs such a - * mapping. One can clear the cached values with the #GstRtpSession::clear-pt-map - * signal. - * - * <refsect2> - * <title>Example pipelines</title> - * |[ - * gst-launch udpsrc port=5000 caps="application/x-rtp, ..." ! .recv_rtp_sink gstrtpsession .recv_rtp_src ! rtptheoradepay ! theoradec ! xvimagesink - * ]| Receive theora RTP packets from port 5000 and send them to the depayloader, - * decoder and display. Note that the application/x-rtp caps on udpsrc should be - * configured based on some negotiation process such as RTSP for this pipeline - * to work correctly. - * |[ - * gst-launch udpsrc port=5000 caps="application/x-rtp, ..." ! .recv_rtp_sink gstrtpsession name=session \ - * .recv_rtp_src ! rtptheoradepay ! theoradec ! xvimagesink \ - * udpsrc port=5001 caps="application/x-rtcp" ! session.recv_rtcp_sink - * ]| Receive theora RTP packets from port 5000 and send them to the depayloader, - * decoder and display. Receive RTCP packets from port 5001 and process them in - * the session manager. - * Note that the application/x-rtp caps on udpsrc should be - * configured based on some negotiation process such as RTSP for this pipeline - * to work correctly. - * |[ - * gst-launch videotestsrc ! theoraenc ! rtptheorapay ! .send_rtp_sink gstrtpsession .send_rtp_src ! udpsink port=5000 - * ]| Send theora RTP packets through the session manager and out on UDP port - * 5000. - * |[ - * gst-launch videotestsrc ! theoraenc ! rtptheorapay ! .send_rtp_sink gstrtpsession name=session .send_rtp_src \ - * ! udpsink port=5000 session.send_rtcp_src ! udpsink port=5001 - * ]| Send theora RTP packets through the session manager and out on UDP port - * 5000. Send RTCP packets on port 5001. Note that this pipeline will not preroll - * correctly because the second udpsink will not preroll correctly (no RTCP - * packets are sent in the PAUSED state). Applications should manually set and - * keep (see gst_element_set_locked_state()) the RTCP udpsink to the PLAYING state. - * </refsect2> - * - * Last reviewed on 2007-05-28 (0.10.5) - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <gst/rtp/gstrtpbuffer.h> - -#include "gstrtpbin-marshal.h" -#include "gstrtpsession.h" -#include "rtpsession.h" - -GST_DEBUG_CATEGORY_STATIC (gst_rtp_session_debug); -#define GST_CAT_DEFAULT gst_rtp_session_debug - -/* elementfactory information */ -static const GstElementDetails rtpsession_details = -GST_ELEMENT_DETAILS ("RTP Session", - "Filter/Network/RTP", - "Implement an RTP session", - "Wim Taymans <wim.taymans@gmail.com>"); - -/* sink pads */ -static GstStaticPadTemplate rtpsession_recv_rtp_sink_template = -GST_STATIC_PAD_TEMPLATE ("recv_rtp_sink", - GST_PAD_SINK, - GST_PAD_REQUEST, - GST_STATIC_CAPS ("application/x-rtp") - ); - -static GstStaticPadTemplate rtpsession_recv_rtcp_sink_template = -GST_STATIC_PAD_TEMPLATE ("recv_rtcp_sink", - GST_PAD_SINK, - GST_PAD_REQUEST, - GST_STATIC_CAPS ("application/x-rtcp") - ); - -static GstStaticPadTemplate rtpsession_send_rtp_sink_template = -GST_STATIC_PAD_TEMPLATE ("send_rtp_sink", - GST_PAD_SINK, - GST_PAD_REQUEST, - GST_STATIC_CAPS ("application/x-rtp") - ); - -/* src pads */ -static GstStaticPadTemplate rtpsession_recv_rtp_src_template = -GST_STATIC_PAD_TEMPLATE ("recv_rtp_src", - GST_PAD_SRC, - GST_PAD_SOMETIMES, - GST_STATIC_CAPS ("application/x-rtp") - ); - -static GstStaticPadTemplate rtpsession_sync_src_template = -GST_STATIC_PAD_TEMPLATE ("sync_src", - GST_PAD_SRC, - GST_PAD_SOMETIMES, - GST_STATIC_CAPS ("application/x-rtcp") - ); - -static GstStaticPadTemplate rtpsession_send_rtp_src_template = -GST_STATIC_PAD_TEMPLATE ("send_rtp_src", - GST_PAD_SRC, - GST_PAD_SOMETIMES, - GST_STATIC_CAPS ("application/x-rtp") - ); - -static GstStaticPadTemplate rtpsession_send_rtcp_src_template = -GST_STATIC_PAD_TEMPLATE ("send_rtcp_src", - GST_PAD_SRC, - GST_PAD_REQUEST, - GST_STATIC_CAPS ("application/x-rtcp") - ); - -/* signals and args */ -enum -{ - SIGNAL_REQUEST_PT_MAP, - SIGNAL_CLEAR_PT_MAP, - - SIGNAL_ON_NEW_SSRC, - SIGNAL_ON_SSRC_COLLISION, - SIGNAL_ON_SSRC_VALIDATED, - SIGNAL_ON_SSRC_ACTIVE, - SIGNAL_ON_SSRC_SDES, - SIGNAL_ON_BYE_SSRC, - SIGNAL_ON_BYE_TIMEOUT, - SIGNAL_ON_TIMEOUT, - SIGNAL_ON_SENDER_TIMEOUT, - LAST_SIGNAL -}; - -#define DEFAULT_NTP_NS_BASE 0 -#define DEFAULT_BANDWIDTH RTP_STATS_BANDWIDTH -#define DEFAULT_RTCP_FRACTION RTP_STATS_RTCP_BANDWIDTH -#define DEFAULT_SDES NULL -#define DEFAULT_NUM_SOURCES 0 -#define DEFAULT_NUM_ACTIVE_SOURCES 0 - -enum -{ - PROP_0, - PROP_NTP_NS_BASE, - PROP_BANDWIDTH, - PROP_RTCP_FRACTION, - PROP_SDES, - PROP_NUM_SOURCES, - PROP_NUM_ACTIVE_SOURCES, - PROP_INTERNAL_SESSION, - PROP_LAST -}; - -#define GST_RTP_SESSION_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_RTP_SESSION, GstRtpSessionPrivate)) - -#define GST_RTP_SESSION_LOCK(sess) g_mutex_lock ((sess)->priv->lock) -#define GST_RTP_SESSION_UNLOCK(sess) g_mutex_unlock ((sess)->priv->lock) - -struct _GstRtpSessionPrivate -{ - GMutex *lock; - GstClock *sysclock; - - RTPSession *session; - - /* thread for sending out RTCP */ - GstClockID id; - gboolean stop_thread; - GThread *thread; - gboolean thread_stopped; - - /* caps mapping */ - GHashTable *ptmap; - - /* NTP base time */ - guint64 ntpnsbase; -}; - -/* callbacks to handle actions from the session manager */ -static GstFlowReturn gst_rtp_session_process_rtp (RTPSession * sess, - RTPSource * src, GstBuffer * buffer, gpointer user_data); -static GstFlowReturn gst_rtp_session_send_rtp (RTPSession * sess, - RTPSource * src, gpointer data, gpointer user_data); -static GstFlowReturn gst_rtp_session_send_rtcp (RTPSession * sess, - RTPSource * src, GstBuffer * buffer, gboolean eos, gpointer user_data); -static GstFlowReturn gst_rtp_session_sync_rtcp (RTPSession * sess, - RTPSource * src, GstBuffer * buffer, gpointer user_data); -static gint gst_rtp_session_clock_rate (RTPSession * sess, guint8 payload, - gpointer user_data); -static void gst_rtp_session_reconsider (RTPSession * sess, gpointer user_data); - -static RTPSessionCallbacks callbacks = { - gst_rtp_session_process_rtp, - gst_rtp_session_send_rtp, - gst_rtp_session_sync_rtcp, - gst_rtp_session_send_rtcp, - gst_rtp_session_clock_rate, - gst_rtp_session_reconsider -}; - -/* GObject vmethods */ -static void gst_rtp_session_finalize (GObject * object); -static void gst_rtp_session_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec); -static void gst_rtp_session_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec); - -/* GstElement vmethods */ -static GstStateChangeReturn gst_rtp_session_change_state (GstElement * element, - GstStateChange transition); -static GstPad *gst_rtp_session_request_new_pad (GstElement * element, - GstPadTemplate * templ, const gchar * name); -static void gst_rtp_session_release_pad (GstElement * element, GstPad * pad); - -static void gst_rtp_session_clear_pt_map (GstRtpSession * rtpsession); - -static guint gst_rtp_session_signals[LAST_SIGNAL] = { 0 }; - -static void -on_new_ssrc (RTPSession * session, RTPSource * src, GstRtpSession * sess) -{ - g_signal_emit (sess, gst_rtp_session_signals[SIGNAL_ON_NEW_SSRC], 0, - src->ssrc); -} - -static void -on_ssrc_collision (RTPSession * session, RTPSource * src, GstRtpSession * sess) -{ - g_signal_emit (sess, gst_rtp_session_signals[SIGNAL_ON_SSRC_COLLISION], 0, - src->ssrc); -} - -static void -on_ssrc_validated (RTPSession * session, RTPSource * src, GstRtpSession * sess) -{ - g_signal_emit (sess, gst_rtp_session_signals[SIGNAL_ON_SSRC_VALIDATED], 0, - src->ssrc); -} - -static void -on_ssrc_active (RTPSession * session, RTPSource * src, GstRtpSession * sess) -{ - g_signal_emit (sess, gst_rtp_session_signals[SIGNAL_ON_SSRC_ACTIVE], 0, - src->ssrc); -} - -static void -on_ssrc_sdes (RTPSession * session, RTPSource * src, GstRtpSession * sess) -{ - GstStructure *s; - GstMessage *m; - - /* convert the new SDES info into a message */ - RTP_SESSION_LOCK (session); - g_object_get (src, "sdes", &s, NULL); - RTP_SESSION_UNLOCK (session); - - m = gst_message_new_custom (GST_MESSAGE_ELEMENT, GST_OBJECT (sess), s); - gst_element_post_message (GST_ELEMENT_CAST (sess), m); - - g_signal_emit (sess, gst_rtp_session_signals[SIGNAL_ON_SSRC_SDES], 0, - src->ssrc); -} - -static void -on_bye_ssrc (RTPSession * session, RTPSource * src, GstRtpSession * sess) -{ - g_signal_emit (sess, gst_rtp_session_signals[SIGNAL_ON_BYE_SSRC], 0, - src->ssrc); -} - -static void -on_bye_timeout (RTPSession * session, RTPSource * src, GstRtpSession * sess) -{ - g_signal_emit (sess, gst_rtp_session_signals[SIGNAL_ON_BYE_TIMEOUT], 0, - src->ssrc); -} - -static void -on_timeout (RTPSession * session, RTPSource * src, GstRtpSession * sess) -{ - g_signal_emit (sess, gst_rtp_session_signals[SIGNAL_ON_TIMEOUT], 0, - src->ssrc); -} - -static void -on_sender_timeout (RTPSession * session, RTPSource * src, GstRtpSession * sess) -{ - g_signal_emit (sess, gst_rtp_session_signals[SIGNAL_ON_SENDER_TIMEOUT], 0, - src->ssrc); -} - -GST_BOILERPLATE (GstRtpSession, gst_rtp_session, GstElement, GST_TYPE_ELEMENT); - -static void -gst_rtp_session_base_init (gpointer klass) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS (klass); - - /* sink pads */ - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&rtpsession_recv_rtp_sink_template)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&rtpsession_recv_rtcp_sink_template)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&rtpsession_send_rtp_sink_template)); - - /* src pads */ - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&rtpsession_recv_rtp_src_template)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&rtpsession_sync_src_template)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&rtpsession_send_rtp_src_template)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&rtpsession_send_rtcp_src_template)); - - gst_element_class_set_details (element_class, &rtpsession_details); -} - -static void -gst_rtp_session_class_init (GstRtpSessionClass * klass) -{ - GObjectClass *gobject_class; - GstElementClass *gstelement_class; - - gobject_class = (GObjectClass *) klass; - gstelement_class = (GstElementClass *) klass; - - g_type_class_add_private (klass, sizeof (GstRtpSessionPrivate)); - - gobject_class->finalize = gst_rtp_session_finalize; - gobject_class->set_property = gst_rtp_session_set_property; - gobject_class->get_property = gst_rtp_session_get_property; - - /** - * GstRtpSession::request-pt-map: - * @sess: the object which received the signal - * @pt: the pt - * - * Request the payload type as #GstCaps for @pt. - */ - gst_rtp_session_signals[SIGNAL_REQUEST_PT_MAP] = - g_signal_new ("request-pt-map", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpSessionClass, request_pt_map), - NULL, NULL, gst_rtp_bin_marshal_BOXED__UINT, GST_TYPE_CAPS, 1, - G_TYPE_UINT); - /** - * GstRtpSession::clear-pt-map: - * @sess: the object which received the signal - * - * Clear the cached pt-maps requested with #GstRtpSession::request-pt-map. - */ - gst_rtp_session_signals[SIGNAL_CLEAR_PT_MAP] = - g_signal_new ("clear-pt-map", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_ACTION, G_STRUCT_OFFSET (GstRtpSessionClass, clear_pt_map), - NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0, G_TYPE_NONE); - - /** - * GstRtpSession::on-new-ssrc: - * @sess: the object which received the signal - * @ssrc: the SSRC - * - * Notify of a new SSRC that entered @session. - */ - gst_rtp_session_signals[SIGNAL_ON_NEW_SSRC] = - g_signal_new ("on-new-ssrc", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpSessionClass, on_new_ssrc), - NULL, NULL, g_cclosure_marshal_VOID__UINT, G_TYPE_NONE, 1, G_TYPE_UINT); - /** - * GstRtpSession::on-ssrc_collision: - * @sess: the object which received the signal - * @ssrc: the SSRC - * - * Notify when we have an SSRC collision - */ - gst_rtp_session_signals[SIGNAL_ON_SSRC_COLLISION] = - g_signal_new ("on-ssrc-collision", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpSessionClass, - on_ssrc_collision), NULL, NULL, g_cclosure_marshal_VOID__UINT, - G_TYPE_NONE, 1, G_TYPE_UINT); - /** - * GstRtpSession::on-ssrc_validated: - * @sess: the object which received the signal - * @ssrc: the SSRC - * - * Notify of a new SSRC that became validated. - */ - gst_rtp_session_signals[SIGNAL_ON_SSRC_VALIDATED] = - g_signal_new ("on-ssrc-validated", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpSessionClass, - on_ssrc_validated), NULL, NULL, g_cclosure_marshal_VOID__UINT, - G_TYPE_NONE, 1, G_TYPE_UINT); - /** - * GstRtpSession::on-ssrc_active: - * @sess: the object which received the signal - * @ssrc: the SSRC - * - * Notify of a SSRC that is active, i.e., sending RTCP. - */ - gst_rtp_session_signals[SIGNAL_ON_SSRC_ACTIVE] = - g_signal_new ("on-ssrc-active", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpSessionClass, - on_ssrc_active), NULL, NULL, g_cclosure_marshal_VOID__UINT, - G_TYPE_NONE, 1, G_TYPE_UINT); - /** - * GstRtpSession::on-ssrc-sdes: - * @session: the object which received the signal - * @src: the SSRC - * - * Notify that a new SDES was received for SSRC. - */ - gst_rtp_session_signals[SIGNAL_ON_SSRC_SDES] = - g_signal_new ("on-ssrc-sdes", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpSessionClass, on_ssrc_sdes), - NULL, NULL, g_cclosure_marshal_VOID__UINT, G_TYPE_NONE, 1, G_TYPE_UINT); - - /** - * GstRtpSession::on-bye-ssrc: - * @sess: the object which received the signal - * @ssrc: the SSRC - * - * Notify of an SSRC that became inactive because of a BYE packet. - */ - gst_rtp_session_signals[SIGNAL_ON_BYE_SSRC] = - g_signal_new ("on-bye-ssrc", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpSessionClass, on_bye_ssrc), - NULL, NULL, g_cclosure_marshal_VOID__UINT, G_TYPE_NONE, 1, G_TYPE_UINT); - /** - * GstRtpSession::on-bye-timeout: - * @sess: the object which received the signal - * @ssrc: the SSRC - * - * Notify of an SSRC that has timed out because of BYE - */ - gst_rtp_session_signals[SIGNAL_ON_BYE_TIMEOUT] = - g_signal_new ("on-bye-timeout", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpSessionClass, on_bye_timeout), - NULL, NULL, g_cclosure_marshal_VOID__UINT, G_TYPE_NONE, 1, G_TYPE_UINT); - /** - * GstRtpSession::on-timeout: - * @sess: the object which received the signal - * @ssrc: the SSRC - * - * Notify of an SSRC that has timed out - */ - gst_rtp_session_signals[SIGNAL_ON_TIMEOUT] = - g_signal_new ("on-timeout", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpSessionClass, on_timeout), - NULL, NULL, g_cclosure_marshal_VOID__UINT, G_TYPE_NONE, 1, G_TYPE_UINT); - /** - * GstRtpSession::on-sender-timeout: - * @sess: the object which received the signal - * @ssrc: the SSRC - * - * Notify of a sender SSRC that has timed out and became a receiver - */ - gst_rtp_session_signals[SIGNAL_ON_SENDER_TIMEOUT] = - g_signal_new ("on-sender-timeout", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpSessionClass, - on_sender_timeout), NULL, NULL, g_cclosure_marshal_VOID__UINT, - G_TYPE_NONE, 1, G_TYPE_UINT); - - g_object_class_install_property (gobject_class, PROP_NTP_NS_BASE, - g_param_spec_uint64 ("ntp-ns-base", "NTP base time", - "The NTP base time corresponding to running_time 0", 0, - G_MAXUINT64, DEFAULT_NTP_NS_BASE, G_PARAM_READWRITE)); - - g_object_class_install_property (gobject_class, PROP_BANDWIDTH, - g_param_spec_double ("bandwidth", "Bandwidth", - "The bandwidth of the session", - 0.0, G_MAXDOUBLE, DEFAULT_BANDWIDTH, G_PARAM_READWRITE)); - - g_object_class_install_property (gobject_class, PROP_RTCP_FRACTION, - g_param_spec_double ("rtcp-fraction", "RTCP Fraction", - "The fraction of the bandwidth used for RTCP", - 0.0, G_MAXDOUBLE, DEFAULT_RTCP_FRACTION, G_PARAM_READWRITE)); - - g_object_class_install_property (gobject_class, PROP_SDES, - g_param_spec_boxed ("sdes", "SDES", - "The SDES items of this session", - GST_TYPE_STRUCTURE, G_PARAM_READWRITE)); - - g_object_class_install_property (gobject_class, PROP_NUM_SOURCES, - g_param_spec_uint ("num-sources", "Num Sources", - "The number of sources in the session", 0, G_MAXUINT, - DEFAULT_NUM_SOURCES, G_PARAM_READABLE)); - - g_object_class_install_property (gobject_class, PROP_NUM_ACTIVE_SOURCES, - g_param_spec_uint ("num-active-sources", "Num Active Sources", - "The number of active sources in the session", 0, G_MAXUINT, - DEFAULT_NUM_ACTIVE_SOURCES, G_PARAM_READABLE)); - - g_object_class_install_property (gobject_class, PROP_INTERNAL_SESSION, - g_param_spec_object ("internal-session", "Internal Session", - "The internal RTPSession object", RTP_TYPE_SESSION, - G_PARAM_READABLE)); - - gstelement_class->change_state = - GST_DEBUG_FUNCPTR (gst_rtp_session_change_state); - gstelement_class->request_new_pad = - GST_DEBUG_FUNCPTR (gst_rtp_session_request_new_pad); - gstelement_class->release_pad = - GST_DEBUG_FUNCPTR (gst_rtp_session_release_pad); - - klass->clear_pt_map = GST_DEBUG_FUNCPTR (gst_rtp_session_clear_pt_map); - - GST_DEBUG_CATEGORY_INIT (gst_rtp_session_debug, - "rtpsession", 0, "RTP Session"); -} - -static void -gst_rtp_session_init (GstRtpSession * rtpsession, GstRtpSessionClass * klass) -{ - rtpsession->priv = GST_RTP_SESSION_GET_PRIVATE (rtpsession); - rtpsession->priv->lock = g_mutex_new (); - rtpsession->priv->sysclock = gst_system_clock_obtain (); - rtpsession->priv->session = rtp_session_new (); - - /* configure callbacks */ - rtp_session_set_callbacks (rtpsession->priv->session, &callbacks, rtpsession); - /* configure signals */ - g_signal_connect (rtpsession->priv->session, "on-new-ssrc", - (GCallback) on_new_ssrc, rtpsession); - g_signal_connect (rtpsession->priv->session, "on-ssrc-collision", - (GCallback) on_ssrc_collision, rtpsession); - g_signal_connect (rtpsession->priv->session, "on-ssrc-validated", - (GCallback) on_ssrc_validated, rtpsession); - g_signal_connect (rtpsession->priv->session, "on-ssrc-active", - (GCallback) on_ssrc_active, rtpsession); - g_signal_connect (rtpsession->priv->session, "on-ssrc-sdes", - (GCallback) on_ssrc_sdes, rtpsession); - g_signal_connect (rtpsession->priv->session, "on-bye-ssrc", - (GCallback) on_bye_ssrc, rtpsession); - g_signal_connect (rtpsession->priv->session, "on-bye-timeout", - (GCallback) on_bye_timeout, rtpsession); - g_signal_connect (rtpsession->priv->session, "on-timeout", - (GCallback) on_timeout, rtpsession); - g_signal_connect (rtpsession->priv->session, "on-sender-timeout", - (GCallback) on_sender_timeout, rtpsession); - rtpsession->priv->ptmap = g_hash_table_new_full (NULL, NULL, NULL, - (GDestroyNotify) gst_caps_unref); - - gst_segment_init (&rtpsession->recv_rtp_seg, GST_FORMAT_UNDEFINED); - gst_segment_init (&rtpsession->send_rtp_seg, GST_FORMAT_UNDEFINED); - - rtpsession->priv->thread_stopped = TRUE; -} - -static void -gst_rtp_session_finalize (GObject * object) -{ - GstRtpSession *rtpsession; - - rtpsession = GST_RTP_SESSION (object); - - if (rtpsession->recv_rtp_sink != NULL) - gst_object_unref (rtpsession->recv_rtp_sink); - if (rtpsession->recv_rtcp_sink != NULL) - gst_object_unref (rtpsession->recv_rtcp_sink); - if (rtpsession->send_rtp_sink != NULL) - gst_object_unref (rtpsession->send_rtp_sink); - if (rtpsession->send_rtcp_src != NULL) - gst_object_unref (rtpsession->send_rtcp_src); - - g_hash_table_destroy (rtpsession->priv->ptmap); - g_mutex_free (rtpsession->priv->lock); - g_object_unref (rtpsession->priv->sysclock); - g_object_unref (rtpsession->priv->session); - - G_OBJECT_CLASS (parent_class)->finalize (object); -} - -static void -gst_rtp_session_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) -{ - GstRtpSession *rtpsession; - GstRtpSessionPrivate *priv; - - rtpsession = GST_RTP_SESSION (object); - priv = rtpsession->priv; - - switch (prop_id) { - case PROP_NTP_NS_BASE: - GST_OBJECT_LOCK (rtpsession); - priv->ntpnsbase = g_value_get_uint64 (value); - GST_DEBUG_OBJECT (rtpsession, "setting NTP base to %" GST_TIME_FORMAT, - GST_TIME_ARGS (priv->ntpnsbase)); - GST_OBJECT_UNLOCK (rtpsession); - break; - case PROP_BANDWIDTH: - rtp_session_set_bandwidth (priv->session, g_value_get_double (value)); - break; - case PROP_RTCP_FRACTION: - rtp_session_set_rtcp_fraction (priv->session, g_value_get_double (value)); - break; - case PROP_SDES: - rtp_session_set_sdes_struct (priv->session, g_value_get_boxed (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_rtp_session_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec) -{ - GstRtpSession *rtpsession; - GstRtpSessionPrivate *priv; - - rtpsession = GST_RTP_SESSION (object); - priv = rtpsession->priv; - - switch (prop_id) { - case PROP_NTP_NS_BASE: - GST_OBJECT_LOCK (rtpsession); - g_value_set_uint64 (value, priv->ntpnsbase); - GST_OBJECT_UNLOCK (rtpsession); - break; - case PROP_BANDWIDTH: - g_value_set_double (value, rtp_session_get_bandwidth (priv->session)); - break; - case PROP_RTCP_FRACTION: - g_value_set_double (value, rtp_session_get_rtcp_fraction (priv->session)); - break; - case PROP_SDES: - g_value_take_boxed (value, rtp_session_get_sdes_struct (priv->session)); - break; - case PROP_NUM_SOURCES: - g_value_set_uint (value, rtp_session_get_num_sources (priv->session)); - break; - case PROP_NUM_ACTIVE_SOURCES: - g_value_set_uint (value, - rtp_session_get_num_active_sources (priv->session)); - break; - case PROP_INTERNAL_SESSION: - g_value_set_object (value, priv->session); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -get_current_times (GstRtpSession * rtpsession, - GstClockTime * running_time, guint64 * ntpnstime) -{ - guint64 ntpns; - GstClock *clock; - GstClockTime base_time, ntpnsbase, rt; - - GST_OBJECT_LOCK (rtpsession); - if ((clock = GST_ELEMENT_CLOCK (rtpsession))) { - base_time = GST_ELEMENT_CAST (rtpsession)->base_time; - ntpnsbase = rtpsession->priv->ntpnsbase; - gst_object_ref (clock); - GST_OBJECT_UNLOCK (rtpsession); - - /* get current clock time and convert to running time */ - rt = gst_clock_get_time (clock) - base_time; - /* add NTP base offset to get NTP ns time */ - ntpns = rt + ntpnsbase; - - gst_object_unref (clock); - } else { - GST_OBJECT_UNLOCK (rtpsession); - rt = -1; - ntpns = -1; - } - if (running_time) - *running_time = rt; - if (ntpnstime) - *ntpnstime = ntpns; -} - -static void -rtcp_thread (GstRtpSession * rtpsession) -{ - GstClockID id; - GstClockTime current_time; - GstClockTime next_timeout; - guint64 ntpnstime; - - GST_DEBUG_OBJECT (rtpsession, "entering RTCP thread"); - - GST_RTP_SESSION_LOCK (rtpsession); - - current_time = gst_clock_get_time (rtpsession->priv->sysclock); - - while (!rtpsession->priv->stop_thread) { - GstClockReturn res; - - /* get initial estimate */ - next_timeout = - rtp_session_next_timeout (rtpsession->priv->session, current_time); - - GST_DEBUG_OBJECT (rtpsession, "next check time %" GST_TIME_FORMAT, - GST_TIME_ARGS (next_timeout)); - - /* leave if no more timeouts, the session ended */ - if (next_timeout == GST_CLOCK_TIME_NONE) - break; - - id = rtpsession->priv->id = - gst_clock_new_single_shot_id (rtpsession->priv->sysclock, next_timeout); - GST_RTP_SESSION_UNLOCK (rtpsession); - - res = gst_clock_id_wait (id, NULL); - - GST_RTP_SESSION_LOCK (rtpsession); - gst_clock_id_unref (id); - rtpsession->priv->id = NULL; - - if (rtpsession->priv->stop_thread) - break; - - /* update current time */ - current_time = gst_clock_get_time (rtpsession->priv->sysclock); - - /* get current NTP time */ - get_current_times (rtpsession, NULL, &ntpnstime); - - /* we get unlocked because we need to perform reconsideration, don't perform - * the timeout but get a new reporting estimate. */ - GST_DEBUG_OBJECT (rtpsession, "unlocked %d, current %" GST_TIME_FORMAT, - res, GST_TIME_ARGS (current_time)); - - /* perform actions, we ignore result. Release lock because it might push. */ - GST_RTP_SESSION_UNLOCK (rtpsession); - rtp_session_on_timeout (rtpsession->priv->session, current_time, ntpnstime); - GST_RTP_SESSION_LOCK (rtpsession); - } - /* mark the thread as stopped now */ - rtpsession->priv->thread_stopped = TRUE; - GST_RTP_SESSION_UNLOCK (rtpsession); - - GST_DEBUG_OBJECT (rtpsession, "leaving RTCP thread"); -} - -static gboolean -start_rtcp_thread (GstRtpSession * rtpsession) -{ - GError *error = NULL; - gboolean res; - - GST_DEBUG_OBJECT (rtpsession, "starting RTCP thread"); - - GST_RTP_SESSION_LOCK (rtpsession); - rtpsession->priv->stop_thread = FALSE; - if (rtpsession->priv->thread_stopped) { - /* if the thread stopped, and we still have a handle to the thread, join it - * now. We can safely join with the lock held, the thread will not take it - * anymore. */ - if (rtpsession->priv->thread) - g_thread_join (rtpsession->priv->thread); - /* only create a new thread if the old one was stopped. Otherwise we can - * just reuse the currently running one. */ - rtpsession->priv->thread = - g_thread_create ((GThreadFunc) rtcp_thread, rtpsession, TRUE, &error); - rtpsession->priv->thread_stopped = FALSE; - } - GST_RTP_SESSION_UNLOCK (rtpsession); - - if (error != NULL) { - res = FALSE; - GST_DEBUG_OBJECT (rtpsession, "failed to start thread, %s", error->message); - g_error_free (error); - } else { - res = TRUE; - } - return res; -} - -static void -stop_rtcp_thread (GstRtpSession * rtpsession) -{ - GST_DEBUG_OBJECT (rtpsession, "stopping RTCP thread"); - - GST_RTP_SESSION_LOCK (rtpsession); - rtpsession->priv->stop_thread = TRUE; - if (rtpsession->priv->id) - gst_clock_id_unschedule (rtpsession->priv->id); - GST_RTP_SESSION_UNLOCK (rtpsession); -} - -static void -join_rtcp_thread (GstRtpSession * rtpsession) -{ - GST_RTP_SESSION_LOCK (rtpsession); - /* don't try to join when we have no thread */ - if (rtpsession->priv->thread != NULL) { - GST_DEBUG_OBJECT (rtpsession, "joining RTCP thread"); - GST_RTP_SESSION_UNLOCK (rtpsession); - - g_thread_join (rtpsession->priv->thread); - - GST_RTP_SESSION_LOCK (rtpsession); - /* after the join, take the lock and clear the thread structure. The caller - * is supposed to not concurrently call start and join. */ - rtpsession->priv->thread = NULL; - } - GST_RTP_SESSION_UNLOCK (rtpsession); -} - -static GstStateChangeReturn -gst_rtp_session_change_state (GstElement * element, GstStateChange transition) -{ - GstStateChangeReturn res; - GstRtpSession *rtpsession; - GstRtpSessionPrivate *priv; - - rtpsession = GST_RTP_SESSION (element); - priv = rtpsession->priv; - - switch (transition) { - case GST_STATE_CHANGE_NULL_TO_READY: - break; - case GST_STATE_CHANGE_READY_TO_PAUSED: - break; - case GST_STATE_CHANGE_PAUSED_TO_PLAYING: - break; - case GST_STATE_CHANGE_PLAYING_TO_PAUSED: - case GST_STATE_CHANGE_PAUSED_TO_READY: - /* no need to join yet, we might want to continue later. Also, the - * dataflow could block downstream so that a join could just block - * forever. */ - stop_rtcp_thread (rtpsession); - break; - default: - break; - } - - res = parent_class->change_state (element, transition); - - switch (transition) { - case GST_STATE_CHANGE_PAUSED_TO_PLAYING: - if (!start_rtcp_thread (rtpsession)) - goto failed_thread; - break; - case GST_STATE_CHANGE_PLAYING_TO_PAUSED: - break; - case GST_STATE_CHANGE_PAUSED_TO_READY: - /* downstream is now releasing the dataflow and we can join. */ - join_rtcp_thread (rtpsession); - break; - case GST_STATE_CHANGE_READY_TO_NULL: - break; - default: - break; - } - return res; - - /* ERRORS */ -failed_thread: - { - return GST_STATE_CHANGE_FAILURE; - } -} - -static gboolean -return_true (gpointer key, gpointer value, gpointer user_data) -{ - return TRUE; -} - -static void -gst_rtp_session_clear_pt_map (GstRtpSession * rtpsession) -{ - g_hash_table_foreach_remove (rtpsession->priv->ptmap, return_true, NULL); -} - -/* called when the session manager has an RTP packet or a list of packets - * ready for further processing */ -static GstFlowReturn -gst_rtp_session_process_rtp (RTPSession * sess, RTPSource * src, - GstBuffer * buffer, gpointer user_data) -{ - GstFlowReturn result; - GstRtpSession *rtpsession; - GstRtpSessionPrivate *priv; - - rtpsession = GST_RTP_SESSION (user_data); - priv = rtpsession->priv; - - if (rtpsession->recv_rtp_src) { - GST_LOG_OBJECT (rtpsession, "pushing received RTP packet"); - result = gst_pad_push (rtpsession->recv_rtp_src, buffer); - } else { - GST_DEBUG_OBJECT (rtpsession, "dropping received RTP packet"); - gst_buffer_unref (buffer); - result = GST_FLOW_OK; - } - return result; -} - -/* called when the session manager has an RTP packet ready for further - * sending */ -static GstFlowReturn -gst_rtp_session_send_rtp (RTPSession * sess, RTPSource * src, - gpointer data, gpointer user_data) -{ - GstFlowReturn result; - GstRtpSession *rtpsession; - GstRtpSessionPrivate *priv; - - rtpsession = GST_RTP_SESSION (user_data); - priv = rtpsession->priv; - - if (rtpsession->send_rtp_src) { - if (GST_IS_BUFFER (data)) { - GST_LOG_OBJECT (rtpsession, "sending RTP packet"); - result = gst_pad_push (rtpsession->send_rtp_src, GST_BUFFER_CAST (data)); - } else { - GST_LOG_OBJECT (rtpsession, "sending RTP list"); - result = gst_pad_push_list (rtpsession->send_rtp_src, - GST_BUFFER_LIST_CAST (data)); - } - } else { - gst_mini_object_unref (GST_MINI_OBJECT_CAST (data)); - result = GST_FLOW_OK; - } - return result; -} - -/* called when the session manager has an RTCP packet ready for further - * sending. The eos flag is set when an EOS event should be sent downstream as - * well. */ -static GstFlowReturn -gst_rtp_session_send_rtcp (RTPSession * sess, RTPSource * src, - GstBuffer * buffer, gboolean eos, gpointer user_data) -{ - GstFlowReturn result; - GstRtpSession *rtpsession; - GstRtpSessionPrivate *priv; - - rtpsession = GST_RTP_SESSION (user_data); - priv = rtpsession->priv; - - if (rtpsession->send_rtcp_src) { - GstCaps *caps; - - /* set rtcp caps on output pad */ - if (!(caps = GST_PAD_CAPS (rtpsession->send_rtcp_src))) { - caps = gst_caps_new_simple ("application/x-rtcp", NULL); - gst_pad_set_caps (rtpsession->send_rtcp_src, caps); - gst_caps_unref (caps); - } - gst_buffer_set_caps (buffer, caps); - GST_LOG_OBJECT (rtpsession, "sending RTCP"); - result = gst_pad_push (rtpsession->send_rtcp_src, buffer); - - /* we have to send EOS after this packet */ - if (eos) { - GST_LOG_OBJECT (rtpsession, "sending EOS"); - gst_pad_push_event (rtpsession->send_rtcp_src, gst_event_new_eos ()); - } - } else { - GST_DEBUG_OBJECT (rtpsession, "not sending RTCP, no output pad"); - gst_buffer_unref (buffer); - result = GST_FLOW_OK; - } - return result; -} - -/* called when the session manager has an SR RTCP packet ready for handling - * inter stream synchronisation */ -static GstFlowReturn -gst_rtp_session_sync_rtcp (RTPSession * sess, - RTPSource * src, GstBuffer * buffer, gpointer user_data) -{ - GstFlowReturn result; - GstRtpSession *rtpsession; - GstRtpSessionPrivate *priv; - - rtpsession = GST_RTP_SESSION (user_data); - priv = rtpsession->priv; - - if (rtpsession->sync_src) { - GstCaps *caps; - - /* set rtcp caps on output pad */ - if (!(caps = GST_PAD_CAPS (rtpsession->sync_src))) { - caps = gst_caps_new_simple ("application/x-rtcp", NULL); - gst_pad_set_caps (rtpsession->sync_src, caps); - gst_caps_unref (caps); - } - gst_buffer_set_caps (buffer, caps); - GST_LOG_OBJECT (rtpsession, "sending Sync RTCP"); - result = gst_pad_push (rtpsession->sync_src, buffer); - } else { - GST_DEBUG_OBJECT (rtpsession, "not sending Sync RTCP, no output pad"); - gst_buffer_unref (buffer); - result = GST_FLOW_OK; - } - return result; -} - -static void -gst_rtp_session_cache_caps (GstRtpSession * rtpsession, GstCaps * caps) -{ - GstRtpSessionPrivate *priv; - const GstStructure *s; - gint payload; - - priv = rtpsession->priv; - - GST_DEBUG_OBJECT (rtpsession, "parsing caps"); - - s = gst_caps_get_structure (caps, 0); - if (!gst_structure_get_int (s, "payload", &payload)) - return; - - if (g_hash_table_lookup (priv->ptmap, GINT_TO_POINTER (payload))) - return; - - g_hash_table_insert (priv->ptmap, GINT_TO_POINTER (payload), - gst_caps_ref (caps)); -} - -/* called when the session manager needs the clock rate */ -static gint -gst_rtp_session_clock_rate (RTPSession * sess, guint8 payload, - gpointer user_data) -{ - gint ipayload, result = -1; - GstRtpSession *rtpsession; - GstRtpSessionPrivate *priv; - GValue ret = { 0 }; - GValue args[2] = { {0}, {0} }; - GstCaps *caps; - const GstStructure *s; - - rtpsession = GST_RTP_SESSION_CAST (user_data); - priv = rtpsession->priv; - - GST_RTP_SESSION_LOCK (rtpsession); - ipayload = payload; /* make compiler happy */ - caps = g_hash_table_lookup (priv->ptmap, GINT_TO_POINTER (ipayload)); - if (caps) { - gst_caps_ref (caps); - goto found; - } - - /* not found in the cache, try to get it with a signal */ - g_value_init (&args[0], GST_TYPE_ELEMENT); - g_value_set_object (&args[0], rtpsession); - g_value_init (&args[1], G_TYPE_UINT); - g_value_set_uint (&args[1], payload); - - g_value_init (&ret, GST_TYPE_CAPS); - g_value_set_boxed (&ret, NULL); - - g_signal_emitv (args, gst_rtp_session_signals[SIGNAL_REQUEST_PT_MAP], 0, - &ret); - - g_value_unset (&args[0]); - g_value_unset (&args[1]); - caps = (GstCaps *) g_value_dup_boxed (&ret); - g_value_unset (&ret); - if (!caps) - goto no_caps; - - gst_rtp_session_cache_caps (rtpsession, caps); - -found: - s = gst_caps_get_structure (caps, 0); - if (!gst_structure_get_int (s, "clock-rate", &result)) - goto no_clock_rate; - - gst_caps_unref (caps); - - GST_DEBUG_OBJECT (rtpsession, "parsed clock-rate %d", result); - -done: - GST_RTP_SESSION_UNLOCK (rtpsession); - - return result; - - /* ERRORS */ -no_caps: - { - GST_DEBUG_OBJECT (rtpsession, "could not get caps"); - goto done; - } -no_clock_rate: - { - gst_caps_unref (caps); - GST_DEBUG_OBJECT (rtpsession, "No clock-rate in caps!"); - goto done; - } -} - -/* called when the session manager asks us to reconsider the timeout */ -static void -gst_rtp_session_reconsider (RTPSession * sess, gpointer user_data) -{ - GstRtpSession *rtpsession; - - rtpsession = GST_RTP_SESSION_CAST (user_data); - - GST_RTP_SESSION_LOCK (rtpsession); - GST_DEBUG_OBJECT (rtpsession, "unlock timer for reconsideration"); - if (rtpsession->priv->id) - gst_clock_id_unschedule (rtpsession->priv->id); - GST_RTP_SESSION_UNLOCK (rtpsession); -} - -static gboolean -gst_rtp_session_event_recv_rtp_sink (GstPad * pad, GstEvent * event) -{ - GstRtpSession *rtpsession; - GstRtpSessionPrivate *priv; - gboolean ret = FALSE; - - rtpsession = GST_RTP_SESSION (gst_pad_get_parent (pad)); - priv = rtpsession->priv; - - GST_DEBUG_OBJECT (rtpsession, "received event %s", - GST_EVENT_TYPE_NAME (event)); - - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_FLUSH_STOP: - gst_segment_init (&rtpsession->recv_rtp_seg, GST_FORMAT_UNDEFINED); - ret = gst_pad_push_event (rtpsession->recv_rtp_src, event); - break; - case GST_EVENT_NEWSEGMENT: - { - gboolean update; - gdouble rate, arate; - GstFormat format; - gint64 start, stop, time; - GstSegment *segment; - - segment = &rtpsession->recv_rtp_seg; - - /* the newsegment event is needed to convert the RTP timestamp to - * running_time, which is needed to generate a mapping from RTP to NTP - * timestamps in SR reports */ - gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format, - &start, &stop, &time); - - GST_DEBUG_OBJECT (rtpsession, - "configured NEWSEGMENT update %d, rate %lf, applied rate %lf, " - "format GST_FORMAT_TIME, " - "%" GST_TIME_FORMAT " -- %" GST_TIME_FORMAT - ", time %" GST_TIME_FORMAT ", accum %" GST_TIME_FORMAT, - update, rate, arate, GST_TIME_ARGS (segment->start), - GST_TIME_ARGS (segment->stop), GST_TIME_ARGS (segment->time), - GST_TIME_ARGS (segment->accum)); - - gst_segment_set_newsegment_full (segment, update, rate, - arate, format, start, stop, time); - - /* push event forward */ - ret = gst_pad_push_event (rtpsession->recv_rtp_src, event); - break; - } - default: - ret = gst_pad_push_event (rtpsession->recv_rtp_src, event); - break; - } - gst_object_unref (rtpsession); - - return ret; - -} - -static GList * -gst_rtp_session_internal_links (GstPad * pad) -{ - GstRtpSession *rtpsession; - GstRtpSessionPrivate *priv; - GList *res = NULL; - - rtpsession = GST_RTP_SESSION (gst_pad_get_parent (pad)); - priv = rtpsession->priv; - - if (pad == rtpsession->recv_rtp_src) { - res = g_list_prepend (res, rtpsession->recv_rtp_sink); - } else if (pad == rtpsession->recv_rtp_sink) { - res = g_list_prepend (res, rtpsession->recv_rtp_src); - } else if (pad == rtpsession->send_rtp_src) { - res = g_list_prepend (res, rtpsession->send_rtp_sink); - } else if (pad == rtpsession->send_rtp_sink) { - res = g_list_prepend (res, rtpsession->send_rtp_src); - } - - gst_object_unref (rtpsession); - - return res; -} - -static gboolean -gst_rtp_session_sink_setcaps (GstPad * pad, GstCaps * caps) -{ - GstRtpSession *rtpsession; - GstRtpSessionPrivate *priv; - - rtpsession = GST_RTP_SESSION (gst_pad_get_parent (pad)); - priv = rtpsession->priv; - - GST_RTP_SESSION_LOCK (rtpsession); - gst_rtp_session_cache_caps (rtpsession, caps); - GST_RTP_SESSION_UNLOCK (rtpsession); - - gst_object_unref (rtpsession); - - return TRUE; -} - -/* receive a packet from a sender, send it to the RTP session manager and - * forward the packet on the rtp_src pad - */ -static GstFlowReturn -gst_rtp_session_chain_recv_rtp (GstPad * pad, GstBuffer * buffer) -{ - GstRtpSession *rtpsession; - GstRtpSessionPrivate *priv; - GstFlowReturn ret; - GstClockTime current_time, running_time; - guint64 ntpnstime; - GstClockTime timestamp; - - rtpsession = GST_RTP_SESSION (gst_pad_get_parent (pad)); - priv = rtpsession->priv; - - GST_LOG_OBJECT (rtpsession, "received RTP packet"); - - /* get NTP time when this packet was captured, this depends on the timestamp. */ - timestamp = GST_BUFFER_TIMESTAMP (buffer); - if (GST_CLOCK_TIME_IS_VALID (timestamp)) { - /* convert to running time using the segment values */ - running_time = - gst_segment_to_running_time (&rtpsession->recv_rtp_seg, GST_FORMAT_TIME, - timestamp); - /* add constant to convert running time to NTP time */ - ntpnstime = running_time + priv->ntpnsbase; - } else { - get_current_times (rtpsession, &running_time, &ntpnstime); - } - current_time = gst_clock_get_time (priv->sysclock); - - ret = rtp_session_process_rtp (priv->session, buffer, current_time, - running_time, ntpnstime); - if (ret != GST_FLOW_OK) - goto push_error; - -done: - gst_object_unref (rtpsession); - - return ret; - - /* ERRORS */ -push_error: - { - GST_DEBUG_OBJECT (rtpsession, "process returned %s", - gst_flow_get_name (ret)); - goto done; - } -} - -static gboolean -gst_rtp_session_event_recv_rtcp_sink (GstPad * pad, GstEvent * event) -{ - GstRtpSession *rtpsession; - GstRtpSessionPrivate *priv; - gboolean ret = FALSE; - - rtpsession = GST_RTP_SESSION (gst_pad_get_parent (pad)); - priv = rtpsession->priv; - - GST_DEBUG_OBJECT (rtpsession, "received event %s", - GST_EVENT_TYPE_NAME (event)); - - switch (GST_EVENT_TYPE (event)) { - default: - ret = gst_pad_push_event (rtpsession->sync_src, event); - break; - } - gst_object_unref (rtpsession); - - return ret; -} - -/* Receive an RTCP packet from a sender, send it to the RTP session manager and - * forward the SR packets to the sync_src pad. - */ -static GstFlowReturn -gst_rtp_session_chain_recv_rtcp (GstPad * pad, GstBuffer * buffer) -{ - GstRtpSession *rtpsession; - GstRtpSessionPrivate *priv; - GstClockTime current_time; - GstFlowReturn ret; - - rtpsession = GST_RTP_SESSION (gst_pad_get_parent (pad)); - priv = rtpsession->priv; - - GST_LOG_OBJECT (rtpsession, "received RTCP packet"); - - current_time = gst_clock_get_time (priv->sysclock); - ret = rtp_session_process_rtcp (priv->session, buffer, current_time); - - gst_object_unref (rtpsession); - - return GST_FLOW_OK; -} - -static gboolean -gst_rtp_session_query_send_rtcp_src (GstPad * pad, GstQuery * query) -{ - GstRtpSession *rtpsession; - GstRtpSessionPrivate *priv; - gboolean ret = FALSE; - - rtpsession = GST_RTP_SESSION (gst_pad_get_parent (pad)); - priv = rtpsession->priv; - - GST_DEBUG_OBJECT (rtpsession, "received QUERY"); - - switch (GST_QUERY_TYPE (query)) { - case GST_QUERY_LATENCY: - ret = TRUE; - /* use the defaults for the latency query. */ - gst_query_set_latency (query, FALSE, 0, -1); - break; - default: - /* other queries simply fail for now */ - break; - } - - gst_object_unref (rtpsession); - - return ret; -} - -static gboolean -gst_rtp_session_event_send_rtcp_src (GstPad * pad, GstEvent * event) -{ - GstRtpSession *rtpsession; - GstRtpSessionPrivate *priv; - gboolean ret; - - rtpsession = GST_RTP_SESSION (gst_pad_get_parent (pad)); - priv = rtpsession->priv; - - GST_DEBUG_OBJECT (rtpsession, "received EVENT"); - - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_SEEK: - case GST_EVENT_LATENCY: - gst_event_unref (event); - ret = TRUE; - break; - default: - /* other events simply fail for now */ - gst_event_unref (event); - ret = FALSE; - break; - } - - gst_object_unref (rtpsession); - - return ret; -} - - -static gboolean -gst_rtp_session_event_send_rtp_sink (GstPad * pad, GstEvent * event) -{ - GstRtpSession *rtpsession; - GstRtpSessionPrivate *priv; - gboolean ret = FALSE; - - rtpsession = GST_RTP_SESSION (gst_pad_get_parent (pad)); - priv = rtpsession->priv; - - GST_DEBUG_OBJECT (rtpsession, "received event"); - - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_FLUSH_STOP: - gst_segment_init (&rtpsession->send_rtp_seg, GST_FORMAT_UNDEFINED); - ret = gst_pad_push_event (rtpsession->send_rtp_src, event); - break; - case GST_EVENT_NEWSEGMENT:{ - gboolean update; - gdouble rate, arate; - GstFormat format; - gint64 start, stop, time; - GstSegment *segment; - - segment = &rtpsession->send_rtp_seg; - - /* the newsegment event is needed to convert the RTP timestamp to - * running_time, which is needed to generate a mapping from RTP to NTP - * timestamps in SR reports */ - gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format, - &start, &stop, &time); - - GST_DEBUG_OBJECT (rtpsession, - "configured NEWSEGMENT update %d, rate %lf, applied rate %lf, " - "format GST_FORMAT_TIME, " - "%" GST_TIME_FORMAT " -- %" GST_TIME_FORMAT - ", time %" GST_TIME_FORMAT ", accum %" GST_TIME_FORMAT, - update, rate, arate, GST_TIME_ARGS (segment->start), - GST_TIME_ARGS (segment->stop), GST_TIME_ARGS (segment->time), - GST_TIME_ARGS (segment->accum)); - - gst_segment_set_newsegment_full (segment, update, rate, - arate, format, start, stop, time); - - /* push event forward */ - ret = gst_pad_push_event (rtpsession->send_rtp_src, event); - break; - } - case GST_EVENT_EOS:{ - GstClockTime current_time; - - /* push downstream FIXME, we are not supposed to leave the session just - * because we stop sending. */ - ret = gst_pad_push_event (rtpsession->send_rtp_src, event); - current_time = gst_clock_get_time (rtpsession->priv->sysclock); - GST_DEBUG_OBJECT (rtpsession, "scheduling BYE message"); - rtp_session_schedule_bye (rtpsession->priv->session, "End of stream", - current_time); - break; - } - default: - ret = gst_pad_push_event (rtpsession->send_rtp_src, event); - break; - } - gst_object_unref (rtpsession); - - return ret; -} - -static GstCaps * -gst_rtp_session_getcaps_send_rtp (GstPad * pad) -{ - GstRtpSession *rtpsession; - GstRtpSessionPrivate *priv; - GstCaps *result; - GstStructure *s1, *s2; - guint ssrc; - - rtpsession = GST_RTP_SESSION (gst_pad_get_parent (pad)); - priv = rtpsession->priv; - - ssrc = rtp_session_get_internal_ssrc (priv->session); - - /* we can basically accept anything but we prefer to receive packets with our - * internal SSRC so that we don't have to patch it. Create a structure with - * the SSRC and another one without. */ - s1 = gst_structure_new ("application/x-rtp", "ssrc", G_TYPE_UINT, ssrc, NULL); - s2 = gst_structure_new ("application/x-rtp", NULL); - - result = gst_caps_new_full (s1, s2, NULL); - - GST_DEBUG_OBJECT (rtpsession, "getting caps %" GST_PTR_FORMAT, result); - - gst_object_unref (rtpsession); - - return result; -} - -static gboolean -gst_rtp_session_setcaps_send_rtp (GstPad * pad, GstCaps * caps) -{ - GstRtpSession *rtpsession; - GstRtpSessionPrivate *priv; - GstStructure *s = gst_caps_get_structure (caps, 0); - guint ssrc; - - rtpsession = GST_RTP_SESSION (gst_pad_get_parent (pad)); - priv = rtpsession->priv; - - if (gst_structure_get_uint (s, "ssrc", &ssrc)) { - GST_DEBUG_OBJECT (rtpsession, "setting internal SSRC to %08x", ssrc); - rtp_session_set_internal_ssrc (priv->session, ssrc); - } - - gst_object_unref (rtpsession); - - return TRUE; -} - -/* Recieve an RTP packet or a list of packets to be send to the receivers, - * send to RTP session manager and forward to send_rtp_src. - */ -static GstFlowReturn -gst_rtp_session_chain_send_rtp_common (GstPad * pad, gpointer data, - gboolean is_list) -{ - GstRtpSession *rtpsession; - GstRtpSessionPrivate *priv; - GstFlowReturn ret; - GstClockTime timestamp; - GstClockTime current_time; - guint64 ntpnstime; - - rtpsession = GST_RTP_SESSION (gst_pad_get_parent (pad)); - priv = rtpsession->priv; - - GST_LOG_OBJECT (rtpsession, "received RTP %s", is_list ? "list" : "packet"); - - /* get NTP time when this packet was captured, this depends on the timestamp. */ - if (is_list) { - GstBuffer *buffer = NULL; - - /* All groups in an list have the same timestamp. - * So, just take it from the first group. */ - buffer = gst_buffer_list_get (GST_BUFFER_LIST_CAST (data), 0, 0); - if (buffer) - timestamp = GST_BUFFER_TIMESTAMP (buffer); - else - timestamp = -1; - } else { - timestamp = GST_BUFFER_TIMESTAMP (GST_BUFFER_CAST (data)); - } - if (GST_CLOCK_TIME_IS_VALID (timestamp)) { - /* convert to running time using the segment start value. */ - ntpnstime = - gst_segment_to_running_time (&rtpsession->send_rtp_seg, GST_FORMAT_TIME, - timestamp); - /* convert to NTP time by adding the NTP base */ - ntpnstime += priv->ntpnsbase; - } else { - /* no timestamp, we could take the current running_time and convert it to - * NTP time. */ - ntpnstime = -1; - } - - current_time = gst_clock_get_time (priv->sysclock); - ret = - rtp_session_send_rtp (priv->session, data, is_list, current_time, - ntpnstime); - if (ret != GST_FLOW_OK) - goto push_error; - -done: - gst_object_unref (rtpsession); - - return ret; - - /* ERRORS */ -push_error: - { - GST_DEBUG_OBJECT (rtpsession, "process returned %s", - gst_flow_get_name (ret)); - goto done; - } -} - -static GstFlowReturn -gst_rtp_session_chain_send_rtp (GstPad * pad, GstBuffer * buffer) -{ - return gst_rtp_session_chain_send_rtp_common (pad, buffer, FALSE); -} - -static GstFlowReturn -gst_rtp_session_chain_send_rtp_list (GstPad * pad, GstBufferList * list) -{ - return gst_rtp_session_chain_send_rtp_common (pad, list, TRUE); -} - -/* Create sinkpad to receive RTP packets from senders. This will also create a - * srcpad for the RTP packets. - */ -static GstPad * -create_recv_rtp_sink (GstRtpSession * rtpsession) -{ - GST_DEBUG_OBJECT (rtpsession, "creating RTP sink pad"); - - rtpsession->recv_rtp_sink = - gst_pad_new_from_static_template (&rtpsession_recv_rtp_sink_template, - "recv_rtp_sink"); - gst_pad_set_chain_function (rtpsession->recv_rtp_sink, - gst_rtp_session_chain_recv_rtp); - gst_pad_set_event_function (rtpsession->recv_rtp_sink, - (GstPadEventFunction) gst_rtp_session_event_recv_rtp_sink); - gst_pad_set_setcaps_function (rtpsession->recv_rtp_sink, - gst_rtp_session_sink_setcaps); - gst_pad_set_internal_link_function (rtpsession->recv_rtp_sink, - gst_rtp_session_internal_links); - gst_pad_set_active (rtpsession->recv_rtp_sink, TRUE); - gst_element_add_pad (GST_ELEMENT_CAST (rtpsession), - rtpsession->recv_rtp_sink); - - GST_DEBUG_OBJECT (rtpsession, "creating RTP src pad"); - rtpsession->recv_rtp_src = - gst_pad_new_from_static_template (&rtpsession_recv_rtp_src_template, - "recv_rtp_src"); - gst_pad_set_internal_link_function (rtpsession->recv_rtp_src, - gst_rtp_session_internal_links); - gst_pad_use_fixed_caps (rtpsession->recv_rtp_src); - gst_pad_set_active (rtpsession->recv_rtp_src, TRUE); - gst_element_add_pad (GST_ELEMENT_CAST (rtpsession), rtpsession->recv_rtp_src); - - return rtpsession->recv_rtp_sink; -} - -/* Remove sinkpad to receive RTP packets from senders. This will also remove - * the srcpad for the RTP packets. - */ -static void -remove_recv_rtp_sink (GstRtpSession * rtpsession) -{ - GST_DEBUG_OBJECT (rtpsession, "removing RTP sink pad"); - - /* deactivate from source to sink */ - gst_pad_set_active (rtpsession->recv_rtp_src, FALSE); - gst_pad_set_active (rtpsession->recv_rtp_sink, FALSE); - - /* remove pads */ - gst_element_remove_pad (GST_ELEMENT_CAST (rtpsession), - rtpsession->recv_rtp_sink); - rtpsession->recv_rtp_sink = NULL; - - GST_DEBUG_OBJECT (rtpsession, "removing RTP src pad"); - gst_element_remove_pad (GST_ELEMENT_CAST (rtpsession), - rtpsession->recv_rtp_src); - rtpsession->recv_rtp_src = NULL; -} - -/* Create a sinkpad to receive RTCP messages from senders, this will also create a - * sync_src pad for the SR packets. - */ -static GstPad * -create_recv_rtcp_sink (GstRtpSession * rtpsession) -{ - GST_DEBUG_OBJECT (rtpsession, "creating RTCP sink pad"); - - rtpsession->recv_rtcp_sink = - gst_pad_new_from_static_template (&rtpsession_recv_rtcp_sink_template, - "recv_rtcp_sink"); - gst_pad_set_chain_function (rtpsession->recv_rtcp_sink, - gst_rtp_session_chain_recv_rtcp); - gst_pad_set_event_function (rtpsession->recv_rtcp_sink, - (GstPadEventFunction) gst_rtp_session_event_recv_rtcp_sink); - gst_pad_set_internal_link_function (rtpsession->recv_rtcp_sink, - gst_rtp_session_internal_links); - gst_pad_set_active (rtpsession->recv_rtcp_sink, TRUE); - gst_element_add_pad (GST_ELEMENT_CAST (rtpsession), - rtpsession->recv_rtcp_sink); - - GST_DEBUG_OBJECT (rtpsession, "creating sync src pad"); - rtpsession->sync_src = - gst_pad_new_from_static_template (&rtpsession_sync_src_template, - "sync_src"); - gst_pad_set_internal_link_function (rtpsession->sync_src, - gst_rtp_session_internal_links); - gst_pad_use_fixed_caps (rtpsession->sync_src); - gst_pad_set_active (rtpsession->sync_src, TRUE); - gst_element_add_pad (GST_ELEMENT_CAST (rtpsession), rtpsession->sync_src); - - return rtpsession->recv_rtcp_sink; -} - -static void -remove_recv_rtcp_sink (GstRtpSession * rtpsession) -{ - GST_DEBUG_OBJECT (rtpsession, "removing RTCP sink pad"); - - gst_pad_set_active (rtpsession->sync_src, FALSE); - gst_pad_set_active (rtpsession->recv_rtcp_sink, FALSE); - - gst_element_remove_pad (GST_ELEMENT_CAST (rtpsession), - rtpsession->recv_rtcp_sink); - rtpsession->recv_rtcp_sink = NULL; - - GST_DEBUG_OBJECT (rtpsession, "removing sync src pad"); - gst_element_remove_pad (GST_ELEMENT_CAST (rtpsession), rtpsession->sync_src); - rtpsession->sync_src = NULL; -} - -/* Create a sinkpad to receive RTP packets for receivers. This will also create a - * send_rtp_src pad. - */ -static GstPad * -create_send_rtp_sink (GstRtpSession * rtpsession) -{ - GST_DEBUG_OBJECT (rtpsession, "creating pad"); - - rtpsession->send_rtp_sink = - gst_pad_new_from_static_template (&rtpsession_send_rtp_sink_template, - "send_rtp_sink"); - gst_pad_set_chain_function (rtpsession->send_rtp_sink, - gst_rtp_session_chain_send_rtp); - gst_pad_set_chain_list_function (rtpsession->send_rtp_sink, - gst_rtp_session_chain_send_rtp_list); - gst_pad_set_getcaps_function (rtpsession->send_rtp_sink, - gst_rtp_session_getcaps_send_rtp); - gst_pad_set_setcaps_function (rtpsession->send_rtp_sink, - gst_rtp_session_setcaps_send_rtp); - gst_pad_set_event_function (rtpsession->send_rtp_sink, - (GstPadEventFunction) gst_rtp_session_event_send_rtp_sink); - gst_pad_set_internal_link_function (rtpsession->send_rtp_sink, - gst_rtp_session_internal_links); - gst_pad_set_active (rtpsession->send_rtp_sink, TRUE); - gst_element_add_pad (GST_ELEMENT_CAST (rtpsession), - rtpsession->send_rtp_sink); - - rtpsession->send_rtp_src = - gst_pad_new_from_static_template (&rtpsession_send_rtp_src_template, - "send_rtp_src"); - gst_pad_set_internal_link_function (rtpsession->send_rtp_src, - gst_rtp_session_internal_links); - gst_pad_set_active (rtpsession->send_rtp_src, TRUE); - gst_element_add_pad (GST_ELEMENT_CAST (rtpsession), rtpsession->send_rtp_src); - - return rtpsession->send_rtp_sink; -} - -static void -remove_send_rtp_sink (GstRtpSession * rtpsession) -{ - GST_DEBUG_OBJECT (rtpsession, "removing pad"); - - gst_pad_set_active (rtpsession->send_rtp_src, FALSE); - gst_pad_set_active (rtpsession->send_rtp_sink, FALSE); - - gst_element_remove_pad (GST_ELEMENT_CAST (rtpsession), - rtpsession->send_rtp_sink); - rtpsession->send_rtp_sink = NULL; - - gst_element_remove_pad (GST_ELEMENT_CAST (rtpsession), - rtpsession->send_rtp_src); - rtpsession->send_rtp_src = NULL; -} - -/* Create a srcpad with the RTCP packets to send out. - * This pad will be driven by the RTP session manager when it wants to send out - * RTCP packets. - */ -static GstPad * -create_send_rtcp_src (GstRtpSession * rtpsession) -{ - GST_DEBUG_OBJECT (rtpsession, "creating pad"); - - rtpsession->send_rtcp_src = - gst_pad_new_from_static_template (&rtpsession_send_rtcp_src_template, - "send_rtcp_src"); - gst_pad_use_fixed_caps (rtpsession->send_rtcp_src); - gst_pad_set_active (rtpsession->send_rtcp_src, TRUE); - gst_pad_set_internal_link_function (rtpsession->send_rtcp_src, - gst_rtp_session_internal_links); - gst_pad_set_query_function (rtpsession->send_rtcp_src, - gst_rtp_session_query_send_rtcp_src); - gst_pad_set_event_function (rtpsession->send_rtcp_src, - gst_rtp_session_event_send_rtcp_src); - gst_element_add_pad (GST_ELEMENT_CAST (rtpsession), - rtpsession->send_rtcp_src); - - return rtpsession->send_rtcp_src; -} - -static void -remove_send_rtcp_src (GstRtpSession * rtpsession) -{ - GST_DEBUG_OBJECT (rtpsession, "removing pad"); - - gst_pad_set_active (rtpsession->send_rtcp_src, FALSE); - - gst_element_remove_pad (GST_ELEMENT_CAST (rtpsession), - rtpsession->send_rtcp_src); - rtpsession->send_rtcp_src = NULL; -} - -static GstPad * -gst_rtp_session_request_new_pad (GstElement * element, - GstPadTemplate * templ, const gchar * name) -{ - GstRtpSession *rtpsession; - GstElementClass *klass; - GstPad *result; - - g_return_val_if_fail (templ != NULL, NULL); - g_return_val_if_fail (GST_IS_RTP_SESSION (element), NULL); - - rtpsession = GST_RTP_SESSION (element); - klass = GST_ELEMENT_GET_CLASS (element); - - GST_DEBUG_OBJECT (element, "requesting pad %s", GST_STR_NULL (name)); - - GST_RTP_SESSION_LOCK (rtpsession); - - /* figure out the template */ - if (templ == gst_element_class_get_pad_template (klass, "recv_rtp_sink")) { - if (rtpsession->recv_rtp_sink != NULL) - goto exists; - - result = create_recv_rtp_sink (rtpsession); - } else if (templ == gst_element_class_get_pad_template (klass, - "recv_rtcp_sink")) { - if (rtpsession->recv_rtcp_sink != NULL) - goto exists; - - result = create_recv_rtcp_sink (rtpsession); - } else if (templ == gst_element_class_get_pad_template (klass, - "send_rtp_sink")) { - if (rtpsession->send_rtp_sink != NULL) - goto exists; - - result = create_send_rtp_sink (rtpsession); - } else if (templ == gst_element_class_get_pad_template (klass, - "send_rtcp_src")) { - if (rtpsession->send_rtcp_src != NULL) - goto exists; - - result = create_send_rtcp_src (rtpsession); - } else - goto wrong_template; - - GST_RTP_SESSION_UNLOCK (rtpsession); - - return result; - - /* ERRORS */ -wrong_template: - { - GST_RTP_SESSION_UNLOCK (rtpsession); - g_warning ("gstrtpsession: this is not our template"); - return NULL; - } -exists: - { - GST_RTP_SESSION_UNLOCK (rtpsession); - g_warning ("gstrtpsession: pad already requested"); - return NULL; - } -} - -static void -gst_rtp_session_release_pad (GstElement * element, GstPad * pad) -{ - GstRtpSession *rtpsession; - - g_return_if_fail (GST_IS_RTP_SESSION (element)); - g_return_if_fail (GST_IS_PAD (pad)); - - rtpsession = GST_RTP_SESSION (element); - - GST_DEBUG_OBJECT (element, "releasing pad %s:%s", GST_DEBUG_PAD_NAME (pad)); - - GST_RTP_SESSION_LOCK (rtpsession); - - if (rtpsession->recv_rtp_sink == pad) { - remove_recv_rtp_sink (rtpsession); - } else if (rtpsession->recv_rtcp_sink == pad) { - remove_recv_rtcp_sink (rtpsession); - } else if (rtpsession->send_rtp_sink == pad) { - remove_send_rtp_sink (rtpsession); - } else if (rtpsession->send_rtcp_src == pad) { - remove_send_rtcp_src (rtpsession); - } else - goto wrong_pad; - - GST_RTP_SESSION_UNLOCK (rtpsession); - - return; - - /* ERRORS */ -wrong_pad: - { - GST_RTP_SESSION_UNLOCK (rtpsession); - g_warning ("gstrtpsession: asked to release an unknown pad"); - return; - } -} diff --git a/gst/rtpmanager/gstrtpsession.h b/gst/rtpmanager/gstrtpsession.h deleted file mode 100644 index 9481a1c2..00000000 --- a/gst/rtpmanager/gstrtpsession.h +++ /dev/null @@ -1,81 +0,0 @@ -/* GStreamer - * Copyright (C) <2007> Wim Taymans <wim.taymans@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., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __GST_RTP_SESSION_H__ -#define __GST_RTP_SESSION_H__ - -#include <gst/gst.h> - -#define GST_TYPE_RTP_SESSION \ - (gst_rtp_session_get_type()) -#define GST_RTP_SESSION(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_SESSION,GstRtpSession)) -#define GST_RTP_SESSION_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_SESSION,GstRtpSessionClass)) -#define GST_IS_RTP_SESSION(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_SESSION)) -#define GST_IS_RTP_SESSION_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_SESSION)) -#define GST_RTP_SESSION_CAST(obj) ((GstRtpSession *)(obj)) - -typedef struct _GstRtpSession GstRtpSession; -typedef struct _GstRtpSessionClass GstRtpSessionClass; -typedef struct _GstRtpSessionPrivate GstRtpSessionPrivate; - -struct _GstRtpSession { - GstElement element; - - /*< private >*/ - GstPad *recv_rtp_sink; - GstSegment recv_rtp_seg; - GstPad *recv_rtcp_sink; - GstPad *send_rtp_sink; - GstSegment send_rtp_seg; - - GstPad *recv_rtp_src; - GstPad *sync_src; - GstPad *send_rtp_src; - GstPad *send_rtcp_src; - - GstRtpSessionPrivate *priv; -}; - -struct _GstRtpSessionClass { - GstElementClass parent_class; - - /* signals */ - GstCaps* (*request_pt_map) (GstRtpSession *sess, guint pt); - void (*clear_pt_map) (GstRtpSession *sess); - - void (*on_new_ssrc) (GstRtpSession *sess, guint32 ssrc); - void (*on_ssrc_collision) (GstRtpSession *sess, guint32 ssrc); - void (*on_ssrc_validated) (GstRtpSession *sess, guint32 ssrc); - void (*on_ssrc_active) (GstRtpSession *sess, guint32 ssrc); - void (*on_ssrc_sdes) (GstRtpSession *sess, guint32 ssrc); - void (*on_bye_ssrc) (GstRtpSession *sess, guint32 ssrc); - void (*on_bye_timeout) (GstRtpSession *sess, guint32 ssrc); - void (*on_timeout) (GstRtpSession *sess, guint32 ssrc); - void (*on_sender_timeout) (GstRtpSession *sess, guint32 ssrc); -}; - -GType gst_rtp_session_get_type (void); - -void gst_rtp_session_set_ssrc (GstRtpSession *sess, guint32 ssrc); - -#endif /* __GST_RTP_SESSION_H__ */ diff --git a/gst/rtpmanager/gstrtpssrcdemux.c b/gst/rtpmanager/gstrtpssrcdemux.c deleted file mode 100644 index 6a305d8e..00000000 --- a/gst/rtpmanager/gstrtpssrcdemux.c +++ /dev/null @@ -1,722 +0,0 @@ -/* GStreamer - * Copyright (C) <2007> Wim Taymans <wim.taymans@gmail.com> - * - * RTP SSRC demuxer - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/** - * SECTION:element-gstrtpssrcdemux - * - * gstrtpssrcdemux acts as a demuxer for RTP packets based on the SSRC of the - * packets. Its main purpose is to allow an application to easily receive and - * decode an RTP stream with multiple SSRCs. - * - * For each SSRC that is detected, a new pad will be created and the - * #GstRtpSsrcDemux::new-ssrc-pad signal will be emitted. - * - * <refsect2> - * <title>Example pipelines</title> - * |[ - * gst-launch udpsrc caps="application/x-rtp" ! gstrtpssrcdemux ! fakesink - * ]| Takes an RTP stream and send the RTP packets with the first detected SSRC - * to fakesink, discarding the other SSRCs. - * </refsect2> - * - * Last reviewed on 2007-05-28 (0.10.5) - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <string.h> -#include <gst/rtp/gstrtpbuffer.h> -#include <gst/rtp/gstrtcpbuffer.h> - -#include "gstrtpbin-marshal.h" -#include "gstrtpssrcdemux.h" - -GST_DEBUG_CATEGORY_STATIC (gst_rtp_ssrc_demux_debug); -#define GST_CAT_DEFAULT gst_rtp_ssrc_demux_debug - -/* generic templates */ -static GstStaticPadTemplate rtp_ssrc_demux_sink_template = -GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("application/x-rtp") - ); - -static GstStaticPadTemplate rtp_ssrc_demux_rtcp_sink_template = -GST_STATIC_PAD_TEMPLATE ("rtcp_sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("application/x-rtcp") - ); - -static GstStaticPadTemplate rtp_ssrc_demux_src_template = -GST_STATIC_PAD_TEMPLATE ("src_%d", - GST_PAD_SRC, - GST_PAD_SOMETIMES, - GST_STATIC_CAPS ("application/x-rtp") - ); - -static GstStaticPadTemplate rtp_ssrc_demux_rtcp_src_template = -GST_STATIC_PAD_TEMPLATE ("rtcp_src_%d", - GST_PAD_SRC, - GST_PAD_SOMETIMES, - GST_STATIC_CAPS ("application/x-rtcp") - ); - -static GstElementDetails gst_rtp_ssrc_demux_details = { - "RTP SSRC Demux", - "Demux/Network/RTP", - "Splits RTP streams based on the SSRC", - "Wim Taymans <wim.taymans@gmail.com>" -}; - -#define GST_PAD_LOCK(obj) (g_mutex_lock ((obj)->padlock)) -#define GST_PAD_UNLOCK(obj) (g_mutex_unlock ((obj)->padlock)) - -/* signals */ -enum -{ - SIGNAL_NEW_SSRC_PAD, - SIGNAL_REMOVED_SSRC_PAD, - SIGNAL_CLEAR_SSRC, - LAST_SIGNAL -}; - -GST_BOILERPLATE (GstRtpSsrcDemux, gst_rtp_ssrc_demux, GstElement, - GST_TYPE_ELEMENT); - - -/* GObject vmethods */ -static void gst_rtp_ssrc_demux_dispose (GObject * object); -static void gst_rtp_ssrc_demux_finalize (GObject * object); - -/* GstElement vmethods */ -static GstStateChangeReturn gst_rtp_ssrc_demux_change_state (GstElement * - element, GstStateChange transition); - -static void gst_rtp_ssrc_demux_clear_ssrc (GstRtpSsrcDemux * demux, - guint32 ssrc); - -/* sinkpad stuff */ -static GstFlowReturn gst_rtp_ssrc_demux_chain (GstPad * pad, GstBuffer * buf); -static gboolean gst_rtp_ssrc_demux_sink_event (GstPad * pad, GstEvent * event); - -static GstFlowReturn gst_rtp_ssrc_demux_rtcp_chain (GstPad * pad, - GstBuffer * buf); -static gboolean gst_rtp_ssrc_demux_rtcp_sink_event (GstPad * pad, - GstEvent * event); - -/* srcpad stuff */ -static gboolean gst_rtp_ssrc_demux_src_event (GstPad * pad, GstEvent * event); -static GList *gst_rtp_ssrc_demux_internal_links (GstPad * pad); -static gboolean gst_rtp_ssrc_demux_src_query (GstPad * pad, GstQuery * query); - -static guint gst_rtp_ssrc_demux_signals[LAST_SIGNAL] = { 0 }; - -/* - * Item for storing GstPad <-> SSRC pairs. - */ -struct _GstRtpSsrcDemuxPad -{ - guint32 ssrc; - GstPad *rtp_pad; - GstCaps *caps; - GstPad *rtcp_pad; -}; - -/* find a src pad for a given SSRC, returns NULL if the SSRC was not found - */ -static GstRtpSsrcDemuxPad * -find_demux_pad_for_ssrc (GstRtpSsrcDemux * demux, guint32 ssrc) -{ - GSList *walk; - - for (walk = demux->srcpads; walk; walk = g_slist_next (walk)) { - GstRtpSsrcDemuxPad *pad = (GstRtpSsrcDemuxPad *) walk->data; - - if (pad->ssrc == ssrc) - return pad; - } - return NULL; -} - -/* with PAD_LOCK */ -static GstRtpSsrcDemuxPad * -create_demux_pad_for_ssrc (GstRtpSsrcDemux * demux, guint32 ssrc, - GstClockTime timestamp) -{ - GstPad *rtp_pad, *rtcp_pad; - GstElementClass *klass; - GstPadTemplate *templ; - gchar *padname; - GstRtpSsrcDemuxPad *demuxpad; - - GST_DEBUG_OBJECT (demux, "creating pad for SSRC %08x", ssrc); - - klass = GST_ELEMENT_GET_CLASS (demux); - templ = gst_element_class_get_pad_template (klass, "src_%d"); - padname = g_strdup_printf ("src_%d", ssrc); - rtp_pad = gst_pad_new_from_template (templ, padname); - g_free (padname); - - templ = gst_element_class_get_pad_template (klass, "rtcp_src_%d"); - padname = g_strdup_printf ("rtcp_src_%d", ssrc); - rtcp_pad = gst_pad_new_from_template (templ, padname); - g_free (padname); - - /* we use the first timestamp received to calculate the difference between - * timestamps on all streams */ - GST_DEBUG_OBJECT (demux, "SSRC %08x, first timestamp %" GST_TIME_FORMAT, - ssrc, GST_TIME_ARGS (timestamp)); - - /* wrap in structure and add to list */ - demuxpad = g_new0 (GstRtpSsrcDemuxPad, 1); - demuxpad->ssrc = ssrc; - demuxpad->rtp_pad = rtp_pad; - demuxpad->rtcp_pad = rtcp_pad; - - GST_DEBUG_OBJECT (demux, "first timestamp %" GST_TIME_FORMAT, - GST_TIME_ARGS (timestamp)); - - gst_pad_set_element_private (rtp_pad, demuxpad); - gst_pad_set_element_private (rtcp_pad, demuxpad); - - demux->srcpads = g_slist_prepend (demux->srcpads, demuxpad); - - /* copy caps from input */ - gst_pad_set_caps (rtp_pad, GST_PAD_CAPS (demux->rtp_sink)); - gst_pad_use_fixed_caps (rtp_pad); - gst_pad_set_caps (rtcp_pad, GST_PAD_CAPS (demux->rtcp_sink)); - gst_pad_use_fixed_caps (rtcp_pad); - - gst_pad_set_event_function (rtp_pad, gst_rtp_ssrc_demux_src_event); - gst_pad_set_query_function (rtp_pad, gst_rtp_ssrc_demux_src_query); - gst_pad_set_internal_link_function (rtp_pad, - gst_rtp_ssrc_demux_internal_links); - gst_pad_set_active (rtp_pad, TRUE); - - gst_pad_set_internal_link_function (rtcp_pad, - gst_rtp_ssrc_demux_internal_links); - gst_pad_set_active (rtcp_pad, TRUE); - - gst_element_add_pad (GST_ELEMENT_CAST (demux), rtp_pad); - gst_element_add_pad (GST_ELEMENT_CAST (demux), rtcp_pad); - - g_signal_emit (G_OBJECT (demux), - gst_rtp_ssrc_demux_signals[SIGNAL_NEW_SSRC_PAD], 0, ssrc, rtp_pad); - - return demuxpad; -} - -static void -gst_rtp_ssrc_demux_base_init (gpointer g_class) -{ - GstElementClass *gstelement_klass = GST_ELEMENT_CLASS (g_class); - - gst_element_class_add_pad_template (gstelement_klass, - gst_static_pad_template_get (&rtp_ssrc_demux_sink_template)); - gst_element_class_add_pad_template (gstelement_klass, - gst_static_pad_template_get (&rtp_ssrc_demux_rtcp_sink_template)); - gst_element_class_add_pad_template (gstelement_klass, - gst_static_pad_template_get (&rtp_ssrc_demux_src_template)); - gst_element_class_add_pad_template (gstelement_klass, - gst_static_pad_template_get (&rtp_ssrc_demux_rtcp_src_template)); - - gst_element_class_set_details (gstelement_klass, &gst_rtp_ssrc_demux_details); -} - -static void -gst_rtp_ssrc_demux_class_init (GstRtpSsrcDemuxClass * klass) -{ - GObjectClass *gobject_klass; - GstElementClass *gstelement_klass; - GstRtpSsrcDemuxClass *gstrtpssrcdemux_klass; - - gobject_klass = (GObjectClass *) klass; - gstelement_klass = (GstElementClass *) klass; - gstrtpssrcdemux_klass = (GstRtpSsrcDemuxClass *) klass; - - gobject_klass->dispose = GST_DEBUG_FUNCPTR (gst_rtp_ssrc_demux_dispose); - gobject_klass->finalize = GST_DEBUG_FUNCPTR (gst_rtp_ssrc_demux_finalize); - - /** - * GstRtpSsrcDemux::new-ssrc-pad: - * @demux: the object which received the signal - * @ssrc: the SSRC of the pad - * @pad: the new pad. - * - * Emited when a new SSRC pad has been created. - */ - gst_rtp_ssrc_demux_signals[SIGNAL_NEW_SSRC_PAD] = - g_signal_new ("new-ssrc-pad", - G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GstRtpSsrcDemuxClass, new_ssrc_pad), - NULL, NULL, gst_rtp_bin_marshal_VOID__UINT_OBJECT, - G_TYPE_NONE, 2, G_TYPE_UINT, GST_TYPE_PAD); - - /** - * GstRtpSsrcDemux::removed-ssrc-pad: - * @demux: the object which received the signal - * @ssrc: the SSRC of the pad - * @pad: the removed pad. - * - * Emited when a SSRC pad has been removed. - */ - gst_rtp_ssrc_demux_signals[SIGNAL_REMOVED_SSRC_PAD] = - g_signal_new ("removed-ssrc-pad", - G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GstRtpSsrcDemuxClass, removed_ssrc_pad), - NULL, NULL, gst_rtp_bin_marshal_VOID__UINT_OBJECT, - G_TYPE_NONE, 2, G_TYPE_UINT, GST_TYPE_PAD); - - /** - * GstRtpSsrcDemux::clear-ssrc: - * @demux: the object which received the signal - * @ssrc: the SSRC of the pad - * - * Action signal to remove the pad for SSRC. - */ - gst_rtp_ssrc_demux_signals[SIGNAL_CLEAR_SSRC] = - g_signal_new ("clear-ssrc", - G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, - G_STRUCT_OFFSET (GstRtpSsrcDemuxClass, clear_ssrc), - NULL, NULL, gst_rtp_bin_marshal_VOID__UINT, G_TYPE_NONE, 1, G_TYPE_UINT); - - gstelement_klass->change_state = - GST_DEBUG_FUNCPTR (gst_rtp_ssrc_demux_change_state); - gstrtpssrcdemux_klass->clear_ssrc = - GST_DEBUG_FUNCPTR (gst_rtp_ssrc_demux_clear_ssrc); - - GST_DEBUG_CATEGORY_INIT (gst_rtp_ssrc_demux_debug, - "rtpssrcdemux", 0, "RTP SSRC demuxer"); -} - -static void -gst_rtp_ssrc_demux_init (GstRtpSsrcDemux * demux, - GstRtpSsrcDemuxClass * g_class) -{ - GstElementClass *klass = GST_ELEMENT_GET_CLASS (demux); - - demux->rtp_sink = - gst_pad_new_from_template (gst_element_class_get_pad_template (klass, - "sink"), "sink"); - gst_pad_set_chain_function (demux->rtp_sink, gst_rtp_ssrc_demux_chain); - gst_pad_set_event_function (demux->rtp_sink, gst_rtp_ssrc_demux_sink_event); - gst_element_add_pad (GST_ELEMENT_CAST (demux), demux->rtp_sink); - - demux->rtcp_sink = - gst_pad_new_from_template (gst_element_class_get_pad_template (klass, - "rtcp_sink"), "rtcp_sink"); - gst_pad_set_chain_function (demux->rtcp_sink, gst_rtp_ssrc_demux_rtcp_chain); - gst_pad_set_event_function (demux->rtcp_sink, - gst_rtp_ssrc_demux_rtcp_sink_event); - gst_element_add_pad (GST_ELEMENT_CAST (demux), demux->rtcp_sink); - - demux->padlock = g_mutex_new (); - - gst_segment_init (&demux->segment, GST_FORMAT_UNDEFINED); -} - -static void -gst_rtp_ssrc_demux_reset (GstRtpSsrcDemux * demux) -{ - GSList *walk; - - for (walk = demux->srcpads; walk; walk = g_slist_next (walk)) { - GstRtpSsrcDemuxPad *dpad = (GstRtpSsrcDemuxPad *) walk->data; - - gst_pad_set_active (dpad->rtp_pad, FALSE); - gst_pad_set_active (dpad->rtcp_pad, FALSE); - - gst_element_remove_pad (GST_ELEMENT_CAST (demux), dpad->rtp_pad); - gst_element_remove_pad (GST_ELEMENT_CAST (demux), dpad->rtcp_pad); - g_free (dpad); - } - g_slist_free (demux->srcpads); - demux->srcpads = NULL; -} - -static void -gst_rtp_ssrc_demux_dispose (GObject * object) -{ - GstRtpSsrcDemux *demux; - - demux = GST_RTP_SSRC_DEMUX (object); - - gst_rtp_ssrc_demux_reset (demux); - - G_OBJECT_CLASS (parent_class)->dispose (object); -} - -static void -gst_rtp_ssrc_demux_finalize (GObject * object) -{ - GstRtpSsrcDemux *demux; - - demux = GST_RTP_SSRC_DEMUX (object); - g_mutex_free (demux->padlock); - - G_OBJECT_CLASS (parent_class)->finalize (object); -} - -static void -gst_rtp_ssrc_demux_clear_ssrc (GstRtpSsrcDemux * demux, guint32 ssrc) -{ - GstRtpSsrcDemuxPad *dpad; - - GST_PAD_LOCK (demux); - dpad = find_demux_pad_for_ssrc (demux, ssrc); - if (dpad != NULL) - goto unknown_pad; - - GST_DEBUG_OBJECT (demux, "clearing pad for SSRC %08x", ssrc); - - demux->srcpads = g_slist_remove (demux->srcpads, dpad); - GST_PAD_UNLOCK (demux); - - gst_pad_set_active (dpad->rtp_pad, FALSE); - gst_pad_set_active (dpad->rtcp_pad, FALSE); - - g_signal_emit (G_OBJECT (demux), - gst_rtp_ssrc_demux_signals[SIGNAL_REMOVED_SSRC_PAD], 0, ssrc, - dpad->rtp_pad); - - gst_element_remove_pad (GST_ELEMENT_CAST (demux), dpad->rtp_pad); - gst_element_remove_pad (GST_ELEMENT_CAST (demux), dpad->rtcp_pad); - - g_free (dpad); - - return; - - /* ERRORS */ -unknown_pad: - { - g_warning ("unknown SSRC %08x", ssrc); - return; - } -} - -static gboolean -gst_rtp_ssrc_demux_sink_event (GstPad * pad, GstEvent * event) -{ - GstRtpSsrcDemux *demux; - gboolean res = FALSE; - - demux = GST_RTP_SSRC_DEMUX (gst_pad_get_parent (pad)); - - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_FLUSH_STOP: - gst_segment_init (&demux->segment, GST_FORMAT_UNDEFINED); - case GST_EVENT_NEWSEGMENT: - default: - { - GSList *walk; - - res = TRUE; - GST_PAD_LOCK (demux); - for (walk = demux->srcpads; walk; walk = g_slist_next (walk)) { - GstRtpSsrcDemuxPad *pad = (GstRtpSsrcDemuxPad *) walk->data; - - gst_event_ref (event); - res &= gst_pad_push_event (pad->rtp_pad, event); - } - GST_PAD_UNLOCK (demux); - gst_event_unref (event); - break; - } - } - - gst_object_unref (demux); - return res; -} - -static gboolean -gst_rtp_ssrc_demux_rtcp_sink_event (GstPad * pad, GstEvent * event) -{ - GstRtpSsrcDemux *demux; - gboolean res = FALSE; - - demux = GST_RTP_SSRC_DEMUX (gst_pad_get_parent (pad)); - - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_NEWSEGMENT: - default: - { - GSList *walk; - - res = TRUE; - GST_PAD_LOCK (demux); - for (walk = demux->srcpads; walk; walk = g_slist_next (walk)) { - GstRtpSsrcDemuxPad *pad = (GstRtpSsrcDemuxPad *) walk->data; - - gst_event_ref (event); - res &= gst_pad_push_event (pad->rtcp_pad, event); - } - GST_PAD_UNLOCK (demux); - gst_event_unref (event); - break; - } - } - gst_object_unref (demux); - return res; -} - -static GstFlowReturn -gst_rtp_ssrc_demux_chain (GstPad * pad, GstBuffer * buf) -{ - GstFlowReturn ret; - GstRtpSsrcDemux *demux; - guint32 ssrc; - GstRtpSsrcDemuxPad *dpad; - - demux = GST_RTP_SSRC_DEMUX (GST_OBJECT_PARENT (pad)); - - if (!gst_rtp_buffer_validate (buf)) - goto invalid_payload; - - ssrc = gst_rtp_buffer_get_ssrc (buf); - - GST_DEBUG_OBJECT (demux, "received buffer of SSRC %08x", ssrc); - - GST_PAD_LOCK (demux); - dpad = find_demux_pad_for_ssrc (demux, ssrc); - if (dpad == NULL) { - if (!(dpad = - create_demux_pad_for_ssrc (demux, ssrc, - GST_BUFFER_TIMESTAMP (buf)))) - goto create_failed; - } - GST_PAD_UNLOCK (demux); - - /* push to srcpad */ - ret = gst_pad_push (dpad->rtp_pad, buf); - - return ret; - - /* ERRORS */ -invalid_payload: - { - /* this is fatal and should be filtered earlier */ - GST_ELEMENT_ERROR (demux, STREAM, DECODE, (NULL), - ("Dropping invalid RTP payload")); - gst_buffer_unref (buf); - return GST_FLOW_ERROR; - } -create_failed: - { - GST_ELEMENT_ERROR (demux, STREAM, DECODE, (NULL), - ("Could not create new pad")); - GST_PAD_UNLOCK (demux); - gst_buffer_unref (buf); - return GST_FLOW_ERROR; - } -} - -static GstFlowReturn -gst_rtp_ssrc_demux_rtcp_chain (GstPad * pad, GstBuffer * buf) -{ - GstFlowReturn ret; - GstRtpSsrcDemux *demux; - guint32 ssrc; - GstRtpSsrcDemuxPad *dpad; - GstRTCPPacket packet; - - demux = GST_RTP_SSRC_DEMUX (GST_OBJECT_PARENT (pad)); - - if (!gst_rtcp_buffer_validate (buf)) - goto invalid_rtcp; - - if (!gst_rtcp_buffer_get_first_packet (buf, &packet)) - goto invalid_rtcp; - - /* first packet must be SR or RR or else the validate would have failed */ - switch (gst_rtcp_packet_get_type (&packet)) { - case GST_RTCP_TYPE_SR: - /* get the ssrc so that we can route it to the right source pad */ - gst_rtcp_packet_sr_get_sender_info (&packet, &ssrc, NULL, NULL, NULL, - NULL); - break; - default: - goto unexpected_rtcp; - } - - GST_DEBUG_OBJECT (demux, "received RTCP of SSRC %08x", ssrc); - - GST_PAD_LOCK (demux); - dpad = find_demux_pad_for_ssrc (demux, ssrc); - if (dpad == NULL) { - GST_DEBUG_OBJECT (demux, "creating pad for SSRC %08x", ssrc); - if (!(dpad = create_demux_pad_for_ssrc (demux, ssrc, -1))) - goto create_failed; - } - GST_PAD_UNLOCK (demux); - - /* push to srcpad */ - ret = gst_pad_push (dpad->rtcp_pad, buf); - - return ret; - - /* ERRORS */ -invalid_rtcp: - { - /* this is fatal and should be filtered earlier */ - GST_ELEMENT_ERROR (demux, STREAM, DECODE, (NULL), - ("Dropping invalid RTCP packet")); - gst_buffer_unref (buf); - return GST_FLOW_ERROR; - } -unexpected_rtcp: - { - GST_DEBUG_OBJECT (demux, "dropping unexpected RTCP packet"); - gst_buffer_unref (buf); - return GST_FLOW_OK; - } -create_failed: - { - GST_ELEMENT_ERROR (demux, STREAM, DECODE, (NULL), - ("Could not create new pad")); - GST_PAD_UNLOCK (demux); - gst_buffer_unref (buf); - return GST_FLOW_ERROR; - } -} - -static gboolean -gst_rtp_ssrc_demux_src_event (GstPad * pad, GstEvent * event) -{ - GstRtpSsrcDemux *demux; - gboolean res = FALSE; - - demux = GST_RTP_SSRC_DEMUX (gst_pad_get_parent (pad)); - - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_SEEK: - default: - res = gst_pad_event_default (pad, event); - break; - } - gst_object_unref (demux); - return res; -} - -static GList * -gst_rtp_ssrc_demux_internal_links (GstPad * pad) -{ - GstRtpSsrcDemux *demux; - GList *res = NULL; - GSList *walk; - - demux = GST_RTP_SSRC_DEMUX (gst_pad_get_parent (pad)); - - GST_PAD_LOCK (demux); - for (walk = demux->srcpads; walk; walk = g_slist_next (walk)) { - GstRtpSsrcDemuxPad *dpad = (GstRtpSsrcDemuxPad *) walk->data; - - if (pad == demux->rtp_sink) { - res = g_list_prepend (res, dpad->rtp_pad); - } else if (pad == demux->rtcp_sink) { - res = g_list_prepend (res, dpad->rtcp_pad); - } else if (pad == dpad->rtp_pad) { - res = g_list_prepend (res, demux->rtp_sink); - break; - } else if (pad == dpad->rtcp_pad) { - res = g_list_prepend (res, demux->rtcp_sink); - break; - } - } - GST_PAD_UNLOCK (demux); - - gst_object_unref (demux); - return res; -} - -static gboolean -gst_rtp_ssrc_demux_src_query (GstPad * pad, GstQuery * query) -{ - GstRtpSsrcDemux *demux; - gboolean res = FALSE; - - demux = GST_RTP_SSRC_DEMUX (gst_pad_get_parent (pad)); - - switch (GST_QUERY_TYPE (query)) { - case GST_QUERY_LATENCY: - { - - if ((res = gst_pad_peer_query (demux->rtp_sink, query))) { - gboolean live; - GstClockTime min_latency, max_latency; - GstRtpSsrcDemuxPad *demuxpad; - - demuxpad = gst_pad_get_element_private (pad); - - gst_query_parse_latency (query, &live, &min_latency, &max_latency); - - GST_DEBUG_OBJECT (demux, "peer min latency %" GST_TIME_FORMAT, - GST_TIME_ARGS (min_latency)); - - GST_DEBUG_OBJECT (demux, "latency for SSRC %08x", demuxpad->ssrc); - - gst_query_set_latency (query, live, min_latency, max_latency); - } - break; - } - default: - res = gst_pad_query_default (pad, query); - break; - } - gst_object_unref (demux); - - return res; -} - -static GstStateChangeReturn -gst_rtp_ssrc_demux_change_state (GstElement * element, - GstStateChange transition) -{ - GstStateChangeReturn ret; - GstRtpSsrcDemux *demux; - - demux = GST_RTP_SSRC_DEMUX (element); - - switch (transition) { - case GST_STATE_CHANGE_NULL_TO_READY: - case GST_STATE_CHANGE_READY_TO_PAUSED: - case GST_STATE_CHANGE_PAUSED_TO_PLAYING: - default: - break; - } - - ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); - - switch (transition) { - case GST_STATE_CHANGE_PLAYING_TO_PAUSED: - break; - case GST_STATE_CHANGE_PAUSED_TO_READY: - gst_rtp_ssrc_demux_reset (demux); - break; - case GST_STATE_CHANGE_READY_TO_NULL: - default: - break; - } - return ret; -} diff --git a/gst/rtpmanager/gstrtpssrcdemux.h b/gst/rtpmanager/gstrtpssrcdemux.h deleted file mode 100644 index d5a13caf..00000000 --- a/gst/rtpmanager/gstrtpssrcdemux.h +++ /dev/null @@ -1,62 +0,0 @@ -/* GStreamer - * Copyright (C) <2007> Wim Taymans <wim.taymans@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., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __GST_RTP_SSRC_DEMUX_H__ -#define __GST_RTP_SSRC_DEMUX_H__ - -#include <gst/gst.h> - -#define GST_TYPE_RTP_SSRC_DEMUX (gst_rtp_ssrc_demux_get_type()) -#define GST_RTP_SSRC_DEMUX(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_SSRC_DEMUX,GstRtpSsrcDemux)) -#define GST_RTP_SSRC_DEMUX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_SSRC_DEMUX,GstRtpSsrcDemuxClass)) -#define GST_IS_RTP_SSRC_DEMUX(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_SSRC_DEMUX)) -#define GST_IS_RTP_SSRC_DEMUX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_SSRC_DEMUX)) - -typedef struct _GstRtpSsrcDemux GstRtpSsrcDemux; -typedef struct _GstRtpSsrcDemuxClass GstRtpSsrcDemuxClass; -typedef struct _GstRtpSsrcDemuxPad GstRtpSsrcDemuxPad; - -struct _GstRtpSsrcDemux -{ - GstElement parent; - - GstSegment segment; - - GstPad *rtp_sink; - GstPad *rtcp_sink; - - GMutex *padlock; - GSList *srcpads; -}; - -struct _GstRtpSsrcDemuxClass -{ - GstElementClass parent_class; - - /* signals */ - void (*new_ssrc_pad) (GstRtpSsrcDemux *demux, guint32 ssrc, GstPad *pad); - void (*removed_ssrc_pad) (GstRtpSsrcDemux *demux, guint32 ssrc, GstPad *pad); - - /* actions */ - void (*clear_ssrc) (GstRtpSsrcDemux *demux, guint32 ssrc); -}; - -GType gst_rtp_ssrc_demux_get_type (void); - -#endif /* __GST_RTP_SSRC_DEMUX_H__ */ diff --git a/gst/rtpmanager/rtpjitterbuffer.c b/gst/rtpmanager/rtpjitterbuffer.c deleted file mode 100644 index 123d26f0..00000000 --- a/gst/rtpmanager/rtpjitterbuffer.c +++ /dev/null @@ -1,593 +0,0 @@ -/* GStreamer - * Copyright (C) <2007> Wim Taymans <wim.taymans@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., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ -#include <string.h> -#include <stdlib.h> - -#include <gst/rtp/gstrtpbuffer.h> -#include <gst/rtp/gstrtcpbuffer.h> - -#include "rtpjitterbuffer.h" - -GST_DEBUG_CATEGORY_STATIC (rtp_jitter_buffer_debug); -#define GST_CAT_DEFAULT rtp_jitter_buffer_debug - -#define MAX_WINDOW RTP_JITTER_BUFFER_MAX_WINDOW -#define MAX_TIME (2 * GST_SECOND) - -/* signals and args */ -enum -{ - LAST_SIGNAL -}; - -enum -{ - PROP_0 -}; - -/* GObject vmethods */ -static void rtp_jitter_buffer_finalize (GObject * object); - -/* static guint rtp_jitter_buffer_signals[LAST_SIGNAL] = { 0 }; */ - -G_DEFINE_TYPE (RTPJitterBuffer, rtp_jitter_buffer, G_TYPE_OBJECT); - -static void -rtp_jitter_buffer_class_init (RTPJitterBufferClass * klass) -{ - GObjectClass *gobject_class; - - gobject_class = (GObjectClass *) klass; - - gobject_class->finalize = rtp_jitter_buffer_finalize; - - GST_DEBUG_CATEGORY_INIT (rtp_jitter_buffer_debug, "rtpjitterbuffer", 0, - "RTP Jitter Buffer"); -} - -static void -rtp_jitter_buffer_init (RTPJitterBuffer * jbuf) -{ - jbuf->packets = g_queue_new (); - - rtp_jitter_buffer_reset_skew (jbuf); -} - -static void -rtp_jitter_buffer_finalize (GObject * object) -{ - RTPJitterBuffer *jbuf; - - jbuf = RTP_JITTER_BUFFER_CAST (object); - - rtp_jitter_buffer_flush (jbuf); - g_queue_free (jbuf->packets); - - G_OBJECT_CLASS (rtp_jitter_buffer_parent_class)->finalize (object); -} - -/** - * rtp_jitter_buffer_new: - * - * Create an #RTPJitterBuffer. - * - * Returns: a new #RTPJitterBuffer. Use g_object_unref() after usage. - */ -RTPJitterBuffer * -rtp_jitter_buffer_new (void) -{ - RTPJitterBuffer *jbuf; - - jbuf = g_object_new (RTP_TYPE_JITTER_BUFFER, NULL); - - return jbuf; -} - -void -rtp_jitter_buffer_reset_skew (RTPJitterBuffer * jbuf) -{ - jbuf->base_time = -1; - jbuf->base_rtptime = -1; - jbuf->base_extrtp = -1; - jbuf->clock_rate = -1; - jbuf->ext_rtptime = -1; - jbuf->last_rtptime = -1; - jbuf->window_pos = 0; - jbuf->window_filling = TRUE; - jbuf->window_min = 0; - jbuf->skew = 0; - jbuf->prev_send_diff = -1; - jbuf->prev_out_time = -1; - GST_DEBUG ("reset skew correction"); -} - -/* For the clock skew we use a windowed low point averaging algorithm as can be - * found in http://www.grame.fr/pub/TR-050601.pdf. The idea is that the jitter is - * composed of: - * - * J = N + n - * - * N : a constant network delay. - * n : random added noise. The noise is concentrated around 0 - * - * In the receiver we can track the elapsed time at the sender with: - * - * send_diff(i) = (Tsi - Ts0); - * - * Tsi : The time at the sender at packet i - * Ts0 : The time at the sender at the first packet - * - * This is the difference between the RTP timestamp in the first received packet - * and the current packet. - * - * At the receiver we have to deal with the jitter introduced by the network. - * - * recv_diff(i) = (Tri - Tr0) - * - * Tri : The time at the receiver at packet i - * Tr0 : The time at the receiver at the first packet - * - * Both of these values contain a jitter Ji, a jitter for packet i, so we can - * write: - * - * recv_diff(i) = (Cri + D + ni) - (Cr0 + D + n0)) - * - * Cri : The time of the clock at the receiver for packet i - * D + ni : The jitter when receiving packet i - * - * We see that the network delay is irrelevant here as we can elliminate D: - * - * recv_diff(i) = (Cri + ni) - (Cr0 + n0)) - * - * The drift is now expressed as: - * - * Drift(i) = recv_diff(i) - send_diff(i); - * - * We now keep the W latest values of Drift and find the minimum (this is the - * one with the lowest network jitter and thus the one which is least affected - * by it). We average this lowest value to smooth out the resulting network skew. - * - * Both the window and the weighting used for averaging influence the accuracy - * of the drift estimation. Finding the correct parameters turns out to be a - * compromise between accuracy and inertia. - * - * We use a 2 second window or up to 512 data points, which is statistically big - * enough to catch spikes (FIXME, detect spikes). - * We also use a rather large weighting factor (125) to smoothly adapt. During - * startup, when filling the window, we use a parabolic weighting factor, the - * more the window is filled, the faster we move to the detected possible skew. - * - * Returns: @time adjusted with the clock skew. - */ -static GstClockTime -calculate_skew (RTPJitterBuffer * jbuf, guint32 rtptime, GstClockTime time, - guint32 clock_rate) -{ - guint64 ext_rtptime; - guint64 send_diff, recv_diff; - gint64 delta; - gint64 old; - gint pos, i; - GstClockTime gstrtptime, out_time; - - ext_rtptime = gst_rtp_buffer_ext_timestamp (&jbuf->ext_rtptime, rtptime); - - gstrtptime = gst_util_uint64_scale_int (ext_rtptime, GST_SECOND, clock_rate); - - /* keep track of the last extended rtptime */ - jbuf->last_rtptime = ext_rtptime; - - if (jbuf->clock_rate != clock_rate) { - GST_WARNING ("Clock rate changed from %" G_GUINT32_FORMAT " to %" - G_GUINT32_FORMAT, jbuf->clock_rate, clock_rate); - jbuf->base_time = -1; - jbuf->base_rtptime = -1; - jbuf->clock_rate = clock_rate; - jbuf->prev_out_time = -1; - jbuf->prev_send_diff = -1; - } - - /* first time, lock on to time and gstrtptime */ - if (G_UNLIKELY (jbuf->base_time == -1)) { - jbuf->base_time = time; - jbuf->prev_out_time = -1; - GST_DEBUG ("Taking new base time %" GST_TIME_FORMAT, GST_TIME_ARGS (time)); - } - if (G_UNLIKELY (jbuf->base_rtptime == -1)) { - jbuf->base_rtptime = gstrtptime; - jbuf->base_extrtp = ext_rtptime; - jbuf->prev_send_diff = -1; - GST_DEBUG ("Taking new base rtptime %" GST_TIME_FORMAT, - GST_TIME_ARGS (gstrtptime)); - } - - if (G_LIKELY (gstrtptime >= jbuf->base_rtptime)) - send_diff = gstrtptime - jbuf->base_rtptime; - else { - /* elapsed time at sender, timestamps can go backwards and thus be smaller - * than our base time, take a new base time in that case. */ - GST_WARNING ("backward timestamps at server, taking new base time"); - jbuf->base_time = time; - jbuf->base_rtptime = gstrtptime; - jbuf->base_extrtp = ext_rtptime; - jbuf->prev_out_time = -1; - jbuf->prev_send_diff = -1; - send_diff = 0; - } - - GST_DEBUG ("extrtp %" G_GUINT64_FORMAT ", gstrtp %" GST_TIME_FORMAT ", base %" - GST_TIME_FORMAT ", send_diff %" GST_TIME_FORMAT, ext_rtptime, - GST_TIME_ARGS (gstrtptime), GST_TIME_ARGS (jbuf->base_rtptime), - GST_TIME_ARGS (send_diff)); - - /* we don't have an arrival timestamp so we can't do skew detection. we - * should still apply a timestamp based on RTP timestamp and base_time */ - if (time == -1 || jbuf->base_time == -1) - goto no_skew; - - /* elapsed time at receiver, includes the jitter */ - recv_diff = time - jbuf->base_time; - - GST_DEBUG ("time %" GST_TIME_FORMAT ", base %" GST_TIME_FORMAT ", recv_diff %" - GST_TIME_FORMAT, GST_TIME_ARGS (time), GST_TIME_ARGS (jbuf->base_time), - GST_TIME_ARGS (recv_diff)); - - /* measure the diff */ - delta = ((gint64) recv_diff) - ((gint64) send_diff); - - /* if the difference between the sender timeline and the receiver timeline - * changed too quickly we have to resync because the server likely restarted - * its timestamps. */ - if (ABS (delta - jbuf->skew) > GST_SECOND) { - GST_WARNING ("delta %" GST_TIME_FORMAT " too big, reset skew", - GST_TIME_ARGS (delta - jbuf->skew)); - jbuf->base_time = time; - jbuf->base_rtptime = gstrtptime; - jbuf->base_extrtp = ext_rtptime; - jbuf->prev_out_time = -1; - jbuf->prev_send_diff = -1; - send_diff = 0; - delta = 0; - } - - pos = jbuf->window_pos; - - if (G_UNLIKELY (jbuf->window_filling)) { - /* we are filling the window */ - GST_DEBUG ("filling %d, delta %" G_GINT64_FORMAT, pos, delta); - jbuf->window[pos++] = delta; - /* calc the min delta we observed */ - if (G_UNLIKELY (pos == 1 || delta < jbuf->window_min)) - jbuf->window_min = delta; - - if (G_UNLIKELY (send_diff >= MAX_TIME || pos >= MAX_WINDOW)) { - jbuf->window_size = pos; - - /* window filled */ - GST_DEBUG ("min %" G_GINT64_FORMAT, jbuf->window_min); - - /* the skew is now the min */ - jbuf->skew = jbuf->window_min; - jbuf->window_filling = FALSE; - } else { - gint perc_time, perc_window, perc; - - /* figure out how much we filled the window, this depends on the amount of - * time we have or the max number of points we keep. */ - perc_time = send_diff * 100 / MAX_TIME; - perc_window = pos * 100 / MAX_WINDOW; - perc = MAX (perc_time, perc_window); - - /* make a parabolic function, the closer we get to the MAX, the more value - * we give to the scaling factor of the new value */ - perc = perc * perc; - - /* quickly go to the min value when we are filling up, slowly when we are - * just starting because we're not sure it's a good value yet. */ - jbuf->skew = - (perc * jbuf->window_min + ((10000 - perc) * jbuf->skew)) / 10000; - jbuf->window_size = pos + 1; - } - } else { - /* pick old value and store new value. We keep the previous value in order - * to quickly check if the min of the window changed */ - old = jbuf->window[pos]; - jbuf->window[pos++] = delta; - - if (G_UNLIKELY (delta <= jbuf->window_min)) { - /* if the new value we inserted is smaller or equal to the current min, - * it becomes the new min */ - jbuf->window_min = delta; - } else if (G_UNLIKELY (old == jbuf->window_min)) { - gint64 min = G_MAXINT64; - - /* if we removed the old min, we have to find a new min */ - for (i = 0; i < jbuf->window_size; i++) { - /* we found another value equal to the old min, we can stop searching now */ - if (jbuf->window[i] == old) { - min = old; - break; - } - if (jbuf->window[i] < min) - min = jbuf->window[i]; - } - jbuf->window_min = min; - } - /* average the min values */ - jbuf->skew = (jbuf->window_min + (124 * jbuf->skew)) / 125; - GST_DEBUG ("delta %" G_GINT64_FORMAT ", new min: %" G_GINT64_FORMAT, - delta, jbuf->window_min); - } - /* wrap around in the window */ - if (G_UNLIKELY (pos >= jbuf->window_size)) - pos = 0; - jbuf->window_pos = pos; - -no_skew: - /* the output time is defined as the base timestamp plus the RTP time - * adjusted for the clock skew .*/ - if (jbuf->base_time != -1) { - out_time = jbuf->base_time + send_diff + jbuf->skew; - /* check if timestamps are not going backwards, we can only check this if we - * have a previous out time and a previous send_diff */ - if (G_LIKELY (jbuf->prev_out_time != -1 && jbuf->prev_send_diff != -1)) { - /* now check for backwards timestamps */ - if (G_UNLIKELY ( - /* if the server timestamps went up and the out_time backwards */ - (send_diff > jbuf->prev_send_diff - && out_time < jbuf->prev_out_time) || - /* if the server timestamps went backwards and the out_time forwards */ - (send_diff < jbuf->prev_send_diff - && out_time > jbuf->prev_out_time) || - /* if the server timestamps did not change */ - send_diff == jbuf->prev_send_diff)) { - GST_DEBUG ("backwards timestamps, using previous time"); - out_time = jbuf->prev_out_time; - } - } - } else - out_time = -1; - - jbuf->prev_out_time = out_time; - jbuf->prev_send_diff = send_diff; - - GST_DEBUG ("skew %" G_GINT64_FORMAT ", out %" GST_TIME_FORMAT, - jbuf->skew, GST_TIME_ARGS (out_time)); - - return out_time; -} - -/** - * rtp_jitter_buffer_insert: - * @jbuf: an #RTPJitterBuffer - * @buf: a buffer - * @time: a running_time when this buffer was received in nanoseconds - * @clock_rate: the clock-rate of the payload of @buf - * @tail: TRUE when the tail element changed. - * - * Inserts @buf into the packet queue of @jbuf. The sequence number of the - * packet will be used to sort the packets. This function takes ownerhip of - * @buf when the function returns %TRUE. - * @buf should have writable metadata when calling this function. - * - * Returns: %FALSE if a packet with the same number already existed. - */ -gboolean -rtp_jitter_buffer_insert (RTPJitterBuffer * jbuf, GstBuffer * buf, - GstClockTime time, guint32 clock_rate, gboolean * tail) -{ - GList *list; - guint32 rtptime; - guint16 seqnum; - - g_return_val_if_fail (jbuf != NULL, FALSE); - g_return_val_if_fail (buf != NULL, FALSE); - - seqnum = gst_rtp_buffer_get_seq (buf); - - /* loop the list to skip strictly smaller seqnum buffers */ - for (list = jbuf->packets->head; list; list = g_list_next (list)) { - guint16 qseq; - gint gap; - - qseq = gst_rtp_buffer_get_seq (GST_BUFFER_CAST (list->data)); - - /* compare the new seqnum to the one in the buffer */ - gap = gst_rtp_buffer_compare_seqnum (seqnum, qseq); - - /* we hit a packet with the same seqnum, notify a duplicate */ - if (G_UNLIKELY (gap == 0)) - goto duplicate; - - /* seqnum > qseq, we can stop looking */ - if (G_LIKELY (gap < 0)) - break; - } - - /* do skew calculation by measuring the difference between rtptime and the - * receive time, this function will retimestamp @buf with the skew corrected - * running time. */ - rtptime = gst_rtp_buffer_get_timestamp (buf); - time = calculate_skew (jbuf, rtptime, time, clock_rate); - GST_BUFFER_TIMESTAMP (buf) = time; - - /* It's more likely that the packet was inserted in the front of the buffer */ - if (G_LIKELY (list)) - g_queue_insert_before (jbuf->packets, list, buf); - else - g_queue_push_tail (jbuf->packets, buf); - - /* tail was changed when we did not find a previous packet, we set the return - * flag when requested. */ - if (G_LIKELY (tail)) - *tail = (list == NULL); - - return TRUE; - - /* ERRORS */ -duplicate: - { - GST_WARNING ("duplicate packet %d found", (gint) seqnum); - return FALSE; - } -} - -/** - * rtp_jitter_buffer_pop: - * @jbuf: an #RTPJitterBuffer - * - * Pops the oldest buffer from the packet queue of @jbuf. The popped buffer will - * have its timestamp adjusted with the incomming running_time and the detected - * clock skew. - * - * Returns: a #GstBuffer or %NULL when there was no packet in the queue. - */ -GstBuffer * -rtp_jitter_buffer_pop (RTPJitterBuffer * jbuf) -{ - GstBuffer *buf; - - g_return_val_if_fail (jbuf != NULL, FALSE); - - buf = g_queue_pop_tail (jbuf->packets); - - return buf; -} - -/** - * rtp_jitter_buffer_peek: - * @jbuf: an #RTPJitterBuffer - * - * Peek the oldest buffer from the packet queue of @jbuf. Register a callback - * with rtp_jitter_buffer_set_tail_changed() to be notified when an older packet - * was inserted in the queue. - * - * Returns: a #GstBuffer or %NULL when there was no packet in the queue. - */ -GstBuffer * -rtp_jitter_buffer_peek (RTPJitterBuffer * jbuf) -{ - GstBuffer *buf; - - g_return_val_if_fail (jbuf != NULL, FALSE); - - buf = g_queue_peek_tail (jbuf->packets); - - return buf; -} - -/** - * rtp_jitter_buffer_flush: - * @jbuf: an #RTPJitterBuffer - * - * Flush all packets from the jitterbuffer. - */ -void -rtp_jitter_buffer_flush (RTPJitterBuffer * jbuf) -{ - GstBuffer *buffer; - - g_return_if_fail (jbuf != NULL); - - while ((buffer = g_queue_pop_head (jbuf->packets))) - gst_buffer_unref (buffer); -} - -/** - * rtp_jitter_buffer_num_packets: - * @jbuf: an #RTPJitterBuffer - * - * Get the number of packets currently in "jbuf. - * - * Returns: The number of packets in @jbuf. - */ -guint -rtp_jitter_buffer_num_packets (RTPJitterBuffer * jbuf) -{ - g_return_val_if_fail (jbuf != NULL, 0); - - return jbuf->packets->length; -} - -/** - * rtp_jitter_buffer_get_ts_diff: - * @jbuf: an #RTPJitterBuffer - * - * Get the difference between the timestamps of first and last packet in the - * jitterbuffer. - * - * Returns: The difference expressed in the timestamp units of the packets. - */ -guint32 -rtp_jitter_buffer_get_ts_diff (RTPJitterBuffer * jbuf) -{ - guint64 high_ts, low_ts; - GstBuffer *high_buf, *low_buf; - guint32 result; - - g_return_val_if_fail (jbuf != NULL, 0); - - high_buf = g_queue_peek_head (jbuf->packets); - low_buf = g_queue_peek_tail (jbuf->packets); - - if (!high_buf || !low_buf || high_buf == low_buf) - return 0; - - high_ts = gst_rtp_buffer_get_timestamp (high_buf); - low_ts = gst_rtp_buffer_get_timestamp (low_buf); - - /* it needs to work if ts wraps */ - if (high_ts >= low_ts) { - result = (guint32) (high_ts - low_ts); - } else { - result = (guint32) (high_ts + G_MAXUINT32 + 1 - low_ts); - } - return result; -} - -/** - * rtp_jitter_buffer_get_sync: - * @jbuf: an #RTPJitterBuffer - * @rtptime: result RTP time - * @timestamp: result GStreamer timestamp - * @clock_rate: clock-rate of @rtptime - * @last_rtptime: last seen rtptime. - * - * Calculates the relation between the RTP timestamp and the GStreamer timestamp - * used for constructing timestamps. - * - * For extended RTP timestamp @rtptime with a clock-rate of @clock_rate, - * the GStreamer timestamp is currently @timestamp. - * - * The last seen extended RTP timestamp with clock-rate @clock-rate is returned in - * @last_rtptime. - */ -void -rtp_jitter_buffer_get_sync (RTPJitterBuffer * jbuf, guint64 * rtptime, - guint64 * timestamp, guint32 * clock_rate, guint64 * last_rtptime) -{ - if (rtptime) - *rtptime = jbuf->base_extrtp; - if (timestamp) - *timestamp = jbuf->base_time + jbuf->skew; - if (clock_rate) - *clock_rate = jbuf->clock_rate; - if (last_rtptime) - *last_rtptime = jbuf->last_rtptime; -} diff --git a/gst/rtpmanager/rtpjitterbuffer.h b/gst/rtpmanager/rtpjitterbuffer.h deleted file mode 100644 index ff1a16b0..00000000 --- a/gst/rtpmanager/rtpjitterbuffer.h +++ /dev/null @@ -1,101 +0,0 @@ -/* GStreamer - * Copyright (C) <2007> Wim Taymans <wim.taymans@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., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __RTP_JITTER_BUFFER_H__ -#define __RTP_JITTER_BUFFER_H__ - -#include <gst/gst.h> -#include <gst/rtp/gstrtcpbuffer.h> - -typedef struct _RTPJitterBuffer RTPJitterBuffer; -typedef struct _RTPJitterBufferClass RTPJitterBufferClass; - -#define RTP_TYPE_JITTER_BUFFER (rtp_jitter_buffer_get_type()) -#define RTP_JITTER_BUFFER(src) (G_TYPE_CHECK_INSTANCE_CAST((src),RTP_TYPE_JITTER_BUFFER,RTPJitterBuffer)) -#define RTP_JITTER_BUFFER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),RTP_TYPE_JITTER_BUFFER,RTPJitterBufferClass)) -#define RTP_IS_JITTER_BUFFER(src) (G_TYPE_CHECK_INSTANCE_TYPE((src),RTP_TYPE_JITTER_BUFFER)) -#define RTP_IS_JITTER_BUFFER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),RTP_TYPE_JITTER_BUFFER)) -#define RTP_JITTER_BUFFER_CAST(src) ((RTPJitterBuffer *)(src)) - -/** - * RTPTailChanged: - * @jbuf: an #RTPJitterBuffer - * @user_data: user data specified when registering - * - * This callback will be called when the tail buffer of @jbuf changed. - */ -typedef void (*RTPTailChanged) (RTPJitterBuffer *jbuf, gpointer user_data); - -#define RTP_JITTER_BUFFER_MAX_WINDOW 512 -/** - * RTPJitterBuffer: - * - * A JitterBuffer in the #RTPSession - */ -struct _RTPJitterBuffer { - GObject object; - - GQueue *packets; - - /* for calculating skew */ - GstClockTime base_time; - GstClockTime base_rtptime; - guint32 clock_rate; - GstClockTime base_extrtp; - GstClockTime prev_out_time; - guint64 ext_rtptime; - guint64 last_rtptime; - gint64 window[RTP_JITTER_BUFFER_MAX_WINDOW]; - guint window_pos; - guint window_size; - gboolean window_filling; - gint64 window_min; - gint64 skew; - gint64 prev_send_diff; -}; - -struct _RTPJitterBufferClass { - GObjectClass parent_class; -}; - -GType rtp_jitter_buffer_get_type (void); - -/* managing lifetime */ -RTPJitterBuffer* rtp_jitter_buffer_new (void); - -void rtp_jitter_buffer_reset_skew (RTPJitterBuffer *jbuf); - -gboolean rtp_jitter_buffer_insert (RTPJitterBuffer *jbuf, GstBuffer *buf, - GstClockTime time, - guint32 clock_rate, - gboolean *tail); -GstBuffer * rtp_jitter_buffer_peek (RTPJitterBuffer *jbuf); -GstBuffer * rtp_jitter_buffer_pop (RTPJitterBuffer *jbuf); - -void rtp_jitter_buffer_flush (RTPJitterBuffer *jbuf); - -guint rtp_jitter_buffer_num_packets (RTPJitterBuffer *jbuf); -guint32 rtp_jitter_buffer_get_ts_diff (RTPJitterBuffer *jbuf); - -void rtp_jitter_buffer_get_sync (RTPJitterBuffer *jbuf, guint64 *rtptime, - guint64 *timestamp, guint32 *clock_rate, - guint64 *last_rtptime); - - -#endif /* __RTP_JITTER_BUFFER_H__ */ diff --git a/gst/rtpmanager/rtpsession.c b/gst/rtpmanager/rtpsession.c deleted file mode 100644 index 3e17ec12..00000000 --- a/gst/rtpmanager/rtpsession.c +++ /dev/null @@ -1,2521 +0,0 @@ -/* GStreamer - * Copyright (C) <2007> Wim Taymans <wim.taymans@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., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#include <string.h> - -#include <gst/rtp/gstrtpbuffer.h> -#include <gst/rtp/gstrtcpbuffer.h> -#include <gst/netbuffer/gstnetbuffer.h> - -#include "gstrtpbin-marshal.h" -#include "rtpsession.h" - -GST_DEBUG_CATEGORY_STATIC (rtp_session_debug); -#define GST_CAT_DEFAULT rtp_session_debug - -/* signals and args */ -enum -{ - SIGNAL_GET_SOURCE_BY_SSRC, - SIGNAL_ON_NEW_SSRC, - SIGNAL_ON_SSRC_COLLISION, - SIGNAL_ON_SSRC_VALIDATED, - SIGNAL_ON_SSRC_ACTIVE, - SIGNAL_ON_SSRC_SDES, - SIGNAL_ON_BYE_SSRC, - SIGNAL_ON_BYE_TIMEOUT, - SIGNAL_ON_TIMEOUT, - SIGNAL_ON_SENDER_TIMEOUT, - LAST_SIGNAL -}; - -#define DEFAULT_INTERNAL_SOURCE NULL -#define DEFAULT_BANDWIDTH RTP_STATS_BANDWIDTH -#define DEFAULT_RTCP_FRACTION RTP_STATS_RTCP_BANDWIDTH -#define DEFAULT_RTCP_MTU 1400 -#define DEFAULT_SDES NULL -#define DEFAULT_NUM_SOURCES 0 -#define DEFAULT_NUM_ACTIVE_SOURCES 0 -#define DEFAULT_SOURCES NULL - -enum -{ - PROP_0, - PROP_INTERNAL_SSRC, - PROP_INTERNAL_SOURCE, - PROP_BANDWIDTH, - PROP_RTCP_FRACTION, - PROP_RTCP_MTU, - PROP_SDES, - PROP_NUM_SOURCES, - PROP_NUM_ACTIVE_SOURCES, - PROP_SOURCES, - PROP_LAST -}; - -/* update average packet size, we keep this scaled by 16 to keep enough - * precision. */ -#define UPDATE_AVG(avg, val) \ - if ((avg) == 0) \ - (avg) = (val) << 4; \ - else \ - (avg) = ((val) + (15 * (avg))) >> 4; - -/* The number RTCP intervals after which to timeout entries in the - * collision table - */ -#define RTCP_INTERVAL_COLLISION_TIMEOUT 10 - -/* GObject vmethods */ -static void rtp_session_finalize (GObject * object); -static void rtp_session_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec); -static void rtp_session_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec); - -static guint rtp_session_signals[LAST_SIGNAL] = { 0 }; - -G_DEFINE_TYPE (RTPSession, rtp_session, G_TYPE_OBJECT); - -static RTPSource *obtain_source (RTPSession * sess, guint32 ssrc, - gboolean * created, RTPArrivalStats * arrival, gboolean rtp); -static GstFlowReturn rtp_session_schedule_bye_locked (RTPSession * sess, - const gchar * reason, GstClockTime current_time); -static GstClockTime calculate_rtcp_interval (RTPSession * sess, - gboolean deterministic, gboolean first); - -static void -rtp_session_class_init (RTPSessionClass * klass) -{ - GObjectClass *gobject_class; - - gobject_class = (GObjectClass *) klass; - - gobject_class->finalize = rtp_session_finalize; - gobject_class->set_property = rtp_session_set_property; - gobject_class->get_property = rtp_session_get_property; - - /** - * RTPSession::get-source-by-ssrc: - * @session: the object which received the signal - * @ssrc: the SSRC of the RTPSource - * - * Request the #RTPSource object with SSRC @ssrc in @session. - */ - rtp_session_signals[SIGNAL_GET_SOURCE_BY_SSRC] = - g_signal_new ("get-source-by-ssrc", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (RTPSessionClass, - get_source_by_ssrc), NULL, NULL, gst_rtp_bin_marshal_OBJECT__UINT, - RTP_TYPE_SOURCE, 1, G_TYPE_UINT); - - /** - * RTPSession::on-new-ssrc: - * @session: the object which received the signal - * @src: the new RTPSource - * - * Notify of a new SSRC that entered @session. - */ - rtp_session_signals[SIGNAL_ON_NEW_SSRC] = - g_signal_new ("on-new-ssrc", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (RTPSessionClass, on_new_ssrc), - NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, - RTP_TYPE_SOURCE); - /** - * RTPSession::on-ssrc-collision: - * @session: the object which received the signal - * @src: the #RTPSource that caused a collision - * - * Notify when we have an SSRC collision - */ - rtp_session_signals[SIGNAL_ON_SSRC_COLLISION] = - g_signal_new ("on-ssrc-collision", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (RTPSessionClass, on_ssrc_collision), - NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, - RTP_TYPE_SOURCE); - /** - * RTPSession::on-ssrc-validated: - * @session: the object which received the signal - * @src: the new validated RTPSource - * - * Notify of a new SSRC that became validated. - */ - rtp_session_signals[SIGNAL_ON_SSRC_VALIDATED] = - g_signal_new ("on-ssrc-validated", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (RTPSessionClass, on_ssrc_validated), - NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, - RTP_TYPE_SOURCE); - /** - * RTPSession::on-ssrc-active: - * @session: the object which received the signal - * @src: the active RTPSource - * - * Notify of a SSRC that is active, i.e., sending RTCP. - */ - rtp_session_signals[SIGNAL_ON_SSRC_ACTIVE] = - g_signal_new ("on-ssrc-active", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (RTPSessionClass, on_ssrc_active), - NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, - RTP_TYPE_SOURCE); - /** - * RTPSession::on-ssrc-sdes: - * @session: the object which received the signal - * @src: the RTPSource - * - * Notify that a new SDES was received for SSRC. - */ - rtp_session_signals[SIGNAL_ON_SSRC_SDES] = - g_signal_new ("on-ssrc-sdes", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (RTPSessionClass, on_ssrc_sdes), - NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, - RTP_TYPE_SOURCE); - /** - * RTPSession::on-bye-ssrc: - * @session: the object which received the signal - * @src: the RTPSource that went away - * - * Notify of an SSRC that became inactive because of a BYE packet. - */ - rtp_session_signals[SIGNAL_ON_BYE_SSRC] = - g_signal_new ("on-bye-ssrc", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (RTPSessionClass, on_bye_ssrc), - NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, - RTP_TYPE_SOURCE); - /** - * RTPSession::on-bye-timeout: - * @session: the object which received the signal - * @src: the RTPSource that timed out - * - * Notify of an SSRC that has timed out because of BYE - */ - rtp_session_signals[SIGNAL_ON_BYE_TIMEOUT] = - g_signal_new ("on-bye-timeout", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (RTPSessionClass, on_bye_timeout), - NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, - RTP_TYPE_SOURCE); - /** - * RTPSession::on-timeout: - * @session: the object which received the signal - * @src: the RTPSource that timed out - * - * Notify of an SSRC that has timed out - */ - rtp_session_signals[SIGNAL_ON_TIMEOUT] = - g_signal_new ("on-timeout", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (RTPSessionClass, on_timeout), - NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, - RTP_TYPE_SOURCE); - /** - * RTPSession::on-sender-timeout: - * @session: the object which received the signal - * @src: the RTPSource that timed out - * - * Notify of an SSRC that was a sender but timed out and became a receiver. - */ - rtp_session_signals[SIGNAL_ON_SENDER_TIMEOUT] = - g_signal_new ("on-sender-timeout", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (RTPSessionClass, on_sender_timeout), - NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, - RTP_TYPE_SOURCE); - - g_object_class_install_property (gobject_class, PROP_INTERNAL_SSRC, - g_param_spec_uint ("internal-ssrc", "Internal SSRC", - "The internal SSRC used for the session", - 0, G_MAXUINT, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (gobject_class, PROP_INTERNAL_SOURCE, - g_param_spec_object ("internal-source", "Internal Source", - "The internal source element of the session", - RTP_TYPE_SOURCE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (gobject_class, PROP_BANDWIDTH, - g_param_spec_double ("bandwidth", "Bandwidth", - "The bandwidth of the session", - 0.0, G_MAXDOUBLE, DEFAULT_BANDWIDTH, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (gobject_class, PROP_RTCP_FRACTION, - g_param_spec_double ("rtcp-fraction", "RTCP Fraction", - "The fraction of the bandwidth used for RTCP", - 0.0, G_MAXDOUBLE, DEFAULT_RTCP_FRACTION, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (gobject_class, PROP_RTCP_MTU, - g_param_spec_uint ("rtcp-mtu", "RTCP MTU", - "The maximum size of the RTCP packets", - 16, G_MAXINT16, DEFAULT_RTCP_MTU, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (gobject_class, PROP_SDES, - g_param_spec_boxed ("sdes", "SDES", - "The SDES items of this session", - GST_TYPE_STRUCTURE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (gobject_class, PROP_NUM_SOURCES, - g_param_spec_uint ("num-sources", "Num Sources", - "The number of sources in the session", 0, G_MAXUINT, - DEFAULT_NUM_SOURCES, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (gobject_class, PROP_NUM_ACTIVE_SOURCES, - g_param_spec_uint ("num-active-sources", "Num Active Sources", - "The number of active sources in the session", 0, G_MAXUINT, - DEFAULT_NUM_ACTIVE_SOURCES, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); - /** - * RTPSource::sources - * - * Get a GValue Array of all sources in the session. - * - * <example> - * <title>Getting the #RTPSources of a session - * <programlisting> - * { - * GValueArray *arr; - * GValue *val; - * guint i; - * - * g_object_get (sess, "sources", &arr, NULL); - * - * for (i = 0; i < arr->n_values; i++) { - * RTPSource *source; - * - * val = g_value_array_get_nth (arr, i); - * source = g_value_get_object (val); - * } - * g_value_array_free (arr); - * } - * </programlisting> - * </example> - */ - g_object_class_install_property (gobject_class, PROP_SOURCES, - g_param_spec_boxed ("sources", "Sources", - "An array of all known sources in the session", - G_TYPE_VALUE_ARRAY, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); - - klass->get_source_by_ssrc = - GST_DEBUG_FUNCPTR (rtp_session_get_source_by_ssrc); - - GST_DEBUG_CATEGORY_INIT (rtp_session_debug, "rtpsession", 0, "RTP Session"); -} - -static void -rtp_session_init (RTPSession * sess) -{ - gint i; - gchar *str; - - sess->lock = g_mutex_new (); - sess->key = g_random_int (); - sess->mask_idx = 0; - sess->mask = 0; - - for (i = 0; i < 32; i++) { - sess->ssrcs[i] = - g_hash_table_new_full (NULL, NULL, NULL, - (GDestroyNotify) g_object_unref); - } - sess->cnames = g_hash_table_new_full (NULL, NULL, g_free, NULL); - - rtp_stats_init_defaults (&sess->stats); - - /* create an active SSRC for this session manager */ - sess->source = rtp_session_create_source (sess); - sess->source->validated = TRUE; - sess->source->internal = TRUE; - sess->stats.active_sources++; - - /* default UDP header length */ - sess->header_len = 28; - sess->mtu = DEFAULT_RTCP_MTU; - - /* some default SDES entries */ - str = g_strdup_printf ("%s@%s", g_get_user_name (), g_get_host_name ()); - rtp_source_set_sdes_string (sess->source, GST_RTCP_SDES_CNAME, str); - g_free (str); - - rtp_source_set_sdes_string (sess->source, GST_RTCP_SDES_NAME, - g_get_real_name ()); - rtp_source_set_sdes_string (sess->source, GST_RTCP_SDES_TOOL, "GStreamer"); - - sess->first_rtcp = TRUE; - - GST_DEBUG ("%p: session using SSRC: %08x", sess, sess->source->ssrc); -} - -static void -rtp_session_finalize (GObject * object) -{ - RTPSession *sess; - gint i; - - sess = RTP_SESSION_CAST (object); - - g_mutex_free (sess->lock); - for (i = 0; i < 32; i++) - g_hash_table_destroy (sess->ssrcs[i]); - - g_list_foreach (sess->conflicting_addresses, (GFunc) g_free, NULL); - g_list_free (sess->conflicting_addresses); - - g_free (sess->bye_reason); - - g_hash_table_destroy (sess->cnames); - g_object_unref (sess->source); - - G_OBJECT_CLASS (rtp_session_parent_class)->finalize (object); -} - -static void -copy_source (gpointer key, RTPSource * source, GValueArray * arr) -{ - GValue value = { 0 }; - - g_value_init (&value, RTP_TYPE_SOURCE); - g_value_take_object (&value, source); - /* copies the value */ - g_value_array_append (arr, &value); -} - -static GValueArray * -rtp_session_create_sources (RTPSession * sess) -{ - GValueArray *res; - guint size; - - RTP_SESSION_LOCK (sess); - /* get number of elements in the table */ - size = g_hash_table_size (sess->ssrcs[sess->mask_idx]); - /* create the result value array */ - res = g_value_array_new (size); - - /* and copy all values into the array */ - g_hash_table_foreach (sess->ssrcs[sess->mask_idx], (GHFunc) copy_source, res); - RTP_SESSION_UNLOCK (sess); - - return res; -} - -static void -rtp_session_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) -{ - RTPSession *sess; - - sess = RTP_SESSION (object); - - switch (prop_id) { - case PROP_INTERNAL_SSRC: - rtp_session_set_internal_ssrc (sess, g_value_get_uint (value)); - break; - case PROP_BANDWIDTH: - rtp_session_set_bandwidth (sess, g_value_get_double (value)); - break; - case PROP_RTCP_FRACTION: - rtp_session_set_rtcp_fraction (sess, g_value_get_double (value)); - break; - case PROP_RTCP_MTU: - sess->mtu = g_value_get_uint (value); - break; - case PROP_SDES: - rtp_session_set_sdes_struct (sess, g_value_get_boxed (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -rtp_session_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec) -{ - RTPSession *sess; - - sess = RTP_SESSION (object); - - switch (prop_id) { - case PROP_INTERNAL_SSRC: - g_value_set_uint (value, rtp_session_get_internal_ssrc (sess)); - break; - case PROP_INTERNAL_SOURCE: - g_value_take_object (value, rtp_session_get_internal_source (sess)); - break; - case PROP_BANDWIDTH: - g_value_set_double (value, rtp_session_get_bandwidth (sess)); - break; - case PROP_RTCP_FRACTION: - g_value_set_double (value, rtp_session_get_rtcp_fraction (sess)); - break; - case PROP_RTCP_MTU: - g_value_set_uint (value, sess->mtu); - break; - case PROP_SDES: - g_value_take_boxed (value, rtp_session_get_sdes_struct (sess)); - break; - case PROP_NUM_SOURCES: - g_value_set_uint (value, rtp_session_get_num_sources (sess)); - break; - case PROP_NUM_ACTIVE_SOURCES: - g_value_set_uint (value, rtp_session_get_num_active_sources (sess)); - break; - case PROP_SOURCES: - g_value_take_boxed (value, rtp_session_create_sources (sess)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -on_new_ssrc (RTPSession * sess, RTPSource * source) -{ - g_object_ref (source); - RTP_SESSION_UNLOCK (sess); - g_signal_emit (sess, rtp_session_signals[SIGNAL_ON_NEW_SSRC], 0, source); - RTP_SESSION_LOCK (sess); - g_object_unref (source); -} - -static void -on_ssrc_collision (RTPSession * sess, RTPSource * source) -{ - g_object_ref (source); - RTP_SESSION_UNLOCK (sess); - g_signal_emit (sess, rtp_session_signals[SIGNAL_ON_SSRC_COLLISION], 0, - source); - RTP_SESSION_LOCK (sess); - g_object_unref (source); -} - -static void -on_ssrc_validated (RTPSession * sess, RTPSource * source) -{ - g_object_ref (source); - RTP_SESSION_UNLOCK (sess); - g_signal_emit (sess, rtp_session_signals[SIGNAL_ON_SSRC_VALIDATED], 0, - source); - RTP_SESSION_LOCK (sess); - g_object_unref (source); -} - -static void -on_ssrc_active (RTPSession * sess, RTPSource * source) -{ - g_object_ref (source); - RTP_SESSION_UNLOCK (sess); - g_signal_emit (sess, rtp_session_signals[SIGNAL_ON_SSRC_ACTIVE], 0, source); - RTP_SESSION_LOCK (sess); - g_object_unref (source); -} - -static void -on_ssrc_sdes (RTPSession * sess, RTPSource * source) -{ - g_object_ref (source); - GST_DEBUG ("SDES changed for SSRC %08x", source->ssrc); - RTP_SESSION_UNLOCK (sess); - g_signal_emit (sess, rtp_session_signals[SIGNAL_ON_SSRC_SDES], 0, source); - RTP_SESSION_LOCK (sess); - g_object_unref (source); -} - -static void -on_bye_ssrc (RTPSession * sess, RTPSource * source) -{ - g_object_ref (source); - RTP_SESSION_UNLOCK (sess); - g_signal_emit (sess, rtp_session_signals[SIGNAL_ON_BYE_SSRC], 0, source); - RTP_SESSION_LOCK (sess); - g_object_unref (source); -} - -static void -on_bye_timeout (RTPSession * sess, RTPSource * source) -{ - g_object_ref (source); - RTP_SESSION_UNLOCK (sess); - g_signal_emit (sess, rtp_session_signals[SIGNAL_ON_BYE_TIMEOUT], 0, source); - RTP_SESSION_LOCK (sess); - g_object_unref (source); -} - -static void -on_timeout (RTPSession * sess, RTPSource * source) -{ - g_object_ref (source); - RTP_SESSION_UNLOCK (sess); - g_signal_emit (sess, rtp_session_signals[SIGNAL_ON_TIMEOUT], 0, source); - RTP_SESSION_LOCK (sess); - g_object_unref (source); -} - -static void -on_sender_timeout (RTPSession * sess, RTPSource * source) -{ - g_object_ref (source); - RTP_SESSION_UNLOCK (sess); - g_signal_emit (sess, rtp_session_signals[SIGNAL_ON_SENDER_TIMEOUT], 0, - source); - RTP_SESSION_LOCK (sess); - g_object_unref (source); -} - -/** - * rtp_session_new: - * - * Create a new session object. - * - * Returns: a new #RTPSession. g_object_unref() after usage. - */ -RTPSession * -rtp_session_new (void) -{ - RTPSession *sess; - - sess = g_object_new (RTP_TYPE_SESSION, NULL); - - return sess; -} - -/** - * rtp_session_set_callbacks: - * @sess: an #RTPSession - * @callbacks: callbacks to configure - * @user_data: user data passed in the callbacks - * - * Configure a set of callbacks to be notified of actions. - */ -void -rtp_session_set_callbacks (RTPSession * sess, RTPSessionCallbacks * callbacks, - gpointer user_data) -{ - g_return_if_fail (RTP_IS_SESSION (sess)); - - if (callbacks->process_rtp) { - sess->callbacks.process_rtp = callbacks->process_rtp; - sess->process_rtp_user_data = user_data; - } - if (callbacks->send_rtp) { - sess->callbacks.send_rtp = callbacks->send_rtp; - sess->send_rtp_user_data = user_data; - } - if (callbacks->send_rtcp) { - sess->callbacks.send_rtcp = callbacks->send_rtcp; - sess->send_rtcp_user_data = user_data; - } - if (callbacks->sync_rtcp) { - sess->callbacks.sync_rtcp = callbacks->sync_rtcp; - sess->sync_rtcp_user_data = user_data; - } - if (callbacks->clock_rate) { - sess->callbacks.clock_rate = callbacks->clock_rate; - sess->clock_rate_user_data = user_data; - } - if (callbacks->reconsider) { - sess->callbacks.reconsider = callbacks->reconsider; - sess->reconsider_user_data = user_data; - } -} - -/** - * rtp_session_set_process_rtp_callback: - * @sess: an #RTPSession - * @callback: callback to set - * @user_data: user data passed in the callback - * - * Configure only the process_rtp callback to be notified of the process_rtp action. - */ -void -rtp_session_set_process_rtp_callback (RTPSession * sess, - RTPSessionProcessRTP callback, gpointer user_data) -{ - g_return_if_fail (RTP_IS_SESSION (sess)); - - sess->callbacks.process_rtp = callback; - sess->process_rtp_user_data = user_data; -} - -/** - * rtp_session_set_send_rtp_callback: - * @sess: an #RTPSession - * @callback: callback to set - * @user_data: user data passed in the callback - * - * Configure only the send_rtp callback to be notified of the send_rtp action. - */ -void -rtp_session_set_send_rtp_callback (RTPSession * sess, - RTPSessionSendRTP callback, gpointer user_data) -{ - g_return_if_fail (RTP_IS_SESSION (sess)); - - sess->callbacks.send_rtp = callback; - sess->send_rtp_user_data = user_data; -} - -/** - * rtp_session_set_send_rtcp_callback: - * @sess: an #RTPSession - * @callback: callback to set - * @user_data: user data passed in the callback - * - * Configure only the send_rtcp callback to be notified of the send_rtcp action. - */ -void -rtp_session_set_send_rtcp_callback (RTPSession * sess, - RTPSessionSendRTCP callback, gpointer user_data) -{ - g_return_if_fail (RTP_IS_SESSION (sess)); - - sess->callbacks.send_rtcp = callback; - sess->send_rtcp_user_data = user_data; -} - -/** - * rtp_session_set_sync_rtcp_callback: - * @sess: an #RTPSession - * @callback: callback to set - * @user_data: user data passed in the callback - * - * Configure only the sync_rtcp callback to be notified of the sync_rtcp action. - */ -void -rtp_session_set_sync_rtcp_callback (RTPSession * sess, - RTPSessionSyncRTCP callback, gpointer user_data) -{ - g_return_if_fail (RTP_IS_SESSION (sess)); - - sess->callbacks.sync_rtcp = callback; - sess->sync_rtcp_user_data = user_data; -} - -/** - * rtp_session_set_clock_rate_callback: - * @sess: an #RTPSession - * @callback: callback to set - * @user_data: user data passed in the callback - * - * Configure only the clock_rate callback to be notified of the clock_rate action. - */ -void -rtp_session_set_clock_rate_callback (RTPSession * sess, - RTPSessionClockRate callback, gpointer user_data) -{ - g_return_if_fail (RTP_IS_SESSION (sess)); - - sess->callbacks.clock_rate = callback; - sess->clock_rate_user_data = user_data; -} - -/** - * rtp_session_set_reconsider_callback: - * @sess: an #RTPSession - * @callback: callback to set - * @user_data: user data passed in the callback - * - * Configure only the reconsider callback to be notified of the reconsider action. - */ -void -rtp_session_set_reconsider_callback (RTPSession * sess, - RTPSessionReconsider callback, gpointer user_data) -{ - g_return_if_fail (RTP_IS_SESSION (sess)); - - sess->callbacks.reconsider = callback; - sess->reconsider_user_data = user_data; -} - -/** - * rtp_session_set_bandwidth: - * @sess: an #RTPSession - * @bandwidth: the bandwidth allocated - * - * Set the session bandwidth in bytes per second. - */ -void -rtp_session_set_bandwidth (RTPSession * sess, gdouble bandwidth) -{ - g_return_if_fail (RTP_IS_SESSION (sess)); - - RTP_SESSION_LOCK (sess); - sess->stats.bandwidth = bandwidth; - RTP_SESSION_UNLOCK (sess); -} - -/** - * rtp_session_get_bandwidth: - * @sess: an #RTPSession - * - * Get the session bandwidth. - * - * Returns: the session bandwidth. - */ -gdouble -rtp_session_get_bandwidth (RTPSession * sess) -{ - gdouble result; - - g_return_val_if_fail (RTP_IS_SESSION (sess), 0); - - RTP_SESSION_LOCK (sess); - result = sess->stats.bandwidth; - RTP_SESSION_UNLOCK (sess); - - return result; -} - -/** - * rtp_session_set_rtcp_fraction: - * @sess: an #RTPSession - * @bandwidth: the RTCP bandwidth - * - * Set the bandwidth that should be used for RTCP - * messages. - */ -void -rtp_session_set_rtcp_fraction (RTPSession * sess, gdouble bandwidth) -{ - g_return_if_fail (RTP_IS_SESSION (sess)); - - RTP_SESSION_LOCK (sess); - sess->stats.rtcp_bandwidth = bandwidth; - RTP_SESSION_UNLOCK (sess); -} - -/** - * rtp_session_get_rtcp_fraction: - * @sess: an #RTPSession - * - * Get the session bandwidth used for RTCP. - * - * Returns: The bandwidth used for RTCP messages. - */ -gdouble -rtp_session_get_rtcp_fraction (RTPSession * sess) -{ - gdouble result; - - g_return_val_if_fail (RTP_IS_SESSION (sess), 0.0); - - RTP_SESSION_LOCK (sess); - result = sess->stats.rtcp_bandwidth; - RTP_SESSION_UNLOCK (sess); - - return result; -} - -/** - * rtp_session_set_sdes_string: - * @sess: an #RTPSession - * @type: the type of the SDES item - * @item: a null-terminated string to set. - * - * Store an SDES item of @type in @sess. - * - * Returns: %FALSE if the data was unchanged @type is invalid. - */ -gboolean -rtp_session_set_sdes_string (RTPSession * sess, GstRTCPSDESType type, - const gchar * item) -{ - gboolean result; - - g_return_val_if_fail (RTP_IS_SESSION (sess), FALSE); - - RTP_SESSION_LOCK (sess); - result = rtp_source_set_sdes_string (sess->source, type, item); - RTP_SESSION_UNLOCK (sess); - - return result; -} - -/** - * rtp_session_get_sdes_string: - * @sess: an #RTPSession - * @type: the type of the SDES item - * - * Get the SDES item of @type from @sess. - * - * Returns: a null-terminated copy of the SDES item or NULL when @type was not - * valid. g_free() after usage. - */ -gchar * -rtp_session_get_sdes_string (RTPSession * sess, GstRTCPSDESType type) -{ - gchar *result; - - g_return_val_if_fail (RTP_IS_SESSION (sess), NULL); - - RTP_SESSION_LOCK (sess); - result = rtp_source_get_sdes_string (sess->source, type); - RTP_SESSION_UNLOCK (sess); - - return result; -} - -/** - * rtp_session_get_sdes_struct: - * @sess: an #RTSPSession - * - * Get the SDES data as a #GstStructure - * - * Returns: a GstStructure with SDES items for @sess. - */ -GstStructure * -rtp_session_get_sdes_struct (RTPSession * sess) -{ - GstStructure *result; - - g_return_val_if_fail (RTP_IS_SESSION (sess), NULL); - - RTP_SESSION_LOCK (sess); - result = rtp_source_get_sdes_struct (sess->source); - RTP_SESSION_UNLOCK (sess); - - return result; -} - -/** - * rtp_session_set_sdes_struct: - * @sess: an #RTSPSession - * @sdes: a #GstStructure - * - * Set the SDES data as a #GstStructure. - */ -void -rtp_session_set_sdes_struct (RTPSession * sess, const GstStructure * sdes) -{ - g_return_if_fail (RTP_IS_SESSION (sess)); - - RTP_SESSION_LOCK (sess); - rtp_source_set_sdes_struct (sess->source, sdes); - RTP_SESSION_UNLOCK (sess); -} - -static GstFlowReturn -source_push_rtp (RTPSource * source, gpointer data, RTPSession * session) -{ - GstFlowReturn result = GST_FLOW_OK; - - if (source == session->source) { - GST_LOG ("source %08x pushed sender RTP packet", source->ssrc); - - RTP_SESSION_UNLOCK (session); - - if (session->callbacks.send_rtp) - result = - session->callbacks.send_rtp (session, source, data, - session->send_rtp_user_data); - else { - gst_mini_object_unref (GST_MINI_OBJECT_CAST (data)); - } - } else { - GST_LOG ("source %08x pushed receiver RTP packet", source->ssrc); - RTP_SESSION_UNLOCK (session); - - if (session->callbacks.process_rtp) - result = - session->callbacks.process_rtp (session, source, - GST_BUFFER_CAST (data), session->process_rtp_user_data); - else - gst_buffer_unref (GST_BUFFER_CAST (data)); - } - RTP_SESSION_LOCK (session); - - return result; -} - -static gint -source_clock_rate (RTPSource * source, guint8 pt, RTPSession * session) -{ - gint result; - - RTP_SESSION_UNLOCK (session); - - if (session->callbacks.clock_rate) - result = - session->callbacks.clock_rate (session, pt, - session->clock_rate_user_data); - else - result = -1; - - RTP_SESSION_LOCK (session); - - GST_DEBUG ("got clock-rate %d for pt %d", result, pt); - - return result; -} - -static RTPSourceCallbacks callbacks = { - (RTPSourcePushRTP) source_push_rtp, - (RTPSourceClockRate) source_clock_rate, -}; - -/** - * find_add_conflicting_addresses: - * @sess: The session to check in - * @arrival: The arrival stats for the buffer - * - * Checks if an address which has a conflict is already known, - * otherwise remembers it to prevent loops. - * - * Returns: TRUE if it was a known conflict, FALSE otherwise - */ - -static gboolean -find_add_conflicting_addresses (RTPSession * sess, RTPArrivalStats * arrival) -{ - GList *item; - RTPConflictingAddress *new_conflict; - - for (item = g_list_first (sess->conflicting_addresses); - item; item = g_list_next (item)) { - RTPConflictingAddress *known_conflict = item->data; - - if (gst_netaddress_equal (&arrival->address, &known_conflict->address)) { - known_conflict->time = arrival->time; - return TRUE; - } - } - - new_conflict = g_new0 (RTPConflictingAddress, 1); - - memcpy (&new_conflict->address, &arrival->address, sizeof (GstNetAddress)); - new_conflict->time = arrival->time; - - sess->conflicting_addresses = g_list_prepend (sess->conflicting_addresses, - new_conflict); - - return FALSE; -} - -static gboolean -check_collision (RTPSession * sess, RTPSource * source, - RTPArrivalStats * arrival, gboolean rtp) -{ - /* If we have no arrival address, we can't do collision checking */ - if (!arrival->have_address) - return FALSE; - - if (sess->source != source) { - /* This is not our local source, but lets check if two remote - * source collide - */ - if (rtp) { - if (source->have_rtp_from) { - if (gst_netaddress_equal (&source->rtp_from, &arrival->address)) - /* Address is the same */ - return FALSE; - } else { - /* We don't already have a from address for RTP, just set it */ - rtp_source_set_rtp_from (source, &arrival->address); - return FALSE; - } - } else { - if (source->have_rtcp_from) { - if (gst_netaddress_equal (&source->rtcp_from, &arrival->address)) - /* Address is the same */ - return FALSE; - } else { - /* We don't already have a from address for RTCP, just set it */ - rtp_source_set_rtcp_from (source, &arrival->address); - return FALSE; - } - } - /* We received RTP or RTCP from this source before but the network address - * changed. In this case, we have third-party collision or loop */ - GST_DEBUG ("we have a third-party collision or loop"); - - /* FIXME: Log 3rd party collision somehow - * Maybe should be done in upper layer, only the SDES can tell us - * if its a collision or a loop - */ - } else { - /* This is sending with our ssrc, is it an address we already know */ - - if (find_add_conflicting_addresses (sess, arrival)) { - /* Its a known conflict, its probably a loop, not a collision - * lets just drop the incoming packet - */ - GST_DEBUG ("Our packets are being looped back to us, dropping"); - } else { - /* Its a new collision, lets change our SSRC */ - - GST_DEBUG ("Collision for SSRC %x", rtp_source_get_ssrc (source)); - on_ssrc_collision (sess, source); - - rtp_session_schedule_bye_locked (sess, "SSRC Collision", arrival->time); - - sess->change_ssrc = TRUE; - } - } - - return TRUE; -} - - -/* must be called with the session lock, the returned source needs to be - * unreffed after usage. */ -static RTPSource * -obtain_source (RTPSession * sess, guint32 ssrc, gboolean * created, - RTPArrivalStats * arrival, gboolean rtp) -{ - RTPSource *source; - - source = - g_hash_table_lookup (sess->ssrcs[sess->mask_idx], GINT_TO_POINTER (ssrc)); - if (source == NULL) { - /* make new Source in probation and insert */ - source = rtp_source_new (ssrc); - - /* for RTP packets we need to set the source in probation. Receiving RTCP - * packets of an SSRC, on the other hand, is a strong indication that we - * are dealing with a valid source. */ - if (rtp) - source->probation = RTP_DEFAULT_PROBATION; - else - source->probation = 0; - - /* store from address, if any */ - if (arrival->have_address) { - if (rtp) - rtp_source_set_rtp_from (source, &arrival->address); - else - rtp_source_set_rtcp_from (source, &arrival->address); - } - - /* configure a callback on the source */ - rtp_source_set_callbacks (source, &callbacks, sess); - - g_hash_table_insert (sess->ssrcs[sess->mask_idx], GINT_TO_POINTER (ssrc), - source); - - /* we have one more source now */ - sess->total_sources++; - *created = TRUE; - } else { - *created = FALSE; - /* check for collision, this updates the address when not previously set */ - if (check_collision (sess, source, arrival, rtp)) { - return NULL; - } - } - /* update last activity */ - source->last_activity = arrival->time; - if (rtp) - source->last_rtp_activity = arrival->time; - g_object_ref (source); - - return source; -} - -/** - * rtp_session_get_internal_source: - * @sess: a #RTPSession - * - * Get the internal #RTPSource of @sess. - * - * Returns: The internal #RTPSource. g_object_unref() after usage. - */ -RTPSource * -rtp_session_get_internal_source (RTPSession * sess) -{ - RTPSource *result; - - g_return_val_if_fail (RTP_IS_SESSION (sess), NULL); - - result = g_object_ref (sess->source); - - return result; -} - -/** - * rtp_session_set_internal_ssrc: - * @sess: a #RTPSession - * @ssrc: an SSRC - * - * Set the SSRC of @sess to @ssrc. - */ -void -rtp_session_set_internal_ssrc (RTPSession * sess, guint32 ssrc) -{ - RTP_SESSION_LOCK (sess); - if (ssrc != sess->source->ssrc) { - g_hash_table_steal (sess->ssrcs[sess->mask_idx], - GINT_TO_POINTER (sess->source->ssrc)); - - GST_DEBUG ("setting internal SSRC to %08x", ssrc); - /* After this call, any receiver of the old SSRC either in RTP or RTCP - * packets will timeout on the old SSRC, we could potentially schedule a - * BYE RTCP for the old SSRC... */ - sess->source->ssrc = ssrc; - rtp_source_reset (sess->source); - - /* rehash with the new SSRC */ - g_hash_table_insert (sess->ssrcs[sess->mask_idx], - GINT_TO_POINTER (sess->source->ssrc), sess->source); - } - RTP_SESSION_UNLOCK (sess); - - g_object_notify (G_OBJECT (sess), "internal-ssrc"); -} - -/** - * rtp_session_get_internal_ssrc: - * @sess: a #RTPSession - * - * Get the internal SSRC of @sess. - * - * Returns: The SSRC of the session. - */ -guint32 -rtp_session_get_internal_ssrc (RTPSession * sess) -{ - guint32 ssrc; - - RTP_SESSION_LOCK (sess); - ssrc = sess->source->ssrc; - RTP_SESSION_UNLOCK (sess); - - return ssrc; -} - -/** - * rtp_session_add_source: - * @sess: a #RTPSession - * @src: #RTPSource to add - * - * Add @src to @session. - * - * Returns: %TRUE on success, %FALSE if a source with the same SSRC already - * existed in the session. - */ -gboolean -rtp_session_add_source (RTPSession * sess, RTPSource * src) -{ - gboolean result = FALSE; - RTPSource *find; - - g_return_val_if_fail (RTP_IS_SESSION (sess), FALSE); - g_return_val_if_fail (src != NULL, FALSE); - - RTP_SESSION_LOCK (sess); - find = - g_hash_table_lookup (sess->ssrcs[sess->mask_idx], - GINT_TO_POINTER (src->ssrc)); - if (find == NULL) { - g_hash_table_insert (sess->ssrcs[sess->mask_idx], - GINT_TO_POINTER (src->ssrc), src); - /* we have one more source now */ - sess->total_sources++; - result = TRUE; - } - RTP_SESSION_UNLOCK (sess); - - return result; -} - -/** - * rtp_session_get_num_sources: - * @sess: an #RTPSession - * - * Get the number of sources in @sess. - * - * Returns: The number of sources in @sess. - */ -guint -rtp_session_get_num_sources (RTPSession * sess) -{ - guint result; - - g_return_val_if_fail (RTP_IS_SESSION (sess), FALSE); - - RTP_SESSION_LOCK (sess); - result = sess->total_sources; - RTP_SESSION_UNLOCK (sess); - - return result; -} - -/** - * rtp_session_get_num_active_sources: - * @sess: an #RTPSession - * - * Get the number of active sources in @sess. A source is considered active when - * it has been validated and has not yet received a BYE RTCP message. - * - * Returns: The number of active sources in @sess. - */ -guint -rtp_session_get_num_active_sources (RTPSession * sess) -{ - guint result; - - g_return_val_if_fail (RTP_IS_SESSION (sess), 0); - - RTP_SESSION_LOCK (sess); - result = sess->stats.active_sources; - RTP_SESSION_UNLOCK (sess); - - return result; -} - -/** - * rtp_session_get_source_by_ssrc: - * @sess: an #RTPSession - * @ssrc: an SSRC - * - * Find the source with @ssrc in @sess. - * - * Returns: a #RTPSource with SSRC @ssrc or NULL if the source was not found. - * g_object_unref() after usage. - */ -RTPSource * -rtp_session_get_source_by_ssrc (RTPSession * sess, guint32 ssrc) -{ - RTPSource *result; - - g_return_val_if_fail (RTP_IS_SESSION (sess), NULL); - - RTP_SESSION_LOCK (sess); - result = - g_hash_table_lookup (sess->ssrcs[sess->mask_idx], GINT_TO_POINTER (ssrc)); - if (result) - g_object_ref (result); - RTP_SESSION_UNLOCK (sess); - - return result; -} - -/** - * rtp_session_get_source_by_cname: - * @sess: a #RTPSession - * @cname: an CNAME - * - * Find the source with @cname in @sess. - * - * Returns: a #RTPSource with CNAME @cname or NULL if the source was not found. - * g_object_unref() after usage. - */ -RTPSource * -rtp_session_get_source_by_cname (RTPSession * sess, const gchar * cname) -{ - RTPSource *result; - - g_return_val_if_fail (RTP_IS_SESSION (sess), NULL); - g_return_val_if_fail (cname != NULL, NULL); - - RTP_SESSION_LOCK (sess); - result = g_hash_table_lookup (sess->cnames, cname); - if (result) - g_object_ref (result); - RTP_SESSION_UNLOCK (sess); - - return result; -} - -static guint32 -rtp_session_create_new_ssrc (RTPSession * sess) -{ - guint32 ssrc; - - while (TRUE) { - ssrc = g_random_int (); - - /* see if it exists in the session, we're done if it doesn't */ - if (g_hash_table_lookup (sess->ssrcs[sess->mask_idx], - GINT_TO_POINTER (ssrc)) == NULL) - break; - } - return ssrc; -} - - -/** - * rtp_session_create_source: - * @sess: an #RTPSession - * - * Create an #RTPSource for use in @sess. This function will create a source - * with an ssrc that is currently not used by any participants in the session. - * - * Returns: an #RTPSource. - */ -RTPSource * -rtp_session_create_source (RTPSession * sess) -{ - guint32 ssrc; - RTPSource *source; - - RTP_SESSION_LOCK (sess); - ssrc = rtp_session_create_new_ssrc (sess); - source = rtp_source_new (ssrc); - rtp_source_set_callbacks (source, &callbacks, sess); - /* we need an additional ref for the source in the hashtable */ - g_object_ref (source); - g_hash_table_insert (sess->ssrcs[sess->mask_idx], GINT_TO_POINTER (ssrc), - source); - /* we have one more source now */ - sess->total_sources++; - RTP_SESSION_UNLOCK (sess); - - return source; -} - -/* update the RTPArrivalStats structure with the current time and other bits - * about the current buffer we are handling. - * This function is typically called when a validated packet is received. - * This function should be called with the SESSION_LOCK - */ -static void -update_arrival_stats (RTPSession * sess, RTPArrivalStats * arrival, - gboolean rtp, GstBuffer * buffer, GstClockTime current_time, - GstClockTime running_time, guint64 ntpnstime) -{ - /* get time of arrival */ - arrival->time = current_time; - arrival->running_time = running_time; - arrival->ntpnstime = ntpnstime; - - /* get packet size including header overhead */ - arrival->bytes = GST_BUFFER_SIZE (buffer) + sess->header_len; - - if (rtp) { - arrival->payload_len = gst_rtp_buffer_get_payload_len (buffer); - } else { - arrival->payload_len = 0; - } - - /* for netbuffer we can store the IP address to check for collisions */ - arrival->have_address = GST_IS_NETBUFFER (buffer); - if (arrival->have_address) { - GstNetBuffer *netbuf = (GstNetBuffer *) buffer; - - memcpy (&arrival->address, &netbuf->from, sizeof (GstNetAddress)); - } -} - -/** - * rtp_session_process_rtp: - * @sess: and #RTPSession - * @buffer: an RTP buffer - * @current_time: the current system time - * @ntpnstime: the NTP arrival time in nanoseconds - * - * Process an RTP buffer in the session manager. This function takes ownership - * of @buffer. - * - * Returns: a #GstFlowReturn. - */ -GstFlowReturn -rtp_session_process_rtp (RTPSession * sess, GstBuffer * buffer, - GstClockTime current_time, GstClockTime running_time, guint64 ntpnstime) -{ - GstFlowReturn result; - guint32 ssrc; - RTPSource *source; - gboolean created; - gboolean prevsender, prevactive; - RTPArrivalStats arrival; - - g_return_val_if_fail (RTP_IS_SESSION (sess), GST_FLOW_ERROR); - g_return_val_if_fail (GST_IS_BUFFER (buffer), GST_FLOW_ERROR); - - if (!gst_rtp_buffer_validate (buffer)) - goto invalid_packet; - - RTP_SESSION_LOCK (sess); - /* update arrival stats */ - update_arrival_stats (sess, &arrival, TRUE, buffer, current_time, - running_time, ntpnstime); - - /* ignore more RTP packets when we left the session */ - if (sess->source->received_bye) - goto ignore; - - /* get SSRC and look up in session database */ - ssrc = gst_rtp_buffer_get_ssrc (buffer); - source = obtain_source (sess, ssrc, &created, &arrival, TRUE); - if (!source) - goto collision; - - prevsender = RTP_SOURCE_IS_SENDER (source); - prevactive = RTP_SOURCE_IS_ACTIVE (source); - - /* we need to ref so that we can process the CSRCs later */ - gst_buffer_ref (buffer); - - /* let source process the packet */ - result = rtp_source_process_rtp (source, buffer, &arrival); - - /* source became active */ - if (prevactive != RTP_SOURCE_IS_ACTIVE (source)) { - sess->stats.active_sources++; - GST_DEBUG ("source: %08x became active, %d active sources", ssrc, - sess->stats.active_sources); - on_ssrc_validated (sess, source); - } - if (prevsender != RTP_SOURCE_IS_SENDER (source)) { - sess->stats.sender_sources++; - GST_DEBUG ("source: %08x became sender, %d sender sources", ssrc, - sess->stats.sender_sources); - } - - if (created) - on_new_ssrc (sess, source); - - if (source->validated) { - guint8 i, count; - gboolean created; - - /* for validated sources, we add the CSRCs as well */ - count = gst_rtp_buffer_get_csrc_count (buffer); - - for (i = 0; i < count; i++) { - guint32 csrc; - RTPSource *csrc_src; - - csrc = gst_rtp_buffer_get_csrc (buffer, i); - - /* get source */ - csrc_src = obtain_source (sess, csrc, &created, &arrival, TRUE); - if (!csrc_src) - continue; - - if (created) { - GST_DEBUG ("created new CSRC: %08x", csrc); - rtp_source_set_as_csrc (csrc_src); - if (RTP_SOURCE_IS_ACTIVE (csrc_src)) - sess->stats.active_sources++; - on_new_ssrc (sess, csrc_src); - } - g_object_unref (csrc_src); - } - } - g_object_unref (source); - gst_buffer_unref (buffer); - - RTP_SESSION_UNLOCK (sess); - - return result; - - /* ERRORS */ -invalid_packet: - { - gst_buffer_unref (buffer); - GST_DEBUG ("invalid RTP packet received"); - return GST_FLOW_OK; - } -ignore: - { - gst_buffer_unref (buffer); - RTP_SESSION_UNLOCK (sess); - GST_DEBUG ("ignoring RTP packet because we are leaving"); - return GST_FLOW_OK; - } -collision: - { - gst_buffer_unref (buffer); - RTP_SESSION_UNLOCK (sess); - GST_DEBUG ("ignoring packet because its collisioning"); - return GST_FLOW_OK; - } -} - -static void -rtp_session_process_rb (RTPSession * sess, RTPSource * source, - GstRTCPPacket * packet, RTPArrivalStats * arrival) -{ - guint count, i; - - count = gst_rtcp_packet_get_rb_count (packet); - for (i = 0; i < count; i++) { - guint32 ssrc, exthighestseq, jitter, lsr, dlsr; - guint8 fractionlost; - gint32 packetslost; - - gst_rtcp_packet_get_rb (packet, i, &ssrc, &fractionlost, - &packetslost, &exthighestseq, &jitter, &lsr, &dlsr); - - GST_DEBUG ("RB %d: SSRC %08x, jitter %" G_GUINT32_FORMAT, i, ssrc, jitter); - - if (ssrc == sess->source->ssrc) { - /* only deal with report blocks for our session, we update the stats of - * the sender of the RTCP message. We could also compare our stats against - * the other sender to see if we are better or worse. */ - rtp_source_process_rb (source, arrival->time, fractionlost, packetslost, - exthighestseq, jitter, lsr, dlsr); - - on_ssrc_active (sess, source); - } - } -} - -/* A Sender report contains statistics about how the sender is doing. This - * includes timing informataion such as the relation between RTP and NTP - * timestamps and the number of packets/bytes it sent to us. - * - * In this report is also included a set of report blocks related to how this - * sender is receiving data (in case we (or somebody else) is also sending stuff - * to it). This info includes the packet loss, jitter and seqnum. It also - * contains information to calculate the round trip time (LSR/DLSR). - */ -static void -rtp_session_process_sr (RTPSession * sess, GstRTCPPacket * packet, - RTPArrivalStats * arrival, gboolean * do_sync) -{ - guint32 senderssrc, rtptime, packet_count, octet_count; - guint64 ntptime; - RTPSource *source; - gboolean created, prevsender; - - gst_rtcp_packet_sr_get_sender_info (packet, &senderssrc, &ntptime, &rtptime, - &packet_count, &octet_count); - - GST_DEBUG ("got SR packet: SSRC %08x, time %" GST_TIME_FORMAT, - senderssrc, GST_TIME_ARGS (arrival->time)); - - source = obtain_source (sess, senderssrc, &created, arrival, FALSE); - if (!source) - return; - - /* don't try to do lip-sync for sources that sent a BYE */ - if (rtp_source_received_bye (source)) - *do_sync = FALSE; - else - *do_sync = TRUE; - - prevsender = RTP_SOURCE_IS_SENDER (source); - - /* first update the source */ - rtp_source_process_sr (source, arrival->time, ntptime, rtptime, packet_count, - octet_count); - - if (prevsender != RTP_SOURCE_IS_SENDER (source)) { - sess->stats.sender_sources++; - GST_DEBUG ("source: %08x became sender, %d sender sources", senderssrc, - sess->stats.sender_sources); - } - - if (created) - on_new_ssrc (sess, source); - - rtp_session_process_rb (sess, source, packet, arrival); - g_object_unref (source); -} - -/* A receiver report contains statistics about how a receiver is doing. It - * includes stuff like packet loss, jitter and the seqnum it received last. It - * also contains info to calculate the round trip time. - * - * We are only interested in how the sender of this report is doing wrt to us. - */ -static void -rtp_session_process_rr (RTPSession * sess, GstRTCPPacket * packet, - RTPArrivalStats * arrival) -{ - guint32 senderssrc; - RTPSource *source; - gboolean created; - - senderssrc = gst_rtcp_packet_rr_get_ssrc (packet); - - GST_DEBUG ("got RR packet: SSRC %08x", senderssrc); - - source = obtain_source (sess, senderssrc, &created, arrival, FALSE); - if (!source) - return; - - if (created) - on_new_ssrc (sess, source); - - rtp_session_process_rb (sess, source, packet, arrival); - g_object_unref (source); -} - -/* Get SDES items and store them in the SSRC */ -static void -rtp_session_process_sdes (RTPSession * sess, GstRTCPPacket * packet, - RTPArrivalStats * arrival) -{ - guint items, i, j; - gboolean more_items, more_entries; - - items = gst_rtcp_packet_sdes_get_item_count (packet); - GST_DEBUG ("got SDES packet with %d items", items); - - more_items = gst_rtcp_packet_sdes_first_item (packet); - i = 0; - while (more_items) { - guint32 ssrc; - gboolean changed, created; - RTPSource *source; - - ssrc = gst_rtcp_packet_sdes_get_ssrc (packet); - - GST_DEBUG ("item %d, SSRC %08x", i, ssrc); - - changed = FALSE; - - /* find src, no probation when dealing with RTCP */ - source = obtain_source (sess, ssrc, &created, arrival, FALSE); - if (!source) - return; - - more_entries = gst_rtcp_packet_sdes_first_entry (packet); - j = 0; - while (more_entries) { - GstRTCPSDESType type; - guint8 len; - guint8 *data; - - gst_rtcp_packet_sdes_get_entry (packet, &type, &len, &data); - - GST_DEBUG ("entry %d, type %d, len %d, data %.*s", j, type, len, len, - data); - - changed |= rtp_source_set_sdes (source, type, data, len); - - more_entries = gst_rtcp_packet_sdes_next_entry (packet); - j++; - } - - source->validated = TRUE; - - if (created) - on_new_ssrc (sess, source); - if (changed) - on_ssrc_sdes (sess, source); - - g_object_unref (source); - - more_items = gst_rtcp_packet_sdes_next_item (packet); - i++; - } -} - -/* BYE is sent when a client leaves the session - */ -static void -rtp_session_process_bye (RTPSession * sess, GstRTCPPacket * packet, - RTPArrivalStats * arrival) -{ - guint count, i; - gchar *reason; - gboolean reconsider = FALSE; - - reason = gst_rtcp_packet_bye_get_reason (packet); - GST_DEBUG ("got BYE packet (reason: %s)", GST_STR_NULL (reason)); - - count = gst_rtcp_packet_bye_get_ssrc_count (packet); - for (i = 0; i < count; i++) { - guint32 ssrc; - RTPSource *source; - gboolean created, prevactive, prevsender; - guint pmembers, members; - - ssrc = gst_rtcp_packet_bye_get_nth_ssrc (packet, i); - GST_DEBUG ("SSRC: %08x", ssrc); - - /* find src and mark bye, no probation when dealing with RTCP */ - source = obtain_source (sess, ssrc, &created, arrival, FALSE); - if (!source) - return; - - /* store time for when we need to time out this source */ - source->bye_time = arrival->time; - - prevactive = RTP_SOURCE_IS_ACTIVE (source); - prevsender = RTP_SOURCE_IS_SENDER (source); - - /* let the source handle the rest */ - rtp_source_process_bye (source, reason); - - pmembers = sess->stats.active_sources; - - if (prevactive && !RTP_SOURCE_IS_ACTIVE (source)) { - sess->stats.active_sources--; - GST_DEBUG ("source: %08x became inactive, %d active sources", ssrc, - sess->stats.active_sources); - } - if (prevsender && !RTP_SOURCE_IS_SENDER (source)) { - sess->stats.sender_sources--; - GST_DEBUG ("source: %08x became non sender, %d sender sources", ssrc, - sess->stats.sender_sources); - } - members = sess->stats.active_sources; - - if (!sess->source->received_bye && members < pmembers) { - /* some members went away since the previous timeout estimate. - * Perform reverse reconsideration but only when we are not scheduling a - * BYE ourselves. */ - if (arrival->time < sess->next_rtcp_check_time) { - GstClockTime time_remaining; - - time_remaining = sess->next_rtcp_check_time - arrival->time; - sess->next_rtcp_check_time = - gst_util_uint64_scale (time_remaining, members, pmembers); - - GST_DEBUG ("reverse reconsideration %" GST_TIME_FORMAT, - GST_TIME_ARGS (sess->next_rtcp_check_time)); - - sess->next_rtcp_check_time += arrival->time; - - /* mark pending reconsider. We only want to signal the reconsideration - * once after we handled all the source in the bye packet */ - reconsider = TRUE; - } - } - - if (created) - on_new_ssrc (sess, source); - - on_bye_ssrc (sess, source); - - g_object_unref (source); - } - if (reconsider) { - RTP_SESSION_UNLOCK (sess); - /* notify app of reconsideration */ - if (sess->callbacks.reconsider) - sess->callbacks.reconsider (sess, sess->reconsider_user_data); - RTP_SESSION_LOCK (sess); - } - g_free (reason); -} - -static void -rtp_session_process_app (RTPSession * sess, GstRTCPPacket * packet, - RTPArrivalStats * arrival) -{ - GST_DEBUG ("received APP"); -} - -/** - * rtp_session_process_rtcp: - * @sess: and #RTPSession - * @buffer: an RTCP buffer - * @current_time: the current system time - * - * Process an RTCP buffer in the session manager. This function takes ownership - * of @buffer. - * - * Returns: a #GstFlowReturn. - */ -GstFlowReturn -rtp_session_process_rtcp (RTPSession * sess, GstBuffer * buffer, - GstClockTime current_time) -{ - GstRTCPPacket packet; - gboolean more, is_bye = FALSE, do_sync = FALSE; - RTPArrivalStats arrival; - GstFlowReturn result = GST_FLOW_OK; - - g_return_val_if_fail (RTP_IS_SESSION (sess), GST_FLOW_ERROR); - g_return_val_if_fail (GST_IS_BUFFER (buffer), GST_FLOW_ERROR); - - if (!gst_rtcp_buffer_validate (buffer)) - goto invalid_packet; - - GST_DEBUG ("received RTCP packet"); - - RTP_SESSION_LOCK (sess); - /* update arrival stats */ - update_arrival_stats (sess, &arrival, FALSE, buffer, current_time, -1, -1); - - if (sess->sent_bye) - goto ignore; - - /* make writable, we might want to change the buffer */ - buffer = gst_buffer_make_metadata_writable (buffer); - - /* start processing the compound packet */ - more = gst_rtcp_buffer_get_first_packet (buffer, &packet); - while (more) { - GstRTCPType type; - - type = gst_rtcp_packet_get_type (&packet); - - /* when we are leaving the session, we should ignore all non-BYE messages */ - if (sess->source->received_bye && type != GST_RTCP_TYPE_BYE) { - GST_DEBUG ("ignoring non-BYE RTCP packet because we are leaving"); - goto next; - } - - switch (type) { - case GST_RTCP_TYPE_SR: - rtp_session_process_sr (sess, &packet, &arrival, &do_sync); - break; - case GST_RTCP_TYPE_RR: - rtp_session_process_rr (sess, &packet, &arrival); - break; - case GST_RTCP_TYPE_SDES: - rtp_session_process_sdes (sess, &packet, &arrival); - break; - case GST_RTCP_TYPE_BYE: - is_bye = TRUE; - /* don't try to attempt lip-sync anymore for streams with a BYE */ - do_sync = FALSE; - rtp_session_process_bye (sess, &packet, &arrival); - break; - case GST_RTCP_TYPE_APP: - rtp_session_process_app (sess, &packet, &arrival); - break; - default: - GST_WARNING ("got unknown RTCP packet"); - break; - } - next: - more = gst_rtcp_packet_move_to_next (&packet); - } - - /* if we are scheduling a BYE, we only want to count bye packets, else we - * count everything */ - if (sess->source->received_bye) { - if (is_bye) { - sess->stats.bye_members++; - UPDATE_AVG (sess->stats.avg_rtcp_packet_size, arrival.bytes); - } - } else { - /* keep track of average packet size */ - UPDATE_AVG (sess->stats.avg_rtcp_packet_size, arrival.bytes); - } - RTP_SESSION_UNLOCK (sess); - - /* notify caller of sr packets in the callback */ - if (do_sync && sess->callbacks.sync_rtcp) - result = sess->callbacks.sync_rtcp (sess, sess->source, buffer, - sess->sync_rtcp_user_data); - else - gst_buffer_unref (buffer); - - return result; - - /* ERRORS */ -invalid_packet: - { - GST_DEBUG ("invalid RTCP packet received"); - gst_buffer_unref (buffer); - return GST_FLOW_OK; - } -ignore: - { - gst_buffer_unref (buffer); - RTP_SESSION_UNLOCK (sess); - GST_DEBUG ("ignoring RTP packet because we left"); - return GST_FLOW_OK; - } -} - -/** - * rtp_session_send_rtp: - * @sess: an #RTPSession - * @data: pointer to either an RTP buffer or a list of RTP buffers - * @current_time: the current system time - * @ntpnstime: the NTP time in nanoseconds of when this buffer was captured. - * This is the buffer timestamp converted to NTP time. - * - * Send the RTP buffer in the session manager. This function takes ownership of - * @buffer. - * - * Returns: a #GstFlowReturn. - */ -GstFlowReturn -rtp_session_send_rtp (RTPSession * sess, gpointer data, gboolean is_list, - GstClockTime current_time, guint64 ntpnstime) -{ - GstFlowReturn result; - RTPSource *source; - gboolean prevsender; - gboolean valid_packet; - - g_return_val_if_fail (RTP_IS_SESSION (sess), GST_FLOW_ERROR); - g_return_val_if_fail (is_list || GST_IS_BUFFER (data), GST_FLOW_ERROR); - - if (is_list) { - valid_packet = gst_rtp_buffer_list_validate (GST_BUFFER_LIST_CAST (data)); - } else { - valid_packet = gst_rtp_buffer_validate (GST_BUFFER_CAST (data)); - } - - if (!valid_packet) - goto invalid_packet; - - GST_LOG ("received RTP %s for sending", is_list ? "list" : "packet"); - - RTP_SESSION_LOCK (sess); - source = sess->source; - - /* update last activity */ - source->last_rtp_activity = current_time; - - prevsender = RTP_SOURCE_IS_SENDER (source); - - /* we use our own source to send */ - result = rtp_source_send_rtp (source, data, is_list, ntpnstime); - - if (RTP_SOURCE_IS_SENDER (source) && !prevsender) - sess->stats.sender_sources++; - RTP_SESSION_UNLOCK (sess); - - return result; - - /* ERRORS */ -invalid_packet: - { - gst_mini_object_unref (GST_MINI_OBJECT_CAST (data)); - GST_DEBUG ("invalid RTP packet received"); - return GST_FLOW_OK; - } -} - -static GstClockTime -calculate_rtcp_interval (RTPSession * sess, gboolean deterministic, - gboolean first) -{ - GstClockTime result; - - if (sess->source->received_bye) { - result = rtp_stats_calculate_bye_interval (&sess->stats); - } else { - result = rtp_stats_calculate_rtcp_interval (&sess->stats, - RTP_SOURCE_IS_SENDER (sess->source), first); - } - - GST_DEBUG ("next deterministic interval: %" GST_TIME_FORMAT ", first %d", - GST_TIME_ARGS (result), first); - - if (!deterministic) - result = rtp_stats_add_rtcp_jitter (&sess->stats, result); - - GST_DEBUG ("next interval: %" GST_TIME_FORMAT, GST_TIME_ARGS (result)); - - return result; -} - -/* Stop the current @sess and schedule a BYE message for the other members. - * One must have the session lock to call this function - */ -static GstFlowReturn -rtp_session_schedule_bye_locked (RTPSession * sess, const gchar * reason, - GstClockTime current_time) -{ - GstFlowReturn result = GST_FLOW_OK; - RTPSource *source; - GstClockTime interval; - - g_return_val_if_fail (RTP_IS_SESSION (sess), GST_FLOW_ERROR); - - source = sess->source; - - /* ignore more BYEs */ - if (source->received_bye) - goto done; - - /* we have BYE now */ - source->received_bye = TRUE; - /* at least one member wants to send a BYE */ - g_free (sess->bye_reason); - sess->bye_reason = g_strdup (reason); - sess->stats.avg_rtcp_packet_size = 100; - sess->stats.bye_members = 1; - sess->first_rtcp = TRUE; - sess->sent_bye = FALSE; - - /* reschedule transmission */ - sess->last_rtcp_send_time = current_time; - interval = calculate_rtcp_interval (sess, FALSE, TRUE); - sess->next_rtcp_check_time = current_time + interval; - - GST_DEBUG ("Schedule BYE for %" GST_TIME_FORMAT ", %" GST_TIME_FORMAT, - GST_TIME_ARGS (interval), GST_TIME_ARGS (sess->next_rtcp_check_time)); - - RTP_SESSION_UNLOCK (sess); - /* notify app of reconsideration */ - if (sess->callbacks.reconsider) - sess->callbacks.reconsider (sess, sess->reconsider_user_data); - RTP_SESSION_LOCK (sess); -done: - - return result; -} - -/** - * rtp_session_schedule_bye: - * @sess: an #RTPSession - * @reason: a reason or NULL - * @current_time: the current system time - * - * Stop the current @sess and schedule a BYE message for the other members. - * - * Returns: a #GstFlowReturn. - */ -GstFlowReturn -rtp_session_schedule_bye (RTPSession * sess, const gchar * reason, - GstClockTime current_time) -{ - GstFlowReturn result = GST_FLOW_OK; - - g_return_val_if_fail (RTP_IS_SESSION (sess), GST_FLOW_ERROR); - - RTP_SESSION_LOCK (sess); - result = rtp_session_schedule_bye_locked (sess, reason, current_time); - RTP_SESSION_UNLOCK (sess); - - return result; -} - -/** - * rtp_session_next_timeout: - * @sess: an #RTPSession - * @current_time: the current system time - * - * Get the next time we should perform session maintenance tasks. - * - * Returns: a time when rtp_session_on_timeout() should be called with the - * current system time. - */ -GstClockTime -rtp_session_next_timeout (RTPSession * sess, GstClockTime current_time) -{ - GstClockTime result; - - g_return_val_if_fail (RTP_IS_SESSION (sess), GST_FLOW_ERROR); - - RTP_SESSION_LOCK (sess); - - result = sess->next_rtcp_check_time; - - GST_DEBUG ("current time: %" GST_TIME_FORMAT ", next :%" GST_TIME_FORMAT, - GST_TIME_ARGS (current_time), GST_TIME_ARGS (result)); - - if (result < current_time) { - GST_DEBUG ("take current time as base"); - /* our previous check time expired, start counting from the current time - * again. */ - result = current_time; - } - - if (sess->source->received_bye) { - if (sess->sent_bye) { - GST_DEBUG ("we sent BYE already"); - result = GST_CLOCK_TIME_NONE; - } else if (sess->stats.active_sources >= 50) { - GST_DEBUG ("reconsider BYE, more than 50 sources"); - /* reconsider BYE if members >= 50 */ - result += calculate_rtcp_interval (sess, FALSE, TRUE); - } - } else { - if (sess->first_rtcp) { - GST_DEBUG ("first RTCP packet"); - /* we are called for the first time */ - result += calculate_rtcp_interval (sess, FALSE, TRUE); - } else if (sess->next_rtcp_check_time < current_time) { - GST_DEBUG ("old check time expired, getting new timeout"); - /* get a new timeout when we need to */ - result += calculate_rtcp_interval (sess, FALSE, FALSE); - } - } - sess->next_rtcp_check_time = result; - - GST_DEBUG ("next timeout: %" GST_TIME_FORMAT, GST_TIME_ARGS (result)); - RTP_SESSION_UNLOCK (sess); - - return result; -} - -typedef struct -{ - RTPSession *sess; - GstBuffer *rtcp; - GstClockTime current_time; - guint64 ntpnstime; - GstClockTime interval; - GstRTCPPacket packet; - gboolean is_bye; - gboolean has_sdes; -} ReportData; - -static void -session_start_rtcp (RTPSession * sess, ReportData * data) -{ - GstRTCPPacket *packet = &data->packet; - RTPSource *own = sess->source; - - data->rtcp = gst_rtcp_buffer_new (sess->mtu); - - if (RTP_SOURCE_IS_SENDER (own)) { - guint64 ntptime; - guint32 rtptime; - guint32 packet_count, octet_count; - - /* we are a sender, create SR */ - GST_DEBUG ("create SR for SSRC %08x", own->ssrc); - gst_rtcp_buffer_add_packet (data->rtcp, GST_RTCP_TYPE_SR, packet); - - /* get latest stats */ - rtp_source_get_new_sr (own, data->ntpnstime, &ntptime, &rtptime, - &packet_count, &octet_count); - /* store stats */ - rtp_source_process_sr (own, data->current_time, ntptime, rtptime, - packet_count, octet_count); - - /* fill in sender report info */ - gst_rtcp_packet_sr_set_sender_info (packet, own->ssrc, - ntptime, rtptime, packet_count, octet_count); - } else { - /* we are only receiver, create RR */ - GST_DEBUG ("create RR for SSRC %08x", own->ssrc); - gst_rtcp_buffer_add_packet (data->rtcp, GST_RTCP_TYPE_RR, packet); - gst_rtcp_packet_rr_set_ssrc (packet, own->ssrc); - } -} - -/* construct a Sender or Receiver Report */ -static void -session_report_blocks (const gchar * key, RTPSource * source, ReportData * data) -{ - RTPSession *sess = data->sess; - GstRTCPPacket *packet = &data->packet; - - /* create a new buffer if needed */ - if (data->rtcp == NULL) { - session_start_rtcp (sess, data); - } - if (gst_rtcp_packet_get_rb_count (packet) < GST_RTCP_MAX_RB_COUNT) { - /* only report about other sender sources */ - if (source != sess->source && RTP_SOURCE_IS_SENDER (source)) { - guint8 fractionlost; - gint32 packetslost; - guint32 exthighestseq, jitter; - guint32 lsr, dlsr; - - /* get new stats */ - rtp_source_get_new_rb (source, data->current_time, &fractionlost, - &packetslost, &exthighestseq, &jitter, &lsr, &dlsr); - - /* packet is not yet filled, add report block for this source. */ - gst_rtcp_packet_add_rb (packet, source->ssrc, fractionlost, packetslost, - exthighestseq, jitter, lsr, dlsr); - } - } -} - -/* perform cleanup of sources that timed out */ -static gboolean -session_cleanup (const gchar * key, RTPSource * source, ReportData * data) -{ - gboolean remove = FALSE; - gboolean byetimeout = FALSE; - gboolean sendertimeout = FALSE; - gboolean is_sender, is_active; - RTPSession *sess = data->sess; - GstClockTime interval; - - is_sender = RTP_SOURCE_IS_SENDER (source); - is_active = RTP_SOURCE_IS_ACTIVE (source); - - /* check for our own source, we don't want to delete our own source. */ - if (!(source == sess->source)) { - if (source->received_bye) { - /* if we received a BYE from the source, remove the source after some - * time. */ - if (data->current_time > source->bye_time && - data->current_time - source->bye_time > sess->stats.bye_timeout) { - GST_DEBUG ("removing BYE source %08x", source->ssrc); - remove = TRUE; - byetimeout = TRUE; - } - } - /* sources that were inactive for more than 5 times the deterministic reporting - * interval get timed out. the min timeout is 5 seconds. */ - if (data->current_time > source->last_activity) { - interval = MAX (data->interval * 5, 5 * GST_SECOND); - if (data->current_time - source->last_activity > interval) { - GST_DEBUG ("removing timeout source %08x, last %" GST_TIME_FORMAT, - source->ssrc, GST_TIME_ARGS (source->last_activity)); - remove = TRUE; - } - } - } - - /* senders that did not send for a long time become a receiver, this also - * holds for our own source. */ - if (is_sender) { - if (data->current_time > source->last_rtp_activity) { - interval = MAX (data->interval * 2, 5 * GST_SECOND); - if (data->current_time - source->last_rtp_activity > interval) { - GST_DEBUG ("sender source %08x timed out and became receiver, last %" - GST_TIME_FORMAT, source->ssrc, - GST_TIME_ARGS (source->last_rtp_activity)); - source->is_sender = FALSE; - sess->stats.sender_sources--; - sendertimeout = TRUE; - } - } - } - - if (remove) { - sess->total_sources--; - if (is_sender) - sess->stats.sender_sources--; - if (is_active) - sess->stats.active_sources--; - - if (byetimeout) - on_bye_timeout (sess, source); - else - on_timeout (sess, source); - } else { - if (sendertimeout) - on_sender_timeout (sess, source); - } - return remove; -} - -static void -session_sdes (RTPSession * sess, ReportData * data) -{ - GstRTCPPacket *packet = &data->packet; - guint8 *sdes_data; - guint sdes_len; - - /* add SDES packet */ - gst_rtcp_buffer_add_packet (data->rtcp, GST_RTCP_TYPE_SDES, packet); - - gst_rtcp_packet_sdes_add_item (packet, sess->source->ssrc); - - rtp_source_get_sdes (sess->source, GST_RTCP_SDES_CNAME, &sdes_data, - &sdes_len); - gst_rtcp_packet_sdes_add_entry (packet, GST_RTCP_SDES_CNAME, sdes_len, - sdes_data); - - /* other SDES items must only be added at regular intervals and only when the - * user requests to since it might be a privacy problem */ -#if 0 - gst_rtcp_packet_sdes_add_entry (&packet, GST_RTCP_SDES_NAME, - strlen (sess->name), (guint8 *) sess->name); - gst_rtcp_packet_sdes_add_entry (&packet, GST_RTCP_SDES_TOOL, - strlen (sess->tool), (guint8 *) sess->tool); -#endif - - data->has_sdes = TRUE; -} - -/* schedule a BYE packet */ -static void -session_bye (RTPSession * sess, ReportData * data) -{ - GstRTCPPacket *packet = &data->packet; - - /* open packet */ - session_start_rtcp (sess, data); - - /* add SDES */ - session_sdes (sess, data); - - /* add a BYE packet */ - gst_rtcp_buffer_add_packet (data->rtcp, GST_RTCP_TYPE_BYE, packet); - gst_rtcp_packet_bye_add_ssrc (packet, sess->source->ssrc); - if (sess->bye_reason) - gst_rtcp_packet_bye_set_reason (packet, sess->bye_reason); - - /* we have a BYE packet now */ - data->is_bye = TRUE; -} - -static gboolean -is_rtcp_time (RTPSession * sess, GstClockTime current_time, ReportData * data) -{ - GstClockTime new_send_time, elapsed; - gboolean result; - - /* no need to check yet */ - if (sess->next_rtcp_check_time > current_time) { - GST_DEBUG ("no check time yet, next %" GST_TIME_FORMAT " > now %" - GST_TIME_FORMAT, GST_TIME_ARGS (sess->next_rtcp_check_time), - GST_TIME_ARGS (current_time)); - return FALSE; - } - - /* get elapsed time since we last reported */ - elapsed = current_time - sess->last_rtcp_send_time; - - /* perform forward reconsideration */ - new_send_time = rtp_stats_add_rtcp_jitter (&sess->stats, data->interval); - - GST_DEBUG ("forward reconsideration %" GST_TIME_FORMAT ", elapsed %" - GST_TIME_FORMAT, GST_TIME_ARGS (new_send_time), GST_TIME_ARGS (elapsed)); - - new_send_time += sess->last_rtcp_send_time; - - /* check if reconsideration */ - if (current_time < new_send_time) { - GST_DEBUG ("reconsider RTCP for %" GST_TIME_FORMAT, - GST_TIME_ARGS (new_send_time)); - result = FALSE; - /* store new check time */ - sess->next_rtcp_check_time = new_send_time; - } else { - result = TRUE; - new_send_time = calculate_rtcp_interval (sess, FALSE, FALSE); - - GST_DEBUG ("can send RTCP now, next interval %" GST_TIME_FORMAT, - GST_TIME_ARGS (new_send_time)); - sess->next_rtcp_check_time = current_time + new_send_time; - } - return result; -} - -/** - * rtp_session_on_timeout: - * @sess: an #RTPSession - * @current_time: the current system time - * @ntpnstime: the current NTP time in nanoseconds - * - * Perform maintenance actions after the timeout obtained with - * rtp_session_next_timeout() expired. - * - * This function will perform timeouts of receivers and senders, send a BYE - * packet or generate RTCP packets with current session stats. - * - * This function can call the #RTPSessionSendRTCP callback, possibly multiple - * times, for each packet that should be processed. - * - * Returns: a #GstFlowReturn. - */ -GstFlowReturn -rtp_session_on_timeout (RTPSession * sess, GstClockTime current_time, - guint64 ntpnstime) -{ - GstFlowReturn result = GST_FLOW_OK; - GList *item; - ReportData data; - RTPSource *own; - gboolean notify = FALSE; - - g_return_val_if_fail (RTP_IS_SESSION (sess), GST_FLOW_ERROR); - - GST_DEBUG ("reporting at %" GST_TIME_FORMAT ", NTP time %" GST_TIME_FORMAT, - GST_TIME_ARGS (current_time), GST_TIME_ARGS (ntpnstime)); - - data.sess = sess; - data.rtcp = NULL; - data.current_time = current_time; - data.ntpnstime = ntpnstime; - data.is_bye = FALSE; - data.has_sdes = FALSE; - - own = sess->source; - - RTP_SESSION_LOCK (sess); - /* get a new interval, we need this for various cleanups etc */ - data.interval = calculate_rtcp_interval (sess, TRUE, sess->first_rtcp); - - /* first perform cleanups */ - g_hash_table_foreach_remove (sess->ssrcs[sess->mask_idx], - (GHRFunc) session_cleanup, &data); - - /* see if we need to generate SR or RR packets */ - if (is_rtcp_time (sess, current_time, &data)) { - if (own->received_bye) { - /* generate BYE instead */ - GST_DEBUG ("generating BYE message"); - session_bye (sess, &data); - sess->sent_bye = TRUE; - } else { - /* loop over all known sources and do something */ - g_hash_table_foreach (sess->ssrcs[sess->mask_idx], - (GHFunc) session_report_blocks, &data); - } - } - - if (data.rtcp) { - guint size; - - /* we keep track of the last report time in order to timeout inactive - * receivers or senders */ - sess->last_rtcp_send_time = data.current_time; - sess->first_rtcp = FALSE; - - /* add SDES for this source when not already added */ - if (!data.has_sdes) - session_sdes (sess, &data); - - /* update average RTCP size before sending */ - size = GST_BUFFER_SIZE (data.rtcp) + sess->header_len; - UPDATE_AVG (sess->stats.avg_rtcp_packet_size, size); - } - - /* check for outdated collisions */ - GST_DEBUG ("checking collision list"); - item = g_list_first (sess->conflicting_addresses); - while (item) { - RTPConflictingAddress *known_conflict = item->data; - GList *next_item = g_list_next (item); - - if (known_conflict->time < current_time - (data.interval * - RTCP_INTERVAL_COLLISION_TIMEOUT)) { - sess->conflicting_addresses = - g_list_delete_link (sess->conflicting_addresses, item); - GST_DEBUG ("collision %p timed out", known_conflict); - g_free (known_conflict); - } - item = next_item; - } - - if (sess->change_ssrc) { - GST_DEBUG ("need to change our SSRC (%08x)", own->ssrc); - g_hash_table_steal (sess->ssrcs[sess->mask_idx], - GINT_TO_POINTER (own->ssrc)); - - own->ssrc = rtp_session_create_new_ssrc (sess); - rtp_source_reset (own); - - g_hash_table_insert (sess->ssrcs[sess->mask_idx], - GINT_TO_POINTER (own->ssrc), own); - - g_free (sess->bye_reason); - sess->bye_reason = NULL; - sess->sent_bye = FALSE; - sess->change_ssrc = FALSE; - notify = TRUE; - GST_DEBUG ("changed our SSRC to %08x", own->ssrc); - } - RTP_SESSION_UNLOCK (sess); - - if (notify) - g_object_notify (G_OBJECT (sess), "internal-ssrc"); - - /* push out the RTCP packet */ - if (data.rtcp) { - /* close the RTCP packet */ - gst_rtcp_buffer_end (data.rtcp); - - GST_DEBUG ("sending packet"); - if (sess->callbacks.send_rtcp) - result = sess->callbacks.send_rtcp (sess, own, data.rtcp, - sess->sent_bye, sess->send_rtcp_user_data); - else { - GST_DEBUG ("freeing packet"); - gst_buffer_unref (data.rtcp); - } - } - - return result; -} diff --git a/gst/rtpmanager/rtpsession.h b/gst/rtpmanager/rtpsession.h deleted file mode 100644 index 25e228b0..00000000 --- a/gst/rtpmanager/rtpsession.h +++ /dev/null @@ -1,306 +0,0 @@ -/* GStreamer - * Copyright (C) <2007> Wim Taymans <wim.taymans@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., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __RTP_SESSION_H__ -#define __RTP_SESSION_H__ - -#include <gst/gst.h> -#include <gst/netbuffer/gstnetbuffer.h> - -#include "rtpsource.h" - -typedef struct _RTPSession RTPSession; -typedef struct _RTPSessionClass RTPSessionClass; - -#define RTP_TYPE_SESSION (rtp_session_get_type()) -#define RTP_SESSION(sess) (G_TYPE_CHECK_INSTANCE_CAST((sess),RTP_TYPE_SESSION,RTPSession)) -#define RTP_SESSION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),RTP_TYPE_SESSION,RTPSessionClass)) -#define RTP_IS_SESSION(sess) (G_TYPE_CHECK_INSTANCE_TYPE((sess),RTP_TYPE_SESSION)) -#define RTP_IS_SESSION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),RTP_TYPE_SESSION)) -#define RTP_SESSION_CAST(sess) ((RTPSession *)(sess)) - -#define RTP_SESSION_LOCK(sess) (g_mutex_lock ((sess)->lock)) -#define RTP_SESSION_UNLOCK(sess) (g_mutex_unlock ((sess)->lock)) - -/** - * RTPSessionProcessRTP: - * @sess: an #RTPSession - * @src: the #RTPSource - * @buffer: the RTP buffer ready for processing - * @user_data: user data specified when registering - * - * This callback will be called when @sess has @buffer ready for further - * processing. Processing the buffer typically includes decoding and displaying - * the buffer. - * - * Returns: a #GstFlowReturn. - */ -typedef GstFlowReturn (*RTPSessionProcessRTP) (RTPSession *sess, RTPSource *src, GstBuffer *buffer, gpointer user_data); - -/** - * RTPSessionSendRTP: - * @sess: an #RTPSession - * @src: the #RTPSource - * @buffer: the RTP buffer ready for sending - * @user_data: user data specified when registering - * - * This callback will be called when @sess has @buffer ready for sending to - * all listening participants in this session. - * - * Returns: a #GstFlowReturn. - */ -typedef GstFlowReturn (*RTPSessionSendRTP) (RTPSession *sess, RTPSource *src, gpointer data, gpointer user_data); - -/** - * RTPSessionSendRTCP: - * @sess: an #RTPSession - * @src: the #RTPSource - * @buffer: the RTCP buffer ready for sending - * @eos: if an EOS event should be pushed - * @user_data: user data specified when registering - * - * This callback will be called when @sess has @buffer ready for sending to - * all listening participants in this session. - * - * Returns: a #GstFlowReturn. - */ -typedef GstFlowReturn (*RTPSessionSendRTCP) (RTPSession *sess, RTPSource *src, GstBuffer *buffer, - gboolean eos, gpointer user_data); - -/** - * RTPSessionSyncRTCP: - * @sess: an #RTPSession - * @src: the #RTPSource - * @buffer: the RTCP buffer ready for synchronisation - * @user_data: user data specified when registering - * - * This callback will be called when @sess has an SR @buffer ready for doing - * synchronisation between streams. - * - * Returns: a #GstFlowReturn. - */ -typedef GstFlowReturn (*RTPSessionSyncRTCP) (RTPSession *sess, RTPSource *src, GstBuffer *buffer, gpointer user_data); - -/** - * RTPSessionClockRate: - * @sess: an #RTPSession - * @payload: the payload - * @user_data: user data specified when registering - * - * This callback will be called when @sess needs the clock-rate of @payload. - * - * Returns: the clock-rate of @pt. - */ -typedef gint (*RTPSessionClockRate) (RTPSession *sess, guint8 payload, gpointer user_data); - -/** - * RTPSessionReconsider: - * @sess: an #RTPSession - * @user_data: user data specified when registering - * - * This callback will be called when @sess needs to cancel the current timeout. - * The currently running timeout should be canceled and a new reporting interval - * should be requested from @sess. - */ -typedef void (*RTPSessionReconsider) (RTPSession *sess, gpointer user_data); - -/** - * RTPSessionCallbacks: - * @RTPSessionProcessRTP: callback to process RTP packets - * @RTPSessionSendRTP: callback for sending RTP packets - * @RTPSessionSendRTCP: callback for sending RTCP packets - * @RTPSessionSyncRTCP: callback for handling SR packets - * @RTPSessionReconsider: callback for reconsidering the timeout - * - * These callbacks can be installed on the session manager to get notification - * when RTP and RTCP packets are ready for further processing. These callbacks - * are not implemented with signals for performance reasons. - */ -typedef struct { - RTPSessionProcessRTP process_rtp; - RTPSessionSendRTP send_rtp; - RTPSessionSyncRTCP sync_rtcp; - RTPSessionSendRTCP send_rtcp; - RTPSessionClockRate clock_rate; - RTPSessionReconsider reconsider; -} RTPSessionCallbacks; - -/** - * RTPConflictingAddress: - * @address: #GstNetAddress which conflicted - * @last_conflict_time: time when the last conflict was seen - * - * This structure is used to account for addresses that have conflicted to find - * loops. - */ -typedef struct { - GstNetAddress address; - GstClockTime time; -} RTPConflictingAddress; - -/** - * RTPSession: - * @lock: lock to protect the session - * @source: the source of this session - * @ssrcs: Hashtable of sources indexed by SSRC - * @cnames: Hashtable of sources indexed by CNAME - * @num_sources: the number of sources - * @activecount: the number of active sources - * @callbacks: callbacks - * @user_data: user data passed in callbacks - * @stats: session statistics - * @conflicting_addresses: GList of conflicting addresses - * - * The RTP session manager object - */ -struct _RTPSession { - GObject object; - - GMutex *lock; - - guint header_len; - guint mtu; - - RTPSource *source; - - /* for sender/receiver counting */ - guint32 key; - guint32 mask_idx; - guint32 mask; - GHashTable *ssrcs[32]; - GHashTable *cnames; - guint total_sources; - - GstClockTime next_rtcp_check_time; - GstClockTime last_rtcp_send_time; - gboolean first_rtcp; - - gchar *bye_reason; - gboolean sent_bye; - - RTPSessionCallbacks callbacks; - gpointer process_rtp_user_data; - gpointer send_rtp_user_data; - gpointer send_rtcp_user_data; - gpointer sync_rtcp_user_data; - gpointer clock_rate_user_data; - gpointer reconsider_user_data; - - RTPSessionStats stats; - - GList *conflicting_addresses; - gboolean change_ssrc; -}; - -/** - * RTPSessionClass: - * @on_new_ssrc: emited when a new source is found - * @on_bye_ssrc: emited when a source is gone - * - * The session class. - */ -struct _RTPSessionClass { - GObjectClass parent_class; - - /* action signals */ - RTPSource* (*get_source_by_ssrc) (RTPSession *sess, guint32 ssrc); - - /* signals */ - void (*on_new_ssrc) (RTPSession *sess, RTPSource *source); - void (*on_ssrc_collision) (RTPSession *sess, RTPSource *source); - void (*on_ssrc_validated) (RTPSession *sess, RTPSource *source); - void (*on_ssrc_active) (RTPSession *sess, RTPSource *source); - void (*on_ssrc_sdes) (RTPSession *sess, RTPSource *source); - void (*on_bye_ssrc) (RTPSession *sess, RTPSource *source); - void (*on_bye_timeout) (RTPSession *sess, RTPSource *source); - void (*on_timeout) (RTPSession *sess, RTPSource *source); - void (*on_sender_timeout) (RTPSession *sess, RTPSource *source); -}; - -GType rtp_session_get_type (void); - -/* create and configure */ -RTPSession* rtp_session_new (void); -void rtp_session_set_callbacks (RTPSession *sess, - RTPSessionCallbacks *callbacks, - gpointer user_data); -void rtp_session_set_process_rtp_callback (RTPSession * sess, - RTPSessionProcessRTP callback, - gpointer user_data); -void rtp_session_set_send_rtp_callback (RTPSession * sess, - RTPSessionSendRTP callback, - gpointer user_data); -void rtp_session_set_send_rtcp_callback (RTPSession * sess, - RTPSessionSendRTCP callback, - gpointer user_data); -void rtp_session_set_sync_rtcp_callback (RTPSession * sess, - RTPSessionSyncRTCP callback, - gpointer user_data); -void rtp_session_set_clock_rate_callback (RTPSession * sess, - RTPSessionClockRate callback, - gpointer user_data); -void rtp_session_set_reconsider_callback (RTPSession * sess, - RTPSessionReconsider callback, - gpointer user_data); -void rtp_session_set_bandwidth (RTPSession *sess, gdouble bandwidth); -gdouble rtp_session_get_bandwidth (RTPSession *sess); -void rtp_session_set_rtcp_fraction (RTPSession *sess, gdouble fraction); -gdouble rtp_session_get_rtcp_fraction (RTPSession *sess); - -gboolean rtp_session_set_sdes_string (RTPSession *sess, GstRTCPSDESType type, - const gchar *cname); -gchar* rtp_session_get_sdes_string (RTPSession *sess, GstRTCPSDESType type); - -GstStructure * rtp_session_get_sdes_struct (RTPSession *sess); -void rtp_session_set_sdes_struct (RTPSession *sess, const GstStructure *sdes); - -/* handling sources */ -RTPSource* rtp_session_get_internal_source (RTPSession *sess); - -void rtp_session_set_internal_ssrc (RTPSession *sess, guint32 ssrc); -guint32 rtp_session_get_internal_ssrc (RTPSession *sess); - -gboolean rtp_session_add_source (RTPSession *sess, RTPSource *src); -guint rtp_session_get_num_sources (RTPSession *sess); -guint rtp_session_get_num_active_sources (RTPSession *sess); -RTPSource* rtp_session_get_source_by_ssrc (RTPSession *sess, guint32 ssrc); -RTPSource* rtp_session_get_source_by_cname (RTPSession *sess, const gchar *cname); -RTPSource* rtp_session_create_source (RTPSession *sess); - -/* processing packets from receivers */ -GstFlowReturn rtp_session_process_rtp (RTPSession *sess, GstBuffer *buffer, - GstClockTime current_time, - GstClockTime running_time, guint64 ntpnstime); -GstFlowReturn rtp_session_process_rtcp (RTPSession *sess, GstBuffer *buffer, - GstClockTime current_time); - -/* processing packets for sending */ -GstFlowReturn rtp_session_send_rtp (RTPSession *sess, gpointer data, gboolean is_list, - GstClockTime current_time, guint64 ntpnstime); - -/* stopping the session */ -GstFlowReturn rtp_session_schedule_bye (RTPSession *sess, const gchar *reason, - GstClockTime current_time); - -/* get interval for next RTCP interval */ -GstClockTime rtp_session_next_timeout (RTPSession *sess, GstClockTime current_time); -GstFlowReturn rtp_session_on_timeout (RTPSession *sess, GstClockTime current_time, - guint64 ntpnstime); - -#endif /* __RTP_SESSION_H__ */ diff --git a/gst/rtpmanager/rtpsource.c b/gst/rtpmanager/rtpsource.c deleted file mode 100644 index 28fa23ef..00000000 --- a/gst/rtpmanager/rtpsource.c +++ /dev/null @@ -1,1625 +0,0 @@ -/* GStreamer - * Copyright (C) <2007> Wim Taymans <wim.taymans@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., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ -#include <string.h> - -#include <gst/rtp/gstrtpbuffer.h> -#include <gst/rtp/gstrtcpbuffer.h> - -#include "rtpsource.h" - -GST_DEBUG_CATEGORY_STATIC (rtp_source_debug); -#define GST_CAT_DEFAULT rtp_source_debug - -#define RTP_MAX_PROBATION_LEN 32 - -/* signals and args */ -enum -{ - LAST_SIGNAL -}; - -#define DEFAULT_SSRC 0 -#define DEFAULT_IS_CSRC FALSE -#define DEFAULT_IS_VALIDATED FALSE -#define DEFAULT_IS_SENDER FALSE -#define DEFAULT_SDES NULL - -enum -{ - PROP_0, - PROP_SSRC, - PROP_IS_CSRC, - PROP_IS_VALIDATED, - PROP_IS_SENDER, - PROP_SDES, - PROP_STATS, - PROP_LAST -}; - -/* GObject vmethods */ -static void rtp_source_finalize (GObject * object); -static void rtp_source_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec); -static void rtp_source_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec); - -/* static guint rtp_source_signals[LAST_SIGNAL] = { 0 }; */ - -G_DEFINE_TYPE (RTPSource, rtp_source, G_TYPE_OBJECT); - -static void -rtp_source_class_init (RTPSourceClass * klass) -{ - GObjectClass *gobject_class; - - gobject_class = (GObjectClass *) klass; - - gobject_class->finalize = rtp_source_finalize; - - gobject_class->set_property = rtp_source_set_property; - gobject_class->get_property = rtp_source_get_property; - - g_object_class_install_property (gobject_class, PROP_SSRC, - g_param_spec_uint ("ssrc", "SSRC", - "The SSRC of this source", 0, G_MAXUINT, DEFAULT_SSRC, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (gobject_class, PROP_IS_CSRC, - g_param_spec_boolean ("is-csrc", "Is CSRC", - "If this SSRC is acting as a contributing source", - DEFAULT_IS_CSRC, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (gobject_class, PROP_IS_VALIDATED, - g_param_spec_boolean ("is-validated", "Is Validated", - "If this SSRC is validated", DEFAULT_IS_VALIDATED, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (gobject_class, PROP_IS_SENDER, - g_param_spec_boolean ("is-sender", "Is Sender", - "If this SSRC is a sender", DEFAULT_IS_SENDER, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); - - /** - * RTPSource::sdes - * - * The current SDES items of the source. Returns a structure with the - * following fields: - * - * 'cname' G_TYPE_STRING : The canonical name - * 'name' G_TYPE_STRING : The user name - * 'email' G_TYPE_STRING : The user's electronic mail address - * 'phone' G_TYPE_STRING : The user's phone number - * 'location' G_TYPE_STRING : The geographic user location - * 'tool' G_TYPE_STRING : The name of application or tool - * 'note' G_TYPE_STRING : A notice about the source - */ - g_object_class_install_property (gobject_class, PROP_SDES, - g_param_spec_boxed ("sdes", "SDES", - "The SDES information for this source", - GST_TYPE_STRUCTURE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); - - /** - * RTPSource::stats - * - * The statistics of the source. This property returns a GstStructure with - * name application/x-rtp-source-stats with the following fields: - * - */ - g_object_class_install_property (gobject_class, PROP_STATS, - g_param_spec_boxed ("stats", "Stats", - "The stats of this source", GST_TYPE_STRUCTURE, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); - - GST_DEBUG_CATEGORY_INIT (rtp_source_debug, "rtpsource", 0, "RTP Source"); -} - -/** - * rtp_source_reset: - * @src: an #RTPSource - * - * Reset the stats of @src. - */ -void -rtp_source_reset (RTPSource * src) -{ - src->received_bye = FALSE; - - src->stats.cycles = -1; - src->stats.jitter = 0; - src->stats.transit = -1; - src->stats.curr_sr = 0; - src->stats.curr_rr = 0; -} - -static void -rtp_source_init (RTPSource * src) -{ - /* sources are initialy on probation until we receive enough valid RTP - * packets or a valid RTCP packet */ - src->validated = FALSE; - src->internal = FALSE; - src->probation = RTP_DEFAULT_PROBATION; - - src->payload = -1; - src->clock_rate = -1; - src->packets = g_queue_new (); - src->seqnum_base = -1; - src->last_rtptime = -1; - - rtp_source_reset (src); -} - -static void -rtp_source_finalize (GObject * object) -{ - RTPSource *src; - GstBuffer *buffer; - gint i; - - src = RTP_SOURCE_CAST (object); - - while ((buffer = g_queue_pop_head (src->packets))) - gst_buffer_unref (buffer); - g_queue_free (src->packets); - - for (i = 0; i < 9; i++) - g_free (src->sdes[i]); - - g_free (src->bye_reason); - - gst_caps_replace (&src->caps, NULL); - - G_OBJECT_CLASS (rtp_source_parent_class)->finalize (object); -} - -static GstStructure * -rtp_source_create_stats (RTPSource * src) -{ - GstStructure *s; - gboolean is_sender = src->is_sender; - gboolean internal = src->internal; - gchar address_str[GST_NETADDRESS_MAX_LEN]; - - /* common data for all types of sources */ - s = gst_structure_new ("application/x-rtp-source-stats", - "ssrc", G_TYPE_UINT, (guint) src->ssrc, - "internal", G_TYPE_BOOLEAN, internal, - "validated", G_TYPE_BOOLEAN, src->validated, - "received-bye", G_TYPE_BOOLEAN, src->received_bye, - "is-csrc", G_TYPE_BOOLEAN, src->is_csrc, - "is-sender", G_TYPE_BOOLEAN, is_sender, NULL); - - /* add address and port */ - if (src->have_rtp_from) { - gst_netaddress_to_string (&src->rtp_from, address_str, - sizeof (address_str)); - gst_structure_set (s, "rtp-from", G_TYPE_STRING, address_str, NULL); - } - if (src->have_rtcp_from) { - gst_netaddress_to_string (&src->rtcp_from, address_str, - sizeof (address_str)); - gst_structure_set (s, "rtcp-from", G_TYPE_STRING, address_str, NULL); - } - - if (internal) { - /* our internal source */ - if (is_sender) { - /* if we are sending, report about how much we sent, other sources will - * have a RB with info on reception. */ - gst_structure_set (s, - "octets-sent", G_TYPE_UINT64, src->stats.octets_sent, - "packets-sent", G_TYPE_UINT64, src->stats.packets_sent, - "bitrate", G_TYPE_UINT64, src->bitrate, NULL); - } else { - /* if we are not sending we have nothing more to report */ - } - } else { - gboolean have_rb; - guint8 fractionlost = 0; - gint32 packetslost = 0; - guint32 exthighestseq = 0; - guint32 jitter = 0; - guint32 lsr = 0; - guint32 dlsr = 0; - guint32 round_trip = 0; - - /* other sources */ - if (is_sender) { - gboolean have_sr; - GstClockTime time = 0; - guint64 ntptime = 0; - guint32 rtptime = 0; - guint32 packet_count = 0; - guint32 octet_count = 0; - - /* this source is sending to us, get the last SR. */ - have_sr = rtp_source_get_last_sr (src, &time, &ntptime, &rtptime, - &packet_count, &octet_count); - gst_structure_set (s, - "octets-received", G_TYPE_UINT64, src->stats.octets_received, - "packets-received", G_TYPE_UINT64, src->stats.packets_received, - "have-sr", G_TYPE_BOOLEAN, have_sr, - "sr-ntptime", G_TYPE_UINT64, ntptime, - "sr-rtptime", G_TYPE_UINT, (guint) rtptime, - "sr-octet-count", G_TYPE_UINT, (guint) octet_count, - "sr-packet-count", G_TYPE_UINT, (guint) packet_count, NULL); - } - /* we might be sending to this SSRC so we report about how it is - * receiving our data */ - have_rb = rtp_source_get_last_rb (src, &fractionlost, &packetslost, - &exthighestseq, &jitter, &lsr, &dlsr, &round_trip); - - gst_structure_set (s, - "have-rb", G_TYPE_BOOLEAN, have_rb, - "rb-fractionlost", G_TYPE_UINT, (guint) fractionlost, - "rb-packetslost", G_TYPE_INT, (gint) packetslost, - "rb-exthighestseq", G_TYPE_UINT, (guint) exthighestseq, - "rb-jitter", G_TYPE_UINT, (guint) jitter, - "rb-lsr", G_TYPE_UINT, (guint) lsr, - "rb-dlsr", G_TYPE_UINT, (guint) dlsr, - "rb-round-trip", G_TYPE_UINT, (guint) round_trip, NULL); - } - - return s; -} - -/** - * rtp_source_get_sdes_struct: - * @src: an #RTSPSource - * - * Get the SDES data as a GstStructure - * - * Returns: a GstStructure with SDES items for @src. - */ -GstStructure * -rtp_source_get_sdes_struct (RTPSource * src) -{ - GstStructure *s; - gchar *str; - - s = gst_structure_new ("application/x-rtp-source-sdes", - "ssrc", G_TYPE_UINT, (guint) src->ssrc, NULL); - - if ((str = rtp_source_get_sdes_string (src, GST_RTCP_SDES_CNAME))) { - gst_structure_set (s, "cname", G_TYPE_STRING, str, NULL); - g_free (str); - } - if ((str = rtp_source_get_sdes_string (src, GST_RTCP_SDES_NAME))) { - gst_structure_set (s, "name", G_TYPE_STRING, str, NULL); - g_free (str); - } - if ((str = rtp_source_get_sdes_string (src, GST_RTCP_SDES_EMAIL))) { - gst_structure_set (s, "email", G_TYPE_STRING, str, NULL); - g_free (str); - } - if ((str = rtp_source_get_sdes_string (src, GST_RTCP_SDES_PHONE))) { - gst_structure_set (s, "phone", G_TYPE_STRING, str, NULL); - g_free (str); - } - if ((str = rtp_source_get_sdes_string (src, GST_RTCP_SDES_LOC))) { - gst_structure_set (s, "location", G_TYPE_STRING, str, NULL); - g_free (str); - } - if ((str = rtp_source_get_sdes_string (src, GST_RTCP_SDES_TOOL))) { - gst_structure_set (s, "tool", G_TYPE_STRING, str, NULL); - g_free (str); - } - if ((str = rtp_source_get_sdes_string (src, GST_RTCP_SDES_NOTE))) { - gst_structure_set (s, "note", G_TYPE_STRING, str, NULL); - g_free (str); - } - return s; -} - -/** - * rtp_source_set_sdes_struct: - * @src: an #RTSPSource - * @sdes: a #GstStructure with SDES info - * - * Set the SDES items from @sdes. - */ -void -rtp_source_set_sdes_struct (RTPSource * src, const GstStructure * sdes) -{ - const gchar *str; - - if (!gst_structure_has_name (sdes, "application/x-rtp-source-sdes")) - return; - - if ((str = gst_structure_get_string (sdes, "cname"))) { - rtp_source_set_sdes_string (src, GST_RTCP_SDES_CNAME, str); - } - if ((str = gst_structure_get_string (sdes, "name"))) { - rtp_source_set_sdes_string (src, GST_RTCP_SDES_NAME, str); - } - if ((str = gst_structure_get_string (sdes, "email"))) { - rtp_source_set_sdes_string (src, GST_RTCP_SDES_EMAIL, str); - } - if ((str = gst_structure_get_string (sdes, "phone"))) { - rtp_source_set_sdes_string (src, GST_RTCP_SDES_PHONE, str); - } - if ((str = gst_structure_get_string (sdes, "location"))) { - rtp_source_set_sdes_string (src, GST_RTCP_SDES_LOC, str); - } - if ((str = gst_structure_get_string (sdes, "tool"))) { - rtp_source_set_sdes_string (src, GST_RTCP_SDES_TOOL, str); - } - if ((str = gst_structure_get_string (sdes, "note"))) { - rtp_source_set_sdes_string (src, GST_RTCP_SDES_NOTE, str); - } -} - -static void -rtp_source_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) -{ - RTPSource *src; - - src = RTP_SOURCE (object); - - switch (prop_id) { - case PROP_SSRC: - src->ssrc = g_value_get_uint (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -rtp_source_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec) -{ - RTPSource *src; - - src = RTP_SOURCE (object); - - switch (prop_id) { - case PROP_SSRC: - g_value_set_uint (value, rtp_source_get_ssrc (src)); - break; - case PROP_IS_CSRC: - g_value_set_boolean (value, rtp_source_is_as_csrc (src)); - break; - case PROP_IS_VALIDATED: - g_value_set_boolean (value, rtp_source_is_validated (src)); - break; - case PROP_IS_SENDER: - g_value_set_boolean (value, rtp_source_is_sender (src)); - break; - case PROP_SDES: - g_value_take_boxed (value, rtp_source_get_sdes_struct (src)); - break; - case PROP_STATS: - g_value_take_boxed (value, rtp_source_create_stats (src)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -/** - * rtp_source_new: - * @ssrc: an SSRC - * - * Create a #RTPSource with @ssrc. - * - * Returns: a new #RTPSource. Use g_object_unref() after usage. - */ -RTPSource * -rtp_source_new (guint32 ssrc) -{ - RTPSource *src; - - src = g_object_new (RTP_TYPE_SOURCE, NULL); - src->ssrc = ssrc; - - return src; -} - -/** - * rtp_source_set_callbacks: - * @src: an #RTPSource - * @cb: callback functions - * @user_data: user data - * - * Set the callbacks for the source. - */ -void -rtp_source_set_callbacks (RTPSource * src, RTPSourceCallbacks * cb, - gpointer user_data) -{ - g_return_if_fail (RTP_IS_SOURCE (src)); - - src->callbacks.push_rtp = cb->push_rtp; - src->callbacks.clock_rate = cb->clock_rate; - src->user_data = user_data; -} - -/** - * rtp_source_get_ssrc: - * @src: an #RTPSource - * - * Get the SSRC of @source. - * - * Returns: the SSRC of src. - */ -guint32 -rtp_source_get_ssrc (RTPSource * src) -{ - guint32 result; - - g_return_val_if_fail (RTP_IS_SOURCE (src), 0); - - result = src->ssrc; - - return result; -} - -/** - * rtp_source_set_as_csrc: - * @src: an #RTPSource - * - * Configure @src as a CSRC, this will also validate @src. - */ -void -rtp_source_set_as_csrc (RTPSource * src) -{ - g_return_if_fail (RTP_IS_SOURCE (src)); - - src->validated = TRUE; - src->is_csrc = TRUE; -} - -/** - * rtp_source_is_as_csrc: - * @src: an #RTPSource - * - * Check if @src is a contributing source. - * - * Returns: %TRUE if @src is acting as a contributing source. - */ -gboolean -rtp_source_is_as_csrc (RTPSource * src) -{ - gboolean result; - - g_return_val_if_fail (RTP_IS_SOURCE (src), FALSE); - - result = src->is_csrc; - - return result; -} - -/** - * rtp_source_is_active: - * @src: an #RTPSource - * - * Check if @src is an active source. A source is active if it has been - * validated and has not yet received a BYE packet - * - * Returns: %TRUE if @src is an qactive source. - */ -gboolean -rtp_source_is_active (RTPSource * src) -{ - gboolean result; - - g_return_val_if_fail (RTP_IS_SOURCE (src), FALSE); - - result = RTP_SOURCE_IS_ACTIVE (src); - - return result; -} - -/** - * rtp_source_is_validated: - * @src: an #RTPSource - * - * Check if @src is a validated source. - * - * Returns: %TRUE if @src is a validated source. - */ -gboolean -rtp_source_is_validated (RTPSource * src) -{ - gboolean result; - - g_return_val_if_fail (RTP_IS_SOURCE (src), FALSE); - - result = src->validated; - - return result; -} - -/** - * rtp_source_is_sender: - * @src: an #RTPSource - * - * Check if @src is a sending source. - * - * Returns: %TRUE if @src is a sending source. - */ -gboolean -rtp_source_is_sender (RTPSource * src) -{ - gboolean result; - - g_return_val_if_fail (RTP_IS_SOURCE (src), FALSE); - - result = RTP_SOURCE_IS_SENDER (src); - - return result; -} - -/** - * rtp_source_received_bye: - * @src: an #RTPSource - * - * Check if @src has receoved a BYE packet. - * - * Returns: %TRUE if @src has received a BYE packet. - */ -gboolean -rtp_source_received_bye (RTPSource * src) -{ - gboolean result; - - g_return_val_if_fail (RTP_IS_SOURCE (src), FALSE); - - result = src->received_bye; - - return result; -} - - -/** - * rtp_source_get_bye_reason: - * @src: an #RTPSource - * - * Get the BYE reason for @src. Check if the source receoved a BYE message first - * with rtp_source_received_bye(). - * - * Returns: The BYE reason or NULL when no reason was given or the source did - * not receive a BYE message yet. g_fee() after usage. - */ -gchar * -rtp_source_get_bye_reason (RTPSource * src) -{ - gchar *result; - - g_return_val_if_fail (RTP_IS_SOURCE (src), NULL); - - result = g_strdup (src->bye_reason); - - return result; -} - -/** - * rtp_source_update_caps: - * @src: an #RTPSource - * @caps: a #GstCaps - * - * Parse @caps and store all relevant information in @source. - */ -void -rtp_source_update_caps (RTPSource * src, GstCaps * caps) -{ - GstStructure *s; - guint val; - gint ival; - - /* nothing changed, return */ - if (caps == NULL || src->caps == caps) - return; - - s = gst_caps_get_structure (caps, 0); - - if (gst_structure_get_int (s, "payload", &ival)) - src->payload = ival; - else - src->payload = -1; - GST_DEBUG ("got payload %d", src->payload); - - if (gst_structure_get_int (s, "clock-rate", &ival)) - src->clock_rate = ival; - else - src->clock_rate = -1; - - GST_DEBUG ("got clock-rate %d", src->clock_rate); - - if (gst_structure_get_uint (s, "seqnum-base", &val)) - src->seqnum_base = val; - else - src->seqnum_base = -1; - - GST_DEBUG ("got seqnum-base %" G_GINT32_FORMAT, src->seqnum_base); - - gst_caps_replace (&src->caps, caps); -} - -/** - * rtp_source_set_sdes: - * @src: an #RTPSource - * @type: the type of the SDES item - * @data: the SDES data - * @len: the SDES length - * - * Store an SDES item of @type in @src. - * - * Returns: %FALSE if the SDES item was unchanged or @type is unknown. - */ -gboolean -rtp_source_set_sdes (RTPSource * src, GstRTCPSDESType type, - const guint8 * data, guint len) -{ - guint8 *old; - - g_return_val_if_fail (RTP_IS_SOURCE (src), FALSE); - - if (type < 0 || type > GST_RTCP_SDES_PRIV) - return FALSE; - - old = src->sdes[type]; - - /* lengths are the same, check if the data is the same */ - if ((src->sdes_len[type] == len)) - if (data != NULL && old != NULL && (memcmp (old, data, len) == 0)) - return FALSE; - - /* NULL data, make sure we store 0 length or if no length is given, - * take strlen */ - if (data == NULL) - len = 0; - - g_free (src->sdes[type]); - src->sdes[type] = g_memdup (data, len); - src->sdes_len[type] = len; - - return TRUE; -} - -/** - * rtp_source_set_sdes_string: - * @src: an #RTPSource - * @type: the type of the SDES item - * @data: the SDES data - * - * Store an SDES item of @type in @src. This function is similar to - * rtp_source_set_sdes() but takes a null-terminated string for convenience. - * - * Returns: %FALSE if the SDES item was unchanged or @type is unknown. - */ -gboolean -rtp_source_set_sdes_string (RTPSource * src, GstRTCPSDESType type, - const gchar * data) -{ - guint len; - gboolean result; - - if (data) - len = strlen (data); - else - len = 0; - - result = rtp_source_set_sdes (src, type, (guint8 *) data, len); - - return result; -} - -/** - * rtp_source_get_sdes: - * @src: an #RTPSource - * @type: the type of the SDES item - * @data: location to store the SDES data or NULL - * @len: location to store the SDES length or NULL - * - * Get the SDES item of @type from @src. Note that @data does not always point - * to a null-terminated string, use rtp_source_get_sdes_string() to retrieve a - * null-terminated string instead. - * - * @data remains valid until the next call to rtp_source_set_sdes(). - * - * Returns: %TRUE if @type was valid and @data and @len contain valid - * data. @data can be NULL when the item was unset. - */ -gboolean -rtp_source_get_sdes (RTPSource * src, GstRTCPSDESType type, guint8 ** data, - guint * len) -{ - g_return_val_if_fail (RTP_IS_SOURCE (src), FALSE); - - if (type < 0 || type > GST_RTCP_SDES_PRIV) - return FALSE; - - if (data) - *data = src->sdes[type]; - if (len) - *len = src->sdes_len[type]; - - return TRUE; -} - -/** - * rtp_source_get_sdes_string: - * @src: an #RTPSource - * @type: the type of the SDES item - * - * Get the SDES item of @type from @src. - * - * Returns: a null-terminated copy of the SDES item or NULL when @type was not - * valid or the SDES item was unset. g_free() after usage. - */ -gchar * -rtp_source_get_sdes_string (RTPSource * src, GstRTCPSDESType type) -{ - gchar *result; - - g_return_val_if_fail (RTP_IS_SOURCE (src), NULL); - - if (type < 0 || type > GST_RTCP_SDES_PRIV) - return NULL; - - result = g_strndup ((const gchar *) src->sdes[type], src->sdes_len[type]); - - return result; -} - -/** - * rtp_source_set_rtp_from: - * @src: an #RTPSource - * @address: the RTP address to set - * - * Set that @src is receiving RTP packets from @address. This is used for - * collistion checking. - */ -void -rtp_source_set_rtp_from (RTPSource * src, GstNetAddress * address) -{ - g_return_if_fail (RTP_IS_SOURCE (src)); - - src->have_rtp_from = TRUE; - memcpy (&src->rtp_from, address, sizeof (GstNetAddress)); -} - -/** - * rtp_source_set_rtcp_from: - * @src: an #RTPSource - * @address: the RTCP address to set - * - * Set that @src is receiving RTCP packets from @address. This is used for - * collistion checking. - */ -void -rtp_source_set_rtcp_from (RTPSource * src, GstNetAddress * address) -{ - g_return_if_fail (RTP_IS_SOURCE (src)); - - src->have_rtcp_from = TRUE; - memcpy (&src->rtcp_from, address, sizeof (GstNetAddress)); -} - -static GstFlowReturn -push_packet (RTPSource * src, GstBuffer * buffer) -{ - GstFlowReturn ret = GST_FLOW_OK; - - /* push queued packets first if any */ - while (!g_queue_is_empty (src->packets)) { - GstBuffer *buffer = GST_BUFFER_CAST (g_queue_pop_head (src->packets)); - - GST_LOG ("pushing queued packet"); - if (src->callbacks.push_rtp) - src->callbacks.push_rtp (src, buffer, src->user_data); - else - gst_buffer_unref (buffer); - } - GST_LOG ("pushing new packet"); - /* push packet */ - if (src->callbacks.push_rtp) - ret = src->callbacks.push_rtp (src, buffer, src->user_data); - else - gst_buffer_unref (buffer); - - return ret; -} - -static gint -get_clock_rate (RTPSource * src, guint8 payload) -{ - if (src->payload == -1) { - /* first payload received, nothing was in the caps, lock on to this payload */ - src->payload = payload; - GST_DEBUG ("first payload %d", payload); - } else if (payload != src->payload) { - /* we have a different payload than before, reset the clock-rate */ - GST_DEBUG ("new payload %d", payload); - src->payload = payload; - src->clock_rate = -1; - src->stats.transit = -1; - } - - if (src->clock_rate == -1) { - gint clock_rate = -1; - - if (src->callbacks.clock_rate) - clock_rate = src->callbacks.clock_rate (src, payload, src->user_data); - - GST_DEBUG ("got clock-rate %d", clock_rate); - - src->clock_rate = clock_rate; - } - return src->clock_rate; -} - -/* Jitter is the variation in the delay of received packets in a flow. It is - * measured by comparing the interval when RTP packets were sent to the interval - * at which they were received. For instance, if packet #1 and packet #2 leave - * 50 milliseconds apart and arrive 60 milliseconds apart, then the jitter is 10 - * milliseconds. */ -static void -calculate_jitter (RTPSource * src, GstBuffer * buffer, - RTPArrivalStats * arrival) -{ - guint64 ntpnstime; - guint32 rtparrival, transit, rtptime; - gint32 diff; - gint clock_rate; - guint8 pt; - - /* get arrival time */ - if ((ntpnstime = arrival->ntpnstime) == GST_CLOCK_TIME_NONE) - goto no_time; - - pt = gst_rtp_buffer_get_payload_type (buffer); - - GST_LOG ("SSRC %08x got payload %d", src->ssrc, pt); - - /* get clockrate */ - if ((clock_rate = get_clock_rate (src, pt)) == -1) - goto no_clock_rate; - - rtptime = gst_rtp_buffer_get_timestamp (buffer); - - /* convert arrival time to RTP timestamp units, truncate to 32 bits, we don't - * care about the absolute value, just the difference. */ - rtparrival = gst_util_uint64_scale_int (ntpnstime, clock_rate, GST_SECOND); - - /* transit time is difference with RTP timestamp */ - transit = rtparrival - rtptime; - - /* get ABS diff with previous transit time */ - if (src->stats.transit != -1) { - if (transit > src->stats.transit) - diff = transit - src->stats.transit; - else - diff = src->stats.transit - transit; - } else - diff = 0; - - src->stats.transit = transit; - - /* update jitter, the value we store is scaled up so we can keep precision. */ - src->stats.jitter += diff - ((src->stats.jitter + 8) >> 4); - - src->stats.prev_rtptime = src->stats.last_rtptime; - src->stats.last_rtptime = rtparrival; - - GST_LOG ("rtparrival %u, rtptime %u, clock-rate %d, diff %d, jitter: %f", - rtparrival, rtptime, clock_rate, diff, (src->stats.jitter) / 16.0); - - return; - - /* ERRORS */ -no_time: - { - GST_WARNING ("cannot get current time"); - return; - } -no_clock_rate: - { - GST_WARNING ("cannot get clock-rate for pt %d", pt); - return; - } -} - -static void -init_seq (RTPSource * src, guint16 seq) -{ - src->stats.base_seq = seq; - src->stats.max_seq = seq; - src->stats.bad_seq = RTP_SEQ_MOD + 1; /* so seq == bad_seq is false */ - src->stats.cycles = 0; - src->stats.packets_received = 0; - src->stats.octets_received = 0; - src->stats.bytes_received = 0; - src->stats.prev_received = 0; - src->stats.prev_expected = 0; - - GST_DEBUG ("base_seq %d", seq); -} - -/** - * rtp_source_process_rtp: - * @src: an #RTPSource - * @buffer: an RTP buffer - * - * Let @src handle the incomming RTP @buffer. - * - * Returns: a #GstFlowReturn. - */ -GstFlowReturn -rtp_source_process_rtp (RTPSource * src, GstBuffer * buffer, - RTPArrivalStats * arrival) -{ - GstFlowReturn result = GST_FLOW_OK; - guint16 seqnr, udelta; - RTPSourceStats *stats; - - g_return_val_if_fail (RTP_IS_SOURCE (src), GST_FLOW_ERROR); - g_return_val_if_fail (GST_IS_BUFFER (buffer), GST_FLOW_ERROR); - - stats = &src->stats; - - seqnr = gst_rtp_buffer_get_seq (buffer); - - rtp_source_update_caps (src, GST_BUFFER_CAPS (buffer)); - - if (stats->cycles == -1) { - GST_DEBUG ("received first buffer"); - /* first time we heard of this source */ - init_seq (src, seqnr); - src->stats.max_seq = seqnr - 1; - src->probation = RTP_DEFAULT_PROBATION; - } - - udelta = seqnr - stats->max_seq; - - /* if we are still on probation, check seqnum */ - if (src->probation) { - guint16 expected; - - expected = src->stats.max_seq + 1; - - /* when in probation, we require consecutive seqnums */ - if (seqnr == expected) { - /* expected packet */ - GST_DEBUG ("probation: seqnr %d == expected %d", seqnr, expected); - src->probation--; - src->stats.max_seq = seqnr; - if (src->probation == 0) { - GST_DEBUG ("probation done!"); - init_seq (src, seqnr); - } else { - GstBuffer *q; - - GST_DEBUG ("probation %d: queue buffer", src->probation); - /* when still in probation, keep packets in a list. */ - g_queue_push_tail (src->packets, buffer); - /* remove packets from queue if there are too many */ - while (g_queue_get_length (src->packets) > RTP_MAX_PROBATION_LEN) { - q = g_queue_pop_head (src->packets); - gst_buffer_unref (q); - } - goto done; - } - } else { - GST_DEBUG ("probation: seqnr %d != expected %d", seqnr, expected); - src->probation = RTP_DEFAULT_PROBATION; - src->stats.max_seq = seqnr; - goto done; - } - } else if (udelta < RTP_MAX_DROPOUT) { - /* in order, with permissible gap */ - if (seqnr < stats->max_seq) { - /* sequence number wrapped - count another 64K cycle. */ - stats->cycles += RTP_SEQ_MOD; - } - stats->max_seq = seqnr; - } else if (udelta <= RTP_SEQ_MOD - RTP_MAX_MISORDER) { - /* the sequence number made a very large jump */ - if (seqnr == stats->bad_seq) { - /* two sequential packets -- assume that the other side - * restarted without telling us so just re-sync - * (i.e., pretend this was the first packet). */ - init_seq (src, seqnr); - } else { - /* unacceptable jump */ - stats->bad_seq = (seqnr + 1) & (RTP_SEQ_MOD - 1); - goto bad_sequence; - } - } else { - /* duplicate or reordered packet, will be filtered by jitterbuffer. */ - GST_WARNING ("duplicate or reordered packet"); - } - - src->stats.octets_received += arrival->payload_len; - src->stats.bytes_received += arrival->bytes; - src->stats.packets_received++; - /* the source that sent the packet must be a sender */ - src->is_sender = TRUE; - src->validated = TRUE; - - GST_LOG ("seq %d, PC: %" G_GUINT64_FORMAT ", OC: %" G_GUINT64_FORMAT, - seqnr, src->stats.packets_received, src->stats.octets_received); - - /* calculate jitter for the stats */ - calculate_jitter (src, buffer, arrival); - - /* we're ready to push the RTP packet now */ - result = push_packet (src, buffer); - -done: - return result; - - /* ERRORS */ -bad_sequence: - { - GST_WARNING ("unacceptable seqnum received"); - gst_buffer_unref (buffer); - return GST_FLOW_OK; - } -} - -/** - * rtp_source_process_bye: - * @src: an #RTPSource - * @reason: the reason for leaving - * - * Notify @src that a BYE packet has been received. This will make the source - * inactive. - */ -void -rtp_source_process_bye (RTPSource * src, const gchar * reason) -{ - g_return_if_fail (RTP_IS_SOURCE (src)); - - GST_DEBUG ("marking SSRC %08x as BYE, reason: %s", src->ssrc, - GST_STR_NULL (reason)); - - /* copy the reason and mark as received_bye */ - g_free (src->bye_reason); - src->bye_reason = g_strdup (reason); - src->received_bye = TRUE; -} - -static GstBufferListItem -set_ssrc (GstBuffer ** buffer, guint group, guint idx, RTPSource * src) -{ - *buffer = gst_buffer_make_writable (*buffer); - gst_rtp_buffer_set_ssrc (*buffer, src->ssrc); - return GST_BUFFER_LIST_SKIP_GROUP; -} - -/** - * rtp_source_send_rtp: - * @src: an #RTPSource - * @data: an RTP buffer or a list of RTP buffers - * @is_list: if @data is a buffer or list - * @ntpnstime: the NTP time when this buffer was captured in nanoseconds. This - * is the buffer timestamp converted to NTP time. - * - * Send @data (an RTP buffer or list of buffers) originating from @src. - * This will make @src a sender. This function takes ownership of @data and - * modifies the SSRC in the RTP packet to that of @src when needed. - * - * Returns: a #GstFlowReturn. - */ -GstFlowReturn -rtp_source_send_rtp (RTPSource * src, gpointer data, gboolean is_list, - guint64 ntpnstime) -{ - GstFlowReturn result; - guint len; - guint32 rtptime; - guint64 ext_rtptime; - guint64 ntp_diff, rtp_diff; - guint64 elapsed; - GstBufferList *list = NULL; - GstBuffer *buffer = NULL; - guint packets; - guint32 ssrc; - - g_return_val_if_fail (RTP_IS_SOURCE (src), GST_FLOW_ERROR); - g_return_val_if_fail (is_list || GST_IS_BUFFER (data), GST_FLOW_ERROR); - - if (is_list) { - list = GST_BUFFER_LIST_CAST (data); - - /* We can grab the caps from the first group, since all - * groups of a buffer list have same caps. */ - buffer = gst_buffer_list_get (list, 0, 0); - if (!buffer) - goto no_buffer; - } else { - buffer = GST_BUFFER_CAST (data); - } - rtp_source_update_caps (src, GST_BUFFER_CAPS (buffer)); - - /* we are a sender now */ - src->is_sender = TRUE; - - if (is_list) { - /* Each group makes up a network packet. */ - packets = gst_buffer_list_n_groups (list); - len = gst_rtp_buffer_list_get_payload_len (list); - } else { - packets = 1; - len = gst_rtp_buffer_get_payload_len (buffer); - } - - /* update stats for the SR */ - src->stats.packets_sent += packets; - src->stats.octets_sent += len; - src->bytes_sent += len; - - if (src->prev_ntpnstime) { - elapsed = ntpnstime - src->prev_ntpnstime; - - if (elapsed > (G_GINT64_CONSTANT (1) << 31)) { - guint64 rate; - - rate = - gst_util_uint64_scale (src->bytes_sent, elapsed, - (G_GINT64_CONSTANT (1) << 29)); - - GST_LOG ("Elapsed %" G_GUINT64_FORMAT ", bytes %" G_GUINT64_FORMAT - ", rate %" G_GUINT64_FORMAT, elapsed, src->bytes_sent, rate); - - if (src->bitrate == 0) - src->bitrate = rate; - else - src->bitrate = ((src->bitrate * 3) + rate) / 4; - - src->prev_ntpnstime = ntpnstime; - src->bytes_sent = 0; - } - } else { - GST_LOG ("Reset bitrate measurement"); - src->prev_ntpnstime = ntpnstime; - src->bitrate = 0; - } - - if (is_list) { - rtptime = gst_rtp_buffer_list_get_timestamp (list); - } else { - rtptime = gst_rtp_buffer_get_timestamp (buffer); - } - ext_rtptime = src->last_rtptime; - ext_rtptime = gst_rtp_buffer_ext_timestamp (&ext_rtptime, rtptime); - - GST_LOG ("SSRC %08x, RTP %" G_GUINT64_FORMAT ", NTP %" GST_TIME_FORMAT, - src->ssrc, ext_rtptime, GST_TIME_ARGS (ntpnstime)); - - if (ext_rtptime > src->last_rtptime) { - rtp_diff = ext_rtptime - src->last_rtptime; - ntp_diff = ntpnstime - src->last_ntpnstime; - - /* calc the diff so we can detect drift at the sender. This can also be used - * to guestimate the clock rate if the NTP time is locked to the RTP - * timestamps (as is the case when the capture device is providing the clock). */ - GST_LOG ("SSRC %08x, diff RTP %" G_GUINT64_FORMAT ", diff NTP %" - GST_TIME_FORMAT, src->ssrc, rtp_diff, GST_TIME_ARGS (ntp_diff)); - } - - /* we keep track of the last received RTP timestamp and the corresponding - * NTP timestamp so that we can use this info when constructing SR reports */ - src->last_rtptime = ext_rtptime; - src->last_ntpnstime = ntpnstime; - - /* push packet */ - if (!src->callbacks.push_rtp) - goto no_callback; - - if (is_list) { - ssrc = gst_rtp_buffer_list_get_ssrc (list); - } else { - ssrc = gst_rtp_buffer_get_ssrc (buffer); - } - - if (ssrc != src->ssrc) { - /* the SSRC of the packet is not correct, make a writable buffer and - * update the SSRC. This could involve a complete copy of the packet when - * it is not writable. Usually the payloader will use caps negotiation to - * get the correct SSRC from the session manager before pushing anything. */ - - /* FIXME, we don't want to warn yet because we can't inform any payloader - * of the changes SSRC yet because we don't implement pad-alloc. */ - GST_LOG ("updating SSRC from %08x to %08x, fix the payloader", ssrc, - src->ssrc); - - if (is_list) { - list = gst_buffer_list_make_writable (list); - gst_buffer_list_foreach (list, (GstBufferListFunc) set_ssrc, src); - } else { - set_ssrc (&buffer, 0, 0, src); - } - } - GST_LOG ("pushing RTP %s %" G_GUINT64_FORMAT, is_list ? "list" : "packet", - src->stats.packets_sent); - - result = src->callbacks.push_rtp (src, data, src->user_data); - - return result; - - /* ERRORS */ -no_buffer: - { - GST_WARNING ("no buffers in buffer list"); - gst_mini_object_unref (GST_MINI_OBJECT_CAST (data)); - return GST_FLOW_OK; - } -no_callback: - { - GST_WARNING ("no callback installed, dropping packet"); - gst_mini_object_unref (GST_MINI_OBJECT_CAST (data)); - return GST_FLOW_OK; - } -} - -/** - * rtp_source_process_sr: - * @src: an #RTPSource - * @time: time of packet arrival - * @ntptime: the NTP time in 32.32 fixed point - * @rtptime: the RTP time - * @packet_count: the packet count - * @octet_count: the octect count - * - * Update the sender report in @src. - */ -void -rtp_source_process_sr (RTPSource * src, GstClockTime time, guint64 ntptime, - guint32 rtptime, guint32 packet_count, guint32 octet_count) -{ - RTPSenderReport *curr; - gint curridx; - - g_return_if_fail (RTP_IS_SOURCE (src)); - - GST_DEBUG ("got SR packet: SSRC %08x, NTP %08x:%08x, RTP %" G_GUINT32_FORMAT - ", PC %" G_GUINT32_FORMAT ", OC %" G_GUINT32_FORMAT, src->ssrc, - (guint32) (ntptime >> 32), (guint32) (ntptime & 0xffffffff), rtptime, - packet_count, octet_count); - - curridx = src->stats.curr_sr ^ 1; - curr = &src->stats.sr[curridx]; - - /* this is a sender now */ - src->is_sender = TRUE; - - /* update current */ - curr->is_valid = TRUE; - curr->ntptime = ntptime; - curr->rtptime = rtptime; - curr->packet_count = packet_count; - curr->octet_count = octet_count; - curr->time = time; - - /* make current */ - src->stats.curr_sr = curridx; -} - -/** - * rtp_source_process_rb: - * @src: an #RTPSource - * @time: the current time in nanoseconds since 1970 - * @fractionlost: fraction lost since last SR/RR - * @packetslost: the cumululative number of packets lost - * @exthighestseq: the extended last sequence number received - * @jitter: the interarrival jitter - * @lsr: the last SR packet from this source - * @dlsr: the delay since last SR packet - * - * Update the report block in @src. - */ -void -rtp_source_process_rb (RTPSource * src, GstClockTime time, guint8 fractionlost, - gint32 packetslost, guint32 exthighestseq, guint32 jitter, guint32 lsr, - guint32 dlsr) -{ - RTPReceiverReport *curr; - gint curridx; - guint32 ntp, A; - - g_return_if_fail (RTP_IS_SOURCE (src)); - - GST_DEBUG ("got RB packet: SSRC %08x, FL %2x, PL %d, HS %" G_GUINT32_FORMAT - ", jitter %" G_GUINT32_FORMAT ", LSR %04x:%04x, DLSR %04x:%04x", - src->ssrc, fractionlost, packetslost, exthighestseq, jitter, lsr >> 16, - lsr & 0xffff, dlsr >> 16, dlsr & 0xffff); - - curridx = src->stats.curr_rr ^ 1; - curr = &src->stats.rr[curridx]; - - /* update current */ - curr->is_valid = TRUE; - curr->fractionlost = fractionlost; - curr->packetslost = packetslost; - curr->exthighestseq = exthighestseq; - curr->jitter = jitter; - curr->lsr = lsr; - curr->dlsr = dlsr; - - /* calculate round trip, round the time up */ - ntp = ((gst_rtcp_unix_to_ntp (time) + 0xffff) >> 16) & 0xffffffff; - A = dlsr + lsr; - if (A > 0 && ntp > A) - A = ntp - A; - else - A = 0; - curr->round_trip = A; - - GST_DEBUG ("NTP %04x:%04x, round trip %04x:%04x", ntp >> 16, ntp & 0xffff, - A >> 16, A & 0xffff); - - /* make current */ - src->stats.curr_rr = curridx; -} - -/** - * rtp_source_get_new_sr: - * @src: an #RTPSource - * @ntpnstime: the current time in nanoseconds since 1970 - * @ntptime: the NTP time in 32.32 fixed point - * @rtptime: the RTP time corresponding to @ntptime - * @packet_count: the packet count - * @octet_count: the octect count - * - * Get new values to put into a new SR report from this source. - * - * Returns: %TRUE on success. - */ -gboolean -rtp_source_get_new_sr (RTPSource * src, guint64 ntpnstime, - guint64 * ntptime, guint32 * rtptime, guint32 * packet_count, - guint32 * octet_count) -{ - guint64 t_rtp; - guint64 t_current_ntp; - GstClockTimeDiff diff; - - g_return_val_if_fail (RTP_IS_SOURCE (src), FALSE); - - /* use the sync params to interpolate the date->time member to rtptime. We - * use the last sent timestamp and rtptime as reference points. We assume - * that the slope of the rtptime vs timestamp curve is 1, which is certainly - * sufficient for the frequency at which we report SR and the rate we send - * out RTP packets. */ - t_rtp = src->last_rtptime; - - GST_DEBUG ("last_ntpnstime %" GST_TIME_FORMAT ", last_rtptime %" - G_GUINT64_FORMAT, GST_TIME_ARGS (src->last_ntpnstime), t_rtp); - - if (src->clock_rate != -1) { - /* get the diff with the SR time */ - diff = GST_CLOCK_DIFF (src->last_ntpnstime, ntpnstime); - - /* now translate the diff to RTP time, handle positive and negative cases. - * If there is no diff, we already set rtptime correctly above. */ - if (diff > 0) { - GST_DEBUG ("ntpnstime %" GST_TIME_FORMAT ", diff %" GST_TIME_FORMAT, - GST_TIME_ARGS (ntpnstime), GST_TIME_ARGS (diff)); - t_rtp += gst_util_uint64_scale_int (diff, src->clock_rate, GST_SECOND); - } else { - diff = -diff; - GST_DEBUG ("ntpnstime %" GST_TIME_FORMAT ", diff -%" GST_TIME_FORMAT, - GST_TIME_ARGS (ntpnstime), GST_TIME_ARGS (diff)); - t_rtp -= gst_util_uint64_scale_int (diff, src->clock_rate, GST_SECOND); - } - } else { - GST_WARNING ("no clock-rate, cannot interpolate rtp time"); - } - - /* convert the NTP time in nanoseconds to 32.32 fixed point */ - t_current_ntp = gst_util_uint64_scale (ntpnstime, (1LL << 32), GST_SECOND); - - GST_DEBUG ("NTP %08x:%08x, RTP %" G_GUINT32_FORMAT, - (guint32) (t_current_ntp >> 32), (guint32) (t_current_ntp & 0xffffffff), - (guint32) t_rtp); - - if (ntptime) - *ntptime = t_current_ntp; - if (rtptime) - *rtptime = t_rtp; - if (packet_count) - *packet_count = src->stats.packets_sent; - if (octet_count) - *octet_count = src->stats.octets_sent; - - return TRUE; -} - -/** - * rtp_source_get_new_rb: - * @src: an #RTPSource - * @time: the current time of the system clock - * @fractionlost: fraction lost since last SR/RR - * @packetslost: the cumululative number of packets lost - * @exthighestseq: the extended last sequence number received - * @jitter: the interarrival jitter - * @lsr: the last SR packet from this source - * @dlsr: the delay since last SR packet - * - * Get new values to put into a new report block from this source. - * - * Returns: %TRUE on success. - */ -gboolean -rtp_source_get_new_rb (RTPSource * src, GstClockTime time, - guint8 * fractionlost, gint32 * packetslost, guint32 * exthighestseq, - guint32 * jitter, guint32 * lsr, guint32 * dlsr) -{ - RTPSourceStats *stats; - guint64 extended_max, expected; - guint64 expected_interval, received_interval, ntptime; - gint64 lost, lost_interval; - guint32 fraction, LSR, DLSR; - GstClockTime sr_time; - - stats = &src->stats; - - extended_max = stats->cycles + stats->max_seq; - expected = extended_max - stats->base_seq + 1; - - GST_DEBUG ("ext_max %" G_GUINT64_FORMAT ", expected %" G_GUINT64_FORMAT - ", received %" G_GUINT64_FORMAT ", base_seq %" G_GUINT32_FORMAT, - extended_max, expected, stats->packets_received, stats->base_seq); - - lost = expected - stats->packets_received; - lost = CLAMP (lost, -0x800000, 0x7fffff); - - expected_interval = expected - stats->prev_expected; - stats->prev_expected = expected; - received_interval = stats->packets_received - stats->prev_received; - stats->prev_received = stats->packets_received; - - lost_interval = expected_interval - received_interval; - - if (expected_interval == 0 || lost_interval <= 0) - fraction = 0; - else - fraction = (lost_interval << 8) / expected_interval; - - GST_DEBUG ("add RR for SSRC %08x", src->ssrc); - /* we scaled the jitter up for additional precision */ - GST_DEBUG ("fraction %" G_GUINT32_FORMAT ", lost %" G_GINT64_FORMAT - ", extseq %" G_GUINT64_FORMAT ", jitter %d", fraction, lost, - extended_max, stats->jitter >> 4); - - if (rtp_source_get_last_sr (src, &sr_time, &ntptime, NULL, NULL, NULL)) { - GstClockTime diff; - - /* LSR is middle 32 bits of the last ntptime */ - LSR = (ntptime >> 16) & 0xffffffff; - diff = time - sr_time; - GST_DEBUG ("last SR time diff %" GST_TIME_FORMAT, GST_TIME_ARGS (diff)); - /* DLSR, delay since last SR is expressed in 1/65536 second units */ - DLSR = gst_util_uint64_scale_int (diff, 65536, GST_SECOND); - } else { - /* No valid SR received, LSR/DLSR are set to 0 then */ - GST_DEBUG ("no valid SR received"); - LSR = 0; - DLSR = 0; - } - GST_DEBUG ("LSR %04x:%04x, DLSR %04x:%04x", LSR >> 16, LSR & 0xffff, - DLSR >> 16, DLSR & 0xffff); - - if (fractionlost) - *fractionlost = fraction; - if (packetslost) - *packetslost = lost; - if (exthighestseq) - *exthighestseq = extended_max; - if (jitter) - *jitter = stats->jitter >> 4; - if (lsr) - *lsr = LSR; - if (dlsr) - *dlsr = DLSR; - - return TRUE; -} - -/** - * rtp_source_get_last_sr: - * @src: an #RTPSource - * @time: time of packet arrival - * @ntptime: the NTP time in 32.32 fixed point - * @rtptime: the RTP time - * @packet_count: the packet count - * @octet_count: the octect count - * - * Get the values of the last sender report as set with rtp_source_process_sr(). - * - * Returns: %TRUE if there was a valid SR report. - */ -gboolean -rtp_source_get_last_sr (RTPSource * src, GstClockTime * time, guint64 * ntptime, - guint32 * rtptime, guint32 * packet_count, guint32 * octet_count) -{ - RTPSenderReport *curr; - - g_return_val_if_fail (RTP_IS_SOURCE (src), FALSE); - - curr = &src->stats.sr[src->stats.curr_sr]; - if (!curr->is_valid) - return FALSE; - - if (ntptime) - *ntptime = curr->ntptime; - if (rtptime) - *rtptime = curr->rtptime; - if (packet_count) - *packet_count = curr->packet_count; - if (octet_count) - *octet_count = curr->octet_count; - if (time) - *time = curr->time; - - return TRUE; -} - -/** - * rtp_source_get_last_rb: - * @src: an #RTPSource - * @fractionlost: fraction lost since last SR/RR - * @packetslost: the cumululative number of packets lost - * @exthighestseq: the extended last sequence number received - * @jitter: the interarrival jitter - * @lsr: the last SR packet from this source - * @dlsr: the delay since last SR packet - * @round_trip: the round trip time - * - * Get the values of the last RB report set with rtp_source_process_rb(). - * - * Returns: %TRUE if there was a valid SB report. - */ -gboolean -rtp_source_get_last_rb (RTPSource * src, guint8 * fractionlost, - gint32 * packetslost, guint32 * exthighestseq, guint32 * jitter, - guint32 * lsr, guint32 * dlsr, guint32 * round_trip) -{ - RTPReceiverReport *curr; - - g_return_val_if_fail (RTP_IS_SOURCE (src), FALSE); - - curr = &src->stats.rr[src->stats.curr_rr]; - if (!curr->is_valid) - return FALSE; - - if (fractionlost) - *fractionlost = curr->fractionlost; - if (packetslost) - *packetslost = curr->packetslost; - if (exthighestseq) - *exthighestseq = curr->exthighestseq; - if (jitter) - *jitter = curr->jitter; - if (lsr) - *lsr = curr->lsr; - if (dlsr) - *dlsr = curr->dlsr; - if (round_trip) - *round_trip = curr->round_trip; - - return TRUE; -} diff --git a/gst/rtpmanager/rtpsource.h b/gst/rtpmanager/rtpsource.h deleted file mode 100644 index 8355bc0c..00000000 --- a/gst/rtpmanager/rtpsource.h +++ /dev/null @@ -1,226 +0,0 @@ -/* GStreamer - * Copyright (C) <2007> Wim Taymans <wim.taymans@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., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __RTP_SOURCE_H__ -#define __RTP_SOURCE_H__ - -#include <gst/gst.h> -#include <gst/rtp/gstrtcpbuffer.h> -#include <gst/netbuffer/gstnetbuffer.h> - -#include "rtpstats.h" - -/* the default number of consecutive RTP packets we need to receive before the - * source is considered valid */ -#define RTP_NO_PROBATION 0 -#define RTP_DEFAULT_PROBATION 2 - -#define RTP_SEQ_MOD (1 << 16) - -typedef struct _RTPSource RTPSource; -typedef struct _RTPSourceClass RTPSourceClass; - -#define RTP_TYPE_SOURCE (rtp_source_get_type()) -#define RTP_SOURCE(src) (G_TYPE_CHECK_INSTANCE_CAST((src),RTP_TYPE_SOURCE,RTPSource)) -#define RTP_SOURCE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),RTP_TYPE_SOURCE,RTPSourceClass)) -#define RTP_IS_SOURCE(src) (G_TYPE_CHECK_INSTANCE_TYPE((src),RTP_TYPE_SOURCE)) -#define RTP_IS_SOURCE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),RTP_TYPE_SOURCE)) -#define RTP_SOURCE_CAST(src) ((RTPSource *)(src)) - -/** - * RTP_SOURCE_IS_ACTIVE: - * @src: an #RTPSource - * - * Check if @src is active. A source is active when it has been validated - * and has not yet received a BYE packet. - */ -#define RTP_SOURCE_IS_ACTIVE(src) (src->validated && !src->received_bye) - -/** - * RTP_SOURCE_IS_SENDER: - * @src: an #RTPSource - * - * Check if @src is a sender. - */ -#define RTP_SOURCE_IS_SENDER(src) (src->is_sender) - -/** - * RTPSourcePushRTP: - * @src: an #RTPSource - * @buffer: the RTP buffer ready for processing - * @user_data: user data specified when registering - * - * This callback will be called when @src has @buffer ready for further - * processing. - * - * Returns: a #GstFlowReturn. - */ -typedef GstFlowReturn (*RTPSourcePushRTP) (RTPSource *src, GstBuffer *buffer, - gpointer user_data); - -/** - * RTPSourceClockRate: - * @src: an #RTPSource - * @payload: a payload type - * @user_data: user data specified when registering - * - * This callback will be called when @src needs the clock-rate of the - * @payload. - * - * Returns: a clock-rate for @payload. - */ -typedef gint (*RTPSourceClockRate) (RTPSource *src, guint8 payload, gpointer user_data); - -/** - * RTPSourceCallbacks: - * @push_rtp: a packet becomes available for handling - * @clock_rate: a clock-rate is requested - * @get_time: the current clock time is requested - * - * Callbacks performed by #RTPSource when actions need to be performed. - */ -typedef struct { - RTPSourcePushRTP push_rtp; - RTPSourceClockRate clock_rate; -} RTPSourceCallbacks; - -/** - * RTPSource: - * - * A source in the #RTPSession - */ -struct _RTPSource { - GObject object; - - /*< private >*/ - guint32 ssrc; - - gint probation; - gboolean validated; - gboolean internal; - gboolean is_csrc; - gboolean is_sender; - - guint8 *sdes[9]; - guint sdes_len[9]; - - gboolean received_bye; - gchar *bye_reason; - - gboolean have_rtp_from; - GstNetAddress rtp_from; - gboolean have_rtcp_from; - GstNetAddress rtcp_from; - - gint payload; - GstCaps *caps; - gint clock_rate; - gint32 seqnum_base; - - GstClockTime bye_time; - GstClockTime last_activity; - GstClockTime last_rtp_activity; - - GstClockTime last_rtptime; - GstClockTime last_ntpnstime; - - /* for bitrate estimation */ - guint64 bitrate; - GstClockTime prev_ntpnstime; - guint64 bytes_sent; - - GQueue *packets; - - RTPSourceCallbacks callbacks; - gpointer user_data; - - RTPSourceStats stats; -}; - -struct _RTPSourceClass { - GObjectClass parent_class; -}; - -GType rtp_source_get_type (void); - -/* managing lifetime of sources */ -RTPSource* rtp_source_new (guint32 ssrc); -void rtp_source_set_callbacks (RTPSource *src, RTPSourceCallbacks *cb, gpointer data); - -/* properties */ -guint32 rtp_source_get_ssrc (RTPSource *src); - -void rtp_source_set_as_csrc (RTPSource *src); -gboolean rtp_source_is_as_csrc (RTPSource *src); - -gboolean rtp_source_is_active (RTPSource *src); -gboolean rtp_source_is_validated (RTPSource *src); -gboolean rtp_source_is_sender (RTPSource *src); - -gboolean rtp_source_received_bye (RTPSource *src); -gchar * rtp_source_get_bye_reason (RTPSource *src); - -void rtp_source_update_caps (RTPSource *src, GstCaps *caps); - -/* SDES info */ -gboolean rtp_source_set_sdes (RTPSource *src, GstRTCPSDESType type, - const guint8 *data, guint len); -gboolean rtp_source_set_sdes_string (RTPSource *src, GstRTCPSDESType type, - const gchar *data); -gboolean rtp_source_get_sdes (RTPSource *src, GstRTCPSDESType type, - guint8 **data, guint *len); -gchar* rtp_source_get_sdes_string (RTPSource *src, GstRTCPSDESType type); - -GstStructure * rtp_source_get_sdes_struct (RTPSource * src); -void rtp_source_set_sdes_struct (RTPSource * src, const GstStructure *sdes); - -/* handling network address */ -void rtp_source_set_rtp_from (RTPSource *src, GstNetAddress *address); -void rtp_source_set_rtcp_from (RTPSource *src, GstNetAddress *address); - -/* handling RTP */ -GstFlowReturn rtp_source_process_rtp (RTPSource *src, GstBuffer *buffer, RTPArrivalStats *arrival); - -GstFlowReturn rtp_source_send_rtp (RTPSource *src, gpointer data, gboolean is_list, guint64 ntpnstime); - -/* RTCP messages */ -void rtp_source_process_bye (RTPSource *src, const gchar *reason); -void rtp_source_process_sr (RTPSource *src, GstClockTime time, guint64 ntptime, - guint32 rtptime, guint32 packet_count, guint32 octet_count); -void rtp_source_process_rb (RTPSource *src, GstClockTime time, guint8 fractionlost, - gint32 packetslost, guint32 exthighestseq, guint32 jitter, - guint32 lsr, guint32 dlsr); - -gboolean rtp_source_get_new_sr (RTPSource *src, guint64 ntpnstime, guint64 *ntptime, - guint32 *rtptime, guint32 *packet_count, - guint32 *octet_count); -gboolean rtp_source_get_new_rb (RTPSource *src, GstClockTime time, guint8 *fractionlost, - gint32 *packetslost, guint32 *exthighestseq, guint32 *jitter, - guint32 *lsr, guint32 *dlsr); - -gboolean rtp_source_get_last_sr (RTPSource *src, GstClockTime *time, guint64 *ntptime, - guint32 *rtptime, guint32 *packet_count, - guint32 *octet_count); -gboolean rtp_source_get_last_rb (RTPSource *src, guint8 *fractionlost, gint32 *packetslost, - guint32 *exthighestseq, guint32 *jitter, - guint32 *lsr, guint32 *dlsr, guint32 *round_trip); - -void rtp_source_reset (RTPSource * src); - -#endif /* __RTP_SOURCE_H__ */ diff --git a/gst/rtpmanager/rtpstats.c b/gst/rtpmanager/rtpstats.c deleted file mode 100644 index 640c3194..00000000 --- a/gst/rtpmanager/rtpstats.c +++ /dev/null @@ -1,176 +0,0 @@ -/* GStreamer - * Copyright (C) <2007> Wim Taymans <wim.taymans@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., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#include "rtpstats.h" - -/** - * rtp_stats_init_defaults: - * @stats: an #RTPSessionStats struct - * - * Initialize @stats with its default values. - */ -void -rtp_stats_init_defaults (RTPSessionStats * stats) -{ - stats->bandwidth = RTP_STATS_BANDWIDTH; - stats->sender_fraction = RTP_STATS_SENDER_FRACTION; - stats->receiver_fraction = RTP_STATS_RECEIVER_FRACTION; - stats->rtcp_bandwidth = RTP_STATS_RTCP_BANDWIDTH; - stats->min_interval = RTP_STATS_MIN_INTERVAL; - stats->bye_timeout = RTP_STATS_BYE_TIMEOUT; -} - -/** - * rtp_stats_calculate_rtcp_interval: - * @stats: an #RTPSessionStats struct - * @sender: if we are a sender - * @first: if this is the first time - * - * Calculate the RTCP interval. The result of this function is the amount of - * time to wait (in nanoseconds) before sending a new RTCP message. - * - * Returns: the RTCP interval. - */ -GstClockTime -rtp_stats_calculate_rtcp_interval (RTPSessionStats * stats, gboolean we_send, - gboolean first) -{ - gdouble members, senders, n; - gdouble avg_rtcp_size, rtcp_bw; - gdouble interval; - gdouble rtcp_min_time; - - /* Very first call at application start-up uses half the min - * delay for quicker notification while still allowing some time - * before reporting for randomization and to learn about other - * sources so the report interval will converge to the correct - * interval more quickly. - */ - rtcp_min_time = stats->min_interval; - if (first) - rtcp_min_time /= 2.0; - - /* Dedicate a fraction of the RTCP bandwidth to senders unless - * the number of senders is large enough that their share is - * more than that fraction. - */ - n = members = stats->active_sources; - senders = (gdouble) stats->sender_sources; - rtcp_bw = stats->rtcp_bandwidth; - - if (senders <= members * RTP_STATS_SENDER_FRACTION) { - if (we_send) { - rtcp_bw *= RTP_STATS_SENDER_FRACTION; - n = senders; - } else { - rtcp_bw *= RTP_STATS_RECEIVER_FRACTION; - n -= senders; - } - } - - avg_rtcp_size = stats->avg_rtcp_packet_size / 16.0; - /* - * The effective number of sites times the average packet size is - * the total number of octets sent when each site sends a report. - * Dividing this by the effective bandwidth gives the time - * interval over which those packets must be sent in order to - * meet the bandwidth target, with a minimum enforced. In that - * time interval we send one report so this time is also our - * average time between reports. - */ - interval = avg_rtcp_size * n / rtcp_bw; - if (interval < rtcp_min_time) - interval = rtcp_min_time; - - return interval * GST_SECOND; -} - -/** - * rtp_stats_add_rtcp_jitter: - * @stats: an #RTPSessionStats struct - * @interval: an RTCP interval - * - * Apply a random jitter to the @interval. @interval is typically obtained with - * rtp_stats_calculate_rtcp_interval(). - * - * Returns: the new RTCP interval. - */ -GstClockTime -rtp_stats_add_rtcp_jitter (RTPSessionStats * stats, GstClockTime interval) -{ - gdouble temp; - - /* see RFC 3550 p 30 - * To compensate for "unconditional reconsideration" converging to a - * value below the intended average. - */ -#define COMPENSATION (2.71828 - 1.5); - - temp = (interval * g_random_double_range (0.5, 1.5)) / COMPENSATION; - - return (GstClockTime) temp; -} - - -/** - * rtp_stats_calculate_bye_interval: - * @stats: an #RTPSessionStats struct - * - * Calculate the BYE interval. The result of this function is the amount of - * time to wait (in nanoseconds) before sending a BYE message. - * - * Returns: the BYE interval. - */ -GstClockTime -rtp_stats_calculate_bye_interval (RTPSessionStats * stats) -{ - gdouble members; - gdouble avg_rtcp_size, rtcp_bw; - gdouble interval; - gdouble rtcp_min_time; - - /* no interval when we have less than 50 members */ - if (stats->active_sources < 50) - return 0; - - rtcp_min_time = (stats->min_interval) / 2.0; - - /* Dedicate a fraction of the RTCP bandwidth to senders unless - * the number of senders is large enough that their share is - * more than that fraction. - */ - members = stats->bye_members; - rtcp_bw = stats->rtcp_bandwidth * RTP_STATS_RECEIVER_FRACTION; - - avg_rtcp_size = stats->avg_rtcp_packet_size / 16.0; - /* - * The effective number of sites times the average packet size is - * the total number of octets sent when each site sends a report. - * Dividing this by the effective bandwidth gives the time - * interval over which those packets must be sent in order to - * meet the bandwidth target, with a minimum enforced. In that - * time interval we send one report so this time is also our - * average time between reports. - */ - interval = avg_rtcp_size * members / rtcp_bw; - if (interval < rtcp_min_time) - interval = rtcp_min_time; - - return interval * GST_SECOND; -} diff --git a/gst/rtpmanager/rtpstats.h b/gst/rtpmanager/rtpstats.h deleted file mode 100644 index e5824315..00000000 --- a/gst/rtpmanager/rtpstats.h +++ /dev/null @@ -1,195 +0,0 @@ -/* GStreamer - * Copyright (C) <2007> Wim Taymans <wim.taymans@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., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __RTP_STATS_H__ -#define __RTP_STATS_H__ - -#include <gst/gst.h> -#include <gst/netbuffer/gstnetbuffer.h> - -/** - * RTPSenderReport: - * - * A sender report structure. - */ -typedef struct { - gboolean is_valid; - guint64 ntptime; - guint32 rtptime; - guint32 packet_count; - guint32 octet_count; - GstClockTime time; -} RTPSenderReport; - -/** - * RTPReceiverReport: - * - * A receiver report structure. - */ -typedef struct { - gboolean is_valid; - guint32 ssrc; /* who the report is from */ - guint8 fractionlost; - guint32 packetslost; - guint32 exthighestseq; - guint32 jitter; - guint32 lsr; - guint32 dlsr; - guint32 round_trip; -} RTPReceiverReport; - -/** - * RTPArrivalStats: - * @time: arrival time of a packet according to the system clock - * @running_time: arrival time of a packet as buffer running_time - * @ntpnstime: arrival time of a packet as NTP time in nanoseconds - * @have_address: if the @address field contains a valid address - * @address: address of the sender of the packet - * @bytes: bytes of the packet including lowlevel overhead - * @payload_len: bytes of the RTP payload - * - * Structure holding information about the arrival stats of a packet. - */ -typedef struct { - GstClockTime time; - GstClockTime running_time; - guint64 ntpnstime; - gboolean have_address; - GstNetAddress address; - guint bytes; - guint payload_len; -} RTPArrivalStats; - -/** - * RTPSourceStats: - * @packetsreceived: number of received packets in total - * @prevpacketsreceived: number of packets received in previous reporting - * interval - * @octetsreceived: number of payload bytes received - * @bytesreceived: number of total bytes received including headers and lower - * protocol level overhead - * @max_seqnr: highest sequence number received - * @transit: previous transit time used for calculating @jitter - * @jitter: current jitter - * @prev_rtptime: previous time when an RTP packet was received - * @prev_rtcptime: previous time when an RTCP packet was received - * @last_rtptime: time when last RTP packet received - * @last_rtcptime: time when last RTCP packet received - * @curr_rr: index of current @rr block - * @rr: previous and current receiver report block - * @curr_sr: index of current @sr block - * @sr: previous and current sender report block - * - * Stats about a source. - */ -typedef struct { - guint64 packets_received; - guint64 octets_received; - guint64 bytes_received; - - guint32 prev_expected; - guint32 prev_received; - - guint16 max_seq; - guint64 cycles; - guint32 base_seq; - guint32 bad_seq; - guint32 transit; - guint32 jitter; - - guint64 packets_sent; - guint64 octets_sent; - - /* when we received stuff */ - GstClockTime prev_rtptime; - GstClockTime prev_rtcptime; - GstClockTime last_rtptime; - GstClockTime last_rtcptime; - - /* sender and receiver reports */ - gint curr_rr; - RTPReceiverReport rr[2]; - gint curr_sr; - RTPSenderReport sr[2]; -} RTPSourceStats; - -#define RTP_STATS_BANDWIDTH 64000.0 -#define RTP_STATS_RTCP_BANDWIDTH 3000.0 -/* - * Minimum average time between RTCP packets from this site (in - * seconds). This time prevents the reports from `clumping' when - * sessions are small and the law of large numbers isn't helping - * to smooth out the traffic. It also keeps the report interval - * from becoming ridiculously small during transient outages like - * a network partition. - */ -#define RTP_STATS_MIN_INTERVAL 5.0 -/* - * Fraction of the RTCP bandwidth to be shared among active - * senders. (This fraction was chosen so that in a typical - * session with one or two active senders, the computed report - * time would be roughly equal to the minimum report time so that - * we don't unnecessarily slow down receiver reports.) The - * receiver fraction must be 1 - the sender fraction. - */ -#define RTP_STATS_SENDER_FRACTION (0.25) -#define RTP_STATS_RECEIVER_FRACTION (1.0 - RTP_STATS_SENDER_FRACTION) - -/* - * When receiving a BYE from a source, remove the source from the database - * after this timeout. - */ -#define RTP_STATS_BYE_TIMEOUT (2 * GST_SECOND) - -/* - * The maximum number of missing packets we tollerate. These are packets with a - * sequence number bigger than the last seen packet. - */ -#define RTP_MAX_DROPOUT 3000 -/* - * The maximum number of misordered packets we tollerate. These are packets with - * a sequence number smaller than the last seen packet. - */ -#define RTP_MAX_MISORDER 100 - -/** - * RTPSessionStats: - * - * Stats kept for a session and used to produce RTCP packet timeouts. - */ -typedef struct { - gdouble bandwidth; - gdouble sender_fraction; - gdouble receiver_fraction; - gdouble rtcp_bandwidth; - gdouble min_interval; - GstClockTime bye_timeout; - guint sender_sources; - guint active_sources; - guint avg_rtcp_packet_size; - guint bye_members; -} RTPSessionStats; - -void rtp_stats_init_defaults (RTPSessionStats *stats); - -GstClockTime rtp_stats_calculate_rtcp_interval (RTPSessionStats *stats, gboolean sender, gboolean first); -GstClockTime rtp_stats_add_rtcp_jitter (RTPSessionStats *stats, GstClockTime interval); -GstClockTime rtp_stats_calculate_bye_interval (RTPSessionStats *stats); - -#endif /* __RTP_STATS_H__ */ @@ -1 +1 @@ -af az bg ca cs da de en_GB es fi fr hu id it ja ky lt mt nb nl or pl pt_BR ru sk sq sr sv tr uk vi zh_CN +af az bg ca cs da de en_GB es fi fr hu id it ja ky lt lv mt nb nl or pl pt_BR ru sk sq sr sv tr uk vi zh_CN @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: gst-plugins 0.7.6\n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n" -"POT-Creation-Date: 2009-06-17 21:54+0100\n" +"POT-Creation-Date: 2009-08-11 17:42+0100\n" "PO-Revision-Date: 2004-03-18 14:16+0200\n" "Last-Translator: Petri Jooste <rkwjpj@puk.ac.za>\n" "Language-Team: Afrikaans <i18n@af.org.za>\n" @@ -72,208 +72,327 @@ msgid "" "Open Sound System is not supported by this element." msgstr "" -msgid "Fast" +msgid "Volume" +msgstr "Volume" + +msgid "Master" msgstr "" -msgid "Low" +msgid "Front" msgstr "" -msgid "Medium" +#, fuzzy +msgid "Rear" +msgstr "Neem op" + +msgid "Headphones" msgstr "" -msgid "High" +msgid "Center" msgstr "" -msgid "Very high" +msgid "LFE" msgstr "" -msgid "Production" +msgid "Surround" msgstr "" -msgid "Off" +#, fuzzy +msgid "Side" +msgstr "Video" + +#, fuzzy +msgid "Built-in Speaker" +msgstr "Luidspreker" + +msgid "AUX 1 Out" msgstr "" -msgid "On" +msgid "AUX 2 Out" msgstr "" -msgid "Stereo" +msgid "AUX Out" msgstr "" -msgid "Surround sound" +msgid "Bass" +msgstr "Bas" + +msgid "Treble" +msgstr "Treble" + +msgid "3D Depth" msgstr "" -msgid "Input mix" +msgid "3D Center" msgstr "" -msgid "Front" +msgid "3D Enhance" +msgstr "" + +msgid "Telephone" +msgstr "" + +msgid "Microphone" +msgstr "Mikrofoon" + +msgid "Line Out" msgstr "" #, fuzzy -msgid "Rear" -msgstr "Neem op" +msgid "Line In" +msgstr "Lyn-in" + +msgid "Internal CD" +msgstr "" #, fuzzy -msgid "Side" +msgid "Video In" msgstr "Video" -msgid "Center / LFE" +msgid "AUX 1 In" msgstr "" -msgid "Microphone" +msgid "AUX 2 In" +msgstr "" + +msgid "AUX In" +msgstr "" + +msgid "PCM" +msgstr "PCM" + +#, fuzzy +msgid "Record Gain" +msgstr "Neem op" + +#, fuzzy +msgid "Output Gain" +msgstr "Uit-versterking" + +#, fuzzy +msgid "Microphone Boost" msgstr "Mikrofoon" -msgid "Front panel microphone" +msgid "Loopback" +msgstr "" + +msgid "Diagnostic" +msgstr "" + +msgid "Bass Boost" +msgstr "" + +msgid "Playback Ports" msgstr "" msgid "Input" msgstr "" -msgid "Line-in" -msgstr "Lyn-in" +#, fuzzy +msgid "Record Source" +msgstr "Neem op" #, fuzzy -msgid "PCM 1" -msgstr "PCM" +msgid "Monitor Source" +msgstr "Monitor" + +msgid "Keyboard Beep" +msgstr "" + +msgid "Monitor" +msgstr "Monitor" + +msgid "Simulate Stereo" +msgstr "" + +msgid "Stereo" +msgstr "" + +msgid "Surround Sound" +msgstr "" #, fuzzy -msgid "PCM 2" -msgstr "PCM-2" +msgid "Microphone Gain" +msgstr "Mikrofoon" #, fuzzy -msgid "PCM 3" -msgstr "PCM" +msgid "Speaker Source" +msgstr "Luidspreker" #, fuzzy -msgid "PCM 4" -msgstr "PCM" +msgid "Microphone Source" +msgstr "Mikrofoon" -msgid "Green connector" +msgid "Jack" msgstr "" -msgid "Green front panel connector" +msgid "Center / LFE" msgstr "" -msgid "Pink connector" +msgid "Stereo Mix" msgstr "" -msgid "Pink front panel connector" +msgid "Mono Mix" msgstr "" -msgid "Blue connector" +msgid "Input Mix" msgstr "" -msgid "Blue front panel connector" +msgid "SPDIF In" msgstr "" -msgid "Orange connector" +msgid "SPDIF Out" msgstr "" -msgid "Orange front panel connector" +#, fuzzy +msgid "Microphone 1" +msgstr "Mikrofoon" + +#, fuzzy +msgid "Microphone 2" +msgstr "Mikrofoon" + +#, fuzzy +msgid "Digital Out" +msgstr "Digitaal-1" + +#, fuzzy +msgid "Digital In" +msgstr "Digitaal-1" + +msgid "HDMI" msgstr "" -msgid "Black connector" +msgid "Modem" msgstr "" -msgid "Black front panel connector" +msgid "Handset" msgstr "" -msgid "Gray connector" +msgid "Other" msgstr "" -msgid "Gray front panel connector" +msgid "None" msgstr "" -msgid "White connector" +msgid "On" msgstr "" -msgid "White front panel connector" +msgid "Off" msgstr "" -msgid "Red connector" +msgid "Mute" msgstr "" -msgid "Red front panel connector" +msgid "Fast" msgstr "" -msgid "Yellow connector" +msgid "Very Low" msgstr "" -msgid "Yellow front panel connector" +msgid "Low" msgstr "" -msgid "Green connector function" +msgid "Medium" msgstr "" -msgid "Green front panel connector function" +msgid "High" msgstr "" -msgid "Pink connector function" +msgid "Very High" msgstr "" -msgid "Pink front panel connector function" +msgid "Production" msgstr "" -msgid "Blue connector function" +#, fuzzy +msgid "Front Panel Microphone" +msgstr "Mikrofoon" + +msgid "Front Panel Line In" msgstr "" -msgid "Blue front panel connector function" +msgid "Front Panel Headphones" msgstr "" -msgid "Orange connector function" +msgid "Front Panel Line Out" msgstr "" -msgid "Orange front panel connector function" +msgid "Green Connector" msgstr "" -msgid "Black connector function" +msgid "Pink Connector" msgstr "" -msgid "Black front panel connector function" +msgid "Blue Connector" msgstr "" -msgid "Gray connector function" +msgid "White Connector" msgstr "" -msgid "Gray front panel connector function" +msgid "Black Connector" msgstr "" -msgid "White connector function" +msgid "Gray Connector" msgstr "" -msgid "White front panel connector function" +msgid "Orange Connector" msgstr "" -msgid "Red connector function" +msgid "Red Connector" msgstr "" -msgid "Red front panel connector function" +msgid "Yellow Connector" msgstr "" -msgid "Yellow connector function" +msgid "Green Front Panel Connector" msgstr "" -msgid "Yellow front panel connector function" +msgid "Pink Front Panel Connector" msgstr "" -msgid "Front panel line-in" +msgid "Blue Front Panel Connector" msgstr "" -msgid "Headphones" +msgid "White Front Panel Connector" msgstr "" -msgid "Front panel headphones" +msgid "Black Front Panel Connector" msgstr "" -msgid "PCM" -msgstr "PCM" +msgid "Gray Front Panel Connector" +msgstr "" + +msgid "Orange Front Panel Connector" +msgstr "" + +msgid "Red Front Panel Connector" +msgstr "" + +msgid "Yellow Front Panel Connector" +msgstr "" + +msgid "Spread Output" +msgstr "" + +msgid "Downmix" +msgstr "" -msgid "Virtual mixer input" +msgid "Virtual Mixer Input" msgstr "" -msgid "Virtual mixer output" +msgid "Virtual Mixer Output" msgstr "" -msgid "Virtual mixer channel configuration" +msgid "Virtual Mixer Channels" +msgstr "" + +#, c-format +msgid "%s Function" +msgstr "" + +#, c-format +msgid "%s %d" msgstr "" msgid "" @@ -355,33 +474,21 @@ msgstr "" #~ msgid "Could not open device \"%s\" for reading." #~ msgstr "Kon nie toestel \"%s\" oopmaak vir lees nie." -#~ msgid "Volume" -#~ msgstr "Volume" - -#~ msgid "Bass" -#~ msgstr "Bas" - -#~ msgid "Treble" -#~ msgstr "Treble" - #~ msgid "Synth" #~ msgstr "Sintetiseerder" -#~ msgid "Speaker" -#~ msgstr "Luidspreker" - #~ msgid "CD" #~ msgstr "CD" #~ msgid "Mixer" #~ msgstr "Menger" +#~ msgid "PCM-2" +#~ msgstr "PCM-2" + #~ msgid "In-gain" #~ msgstr "In-versterking" -#~ msgid "Out-gain" -#~ msgstr "Uit-versterking" - #~ msgid "Line-1" #~ msgstr "Lyn-1" @@ -391,9 +498,6 @@ msgstr "" #~ msgid "Line-3" #~ msgstr "Lyn-3" -#~ msgid "Digital-1" -#~ msgstr "Digitaal-1" - #~ msgid "Digital-2" #~ msgstr "Digitaal-2" @@ -409,13 +513,6 @@ msgstr "" #~ msgid "Radio" #~ msgstr "Radio" -#~ msgid "Monitor" -#~ msgstr "Monitor" - -#, fuzzy -#~ msgid "PC Speaker" -#~ msgstr "Luidspreker" - #~ msgid "Could not open CD device for reading." #~ msgstr "Kon nie CD-toestel oopmaak om te lees nie." @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: gst-plugins-0.8.0\n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n" -"POT-Creation-Date: 2009-06-17 21:54+0100\n" +"POT-Creation-Date: 2009-08-11 17:42+0100\n" "PO-Revision-Date: 2004-03-19 18:29+0200\n" "Last-Translator: Metin Amiroff <metin@karegen.com>\n" "Language-Team: Azerbaijani <translation-team-az@lists.sourceforge.net>\n" @@ -73,208 +73,327 @@ msgid "" "Open Sound System is not supported by this element." msgstr "" -msgid "Fast" +msgid "Volume" +msgstr "SÉ™s" + +msgid "Master" msgstr "" -msgid "Low" +msgid "Front" msgstr "" -msgid "Medium" +#, fuzzy +msgid "Rear" +msgstr "Qeyd" + +msgid "Headphones" msgstr "" -msgid "High" +msgid "Center" msgstr "" -msgid "Very high" +msgid "LFE" msgstr "" -msgid "Production" +msgid "Surround" msgstr "" -msgid "Off" +#, fuzzy +msgid "Side" +msgstr "Video" + +#, fuzzy +msgid "Built-in Speaker" +msgstr "Spiker" + +msgid "AUX 1 Out" msgstr "" -msgid "On" +msgid "AUX 2 Out" msgstr "" -msgid "Stereo" +msgid "AUX Out" msgstr "" -msgid "Surround sound" +msgid "Bass" +msgstr "Bas" + +msgid "Treble" +msgstr "Ä°ncÉ™" + +msgid "3D Depth" msgstr "" -msgid "Input mix" +msgid "3D Center" msgstr "" -msgid "Front" +msgid "3D Enhance" +msgstr "" + +msgid "Telephone" +msgstr "" + +msgid "Microphone" +msgstr "Mikrofon" + +msgid "Line Out" msgstr "" #, fuzzy -msgid "Rear" -msgstr "Qeyd" +msgid "Line In" +msgstr "XÉ™td-giriÅŸ" + +msgid "Internal CD" +msgstr "" #, fuzzy -msgid "Side" +msgid "Video In" msgstr "Video" -msgid "Center / LFE" +msgid "AUX 1 In" msgstr "" -msgid "Microphone" +msgid "AUX 2 In" +msgstr "" + +msgid "AUX In" +msgstr "" + +msgid "PCM" +msgstr "PCM" + +#, fuzzy +msgid "Record Gain" +msgstr "Qeyd" + +#, fuzzy +msgid "Output Gain" +msgstr "Çıxış-gain" + +#, fuzzy +msgid "Microphone Boost" msgstr "Mikrofon" -msgid "Front panel microphone" +msgid "Loopback" +msgstr "" + +msgid "Diagnostic" +msgstr "" + +msgid "Bass Boost" +msgstr "" + +msgid "Playback Ports" msgstr "" msgid "Input" msgstr "" -msgid "Line-in" -msgstr "XÉ™td-giriÅŸ" +#, fuzzy +msgid "Record Source" +msgstr "Qeyd" #, fuzzy -msgid "PCM 1" -msgstr "PCM" +msgid "Monitor Source" +msgstr "Monitor" + +msgid "Keyboard Beep" +msgstr "" + +msgid "Monitor" +msgstr "Monitor" + +msgid "Simulate Stereo" +msgstr "" + +msgid "Stereo" +msgstr "" + +msgid "Surround Sound" +msgstr "" #, fuzzy -msgid "PCM 2" -msgstr "PCM-2" +msgid "Microphone Gain" +msgstr "Mikrofon" #, fuzzy -msgid "PCM 3" -msgstr "PCM" +msgid "Speaker Source" +msgstr "Spiker" #, fuzzy -msgid "PCM 4" -msgstr "PCM" +msgid "Microphone Source" +msgstr "Mikrofon" -msgid "Green connector" +msgid "Jack" msgstr "" -msgid "Green front panel connector" +msgid "Center / LFE" msgstr "" -msgid "Pink connector" +msgid "Stereo Mix" msgstr "" -msgid "Pink front panel connector" +msgid "Mono Mix" msgstr "" -msgid "Blue connector" +msgid "Input Mix" msgstr "" -msgid "Blue front panel connector" +msgid "SPDIF In" msgstr "" -msgid "Orange connector" +msgid "SPDIF Out" msgstr "" -msgid "Orange front panel connector" +#, fuzzy +msgid "Microphone 1" +msgstr "Mikrofon" + +#, fuzzy +msgid "Microphone 2" +msgstr "Mikrofon" + +#, fuzzy +msgid "Digital Out" +msgstr "Dijital-1" + +#, fuzzy +msgid "Digital In" +msgstr "Dijital-1" + +msgid "HDMI" msgstr "" -msgid "Black connector" +msgid "Modem" msgstr "" -msgid "Black front panel connector" +msgid "Handset" msgstr "" -msgid "Gray connector" +msgid "Other" msgstr "" -msgid "Gray front panel connector" +msgid "None" msgstr "" -msgid "White connector" +msgid "On" msgstr "" -msgid "White front panel connector" +msgid "Off" msgstr "" -msgid "Red connector" +msgid "Mute" msgstr "" -msgid "Red front panel connector" +msgid "Fast" msgstr "" -msgid "Yellow connector" +msgid "Very Low" msgstr "" -msgid "Yellow front panel connector" +msgid "Low" msgstr "" -msgid "Green connector function" +msgid "Medium" msgstr "" -msgid "Green front panel connector function" +msgid "High" msgstr "" -msgid "Pink connector function" +msgid "Very High" msgstr "" -msgid "Pink front panel connector function" +msgid "Production" msgstr "" -msgid "Blue connector function" +#, fuzzy +msgid "Front Panel Microphone" +msgstr "Mikrofon" + +msgid "Front Panel Line In" msgstr "" -msgid "Blue front panel connector function" +msgid "Front Panel Headphones" msgstr "" -msgid "Orange connector function" +msgid "Front Panel Line Out" msgstr "" -msgid "Orange front panel connector function" +msgid "Green Connector" msgstr "" -msgid "Black connector function" +msgid "Pink Connector" msgstr "" -msgid "Black front panel connector function" +msgid "Blue Connector" msgstr "" -msgid "Gray connector function" +msgid "White Connector" msgstr "" -msgid "Gray front panel connector function" +msgid "Black Connector" msgstr "" -msgid "White connector function" +msgid "Gray Connector" msgstr "" -msgid "White front panel connector function" +msgid "Orange Connector" msgstr "" -msgid "Red connector function" +msgid "Red Connector" msgstr "" -msgid "Red front panel connector function" +msgid "Yellow Connector" msgstr "" -msgid "Yellow connector function" +msgid "Green Front Panel Connector" msgstr "" -msgid "Yellow front panel connector function" +msgid "Pink Front Panel Connector" msgstr "" -msgid "Front panel line-in" +msgid "Blue Front Panel Connector" msgstr "" -msgid "Headphones" +msgid "White Front Panel Connector" msgstr "" -msgid "Front panel headphones" +msgid "Black Front Panel Connector" msgstr "" -msgid "PCM" -msgstr "PCM" +msgid "Gray Front Panel Connector" +msgstr "" + +msgid "Orange Front Panel Connector" +msgstr "" + +msgid "Red Front Panel Connector" +msgstr "" + +msgid "Yellow Front Panel Connector" +msgstr "" + +msgid "Spread Output" +msgstr "" + +msgid "Downmix" +msgstr "" -msgid "Virtual mixer input" +msgid "Virtual Mixer Input" msgstr "" -msgid "Virtual mixer output" +msgid "Virtual Mixer Output" msgstr "" -msgid "Virtual mixer channel configuration" +msgid "Virtual Mixer Channels" +msgstr "" + +#, c-format +msgid "%s Function" +msgstr "" + +#, c-format +msgid "%s %d" msgstr "" msgid "" @@ -356,33 +475,21 @@ msgstr "" #~ msgid "Could not open device \"%s\" for reading." #~ msgstr "\"%s\" avadanlığı oxuma üçün açıla bilmÉ™di." -#~ msgid "Volume" -#~ msgstr "SÉ™s" - -#~ msgid "Bass" -#~ msgstr "Bas" - -#~ msgid "Treble" -#~ msgstr "Ä°ncÉ™" - #~ msgid "Synth" #~ msgstr "Sint" -#~ msgid "Speaker" -#~ msgstr "Spiker" - #~ msgid "CD" #~ msgstr "CD" #~ msgid "Mixer" #~ msgstr "Mikser" +#~ msgid "PCM-2" +#~ msgstr "PCM-2" + #~ msgid "In-gain" #~ msgstr "GiriÅŸ-gain" -#~ msgid "Out-gain" -#~ msgstr "Çıxış-gain" - #~ msgid "Line-1" #~ msgstr "XÉ™td-1" @@ -392,9 +499,6 @@ msgstr "" #~ msgid "Line-3" #~ msgstr "XÉ™td-3" -#~ msgid "Digital-1" -#~ msgstr "Dijital-1" - #~ msgid "Digital-2" #~ msgstr "Dijital-2" @@ -410,13 +514,6 @@ msgstr "" #~ msgid "Radio" #~ msgstr "Radio" -#~ msgid "Monitor" -#~ msgstr "Monitor" - -#, fuzzy -#~ msgid "PC Speaker" -#~ msgstr "Spiker" - #~ msgid "Could not open CD device for reading." #~ msgstr "CD avadanlığı oxuma üçün açıla bilmÉ™di." @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: gst-plugins-bad 0.10.12.3\n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n" -"POT-Creation-Date: 2009-06-17 21:54+0100\n" +"POT-Creation-Date: 2009-08-11 17:42+0100\n" "PO-Revision-Date: 2009-06-15 07:48+0300\n" "Last-Translator: Alexander Shopov <ash@contact.bg>\n" "Language-Team: Bulgarian <dict@fsa-bg.org>\n" @@ -73,203 +73,349 @@ msgstr "" "Ðудио уÑтройÑтвото не може да бъде отворено за управление на ÑмеÑването. " "Тази верÑÐ¸Ñ Ð½Ð° Open Sound System не Ñе поддържа от този елемент." -msgid "Fast" +msgid "Volume" +msgstr "" + +#, fuzzy +msgid "Master" msgstr "Бързо" -msgid "Low" -msgstr "ÐиÑки" +msgid "Front" +msgstr "Отпред" -msgid "Medium" -msgstr "Средни" +msgid "Rear" +msgstr "Отзад" -msgid "High" -msgstr "ВиÑоки" +msgid "Headphones" +msgstr "Слушалки" -msgid "Very high" -msgstr "Много виÑоки" +#, fuzzy +msgid "Center" +msgstr "Център/баÑи" -msgid "Production" -msgstr "ПроизводÑтво" +msgid "LFE" +msgstr "" -msgid "Off" -msgstr "Изключено" +#, fuzzy +msgid "Surround" +msgstr "Стерео и Ñъраунд" -msgid "On" -msgstr "Включено" +msgid "Side" +msgstr "ОтÑтрани" + +msgid "Built-in Speaker" +msgstr "" + +msgid "AUX 1 Out" +msgstr "" + +msgid "AUX 2 Out" +msgstr "" + +msgid "AUX Out" +msgstr "" + +msgid "Bass" +msgstr "" + +msgid "Treble" +msgstr "" + +msgid "3D Depth" +msgstr "" + +msgid "3D Center" +msgstr "" + +msgid "3D Enhance" +msgstr "" + +#, fuzzy +msgid "Telephone" +msgstr "Слушалки" + +msgid "Microphone" +msgstr "Микрофон" + +msgid "Line Out" +msgstr "" + +#, fuzzy +msgid "Line In" +msgstr "ВходÑщ канал" + +msgid "Internal CD" +msgstr "" + +msgid "Video In" +msgstr "" + +msgid "AUX 1 In" +msgstr "" + +msgid "AUX 2 In" +msgstr "" + +msgid "AUX In" +msgstr "" + +msgid "PCM" +msgstr "PCM" + +msgid "Record Gain" +msgstr "" + +msgid "Output Gain" +msgstr "" + +#, fuzzy +msgid "Microphone Boost" +msgstr "Микрофон" + +msgid "Loopback" +msgstr "" + +msgid "Diagnostic" +msgstr "" + +msgid "Bass Boost" +msgstr "" + +msgid "Playback Ports" +msgstr "" + +msgid "Input" +msgstr "Вход" + +msgid "Record Source" +msgstr "" + +msgid "Monitor Source" +msgstr "" + +msgid "Keyboard Beep" +msgstr "" + +msgid "Monitor" +msgstr "" + +msgid "Simulate Stereo" +msgstr "" msgid "Stereo" msgstr "Стерео" -msgid "Surround sound" +#, fuzzy +msgid "Surround Sound" msgstr "Стерео и Ñъраунд" -msgid "Input mix" -msgstr "ВходÑщ ÑмеÑител" +#, fuzzy +msgid "Microphone Gain" +msgstr "Микрофон" -msgid "Front" -msgstr "Отпред" +msgid "Speaker Source" +msgstr "" -msgid "Rear" -msgstr "Отзад" +#, fuzzy +msgid "Microphone Source" +msgstr "Микрофон" -msgid "Side" -msgstr "ОтÑтрани" +msgid "Jack" +msgstr "" msgid "Center / LFE" msgstr "Център/баÑи" -msgid "Microphone" -msgstr "Микрофон" +#, fuzzy +msgid "Stereo Mix" +msgstr "Стерео" -msgid "Front panel microphone" -msgstr "Микрофон на Ð¿Ñ€ÐµÐ´Ð½Ð¸Ñ Ð¿Ð°Ð½ÐµÐ»" +msgid "Mono Mix" +msgstr "" -msgid "Input" -msgstr "Вход" +#, fuzzy +msgid "Input Mix" +msgstr "ВходÑщ ÑмеÑител" -msgid "Line-in" -msgstr "ВходÑщ канал" +msgid "SPDIF In" +msgstr "" -msgid "PCM 1" -msgstr "PCM 1" +msgid "SPDIF Out" +msgstr "" -msgid "PCM 2" -msgstr "PCM 2" +#, fuzzy +msgid "Microphone 1" +msgstr "Микрофон" -msgid "PCM 3" -msgstr "PCM 3" +#, fuzzy +msgid "Microphone 2" +msgstr "Микрофон" -msgid "PCM 4" -msgstr "PCM 4" +msgid "Digital Out" +msgstr "" -msgid "Green connector" -msgstr "Зелено гнездо" +msgid "Digital In" +msgstr "" -msgid "Green front panel connector" -msgstr "Зелено гнездо на Ð¿Ñ€ÐµÐ´Ð½Ð¸Ñ Ð¿Ð°Ð½ÐµÐ»" +msgid "HDMI" +msgstr "" -msgid "Pink connector" -msgstr "Розово гнездо" +msgid "Modem" +msgstr "" -msgid "Pink front panel connector" -msgstr "Розово гнездо на Ð¿Ñ€ÐµÐ´Ð½Ð¸Ñ Ð¿Ð°Ð½ÐµÐ»" +msgid "Handset" +msgstr "" -msgid "Blue connector" -msgstr "Синьо гнездо" +msgid "Other" +msgstr "" -msgid "Blue front panel connector" -msgstr "Синьо гнездо на Ð¿Ñ€ÐµÐ´Ð½Ð¸Ñ Ð¿Ð°Ð½ÐµÐ»" +msgid "None" +msgstr "" -msgid "Orange connector" -msgstr "Оранжево гнездо" +msgid "On" +msgstr "Включено" -msgid "Orange front panel connector" -msgstr "Оранжево гнездо на предни панел" +msgid "Off" +msgstr "Изключено" -msgid "Black connector" -msgstr "Черно гнездо" +msgid "Mute" +msgstr "" -msgid "Black front panel connector" -msgstr "Черно гнездо на Ð¿Ñ€ÐµÐ´Ð½Ð¸Ñ Ð¿Ð°Ð½ÐµÐ»" +msgid "Fast" +msgstr "Бързо" -msgid "Gray connector" -msgstr "Сиво гнездо" +msgid "Very Low" +msgstr "" -msgid "Gray front panel connector" -msgstr "Сиво гнездо на Ð¿Ñ€ÐµÐ´Ð½Ð¸Ñ Ð¿Ð°Ð½ÐµÐ»" +msgid "Low" +msgstr "ÐиÑки" -msgid "White connector" -msgstr "БÑло гнездо" +msgid "Medium" +msgstr "Средни" -msgid "White front panel connector" -msgstr "БÑло гнездо на Ð¿Ñ€ÐµÐ´Ð½Ð¸Ñ Ð¿Ð°Ð½ÐµÐ»" +msgid "High" +msgstr "ВиÑоки" -msgid "Red connector" -msgstr "Червено гнездо" +#, fuzzy +msgid "Very High" +msgstr "Много виÑоки" -msgid "Red front panel connector" -msgstr "Червено гнездо на Ð¿Ñ€ÐµÐ´Ð½Ð¸Ñ Ð¿Ð°Ð½ÐµÐ»" +msgid "Production" +msgstr "ПроизводÑтво" -msgid "Yellow connector" -msgstr "Жълто гнездо" +#, fuzzy +msgid "Front Panel Microphone" +msgstr "Микрофон на Ð¿Ñ€ÐµÐ´Ð½Ð¸Ñ Ð¿Ð°Ð½ÐµÐ»" -msgid "Yellow front panel connector" -msgstr "Жълто гнездо на Ð¿Ñ€ÐµÐ´Ð½Ð¸Ñ Ð¿Ð°Ð½ÐµÐ»" +#, fuzzy +msgid "Front Panel Line In" +msgstr "ВходÑщ канал на Ð¿Ñ€ÐµÐ´Ð½Ð¸Ñ Ð¿Ð°Ð½ÐµÐ»" -msgid "Green connector function" -msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ð½Ð° зеленото гнездо" +#, fuzzy +msgid "Front Panel Headphones" +msgstr "Слушалки на Ð¿Ñ€ÐµÐ´Ð½Ð¸Ñ Ð¿Ð°Ð½ÐµÐ»" -msgid "Green front panel connector function" -msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ð½Ð° зеленото гнездо на Ð¿Ñ€ÐµÐ´Ð½Ð¸Ñ Ð¿Ð°Ð½ÐµÐ»" +#, fuzzy +msgid "Front Panel Line Out" +msgstr "ВходÑщ канал на Ð¿Ñ€ÐµÐ´Ð½Ð¸Ñ Ð¿Ð°Ð½ÐµÐ»" -msgid "Pink connector function" -msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ð½Ð° розовото гнездо" +#, fuzzy +msgid "Green Connector" +msgstr "Зелено гнездо" -msgid "Pink front panel connector function" -msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ð½Ð° розовото гнездо на Ð¿Ñ€ÐµÐ´Ð½Ð¸Ñ Ð¿Ð°Ð½ÐµÐ»" +#, fuzzy +msgid "Pink Connector" +msgstr "Розово гнездо" -msgid "Blue connector function" -msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ð½Ð° Ñиньото гнездо" +#, fuzzy +msgid "Blue Connector" +msgstr "Синьо гнездо" -msgid "Blue front panel connector function" -msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ð½Ð° Ñиньото гнездо на Ð¿Ñ€ÐµÐ´Ð½Ð¸Ñ Ð¿Ð°Ð½ÐµÐ»" +#, fuzzy +msgid "White Connector" +msgstr "БÑло гнездо" -msgid "Orange connector function" -msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ð½Ð° оранжевото гнездо" +#, fuzzy +msgid "Black Connector" +msgstr "Черно гнездо" -msgid "Orange front panel connector function" -msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ð½Ð° оранжевото гнездо на Ð¿Ñ€ÐµÐ´Ð½Ð¸Ñ Ð¿Ð°Ð½ÐµÐ»" +#, fuzzy +msgid "Gray Connector" +msgstr "Сиво гнездо" -msgid "Black connector function" -msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ð½Ð° черното гнездо" +#, fuzzy +msgid "Orange Connector" +msgstr "Оранжево гнездо" -msgid "Black front panel connector function" -msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ð½Ð° черното гнездо на Ð¿Ñ€ÐµÐ´Ð½Ð¸Ñ Ð¿Ð°Ð½ÐµÐ»" +#, fuzzy +msgid "Red Connector" +msgstr "Червено гнездо" -msgid "Gray connector function" -msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ð½Ð° Ñивото гнездо" +#, fuzzy +msgid "Yellow Connector" +msgstr "Жълто гнездо" -msgid "Gray front panel connector function" -msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ð½Ð° Ñивото гнездо на Ð¿Ñ€ÐµÐ´Ð½Ð¸Ñ Ð¿Ð°Ð½ÐµÐ»" +#, fuzzy +msgid "Green Front Panel Connector" +msgstr "Зелено гнездо на Ð¿Ñ€ÐµÐ´Ð½Ð¸Ñ Ð¿Ð°Ð½ÐµÐ»" -msgid "White connector function" -msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ð½Ð° бÑлото гнездо" +#, fuzzy +msgid "Pink Front Panel Connector" +msgstr "Розово гнездо на Ð¿Ñ€ÐµÐ´Ð½Ð¸Ñ Ð¿Ð°Ð½ÐµÐ»" -msgid "White front panel connector function" -msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ð½Ð° бÑлото гнездо на Ð¿Ñ€ÐµÐ´Ð½Ð¸Ñ Ð¿Ð°Ð½ÐµÐ»" +#, fuzzy +msgid "Blue Front Panel Connector" +msgstr "Синьо гнездо на Ð¿Ñ€ÐµÐ´Ð½Ð¸Ñ Ð¿Ð°Ð½ÐµÐ»" -msgid "Red connector function" -msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ð½Ð° червеното гнездо" +#, fuzzy +msgid "White Front Panel Connector" +msgstr "БÑло гнездо на Ð¿Ñ€ÐµÐ´Ð½Ð¸Ñ Ð¿Ð°Ð½ÐµÐ»" -msgid "Red front panel connector function" -msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ð½Ð° червеното гнездо на Ð¿Ñ€ÐµÐ´Ð½Ð¸Ñ Ð¿Ð°Ð½ÐµÐ»" +#, fuzzy +msgid "Black Front Panel Connector" +msgstr "Черно гнездо на Ð¿Ñ€ÐµÐ´Ð½Ð¸Ñ Ð¿Ð°Ð½ÐµÐ»" -msgid "Yellow connector function" -msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ð½Ð° жълтото гнездо" +#, fuzzy +msgid "Gray Front Panel Connector" +msgstr "Сиво гнездо на Ð¿Ñ€ÐµÐ´Ð½Ð¸Ñ Ð¿Ð°Ð½ÐµÐ»" -msgid "Yellow front panel connector function" -msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ð½Ð° жълтото гнездо на Ð¿Ñ€ÐµÐ´Ð½Ð¸Ñ Ð¿Ð°Ð½ÐµÐ»" +#, fuzzy +msgid "Orange Front Panel Connector" +msgstr "Оранжево гнездо на предни панел" -msgid "Front panel line-in" -msgstr "ВходÑщ канал на Ð¿Ñ€ÐµÐ´Ð½Ð¸Ñ Ð¿Ð°Ð½ÐµÐ»" +#, fuzzy +msgid "Red Front Panel Connector" +msgstr "Червено гнездо на Ð¿Ñ€ÐµÐ´Ð½Ð¸Ñ Ð¿Ð°Ð½ÐµÐ»" -msgid "Headphones" -msgstr "Слушалки" +#, fuzzy +msgid "Yellow Front Panel Connector" +msgstr "Жълто гнездо на Ð¿Ñ€ÐµÐ´Ð½Ð¸Ñ Ð¿Ð°Ð½ÐµÐ»" -msgid "Front panel headphones" -msgstr "Слушалки на Ð¿Ñ€ÐµÐ´Ð½Ð¸Ñ Ð¿Ð°Ð½ÐµÐ»" +msgid "Spread Output" +msgstr "" -msgid "PCM" -msgstr "PCM" +msgid "Downmix" +msgstr "" -msgid "Virtual mixer input" +#, fuzzy +msgid "Virtual Mixer Input" msgstr "Вход на виртуален ÑмеÑител" -msgid "Virtual mixer output" +#, fuzzy +msgid "Virtual Mixer Output" msgstr "Изход на виртуален ÑмеÑител" -msgid "Virtual mixer channel configuration" -msgstr "ÐаÑтройки на каналите на виртуален ÑмеÑител" +#, fuzzy +msgid "Virtual Mixer Channels" +msgstr "Вход на виртуален ÑмеÑител" + +#, c-format +msgid "%s Function" +msgstr "" + +#, c-format +msgid "%s %d" +msgstr "" msgid "" "Could not open audio device for playback. Device is being used by another " @@ -306,3 +452,72 @@ msgstr "Това аудио уÑтройÑтво не поддържа Ð·Ð°Ð¿Ð¸Ñ msgid "Error recording from audio device." msgstr "Грешка при запиÑа от аудио уÑтройÑтвото." + +#~ msgid "PCM 1" +#~ msgstr "PCM 1" + +#~ msgid "PCM 2" +#~ msgstr "PCM 2" + +#~ msgid "PCM 3" +#~ msgstr "PCM 3" + +#~ msgid "PCM 4" +#~ msgstr "PCM 4" + +#~ msgid "Green connector function" +#~ msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ð½Ð° зеленото гнездо" + +#~ msgid "Green front panel connector function" +#~ msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ð½Ð° зеленото гнездо на Ð¿Ñ€ÐµÐ´Ð½Ð¸Ñ Ð¿Ð°Ð½ÐµÐ»" + +#~ msgid "Pink connector function" +#~ msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ð½Ð° розовото гнездо" + +#~ msgid "Pink front panel connector function" +#~ msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ð½Ð° розовото гнездо на Ð¿Ñ€ÐµÐ´Ð½Ð¸Ñ Ð¿Ð°Ð½ÐµÐ»" + +#~ msgid "Blue connector function" +#~ msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ð½Ð° Ñиньото гнездо" + +#~ msgid "Blue front panel connector function" +#~ msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ð½Ð° Ñиньото гнездо на Ð¿Ñ€ÐµÐ´Ð½Ð¸Ñ Ð¿Ð°Ð½ÐµÐ»" + +#~ msgid "Orange connector function" +#~ msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ð½Ð° оранжевото гнездо" + +#~ msgid "Orange front panel connector function" +#~ msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ð½Ð° оранжевото гнездо на Ð¿Ñ€ÐµÐ´Ð½Ð¸Ñ Ð¿Ð°Ð½ÐµÐ»" + +#~ msgid "Black connector function" +#~ msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ð½Ð° черното гнездо" + +#~ msgid "Black front panel connector function" +#~ msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ð½Ð° черното гнездо на Ð¿Ñ€ÐµÐ´Ð½Ð¸Ñ Ð¿Ð°Ð½ÐµÐ»" + +#~ msgid "Gray connector function" +#~ msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ð½Ð° Ñивото гнездо" + +#~ msgid "Gray front panel connector function" +#~ msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ð½Ð° Ñивото гнездо на Ð¿Ñ€ÐµÐ´Ð½Ð¸Ñ Ð¿Ð°Ð½ÐµÐ»" + +#~ msgid "White connector function" +#~ msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ð½Ð° бÑлото гнездо" + +#~ msgid "White front panel connector function" +#~ msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ð½Ð° бÑлото гнездо на Ð¿Ñ€ÐµÐ´Ð½Ð¸Ñ Ð¿Ð°Ð½ÐµÐ»" + +#~ msgid "Red connector function" +#~ msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ð½Ð° червеното гнездо" + +#~ msgid "Red front panel connector function" +#~ msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ð½Ð° червеното гнездо на Ð¿Ñ€ÐµÐ´Ð½Ð¸Ñ Ð¿Ð°Ð½ÐµÐ»" + +#~ msgid "Yellow connector function" +#~ msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ð½Ð° жълтото гнездо" + +#~ msgid "Yellow front panel connector function" +#~ msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ð½Ð° жълтото гнездо на Ð¿Ñ€ÐµÐ´Ð½Ð¸Ñ Ð¿Ð°Ð½ÐµÐ»" + +#~ msgid "Virtual mixer channel configuration" +#~ msgstr "ÐаÑтройки на каналите на виртуален ÑмеÑител" @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: gst-plugins 0.8.3\n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n" -"POT-Creation-Date: 2009-06-17 21:54+0100\n" +"POT-Creation-Date: 2009-08-11 17:42+0100\n" "PO-Revision-Date: 2004-08-05 15:48+0200\n" "Last-Translator: Jordi Mallach <jordi@sindominio.net>\n" "Language-Team: Catalan <ca@dodds.net>\n" @@ -73,208 +73,324 @@ msgid "" "Open Sound System is not supported by this element." msgstr "No s'ha pogut el dispositiu d'à udio «%s» per a l'escriptura." -msgid "Fast" +msgid "Volume" +msgstr "Volum" + +msgid "Master" msgstr "" -msgid "Low" +msgid "Front" msgstr "" -msgid "Medium" +#, fuzzy +msgid "Rear" +msgstr "Enregistrament" + +msgid "Headphones" msgstr "" -msgid "High" +msgid "Center" msgstr "" -msgid "Very high" +msgid "LFE" msgstr "" -msgid "Production" +msgid "Surround" msgstr "" -msgid "Off" +#, fuzzy +msgid "Side" +msgstr "VÃdeo" + +#, fuzzy +msgid "Built-in Speaker" +msgstr "Altaveu" + +msgid "AUX 1 Out" msgstr "" -msgid "On" +msgid "AUX 2 Out" msgstr "" -msgid "Stereo" +msgid "AUX Out" msgstr "" -msgid "Surround sound" +msgid "Bass" +msgstr "Baixos" + +msgid "Treble" +msgstr "Aguts" + +msgid "3D Depth" msgstr "" -msgid "Input mix" +msgid "3D Center" msgstr "" -msgid "Front" +msgid "3D Enhance" msgstr "" -#, fuzzy -msgid "Rear" -msgstr "Enregistrament" +msgid "Telephone" +msgstr "" + +msgid "Microphone" +msgstr "Micròfon" + +msgid "Line Out" +msgstr "" #, fuzzy -msgid "Side" -msgstr "VÃdeo" +msgid "Line In" +msgstr "LÃnia-entrada" -msgid "Center / LFE" +msgid "Internal CD" msgstr "" -msgid "Microphone" +msgid "Video In" +msgstr "" + +msgid "AUX 1 In" +msgstr "" + +msgid "AUX 2 In" +msgstr "" + +msgid "AUX In" +msgstr "" + +msgid "PCM" +msgstr "PCM" + +msgid "Record Gain" +msgstr "" + +#, fuzzy +msgid "Output Gain" +msgstr "Ganà ncia-sortida" + +#, fuzzy +msgid "Microphone Boost" msgstr "Micròfon" -msgid "Front panel microphone" +msgid "Loopback" +msgstr "" + +msgid "Diagnostic" +msgstr "" + +msgid "Bass Boost" +msgstr "" + +msgid "Playback Ports" msgstr "" msgid "Input" msgstr "" -msgid "Line-in" -msgstr "LÃnia-entrada" +msgid "Record Source" +msgstr "" #, fuzzy -msgid "PCM 1" -msgstr "PCM" +msgid "Monitor Source" +msgstr "Monitor" + +msgid "Keyboard Beep" +msgstr "" + +msgid "Monitor" +msgstr "Monitor" + +msgid "Simulate Stereo" +msgstr "" + +msgid "Stereo" +msgstr "" + +msgid "Surround Sound" +msgstr "" #, fuzzy -msgid "PCM 2" -msgstr "PCM-2" +msgid "Microphone Gain" +msgstr "Micròfon" #, fuzzy -msgid "PCM 3" -msgstr "PCM" +msgid "Speaker Source" +msgstr "Altaveu" #, fuzzy -msgid "PCM 4" -msgstr "PCM" +msgid "Microphone Source" +msgstr "Micròfon" -msgid "Green connector" +msgid "Jack" msgstr "" -msgid "Green front panel connector" +msgid "Center / LFE" msgstr "" -msgid "Pink connector" +msgid "Stereo Mix" msgstr "" -msgid "Pink front panel connector" +msgid "Mono Mix" msgstr "" -msgid "Blue connector" +msgid "Input Mix" msgstr "" -msgid "Blue front panel connector" +msgid "SPDIF In" msgstr "" -msgid "Orange connector" +msgid "SPDIF Out" msgstr "" -msgid "Orange front panel connector" +#, fuzzy +msgid "Microphone 1" +msgstr "Micròfon" + +#, fuzzy +msgid "Microphone 2" +msgstr "Micròfon" + +#, fuzzy +msgid "Digital Out" +msgstr "Digital-1" + +#, fuzzy +msgid "Digital In" +msgstr "Digital-1" + +msgid "HDMI" msgstr "" -msgid "Black connector" +msgid "Modem" msgstr "" -msgid "Black front panel connector" +msgid "Handset" msgstr "" -msgid "Gray connector" +msgid "Other" msgstr "" -msgid "Gray front panel connector" +msgid "None" msgstr "" -msgid "White connector" +msgid "On" msgstr "" -msgid "White front panel connector" +msgid "Off" msgstr "" -msgid "Red connector" +msgid "Mute" msgstr "" -msgid "Red front panel connector" +msgid "Fast" msgstr "" -msgid "Yellow connector" +msgid "Very Low" msgstr "" -msgid "Yellow front panel connector" +msgid "Low" msgstr "" -msgid "Green connector function" +msgid "Medium" msgstr "" -msgid "Green front panel connector function" +msgid "High" msgstr "" -msgid "Pink connector function" +msgid "Very High" msgstr "" -msgid "Pink front panel connector function" +msgid "Production" msgstr "" -msgid "Blue connector function" +#, fuzzy +msgid "Front Panel Microphone" +msgstr "Micròfon" + +msgid "Front Panel Line In" msgstr "" -msgid "Blue front panel connector function" +msgid "Front Panel Headphones" msgstr "" -msgid "Orange connector function" +msgid "Front Panel Line Out" msgstr "" -msgid "Orange front panel connector function" +msgid "Green Connector" msgstr "" -msgid "Black connector function" +msgid "Pink Connector" msgstr "" -msgid "Black front panel connector function" +msgid "Blue Connector" msgstr "" -msgid "Gray connector function" +msgid "White Connector" msgstr "" -msgid "Gray front panel connector function" +msgid "Black Connector" msgstr "" -msgid "White connector function" +msgid "Gray Connector" msgstr "" -msgid "White front panel connector function" +msgid "Orange Connector" msgstr "" -msgid "Red connector function" +msgid "Red Connector" msgstr "" -msgid "Red front panel connector function" +msgid "Yellow Connector" msgstr "" -msgid "Yellow connector function" +msgid "Green Front Panel Connector" msgstr "" -msgid "Yellow front panel connector function" +msgid "Pink Front Panel Connector" msgstr "" -msgid "Front panel line-in" +msgid "Blue Front Panel Connector" msgstr "" -msgid "Headphones" +msgid "White Front Panel Connector" msgstr "" -msgid "Front panel headphones" +msgid "Black Front Panel Connector" msgstr "" -msgid "PCM" -msgstr "PCM" +msgid "Gray Front Panel Connector" +msgstr "" -msgid "Virtual mixer input" +msgid "Orange Front Panel Connector" msgstr "" -msgid "Virtual mixer output" +msgid "Red Front Panel Connector" msgstr "" -msgid "Virtual mixer channel configuration" +msgid "Yellow Front Panel Connector" +msgstr "" + +msgid "Spread Output" +msgstr "" + +msgid "Downmix" +msgstr "" + +msgid "Virtual Mixer Input" +msgstr "" + +msgid "Virtual Mixer Output" +msgstr "" + +msgid "Virtual Mixer Channels" +msgstr "" + +#, c-format +msgid "%s Function" +msgstr "" + +#, c-format +msgid "%s %d" msgstr "" msgid "" @@ -309,6 +425,22 @@ msgstr "" msgid "Error recording from audio device." msgstr "" +#, fuzzy +#~ msgid "PCM 1" +#~ msgstr "PCM" + +#, fuzzy +#~ msgid "PCM 2" +#~ msgstr "PCM-2" + +#, fuzzy +#~ msgid "PCM 3" +#~ msgstr "PCM" + +#, fuzzy +#~ msgid "PCM 4" +#~ msgstr "PCM" + #~ msgid "Error closing file \"%s\"." #~ msgstr "S'ha produït un error en tancar el fitxer «%s»." @@ -385,21 +517,9 @@ msgstr "" #~ msgid "Your OSS device could not be probed correctly" #~ msgstr "No s'ha pogut detectar el vostre dispositiu d'OSS correctament" -#~ msgid "Volume" -#~ msgstr "Volum" - -#~ msgid "Bass" -#~ msgstr "Baixos" - -#~ msgid "Treble" -#~ msgstr "Aguts" - #~ msgid "Synth" #~ msgstr "Sintetitzador" -#~ msgid "Speaker" -#~ msgstr "Altaveu" - #~ msgid "CD" #~ msgstr "CD" @@ -409,9 +529,6 @@ msgstr "" #~ msgid "In-gain" #~ msgstr "Ganà ncia-entrada" -#~ msgid "Out-gain" -#~ msgstr "Ganà ncia-sortida" - #~ msgid "Line-1" #~ msgstr "LÃnia-1" @@ -421,9 +538,6 @@ msgstr "" #~ msgid "Line-3" #~ msgstr "LÃnia-3" -#~ msgid "Digital-1" -#~ msgstr "Digital-1" - #~ msgid "Digital-2" #~ msgstr "Digital-2" @@ -439,9 +553,6 @@ msgstr "" #~ msgid "Radio" #~ msgstr "Rà dio" -#~ msgid "Monitor" -#~ msgstr "Monitor" - #~ msgid "No device specified." #~ msgstr "No s'ha especificat cap dispositiu." @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: gst-plugins-bad 0.10.9.3\n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n" -"POT-Creation-Date: 2009-06-17 21:54+0100\n" +"POT-Creation-Date: 2009-08-11 17:42+0100\n" "PO-Revision-Date: 2009-01-18 18:55+0100\n" "Last-Translator: Petr Kovar <pknbe@volny.cz>\n" "Language-Team: Czech <translation-team-cs@lists.sourceforge.net>\n" @@ -75,203 +75,349 @@ msgstr "" "NezdaÅ™ilo se otevÅ™enà zvukového zaÅ™Ãzenà k obsluze ovládánà směšovaÄe. Tato " "verze Open Sound System nenà pÅ™ÃsluÅ¡ným prvkem podporována." -msgid "Fast" +msgid "Volume" +msgstr "" + +#, fuzzy +msgid "Master" msgstr "Rychlé" -msgid "Low" -msgstr "NÃzké" +msgid "Front" +msgstr "PÅ™ednÃ" -msgid "Medium" -msgstr "StÅ™ednÃ" +msgid "Rear" +msgstr "ZadnÃ" -msgid "High" -msgstr "Vysoké" +msgid "Headphones" +msgstr "Sluchátka" -msgid "Very high" -msgstr "Velmi vysoké" +#, fuzzy +msgid "Center" +msgstr "StÅ™edový / LFE" -msgid "Production" -msgstr "Výroba" +msgid "LFE" +msgstr "" -msgid "Off" -msgstr "Vypnuto" +#, fuzzy +msgid "Surround" +msgstr "Prostorový zvuk" -msgid "On" -msgstr "Zapnuto" +msgid "Side" +msgstr "BoÄnÃ" + +msgid "Built-in Speaker" +msgstr "" + +msgid "AUX 1 Out" +msgstr "" + +msgid "AUX 2 Out" +msgstr "" + +msgid "AUX Out" +msgstr "" + +msgid "Bass" +msgstr "" + +msgid "Treble" +msgstr "" + +msgid "3D Depth" +msgstr "" + +msgid "3D Center" +msgstr "" + +msgid "3D Enhance" +msgstr "" + +#, fuzzy +msgid "Telephone" +msgstr "Sluchátka" + +msgid "Microphone" +msgstr "Mikrofon" + +msgid "Line Out" +msgstr "" + +#, fuzzy +msgid "Line In" +msgstr "Linkový vstup" + +msgid "Internal CD" +msgstr "" + +msgid "Video In" +msgstr "" + +msgid "AUX 1 In" +msgstr "" + +msgid "AUX 2 In" +msgstr "" + +msgid "AUX In" +msgstr "" + +msgid "PCM" +msgstr "PCM" + +msgid "Record Gain" +msgstr "" + +msgid "Output Gain" +msgstr "" + +#, fuzzy +msgid "Microphone Boost" +msgstr "Mikrofon" + +msgid "Loopback" +msgstr "" + +msgid "Diagnostic" +msgstr "" + +msgid "Bass Boost" +msgstr "" + +msgid "Playback Ports" +msgstr "" + +msgid "Input" +msgstr "Vstup" + +msgid "Record Source" +msgstr "" + +msgid "Monitor Source" +msgstr "" + +msgid "Keyboard Beep" +msgstr "" + +msgid "Monitor" +msgstr "" + +msgid "Simulate Stereo" +msgstr "" msgid "Stereo" msgstr "Stereo" -msgid "Surround sound" +#, fuzzy +msgid "Surround Sound" msgstr "Prostorový zvuk" -msgid "Input mix" -msgstr "SměšovaÄ vstupu" +#, fuzzy +msgid "Microphone Gain" +msgstr "Mikrofon" -msgid "Front" -msgstr "PÅ™ednÃ" +msgid "Speaker Source" +msgstr "" -msgid "Rear" -msgstr "ZadnÃ" +#, fuzzy +msgid "Microphone Source" +msgstr "Mikrofon" -msgid "Side" -msgstr "BoÄnÃ" +msgid "Jack" +msgstr "" msgid "Center / LFE" msgstr "StÅ™edový / LFE" -msgid "Microphone" -msgstr "Mikrofon" +#, fuzzy +msgid "Stereo Mix" +msgstr "Stereo" -msgid "Front panel microphone" -msgstr "Mikrofon na pÅ™ednÃm panelu" +msgid "Mono Mix" +msgstr "" -msgid "Input" -msgstr "Vstup" +#, fuzzy +msgid "Input Mix" +msgstr "SměšovaÄ vstupu" -msgid "Line-in" -msgstr "Linkový vstup" +msgid "SPDIF In" +msgstr "" -msgid "PCM 1" -msgstr "PCM 1" +msgid "SPDIF Out" +msgstr "" -msgid "PCM 2" -msgstr "PCM 2" +#, fuzzy +msgid "Microphone 1" +msgstr "Mikrofon" -msgid "PCM 3" -msgstr "PCM 3" +#, fuzzy +msgid "Microphone 2" +msgstr "Mikrofon" -msgid "PCM 4" -msgstr "PCM 4" +msgid "Digital Out" +msgstr "" -msgid "Green connector" -msgstr "Zelený konektor" +msgid "Digital In" +msgstr "" -msgid "Green front panel connector" -msgstr "Zelený konektor na pÅ™ednÃm panelu" +msgid "HDMI" +msgstr "" -msgid "Pink connector" -msgstr "Růžový konektor" +msgid "Modem" +msgstr "" -msgid "Pink front panel connector" -msgstr "Růžový konektor na pÅ™ednÃm panelu" +msgid "Handset" +msgstr "" -msgid "Blue connector" -msgstr "Modrý konektor" +msgid "Other" +msgstr "" -msgid "Blue front panel connector" -msgstr "Modrý konektor na pÅ™ednÃm panelu" +msgid "None" +msgstr "" -msgid "Orange connector" -msgstr "Oranžový konektor" +msgid "On" +msgstr "Zapnuto" -msgid "Orange front panel connector" -msgstr "Oranžový konektor na pÅ™ednÃm panelu" +msgid "Off" +msgstr "Vypnuto" -msgid "Black connector" -msgstr "ÄŒerný konektor" +msgid "Mute" +msgstr "" -msgid "Black front panel connector" -msgstr "ÄŒerný konektor na pÅ™ednÃm panelu" +msgid "Fast" +msgstr "Rychlé" -msgid "Gray connector" -msgstr "Å edý konektor" +msgid "Very Low" +msgstr "" -msgid "Gray front panel connector" -msgstr "Å edý konektor na pÅ™ednÃm panelu" +msgid "Low" +msgstr "NÃzké" -msgid "White connector" -msgstr "BÃlý konektor" +msgid "Medium" +msgstr "StÅ™ednÃ" -msgid "White front panel connector" -msgstr "BÃlý konektor na pÅ™ednÃm panelu" +msgid "High" +msgstr "Vysoké" -msgid "Red connector" -msgstr "ÄŒervený konektor" +#, fuzzy +msgid "Very High" +msgstr "Velmi vysoké" -msgid "Red front panel connector" -msgstr "ÄŒervený konektor na pÅ™ednÃm panelu" +msgid "Production" +msgstr "Výroba" -msgid "Yellow connector" -msgstr "Žlutý konektor" +#, fuzzy +msgid "Front Panel Microphone" +msgstr "Mikrofon na pÅ™ednÃm panelu" -msgid "Yellow front panel connector" -msgstr "Žlutý konektor na pÅ™ednÃm panelu" +#, fuzzy +msgid "Front Panel Line In" +msgstr "Linkový vstup na pÅ™ednÃm panelu" -msgid "Green connector function" -msgstr "Funkce zeleného konektoru" +#, fuzzy +msgid "Front Panel Headphones" +msgstr "Sluchátka na pÅ™ednÃm panelu" -msgid "Green front panel connector function" -msgstr "Funkce zeleného konektoru na pÅ™ednÃm panelu" +#, fuzzy +msgid "Front Panel Line Out" +msgstr "Linkový vstup na pÅ™ednÃm panelu" -msgid "Pink connector function" -msgstr "Funkce růžového konektoru" +#, fuzzy +msgid "Green Connector" +msgstr "Zelený konektor" -msgid "Pink front panel connector function" -msgstr "Funkce růžového konektoru na pÅ™ednÃm panelu" +#, fuzzy +msgid "Pink Connector" +msgstr "Růžový konektor" -msgid "Blue connector function" -msgstr "Funkce modrého konektoru" +#, fuzzy +msgid "Blue Connector" +msgstr "Modrý konektor" -msgid "Blue front panel connector function" -msgstr "Funkce modrého konektoru na pÅ™ednÃm panelu" +#, fuzzy +msgid "White Connector" +msgstr "BÃlý konektor" -msgid "Orange connector function" -msgstr "Funkce oranžového konektoru" +#, fuzzy +msgid "Black Connector" +msgstr "ÄŒerný konektor" -msgid "Orange front panel connector function" -msgstr "Funkce oranžového konektoru na pÅ™ednÃm panelu" +#, fuzzy +msgid "Gray Connector" +msgstr "Å edý konektor" -msgid "Black connector function" -msgstr "Funkce Äerného konektoru" +#, fuzzy +msgid "Orange Connector" +msgstr "Oranžový konektor" -msgid "Black front panel connector function" -msgstr "Funkce Äerného konektoru na pÅ™ednÃm panelu" +#, fuzzy +msgid "Red Connector" +msgstr "ÄŒervený konektor" -msgid "Gray connector function" -msgstr "Funkce Å¡edého konektoru" +#, fuzzy +msgid "Yellow Connector" +msgstr "Žlutý konektor" -msgid "Gray front panel connector function" -msgstr "Funkce Å¡edého konektoru na pÅ™ednÃm panelu" +#, fuzzy +msgid "Green Front Panel Connector" +msgstr "Zelený konektor na pÅ™ednÃm panelu" -msgid "White connector function" -msgstr "Funkce bÃlého konektoru" +#, fuzzy +msgid "Pink Front Panel Connector" +msgstr "Růžový konektor na pÅ™ednÃm panelu" -msgid "White front panel connector function" -msgstr "Funkce bÃlého konektoru na pÅ™ednÃm panelu" +#, fuzzy +msgid "Blue Front Panel Connector" +msgstr "Modrý konektor na pÅ™ednÃm panelu" -msgid "Red connector function" -msgstr "Funkce Äerveného konektoru" +#, fuzzy +msgid "White Front Panel Connector" +msgstr "BÃlý konektor na pÅ™ednÃm panelu" -msgid "Red front panel connector function" -msgstr "Funkce Äerveného konektoru na pÅ™ednÃm panelu" +#, fuzzy +msgid "Black Front Panel Connector" +msgstr "ÄŒerný konektor na pÅ™ednÃm panelu" -msgid "Yellow connector function" -msgstr "Funkce žlutého konektoru" +#, fuzzy +msgid "Gray Front Panel Connector" +msgstr "Å edý konektor na pÅ™ednÃm panelu" -msgid "Yellow front panel connector function" -msgstr "Funkce žlutého konektoru na pÅ™ednÃm panelu" +#, fuzzy +msgid "Orange Front Panel Connector" +msgstr "Oranžový konektor na pÅ™ednÃm panelu" -msgid "Front panel line-in" -msgstr "Linkový vstup na pÅ™ednÃm panelu" +#, fuzzy +msgid "Red Front Panel Connector" +msgstr "ÄŒervený konektor na pÅ™ednÃm panelu" -msgid "Headphones" -msgstr "Sluchátka" +#, fuzzy +msgid "Yellow Front Panel Connector" +msgstr "Žlutý konektor na pÅ™ednÃm panelu" -msgid "Front panel headphones" -msgstr "Sluchátka na pÅ™ednÃm panelu" +msgid "Spread Output" +msgstr "" -msgid "PCM" -msgstr "PCM" +msgid "Downmix" +msgstr "" -msgid "Virtual mixer input" +#, fuzzy +msgid "Virtual Mixer Input" msgstr "Vstup virtuálnÃho směšovaÄe" -msgid "Virtual mixer output" +#, fuzzy +msgid "Virtual Mixer Output" msgstr "Výstup virtuálnÃho směšovaÄe" -msgid "Virtual mixer channel configuration" -msgstr "Konfigurace kanálu virtuálnÃho směšovaÄe" +#, fuzzy +msgid "Virtual Mixer Channels" +msgstr "Vstup virtuálnÃho směšovaÄe" + +#, c-format +msgid "%s Function" +msgstr "" + +#, c-format +msgid "%s %d" +msgstr "" msgid "" "Could not open audio device for playback. Device is being used by another " @@ -320,3 +466,72 @@ msgstr "Chyba pÅ™i nahrávánà ze zvukového zaÅ™ÃzenÃ." #~ msgstr "" #~ "Požadovaná pÅ™enosová rychlost %d kbit/s vlastnosti \"%s\" nenà dovolena. " #~ "PÅ™enosová rychlost byla zmÄ›nÄ›na na %d kbit/s." + +#~ msgid "PCM 1" +#~ msgstr "PCM 1" + +#~ msgid "PCM 2" +#~ msgstr "PCM 2" + +#~ msgid "PCM 3" +#~ msgstr "PCM 3" + +#~ msgid "PCM 4" +#~ msgstr "PCM 4" + +#~ msgid "Green connector function" +#~ msgstr "Funkce zeleného konektoru" + +#~ msgid "Green front panel connector function" +#~ msgstr "Funkce zeleného konektoru na pÅ™ednÃm panelu" + +#~ msgid "Pink connector function" +#~ msgstr "Funkce růžového konektoru" + +#~ msgid "Pink front panel connector function" +#~ msgstr "Funkce růžového konektoru na pÅ™ednÃm panelu" + +#~ msgid "Blue connector function" +#~ msgstr "Funkce modrého konektoru" + +#~ msgid "Blue front panel connector function" +#~ msgstr "Funkce modrého konektoru na pÅ™ednÃm panelu" + +#~ msgid "Orange connector function" +#~ msgstr "Funkce oranžového konektoru" + +#~ msgid "Orange front panel connector function" +#~ msgstr "Funkce oranžového konektoru na pÅ™ednÃm panelu" + +#~ msgid "Black connector function" +#~ msgstr "Funkce Äerného konektoru" + +#~ msgid "Black front panel connector function" +#~ msgstr "Funkce Äerného konektoru na pÅ™ednÃm panelu" + +#~ msgid "Gray connector function" +#~ msgstr "Funkce Å¡edého konektoru" + +#~ msgid "Gray front panel connector function" +#~ msgstr "Funkce Å¡edého konektoru na pÅ™ednÃm panelu" + +#~ msgid "White connector function" +#~ msgstr "Funkce bÃlého konektoru" + +#~ msgid "White front panel connector function" +#~ msgstr "Funkce bÃlého konektoru na pÅ™ednÃm panelu" + +#~ msgid "Red connector function" +#~ msgstr "Funkce Äerveného konektoru" + +#~ msgid "Red front panel connector function" +#~ msgstr "Funkce Äerveného konektoru na pÅ™ednÃm panelu" + +#~ msgid "Yellow connector function" +#~ msgstr "Funkce žlutého konektoru" + +#~ msgid "Yellow front panel connector function" +#~ msgstr "Funkce žlutého konektoru na pÅ™ednÃm panelu" + +#~ msgid "Virtual mixer channel configuration" +#~ msgstr "Konfigurace kanálu virtuálnÃho směšovaÄe" @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: gst-plugins-bad-0.10.10.2\n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n" -"POT-Creation-Date: 2009-06-17 21:54+0100\n" +"POT-Creation-Date: 2009-08-11 17:42+0100\n" "PO-Revision-Date: 2009-04-13 11:28+0200\n" "Last-Translator: Joe Hansen <joedalton2@yahoo.dk>\n" "Language-Team: Danish <dansk@dansk-gruppen.dk>\n" @@ -72,205 +72,351 @@ msgstr "" "Kunne ikke Ã¥bne lydenhed til mikserpulthÃ¥ndtering. Denne version af Open " "Sound System er ikke understøttet af dette element." -msgid "Fast" +msgid "Volume" +msgstr "" + +#, fuzzy +msgid "Master" msgstr "Hurtig" -msgid "Low" -msgstr "Lav" +msgid "Front" +msgstr "Front" -msgid "Medium" -msgstr "Medium" +# bagende eller eller "Bag" hvis det er den bagerste lydkanal +# vi snakker om +msgid "Rear" +msgstr "Bag" -msgid "High" -msgstr "Højt" +msgid "Headphones" +msgstr "Høretelefoner" -msgid "Very high" -msgstr "Meget højt" +#, fuzzy +msgid "Center" +msgstr "Center / LFE" -msgid "Production" -msgstr "Produktion" +msgid "LFE" +msgstr "" -msgid "Off" -msgstr "Slukket" +#, fuzzy +msgid "Surround" +msgstr "Surround-lyd" -msgid "On" -msgstr "Tændt" +msgid "Side" +msgstr "Side" + +msgid "Built-in Speaker" +msgstr "" + +msgid "AUX 1 Out" +msgstr "" + +msgid "AUX 2 Out" +msgstr "" + +msgid "AUX Out" +msgstr "" + +msgid "Bass" +msgstr "" + +msgid "Treble" +msgstr "" + +msgid "3D Depth" +msgstr "" + +msgid "3D Center" +msgstr "" + +msgid "3D Enhance" +msgstr "" + +#, fuzzy +msgid "Telephone" +msgstr "Høretelefoner" + +msgid "Microphone" +msgstr "Mikrofon" + +msgid "Line Out" +msgstr "" + +#, fuzzy +msgid "Line In" +msgstr "Linje-ind" + +msgid "Internal CD" +msgstr "" + +msgid "Video In" +msgstr "" + +msgid "AUX 1 In" +msgstr "" + +msgid "AUX 2 In" +msgstr "" + +msgid "AUX In" +msgstr "" + +msgid "PCM" +msgstr "PCM" + +msgid "Record Gain" +msgstr "" + +msgid "Output Gain" +msgstr "" + +#, fuzzy +msgid "Microphone Boost" +msgstr "Mikrofon" + +msgid "Loopback" +msgstr "" + +msgid "Diagnostic" +msgstr "" + +msgid "Bass Boost" +msgstr "" + +msgid "Playback Ports" +msgstr "" + +msgid "Input" +msgstr "Inddata" + +msgid "Record Source" +msgstr "" + +msgid "Monitor Source" +msgstr "" + +msgid "Keyboard Beep" +msgstr "" + +msgid "Monitor" +msgstr "" + +msgid "Simulate Stereo" +msgstr "" msgid "Stereo" msgstr "Stereo" -msgid "Surround sound" +#, fuzzy +msgid "Surround Sound" msgstr "Surround-lyd" -msgid "Input mix" -msgstr "Inddata mix" +#, fuzzy +msgid "Microphone Gain" +msgstr "Mikrofon" -msgid "Front" -msgstr "Front" +msgid "Speaker Source" +msgstr "" -# bagende eller eller "Bag" hvis det er den bagerste lydkanal -# vi snakker om -msgid "Rear" -msgstr "Bag" +#, fuzzy +msgid "Microphone Source" +msgstr "Mikrofon" -msgid "Side" -msgstr "Side" +msgid "Jack" +msgstr "" msgid "Center / LFE" msgstr "Center / LFE" -msgid "Microphone" -msgstr "Mikrofon" +#, fuzzy +msgid "Stereo Mix" +msgstr "Stereo" -msgid "Front panel microphone" -msgstr "Frontpanelmikrofon" +msgid "Mono Mix" +msgstr "" -msgid "Input" -msgstr "Inddata" +#, fuzzy +msgid "Input Mix" +msgstr "Inddata mix" -msgid "Line-in" -msgstr "Linje-ind" +msgid "SPDIF In" +msgstr "" -msgid "PCM 1" -msgstr "PCM 1" +msgid "SPDIF Out" +msgstr "" -msgid "PCM 2" -msgstr "PCM 2" +#, fuzzy +msgid "Microphone 1" +msgstr "Mikrofon" -msgid "PCM 3" -msgstr "PCM 3" +#, fuzzy +msgid "Microphone 2" +msgstr "Mikrofon" -msgid "PCM 4" -msgstr "PCM 4" +msgid "Digital Out" +msgstr "" -msgid "Green connector" -msgstr "Grøn forbindelse" +msgid "Digital In" +msgstr "" -msgid "Green front panel connector" -msgstr "Grøn frontpanelforbindelse" +msgid "HDMI" +msgstr "" -msgid "Pink connector" -msgstr "Lyserød forbindelse" +msgid "Modem" +msgstr "" -msgid "Pink front panel connector" -msgstr "Lyserød frontpanelforbindelse" +msgid "Handset" +msgstr "" -msgid "Blue connector" -msgstr "BlÃ¥ forbindelse" +msgid "Other" +msgstr "" -msgid "Blue front panel connector" -msgstr "BlÃ¥ frontpanelforbindelse" +msgid "None" +msgstr "" -msgid "Orange connector" -msgstr "Orange forbindelse" +msgid "On" +msgstr "Tændt" -msgid "Orange front panel connector" -msgstr "Orange frontpanelforbindelse" +msgid "Off" +msgstr "Slukket" -msgid "Black connector" -msgstr "Sort forbindelse" +msgid "Mute" +msgstr "" -msgid "Black front panel connector" -msgstr "Sort frontpanelforbindelse" +msgid "Fast" +msgstr "Hurtig" -msgid "Gray connector" -msgstr "GrÃ¥ forbindelse" +msgid "Very Low" +msgstr "" -msgid "Gray front panel connector" -msgstr "GrÃ¥ frontpanelforbindelse" +msgid "Low" +msgstr "Lav" -msgid "White connector" -msgstr "Hvid forbindelse" +msgid "Medium" +msgstr "Medium" -msgid "White front panel connector" -msgstr "Hvid frontpanelforbindelse" +msgid "High" +msgstr "Højt" -msgid "Red connector" -msgstr "Rød forbindelse" +#, fuzzy +msgid "Very High" +msgstr "Meget højt" -msgid "Red front panel connector" -msgstr "Rød frontpanelforbindelse" +msgid "Production" +msgstr "Produktion" -msgid "Yellow connector" -msgstr "Gul forbindelse" +#, fuzzy +msgid "Front Panel Microphone" +msgstr "Frontpanelmikrofon" -msgid "Yellow front panel connector" -msgstr "Gul frontpanelforbindelse" +#, fuzzy +msgid "Front Panel Line In" +msgstr "Frontpanel linje-ind" -msgid "Green connector function" -msgstr "Grøn forbindelsesfunktion" +#, fuzzy +msgid "Front Panel Headphones" +msgstr "Frontpanel høretelefoner" -msgid "Green front panel connector function" -msgstr "Grøn frontpanelforbindelsesfunktion" +#, fuzzy +msgid "Front Panel Line Out" +msgstr "Frontpanel linje-ind" -msgid "Pink connector function" -msgstr "Lyserød forbindelsesfunktion" +#, fuzzy +msgid "Green Connector" +msgstr "Grøn forbindelse" -msgid "Pink front panel connector function" -msgstr "Lyserød frontpanelforbindelsesfunktion" +#, fuzzy +msgid "Pink Connector" +msgstr "Lyserød forbindelse" -msgid "Blue connector function" -msgstr "BlÃ¥ forbindelsesfunktion" +#, fuzzy +msgid "Blue Connector" +msgstr "BlÃ¥ forbindelse" -msgid "Blue front panel connector function" -msgstr "BlÃ¥ frontpanelforbindelsesfunktion" +#, fuzzy +msgid "White Connector" +msgstr "Hvid forbindelse" -msgid "Orange connector function" -msgstr "Orange forbindelsesfunktion" +#, fuzzy +msgid "Black Connector" +msgstr "Sort forbindelse" -msgid "Orange front panel connector function" -msgstr "Orange frontpanelforbindelsesfunktion" +#, fuzzy +msgid "Gray Connector" +msgstr "GrÃ¥ forbindelse" -msgid "Black connector function" -msgstr "Sort forbindelsesfunktion" +#, fuzzy +msgid "Orange Connector" +msgstr "Orange forbindelse" -msgid "Black front panel connector function" -msgstr "Sort frontpanelforbindelsesfunktion" +#, fuzzy +msgid "Red Connector" +msgstr "Rød forbindelse" -msgid "Gray connector function" -msgstr "GrÃ¥ forbindelsesfunktion" +#, fuzzy +msgid "Yellow Connector" +msgstr "Gul forbindelse" -msgid "Gray front panel connector function" -msgstr "GrÃ¥ frontpanelforbindelsesfunktion" +#, fuzzy +msgid "Green Front Panel Connector" +msgstr "Grøn frontpanelforbindelse" -msgid "White connector function" -msgstr "Hvid forbindelsesfunktion" +#, fuzzy +msgid "Pink Front Panel Connector" +msgstr "Lyserød frontpanelforbindelse" -msgid "White front panel connector function" -msgstr "Hvid frontpanelforbindelsesfunktion" +#, fuzzy +msgid "Blue Front Panel Connector" +msgstr "BlÃ¥ frontpanelforbindelse" -msgid "Red connector function" -msgstr "Rød forbindelsesfunktion" +#, fuzzy +msgid "White Front Panel Connector" +msgstr "Hvid frontpanelforbindelse" -msgid "Red front panel connector function" -msgstr "Rød frontpanelforbindelsesfunktion" +#, fuzzy +msgid "Black Front Panel Connector" +msgstr "Sort frontpanelforbindelse" -msgid "Yellow connector function" -msgstr "Gul forbindelsesfunktion" +#, fuzzy +msgid "Gray Front Panel Connector" +msgstr "GrÃ¥ frontpanelforbindelse" -msgid "Yellow front panel connector function" -msgstr "Gul frontpanelforbindelsesfunktion" +#, fuzzy +msgid "Orange Front Panel Connector" +msgstr "Orange frontpanelforbindelse" -msgid "Front panel line-in" -msgstr "Frontpanel linje-ind" +#, fuzzy +msgid "Red Front Panel Connector" +msgstr "Rød frontpanelforbindelse" -msgid "Headphones" -msgstr "Høretelefoner" +#, fuzzy +msgid "Yellow Front Panel Connector" +msgstr "Gul frontpanelforbindelse" -msgid "Front panel headphones" -msgstr "Frontpanel høretelefoner" +msgid "Spread Output" +msgstr "" -msgid "PCM" -msgstr "PCM" +msgid "Downmix" +msgstr "" -msgid "Virtual mixer input" +#, fuzzy +msgid "Virtual Mixer Input" msgstr "Virtuel mikserpultinddata" -msgid "Virtual mixer output" +#, fuzzy +msgid "Virtual Mixer Output" msgstr "Virtuel mikserpultuddata" -msgid "Virtual mixer channel configuration" -msgstr "Virtuel mikserkanalkonfiguration" +#, fuzzy +msgid "Virtual Mixer Channels" +msgstr "Virtuel mikserpultinddata" + +#, c-format +msgid "%s Function" +msgstr "" + +#, c-format +msgid "%s %d" +msgstr "" msgid "" "Could not open audio device for playback. Device is being used by another " @@ -307,6 +453,75 @@ msgstr "Optagelse er ikke understøttet af denne lydenhed." msgid "Error recording from audio device." msgstr "Fejl under optagelse fra lydenhed." +#~ msgid "PCM 1" +#~ msgstr "PCM 1" + +#~ msgid "PCM 2" +#~ msgstr "PCM 2" + +#~ msgid "PCM 3" +#~ msgstr "PCM 3" + +#~ msgid "PCM 4" +#~ msgstr "PCM 4" + +#~ msgid "Green connector function" +#~ msgstr "Grøn forbindelsesfunktion" + +#~ msgid "Green front panel connector function" +#~ msgstr "Grøn frontpanelforbindelsesfunktion" + +#~ msgid "Pink connector function" +#~ msgstr "Lyserød forbindelsesfunktion" + +#~ msgid "Pink front panel connector function" +#~ msgstr "Lyserød frontpanelforbindelsesfunktion" + +#~ msgid "Blue connector function" +#~ msgstr "BlÃ¥ forbindelsesfunktion" + +#~ msgid "Blue front panel connector function" +#~ msgstr "BlÃ¥ frontpanelforbindelsesfunktion" + +#~ msgid "Orange connector function" +#~ msgstr "Orange forbindelsesfunktion" + +#~ msgid "Orange front panel connector function" +#~ msgstr "Orange frontpanelforbindelsesfunktion" + +#~ msgid "Black connector function" +#~ msgstr "Sort forbindelsesfunktion" + +#~ msgid "Black front panel connector function" +#~ msgstr "Sort frontpanelforbindelsesfunktion" + +#~ msgid "Gray connector function" +#~ msgstr "GrÃ¥ forbindelsesfunktion" + +#~ msgid "Gray front panel connector function" +#~ msgstr "GrÃ¥ frontpanelforbindelsesfunktion" + +#~ msgid "White connector function" +#~ msgstr "Hvid forbindelsesfunktion" + +#~ msgid "White front panel connector function" +#~ msgstr "Hvid frontpanelforbindelsesfunktion" + +#~ msgid "Red connector function" +#~ msgstr "Rød forbindelsesfunktion" + +#~ msgid "Red front panel connector function" +#~ msgstr "Rød frontpanelforbindelsesfunktion" + +#~ msgid "Yellow connector function" +#~ msgstr "Gul forbindelsesfunktion" + +#~ msgid "Yellow front panel connector function" +#~ msgstr "Gul frontpanelforbindelsesfunktion" + +#~ msgid "Virtual mixer channel configuration" +#~ msgstr "Virtuel mikserkanalkonfiguration" + #~ msgid "Failed to configure TwoLAME encoder. Check your encoding parameters." #~ msgstr "" #~ "Mislykkedes i at konfigurere TwoLAME-koder. Undersøg dine " @@ -6,11 +6,11 @@ # msgid "" msgstr "" -"Project-Id-Version: gst-plugins-bad 0.10.11.2\n" +"Project-Id-Version: gst-plugins-bad 0.10.12.3\n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n" -"POT-Creation-Date: 2009-06-17 21:54+0100\n" -"PO-Revision-Date: 2009-05-14 21:52+0200\n" -"Last-Translator: Andre Klapper <ak-47@gmx.net>\n" +"POT-Creation-Date: 2009-08-11 17:42+0100\n" +"PO-Revision-Date: 2009-06-24 16:58+0200\n" +"Last-Translator: Christian Kirbach <christian.kirbach@googlemail.com>\n" "Language-Team: German <translation-team-de@lists.sourceforge.net>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -25,7 +25,7 @@ msgid "Failed to open DVD device '%s'." msgstr "Öffnen des DVD-Geräts »%s« schlug fehl." msgid "Failed to set PGC based seeking." -msgstr "" +msgstr "PGC-basiertes Suchen schlug fehl." msgid "Internal clock error." msgstr "Interner Zeitfehler." @@ -73,203 +73,349 @@ msgstr "" "Audio-Gerät konnte nicht zum Regeln geöffnet werden. Diese Version des Open " "Sound System (OSS) wird nicht von diesem Element unterstützt." -msgid "Fast" +msgid "Volume" +msgstr "" + +#, fuzzy +msgid "Master" msgstr "Schnell" -msgid "Low" -msgstr "Tief" +msgid "Front" +msgstr "Vorne" -msgid "Medium" -msgstr "Mittel" +msgid "Rear" +msgstr "Hinten" -msgid "High" -msgstr "Hoch" +msgid "Headphones" +msgstr "Kopfhörer" -msgid "Very high" -msgstr "Sehr hoch" +#, fuzzy +msgid "Center" +msgstr "Mitte / LFE" -msgid "Production" -msgstr "Produktion" +msgid "LFE" +msgstr "" -msgid "Off" -msgstr "Aus" +#, fuzzy +msgid "Surround" +msgstr "Surround-Ton" -msgid "On" -msgstr "Ein" +msgid "Side" +msgstr "Seite" + +msgid "Built-in Speaker" +msgstr "" + +msgid "AUX 1 Out" +msgstr "" + +msgid "AUX 2 Out" +msgstr "" + +msgid "AUX Out" +msgstr "" + +msgid "Bass" +msgstr "" + +msgid "Treble" +msgstr "" + +msgid "3D Depth" +msgstr "" + +msgid "3D Center" +msgstr "" + +msgid "3D Enhance" +msgstr "" + +#, fuzzy +msgid "Telephone" +msgstr "Kopfhörer" + +msgid "Microphone" +msgstr "Mikrofon" + +msgid "Line Out" +msgstr "" + +#, fuzzy +msgid "Line In" +msgstr "Line-in" + +msgid "Internal CD" +msgstr "" + +msgid "Video In" +msgstr "" + +msgid "AUX 1 In" +msgstr "" + +msgid "AUX 2 In" +msgstr "" + +msgid "AUX In" +msgstr "" + +msgid "PCM" +msgstr "PCM" + +msgid "Record Gain" +msgstr "" + +msgid "Output Gain" +msgstr "" + +#, fuzzy +msgid "Microphone Boost" +msgstr "Mikrofon" + +msgid "Loopback" +msgstr "" + +msgid "Diagnostic" +msgstr "" + +msgid "Bass Boost" +msgstr "" + +msgid "Playback Ports" +msgstr "" + +msgid "Input" +msgstr "Aufnahme" + +msgid "Record Source" +msgstr "" + +msgid "Monitor Source" +msgstr "" + +msgid "Keyboard Beep" +msgstr "" + +msgid "Monitor" +msgstr "" + +msgid "Simulate Stereo" +msgstr "" msgid "Stereo" msgstr "Stereo" -msgid "Surround sound" +#, fuzzy +msgid "Surround Sound" msgstr "Surround-Ton" -msgid "Input mix" -msgstr "Aufnahmemixer" +#, fuzzy +msgid "Microphone Gain" +msgstr "Mikrofon" -msgid "Front" -msgstr "Vorne" +msgid "Speaker Source" +msgstr "" -msgid "Rear" -msgstr "Hinten" +#, fuzzy +msgid "Microphone Source" +msgstr "Mikrofon" -msgid "Side" -msgstr "Seite" +msgid "Jack" +msgstr "" msgid "Center / LFE" msgstr "Mitte / LFE" -msgid "Microphone" -msgstr "Mikrofon" +#, fuzzy +msgid "Stereo Mix" +msgstr "Stereo" -msgid "Front panel microphone" -msgstr "Mikrofon am Fronteingang" +msgid "Mono Mix" +msgstr "" -msgid "Input" -msgstr "Aufnahme" +#, fuzzy +msgid "Input Mix" +msgstr "Aufnahmemixer" -msgid "Line-in" -msgstr "Line-in" +msgid "SPDIF In" +msgstr "" -msgid "PCM 1" -msgstr "PCM 1" +msgid "SPDIF Out" +msgstr "" -msgid "PCM 2" -msgstr "PCM 2" +#, fuzzy +msgid "Microphone 1" +msgstr "Mikrofon" -msgid "PCM 3" -msgstr "PCM 3" +#, fuzzy +msgid "Microphone 2" +msgstr "Mikrofon" -msgid "PCM 4" -msgstr "PCM 4" +msgid "Digital Out" +msgstr "" -msgid "Green connector" -msgstr "Grüner Stecker" +msgid "Digital In" +msgstr "" -msgid "Green front panel connector" -msgstr "Grüner Frontstecker" +msgid "HDMI" +msgstr "" -msgid "Pink connector" -msgstr "Rosa Stecker" +msgid "Modem" +msgstr "" -msgid "Pink front panel connector" -msgstr "Rosa Frontstecker" +msgid "Handset" +msgstr "" -msgid "Blue connector" -msgstr "Blauer Stecker" +msgid "Other" +msgstr "" -msgid "Blue front panel connector" -msgstr "Blauer Frontstecker" +msgid "None" +msgstr "" -msgid "Orange connector" -msgstr "Oranger Stecker" +msgid "On" +msgstr "Ein" -msgid "Orange front panel connector" -msgstr "Oranger Frontstecker" +msgid "Off" +msgstr "Aus" -msgid "Black connector" -msgstr "Schwarzer Stecker" +msgid "Mute" +msgstr "" -msgid "Black front panel connector" -msgstr "Schwarzer Frontstecker" +msgid "Fast" +msgstr "Schnell" -msgid "Gray connector" -msgstr "Grauer Stecker" +msgid "Very Low" +msgstr "" -msgid "Gray front panel connector" -msgstr "Grauer Frontstecker" +msgid "Low" +msgstr "Tief" -msgid "White connector" -msgstr "Weißer Stecker" +msgid "Medium" +msgstr "Mittel" -msgid "White front panel connector" -msgstr "Weißer Frontstecker" +msgid "High" +msgstr "Hoch" -msgid "Red connector" -msgstr "Roter Stecker" +#, fuzzy +msgid "Very High" +msgstr "Sehr hoch" -msgid "Red front panel connector" -msgstr "Roter Frontstecker" +msgid "Production" +msgstr "Produktion" -msgid "Yellow connector" -msgstr "Gelber Stecker" +#, fuzzy +msgid "Front Panel Microphone" +msgstr "Mikrofon am Fronteingang" -msgid "Yellow front panel connector" -msgstr "Gelber Frontstecker" +#, fuzzy +msgid "Front Panel Line In" +msgstr "Front-Line-in" -msgid "Green connector function" -msgstr "Funktion des grünen Steckers" +#, fuzzy +msgid "Front Panel Headphones" +msgstr "Front-Kopfhörer" -msgid "Green front panel connector function" -msgstr "Funktion des grünen Frontsteckers" +#, fuzzy +msgid "Front Panel Line Out" +msgstr "Front-Line-in" -msgid "Pink connector function" -msgstr "Funktion des rosa Steckers" +#, fuzzy +msgid "Green Connector" +msgstr "Grüner Stecker" -msgid "Pink front panel connector function" -msgstr "Funktion des rosa Frontsteckers" +#, fuzzy +msgid "Pink Connector" +msgstr "Rosa Stecker" -msgid "Blue connector function" -msgstr "Funktion des blauen Steckers" +#, fuzzy +msgid "Blue Connector" +msgstr "Blauer Stecker" -msgid "Blue front panel connector function" -msgstr "Funktion des blauen Frontsteckers" +#, fuzzy +msgid "White Connector" +msgstr "Weißer Stecker" -msgid "Orange connector function" -msgstr "Funktion des orangen Steckers" +#, fuzzy +msgid "Black Connector" +msgstr "Schwarzer Stecker" -msgid "Orange front panel connector function" -msgstr "Funktion des orangen Frontsteckers" +#, fuzzy +msgid "Gray Connector" +msgstr "Grauer Stecker" -msgid "Black connector function" -msgstr "Funktion des schwarzen Steckers" +#, fuzzy +msgid "Orange Connector" +msgstr "Oranger Stecker" -msgid "Black front panel connector function" -msgstr "Funktion des schwarzen Frontsteckers" +#, fuzzy +msgid "Red Connector" +msgstr "Roter Stecker" -msgid "Gray connector function" -msgstr "Funktion des grauen Steckers" +#, fuzzy +msgid "Yellow Connector" +msgstr "Gelber Stecker" -msgid "Gray front panel connector function" -msgstr "Funktion des grauen Frontsteckers" +#, fuzzy +msgid "Green Front Panel Connector" +msgstr "Grüner Frontstecker" -msgid "White connector function" -msgstr "Funktion des weißen Steckers" +#, fuzzy +msgid "Pink Front Panel Connector" +msgstr "Rosa Frontstecker" -msgid "White front panel connector function" -msgstr "Funktion des weißen Frontsteckers" +#, fuzzy +msgid "Blue Front Panel Connector" +msgstr "Blauer Frontstecker" -msgid "Red connector function" -msgstr "Funktion des roten Steckers" +#, fuzzy +msgid "White Front Panel Connector" +msgstr "Weißer Frontstecker" -msgid "Red front panel connector function" -msgstr "Funktion des roten Frontsteckers" +#, fuzzy +msgid "Black Front Panel Connector" +msgstr "Schwarzer Frontstecker" -msgid "Yellow connector function" -msgstr "Funktion des gelben Steckers" +#, fuzzy +msgid "Gray Front Panel Connector" +msgstr "Grauer Frontstecker" -msgid "Yellow front panel connector function" -msgstr "Funktion des gelben Frontsteckers" +#, fuzzy +msgid "Orange Front Panel Connector" +msgstr "Oranger Frontstecker" -msgid "Front panel line-in" -msgstr "Front-Line-in" +#, fuzzy +msgid "Red Front Panel Connector" +msgstr "Roter Frontstecker" -msgid "Headphones" -msgstr "Kopfhörer" +#, fuzzy +msgid "Yellow Front Panel Connector" +msgstr "Gelber Frontstecker" -msgid "Front panel headphones" -msgstr "Front-Kopfhörer" +msgid "Spread Output" +msgstr "" -msgid "PCM" -msgstr "PCM" +msgid "Downmix" +msgstr "" -msgid "Virtual mixer input" +#, fuzzy +msgid "Virtual Mixer Input" msgstr "Eingang des virtuellen Mischers" -msgid "Virtual mixer output" +#, fuzzy +msgid "Virtual Mixer Output" msgstr "Ausgang des virtuellen Mischers" -msgid "Virtual mixer channel configuration" -msgstr "Konfiguration des virtuellen Mischers" +#, fuzzy +msgid "Virtual Mixer Channels" +msgstr "Eingang des virtuellen Mischers" + +#, c-format +msgid "%s Function" +msgstr "" + +#, c-format +msgid "%s %d" +msgstr "" msgid "" "Could not open audio device for playback. Device is being used by another " @@ -306,3 +452,72 @@ msgstr "Die Aufnahme wird nicht von diesem Audio-Gerät unterstützt." msgid "Error recording from audio device." msgstr "Fehler bei der Aufnahme vom Audio-Gerät." + +#~ msgid "PCM 1" +#~ msgstr "PCM 1" + +#~ msgid "PCM 2" +#~ msgstr "PCM 2" + +#~ msgid "PCM 3" +#~ msgstr "PCM 3" + +#~ msgid "PCM 4" +#~ msgstr "PCM 4" + +#~ msgid "Green connector function" +#~ msgstr "Funktion des grünen Steckers" + +#~ msgid "Green front panel connector function" +#~ msgstr "Funktion des grünen Frontsteckers" + +#~ msgid "Pink connector function" +#~ msgstr "Funktion des rosa Steckers" + +#~ msgid "Pink front panel connector function" +#~ msgstr "Funktion des rosa Frontsteckers" + +#~ msgid "Blue connector function" +#~ msgstr "Funktion des blauen Steckers" + +#~ msgid "Blue front panel connector function" +#~ msgstr "Funktion des blauen Frontsteckers" + +#~ msgid "Orange connector function" +#~ msgstr "Funktion des orangen Steckers" + +#~ msgid "Orange front panel connector function" +#~ msgstr "Funktion des orangen Frontsteckers" + +#~ msgid "Black connector function" +#~ msgstr "Funktion des schwarzen Steckers" + +#~ msgid "Black front panel connector function" +#~ msgstr "Funktion des schwarzen Frontsteckers" + +#~ msgid "Gray connector function" +#~ msgstr "Funktion des grauen Steckers" + +#~ msgid "Gray front panel connector function" +#~ msgstr "Funktion des grauen Frontsteckers" + +#~ msgid "White connector function" +#~ msgstr "Funktion des weißen Steckers" + +#~ msgid "White front panel connector function" +#~ msgstr "Funktion des weißen Frontsteckers" + +#~ msgid "Red connector function" +#~ msgstr "Funktion des roten Steckers" + +#~ msgid "Red front panel connector function" +#~ msgstr "Funktion des roten Frontsteckers" + +#~ msgid "Yellow connector function" +#~ msgstr "Funktion des gelben Steckers" + +#~ msgid "Yellow front panel connector function" +#~ msgstr "Funktion des gelben Frontsteckers" + +#~ msgid "Virtual mixer channel configuration" +#~ msgstr "Konfiguration des virtuellen Mischers" diff --git a/po/en_GB.po b/po/en_GB.po index 75378d9f..16953732 100644 --- a/po/en_GB.po +++ b/po/en_GB.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: gst-plugins 0.8.1\n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n" -"POT-Creation-Date: 2009-06-17 21:54+0100\n" +"POT-Creation-Date: 2009-08-11 17:42+0100\n" "PO-Revision-Date: 2004-04-26 10:41-0400\n" "Last-Translator: Gareth Owen <gowen72@yahoo.com>\n" "Language-Team: English (British) <en_gb@li.org>\n" @@ -71,208 +71,327 @@ msgid "" "Open Sound System is not supported by this element." msgstr "" -msgid "Fast" +msgid "Volume" +msgstr "Volume" + +msgid "Master" msgstr "" -msgid "Low" +msgid "Front" msgstr "" -msgid "Medium" +#, fuzzy +msgid "Rear" +msgstr "Record" + +msgid "Headphones" msgstr "" -msgid "High" +msgid "Center" msgstr "" -msgid "Very high" +msgid "LFE" msgstr "" -msgid "Production" +msgid "Surround" msgstr "" -msgid "Off" +#, fuzzy +msgid "Side" +msgstr "Video" + +#, fuzzy +msgid "Built-in Speaker" +msgstr "Speaker" + +msgid "AUX 1 Out" msgstr "" -msgid "On" +msgid "AUX 2 Out" msgstr "" -msgid "Stereo" +msgid "AUX Out" msgstr "" -msgid "Surround sound" +msgid "Bass" +msgstr "Bass" + +msgid "Treble" +msgstr "Treble" + +msgid "3D Depth" msgstr "" -msgid "Input mix" +msgid "3D Center" msgstr "" -msgid "Front" +msgid "3D Enhance" +msgstr "" + +msgid "Telephone" +msgstr "" + +msgid "Microphone" +msgstr "Microphone" + +msgid "Line Out" msgstr "" #, fuzzy -msgid "Rear" -msgstr "Record" +msgid "Line In" +msgstr "Line-in" + +msgid "Internal CD" +msgstr "" #, fuzzy -msgid "Side" +msgid "Video In" msgstr "Video" -msgid "Center / LFE" +msgid "AUX 1 In" msgstr "" -msgid "Microphone" +msgid "AUX 2 In" +msgstr "" + +msgid "AUX In" +msgstr "" + +msgid "PCM" +msgstr "PCM" + +#, fuzzy +msgid "Record Gain" +msgstr "Record" + +#, fuzzy +msgid "Output Gain" +msgstr "Out-gain" + +#, fuzzy +msgid "Microphone Boost" msgstr "Microphone" -msgid "Front panel microphone" +msgid "Loopback" +msgstr "" + +msgid "Diagnostic" +msgstr "" + +msgid "Bass Boost" +msgstr "" + +msgid "Playback Ports" msgstr "" msgid "Input" msgstr "" -msgid "Line-in" -msgstr "Line-in" +#, fuzzy +msgid "Record Source" +msgstr "Record" #, fuzzy -msgid "PCM 1" -msgstr "PCM" +msgid "Monitor Source" +msgstr "Monitor" + +msgid "Keyboard Beep" +msgstr "" + +msgid "Monitor" +msgstr "Monitor" + +msgid "Simulate Stereo" +msgstr "" + +msgid "Stereo" +msgstr "" + +msgid "Surround Sound" +msgstr "" #, fuzzy -msgid "PCM 2" -msgstr "PCM-2" +msgid "Microphone Gain" +msgstr "Microphone" #, fuzzy -msgid "PCM 3" -msgstr "PCM" +msgid "Speaker Source" +msgstr "Speaker" #, fuzzy -msgid "PCM 4" -msgstr "PCM" +msgid "Microphone Source" +msgstr "Microphone" -msgid "Green connector" +msgid "Jack" msgstr "" -msgid "Green front panel connector" +msgid "Center / LFE" msgstr "" -msgid "Pink connector" +msgid "Stereo Mix" msgstr "" -msgid "Pink front panel connector" +msgid "Mono Mix" msgstr "" -msgid "Blue connector" +msgid "Input Mix" msgstr "" -msgid "Blue front panel connector" +msgid "SPDIF In" msgstr "" -msgid "Orange connector" +msgid "SPDIF Out" msgstr "" -msgid "Orange front panel connector" +#, fuzzy +msgid "Microphone 1" +msgstr "Microphone" + +#, fuzzy +msgid "Microphone 2" +msgstr "Microphone" + +#, fuzzy +msgid "Digital Out" +msgstr "Digital-1" + +#, fuzzy +msgid "Digital In" +msgstr "Digital-1" + +msgid "HDMI" msgstr "" -msgid "Black connector" +msgid "Modem" msgstr "" -msgid "Black front panel connector" +msgid "Handset" msgstr "" -msgid "Gray connector" +msgid "Other" msgstr "" -msgid "Gray front panel connector" +msgid "None" msgstr "" -msgid "White connector" +msgid "On" msgstr "" -msgid "White front panel connector" +msgid "Off" msgstr "" -msgid "Red connector" +msgid "Mute" msgstr "" -msgid "Red front panel connector" +msgid "Fast" msgstr "" -msgid "Yellow connector" +msgid "Very Low" msgstr "" -msgid "Yellow front panel connector" +msgid "Low" msgstr "" -msgid "Green connector function" +msgid "Medium" msgstr "" -msgid "Green front panel connector function" +msgid "High" msgstr "" -msgid "Pink connector function" +msgid "Very High" msgstr "" -msgid "Pink front panel connector function" +msgid "Production" msgstr "" -msgid "Blue connector function" +#, fuzzy +msgid "Front Panel Microphone" +msgstr "Microphone" + +msgid "Front Panel Line In" msgstr "" -msgid "Blue front panel connector function" +msgid "Front Panel Headphones" msgstr "" -msgid "Orange connector function" +msgid "Front Panel Line Out" msgstr "" -msgid "Orange front panel connector function" +msgid "Green Connector" msgstr "" -msgid "Black connector function" +msgid "Pink Connector" msgstr "" -msgid "Black front panel connector function" +msgid "Blue Connector" msgstr "" -msgid "Gray connector function" +msgid "White Connector" msgstr "" -msgid "Gray front panel connector function" +msgid "Black Connector" msgstr "" -msgid "White connector function" +msgid "Gray Connector" msgstr "" -msgid "White front panel connector function" +msgid "Orange Connector" msgstr "" -msgid "Red connector function" +msgid "Red Connector" msgstr "" -msgid "Red front panel connector function" +msgid "Yellow Connector" msgstr "" -msgid "Yellow connector function" +msgid "Green Front Panel Connector" msgstr "" -msgid "Yellow front panel connector function" +msgid "Pink Front Panel Connector" msgstr "" -msgid "Front panel line-in" +msgid "Blue Front Panel Connector" msgstr "" -msgid "Headphones" +msgid "White Front Panel Connector" msgstr "" -msgid "Front panel headphones" +msgid "Black Front Panel Connector" msgstr "" -msgid "PCM" -msgstr "PCM" +msgid "Gray Front Panel Connector" +msgstr "" + +msgid "Orange Front Panel Connector" +msgstr "" + +msgid "Red Front Panel Connector" +msgstr "" + +msgid "Yellow Front Panel Connector" +msgstr "" + +msgid "Spread Output" +msgstr "" + +msgid "Downmix" +msgstr "" -msgid "Virtual mixer input" +msgid "Virtual Mixer Input" msgstr "" -msgid "Virtual mixer output" +msgid "Virtual Mixer Output" msgstr "" -msgid "Virtual mixer channel configuration" +msgid "Virtual Mixer Channels" +msgstr "" + +#, c-format +msgid "%s Function" +msgstr "" + +#, c-format +msgid "%s %d" msgstr "" msgid "" @@ -358,33 +477,21 @@ msgstr "" #~ msgid "Your OSS device could not be probed correctly" #~ msgstr "Your oss device could not be probed correctly" -#~ msgid "Volume" -#~ msgstr "Volume" - -#~ msgid "Bass" -#~ msgstr "Bass" - -#~ msgid "Treble" -#~ msgstr "Treble" - #~ msgid "Synth" #~ msgstr "Synth" -#~ msgid "Speaker" -#~ msgstr "Speaker" - #~ msgid "CD" #~ msgstr "CD" #~ msgid "Mixer" #~ msgstr "Mixer" +#~ msgid "PCM-2" +#~ msgstr "PCM-2" + #~ msgid "In-gain" #~ msgstr "In-gain" -#~ msgid "Out-gain" -#~ msgstr "Out-gain" - #~ msgid "Line-1" #~ msgstr "Line-1" @@ -394,9 +501,6 @@ msgstr "" #~ msgid "Line-3" #~ msgstr "Line-3" -#~ msgid "Digital-1" -#~ msgstr "Digital-1" - #~ msgid "Digital-2" #~ msgstr "Digital-2" @@ -412,13 +516,6 @@ msgstr "" #~ msgid "Radio" #~ msgstr "Radio" -#~ msgid "Monitor" -#~ msgstr "Monitor" - -#, fuzzy -#~ msgid "PC Speaker" -#~ msgstr "Speaker" - #~ msgid "Could not open CD device for reading." #~ msgstr "Could not open CD device for reading." @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: gst-plugins-bad 0.10.10.2\n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n" -"POT-Creation-Date: 2009-06-17 21:54+0100\n" +"POT-Creation-Date: 2009-08-11 17:42+0100\n" "PO-Revision-Date: 2009-04-04 13:31+0200\n" "Last-Translator: Jorge González González <aloriel@gmail.com>\n" "Language-Team: Spanish <es@li.org>\n" @@ -75,203 +75,349 @@ msgstr "" "No se pudo abrir el dispositivo para manejar el control del mezclador. Este " "elemento no soporta esta versión del Open Sound System." -msgid "Fast" +msgid "Volume" +msgstr "" + +#, fuzzy +msgid "Master" msgstr "Rápido" -msgid "Low" -msgstr "Bajo" +msgid "Front" +msgstr "Frontal" -msgid "Medium" -msgstr "Medio" +msgid "Rear" +msgstr "Trasero" -msgid "High" -msgstr "Alto" +msgid "Headphones" +msgstr "Auriculares" -msgid "Very high" -msgstr "Muy alto" +#, fuzzy +msgid "Center" +msgstr "Centrado / LFE" -msgid "Production" -msgstr "Producción" +msgid "LFE" +msgstr "" -msgid "Off" -msgstr "Apagado" +#, fuzzy +msgid "Surround" +msgstr "Sonido envolvente" -msgid "On" -msgstr "Encendido" +msgid "Side" +msgstr "Lateral" + +msgid "Built-in Speaker" +msgstr "" + +msgid "AUX 1 Out" +msgstr "" + +msgid "AUX 2 Out" +msgstr "" + +msgid "AUX Out" +msgstr "" + +msgid "Bass" +msgstr "" + +msgid "Treble" +msgstr "" + +msgid "3D Depth" +msgstr "" + +msgid "3D Center" +msgstr "" + +msgid "3D Enhance" +msgstr "" + +#, fuzzy +msgid "Telephone" +msgstr "Auriculares" + +msgid "Microphone" +msgstr "Micrófono" + +msgid "Line Out" +msgstr "" + +#, fuzzy +msgid "Line In" +msgstr "LÃnea de entrada" + +msgid "Internal CD" +msgstr "" + +msgid "Video In" +msgstr "" + +msgid "AUX 1 In" +msgstr "" + +msgid "AUX 2 In" +msgstr "" + +msgid "AUX In" +msgstr "" + +msgid "PCM" +msgstr "PCM" + +msgid "Record Gain" +msgstr "" + +msgid "Output Gain" +msgstr "" + +#, fuzzy +msgid "Microphone Boost" +msgstr "Micrófono" + +msgid "Loopback" +msgstr "" + +msgid "Diagnostic" +msgstr "" + +msgid "Bass Boost" +msgstr "" + +msgid "Playback Ports" +msgstr "" + +msgid "Input" +msgstr "Entrada" + +msgid "Record Source" +msgstr "" + +msgid "Monitor Source" +msgstr "" + +msgid "Keyboard Beep" +msgstr "" + +msgid "Monitor" +msgstr "" + +msgid "Simulate Stereo" +msgstr "" msgid "Stereo" msgstr "Estéreo" -msgid "Surround sound" +#, fuzzy +msgid "Surround Sound" msgstr "Sonido envolvente" -msgid "Input mix" -msgstr "Mezclador de entrada" +#, fuzzy +msgid "Microphone Gain" +msgstr "Micrófono" -msgid "Front" -msgstr "Frontal" +msgid "Speaker Source" +msgstr "" -msgid "Rear" -msgstr "Trasero" +#, fuzzy +msgid "Microphone Source" +msgstr "Micrófono" -msgid "Side" -msgstr "Lateral" +msgid "Jack" +msgstr "" msgid "Center / LFE" msgstr "Centrado / LFE" -msgid "Microphone" -msgstr "Micrófono" +#, fuzzy +msgid "Stereo Mix" +msgstr "Estéreo" -msgid "Front panel microphone" -msgstr "Micrófono del panel frontal" +msgid "Mono Mix" +msgstr "" -msgid "Input" -msgstr "Entrada" +#, fuzzy +msgid "Input Mix" +msgstr "Mezclador de entrada" -msgid "Line-in" -msgstr "LÃnea de entrada" +msgid "SPDIF In" +msgstr "" -msgid "PCM 1" -msgstr "PCM 1" +msgid "SPDIF Out" +msgstr "" -msgid "PCM 2" -msgstr "PCM 2" +#, fuzzy +msgid "Microphone 1" +msgstr "Micrófono" -msgid "PCM 3" -msgstr "PCM 3" +#, fuzzy +msgid "Microphone 2" +msgstr "Micrófono" -msgid "PCM 4" -msgstr "PCM 4" +msgid "Digital Out" +msgstr "" -msgid "Green connector" -msgstr "Conector verde" +msgid "Digital In" +msgstr "" -msgid "Green front panel connector" -msgstr "Conector verde del panel frontal" +msgid "HDMI" +msgstr "" -msgid "Pink connector" -msgstr "Conector rosa" +msgid "Modem" +msgstr "" -msgid "Pink front panel connector" -msgstr "Conector rosa del panel frontal" +msgid "Handset" +msgstr "" -msgid "Blue connector" -msgstr "Conector azul" +msgid "Other" +msgstr "" -msgid "Blue front panel connector" -msgstr "Conector azul del panel frontal" +msgid "None" +msgstr "" -msgid "Orange connector" -msgstr "Conector naranja" +msgid "On" +msgstr "Encendido" -msgid "Orange front panel connector" -msgstr "Conector naranja del panel frontal" +msgid "Off" +msgstr "Apagado" -msgid "Black connector" -msgstr "Conector negro" +msgid "Mute" +msgstr "" -msgid "Black front panel connector" -msgstr "Conector negro del panel frontal" +msgid "Fast" +msgstr "Rápido" -msgid "Gray connector" -msgstr "Conector gris" +msgid "Very Low" +msgstr "" -msgid "Gray front panel connector" -msgstr "Conector gris del panel frontal" +msgid "Low" +msgstr "Bajo" -msgid "White connector" -msgstr "Conector blanco" +msgid "Medium" +msgstr "Medio" -msgid "White front panel connector" -msgstr "Conector blanco del panel frontal" +msgid "High" +msgstr "Alto" -msgid "Red connector" -msgstr "Conector rojo" +#, fuzzy +msgid "Very High" +msgstr "Muy alto" -msgid "Red front panel connector" -msgstr "Conector rojo del panel frontal" +msgid "Production" +msgstr "Producción" -msgid "Yellow connector" -msgstr "Conector amarillo" +#, fuzzy +msgid "Front Panel Microphone" +msgstr "Micrófono del panel frontal" -msgid "Yellow front panel connector" -msgstr "Conector amarillo del panel frontal" +#, fuzzy +msgid "Front Panel Line In" +msgstr "LÃnea de entrada del panel frontal" -msgid "Green connector function" -msgstr "Función del conector verde" +#, fuzzy +msgid "Front Panel Headphones" +msgstr "Auriculares del panel frontal" -msgid "Green front panel connector function" -msgstr "Función del conector verde del panel frontal" +#, fuzzy +msgid "Front Panel Line Out" +msgstr "LÃnea de entrada del panel frontal" -msgid "Pink connector function" -msgstr "Función del conector rosa" +#, fuzzy +msgid "Green Connector" +msgstr "Conector verde" -msgid "Pink front panel connector function" -msgstr "Función del conector rosa del panel frontal" +#, fuzzy +msgid "Pink Connector" +msgstr "Conector rosa" -msgid "Blue connector function" -msgstr "Función del conector azul" +#, fuzzy +msgid "Blue Connector" +msgstr "Conector azul" -msgid "Blue front panel connector function" -msgstr "Función del conector azul del panel frontal" +#, fuzzy +msgid "White Connector" +msgstr "Conector blanco" -msgid "Orange connector function" -msgstr "Función del conector naranja" +#, fuzzy +msgid "Black Connector" +msgstr "Conector negro" -msgid "Orange front panel connector function" -msgstr "Función del conector naranja del panel frontal" +#, fuzzy +msgid "Gray Connector" +msgstr "Conector gris" -msgid "Black connector function" -msgstr "Función del conector negro" +#, fuzzy +msgid "Orange Connector" +msgstr "Conector naranja" -msgid "Black front panel connector function" -msgstr "Función del conector negro del panel frontal" +#, fuzzy +msgid "Red Connector" +msgstr "Conector rojo" -msgid "Gray connector function" -msgstr "Función del conector gris" +#, fuzzy +msgid "Yellow Connector" +msgstr "Conector amarillo" -msgid "Gray front panel connector function" -msgstr "Función del conector gris del panel frontal" +#, fuzzy +msgid "Green Front Panel Connector" +msgstr "Conector verde del panel frontal" -msgid "White connector function" -msgstr "Función del conector blanco" +#, fuzzy +msgid "Pink Front Panel Connector" +msgstr "Conector rosa del panel frontal" -msgid "White front panel connector function" -msgstr "Función del conector blanco del panel frontal" +#, fuzzy +msgid "Blue Front Panel Connector" +msgstr "Conector azul del panel frontal" -msgid "Red connector function" -msgstr "Función del conector rojo" +#, fuzzy +msgid "White Front Panel Connector" +msgstr "Conector blanco del panel frontal" -msgid "Red front panel connector function" -msgstr "Función del conector rojo del panel frontal" +#, fuzzy +msgid "Black Front Panel Connector" +msgstr "Conector negro del panel frontal" -msgid "Yellow connector function" -msgstr "Función del conector amarillo" +#, fuzzy +msgid "Gray Front Panel Connector" +msgstr "Conector gris del panel frontal" -msgid "Yellow front panel connector function" -msgstr "Función del conector amarillo del panel frontal" +#, fuzzy +msgid "Orange Front Panel Connector" +msgstr "Conector naranja del panel frontal" -msgid "Front panel line-in" -msgstr "LÃnea de entrada del panel frontal" +#, fuzzy +msgid "Red Front Panel Connector" +msgstr "Conector rojo del panel frontal" -msgid "Headphones" -msgstr "Auriculares" +#, fuzzy +msgid "Yellow Front Panel Connector" +msgstr "Conector amarillo del panel frontal" -msgid "Front panel headphones" -msgstr "Auriculares del panel frontal" +msgid "Spread Output" +msgstr "" -msgid "PCM" -msgstr "PCM" +msgid "Downmix" +msgstr "" -msgid "Virtual mixer input" +#, fuzzy +msgid "Virtual Mixer Input" msgstr "Entrada del mezclador virtual" -msgid "Virtual mixer output" +#, fuzzy +msgid "Virtual Mixer Output" msgstr "Salida del mezclador virtual" -msgid "Virtual mixer channel configuration" -msgstr "Configuración del canal del mezclador virtual" +#, fuzzy +msgid "Virtual Mixer Channels" +msgstr "Entrada del mezclador virtual" + +#, c-format +msgid "%s Function" +msgstr "" + +#, c-format +msgid "%s %d" +msgstr "" msgid "" "Could not open audio device for playback. Device is being used by another " @@ -309,6 +455,75 @@ msgstr "Este dispositivo de sonido no soporta grabación." msgid "Error recording from audio device." msgstr "Error al grabar desde el dispositivo de sonido." +#~ msgid "PCM 1" +#~ msgstr "PCM 1" + +#~ msgid "PCM 2" +#~ msgstr "PCM 2" + +#~ msgid "PCM 3" +#~ msgstr "PCM 3" + +#~ msgid "PCM 4" +#~ msgstr "PCM 4" + +#~ msgid "Green connector function" +#~ msgstr "Función del conector verde" + +#~ msgid "Green front panel connector function" +#~ msgstr "Función del conector verde del panel frontal" + +#~ msgid "Pink connector function" +#~ msgstr "Función del conector rosa" + +#~ msgid "Pink front panel connector function" +#~ msgstr "Función del conector rosa del panel frontal" + +#~ msgid "Blue connector function" +#~ msgstr "Función del conector azul" + +#~ msgid "Blue front panel connector function" +#~ msgstr "Función del conector azul del panel frontal" + +#~ msgid "Orange connector function" +#~ msgstr "Función del conector naranja" + +#~ msgid "Orange front panel connector function" +#~ msgstr "Función del conector naranja del panel frontal" + +#~ msgid "Black connector function" +#~ msgstr "Función del conector negro" + +#~ msgid "Black front panel connector function" +#~ msgstr "Función del conector negro del panel frontal" + +#~ msgid "Gray connector function" +#~ msgstr "Función del conector gris" + +#~ msgid "Gray front panel connector function" +#~ msgstr "Función del conector gris del panel frontal" + +#~ msgid "White connector function" +#~ msgstr "Función del conector blanco" + +#~ msgid "White front panel connector function" +#~ msgstr "Función del conector blanco del panel frontal" + +#~ msgid "Red connector function" +#~ msgstr "Función del conector rojo" + +#~ msgid "Red front panel connector function" +#~ msgstr "Función del conector rojo del panel frontal" + +#~ msgid "Yellow connector function" +#~ msgstr "Función del conector amarillo" + +#~ msgid "Yellow front panel connector function" +#~ msgstr "Función del conector amarillo del panel frontal" + +#~ msgid "Virtual mixer channel configuration" +#~ msgstr "Configuración del canal del mezclador virtual" + #~ msgid "Failed to configure TwoLAME encoder. Check your encoding parameters." #~ msgstr "" #~ "Falló al configurar el codificador TwoLAME. Compruebe sus parámetros de " @@ -11,7 +11,7 @@ msgid "" msgstr "" "Project-Id-Version: gst-plugins-bad 0.10.10.2\n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n" -"POT-Creation-Date: 2009-06-17 21:54+0100\n" +"POT-Creation-Date: 2009-08-11 17:42+0100\n" "PO-Revision-Date: 2009-03-11 08:23+0200\n" "Last-Translator: Tommi Vainikainen <Tommi.Vainikainen@iki.fi>\n" "Language-Team: Finnish <translation-team-fi@lists.sourceforge.net>\n" @@ -77,203 +77,349 @@ msgstr "" "Äänilaitetta ei voitu avata mikserinhallinnan käsiteltäväksi. Tämä elementti " "ei tue tätä versiota Open Sound Systemistä." -msgid "Fast" +msgid "Volume" +msgstr "" + +#, fuzzy +msgid "Master" msgstr "Nopea" -msgid "Low" -msgstr "Matala" +msgid "Front" +msgstr "Etu" -msgid "Medium" -msgstr "Keskitaso" +msgid "Rear" +msgstr "Taka" -msgid "High" -msgstr "Korkea" +msgid "Headphones" +msgstr "Kuulokkeet" -msgid "Very high" -msgstr "Erittäin korkea" +#, fuzzy +msgid "Center" +msgstr "Keski / LFE" -msgid "Production" -msgstr "Tuotanto" +msgid "LFE" +msgstr "" -msgid "Off" -msgstr "Poissa" +#, fuzzy +msgid "Surround" +msgstr "Surround-ääni" -msgid "On" -msgstr "Päällä" +msgid "Side" +msgstr "Sivu" + +msgid "Built-in Speaker" +msgstr "" + +msgid "AUX 1 Out" +msgstr "" + +msgid "AUX 2 Out" +msgstr "" + +msgid "AUX Out" +msgstr "" + +msgid "Bass" +msgstr "" + +msgid "Treble" +msgstr "" + +msgid "3D Depth" +msgstr "" + +msgid "3D Center" +msgstr "" + +msgid "3D Enhance" +msgstr "" + +#, fuzzy +msgid "Telephone" +msgstr "Kuulokkeet" + +msgid "Microphone" +msgstr "Mikrofoni" + +msgid "Line Out" +msgstr "" + +#, fuzzy +msgid "Line In" +msgstr "Linja sisään" + +msgid "Internal CD" +msgstr "" + +msgid "Video In" +msgstr "" + +msgid "AUX 1 In" +msgstr "" + +msgid "AUX 2 In" +msgstr "" + +msgid "AUX In" +msgstr "" + +msgid "PCM" +msgstr "PCM" + +msgid "Record Gain" +msgstr "" + +msgid "Output Gain" +msgstr "" + +#, fuzzy +msgid "Microphone Boost" +msgstr "Mikrofoni" + +msgid "Loopback" +msgstr "" + +msgid "Diagnostic" +msgstr "" + +msgid "Bass Boost" +msgstr "" + +msgid "Playback Ports" +msgstr "" + +msgid "Input" +msgstr "Sisääntulo" + +msgid "Record Source" +msgstr "" + +msgid "Monitor Source" +msgstr "" + +msgid "Keyboard Beep" +msgstr "" + +msgid "Monitor" +msgstr "" + +msgid "Simulate Stereo" +msgstr "" msgid "Stereo" msgstr "Stereo" -msgid "Surround sound" +#, fuzzy +msgid "Surround Sound" msgstr "Surround-ääni" -msgid "Input mix" -msgstr "Sisääntulomiksaus" +#, fuzzy +msgid "Microphone Gain" +msgstr "Mikrofoni" -msgid "Front" -msgstr "Etu" +msgid "Speaker Source" +msgstr "" -msgid "Rear" -msgstr "Taka" +#, fuzzy +msgid "Microphone Source" +msgstr "Mikrofoni" -msgid "Side" -msgstr "Sivu" +msgid "Jack" +msgstr "" msgid "Center / LFE" msgstr "Keski / LFE" -msgid "Microphone" -msgstr "Mikrofoni" +#, fuzzy +msgid "Stereo Mix" +msgstr "Stereo" -msgid "Front panel microphone" -msgstr "Etupaneelin mikrofoni" +msgid "Mono Mix" +msgstr "" -msgid "Input" -msgstr "Sisääntulo" +#, fuzzy +msgid "Input Mix" +msgstr "Sisääntulomiksaus" -msgid "Line-in" -msgstr "Linja sisään" +msgid "SPDIF In" +msgstr "" -msgid "PCM 1" -msgstr "PCM 1" +msgid "SPDIF Out" +msgstr "" -msgid "PCM 2" -msgstr "PCM 2" +#, fuzzy +msgid "Microphone 1" +msgstr "Mikrofoni" -msgid "PCM 3" -msgstr "PCM 3" +#, fuzzy +msgid "Microphone 2" +msgstr "Mikrofoni" -msgid "PCM 4" -msgstr "PCM 4" +msgid "Digital Out" +msgstr "" -msgid "Green connector" -msgstr "Vihreä liitin" +msgid "Digital In" +msgstr "" -msgid "Green front panel connector" -msgstr "Vihreä etupaneelin liitin" +msgid "HDMI" +msgstr "" -msgid "Pink connector" -msgstr "Violetti liitin" +msgid "Modem" +msgstr "" -msgid "Pink front panel connector" -msgstr "Violetti etupaneelin liitin" +msgid "Handset" +msgstr "" -msgid "Blue connector" -msgstr "Sininen liitin" +msgid "Other" +msgstr "" -msgid "Blue front panel connector" -msgstr "Sininen etupaneelin liitin" +msgid "None" +msgstr "" -msgid "Orange connector" -msgstr "Oranssi liitin" +msgid "On" +msgstr "Päällä" -msgid "Orange front panel connector" -msgstr "Oranssi etupaneelin liitin" +msgid "Off" +msgstr "Poissa" -msgid "Black connector" -msgstr "Musta liitin" +msgid "Mute" +msgstr "" -msgid "Black front panel connector" -msgstr "Musta etupaneelin liitin" +msgid "Fast" +msgstr "Nopea" -msgid "Gray connector" -msgstr "Harmaa liitin" +msgid "Very Low" +msgstr "" -msgid "Gray front panel connector" -msgstr "Harmaa etupaneelin liitin" +msgid "Low" +msgstr "Matala" -msgid "White connector" -msgstr "Valkoinen liitin" +msgid "Medium" +msgstr "Keskitaso" -msgid "White front panel connector" -msgstr "Valkoinen etupaneelin liitin" +msgid "High" +msgstr "Korkea" -msgid "Red connector" -msgstr "Punainen liitin" +#, fuzzy +msgid "Very High" +msgstr "Erittäin korkea" -msgid "Red front panel connector" -msgstr "Punainen etupaneelin liitin" +msgid "Production" +msgstr "Tuotanto" -msgid "Yellow connector" -msgstr "Keltainen liitin" +#, fuzzy +msgid "Front Panel Microphone" +msgstr "Etupaneelin mikrofoni" -msgid "Yellow front panel connector" -msgstr "Keltainen etupaneelin liitin" +#, fuzzy +msgid "Front Panel Line In" +msgstr "Etupaneelin linjasisääntulo" -msgid "Green connector function" -msgstr "Vihreän liittimen toiminto" +#, fuzzy +msgid "Front Panel Headphones" +msgstr "Etupaneelin kuulokkeet" -msgid "Green front panel connector function" -msgstr "Vihreän etupaneelin liittimen toiminto" +#, fuzzy +msgid "Front Panel Line Out" +msgstr "Etupaneelin linjasisääntulo" -msgid "Pink connector function" -msgstr "Violetin liittimen toiminto" +#, fuzzy +msgid "Green Connector" +msgstr "Vihreä liitin" -msgid "Pink front panel connector function" -msgstr "Violetin etupaneelin liittimen toiminto" +#, fuzzy +msgid "Pink Connector" +msgstr "Violetti liitin" -msgid "Blue connector function" -msgstr "Sinisen liittimen toiminto" +#, fuzzy +msgid "Blue Connector" +msgstr "Sininen liitin" -msgid "Blue front panel connector function" -msgstr "Sinisen etupaneelin liittimen toiminto" +#, fuzzy +msgid "White Connector" +msgstr "Valkoinen liitin" -msgid "Orange connector function" -msgstr "Oranssin liittimen toiminto" +#, fuzzy +msgid "Black Connector" +msgstr "Musta liitin" -msgid "Orange front panel connector function" -msgstr "Oranssin etupaneelin liittimen toiminto" +#, fuzzy +msgid "Gray Connector" +msgstr "Harmaa liitin" -msgid "Black connector function" -msgstr "Mustan liittimen toiminto" +#, fuzzy +msgid "Orange Connector" +msgstr "Oranssi liitin" -msgid "Black front panel connector function" -msgstr "Mustan etupaneelin liittimen toiminto" +#, fuzzy +msgid "Red Connector" +msgstr "Punainen liitin" -msgid "Gray connector function" -msgstr "Harmaan liittimen toiminto" +#, fuzzy +msgid "Yellow Connector" +msgstr "Keltainen liitin" -msgid "Gray front panel connector function" -msgstr "Harmaan etupaneelin liittimen toiminto" +#, fuzzy +msgid "Green Front Panel Connector" +msgstr "Vihreä etupaneelin liitin" -msgid "White connector function" -msgstr "Valkoisen liittimen toiminto" +#, fuzzy +msgid "Pink Front Panel Connector" +msgstr "Violetti etupaneelin liitin" -msgid "White front panel connector function" -msgstr "Valkoisen etupaneelin liittimen toiminto" +#, fuzzy +msgid "Blue Front Panel Connector" +msgstr "Sininen etupaneelin liitin" -msgid "Red connector function" -msgstr "Punaisen liittimen toiminto" +#, fuzzy +msgid "White Front Panel Connector" +msgstr "Valkoinen etupaneelin liitin" -msgid "Red front panel connector function" -msgstr "Punaisen etupaneelin liittimen toiminto" +#, fuzzy +msgid "Black Front Panel Connector" +msgstr "Musta etupaneelin liitin" -msgid "Yellow connector function" -msgstr "Keltaisen liittimen toiminto" +#, fuzzy +msgid "Gray Front Panel Connector" +msgstr "Harmaa etupaneelin liitin" -msgid "Yellow front panel connector function" -msgstr "Keltaisen etupaneelin liittimen toiminto" +#, fuzzy +msgid "Orange Front Panel Connector" +msgstr "Oranssi etupaneelin liitin" -msgid "Front panel line-in" -msgstr "Etupaneelin linjasisääntulo" +#, fuzzy +msgid "Red Front Panel Connector" +msgstr "Punainen etupaneelin liitin" -msgid "Headphones" -msgstr "Kuulokkeet" +#, fuzzy +msgid "Yellow Front Panel Connector" +msgstr "Keltainen etupaneelin liitin" -msgid "Front panel headphones" -msgstr "Etupaneelin kuulokkeet" +msgid "Spread Output" +msgstr "" -msgid "PCM" -msgstr "PCM" +msgid "Downmix" +msgstr "" -msgid "Virtual mixer input" +#, fuzzy +msgid "Virtual Mixer Input" msgstr "Näennäinen mikserisisääntulo" -msgid "Virtual mixer output" +#, fuzzy +msgid "Virtual Mixer Output" msgstr "Näennäinen mikseriulostulo" -msgid "Virtual mixer channel configuration" -msgstr "Näennäinen mikserikanava-asetus" +#, fuzzy +msgid "Virtual Mixer Channels" +msgstr "Näennäinen mikserisisääntulo" + +#, c-format +msgid "%s Function" +msgstr "" + +#, c-format +msgid "%s %d" +msgstr "" msgid "" "Could not open audio device for playback. Device is being used by another " @@ -310,3 +456,72 @@ msgstr "Tämä äänilaite ei tue nauhoitusta." msgid "Error recording from audio device." msgstr "Virhe nauhoitettaessa äänilaitteelta." + +#~ msgid "PCM 1" +#~ msgstr "PCM 1" + +#~ msgid "PCM 2" +#~ msgstr "PCM 2" + +#~ msgid "PCM 3" +#~ msgstr "PCM 3" + +#~ msgid "PCM 4" +#~ msgstr "PCM 4" + +#~ msgid "Green connector function" +#~ msgstr "Vihreän liittimen toiminto" + +#~ msgid "Green front panel connector function" +#~ msgstr "Vihreän etupaneelin liittimen toiminto" + +#~ msgid "Pink connector function" +#~ msgstr "Violetin liittimen toiminto" + +#~ msgid "Pink front panel connector function" +#~ msgstr "Violetin etupaneelin liittimen toiminto" + +#~ msgid "Blue connector function" +#~ msgstr "Sinisen liittimen toiminto" + +#~ msgid "Blue front panel connector function" +#~ msgstr "Sinisen etupaneelin liittimen toiminto" + +#~ msgid "Orange connector function" +#~ msgstr "Oranssin liittimen toiminto" + +#~ msgid "Orange front panel connector function" +#~ msgstr "Oranssin etupaneelin liittimen toiminto" + +#~ msgid "Black connector function" +#~ msgstr "Mustan liittimen toiminto" + +#~ msgid "Black front panel connector function" +#~ msgstr "Mustan etupaneelin liittimen toiminto" + +#~ msgid "Gray connector function" +#~ msgstr "Harmaan liittimen toiminto" + +#~ msgid "Gray front panel connector function" +#~ msgstr "Harmaan etupaneelin liittimen toiminto" + +#~ msgid "White connector function" +#~ msgstr "Valkoisen liittimen toiminto" + +#~ msgid "White front panel connector function" +#~ msgstr "Valkoisen etupaneelin liittimen toiminto" + +#~ msgid "Red connector function" +#~ msgstr "Punaisen liittimen toiminto" + +#~ msgid "Red front panel connector function" +#~ msgstr "Punaisen etupaneelin liittimen toiminto" + +#~ msgid "Yellow connector function" +#~ msgstr "Keltaisen liittimen toiminto" + +#~ msgid "Yellow front panel connector function" +#~ msgstr "Keltaisen etupaneelin liittimen toiminto" + +#~ msgid "Virtual mixer channel configuration" +#~ msgstr "Näennäinen mikserikanava-asetus" @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: gst-plugins-bad 0.10.8.3\n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n" -"POT-Creation-Date: 2009-06-17 21:54+0100\n" +"POT-Creation-Date: 2009-08-11 17:42+0100\n" "PO-Revision-Date: 2008-10-21 09:59+0200\n" "Last-Translator: Claude Paroz <claude@2xlibre.net>\n" "Language-Team: French <traduc@traduc.org>\n" @@ -75,203 +75,349 @@ msgstr "" "mixage. Cette version de OSS (Open Sound System) n'est pas prise en charge " "par cet élément." -msgid "Fast" +msgid "Volume" +msgstr "" + +#, fuzzy +msgid "Master" msgstr "Rapide" -msgid "Low" -msgstr "Bas" +msgid "Front" +msgstr "Avant" -msgid "Medium" -msgstr "Moyen" +msgid "Rear" +msgstr "Arrière" -msgid "High" -msgstr "Élevé" +msgid "Headphones" +msgstr "Écouteurs" -msgid "Very high" -msgstr "Très élevé" +#, fuzzy +msgid "Center" +msgstr "Centre / LFE" -msgid "Production" -msgstr "Production" +msgid "LFE" +msgstr "" -msgid "Off" -msgstr "Désactivé" +#, fuzzy +msgid "Surround" +msgstr "Son ambiophonique" -msgid "On" -msgstr "Activé" +msgid "Side" +msgstr "Côté" + +msgid "Built-in Speaker" +msgstr "" + +msgid "AUX 1 Out" +msgstr "" + +msgid "AUX 2 Out" +msgstr "" + +msgid "AUX Out" +msgstr "" + +msgid "Bass" +msgstr "" + +msgid "Treble" +msgstr "" + +msgid "3D Depth" +msgstr "" + +msgid "3D Center" +msgstr "" + +msgid "3D Enhance" +msgstr "" + +#, fuzzy +msgid "Telephone" +msgstr "Écouteurs" + +msgid "Microphone" +msgstr "Microphone" + +msgid "Line Out" +msgstr "" + +#, fuzzy +msgid "Line In" +msgstr "Entrée ligne" + +msgid "Internal CD" +msgstr "" + +msgid "Video In" +msgstr "" + +msgid "AUX 1 In" +msgstr "" + +msgid "AUX 2 In" +msgstr "" + +msgid "AUX In" +msgstr "" + +msgid "PCM" +msgstr "PCM" + +msgid "Record Gain" +msgstr "" + +msgid "Output Gain" +msgstr "" + +#, fuzzy +msgid "Microphone Boost" +msgstr "Microphone" + +msgid "Loopback" +msgstr "" + +msgid "Diagnostic" +msgstr "" + +msgid "Bass Boost" +msgstr "" + +msgid "Playback Ports" +msgstr "" + +msgid "Input" +msgstr "Entrée" + +msgid "Record Source" +msgstr "" + +msgid "Monitor Source" +msgstr "" + +msgid "Keyboard Beep" +msgstr "" + +msgid "Monitor" +msgstr "" + +msgid "Simulate Stereo" +msgstr "" msgid "Stereo" msgstr "Stéréo" -msgid "Surround sound" +#, fuzzy +msgid "Surround Sound" msgstr "Son ambiophonique" -msgid "Input mix" -msgstr "Mélangeur d'entrée" +#, fuzzy +msgid "Microphone Gain" +msgstr "Microphone" -msgid "Front" -msgstr "Avant" +msgid "Speaker Source" +msgstr "" -msgid "Rear" -msgstr "Arrière" +#, fuzzy +msgid "Microphone Source" +msgstr "Microphone" -msgid "Side" -msgstr "Côté" +msgid "Jack" +msgstr "" msgid "Center / LFE" msgstr "Centre / LFE" -msgid "Microphone" -msgstr "Microphone" +#, fuzzy +msgid "Stereo Mix" +msgstr "Stéréo" -msgid "Front panel microphone" -msgstr "Micro du panneau avant" +msgid "Mono Mix" +msgstr "" -msgid "Input" -msgstr "Entrée" +#, fuzzy +msgid "Input Mix" +msgstr "Mélangeur d'entrée" -msgid "Line-in" -msgstr "Entrée ligne" +msgid "SPDIF In" +msgstr "" -msgid "PCM 1" -msgstr "PCM 1" +msgid "SPDIF Out" +msgstr "" -msgid "PCM 2" -msgstr "PCM 2" +#, fuzzy +msgid "Microphone 1" +msgstr "Microphone" -msgid "PCM 3" -msgstr "PCM 3" +#, fuzzy +msgid "Microphone 2" +msgstr "Microphone" -msgid "PCM 4" -msgstr "PCM 4" +msgid "Digital Out" +msgstr "" -msgid "Green connector" -msgstr "Connecteur vert" +msgid "Digital In" +msgstr "" -msgid "Green front panel connector" -msgstr "Connecteur vert du panneau avant" +msgid "HDMI" +msgstr "" -msgid "Pink connector" -msgstr "Connecteur rose" +msgid "Modem" +msgstr "" -msgid "Pink front panel connector" -msgstr "Connecteur rose du panneau avant" +msgid "Handset" +msgstr "" -msgid "Blue connector" -msgstr "Connecteur bleu" +msgid "Other" +msgstr "" -msgid "Blue front panel connector" -msgstr "Connecteur bleu du panneau avant" +msgid "None" +msgstr "" -msgid "Orange connector" -msgstr "Connecteur orange" +msgid "On" +msgstr "Activé" -msgid "Orange front panel connector" -msgstr "Connecteur orange du panneau avant" +msgid "Off" +msgstr "Désactivé" -msgid "Black connector" -msgstr "Connecteur noir" +msgid "Mute" +msgstr "" -msgid "Black front panel connector" -msgstr "Connecteur noir du panneau avant" +msgid "Fast" +msgstr "Rapide" -msgid "Gray connector" -msgstr "Connecteur gris" +msgid "Very Low" +msgstr "" -msgid "Gray front panel connector" -msgstr "Connecteur gris du panneau avant" +msgid "Low" +msgstr "Bas" -msgid "White connector" -msgstr "Connecteur blanc" +msgid "Medium" +msgstr "Moyen" -msgid "White front panel connector" -msgstr "Connecteur blanc du panneau avant" +msgid "High" +msgstr "Élevé" -msgid "Red connector" -msgstr "Connecteur rouge" +#, fuzzy +msgid "Very High" +msgstr "Très élevé" -msgid "Red front panel connector" -msgstr "Connecteur rouge du panneau avant" +msgid "Production" +msgstr "Production" -msgid "Yellow connector" -msgstr "Connecteur jaune" +#, fuzzy +msgid "Front Panel Microphone" +msgstr "Micro du panneau avant" -msgid "Yellow front panel connector" -msgstr "Connecteur jaune du panneau avant" +#, fuzzy +msgid "Front Panel Line In" +msgstr "Entrée ligne du panneau avant" -msgid "Green connector function" -msgstr "Fonction du connecteur vert" +#, fuzzy +msgid "Front Panel Headphones" +msgstr "Écouteurs du panneau avant" -msgid "Green front panel connector function" -msgstr "Fonction du connecteur vert du panneau avant" +#, fuzzy +msgid "Front Panel Line Out" +msgstr "Entrée ligne du panneau avant" -msgid "Pink connector function" -msgstr "Fonction du connecteur rose" +#, fuzzy +msgid "Green Connector" +msgstr "Connecteur vert" -msgid "Pink front panel connector function" -msgstr "Fonction du connecteur rose du panneau avant" +#, fuzzy +msgid "Pink Connector" +msgstr "Connecteur rose" -msgid "Blue connector function" -msgstr "Fonction du connecteur bleu" +#, fuzzy +msgid "Blue Connector" +msgstr "Connecteur bleu" -msgid "Blue front panel connector function" -msgstr "Fonction du connecteur bleu du panneau avant" +#, fuzzy +msgid "White Connector" +msgstr "Connecteur blanc" -msgid "Orange connector function" -msgstr "Fonction du connecteur orange" +#, fuzzy +msgid "Black Connector" +msgstr "Connecteur noir" -msgid "Orange front panel connector function" -msgstr "Fonction du connecteur orange du panneau avant" +#, fuzzy +msgid "Gray Connector" +msgstr "Connecteur gris" -msgid "Black connector function" -msgstr "Fonction du connecteur noir" +#, fuzzy +msgid "Orange Connector" +msgstr "Connecteur orange" -msgid "Black front panel connector function" -msgstr "Fonction du connecteur noir du panneau avant" +#, fuzzy +msgid "Red Connector" +msgstr "Connecteur rouge" -msgid "Gray connector function" -msgstr "Fonction du connecteur gris" +#, fuzzy +msgid "Yellow Connector" +msgstr "Connecteur jaune" -msgid "Gray front panel connector function" -msgstr "Fonction du connecteur gris du panneau avant" +#, fuzzy +msgid "Green Front Panel Connector" +msgstr "Connecteur vert du panneau avant" -msgid "White connector function" -msgstr "Fonction du connecteur blanc" +#, fuzzy +msgid "Pink Front Panel Connector" +msgstr "Connecteur rose du panneau avant" -msgid "White front panel connector function" -msgstr "Fonction du connecteur blanc du panneau avant" +#, fuzzy +msgid "Blue Front Panel Connector" +msgstr "Connecteur bleu du panneau avant" -msgid "Red connector function" -msgstr "Fonction du connecteur rouge" +#, fuzzy +msgid "White Front Panel Connector" +msgstr "Connecteur blanc du panneau avant" -msgid "Red front panel connector function" -msgstr "Fonction du connecteur rouge du panneau avant" +#, fuzzy +msgid "Black Front Panel Connector" +msgstr "Connecteur noir du panneau avant" -msgid "Yellow connector function" -msgstr "Fonction du connecteur jaune" +#, fuzzy +msgid "Gray Front Panel Connector" +msgstr "Connecteur gris du panneau avant" -msgid "Yellow front panel connector function" -msgstr "Fonction du connecteur jaune du panneau avant" +#, fuzzy +msgid "Orange Front Panel Connector" +msgstr "Connecteur orange du panneau avant" -msgid "Front panel line-in" -msgstr "Entrée ligne du panneau avant" +#, fuzzy +msgid "Red Front Panel Connector" +msgstr "Connecteur rouge du panneau avant" -msgid "Headphones" -msgstr "Écouteurs" +#, fuzzy +msgid "Yellow Front Panel Connector" +msgstr "Connecteur jaune du panneau avant" -msgid "Front panel headphones" -msgstr "Écouteurs du panneau avant" +msgid "Spread Output" +msgstr "" -msgid "PCM" -msgstr "PCM" +msgid "Downmix" +msgstr "" -msgid "Virtual mixer input" +#, fuzzy +msgid "Virtual Mixer Input" msgstr "Entrée de mélangeur virtuel" -msgid "Virtual mixer output" +#, fuzzy +msgid "Virtual Mixer Output" msgstr "Sortie de mélangeur virtuel" -msgid "Virtual mixer channel configuration" -msgstr "Configuration du canal du mélangeur virtuel" +#, fuzzy +msgid "Virtual Mixer Channels" +msgstr "Entrée de mélangeur virtuel" + +#, c-format +msgid "%s Function" +msgstr "" + +#, c-format +msgid "%s %d" +msgstr "" msgid "" "Could not open audio device for playback. Device is being used by another " @@ -320,3 +466,72 @@ msgstr "Erreur lors de l'enregistrement à partir du périphérique audio." #~ msgstr "" #~ "Le débit binaire demandé de %d kbit/s pour la propriété « %s » n'est pas " #~ "autorisé. Le débit binaire a été défini à %d kbits/s." + +#~ msgid "PCM 1" +#~ msgstr "PCM 1" + +#~ msgid "PCM 2" +#~ msgstr "PCM 2" + +#~ msgid "PCM 3" +#~ msgstr "PCM 3" + +#~ msgid "PCM 4" +#~ msgstr "PCM 4" + +#~ msgid "Green connector function" +#~ msgstr "Fonction du connecteur vert" + +#~ msgid "Green front panel connector function" +#~ msgstr "Fonction du connecteur vert du panneau avant" + +#~ msgid "Pink connector function" +#~ msgstr "Fonction du connecteur rose" + +#~ msgid "Pink front panel connector function" +#~ msgstr "Fonction du connecteur rose du panneau avant" + +#~ msgid "Blue connector function" +#~ msgstr "Fonction du connecteur bleu" + +#~ msgid "Blue front panel connector function" +#~ msgstr "Fonction du connecteur bleu du panneau avant" + +#~ msgid "Orange connector function" +#~ msgstr "Fonction du connecteur orange" + +#~ msgid "Orange front panel connector function" +#~ msgstr "Fonction du connecteur orange du panneau avant" + +#~ msgid "Black connector function" +#~ msgstr "Fonction du connecteur noir" + +#~ msgid "Black front panel connector function" +#~ msgstr "Fonction du connecteur noir du panneau avant" + +#~ msgid "Gray connector function" +#~ msgstr "Fonction du connecteur gris" + +#~ msgid "Gray front panel connector function" +#~ msgstr "Fonction du connecteur gris du panneau avant" + +#~ msgid "White connector function" +#~ msgstr "Fonction du connecteur blanc" + +#~ msgid "White front panel connector function" +#~ msgstr "Fonction du connecteur blanc du panneau avant" + +#~ msgid "Red connector function" +#~ msgstr "Fonction du connecteur rouge" + +#~ msgid "Red front panel connector function" +#~ msgstr "Fonction du connecteur rouge du panneau avant" + +#~ msgid "Yellow connector function" +#~ msgstr "Fonction du connecteur jaune" + +#~ msgid "Yellow front panel connector function" +#~ msgstr "Fonction du connecteur jaune du panneau avant" + +#~ msgid "Virtual mixer channel configuration" +#~ msgstr "Configuration du canal du mélangeur virtuel" @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: gst-plugins-bad 0.10.10.2\n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n" -"POT-Creation-Date: 2009-06-17 21:54+0100\n" +"POT-Creation-Date: 2009-08-11 17:42+0100\n" "PO-Revision-Date: 2009-04-20 02:16+0200\n" "Last-Translator: Gabor Kelemen <kelemeng@gnome.hu>\n" "Language-Team: Hungarian <translation-team-hu@lists.sourceforge.net>\n" @@ -72,203 +72,349 @@ msgstr "" "A hangeszköz nem nyitható meg a keverÅ‘ vezérlÅ‘inek kezeléséhez. A NyÃlt " "hangrendszer ezen verzióját nem támogatja az elem." -msgid "Fast" +msgid "Volume" +msgstr "" + +#, fuzzy +msgid "Master" msgstr "Gyors" -msgid "Low" -msgstr "Alacsony" +msgid "Front" +msgstr "Elöl" -msgid "Medium" -msgstr "Közepes" +msgid "Rear" +msgstr "Hátul" -msgid "High" -msgstr "Magas" +msgid "Headphones" +msgstr "Fülhallgatók" -msgid "Very high" -msgstr "Nagyon magas" +#, fuzzy +msgid "Center" +msgstr "Közép/LFE" -msgid "Production" -msgstr "ElőállÃtás" +msgid "LFE" +msgstr "" -msgid "Off" -msgstr "Ki" +#, fuzzy +msgid "Surround" +msgstr "Térhatású hang" -msgid "On" -msgstr "Be" +msgid "Side" +msgstr "Oldalt" + +msgid "Built-in Speaker" +msgstr "" + +msgid "AUX 1 Out" +msgstr "" + +msgid "AUX 2 Out" +msgstr "" + +msgid "AUX Out" +msgstr "" + +msgid "Bass" +msgstr "" + +msgid "Treble" +msgstr "" + +msgid "3D Depth" +msgstr "" + +msgid "3D Center" +msgstr "" + +msgid "3D Enhance" +msgstr "" + +#, fuzzy +msgid "Telephone" +msgstr "Fülhallgatók" + +msgid "Microphone" +msgstr "Mikrofon" + +msgid "Line Out" +msgstr "" + +#, fuzzy +msgid "Line In" +msgstr "Vonalbemenet" + +msgid "Internal CD" +msgstr "" + +msgid "Video In" +msgstr "" + +msgid "AUX 1 In" +msgstr "" + +msgid "AUX 2 In" +msgstr "" + +msgid "AUX In" +msgstr "" + +msgid "PCM" +msgstr "PCM" + +msgid "Record Gain" +msgstr "" + +msgid "Output Gain" +msgstr "" + +#, fuzzy +msgid "Microphone Boost" +msgstr "Mikrofon" + +msgid "Loopback" +msgstr "" + +msgid "Diagnostic" +msgstr "" + +msgid "Bass Boost" +msgstr "" + +msgid "Playback Ports" +msgstr "" + +msgid "Input" +msgstr "Bemenet" + +msgid "Record Source" +msgstr "" + +msgid "Monitor Source" +msgstr "" + +msgid "Keyboard Beep" +msgstr "" + +msgid "Monitor" +msgstr "" + +msgid "Simulate Stereo" +msgstr "" msgid "Stereo" msgstr "Sztereó" -msgid "Surround sound" +#, fuzzy +msgid "Surround Sound" msgstr "Térhatású hang" -msgid "Input mix" -msgstr "Bemeneti keverÅ‘" +#, fuzzy +msgid "Microphone Gain" +msgstr "Mikrofon" -msgid "Front" -msgstr "Elöl" +msgid "Speaker Source" +msgstr "" -msgid "Rear" -msgstr "Hátul" +#, fuzzy +msgid "Microphone Source" +msgstr "Mikrofon" -msgid "Side" -msgstr "Oldalt" +msgid "Jack" +msgstr "" msgid "Center / LFE" msgstr "Közép/LFE" -msgid "Microphone" -msgstr "Mikrofon" +#, fuzzy +msgid "Stereo Mix" +msgstr "Sztereó" -msgid "Front panel microphone" -msgstr "ElÅ‘lapi mikrofon" +msgid "Mono Mix" +msgstr "" -msgid "Input" -msgstr "Bemenet" +#, fuzzy +msgid "Input Mix" +msgstr "Bemeneti keverÅ‘" -msgid "Line-in" -msgstr "Vonalbemenet" +msgid "SPDIF In" +msgstr "" -msgid "PCM 1" -msgstr "PCM 1" +msgid "SPDIF Out" +msgstr "" -msgid "PCM 2" -msgstr "PCM 2" +#, fuzzy +msgid "Microphone 1" +msgstr "Mikrofon" -msgid "PCM 3" -msgstr "PCM 3" +#, fuzzy +msgid "Microphone 2" +msgstr "Mikrofon" -msgid "PCM 4" -msgstr "PCM 4" +msgid "Digital Out" +msgstr "" -msgid "Green connector" -msgstr "Zöld csatlakozó" +msgid "Digital In" +msgstr "" -msgid "Green front panel connector" -msgstr "Zöld elÅ‘lapi csatlakozó" +msgid "HDMI" +msgstr "" -msgid "Pink connector" -msgstr "RózsaszÃn csatlakozó" +msgid "Modem" +msgstr "" -msgid "Pink front panel connector" -msgstr "RózsaszÃn elÅ‘lapi csatlakozó" +msgid "Handset" +msgstr "" -msgid "Blue connector" -msgstr "Kék csatlakozó" +msgid "Other" +msgstr "" -msgid "Blue front panel connector" -msgstr "Kék elÅ‘lapi csatlakozó" +msgid "None" +msgstr "" -msgid "Orange connector" -msgstr "Narancs csatlakozó" +msgid "On" +msgstr "Be" -msgid "Orange front panel connector" -msgstr "Narancs elÅ‘lapi csatlakozó" +msgid "Off" +msgstr "Ki" -msgid "Black connector" -msgstr "Fekete csatlakozó" +msgid "Mute" +msgstr "" -msgid "Black front panel connector" -msgstr "Fekete elÅ‘lapi csatlakozó" +msgid "Fast" +msgstr "Gyors" -msgid "Gray connector" -msgstr "Szürke csatlakozó" +msgid "Very Low" +msgstr "" -msgid "Gray front panel connector" -msgstr "Szürke elÅ‘lapi csatlakozó" +msgid "Low" +msgstr "Alacsony" -msgid "White connector" -msgstr "Fehér csatlakozó" +msgid "Medium" +msgstr "Közepes" -msgid "White front panel connector" -msgstr "Fehér elÅ‘lapi csatlakozó" +msgid "High" +msgstr "Magas" -msgid "Red connector" -msgstr "Vörös csatlakozó" +#, fuzzy +msgid "Very High" +msgstr "Nagyon magas" -msgid "Red front panel connector" -msgstr "Vörös elÅ‘lapi csatlakozó" +msgid "Production" +msgstr "ElőállÃtás" -msgid "Yellow connector" -msgstr "Sárga csatlakozó" +#, fuzzy +msgid "Front Panel Microphone" +msgstr "ElÅ‘lapi mikrofon" -msgid "Yellow front panel connector" -msgstr "Sárga elÅ‘lapi csatlakozó" +#, fuzzy +msgid "Front Panel Line In" +msgstr "ElÅ‘lapi vonalbemenet" -msgid "Green connector function" -msgstr "Zöld csatlakozó funkciója" +#, fuzzy +msgid "Front Panel Headphones" +msgstr "ElÅ‘lapi fülhallgató" -msgid "Green front panel connector function" -msgstr "Zöld elÅ‘lapi csatlakozó funkciója" +#, fuzzy +msgid "Front Panel Line Out" +msgstr "ElÅ‘lapi vonalbemenet" -msgid "Pink connector function" -msgstr "RózsaszÃn csatlakozó funkciója" +#, fuzzy +msgid "Green Connector" +msgstr "Zöld csatlakozó" -msgid "Pink front panel connector function" -msgstr "RózsaszÃn elÅ‘lapi csatlakozó funkciója" +#, fuzzy +msgid "Pink Connector" +msgstr "RózsaszÃn csatlakozó" -msgid "Blue connector function" -msgstr "Kék csatlakozó funkciója" +#, fuzzy +msgid "Blue Connector" +msgstr "Kék csatlakozó" -msgid "Blue front panel connector function" -msgstr "Kék elÅ‘lapi csatlakozó funkciója" +#, fuzzy +msgid "White Connector" +msgstr "Fehér csatlakozó" -msgid "Orange connector function" -msgstr "Narancs csatlakozó funkciója" +#, fuzzy +msgid "Black Connector" +msgstr "Fekete csatlakozó" -msgid "Orange front panel connector function" -msgstr "Narancs elÅ‘lapi csatlakozó funkciója" +#, fuzzy +msgid "Gray Connector" +msgstr "Szürke csatlakozó" -msgid "Black connector function" -msgstr "Fekete csatlakozó funkciója" +#, fuzzy +msgid "Orange Connector" +msgstr "Narancs csatlakozó" -msgid "Black front panel connector function" -msgstr "Fekete elÅ‘lapi csatlakozó funkciója" +#, fuzzy +msgid "Red Connector" +msgstr "Vörös csatlakozó" -msgid "Gray connector function" -msgstr "Szürke csatlakozó funkciója" +#, fuzzy +msgid "Yellow Connector" +msgstr "Sárga csatlakozó" -msgid "Gray front panel connector function" -msgstr "Szürke elÅ‘lapi csatlakozó funkciója" +#, fuzzy +msgid "Green Front Panel Connector" +msgstr "Zöld elÅ‘lapi csatlakozó" -msgid "White connector function" -msgstr "Fehér csatlakozó funkciója" +#, fuzzy +msgid "Pink Front Panel Connector" +msgstr "RózsaszÃn elÅ‘lapi csatlakozó" -msgid "White front panel connector function" -msgstr "Fehér elÅ‘lapi csatlakozó funkciója" +#, fuzzy +msgid "Blue Front Panel Connector" +msgstr "Kék elÅ‘lapi csatlakozó" -msgid "Red connector function" -msgstr "Vörös csatlakozó funkciója" +#, fuzzy +msgid "White Front Panel Connector" +msgstr "Fehér elÅ‘lapi csatlakozó" -msgid "Red front panel connector function" -msgstr "Vörös elÅ‘lapi csatlakozó funkciója" +#, fuzzy +msgid "Black Front Panel Connector" +msgstr "Fekete elÅ‘lapi csatlakozó" -msgid "Yellow connector function" -msgstr "Sárga csatlakozó funkciója" +#, fuzzy +msgid "Gray Front Panel Connector" +msgstr "Szürke elÅ‘lapi csatlakozó" -msgid "Yellow front panel connector function" -msgstr "Sárga elÅ‘lapi csatlakozó funkciója" +#, fuzzy +msgid "Orange Front Panel Connector" +msgstr "Narancs elÅ‘lapi csatlakozó" -msgid "Front panel line-in" -msgstr "ElÅ‘lapi vonalbemenet" +#, fuzzy +msgid "Red Front Panel Connector" +msgstr "Vörös elÅ‘lapi csatlakozó" -msgid "Headphones" -msgstr "Fülhallgatók" +#, fuzzy +msgid "Yellow Front Panel Connector" +msgstr "Sárga elÅ‘lapi csatlakozó" -msgid "Front panel headphones" -msgstr "ElÅ‘lapi fülhallgató" +msgid "Spread Output" +msgstr "" -msgid "PCM" -msgstr "PCM" +msgid "Downmix" +msgstr "" -msgid "Virtual mixer input" +#, fuzzy +msgid "Virtual Mixer Input" msgstr "Virtuális keverÅ‘bemenet" -msgid "Virtual mixer output" +#, fuzzy +msgid "Virtual Mixer Output" msgstr "Virtuális keverÅ‘kimenet" -msgid "Virtual mixer channel configuration" -msgstr "Virtuális keverÅ‘ csatornabeállÃtásai" +#, fuzzy +msgid "Virtual Mixer Channels" +msgstr "Virtuális keverÅ‘bemenet" + +#, c-format +msgid "%s Function" +msgstr "" + +#, c-format +msgid "%s %d" +msgstr "" msgid "" "Could not open audio device for playback. Device is being used by another " @@ -305,3 +451,72 @@ msgstr "A hangeszköz nem támogatja a felvételt." msgid "Error recording from audio device." msgstr "Hiba a hangeszközrÅ‘l való felvételkor." + +#~ msgid "PCM 1" +#~ msgstr "PCM 1" + +#~ msgid "PCM 2" +#~ msgstr "PCM 2" + +#~ msgid "PCM 3" +#~ msgstr "PCM 3" + +#~ msgid "PCM 4" +#~ msgstr "PCM 4" + +#~ msgid "Green connector function" +#~ msgstr "Zöld csatlakozó funkciója" + +#~ msgid "Green front panel connector function" +#~ msgstr "Zöld elÅ‘lapi csatlakozó funkciója" + +#~ msgid "Pink connector function" +#~ msgstr "RózsaszÃn csatlakozó funkciója" + +#~ msgid "Pink front panel connector function" +#~ msgstr "RózsaszÃn elÅ‘lapi csatlakozó funkciója" + +#~ msgid "Blue connector function" +#~ msgstr "Kék csatlakozó funkciója" + +#~ msgid "Blue front panel connector function" +#~ msgstr "Kék elÅ‘lapi csatlakozó funkciója" + +#~ msgid "Orange connector function" +#~ msgstr "Narancs csatlakozó funkciója" + +#~ msgid "Orange front panel connector function" +#~ msgstr "Narancs elÅ‘lapi csatlakozó funkciója" + +#~ msgid "Black connector function" +#~ msgstr "Fekete csatlakozó funkciója" + +#~ msgid "Black front panel connector function" +#~ msgstr "Fekete elÅ‘lapi csatlakozó funkciója" + +#~ msgid "Gray connector function" +#~ msgstr "Szürke csatlakozó funkciója" + +#~ msgid "Gray front panel connector function" +#~ msgstr "Szürke elÅ‘lapi csatlakozó funkciója" + +#~ msgid "White connector function" +#~ msgstr "Fehér csatlakozó funkciója" + +#~ msgid "White front panel connector function" +#~ msgstr "Fehér elÅ‘lapi csatlakozó funkciója" + +#~ msgid "Red connector function" +#~ msgstr "Vörös csatlakozó funkciója" + +#~ msgid "Red front panel connector function" +#~ msgstr "Vörös elÅ‘lapi csatlakozó funkciója" + +#~ msgid "Yellow connector function" +#~ msgstr "Sárga csatlakozó funkciója" + +#~ msgid "Yellow front panel connector function" +#~ msgstr "Sárga elÅ‘lapi csatlakozó funkciója" + +#~ msgid "Virtual mixer channel configuration" +#~ msgstr "Virtuális keverÅ‘ csatornabeállÃtásai" @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: gst-plugins-bad 0.10.12.3\n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n" -"POT-Creation-Date: 2009-06-17 21:54+0100\n" +"POT-Creation-Date: 2009-08-11 17:42+0100\n" "PO-Revision-Date: 2009-06-13 22:03+0700\n" "Last-Translator: Andhika Padmawan <andhika.padmawan@gmail.com>\n" "Language-Team: Indonesian <translation-team-id@lists.sourceforge.net>\n" @@ -70,203 +70,349 @@ msgstr "" "Tak dapat membuka divais audio untuk pengendalian kontrol mixer. Versi Open " "Sound System ini tak didukung oleh elemen ini." -msgid "Fast" +msgid "Volume" +msgstr "" + +#, fuzzy +msgid "Master" msgstr "Cepat" -msgid "Low" -msgstr "Rendah" +msgid "Front" +msgstr "Depan" -msgid "Medium" -msgstr "Sedang" +msgid "Rear" +msgstr "Belakang" -msgid "High" -msgstr "Tinggi" +msgid "Headphones" +msgstr "Headphone" -msgid "Very high" -msgstr "Sangat tinggi" +#, fuzzy +msgid "Center" +msgstr "Tengah / LFE" -msgid "Production" -msgstr "Produksi" +msgid "LFE" +msgstr "" -msgid "Off" -msgstr "Mati" +#, fuzzy +msgid "Surround" +msgstr "Surround sound" -msgid "On" -msgstr "Hidup" +msgid "Side" +msgstr "Samping" + +msgid "Built-in Speaker" +msgstr "" + +msgid "AUX 1 Out" +msgstr "" + +msgid "AUX 2 Out" +msgstr "" + +msgid "AUX Out" +msgstr "" + +msgid "Bass" +msgstr "" + +msgid "Treble" +msgstr "" + +msgid "3D Depth" +msgstr "" + +msgid "3D Center" +msgstr "" + +msgid "3D Enhance" +msgstr "" + +#, fuzzy +msgid "Telephone" +msgstr "Headphone" + +msgid "Microphone" +msgstr "Mikrofon" + +msgid "Line Out" +msgstr "" + +#, fuzzy +msgid "Line In" +msgstr "Jalur-masuk" + +msgid "Internal CD" +msgstr "" + +msgid "Video In" +msgstr "" + +msgid "AUX 1 In" +msgstr "" + +msgid "AUX 2 In" +msgstr "" + +msgid "AUX In" +msgstr "" + +msgid "PCM" +msgstr "PCM" + +msgid "Record Gain" +msgstr "" + +msgid "Output Gain" +msgstr "" + +#, fuzzy +msgid "Microphone Boost" +msgstr "Mikrofon" + +msgid "Loopback" +msgstr "" + +msgid "Diagnostic" +msgstr "" + +msgid "Bass Boost" +msgstr "" + +msgid "Playback Ports" +msgstr "" + +msgid "Input" +msgstr "Masukan" + +msgid "Record Source" +msgstr "" + +msgid "Monitor Source" +msgstr "" + +msgid "Keyboard Beep" +msgstr "" + +msgid "Monitor" +msgstr "" + +msgid "Simulate Stereo" +msgstr "" msgid "Stereo" msgstr "Stereo" -msgid "Surround sound" +#, fuzzy +msgid "Surround Sound" msgstr "Surround sound" -msgid "Input mix" -msgstr "Mix masukan" +#, fuzzy +msgid "Microphone Gain" +msgstr "Mikrofon" -msgid "Front" -msgstr "Depan" +msgid "Speaker Source" +msgstr "" -msgid "Rear" -msgstr "Belakang" +#, fuzzy +msgid "Microphone Source" +msgstr "Mikrofon" -msgid "Side" -msgstr "Samping" +msgid "Jack" +msgstr "" msgid "Center / LFE" msgstr "Tengah / LFE" -msgid "Microphone" -msgstr "Mikrofon" +#, fuzzy +msgid "Stereo Mix" +msgstr "Stereo" -msgid "Front panel microphone" -msgstr "Mikrofon panel depan" +msgid "Mono Mix" +msgstr "" -msgid "Input" -msgstr "Masukan" +#, fuzzy +msgid "Input Mix" +msgstr "Mix masukan" -msgid "Line-in" -msgstr "Jalur-masuk" +msgid "SPDIF In" +msgstr "" -msgid "PCM 1" -msgstr "PCM 1" +msgid "SPDIF Out" +msgstr "" -msgid "PCM 2" -msgstr "PCM 2" +#, fuzzy +msgid "Microphone 1" +msgstr "Mikrofon" -msgid "PCM 3" -msgstr "PCM 3" +#, fuzzy +msgid "Microphone 2" +msgstr "Mikrofon" -msgid "PCM 4" -msgstr "PCM 4" +msgid "Digital Out" +msgstr "" -msgid "Green connector" -msgstr "Penyambung hijau" +msgid "Digital In" +msgstr "" -msgid "Green front panel connector" -msgstr "Penyambung panel depan hijau" +msgid "HDMI" +msgstr "" -msgid "Pink connector" -msgstr "Penyambung merah jambu" +msgid "Modem" +msgstr "" -msgid "Pink front panel connector" -msgstr "Penyambung panel depan merah jambu" +msgid "Handset" +msgstr "" -msgid "Blue connector" -msgstr "Penyambung biru" +msgid "Other" +msgstr "" -msgid "Blue front panel connector" -msgstr "Penyambung panel depan biru" +msgid "None" +msgstr "" -msgid "Orange connector" -msgstr "Penyambung jingga" +msgid "On" +msgstr "Hidup" -msgid "Orange front panel connector" -msgstr "Penyambung panel depan jingga" +msgid "Off" +msgstr "Mati" -msgid "Black connector" -msgstr "Penyambung hitam" +msgid "Mute" +msgstr "" -msgid "Black front panel connector" -msgstr "Penyambung panel depan hitam" +msgid "Fast" +msgstr "Cepat" -msgid "Gray connector" -msgstr "Penyambung abu-abu" +msgid "Very Low" +msgstr "" -msgid "Gray front panel connector" -msgstr "Penyambung panel depan abu-abu" +msgid "Low" +msgstr "Rendah" -msgid "White connector" -msgstr "Penyambung putih" +msgid "Medium" +msgstr "Sedang" -msgid "White front panel connector" -msgstr "Penyambung panel depan putih" +msgid "High" +msgstr "Tinggi" -msgid "Red connector" -msgstr "Penyambung merah" +#, fuzzy +msgid "Very High" +msgstr "Sangat tinggi" -msgid "Red front panel connector" -msgstr "Penyambung panel depan merah" +msgid "Production" +msgstr "Produksi" -msgid "Yellow connector" -msgstr "Penyambung kuning" +#, fuzzy +msgid "Front Panel Microphone" +msgstr "Mikrofon panel depan" -msgid "Yellow front panel connector" -msgstr "Penyambung panel depan kuning" +#, fuzzy +msgid "Front Panel Line In" +msgstr "Jalur-masuk panel depan" -msgid "Green connector function" -msgstr "Fungsi penyambung hijau" +#, fuzzy +msgid "Front Panel Headphones" +msgstr "Headphone panel depan" -msgid "Green front panel connector function" -msgstr "Fungsi penyambung panel depan hijau" +#, fuzzy +msgid "Front Panel Line Out" +msgstr "Jalur-masuk panel depan" -msgid "Pink connector function" -msgstr "Fungsi penyambung merah jambu" +#, fuzzy +msgid "Green Connector" +msgstr "Penyambung hijau" -msgid "Pink front panel connector function" -msgstr "Fungsi penyambung panel depan merah jambu" +#, fuzzy +msgid "Pink Connector" +msgstr "Penyambung merah jambu" -msgid "Blue connector function" -msgstr "Fungsi penyambung biru" +#, fuzzy +msgid "Blue Connector" +msgstr "Penyambung biru" -msgid "Blue front panel connector function" -msgstr "Fungsi penyambung panel depan biru" +#, fuzzy +msgid "White Connector" +msgstr "Penyambung putih" -msgid "Orange connector function" -msgstr "Fungsi penyambung jingga" +#, fuzzy +msgid "Black Connector" +msgstr "Penyambung hitam" -msgid "Orange front panel connector function" -msgstr "Fungsi penyambung panel depan jingga" +#, fuzzy +msgid "Gray Connector" +msgstr "Penyambung abu-abu" -msgid "Black connector function" -msgstr "Fungsi penyambung hitam" +#, fuzzy +msgid "Orange Connector" +msgstr "Penyambung jingga" -msgid "Black front panel connector function" -msgstr "Fungsi penyambung panel depan hitam" +#, fuzzy +msgid "Red Connector" +msgstr "Penyambung merah" -msgid "Gray connector function" -msgstr "Fungsi penyambung abu-abu" +#, fuzzy +msgid "Yellow Connector" +msgstr "Penyambung kuning" -msgid "Gray front panel connector function" -msgstr "Fungsi penyambung panel depan abu-abu" +#, fuzzy +msgid "Green Front Panel Connector" +msgstr "Penyambung panel depan hijau" -msgid "White connector function" -msgstr "Fungsi penyambung putih" +#, fuzzy +msgid "Pink Front Panel Connector" +msgstr "Penyambung panel depan merah jambu" -msgid "White front panel connector function" -msgstr "Fungsi penyambung panel depan putih" +#, fuzzy +msgid "Blue Front Panel Connector" +msgstr "Penyambung panel depan biru" -msgid "Red connector function" -msgstr "Fungsi penyambung merah" +#, fuzzy +msgid "White Front Panel Connector" +msgstr "Penyambung panel depan putih" -msgid "Red front panel connector function" -msgstr "Fungsi penyambung panel depan merah" +#, fuzzy +msgid "Black Front Panel Connector" +msgstr "Penyambung panel depan hitam" -msgid "Yellow connector function" -msgstr "Fungsi penyambung kuning" +#, fuzzy +msgid "Gray Front Panel Connector" +msgstr "Penyambung panel depan abu-abu" -msgid "Yellow front panel connector function" -msgstr "Fungsi penyambung panel depan kuning" +#, fuzzy +msgid "Orange Front Panel Connector" +msgstr "Penyambung panel depan jingga" -msgid "Front panel line-in" -msgstr "Jalur-masuk panel depan" +#, fuzzy +msgid "Red Front Panel Connector" +msgstr "Penyambung panel depan merah" -msgid "Headphones" -msgstr "Headphone" +#, fuzzy +msgid "Yellow Front Panel Connector" +msgstr "Penyambung panel depan kuning" -msgid "Front panel headphones" -msgstr "Headphone panel depan" +msgid "Spread Output" +msgstr "" -msgid "PCM" -msgstr "PCM" +msgid "Downmix" +msgstr "" -msgid "Virtual mixer input" +#, fuzzy +msgid "Virtual Mixer Input" msgstr "Masukan mixer virtual" -msgid "Virtual mixer output" +#, fuzzy +msgid "Virtual Mixer Output" msgstr "Keluaran mixer virtual" -msgid "Virtual mixer channel configuration" -msgstr "Konfigurasi kanal mixer virtual" +#, fuzzy +msgid "Virtual Mixer Channels" +msgstr "Masukan mixer virtual" + +#, c-format +msgid "%s Function" +msgstr "" + +#, c-format +msgid "%s %d" +msgstr "" msgid "" "Could not open audio device for playback. Device is being used by another " @@ -304,6 +450,75 @@ msgstr "Perekaman tak didukung oleh divais audio ini." msgid "Error recording from audio device." msgstr "Galat ketika merekam dari divais audio." +#~ msgid "PCM 1" +#~ msgstr "PCM 1" + +#~ msgid "PCM 2" +#~ msgstr "PCM 2" + +#~ msgid "PCM 3" +#~ msgstr "PCM 3" + +#~ msgid "PCM 4" +#~ msgstr "PCM 4" + +#~ msgid "Green connector function" +#~ msgstr "Fungsi penyambung hijau" + +#~ msgid "Green front panel connector function" +#~ msgstr "Fungsi penyambung panel depan hijau" + +#~ msgid "Pink connector function" +#~ msgstr "Fungsi penyambung merah jambu" + +#~ msgid "Pink front panel connector function" +#~ msgstr "Fungsi penyambung panel depan merah jambu" + +#~ msgid "Blue connector function" +#~ msgstr "Fungsi penyambung biru" + +#~ msgid "Blue front panel connector function" +#~ msgstr "Fungsi penyambung panel depan biru" + +#~ msgid "Orange connector function" +#~ msgstr "Fungsi penyambung jingga" + +#~ msgid "Orange front panel connector function" +#~ msgstr "Fungsi penyambung panel depan jingga" + +#~ msgid "Black connector function" +#~ msgstr "Fungsi penyambung hitam" + +#~ msgid "Black front panel connector function" +#~ msgstr "Fungsi penyambung panel depan hitam" + +#~ msgid "Gray connector function" +#~ msgstr "Fungsi penyambung abu-abu" + +#~ msgid "Gray front panel connector function" +#~ msgstr "Fungsi penyambung panel depan abu-abu" + +#~ msgid "White connector function" +#~ msgstr "Fungsi penyambung putih" + +#~ msgid "White front panel connector function" +#~ msgstr "Fungsi penyambung panel depan putih" + +#~ msgid "Red connector function" +#~ msgstr "Fungsi penyambung merah" + +#~ msgid "Red front panel connector function" +#~ msgstr "Fungsi penyambung panel depan merah" + +#~ msgid "Yellow connector function" +#~ msgstr "Fungsi penyambung kuning" + +#~ msgid "Yellow front panel connector function" +#~ msgstr "Fungsi penyambung panel depan kuning" + +#~ msgid "Virtual mixer channel configuration" +#~ msgstr "Konfigurasi kanal mixer virtual" + #~ msgid "Failed to configure TwoLAME encoder. Check your encoding parameters." #~ msgstr "Gagal mengatur penyandi TwoLAME. Cek parameter penyandian anda." @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: gst-plugins-bad 0.10.11.2\n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n" -"POT-Creation-Date: 2009-06-17 21:54+0100\n" +"POT-Creation-Date: 2009-08-11 17:42+0100\n" "PO-Revision-Date: 2009-05-13 09:14+0200\n" "Last-Translator: Luca Ferretti <elle.uca@infinito.it>\n" "Language-Team: Italian <tp@lists.linux.it>\n" @@ -74,48 +74,160 @@ msgstr "" "mixer. Questa versione di Open Sound System non è supportata da questo " "elemento." +msgid "Volume" +msgstr "" + # NdT: questo e i successivi non ho controllato che sono.... -msgid "Fast" +#, fuzzy +msgid "Master" msgstr "Veloce" -msgid "Low" -msgstr "Lento" +msgid "Front" +msgstr "Fronte" -msgid "Medium" -msgstr "Medio" +msgid "Rear" +msgstr "Dietro" -msgid "High" -msgstr "Alto" +msgid "Headphones" +msgstr "Cuffie" -msgid "Very high" -msgstr "Molto alto" +# NdT: forse questo? --> http://en.wikipedia.org/wiki/Low-frequency_effect +# +# o forse Low Frequency Emitter +#, fuzzy +msgid "Center" +msgstr "Centro / LFE" -msgid "Production" -msgstr "Produzione" +msgid "LFE" +msgstr "" -msgid "Off" -msgstr "Spento" +#, fuzzy +msgid "Surround" +msgstr "Suono surround" -msgid "On" -msgstr "Acceso" +msgid "Side" +msgstr "Lato" + +msgid "Built-in Speaker" +msgstr "" + +msgid "AUX 1 Out" +msgstr "" + +msgid "AUX 2 Out" +msgstr "" + +msgid "AUX Out" +msgstr "" + +msgid "Bass" +msgstr "" + +msgid "Treble" +msgstr "" + +msgid "3D Depth" +msgstr "" + +msgid "3D Center" +msgstr "" + +msgid "3D Enhance" +msgstr "" + +#, fuzzy +msgid "Telephone" +msgstr "Cuffie" + +msgid "Microphone" +msgstr "Microfono" + +msgid "Line Out" +msgstr "" + +#, fuzzy +msgid "Line In" +msgstr "Linea in" + +msgid "Internal CD" +msgstr "" + +msgid "Video In" +msgstr "" + +msgid "AUX 1 In" +msgstr "" + +msgid "AUX 2 In" +msgstr "" + +msgid "AUX In" +msgstr "" + +# http://it.wikipedia.org/wiki/Pulse-Code_Modulation +msgid "PCM" +msgstr "PCM" + +msgid "Record Gain" +msgstr "" + +msgid "Output Gain" +msgstr "" + +#, fuzzy +msgid "Microphone Boost" +msgstr "Microfono" + +msgid "Loopback" +msgstr "" + +msgid "Diagnostic" +msgstr "" + +msgid "Bass Boost" +msgstr "" + +msgid "Playback Ports" +msgstr "" + +msgid "Input" +msgstr "Input" + +msgid "Record Source" +msgstr "" + +msgid "Monitor Source" +msgstr "" + +msgid "Keyboard Beep" +msgstr "" + +msgid "Monitor" +msgstr "" + +msgid "Simulate Stereo" +msgstr "" msgid "Stereo" msgstr "Stereo" -msgid "Surround sound" +#, fuzzy +msgid "Surround Sound" msgstr "Suono surround" -msgid "Input mix" -msgstr "Mix ingresso" +#, fuzzy +msgid "Microphone Gain" +msgstr "Microfono" -msgid "Front" -msgstr "Fronte" +msgid "Speaker Source" +msgstr "" -msgid "Rear" -msgstr "Dietro" +#, fuzzy +msgid "Microphone Source" +msgstr "Microfono" -msgid "Side" -msgstr "Lato" +msgid "Jack" +msgstr "" # NdT: forse questo? --> http://en.wikipedia.org/wiki/Low-frequency_effect # @@ -123,159 +235,197 @@ msgstr "Lato" msgid "Center / LFE" msgstr "Centro / LFE" -msgid "Microphone" -msgstr "Microfono" +#, fuzzy +msgid "Stereo Mix" +msgstr "Stereo" -msgid "Front panel microphone" -msgstr "Microfono pannello frontale" +msgid "Mono Mix" +msgstr "" -msgid "Input" -msgstr "Input" +#, fuzzy +msgid "Input Mix" +msgstr "Mix ingresso" -msgid "Line-in" -msgstr "Linea in" +msgid "SPDIF In" +msgstr "" -msgid "PCM 1" -msgstr "PCM 1" +msgid "SPDIF Out" +msgstr "" -msgid "PCM 2" -msgstr "PCM 2" +#, fuzzy +msgid "Microphone 1" +msgstr "Microfono" -msgid "PCM 3" -msgstr "PCM 3" +#, fuzzy +msgid "Microphone 2" +msgstr "Microfono" -msgid "PCM 4" -msgstr "PCM 4" +msgid "Digital Out" +msgstr "" -msgid "Green connector" -msgstr "Connettore verde" +msgid "Digital In" +msgstr "" -msgid "Green front panel connector" -msgstr "Connettore verde pannello frontale" +msgid "HDMI" +msgstr "" -msgid "Pink connector" -msgstr "Connettore rosa" +msgid "Modem" +msgstr "" -msgid "Pink front panel connector" -msgstr "Connettore rosa pannello frontale" +msgid "Handset" +msgstr "" -msgid "Blue connector" -msgstr "Connettore blu" +msgid "Other" +msgstr "" -msgid "Blue front panel connector" -msgstr "Connettore blu pannello frontale" +msgid "None" +msgstr "" -msgid "Orange connector" -msgstr "Connettore arancione" +msgid "On" +msgstr "Acceso" -msgid "Orange front panel connector" -msgstr "Connettore arancione pannello frontale" +msgid "Off" +msgstr "Spento" -msgid "Black connector" -msgstr "Connettore nero" +msgid "Mute" +msgstr "" -msgid "Black front panel connector" -msgstr "Connettore nero pannello frontale" +# NdT: questo e i successivi non ho controllato che sono.... +msgid "Fast" +msgstr "Veloce" -msgid "Gray connector" -msgstr "Connettore grigio" +msgid "Very Low" +msgstr "" -msgid "Gray front panel connector" -msgstr "Connettore grigio pannello frontale" +msgid "Low" +msgstr "Lento" -msgid "White connector" -msgstr "Connettore bianco" +msgid "Medium" +msgstr "Medio" -msgid "White front panel connector" -msgstr "Connettore bianco pannello frontale" +msgid "High" +msgstr "Alto" -msgid "Red connector" -msgstr "Connettore rosso" +#, fuzzy +msgid "Very High" +msgstr "Molto alto" -msgid "Red front panel connector" -msgstr "Connettore rosso pannello frontale" +msgid "Production" +msgstr "Produzione" -msgid "Yellow connector" -msgstr "Connettore giallo" +#, fuzzy +msgid "Front Panel Microphone" +msgstr "Microfono pannello frontale" -msgid "Yellow front panel connector" -msgstr "Connettore giallo pannello frontale" +#, fuzzy +msgid "Front Panel Line In" +msgstr "Canale ingresso pannello frontale" -msgid "Green connector function" -msgstr "Funzione connettore verde" +#, fuzzy +msgid "Front Panel Headphones" +msgstr "Cuffie pannello frontale" -msgid "Green front panel connector function" -msgstr "Funzione connettore verde pannello frontale" +#, fuzzy +msgid "Front Panel Line Out" +msgstr "Canale ingresso pannello frontale" -msgid "Pink connector function" -msgstr "Funzione connettore rosa" +#, fuzzy +msgid "Green Connector" +msgstr "Connettore verde" -msgid "Pink front panel connector function" -msgstr "Funzione connettore rosa pannello frontale" +#, fuzzy +msgid "Pink Connector" +msgstr "Connettore rosa" -msgid "Blue connector function" -msgstr "Funzione connettore blu" +#, fuzzy +msgid "Blue Connector" +msgstr "Connettore blu" -msgid "Blue front panel connector function" -msgstr "Funzione connettore blu pannello frontale" +#, fuzzy +msgid "White Connector" +msgstr "Connettore bianco" -msgid "Orange connector function" -msgstr "Funzione connettore arancione" +#, fuzzy +msgid "Black Connector" +msgstr "Connettore nero" -msgid "Orange front panel connector function" -msgstr "Funzione connettore arancione pannello frontale" +#, fuzzy +msgid "Gray Connector" +msgstr "Connettore grigio" -msgid "Black connector function" -msgstr "Funzione connettore nero" +#, fuzzy +msgid "Orange Connector" +msgstr "Connettore arancione" -msgid "Black front panel connector function" -msgstr "Funzione connettore nero pannello frontale" +#, fuzzy +msgid "Red Connector" +msgstr "Connettore rosso" -msgid "Gray connector function" -msgstr "Funzione connettore grigio" +#, fuzzy +msgid "Yellow Connector" +msgstr "Connettore giallo" -msgid "Gray front panel connector function" -msgstr "Funzione connettore grigio pannello frontale" +#, fuzzy +msgid "Green Front Panel Connector" +msgstr "Connettore verde pannello frontale" -msgid "White connector function" -msgstr "Funzione connettore bianco" +#, fuzzy +msgid "Pink Front Panel Connector" +msgstr "Connettore rosa pannello frontale" -msgid "White front panel connector function" -msgstr "Funzione connettore bianco pannello frontale" +#, fuzzy +msgid "Blue Front Panel Connector" +msgstr "Connettore blu pannello frontale" -msgid "Red connector function" -msgstr "Funzione connettore rosso" +#, fuzzy +msgid "White Front Panel Connector" +msgstr "Connettore bianco pannello frontale" -msgid "Red front panel connector function" -msgstr "Funzione connettore rosso pannello frontale" +#, fuzzy +msgid "Black Front Panel Connector" +msgstr "Connettore nero pannello frontale" -msgid "Yellow connector function" -msgstr "Funzione connettore giallo" +#, fuzzy +msgid "Gray Front Panel Connector" +msgstr "Connettore grigio pannello frontale" -msgid "Yellow front panel connector function" -msgstr "Funzione connettore giallo pannello frontale" +#, fuzzy +msgid "Orange Front Panel Connector" +msgstr "Connettore arancione pannello frontale" -msgid "Front panel line-in" -msgstr "Canale ingresso pannello frontale" +#, fuzzy +msgid "Red Front Panel Connector" +msgstr "Connettore rosso pannello frontale" -msgid "Headphones" -msgstr "Cuffie" +#, fuzzy +msgid "Yellow Front Panel Connector" +msgstr "Connettore giallo pannello frontale" -msgid "Front panel headphones" -msgstr "Cuffie pannello frontale" +msgid "Spread Output" +msgstr "" -# http://it.wikipedia.org/wiki/Pulse-Code_Modulation -msgid "PCM" -msgstr "PCM" +msgid "Downmix" +msgstr "" -msgid "Virtual mixer input" +#, fuzzy +msgid "Virtual Mixer Input" msgstr "Ingresso mixer virtuale" -msgid "Virtual mixer output" +#, fuzzy +msgid "Virtual Mixer Output" msgstr "Uscita mixer virtuale" -msgid "Virtual mixer channel configuration" -msgstr "Configurazione canale mixer virtuale" +#, fuzzy +msgid "Virtual Mixer Channels" +msgstr "Ingresso mixer virtuale" + +#, c-format +msgid "%s Function" +msgstr "" + +#, c-format +msgid "%s %d" +msgstr "" msgid "" "Could not open audio device for playback. Device is being used by another " @@ -313,6 +463,75 @@ msgstr "Questo dispositivo audio non supporta la registrazione." msgid "Error recording from audio device." msgstr "Errore nel registrare dal dispositivo audio." +#~ msgid "PCM 1" +#~ msgstr "PCM 1" + +#~ msgid "PCM 2" +#~ msgstr "PCM 2" + +#~ msgid "PCM 3" +#~ msgstr "PCM 3" + +#~ msgid "PCM 4" +#~ msgstr "PCM 4" + +#~ msgid "Green connector function" +#~ msgstr "Funzione connettore verde" + +#~ msgid "Green front panel connector function" +#~ msgstr "Funzione connettore verde pannello frontale" + +#~ msgid "Pink connector function" +#~ msgstr "Funzione connettore rosa" + +#~ msgid "Pink front panel connector function" +#~ msgstr "Funzione connettore rosa pannello frontale" + +#~ msgid "Blue connector function" +#~ msgstr "Funzione connettore blu" + +#~ msgid "Blue front panel connector function" +#~ msgstr "Funzione connettore blu pannello frontale" + +#~ msgid "Orange connector function" +#~ msgstr "Funzione connettore arancione" + +#~ msgid "Orange front panel connector function" +#~ msgstr "Funzione connettore arancione pannello frontale" + +#~ msgid "Black connector function" +#~ msgstr "Funzione connettore nero" + +#~ msgid "Black front panel connector function" +#~ msgstr "Funzione connettore nero pannello frontale" + +#~ msgid "Gray connector function" +#~ msgstr "Funzione connettore grigio" + +#~ msgid "Gray front panel connector function" +#~ msgstr "Funzione connettore grigio pannello frontale" + +#~ msgid "White connector function" +#~ msgstr "Funzione connettore bianco" + +#~ msgid "White front panel connector function" +#~ msgstr "Funzione connettore bianco pannello frontale" + +#~ msgid "Red connector function" +#~ msgstr "Funzione connettore rosso" + +#~ msgid "Red front panel connector function" +#~ msgstr "Funzione connettore rosso pannello frontale" + +#~ msgid "Yellow connector function" +#~ msgstr "Funzione connettore giallo" + +#~ msgid "Yellow front panel connector function" +#~ msgstr "Funzione connettore giallo pannello frontale" + +#~ msgid "Virtual mixer channel configuration" +#~ msgstr "Configurazione canale mixer virtuale" + #~ msgid "Failed to configure TwoLAME encoder. Check your encoding parameters." #~ msgstr "" #~ "Configurazione dell'encoder TwoLAME non riuscita. Controllare i parametri " @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: gst-plugins-bad 0.10.11.2\n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n" -"POT-Creation-Date: 2009-06-17 21:54+0100\n" +"POT-Creation-Date: 2009-08-11 17:42+0100\n" "PO-Revision-Date: 2009-06-01 20:27+0900\n" "Last-Translator: Makoto Kato <makoto.kt@gmail.com>\n" "Language-Team: Japanese <translation-team-ja@lists.sourceforge.net>\n" @@ -70,203 +70,348 @@ msgid "" "Open Sound System is not supported by this element." msgstr "" -msgid "Fast" +msgid "Volume" msgstr "" -msgid "Low" -msgstr "低音" +msgid "Master" +msgstr "" -msgid "Medium" -msgstr "ä¸éŸ³" +msgid "Front" +msgstr "フãƒãƒ³ãƒˆ" -msgid "High" -msgstr "高音" +msgid "Rear" +msgstr "リア" -msgid "Very high" +msgid "Headphones" +msgstr "ヘッドフォン" + +#, fuzzy +msgid "Center" +msgstr "センター / LFE" + +msgid "LFE" msgstr "" -msgid "Production" -msgstr "プãƒãƒ€ã‚¯ã‚·ãƒ§ãƒ³" +#, fuzzy +msgid "Surround" +msgstr "サラウンドサウンド" -msgid "Off" -msgstr "Off" +msgid "Side" +msgstr "サイド" -msgid "On" -msgstr "On" +msgid "Built-in Speaker" +msgstr "" -msgid "Stereo" -msgstr "ステレオ" +msgid "AUX 1 Out" +msgstr "" -msgid "Surround sound" -msgstr "サラウンドサウンド" +msgid "AUX 2 Out" +msgstr "" -msgid "Input mix" -msgstr "入力ミックス" +msgid "AUX Out" +msgstr "" -msgid "Front" -msgstr "フãƒãƒ³ãƒˆ" +msgid "Bass" +msgstr "" -msgid "Rear" -msgstr "リア" +msgid "Treble" +msgstr "" -msgid "Side" -msgstr "サイド" +msgid "3D Depth" +msgstr "" -msgid "Center / LFE" -msgstr "センター / LFE" +msgid "3D Center" +msgstr "" + +msgid "3D Enhance" +msgstr "" + +#, fuzzy +msgid "Telephone" +msgstr "ヘッドフォン" msgid "Microphone" msgstr "マイクãƒãƒ•ã‚©ãƒ³" -msgid "Front panel microphone" -msgstr "フãƒãƒ³ãƒˆãƒ‘ãƒãƒ«ã®ãƒžã‚¤ã‚¯ãƒãƒ•ã‚©ãƒ³" - -msgid "Input" -msgstr "入力" +msgid "Line Out" +msgstr "" -msgid "Line-in" +#, fuzzy +msgid "Line In" msgstr "ライン入力" -msgid "PCM 1" -msgstr "PCM 1" +msgid "Internal CD" +msgstr "" -msgid "PCM 2" -msgstr "PCM 2" +msgid "Video In" +msgstr "" -msgid "PCM 3" -msgstr "PCM 3" +msgid "AUX 1 In" +msgstr "" -msgid "PCM 4" -msgstr "PCM 4" +msgid "AUX 2 In" +msgstr "" -msgid "Green connector" -msgstr "緑色コãƒã‚¯ã‚¿" +msgid "AUX In" +msgstr "" -msgid "Green front panel connector" -msgstr "緑色ã®ãƒ•ãƒãƒ³ãƒˆãƒ‘ãƒãƒ«ã®ã‚³ãƒã‚¯ã‚¿" +msgid "PCM" +msgstr "PCM" -msgid "Pink connector" -msgstr "ピンク色コãƒã‚¯ã‚¿" +msgid "Record Gain" +msgstr "" -msgid "Pink front panel connector" -msgstr "ピンク色ã®ãƒ•ãƒãƒ³ãƒˆãƒ‘ãƒãƒ«ã‚³ãƒã‚¯ã‚¿" +msgid "Output Gain" +msgstr "" -msgid "Blue connector" -msgstr "é’色コãƒã‚¯ã‚¿" +#, fuzzy +msgid "Microphone Boost" +msgstr "マイクãƒãƒ•ã‚©ãƒ³" -msgid "Blue front panel connector" +msgid "Loopback" msgstr "" -msgid "Orange connector" -msgstr "オレンジ色コãƒã‚¯ã‚¿" - -msgid "Orange front panel connector" +msgid "Diagnostic" msgstr "" -msgid "Black connector" -msgstr "黒色コãƒã‚¯ã‚¿" +msgid "Bass Boost" +msgstr "" -msgid "Black front panel connector" +msgid "Playback Ports" msgstr "" -msgid "Gray connector" -msgstr "グレー色コãƒã‚¯ã‚¿" +msgid "Input" +msgstr "入力" -msgid "Gray front panel connector" +msgid "Record Source" msgstr "" -msgid "White connector" -msgstr "白色コãƒã‚¯ã‚¿" +msgid "Monitor Source" +msgstr "" -msgid "White front panel connector" +msgid "Keyboard Beep" msgstr "" -msgid "Red connector" -msgstr "赤色コãƒã‚¯ã‚¿" +msgid "Monitor" +msgstr "" -msgid "Red front panel connector" +msgid "Simulate Stereo" msgstr "" -msgid "Yellow connector" -msgstr "黄色コãƒã‚¯ã‚¿" +msgid "Stereo" +msgstr "ステレオ" -msgid "Yellow front panel connector" -msgstr "" +#, fuzzy +msgid "Surround Sound" +msgstr "サラウンドサウンド" -msgid "Green connector function" -msgstr "緑色コãƒã‚¯ã‚¿æ©Ÿèƒ½" +#, fuzzy +msgid "Microphone Gain" +msgstr "マイクãƒãƒ•ã‚©ãƒ³" -msgid "Green front panel connector function" +msgid "Speaker Source" msgstr "" -msgid "Pink connector function" -msgstr "" +#, fuzzy +msgid "Microphone Source" +msgstr "マイクãƒãƒ•ã‚©ãƒ³" -msgid "Pink front panel connector function" +msgid "Jack" msgstr "" -msgid "Blue connector function" -msgstr "" +msgid "Center / LFE" +msgstr "センター / LFE" + +#, fuzzy +msgid "Stereo Mix" +msgstr "ステレオ" -msgid "Blue front panel connector function" +msgid "Mono Mix" msgstr "" -msgid "Orange connector function" +#, fuzzy +msgid "Input Mix" +msgstr "入力ミックス" + +msgid "SPDIF In" msgstr "" -msgid "Orange front panel connector function" +msgid "SPDIF Out" msgstr "" -msgid "Black connector function" +#, fuzzy +msgid "Microphone 1" +msgstr "マイクãƒãƒ•ã‚©ãƒ³" + +#, fuzzy +msgid "Microphone 2" +msgstr "マイクãƒãƒ•ã‚©ãƒ³" + +msgid "Digital Out" msgstr "" -msgid "Black front panel connector function" +msgid "Digital In" msgstr "" -msgid "Gray connector function" +msgid "HDMI" msgstr "" -msgid "Gray front panel connector function" +msgid "Modem" msgstr "" -msgid "White connector function" +msgid "Handset" msgstr "" -msgid "White front panel connector function" +msgid "Other" msgstr "" -msgid "Red connector function" +msgid "None" msgstr "" -msgid "Red front panel connector function" +msgid "On" +msgstr "On" + +msgid "Off" +msgstr "Off" + +msgid "Mute" msgstr "" -msgid "Yellow connector function" +msgid "Fast" msgstr "" -msgid "Yellow front panel connector function" +msgid "Very Low" msgstr "" -msgid "Front panel line-in" -msgstr "プãƒãƒ³ãƒˆãƒ‘ãƒãƒ«ã®ãƒ©ã‚¤ãƒ³å…¥åŠ›" +msgid "Low" +msgstr "低音" -msgid "Headphones" -msgstr "ヘッドフォン" +msgid "Medium" +msgstr "ä¸éŸ³" -msgid "Front panel headphones" +msgid "High" +msgstr "高音" + +#, fuzzy +msgid "Very High" +msgstr "高音" + +msgid "Production" +msgstr "プãƒãƒ€ã‚¯ã‚·ãƒ§ãƒ³" + +#, fuzzy +msgid "Front Panel Microphone" +msgstr "フãƒãƒ³ãƒˆãƒ‘ãƒãƒ«ã®ãƒžã‚¤ã‚¯ãƒãƒ•ã‚©ãƒ³" + +#, fuzzy +msgid "Front Panel Line In" +msgstr "プãƒãƒ³ãƒˆãƒ‘ãƒãƒ«ã®ãƒ©ã‚¤ãƒ³å…¥åŠ›" + +#, fuzzy +msgid "Front Panel Headphones" msgstr "フãƒãƒ³ãƒˆãƒ‘ãƒãƒ«ã®ãƒ˜ãƒƒãƒ‰ãƒ•ã‚©ãƒ³" -msgid "PCM" -msgstr "PCM" +#, fuzzy +msgid "Front Panel Line Out" +msgstr "プãƒãƒ³ãƒˆãƒ‘ãƒãƒ«ã®ãƒ©ã‚¤ãƒ³å…¥åŠ›" + +#, fuzzy +msgid "Green Connector" +msgstr "緑色コãƒã‚¯ã‚¿" + +#, fuzzy +msgid "Pink Connector" +msgstr "ピンク色コãƒã‚¯ã‚¿" + +#, fuzzy +msgid "Blue Connector" +msgstr "é’色コãƒã‚¯ã‚¿" + +#, fuzzy +msgid "White Connector" +msgstr "白色コãƒã‚¯ã‚¿" -msgid "Virtual mixer input" +#, fuzzy +msgid "Black Connector" +msgstr "黒色コãƒã‚¯ã‚¿" + +#, fuzzy +msgid "Gray Connector" +msgstr "グレー色コãƒã‚¯ã‚¿" + +#, fuzzy +msgid "Orange Connector" +msgstr "オレンジ色コãƒã‚¯ã‚¿" + +#, fuzzy +msgid "Red Connector" +msgstr "赤色コãƒã‚¯ã‚¿" + +#, fuzzy +msgid "Yellow Connector" +msgstr "黄色コãƒã‚¯ã‚¿" + +#, fuzzy +msgid "Green Front Panel Connector" +msgstr "緑色ã®ãƒ•ãƒãƒ³ãƒˆãƒ‘ãƒãƒ«ã®ã‚³ãƒã‚¯ã‚¿" + +#, fuzzy +msgid "Pink Front Panel Connector" +msgstr "ピンク色ã®ãƒ•ãƒãƒ³ãƒˆãƒ‘ãƒãƒ«ã‚³ãƒã‚¯ã‚¿" + +#, fuzzy +msgid "Blue Front Panel Connector" +msgstr "緑色ã®ãƒ•ãƒãƒ³ãƒˆãƒ‘ãƒãƒ«ã®ã‚³ãƒã‚¯ã‚¿" + +#, fuzzy +msgid "White Front Panel Connector" +msgstr "ピンク色ã®ãƒ•ãƒãƒ³ãƒˆãƒ‘ãƒãƒ«ã‚³ãƒã‚¯ã‚¿" + +#, fuzzy +msgid "Black Front Panel Connector" +msgstr "ピンク色ã®ãƒ•ãƒãƒ³ãƒˆãƒ‘ãƒãƒ«ã‚³ãƒã‚¯ã‚¿" + +#, fuzzy +msgid "Gray Front Panel Connector" +msgstr "緑色ã®ãƒ•ãƒãƒ³ãƒˆãƒ‘ãƒãƒ«ã®ã‚³ãƒã‚¯ã‚¿" + +#, fuzzy +msgid "Orange Front Panel Connector" +msgstr "緑色ã®ãƒ•ãƒãƒ³ãƒˆãƒ‘ãƒãƒ«ã®ã‚³ãƒã‚¯ã‚¿" + +#, fuzzy +msgid "Red Front Panel Connector" +msgstr "緑色ã®ãƒ•ãƒãƒ³ãƒˆãƒ‘ãƒãƒ«ã®ã‚³ãƒã‚¯ã‚¿" + +#, fuzzy +msgid "Yellow Front Panel Connector" +msgstr "緑色ã®ãƒ•ãƒãƒ³ãƒˆãƒ‘ãƒãƒ«ã®ã‚³ãƒã‚¯ã‚¿" + +msgid "Spread Output" +msgstr "" + +msgid "Downmix" +msgstr "" + +#, fuzzy +msgid "Virtual Mixer Input" msgstr "仮想ミã‚サー入力" -msgid "Virtual mixer output" +#, fuzzy +msgid "Virtual Mixer Output" msgstr "仮想ミã‚サー出力" -msgid "Virtual mixer channel configuration" -msgstr "仮想ミックスãƒãƒ£ãƒ³ãƒãƒ«è¨å®š" +#, fuzzy +msgid "Virtual Mixer Channels" +msgstr "仮想ミã‚サー入力" + +#, c-format +msgid "%s Function" +msgstr "" + +#, c-format +msgid "%s %d" +msgstr "" msgid "" "Could not open audio device for playback. Device is being used by another " @@ -304,6 +449,24 @@ msgstr "録音ã¯ã“ã®ã‚ªãƒ¼ãƒ‡ã‚£ã‚ªãƒ‡ãƒã‚¤ã‚¹ã«ã‚ˆã£ã¦ã‚µãƒãƒ¼ãƒˆã•ã‚Œ msgid "Error recording from audio device." msgstr "オーディオデãƒã‚¤ã‚¹ã‹ã‚‰ã®éŒ²éŸ³æ™‚ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚" +#~ msgid "PCM 1" +#~ msgstr "PCM 1" + +#~ msgid "PCM 2" +#~ msgstr "PCM 2" + +#~ msgid "PCM 3" +#~ msgstr "PCM 3" + +#~ msgid "PCM 4" +#~ msgstr "PCM 4" + +#~ msgid "Green connector function" +#~ msgstr "緑色コãƒã‚¯ã‚¿æ©Ÿèƒ½" + +#~ msgid "Virtual mixer channel configuration" +#~ msgstr "仮想ミックスãƒãƒ£ãƒ³ãƒãƒ«è¨å®š" + #~ msgid "Failed to configure TwoLAME encoder. Check your encoding parameters." #~ msgstr "" #~ "TwoLAME エンコーダーã®æ§‹æˆã«å¤±æ•—ã—ã¾ã—ãŸã€‚エンコーディングパラメータを" @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: gst-plugins-bad 0.10.5\n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n" -"POT-Creation-Date: 2009-06-17 21:54+0100\n" +"POT-Creation-Date: 2009-08-11 17:42+0100\n" "PO-Revision-Date: 2007-11-13 17:16+0600\n" "Last-Translator: Ilyas Bakirov <just_ilyas@yahoo.com>\n" "Language-Team: Kirghiz <i18n-team-ky-kyrgyz@lists.sourceforge.net>\n" @@ -71,202 +71,309 @@ msgid "" "Open Sound System is not supported by this element." msgstr "" -msgid "Fast" +msgid "Volume" msgstr "" -msgid "Low" +msgid "Master" msgstr "" -msgid "Medium" +msgid "Front" msgstr "" -msgid "High" +msgid "Rear" msgstr "" -msgid "Very high" +msgid "Headphones" msgstr "" -msgid "Production" +msgid "Center" msgstr "" -msgid "Off" +msgid "LFE" msgstr "" -msgid "On" +msgid "Surround" msgstr "" -msgid "Stereo" +msgid "Side" msgstr "" -msgid "Surround sound" +msgid "Built-in Speaker" msgstr "" -msgid "Input mix" +msgid "AUX 1 Out" msgstr "" -msgid "Front" +msgid "AUX 2 Out" msgstr "" -msgid "Rear" +msgid "AUX Out" msgstr "" -msgid "Side" +msgid "Bass" msgstr "" -msgid "Center / LFE" +msgid "Treble" +msgstr "" + +msgid "3D Depth" +msgstr "" + +msgid "3D Center" +msgstr "" + +msgid "3D Enhance" +msgstr "" + +msgid "Telephone" msgstr "" msgid "Microphone" msgstr "" -msgid "Front panel microphone" +msgid "Line Out" +msgstr "" + +msgid "Line In" +msgstr "" + +msgid "Internal CD" +msgstr "" + +msgid "Video In" +msgstr "" + +msgid "AUX 1 In" +msgstr "" + +msgid "AUX 2 In" +msgstr "" + +msgid "AUX In" +msgstr "" + +msgid "PCM" +msgstr "" + +msgid "Record Gain" +msgstr "" + +msgid "Output Gain" +msgstr "" + +msgid "Microphone Boost" +msgstr "" + +msgid "Loopback" +msgstr "" + +msgid "Diagnostic" +msgstr "" + +msgid "Bass Boost" +msgstr "" + +msgid "Playback Ports" msgstr "" msgid "Input" msgstr "" -msgid "Line-in" +msgid "Record Source" msgstr "" -msgid "PCM 1" +msgid "Monitor Source" msgstr "" -msgid "PCM 2" +msgid "Keyboard Beep" msgstr "" -msgid "PCM 3" +msgid "Monitor" msgstr "" -msgid "PCM 4" +msgid "Simulate Stereo" msgstr "" -msgid "Green connector" +msgid "Stereo" msgstr "" -msgid "Green front panel connector" +msgid "Surround Sound" msgstr "" -msgid "Pink connector" +msgid "Microphone Gain" msgstr "" -msgid "Pink front panel connector" +msgid "Speaker Source" msgstr "" -msgid "Blue connector" +msgid "Microphone Source" msgstr "" -msgid "Blue front panel connector" +msgid "Jack" msgstr "" -msgid "Orange connector" +msgid "Center / LFE" msgstr "" -msgid "Orange front panel connector" +msgid "Stereo Mix" msgstr "" -msgid "Black connector" +msgid "Mono Mix" msgstr "" -msgid "Black front panel connector" +msgid "Input Mix" msgstr "" -msgid "Gray connector" +msgid "SPDIF In" msgstr "" -msgid "Gray front panel connector" +msgid "SPDIF Out" msgstr "" -msgid "White connector" +msgid "Microphone 1" msgstr "" -msgid "White front panel connector" +msgid "Microphone 2" msgstr "" -msgid "Red connector" +msgid "Digital Out" msgstr "" -msgid "Red front panel connector" +msgid "Digital In" msgstr "" -msgid "Yellow connector" +msgid "HDMI" msgstr "" -msgid "Yellow front panel connector" +msgid "Modem" msgstr "" -msgid "Green connector function" +msgid "Handset" msgstr "" -msgid "Green front panel connector function" +msgid "Other" msgstr "" -msgid "Pink connector function" +msgid "None" msgstr "" -msgid "Pink front panel connector function" +msgid "On" msgstr "" -msgid "Blue connector function" +msgid "Off" msgstr "" -msgid "Blue front panel connector function" +msgid "Mute" msgstr "" -msgid "Orange connector function" +msgid "Fast" msgstr "" -msgid "Orange front panel connector function" +msgid "Very Low" msgstr "" -msgid "Black connector function" +msgid "Low" msgstr "" -msgid "Black front panel connector function" +msgid "Medium" msgstr "" -msgid "Gray connector function" +msgid "High" msgstr "" -msgid "Gray front panel connector function" +msgid "Very High" msgstr "" -msgid "White connector function" +msgid "Production" msgstr "" -msgid "White front panel connector function" +msgid "Front Panel Microphone" msgstr "" -msgid "Red connector function" +msgid "Front Panel Line In" msgstr "" -msgid "Red front panel connector function" +msgid "Front Panel Headphones" msgstr "" -msgid "Yellow connector function" +msgid "Front Panel Line Out" msgstr "" -msgid "Yellow front panel connector function" +msgid "Green Connector" msgstr "" -msgid "Front panel line-in" +msgid "Pink Connector" msgstr "" -msgid "Headphones" +msgid "Blue Connector" msgstr "" -msgid "Front panel headphones" +msgid "White Connector" msgstr "" -msgid "PCM" +msgid "Black Connector" +msgstr "" + +msgid "Gray Connector" +msgstr "" + +msgid "Orange Connector" +msgstr "" + +msgid "Red Connector" +msgstr "" + +msgid "Yellow Connector" +msgstr "" + +msgid "Green Front Panel Connector" +msgstr "" + +msgid "Pink Front Panel Connector" +msgstr "" + +msgid "Blue Front Panel Connector" +msgstr "" + +msgid "White Front Panel Connector" +msgstr "" + +msgid "Black Front Panel Connector" +msgstr "" + +msgid "Gray Front Panel Connector" +msgstr "" + +msgid "Orange Front Panel Connector" +msgstr "" + +msgid "Red Front Panel Connector" msgstr "" -msgid "Virtual mixer input" +msgid "Yellow Front Panel Connector" msgstr "" -msgid "Virtual mixer output" +msgid "Spread Output" msgstr "" -msgid "Virtual mixer channel configuration" +msgid "Downmix" +msgstr "" + +msgid "Virtual Mixer Input" +msgstr "" + +msgid "Virtual Mixer Output" +msgstr "" + +msgid "Virtual Mixer Channels" +msgstr "" + +#, c-format +msgid "%s Function" +msgstr "" + +#, c-format +msgid "%s %d" msgstr "" msgid "" @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: gst-plugins-bad-0.10.6.3\n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n" -"POT-Creation-Date: 2009-06-17 21:54+0100\n" +"POT-Creation-Date: 2009-08-11 17:42+0100\n" "PO-Revision-Date: 2008-05-14 02:13+0300\n" "Last-Translator: Gintautas Miliauskas <gintas@akl.lt>\n" "Language-Team: Lithuanian <komp_lt@konferencijos.lt>\n" @@ -75,202 +75,309 @@ msgid "" "Open Sound System is not supported by this element." msgstr "" -msgid "Fast" +msgid "Volume" msgstr "" -msgid "Low" +msgid "Master" msgstr "" -msgid "Medium" +msgid "Front" msgstr "" -msgid "High" +msgid "Rear" msgstr "" -msgid "Very high" +msgid "Headphones" msgstr "" -msgid "Production" +msgid "Center" msgstr "" -msgid "Off" +msgid "LFE" msgstr "" -msgid "On" +msgid "Surround" msgstr "" -msgid "Stereo" +msgid "Side" msgstr "" -msgid "Surround sound" +msgid "Built-in Speaker" msgstr "" -msgid "Input mix" +msgid "AUX 1 Out" msgstr "" -msgid "Front" +msgid "AUX 2 Out" msgstr "" -msgid "Rear" +msgid "AUX Out" msgstr "" -msgid "Side" +msgid "Bass" msgstr "" -msgid "Center / LFE" +msgid "Treble" +msgstr "" + +msgid "3D Depth" +msgstr "" + +msgid "3D Center" +msgstr "" + +msgid "3D Enhance" +msgstr "" + +msgid "Telephone" msgstr "" msgid "Microphone" msgstr "" -msgid "Front panel microphone" +msgid "Line Out" +msgstr "" + +msgid "Line In" +msgstr "" + +msgid "Internal CD" +msgstr "" + +msgid "Video In" +msgstr "" + +msgid "AUX 1 In" +msgstr "" + +msgid "AUX 2 In" +msgstr "" + +msgid "AUX In" +msgstr "" + +msgid "PCM" +msgstr "" + +msgid "Record Gain" +msgstr "" + +msgid "Output Gain" +msgstr "" + +msgid "Microphone Boost" +msgstr "" + +msgid "Loopback" +msgstr "" + +msgid "Diagnostic" +msgstr "" + +msgid "Bass Boost" +msgstr "" + +msgid "Playback Ports" msgstr "" msgid "Input" msgstr "" -msgid "Line-in" +msgid "Record Source" msgstr "" -msgid "PCM 1" +msgid "Monitor Source" msgstr "" -msgid "PCM 2" +msgid "Keyboard Beep" msgstr "" -msgid "PCM 3" +msgid "Monitor" msgstr "" -msgid "PCM 4" +msgid "Simulate Stereo" msgstr "" -msgid "Green connector" +msgid "Stereo" msgstr "" -msgid "Green front panel connector" +msgid "Surround Sound" msgstr "" -msgid "Pink connector" +msgid "Microphone Gain" msgstr "" -msgid "Pink front panel connector" +msgid "Speaker Source" msgstr "" -msgid "Blue connector" +msgid "Microphone Source" msgstr "" -msgid "Blue front panel connector" +msgid "Jack" msgstr "" -msgid "Orange connector" +msgid "Center / LFE" msgstr "" -msgid "Orange front panel connector" +msgid "Stereo Mix" msgstr "" -msgid "Black connector" +msgid "Mono Mix" msgstr "" -msgid "Black front panel connector" +msgid "Input Mix" msgstr "" -msgid "Gray connector" +msgid "SPDIF In" msgstr "" -msgid "Gray front panel connector" +msgid "SPDIF Out" msgstr "" -msgid "White connector" +msgid "Microphone 1" msgstr "" -msgid "White front panel connector" +msgid "Microphone 2" msgstr "" -msgid "Red connector" +msgid "Digital Out" msgstr "" -msgid "Red front panel connector" +msgid "Digital In" msgstr "" -msgid "Yellow connector" +msgid "HDMI" msgstr "" -msgid "Yellow front panel connector" +msgid "Modem" msgstr "" -msgid "Green connector function" +msgid "Handset" msgstr "" -msgid "Green front panel connector function" +msgid "Other" msgstr "" -msgid "Pink connector function" +msgid "None" msgstr "" -msgid "Pink front panel connector function" +msgid "On" msgstr "" -msgid "Blue connector function" +msgid "Off" msgstr "" -msgid "Blue front panel connector function" +msgid "Mute" msgstr "" -msgid "Orange connector function" +msgid "Fast" msgstr "" -msgid "Orange front panel connector function" +msgid "Very Low" msgstr "" -msgid "Black connector function" +msgid "Low" msgstr "" -msgid "Black front panel connector function" +msgid "Medium" msgstr "" -msgid "Gray connector function" +msgid "High" msgstr "" -msgid "Gray front panel connector function" +msgid "Very High" msgstr "" -msgid "White connector function" +msgid "Production" msgstr "" -msgid "White front panel connector function" +msgid "Front Panel Microphone" msgstr "" -msgid "Red connector function" +msgid "Front Panel Line In" msgstr "" -msgid "Red front panel connector function" +msgid "Front Panel Headphones" msgstr "" -msgid "Yellow connector function" +msgid "Front Panel Line Out" msgstr "" -msgid "Yellow front panel connector function" +msgid "Green Connector" msgstr "" -msgid "Front panel line-in" +msgid "Pink Connector" msgstr "" -msgid "Headphones" +msgid "Blue Connector" msgstr "" -msgid "Front panel headphones" +msgid "White Connector" msgstr "" -msgid "PCM" +msgid "Black Connector" +msgstr "" + +msgid "Gray Connector" +msgstr "" + +msgid "Orange Connector" +msgstr "" + +msgid "Red Connector" +msgstr "" + +msgid "Yellow Connector" +msgstr "" + +msgid "Green Front Panel Connector" +msgstr "" + +msgid "Pink Front Panel Connector" +msgstr "" + +msgid "Blue Front Panel Connector" +msgstr "" + +msgid "White Front Panel Connector" +msgstr "" + +msgid "Black Front Panel Connector" +msgstr "" + +msgid "Gray Front Panel Connector" +msgstr "" + +msgid "Orange Front Panel Connector" +msgstr "" + +msgid "Red Front Panel Connector" msgstr "" -msgid "Virtual mixer input" +msgid "Yellow Front Panel Connector" msgstr "" -msgid "Virtual mixer output" +msgid "Spread Output" msgstr "" -msgid "Virtual mixer channel configuration" +msgid "Downmix" +msgstr "" + +msgid "Virtual Mixer Input" +msgstr "" + +msgid "Virtual Mixer Output" +msgstr "" + +msgid "Virtual Mixer Channels" +msgstr "" + +#, c-format +msgid "%s Function" +msgstr "" + +#, c-format +msgid "%s %d" msgstr "" msgid "" diff --git a/po/lv.po b/po/lv.po new file mode 100644 index 00000000..8471d3ab --- /dev/null +++ b/po/lv.po @@ -0,0 +1,524 @@ +# Latvian translation of gst-plugins-bad +# This file is put in the public domain. +# Arvis LÄcis <arvis.lacis@inbox.lv>, 2009. +# +msgid "" +msgstr "" +"Project-Id-Version: gst-plugins-bad 0.10.12.3\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n" +"POT-Creation-Date: 2009-08-11 17:42+0100\n" +"PO-Revision-Date: 2009-07-30 11:40+0100\n" +"Last-Translator: Rihards PriedÄ«tis <rprieditis@gmail.com>\n" +"Language-Team: Latvian <translation-team-lv@lists.sourceforge.net>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-Language: Latvian\n" +"X-Poedit-Country: LATVIA\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : " +"2);\n" + +msgid "Could not read title information for DVD." +msgstr "NevarÄ“ja nolasÄ«t virsrakstu informÄciju no DVD." + +#, c-format +msgid "Failed to open DVD device '%s'." +msgstr "NeizdevÄs atvÄ“rt DVD ierÄ«ci '%s'." + +msgid "Failed to set PGC based seeking." +msgstr "NeizdevÄs uzstÄdÄ«t PCG balstÄ«to meklÄ“Å¡anu." + +msgid "Internal clock error." +msgstr "IekÅ¡Ä“jÄ pulksteņa kļūda." + +msgid "Internal data flow error." +msgstr "IekÅ¡Ä“jÄ datu plÅ«smas kļūda." + +msgid "No file name specified for writing." +msgstr "IerakstÄ«Å¡anai nav norÄdÄ«ts neviens faila nosaukums." + +#, c-format +msgid "Could not open file \"%s\" for writing." +msgstr "Nav iespÄ“jams atvÄ“rt failu \"%s\" ierakstÄ«Å¡anai." + +msgid "Internal data stream error." +msgstr "IekÅ¡Ä“jÄs datu plÅ«smas kļūda." + +#, c-format +msgid "Could not write to file \"%s\"." +msgstr "NevarÄ“ja ierakstÄ«t failÄ \"%s\"." + +#, c-format +msgid "Device \"%s\" does not exist." +msgstr "IerÄ«ce \"%s\" neeksistÄ“." + +#, c-format +msgid "Could not open frontend device \"%s\"." +msgstr "Nav iespÄ“jams atvÄ“rt priekÅ¡Ä“jo ierÄ«ci \"%s\"." + +#, c-format +msgid "Could not get settings from frontend device \"%s\"." +msgstr "Nav iespÄ“jams iegÅ«t uzstÄdÄ«jumus no priekÅ¡Ä“jÄs ierÄ«ces \"%s\"." + +#, c-format +msgid "Could not open file \"%s\" for reading." +msgstr "Nav iespÄ“jams atvÄ“rt failu \"%s\" lasÄ«Å¡anai." + +msgid "Could not open audio device for mixer control handling." +msgstr "Nav iespÄ“jams atvÄ“rt audio ierÄ«ci jaucÄ“ja kontroles vadÄ«Å¡anai." + +msgid "" +"Could not open audio device for mixer control handling. This version of the " +"Open Sound System is not supported by this element." +msgstr "" +"Nav iespÄ“jams atvÄ“rt audio ierÄ«ci jaucÄ“ja kontroles vadÄ«Å¡anai. Å is elements " +"neatbalsta Å¡o Open Sound System versiju." + +msgid "Volume" +msgstr "" + +#, fuzzy +msgid "Master" +msgstr "Ä€trs" + +msgid "Front" +msgstr "PriekÅ¡puse" + +msgid "Rear" +msgstr "Aizmugure" + +msgid "Headphones" +msgstr "Austiņas" + +#, fuzzy +msgid "Center" +msgstr "CentrÄlais / LFE" + +msgid "LFE" +msgstr "" + +#, fuzzy +msgid "Surround" +msgstr "IeskaujoÅ¡a skaņa" + +msgid "Side" +msgstr "Puse" + +msgid "Built-in Speaker" +msgstr "" + +msgid "AUX 1 Out" +msgstr "" + +msgid "AUX 2 Out" +msgstr "" + +msgid "AUX Out" +msgstr "" + +msgid "Bass" +msgstr "" + +msgid "Treble" +msgstr "" + +msgid "3D Depth" +msgstr "" + +msgid "3D Center" +msgstr "" + +msgid "3D Enhance" +msgstr "" + +#, fuzzy +msgid "Telephone" +msgstr "Austiņas" + +msgid "Microphone" +msgstr "Mikrofons" + +msgid "Line Out" +msgstr "" + +#, fuzzy +msgid "Line In" +msgstr "Line-in" + +msgid "Internal CD" +msgstr "" + +msgid "Video In" +msgstr "" + +msgid "AUX 1 In" +msgstr "" + +msgid "AUX 2 In" +msgstr "" + +msgid "AUX In" +msgstr "" + +msgid "PCM" +msgstr "PCM" + +msgid "Record Gain" +msgstr "" + +msgid "Output Gain" +msgstr "" + +#, fuzzy +msgid "Microphone Boost" +msgstr "Mikrofons" + +msgid "Loopback" +msgstr "" + +msgid "Diagnostic" +msgstr "" + +msgid "Bass Boost" +msgstr "" + +msgid "Playback Ports" +msgstr "" + +msgid "Input" +msgstr "Ievade" + +msgid "Record Source" +msgstr "" + +msgid "Monitor Source" +msgstr "" + +msgid "Keyboard Beep" +msgstr "" + +msgid "Monitor" +msgstr "" + +msgid "Simulate Stereo" +msgstr "" + +msgid "Stereo" +msgstr "Stereo" + +#, fuzzy +msgid "Surround Sound" +msgstr "IeskaujoÅ¡a skaņa" + +#, fuzzy +msgid "Microphone Gain" +msgstr "Mikrofons" + +msgid "Speaker Source" +msgstr "" + +#, fuzzy +msgid "Microphone Source" +msgstr "Mikrofons" + +msgid "Jack" +msgstr "" + +msgid "Center / LFE" +msgstr "CentrÄlais / LFE" + +#, fuzzy +msgid "Stereo Mix" +msgstr "Stereo" + +msgid "Mono Mix" +msgstr "" + +#, fuzzy +msgid "Input Mix" +msgstr "Ievades jaukÅ¡ana" + +msgid "SPDIF In" +msgstr "" + +msgid "SPDIF Out" +msgstr "" + +#, fuzzy +msgid "Microphone 1" +msgstr "Mikrofons" + +#, fuzzy +msgid "Microphone 2" +msgstr "Mikrofons" + +msgid "Digital Out" +msgstr "" + +msgid "Digital In" +msgstr "" + +msgid "HDMI" +msgstr "" + +msgid "Modem" +msgstr "" + +msgid "Handset" +msgstr "" + +msgid "Other" +msgstr "" + +msgid "None" +msgstr "" + +msgid "On" +msgstr "IeslÄ“gts" + +msgid "Off" +msgstr "IzslÄ“gts" + +msgid "Mute" +msgstr "" + +msgid "Fast" +msgstr "Ä€trs" + +msgid "Very Low" +msgstr "" + +msgid "Low" +msgstr "Zems" + +msgid "Medium" +msgstr "VidÄ“js" + +msgid "High" +msgstr "Augsts" + +#, fuzzy +msgid "Very High" +msgstr "Ä»oti augsts" + +msgid "Production" +msgstr "IzstrÄde" + +#, fuzzy +msgid "Front Panel Microphone" +msgstr "PriekÅ¡Ä“jÄ paneļa nikrofons" + +#, fuzzy +msgid "Front Panel Line In" +msgstr "PriekÅ¡Ä“jÄ paneļa line-in" + +#, fuzzy +msgid "Front Panel Headphones" +msgstr "PriekÅ¡Ä“jÄ paneļa austiņas" + +#, fuzzy +msgid "Front Panel Line Out" +msgstr "PriekÅ¡Ä“jÄ paneļa line-in" + +#, fuzzy +msgid "Green Connector" +msgstr "Zaļais savienotÄjs" + +#, fuzzy +msgid "Pink Connector" +msgstr "RozÄ savienotÄjs" + +#, fuzzy +msgid "Blue Connector" +msgstr "Zilais savienotÄjs" + +#, fuzzy +msgid "White Connector" +msgstr "Baltais savienotÄjs" + +#, fuzzy +msgid "Black Connector" +msgstr "Melnais savienotÄjs" + +#, fuzzy +msgid "Gray Connector" +msgstr "PelÄ“kais savienotÄjs" + +#, fuzzy +msgid "Orange Connector" +msgstr "Oranžais savienotÄjs" + +#, fuzzy +msgid "Red Connector" +msgstr "Sarkanais savienotÄjs" + +#, fuzzy +msgid "Yellow Connector" +msgstr "Dzeltenais savienotÄjs" + +#, fuzzy +msgid "Green Front Panel Connector" +msgstr "Zaļais priekÅ¡Ä“jÄ paneļa savienotÄjs" + +#, fuzzy +msgid "Pink Front Panel Connector" +msgstr "RozÄ priekÅ¡Ä“jÄ paneļa savienotÄjs" + +#, fuzzy +msgid "Blue Front Panel Connector" +msgstr "Zilais priekÅ¡Ä“jÄ paneļa savienotÄjs" + +#, fuzzy +msgid "White Front Panel Connector" +msgstr "Baltais priekÅ¡Ä“jÄ paneļa savienotÄjs" + +#, fuzzy +msgid "Black Front Panel Connector" +msgstr "Melnais priekÅ¡Ä“jÄ paneļa savienotÄjs" + +#, fuzzy +msgid "Gray Front Panel Connector" +msgstr "PelÄ“kais priekÅ¡Ä“jÄ paneļa savienotÄjs" + +#, fuzzy +msgid "Orange Front Panel Connector" +msgstr "Oranžais priekÅ¡Ä“jÄ paneļa savienotÄjs" + +#, fuzzy +msgid "Red Front Panel Connector" +msgstr "Sarkanais priekÅ¡Ä“jÄ paneļa savienotÄjs" + +#, fuzzy +msgid "Yellow Front Panel Connector" +msgstr "Dzeltenais priekÅ¡Ä“jÄ paneļa savienotÄjs" + +msgid "Spread Output" +msgstr "" + +msgid "Downmix" +msgstr "" + +#, fuzzy +msgid "Virtual Mixer Input" +msgstr "VirtuÄlÄ jaucÄ“ja ieeja" + +#, fuzzy +msgid "Virtual Mixer Output" +msgstr "VirtuÄlÄ jaucÄ“ja izeja" + +#, fuzzy +msgid "Virtual Mixer Channels" +msgstr "VirtuÄlÄ jaucÄ“ja ieeja" + +#, c-format +msgid "%s Function" +msgstr "" + +#, c-format +msgid "%s %d" +msgstr "" + +msgid "" +"Could not open audio device for playback. Device is being used by another " +"application." +msgstr "" +"Nav iespÄ“jams atvÄ“rt audio ierÄ«ci atskaņoÅ¡anai. IerÄ«ci paÅ¡laik izmanto cita " +"programma." + +msgid "" +"Could not open audio device for playback. You don't have permission to open " +"the device." +msgstr "" +"Nav iespÄ“jams atvÄ“rt audio ierÄ«ci atskaņoÅ¡anai. Jums nav nepiecieÅ¡amÄs " +"atļaujas, lai atvÄ“rtu ierÄ«ci." + +msgid "Could not open audio device for playback." +msgstr "Nav iespÄ“jams atvÄ“rt audio ierÄ«ci atskaņoÅ¡anai." + +msgid "" +"Could not open audio device for playback. This version of the Open Sound " +"System is not supported by this element." +msgstr "" +"Nav iespÄ“jams atvÄ“rt audio ierÄ«ci atskaņoÅ¡anai. Å is elements neatbalsta Å¡o " +"Open Sound System versiju." + +msgid "Playback is not supported by this audio device." +msgstr "Å Ä« audio ierÄ«ce neatbalsta atskaņoÅ¡anu." + +msgid "Audio playback error." +msgstr "Audio atskaņoÅ¡anas kļūda." + +msgid "Recording is not supported by this audio device." +msgstr "Å Ä« audio ierÄ«ce neatbalsta ierakstÄ«Å¡anu." + +msgid "Error recording from audio device." +msgstr "RadÄs kļūda ierakstot no audio ierÄ«ces." + +#~ msgid "PCM 1" +#~ msgstr "PCM 1" + +#~ msgid "PCM 2" +#~ msgstr "PCM 2" + +#~ msgid "PCM 3" +#~ msgstr "PCM 3" + +#~ msgid "PCM 4" +#~ msgstr "PCM 4" + +#~ msgid "Green connector function" +#~ msgstr "ZaÄ¼Ä savienotÄja funkcija" + +#~ msgid "Green front panel connector function" +#~ msgstr "ZaÄ¼Ä priekÅ¡Ä“jÄ paneļa savienotÄja funkcija" + +#~ msgid "Pink connector function" +#~ msgstr "RozÄ savienotÄja funkcija" + +#~ msgid "Pink front panel connector function" +#~ msgstr "RozÄ priekÅ¡Ä“jÄ paneļa savienotÄja funkcija" + +#~ msgid "Blue connector function" +#~ msgstr "ZilÄ savienotÄja funkcija" + +#~ msgid "Blue front panel connector function" +#~ msgstr "ZilÄ priekÅ¡Ä“jÄ paneļa savienotÄja funkcija" + +#~ msgid "Orange connector function" +#~ msgstr "OranÅ¾Ä savienotÄja funkcija" + +#~ msgid "Orange front panel connector function" +#~ msgstr "OranÅ¾Ä priekÅ¡Ä“jÄ paneļa savienotÄja funkcija" + +#~ msgid "Black connector function" +#~ msgstr "MelnÄ savienotÄja funkcija" + +#~ msgid "Black front panel connector function" +#~ msgstr "MelnÄ priekÅ¡Ä“jÄ paneļa savienotÄja funkcija" + +#~ msgid "Gray connector function" +#~ msgstr "PelÄ“kÄ savienotÄja funkcija" + +#~ msgid "Gray front panel connector function" +#~ msgstr "PelÄ“kÄ priekÅ¡Ä“jÄ paneļa savienotÄja funkcija" + +#~ msgid "White connector function" +#~ msgstr "BaltÄ savienotÄja funkcija" + +#~ msgid "White front panel connector function" +#~ msgstr "BaltÄ priekÅ¡Ä“jÄ paneļa savienotÄja funkcija" + +#~ msgid "Red connector function" +#~ msgstr "SarkanÄ savienotÄja funkcija" + +#~ msgid "Red front panel connector function" +#~ msgstr "SarkanÄ priekÅ¡Ä“jÄ paneļa savienotÄja funkcija" + +#~ msgid "Yellow connector function" +#~ msgstr "DzeltenÄ savienotÄja funkcija" + +#~ msgid "Yellow front panel connector function" +#~ msgstr "DzeltenÄ priekÅ¡Ä“jÄ paneļa savienotÄja funkcija" + +#~ msgid "Virtual mixer channel configuration" +#~ msgstr "VirtuÄlÄ jaucÄ“ja kanÄlu konfigurÄcija" @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: gst-plugins-bad-0.10.8.3\n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n" -"POT-Creation-Date: 2009-06-17 21:54+0100\n" +"POT-Creation-Date: 2009-08-11 17:42+0100\n" "PO-Revision-Date: 2008-10-26 20:27+0100\n" "Last-Translator: Michel Bugeja <michelbugeja@rabatmalta.com>\n" "Language-Team: Maltese <translation-team-mt@lists.sourceforge.net>\n" @@ -73,203 +73,349 @@ msgstr "" "Ma nistax niftaħ apparat tal-awdjo għal mixer control handling. Din il-" "verzjoni ta' Open Sound System mhux issapportjata minn din l-element." -msgid "Fast" +msgid "Volume" +msgstr "" + +#, fuzzy +msgid "Master" msgstr "Fast" -msgid "Low" -msgstr "Low" +msgid "Front" +msgstr "Quddiem" -msgid "Medium" -msgstr "Medium" +msgid "Rear" +msgstr "Wara" -msgid "High" -msgstr "High" +msgid "Headphones" +msgstr "Headphones" -msgid "Very high" -msgstr "Very high" +#, fuzzy +msgid "Center" +msgstr "Center / LFE" -msgid "Production" -msgstr "Production" +msgid "LFE" +msgstr "" -msgid "Off" -msgstr "Off" +#, fuzzy +msgid "Surround" +msgstr "Surround sound" -msgid "On" -msgstr "On" +msgid "Side" +msgstr "Ä enb" + +msgid "Built-in Speaker" +msgstr "" + +msgid "AUX 1 Out" +msgstr "" + +msgid "AUX 2 Out" +msgstr "" + +msgid "AUX Out" +msgstr "" + +msgid "Bass" +msgstr "" + +msgid "Treble" +msgstr "" + +msgid "3D Depth" +msgstr "" + +msgid "3D Center" +msgstr "" + +msgid "3D Enhance" +msgstr "" + +#, fuzzy +msgid "Telephone" +msgstr "Headphones" + +msgid "Microphone" +msgstr "Mikrofonu" + +msgid "Line Out" +msgstr "" + +#, fuzzy +msgid "Line In" +msgstr "Line-in" + +msgid "Internal CD" +msgstr "" + +msgid "Video In" +msgstr "" + +msgid "AUX 1 In" +msgstr "" + +msgid "AUX 2 In" +msgstr "" + +msgid "AUX In" +msgstr "" + +msgid "PCM" +msgstr "PCM" + +msgid "Record Gain" +msgstr "" + +msgid "Output Gain" +msgstr "" + +#, fuzzy +msgid "Microphone Boost" +msgstr "Mikrofonu" + +msgid "Loopback" +msgstr "" + +msgid "Diagnostic" +msgstr "" + +msgid "Bass Boost" +msgstr "" + +msgid "Playback Ports" +msgstr "" + +msgid "Input" +msgstr "Input" + +msgid "Record Source" +msgstr "" + +msgid "Monitor Source" +msgstr "" + +msgid "Keyboard Beep" +msgstr "" + +msgid "Monitor" +msgstr "" + +msgid "Simulate Stereo" +msgstr "" msgid "Stereo" msgstr "Stereo" -msgid "Surround sound" +#, fuzzy +msgid "Surround Sound" msgstr "Surround sound" -msgid "Input mix" -msgstr "Input mix" +#, fuzzy +msgid "Microphone Gain" +msgstr "Mikrofonu" -msgid "Front" -msgstr "Quddiem" +msgid "Speaker Source" +msgstr "" -msgid "Rear" -msgstr "Wara" +#, fuzzy +msgid "Microphone Source" +msgstr "Mikrofonu" -msgid "Side" -msgstr "Ä enb" +msgid "Jack" +msgstr "" msgid "Center / LFE" msgstr "Center / LFE" -msgid "Microphone" -msgstr "Mikrofonu" +#, fuzzy +msgid "Stereo Mix" +msgstr "Stereo" -msgid "Front panel microphone" -msgstr "Mikrofonu tal-panella ta' quddiem" +msgid "Mono Mix" +msgstr "" -msgid "Input" -msgstr "Input" +#, fuzzy +msgid "Input Mix" +msgstr "Input mix" -msgid "Line-in" -msgstr "Line-in" +msgid "SPDIF In" +msgstr "" -msgid "PCM 1" -msgstr "PCM 1" +msgid "SPDIF Out" +msgstr "" -msgid "PCM 2" -msgstr "PCM 2" +#, fuzzy +msgid "Microphone 1" +msgstr "Mikrofonu" -msgid "PCM 3" -msgstr "PCM 3" +#, fuzzy +msgid "Microphone 2" +msgstr "Mikrofonu" -msgid "PCM 4" -msgstr "PCM 4" +msgid "Digital Out" +msgstr "" -msgid "Green connector" -msgstr "Connector aħdar" +msgid "Digital In" +msgstr "" -msgid "Green front panel connector" -msgstr "Front panel connector aħdar" +msgid "HDMI" +msgstr "" -msgid "Pink connector" -msgstr "Connector roża" +msgid "Modem" +msgstr "" -msgid "Pink front panel connector" -msgstr "Front panel connector roża" +msgid "Handset" +msgstr "" -msgid "Blue connector" -msgstr "Connector Blu" +msgid "Other" +msgstr "" -msgid "Blue front panel connector" -msgstr "Front panel connector blu" +msgid "None" +msgstr "" -msgid "Orange connector" -msgstr "Connector oranÄ¡jo" +msgid "On" +msgstr "On" -msgid "Orange front panel connector" -msgstr "Front Panel connector oranÄ¡jo" +msgid "Off" +msgstr "Off" -msgid "Black connector" -msgstr "Connector iswed" +msgid "Mute" +msgstr "" -msgid "Black front panel connector" -msgstr "Front panel connector iswed" +msgid "Fast" +msgstr "Fast" -msgid "Gray connector" -msgstr "Connector Griż" +msgid "Very Low" +msgstr "" -msgid "Gray front panel connector" -msgstr "Front panel connector Griż" +msgid "Low" +msgstr "Low" -msgid "White connector" -msgstr "Connector abjad" +msgid "Medium" +msgstr "Medium" -msgid "White front panel connector" -msgstr "Front panel connector abjad" +msgid "High" +msgstr "High" -msgid "Red connector" -msgstr "Connector aħmar" +#, fuzzy +msgid "Very High" +msgstr "Very high" -msgid "Red front panel connector" -msgstr "Front panel connector aħmar" +msgid "Production" +msgstr "Production" -msgid "Yellow connector" -msgstr "Connector isfar" +#, fuzzy +msgid "Front Panel Microphone" +msgstr "Mikrofonu tal-panella ta' quddiem" -msgid "Yellow front panel connector" -msgstr "Front panel connector isfar" +#, fuzzy +msgid "Front Panel Line In" +msgstr "Front panel line-in" -msgid "Green connector function" -msgstr "Connector function aħdar" +#, fuzzy +msgid "Front Panel Headphones" +msgstr "Front panel headphones" -msgid "Green front panel connector function" -msgstr "Front panel connector function aħdar" +#, fuzzy +msgid "Front Panel Line Out" +msgstr "Front panel line-in" -msgid "Pink connector function" -msgstr "Connector function roża" +#, fuzzy +msgid "Green Connector" +msgstr "Connector aħdar" -msgid "Pink front panel connector function" -msgstr "Front panel connector function roża" +#, fuzzy +msgid "Pink Connector" +msgstr "Connector roża" -msgid "Blue connector function" -msgstr "Connector function blu" +#, fuzzy +msgid "Blue Connector" +msgstr "Connector Blu" -msgid "Blue front panel connector function" -msgstr "Front panel connector function blu" +#, fuzzy +msgid "White Connector" +msgstr "Connector abjad" -msgid "Orange connector function" -msgstr "Connector function oranÄ¡jo" +#, fuzzy +msgid "Black Connector" +msgstr "Connector iswed" -msgid "Orange front panel connector function" -msgstr "Front panel connector function oranÄ¡jo" +#, fuzzy +msgid "Gray Connector" +msgstr "Connector Griż" -msgid "Black connector function" -msgstr "Connector function iswed" +#, fuzzy +msgid "Orange Connector" +msgstr "Connector oranÄ¡jo" -msgid "Black front panel connector function" -msgstr "Front panel connector function iswed" +#, fuzzy +msgid "Red Connector" +msgstr "Connector aħmar" -msgid "Gray connector function" -msgstr "Connector function griż" +#, fuzzy +msgid "Yellow Connector" +msgstr "Connector isfar" -msgid "Gray front panel connector function" -msgstr "Front panel connector function griż" +#, fuzzy +msgid "Green Front Panel Connector" +msgstr "Front panel connector aħdar" -msgid "White connector function" -msgstr "Connector function abjad" +#, fuzzy +msgid "Pink Front Panel Connector" +msgstr "Front panel connector roża" -msgid "White front panel connector function" -msgstr "Front panel connector function abjad" +#, fuzzy +msgid "Blue Front Panel Connector" +msgstr "Front panel connector blu" -msgid "Red connector function" -msgstr "Connector function aħmar" +#, fuzzy +msgid "White Front Panel Connector" +msgstr "Front panel connector abjad" -msgid "Red front panel connector function" -msgstr "Front panel connector function aħmar" +#, fuzzy +msgid "Black Front Panel Connector" +msgstr "Front panel connector iswed" -msgid "Yellow connector function" -msgstr "Connector function isfar" +#, fuzzy +msgid "Gray Front Panel Connector" +msgstr "Front panel connector Griż" -msgid "Yellow front panel connector function" -msgstr "Front panel connector function isfar" +#, fuzzy +msgid "Orange Front Panel Connector" +msgstr "Front Panel connector oranÄ¡jo" -msgid "Front panel line-in" -msgstr "Front panel line-in" +#, fuzzy +msgid "Red Front Panel Connector" +msgstr "Front panel connector aħmar" -msgid "Headphones" -msgstr "Headphones" +#, fuzzy +msgid "Yellow Front Panel Connector" +msgstr "Front panel connector isfar" -msgid "Front panel headphones" -msgstr "Front panel headphones" +msgid "Spread Output" +msgstr "" -msgid "PCM" -msgstr "PCM" +msgid "Downmix" +msgstr "" -msgid "Virtual mixer input" +#, fuzzy +msgid "Virtual Mixer Input" msgstr "Virtual mixer input" -msgid "Virtual mixer output" +#, fuzzy +msgid "Virtual Mixer Output" msgstr "Virtual mixer output" -msgid "Virtual mixer channel configuration" -msgstr "Virtual mixer channel configuration" +#, fuzzy +msgid "Virtual Mixer Channels" +msgstr "Virtual mixer input" + +#, c-format +msgid "%s Function" +msgstr "" + +#, c-format +msgid "%s %d" +msgstr "" msgid "" "Could not open audio device for playback. Device is being used by another " @@ -318,3 +464,72 @@ msgstr "Å»ball fl-irrekordjar mill-apparat tal-awdjo." #~ msgstr "" #~ "Il-bitrate rikjesta ta' %d kbit/s għal-property '%s' mhux permessa. Il-" #~ "bitrate Ä¡iet mibdula għal %d kbit/s. " + +#~ msgid "PCM 1" +#~ msgstr "PCM 1" + +#~ msgid "PCM 2" +#~ msgstr "PCM 2" + +#~ msgid "PCM 3" +#~ msgstr "PCM 3" + +#~ msgid "PCM 4" +#~ msgstr "PCM 4" + +#~ msgid "Green connector function" +#~ msgstr "Connector function aħdar" + +#~ msgid "Green front panel connector function" +#~ msgstr "Front panel connector function aħdar" + +#~ msgid "Pink connector function" +#~ msgstr "Connector function roża" + +#~ msgid "Pink front panel connector function" +#~ msgstr "Front panel connector function roża" + +#~ msgid "Blue connector function" +#~ msgstr "Connector function blu" + +#~ msgid "Blue front panel connector function" +#~ msgstr "Front panel connector function blu" + +#~ msgid "Orange connector function" +#~ msgstr "Connector function oranÄ¡jo" + +#~ msgid "Orange front panel connector function" +#~ msgstr "Front panel connector function oranÄ¡jo" + +#~ msgid "Black connector function" +#~ msgstr "Connector function iswed" + +#~ msgid "Black front panel connector function" +#~ msgstr "Front panel connector function iswed" + +#~ msgid "Gray connector function" +#~ msgstr "Connector function griż" + +#~ msgid "Gray front panel connector function" +#~ msgstr "Front panel connector function griż" + +#~ msgid "White connector function" +#~ msgstr "Connector function abjad" + +#~ msgid "White front panel connector function" +#~ msgstr "Front panel connector function abjad" + +#~ msgid "Red connector function" +#~ msgstr "Connector function aħmar" + +#~ msgid "Red front panel connector function" +#~ msgstr "Front panel connector function aħmar" + +#~ msgid "Yellow connector function" +#~ msgstr "Connector function isfar" + +#~ msgid "Yellow front panel connector function" +#~ msgstr "Front panel connector function isfar" + +#~ msgid "Virtual mixer channel configuration" +#~ msgstr "Virtual mixer channel configuration" @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: gst-plugins-bad 0.10.5\n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n" -"POT-Creation-Date: 2009-06-17 21:54+0100\n" +"POT-Creation-Date: 2009-08-11 17:42+0100\n" "PO-Revision-Date: 2007-11-03 14:46+0100\n" "Last-Translator: Kjartan Maraas <kmaraas@gnome.org>\n" "Language-Team: Norwegian Bokmaal <i18n-nb@lister.ping.uio.no>\n" @@ -72,202 +72,309 @@ msgid "" "Open Sound System is not supported by this element." msgstr "" -msgid "Fast" +msgid "Volume" msgstr "" -msgid "Low" +msgid "Master" msgstr "" -msgid "Medium" +msgid "Front" msgstr "" -msgid "High" +msgid "Rear" msgstr "" -msgid "Very high" +msgid "Headphones" msgstr "" -msgid "Production" +msgid "Center" msgstr "" -msgid "Off" +msgid "LFE" msgstr "" -msgid "On" +msgid "Surround" msgstr "" -msgid "Stereo" +msgid "Side" msgstr "" -msgid "Surround sound" +msgid "Built-in Speaker" msgstr "" -msgid "Input mix" +msgid "AUX 1 Out" msgstr "" -msgid "Front" +msgid "AUX 2 Out" msgstr "" -msgid "Rear" +msgid "AUX Out" msgstr "" -msgid "Side" +msgid "Bass" msgstr "" -msgid "Center / LFE" +msgid "Treble" +msgstr "" + +msgid "3D Depth" +msgstr "" + +msgid "3D Center" +msgstr "" + +msgid "3D Enhance" +msgstr "" + +msgid "Telephone" msgstr "" msgid "Microphone" msgstr "" -msgid "Front panel microphone" +msgid "Line Out" +msgstr "" + +msgid "Line In" +msgstr "" + +msgid "Internal CD" +msgstr "" + +msgid "Video In" +msgstr "" + +msgid "AUX 1 In" +msgstr "" + +msgid "AUX 2 In" +msgstr "" + +msgid "AUX In" +msgstr "" + +msgid "PCM" +msgstr "" + +msgid "Record Gain" +msgstr "" + +msgid "Output Gain" +msgstr "" + +msgid "Microphone Boost" +msgstr "" + +msgid "Loopback" +msgstr "" + +msgid "Diagnostic" +msgstr "" + +msgid "Bass Boost" +msgstr "" + +msgid "Playback Ports" msgstr "" msgid "Input" msgstr "" -msgid "Line-in" +msgid "Record Source" msgstr "" -msgid "PCM 1" +msgid "Monitor Source" msgstr "" -msgid "PCM 2" +msgid "Keyboard Beep" msgstr "" -msgid "PCM 3" +msgid "Monitor" msgstr "" -msgid "PCM 4" +msgid "Simulate Stereo" msgstr "" -msgid "Green connector" +msgid "Stereo" msgstr "" -msgid "Green front panel connector" +msgid "Surround Sound" msgstr "" -msgid "Pink connector" +msgid "Microphone Gain" msgstr "" -msgid "Pink front panel connector" +msgid "Speaker Source" msgstr "" -msgid "Blue connector" +msgid "Microphone Source" msgstr "" -msgid "Blue front panel connector" +msgid "Jack" msgstr "" -msgid "Orange connector" +msgid "Center / LFE" msgstr "" -msgid "Orange front panel connector" +msgid "Stereo Mix" msgstr "" -msgid "Black connector" +msgid "Mono Mix" msgstr "" -msgid "Black front panel connector" +msgid "Input Mix" msgstr "" -msgid "Gray connector" +msgid "SPDIF In" msgstr "" -msgid "Gray front panel connector" +msgid "SPDIF Out" msgstr "" -msgid "White connector" +msgid "Microphone 1" msgstr "" -msgid "White front panel connector" +msgid "Microphone 2" msgstr "" -msgid "Red connector" +msgid "Digital Out" msgstr "" -msgid "Red front panel connector" +msgid "Digital In" msgstr "" -msgid "Yellow connector" +msgid "HDMI" msgstr "" -msgid "Yellow front panel connector" +msgid "Modem" msgstr "" -msgid "Green connector function" +msgid "Handset" msgstr "" -msgid "Green front panel connector function" +msgid "Other" msgstr "" -msgid "Pink connector function" +msgid "None" msgstr "" -msgid "Pink front panel connector function" +msgid "On" msgstr "" -msgid "Blue connector function" +msgid "Off" msgstr "" -msgid "Blue front panel connector function" +msgid "Mute" msgstr "" -msgid "Orange connector function" +msgid "Fast" msgstr "" -msgid "Orange front panel connector function" +msgid "Very Low" msgstr "" -msgid "Black connector function" +msgid "Low" msgstr "" -msgid "Black front panel connector function" +msgid "Medium" msgstr "" -msgid "Gray connector function" +msgid "High" msgstr "" -msgid "Gray front panel connector function" +msgid "Very High" msgstr "" -msgid "White connector function" +msgid "Production" msgstr "" -msgid "White front panel connector function" +msgid "Front Panel Microphone" msgstr "" -msgid "Red connector function" +msgid "Front Panel Line In" msgstr "" -msgid "Red front panel connector function" +msgid "Front Panel Headphones" msgstr "" -msgid "Yellow connector function" +msgid "Front Panel Line Out" msgstr "" -msgid "Yellow front panel connector function" +msgid "Green Connector" msgstr "" -msgid "Front panel line-in" +msgid "Pink Connector" msgstr "" -msgid "Headphones" +msgid "Blue Connector" msgstr "" -msgid "Front panel headphones" +msgid "White Connector" msgstr "" -msgid "PCM" +msgid "Black Connector" +msgstr "" + +msgid "Gray Connector" +msgstr "" + +msgid "Orange Connector" +msgstr "" + +msgid "Red Connector" +msgstr "" + +msgid "Yellow Connector" +msgstr "" + +msgid "Green Front Panel Connector" +msgstr "" + +msgid "Pink Front Panel Connector" +msgstr "" + +msgid "Blue Front Panel Connector" +msgstr "" + +msgid "White Front Panel Connector" +msgstr "" + +msgid "Black Front Panel Connector" +msgstr "" + +msgid "Gray Front Panel Connector" +msgstr "" + +msgid "Orange Front Panel Connector" +msgstr "" + +msgid "Red Front Panel Connector" msgstr "" -msgid "Virtual mixer input" +msgid "Yellow Front Panel Connector" msgstr "" -msgid "Virtual mixer output" +msgid "Spread Output" msgstr "" -msgid "Virtual mixer channel configuration" +msgid "Downmix" +msgstr "" + +msgid "Virtual Mixer Input" +msgstr "" + +msgid "Virtual Mixer Output" +msgstr "" + +msgid "Virtual Mixer Channels" +msgstr "" + +#, c-format +msgid "%s Function" +msgstr "" + +#, c-format +msgid "%s %d" msgstr "" msgid "" @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: gst-plugins-bad 0.10.9.3\n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n" -"POT-Creation-Date: 2009-06-17 21:54+0100\n" +"POT-Creation-Date: 2009-08-11 17:42+0100\n" "PO-Revision-Date: 2009-01-23 18:06+0100\n" "Last-Translator: Freek de Kruijf <f.de.kruijf@hetnet.nl>\n" "Language-Team: Dutch <vertaling@vrijschrift.org>\n" @@ -74,203 +74,349 @@ msgstr "" "Kan het audio-apparaat niet openen voor de mixerbesturing. Deze versie van " "het Open Soundsysteem wordt niet ondersteund door dit element." -msgid "Fast" +msgid "Volume" +msgstr "" + +#, fuzzy +msgid "Master" msgstr "Snel" -msgid "Low" -msgstr "Laag" +msgid "Front" +msgstr "Voorzijde" -msgid "Medium" -msgstr "Gemiddeld" +msgid "Rear" +msgstr "Achterzijde" -msgid "High" -msgstr "Hoog" +msgid "Headphones" +msgstr "Hoofdtelefoon" -msgid "Very high" -msgstr "Erg hoog" +#, fuzzy +msgid "Center" +msgstr "Midden / LFE" -msgid "Production" -msgstr "Productie" +msgid "LFE" +msgstr "" -msgid "Off" -msgstr "Uit" +#, fuzzy +msgid "Surround" +msgstr "Surround geluid" -msgid "On" -msgstr "Aan" +msgid "Side" +msgstr "Zijkant" + +msgid "Built-in Speaker" +msgstr "" + +msgid "AUX 1 Out" +msgstr "" + +msgid "AUX 2 Out" +msgstr "" + +msgid "AUX Out" +msgstr "" + +msgid "Bass" +msgstr "" + +msgid "Treble" +msgstr "" + +msgid "3D Depth" +msgstr "" + +msgid "3D Center" +msgstr "" + +msgid "3D Enhance" +msgstr "" + +#, fuzzy +msgid "Telephone" +msgstr "Hoofdtelefoon" + +msgid "Microphone" +msgstr "Microfoon" + +msgid "Line Out" +msgstr "" + +#, fuzzy +msgid "Line In" +msgstr "Lijn-in" + +msgid "Internal CD" +msgstr "" + +msgid "Video In" +msgstr "" + +msgid "AUX 1 In" +msgstr "" + +msgid "AUX 2 In" +msgstr "" + +msgid "AUX In" +msgstr "" + +msgid "PCM" +msgstr "PCM" + +msgid "Record Gain" +msgstr "" + +msgid "Output Gain" +msgstr "" + +#, fuzzy +msgid "Microphone Boost" +msgstr "Microfoon" + +msgid "Loopback" +msgstr "" + +msgid "Diagnostic" +msgstr "" + +msgid "Bass Boost" +msgstr "" + +msgid "Playback Ports" +msgstr "" + +msgid "Input" +msgstr "Invoer" + +msgid "Record Source" +msgstr "" + +msgid "Monitor Source" +msgstr "" + +msgid "Keyboard Beep" +msgstr "" + +msgid "Monitor" +msgstr "" + +msgid "Simulate Stereo" +msgstr "" msgid "Stereo" msgstr "Stereo" -msgid "Surround sound" +#, fuzzy +msgid "Surround Sound" msgstr "Surround geluid" -msgid "Input mix" -msgstr "Invoermix" +#, fuzzy +msgid "Microphone Gain" +msgstr "Microfoon" -msgid "Front" -msgstr "Voorzijde" +msgid "Speaker Source" +msgstr "" -msgid "Rear" -msgstr "Achterzijde" +#, fuzzy +msgid "Microphone Source" +msgstr "Microfoon" -msgid "Side" -msgstr "Zijkant" +msgid "Jack" +msgstr "" msgid "Center / LFE" msgstr "Midden / LFE" -msgid "Microphone" -msgstr "Microfoon" +#, fuzzy +msgid "Stereo Mix" +msgstr "Stereo" -msgid "Front panel microphone" -msgstr "Microfoon in frontpaneel" +msgid "Mono Mix" +msgstr "" -msgid "Input" -msgstr "Invoer" +#, fuzzy +msgid "Input Mix" +msgstr "Invoermix" -msgid "Line-in" -msgstr "Lijn-in" +msgid "SPDIF In" +msgstr "" -msgid "PCM 1" -msgstr "PCM 1" +msgid "SPDIF Out" +msgstr "" -msgid "PCM 2" -msgstr "PCM 2" +#, fuzzy +msgid "Microphone 1" +msgstr "Microfoon" -msgid "PCM 3" -msgstr "PCM 3" +#, fuzzy +msgid "Microphone 2" +msgstr "Microfoon" -msgid "PCM 4" -msgstr "PCM 4" +msgid "Digital Out" +msgstr "" -msgid "Green connector" -msgstr "Groene connector" +msgid "Digital In" +msgstr "" -msgid "Green front panel connector" -msgstr "Groene connector in frontpaneel" +msgid "HDMI" +msgstr "" -msgid "Pink connector" -msgstr "Roze connector" +msgid "Modem" +msgstr "" -msgid "Pink front panel connector" -msgstr "Roze connector in frontpaneel" +msgid "Handset" +msgstr "" -msgid "Blue connector" -msgstr "Blauwe connector" +msgid "Other" +msgstr "" -msgid "Blue front panel connector" -msgstr "Blauwe connector in frontpaneel" +msgid "None" +msgstr "" -msgid "Orange connector" -msgstr "Oranje connector" +msgid "On" +msgstr "Aan" -msgid "Orange front panel connector" -msgstr "Oranje connector in frontpaneel" +msgid "Off" +msgstr "Uit" -msgid "Black connector" -msgstr "Zwarte connector" +msgid "Mute" +msgstr "" -msgid "Black front panel connector" -msgstr "Zwarte connector in frontpaneel" +msgid "Fast" +msgstr "Snel" -msgid "Gray connector" -msgstr "Grijze connector" +msgid "Very Low" +msgstr "" -msgid "Gray front panel connector" -msgstr "Grijze connector in frontpaneel" +msgid "Low" +msgstr "Laag" -msgid "White connector" -msgstr "Witte connector" +msgid "Medium" +msgstr "Gemiddeld" -msgid "White front panel connector" -msgstr "Witte connector in frontpaneel" +msgid "High" +msgstr "Hoog" -msgid "Red connector" -msgstr "Rode connector" +#, fuzzy +msgid "Very High" +msgstr "Erg hoog" -msgid "Red front panel connector" -msgstr "Rode connector in frontpaneel" +msgid "Production" +msgstr "Productie" -msgid "Yellow connector" -msgstr "Gele connector" +#, fuzzy +msgid "Front Panel Microphone" +msgstr "Microfoon in frontpaneel" -msgid "Yellow front panel connector" -msgstr "Gele connector in frontpaneel" +#, fuzzy +msgid "Front Panel Line In" +msgstr "Lijn-in in frontpaneel" -msgid "Green connector function" -msgstr "Functie van groene connector" +#, fuzzy +msgid "Front Panel Headphones" +msgstr "Hoofdtelefoon in frontpaneel" -msgid "Green front panel connector function" -msgstr "Functie van groene connector in frontpaneel" +#, fuzzy +msgid "Front Panel Line Out" +msgstr "Lijn-in in frontpaneel" -msgid "Pink connector function" -msgstr "Functie van roze connector" +#, fuzzy +msgid "Green Connector" +msgstr "Groene connector" -msgid "Pink front panel connector function" -msgstr "Functie van roze connector in frontpaneel" +#, fuzzy +msgid "Pink Connector" +msgstr "Roze connector" -msgid "Blue connector function" -msgstr "Functie van blauwe connector" +#, fuzzy +msgid "Blue Connector" +msgstr "Blauwe connector" -msgid "Blue front panel connector function" -msgstr "Functie van blauwe connector in frontpaneel" +#, fuzzy +msgid "White Connector" +msgstr "Witte connector" -msgid "Orange connector function" -msgstr "Functie van oranje connector" +#, fuzzy +msgid "Black Connector" +msgstr "Zwarte connector" -msgid "Orange front panel connector function" -msgstr "Functie van oranje connector in frontpaneel" +#, fuzzy +msgid "Gray Connector" +msgstr "Grijze connector" -msgid "Black connector function" -msgstr "Functie van zwarte connector" +#, fuzzy +msgid "Orange Connector" +msgstr "Oranje connector" -msgid "Black front panel connector function" -msgstr "Functie van zwarte connector in frontpaneel" +#, fuzzy +msgid "Red Connector" +msgstr "Rode connector" -msgid "Gray connector function" -msgstr "Functie van grijze connector" +#, fuzzy +msgid "Yellow Connector" +msgstr "Gele connector" -msgid "Gray front panel connector function" -msgstr "Functie van grijze connector in frontpaneel" +#, fuzzy +msgid "Green Front Panel Connector" +msgstr "Groene connector in frontpaneel" -msgid "White connector function" -msgstr "Functie van witte connector" +#, fuzzy +msgid "Pink Front Panel Connector" +msgstr "Roze connector in frontpaneel" -msgid "White front panel connector function" -msgstr "Functie van witte connector in frontpaneel" +#, fuzzy +msgid "Blue Front Panel Connector" +msgstr "Blauwe connector in frontpaneel" -msgid "Red connector function" -msgstr "Functie van rode connector" +#, fuzzy +msgid "White Front Panel Connector" +msgstr "Witte connector in frontpaneel" -msgid "Red front panel connector function" -msgstr "Functie van rode connector in frontpaneel" +#, fuzzy +msgid "Black Front Panel Connector" +msgstr "Zwarte connector in frontpaneel" -msgid "Yellow connector function" -msgstr "Functie van gele connector" +#, fuzzy +msgid "Gray Front Panel Connector" +msgstr "Grijze connector in frontpaneel" -msgid "Yellow front panel connector function" -msgstr "Functie van gele connector in frontpaneel" +#, fuzzy +msgid "Orange Front Panel Connector" +msgstr "Oranje connector in frontpaneel" -msgid "Front panel line-in" -msgstr "Lijn-in in frontpaneel" +#, fuzzy +msgid "Red Front Panel Connector" +msgstr "Rode connector in frontpaneel" -msgid "Headphones" -msgstr "Hoofdtelefoon" +#, fuzzy +msgid "Yellow Front Panel Connector" +msgstr "Gele connector in frontpaneel" -msgid "Front panel headphones" -msgstr "Hoofdtelefoon in frontpaneel" +msgid "Spread Output" +msgstr "" -msgid "PCM" -msgstr "PCM" +msgid "Downmix" +msgstr "" -msgid "Virtual mixer input" +#, fuzzy +msgid "Virtual Mixer Input" msgstr "Virtuele mixer-invoer" -msgid "Virtual mixer output" +#, fuzzy +msgid "Virtual Mixer Output" msgstr "Virtuele mixer-uitvoer" -msgid "Virtual mixer channel configuration" -msgstr "Kanaalconfiguratie van virtuele mixer " +#, fuzzy +msgid "Virtual Mixer Channels" +msgstr "Virtuele mixer-invoer" + +#, c-format +msgid "%s Function" +msgstr "" + +#, c-format +msgid "%s %d" +msgstr "" msgid "" "Could not open audio device for playback. Device is being used by another " @@ -319,3 +465,72 @@ msgstr "Fout bij opnemen met dit audio-apparaat." #~ msgstr "" #~ "De gevraagde bitsnelheid %d kbits/s voor eigenschap '%s' is niet " #~ "toegestaan. De bitsnelheid is gewijzigd in %d kbits/s." + +#~ msgid "PCM 1" +#~ msgstr "PCM 1" + +#~ msgid "PCM 2" +#~ msgstr "PCM 2" + +#~ msgid "PCM 3" +#~ msgstr "PCM 3" + +#~ msgid "PCM 4" +#~ msgstr "PCM 4" + +#~ msgid "Green connector function" +#~ msgstr "Functie van groene connector" + +#~ msgid "Green front panel connector function" +#~ msgstr "Functie van groene connector in frontpaneel" + +#~ msgid "Pink connector function" +#~ msgstr "Functie van roze connector" + +#~ msgid "Pink front panel connector function" +#~ msgstr "Functie van roze connector in frontpaneel" + +#~ msgid "Blue connector function" +#~ msgstr "Functie van blauwe connector" + +#~ msgid "Blue front panel connector function" +#~ msgstr "Functie van blauwe connector in frontpaneel" + +#~ msgid "Orange connector function" +#~ msgstr "Functie van oranje connector" + +#~ msgid "Orange front panel connector function" +#~ msgstr "Functie van oranje connector in frontpaneel" + +#~ msgid "Black connector function" +#~ msgstr "Functie van zwarte connector" + +#~ msgid "Black front panel connector function" +#~ msgstr "Functie van zwarte connector in frontpaneel" + +#~ msgid "Gray connector function" +#~ msgstr "Functie van grijze connector" + +#~ msgid "Gray front panel connector function" +#~ msgstr "Functie van grijze connector in frontpaneel" + +#~ msgid "White connector function" +#~ msgstr "Functie van witte connector" + +#~ msgid "White front panel connector function" +#~ msgstr "Functie van witte connector in frontpaneel" + +#~ msgid "Red connector function" +#~ msgstr "Functie van rode connector" + +#~ msgid "Red front panel connector function" +#~ msgstr "Functie van rode connector in frontpaneel" + +#~ msgid "Yellow connector function" +#~ msgstr "Functie van gele connector" + +#~ msgid "Yellow front panel connector function" +#~ msgstr "Functie van gele connector in frontpaneel" + +#~ msgid "Virtual mixer channel configuration" +#~ msgstr "Kanaalconfiguratie van virtuele mixer " @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: gst-plugins-0.8.3\n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n" -"POT-Creation-Date: 2009-06-17 21:54+0100\n" +"POT-Creation-Date: 2009-08-11 17:42+0100\n" "PO-Revision-Date: 2004-09-27 13:32+0530\n" "Last-Translator: Gora Mohanty <gora_mohanty@yahoo.co.in>\n" "Language-Team: Oriya <gora_mohanty@yahoo.co.in>\n" @@ -74,208 +74,324 @@ msgid "" "Open Sound System is not supported by this element." msgstr "\"%s\" ଧàବନି ଯନàତàର ଲà‡à¬–ିବା ପାଇଠଖà‹à¬²à¬¿à¬¹à‡à¬²à¬¾ ନାହିà¬." -msgid "Fast" +msgid "Volume" +msgstr "ପàରବଳତା" + +msgid "Master" msgstr "" -msgid "Low" +msgid "Front" msgstr "" -msgid "Medium" +#, fuzzy +msgid "Rear" +msgstr "ଅନàଲିପିକରଣ" + +msgid "Headphones" msgstr "" -msgid "High" +msgid "Center" msgstr "" -msgid "Very high" +msgid "LFE" msgstr "" -msgid "Production" +msgid "Surround" msgstr "" -msgid "Off" +#, fuzzy +msgid "Side" +msgstr "à¬à¬¿à¬¡à¬¿à¬“" + +#, fuzzy +msgid "Built-in Speaker" +msgstr "ସàବରବରàଦàଧକ àŸà¬¨àତàର" + +msgid "AUX 1 Out" msgstr "" -msgid "On" +msgid "AUX 2 Out" msgstr "" -msgid "Stereo" +msgid "AUX Out" msgstr "" -msgid "Surround sound" +msgid "Bass" +msgstr "ଅନàଚàଚ ସàବର" + +msgid "Treble" +msgstr "ଉଚàଚ ସàବର" + +msgid "3D Depth" msgstr "" -msgid "Input mix" +msgid "3D Center" msgstr "" -msgid "Front" +msgid "3D Enhance" msgstr "" -#, fuzzy -msgid "Rear" -msgstr "ଅନàଲିପିକରଣ" +msgid "Telephone" +msgstr "" + +msgid "Microphone" +msgstr "ମାଇକàରà‹à¬«à‹à¬¨à" + +msgid "Line Out" +msgstr "" #, fuzzy -msgid "Side" -msgstr "à¬à¬¿à¬¡à¬¿à¬“" +msgid "Line In" +msgstr "ଲାଇନ-ଇନ" -msgid "Center / LFE" +msgid "Internal CD" msgstr "" -msgid "Microphone" +msgid "Video In" +msgstr "" + +msgid "AUX 1 In" +msgstr "" + +msgid "AUX 2 In" +msgstr "" + +msgid "AUX In" +msgstr "" + +msgid "PCM" +msgstr "ପି.ସି.à¬à¬®." + +msgid "Record Gain" +msgstr "" + +#, fuzzy +msgid "Output Gain" +msgstr "ନିରàଗମ-ବàƒà¬¦àଧି" + +#, fuzzy +msgid "Microphone Boost" msgstr "ମାଇକàରà‹à¬«à‹à¬¨à" -msgid "Front panel microphone" +msgid "Loopback" +msgstr "" + +msgid "Diagnostic" +msgstr "" + +msgid "Bass Boost" +msgstr "" + +msgid "Playback Ports" msgstr "" msgid "Input" msgstr "" -msgid "Line-in" -msgstr "ଲାଇନ-ଇନ" +msgid "Record Source" +msgstr "" #, fuzzy -msgid "PCM 1" -msgstr "ପି.ସି.à¬à¬®." +msgid "Monitor Source" +msgstr "ପàରଦରàଶିକା" + +msgid "Keyboard Beep" +msgstr "" + +msgid "Monitor" +msgstr "ପàରଦରàଶିକା" + +msgid "Simulate Stereo" +msgstr "" + +msgid "Stereo" +msgstr "" + +msgid "Surround Sound" +msgstr "" #, fuzzy -msgid "PCM 2" -msgstr "ପି.ସି.à¬à¬®.-à¨" +msgid "Microphone Gain" +msgstr "ମାଇକàରà‹à¬«à‹à¬¨à" #, fuzzy -msgid "PCM 3" -msgstr "ପି.ସି.à¬à¬®." +msgid "Speaker Source" +msgstr "ସàବରବରàଦàଧକ àŸà¬¨àତàର" #, fuzzy -msgid "PCM 4" -msgstr "ପି.ସି.à¬à¬®." +msgid "Microphone Source" +msgstr "ମାଇକàରà‹à¬«à‹à¬¨à" -msgid "Green connector" +msgid "Jack" msgstr "" -msgid "Green front panel connector" +msgid "Center / LFE" msgstr "" -msgid "Pink connector" +msgid "Stereo Mix" msgstr "" -msgid "Pink front panel connector" +msgid "Mono Mix" msgstr "" -msgid "Blue connector" +msgid "Input Mix" msgstr "" -msgid "Blue front panel connector" +msgid "SPDIF In" msgstr "" -msgid "Orange connector" +msgid "SPDIF Out" msgstr "" -msgid "Orange front panel connector" +#, fuzzy +msgid "Microphone 1" +msgstr "ମାଇକàରà‹à¬«à‹à¬¨à" + +#, fuzzy +msgid "Microphone 2" +msgstr "ମାଇକàରà‹à¬«à‹à¬¨à" + +#, fuzzy +msgid "Digital Out" +msgstr "ସାଂଖàଯିକ-à§" + +#, fuzzy +msgid "Digital In" +msgstr "ସାଂଖàଯିକ-à§" + +msgid "HDMI" msgstr "" -msgid "Black connector" +msgid "Modem" msgstr "" -msgid "Black front panel connector" +msgid "Handset" msgstr "" -msgid "Gray connector" +msgid "Other" msgstr "" -msgid "Gray front panel connector" +msgid "None" msgstr "" -msgid "White connector" +msgid "On" msgstr "" -msgid "White front panel connector" +msgid "Off" msgstr "" -msgid "Red connector" +msgid "Mute" msgstr "" -msgid "Red front panel connector" +msgid "Fast" msgstr "" -msgid "Yellow connector" +msgid "Very Low" msgstr "" -msgid "Yellow front panel connector" +msgid "Low" msgstr "" -msgid "Green connector function" +msgid "Medium" msgstr "" -msgid "Green front panel connector function" +msgid "High" msgstr "" -msgid "Pink connector function" +msgid "Very High" msgstr "" -msgid "Pink front panel connector function" +msgid "Production" msgstr "" -msgid "Blue connector function" +#, fuzzy +msgid "Front Panel Microphone" +msgstr "ମାଇକàରà‹à¬«à‹à¬¨à" + +msgid "Front Panel Line In" msgstr "" -msgid "Blue front panel connector function" +msgid "Front Panel Headphones" msgstr "" -msgid "Orange connector function" +msgid "Front Panel Line Out" msgstr "" -msgid "Orange front panel connector function" +msgid "Green Connector" msgstr "" -msgid "Black connector function" +msgid "Pink Connector" msgstr "" -msgid "Black front panel connector function" +msgid "Blue Connector" msgstr "" -msgid "Gray connector function" +msgid "White Connector" msgstr "" -msgid "Gray front panel connector function" +msgid "Black Connector" msgstr "" -msgid "White connector function" +msgid "Gray Connector" msgstr "" -msgid "White front panel connector function" +msgid "Orange Connector" msgstr "" -msgid "Red connector function" +msgid "Red Connector" msgstr "" -msgid "Red front panel connector function" +msgid "Yellow Connector" msgstr "" -msgid "Yellow connector function" +msgid "Green Front Panel Connector" msgstr "" -msgid "Yellow front panel connector function" +msgid "Pink Front Panel Connector" msgstr "" -msgid "Front panel line-in" +msgid "Blue Front Panel Connector" msgstr "" -msgid "Headphones" +msgid "White Front Panel Connector" msgstr "" -msgid "Front panel headphones" +msgid "Black Front Panel Connector" msgstr "" -msgid "PCM" -msgstr "ପି.ସି.à¬à¬®." +msgid "Gray Front Panel Connector" +msgstr "" -msgid "Virtual mixer input" +msgid "Orange Front Panel Connector" msgstr "" -msgid "Virtual mixer output" +msgid "Red Front Panel Connector" msgstr "" -msgid "Virtual mixer channel configuration" +msgid "Yellow Front Panel Connector" +msgstr "" + +msgid "Spread Output" +msgstr "" + +msgid "Downmix" +msgstr "" + +msgid "Virtual Mixer Input" +msgstr "" + +msgid "Virtual Mixer Output" +msgstr "" + +msgid "Virtual Mixer Channels" +msgstr "" + +#, c-format +msgid "%s Function" +msgstr "" + +#, c-format +msgid "%s %d" msgstr "" msgid "" @@ -310,6 +426,22 @@ msgstr "" msgid "Error recording from audio device." msgstr "" +#, fuzzy +#~ msgid "PCM 1" +#~ msgstr "ପି.ସି.à¬à¬®." + +#, fuzzy +#~ msgid "PCM 2" +#~ msgstr "ପି.ସି.à¬à¬®.-à¨" + +#, fuzzy +#~ msgid "PCM 3" +#~ msgstr "ପି.ସି.à¬à¬®." + +#, fuzzy +#~ msgid "PCM 4" +#~ msgstr "ପି.ସି.à¬à¬®." + #~ msgid "Could not open device \"%s\" for reading and writing." #~ msgstr "\"%s\" ଯନàତàର ପଢ଼ିବା ଓ ଲà‡à¬–ିବା ପାଇଠଖà‹à¬²à¬¿à¬¹à‡à¬²à¬¾ ନାହିà¬." @@ -361,21 +493,9 @@ msgstr "" #~ msgid "Your OSS device could not be probed correctly" #~ msgstr "ଆପଣଙàକର ଓ.à¬à¬¸.à¬à¬¸. ଯନàତàରର ଠିକ à¬à¬¾à¬¬à¬°à‡ ଅନàସନàଧାନ କରିହà‡à¬²à¬¾ ନାହିà¬." -#~ msgid "Volume" -#~ msgstr "ପàରବଳତା" - -#~ msgid "Bass" -#~ msgstr "ଅନàଚàଚ ସàବର" - -#~ msgid "Treble" -#~ msgstr "ଉଚàଚ ସàବର" - #~ msgid "Synth" #~ msgstr "ସିନàଥà‡à¬¸à¬¾à¬‡à¬œà¬°" -#~ msgid "Speaker" -#~ msgstr "ସàବରବରàଦàଧକ àŸà¬¨àତàର" - #~ msgid "CD" #~ msgstr "ସି.ଡି." @@ -385,9 +505,6 @@ msgstr "" #~ msgid "In-gain" #~ msgstr "ନିବà‡à¬¶-ବàƒà¬¦àଧି" -#~ msgid "Out-gain" -#~ msgstr "ନିରàଗମ-ବàƒà¬¦àଧି" - #~ msgid "Line-1" #~ msgstr "ଲାଇନ-à§" @@ -397,9 +514,6 @@ msgstr "" #~ msgid "Line-3" #~ msgstr "ଲାଇନ-à©" -#~ msgid "Digital-1" -#~ msgstr "ସାଂଖàଯିକ-à§" - #~ msgid "Digital-2" #~ msgstr "ସାଂଖàଯିକ-à¨" @@ -415,13 +529,6 @@ msgstr "" #~ msgid "Radio" #~ msgstr "ରà‡à¬¡à¬¿à¬“" -#~ msgid "Monitor" -#~ msgstr "ପàରଦରàଶିକା" - -#, fuzzy -#~ msgid "PC Speaker" -#~ msgstr "ସàବରବରàଦàଧକ àŸà¬¨àତàର" - #~ msgid "Could not open CD device for reading." #~ msgstr "ସି.ଡି. ଯନàତàର ପଢ଼ିବା ପାଇଠଖà‹à¬²à¬¿à¬¹à‡à¬²à¬¾ ନାହିà¬." @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: gst-plugins-bad 0.10.9.3\n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n" -"POT-Creation-Date: 2009-06-17 21:54+0100\n" +"POT-Creation-Date: 2009-08-11 17:42+0100\n" "PO-Revision-Date: 2009-01-12 20:15+0100\n" "Last-Translator: Jakub Bogusz <qboosh@pld-linux.org>\n" "Language-Team: Polish <translation-team-pl@lists.sourceforge.net>\n" @@ -70,203 +70,349 @@ msgstr "" "Nie udaÅ‚o siÄ™ otworzyć urzÄ…dzenia dźwiÄ™kowego do sterowania mikserem. Ta " "wersja Open Sound System nie jest obsÅ‚ugiwana przez ten moduÅ‚." -msgid "Fast" +msgid "Volume" +msgstr "" + +#, fuzzy +msgid "Master" msgstr "Szybka" -msgid "Low" -msgstr "Niska" +msgid "Front" +msgstr "Przód" -msgid "Medium" -msgstr "Åšrednia" +msgid "Rear" +msgstr "TyÅ‚" -msgid "High" -msgstr "Wysoka" +msgid "Headphones" +msgstr "SÅ‚uchawki" -msgid "Very high" -msgstr "Bardzo wysoka" +#, fuzzy +msgid "Center" +msgstr "Åšrodek / LFE" -msgid "Production" -msgstr "Produkcyjna" +msgid "LFE" +msgstr "" -msgid "Off" -msgstr "WyÅ‚Ä…czone" +#, fuzzy +msgid "Surround" +msgstr "DźwiÄ™k surround" -msgid "On" -msgstr "WÅ‚Ä…czone" +msgid "Side" +msgstr "Bok" + +msgid "Built-in Speaker" +msgstr "" + +msgid "AUX 1 Out" +msgstr "" + +msgid "AUX 2 Out" +msgstr "" + +msgid "AUX Out" +msgstr "" + +msgid "Bass" +msgstr "" + +msgid "Treble" +msgstr "" + +msgid "3D Depth" +msgstr "" + +msgid "3D Center" +msgstr "" + +msgid "3D Enhance" +msgstr "" + +#, fuzzy +msgid "Telephone" +msgstr "SÅ‚uchawki" + +msgid "Microphone" +msgstr "Mikrofon" + +msgid "Line Out" +msgstr "" + +#, fuzzy +msgid "Line In" +msgstr "WejÅ›cie linii" + +msgid "Internal CD" +msgstr "" + +msgid "Video In" +msgstr "" + +msgid "AUX 1 In" +msgstr "" + +msgid "AUX 2 In" +msgstr "" + +msgid "AUX In" +msgstr "" + +msgid "PCM" +msgstr "PCM" + +msgid "Record Gain" +msgstr "" + +msgid "Output Gain" +msgstr "" + +#, fuzzy +msgid "Microphone Boost" +msgstr "Mikrofon" + +msgid "Loopback" +msgstr "" + +msgid "Diagnostic" +msgstr "" + +msgid "Bass Boost" +msgstr "" + +msgid "Playback Ports" +msgstr "" + +msgid "Input" +msgstr "WejÅ›cie" + +msgid "Record Source" +msgstr "" + +msgid "Monitor Source" +msgstr "" + +msgid "Keyboard Beep" +msgstr "" + +msgid "Monitor" +msgstr "" + +msgid "Simulate Stereo" +msgstr "" msgid "Stereo" msgstr "Stereo" -msgid "Surround sound" +#, fuzzy +msgid "Surround Sound" msgstr "DźwiÄ™k surround" -msgid "Input mix" -msgstr "Miksowanie wejÅ›cia" +#, fuzzy +msgid "Microphone Gain" +msgstr "Mikrofon" -msgid "Front" -msgstr "Przód" +msgid "Speaker Source" +msgstr "" -msgid "Rear" -msgstr "TyÅ‚" +#, fuzzy +msgid "Microphone Source" +msgstr "Mikrofon" -msgid "Side" -msgstr "Bok" +msgid "Jack" +msgstr "" msgid "Center / LFE" msgstr "Åšrodek / LFE" -msgid "Microphone" -msgstr "Mikrofon" +#, fuzzy +msgid "Stereo Mix" +msgstr "Stereo" -msgid "Front panel microphone" -msgstr "Mikrofon na przednim panelu" +msgid "Mono Mix" +msgstr "" -msgid "Input" -msgstr "WejÅ›cie" +#, fuzzy +msgid "Input Mix" +msgstr "Miksowanie wejÅ›cia" -msgid "Line-in" -msgstr "WejÅ›cie linii" +msgid "SPDIF In" +msgstr "" -msgid "PCM 1" -msgstr "PCM 1" +msgid "SPDIF Out" +msgstr "" -msgid "PCM 2" -msgstr "PCM 2" +#, fuzzy +msgid "Microphone 1" +msgstr "Mikrofon" -msgid "PCM 3" -msgstr "PCM 3" +#, fuzzy +msgid "Microphone 2" +msgstr "Mikrofon" -msgid "PCM 4" -msgstr "PCM 4" +msgid "Digital Out" +msgstr "" -msgid "Green connector" -msgstr "Zielone gniazdo" +msgid "Digital In" +msgstr "" -msgid "Green front panel connector" -msgstr "Zielone gniazdo na przednim panelu" +msgid "HDMI" +msgstr "" -msgid "Pink connector" -msgstr "Różowe gniazdo" +msgid "Modem" +msgstr "" -msgid "Pink front panel connector" -msgstr "Różowe gniazdo na przednim panelu" +msgid "Handset" +msgstr "" -msgid "Blue connector" -msgstr "Niebieskie gniazdo" +msgid "Other" +msgstr "" -msgid "Blue front panel connector" -msgstr "Niebieskie gniazdo na przednim panelu" +msgid "None" +msgstr "" -msgid "Orange connector" -msgstr "PomaraÅ„czowe gniazdo" +msgid "On" +msgstr "WÅ‚Ä…czone" -msgid "Orange front panel connector" -msgstr "PomaraÅ„czowe gniazdo na przednim panelu" +msgid "Off" +msgstr "WyÅ‚Ä…czone" -msgid "Black connector" -msgstr "Czarne gniazdo" +msgid "Mute" +msgstr "" -msgid "Black front panel connector" -msgstr "Czarne gniazdo na przednim panelu" +msgid "Fast" +msgstr "Szybka" -msgid "Gray connector" -msgstr "Szare gniazdo" +msgid "Very Low" +msgstr "" -msgid "Gray front panel connector" -msgstr "Szare gniazdo na przednim panelu" +msgid "Low" +msgstr "Niska" -msgid "White connector" -msgstr "BiaÅ‚e gniazdo" +msgid "Medium" +msgstr "Åšrednia" -msgid "White front panel connector" -msgstr "BiaÅ‚e gniazdo na przednim panelu" +msgid "High" +msgstr "Wysoka" -msgid "Red connector" -msgstr "Czerwone gniazdo" +#, fuzzy +msgid "Very High" +msgstr "Bardzo wysoka" -msgid "Red front panel connector" -msgstr "Czerwone gniazdo na przednim panelu" +msgid "Production" +msgstr "Produkcyjna" -msgid "Yellow connector" -msgstr "Żółte gniazdo" +#, fuzzy +msgid "Front Panel Microphone" +msgstr "Mikrofon na przednim panelu" -msgid "Yellow front panel connector" -msgstr "Żółte gniazdo na przednim panelu" +#, fuzzy +msgid "Front Panel Line In" +msgstr "WejÅ›cie linii na przednim panelu" -msgid "Green connector function" -msgstr "Funkcja zielonego gniazda" +#, fuzzy +msgid "Front Panel Headphones" +msgstr "SÅ‚uchawki na przednim panelu" -msgid "Green front panel connector function" -msgstr "Funkcja zielonego gniazda na przednim panelu" +#, fuzzy +msgid "Front Panel Line Out" +msgstr "WejÅ›cie linii na przednim panelu" -msgid "Pink connector function" -msgstr "Funkcja różowego gniazda" +#, fuzzy +msgid "Green Connector" +msgstr "Zielone gniazdo" -msgid "Pink front panel connector function" -msgstr "Funkcja różowego gniazda na przednim panelu" +#, fuzzy +msgid "Pink Connector" +msgstr "Różowe gniazdo" -msgid "Blue connector function" -msgstr "Funkcja niebieskiego gniazda" +#, fuzzy +msgid "Blue Connector" +msgstr "Niebieskie gniazdo" -msgid "Blue front panel connector function" -msgstr "Funkcja niebieskiego gniazda na przednim panelu" +#, fuzzy +msgid "White Connector" +msgstr "BiaÅ‚e gniazdo" -msgid "Orange connector function" -msgstr "Funkcja pomaraÅ„czowego gniazda" +#, fuzzy +msgid "Black Connector" +msgstr "Czarne gniazdo" -msgid "Orange front panel connector function" -msgstr "Funkcja pomaraÅ„czowego gniazda na przednim panelu" +#, fuzzy +msgid "Gray Connector" +msgstr "Szare gniazdo" -msgid "Black connector function" -msgstr "Funkcja czarnego gniazda" +#, fuzzy +msgid "Orange Connector" +msgstr "PomaraÅ„czowe gniazdo" -msgid "Black front panel connector function" -msgstr "Funkcja czarnego gniazda na przednim panelu" +#, fuzzy +msgid "Red Connector" +msgstr "Czerwone gniazdo" -msgid "Gray connector function" -msgstr "Funkcja szarego gniazda" +#, fuzzy +msgid "Yellow Connector" +msgstr "Żółte gniazdo" -msgid "Gray front panel connector function" -msgstr "Funkcja szarego gniazda na przednim panelu" +#, fuzzy +msgid "Green Front Panel Connector" +msgstr "Zielone gniazdo na przednim panelu" -msgid "White connector function" -msgstr "Funkcja biaÅ‚ego gniazda" +#, fuzzy +msgid "Pink Front Panel Connector" +msgstr "Różowe gniazdo na przednim panelu" -msgid "White front panel connector function" -msgstr "Funkcja biaÅ‚ego gniazda na przednim panelu" +#, fuzzy +msgid "Blue Front Panel Connector" +msgstr "Niebieskie gniazdo na przednim panelu" -msgid "Red connector function" -msgstr "Funkcja czerwonego gniazda" +#, fuzzy +msgid "White Front Panel Connector" +msgstr "BiaÅ‚e gniazdo na przednim panelu" -msgid "Red front panel connector function" -msgstr "Funkcja czerwonego gniazda na przednim panelu" +#, fuzzy +msgid "Black Front Panel Connector" +msgstr "Czarne gniazdo na przednim panelu" -msgid "Yellow connector function" -msgstr "Funkcja żółtego gniazda" +#, fuzzy +msgid "Gray Front Panel Connector" +msgstr "Szare gniazdo na przednim panelu" -msgid "Yellow front panel connector function" -msgstr "Funkcja żółtego gniazda na przednim panelu" +#, fuzzy +msgid "Orange Front Panel Connector" +msgstr "PomaraÅ„czowe gniazdo na przednim panelu" -msgid "Front panel line-in" -msgstr "WejÅ›cie linii na przednim panelu" +#, fuzzy +msgid "Red Front Panel Connector" +msgstr "Czerwone gniazdo na przednim panelu" -msgid "Headphones" -msgstr "SÅ‚uchawki" +#, fuzzy +msgid "Yellow Front Panel Connector" +msgstr "Żółte gniazdo na przednim panelu" -msgid "Front panel headphones" -msgstr "SÅ‚uchawki na przednim panelu" +msgid "Spread Output" +msgstr "" -msgid "PCM" -msgstr "PCM" +msgid "Downmix" +msgstr "" -msgid "Virtual mixer input" +#, fuzzy +msgid "Virtual Mixer Input" msgstr "WejÅ›cie wirtualnego miksera" -msgid "Virtual mixer output" +#, fuzzy +msgid "Virtual Mixer Output" msgstr "WyjÅ›cie wirtualnego miksera" -msgid "Virtual mixer channel configuration" -msgstr "Konfiguracja kanałów wirtualnego miksera" +#, fuzzy +msgid "Virtual Mixer Channels" +msgstr "WejÅ›cie wirtualnego miksera" + +#, c-format +msgid "%s Function" +msgstr "" + +#, c-format +msgid "%s %d" +msgstr "" msgid "" "Could not open audio device for playback. Device is being used by another " @@ -315,3 +461,72 @@ msgstr "BÅ‚Ä…d nagrywania z urzÄ…dzenia dźwiÄ™kowego." #~ msgstr "" #~ "Żądane bitrate %d kbit/s dla wÅ‚aÅ›ciwoÅ›ci '%s' nie jest dozwolone - " #~ "zmieniono na %d kbit/s." + +#~ msgid "PCM 1" +#~ msgstr "PCM 1" + +#~ msgid "PCM 2" +#~ msgstr "PCM 2" + +#~ msgid "PCM 3" +#~ msgstr "PCM 3" + +#~ msgid "PCM 4" +#~ msgstr "PCM 4" + +#~ msgid "Green connector function" +#~ msgstr "Funkcja zielonego gniazda" + +#~ msgid "Green front panel connector function" +#~ msgstr "Funkcja zielonego gniazda na przednim panelu" + +#~ msgid "Pink connector function" +#~ msgstr "Funkcja różowego gniazda" + +#~ msgid "Pink front panel connector function" +#~ msgstr "Funkcja różowego gniazda na przednim panelu" + +#~ msgid "Blue connector function" +#~ msgstr "Funkcja niebieskiego gniazda" + +#~ msgid "Blue front panel connector function" +#~ msgstr "Funkcja niebieskiego gniazda na przednim panelu" + +#~ msgid "Orange connector function" +#~ msgstr "Funkcja pomaraÅ„czowego gniazda" + +#~ msgid "Orange front panel connector function" +#~ msgstr "Funkcja pomaraÅ„czowego gniazda na przednim panelu" + +#~ msgid "Black connector function" +#~ msgstr "Funkcja czarnego gniazda" + +#~ msgid "Black front panel connector function" +#~ msgstr "Funkcja czarnego gniazda na przednim panelu" + +#~ msgid "Gray connector function" +#~ msgstr "Funkcja szarego gniazda" + +#~ msgid "Gray front panel connector function" +#~ msgstr "Funkcja szarego gniazda na przednim panelu" + +#~ msgid "White connector function" +#~ msgstr "Funkcja biaÅ‚ego gniazda" + +#~ msgid "White front panel connector function" +#~ msgstr "Funkcja biaÅ‚ego gniazda na przednim panelu" + +#~ msgid "Red connector function" +#~ msgstr "Funkcja czerwonego gniazda" + +#~ msgid "Red front panel connector function" +#~ msgstr "Funkcja czerwonego gniazda na przednim panelu" + +#~ msgid "Yellow connector function" +#~ msgstr "Funkcja żółtego gniazda" + +#~ msgid "Yellow front panel connector function" +#~ msgstr "Funkcja żółtego gniazda na przednim panelu" + +#~ msgid "Virtual mixer channel configuration" +#~ msgstr "Konfiguracja kanałów wirtualnego miksera" diff --git a/po/pt_BR.po b/po/pt_BR.po index 1e8ada4c..5528a7ce 100644 --- a/po/pt_BR.po +++ b/po/pt_BR.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: gst-plugins-bad-0.10.10.2\n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n" -"POT-Creation-Date: 2009-06-17 21:54+0100\n" +"POT-Creation-Date: 2009-08-11 17:42+0100\n" "PO-Revision-Date: 2009-03-11 02:31-0300\n" "Last-Translator: FabrÃcio Godoy <skarllot@gmail.com>\n" "Language-Team: Brazilian Portuguese <ldp-br@bazar.conectiva.com.br>\n" @@ -76,203 +76,349 @@ msgstr "" "Não foi possÃvel abrir o dispositivo de áudio para manuseio do controle de " "mixer. Não há suporte a este elemento nesta versão do Open Sound System." -msgid "Fast" +msgid "Volume" +msgstr "" + +#, fuzzy +msgid "Master" msgstr "Rápido" -msgid "Low" -msgstr "Baixo" +msgid "Front" +msgstr "Frontal" -msgid "Medium" -msgstr "Médio" +msgid "Rear" +msgstr "Traseira" -msgid "High" -msgstr "Alto" +msgid "Headphones" +msgstr "Fones de ouvido" -msgid "Very high" -msgstr "Muito alto" +#, fuzzy +msgid "Center" +msgstr "Centro/LFE" -msgid "Production" -msgstr "Produção" +msgid "LFE" +msgstr "" -msgid "Off" -msgstr "Desligado" +#, fuzzy +msgid "Surround" +msgstr "Som surround" -msgid "On" -msgstr "Ligado" +msgid "Side" +msgstr "Lateral" + +msgid "Built-in Speaker" +msgstr "" + +msgid "AUX 1 Out" +msgstr "" + +msgid "AUX 2 Out" +msgstr "" + +msgid "AUX Out" +msgstr "" + +msgid "Bass" +msgstr "" + +msgid "Treble" +msgstr "" + +msgid "3D Depth" +msgstr "" + +msgid "3D Center" +msgstr "" + +msgid "3D Enhance" +msgstr "" + +#, fuzzy +msgid "Telephone" +msgstr "Fones de ouvido" + +msgid "Microphone" +msgstr "Microfone" + +msgid "Line Out" +msgstr "" + +#, fuzzy +msgid "Line In" +msgstr "Entrada de linha" + +msgid "Internal CD" +msgstr "" + +msgid "Video In" +msgstr "" + +msgid "AUX 1 In" +msgstr "" + +msgid "AUX 2 In" +msgstr "" + +msgid "AUX In" +msgstr "" + +msgid "PCM" +msgstr "PCM" + +msgid "Record Gain" +msgstr "" + +msgid "Output Gain" +msgstr "" + +#, fuzzy +msgid "Microphone Boost" +msgstr "Microfone" + +msgid "Loopback" +msgstr "" + +msgid "Diagnostic" +msgstr "" + +msgid "Bass Boost" +msgstr "" + +msgid "Playback Ports" +msgstr "" + +msgid "Input" +msgstr "Entrada" + +msgid "Record Source" +msgstr "" + +msgid "Monitor Source" +msgstr "" + +msgid "Keyboard Beep" +msgstr "" + +msgid "Monitor" +msgstr "" + +msgid "Simulate Stereo" +msgstr "" msgid "Stereo" msgstr "Estéreo" -msgid "Surround sound" +#, fuzzy +msgid "Surround Sound" msgstr "Som surround" -msgid "Input mix" -msgstr "Mistura de entrada" +#, fuzzy +msgid "Microphone Gain" +msgstr "Microfone" -msgid "Front" -msgstr "Frontal" +msgid "Speaker Source" +msgstr "" -msgid "Rear" -msgstr "Traseira" +#, fuzzy +msgid "Microphone Source" +msgstr "Microfone" -msgid "Side" -msgstr "Lateral" +msgid "Jack" +msgstr "" msgid "Center / LFE" msgstr "Centro/LFE" -msgid "Microphone" -msgstr "Microfone" +#, fuzzy +msgid "Stereo Mix" +msgstr "Estéreo" -msgid "Front panel microphone" -msgstr "Microfone do painel frontal" +msgid "Mono Mix" +msgstr "" -msgid "Input" -msgstr "Entrada" +#, fuzzy +msgid "Input Mix" +msgstr "Mistura de entrada" -msgid "Line-in" -msgstr "Entrada de linha" +msgid "SPDIF In" +msgstr "" -msgid "PCM 1" -msgstr "PCM 1" +msgid "SPDIF Out" +msgstr "" -msgid "PCM 2" -msgstr "PCM 2" +#, fuzzy +msgid "Microphone 1" +msgstr "Microfone" -msgid "PCM 3" -msgstr "PCM 3" +#, fuzzy +msgid "Microphone 2" +msgstr "Microfone" -msgid "PCM 4" -msgstr "PCM 4" +msgid "Digital Out" +msgstr "" -msgid "Green connector" -msgstr "Conector verde" +msgid "Digital In" +msgstr "" -msgid "Green front panel connector" -msgstr "Conector verde do painel frontal" +msgid "HDMI" +msgstr "" -msgid "Pink connector" -msgstr "Conector rosa" +msgid "Modem" +msgstr "" -msgid "Pink front panel connector" -msgstr "Conector rosa do painel frontal" +msgid "Handset" +msgstr "" -msgid "Blue connector" -msgstr "Conector azul" +msgid "Other" +msgstr "" -msgid "Blue front panel connector" -msgstr "Conector azul do painel frontal" +msgid "None" +msgstr "" -msgid "Orange connector" -msgstr "Conector laranja" +msgid "On" +msgstr "Ligado" -msgid "Orange front panel connector" -msgstr "Conector laranja do painel frontal" +msgid "Off" +msgstr "Desligado" -msgid "Black connector" -msgstr "Conector preto" +msgid "Mute" +msgstr "" -msgid "Black front panel connector" -msgstr "Conector preto do painel frontal" +msgid "Fast" +msgstr "Rápido" -msgid "Gray connector" -msgstr "Conector cinza" +msgid "Very Low" +msgstr "" -msgid "Gray front panel connector" -msgstr "Conector cinza do painel frontal" +msgid "Low" +msgstr "Baixo" -msgid "White connector" -msgstr "Conector branco" +msgid "Medium" +msgstr "Médio" -msgid "White front panel connector" -msgstr "Conector branco do painel frontal" +msgid "High" +msgstr "Alto" -msgid "Red connector" -msgstr "Conector vermelho" +#, fuzzy +msgid "Very High" +msgstr "Muito alto" -msgid "Red front panel connector" -msgstr "Conector vermelho do painel frontal" +msgid "Production" +msgstr "Produção" -msgid "Yellow connector" -msgstr "Conector amarelo" +#, fuzzy +msgid "Front Panel Microphone" +msgstr "Microfone do painel frontal" -msgid "Yellow front panel connector" -msgstr "Conector amarelo do painel frontal" +#, fuzzy +msgid "Front Panel Line In" +msgstr "Entrada de linha do painel frontal" -msgid "Green connector function" -msgstr "Função do conector verde" +#, fuzzy +msgid "Front Panel Headphones" +msgstr "Fones de ouvido do painel frontal" -msgid "Green front panel connector function" -msgstr "Função do conector verde do painel frontal" +#, fuzzy +msgid "Front Panel Line Out" +msgstr "Entrada de linha do painel frontal" -msgid "Pink connector function" -msgstr "Função do conector rosa" +#, fuzzy +msgid "Green Connector" +msgstr "Conector verde" -msgid "Pink front panel connector function" -msgstr "Função do conector rosa do painel frontal" +#, fuzzy +msgid "Pink Connector" +msgstr "Conector rosa" -msgid "Blue connector function" -msgstr "Função do conector azul" +#, fuzzy +msgid "Blue Connector" +msgstr "Conector azul" -msgid "Blue front panel connector function" -msgstr "Função do conector azul do painel frontal" +#, fuzzy +msgid "White Connector" +msgstr "Conector branco" -msgid "Orange connector function" -msgstr "Função do conector laranja" +#, fuzzy +msgid "Black Connector" +msgstr "Conector preto" -msgid "Orange front panel connector function" -msgstr "Função do conector laranja do painel frontal" +#, fuzzy +msgid "Gray Connector" +msgstr "Conector cinza" -msgid "Black connector function" -msgstr "Função do conector preto" +#, fuzzy +msgid "Orange Connector" +msgstr "Conector laranja" -msgid "Black front panel connector function" -msgstr "Função do conector preto do painel frontal" +#, fuzzy +msgid "Red Connector" +msgstr "Conector vermelho" -msgid "Gray connector function" -msgstr "Função do conector cinza" +#, fuzzy +msgid "Yellow Connector" +msgstr "Conector amarelo" -msgid "Gray front panel connector function" -msgstr "Função do conector cinza do painel frontal" +#, fuzzy +msgid "Green Front Panel Connector" +msgstr "Conector verde do painel frontal" -msgid "White connector function" -msgstr "Função do conector branco" +#, fuzzy +msgid "Pink Front Panel Connector" +msgstr "Conector rosa do painel frontal" -msgid "White front panel connector function" -msgstr "Função do conector branco do painel frontal" +#, fuzzy +msgid "Blue Front Panel Connector" +msgstr "Conector azul do painel frontal" -msgid "Red connector function" -msgstr "Função do conector vermelho" +#, fuzzy +msgid "White Front Panel Connector" +msgstr "Conector branco do painel frontal" -msgid "Red front panel connector function" -msgstr "Função do conector vermelho do painel frontal" +#, fuzzy +msgid "Black Front Panel Connector" +msgstr "Conector preto do painel frontal" -msgid "Yellow connector function" -msgstr "Função do conector amarelo" +#, fuzzy +msgid "Gray Front Panel Connector" +msgstr "Conector cinza do painel frontal" -msgid "Yellow front panel connector function" -msgstr "Função do conector amarelo do painel frontal" +#, fuzzy +msgid "Orange Front Panel Connector" +msgstr "Conector laranja do painel frontal" -msgid "Front panel line-in" -msgstr "Entrada de linha do painel frontal" +#, fuzzy +msgid "Red Front Panel Connector" +msgstr "Conector vermelho do painel frontal" -msgid "Headphones" -msgstr "Fones de ouvido" +#, fuzzy +msgid "Yellow Front Panel Connector" +msgstr "Conector amarelo do painel frontal" -msgid "Front panel headphones" -msgstr "Fones de ouvido do painel frontal" +msgid "Spread Output" +msgstr "" -msgid "PCM" -msgstr "PCM" +msgid "Downmix" +msgstr "" -msgid "Virtual mixer input" +#, fuzzy +msgid "Virtual Mixer Input" msgstr "Entrada do mixer virtual" -msgid "Virtual mixer output" +#, fuzzy +msgid "Virtual Mixer Output" msgstr "SaÃda do mixer virtual" -msgid "Virtual mixer channel configuration" -msgstr "Configuração de canal do mixer virtual" +#, fuzzy +msgid "Virtual Mixer Channels" +msgstr "Entrada do mixer virtual" + +#, c-format +msgid "%s Function" +msgstr "" + +#, c-format +msgid "%s %d" +msgstr "" msgid "" "Could not open audio device for playback. Device is being used by another " @@ -309,3 +455,72 @@ msgstr "Não há suporte a gravação neste dispositivo de áudio." msgid "Error recording from audio device." msgstr "Erro ao gravar deste dispositivo de áudio." + +#~ msgid "PCM 1" +#~ msgstr "PCM 1" + +#~ msgid "PCM 2" +#~ msgstr "PCM 2" + +#~ msgid "PCM 3" +#~ msgstr "PCM 3" + +#~ msgid "PCM 4" +#~ msgstr "PCM 4" + +#~ msgid "Green connector function" +#~ msgstr "Função do conector verde" + +#~ msgid "Green front panel connector function" +#~ msgstr "Função do conector verde do painel frontal" + +#~ msgid "Pink connector function" +#~ msgstr "Função do conector rosa" + +#~ msgid "Pink front panel connector function" +#~ msgstr "Função do conector rosa do painel frontal" + +#~ msgid "Blue connector function" +#~ msgstr "Função do conector azul" + +#~ msgid "Blue front panel connector function" +#~ msgstr "Função do conector azul do painel frontal" + +#~ msgid "Orange connector function" +#~ msgstr "Função do conector laranja" + +#~ msgid "Orange front panel connector function" +#~ msgstr "Função do conector laranja do painel frontal" + +#~ msgid "Black connector function" +#~ msgstr "Função do conector preto" + +#~ msgid "Black front panel connector function" +#~ msgstr "Função do conector preto do painel frontal" + +#~ msgid "Gray connector function" +#~ msgstr "Função do conector cinza" + +#~ msgid "Gray front panel connector function" +#~ msgstr "Função do conector cinza do painel frontal" + +#~ msgid "White connector function" +#~ msgstr "Função do conector branco" + +#~ msgid "White front panel connector function" +#~ msgstr "Função do conector branco do painel frontal" + +#~ msgid "Red connector function" +#~ msgstr "Função do conector vermelho" + +#~ msgid "Red front panel connector function" +#~ msgstr "Função do conector vermelho do painel frontal" + +#~ msgid "Yellow connector function" +#~ msgstr "Função do conector amarelo" + +#~ msgid "Yellow front panel connector function" +#~ msgstr "Função do conector amarelo do painel frontal" + +#~ msgid "Virtual mixer channel configuration" +#~ msgstr "Configuração de canal do mixer virtual" @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: gst-plugins-bad 0.10.9.3\n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n" -"POT-Creation-Date: 2009-06-17 21:54+0100\n" +"POT-Creation-Date: 2009-08-11 17:42+0100\n" "PO-Revision-Date: 2009-02-12 15:00+0200\n" "Last-Translator: Pavel Maryanov <acid_jack@ukr.net>\n" "Language-Team: Russian <gnu@mx.ru>\n" @@ -71,203 +71,349 @@ msgstr "" "Ðе удалоÑÑŒ открыть аудио-уÑтройÑтво Ð´Ð»Ñ Ð¾Ð±Ñ€Ð°Ð±Ð¾Ñ‚ÐºÐ¸ параметров микшера. Ð”Ð°Ð½Ð½Ð°Ñ " "верÑÐ¸Ñ Open Sound System не поддерживаетÑÑ Ñтим Ñлементом." -msgid "Fast" +msgid "Volume" +msgstr "" + +#, fuzzy +msgid "Master" msgstr "СкороÑÑ‚ÑŒ" -msgid "Low" -msgstr "Ðизкое" +msgid "Front" +msgstr "Фронт" -msgid "Medium" -msgstr "Среднее" +msgid "Rear" +msgstr "Тыл" -msgid "High" -msgstr "Ð’Ñ‹Ñокое" +msgid "Headphones" +msgstr "Ðаушники" -msgid "Very high" -msgstr "Очень выÑокое" +#, fuzzy +msgid "Center" +msgstr "Центр / Сабвуфер" -msgid "Production" -msgstr "ПродукциÑ" +msgid "LFE" +msgstr "" -msgid "Off" -msgstr "Выкл" +#, fuzzy +msgid "Surround" +msgstr "Объёмный звук" -msgid "On" -msgstr "Вкл" +msgid "Side" +msgstr "Боковые" + +msgid "Built-in Speaker" +msgstr "" + +msgid "AUX 1 Out" +msgstr "" + +msgid "AUX 2 Out" +msgstr "" + +msgid "AUX Out" +msgstr "" + +msgid "Bass" +msgstr "" + +msgid "Treble" +msgstr "" + +msgid "3D Depth" +msgstr "" + +msgid "3D Center" +msgstr "" + +msgid "3D Enhance" +msgstr "" + +#, fuzzy +msgid "Telephone" +msgstr "Ðаушники" + +msgid "Microphone" +msgstr "Микрофон" + +msgid "Line Out" +msgstr "" + +#, fuzzy +msgid "Line In" +msgstr "Линейный вход" + +msgid "Internal CD" +msgstr "" + +msgid "Video In" +msgstr "" + +msgid "AUX 1 In" +msgstr "" + +msgid "AUX 2 In" +msgstr "" + +msgid "AUX In" +msgstr "" + +msgid "PCM" +msgstr "PCM" + +msgid "Record Gain" +msgstr "" + +msgid "Output Gain" +msgstr "" + +#, fuzzy +msgid "Microphone Boost" +msgstr "Микрофон" + +msgid "Loopback" +msgstr "" + +msgid "Diagnostic" +msgstr "" + +msgid "Bass Boost" +msgstr "" + +msgid "Playback Ports" +msgstr "" + +msgid "Input" +msgstr "Вход" + +msgid "Record Source" +msgstr "" + +msgid "Monitor Source" +msgstr "" + +msgid "Keyboard Beep" +msgstr "" + +msgid "Monitor" +msgstr "" + +msgid "Simulate Stereo" +msgstr "" msgid "Stereo" msgstr "Стерео" -msgid "Surround sound" +#, fuzzy +msgid "Surround Sound" msgstr "Объёмный звук" -msgid "Input mix" -msgstr "Уровень входа" +#, fuzzy +msgid "Microphone Gain" +msgstr "Микрофон" -msgid "Front" -msgstr "Фронт" +msgid "Speaker Source" +msgstr "" -msgid "Rear" -msgstr "Тыл" +#, fuzzy +msgid "Microphone Source" +msgstr "Микрофон" -msgid "Side" -msgstr "Боковые" +msgid "Jack" +msgstr "" msgid "Center / LFE" msgstr "Центр / Сабвуфер" -msgid "Microphone" -msgstr "Микрофон" +#, fuzzy +msgid "Stereo Mix" +msgstr "Стерео" -msgid "Front panel microphone" -msgstr "Фронтальный микрофон" +msgid "Mono Mix" +msgstr "" -msgid "Input" -msgstr "Вход" +#, fuzzy +msgid "Input Mix" +msgstr "Уровень входа" -msgid "Line-in" -msgstr "Линейный вход" +msgid "SPDIF In" +msgstr "" -msgid "PCM 1" -msgstr "PCM 1" +msgid "SPDIF Out" +msgstr "" -msgid "PCM 2" -msgstr "PCM 2" +#, fuzzy +msgid "Microphone 1" +msgstr "Микрофон" -msgid "PCM 3" -msgstr "PCM 3" +#, fuzzy +msgid "Microphone 2" +msgstr "Микрофон" -msgid "PCM 4" -msgstr "PCM 4" +msgid "Digital Out" +msgstr "" -msgid "Green connector" -msgstr "Зелёный разъём" +msgid "Digital In" +msgstr "" -msgid "Green front panel connector" -msgstr "Фронтальный зелёный разъём" +msgid "HDMI" +msgstr "" -msgid "Pink connector" -msgstr "Розовый разъём" +msgid "Modem" +msgstr "" -msgid "Pink front panel connector" -msgstr "Фронтальный розовый разъём" +msgid "Handset" +msgstr "" -msgid "Blue connector" -msgstr "Синий разъём" +msgid "Other" +msgstr "" -msgid "Blue front panel connector" -msgstr "Фронтальный Ñиний разъём" +msgid "None" +msgstr "" -msgid "Orange connector" -msgstr "Оранжевый разъём" +msgid "On" +msgstr "Вкл" -msgid "Orange front panel connector" -msgstr "Фронтальный оранжевый разъём" +msgid "Off" +msgstr "Выкл" -msgid "Black connector" -msgstr "Чёрный разъём" +msgid "Mute" +msgstr "" -msgid "Black front panel connector" -msgstr "Фронтальный чёрный разъём" +msgid "Fast" +msgstr "СкороÑÑ‚ÑŒ" -msgid "Gray connector" -msgstr "Серый разъём" +msgid "Very Low" +msgstr "" -msgid "Gray front panel connector" -msgstr "Фронтальный Ñерый разъём" +msgid "Low" +msgstr "Ðизкое" -msgid "White connector" -msgstr "Белый разъём" +msgid "Medium" +msgstr "Среднее" -msgid "White front panel connector" -msgstr "Фронтальный белый разъём" +msgid "High" +msgstr "Ð’Ñ‹Ñокое" -msgid "Red connector" -msgstr "КраÑный разъём" +#, fuzzy +msgid "Very High" +msgstr "Очень выÑокое" -msgid "Red front panel connector" -msgstr "Фронтальный краÑный разъём" +msgid "Production" +msgstr "ПродукциÑ" -msgid "Yellow connector" -msgstr "Жёлтый разъём" +#, fuzzy +msgid "Front Panel Microphone" +msgstr "Фронтальный микрофон" -msgid "Yellow front panel connector" -msgstr "Фронтальный жёлтый разъём" +#, fuzzy +msgid "Front Panel Line In" +msgstr "Фронтальный линейный вход" -msgid "Green connector function" -msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ð·ÐµÐ»Ñ‘Ð½Ð¾Ð³Ð¾ разъёма" +#, fuzzy +msgid "Front Panel Headphones" +msgstr "Фронтальные наушники" -msgid "Green front panel connector function" -msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ñ„Ñ€Ð¾Ð½Ñ‚Ð°Ð»ÑŒÐ½Ð¾Ð³Ð¾ зелёного разъёма" +#, fuzzy +msgid "Front Panel Line Out" +msgstr "Фронтальный линейный вход" -msgid "Pink connector function" -msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ñ€Ð¾Ð·Ð¾Ð²Ð¾Ð³Ð¾ разъёма" +#, fuzzy +msgid "Green Connector" +msgstr "Зелёный разъём" -msgid "Pink front panel connector function" -msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ñ„Ñ€Ð¾Ð½Ñ‚Ð°Ð»ÑŒÐ½Ð¾Ð³Ð¾ розового разъёма" +#, fuzzy +msgid "Pink Connector" +msgstr "Розовый разъём" -msgid "Blue connector function" -msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ñинего разъёма" +#, fuzzy +msgid "Blue Connector" +msgstr "Синий разъём" -msgid "Blue front panel connector function" -msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ñ„Ñ€Ð¾Ð½Ñ‚Ð°Ð»ÑŒÐ½Ð¾Ð³Ð¾ Ñинего разъёма" +#, fuzzy +msgid "White Connector" +msgstr "Белый разъём" -msgid "Orange connector function" -msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ð¾Ñ€Ð°Ð½Ð¶ÐµÐ²Ð¾Ð³Ð¾ разъёма" +#, fuzzy +msgid "Black Connector" +msgstr "Чёрный разъём" -msgid "Orange front panel connector function" -msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ñ„Ñ€Ð¾Ð½Ñ‚Ð°Ð»ÑŒÐ½Ð¾Ð³Ð¾ оранжевого разъёма" +#, fuzzy +msgid "Gray Connector" +msgstr "Серый разъём" -msgid "Black connector function" -msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ñ‡Ñ‘Ñ€Ð½Ð¾Ð³Ð¾ разъёма" +#, fuzzy +msgid "Orange Connector" +msgstr "Оранжевый разъём" -msgid "Black front panel connector function" -msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ñ„Ñ€Ð¾Ð½Ñ‚Ð°Ð»ÑŒÐ½Ð¾Ð³Ð¾ чёрного разъёма" +#, fuzzy +msgid "Red Connector" +msgstr "КраÑный разъём" -msgid "Gray connector function" -msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ñерого разъёма" +#, fuzzy +msgid "Yellow Connector" +msgstr "Жёлтый разъём" -msgid "Gray front panel connector function" -msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ñ„Ñ€Ð¾Ð½Ñ‚Ð°Ð»ÑŒÐ½Ð¾Ð³Ð¾ Ñерого разъёма" +#, fuzzy +msgid "Green Front Panel Connector" +msgstr "Фронтальный зелёный разъём" -msgid "White connector function" -msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ð±ÐµÐ»Ð¾Ð³Ð¾ разъёма" +#, fuzzy +msgid "Pink Front Panel Connector" +msgstr "Фронтальный розовый разъём" -msgid "White front panel connector function" -msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ñ„Ñ€Ð¾Ð½Ñ‚Ð°Ð»ÑŒÐ½Ð¾Ð³Ð¾ белого разъёма" +#, fuzzy +msgid "Blue Front Panel Connector" +msgstr "Фронтальный Ñиний разъём" -msgid "Red connector function" -msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ ÐºÑ€Ð°Ñного разъёма" +#, fuzzy +msgid "White Front Panel Connector" +msgstr "Фронтальный белый разъём" -msgid "Red front panel connector function" -msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ñ„Ñ€Ð¾Ð½Ñ‚Ð°Ð»ÑŒÐ½Ð¾Ð³Ð¾ краÑного разъёма" +#, fuzzy +msgid "Black Front Panel Connector" +msgstr "Фронтальный чёрный разъём" -msgid "Yellow connector function" -msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ð¶Ñ‘Ð»Ñ‚Ð¾Ð³Ð¾ разъёма" +#, fuzzy +msgid "Gray Front Panel Connector" +msgstr "Фронтальный Ñерый разъём" -msgid "Yellow front panel connector function" -msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ñ„Ñ€Ð¾Ð½Ñ‚Ð°Ð»ÑŒÐ½Ð¾Ð³Ð¾ жёлтого разъёма" +#, fuzzy +msgid "Orange Front Panel Connector" +msgstr "Фронтальный оранжевый разъём" -msgid "Front panel line-in" -msgstr "Фронтальный линейный вход" +#, fuzzy +msgid "Red Front Panel Connector" +msgstr "Фронтальный краÑный разъём" -msgid "Headphones" -msgstr "Ðаушники" +#, fuzzy +msgid "Yellow Front Panel Connector" +msgstr "Фронтальный жёлтый разъём" -msgid "Front panel headphones" -msgstr "Фронтальные наушники" +msgid "Spread Output" +msgstr "" -msgid "PCM" -msgstr "PCM" +msgid "Downmix" +msgstr "" -msgid "Virtual mixer input" +#, fuzzy +msgid "Virtual Mixer Input" msgstr "Виртуальный вход микшера" -msgid "Virtual mixer output" +#, fuzzy +msgid "Virtual Mixer Output" msgstr "Виртуальный выход микшера" -msgid "Virtual mixer channel configuration" -msgstr "ÐšÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ Ð²Ð¸Ñ€Ñ‚ÑƒÐ°Ð»ÑŒÐ½Ñ‹Ñ… каналов микшера" +#, fuzzy +msgid "Virtual Mixer Channels" +msgstr "Виртуальный вход микшера" + +#, c-format +msgid "%s Function" +msgstr "" + +#, c-format +msgid "%s %d" +msgstr "" msgid "" "Could not open audio device for playback. Device is being used by another " @@ -315,3 +461,72 @@ msgstr "Ошибка запиÑи Ñ Ð°ÑƒÐ´Ð¸Ð¾-уÑтройÑтва." #~ msgstr "" #~ "Запрашиваемый битрейт %d кбит/Ñ Ð½ÐµÐ´Ð¾Ð¿ÑƒÑтим Ð´Ð»Ñ ÑвойÑтва «%s». Битрейт " #~ "изменён на %d кбит/Ñ." + +#~ msgid "PCM 1" +#~ msgstr "PCM 1" + +#~ msgid "PCM 2" +#~ msgstr "PCM 2" + +#~ msgid "PCM 3" +#~ msgstr "PCM 3" + +#~ msgid "PCM 4" +#~ msgstr "PCM 4" + +#~ msgid "Green connector function" +#~ msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ð·ÐµÐ»Ñ‘Ð½Ð¾Ð³Ð¾ разъёма" + +#~ msgid "Green front panel connector function" +#~ msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ñ„Ñ€Ð¾Ð½Ñ‚Ð°Ð»ÑŒÐ½Ð¾Ð³Ð¾ зелёного разъёма" + +#~ msgid "Pink connector function" +#~ msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ñ€Ð¾Ð·Ð¾Ð²Ð¾Ð³Ð¾ разъёма" + +#~ msgid "Pink front panel connector function" +#~ msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ñ„Ñ€Ð¾Ð½Ñ‚Ð°Ð»ÑŒÐ½Ð¾Ð³Ð¾ розового разъёма" + +#~ msgid "Blue connector function" +#~ msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ñинего разъёма" + +#~ msgid "Blue front panel connector function" +#~ msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ñ„Ñ€Ð¾Ð½Ñ‚Ð°Ð»ÑŒÐ½Ð¾Ð³Ð¾ Ñинего разъёма" + +#~ msgid "Orange connector function" +#~ msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ð¾Ñ€Ð°Ð½Ð¶ÐµÐ²Ð¾Ð³Ð¾ разъёма" + +#~ msgid "Orange front panel connector function" +#~ msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ñ„Ñ€Ð¾Ð½Ñ‚Ð°Ð»ÑŒÐ½Ð¾Ð³Ð¾ оранжевого разъёма" + +#~ msgid "Black connector function" +#~ msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ñ‡Ñ‘Ñ€Ð½Ð¾Ð³Ð¾ разъёма" + +#~ msgid "Black front panel connector function" +#~ msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ñ„Ñ€Ð¾Ð½Ñ‚Ð°Ð»ÑŒÐ½Ð¾Ð³Ð¾ чёрного разъёма" + +#~ msgid "Gray connector function" +#~ msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ñерого разъёма" + +#~ msgid "Gray front panel connector function" +#~ msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ñ„Ñ€Ð¾Ð½Ñ‚Ð°Ð»ÑŒÐ½Ð¾Ð³Ð¾ Ñерого разъёма" + +#~ msgid "White connector function" +#~ msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ð±ÐµÐ»Ð¾Ð³Ð¾ разъёма" + +#~ msgid "White front panel connector function" +#~ msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ñ„Ñ€Ð¾Ð½Ñ‚Ð°Ð»ÑŒÐ½Ð¾Ð³Ð¾ белого разъёма" + +#~ msgid "Red connector function" +#~ msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ ÐºÑ€Ð°Ñного разъёма" + +#~ msgid "Red front panel connector function" +#~ msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ñ„Ñ€Ð¾Ð½Ñ‚Ð°Ð»ÑŒÐ½Ð¾Ð³Ð¾ краÑного разъёма" + +#~ msgid "Yellow connector function" +#~ msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ð¶Ñ‘Ð»Ñ‚Ð¾Ð³Ð¾ разъёма" + +#~ msgid "Yellow front panel connector function" +#~ msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ñ„Ñ€Ð¾Ð½Ñ‚Ð°Ð»ÑŒÐ½Ð¾Ð³Ð¾ жёлтого разъёма" + +#~ msgid "Virtual mixer channel configuration" +#~ msgstr "ÐšÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ Ð²Ð¸Ñ€Ñ‚ÑƒÐ°Ð»ÑŒÐ½Ñ‹Ñ… каналов микшера" @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: gst-plugins-bad 0.10.8.3\n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n" -"POT-Creation-Date: 2009-06-17 21:54+0100\n" +"POT-Creation-Date: 2009-08-11 17:42+0100\n" "PO-Revision-Date: 2008-11-04 09:39+0100\n" "Last-Translator: Peter Tuhársky <tuharsky@misbb.sk>\n" "Language-Team: Slovak <sk-i18n@lists.linux.sk>\n" @@ -76,203 +76,349 @@ msgstr "" "Nepodarilo sa otvoriÅ¥ zvukové zariadenie pre obsluhu ovládania mixéra. Táto " "verzia Open Sound System nie je podporovaná týmto prvkom." -msgid "Fast" +msgid "Volume" +msgstr "" + +#, fuzzy +msgid "Master" msgstr "Rýchla" -msgid "Low" -msgstr "NÃzka" +msgid "Front" +msgstr "Predné" -msgid "Medium" -msgstr "Stredná" +msgid "Rear" +msgstr "Zadné" -msgid "High" -msgstr "Vysoká" +msgid "Headphones" +msgstr "Slúchadlá" -msgid "Very high" -msgstr "Veľmi vysoká" +#, fuzzy +msgid "Center" +msgstr "Stredné / LFE" -msgid "Production" -msgstr "ProdukÄná" +msgid "LFE" +msgstr "" -msgid "Off" -msgstr "Vyp" +#, fuzzy +msgid "Surround" +msgstr "Surround" -msgid "On" -msgstr "Zap" +msgid "Side" +msgstr "Postranné" + +msgid "Built-in Speaker" +msgstr "" + +msgid "AUX 1 Out" +msgstr "" + +msgid "AUX 2 Out" +msgstr "" + +msgid "AUX Out" +msgstr "" + +msgid "Bass" +msgstr "" + +msgid "Treble" +msgstr "" + +msgid "3D Depth" +msgstr "" + +msgid "3D Center" +msgstr "" + +msgid "3D Enhance" +msgstr "" + +#, fuzzy +msgid "Telephone" +msgstr "Slúchadlá" + +msgid "Microphone" +msgstr "Mikrofón" + +msgid "Line Out" +msgstr "" + +#, fuzzy +msgid "Line In" +msgstr "Linkový vstup" + +msgid "Internal CD" +msgstr "" + +msgid "Video In" +msgstr "" + +msgid "AUX 1 In" +msgstr "" + +msgid "AUX 2 In" +msgstr "" + +msgid "AUX In" +msgstr "" + +msgid "PCM" +msgstr "PCM" + +msgid "Record Gain" +msgstr "" + +msgid "Output Gain" +msgstr "" + +#, fuzzy +msgid "Microphone Boost" +msgstr "Mikrofón" + +msgid "Loopback" +msgstr "" + +msgid "Diagnostic" +msgstr "" + +msgid "Bass Boost" +msgstr "" + +msgid "Playback Ports" +msgstr "" + +msgid "Input" +msgstr "Vstup" + +msgid "Record Source" +msgstr "" + +msgid "Monitor Source" +msgstr "" + +msgid "Keyboard Beep" +msgstr "" + +msgid "Monitor" +msgstr "" + +msgid "Simulate Stereo" +msgstr "" msgid "Stereo" msgstr "Stereo" -msgid "Surround sound" +#, fuzzy +msgid "Surround Sound" msgstr "Surround" -msgid "Input mix" -msgstr "Vstup mix" +#, fuzzy +msgid "Microphone Gain" +msgstr "Mikrofón" -msgid "Front" -msgstr "Predné" +msgid "Speaker Source" +msgstr "" -msgid "Rear" -msgstr "Zadné" +#, fuzzy +msgid "Microphone Source" +msgstr "Mikrofón" -msgid "Side" -msgstr "Postranné" +msgid "Jack" +msgstr "" msgid "Center / LFE" msgstr "Stredné / LFE" -msgid "Microphone" -msgstr "Mikrofón" +#, fuzzy +msgid "Stereo Mix" +msgstr "Stereo" -msgid "Front panel microphone" -msgstr "Mikrofón predného panelu" +msgid "Mono Mix" +msgstr "" -msgid "Input" -msgstr "Vstup" +#, fuzzy +msgid "Input Mix" +msgstr "Vstup mix" -msgid "Line-in" -msgstr "Linkový vstup" +msgid "SPDIF In" +msgstr "" -msgid "PCM 1" -msgstr "PCM 1" +msgid "SPDIF Out" +msgstr "" -msgid "PCM 2" -msgstr "PCM 2" +#, fuzzy +msgid "Microphone 1" +msgstr "Mikrofón" -msgid "PCM 3" -msgstr "PCM 3" +#, fuzzy +msgid "Microphone 2" +msgstr "Mikrofón" -msgid "PCM 4" -msgstr "PCM 4" +msgid "Digital Out" +msgstr "" -msgid "Green connector" -msgstr "Zelený konektor" +msgid "Digital In" +msgstr "" -msgid "Green front panel connector" -msgstr "Zelený konektor na prednom paneli" +msgid "HDMI" +msgstr "" -msgid "Pink connector" -msgstr "Ružový konektor" +msgid "Modem" +msgstr "" -msgid "Pink front panel connector" -msgstr "Ružový konektor na prednom paneli" +msgid "Handset" +msgstr "" -msgid "Blue connector" -msgstr "Modrý konektor" +msgid "Other" +msgstr "" -msgid "Blue front panel connector" -msgstr "Modrý konektor na prednom paneli" +msgid "None" +msgstr "" -msgid "Orange connector" -msgstr "Oranžový konektor" +msgid "On" +msgstr "Zap" -msgid "Orange front panel connector" -msgstr "Oranžový konektor na prednom paneli" +msgid "Off" +msgstr "Vyp" -msgid "Black connector" -msgstr "ÄŒierny konektor" +msgid "Mute" +msgstr "" -msgid "Black front panel connector" -msgstr "ÄŒierny konektor na prednom paneli" +msgid "Fast" +msgstr "Rýchla" -msgid "Gray connector" -msgstr "Å edý konektor" +msgid "Very Low" +msgstr "" -msgid "Gray front panel connector" -msgstr "Å edý konektor na prednom paneli" +msgid "Low" +msgstr "NÃzka" -msgid "White connector" -msgstr "Biely konektor" +msgid "Medium" +msgstr "Stredná" -msgid "White front panel connector" -msgstr "Biely konektor na prednom paneli" +msgid "High" +msgstr "Vysoká" -msgid "Red connector" -msgstr "ÄŒervený konektor" +#, fuzzy +msgid "Very High" +msgstr "Veľmi vysoká" -msgid "Red front panel connector" -msgstr "ÄŒervený konektor na prednom paneli" +msgid "Production" +msgstr "ProdukÄná" -msgid "Yellow connector" -msgstr "Žltý konektor" +#, fuzzy +msgid "Front Panel Microphone" +msgstr "Mikrofón predného panelu" -msgid "Yellow front panel connector" -msgstr "Žltý konektor na prednom paneli" +#, fuzzy +msgid "Front Panel Line In" +msgstr "Linkový vstup na prednom paneli" -msgid "Green connector function" -msgstr "Funkcia zeleného konektora" +#, fuzzy +msgid "Front Panel Headphones" +msgstr "Slúchadlá na prednom paneli" -msgid "Green front panel connector function" -msgstr "Funkcia zeleného konektora na prednom paneli" +#, fuzzy +msgid "Front Panel Line Out" +msgstr "Linkový vstup na prednom paneli" -msgid "Pink connector function" -msgstr "Funkcia ružového konektora" +#, fuzzy +msgid "Green Connector" +msgstr "Zelený konektor" -msgid "Pink front panel connector function" -msgstr "Funkcia ružového konektora na prednom paneli" +#, fuzzy +msgid "Pink Connector" +msgstr "Ružový konektor" -msgid "Blue connector function" -msgstr "Funkcia modrého konektora" +#, fuzzy +msgid "Blue Connector" +msgstr "Modrý konektor" -msgid "Blue front panel connector function" -msgstr "Funkcia modrého konektora na prednom paneli" +#, fuzzy +msgid "White Connector" +msgstr "Biely konektor" -msgid "Orange connector function" -msgstr "Funkcia oranžového konektora" +#, fuzzy +msgid "Black Connector" +msgstr "ÄŒierny konektor" -msgid "Orange front panel connector function" -msgstr "Funkcia oranžového konektora na prednom paneli" +#, fuzzy +msgid "Gray Connector" +msgstr "Å edý konektor" -msgid "Black connector function" -msgstr "Funkcia Äierneho konektora" +#, fuzzy +msgid "Orange Connector" +msgstr "Oranžový konektor" -msgid "Black front panel connector function" -msgstr "Funkcia Äierneho konektora na prednom paneli" +#, fuzzy +msgid "Red Connector" +msgstr "ÄŒervený konektor" -msgid "Gray connector function" -msgstr "Funkcia Å¡edého konektora" +#, fuzzy +msgid "Yellow Connector" +msgstr "Žltý konektor" -msgid "Gray front panel connector function" -msgstr "Funkcia Å¡edého konektora na prednom paneli" +#, fuzzy +msgid "Green Front Panel Connector" +msgstr "Zelený konektor na prednom paneli" -msgid "White connector function" -msgstr "Funkcia bieleho konektora" +#, fuzzy +msgid "Pink Front Panel Connector" +msgstr "Ružový konektor na prednom paneli" -msgid "White front panel connector function" -msgstr "Funkcia bieleho konektora na prednom paneli" +#, fuzzy +msgid "Blue Front Panel Connector" +msgstr "Modrý konektor na prednom paneli" -msgid "Red connector function" -msgstr "Funkcia Äerveného konektora" +#, fuzzy +msgid "White Front Panel Connector" +msgstr "Biely konektor na prednom paneli" -msgid "Red front panel connector function" -msgstr "Funkcia Äerveného konektora na prednom paneli" +#, fuzzy +msgid "Black Front Panel Connector" +msgstr "ÄŒierny konektor na prednom paneli" -msgid "Yellow connector function" -msgstr "Funkcia žltého konektora" +#, fuzzy +msgid "Gray Front Panel Connector" +msgstr "Å edý konektor na prednom paneli" -msgid "Yellow front panel connector function" -msgstr "Funkcia žltého konektora na prednom paneli" +#, fuzzy +msgid "Orange Front Panel Connector" +msgstr "Oranžový konektor na prednom paneli" -msgid "Front panel line-in" -msgstr "Linkový vstup na prednom paneli" +#, fuzzy +msgid "Red Front Panel Connector" +msgstr "ÄŒervený konektor na prednom paneli" -msgid "Headphones" -msgstr "Slúchadlá" +#, fuzzy +msgid "Yellow Front Panel Connector" +msgstr "Žltý konektor na prednom paneli" -msgid "Front panel headphones" -msgstr "Slúchadlá na prednom paneli" +msgid "Spread Output" +msgstr "" -msgid "PCM" -msgstr "PCM" +msgid "Downmix" +msgstr "" -msgid "Virtual mixer input" +#, fuzzy +msgid "Virtual Mixer Input" msgstr "Vstup virtuálneho mixéra" -msgid "Virtual mixer output" +#, fuzzy +msgid "Virtual Mixer Output" msgstr "Výstup virtuálneho mixéra" -msgid "Virtual mixer channel configuration" -msgstr "Konfigurácia kanálov virtuálneho mixéra" +#, fuzzy +msgid "Virtual Mixer Channels" +msgstr "Vstup virtuálneho mixéra" + +#, c-format +msgid "%s Function" +msgstr "" + +#, c-format +msgid "%s %d" +msgstr "" msgid "" "Could not open audio device for playback. Device is being used by another " @@ -321,3 +467,72 @@ msgstr "Chyba pri zázname zo zvukového zariadenia." #~ msgstr "" #~ "Požadovaná bitová rýchlosÅ¥ %d kbit/s pre vlastnosÅ¥ '%s' nie je povolená. " #~ "RýchlosÅ¥ bola zmenená na %d kbit/s." + +#~ msgid "PCM 1" +#~ msgstr "PCM 1" + +#~ msgid "PCM 2" +#~ msgstr "PCM 2" + +#~ msgid "PCM 3" +#~ msgstr "PCM 3" + +#~ msgid "PCM 4" +#~ msgstr "PCM 4" + +#~ msgid "Green connector function" +#~ msgstr "Funkcia zeleného konektora" + +#~ msgid "Green front panel connector function" +#~ msgstr "Funkcia zeleného konektora na prednom paneli" + +#~ msgid "Pink connector function" +#~ msgstr "Funkcia ružového konektora" + +#~ msgid "Pink front panel connector function" +#~ msgstr "Funkcia ružového konektora na prednom paneli" + +#~ msgid "Blue connector function" +#~ msgstr "Funkcia modrého konektora" + +#~ msgid "Blue front panel connector function" +#~ msgstr "Funkcia modrého konektora na prednom paneli" + +#~ msgid "Orange connector function" +#~ msgstr "Funkcia oranžového konektora" + +#~ msgid "Orange front panel connector function" +#~ msgstr "Funkcia oranžového konektora na prednom paneli" + +#~ msgid "Black connector function" +#~ msgstr "Funkcia Äierneho konektora" + +#~ msgid "Black front panel connector function" +#~ msgstr "Funkcia Äierneho konektora na prednom paneli" + +#~ msgid "Gray connector function" +#~ msgstr "Funkcia Å¡edého konektora" + +#~ msgid "Gray front panel connector function" +#~ msgstr "Funkcia Å¡edého konektora na prednom paneli" + +#~ msgid "White connector function" +#~ msgstr "Funkcia bieleho konektora" + +#~ msgid "White front panel connector function" +#~ msgstr "Funkcia bieleho konektora na prednom paneli" + +#~ msgid "Red connector function" +#~ msgstr "Funkcia Äerveného konektora" + +#~ msgid "Red front panel connector function" +#~ msgstr "Funkcia Äerveného konektora na prednom paneli" + +#~ msgid "Yellow connector function" +#~ msgstr "Funkcia žltého konektora" + +#~ msgid "Yellow front panel connector function" +#~ msgstr "Funkcia žltého konektora na prednom paneli" + +#~ msgid "Virtual mixer channel configuration" +#~ msgstr "Konfigurácia kanálov virtuálneho mixéra" @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: gst-plugins-bad 0.10.7.2\n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n" -"POT-Creation-Date: 2009-06-17 21:54+0100\n" +"POT-Creation-Date: 2009-08-11 17:42+0100\n" "PO-Revision-Date: 2008-08-15 16:07+0200\n" "Last-Translator: Laurent Dhima <laurenti@alblinux.net>\n" "Language-Team: Albanian <translation-team-sq@lists.sourceforge.net>\n" @@ -72,208 +72,327 @@ msgid "" "Open Sound System is not supported by this element." msgstr "" -msgid "Fast" +msgid "Volume" +msgstr "Volumi" + +msgid "Master" msgstr "" -msgid "Low" +msgid "Front" msgstr "" -msgid "Medium" +#, fuzzy +msgid "Rear" +msgstr "Regjistrimi" + +msgid "Headphones" msgstr "" -msgid "High" +msgid "Center" msgstr "" -msgid "Very high" +msgid "LFE" msgstr "" -msgid "Production" +msgid "Surround" msgstr "" -msgid "Off" +#, fuzzy +msgid "Side" +msgstr "Video" + +#, fuzzy +msgid "Built-in Speaker" +msgstr "Zë folës" + +msgid "AUX 1 Out" msgstr "" -msgid "On" +msgid "AUX 2 Out" msgstr "" -msgid "Stereo" +msgid "AUX Out" msgstr "" -msgid "Surround sound" +msgid "Bass" +msgstr "Bas" + +msgid "Treble" +msgstr "Treble" + +msgid "3D Depth" msgstr "" -msgid "Input mix" +msgid "3D Center" msgstr "" -msgid "Front" +msgid "3D Enhance" +msgstr "" + +msgid "Telephone" +msgstr "" + +msgid "Microphone" +msgstr "Mikrofoni" + +msgid "Line Out" msgstr "" #, fuzzy -msgid "Rear" -msgstr "Regjistrimi" +msgid "Line In" +msgstr "Linja-hyrje" + +msgid "Internal CD" +msgstr "" #, fuzzy -msgid "Side" +msgid "Video In" msgstr "Video" -msgid "Center / LFE" +msgid "AUX 1 In" msgstr "" -msgid "Microphone" +msgid "AUX 2 In" +msgstr "" + +msgid "AUX In" +msgstr "" + +msgid "PCM" +msgstr "PCM" + +#, fuzzy +msgid "Record Gain" +msgstr "Regjistrimi" + +#, fuzzy +msgid "Output Gain" +msgstr "Out-gain" + +#, fuzzy +msgid "Microphone Boost" msgstr "Mikrofoni" -msgid "Front panel microphone" +msgid "Loopback" +msgstr "" + +msgid "Diagnostic" +msgstr "" + +msgid "Bass Boost" +msgstr "" + +msgid "Playback Ports" msgstr "" msgid "Input" msgstr "" -msgid "Line-in" -msgstr "Linja-hyrje" +#, fuzzy +msgid "Record Source" +msgstr "Regjistrimi" #, fuzzy -msgid "PCM 1" -msgstr "PCM" +msgid "Monitor Source" +msgstr "Ekrani" + +msgid "Keyboard Beep" +msgstr "" + +msgid "Monitor" +msgstr "Ekrani" + +msgid "Simulate Stereo" +msgstr "" + +msgid "Stereo" +msgstr "" + +msgid "Surround Sound" +msgstr "" #, fuzzy -msgid "PCM 2" -msgstr "PCM-2" +msgid "Microphone Gain" +msgstr "Mikrofoni" #, fuzzy -msgid "PCM 3" -msgstr "PCM" +msgid "Speaker Source" +msgstr "Zë folës" #, fuzzy -msgid "PCM 4" -msgstr "PCM" +msgid "Microphone Source" +msgstr "Mikrofoni" -msgid "Green connector" +msgid "Jack" msgstr "" -msgid "Green front panel connector" +msgid "Center / LFE" msgstr "" -msgid "Pink connector" +msgid "Stereo Mix" msgstr "" -msgid "Pink front panel connector" +msgid "Mono Mix" msgstr "" -msgid "Blue connector" +msgid "Input Mix" msgstr "" -msgid "Blue front panel connector" +msgid "SPDIF In" msgstr "" -msgid "Orange connector" +msgid "SPDIF Out" msgstr "" -msgid "Orange front panel connector" +#, fuzzy +msgid "Microphone 1" +msgstr "Mikrofoni" + +#, fuzzy +msgid "Microphone 2" +msgstr "Mikrofoni" + +#, fuzzy +msgid "Digital Out" +msgstr "Dixhitale-1" + +#, fuzzy +msgid "Digital In" +msgstr "Dixhitale-1" + +msgid "HDMI" msgstr "" -msgid "Black connector" +msgid "Modem" msgstr "" -msgid "Black front panel connector" +msgid "Handset" msgstr "" -msgid "Gray connector" +msgid "Other" msgstr "" -msgid "Gray front panel connector" +msgid "None" msgstr "" -msgid "White connector" +msgid "On" msgstr "" -msgid "White front panel connector" +msgid "Off" msgstr "" -msgid "Red connector" +msgid "Mute" msgstr "" -msgid "Red front panel connector" +msgid "Fast" msgstr "" -msgid "Yellow connector" +msgid "Very Low" msgstr "" -msgid "Yellow front panel connector" +msgid "Low" msgstr "" -msgid "Green connector function" +msgid "Medium" msgstr "" -msgid "Green front panel connector function" +msgid "High" msgstr "" -msgid "Pink connector function" +msgid "Very High" msgstr "" -msgid "Pink front panel connector function" +msgid "Production" msgstr "" -msgid "Blue connector function" +#, fuzzy +msgid "Front Panel Microphone" +msgstr "Mikrofoni" + +msgid "Front Panel Line In" msgstr "" -msgid "Blue front panel connector function" +msgid "Front Panel Headphones" msgstr "" -msgid "Orange connector function" +msgid "Front Panel Line Out" msgstr "" -msgid "Orange front panel connector function" +msgid "Green Connector" msgstr "" -msgid "Black connector function" +msgid "Pink Connector" msgstr "" -msgid "Black front panel connector function" +msgid "Blue Connector" msgstr "" -msgid "Gray connector function" +msgid "White Connector" msgstr "" -msgid "Gray front panel connector function" +msgid "Black Connector" msgstr "" -msgid "White connector function" +msgid "Gray Connector" msgstr "" -msgid "White front panel connector function" +msgid "Orange Connector" msgstr "" -msgid "Red connector function" +msgid "Red Connector" msgstr "" -msgid "Red front panel connector function" +msgid "Yellow Connector" msgstr "" -msgid "Yellow connector function" +msgid "Green Front Panel Connector" msgstr "" -msgid "Yellow front panel connector function" +msgid "Pink Front Panel Connector" msgstr "" -msgid "Front panel line-in" +msgid "Blue Front Panel Connector" msgstr "" -msgid "Headphones" +msgid "White Front Panel Connector" msgstr "" -msgid "Front panel headphones" +msgid "Black Front Panel Connector" msgstr "" -msgid "PCM" -msgstr "PCM" +msgid "Gray Front Panel Connector" +msgstr "" + +msgid "Orange Front Panel Connector" +msgstr "" + +msgid "Red Front Panel Connector" +msgstr "" + +msgid "Yellow Front Panel Connector" +msgstr "" + +msgid "Spread Output" +msgstr "" + +msgid "Downmix" +msgstr "" -msgid "Virtual mixer input" +msgid "Virtual Mixer Input" msgstr "" -msgid "Virtual mixer output" +msgid "Virtual Mixer Output" msgstr "" -msgid "Virtual mixer channel configuration" +msgid "Virtual Mixer Channels" +msgstr "" + +#, c-format +msgid "%s Function" +msgstr "" + +#, c-format +msgid "%s %d" msgstr "" msgid "" @@ -360,33 +479,21 @@ msgstr "" #~ msgid "Your OSS device could not be probed correctly" #~ msgstr "Dispozitivi juaj OSS mund të mos provohet korrektësisht" -#~ msgid "Volume" -#~ msgstr "Volumi" - -#~ msgid "Bass" -#~ msgstr "Bas" - -#~ msgid "Treble" -#~ msgstr "Treble" - #~ msgid "Synth" #~ msgstr "Sintetizuesi" -#~ msgid "Speaker" -#~ msgstr "Zë folës" - #~ msgid "CD" #~ msgstr "CD" #~ msgid "Mixer" #~ msgstr "Kontrolli i volumit" +#~ msgid "PCM-2" +#~ msgstr "PCM-2" + #~ msgid "In-gain" #~ msgstr "In-gain" -#~ msgid "Out-gain" -#~ msgstr "Out-gain" - #~ msgid "Line-1" #~ msgstr "Linja-1" @@ -396,9 +503,6 @@ msgstr "" #~ msgid "Line-3" #~ msgstr "Linja-3" -#~ msgid "Digital-1" -#~ msgstr "Dixhitale-1" - #~ msgid "Digital-2" #~ msgstr "Dixhitale-2" @@ -414,13 +518,6 @@ msgstr "" #~ msgid "Radio" #~ msgstr "Radio" -#~ msgid "Monitor" -#~ msgstr "Ekrani" - -#, fuzzy -#~ msgid "PC Speaker" -#~ msgstr "Zë folës" - #~ msgid "Could not open CD device for reading." #~ msgstr "I pamundur hapja e dispozitivit CD për lexim." @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: gst-plugins 0.7.6\n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n" -"POT-Creation-Date: 2009-06-17 21:54+0100\n" +"POT-Creation-Date: 2009-08-11 17:42+0100\n" "PO-Revision-Date: 2004-03-13 00:18+0100\n" "Last-Translator: Danilo Segan <dsegan@gmx.net>\n" "Language-Team: Serbian <gnu@prevod.org>\n" @@ -73,208 +73,327 @@ msgid "" "Open Sound System is not supported by this element." msgstr "" -msgid "Fast" +msgid "Volume" +msgstr "Јачина звука" + +msgid "Master" msgstr "" -msgid "Low" +msgid "Front" msgstr "" -msgid "Medium" +#, fuzzy +msgid "Rear" +msgstr "Снимање" + +msgid "Headphones" msgstr "" -msgid "High" +msgid "Center" msgstr "" -msgid "Very high" +msgid "LFE" msgstr "" -msgid "Production" +msgid "Surround" msgstr "" -msgid "Off" +#, fuzzy +msgid "Side" +msgstr "Видео" + +#, fuzzy +msgid "Built-in Speaker" +msgstr "Звучник" + +msgid "AUX 1 Out" msgstr "" -msgid "On" +msgid "AUX 2 Out" msgstr "" -msgid "Stereo" +msgid "AUX Out" msgstr "" -msgid "Surround sound" +msgid "Bass" +msgstr "БаÑ" + +msgid "Treble" +msgstr "Шум" + +msgid "3D Depth" msgstr "" -msgid "Input mix" +msgid "3D Center" msgstr "" -msgid "Front" +msgid "3D Enhance" +msgstr "" + +msgid "Telephone" +msgstr "" + +msgid "Microphone" +msgstr "Микрофон" + +msgid "Line Out" msgstr "" #, fuzzy -msgid "Rear" -msgstr "Снимање" +msgid "Line In" +msgstr "Ул.лин." + +msgid "Internal CD" +msgstr "" #, fuzzy -msgid "Side" +msgid "Video In" msgstr "Видео" -msgid "Center / LFE" +msgid "AUX 1 In" msgstr "" -msgid "Microphone" +msgid "AUX 2 In" +msgstr "" + +msgid "AUX In" +msgstr "" + +msgid "PCM" +msgstr "ПЦМ" + +#, fuzzy +msgid "Record Gain" +msgstr "Снимање" + +#, fuzzy +msgid "Output Gain" +msgstr "Из. пој." + +#, fuzzy +msgid "Microphone Boost" msgstr "Микрофон" -msgid "Front panel microphone" +msgid "Loopback" +msgstr "" + +msgid "Diagnostic" +msgstr "" + +msgid "Bass Boost" +msgstr "" + +msgid "Playback Ports" msgstr "" msgid "Input" msgstr "" -msgid "Line-in" -msgstr "Ул.лин." +#, fuzzy +msgid "Record Source" +msgstr "Снимање" #, fuzzy -msgid "PCM 1" -msgstr "ПЦМ" +msgid "Monitor Source" +msgstr "Праћење" + +msgid "Keyboard Beep" +msgstr "" + +msgid "Monitor" +msgstr "Праћење" + +msgid "Simulate Stereo" +msgstr "" + +msgid "Stereo" +msgstr "" + +msgid "Surround Sound" +msgstr "" #, fuzzy -msgid "PCM 2" -msgstr "ПЦМ-2" +msgid "Microphone Gain" +msgstr "Микрофон" #, fuzzy -msgid "PCM 3" -msgstr "ПЦМ" +msgid "Speaker Source" +msgstr "Звучник" #, fuzzy -msgid "PCM 4" -msgstr "ПЦМ" +msgid "Microphone Source" +msgstr "Микрофон" -msgid "Green connector" +msgid "Jack" msgstr "" -msgid "Green front panel connector" +msgid "Center / LFE" msgstr "" -msgid "Pink connector" +msgid "Stereo Mix" msgstr "" -msgid "Pink front panel connector" +msgid "Mono Mix" msgstr "" -msgid "Blue connector" +msgid "Input Mix" msgstr "" -msgid "Blue front panel connector" +msgid "SPDIF In" msgstr "" -msgid "Orange connector" +msgid "SPDIF Out" msgstr "" -msgid "Orange front panel connector" +#, fuzzy +msgid "Microphone 1" +msgstr "Микрофон" + +#, fuzzy +msgid "Microphone 2" +msgstr "Микрофон" + +#, fuzzy +msgid "Digital Out" +msgstr "Диг. 1" + +#, fuzzy +msgid "Digital In" +msgstr "Диг. 1" + +msgid "HDMI" msgstr "" -msgid "Black connector" +msgid "Modem" msgstr "" -msgid "Black front panel connector" +msgid "Handset" msgstr "" -msgid "Gray connector" +msgid "Other" msgstr "" -msgid "Gray front panel connector" +msgid "None" msgstr "" -msgid "White connector" +msgid "On" msgstr "" -msgid "White front panel connector" +msgid "Off" msgstr "" -msgid "Red connector" +msgid "Mute" msgstr "" -msgid "Red front panel connector" +msgid "Fast" msgstr "" -msgid "Yellow connector" +msgid "Very Low" msgstr "" -msgid "Yellow front panel connector" +msgid "Low" msgstr "" -msgid "Green connector function" +msgid "Medium" msgstr "" -msgid "Green front panel connector function" +msgid "High" msgstr "" -msgid "Pink connector function" +msgid "Very High" msgstr "" -msgid "Pink front panel connector function" +msgid "Production" msgstr "" -msgid "Blue connector function" +#, fuzzy +msgid "Front Panel Microphone" +msgstr "Микрофон" + +msgid "Front Panel Line In" msgstr "" -msgid "Blue front panel connector function" +msgid "Front Panel Headphones" msgstr "" -msgid "Orange connector function" +msgid "Front Panel Line Out" msgstr "" -msgid "Orange front panel connector function" +msgid "Green Connector" msgstr "" -msgid "Black connector function" +msgid "Pink Connector" msgstr "" -msgid "Black front panel connector function" +msgid "Blue Connector" msgstr "" -msgid "Gray connector function" +msgid "White Connector" msgstr "" -msgid "Gray front panel connector function" +msgid "Black Connector" msgstr "" -msgid "White connector function" +msgid "Gray Connector" msgstr "" -msgid "White front panel connector function" +msgid "Orange Connector" msgstr "" -msgid "Red connector function" +msgid "Red Connector" msgstr "" -msgid "Red front panel connector function" +msgid "Yellow Connector" msgstr "" -msgid "Yellow connector function" +msgid "Green Front Panel Connector" msgstr "" -msgid "Yellow front panel connector function" +msgid "Pink Front Panel Connector" msgstr "" -msgid "Front panel line-in" +msgid "Blue Front Panel Connector" msgstr "" -msgid "Headphones" +msgid "White Front Panel Connector" msgstr "" -msgid "Front panel headphones" +msgid "Black Front Panel Connector" msgstr "" -msgid "PCM" -msgstr "ПЦМ" +msgid "Gray Front Panel Connector" +msgstr "" + +msgid "Orange Front Panel Connector" +msgstr "" + +msgid "Red Front Panel Connector" +msgstr "" + +msgid "Yellow Front Panel Connector" +msgstr "" + +msgid "Spread Output" +msgstr "" + +msgid "Downmix" +msgstr "" -msgid "Virtual mixer input" +msgid "Virtual Mixer Input" msgstr "" -msgid "Virtual mixer output" +msgid "Virtual Mixer Output" msgstr "" -msgid "Virtual mixer channel configuration" +msgid "Virtual Mixer Channels" +msgstr "" + +#, c-format +msgid "%s Function" +msgstr "" + +#, c-format +msgid "%s %d" msgstr "" msgid "" @@ -356,33 +475,21 @@ msgstr "" #~ msgid "Could not open device \"%s\" for reading." #~ msgstr "Ðе могу да отворим уређај „%s“ ради читања." -#~ msgid "Volume" -#~ msgstr "Јачина звука" - -#~ msgid "Bass" -#~ msgstr "БаÑ" - -#~ msgid "Treble" -#~ msgstr "Шум" - #~ msgid "Synth" #~ msgstr "Синт." -#~ msgid "Speaker" -#~ msgstr "Звучник" - #~ msgid "CD" #~ msgstr "ЦД" #~ msgid "Mixer" #~ msgstr "МикÑер" +#~ msgid "PCM-2" +#~ msgstr "ПЦМ-2" + #~ msgid "In-gain" #~ msgstr "Ул. пој." -#~ msgid "Out-gain" -#~ msgstr "Из. пој." - #~ msgid "Line-1" #~ msgstr "Лин. 1" @@ -392,9 +499,6 @@ msgstr "" #~ msgid "Line-3" #~ msgstr "Лин. 3" -#~ msgid "Digital-1" -#~ msgstr "Диг. 1" - #~ msgid "Digital-2" #~ msgstr "Диг. 2" @@ -410,13 +514,6 @@ msgstr "" #~ msgid "Radio" #~ msgstr "Радио" -#~ msgid "Monitor" -#~ msgstr "Праћење" - -#, fuzzy -#~ msgid "PC Speaker" -#~ msgstr "Звучник" - #~ msgid "Could not open CD device for reading." #~ msgstr "Ðе могу да отворим ЦД уређај ради читања." @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: gst-plugins-bad 0.10.9.3\n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n" -"POT-Creation-Date: 2009-06-17 21:54+0100\n" +"POT-Creation-Date: 2009-08-11 17:42+0100\n" "PO-Revision-Date: 2009-01-23 00:44+0100\n" "Last-Translator: Daniel Nylander <po@danielnylander.se>\n" "Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n" @@ -71,204 +71,351 @@ msgstr "" "Kunde inte öppna ljudenheten för mixningshantering. Denna version av Open " "Sound System stöds inte av detta element." -msgid "Fast" +msgid "Volume" +msgstr "" + +#, fuzzy +msgid "Master" msgstr "Snabb" -msgid "Low" -msgstr "LÃ¥g" +msgid "Front" +msgstr "Fram" -msgid "Medium" -msgstr "Medel" +msgid "Rear" +msgstr "Bak" -msgid "High" -msgstr "Hög" +msgid "Headphones" +msgstr "Hörlurar" -msgid "Very high" -msgstr "Mycket hög" +# LFE=lÃ¥gfrekvenseffekter +#, fuzzy +msgid "Center" +msgstr "Center / LFE" -msgid "Production" -msgstr "Produktion" +msgid "LFE" +msgstr "" -msgid "Off" -msgstr "Av" +#, fuzzy +msgid "Surround" +msgstr "Surroundljud" -msgid "On" -msgstr "PÃ¥" +msgid "Side" +msgstr "Sida" + +msgid "Built-in Speaker" +msgstr "" + +msgid "AUX 1 Out" +msgstr "" + +msgid "AUX 2 Out" +msgstr "" + +msgid "AUX Out" +msgstr "" + +msgid "Bass" +msgstr "" + +msgid "Treble" +msgstr "" + +msgid "3D Depth" +msgstr "" + +msgid "3D Center" +msgstr "" + +msgid "3D Enhance" +msgstr "" + +#, fuzzy +msgid "Telephone" +msgstr "Hörlurar" + +msgid "Microphone" +msgstr "Mikrofon" + +msgid "Line Out" +msgstr "" + +#, fuzzy +msgid "Line In" +msgstr "Linje-in" + +msgid "Internal CD" +msgstr "" + +msgid "Video In" +msgstr "" + +msgid "AUX 1 In" +msgstr "" + +msgid "AUX 2 In" +msgstr "" + +msgid "AUX In" +msgstr "" + +msgid "PCM" +msgstr "PCM" + +msgid "Record Gain" +msgstr "" + +msgid "Output Gain" +msgstr "" + +#, fuzzy +msgid "Microphone Boost" +msgstr "Mikrofon" + +msgid "Loopback" +msgstr "" + +msgid "Diagnostic" +msgstr "" + +msgid "Bass Boost" +msgstr "" + +msgid "Playback Ports" +msgstr "" + +msgid "Input" +msgstr "IngÃ¥ng" + +msgid "Record Source" +msgstr "" + +msgid "Monitor Source" +msgstr "" + +msgid "Keyboard Beep" +msgstr "" + +msgid "Monitor" +msgstr "" + +msgid "Simulate Stereo" +msgstr "" msgid "Stereo" msgstr "Stereo" -msgid "Surround sound" +#, fuzzy +msgid "Surround Sound" msgstr "Surroundljud" -msgid "Input mix" -msgstr "IngÃ¥ngsmix" +#, fuzzy +msgid "Microphone Gain" +msgstr "Mikrofon" -msgid "Front" -msgstr "Fram" +msgid "Speaker Source" +msgstr "" -msgid "Rear" -msgstr "Bak" +#, fuzzy +msgid "Microphone Source" +msgstr "Mikrofon" -msgid "Side" -msgstr "Sida" +msgid "Jack" +msgstr "" # LFE=lÃ¥gfrekvenseffekter msgid "Center / LFE" msgstr "Center / LFE" -msgid "Microphone" -msgstr "Mikrofon" +#, fuzzy +msgid "Stereo Mix" +msgstr "Stereo" -msgid "Front panel microphone" -msgstr "Frontpanelsmikrofon" +msgid "Mono Mix" +msgstr "" -msgid "Input" -msgstr "IngÃ¥ng" +#, fuzzy +msgid "Input Mix" +msgstr "IngÃ¥ngsmix" -msgid "Line-in" -msgstr "Linje-in" +msgid "SPDIF In" +msgstr "" -msgid "PCM 1" -msgstr "PCM 1" +msgid "SPDIF Out" +msgstr "" -msgid "PCM 2" -msgstr "PCM 2" +#, fuzzy +msgid "Microphone 1" +msgstr "Mikrofon" -msgid "PCM 3" -msgstr "PCM 3" +#, fuzzy +msgid "Microphone 2" +msgstr "Mikrofon" -msgid "PCM 4" -msgstr "PCM 4" +msgid "Digital Out" +msgstr "" -msgid "Green connector" -msgstr "Grön kontakt" +msgid "Digital In" +msgstr "" -msgid "Green front panel connector" -msgstr "Grön frontpanelskontakt" +msgid "HDMI" +msgstr "" -msgid "Pink connector" -msgstr "Rosa kontakt" +msgid "Modem" +msgstr "" -msgid "Pink front panel connector" -msgstr "Rosa frontpanelskontakt" +msgid "Handset" +msgstr "" -msgid "Blue connector" -msgstr "BlÃ¥ kontakt" +msgid "Other" +msgstr "" -msgid "Blue front panel connector" -msgstr "BlÃ¥ frontpanelskontakt" +msgid "None" +msgstr "" -msgid "Orange connector" -msgstr "Orange kontakt" +msgid "On" +msgstr "PÃ¥" -msgid "Orange front panel connector" -msgstr "Orange frontpanelskontakt" +msgid "Off" +msgstr "Av" -msgid "Black connector" -msgstr "Svart kontakt" +msgid "Mute" +msgstr "" -msgid "Black front panel connector" -msgstr "Svart frontpanelskontakt" +msgid "Fast" +msgstr "Snabb" -msgid "Gray connector" -msgstr "GrÃ¥ kontakt" +msgid "Very Low" +msgstr "" -msgid "Gray front panel connector" -msgstr "GrÃ¥ frontpanelskontakt" +msgid "Low" +msgstr "LÃ¥g" -msgid "White connector" -msgstr "Vit kontakt" +msgid "Medium" +msgstr "Medel" -msgid "White front panel connector" -msgstr "Vit frontpanelskontakt" +msgid "High" +msgstr "Hög" -msgid "Red connector" -msgstr "Röd kontakt" +#, fuzzy +msgid "Very High" +msgstr "Mycket hög" -msgid "Red front panel connector" -msgstr "Röd frontpanelskontakt" +msgid "Production" +msgstr "Produktion" -msgid "Yellow connector" -msgstr "Gul kontakt" +#, fuzzy +msgid "Front Panel Microphone" +msgstr "Frontpanelsmikrofon" -msgid "Yellow front panel connector" -msgstr "Gul frontpanelskontakt" +#, fuzzy +msgid "Front Panel Line In" +msgstr "Linje-in pÃ¥ frontpanel" -msgid "Green connector function" -msgstr "Funktion för grön kontakt" +#, fuzzy +msgid "Front Panel Headphones" +msgstr "Hörlurar pÃ¥ frontpanel" -msgid "Green front panel connector function" -msgstr "Funktion för grön frontpanelskontakt" +#, fuzzy +msgid "Front Panel Line Out" +msgstr "Linje-in pÃ¥ frontpanel" -msgid "Pink connector function" -msgstr "Funktion för rosa kontakt" +#, fuzzy +msgid "Green Connector" +msgstr "Grön kontakt" -msgid "Pink front panel connector function" -msgstr "Funktion för rosa frontpanelskontakt" +#, fuzzy +msgid "Pink Connector" +msgstr "Rosa kontakt" -msgid "Blue connector function" -msgstr "Funktion för blÃ¥ kontakt" +#, fuzzy +msgid "Blue Connector" +msgstr "BlÃ¥ kontakt" -msgid "Blue front panel connector function" -msgstr "Funktion för blÃ¥ frontpanelskontakt" +#, fuzzy +msgid "White Connector" +msgstr "Vit kontakt" -msgid "Orange connector function" -msgstr "Funktion för orange kontakt" +#, fuzzy +msgid "Black Connector" +msgstr "Svart kontakt" -msgid "Orange front panel connector function" -msgstr "Funktion för orange frontpanelskontakt" +#, fuzzy +msgid "Gray Connector" +msgstr "GrÃ¥ kontakt" -msgid "Black connector function" -msgstr "Funktion för svart kontakt" +#, fuzzy +msgid "Orange Connector" +msgstr "Orange kontakt" -msgid "Black front panel connector function" -msgstr "Funktion för svart frontpanelskontakt" +#, fuzzy +msgid "Red Connector" +msgstr "Röd kontakt" -msgid "Gray connector function" -msgstr "Funktion för grÃ¥ kontakt" +#, fuzzy +msgid "Yellow Connector" +msgstr "Gul kontakt" -msgid "Gray front panel connector function" -msgstr "Funktion för grÃ¥ frontpanelskontakt" +#, fuzzy +msgid "Green Front Panel Connector" +msgstr "Grön frontpanelskontakt" -msgid "White connector function" -msgstr "Funktion för vit kontakt" +#, fuzzy +msgid "Pink Front Panel Connector" +msgstr "Rosa frontpanelskontakt" -msgid "White front panel connector function" -msgstr "Funktion för vit frontpanelskontakt" +#, fuzzy +msgid "Blue Front Panel Connector" +msgstr "BlÃ¥ frontpanelskontakt" -msgid "Red connector function" -msgstr "Funktion för röd kontakt" +#, fuzzy +msgid "White Front Panel Connector" +msgstr "Vit frontpanelskontakt" -msgid "Red front panel connector function" -msgstr "Funktion för röd frontpanelskontakt" +#, fuzzy +msgid "Black Front Panel Connector" +msgstr "Svart frontpanelskontakt" -msgid "Yellow connector function" -msgstr "Funktion för gul kontakt" +#, fuzzy +msgid "Gray Front Panel Connector" +msgstr "GrÃ¥ frontpanelskontakt" -msgid "Yellow front panel connector function" -msgstr "Funktion för gul frontpanelskontakt" +#, fuzzy +msgid "Orange Front Panel Connector" +msgstr "Orange frontpanelskontakt" -msgid "Front panel line-in" -msgstr "Linje-in pÃ¥ frontpanel" +#, fuzzy +msgid "Red Front Panel Connector" +msgstr "Röd frontpanelskontakt" -msgid "Headphones" -msgstr "Hörlurar" +#, fuzzy +msgid "Yellow Front Panel Connector" +msgstr "Gul frontpanelskontakt" -msgid "Front panel headphones" -msgstr "Hörlurar pÃ¥ frontpanel" +msgid "Spread Output" +msgstr "" -msgid "PCM" -msgstr "PCM" +msgid "Downmix" +msgstr "" -msgid "Virtual mixer input" +#, fuzzy +msgid "Virtual Mixer Input" msgstr "Virtuell mixeringÃ¥ng" -msgid "Virtual mixer output" +#, fuzzy +msgid "Virtual Mixer Output" msgstr "Virtuell mixerutgÃ¥ng" -msgid "Virtual mixer channel configuration" -msgstr "Kanalkonfiguration för virtuell mixer" +#, fuzzy +msgid "Virtual Mixer Channels" +msgstr "Virtuell mixeringÃ¥ng" + +#, c-format +msgid "%s Function" +msgstr "" + +#, c-format +msgid "%s %d" +msgstr "" msgid "" "Could not open audio device for playback. Device is being used by another " @@ -318,6 +465,75 @@ msgstr "Fel vid inspelning frÃ¥n ljudenhet." #~ "Den begärda bitfrekvensen %d kbit/s för egenskapen \"%s\" tillÃ¥ts inte. " #~ "Bitfrekvensen ändrades till %d kbit/s." +#~ msgid "PCM 1" +#~ msgstr "PCM 1" + +#~ msgid "PCM 2" +#~ msgstr "PCM 2" + +#~ msgid "PCM 3" +#~ msgstr "PCM 3" + +#~ msgid "PCM 4" +#~ msgstr "PCM 4" + +#~ msgid "Green connector function" +#~ msgstr "Funktion för grön kontakt" + +#~ msgid "Green front panel connector function" +#~ msgstr "Funktion för grön frontpanelskontakt" + +#~ msgid "Pink connector function" +#~ msgstr "Funktion för rosa kontakt" + +#~ msgid "Pink front panel connector function" +#~ msgstr "Funktion för rosa frontpanelskontakt" + +#~ msgid "Blue connector function" +#~ msgstr "Funktion för blÃ¥ kontakt" + +#~ msgid "Blue front panel connector function" +#~ msgstr "Funktion för blÃ¥ frontpanelskontakt" + +#~ msgid "Orange connector function" +#~ msgstr "Funktion för orange kontakt" + +#~ msgid "Orange front panel connector function" +#~ msgstr "Funktion för orange frontpanelskontakt" + +#~ msgid "Black connector function" +#~ msgstr "Funktion för svart kontakt" + +#~ msgid "Black front panel connector function" +#~ msgstr "Funktion för svart frontpanelskontakt" + +#~ msgid "Gray connector function" +#~ msgstr "Funktion för grÃ¥ kontakt" + +#~ msgid "Gray front panel connector function" +#~ msgstr "Funktion för grÃ¥ frontpanelskontakt" + +#~ msgid "White connector function" +#~ msgstr "Funktion för vit kontakt" + +#~ msgid "White front panel connector function" +#~ msgstr "Funktion för vit frontpanelskontakt" + +#~ msgid "Red connector function" +#~ msgstr "Funktion för röd kontakt" + +#~ msgid "Red front panel connector function" +#~ msgstr "Funktion för röd frontpanelskontakt" + +#~ msgid "Yellow connector function" +#~ msgstr "Funktion för gul kontakt" + +#~ msgid "Yellow front panel connector function" +#~ msgstr "Funktion för gul frontpanelskontakt" + +#~ msgid "Virtual mixer channel configuration" +#~ msgstr "Kanalkonfiguration för virtuell mixer" + #~ msgid "This file is corrupt and cannot be played." #~ msgstr "Den här filen är skadad och kan inte spelas upp." @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: gst-plugins-bad-0.10.10.2\n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n" -"POT-Creation-Date: 2009-06-17 21:54+0100\n" +"POT-Creation-Date: 2009-08-11 17:42+0100\n" "PO-Revision-Date: 2009-03-11 08:01+0200\n" "Last-Translator: Server Acim <sacim@kde.org.tr>\n" "Language-Team: Turkish <gnu-tr-u12a@lists.sourceforge.net>\n" @@ -71,203 +71,349 @@ msgstr "" "Karıştırıcı iÅŸlemi için ses aygıtı açılamıyor. Bu öğe tarafından Açık Ses " "Sistemi'nin bu sürümü desteklenmiyor." -msgid "Fast" +msgid "Volume" +msgstr "" + +#, fuzzy +msgid "Master" msgstr "Hızlı" -msgid "Low" -msgstr "Düşük" +msgid "Front" +msgstr "Ön" -msgid "Medium" -msgstr "Orta" +msgid "Rear" +msgstr "Arka" -msgid "High" -msgstr "Yüksek" +msgid "Headphones" +msgstr "Kulaklıklar" -msgid "Very high" -msgstr "Çok yüksek" +#, fuzzy +msgid "Center" +msgstr "Merkez / LFE" -msgid "Production" -msgstr "Yapım" +msgid "LFE" +msgstr "" -msgid "Off" -msgstr "Kapalı" +#, fuzzy +msgid "Surround" +msgstr "Surround ses" -msgid "On" -msgstr "Açık" +msgid "Side" +msgstr "Yan" + +msgid "Built-in Speaker" +msgstr "" + +msgid "AUX 1 Out" +msgstr "" + +msgid "AUX 2 Out" +msgstr "" + +msgid "AUX Out" +msgstr "" + +msgid "Bass" +msgstr "" + +msgid "Treble" +msgstr "" + +msgid "3D Depth" +msgstr "" + +msgid "3D Center" +msgstr "" + +msgid "3D Enhance" +msgstr "" + +#, fuzzy +msgid "Telephone" +msgstr "Kulaklıklar" + +msgid "Microphone" +msgstr "Mikrofon" + +msgid "Line Out" +msgstr "" + +#, fuzzy +msgid "Line In" +msgstr "Hat giriÅŸi" + +msgid "Internal CD" +msgstr "" + +msgid "Video In" +msgstr "" + +msgid "AUX 1 In" +msgstr "" + +msgid "AUX 2 In" +msgstr "" + +msgid "AUX In" +msgstr "" + +msgid "PCM" +msgstr "PCM" + +msgid "Record Gain" +msgstr "" + +msgid "Output Gain" +msgstr "" + +#, fuzzy +msgid "Microphone Boost" +msgstr "Mikrofon" + +msgid "Loopback" +msgstr "" + +msgid "Diagnostic" +msgstr "" + +msgid "Bass Boost" +msgstr "" + +msgid "Playback Ports" +msgstr "" + +msgid "Input" +msgstr "GiriÅŸ" + +msgid "Record Source" +msgstr "" + +msgid "Monitor Source" +msgstr "" + +msgid "Keyboard Beep" +msgstr "" + +msgid "Monitor" +msgstr "" + +msgid "Simulate Stereo" +msgstr "" msgid "Stereo" msgstr "Stereo" -msgid "Surround sound" +#, fuzzy +msgid "Surround Sound" msgstr "Surround ses" -msgid "Input mix" -msgstr "GiriÅŸ karışımı" +#, fuzzy +msgid "Microphone Gain" +msgstr "Mikrofon" -msgid "Front" -msgstr "Ön" +msgid "Speaker Source" +msgstr "" -msgid "Rear" -msgstr "Arka" +#, fuzzy +msgid "Microphone Source" +msgstr "Mikrofon" -msgid "Side" -msgstr "Yan" +msgid "Jack" +msgstr "" msgid "Center / LFE" msgstr "Merkez / LFE" -msgid "Microphone" -msgstr "Mikrofon" +#, fuzzy +msgid "Stereo Mix" +msgstr "Stereo" -msgid "Front panel microphone" -msgstr "Ön panel mikrofonu" +msgid "Mono Mix" +msgstr "" -msgid "Input" -msgstr "GiriÅŸ" +#, fuzzy +msgid "Input Mix" +msgstr "GiriÅŸ karışımı" -msgid "Line-in" -msgstr "Hat giriÅŸi" +msgid "SPDIF In" +msgstr "" -msgid "PCM 1" -msgstr "PCM 1" +msgid "SPDIF Out" +msgstr "" -msgid "PCM 2" -msgstr "PCM 2" +#, fuzzy +msgid "Microphone 1" +msgstr "Mikrofon" -msgid "PCM 3" -msgstr "PCM 3" +#, fuzzy +msgid "Microphone 2" +msgstr "Mikrofon" -msgid "PCM 4" -msgstr "PCM 4" +msgid "Digital Out" +msgstr "" -msgid "Green connector" -msgstr "YeÅŸil konnektör" +msgid "Digital In" +msgstr "" -msgid "Green front panel connector" -msgstr "YeÅŸil ön panel konnektörü" +msgid "HDMI" +msgstr "" -msgid "Pink connector" -msgstr "Pembe konnektör" +msgid "Modem" +msgstr "" -msgid "Pink front panel connector" -msgstr "Pembe ön panel könnektörü" +msgid "Handset" +msgstr "" -msgid "Blue connector" -msgstr "Mavi konnektör" +msgid "Other" +msgstr "" -msgid "Blue front panel connector" -msgstr "Mavi ön panel konnektörü" +msgid "None" +msgstr "" -msgid "Orange connector" -msgstr "Portakal konnektör" +msgid "On" +msgstr "Açık" -msgid "Orange front panel connector" -msgstr "Portakal ön panel konnektörü" +msgid "Off" +msgstr "Kapalı" -msgid "Black connector" -msgstr "Siyah konnektör" +msgid "Mute" +msgstr "" -msgid "Black front panel connector" -msgstr "Siyah ön panel konnektörü" +msgid "Fast" +msgstr "Hızlı" -msgid "Gray connector" -msgstr "Gri konnektör" +msgid "Very Low" +msgstr "" -msgid "Gray front panel connector" -msgstr "Gri ön panel konnektörü" +msgid "Low" +msgstr "Düşük" -msgid "White connector" -msgstr "Beyaz konnektör" +msgid "Medium" +msgstr "Orta" -msgid "White front panel connector" -msgstr "Beyaz ön panel konnektörü" +msgid "High" +msgstr "Yüksek" -msgid "Red connector" -msgstr "Kırmızı konnektör" +#, fuzzy +msgid "Very High" +msgstr "Çok yüksek" -msgid "Red front panel connector" -msgstr "Kırmızı ön panel konnektörü" +msgid "Production" +msgstr "Yapım" -msgid "Yellow connector" -msgstr "Sarı konnektör" +#, fuzzy +msgid "Front Panel Microphone" +msgstr "Ön panel mikrofonu" -msgid "Yellow front panel connector" -msgstr "Sarı ön panel konnektörü" +#, fuzzy +msgid "Front Panel Line In" +msgstr "Ön panel hat giriÅŸi" -msgid "Green connector function" -msgstr "YeÅŸil konnektör iÅŸlevi" +#, fuzzy +msgid "Front Panel Headphones" +msgstr "Ön panel kulaklıkları" -msgid "Green front panel connector function" -msgstr "YeÅŸil ön panel konnektör iÅŸlevi" +#, fuzzy +msgid "Front Panel Line Out" +msgstr "Ön panel hat giriÅŸi" -msgid "Pink connector function" -msgstr "Pembe konnektör iÅŸlevi" +#, fuzzy +msgid "Green Connector" +msgstr "YeÅŸil konnektör" -msgid "Pink front panel connector function" -msgstr "Pembe ön panel konnektör iÅŸlevi" +#, fuzzy +msgid "Pink Connector" +msgstr "Pembe konnektör" -msgid "Blue connector function" -msgstr "Mavi konnektör iÅŸlevi" +#, fuzzy +msgid "Blue Connector" +msgstr "Mavi konnektör" -msgid "Blue front panel connector function" -msgstr "Mavi ön panel konnektör iÅŸlevi" +#, fuzzy +msgid "White Connector" +msgstr "Beyaz konnektör" -msgid "Orange connector function" -msgstr "Portakal konnektör iÅŸlevi" +#, fuzzy +msgid "Black Connector" +msgstr "Siyah konnektör" -msgid "Orange front panel connector function" -msgstr "Portakal ön panel konnektör iÅŸlevi" +#, fuzzy +msgid "Gray Connector" +msgstr "Gri konnektör" -msgid "Black connector function" -msgstr "Siyah konnektör iÅŸlevi" +#, fuzzy +msgid "Orange Connector" +msgstr "Portakal konnektör" -msgid "Black front panel connector function" -msgstr "Siyah ön panel konnektör iÅŸlevi" +#, fuzzy +msgid "Red Connector" +msgstr "Kırmızı konnektör" -msgid "Gray connector function" -msgstr "Gri konnektör iÅŸlevi" +#, fuzzy +msgid "Yellow Connector" +msgstr "Sarı konnektör" -msgid "Gray front panel connector function" -msgstr "Gri ön panel konnektör iÅŸlevi" +#, fuzzy +msgid "Green Front Panel Connector" +msgstr "YeÅŸil ön panel konnektörü" -msgid "White connector function" -msgstr "Beyaz konnektör iÅŸlevi" +#, fuzzy +msgid "Pink Front Panel Connector" +msgstr "Pembe ön panel könnektörü" -msgid "White front panel connector function" -msgstr "Beyaz ön panel konnektör iÅŸlevi" +#, fuzzy +msgid "Blue Front Panel Connector" +msgstr "Mavi ön panel konnektörü" -msgid "Red connector function" -msgstr "Kırmızı konnektör iÅŸlevi" +#, fuzzy +msgid "White Front Panel Connector" +msgstr "Beyaz ön panel konnektörü" -msgid "Red front panel connector function" -msgstr "Kırmızı ön panel konnektör iÅŸlevi" +#, fuzzy +msgid "Black Front Panel Connector" +msgstr "Siyah ön panel konnektörü" -msgid "Yellow connector function" -msgstr "Sarı konnektör iÅŸlevi" +#, fuzzy +msgid "Gray Front Panel Connector" +msgstr "Gri ön panel konnektörü" -msgid "Yellow front panel connector function" -msgstr "Sarı ön panel konnektör iÅŸlevi" +#, fuzzy +msgid "Orange Front Panel Connector" +msgstr "Portakal ön panel konnektörü" -msgid "Front panel line-in" -msgstr "Ön panel hat giriÅŸi" +#, fuzzy +msgid "Red Front Panel Connector" +msgstr "Kırmızı ön panel konnektörü" -msgid "Headphones" -msgstr "Kulaklıklar" +#, fuzzy +msgid "Yellow Front Panel Connector" +msgstr "Sarı ön panel konnektörü" -msgid "Front panel headphones" -msgstr "Ön panel kulaklıkları" +msgid "Spread Output" +msgstr "" -msgid "PCM" -msgstr "PCM" +msgid "Downmix" +msgstr "" -msgid "Virtual mixer input" +#, fuzzy +msgid "Virtual Mixer Input" msgstr "Sanal karıştırıcı giriÅŸi" -msgid "Virtual mixer output" +#, fuzzy +msgid "Virtual Mixer Output" msgstr "Sanal karıştırıcı çıkışı" -msgid "Virtual mixer channel configuration" -msgstr "Sanal karıştırıcı kanal yapılandırması" +#, fuzzy +msgid "Virtual Mixer Channels" +msgstr "Sanal karıştırıcı giriÅŸi" + +#, c-format +msgid "%s Function" +msgstr "" + +#, c-format +msgid "%s %d" +msgstr "" msgid "" "Could not open audio device for playback. Device is being used by another " @@ -302,3 +448,72 @@ msgstr "Bu ses aygıtı kayıt iÅŸlevini desteklemiyor." msgid "Error recording from audio device." msgstr "Ses aygıtı ile kayıtta hata." + +#~ msgid "PCM 1" +#~ msgstr "PCM 1" + +#~ msgid "PCM 2" +#~ msgstr "PCM 2" + +#~ msgid "PCM 3" +#~ msgstr "PCM 3" + +#~ msgid "PCM 4" +#~ msgstr "PCM 4" + +#~ msgid "Green connector function" +#~ msgstr "YeÅŸil konnektör iÅŸlevi" + +#~ msgid "Green front panel connector function" +#~ msgstr "YeÅŸil ön panel konnektör iÅŸlevi" + +#~ msgid "Pink connector function" +#~ msgstr "Pembe konnektör iÅŸlevi" + +#~ msgid "Pink front panel connector function" +#~ msgstr "Pembe ön panel konnektör iÅŸlevi" + +#~ msgid "Blue connector function" +#~ msgstr "Mavi konnektör iÅŸlevi" + +#~ msgid "Blue front panel connector function" +#~ msgstr "Mavi ön panel konnektör iÅŸlevi" + +#~ msgid "Orange connector function" +#~ msgstr "Portakal konnektör iÅŸlevi" + +#~ msgid "Orange front panel connector function" +#~ msgstr "Portakal ön panel konnektör iÅŸlevi" + +#~ msgid "Black connector function" +#~ msgstr "Siyah konnektör iÅŸlevi" + +#~ msgid "Black front panel connector function" +#~ msgstr "Siyah ön panel konnektör iÅŸlevi" + +#~ msgid "Gray connector function" +#~ msgstr "Gri konnektör iÅŸlevi" + +#~ msgid "Gray front panel connector function" +#~ msgstr "Gri ön panel konnektör iÅŸlevi" + +#~ msgid "White connector function" +#~ msgstr "Beyaz konnektör iÅŸlevi" + +#~ msgid "White front panel connector function" +#~ msgstr "Beyaz ön panel konnektör iÅŸlevi" + +#~ msgid "Red connector function" +#~ msgstr "Kırmızı konnektör iÅŸlevi" + +#~ msgid "Red front panel connector function" +#~ msgstr "Kırmızı ön panel konnektör iÅŸlevi" + +#~ msgid "Yellow connector function" +#~ msgstr "Sarı konnektör iÅŸlevi" + +#~ msgid "Yellow front panel connector function" +#~ msgstr "Sarı ön panel konnektör iÅŸlevi" + +#~ msgid "Virtual mixer channel configuration" +#~ msgstr "Sanal karıştırıcı kanal yapılandırması" @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: gst-plugins-bad 0.10.5\n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n" -"POT-Creation-Date: 2009-06-17 21:54+0100\n" +"POT-Creation-Date: 2009-08-11 17:42+0100\n" "PO-Revision-Date: 2007-07-04 12:19+0200\n" "Last-Translator: Maxim V. Dziumanenko <dziumanenko@gmail.com>\n" "Language-Team: Ukrainian <translation-team-uk@lists.sourceforge.net>\n" @@ -72,202 +72,309 @@ msgid "" "Open Sound System is not supported by this element." msgstr "" -msgid "Fast" +msgid "Volume" msgstr "" -msgid "Low" +msgid "Master" msgstr "" -msgid "Medium" +msgid "Front" msgstr "" -msgid "High" +msgid "Rear" msgstr "" -msgid "Very high" +msgid "Headphones" msgstr "" -msgid "Production" +msgid "Center" msgstr "" -msgid "Off" +msgid "LFE" msgstr "" -msgid "On" +msgid "Surround" msgstr "" -msgid "Stereo" +msgid "Side" msgstr "" -msgid "Surround sound" +msgid "Built-in Speaker" msgstr "" -msgid "Input mix" +msgid "AUX 1 Out" msgstr "" -msgid "Front" +msgid "AUX 2 Out" msgstr "" -msgid "Rear" +msgid "AUX Out" msgstr "" -msgid "Side" +msgid "Bass" msgstr "" -msgid "Center / LFE" +msgid "Treble" +msgstr "" + +msgid "3D Depth" +msgstr "" + +msgid "3D Center" +msgstr "" + +msgid "3D Enhance" +msgstr "" + +msgid "Telephone" msgstr "" msgid "Microphone" msgstr "" -msgid "Front panel microphone" +msgid "Line Out" +msgstr "" + +msgid "Line In" +msgstr "" + +msgid "Internal CD" +msgstr "" + +msgid "Video In" +msgstr "" + +msgid "AUX 1 In" +msgstr "" + +msgid "AUX 2 In" +msgstr "" + +msgid "AUX In" +msgstr "" + +msgid "PCM" +msgstr "" + +msgid "Record Gain" +msgstr "" + +msgid "Output Gain" +msgstr "" + +msgid "Microphone Boost" +msgstr "" + +msgid "Loopback" +msgstr "" + +msgid "Diagnostic" +msgstr "" + +msgid "Bass Boost" +msgstr "" + +msgid "Playback Ports" msgstr "" msgid "Input" msgstr "" -msgid "Line-in" +msgid "Record Source" msgstr "" -msgid "PCM 1" +msgid "Monitor Source" msgstr "" -msgid "PCM 2" +msgid "Keyboard Beep" msgstr "" -msgid "PCM 3" +msgid "Monitor" msgstr "" -msgid "PCM 4" +msgid "Simulate Stereo" msgstr "" -msgid "Green connector" +msgid "Stereo" msgstr "" -msgid "Green front panel connector" +msgid "Surround Sound" msgstr "" -msgid "Pink connector" +msgid "Microphone Gain" msgstr "" -msgid "Pink front panel connector" +msgid "Speaker Source" msgstr "" -msgid "Blue connector" +msgid "Microphone Source" msgstr "" -msgid "Blue front panel connector" +msgid "Jack" msgstr "" -msgid "Orange connector" +msgid "Center / LFE" msgstr "" -msgid "Orange front panel connector" +msgid "Stereo Mix" msgstr "" -msgid "Black connector" +msgid "Mono Mix" msgstr "" -msgid "Black front panel connector" +msgid "Input Mix" msgstr "" -msgid "Gray connector" +msgid "SPDIF In" msgstr "" -msgid "Gray front panel connector" +msgid "SPDIF Out" msgstr "" -msgid "White connector" +msgid "Microphone 1" msgstr "" -msgid "White front panel connector" +msgid "Microphone 2" msgstr "" -msgid "Red connector" +msgid "Digital Out" msgstr "" -msgid "Red front panel connector" +msgid "Digital In" msgstr "" -msgid "Yellow connector" +msgid "HDMI" msgstr "" -msgid "Yellow front panel connector" +msgid "Modem" msgstr "" -msgid "Green connector function" +msgid "Handset" msgstr "" -msgid "Green front panel connector function" +msgid "Other" msgstr "" -msgid "Pink connector function" +msgid "None" msgstr "" -msgid "Pink front panel connector function" +msgid "On" msgstr "" -msgid "Blue connector function" +msgid "Off" msgstr "" -msgid "Blue front panel connector function" +msgid "Mute" msgstr "" -msgid "Orange connector function" +msgid "Fast" msgstr "" -msgid "Orange front panel connector function" +msgid "Very Low" msgstr "" -msgid "Black connector function" +msgid "Low" msgstr "" -msgid "Black front panel connector function" +msgid "Medium" msgstr "" -msgid "Gray connector function" +msgid "High" msgstr "" -msgid "Gray front panel connector function" +msgid "Very High" msgstr "" -msgid "White connector function" +msgid "Production" msgstr "" -msgid "White front panel connector function" +msgid "Front Panel Microphone" msgstr "" -msgid "Red connector function" +msgid "Front Panel Line In" msgstr "" -msgid "Red front panel connector function" +msgid "Front Panel Headphones" msgstr "" -msgid "Yellow connector function" +msgid "Front Panel Line Out" msgstr "" -msgid "Yellow front panel connector function" +msgid "Green Connector" msgstr "" -msgid "Front panel line-in" +msgid "Pink Connector" msgstr "" -msgid "Headphones" +msgid "Blue Connector" msgstr "" -msgid "Front panel headphones" +msgid "White Connector" msgstr "" -msgid "PCM" +msgid "Black Connector" +msgstr "" + +msgid "Gray Connector" +msgstr "" + +msgid "Orange Connector" +msgstr "" + +msgid "Red Connector" +msgstr "" + +msgid "Yellow Connector" +msgstr "" + +msgid "Green Front Panel Connector" +msgstr "" + +msgid "Pink Front Panel Connector" +msgstr "" + +msgid "Blue Front Panel Connector" +msgstr "" + +msgid "White Front Panel Connector" +msgstr "" + +msgid "Black Front Panel Connector" +msgstr "" + +msgid "Gray Front Panel Connector" +msgstr "" + +msgid "Orange Front Panel Connector" +msgstr "" + +msgid "Red Front Panel Connector" msgstr "" -msgid "Virtual mixer input" +msgid "Yellow Front Panel Connector" msgstr "" -msgid "Virtual mixer output" +msgid "Spread Output" msgstr "" -msgid "Virtual mixer channel configuration" +msgid "Downmix" +msgstr "" + +msgid "Virtual Mixer Input" +msgstr "" + +msgid "Virtual Mixer Output" +msgstr "" + +msgid "Virtual Mixer Channels" +msgstr "" + +#, c-format +msgid "%s Function" +msgstr "" + +#, c-format +msgid "%s %d" msgstr "" msgid "" @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: gst-plugins-bad 0.10.11.2\n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n" -"POT-Creation-Date: 2009-06-17 21:54+0100\n" +"POT-Creation-Date: 2009-08-11 17:42+0100\n" "PO-Revision-Date: 2009-05-12 21:32+0930\n" "Last-Translator: Clytie Siddall <clytie@riverland.net.au>\n" "Language-Team: Vietnamese <vi-VN@googlegroups.com>\n" @@ -73,203 +73,349 @@ msgstr "" "Không thể mở thiết bị âm thanh để quản lý Ä‘iá»u khiển máy hoà tiếng. Phiên " "bản Hệ thống Âm thanh Mở nà y không được yếu tố nà y há»— trợ." -msgid "Fast" +msgid "Volume" +msgstr "" + +#, fuzzy +msgid "Master" msgstr "Nhanh" -msgid "Low" -msgstr "Thấp" +msgid "Front" +msgstr "TrÆ°á»›c" -msgid "Medium" -msgstr "Vừa" +msgid "Rear" +msgstr "Sau" -msgid "High" -msgstr "Cao" +msgid "Headphones" +msgstr "Tai nghe" -msgid "Very high" -msgstr "Rất cao" +#, fuzzy +msgid "Center" +msgstr "Giữa/LFE" -msgid "Production" -msgstr "Sản xuất" +msgid "LFE" +msgstr "" -msgid "Off" -msgstr "Tắt" +#, fuzzy +msgid "Surround" +msgstr "Âm thanh vòm" -msgid "On" -msgstr "Báºt" +msgid "Side" +msgstr "Bên" + +msgid "Built-in Speaker" +msgstr "" + +msgid "AUX 1 Out" +msgstr "" + +msgid "AUX 2 Out" +msgstr "" + +msgid "AUX Out" +msgstr "" + +msgid "Bass" +msgstr "" + +msgid "Treble" +msgstr "" + +msgid "3D Depth" +msgstr "" + +msgid "3D Center" +msgstr "" + +msgid "3D Enhance" +msgstr "" + +#, fuzzy +msgid "Telephone" +msgstr "Tai nghe" + +msgid "Microphone" +msgstr "Máy vi âm" + +msgid "Line Out" +msgstr "" + +#, fuzzy +msgid "Line In" +msgstr "Dây và o" + +msgid "Internal CD" +msgstr "" + +msgid "Video In" +msgstr "" + +msgid "AUX 1 In" +msgstr "" + +msgid "AUX 2 In" +msgstr "" + +msgid "AUX In" +msgstr "" + +msgid "PCM" +msgstr "PCM" + +msgid "Record Gain" +msgstr "" + +msgid "Output Gain" +msgstr "" + +#, fuzzy +msgid "Microphone Boost" +msgstr "Máy vi âm" + +msgid "Loopback" +msgstr "" + +msgid "Diagnostic" +msgstr "" + +msgid "Bass Boost" +msgstr "" + +msgid "Playback Ports" +msgstr "" + +msgid "Input" +msgstr "Và o" + +msgid "Record Source" +msgstr "" + +msgid "Monitor Source" +msgstr "" + +msgid "Keyboard Beep" +msgstr "" + +msgid "Monitor" +msgstr "" + +msgid "Simulate Stereo" +msgstr "" msgid "Stereo" msgstr "Âm láºp thể" -msgid "Surround sound" +#, fuzzy +msgid "Surround Sound" msgstr "Âm thanh vòm" -msgid "Input mix" -msgstr "Hoà tiếng đầu và o" +#, fuzzy +msgid "Microphone Gain" +msgstr "Máy vi âm" -msgid "Front" -msgstr "TrÆ°á»›c" +msgid "Speaker Source" +msgstr "" -msgid "Rear" -msgstr "Sau" +#, fuzzy +msgid "Microphone Source" +msgstr "Máy vi âm" -msgid "Side" -msgstr "Bên" +msgid "Jack" +msgstr "" msgid "Center / LFE" msgstr "Giữa/LFE" -msgid "Microphone" -msgstr "Máy vi âm" +#, fuzzy +msgid "Stereo Mix" +msgstr "Âm láºp thể" -msgid "Front panel microphone" -msgstr "Máy vi âm bảng trÆ°á»›c" +msgid "Mono Mix" +msgstr "" -msgid "Input" -msgstr "Và o" +#, fuzzy +msgid "Input Mix" +msgstr "Hoà tiếng đầu và o" -msgid "Line-in" -msgstr "Dây và o" +msgid "SPDIF In" +msgstr "" -msgid "PCM 1" -msgstr "PCM 1" +msgid "SPDIF Out" +msgstr "" -msgid "PCM 2" -msgstr "PCM 2" +#, fuzzy +msgid "Microphone 1" +msgstr "Máy vi âm" -msgid "PCM 3" -msgstr "PCM 3" +#, fuzzy +msgid "Microphone 2" +msgstr "Máy vi âm" -msgid "PCM 4" -msgstr "PCM 4" +msgid "Digital Out" +msgstr "" -msgid "Green connector" -msgstr "Äầu kẹp lục" +msgid "Digital In" +msgstr "" -msgid "Green front panel connector" -msgstr "Äầu kẹp lục bảng trÆ°á»›c" +msgid "HDMI" +msgstr "" -msgid "Pink connector" -msgstr "Äầu kẹp hồng" +msgid "Modem" +msgstr "" -msgid "Pink front panel connector" -msgstr "Äầu kẹp hồng bảng trÆ°á»›c" +msgid "Handset" +msgstr "" -msgid "Blue connector" -msgstr "Äầu kẹp xanh" +msgid "Other" +msgstr "" -msgid "Blue front panel connector" -msgstr "Äầu kẹp xanh bảng trÆ°á»›c" +msgid "None" +msgstr "" -msgid "Orange connector" -msgstr "Äầu kẹp cam" +msgid "On" +msgstr "Báºt" -msgid "Orange front panel connector" -msgstr "Äầu kẹp cam bảng trÆ°á»›c" +msgid "Off" +msgstr "Tắt" -msgid "Black connector" -msgstr "Äầu kẹp Ä‘en" +msgid "Mute" +msgstr "" -msgid "Black front panel connector" -msgstr "Äầu kẹp Ä‘en bảng trÆ°á»›c" +msgid "Fast" +msgstr "Nhanh" -msgid "Gray connector" -msgstr "Äầu kẹp xám" +msgid "Very Low" +msgstr "" -msgid "Gray front panel connector" -msgstr "Äầu kẹp xám bảng trÆ°á»›c" +msgid "Low" +msgstr "Thấp" -msgid "White connector" -msgstr "Äầu kẹp trắng" +msgid "Medium" +msgstr "Vừa" -msgid "White front panel connector" -msgstr "Äầu kẹp trắng bảng trÆ°á»›c" +msgid "High" +msgstr "Cao" -msgid "Red connector" -msgstr "Äầu kẹp Ä‘á»" +#, fuzzy +msgid "Very High" +msgstr "Rất cao" -msgid "Red front panel connector" -msgstr "Äầu kẹp Ä‘á» bảng trÆ°á»›c" +msgid "Production" +msgstr "Sản xuất" -msgid "Yellow connector" -msgstr "Äầu kẹp và ng" +#, fuzzy +msgid "Front Panel Microphone" +msgstr "Máy vi âm bảng trÆ°á»›c" -msgid "Yellow front panel connector" -msgstr "Äầu kẹp và ng bảng trÆ°á»›c" +#, fuzzy +msgid "Front Panel Line In" +msgstr "Dây và o bảng trÆ°á»›c" -msgid "Green connector function" -msgstr "Chức năng đầu kẹp lục" +#, fuzzy +msgid "Front Panel Headphones" +msgstr "Tai nghe bảng trÆ°á»›c" -msgid "Green front panel connector function" -msgstr "Chức năng đầu kẹp lục bảng trÆ°á»›c" +#, fuzzy +msgid "Front Panel Line Out" +msgstr "Dây và o bảng trÆ°á»›c" -msgid "Pink connector function" -msgstr "Chức năng đầu kẹp hồng" +#, fuzzy +msgid "Green Connector" +msgstr "Äầu kẹp lục" -msgid "Pink front panel connector function" -msgstr "Chức năng đầu kẹp hồng bảng trÆ°á»›c" +#, fuzzy +msgid "Pink Connector" +msgstr "Äầu kẹp hồng" -msgid "Blue connector function" -msgstr "Chức năng đầu kẹp xanh" +#, fuzzy +msgid "Blue Connector" +msgstr "Äầu kẹp xanh" -msgid "Blue front panel connector function" -msgstr "Chức năng đầu kẹp xanh bảng trÆ°á»›c" +#, fuzzy +msgid "White Connector" +msgstr "Äầu kẹp trắng" -msgid "Orange connector function" -msgstr "Chức năng đầu kẹp cam" +#, fuzzy +msgid "Black Connector" +msgstr "Äầu kẹp Ä‘en" -msgid "Orange front panel connector function" -msgstr "Chức năng đầu kẹp cam bảng trÆ°á»›c" +#, fuzzy +msgid "Gray Connector" +msgstr "Äầu kẹp xám" -msgid "Black connector function" -msgstr "Chức năng đầu kẹp Ä‘en" +#, fuzzy +msgid "Orange Connector" +msgstr "Äầu kẹp cam" -msgid "Black front panel connector function" -msgstr "Chức năng đầu kẹp Ä‘en bảng trÆ°á»›c" +#, fuzzy +msgid "Red Connector" +msgstr "Äầu kẹp Ä‘á»" -msgid "Gray connector function" -msgstr "Chức năng đầu kẹp xám" +#, fuzzy +msgid "Yellow Connector" +msgstr "Äầu kẹp và ng" -msgid "Gray front panel connector function" -msgstr "Chức năng đầu kẹp xám bảng trÆ°á»›c" +#, fuzzy +msgid "Green Front Panel Connector" +msgstr "Äầu kẹp lục bảng trÆ°á»›c" -msgid "White connector function" -msgstr "Chức năng đầu kẹp trắng" +#, fuzzy +msgid "Pink Front Panel Connector" +msgstr "Äầu kẹp hồng bảng trÆ°á»›c" -msgid "White front panel connector function" -msgstr "Chức năng đầu kẹp trắng bảng trÆ°á»›c" +#, fuzzy +msgid "Blue Front Panel Connector" +msgstr "Äầu kẹp xanh bảng trÆ°á»›c" -msgid "Red connector function" -msgstr "Chức năng đầu kẹp Ä‘á»" +#, fuzzy +msgid "White Front Panel Connector" +msgstr "Äầu kẹp trắng bảng trÆ°á»›c" -msgid "Red front panel connector function" -msgstr "Chức năng đầu kẹp Ä‘á» bảng trÆ°á»›c" +#, fuzzy +msgid "Black Front Panel Connector" +msgstr "Äầu kẹp Ä‘en bảng trÆ°á»›c" -msgid "Yellow connector function" -msgstr "Chức năng đầu kẹp và ng" +#, fuzzy +msgid "Gray Front Panel Connector" +msgstr "Äầu kẹp xám bảng trÆ°á»›c" -msgid "Yellow front panel connector function" -msgstr "Chức năng đầu kẹp và ng bảng trÆ°á»›c" +#, fuzzy +msgid "Orange Front Panel Connector" +msgstr "Äầu kẹp cam bảng trÆ°á»›c" -msgid "Front panel line-in" -msgstr "Dây và o bảng trÆ°á»›c" +#, fuzzy +msgid "Red Front Panel Connector" +msgstr "Äầu kẹp Ä‘á» bảng trÆ°á»›c" -msgid "Headphones" -msgstr "Tai nghe" +#, fuzzy +msgid "Yellow Front Panel Connector" +msgstr "Äầu kẹp và ng bảng trÆ°á»›c" -msgid "Front panel headphones" -msgstr "Tai nghe bảng trÆ°á»›c" +msgid "Spread Output" +msgstr "" -msgid "PCM" -msgstr "PCM" +msgid "Downmix" +msgstr "" -msgid "Virtual mixer input" +#, fuzzy +msgid "Virtual Mixer Input" msgstr "Äầu và o bá»™ hoà tiếng ảo" -msgid "Virtual mixer output" +#, fuzzy +msgid "Virtual Mixer Output" msgstr "Äầu ra bá»™ hoà tiếng ảo" -msgid "Virtual mixer channel configuration" -msgstr "Cấu hình kênh bá»™ hoà tiếng ảo" +#, fuzzy +msgid "Virtual Mixer Channels" +msgstr "Äầu và o bá»™ hoà tiếng ảo" + +#, c-format +msgid "%s Function" +msgstr "" + +#, c-format +msgid "%s %d" +msgstr "" msgid "" "Could not open audio device for playback. Device is being used by another " @@ -306,3 +452,72 @@ msgstr "Thiết bị âm thanh nà y không há»— trợ chức năng thu." msgid "Error recording from audio device." msgstr "Lá»—i thu từ thiết bị âm thanh." + +#~ msgid "PCM 1" +#~ msgstr "PCM 1" + +#~ msgid "PCM 2" +#~ msgstr "PCM 2" + +#~ msgid "PCM 3" +#~ msgstr "PCM 3" + +#~ msgid "PCM 4" +#~ msgstr "PCM 4" + +#~ msgid "Green connector function" +#~ msgstr "Chức năng đầu kẹp lục" + +#~ msgid "Green front panel connector function" +#~ msgstr "Chức năng đầu kẹp lục bảng trÆ°á»›c" + +#~ msgid "Pink connector function" +#~ msgstr "Chức năng đầu kẹp hồng" + +#~ msgid "Pink front panel connector function" +#~ msgstr "Chức năng đầu kẹp hồng bảng trÆ°á»›c" + +#~ msgid "Blue connector function" +#~ msgstr "Chức năng đầu kẹp xanh" + +#~ msgid "Blue front panel connector function" +#~ msgstr "Chức năng đầu kẹp xanh bảng trÆ°á»›c" + +#~ msgid "Orange connector function" +#~ msgstr "Chức năng đầu kẹp cam" + +#~ msgid "Orange front panel connector function" +#~ msgstr "Chức năng đầu kẹp cam bảng trÆ°á»›c" + +#~ msgid "Black connector function" +#~ msgstr "Chức năng đầu kẹp Ä‘en" + +#~ msgid "Black front panel connector function" +#~ msgstr "Chức năng đầu kẹp Ä‘en bảng trÆ°á»›c" + +#~ msgid "Gray connector function" +#~ msgstr "Chức năng đầu kẹp xám" + +#~ msgid "Gray front panel connector function" +#~ msgstr "Chức năng đầu kẹp xám bảng trÆ°á»›c" + +#~ msgid "White connector function" +#~ msgstr "Chức năng đầu kẹp trắng" + +#~ msgid "White front panel connector function" +#~ msgstr "Chức năng đầu kẹp trắng bảng trÆ°á»›c" + +#~ msgid "Red connector function" +#~ msgstr "Chức năng đầu kẹp Ä‘á»" + +#~ msgid "Red front panel connector function" +#~ msgstr "Chức năng đầu kẹp Ä‘á» bảng trÆ°á»›c" + +#~ msgid "Yellow connector function" +#~ msgstr "Chức năng đầu kẹp và ng" + +#~ msgid "Yellow front panel connector function" +#~ msgstr "Chức năng đầu kẹp và ng bảng trÆ°á»›c" + +#~ msgid "Virtual mixer channel configuration" +#~ msgstr "Cấu hình kênh bá»™ hoà tiếng ảo" diff --git a/po/zh_CN.po b/po/zh_CN.po index 1837a8ba..722273de 100644 --- a/po/zh_CN.po +++ b/po/zh_CN.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: gst-plugins-bad 0.10.9.3\n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n" -"POT-Creation-Date: 2009-06-17 21:54+0100\n" +"POT-Creation-Date: 2009-08-11 17:42+0100\n" "PO-Revision-Date: 2009-01-14 12:04+0800\n" "Last-Translator: Ji ZhengYu <zhengyuji@gmail.com>\n" "Language-Team: Chinese (simplified) <translation-team-zh-cn@lists." @@ -73,207 +73,349 @@ msgid "" msgstr "" "æ— æ³•æ‰“å¼€éŸ³é¢‘è®¾å¤‡è¿›è¡ŒéŸ³é‡æŽ§åˆ¶æ“作。æ¤éƒ¨ä»¶ä¸æ”¯æŒå¼€æ”¾å£°éŸ³ç³»ç»Ÿ(OSS)的版本。" -msgid "Fast" +msgid "Volume" +msgstr "" + +#, fuzzy +msgid "Master" msgstr "å¿«" -msgid "Low" -msgstr "æ…¢" +msgid "Front" +msgstr "å‰ç½®å£°é“" -msgid "Medium" -msgstr "ä¸ç‰" +msgid "Rear" +msgstr "åŽç½®å£°é“" -msgid "High" -msgstr "高" +msgid "Headphones" +msgstr "头戴å¼è€³æœº" -msgid "Very high" -msgstr "很高" +#, fuzzy +msgid "Center" +msgstr "ä¸ç½®/低音炮" -msgid "Production" -msgstr "生产商" +msgid "LFE" +msgstr "" -msgid "Off" -msgstr "å…³" +#, fuzzy +msgid "Surround" +msgstr "立体声环绕" -msgid "On" -msgstr "å¼€" +msgid "Side" +msgstr "å·¦å³å£°é“" + +msgid "Built-in Speaker" +msgstr "" + +msgid "AUX 1 Out" +msgstr "" + +msgid "AUX 2 Out" +msgstr "" + +msgid "AUX Out" +msgstr "" + +msgid "Bass" +msgstr "" + +msgid "Treble" +msgstr "" + +msgid "3D Depth" +msgstr "" + +msgid "3D Center" +msgstr "" + +msgid "3D Enhance" +msgstr "" + +#, fuzzy +msgid "Telephone" +msgstr "头戴å¼è€³æœº" + +msgid "Microphone" +msgstr "è¯ç’" + +msgid "Line Out" +msgstr "" + +#, fuzzy +msgid "Line In" +msgstr "线路输入" + +msgid "Internal CD" +msgstr "" + +msgid "Video In" +msgstr "" + +msgid "AUX 1 In" +msgstr "" + +msgid "AUX 2 In" +msgstr "" + +msgid "AUX In" +msgstr "" + +msgid "PCM" +msgstr "PCM" + +msgid "Record Gain" +msgstr "" + +msgid "Output Gain" +msgstr "" + +#, fuzzy +msgid "Microphone Boost" +msgstr "è¯ç’" + +msgid "Loopback" +msgstr "" + +msgid "Diagnostic" +msgstr "" + +msgid "Bass Boost" +msgstr "" + +msgid "Playback Ports" +msgstr "" + +msgid "Input" +msgstr "输入" + +msgid "Record Source" +msgstr "" + +msgid "Monitor Source" +msgstr "" + +msgid "Keyboard Beep" +msgstr "" + +msgid "Monitor" +msgstr "" + +msgid "Simulate Stereo" +msgstr "" msgid "Stereo" msgstr "立体声" -msgid "Surround sound" +#, fuzzy +msgid "Surround Sound" msgstr "立体声环绕" -msgid "Input mix" -msgstr "混音输入" +#, fuzzy +msgid "Microphone Gain" +msgstr "è¯ç’" -msgid "Front" -msgstr "å‰ç½®å£°é“" +msgid "Speaker Source" +msgstr "" -msgid "Rear" -msgstr "åŽç½®å£°é“" +#, fuzzy +msgid "Microphone Source" +msgstr "è¯ç’" -msgid "Side" -msgstr "å·¦å³å£°é“" +msgid "Jack" +msgstr "" msgid "Center / LFE" msgstr "ä¸ç½®/低音炮" -msgid "Microphone" -msgstr "è¯ç’" +#, fuzzy +msgid "Stereo Mix" +msgstr "立体声" -msgid "Front panel microphone" -msgstr "è¯ç’é¢æ¿" +msgid "Mono Mix" +msgstr "" -msgid "Input" -msgstr "输入" +#, fuzzy +msgid "Input Mix" +msgstr "混音输入" -msgid "Line-in" -msgstr "线路输入" +msgid "SPDIF In" +msgstr "" -msgid "PCM 1" -msgstr "PCM 1" +msgid "SPDIF Out" +msgstr "" -msgid "PCM 2" -msgstr "PCM 2" +#, fuzzy +msgid "Microphone 1" +msgstr "è¯ç’" -msgid "PCM 3" -msgstr "PCM 3" +#, fuzzy +msgid "Microphone 2" +msgstr "è¯ç’" -msgid "PCM 4" -msgstr "PCM 4" +msgid "Digital Out" +msgstr "" -msgid "Green connector" -msgstr "线路输出" +msgid "Digital In" +msgstr "" -msgid "Green front panel connector" -msgstr "线路输出é¢æ¿" +msgid "HDMI" +msgstr "" -msgid "Pink connector" -msgstr "è¯ç’输出" +msgid "Modem" +msgstr "" -msgid "Pink front panel connector" -msgstr "è¯ç’输出é¢æ¿" +msgid "Handset" +msgstr "" -msgid "Blue connector" -msgstr "立体声输入" +msgid "Other" +msgstr "" -msgid "Blue front panel connector" -msgstr "立体声输入é¢æ¿" +msgid "None" +msgstr "" -msgid "Orange connector" -msgstr "低音炮输出" +msgid "On" +msgstr "å¼€" -msgid "Orange front panel connector" -msgstr "低音炮输出é¢æ¿" +msgid "Off" +msgstr "å…³" -msgid "Black connector" -msgstr "åŽç½®å£°é“输出" +msgid "Mute" +msgstr "" -msgid "Black front panel connector" -msgstr "åŽç½®å£°é“输出é¢æ¿" +msgid "Fast" +msgstr "å¿«" -msgid "Gray connector" -msgstr "ä¸ç½®å£°é“输出" +msgid "Very Low" +msgstr "" -msgid "Gray front panel connector" -msgstr "ä¸ç½®å£°é“输出é¢æ¿" +msgid "Low" +msgstr "æ…¢" -msgid "White connector" -msgstr "å·¦/å•å£°é“" +msgid "Medium" +msgstr "ä¸ç‰" -msgid "White front panel connector" -msgstr "å·¦/å•å£°é“é¢æ¿" +msgid "High" +msgstr "高" -msgid "Red connector" -msgstr "å³å£°é“" +#, fuzzy +msgid "Very High" +msgstr "很高" -msgid "Red front panel connector" -msgstr "å³å£°é“é¢æ¿" +msgid "Production" +msgstr "生产商" #, fuzzy -msgid "Yellow connector" -msgstr "Midi 输出/游æˆæ‘‡æ†" +msgid "Front Panel Microphone" +msgstr "è¯ç’é¢æ¿" #, fuzzy -msgid "Yellow front panel connector" -msgstr "Midi 输出/游æˆæ‘‡æ†é¢æ¿" +msgid "Front Panel Line In" +msgstr "线路输入é¢æ¿" -msgid "Green connector function" -msgstr "线路输出音效" +#, fuzzy +msgid "Front Panel Headphones" +msgstr "头戴å¼è€³æœºé¢æ¿" -msgid "Green front panel connector function" -msgstr "线路输出音效é¢æ¿" +#, fuzzy +msgid "Front Panel Line Out" +msgstr "线路输入é¢æ¿" -msgid "Pink connector function" -msgstr "è¯ç’输出音效" +#, fuzzy +msgid "Green Connector" +msgstr "线路输出" -msgid "Pink front panel connector function" -msgstr "è¯ç’输出音效é¢æ¿" +#, fuzzy +msgid "Pink Connector" +msgstr "è¯ç’输出" -msgid "Blue connector function" -msgstr "立体声输入音效" +#, fuzzy +msgid "Blue Connector" +msgstr "立体声输入" -msgid "Blue front panel connector function" -msgstr "立体声输入音效é¢æ¿" +#, fuzzy +msgid "White Connector" +msgstr "å·¦/å•å£°é“" -msgid "Orange connector function" -msgstr "低音炮输出音效" +#, fuzzy +msgid "Black Connector" +msgstr "åŽç½®å£°é“输出" -msgid "Orange front panel connector function" -msgstr "低音炮输出音效é¢æ¿" +#, fuzzy +msgid "Gray Connector" +msgstr "ä¸ç½®å£°é“输出" -msgid "Black connector function" -msgstr "åŽç½®å£°é“输出音效" +#, fuzzy +msgid "Orange Connector" +msgstr "低音炮输出" -msgid "Black front panel connector function" -msgstr "åŽç½®å£°é“输出音效é¢æ¿" +#, fuzzy +msgid "Red Connector" +msgstr "å³å£°é“" -msgid "Gray connector function" -msgstr "ä¸ç½®å£°é“输出音效" +#, fuzzy +msgid "Yellow Connector" +msgstr "Midi 输出/游æˆæ‘‡æ†" -msgid "Gray front panel connector function" -msgstr "ä¸ç½®å£°é“输出音效é¢æ¿" +#, fuzzy +msgid "Green Front Panel Connector" +msgstr "线路输出é¢æ¿" -msgid "White connector function" -msgstr "å·¦/å•å£°é“输出音效" +#, fuzzy +msgid "Pink Front Panel Connector" +msgstr "è¯ç’输出é¢æ¿" -msgid "White front panel connector function" -msgstr "å·¦/å•å£°é“输出音效é¢æ¿" +#, fuzzy +msgid "Blue Front Panel Connector" +msgstr "立体声输入é¢æ¿" -msgid "Red connector function" -msgstr "å³å£°é“输出音效" +#, fuzzy +msgid "White Front Panel Connector" +msgstr "å·¦/å•å£°é“é¢æ¿" -msgid "Red front panel connector function" -msgstr "å³å£°é“输出音效é¢æ¿" +#, fuzzy +msgid "Black Front Panel Connector" +msgstr "åŽç½®å£°é“输出é¢æ¿" #, fuzzy -msgid "Yellow connector function" -msgstr "MIDI 输出音效" +msgid "Gray Front Panel Connector" +msgstr "ä¸ç½®å£°é“输出é¢æ¿" #, fuzzy -msgid "Yellow front panel connector function" -msgstr "MIDI 输出音效é¢æ¿" +msgid "Orange Front Panel Connector" +msgstr "低音炮输出é¢æ¿" -msgid "Front panel line-in" -msgstr "线路输入é¢æ¿" +#, fuzzy +msgid "Red Front Panel Connector" +msgstr "å³å£°é“é¢æ¿" -msgid "Headphones" -msgstr "头戴å¼è€³æœº" +#, fuzzy +msgid "Yellow Front Panel Connector" +msgstr "Midi 输出/游æˆæ‘‡æ†é¢æ¿" -msgid "Front panel headphones" -msgstr "头戴å¼è€³æœºé¢æ¿" +msgid "Spread Output" +msgstr "" -msgid "PCM" -msgstr "PCM" +msgid "Downmix" +msgstr "" -msgid "Virtual mixer input" +#, fuzzy +msgid "Virtual Mixer Input" msgstr "模拟混音输入" -msgid "Virtual mixer output" +#, fuzzy +msgid "Virtual Mixer Output" msgstr "模拟混音输出" -msgid "Virtual mixer channel configuration" -msgstr "模拟混音器设置" +#, fuzzy +msgid "Virtual Mixer Channels" +msgstr "模拟混音输入" + +#, c-format +msgid "%s Function" +msgstr "" + +#, c-format +msgid "%s %d" +msgstr "" msgid "" "Could not open audio device for playback. Device is being used by another " @@ -312,3 +454,74 @@ msgstr "从音频设备录音时å‘生错误。" #~ "The requested bitrate %d kbit/s for property '%s' is not allowed. The " #~ "bitrate was changed to %d kbit/s." #~ msgstr "ä¸å…许使用“%2$sâ€æ‰€è¯·æ±‚çš„ç 率 %1$d kbit/s。ç 率改为 %3$d kbit/s。" + +#~ msgid "PCM 1" +#~ msgstr "PCM 1" + +#~ msgid "PCM 2" +#~ msgstr "PCM 2" + +#~ msgid "PCM 3" +#~ msgstr "PCM 3" + +#~ msgid "PCM 4" +#~ msgstr "PCM 4" + +#~ msgid "Green connector function" +#~ msgstr "线路输出音效" + +#~ msgid "Green front panel connector function" +#~ msgstr "线路输出音效é¢æ¿" + +#~ msgid "Pink connector function" +#~ msgstr "è¯ç’输出音效" + +#~ msgid "Pink front panel connector function" +#~ msgstr "è¯ç’输出音效é¢æ¿" + +#~ msgid "Blue connector function" +#~ msgstr "立体声输入音效" + +#~ msgid "Blue front panel connector function" +#~ msgstr "立体声输入音效é¢æ¿" + +#~ msgid "Orange connector function" +#~ msgstr "低音炮输出音效" + +#~ msgid "Orange front panel connector function" +#~ msgstr "低音炮输出音效é¢æ¿" + +#~ msgid "Black connector function" +#~ msgstr "åŽç½®å£°é“输出音效" + +#~ msgid "Black front panel connector function" +#~ msgstr "åŽç½®å£°é“输出音效é¢æ¿" + +#~ msgid "Gray connector function" +#~ msgstr "ä¸ç½®å£°é“输出音效" + +#~ msgid "Gray front panel connector function" +#~ msgstr "ä¸ç½®å£°é“输出音效é¢æ¿" + +#~ msgid "White connector function" +#~ msgstr "å·¦/å•å£°é“输出音效" + +#~ msgid "White front panel connector function" +#~ msgstr "å·¦/å•å£°é“输出音效é¢æ¿" + +#~ msgid "Red connector function" +#~ msgstr "å³å£°é“输出音效" + +#~ msgid "Red front panel connector function" +#~ msgstr "å³å£°é“输出音效é¢æ¿" + +#, fuzzy +#~ msgid "Yellow connector function" +#~ msgstr "MIDI 输出音效" + +#, fuzzy +#~ msgid "Yellow front panel connector function" +#~ msgstr "MIDI 输出音效é¢æ¿" + +#~ msgid "Virtual mixer channel configuration" +#~ msgstr "模拟混音器设置" diff --git a/sys/directdraw/gstdirectdrawsink.c b/sys/directdraw/gstdirectdrawsink.c index 538227de..bb0332f8 100644 --- a/sys/directdraw/gstdirectdrawsink.c +++ b/sys/directdraw/gstdirectdrawsink.c @@ -961,10 +961,12 @@ gst_directdraw_sink_show_frame (GstBaseSink * bsink, GstBuffer * buf) /* Write each line respecting the destination surface pitch */ data = surf_desc.lpSurface; - src_pitch = GST_BUFFER_SIZE (buf) / ddrawsink->video_height; - for (line = 0; line < surf_desc.dwHeight; line++) { - memcpy (data, GST_BUFFER_DATA (buf) + (line * src_pitch), src_pitch); - data += surf_desc.lPitch; + if (ddrawsink->video_height) { + src_pitch = GST_BUFFER_SIZE (buf) / ddrawsink->video_height; + for (line = 0; line < surf_desc.dwHeight; line++) { + memcpy (data, GST_BUFFER_DATA (buf) + (line * src_pitch), src_pitch); + data += surf_desc.lPitch; + } } /* Unlock the surface */ diff --git a/sys/directsound/gstdirectsoundsrc.c b/sys/directsound/gstdirectsoundsrc.c index 429d6b85..fce9d5c8 100644..100755 --- a/sys/directsound/gstdirectsoundsrc.c +++ b/sys/directsound/gstdirectsoundsrc.c @@ -1,587 +1,678 @@ -/*
- * GStreamer
- * Copyright 2005 Thomas Vander Stichele <thomas@apestaart.org>
- * Copyright 2005 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
- * Copyright 2005 Sébastien Moutte <sebastien@moutte.net>
- * Copyright 2006 Joni Valtanen <joni.valtanen@movial.fi>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Alternatively, the contents of this file may be used under the
- * GNU Lesser General Public License Version 2.1 (the "LGPL"), in
- * which case the following provisions apply instead of the ones
- * mentioned above:
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-/*
- TODO: add device selection and check rate etc.
-*/
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif /*
*/ -
-#include <gst/gst.h>
-#include <gst/audio/gstbaseaudiosrc.h>
-
-#include "gstdirectsoundsrc.h"
-
-#include <windows.h>
-#include <dsound.h>
-
GST_DEBUG_CATEGORY_STATIC (directsoundsrc_debug); -
-#define GST_CAT_DEFAULT directsoundsrc_debug
-
static GstElementDetails gst_directsound_src_details = -
GST_ELEMENT_DETAILS ("Audio Source (DIRECTCSOUND)",
"Source/Audio", -
"Capture from a soundcard via DIRECTSOUND", -
"Joni Valtanen <joni.valtanen@movial.fi>"); -
-/* defaults here */
-#define DEFAULT_DEVICE 0
-
-/* properties */
- enum -{
PROP_0,
PROP_DEVICE
+/* + * GStreamer + * Copyright 2005 Thomas Vander Stichele <thomas@apestaart.org> + * Copyright 2005 Ronald S. Bultje <rbultje@ronald.bitfreak.net> + * Copyright 2005 Sébastien Moutte <sebastien@moutte.net> + * Copyright 2006 Joni Valtanen <joni.valtanen@movial.fi> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Alternatively, the contents of this file may be used under the + * GNU Lesser General Public License Version 2.1 (the "LGPL"), in + * which case the following provisions apply instead of the ones + * mentioned above: + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + TODO: add device selection and check rate etc. +*/ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <gst/gst.h> +#include <gst/audio/gstbaseaudiosrc.h> + +#include "gstdirectsoundsrc.h" + +#include <windows.h> +#include <dsound.h> + +GST_DEBUG_CATEGORY_STATIC (directsoundsrc_debug); +#define GST_CAT_DEFAULT directsoundsrc_debug + +static GstElementDetails gst_directsound_src_details = +GST_ELEMENT_DETAILS ("Direct Sound Audio Src", + "Source/Audio", + "Capture from a soundcard via DIRECTSOUND", + "Joni Valtanen <joni.valtanen@movial.fi>"); + +/* defaults here */ +#define DEFAULT_DEVICE 0 + +/* properties */ +enum +{ + PROP_0, + PROP_DEVICE }; -
static HRESULT (WINAPI * pDSoundCaptureCreate) (LPGUID, -
LPDIRECTSOUNDCAPTURE *,
LPUNKNOWN); -
static void gst_directsound_src_finalise (GObject * object); -
static void gst_directsound_src_set_property (GObject * object, -
guint prop_id,
const GValue * value,
GParamSpec * pspec); -
static void gst_directsound_src_get_property (GObject * object, -
guint prop_id,
GValue * value,
GParamSpec * pspec); -
static gboolean gst_directsound_src_open (GstAudioSrc * asrc); -
static gboolean gst_directsound_src_close (GstAudioSrc * asrc); -
static gboolean gst_directsound_src_prepare (GstAudioSrc * asrc, -
GstRingBufferSpec * spec); -
static gboolean gst_directsound_src_unprepare (GstAudioSrc * asrc); -
static void gst_directsound_src_reset (GstAudioSrc * asrc); -
static GstCaps *gst_directsound_src_getcaps (GstBaseSrc * bsrc); -
static guint gst_directsound_src_read (GstAudioSrc * asrc,
gpointer data, -
guint length); -
static void gst_directsound_src_dispose (GObject * object); -
static void gst_directsound_src_do_init (GType type); -
static guint gst_directsound_src_delay (GstAudioSrc * asrc); -
static GstStaticPadTemplate directsound_src_src_factory = -
GST_STATIC_PAD_TEMPLATE (
"src",
GST_PAD_SRC,
GST_PAD_ALWAYS, -
GST_STATIC_CAPS ("audio/x-raw-int, "
- "endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, "
- "signed = (boolean) { TRUE, FALSE }, "
"width = (int) 16, "
- "depth = (int) 16, "
"rate = (int) [ 1, MAX ], " - "channels = (int) [ 1, 2 ]; "
"audio/x-raw-int, "
- "signed = (boolean) { TRUE, FALSE }, "
"width = (int) 8, "
- "depth = (int) 8, "
"rate = (int) [ 1, MAX ], " - "channels = (int) [ 1, 2 ]")); -
static void
-gst_directsound_src_do_init (GType type)
+ + +static HRESULT (WINAPI * pDSoundCaptureCreate) (LPGUID, + LPDIRECTSOUNDCAPTURE *, LPUNKNOWN); + +static void gst_directsound_src_finalise (GObject * object); + +static void gst_directsound_src_set_property (GObject * object, + guint prop_id, const GValue * value, GParamSpec * pspec); + +static void gst_directsound_src_get_property (GObject * object, + guint prop_id, GValue * value, GParamSpec * pspec); + +static gboolean gst_directsound_src_open (GstAudioSrc * asrc); +static gboolean gst_directsound_src_close (GstAudioSrc * asrc); +static gboolean gst_directsound_src_prepare (GstAudioSrc * asrc, + GstRingBufferSpec * spec); +static gboolean gst_directsound_src_unprepare (GstAudioSrc * asrc); +static void gst_directsound_src_reset (GstAudioSrc * asrc); +static GstCaps *gst_directsound_src_getcaps (GstBaseSrc * bsrc); + +static guint gst_directsound_src_read (GstAudioSrc * asrc, + gpointer data, guint length); + +static void gst_directsound_src_dispose (GObject * object); + +static void gst_directsound_src_do_init (GType type); + +static guint gst_directsound_src_delay (GstAudioSrc * asrc); + +static GstStaticPadTemplate directsound_src_src_factory = + GST_STATIC_PAD_TEMPLATE ("src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS ("audio/x-raw-int, " + "endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, " + "signed = (boolean) { TRUE, FALSE }, " + "width = (int) 16, " + "depth = (int) 16, " + "rate = (int) [ 1, MAX ], " "channels = (int) [ 1, 2 ]; " + "audio/x-raw-int, " + "signed = (boolean) { TRUE, FALSE }, " + "width = (int) 8, " + "depth = (int) 8, " + "rate = (int) [ 1, MAX ], " "channels = (int) [ 1, 2 ]")); + +static void +gst_directsound_src_do_init (GType type) { -
GST_DEBUG_CATEGORY_INIT (directsoundsrc_debug, "directsoundsrc", 0, -
"DirectSound Src"); -
}
GST_BOILERPLATE_FULL (GstDirectSoundSrc, gst_directsound_src, - GstAudioSrc,
GST_TYPE_AUDIO_SRC, gst_directsound_src_do_init); -
static void
-gst_directsound_src_dispose (GObject * object)
+ GST_DEBUG_CATEGORY_INIT (directsoundsrc_debug, "directsoundsrc", 0, + "DirectSound Src"); + + +} + +GST_BOILERPLATE_FULL (GstDirectSoundSrc, gst_directsound_src, GstAudioSrc, + GST_TYPE_AUDIO_SRC, gst_directsound_src_do_init); + +static void +gst_directsound_src_dispose (GObject * object) { -
G_OBJECT_CLASS (parent_class)->dispose (object); -
}
static void
+ G_OBJECT_CLASS (parent_class)->dispose (object); +} -gst_directsound_src_finalise (GObject * object)
+static void +gst_directsound_src_finalise (GObject * object) { -
GstDirectSoundSrc * dsoundsrc = GST_DIRECTSOUND_SRC (object); -
g_mutex_free (dsoundsrc->dsound_lock); -
}
static void
+ GstDirectSoundSrc *dsoundsrc = GST_DIRECTSOUND_SRC (object); + + g_mutex_free (dsoundsrc->dsound_lock); +} -gst_directsound_src_base_init (gpointer g_class)
+static void +gst_directsound_src_base_init (gpointer g_class) { -
GstElementClass * element_class = GST_ELEMENT_CLASS (g_class); -
GST_DEBUG ("initializing directsoundsrc base\n"); -
gst_element_class_set_details (element_class, &gst_directsound_src_details); -
gst_element_class_add_pad_template (element_class, -
gst_static_pad_template_get (&directsound_src_src_factory)); -
}
- -/* initialize the plugin's class */
-static void
-gst_directsound_src_class_init (GstDirectSoundSrcClass * klass)
+ GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); + + GST_DEBUG ("initializing directsoundsrc base\n"); + + gst_element_class_set_details (element_class, &gst_directsound_src_details); + + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&directsound_src_src_factory)); +} + + +/* initialize the plugin's class */ +static void +gst_directsound_src_class_init (GstDirectSoundSrcClass * klass) { -
GObjectClass * gobject_class; -
GstElementClass * gstelement_class; -
GstBaseSrcClass * gstbasesrc_class; -
GstBaseAudioSrcClass * gstbaseaudiosrc_class; -
GstAudioSrcClass * gstaudiosrc_class; -
gobject_class = (GObjectClass *) klass; -
gstelement_class = (GstElementClass *) klass; -
gstbasesrc_class = (GstBaseSrcClass *) klass; -
gstbaseaudiosrc_class = (GstBaseAudioSrcClass *) klass; -
gstaudiosrc_class = (GstAudioSrcClass *) klass; -
GST_DEBUG ("initializing directsoundsrc class\n"); -
gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_directsound_src_finalise); -
gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_directsound_src_dispose); -
gobject_class->get_property = + GObjectClass *gobject_class; + GstElementClass *gstelement_class; + GstBaseSrcClass *gstbasesrc_class; + GstBaseAudioSrcClass *gstbaseaudiosrc_class; + GstAudioSrcClass *gstaudiosrc_class; + + gobject_class = (GObjectClass *) klass; + gstelement_class = (GstElementClass *) klass; + gstbasesrc_class = (GstBaseSrcClass *) klass; + gstbaseaudiosrc_class = (GstBaseAudioSrcClass *) klass; + gstaudiosrc_class = (GstAudioSrcClass *) klass; + + GST_DEBUG ("initializing directsoundsrc class\n"); + + gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_directsound_src_finalise); + gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_directsound_src_dispose); + gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_directsound_src_get_property); -
gobject_class->set_property = + gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_directsound_src_set_property); -
gstbasesrc_class->get_caps = - GST_DEBUG_FUNCPTR (gst_directsound_src_getcaps); -
gstaudiosrc_class->open = GST_DEBUG_FUNCPTR (gst_directsound_src_open); -
gstaudiosrc_class->close = GST_DEBUG_FUNCPTR (gst_directsound_src_close); -
gstaudiosrc_class->read = GST_DEBUG_FUNCPTR (gst_directsound_src_read); -
gstaudiosrc_class->prepare = GST_DEBUG_FUNCPTR (gst_directsound_src_prepare); -
gstaudiosrc_class->unprepare = + + gstbasesrc_class->get_caps = GST_DEBUG_FUNCPTR (gst_directsound_src_getcaps); + + gstaudiosrc_class->open = GST_DEBUG_FUNCPTR (gst_directsound_src_open); + gstaudiosrc_class->close = GST_DEBUG_FUNCPTR (gst_directsound_src_close); + gstaudiosrc_class->read = GST_DEBUG_FUNCPTR (gst_directsound_src_read); + gstaudiosrc_class->prepare = GST_DEBUG_FUNCPTR (gst_directsound_src_prepare); + gstaudiosrc_class->unprepare = GST_DEBUG_FUNCPTR (gst_directsound_src_unprepare); -
gstaudiosrc_class->delay = GST_DEBUG_FUNCPTR (gst_directsound_src_delay); -
gstaudiosrc_class->reset = GST_DEBUG_FUNCPTR (gst_directsound_src_reset); -
}
static GstCaps *
+ gstaudiosrc_class->delay = GST_DEBUG_FUNCPTR (gst_directsound_src_delay); + gstaudiosrc_class->reset = GST_DEBUG_FUNCPTR (gst_directsound_src_reset); + + +} -gst_directsound_src_getcaps (GstBaseSrc * bsrc)
+static GstCaps * +gst_directsound_src_getcaps (GstBaseSrc * bsrc) { -
GstDirectSoundSrc * dsoundsrc; -
GstCaps * caps = NULL; -
GST_DEBUG ("get caps\n"); -
dsoundsrc = GST_DIRECTSOUND_SRC (bsrc); -
caps = gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASE_SRC_PAD
+ GstDirectSoundSrc *dsoundsrc; + GstCaps *caps = NULL; + GST_DEBUG ("get caps\n"); + + dsoundsrc = GST_DIRECTSOUND_SRC (bsrc); + + + caps = gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASE_SRC_PAD (bsrc))); -
return caps; -
} + return caps; + +} -
static void
+static void gst_directsound_src_set_property (GObject * object, guint prop_id, -
const GValue * value, GParamSpec * pspec)
+ const GValue * value, GParamSpec * pspec) { -
- // GstDirectSoundSrc *src = GST_DIRECTSOUND_SRC (object);
- GST_DEBUG ("set property\n"); -
switch (prop_id) -
{ -
-#if 0
- /* FIXME */
+ // GstDirectSoundSrc *src = GST_DIRECTSOUND_SRC (object); + GST_DEBUG ("set property\n"); + + switch (prop_id) { +#if 0 + /* FIXME */ case PROP_DEVICE: -
src->device = g_value_get_uint (value); -
break; -
-#endif /*
*/ + src->device = g_value_get_uint (value); + break; +#endif default: -
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); -
break; -
} -
} + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} -
static void
+static void gst_directsound_src_get_property (GObject * object, guint prop_id, -
GValue * value, GParamSpec * pspec)
+ GValue * value, GParamSpec * pspec) { -
-#if 0
- GstDirectSoundSrc * src = GST_DIRECTSOUND_SRC (object); -
-#endif /*
*/ -
GST_DEBUG ("get property\n"); -
switch (prop_id) { -
-#if 0
- /* FIXME */
+#if 0 + GstDirectSoundSrc *src = GST_DIRECTSOUND_SRC (object); +#endif + + GST_DEBUG ("get property\n"); + + switch (prop_id) { +#if 0 + /* FIXME */ case PROP_DEVICE: -
g_value_set_uint (value, src->device); -
break; -
-#endif /*
*/ + g_value_set_uint (value, src->device); + break; +#endif default: -
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); -
break; -
} -
} - -
-/* initialize the new element
- * instantiate pads and add them to element
- * set functions
- * initialize structure
- */
-static void
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + + +/* initialize the new element + * instantiate pads and add them to element + * set functions + * initialize structure + */ +static void gst_directsound_src_init (GstDirectSoundSrc * src, -
GstDirectSoundSrcClass * gclass)
+ GstDirectSoundSrcClass * gclass) { -
GST_DEBUG ("initializing directsoundsrc\n"); -
src->dsound_lock = g_mutex_new (); -
}
static gboolean
+ GST_DEBUG ("initializing directsoundsrc\n"); + src->dsound_lock = g_mutex_new (); +} + + -gst_directsound_src_open (GstAudioSrc * asrc)
+static gboolean +gst_directsound_src_open (GstAudioSrc * asrc) { -
GstDirectSoundSrc * dsoundsrc; -
HRESULT hRes; /* Result for windows functions */ -
GST_DEBUG ("initializing directsoundsrc\n"); -
dsoundsrc = GST_DIRECTSOUND_SRC (asrc); -
- /* Open dsound.dll */
- dsoundsrc->DSoundDLL = LoadLibrary ("dsound.dll"); -
if (!dsoundsrc->DSoundDLL) { -
goto dsound_open; -
} -
- /* Building the DLL Calls */
- pDSoundCaptureCreate =
+ GstDirectSoundSrc *dsoundsrc; + HRESULT hRes; /* Result for windows functions */ + + GST_DEBUG ("initializing directsoundsrc\n"); + + dsoundsrc = GST_DIRECTSOUND_SRC (asrc); + + /* Open dsound.dll */ + dsoundsrc->DSoundDLL = LoadLibrary ("dsound.dll"); + if (!dsoundsrc->DSoundDLL) { + goto dsound_open; + } + + /* Building the DLL Calls */ + pDSoundCaptureCreate = (void *) GetProcAddress (dsoundsrc->DSoundDLL, -
TEXT ("DirectSoundCaptureCreate")); -
- /* If everything is not ok */
- if (!pDSoundCaptureCreate) { -
goto capture_function; -
} -
- /* FIXME: add here device selection */
- /* Create capture object */
- hRes = pDSoundCaptureCreate (NULL, &dsoundsrc->pDSC, NULL); -
if (FAILED (hRes)) { -
goto capture_object; -
} -
return TRUE; -
capture_function:
{ -
FreeLibrary (dsoundsrc->DSoundDLL); -
GST_ELEMENT_ERROR (dsoundsrc, RESOURCE, OPEN_READ,
+ TEXT ("DirectSoundCaptureCreate")); + + /* If everything is not ok */ + if (!pDSoundCaptureCreate) { + goto capture_function; + } + + /* FIXME: add here device selection */ + /* Create capture object */ + hRes = pDSoundCaptureCreate (NULL, &dsoundsrc->pDSC, NULL); + if (FAILED (hRes)) { + goto capture_object; + } + + return TRUE; + +capture_function: + { + FreeLibrary (dsoundsrc->DSoundDLL); + GST_ELEMENT_ERROR (dsoundsrc, RESOURCE, OPEN_READ, ("Unable to get capturecreate function"), (NULL)); -
return FALSE; -
} -
capture_object:
{ -
FreeLibrary (dsoundsrc->DSoundDLL); -
GST_ELEMENT_ERROR (dsoundsrc, RESOURCE, OPEN_READ,
+ return FALSE; + } +capture_object: + { + FreeLibrary (dsoundsrc->DSoundDLL); + GST_ELEMENT_ERROR (dsoundsrc, RESOURCE, OPEN_READ, ("Unable to create capture object"), (NULL)); -
return FALSE; -
} -
dsound_open:
{ -
GST_ELEMENT_ERROR (dsoundsrc, RESOURCE, OPEN_READ,
+ return FALSE; + } +dsound_open: + { + DWORD err = GetLastError (); + GST_ELEMENT_ERROR (dsoundsrc, RESOURCE, OPEN_READ, ("Unable to open dsound.dll"), (NULL)); -
return FALSE; -
} -
} + g_print ("0x%x\n", HRESULT_FROM_WIN32 (err)); + return FALSE; + } +} -
static gboolean
-gst_directsound_src_close (GstAudioSrc * asrc)
+static gboolean +gst_directsound_src_close (GstAudioSrc * asrc) { -
GstDirectSoundSrc * dsoundsrc; -
HRESULT hRes; /* Result for windows functions */ -
GST_DEBUG ("initializing directsoundsrc\n"); -
dsoundsrc = GST_DIRECTSOUND_SRC (asrc); -
- /* Release capture handler */
- hRes = IDirectSoundCapture_Release (dsoundsrc->pDSC); -
- /* Close library */
- FreeLibrary (dsoundsrc->DSoundDLL); -
return TRUE; -
} - -
static gboolean
-gst_directsound_src_prepare (GstAudioSrc * asrc, GstRingBufferSpec * spec)
+ GstDirectSoundSrc *dsoundsrc; + HRESULT hRes; /* Result for windows functions */ + + GST_DEBUG ("initializing directsoundsrc\n"); + + dsoundsrc = GST_DIRECTSOUND_SRC (asrc); + + /* Release capture handler */ + hRes = IDirectSoundCapture_Release (dsoundsrc->pDSC); + + /* Close library */ + FreeLibrary (dsoundsrc->DSoundDLL); + + return TRUE; +} + +static gboolean +gst_directsound_src_prepare (GstAudioSrc * asrc, GstRingBufferSpec * spec) { -
GstDirectSoundSrc * dsoundsrc; -
WAVEFORMATEX wfx; /* Wave format structure */ -
HRESULT hRes; /* Result for windows functions */ -
DSCBUFFERDESC descSecondary; /* Capturebuffer decsiption */ -
int fmt = 0; /* audio format */ -
dsoundsrc = GST_DIRECTSOUND_SRC (asrc); -
GST_DEBUG ("initializing directsoundsrc\n"); -
- /* Define buffer */
- memset (&wfx, 0, sizeof (WAVEFORMATEX)); -
wfx.wFormatTag = WAVE_FORMAT_PCM; /* should be WAVE_FORMAT_PCM */ -
wfx.nChannels = spec->channels; -
wfx.nSamplesPerSec = spec->rate; /* 8000|11025|22050|44100 */ -
wfx.wBitsPerSample = spec->width; // 8|16;
-
wfx.nBlockAlign = wfx.nChannels * (wfx.wBitsPerSample / 8); -
wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign; -
wfx.cbSize = 0; /* This size is allways for PCM-format */ -
- /* 1 or 2 Channels etc...
- FIXME: Never really tested. Is this ok?
- */
- if (spec->width == 16 && spec->channels == 1) { -
spec->format = GST_S16_LE; -
} else if (spec->width == 16 && spec->channels == 2) { -
spec->format = GST_U16_LE; -
} else if (spec->width == 8 && spec->channels == 1) { -
spec->format = GST_S8; -
} else if (spec->width == 8 && spec->channels == 2) { -
spec->format = GST_U8; -
} -
- /* Set the buffer size to two seconds.
- This should never reached.
- */
- dsoundsrc->buffer_size = wfx.nAvgBytesPerSec * 2; -
- //notifysize * 16; //spec->width; /*original 16*/
- GST_DEBUG ("Buffer size: %d", dsoundsrc->buffer_size); -
- /* Init secondary buffer desciption */
- memset (&descSecondary, 0, sizeof (DSCBUFFERDESC)); -
descSecondary.dwSize = sizeof (DSCBUFFERDESC); -
descSecondary.dwFlags = 0; -
descSecondary.dwReserved = 0; -
- /* This is not primary buffer so have to set size */
- descSecondary.dwBufferBytes = dsoundsrc->buffer_size; -
descSecondary.lpwfxFormat = &wfx; -
- /* Create buffer */
- hRes = - IDirectSoundCapture_CreateCaptureBuffer (dsoundsrc->pDSC,
&descSecondary, -
&dsoundsrc->pDSBSecondary,
NULL); -
if (hRes != DS_OK) { -
goto capture_buffer; -
} -
spec->channels = wfx.nChannels; -
spec->rate = wfx.nSamplesPerSec; -
spec->bytes_per_sample = (spec->width / 8) * spec->channels; -
dsoundsrc->bytes_per_sample = spec->bytes_per_sample; -
GST_DEBUG ("latency time: %llu - buffer time: %llu",
spec->latency_time, - spec->buffer_time); -
- /* Buffer-time should be allways more than 2*latency */
- if (spec->buffer_time < spec->latency_time * 2) { -
spec->buffer_time = spec->latency_time * 2; -
GST_WARNING ("buffer-time was less than latency"); -
} -
- /* Save the times */
- dsoundsrc->buffer_time = spec->buffer_time; -
dsoundsrc->latency_time = spec->latency_time; -
dsoundsrc->latency_size = - (gint) wfx.nAvgBytesPerSec *
dsoundsrc->latency_time / 1000000.0; -
spec->segsize = - (guint) (((double) spec->buffer_time / 1000000.0) *
wfx.nAvgBytesPerSec); -
- /* just in case */
- if (spec->segsize < 1) -
spec->segsize = 1; -
spec->segtotal = spec->width * (wfx.nAvgBytesPerSec / spec->segsize); -
GST_DEBUG ("bytes/sec: %d, buffer size: %d, segsize: %d, segtotal: %d", -
wfx.nAvgBytesPerSec,
dsoundsrc->buffer_size,
spec->segsize, -
spec->segtotal); -
spec->silence_sample[0] = 0; -
spec->silence_sample[1] = 0; -
spec->silence_sample[2] = 0; -
spec->silence_sample[3] = 0; -
if (spec->width != 16 && spec->width != 8) -
goto dodgy_width; -
- /* Not readed anything yet */
- dsoundsrc->current_circular_offset = 0; -
GST_DEBUG ("GstRingBufferSpec->channels: %d, GstRingBufferSpec->rate: %d, \
-GstRingBufferSpec->bytes_per_sample: %d\n\
-WAVEFORMATEX.nSamplesPerSec: %ld, WAVEFORMATEX.wBitsPerSample: %d, \
-WAVEFORMATEX.nBlockAlign: %d, WAVEFORMATEX.nAvgBytesPerSec: %ld\n",
spec->channels, spec->rate, spec->bytes_per_sample,
wfx.nSamplesPerSec, wfx.wBitsPerSample,
wfx.nBlockAlign, wfx.nAvgBytesPerSec); -
return TRUE; -
wrong_format:
{ -
GST_ELEMENT_ERROR (dsoundsrc, RESOURCE, OPEN_READ,
+ + GstDirectSoundSrc *dsoundsrc; + WAVEFORMATEX wfx; /* Wave format structure */ + HRESULT hRes; /* Result for windows functions */ + DSCBUFFERDESC descSecondary; /* Capturebuffer decsiption */ + + int fmt = 0; /* audio format */ + + dsoundsrc = GST_DIRECTSOUND_SRC (asrc); + + GST_DEBUG ("initializing directsoundsrc\n"); + + /* Define buffer */ + memset (&wfx, 0, sizeof (WAVEFORMATEX)); + wfx.wFormatTag = WAVE_FORMAT_PCM; /* should be WAVE_FORMAT_PCM */ + wfx.nChannels = spec->channels; + wfx.nSamplesPerSec = spec->rate; /* 8000|11025|22050|44100 */ + wfx.wBitsPerSample = spec->width; // 8|16; + + wfx.nBlockAlign = wfx.nChannels * (wfx.wBitsPerSample / 8); + wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign; + wfx.cbSize = 0; /* This size is allways for PCM-format */ + + /* 1 or 2 Channels etc... + FIXME: Never really tested. Is this ok? + */ + if (spec->width == 16 && spec->channels == 1) { + spec->format = GST_S16_LE; + } else if (spec->width == 16 && spec->channels == 2) { + spec->format = GST_U16_LE; + } else if (spec->width == 8 && spec->channels == 1) { + spec->format = GST_S8; + } else if (spec->width == 8 && spec->channels == 2) { + spec->format = GST_U8; + } + + /* Set the buffer size to two seconds. + This should never reached. + */ + dsoundsrc->buffer_size = wfx.nAvgBytesPerSec * 2; + + //notifysize * 16; //spec->width; /*original 16*/ + GST_DEBUG ("Buffer size: %d", dsoundsrc->buffer_size); + + /* Init secondary buffer desciption */ + memset (&descSecondary, 0, sizeof (DSCBUFFERDESC)); + descSecondary.dwSize = sizeof (DSCBUFFERDESC); + descSecondary.dwFlags = 0; + descSecondary.dwReserved = 0; + + /* This is not primary buffer so have to set size */ + descSecondary.dwBufferBytes = dsoundsrc->buffer_size; + descSecondary.lpwfxFormat = &wfx; + + /* Create buffer */ + hRes = IDirectSoundCapture_CreateCaptureBuffer (dsoundsrc->pDSC, + &descSecondary, &dsoundsrc->pDSBSecondary, NULL); + if (hRes != DS_OK) { + goto capture_buffer; + } + + spec->channels = wfx.nChannels; + spec->rate = wfx.nSamplesPerSec; + spec->bytes_per_sample = (spec->width / 8) * spec->channels; + dsoundsrc->bytes_per_sample = spec->bytes_per_sample; + + GST_DEBUG ("latency time: %llu - buffer time: %llu", + spec->latency_time, spec->buffer_time); + + /* Buffer-time should be allways more than 2*latency */ + if (spec->buffer_time < spec->latency_time * 2) { + spec->buffer_time = spec->latency_time * 2; + GST_WARNING ("buffer-time was less than latency"); + } + + /* Save the times */ + dsoundsrc->buffer_time = spec->buffer_time; + dsoundsrc->latency_time = spec->latency_time; + + dsoundsrc->latency_size = (gint) wfx.nAvgBytesPerSec * + dsoundsrc->latency_time / 1000000.0; + + + spec->segsize = (guint) (((double) spec->buffer_time / 1000000.0) * + wfx.nAvgBytesPerSec); + + /* just in case */ + if (spec->segsize < 1) + spec->segsize = 1; + + spec->segtotal = spec->width * (wfx.nAvgBytesPerSec / spec->segsize); + + GST_DEBUG ("bytes/sec: %d, buffer size: %d, segsize: %d, segtotal: %d", + wfx.nAvgBytesPerSec, + dsoundsrc->buffer_size, spec->segsize, spec->segtotal); + + spec->silence_sample[0] = 0; + spec->silence_sample[1] = 0; + spec->silence_sample[2] = 0; + spec->silence_sample[3] = 0; + + if (spec->width != 16 && spec->width != 8) + goto dodgy_width; + + /* Not readed anything yet */ + dsoundsrc->current_circular_offset = 0; + + GST_DEBUG ("GstRingBufferSpec->channels: %d, GstRingBufferSpec->rate: %d, \ +GstRingBufferSpec->bytes_per_sample: %d\n\ +WAVEFORMATEX.nSamplesPerSec: %ld, WAVEFORMATEX.wBitsPerSample: %d, \ +WAVEFORMATEX.nBlockAlign: %d, WAVEFORMATEX.nAvgBytesPerSec: %ld\n", spec->channels, spec->rate, spec->bytes_per_sample, wfx.nSamplesPerSec, wfx.wBitsPerSample, wfx.nBlockAlign, wfx.nAvgBytesPerSec); + + return TRUE; + +wrong_format: + { + GST_ELEMENT_ERROR (dsoundsrc, RESOURCE, OPEN_READ, ("Unable to get format %d", spec->format), (NULL)); -
return FALSE; -
} -
capture_buffer:
{ -
GST_ELEMENT_ERROR (dsoundsrc, RESOURCE, OPEN_READ,
+ return FALSE; + } +capture_buffer: + { + GST_ELEMENT_ERROR (dsoundsrc, RESOURCE, OPEN_READ, ("Unable to create capturebuffer"), (NULL)); -
return FALSE; -
} -
dodgy_width:
{ -
GST_ELEMENT_ERROR (dsoundsrc, RESOURCE, OPEN_READ,
+ return FALSE; + } +dodgy_width: + { + GST_ELEMENT_ERROR (dsoundsrc, RESOURCE, OPEN_READ, ("Unexpected width %d", spec->width), (NULL)); -
return FALSE; -
} -
} + return FALSE; + } -
static gboolean
-gst_directsound_src_unprepare (GstAudioSrc * asrc)
+} + +static gboolean +gst_directsound_src_unprepare (GstAudioSrc * asrc) { -
GstDirectSoundSrc * dsoundsrc; -
HRESULT hRes; /* Result for windows functions */ -
- /* Resets */
- GST_DEBUG ("unpreparing directsoundsrc"); -
dsoundsrc = GST_DIRECTSOUND_SRC (asrc); -
- /* Stop capturing */
- hRes = IDirectSoundCaptureBuffer_Stop (dsoundsrc->pDSBSecondary); -
- /* Release buffer */
- hRes = IDirectSoundCaptureBuffer_Release (dsoundsrc->pDSBSecondary); -
return TRUE; -
} - -
-/*
-return number of readed bytes */
-static guint
-gst_directsound_src_read (GstAudioSrc * asrc, gpointer data, guint length)
+ GstDirectSoundSrc *dsoundsrc; + + HRESULT hRes; /* Result for windows functions */ + + /* Resets */ + GST_DEBUG ("unpreparing directsoundsrc"); + + dsoundsrc = GST_DIRECTSOUND_SRC (asrc); + + /* Stop capturing */ + hRes = IDirectSoundCaptureBuffer_Stop (dsoundsrc->pDSBSecondary); + + /* Release buffer */ + hRes = IDirectSoundCaptureBuffer_Release (dsoundsrc->pDSBSecondary); + + return TRUE; + +} + +/* +return number of readed bytes */ +static guint +gst_directsound_src_read (GstAudioSrc * asrc, gpointer data, guint length) { -
GstDirectSoundSrc * dsoundsrc; -
HRESULT hRes; /* Result for windows functions */ -
DWORD dwCurrentCaptureCursor = 0; -
DWORD dwBufferSize = 0; -
LPVOID pLockedBuffer1 = NULL; -
LPVOID pLockedBuffer2 = NULL; -
DWORD dwSizeBuffer1 = 0; -
DWORD dwSizeBuffer2 = 0; -
DWORD dwStatus = 0; -
GST_DEBUG ("reading directsoundsrc\n"); -
dsoundsrc = GST_DIRECTSOUND_SRC (asrc); -
GST_DSOUND_LOCK (dsoundsrc); -
- /* Get current buffer status */
- hRes = - IDirectSoundCaptureBuffer_GetStatus (dsoundsrc->pDSBSecondary, -
&dwStatus); -
- /* Starting capturing if not allready */
- if (!(dwStatus & DSCBSTATUS_CAPTURING)) { -
hRes = - IDirectSoundCaptureBuffer_Start (dsoundsrc->pDSBSecondary, -
DSCBSTART_LOOPING); -
- // Sleep (dsoundsrc->latency_time/1000);
- GST_DEBUG ("capture started"); -
} -
- // calculate_buffersize:
- while (length > dwBufferSize) { -
Sleep (dsoundsrc->latency_time / 1000); -
hRes = -
IDirectSoundCaptureBuffer_GetCurrentPosition (dsoundsrc->pDSBSecondary, -
&dwCurrentCaptureCursor,
NULL); -
- /* calculate the buffer */
- if (dwCurrentCaptureCursor < dsoundsrc->current_circular_offset) { -
dwBufferSize = dsoundsrc->buffer_size -
- (dsoundsrc->current_circular_offset -
dwCurrentCaptureCursor); -
} else { -
dwBufferSize = -
dwCurrentCaptureCursor - dsoundsrc->current_circular_offset; -
} -
} // while (...
-
- /* Lock the buffer */
- hRes = - IDirectSoundCaptureBuffer_Lock (dsoundsrc->pDSBSecondary, -
dsoundsrc->current_circular_offset,
length,
&pLockedBuffer1, -
&dwSizeBuffer1,
&pLockedBuffer2,
&dwSizeBuffer2,
0L); -
- /* Copy buffer data to another buffer */
- if (hRes == DS_OK) { -
memcpy (data, pLockedBuffer1, dwSizeBuffer1); -
} -
- /* ...and if something is in another buffer */
- if (pLockedBuffer2 != NULL) { -
memcpy ((data + dwSizeBuffer1), pLockedBuffer2, dwSizeBuffer2); -
} -
dsoundsrc->current_circular_offset += dwSizeBuffer1 + dwSizeBuffer2; -
dsoundsrc->current_circular_offset %= dsoundsrc->buffer_size; -
IDirectSoundCaptureBuffer_Unlock (dsoundsrc->pDSBSecondary,
pLockedBuffer1, -
dwSizeBuffer1,
pLockedBuffer2,
dwSizeBuffer2); -
GST_DSOUND_UNLOCK (dsoundsrc); -
- /* return length (readed data size in bytes) */
- return length; -
} - -
static guint
-gst_directsound_src_delay (GstAudioSrc * asrc)
+ GstDirectSoundSrc *dsoundsrc; + + HRESULT hRes; /* Result for windows functions */ + DWORD dwCurrentCaptureCursor = 0; + DWORD dwBufferSize = 0; + + LPVOID pLockedBuffer1 = NULL; + LPVOID pLockedBuffer2 = NULL; + DWORD dwSizeBuffer1 = 0; + DWORD dwSizeBuffer2 = 0; + + DWORD dwStatus = 0; + + GST_DEBUG ("reading directsoundsrc\n"); + + dsoundsrc = GST_DIRECTSOUND_SRC (asrc); + + GST_DSOUND_LOCK (dsoundsrc); + + /* Get current buffer status */ + hRes = IDirectSoundCaptureBuffer_GetStatus (dsoundsrc->pDSBSecondary, + &dwStatus); + + /* Starting capturing if not allready */ + if (!(dwStatus & DSCBSTATUS_CAPTURING)) { + hRes = IDirectSoundCaptureBuffer_Start (dsoundsrc->pDSBSecondary, + DSCBSTART_LOOPING); + // Sleep (dsoundsrc->latency_time/1000); + GST_DEBUG ("capture started"); + } + // calculate_buffersize: + while (length > dwBufferSize) { + Sleep (dsoundsrc->latency_time / 1000); + + hRes = + IDirectSoundCaptureBuffer_GetCurrentPosition (dsoundsrc->pDSBSecondary, + &dwCurrentCaptureCursor, NULL); + + /* calculate the buffer */ + if (dwCurrentCaptureCursor < dsoundsrc->current_circular_offset) { + dwBufferSize = dsoundsrc->buffer_size - + (dsoundsrc->current_circular_offset - dwCurrentCaptureCursor); + } else { + dwBufferSize = + dwCurrentCaptureCursor - dsoundsrc->current_circular_offset; + } + + + } // while (... + + /* Lock the buffer */ + hRes = IDirectSoundCaptureBuffer_Lock (dsoundsrc->pDSBSecondary, + dsoundsrc->current_circular_offset, + length, + &pLockedBuffer1, &dwSizeBuffer1, &pLockedBuffer2, &dwSizeBuffer2, 0L); + + /* Copy buffer data to another buffer */ + if (hRes == DS_OK) { + memcpy (data, pLockedBuffer1, dwSizeBuffer1); + } + + /* ...and if something is in another buffer */ + if (pLockedBuffer2 != NULL) { + memcpy (((guchar *) data + dwSizeBuffer1), pLockedBuffer2, dwSizeBuffer2); + } + + dsoundsrc->current_circular_offset += dwSizeBuffer1 + dwSizeBuffer2; + dsoundsrc->current_circular_offset %= dsoundsrc->buffer_size; + + IDirectSoundCaptureBuffer_Unlock (dsoundsrc->pDSBSecondary, + pLockedBuffer1, dwSizeBuffer1, pLockedBuffer2, dwSizeBuffer2); + + GST_DSOUND_UNLOCK (dsoundsrc); + + /* return length (readed data size in bytes) */ + return length; + +} + +static guint +gst_directsound_src_delay (GstAudioSrc * asrc) { -
GstDirectSoundSrc * dsoundsrc; -
HRESULT hRes; -
DWORD dwCurrentCaptureCursor; -
DWORD dwBytesInQueue = 0; -
gint nNbSamplesInQueue = 0; -
GST_DEBUG ("Delay\n"); -
dsoundsrc = GST_DIRECTSOUND_SRC (asrc); -
- /* evaluate the number of samples in queue in the circular buffer */
- hRes = -
IDirectSoundCaptureBuffer_GetCurrentPosition (dsoundsrc->pDSBSecondary, -
&dwCurrentCaptureCursor,
NULL); -
- /* FIXME: Check is this calculated right */
- if (hRes == S_OK) { -
if (dwCurrentCaptureCursor < dsoundsrc->current_circular_offset) { -
dwBytesInQueue = -
dsoundsrc->buffer_size - (dsoundsrc->current_circular_offset - -
dwCurrentCaptureCursor); -
} else { -
dwBytesInQueue = -
dwCurrentCaptureCursor - dsoundsrc->current_circular_offset; -
} -
nNbSamplesInQueue = dwBytesInQueue / dsoundsrc->bytes_per_sample; -
} -
return nNbSamplesInQueue; -
} - -
static void
-gst_directsound_src_reset (GstAudioSrc * asrc)
+ GstDirectSoundSrc *dsoundsrc; + HRESULT hRes; + DWORD dwCurrentCaptureCursor; + DWORD dwBytesInQueue = 0; + gint nNbSamplesInQueue = 0; + + GST_DEBUG ("Delay\n"); + + dsoundsrc = GST_DIRECTSOUND_SRC (asrc); + + /* evaluate the number of samples in queue in the circular buffer */ + hRes = + IDirectSoundCaptureBuffer_GetCurrentPosition (dsoundsrc->pDSBSecondary, + &dwCurrentCaptureCursor, NULL); + /* FIXME: Check is this calculated right */ + if (hRes == S_OK) { + if (dwCurrentCaptureCursor < dsoundsrc->current_circular_offset) { + dwBytesInQueue = + dsoundsrc->buffer_size - (dsoundsrc->current_circular_offset - + dwCurrentCaptureCursor); + } else { + dwBytesInQueue = + dwCurrentCaptureCursor - dsoundsrc->current_circular_offset; + } + + nNbSamplesInQueue = dwBytesInQueue / dsoundsrc->bytes_per_sample; + } + + return nNbSamplesInQueue; +} + +static void +gst_directsound_src_reset (GstAudioSrc * asrc) { -
GstDirectSoundSrc * dsoundsrc; -
LPVOID pLockedBuffer = NULL; -
DWORD dwSizeBuffer = 0; -
GST_DEBUG ("reset directsoundsrc\n"); -
dsoundsrc = GST_DIRECTSOUND_SRC (asrc); -
-#if 0
- IDirectSoundCaptureBuffer_Stop (dsoundsrc->pDSBSecondary); -
-#endif /*
*/ -
GST_DSOUND_LOCK (dsoundsrc); -
if (dsoundsrc->pDSBSecondary) { -
- /*stop capturing */
- HRESULT hRes = - IDirectSoundCaptureBuffer_Stop (dsoundsrc->pDSBSecondary); -
- /*reset position */
- /* hRes = IDirectSoundCaptureBuffer_SetCurrentPosition (dsoundsrc->pDSBSecondary, 0); */
-
- /*reset the buffer */
- hRes = - IDirectSoundCaptureBuffer_Lock (dsoundsrc->pDSBSecondary, -
dsoundsrc->current_circular_offset, dsoundsrc->buffer_size, -
pLockedBuffer, &dwSizeBuffer, NULL, NULL, 0L); -
if (SUCCEEDED (hRes)) { -
memset (pLockedBuffer, 0, dwSizeBuffer); -
hRes = -
IDirectSoundCaptureBuffer_Unlock (dsoundsrc->pDSBSecondary, - pLockedBuffer,
dwSizeBuffer, NULL, 0); -
} -
dsoundsrc->current_circular_offset = 0; -
} -
GST_DSOUND_UNLOCK (dsoundsrc); -
} - -
+ GstDirectSoundSrc *dsoundsrc; + LPVOID pLockedBuffer = NULL; + DWORD dwSizeBuffer = 0; + + GST_DEBUG ("reset directsoundsrc\n"); + + dsoundsrc = GST_DIRECTSOUND_SRC (asrc); + +#if 0 + IDirectSoundCaptureBuffer_Stop (dsoundsrc->pDSBSecondary); +#endif + + GST_DSOUND_LOCK (dsoundsrc); + + if (dsoundsrc->pDSBSecondary) { + /*stop capturing */ + HRESULT hRes = IDirectSoundCaptureBuffer_Stop (dsoundsrc->pDSBSecondary); + + /*reset position */ + /* hRes = IDirectSoundCaptureBuffer_SetCurrentPosition (dsoundsrc->pDSBSecondary, 0); */ + + /*reset the buffer */ + hRes = IDirectSoundCaptureBuffer_Lock (dsoundsrc->pDSBSecondary, + dsoundsrc->current_circular_offset, dsoundsrc->buffer_size, + pLockedBuffer, &dwSizeBuffer, NULL, NULL, 0L); + + if (SUCCEEDED (hRes)) { + memset (pLockedBuffer, 0, dwSizeBuffer); + + hRes = + IDirectSoundCaptureBuffer_Unlock (dsoundsrc->pDSBSecondary, + pLockedBuffer, dwSizeBuffer, NULL, 0); + } + dsoundsrc->current_circular_offset = 0; + + } + + GST_DSOUND_UNLOCK (dsoundsrc); +} diff --git a/sys/dshowsrcwrapper/Makefile.am b/sys/dshowsrcwrapper/Makefile.am index de78c531..de78c531 100755..100644 --- a/sys/dshowsrcwrapper/Makefile.am +++ b/sys/dshowsrcwrapper/Makefile.am diff --git a/sys/dshowsrcwrapper/gstdshow.cpp b/sys/dshowsrcwrapper/gstdshow.cpp index 4b090346..8b77b585 100755..100644 --- a/sys/dshowsrcwrapper/gstdshow.cpp +++ b/sys/dshowsrcwrapper/gstdshow.cpp @@ -70,6 +70,21 @@ gst_dshow_free_pins_mediatypes (GList *pins_mediatypes) g_list_free (pins_mediatypes); } +gboolean +gst_dshow_check_mediatype (AM_MEDIA_TYPE *media_type, const GUID sub_type, + const GUID format_type) +{ + RPC_STATUS rpcstatus; + + g_return_val_if_fail (media_type != NULL, FALSE); + + return + UuidCompare (&media_type->subtype, (UUID *) &sub_type, + &rpcstatus) == 0 && rpcstatus == RPC_S_OK && + UuidCompare (&media_type->formattype, (UUID *) &format_type, + &rpcstatus) == 0 && rpcstatus == RPC_S_OK; +} + gboolean gst_dshow_get_pin_from_filter (IBaseFilter *filter, PIN_DIRECTION pindir, IPin **pin) { diff --git a/sys/dshowsrcwrapper/gstdshow.h b/sys/dshowsrcwrapper/gstdshow.h index e71ca789..4491e50d 100755..100644 --- a/sys/dshowsrcwrapper/gstdshow.h +++ b/sys/dshowsrcwrapper/gstdshow.h @@ -54,6 +54,9 @@ void gst_dshow_free_mediatype (AM_MEDIA_TYPE *pmt); /* free the memory of all mediatypes of the input list if pin mediatype */ void gst_dshow_free_pins_mediatypes (GList *mediatypes); +/* allow to know what kind of media type we have */ +gboolean gst_dshow_check_mediatype (AM_MEDIA_TYPE *media_type, const GUID sub_type, const GUID format_type); + /* get a pin from directshow filter */ gboolean gst_dshow_get_pin_from_filter (IBaseFilter *filter, PIN_DIRECTION pindir, IPin **pin); diff --git a/sys/dshowsrcwrapper/gstdshowaudiosrc.cpp b/sys/dshowsrcwrapper/gstdshowaudiosrc.cpp index a0e2d78c..03dab12d 100755..100644 --- a/sys/dshowsrcwrapper/gstdshowaudiosrc.cpp +++ b/sys/dshowsrcwrapper/gstdshowaudiosrc.cpp @@ -264,15 +264,12 @@ static GValueArray * gst_dshowaudiosrc_get_device_name_values (GstDshowAudioSrc * src) { GValueArray *array = g_value_array_new (0); - GValue value = { 0 }; ICreateDevEnum *devices_enum = NULL; IEnumMoniker *moniker_enum = NULL; IMoniker *moniker = NULL; HRESULT hres = S_FALSE; ULONG fetched; - g_value_init (&value, G_TYPE_STRING); - hres = CoCreateInstance (CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (LPVOID *) &devices_enum); if (hres != S_OK) { @@ -310,6 +307,8 @@ gst_dshowaudiosrc_get_device_name_values (GstDshowAudioSrc * src) g_utf16_to_utf8 ((const gunichar2 *) varFriendlyName.bstrVal, wcslen (varFriendlyName.bstrVal), NULL, NULL, NULL); + GValue value = { 0 };
+ g_value_init (&value, G_TYPE_STRING); g_value_set_string (&value, friendly_name); g_value_array_append (array, &value); g_value_unset (&value); @@ -368,6 +367,17 @@ gst_dshowaudiosrc_set_property (GObject * object, guint prop_id, } break; } + case PROP_DEVICE_NAME:
+ {
+ if (src->device_name) {
+ g_free (src->device_name);
+ src->device_name = NULL;
+ }
+ if (g_value_get_string (value)) {
+ src->device_name = g_strdup (g_value_get_string (value));
+ }
+ break;
+ } default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -757,7 +767,6 @@ gst_dshowaudiosrc_getcaps_from_streamcaps (GstDshowAudioSrc * src, IPin * pin, { GstCaps *caps = NULL; HRESULT hres = S_OK; - RPC_STATUS rpcstatus; int icount = 0; int isize = 0; AUDIO_STREAM_CONFIG_CAPS ascc; @@ -785,11 +794,7 @@ gst_dshowaudiosrc_getcaps_from_streamcaps (GstDshowAudioSrc * src, IPin * pin, if (!caps) caps = gst_caps_new_empty (); - if ((UuidCompare (&pin_mediatype->mediatype->subtype, (UUID *) &MEDIASUBTYPE_PCM, - &rpcstatus) == 0 && rpcstatus == RPC_S_OK) - && (UuidCompare (&pin_mediatype->mediatype->formattype, - (UUID *) &FORMAT_WaveFormatEx, &rpcstatus) == 0 - && rpcstatus == RPC_S_OK)) { + if (gst_dshow_check_mediatype (pin_mediatype->mediatype, MEDIASUBTYPE_PCM, FORMAT_WaveFormatEx)) { WAVEFORMATEX *wavformat = (WAVEFORMATEX *) pin_mediatype->mediatype->pbFormat; mediacaps = diff --git a/sys/dshowsrcwrapper/gstdshowaudiosrc.h b/sys/dshowsrcwrapper/gstdshowaudiosrc.h index d5cfe6e0..d5cfe6e0 100755..100644 --- a/sys/dshowsrcwrapper/gstdshowaudiosrc.h +++ b/sys/dshowsrcwrapper/gstdshowaudiosrc.h diff --git a/sys/dshowsrcwrapper/gstdshowfakesink.cpp b/sys/dshowsrcwrapper/gstdshowfakesink.cpp index 6c0c74dc..6c0c74dc 100755..100644 --- a/sys/dshowsrcwrapper/gstdshowfakesink.cpp +++ b/sys/dshowsrcwrapper/gstdshowfakesink.cpp diff --git a/sys/dshowsrcwrapper/gstdshowfakesink.h b/sys/dshowsrcwrapper/gstdshowfakesink.h index 51291c69..51291c69 100755..100644 --- a/sys/dshowsrcwrapper/gstdshowfakesink.h +++ b/sys/dshowsrcwrapper/gstdshowfakesink.h diff --git a/sys/dshowsrcwrapper/gstdshowsrcwrapper.cpp b/sys/dshowsrcwrapper/gstdshowsrcwrapper.cpp index 9acfc344..9acfc344 100755..100644 --- a/sys/dshowsrcwrapper/gstdshowsrcwrapper.cpp +++ b/sys/dshowsrcwrapper/gstdshowsrcwrapper.cpp diff --git a/sys/dshowsrcwrapper/gstdshowvideosrc.cpp b/sys/dshowsrcwrapper/gstdshowvideosrc.cpp index 14654f60..86cb5eb7 100755..100644 --- a/sys/dshowsrcwrapper/gstdshowvideosrc.cpp +++ b/sys/dshowsrcwrapper/gstdshowvideosrc.cpp @@ -1,5 +1,6 @@ /* GStreamer * Copyright (C) 2007 Sebastien Moutte <sebastien@moutte.net> + * Copyright (C) 2009 Julien Isorce <julien.isorce@gmail.com> * * gstdshowvideosrc.c: * @@ -25,6 +26,8 @@ #include "gstdshowvideosrc.h" +#include <gst/video/video.h> + static const GstElementDetails gst_dshowvideosrc_details = GST_ELEMENT_DETAILS ("DirectShow video capture source", "Source/Video", @@ -42,12 +45,9 @@ const GUID MEDIASUBTYPE_I420 static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS, - GST_STATIC_CAPS ("video/x-raw-rgb," - "bpp = (int) 24," - "depth = (int) 24," - "width = (int) [ 1, MAX ]," - "height = (int) [ 1, MAX ]," - "framerate = (fraction) [ 0, MAX ];" + GST_STATIC_CAPS ( + GST_VIDEO_CAPS_BGR ";" + GST_VIDEO_CAPS_YUV ("{ I420 }") ";" "video/x-dv," "systemstream = (boolean) FALSE," "width = (int) [ 1, MAX ]," @@ -55,11 +55,7 @@ static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src", "framerate = (fraction) [ 0, MAX ]," "format = (fourcc) dvsd;" "video/x-dv," - "systemstream = (boolean) TRUE;" - "video/x-raw-yuv," - "width = (int) [ 1, MAX ]," - "height = (int) [ 1, MAX ]," - "framerate = (fraction) [ 0, MAX ]," "format = (fourcc) I420") + "systemstream = (boolean) TRUE") ); static void gst_dshowvideosrc_init_interfaces (GType type); @@ -104,6 +100,7 @@ static gboolean gst_dshowvideosrc_unlock (GstBaseSrc * bsrc); static gboolean gst_dshowvideosrc_unlock_stop (GstBaseSrc * bsrc); static gboolean gst_dshowvideosrc_set_caps (GstBaseSrc * bsrc, GstCaps * caps); static GstCaps *gst_dshowvideosrc_get_caps (GstBaseSrc * bsrc); +static void gst_dshowvideosrc_src_fixate (GstBaseSrc * bsrc, GstCaps * caps); static GstFlowReturn gst_dshowvideosrc_create (GstPushSrc * psrc, GstBuffer ** buf); @@ -170,6 +167,7 @@ gst_dshowvideosrc_class_init (GstDshowVideoSrcClass * klass) gstbasesrc_class->get_caps = GST_DEBUG_FUNCPTR (gst_dshowvideosrc_get_caps); gstbasesrc_class->set_caps = GST_DEBUG_FUNCPTR (gst_dshowvideosrc_set_caps); + gstbasesrc_class->fixate = GST_DEBUG_FUNCPTR (gst_dshowvideosrc_src_fixate); gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_dshowvideosrc_start); gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_dshowvideosrc_stop); gstbasesrc_class->unlock = GST_DEBUG_FUNCPTR (gst_dshowvideosrc_unlock); @@ -205,6 +203,7 @@ gst_dshowvideosrc_init (GstDshowVideoSrc * src, GstDshowVideoSrcClass * klass) src->media_filter = NULL; src->filter_graph = NULL; src->caps = NULL; + src->video_defaults = NULL; src->pins_mediatypes = NULL; src->is_rgb = FALSE; @@ -219,6 +218,36 @@ gst_dshowvideosrc_init (GstDshowVideoSrc * src, GstDshowVideoSrcClass * klass) } static void +gst_dshowvideosrc_src_fixate (GstBaseSrc * bsrc, GstCaps * caps) +{ + /* If there is no desired video size, set default video size to device preffered video size */ + + GstDshowVideoSrc *src = GST_DSHOWVIDEOSRC (bsrc); + GstStructure *structure = gst_caps_get_structure (caps, 0); + guint i = 0; + gint res = -1; + + for (; i < gst_caps_get_size (src->caps) && res == -1; i++) { + GstCaps *capstmp = gst_caps_copy_nth (src->caps, i); + + if (gst_caps_is_subset (caps, capstmp)) { + res = i; + } + gst_caps_unref (capstmp); + } + + if (res != -1) { + GList *type_video_default = g_list_nth (src->video_defaults, res); + if (type_video_default) { + GstCaptureVideoDefault *video_default = (GstCaptureVideoDefault *) type_video_default->data; + gst_structure_fixate_field_nearest_int (structure, "width", video_default->defaultWidth); + gst_structure_fixate_field_nearest_int (structure, "height", video_default->defaultHeight); + gst_structure_fixate_field_nearest_fraction (structure, "framerate", video_default->defaultFPS, 1); + } + } +} + +static void gst_dshowvideosrc_dispose (GObject * gobject) { GstDshowVideoSrc *src = GST_DSHOWVIDEOSRC (gobject); @@ -238,6 +267,11 @@ gst_dshowvideosrc_dispose (GObject * gobject) src->caps = NULL; } + if (src->video_defaults) { + g_list_free (src->video_defaults); + src->video_defaults = NULL; + } + if (src->pins_mediatypes) { gst_dshow_free_pins_mediatypes (src->pins_mediatypes); src->pins_mediatypes = NULL; @@ -292,7 +326,6 @@ gst_dshowvideosrc_probe_probe_property (GstPropertyProbe * probe, switch (prop_id) { case PROP_DEVICE_NAME: - //gst_v4l_class_probe_devices (klass, FALSE); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (probe, prop_id, pspec); @@ -320,15 +353,12 @@ static GValueArray * gst_dshowvideosrc_get_device_name_values (GstDshowVideoSrc * src) { GValueArray *array = g_value_array_new (0); - GValue value = { 0 }; ICreateDevEnum *devices_enum = NULL; IEnumMoniker *moniker_enum = NULL; IMoniker *moniker = NULL; HRESULT hres = S_FALSE; ULONG fetched; - g_value_init (&value, G_TYPE_STRING); - hres = CoCreateInstance (CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (LPVOID *) &devices_enum); if (hres != S_OK) { @@ -367,6 +397,8 @@ gst_dshowvideosrc_get_device_name_values (GstDshowVideoSrc * src) g_utf16_to_utf8 ((const gunichar2 *) varFriendlyName.bstrVal, wcslen (varFriendlyName.bstrVal), NULL, NULL, NULL); + GValue value = { 0 };
+ g_value_init (&value, G_TYPE_STRING); g_value_set_string (&value, friendly_name); g_value_array_append (array, &value); g_value_unset (&value); @@ -556,7 +588,6 @@ static GstStateChangeReturn gst_dshowvideosrc_change_state (GstElement * element, GstStateChange transition) { HRESULT hres = S_FALSE; - IAMVfwCaptureDialogs *dialog = NULL; GstDshowVideoSrc *src = GST_DSHOWVIDEOSRC (element); switch (transition) { @@ -675,13 +706,51 @@ gst_dshowvideosrc_set_caps (GstBaseSrc * bsrc, GstCaps * caps) if (res != -1 && src->pins_mediatypes) { /* get the corresponding media type and build the dshow graph */ - GstCapturePinMediaType *pin_mediatype = NULL; - gchar *caps_string = NULL; GList *type = g_list_nth (src->pins_mediatypes, res); - if (type) { + //will be removed when GST_TYPE_INT_RANGE_STEP exits + GList *type_video_default = g_list_nth (src->video_defaults, res); + + if (type && type_video_default) { + //will be removed when GST_TYPE_INT_RANGE_STEP exits + GstCaptureVideoDefault *video_default = (GstCaptureVideoDefault *) type_video_default->data; + GstCapturePinMediaType *pin_mediatype = NULL; + gchar *caps_string = NULL; + gchar *src_caps_string = NULL; + + /* retrieve the desired video size */ + VIDEOINFOHEADER *video_info = NULL; + gint width = 0; + gint height = 0; + gint numerator = 0; + gint denominator = 0; + gst_structure_get_int (s, "width", &width); + gst_structure_get_int (s, "height", &height); + gst_structure_get_fraction (s, "framerate", &numerator, &denominator); + + /* check if the desired video size is valid about granularity */ + /* This check will be removed when GST_TYPE_INT_RANGE_STEP exits */ + /* See remarks in gst_dshowvideosrc_getcaps_from_streamcaps function */ + if (video_default->granularityWidth != 0 && width % video_default->granularityWidth != 0) + g_warning ("your desired video size is not valid : %d mod %d !=0\n", width, video_default->granularityWidth) ; + if (video_default->granularityHeight !=0 && height % video_default->granularityHeight != 0) + g_warning ("your desired video size is not valid : %d mod %d !=0\n", height, video_default->granularityHeight) ; + + /* display all capabilities when using --gst-debug-level=3 */ + src_caps_string = gst_caps_to_string (src->caps); + GST_CAT_LEVEL_LOG (dshowvideosrc_debug, GST_LEVEL_INFO, src, src_caps_string); + g_free (src_caps_string); + pin_mediatype = (GstCapturePinMediaType *) type->data; + /* update mediatype */ + video_info = (VIDEOINFOHEADER *) pin_mediatype->mediatype->pbFormat; + video_info->bmiHeader.biWidth = width; + video_info->bmiHeader.biHeight = height; + video_info->AvgTimePerFrame = (LONGLONG) (10000000 * denominator / (double)numerator); + video_info->bmiHeader.biSizeImage = DIBSIZE(video_info->bmiHeader); + pin_mediatype->mediatype->lSampleSize = DIBSIZE(video_info->bmiHeader); + src->dshow_fakesink->gst_set_media_type (pin_mediatype->mediatype); src->dshow_fakesink->gst_set_buffer_callback( (push_buffer_func) gst_dshowvideosrc_push_buffer, src); @@ -695,7 +764,7 @@ gst_dshowvideosrc_set_caps (GstBaseSrc * bsrc, GstCaps * caps) } hres = src->filter_graph->ConnectDirect(pin_mediatype->capture_pin, - input_pin, NULL); + input_pin, pin_mediatype->mediatype); input_pin->Release(); if (hres != S_OK) { @@ -829,7 +898,6 @@ gst_dshowvideosrc_getcaps_from_streamcaps (GstDshowVideoSrc * src, IPin * pin, { GstCaps *caps = NULL; HRESULT hres = S_OK; - RPC_STATUS rpcstatus; int icount = 0; int isize = 0; VIDEO_STREAM_CONFIG_CAPS vscc; @@ -845,6 +913,7 @@ gst_dshowvideosrc_getcaps_from_streamcaps (GstDshowVideoSrc * src, IPin * pin, for (; i < icount; i++) { GstCapturePinMediaType *pin_mediatype = g_new0 (GstCapturePinMediaType, 1); + GstCaptureVideoDefault *video_default = g_new0 (GstCaptureVideoDefault, 1); pin->AddRef(); pin_mediatype->capture_pin = pin; @@ -857,91 +926,127 @@ gst_dshowvideosrc_getcaps_from_streamcaps (GstDshowVideoSrc * src, IPin * pin, if (!caps) caps = gst_caps_new_empty (); + /* some remarks: */ + /* Hope GST_TYPE_INT_RANGE_STEP will exits in future gstreamer releases */ + /* because we could use : */ + /* "width", GST_TYPE_INT_RANGE_STEP, video_default->minWidth, video_default->maxWidth, video_default->granularityWidth */ + /* instead of : */ + /* "width", GST_TYPE_INT_RANGE, video_default->minWidth, video_default->maxWidth */ + + /* For framerate we do not need a step (granularity) because */ + /* "The IAMStreamConfig::SetFormat method will set the frame rate to the closest */ + /* value that the filter supports" as it said in the VIDEO_STREAM_CONFIG_CAPS dshwo doc */ + /* I420 */ - if ((UuidCompare (&pin_mediatype->mediatype->subtype, (UUID *) &MEDIASUBTYPE_I420, - &rpcstatus) == 0 && rpcstatus == RPC_S_OK) - && (UuidCompare (&pin_mediatype->mediatype->formattype, - (UUID *) &FORMAT_VideoInfo, &rpcstatus) == 0 - && rpcstatus == RPC_S_OK)) { + if (gst_dshow_check_mediatype (pin_mediatype->mediatype, MEDIASUBTYPE_I420, FORMAT_VideoInfo)) { video_info = (VIDEOINFOHEADER *) pin_mediatype->mediatype->pbFormat; + video_default->defaultWidth = video_info->bmiHeader.biWidth; + video_default->defaultHeight = video_info->bmiHeader.biHeight; + video_default->defaultFPS = (int) (10000000 / video_info->AvgTimePerFrame); + video_default->granularityWidth = vscc.OutputGranularityX; + video_default->granularityHeight = vscc.OutputGranularityY; + mediacaps = gst_caps_new_simple ("video/x-raw-yuv", - "width", G_TYPE_INT, video_info->bmiHeader.biWidth, - "height", G_TYPE_INT, video_info->bmiHeader.biHeight, - "framerate", GST_TYPE_FRACTION, - (int) (10000000 / video_info->AvgTimePerFrame), 1, "format", - GST_TYPE_FOURCC, MAKEFOURCC ('I', '4', '2', '0'), NULL); + "width", GST_TYPE_INT_RANGE, vscc.MinOutputSize.cx, vscc.MaxOutputSize.cx, + "height", GST_TYPE_INT_RANGE, vscc.MinOutputSize.cy, vscc.MaxOutputSize.cy, + "framerate", GST_TYPE_FRACTION_RANGE, + (int) (10000000 / vscc.MaxFrameInterval), 1, + (int) (10000000 / vscc.MinFrameInterval), 1, + "format", GST_TYPE_FOURCC, MAKEFOURCC ('I', '4', '2', '0'), NULL); if (mediacaps) { src->pins_mediatypes = g_list_append (src->pins_mediatypes, pin_mediatype); + src->video_defaults = + g_list_append (src->video_defaults, video_default); gst_caps_append (caps, mediacaps); } else { gst_dshow_free_pin_mediatype (pin_mediatype); + g_free (video_default); } continue; } - /* RGB24 */ - if ((UuidCompare (&pin_mediatype->mediatype->subtype, (UUID *) &MEDIASUBTYPE_RGB24, - &rpcstatus) == 0 && rpcstatus == RPC_S_OK) - && (UuidCompare (&pin_mediatype->mediatype->formattype, - (UUID *) &FORMAT_VideoInfo, &rpcstatus) == 0 - && rpcstatus == RPC_S_OK)) { + /* BGR */ + if (gst_dshow_check_mediatype (pin_mediatype->mediatype, MEDIASUBTYPE_RGB24, FORMAT_VideoInfo)) { video_info = (VIDEOINFOHEADER *) pin_mediatype->mediatype->pbFormat; + video_default->defaultWidth = video_info->bmiHeader.biWidth; + video_default->defaultHeight = video_info->bmiHeader.biHeight; + video_default->defaultFPS = (int) (10000000 / video_info->AvgTimePerFrame); + video_default->granularityWidth = vscc.OutputGranularityX; + video_default->granularityHeight = vscc.OutputGranularityY; + /* ffmpegcolorspace handles RGB24 in BIG_ENDIAN */ mediacaps = gst_caps_new_simple ("video/x-raw-rgb", - "bpp", G_TYPE_INT, 24, - "depth", G_TYPE_INT, 24, - "width", G_TYPE_INT, video_info->bmiHeader.biWidth, - "height", G_TYPE_INT, video_info->bmiHeader.biHeight, - "framerate", GST_TYPE_FRACTION, - (int) (10000000 / video_info->AvgTimePerFrame), 1, "endianness", - G_TYPE_INT, G_BIG_ENDIAN, "red_mask", G_TYPE_INT, 255, "green_mask", - G_TYPE_INT, 65280, "blue_mask", G_TYPE_INT, 16711680, NULL); + "bpp", G_TYPE_INT, 24, + "depth", G_TYPE_INT, 24, + "width", GST_TYPE_INT_RANGE, vscc.MinOutputSize.cx, vscc.MaxOutputSize.cx, + "height", GST_TYPE_INT_RANGE, vscc.MinOutputSize.cy, vscc.MaxOutputSize.cy, + "framerate", GST_TYPE_FRACTION_RANGE, + (int) (10000000 / vscc.MaxFrameInterval), 1, + (int) (10000000 / vscc.MinFrameInterval), 1, + "endianness", G_TYPE_INT, G_BIG_ENDIAN, + "red_mask", G_TYPE_INT, 255, + "green_mask", G_TYPE_INT, 65280, + "blue_mask", G_TYPE_INT, 16711680, NULL); if (mediacaps) { src->pins_mediatypes = g_list_append (src->pins_mediatypes, pin_mediatype); + src->video_defaults = + g_list_append (src->video_defaults, video_default); gst_caps_append (caps, mediacaps); } else { gst_dshow_free_pin_mediatype (pin_mediatype); + g_free (video_default); } continue; } /* DVSD */ - if ((UuidCompare (&pin_mediatype->mediatype->subtype, (UUID *) &MEDIASUBTYPE_dvsd, - &rpcstatus) == 0 && rpcstatus == RPC_S_OK) - && (UuidCompare (&pin_mediatype->mediatype->formattype, - (UUID *) &FORMAT_VideoInfo, &rpcstatus) == 0 - && rpcstatus == RPC_S_OK)) { + if (gst_dshow_check_mediatype (pin_mediatype->mediatype, MEDIASUBTYPE_dvsd, FORMAT_VideoInfo)) { video_info = (VIDEOINFOHEADER *) pin_mediatype->mediatype->pbFormat; + video_default->defaultWidth = video_info->bmiHeader.biWidth; + video_default->defaultHeight = video_info->bmiHeader.biHeight; + video_default->defaultFPS = (int) (10000000 / video_info->AvgTimePerFrame); + video_default->granularityWidth = vscc.OutputGranularityX; + video_default->granularityHeight = vscc.OutputGranularityY; + mediacaps = gst_caps_new_simple ("video/x-dv", - "systemstream", G_TYPE_BOOLEAN, FALSE, - "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('d', 'v', 's', 'd'), - "framerate", GST_TYPE_FRACTION, - (int) (10000000 / video_info->AvgTimePerFrame), 1, "width", - G_TYPE_INT, video_info->bmiHeader.biWidth, "height", G_TYPE_INT, - video_info->bmiHeader.biHeight, NULL); + "systemstream", G_TYPE_BOOLEAN, FALSE, + "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('d', 'v', 's', 'd'), + "framerate", GST_TYPE_FRACTION_RANGE, + (int) (10000000 / vscc.MaxFrameInterval), 1, + (int) (10000000 / vscc.MinFrameInterval), 1, + "width", GST_TYPE_INT_RANGE, vscc.MinOutputSize.cx, vscc.MaxOutputSize.cx, + "height", GST_TYPE_INT_RANGE, vscc.MinOutputSize.cy, vscc.MaxOutputSize.cy, NULL); if (mediacaps) { src->pins_mediatypes = g_list_append (src->pins_mediatypes, pin_mediatype); + src->video_defaults = + g_list_append (src->video_defaults, video_default); gst_caps_append (caps, mediacaps); } else { gst_dshow_free_pin_mediatype (pin_mediatype); + g_free (video_default); } continue; } /* DV stream */ - if ((UuidCompare (&pin_mediatype->mediatype->subtype, (UUID *) &MEDIASUBTYPE_dvsd, - &rpcstatus) == 0 && rpcstatus == RPC_S_OK) - && (UuidCompare (&pin_mediatype->mediatype->formattype, - (UUID *) &FORMAT_DvInfo, &rpcstatus) == 0 && rpcstatus == RPC_S_OK)) { + if (gst_dshow_check_mediatype (pin_mediatype->mediatype, MEDIASUBTYPE_dvsd, FORMAT_DvInfo)) { + video_info = (VIDEOINFOHEADER *) pin_mediatype->mediatype->pbFormat; + + //No video size in caps when stream ? I do know if the following fields exist + video_default->defaultWidth = video_info->bmiHeader.biWidth; + video_default->defaultHeight = video_info->bmiHeader.biHeight; + video_default->defaultFPS = (int) (10000000 / video_info->AvgTimePerFrame); + video_default->granularityWidth = vscc.OutputGranularityX; + video_default->granularityHeight = vscc.OutputGranularityY; mediacaps = gst_caps_new_simple ("video/x-dv", "systemstream", G_TYPE_BOOLEAN, TRUE, NULL); @@ -949,14 +1054,18 @@ gst_dshowvideosrc_getcaps_from_streamcaps (GstDshowVideoSrc * src, IPin * pin, if (mediacaps) { src->pins_mediatypes = g_list_append (src->pins_mediatypes, pin_mediatype); + src->video_defaults = + g_list_append (src->video_defaults, video_default); gst_caps_append (caps, mediacaps); } else { gst_dshow_free_pin_mediatype (pin_mediatype); + g_free (video_default); } continue; } } else { gst_dshow_free_pin_mediatype (pin_mediatype); + g_free (video_default); } } diff --git a/sys/dshowsrcwrapper/gstdshowvideosrc.h b/sys/dshowsrcwrapper/gstdshowvideosrc.h index bf94e61f..41583071 100755..100644 --- a/sys/dshowsrcwrapper/gstdshowvideosrc.h +++ b/sys/dshowsrcwrapper/gstdshowvideosrc.h @@ -42,6 +42,18 @@ G_BEGIN_DECLS typedef struct _GstDshowVideoSrc GstDshowVideoSrc; typedef struct _GstDshowVideoSrcClass GstDshowVideoSrcClass; +/* video default properties associated to a video format (YUY2, I420, RGB24 ...) */ +typedef struct _GstCaptureVideoDefault +{ + gint defaultWidth; + gint defaultHeight; + gint defaultFPS; + + gint granularityWidth; //will be removed when GST_TYPE_INT_RANGE_STEP exits + gint granularityHeight; //will be removed when GST_TYPE_INT_RANGE_STEP exits + +} GstCaptureVideoDefault; + struct _GstDshowVideoSrc { GstPushSrc src; @@ -55,6 +67,9 @@ struct _GstDshowVideoSrc /* list of caps created from the list of supported media types of the dshow capture filter */ GstCaps *caps; + /* list of dshow default video properties from filter's capture pins */ + GList *video_defaults; + /* list of dshow media types from the filter's capture pins */ GList *pins_mediatypes; diff --git a/tests/check/Makefile.am b/tests/check/Makefile.am index 1fc64c54..3a2d92ff 100644 --- a/tests/check/Makefile.am +++ b/tests/check/Makefile.am @@ -78,22 +78,27 @@ VALGRIND_TO_FIX = \ VALGRIND_TESTS_DISABLE = \ $(VALGRIND_TO_FIX) +# these tests don't even pass +# camerabin: temporarily disabled because it fails with current core -git +# (which will be release before the next -bad release though, and chances are +# changes to fix this are needed in the camerabin test) +# neon: too flaky (almost always fails 'the first time') +noinst_PROGRAMS = \ + $(check_neon) \ + elements/camerabin + check_PROGRAMS = \ generic/states \ $(check_mpeg2enc) \ $(check_mplex) \ - $(check_neon) \ $(check_ofa) \ $(check_timidity) \ $(check_kate) \ elements/aacparse \ elements/amrparse \ elements/asfmux \ - elements/camerabin \ elements/legacyresample \ elements/qtmux \ - elements/rtpbin \ - elements/rtpbin_buffer_list \ elements/selector \ elements/shapewipe \ elements/mxfdemux \ @@ -118,13 +123,6 @@ elements_camerabin_LDADD = \ -lgstinterfaces-@GST_MAJORMINOR@ elements_camerabin_SOURCES = elements/camerabin.c -elements_rtpbin_buffer_list_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) \ - $(ERROR_CFLAGS) $(GST_CHECK_CFLAGS) -elements_rtpbin_buffer_list_LDADD = $(GST_PLUGINS_BASE_LIBS) \ - -lgstnetbuffer-@GST_MAJORMINOR@ -lgstrtp-@GST_MAJORMINOR@ \ - $(GST_BASE_LIBS) $(GST_LIBS_LIBS) $(GST_CHECK_LIBS) -elements_rtpbin_buffer_list_SOURCES = elements/rtpbin_buffer_list.c - elements_timidity_CFLAGS = $(GST_BASE_CFLAGS) $(AM_CFLAGS) elements_timidity_LDADD = $(GST_BASE_LIBS) $(LDADD) diff --git a/tests/check/elements/.gitignore b/tests/check/elements/.gitignore index df2bb15d..30c67fe8 100644 --- a/tests/check/elements/.gitignore +++ b/tests/check/elements/.gitignore @@ -1,6 +1,7 @@ .dirstamp aacparse amrparse +asfmux camerabin deinterleave gdpdepay @@ -19,8 +20,6 @@ souphttpsrc rganalysis rglimiter rgvolume -rtpbin -rtpbin_buffer_list selector shapewipe spectrum diff --git a/tests/check/elements/kate.c b/tests/check/elements/kate.c index c848cc5c..9eed574d 100644 --- a/tests/check/elements/kate.c +++ b/tests/check/elements/kate.c @@ -447,6 +447,8 @@ GST_START_TEST (test_kate_encode_simple) GstCaps *caps; kateenc = setup_kateenc (); + g_object_set (kateenc, "category", "subtitles", NULL); + fail_unless (gst_element_set_state (kateenc, GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS, "could not set to playing"); @@ -498,6 +500,8 @@ GST_START_TEST (test_kate_encode_spu) GstCaps *caps; kateenc = setup_kateenc (); + g_object_set (kateenc, "category", "spu-subtitles", NULL); + fail_unless (gst_element_set_state (kateenc, GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS, "could not set to playing"); @@ -560,6 +564,8 @@ GST_START_TEST (test_kate_encode_keepalives) for (round = 0; round < 3; ++round) { kateenc = setup_kateenc (); + /* doesn't matter here, since we never send a packet */ + g_object_set (kateenc, "category", "subtitles", NULL); fail_unless (gst_element_set_state (kateenc, GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS, "could not set to playing"); diff --git a/tests/check/elements/rtpbin.c b/tests/check/elements/rtpbin.c deleted file mode 100644 index 8764da54..00000000 --- a/tests/check/elements/rtpbin.c +++ /dev/null @@ -1,421 +0,0 @@ -/* GStreamer - * - * unit test for gstrtpbin - * - * Copyright (C) <2009> Wim Taymans <wim.taymans@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., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#include <gst/check/gstcheck.h> - -GST_START_TEST (test_cleanup_send) -{ - GstElement *rtpbin; - GstPad *rtp_sink, *rtp_src, *rtcp_src; - GObject *session; - gint count = 2; - - rtpbin = gst_element_factory_make ("gstrtpbin", "rtpbin"); - - while (count--) { - /* request session 0 */ - rtp_sink = gst_element_get_request_pad (rtpbin, "send_rtp_sink_0"); - fail_unless (rtp_sink != NULL); - ASSERT_OBJECT_REFCOUNT (rtp_sink, "rtp_sink", 2); - - /* request again */ - rtp_sink = gst_element_get_request_pad (rtpbin, "send_rtp_sink_0"); - fail_unless (rtp_sink != NULL); - ASSERT_OBJECT_REFCOUNT (rtp_sink, "rtp_sink", 3); - gst_object_unref (rtp_sink); - - /* this static pad should be created automatically now */ - rtp_src = gst_element_get_static_pad (rtpbin, "send_rtp_src_0"); - fail_unless (rtp_src != NULL); - ASSERT_OBJECT_REFCOUNT (rtp_src, "rtp_src", 2); - - /* we should be able to get an internal session 0 now */ - g_signal_emit_by_name (rtpbin, "get-internal-session", 0, &session); - fail_unless (session != NULL); - g_object_unref (session); - - /* get the send RTCP pad too */ - rtcp_src = gst_element_get_request_pad (rtpbin, "send_rtcp_src_0"); - fail_unless (rtcp_src != NULL); - ASSERT_OBJECT_REFCOUNT (rtcp_src, "rtcp_src", 2); - - /* second time */ - rtcp_src = gst_element_get_request_pad (rtpbin, "send_rtcp_src_0"); - fail_unless (rtcp_src != NULL); - ASSERT_OBJECT_REFCOUNT (rtcp_src, "rtcp_src", 3); - gst_object_unref (rtcp_src); - - gst_element_release_request_pad (rtpbin, rtp_sink); - /* we should only have our refs to the pads now */ - ASSERT_OBJECT_REFCOUNT (rtp_sink, "rtp_sink", 1); - ASSERT_OBJECT_REFCOUNT (rtp_src, "rtp_src", 1); - ASSERT_OBJECT_REFCOUNT (rtcp_src, "rtp_src", 2); - - /* the other pad should be gone now */ - fail_unless (gst_element_get_static_pad (rtpbin, "send_rtp_src_0") == NULL); - - /* internal session should still be there */ - g_signal_emit_by_name (rtpbin, "get-internal-session", 0, &session); - fail_unless (session != NULL); - g_object_unref (session); - - /* release the RTCP pad */ - gst_element_release_request_pad (rtpbin, rtcp_src); - /* we should only have our refs to the pads now */ - ASSERT_OBJECT_REFCOUNT (rtp_sink, "rtp_sink", 1); - ASSERT_OBJECT_REFCOUNT (rtp_src, "rtp_src", 1); - ASSERT_OBJECT_REFCOUNT (rtcp_src, "rtp_src", 1); - - /* the session should be gone now */ - g_signal_emit_by_name (rtpbin, "get-internal-session", 0, &session); - fail_unless (session == NULL); - - /* unref the request pad and the static pad */ - gst_object_unref (rtp_sink); - gst_object_unref (rtp_src); - gst_object_unref (rtcp_src); - } - - gst_object_unref (rtpbin); -} - -GST_END_TEST; - -typedef struct -{ - guint16 seqnum; - gboolean pad_added; - GstPad *pad; - GMutex *lock; - GCond *cond; - GstPad *sinkpad; - GList *pads; -} CleanupData; - -static void -init_data (CleanupData * data) -{ - data->seqnum = 10; - data->pad_added = FALSE; - data->lock = g_mutex_new (); - data->cond = g_cond_new (); - data->pads = NULL; -} - -static void -clean_data (CleanupData * data) -{ - g_list_foreach (data->pads, (GFunc) gst_object_unref, NULL); - g_list_free (data->pads); - g_mutex_free (data->lock); - g_cond_free (data->cond); -} - -static guint8 rtp_packet[] = { 0x80, 0x60, 0x94, 0xbc, 0x8f, 0x37, 0x4e, 0xb8, - 0x44, 0xa8, 0xf3, 0x7c, 0x06, 0x6a, 0x0c, 0xce, - 0x13, 0x25, 0x19, 0x69, 0x1f, 0x93, 0x25, 0x9d, - 0x2b, 0x82, 0x31, 0x3b, 0x36, 0xc1, 0x3c, 0x13 -}; - -static GstBuffer * -make_rtp_packet (CleanupData * data) -{ - static GstCaps *caps = NULL; - GstBuffer *result; - guint8 *datap; - - if (caps == NULL) { - caps = gst_caps_from_string ("application/x-rtp," - "media=(string)audio, clock-rate=(int)44100, " - "encoding-name=(string)L16, encoding-params=(string)1, channels=(int)1"); - data->seqnum = 0; - } - - result = gst_buffer_new_and_alloc (sizeof (rtp_packet)); - datap = GST_BUFFER_DATA (result); - memcpy (datap, rtp_packet, sizeof (rtp_packet)); - - datap[2] = (data->seqnum >> 8) & 0xff; - datap[3] = data->seqnum & 0xff; - - data->seqnum++; - - gst_buffer_set_caps (result, caps); - - return result; -} - -static GstFlowReturn -dummy_chain (GstPad * pad, GstBuffer * buffer) -{ - gst_buffer_unref (buffer); - - return GST_FLOW_OK; -} - -static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("application/x-rtp")); - - -static GstPad * -make_sinkpad (CleanupData * data) -{ - GstPad *pad; - - pad = gst_pad_new_from_static_template (&sink_factory, "sink"); - - gst_pad_set_chain_function (pad, dummy_chain); - gst_pad_set_active (pad, TRUE); - - data->pads = g_list_prepend (data->pads, pad); - - return pad; -} - -static void -pad_added_cb (GstElement * rtpbin, GstPad * pad, CleanupData * data) -{ - GstPad *sinkpad; - - GST_DEBUG ("pad added %s:%s\n", GST_DEBUG_PAD_NAME (pad)); - - if (GST_PAD_IS_SINK (pad)) - return; - - fail_unless (data->pad_added == FALSE); - - sinkpad = make_sinkpad (data); - fail_unless (gst_pad_link (pad, sinkpad) == GST_PAD_LINK_OK); - - g_mutex_lock (data->lock); - data->pad_added = TRUE; - data->pad = pad; - g_cond_signal (data->cond); - g_mutex_unlock (data->lock); -} - -static void -pad_removed_cb (GstElement * rtpbin, GstPad * pad, CleanupData * data) -{ - GST_DEBUG ("pad removed %s:%s\n", GST_DEBUG_PAD_NAME (pad)); - - if (data->pad != pad) - return; - - fail_unless (data->pad_added == TRUE); - - g_mutex_lock (data->lock); - data->pad_added = FALSE; - g_cond_signal (data->cond); - g_mutex_unlock (data->lock); -} - -GST_START_TEST (test_cleanup_recv) -{ - GstElement *rtpbin; - GstPad *rtp_sink; - CleanupData data; - GstStateChangeReturn ret; - GstFlowReturn res; - GstBuffer *buffer; - gint count = 2; - - init_data (&data); - - rtpbin = gst_element_factory_make ("gstrtpbin", "rtpbin"); - - g_signal_connect (rtpbin, "pad-added", (GCallback) pad_added_cb, &data); - g_signal_connect (rtpbin, "pad-removed", (GCallback) pad_removed_cb, &data); - - ret = gst_element_set_state (rtpbin, GST_STATE_PLAYING); - fail_unless (ret == GST_STATE_CHANGE_SUCCESS); - - while (count--) { - /* request session 0 */ - rtp_sink = gst_element_get_request_pad (rtpbin, "recv_rtp_sink_0"); - fail_unless (rtp_sink != NULL); - ASSERT_OBJECT_REFCOUNT (rtp_sink, "rtp_sink", 2); - - /* no sourcepads are created yet */ - fail_unless (rtpbin->numsinkpads == 1); - fail_unless (rtpbin->numsrcpads == 0); - - buffer = make_rtp_packet (&data); - res = gst_pad_chain (rtp_sink, buffer); - GST_DEBUG ("res %d, %s\n", res, gst_flow_get_name (res)); - fail_unless (res == GST_FLOW_OK); - - buffer = make_rtp_packet (&data); - res = gst_pad_chain (rtp_sink, buffer); - GST_DEBUG ("res %d, %s\n", res, gst_flow_get_name (res)); - fail_unless (res == GST_FLOW_OK); - - /* we wait for the new pad to appear now */ - g_mutex_lock (data.lock); - while (!data.pad_added) - g_cond_wait (data.cond, data.lock); - g_mutex_unlock (data.lock); - - /* sourcepad created now */ - fail_unless (rtpbin->numsinkpads == 1); - fail_unless (rtpbin->numsrcpads == 1); - - /* remove the session */ - gst_element_release_request_pad (rtpbin, rtp_sink); - gst_object_unref (rtp_sink); - - /* pad should be gone now */ - g_mutex_lock (data.lock); - while (data.pad_added) - g_cond_wait (data.cond, data.lock); - g_mutex_unlock (data.lock); - - /* nothing left anymore now */ - fail_unless (rtpbin->numsinkpads == 0); - fail_unless (rtpbin->numsrcpads == 0); - } - - ret = gst_element_set_state (rtpbin, GST_STATE_NULL); - fail_unless (ret == GST_STATE_CHANGE_SUCCESS); - - gst_object_unref (rtpbin); - - clean_data (&data); -} - -GST_END_TEST; - -GST_START_TEST (test_cleanup_recv2) -{ - GstElement *rtpbin; - GstPad *rtp_sink; - CleanupData data; - GstStateChangeReturn ret; - GstFlowReturn res; - GstBuffer *buffer; - gint count = 2; - - init_data (&data); - - rtpbin = gst_element_factory_make ("gstrtpbin", "rtpbin"); - - g_signal_connect (rtpbin, "pad-added", (GCallback) pad_added_cb, &data); - g_signal_connect (rtpbin, "pad-removed", (GCallback) pad_removed_cb, &data); - - ret = gst_element_set_state (rtpbin, GST_STATE_PLAYING); - fail_unless (ret == GST_STATE_CHANGE_SUCCESS); - - /* request session 0 */ - rtp_sink = gst_element_get_request_pad (rtpbin, "recv_rtp_sink_0"); - fail_unless (rtp_sink != NULL); - ASSERT_OBJECT_REFCOUNT (rtp_sink, "rtp_sink", 2); - - while (count--) { - /* no sourcepads are created yet */ - fail_unless (rtpbin->numsinkpads == 1); - fail_unless (rtpbin->numsrcpads == 0); - - buffer = make_rtp_packet (&data); - res = gst_pad_chain (rtp_sink, buffer); - GST_DEBUG ("res %d, %s\n", res, gst_flow_get_name (res)); - fail_unless (res == GST_FLOW_OK); - - buffer = make_rtp_packet (&data); - res = gst_pad_chain (rtp_sink, buffer); - GST_DEBUG ("res %d, %s\n", res, gst_flow_get_name (res)); - fail_unless (res == GST_FLOW_OK); - - /* we wait for the new pad to appear now */ - g_mutex_lock (data.lock); - while (!data.pad_added) - g_cond_wait (data.cond, data.lock); - g_mutex_unlock (data.lock); - - /* sourcepad created now */ - fail_unless (rtpbin->numsinkpads == 1); - fail_unless (rtpbin->numsrcpads == 1); - - /* change state */ - ret = gst_element_set_state (rtpbin, GST_STATE_NULL); - fail_unless (ret == GST_STATE_CHANGE_SUCCESS); - - /* pad should be gone now */ - g_mutex_lock (data.lock); - while (data.pad_added) - g_cond_wait (data.cond, data.lock); - g_mutex_unlock (data.lock); - - /* back to playing for the next round */ - ret = gst_element_set_state (rtpbin, GST_STATE_PLAYING); - fail_unless (ret == GST_STATE_CHANGE_SUCCESS); - } - - /* remove the session */ - gst_element_release_request_pad (rtpbin, rtp_sink); - gst_object_unref (rtp_sink); - - /* nothing left anymore now */ - fail_unless (rtpbin->numsinkpads == 0); - fail_unless (rtpbin->numsrcpads == 0); - - ret = gst_element_set_state (rtpbin, GST_STATE_NULL); - fail_unless (ret == GST_STATE_CHANGE_SUCCESS); - - gst_object_unref (rtpbin); - - clean_data (&data); -} - -GST_END_TEST; - -Suite * -gstrtpbin_suite (void) -{ - Suite *s = suite_create ("gstrtpbin"); - TCase *tc_chain = tcase_create ("general"); - - suite_add_tcase (s, tc_chain); - tcase_add_test (tc_chain, test_cleanup_send); - tcase_add_test (tc_chain, test_cleanup_recv); - tcase_add_test (tc_chain, test_cleanup_recv2); - - return s; -} - -int -main (int argc, char **argv) -{ - int nf; - - Suite *s = gstrtpbin_suite (); - SRunner *sr = srunner_create (s); - - gst_check_init (&argc, &argv); - - srunner_run_all (sr, CK_NORMAL); - nf = srunner_ntests_failed (sr); - srunner_free (sr); - - return nf; -} diff --git a/tests/check/elements/rtpbin_buffer_list.c b/tests/check/elements/rtpbin_buffer_list.c deleted file mode 100644 index af4003dd..00000000 --- a/tests/check/elements/rtpbin_buffer_list.c +++ /dev/null @@ -1,331 +0,0 @@ -/* GStreamer - * - * Unit test for gstrtpbin sending rtp packets using GstBufferList. - * Copyright (C) 2009 Branko Subasic <branko dot subasic at axis dot 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. - */ - -#include <gst/check/gstcheck.h> - -#include <gst/rtp/gstrtpbuffer.h> - - - -/* This test makes sure that RTP packets sent as buffer lists are sent through - * the rtpbin as they are supposed to, and not corrupted in any way. - */ - - -#define TEST_CAPS \ - "application/x-rtp, " \ - "media=(string)video, " \ - "clock-rate=(int)90000, " \ - "encoding-name=(string)H264, " \ - "profile-level-id=(string)4d4015, " \ - "payload=(int)96, " \ - "ssrc=(guint)2633237432, " \ - "clock-base=(guint)1868267015, " \ - "seqnum-base=(guint)54229" - - -/* RTP headers and the first 2 bytes of the payload (FU indicator and FU header) - */ -static const guint8 rtp_header[2][14] = { - {0x80, 0x60, 0xbb, 0xb7, 0x5c, 0xe9, 0x09, - 0x0d, 0xf5, 0x9c, 0x43, 0x55, 0x1c, 0x86}, - {0x80, 0x60, 0xbb, 0xb8, 0x5c, 0xe9, 0x09, - 0x0d, 0xf5, 0x9c, 0x43, 0x55, 0x1c, 0x46} -}; - -static const guint rtp_header_len[] = { - sizeof rtp_header[0], - sizeof rtp_header[1] -}; - -static GstBuffer *header_buffer[2] = { NULL, NULL }; - - -/* Some payload. - */ -static char *payload = - "0123456789ABSDEF0123456789ABSDEF0123456789ABSDEF0123456789ABSDEF0123456789ABSDEF" - "0123456789ABSDEF0123456789ABSDEF0123456789ABSDEF0123456789ABSDEF0123456789ABSDEF" - "0123456789ABSDEF0123456789ABSDEF0123456789ABSDEF0123456789ABSDEF0123456789ABSDEF" - "0123456789ABSDEF0123456789ABSDEF0123456789ABSDEF0123456789ABSDEF0123456789ABSDEF" - "0123456789ABSDEF0123456789ABSDEF0123456789ABSDEF0123456789ABSDEF0123456789ABSDEF" - "0123456789ABSDEF0123456789ABSDEF0123456789ABSDEF0123456789ABSDEF0123456789ABSDEF" - "0123456789ABSDEF0123456"; - -static const guint payload_offset[] = { - 0, 498 -}; - -static const guint payload_len[] = { - 498, 5 -}; - - -static GstBuffer *original_buffer = NULL; - -static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("application/x-rtp")); - -static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("application/x-rtp")); - - -static GstBuffer * -_create_original_buffer (void) -{ - GstCaps *caps; - - if (original_buffer != NULL) - return original_buffer; - - original_buffer = gst_buffer_new (); - fail_unless (original_buffer != NULL); - - gst_buffer_set_data (original_buffer, (guint8 *) payload, strlen (payload)); - GST_BUFFER_TIMESTAMP (original_buffer) = - gst_clock_get_internal_time (gst_system_clock_obtain ()); - - caps = gst_caps_from_string (TEST_CAPS); - fail_unless (caps != NULL); - gst_buffer_set_caps (original_buffer, caps); - gst_caps_unref (caps); - - return original_buffer; -} - -static GstBufferList * -_create_buffer_list (void) -{ - GstBufferList *list; - GstBufferListIterator *it; - GstBuffer *orig_buffer; - GstBuffer *buffer; - - orig_buffer = _create_original_buffer (); - fail_if (orig_buffer == NULL); - - list = gst_buffer_list_new (); - fail_if (list == NULL); - - it = gst_buffer_list_iterate (list); - fail_if (it == NULL); - - /*** First group, i.e. first packet. **/ - gst_buffer_list_iterator_add_group (it); - - /* Create buffer with RTP header and add it to the 1st group */ - buffer = gst_buffer_new (); - GST_BUFFER_MALLOCDATA (buffer) = g_memdup (&rtp_header[0], rtp_header_len[0]); - GST_BUFFER_DATA (buffer) = GST_BUFFER_MALLOCDATA (buffer); - GST_BUFFER_SIZE (buffer) = rtp_header_len[0]; - gst_buffer_copy_metadata (buffer, orig_buffer, GST_BUFFER_COPY_ALL); - header_buffer[0] = buffer; - gst_buffer_list_iterator_add (it, buffer); - - /* Create the payload buffer and add it to the 1st group - */ - buffer = - gst_buffer_create_sub (orig_buffer, payload_offset[0], payload_len[0]); - fail_if (buffer == NULL); - gst_buffer_list_iterator_add (it, buffer); - - - /*** Second group, i.e. second packet. ***/ - - /* Create a new group to hold the rtp header and the payload */ - gst_buffer_list_iterator_add_group (it); - - /* Create buffer with RTP header and add it to the 2nd group */ - buffer = gst_buffer_new (); - GST_BUFFER_MALLOCDATA (buffer) = g_memdup (&rtp_header[1], rtp_header_len[1]); - GST_BUFFER_DATA (buffer) = GST_BUFFER_MALLOCDATA (buffer); - GST_BUFFER_SIZE (buffer) = rtp_header_len[1]; - gst_buffer_copy_metadata (buffer, orig_buffer, GST_BUFFER_COPY_ALL); - header_buffer[1] = buffer; - - /* Add the rtp header to the buffer list */ - gst_buffer_list_iterator_add (it, buffer); - - /* Create the payload buffer and add it to the 2d group - */ - buffer = - gst_buffer_create_sub (orig_buffer, payload_offset[1], payload_len[1]); - fail_if (buffer == NULL); - gst_buffer_list_iterator_add (it, buffer); - - gst_buffer_list_iterator_free (it); - - return list; -} - - -static void -_check_header (GstBuffer * buffer, guint index) -{ - guint8 *data; - - fail_if (buffer == NULL); - fail_unless (index < 2); - - fail_unless (GST_BUFFER_SIZE (buffer) == rtp_header_len[index]); - - /* Can't do a memcmp() on the whole header, cause the SSRC (bytes 8-11) will - * most likely be changed in gstrtpbin. - */ - fail_unless ((data = GST_BUFFER_DATA (buffer)) != NULL); - fail_unless_equals_uint64 (*(guint64 *) data, *(guint64 *) rtp_header[index]); - fail_unless (*(guint16 *) (data + 12) == - *(guint16 *) (rtp_header[index] + 12)); -} - - -static void -_check_payload (GstBuffer * buffer, guint index) -{ - fail_if (buffer == NULL); - fail_unless (index < 2); - - fail_unless (GST_BUFFER_SIZE (buffer) == payload_len[index]); - fail_if (GST_BUFFER_DATA (buffer) != - (gpointer) (payload + payload_offset[index])); - fail_if (memcmp (GST_BUFFER_DATA (buffer), payload + payload_offset[index], - payload_len[index])); -} - - -static void -_check_group (GstBufferListIterator * it, guint index, GstCaps * caps) -{ - GstBuffer *buffer; - - fail_unless (it != NULL); - fail_unless (gst_buffer_list_iterator_n_buffers (it) == 2); - fail_unless (caps != NULL); - - fail_unless ((buffer = gst_buffer_list_iterator_next (it)) != NULL); - - fail_unless (GST_BUFFER_TIMESTAMP (buffer) == - GST_BUFFER_TIMESTAMP (original_buffer)); - - fail_unless (gst_caps_is_equal (GST_BUFFER_CAPS (original_buffer), - GST_BUFFER_CAPS (buffer))); - - _check_header (buffer, index); - - fail_unless ((buffer = gst_buffer_list_iterator_next (it)) != NULL); - _check_payload (buffer, index); -} - - -static GstFlowReturn -_sink_chain_list (GstPad * pad, GstBufferList * list) -{ - GstCaps *caps; - GstBufferListIterator *it; - - caps = gst_caps_from_string (TEST_CAPS); - fail_unless (caps != NULL); - - fail_unless (GST_IS_BUFFER_LIST (list)); - fail_unless (gst_buffer_list_n_groups (list) == 2); - - it = gst_buffer_list_iterate (list); - fail_if (it == NULL); - - fail_unless (gst_buffer_list_iterator_next_group (it)); - _check_group (it, 0, caps); - - fail_unless (gst_buffer_list_iterator_next_group (it)); - _check_group (it, 1, caps); - - gst_caps_unref (caps); - gst_buffer_list_iterator_free (it); - - gst_buffer_list_unref (list); - - return GST_FLOW_OK; -} - - -static void -_set_chain_functions (GstPad * pad) -{ - gst_pad_set_chain_list_function (pad, _sink_chain_list); -} - - -GST_START_TEST (test_bufferlist) -{ - GstElement *rtpbin; - GstPad *sinkpad; - GstPad *srcpad; - GstBufferList *list; - - list = _create_buffer_list (); - fail_unless (list != NULL); - - rtpbin = gst_check_setup_element ("gstrtpbin"); - - srcpad = - gst_check_setup_src_pad_by_name (rtpbin, &srctemplate, "send_rtp_sink_0"); - fail_if (srcpad == NULL); - sinkpad = - gst_check_setup_sink_pad_by_name (rtpbin, &sinktemplate, - "send_rtp_src_0"); - fail_if (sinkpad == NULL); - - _set_chain_functions (sinkpad); - - gst_pad_set_active (sinkpad, TRUE); - gst_element_set_state (rtpbin, GST_STATE_PLAYING); - fail_unless (gst_pad_push_list (srcpad, list) == GST_FLOW_OK); - gst_pad_set_active (sinkpad, FALSE); - - gst_check_teardown_pad_by_name (rtpbin, "send_rtp_src_0"); - gst_check_teardown_pad_by_name (rtpbin, "send_rtp_sink_0"); - gst_check_teardown_element (rtpbin); -} - -GST_END_TEST; - - - -static Suite * -bufferlist_suite (void) -{ - Suite *s = suite_create ("BufferList"); - - TCase *tc_chain = tcase_create ("general"); - - /* time out after 30s. */ - tcase_set_timeout (tc_chain, 10); - - suite_add_tcase (s, tc_chain); - tcase_add_test (tc_chain, test_bufferlist); - - return s; -} - -GST_CHECK_MAIN (bufferlist); diff --git a/win32/common/config.h b/win32/common/config.h index 19137494..d1903cf6 100644 --- a/win32/common/config.h +++ b/win32/common/config.h @@ -199,7 +199,7 @@ #undef USE_POISONING /* Version number of package */ -#define VERSION "0.10.13.1" +#define VERSION "0.10.13.2" /* Define to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel and VAX). */ diff --git a/win32/vs8/gst-plugins-bad.sln b/win32/vs8/gst-plugins-bad.sln index 109210c9..339290a1 100755 --- a/win32/vs8/gst-plugins-bad.sln +++ b/win32/vs8/gst-plugins-bad.sln @@ -4,6 +4,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libgstdirectdraw", "libgstd EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libgstdshowsrcwrapper", "libdshowsrcwrapper.vcproj", "{42EC1484-5031-4962-9E45-C990BB77EB37}"
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libgstdirectsound", "libgstdirectsound.vcproj", "{667B0437-F668-443B-AFF0-8991DE75DBED}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
@@ -18,6 +20,10 @@ Global {42EC1484-5031-4962-9E45-C990BB77EB37}.Debug|Win32.Build.0 = Debug|Win32
{42EC1484-5031-4962-9E45-C990BB77EB37}.Release|Win32.ActiveCfg = Release|Win32
{42EC1484-5031-4962-9E45-C990BB77EB37}.Release|Win32.Build.0 = Release|Win32
+ {667B0437-F668-443B-AFF0-8991DE75DBED}.Debug|Win32.ActiveCfg = Debug|Win32
+ {667B0437-F668-443B-AFF0-8991DE75DBED}.Debug|Win32.Build.0 = Debug|Win32
+ {667B0437-F668-443B-AFF0-8991DE75DBED}.Release|Win32.ActiveCfg = Release|Win32
+ {667B0437-F668-443B-AFF0-8991DE75DBED}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/win32/vs8/libgstdirectsound.vcproj b/win32/vs8/libgstdirectsound.vcproj new file mode 100755 index 00000000..c3ba07b0 --- /dev/null +++ b/win32/vs8/libgstdirectsound.vcproj @@ -0,0 +1,217 @@ +<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8,00"
+ Name="libgstdirectsound"
+ ProjectGUID="{667B0437-F668-443B-AFF0-8991DE75DBED}"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Debug"
+ IntermediateDirectory="Debug"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="C:\msys\1.0\local\include;C:\msys\1.0\local\include\libxml2;"C:\msys\1.0\local\include\glib-2.0";"C:\msys\1.0\local\lib\glib-2.0\include";"C:\msys\1.0\local\include\gstreamer-0.10";..\common;"$(DXSDK_DIR)Include""
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBGSTDIRECTSOUND_EXPORTS;HAVE_CONFIG_H"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="dsound.lib libgstinterfaces-0.10.lib libgstvideo-0.10.lib libgstreamer-0.10.lib libgstbase-0.10.lib libgstaudio-0.10.lib glib-2.0.lib gobject-2.0.lib user32.lib gdi32.lib dxguid.lib"
+ OutputFile="$(OutDir)/libgstdirectsound.dll"
+ LinkIncremental="2"
+ AdditionalLibraryDirectories="C:\msys\1.0\local\lib;"$(DXSDK_DIR)Lib\x86""
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile="$(OutDir)/libgstdirectsound.pdb"
+ SubSystem="2"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ ImportLibrary="$(OutDir)/libgstdirectsound.lib"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="copy /Y Debug\libgstdirectsound.dll c:\msys\1.0\local\lib\gstreamer-0.10"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ CharacterSet="0"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="C:\msys\1.0\local\include;C:\msys\1.0\local\include\libxml2;"C:\msys\1.0\local\include\glib-2.0";"C:\msys\1.0\local\lib\glib-2.0\include";"C:\msys\1.0\local\include\gstreamer-0.10";..\common;"$(DXSDK_DIR)Include""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBGSTDIRECTSOUND_EXPORTS;HAVE_CONFIG_H"
+ RuntimeLibrary="0"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="dsound.lib libgstinterfaces-0.10.lib libgstvideo-0.10.lib libgstreamer-0.10.lib libgstbase-0.10.lib libgstaudio-0.10.lib glib-2.0.lib gobject-2.0.lib user32.lib gdi32.lib dxguid.lib"
+ OutputFile="$(OutDir)/libgstdirectsound.dll"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories="C:\msys\1.0\local\lib;"$(DXSDK_DIR)Lib\x86""
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ ImportLibrary="$(OutDir)/libgstdirectsound.lib"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="copy /Y Release\libgstdirectsound.dll c:\msys\1.0\local\lib\gstreamer-0.10"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\..\sys\directsound\gstdirectsoundplugin.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sys\directsound\gstdirectsoundsrc.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath="..\..\sys\directsound\gstdirectsoundsrc.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
|