public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
* [rpms/xine-lib] epel9-next: * Wed Apr 16 2008 Ville Skyttä <ville.skytta at iki.fi> - 1.1.12-1
@ 2026-07-20 20:00 
  0 siblings, 0 replies; only message in thread
From:  @ 2026-07-20 20:00 UTC (permalink / raw)
  To: git-commits

            A new commit has been pushed.

            Repo   : rpms/xine-lib
            Branch : epel9-next
            Commit : 93d0f06ea4a38fc9a391838d0e66c0621bd5b0e8
            Author : Ville Skyttä <scop@fedoraproject.org>
            Date   : 2008-04-16T21:05:40+00:00
            Stats  : +13/-1100 in 6 file(s)
            URL    : https://src.fedoraproject.org/rpms/xine-lib/c/93d0f06ea4a38fc9a391838d0e66c0621bd5b0e8?branch=epel9-next

            Log:
            * Wed Apr 16 2008 Ville Skyttä <ville.skytta at iki.fi> - 1.1.12-1
- 1.1.12 (plugin ABI 1.21); qt, mkv, and pulseaudio patches applied upstream.

---
diff --git a/.cvsignore b/.cvsignore
index 907cc99..e68873d 100644
--- a/.cvsignore
+++ b/.cvsignore
@@ -1,2 +1,2 @@
-xine-lib-1.1.11.1-pruned.tar.bz2
-xine-lib-1.1.11.1-autotools.patch.bz2
+xine-lib-1.1.12-pruned.tar.bz2
+xine-lib-1.1.12-autotools.patch.bz2

diff --git a/sources b/sources
index 7c8f9d9..4a02333 100644
--- a/sources
+++ b/sources
@@ -1,2 +1,2 @@
-b6a4fe9dd2ec80452870a8bfbb3974f0  xine-lib-1.1.11.1-pruned.tar.bz2
-c257bf0b964d25592f1c612149ae2c7a  xine-lib-1.1.11.1-autotools.patch.bz2
+3f918af93f52e486fb8fd4dfec04f98f  xine-lib-1.1.12-pruned.tar.bz2
+771565628e4dfcfc8657b1256b9f41ef  xine-lib-1.1.12-autotools.patch.bz2

diff --git a/xine-lib-1.1.11.1-mkv.patch b/xine-lib-1.1.11.1-mkv.patch
deleted file mode 100644
index c835db1..0000000
--- a/xine-lib-1.1.11.1-mkv.patch
+++ /dev/null
@@ -1,21 +0,0 @@
-
-# HG changeset patch
-# User Darren Salt <linux@youmustbejoking.demon.co.uk>
-# Date 1207353205 -3600
-# Node ID ff20b8db74eabc74b7b95da4c1b44fc5d7f2ec8c
-# Parent 05ebc886fd30158b59a26e03cf2f6f3a52114b24
-Fix a regression in the Matroska demuxer.
-One '&'...
-
---- a/src/demuxers/ebml.c	Fri Apr 04 18:35:33 2008 +0100
-+++ b/src/demuxers/ebml.c	Sat Apr 05 00:53:25 2008 +0100
-@@ -327,7 +327,7 @@ char *ebml_alloc_read_ascii (ebml_parser
-   if (text)
-   {
-     text[elem->len] = '\0';
--    if (ebml_read_ascii (ebml, &elem, text))
-+    if (ebml_read_ascii (ebml, elem, text))
-       return text;
-     free (text);
-   }
-

diff --git a/xine-lib-1.1.11.1-qt.patch b/xine-lib-1.1.11.1-qt.patch
deleted file mode 100644
index 54a9c67..0000000
--- a/xine-lib-1.1.11.1-qt.patch
+++ /dev/null
@@ -1,23 +0,0 @@
-
-# HG changeset patch
-# User Darren Salt <linux@youmustbejoking.demon.co.uk>
-# Date 1206976103 -3600
-# Node ID d8e1305c13820b82d896f7bc77d196b9c9645dd6
-# Parent 2cc583bdc498fd6c95b8a21c10e81a0cef4d63c6
-Revert a change which broke Quicktime atom parsing.
-
---- a/src/demuxers/demux_qt.c	Sun Mar 30 19:48:58 2008 +0100
-+++ b/src/demuxers/demux_qt.c	Mon Mar 31 16:08:23 2008 +0100
-@@ -895,11 +895,6 @@ static qt_error parse_trak_atom (qt_trak
-   for (i = ATOM_PREAMBLE_SIZE; i < trak_atom_size - 4; i++) {
-     current_atom_size = _X_BE_32(&trak_atom[i - 4]);	
-     current_atom = _X_BE_32(&trak_atom[i]);
--
--    if (current_atom_size > trak_atom_size - i) {
--      last_error = QT_NOT_A_VALID_FILE;
--      goto free_trak;
--    }
- 
-     if (current_atom == TKHD_ATOM) {
-       trak->flags = _X_BE_16(&trak_atom[i + 6]);
-

diff --git a/xine-lib.spec b/xine-lib.spec
index eb41b78..a1a11c8 100644
--- a/xine-lib.spec
+++ b/xine-lib.spec
@@ -8,7 +8,7 @@
 #    http://www.redhat.com/archives/fedora-devel-list/2007-August/msg01411.html
 # - external dvdnav - not compatible as of 1.1.11 and 4.1.1
 
-%define         abiver      1.20
+%define         abiver      1.21
 %define         codecdir    %{_libdir}/codecs
 
 %ifarch %{ix86}
@@ -31,8 +31,8 @@
 
 Summary:        Xine library
 Name:           xine-lib
-Version:        1.1.11.1
-Release:        3%{?dist}
+Version:        1.1.12
+Release:        1%{?dist}
 License:        GPLv2+
 Group:          System Environment/Libraries
 URL:            http://xinehq.de/
@@ -48,12 +48,6 @@ Patch1:         %{name}-1.1.4-optflags.patch
 Patch6:         %{name}-1.1.1-deepbind-939.patch
 BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 
-# upstream patches
-# lennart said this was upstreamed already.  :)
-Patch100:       http://0pointer.de/public/xine-pulse-rework2.patch
-Patch101:       %{name}-1.1.11.1-mkv.patch
-Patch102:       %{name}-1.1.11.1-qt.patch
-
 Provides:       xine-lib(plugin-abi) = %{abiver}
 # X11
 BuildRequires:  libX11-devel
@@ -183,10 +177,6 @@ touch -r m4/optimizations.m4.stamp m4/optimizations.m4
 # Patch6 needed at least when compiling with external ffmpeg, #939.
 %patch6 -p1 -b .deepbind
 
-%patch100 -p1 -b .pulse-rework2
-%patch101 -p1 -b .mkv
-%patch102 -p1 -b .qt
-
 # Avoid standard rpaths on lib64 archs:
 sed -i -e 's|"/lib /usr/lib\b|"/%{_lib} %{_libdir}|' configure
 
@@ -348,6 +338,7 @@ rm -rf $RPM_BUILD_ROOT
 %{_libdir}/xine/plugins/%{abiver}/xineplug_vo_out_fb.so
 %{_libdir}/xine/plugins/%{abiver}/xineplug_vo_out_none.so
 %{_libdir}/xine/plugins/%{abiver}/xineplug_vo_out_opengl.so
+%{_libdir}/xine/plugins/%{abiver}/xineplug_vo_out_raw.so
 %{_libdir}/xine/plugins/%{abiver}/xineplug_vo_out_syncfb.so
 %if %{have_vidix}
 %{_libdir}/xine/plugins/%{abiver}/xineplug_vo_out_vidix.so
@@ -398,15 +389,20 @@ rm -rf $RPM_BUILD_ROOT
 %defattr(-,root,root,-)
 %doc __docs/hackersguide/*
 %{_bindir}/xine-config
+%{_bindir}/xine-list*
 %{_datadir}/aclocal/xine.m4
 %{_includedir}/xine.h
 %{_includedir}/xine/
 %{_libdir}/libxine.so
 %{_libdir}/pkgconfig/libxine.pc
 %{_mandir}/man1/xine-config.1*
+%{_mandir}/man1/xine-list*.1*
 
 
 %changelog
+* Wed Apr 16 2008 Ville Skyttä <ville.skytta at iki.fi> - 1.1.12-1
+- 1.1.12 (plugin ABI 1.21); qt, mkv, and pulseaudio patches applied upstream.
+
 * Wed Apr  9 2008 Ville Skyttä <ville.skytta at iki.fi> - 1.1.11.1-3
 - Apply upstream fixes for Quicktime (#441705) and Matroska regressions
   introduced in 1.1.11.1.

diff --git a/xine-pulse-rework2.patch b/xine-pulse-rework2.patch
deleted file mode 100644
index 7f29efb..0000000
--- a/xine-pulse-rework2.patch
+++ /dev/null
@@ -1,1039 +0,0 @@
---- xine-lib-1.1.11.1/src/audio_out/audio_pulse_out.c	2008-03-28 15:24:49.000000000 +0100
-+++ xine-lib-1.1.11.1.lennart/src/audio_out/audio_pulse_out.c	2008-04-02 22:55:49.000000000 +0200
-@@ -1,28 +1,28 @@
--/* 
-- * Copyright (C) 2000-2007 the xine project
-- * 
-+/* -*- Mode: C; c-basic-offset: 2; indent-tabs-mode: nil -*- */
-+
-+/*
-+ * Copyright (C) 2000-2008 the xine project
-+ *
-  * This file is part of xine, a free video player.
-- * 
-+ *
-  * xine is free software; you can redistribute it and/or modify
-  * it under the terms of the GNU General Public License as published by
-  * the Free Software Foundation; either version 2 of the License, or
-  * (at your option) any later version.
-- * 
-+ *
-  * xine 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 General Public License for more details.
-- * 
-+ *
-  * You should have received a copy of the GNU General Public License
-  * along with this program; if not, write to the Free Software
-  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
-  *
-- * ao plugin for pulseaudio (rename of polypaudio):
-+ * ao plugin for PulseAudio:
-  * http://0pointer.de/lennart/projects/pulsaudio/
-  *
-- * originally written for polypaudio simple api. Lennart then suggested
-- * using the async api for better control (such as volume), therefore, a lot
-- * of this code comes from Lennart's patch to mplayer.
-+ * Diego Petteno, Lennart Poettering
-  */
- 
- #ifdef HAVE_CONFIG_H
-@@ -48,15 +48,9 @@
- 
- #define GAP_TOLERANCE        AO_MAX_GAP
- 
--/* CHECKME: should this be conditional on autotools? */
--extern const char *__progname;
--
- typedef struct {
-   audio_driver_class_t  driver_class;
-   xine_t                      *xine;
--
--  struct pa_context           *context;   /*< Pulseaudio connection context */
--  struct pa_threaded_mainloop *mainloop;  /*< Main event loop object */
- } pulse_class_t;
- 
- typedef struct pulse_driver_s {
-@@ -67,11 +61,13 @@ typedef struct pulse_driver_s {
- 
-   char             *host;    /*< The host to connect to */
-   char             *sink;    /*< The sink to connect to */
--  struct pa_stream *stream;  /*< Pulseaudio playback stream object */
- 
--  pthread_mutex_t   info_mutex; /**< Mutex for info callback signaling */
-+  pa_threaded_mainloop *mainloop;  /*< Main event loop object */
-+  pa_context *context;             /*< Pulseaudio connection context */
-+  pa_stream  *stream;              /*< Pulseaudio playback stream object */
- 
-   pa_volume_t       swvolume;
-+  int muted;
-   pa_cvolume        cvolume;
- 
-   int               capabilities;
-@@ -82,67 +78,117 @@ typedef struct pulse_driver_s {
-   uint32_t          bits_per_sample;
-   uint32_t          bytes_per_frame;
- 
--  uint32_t          frames_written;
--
- } pulse_driver_t;
- 
- 
- /**
-- * @brief Callback function called when a stream operation succeed
-- * @param stream Stream which operation has succeeded
-- * @param success The success value for the operation (ignored)
-- * @param this_Gen pulse_driver_t pointer for the PulseAudio output
-- *        instance.
-+ * @brief Callback function called when the state of the context is changed
-+ * @param c Context which changed status
-+ * @param this_gen pulse_class_t pointer for the PulseAudio output class
-  */
--static void __xine_pa_stream_success_callback(pa_stream *const stream, const int success,
--					      void *const mutex_gen)
-+static void __xine_pa_context_state_callback(pa_context *c, void *this_gen)
- {
--  pthread_mutex_t *const completion_mutex = (pthread_mutex_t*)mutex_gen;
-+  pulse_driver_t * this = (pulse_driver_t*) this_gen;
-+
-+  switch (pa_context_get_state(c)) {
-+
-+    case PA_CONTEXT_READY:
-+    case PA_CONTEXT_TERMINATED:
-+    case PA_CONTEXT_FAILED:
-+      pa_threaded_mainloop_signal(this->mainloop, 0);
-+      break;
- 
--  pthread_mutex_unlock(completion_mutex);
-+    case PA_CONTEXT_CONNECTING:
-+    case PA_CONTEXT_UNCONNECTED:
-+    case PA_CONTEXT_AUTHORIZING:
-+    case PA_CONTEXT_SETTING_NAME:
-+      break;
-+  }
- }
- 
- /**
-- * @brief Callback function called when the state of the context is changed
-- * @param ctx Context which operation has succeeded
-+ * @brief Callback function called when the state of the stream is changed
-+ * @param s Stream that changed status
-  * @param this_gen pulse_driver_t pointer for the PulseAudio output
-  *        instance.
-  */
--static void __xine_pa_context_status_callback(pa_context *const ctx, void *const this_gen)
-+static void __xine_pa_stream_state_callback(pa_stream *s, void *this_gen)
- {
--  pulse_driver_t *const this = (pulse_driver_t*)this_gen;
-+  pulse_driver_t * this = (pulse_driver_t*) this_gen;
-+
-+  switch (pa_stream_get_state(s)) {
-+
-+    case PA_STREAM_READY:
-+    case PA_STREAM_TERMINATED:
-+    case PA_STREAM_FAILED:
-+      pa_threaded_mainloop_signal(this->mainloop, 0);
-+      break;
- 
--  switch (pa_context_get_state(ctx)) {
--  case PA_CONTEXT_READY:
--  case PA_CONTEXT_TERMINATED:
--  case PA_CONTEXT_FAILED:
--    pa_threaded_mainloop_signal(this->pa_class->mainloop, 0);
--    break;
--
--  case PA_CONTEXT_CONNECTING:
--  case PA_CONTEXT_UNCONNECTED:
--  case PA_CONTEXT_AUTHORIZING:
--  case PA_CONTEXT_SETTING_NAME:
--    break;
-+    case PA_STREAM_UNCONNECTED:
-+    case PA_STREAM_CREATING:
-+      break;
-   }
- }
- 
- /**
-- * @brief Callback function called when a context operation succeed
-+ * @brief Callback function called when PA asks for more audio data.
-+ * @param s Stream on which data is requested
-+ * @param nbytes the number of bytes PA requested
-+ * @param this_gen pulse_driver_t pointer for the PulseAudio output
-+ *        instance.
-+ */
-+static void __xine_pa_stream_request_callback(pa_stream *s, size_t nbytes, void *this_gen)
-+{
-+  pulse_driver_t * this = (pulse_driver_t*) this_gen;
-+
-+  pa_threaded_mainloop_signal(this->mainloop, 0);
-+}
-+
-+/**
-+ * @brief Callback function called when PA notifies about something
-+ * @param s Stream on which the notification happened
-+ * @param this_gen pulse_driver_t pointer for the PulseAudio output
-+ *        instance.
-+ */
-+static void __xine_pa_stream_notify_callback(pa_stream *s, void *this_gen)
-+{
-+  pulse_driver_t * this = (pulse_driver_t*) this_gen;
-+
-+  pa_threaded_mainloop_signal(this->mainloop, 0);
-+}
-+
-+/**
-+ * @brief Callback function called when PA completed an operation
-  * @param ctx Context which operation has succeeded
-- * @param success The success value for the operation (ignored)
-+ * @param nbytes the number of bytes PA requested
-  * @param this_gen pulse_driver_t pointer for the PulseAudio output
-  *        instance.
-  */
--static void __xine_pa_context_success_callback(pa_context *const ctx, const int success,
--					      void *const this_gen)
-+static void __xine_pa_stream_success_callback(pa_stream *s, int success, void *this_gen)
- {
--  pulse_driver_t *const this = (pulse_driver_t*)this_gen;
-+  pulse_driver_t * this = (pulse_driver_t*) this_gen;
- 
--  _x_assert(ctx); _x_assert(this);
--  _x_assert(ctx == this->pa_class->context);
-+  if (!success)
-+    xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: stream operation failed: %s\n", pa_strerror(pa_context_errno(this->context)));
- 
--  pa_threaded_mainloop_signal(this->pa_class->mainloop, 0);
-+  pa_threaded_mainloop_signal(this->mainloop, 0);
-+}
-+
-+/**
-+ * @brief Callback function called when PA completed an operation
-+ * @param c Context on which operation has succeeded
-+ * @param nbytes the number of bytes PA requested
-+ * @param this_gen pulse_driver_t pointer for the PulseAudio output
-+ *        instance.
-+ */
-+static void __xine_pa_context_success_callback(pa_context *c, int success, void *this_gen)
-+{
-+  pulse_driver_t *this = (pulse_driver_t*) this_gen;
-+
-+  if (!success)
-+    xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: context operation failed: %s\n", pa_strerror(pa_context_errno(this->context)));
-+
-+  pa_threaded_mainloop_signal(this->mainloop, 0);
- }
- 
- /**
-@@ -156,14 +202,14 @@ static void __xine_pa_context_success_ca
-  * This function saves the volume field of the passed structure to the
-  * @c cvolume variable of the output instance.
-  */
--static void __xine_pa_sink_info_callback(pa_context *const ctx, const pa_sink_input_info *const info,
--					 const int is_last, void *const userdata) {
-+static void __xine_pa_sink_info_callback(pa_context *c, const pa_sink_input_info *info,
-+                                         int is_last, void *userdata) {
- 
-   pulse_driver_t *const this = (pulse_driver_t *) userdata;
- 
-   if (is_last < 0) {
-     xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: Failed to get sink input info: %s\n",
--             pa_strerror(pa_context_errno(this->pa_class->context)));
-+             pa_strerror(pa_context_errno(this->context)));
-     return;
-   }
- 
-@@ -171,36 +217,90 @@ static void __xine_pa_sink_info_callback
-       return;
- 
-   this->cvolume = info->volume;
-+  this->swvolume = pa_sw_volume_to_linear(pa_cvolume_avg(&info->volume));
-+  this->muted = info->mute;
-+}
-+
-+static int connect_context(pulse_driver_t *this) {
-+
-+  if (this->context && (pa_context_get_state(this->context) == PA_CONTEXT_FAILED ||
-+                        pa_context_get_state(this->context) == PA_CONTEXT_TERMINATED)) {
-+    pa_context_unref(this->context);
-+    this->context = NULL;
-+  }
-+
-+  if (!this->context) {
-+    char fn[PATH_MAX], *p;
-+
-+    if (pa_get_binary_name(fn, sizeof(fn)))
-+      p = pa_path_get_filename(fn);
-+    else
-+      p = "Xine";
- 
--  pthread_mutex_unlock(&this->info_mutex);
-+    this->context = pa_context_new(pa_threaded_mainloop_get_api(this->mainloop), p);
-+    _x_assert(this->context);
-+
-+    pa_context_set_state_callback(this->context, __xine_pa_context_state_callback, this);
-+  }
-+
-+  if (pa_context_get_state(this->context) == PA_CONTEXT_UNCONNECTED) {
-+
-+    if (pa_context_connect(this->context, this->host, 0, NULL) < 0) {
-+      xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: failed to connect context object %s\n", pa_strerror(pa_context_errno(this->context)));
-+      return -1;
-+    }
-+  }
-+
-+  for (;;) {
-+    pa_context_state_t state = pa_context_get_state(this->context);
-+
-+    if (state == PA_CONTEXT_FAILED || state == PA_CONTEXT_TERMINATED) {
-+      xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: failed to connect context object: %s\n", pa_strerror(pa_context_errno(this->context)));
-+      return -1;
-+    }
-+
-+    if (state == PA_CONTEXT_READY)
-+      break;
-+
-+    pa_threaded_mainloop_wait(this->mainloop);
-+  }
-+
-+  return 0;
- }
- 
- /*
-  * open the audio device for writing to
-  */
- static int ao_pulse_open(ao_driver_t *this_gen,
--		   uint32_t bits, uint32_t rate, int mode)
-+                         uint32_t bits, uint32_t rate, int mode)
- {
-   pulse_driver_t *this = (pulse_driver_t *) this_gen;
--  struct pa_sample_spec ss;
--  struct pa_buffer_attr a;
--  pa_stream_state_t streamstate;
-+  pa_sample_spec ss;
-+  pa_channel_map cm;
-+  int r;
- 
-   xprintf (this->xine, XINE_VERBOSITY_DEBUG,
--	   "audio_pulse_out: ao_open bits=%d rate=%d, mode=%d\n", bits, rate, mode);
-+           "audio_pulse_out: ao_open bits=%d rate=%d, mode=%d\n", bits, rate, mode);
- 
-   if ( (mode & this->capabilities) == 0 ) {
-     xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: unsupported mode %08x\n", mode);
-     return 0;
-   }
- 
-+  pa_threaded_mainloop_lock(this->mainloop);
-+
-   if (this->stream) {
- 
--    if ( mode == this->mode && rate == this->sample_rate &&
--         bits == this->bits_per_sample )
-+    if (mode == this->mode && rate == this->sample_rate &&
-+        bits == this->bits_per_sample) {
-+
-+      pa_threaded_mainloop_unlock(this->mainloop);
-       return this->sample_rate;
-+    }
- 
--    this_gen->close(this_gen);
-+    pa_stream_disconnect(this->stream);
-+    pa_stream_unref(this->stream);
-+    this->stream = NULL;
-   }
- 
-   this->mode                   = mode;
-@@ -221,6 +321,8 @@ static int ao_pulse_open(ao_driver_t *th
-     case 32:
-       ss.format = PA_SAMPLE_FLOAT32NE;
-       break;
-+    default:
-+      _x_assert(!"Should not be reached");
-   }
- 
-   if (!pa_sample_spec_valid(&ss)) {
-@@ -228,70 +330,86 @@ static int ao_pulse_open(ao_driver_t *th
-     goto fail;
-   }
- 
--  if ( this->pa_class->context && pa_context_get_state(this->pa_class->context) > PA_CONTEXT_READY ) {
--    pa_context_unref(this->pa_class->context);
--    this->pa_class->context = NULL;
--  }
--
--  if ( this->pa_class->context == NULL ) {
--    this->pa_class->context = pa_context_new(pa_threaded_mainloop_get_api(this->pa_class->mainloop),
--					     __progname);
--  }
--
--  pa_context_ref(this->pa_class->context);
-+  cm.channels = ss.channels;
- 
--  if ( pa_context_get_state(this->pa_class->context) == PA_CONTEXT_UNCONNECTED ) {
--    int ret;
-+  switch (mode) {
-+    case AO_CAP_MODE_MONO:
-+      cm.map[0] = PA_CHANNEL_POSITION_MONO;
-+      _x_assert(cm.channels == 1);
-+      break;
- 
--    pa_threaded_mainloop_lock(this->pa_class->mainloop);
--    ret = pa_context_connect(this->pa_class->context, this->host, 1, NULL);
--    if ( ret < 0 )
--      goto fail_unlock;
-+    case AO_CAP_MODE_STEREO:
-+      cm.map[0] = PA_CHANNEL_POSITION_FRONT_LEFT;
-+      cm.map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT;
-+      _x_assert(cm.channels == 2);
-+      break;
- 
--    pa_context_set_state_callback(this->pa_class->context, __xine_pa_context_status_callback, this);
-+    case AO_CAP_MODE_4CHANNEL:
-+      cm.map[0] = PA_CHANNEL_POSITION_FRONT_LEFT;
-+      cm.map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT;
-+      cm.map[2] = PA_CHANNEL_POSITION_REAR_LEFT;
-+      cm.map[3] = PA_CHANNEL_POSITION_REAR_RIGHT;
-+      _x_assert(cm.channels == 4);
-+      break;
- 
--    pa_threaded_mainloop_wait(this->pa_class->mainloop);
--    pa_threaded_mainloop_unlock(this->pa_class->mainloop);
-+    case AO_CAP_MODE_4_1CHANNEL:
-+    case AO_CAP_MODE_5CHANNEL:
-+    case AO_CAP_MODE_5_1CHANNEL:
-+      cm.map[0] = PA_CHANNEL_POSITION_FRONT_LEFT;
-+      cm.map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT;
-+      cm.map[2] = PA_CHANNEL_POSITION_REAR_LEFT;
-+      cm.map[3] = PA_CHANNEL_POSITION_REAR_RIGHT;
-+      cm.map[4] = PA_CHANNEL_POSITION_FRONT_CENTER;
-+      cm.map[5] = PA_CHANNEL_POSITION_LFE;
-+      cm.channels = 6;
-+      break;
-+    default:
-+      _x_assert(!"Should not be reached");
-   }
- 
--  if (pa_context_get_state(this->pa_class->context) != PA_CONTEXT_READY) {
--    xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: Failed to connect to server: %s\n",
--	     pa_strerror(pa_context_errno(this->pa_class->context)));
-+  if (!pa_channel_map_valid(&cm)) {
-+    xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: Invalid channel map\n");
-     goto fail;
-   }
- 
--  this->stream = pa_stream_new(this->pa_class->context, "audio stream", &ss, NULL);
-+  if (connect_context(this) < 0)
-+    goto fail;
-+
-+  _x_assert(!this->stream);
-+  this->stream = pa_stream_new(this->context, "Audio Stream", &ss, &cm);
-   _x_assert(this->stream);
- 
--  a.maxlength = pa_bytes_per_second(&ss)*1;
--  a.tlength = a.maxlength*9/10;
--  a.prebuf = a.tlength/2;
--  a.minreq = a.tlength/10;
-+  pa_stream_set_state_callback(this->stream, __xine_pa_stream_state_callback, this);
-+  pa_stream_set_write_callback(this->stream, __xine_pa_stream_request_callback, this);
-+  pa_stream_set_latency_update_callback(this->stream, __xine_pa_stream_notify_callback, this);
- 
--  pa_stream_connect_playback(this->stream, this->sink, &a,
--                             PA_STREAM_INTERPOLATE_TIMING|PA_STREAM_AUTO_TIMING_UPDATE, 
-+  r = pa_stream_connect_playback(this->stream, this->sink, NULL,
-+                             PA_STREAM_INTERPOLATE_TIMING|PA_STREAM_AUTO_TIMING_UPDATE,
-                              NULL, NULL);
- 
--  do {
--    xine_usec_sleep (100);
-+  for (;;) {
-+    pa_context_state_t cstate = pa_context_get_state(this->context);
-+    pa_stream_state_t sstate = pa_stream_get_state(this->stream);
-+
-+    if (cstate == PA_CONTEXT_FAILED || cstate == PA_CONTEXT_TERMINATED ||
-+        sstate == PA_STREAM_FAILED || sstate == PA_STREAM_TERMINATED) {
-+      xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: failed to connect context object: %s\n", pa_strerror(pa_context_errno(this->context)));
-+      goto fail;
-+    }
- 
--    streamstate = pa_stream_get_state(this->stream);
--  } while (streamstate < PA_STREAM_READY);
--     
--  if (streamstate != PA_STREAM_READY) {
--    xprintf (this->xine, XINE_VERBOSITY_LOG, "audio_pulse_out: Failed to connect to server: %s\n",
--             pa_strerror(pa_context_errno(this->pa_class->context)));
--    goto fail;
-+    if (sstate == PA_STREAM_READY)
-+      break;
-+
-+    pa_threaded_mainloop_wait(this->mainloop);
-   }
--  this->frames_written = 0;
- 
--  this->ao_driver.set_property(this, AO_PROP_PCM_VOL, 100);
-+  pa_threaded_mainloop_unlock(this->mainloop);
- 
-   return this->sample_rate;
- 
-- fail_unlock:
--  pa_threaded_mainloop_unlock(this->pa_class->mainloop);
-  fail:
-+
-+  pa_threaded_mainloop_unlock(this->mainloop);
-   this_gen->close(this_gen);
-   return 0;
- }
-@@ -319,217 +437,348 @@ static int ao_pulse_write(ao_driver_t *t
- {
-   pulse_driver_t *this = (pulse_driver_t *) this_gen;
-   size_t size = num_frames * this->bytes_per_frame;
--  int ret = 0;
--  
--  if ( !this->stream || !this->pa_class->context)
--    return -1;
--
--  switch( pa_stream_get_state(this->stream) ) {
--  case PA_STREAM_READY:
--    while (size > 0) {
--      size_t l;
-+  int ret = -1;
-+  size_t done = 0;
- 
--      while (!(l = pa_stream_writable_size(this->stream))) {
--        xine_usec_sleep (10000);
--      }
-+  pa_threaded_mainloop_lock(this->mainloop);
- 
--      if (l > size)
--        l = size;
--        
--      pa_stream_write(this->stream, data, l, NULL, 0, PA_SEEK_RELATIVE);
--      data = (int16_t *) ((uint8_t*) data + l);
--      size -= l;
--    }
-+  while (size > 0) {
-+    size_t l;
- 
--    this->frames_written += num_frames;
-+    for (;;) {
- 
--    if (pa_stream_get_state(this->stream) == PA_STREAM_READY)
--      ret = 1;
-+      if (!this->stream ||
-+          !this->context ||
-+          pa_context_get_state(this->context) != PA_CONTEXT_READY ||
-+          pa_stream_get_state(this->stream) != PA_STREAM_READY)
-+        goto finish;
- 
--    break;
-+      if ((l = pa_stream_writable_size(this->stream)) == (size_t) -1)
-+        goto finish;
-+
-+      if (l > 0)
-+        break;
-+
-+      pa_threaded_mainloop_wait(this->mainloop);
-+    }
-+
-+    if (l > size)
-+      l = size;
-+
-+    pa_stream_write(this->stream, data, l, NULL, 0, PA_SEEK_RELATIVE);
-+    data = (int16_t *) ((uint8_t*) data + l);
-+    size -= l;
-+    done += l;
-   }
- 
-+  ret = done;
-+
-+finish:
-+
-+  pa_threaded_mainloop_unlock(this->mainloop);
-+
-+/*   fprintf(stderr, "write-out\n"); */
-+
-   return ret;
--}
- 
-+}
- 
- static int ao_pulse_delay (ao_driver_t *this_gen)
- {
-   pulse_driver_t *this = (pulse_driver_t *) this_gen;
--  pa_usec_t latency = 0;
--  unsigned int delay_frames;
-+  int ret = 0;
- 
--  if ( ! this->stream ) return this->frames_written;
-+/*   fprintf(stderr, "delay-in\n"); */
- 
--  if (pa_stream_get_latency(this->stream, &latency, NULL) < 0) {
--    pa_context_unref(this->pa_class->context);
--    this->pa_class->context = NULL;
-+  pa_threaded_mainloop_lock(this->mainloop);
- 
--    pa_stream_disconnect(this->stream);
--    pa_stream_unref(this->stream);
--    this->stream = NULL;
-+  for (;;) {
-+    pa_usec_t latency = 0;
- 
--    return 0;
-+    if (!this->stream ||
-+        !this->context ||
-+        pa_context_get_state(this->context) != PA_CONTEXT_READY ||
-+        pa_stream_get_state(this->stream) != PA_STREAM_READY)
-+      goto finish;
-+
-+    if (pa_stream_get_latency(this->stream, &latency, NULL) >= 0) {
-+      ret = (int) ((latency * this->sample_rate) / 1000000);
-+      goto finish;
-+    }
-+
-+    if (pa_context_errno(this->context) != PA_ERR_NODATA) {
-+      xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: failed to query latency: %s\n", pa_strerror(pa_context_errno(this->context)));
-+      goto finish;
-+    }
-+
-+    pa_threaded_mainloop_wait(this->mainloop);
-   }
- 
--  /* convert latency (us) to frame units. */
--  delay_frames = (int)(latency * this->sample_rate / 1000000);
-+finish:
- 
--  if( delay_frames > this->frames_written )
--    return this->frames_written;
--  else
--    return delay_frames;
-+  pa_threaded_mainloop_unlock(this->mainloop);
-+
-+  return ret;
- }
- 
- static void ao_pulse_close(ao_driver_t *this_gen)
- {
-   pulse_driver_t *this = (pulse_driver_t *) this_gen;
--  
--  if (this->stream) {
--    if (pa_stream_get_state(this->stream) == PA_STREAM_READY) {
--      pthread_mutex_t completion_callback = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_lock(&completion_callback);
--      pa_stream_drain(this->stream, __xine_pa_stream_success_callback, &completion_callback);
- 
--      pthread_mutex_lock(&completion_callback);
--      pthread_mutex_destroy(&completion_callback);
--    }
-+  pa_threaded_mainloop_lock(this->mainloop);
- 
-+  if (this->stream) {
-     pa_stream_disconnect(this->stream);
-     pa_stream_unref(this->stream);
-     this->stream = NULL;
--
--    pa_context_unref(this->pa_class->context);
-   }
-+
-+  pa_threaded_mainloop_unlock(this->mainloop);
- }
- 
- static uint32_t ao_pulse_get_capabilities (ao_driver_t *this_gen) {
-   pulse_driver_t *this = (pulse_driver_t *) this_gen;
-+
-   return this->capabilities;
- }
- 
--static void ao_pulse_exit(ao_driver_t *this_gen)
--{
-+static void ao_pulse_exit(ao_driver_t *this_gen) {
-   pulse_driver_t *this = (pulse_driver_t *) this_gen;
- 
--  free (this);
-+  ao_pulse_close(this_gen);
-+
-+  pa_threaded_mainloop_lock(this->mainloop);
-+
-+  if (this->context) {
-+    pa_context_disconnect(this->context);
-+    pa_context_unref(this->context);
-+  }
-+
-+  pa_threaded_mainloop_unlock(this->mainloop);
-+
-+  pa_threaded_mainloop_free(this->mainloop);
-+
-+  free(this->host);
-+  free(this->sink);
-+  free(this);
-+}
-+
-+static int wait_for_operation(pulse_driver_t *this, pa_operation *o) {
-+
-+  for (;;) {
-+
-+    if (!this->stream ||
-+        !this->context ||
-+        pa_context_get_state(this->context) != PA_CONTEXT_READY ||
-+        pa_stream_get_state(this->stream) != PA_STREAM_READY)
-+      return -1;
-+
-+    if (pa_operation_get_state(o) != PA_OPERATION_RUNNING)
-+      return 0;
-+
-+    pa_threaded_mainloop_wait(this->mainloop);
-+  }
- }
- 
- static int ao_pulse_get_property (ao_driver_t *this_gen, int property) {
-   pulse_driver_t *this = (pulse_driver_t *) this_gen;
-   int result = 0;
-+  pa_operation *o = NULL;
- 
--  if ( ! this->stream || ! this->pa_class->context )
-+  pa_threaded_mainloop_lock(this->mainloop);
-+
-+  if (!this->stream ||
-+      !this->context ||
-+      pa_context_get_state(this->context) != PA_CONTEXT_READY ||
-+      pa_stream_get_state(this->stream) != PA_STREAM_READY) {
-+    pa_threaded_mainloop_unlock(this->mainloop);
-     return 0;
-+  }
- 
-   switch(property) {
--  case AO_PROP_PCM_VOL:
--  case AO_PROP_MIXER_VOL:
--    {
--      pthread_mutex_lock(&this->info_mutex);
--      pa_operation *o = pa_context_get_sink_input_info(this->pa_class->context,
--						       pa_stream_get_index(this->stream),
--						       __xine_pa_sink_info_callback, this);
--      if ( ! o ) return 0;
--      pthread_mutex_lock(&this->info_mutex); pthread_mutex_unlock(&this->info_mutex);
--			 
--      result = (pa_sw_volume_to_linear(this->swvolume)*100);
--    }
--    break;
- 
--  case AO_PROP_MUTE_VOL:
--    result = pa_cvolume_is_muted(&this->cvolume);
--    break;
-+    case AO_PROP_MUTE_VOL:
-+    case AO_PROP_PCM_VOL:
-+    case AO_PROP_MIXER_VOL:
-+
-+      o = pa_context_get_sink_input_info(this->context, pa_stream_get_index(this->stream),
-+                                         __xine_pa_sink_info_callback, this);
-+
-+      break;
-+  }
-+
-+  if (o) {
-+    wait_for_operation(this, o);
-+    pa_operation_unref(o);
-   }
--  
-+
-+  switch(property) {
-+
-+    case AO_PROP_MUTE_VOL:
-+      result = this->muted;
-+      break;
-+
-+    case AO_PROP_PCM_VOL:
-+    case AO_PROP_MIXER_VOL:
-+      result = (int) (pa_sw_volume_to_linear(this->swvolume)*100);
-+      break;
-+  }
-+
-+  pa_threaded_mainloop_unlock(this->mainloop);
-+
-   return result;
- }
- 
- static int ao_pulse_set_property (ao_driver_t *this_gen, int property, int value) {
-   pulse_driver_t *this = (pulse_driver_t *) this_gen;
-   int result = ~value;
-+  pa_operation *o = NULL;
- 
--  if ( ! this->stream || ! this->pa_class->context )
--    return result;
-+  pa_threaded_mainloop_lock(this->mainloop);
-+
-+  if (!this->stream ||
-+      !this->context ||
-+      pa_context_get_state(this->context) != PA_CONTEXT_READY ||
-+      pa_stream_get_state(this->stream) != PA_STREAM_READY) {
-+    pa_threaded_mainloop_unlock(this->mainloop);
-+    return 0;
-+  }
- 
-   switch(property) {
--  case AO_PROP_PCM_VOL:
--  case AO_PROP_MIXER_VOL:
--    this->swvolume = pa_sw_volume_from_linear((double)value/100.0);
--    pa_cvolume_set(&this->cvolume, pa_stream_get_sample_spec(this->stream)->channels, this->swvolume);
--
--    pa_context_set_sink_input_volume(this->pa_class->context, pa_stream_get_index(this->stream),
--				     &this->cvolume, __xine_pa_context_success_callback, this);
--
--    result = value;
--    break;
--
--  case AO_PROP_MUTE_VOL:
--    if ( value )
--      pa_cvolume_mute(&this->cvolume, pa_stream_get_sample_spec(this->stream)->channels);
--    else
-+    case AO_PROP_PCM_VOL:
-+    case AO_PROP_MIXER_VOL:
-+
-+      this->swvolume = pa_sw_volume_from_linear((double)value/100.0);
-       pa_cvolume_set(&this->cvolume, pa_stream_get_sample_spec(this->stream)->channels, this->swvolume);
- 
--    pa_context_set_sink_input_volume(this->pa_class->context, pa_stream_get_index(this->stream),
--				     &this->cvolume, __xine_pa_context_success_callback, this);
--    
--    result = value;
--    break;
-+      o = pa_context_set_sink_input_volume(this->context, pa_stream_get_index(this->stream),
-+                                           &this->cvolume, __xine_pa_context_success_callback, this);
-+
-+      result = value;
-+      break;
-+
-+    case AO_PROP_MUTE_VOL:
-+
-+      this->muted = value;
-+
-+      o = pa_context_set_sink_input_mute(this->context, pa_stream_get_index(this->stream),
-+                                           value, __xine_pa_context_success_callback, this);
-+
-+      result = value;
-+  }
-+
-+  if (o) {
-+    wait_for_operation(this, o);
-+    pa_operation_unref(o);
-   }
--  
-+
-+  pa_threaded_mainloop_unlock(this->mainloop);
-+
-   return result;
- }
- 
- static int ao_pulse_ctrl(ao_driver_t *this_gen, int cmd, ...) {
-   pulse_driver_t *this = (pulse_driver_t *) this_gen;
-+  pa_operation *o = NULL;
-+
-+  pa_threaded_mainloop_lock(this->mainloop);
- 
--  if ( ! this->stream ) return 0;
-+  if (!this->stream ||
-+      !this->context ||
-+      pa_context_get_state(this->context) != PA_CONTEXT_READY ||
-+      pa_stream_get_state(this->stream) != PA_STREAM_READY) {
-+    pa_threaded_mainloop_unlock(this->mainloop);
-+    return 0;
-+  }
- 
-   switch (cmd) {
- 
--  case AO_CTRL_FLUSH_BUFFERS:
--    _x_assert(this->stream && this->pa_class->context);
-+    case AO_CTRL_FLUSH_BUFFERS:
- 
--    if(pa_stream_get_state(this->stream) == PA_STREAM_READY) {
--      pthread_mutex_t completion_callback = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_lock(&completion_callback);
--      pa_stream_flush(this->stream, __xine_pa_stream_success_callback, &completion_callback);
-+      o = pa_stream_flush(this->stream, __xine_pa_stream_success_callback, this);
-+      break;
- 
--      pthread_mutex_lock(&completion_callback);
--      pthread_mutex_destroy(&completion_callback);
--    }
-+    case AO_CTRL_PLAY_RESUME:
-+    case AO_CTRL_PLAY_PAUSE:
- 
--    this->frames_written = 0;
-+      o = pa_stream_cork(this->stream, cmd == AO_CTRL_PLAY_PAUSE, __xine_pa_stream_success_callback, this);
-+      break;
-+  }
- 
--    break;
-+  if (o) {
-+    wait_for_operation(this, o);
-+    pa_operation_unref(o);
-   }
- 
-+  pa_threaded_mainloop_unlock(this->mainloop);
-+
-   return 0;
- }
- 
- static ao_driver_t *open_plugin (audio_driver_class_t *class_gen, const void *data) {
-   pulse_class_t   *class = (pulse_class_t *) class_gen;
-   pulse_driver_t  *this;
--  char *device;
-+  const char* device;
-+  int r;
- 
-   lprintf ("audio_pulse_out: open_plugin called\n");
- 
-   this = (pulse_driver_t *) xine_xmalloc (sizeof (pulse_driver_t));
-   if (!this)
-     return NULL;
-+
-   this->xine = class->xine;
-+  this->host = NULL;
-+  this->sink = NULL;
-+  this->context = NULL;
-+  this->mainloop = NULL;
-+
-+  device = class->xine->config->register_string(class->xine->config,
-+                                         "audio.pulseaudio_device",
-+                                         "",
-+                                         _("device used for pulseaudio"),
-+                                         _("use 'server[:sink]' for setting the "
-+                                           "pulseaudio sink device."),
-+                                         10, NULL,
-+                                         NULL);
-+
-+  if (device && *device) {
-+    char *sep = strrchr(device, ':');
-+    if ( sep ) {
-+      if (!(this->host = strndup(device, sep-device))) {
-+        free(this);
-+        return NULL;
-+      }
-+
-+      if (!(this->sink = strdup(sep+1))) {
-+        free(this->host);
-+        free(this);
-+        return NULL;
-+      }
-+    } else {
-+
-+      if (!(this->host = strdup(device))) {
-+        free(this);
-+        return NULL;
-+      }
-+    }
-+  }
-+
-+  this->mainloop = pa_threaded_mainloop_new();
-+  _x_assert(this->mainloop);
-+  pa_threaded_mainloop_start(this->mainloop);
- 
-   /*
-    * set capabilities
-    */
--  this->capabilities = AO_CAP_MODE_MONO | AO_CAP_MODE_STEREO | AO_CAP_MODE_4CHANNEL |
--                       AO_CAP_MODE_4_1CHANNEL | AO_CAP_MODE_5CHANNEL |
--                       AO_CAP_MODE_5_1CHANNEL | AO_CAP_MIXER_VOL |
--                       AO_CAP_PCM_VOL | AO_CAP_MUTE_VOL | AO_CAP_8BITS |
--                       AO_CAP_16BITS | AO_CAP_FLOAT32;
-+  this->capabilities =
-+    AO_CAP_MODE_MONO | AO_CAP_MODE_STEREO | AO_CAP_MODE_4CHANNEL |
-+    AO_CAP_MODE_4_1CHANNEL | AO_CAP_MODE_5CHANNEL | AO_CAP_MODE_5_1CHANNEL |
-+    AO_CAP_MIXER_VOL | AO_CAP_PCM_VOL | AO_CAP_MUTE_VOL |
-+    AO_CAP_8BITS | AO_CAP_16BITS | AO_CAP_FLOAT32;
- 
-   this->sample_rate  = 0;
--  this->host         = NULL;
--  this->sink         = NULL;
--  
-+
-   this->ao_driver.get_capabilities    = ao_pulse_get_capabilities;
-   this->ao_driver.get_property        = ao_pulse_get_property;
-   this->ao_driver.set_property        = ao_pulse_set_property;
-@@ -541,33 +790,22 @@ static ao_driver_t *open_plugin (audio_d
-   this->ao_driver.close               = ao_pulse_close;
-   this->ao_driver.exit                = ao_pulse_exit;
-   this->ao_driver.get_gap_tolerance   = ao_pulse_get_gap_tolerance;
--  this->ao_driver.control	      = ao_pulse_ctrl;
--
--  device = this->xine->config->register_string(this->xine->config,
--                                               "audio.pulseaudio_device",
--                                               "",
--                                               _("device used for pulseaudio"),
--                                               _("use 'server[:sink]' for setting the "
--                                                 "pulseaudio sink device."),
--                                               10, NULL,
--                                               NULL);
--
--  if (device && *device) {
--    char *sep = strchr(device, ':');
--    if ( sep ) {
--      this->host = strndup(device, sep-device);
--      this->sink = strdup(&sep[1]);
--    } else
--      this->host = strdup(device);
--  }
--
--  pthread_mutex_init(&this->info_mutex, NULL);
-+  this->ao_driver.control             = ao_pulse_ctrl;
- 
-   xprintf (class->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: host %s sink %s\n",
-            this->host ? this->host : "(null)", this->sink ? this->sink : "(null)");
- 
-   this->pa_class = class;
- 
-+  pa_threaded_mainloop_lock(this->mainloop);
-+  r = connect_context(this);
-+  pa_threaded_mainloop_unlock(this->mainloop);
-+
-+  if (r < 0) {
-+    ao_pulse_exit((ao_driver_t *) this);
-+    return NULL;
-+  }
-+
-   return &this->ao_driver;
- }
- 
-@@ -587,13 +825,7 @@ static void dispose_class (audio_driver_
- 
-   pulse_class_t *this = (pulse_class_t *) this_gen;
- 
--  if ( this->context )
--    pa_context_unref(this->context);
--
--  pa_threaded_mainloop_stop(this->mainloop);
--  pa_threaded_mainloop_free(this->mainloop);
--
--  free (this);
-+  free(this);
- }
- 
- static void *init_class (xine_t *xine, void *data) {
-@@ -606,25 +838,17 @@ static void *init_class (xine_t *xine, v
-   if (!this)
-     return NULL;
- 
-+  this->xine = xine;
-   this->driver_class.open_plugin     = open_plugin;
-   this->driver_class.get_identifier  = get_identifier;
-   this->driver_class.get_description = get_description;
-   this->driver_class.dispose         = dispose_class;
- 
--  this->xine                         = xine;
--
--  this->mainloop = pa_threaded_mainloop_new();
--  _x_assert(this->mainloop);
--
--  pa_threaded_mainloop_start(this->mainloop);
--  
--  this->context = NULL;
--
-   return this;
- }
- 
- static const ao_info_t ao_info_pulse = {
--  6
-+  12
- };
- 
- /*
-@@ -636,5 +860,3 @@ const plugin_info_t xine_plugin_info[] E
-   { PLUGIN_AUDIO_OUT, 8, "pulseaudio", XINE_VERSION_CODE, &ao_info_pulse, init_class },
-   { PLUGIN_NONE, 0, "", 0, NULL, NULL }
- };
--
--

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2026-07-20 20:00 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-07-20 20:00 [rpms/xine-lib] epel9-next: * Wed Apr 16 2008 Ville Skyttä <ville.skytta at iki.fi> - 1.1.12-1 

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox