Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 22 Jul 2018 04:16:38 +0000 (UTC)
From:      Tobias Kortkamp <tobik@FreeBSD.org>
To:        ports-committers@freebsd.org, svn-ports-all@freebsd.org, svn-ports-head@freebsd.org
Subject:   svn commit: r475084 - in head/www/qt5-webengine: . files
Message-ID:  <201807220416.w6M4GcSr064977@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: tobik
Date: Sun Jul 22 04:16:38 2018
New Revision: 475084
URL: https://svnweb.freebsd.org/changeset/ports/475084

Log:
  www/qt5-webengine: Add sndio support
  
  While here fix ALSA and PULSEAUDIO options
  - With alsa-lib installed in the build environment ALSA=off did not
    previously disable ALSA support
  - PulseAudio support was always disabled regardless of option state
  
  Approved by:		kde (tcberner)
  Differential Revision:	https://reviews.freebsd.org/D16383

Added:
  head/www/qt5-webengine/files/audio_manager_openbsd.cc
     - copied, changed from r474875, head/www/iridium/files/audio_manager_openbsd.cc
  head/www/qt5-webengine/files/audio_manager_openbsd.h
     - copied, changed from r474875, head/www/iridium/files/audio_manager_openbsd.h
  head/www/qt5-webengine/files/patch-configure.json   (contents, props changed)
  head/www/qt5-webengine/files/patch-src_3rdparty_chromium_media_BUILD.gn   (contents, props changed)
  head/www/qt5-webengine/files/patch-src_3rdparty_chromium_media_media__options.gni   (contents, props changed)
  head/www/qt5-webengine/files/patch-src_core_config_linux.pri   (contents, props changed)
  head/www/qt5-webengine/files/sndio_input.cc
     - copied unchanged from r474875, head/www/iridium/files/sndio_input.cc
  head/www/qt5-webengine/files/sndio_input.h
     - copied unchanged from r474875, head/www/iridium/files/sndio_input.h
  head/www/qt5-webengine/files/sndio_output.cc
     - copied unchanged from r474875, head/www/iridium/files/sndio_output.cc
  head/www/qt5-webengine/files/sndio_output.h
     - copied unchanged from r474875, head/www/iridium/files/sndio_output.h
Modified:
  head/www/qt5-webengine/Makefile
  head/www/qt5-webengine/files/freebsd.pri
  head/www/qt5-webengine/files/patch-src_3rdparty_chromium_media_audio_BUILD.gn

Modified: head/www/qt5-webengine/Makefile
==============================================================================
--- head/www/qt5-webengine/Makefile	Sun Jul 22 03:22:52 2018	(r475083)
+++ head/www/qt5-webengine/Makefile	Sun Jul 22 04:16:38 2018	(r475084)
@@ -52,15 +52,20 @@ DISTINFO_FILE=	${.CURDIR}/distinfo
 QT5_VERSION=	5.9.5
 
 OPTIONS_SINGLE=		AUDIO
-OPTIONS_SINGLE_AUDIO=	ALSA PULSEAUDIO
+OPTIONS_SINGLE_AUDIO=	ALSA PULSEAUDIO SNDIO
 OPTIONS_DEFAULT=	ALSA
 
 AUDIO_DESC=		Audio backend
 
 ALSA_LIB_DEPENDS=	libasound.so:audio/alsa-lib
-ALSA_QMAKE_ON=		QT_CONFIG+=alsa
+ALSA_VARS=		QMAKE_CONFIGURE_ARGS+=-alsa
+ALSA_VARS_OFF=		QMAKE_CONFIGURE_ARGS+=-no-alsa
 PULSEAUDIO_LIB_DEPENDS=	libpulse.so:audio/pulseaudio
-PULSEAUDIO_QMAKE_ON=	QT_CONFIG+=pulseaudio
+PULSEAUDIO_VARS=	QMAKE_CONFIGURE_ARGS+=-pulseaudio
+PULSEAUDIO_VARS_OFF=	QMAKE_CONFIGURE_ARGS+=-no-pulseaudio
+SNDIO_LIB_DEPENDS=	libsndio.so:audio/sndio
+SNDIO_VARS=		QMAKE_CONFIGURE_ARGS+=-sndio
+SNDIO_VARS_OFF=		QMAKE_CONFIGURE_ARGS+=-no-sndio
 
 # We pass `norecursive' to USES=qmake because src/plugins/plugins.pro checks
 # whether webenginewidgets is available, which fails when qmake processes all
@@ -120,6 +125,13 @@ MAKE_ENV+=	CC="${CC}" CXX="${CXX}"			\
 post-extract:
 # Install FreeBSD's freebsd.pri file.
 	${CP} ${FILESDIR}/freebsd.pri ${WRKSRC}/src/core/config/freebsd.pri
+
+post-extract-SNDIO-on:
+	@cd ${WRKSRC}/src/3rdparty/chromium/media/audio && ${MKDIR} sndio openbsd
+	@${CP} ${FILESDIR}/sndio_*put.* \
+		${WRKSRC}/src/3rdparty/chromium/media/audio/sndio
+	@${CP} ${FILESDIR}/audio_manager_openbsd.* \
+		${WRKSRC}/src/3rdparty/chromium/media/audio/openbsd
 
 pre-configure:
 # Link in ${PYTHON_CMD} to ${CONFIGURE_WRKSRC}/bin -- the scripts hardcode 'python'

Copied and modified: head/www/qt5-webengine/files/audio_manager_openbsd.cc (from r474875, head/www/iridium/files/audio_manager_openbsd.cc)
==============================================================================
--- head/www/iridium/files/audio_manager_openbsd.cc	Wed Jul 18 15:52:26 2018	(r474875, copy source)
+++ head/www/qt5-webengine/files/audio_manager_openbsd.cc	Sun Jul 22 04:16:38 2018	(r475084)
@@ -63,12 +63,6 @@ void AudioManagerOpenBSD::GetAudioOutputDeviceNames(
   AddDefaultDevice(device_names);
 }
 
-#if defined(USE_SNDIO)
-const char* AudioManagerOpenBSD::GetName() {
-  return "SNDIO";
-}
-#endif
-
 AudioParameters AudioManagerOpenBSD::GetInputStreamParameters(
     const std::string& device_id) {
   static const int kDefaultInputBufferSize = 1024;

Copied and modified: head/www/qt5-webengine/files/audio_manager_openbsd.h (from r474875, head/www/iridium/files/audio_manager_openbsd.h)
==============================================================================
--- head/www/iridium/files/audio_manager_openbsd.h	Wed Jul 18 15:52:26 2018	(r474875, copy source)
+++ head/www/qt5-webengine/files/audio_manager_openbsd.h	Sun Jul 22 04:16:38 2018	(r475084)
@@ -30,7 +30,6 @@ class MEDIA_EXPORT AudioManagerOpenBSD : public AudioM
   void GetAudioOutputDeviceNames(AudioDeviceNames* device_names) override;
   AudioParameters GetInputStreamParameters(
       const std::string& device_id) override;
-  const char* GetName() override;
 
   // Implementation of AudioManagerBase.
   AudioOutputStream* MakeLinearOutputStream(

Modified: head/www/qt5-webengine/files/freebsd.pri
==============================================================================
--- head/www/qt5-webengine/files/freebsd.pri	Sun Jul 22 03:22:52 2018	(r475083)
+++ head/www/qt5-webengine/files/freebsd.pri	Sun Jul 22 04:16:38 2018	(r475084)
@@ -4,8 +4,7 @@ gn_args +=   disable_nacl=true           \
              enable_basic_printing=false \
              enable_webrtc=false         \
              enable_hidpi=true           \
-             use_dbus=true               \
-             use_pulseaudio=false
+             use_dbus=true
 
 # Once the port works better, we can think about readding the diverse `use_system_<foo>`
 # for bundled libraries.

Added: head/www/qt5-webengine/files/patch-configure.json
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/www/qt5-webengine/files/patch-configure.json	Sun Jul 22 04:16:38 2018	(r475084)
@@ -0,0 +1,33 @@
+--- configure.json.orig	2018-04-10 14:50:39 UTC
++++ configure.json
+@@ -16,6 +16,7 @@
+             "printing-and-pdf": "boolean",
+             "proprietary-codecs": "boolean",
+             "pulseaudio": "boolean",
++            "sndio": "boolean",
+             "spellchecker": "boolean",
+             "webrtc": "boolean"
+         }
+@@ -113,6 +114,10 @@
+             "condition": "libs.pulseaudio",
+             "output": [ "privateFeature" ]
+         },
++        "sndio": {
++            "label": "sndio",
++            "output": [ "privateFeature" ]
++        },
+         "pepper-plugins": {
+             "label": "Pepper Plugins",
+             "purpose": "Enables use of Pepper Flash and Widevine plugins.",
+@@ -218,6 +223,11 @@
+                 {
+                     "type": "feature",
+                     "args": "pulseaudio",
++                    "condition": "config.unix"
++                },
++                {
++                    "type": "feature",
++                    "args": "sndio",
+                     "condition": "config.unix"
+                 },
+                 {

Added: head/www/qt5-webengine/files/patch-src_3rdparty_chromium_media_BUILD.gn
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/www/qt5-webengine/files/patch-src_3rdparty_chromium_media_BUILD.gn	Sun Jul 22 04:16:38 2018	(r475084)
@@ -0,0 +1,12 @@
+--- src/3rdparty/chromium/media/BUILD.gn.orig	2018-06-21 14:13:32 UTC
++++ src/3rdparty/chromium/media/BUILD.gn
+@@ -53,6 +53,9 @@ config("media_config") {
+   if (use_cras) {
+     defines += [ "USE_CRAS" ]
+   }
++  if (use_sndio) {
++    defines += [ "USE_SNDIO" ]
++  }
+ }
+ 
+ config("media_implementation") {

Modified: head/www/qt5-webengine/files/patch-src_3rdparty_chromium_media_audio_BUILD.gn
==============================================================================
--- head/www/qt5-webengine/files/patch-src_3rdparty_chromium_media_audio_BUILD.gn	Sun Jul 22 03:22:52 2018	(r475083)
+++ head/www/qt5-webengine/files/patch-src_3rdparty_chromium_media_audio_BUILD.gn	Sun Jul 22 04:16:38 2018	(r475084)
@@ -1,15 +1,15 @@
---- src/3rdparty/chromium/media/audio/BUILD.gn.orig	2017-01-26 00:49:15 UTC
+--- src/3rdparty/chromium/media/audio/BUILD.gn.orig	2018-04-10 14:05:55 UTC
 +++ src/3rdparty/chromium/media/audio/BUILD.gn
 @@ -206,7 +206,7 @@ source_set("audio") {
      deps += [ "//media/base/android:media_jni_headers" ]
    }
  
 -  if (is_linux) {
-+  if (is_linux || is_bsd) {
++  if (is_linux || (is_bsd && !use_sndio)) {
      sources += [ "linux/audio_manager_linux.cc" ]
    }
  
-@@ -255,10 +255,12 @@ source_set("audio") {
+@@ -255,10 +255,24 @@ source_set("audio") {
        configs += [ ":libpulse" ]
      } else {
        # TODO(ajwong): Technically, this dl should go in the action.
@@ -20,6 +20,18 @@
 +    if (is_linux) {
 +      libs += [ "dl" ]
 +    }
++  }
++
++  if (use_sndio) {
++    libs += [ "sndio" ]
++    sources += [
++      "openbsd/audio_manager_openbsd.cc",
++      "openbsd/audio_manager_openbsd.h",
++      "sndio/sndio_input.cc",
++      "sndio/sndio_input.h",
++      "sndio/sndio_output.cc",
++      "sndio/sndio_output.h",
++    ]
    }
  
    configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]

Added: head/www/qt5-webengine/files/patch-src_3rdparty_chromium_media_media__options.gni
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/www/qt5-webengine/files/patch-src_3rdparty_chromium_media_media__options.gni	Sun Jul 22 04:16:38 2018	(r475084)
@@ -0,0 +1,12 @@
+--- src/3rdparty/chromium/media/media_options.gni.orig	2018-06-21 14:06:20 UTC
++++ src/3rdparty/chromium/media/media_options.gni
+@@ -53,6 +53,9 @@ declare_args() {
+ 
+   # Enables runtime selection of ALSA library for audio.
+   use_alsa = false
++ 
++  # Enables runtime selection of sndio library for audio.
++  use_sndio = false  
+ 
+   # Alsa should be used on non-Android, non-Mac POSIX systems.
+   # Alsa should be used on desktop Chromecast and audio-only Chromecast builds.

Added: head/www/qt5-webengine/files/patch-src_core_config_linux.pri
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/www/qt5-webengine/files/patch-src_core_config_linux.pri	Sun Jul 22 04:16:38 2018	(r475084)
@@ -0,0 +1,14 @@
+--- src/core/config/linux.pri.orig	2018-06-21 17:19:26 UTC
++++ src/core/config/linux.pri
+@@ -136,6 +136,11 @@ host_build {
+     } else {
+         gn_args += use_alsa=false
+     }
++    qtConfig(sndio) {
++        gn_args += use_sndio=true
++    } else {
++        gn_args += use_sndio=false
++    }
+     packagesExist(libffi): gn_args += use_system_libffi=true
+     else: gn_args += use_system_libffi=false
+     !packagesExist(libpci): gn_args += use_libpci=false

Copied: head/www/qt5-webengine/files/sndio_input.cc (from r474875, head/www/iridium/files/sndio_input.cc)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/www/qt5-webengine/files/sndio_input.cc	Sun Jul 22 04:16:38 2018	(r475084, copy of r474875, head/www/iridium/files/sndio_input.cc)
@@ -0,0 +1,190 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "media/audio/sndio/sndio_input.h"
+
+#include <stddef.h>
+
+#include "base/bind.h"
+#include "base/logging.h"
+#include "base/macros.h"
+#include "base/message_loop/message_loop.h"
+#include "media/audio/openbsd/audio_manager_openbsd.h"
+#include "media/audio/audio_manager.h"
+
+namespace media {
+
+void sndio_in_onmove(void *arg, int delta) {
+  NOTIMPLEMENTED();
+  SndioAudioInputStream* self = static_cast<SndioAudioInputStream*>(arg);
+
+  self->hw_delay_ = delta - self->params_.GetBytesPerFrame();
+}
+
+void *sndio_in_threadstart(void *arg) {
+  NOTIMPLEMENTED();
+  SndioAudioInputStream* self = static_cast<SndioAudioInputStream*>(arg);
+
+  self->ReadAudio();
+  return NULL;
+}
+
+SndioAudioInputStream::SndioAudioInputStream(AudioManagerBase* audio_manager,
+                                       const std::string& device_name,
+                                       const AudioParameters& params)
+    : audio_manager_(audio_manager),
+      device_name_(device_name),
+      params_(params),
+      bytes_per_buffer_(params.frames_per_buffer() *
+                        (params.channels() * params.bits_per_sample()) /
+                        8),
+      buffer_duration_(base::TimeDelta::FromMicroseconds(
+          params.frames_per_buffer() * base::Time::kMicrosecondsPerSecond /
+          static_cast<float>(params.sample_rate()))),
+      callback_(NULL),
+      device_handle_(NULL),
+      read_callback_behind_schedule_(false),
+      audio_bus_(AudioBus::Create(params)) {
+}
+
+SndioAudioInputStream::~SndioAudioInputStream() {}
+
+bool SndioAudioInputStream::Open() {
+  struct sio_par par;
+  int sig;
+
+  if (device_handle_)
+    return false;  // Already open.
+
+  if (params_.format() != AudioParameters::AUDIO_PCM_LINEAR &&
+      params_.format() != AudioParameters::AUDIO_PCM_LOW_LATENCY) {
+    LOG(WARNING) << "Unsupported audio format.";
+    return false;
+  }
+
+  sio_initpar(&par);
+  par.rate = params_.sample_rate();
+  par.pchan = params_.channels();
+  par.bits = params_.bits_per_sample();
+  par.bps = par.bits / 8;
+  par.sig = sig = par.bits != 8 ? 1 : 0;
+  par.le = SIO_LE_NATIVE;
+  par.appbufsz = params_.frames_per_buffer();
+  sndio_rec_bufsz_ = par.bufsz;
+  sndio_rec_bufsize_ = par.round * par.bps * par.rchan;
+
+  device_handle_ = sio_open(SIO_DEVANY, SIO_REC, 0);
+
+  if (device_handle_ == NULL) {
+    LOG(ERROR) << "Couldn't open audio device.";
+    return false;
+  }
+
+  if (!sio_setpar(device_handle_, &par) || !sio_getpar(device_handle_, &par)) {
+    LOG(ERROR) << "Couldn't set audio parameters.";
+    goto bad_close;
+  }
+
+  if (par.rate  != (unsigned int)params_.sample_rate() ||
+      par.pchan != (unsigned int)params_.channels() ||
+      par.bits  != (unsigned int)params_.bits_per_sample() ||
+      par.sig   != (unsigned int)sig ||
+      (par.bps > 1 && par.le != SIO_LE_NATIVE) ||
+      (par.bits != par.bps * 8)) {
+    LOG(ERROR) << "Unsupported audio parameters.";
+    goto bad_close;
+  }
+  sio_onmove(device_handle_, sndio_in_onmove, this);
+
+  audio_buffer_.reset(new uint8_t[bytes_per_buffer_]);
+
+  return true;
+bad_close:
+  sio_close(device_handle_);
+  return false;
+}
+
+void SndioAudioInputStream::Start(AudioInputCallback* callback) {
+  DCHECK(!callback_ && callback);
+  callback_ = callback;
+  StartAgc();
+
+  // We start reading data half |buffer_duration_| later than when the
+  // buffer might have got filled, to accommodate some delays in the audio
+  // driver. This could also give us a smooth read sequence going forward.
+  base::TimeDelta delay = buffer_duration_ + buffer_duration_ / 2;
+  next_read_time_ = base::TimeTicks::Now() + delay;
+  if (pthread_create(&thread_, NULL, sndio_in_threadstart, this) != 0)
+    LOG(ERROR) << "Failed to create real-time thread.";
+}
+
+void SndioAudioInputStream::ReadAudio() {
+  NOTIMPLEMENTED();
+  DCHECK(callback_);
+
+  int num_buffers = sndio_rec_bufsize_ / params_.frames_per_buffer();
+  double normalized_volume = 0.0;
+
+  // Update the AGC volume level once every second. Note that, |volume| is
+  // also updated each time SetVolume() is called through IPC by the
+  // render-side AGC.
+  GetAgcVolume(&normalized_volume);
+
+  while (num_buffers--) {
+    int frames_read = sio_read(device_handle_, audio_buffer_.get(),
+                                         params_.frames_per_buffer());
+    if (frames_read == params_.frames_per_buffer()) {
+      audio_bus_->FromInterleaved(audio_buffer_.get(),
+                                  audio_bus_->frames(),
+                                  params_.bits_per_sample() / 8);
+      callback_->OnData(
+          this, audio_bus_.get(), hw_delay_, normalized_volume);
+    } else {
+      LOG(WARNING) << "sio_read() returning less than expected frames: "
+                   << frames_read << " vs. " << params_.frames_per_buffer()
+                   << ". Dropping this buffer.";
+    }
+  }
+}
+
+void SndioAudioInputStream::Stop() {
+  if (!device_handle_ || !callback_)
+    return;
+
+  StopAgc();
+
+  pthread_join(thread_, NULL);
+  sio_stop(device_handle_);
+
+  callback_ = NULL;
+}
+
+void SndioAudioInputStream::Close() {
+  if (device_handle_) {
+    sio_close(device_handle_);
+    audio_buffer_.reset();
+    device_handle_ = NULL;
+  }
+
+  audio_manager_->ReleaseInputStream(this);
+}
+
+double SndioAudioInputStream::GetMaxVolume() {
+  return static_cast<double>(SIO_MAXVOL);
+}
+
+void SndioAudioInputStream::SetVolume(double volume) {
+  NOTIMPLEMENTED();
+}
+
+double SndioAudioInputStream::GetVolume() {
+  long current_volume = 0;
+  return static_cast<double>(current_volume);
+}
+
+bool SndioAudioInputStream::IsMuted() {
+  return false;
+}
+
+}  // namespace media

Copied: head/www/qt5-webengine/files/sndio_input.h (from r474875, head/www/iridium/files/sndio_input.h)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/www/qt5-webengine/files/sndio_input.h	Sun Jul 22 04:16:38 2018	(r475084, copy of r474875, head/www/iridium/files/sndio_input.h)
@@ -0,0 +1,108 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MEDIA_AUDIO_SNDIO_SNDIO_INPUT_H_
+#define MEDIA_AUDIO_SNDIO_SNDIO_INPUT_H_
+
+#include <stdint.h>
+#include <string>
+#include <sndio.h>
+
+#include "base/compiler_specific.h"
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "base/time/time.h"
+#include "media/audio/agc_audio_stream.h"
+#include "media/audio/audio_io.h"
+#include "media/audio/audio_device_description.h"
+#include "media/base/audio_parameters.h"
+
+namespace media {
+
+class AudioManagerBase;
+
+// call-backs invoked from C libraries, thus requiring C linkage
+extern "C" {
+  // Invoked (on the real-time thread) at each sound card clock tick
+  void sndio_in_onmove(void *arg, int delta);
+  // Invoked (on the real-time thread) whenever the volume changes
+  void sndio_in_onvol(void *arg, unsigned int vol);
+  // Real-time thread entry point
+  void *sndio_in_threadstart(void *arg);
+}
+
+// Provides an input stream for audio capture based on the SNDIO PCM interface.
+// This object is not thread safe and all methods should be invoked in the
+// thread that created the object.
+class SndioAudioInputStream : public AgcAudioStream<AudioInputStream> {
+ public:
+  // Pass this to the constructor if you want to attempt auto-selection
+  // of the audio recording device.
+  static const char kAutoSelectDevice[];
+
+  // Create a PCM Output stream for the SNDIO device identified by
+  // |device_name|. If unsure of what to use for |device_name|, use
+  // |kAutoSelectDevice|.
+  SndioAudioInputStream(AudioManagerBase* audio_manager,
+                     const std::string& device_name,
+                     const AudioParameters& params);
+
+  ~SndioAudioInputStream() override;
+
+  // Implementation of AudioInputStream.
+  bool Open() override;
+  void Start(AudioInputCallback* callback) override;
+  void Stop() override;
+  void Close() override;
+  double GetMaxVolume() override;
+  void SetVolume(double volume) override;
+  double GetVolume() override;
+  bool IsMuted() override;
+
+  // C-linkage call-backs are friends to access private data
+  friend void sndio_in_onmove(void *arg, int delta);
+  friend void sndio_in_onvol(void *arg, unsigned int vol);
+  friend void *sndio_in_threadstart(void *arg);
+
+ private:
+  // Logs the error and invokes any registered callbacks.
+  void HandleError(const char* method, int error);
+
+  // Reads one or more buffers of audio from the device, passes on to the
+  // registered callback and schedules the next read.
+  void ReadAudio();
+
+  // Recovers from any device errors if possible.
+  bool Recover(int error);
+
+  // Non-refcounted pointer back to the audio manager.
+  // The AudioManager indirectly holds on to stream objects, so we don't
+  // want circular references.  Additionally, stream objects live on the audio
+  // thread, which is owned by the audio manager and we don't want to addref
+  // the manager from that thread.
+  AudioManagerBase* audio_manager_;
+  std::string device_name_;
+  AudioParameters params_;
+  int bytes_per_buffer_;
+  base::TimeDelta buffer_duration_;  // Length of each recorded buffer.
+  AudioInputCallback* callback_;  // Valid during a recording session.
+  base::TimeTicks next_read_time_;  // Scheduled time for next read callback.
+  struct sio_hdl* device_handle_;  // Handle to the SNDIO PCM recording device.
+  std::unique_ptr<uint8_t[]> audio_buffer_;  // Buffer used for reading audio data.
+  bool read_callback_behind_schedule_;
+  std::unique_ptr<AudioBus> audio_bus_;
+
+  int hw_delay_;
+  int sndio_rec_bufsize_;
+  int sndio_rec_bufsz_;
+
+  // High priority thread running RealTimeThread()
+  pthread_t thread_;
+
+  DISALLOW_COPY_AND_ASSIGN(SndioAudioInputStream);
+};
+
+}  // namespace media
+
+#endif  // MEDIA_AUDIO_SNDIO_SNDIO_INPUT_H_

Copied: head/www/qt5-webengine/files/sndio_output.cc (from r474875, head/www/iridium/files/sndio_output.cc)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/www/qt5-webengine/files/sndio_output.cc	Sun Jul 22 04:16:38 2018	(r475084, copy of r474875, head/www/iridium/files/sndio_output.cc)
@@ -0,0 +1,177 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/logging.h"
+#include "base/time/time.h"
+#include "base/time/default_tick_clock.h"
+#include "media/audio/audio_manager_base.h"
+#include "media/base/audio_timestamp_helper.h"
+#include "media/audio/sndio/sndio_output.h"
+
+namespace media {
+
+void sndio_onmove(void *arg, int delta) {
+  SndioAudioOutputStream* self = static_cast<SndioAudioOutputStream*>(arg);
+
+  self->hw_delay = delta;
+}
+
+void sndio_onvol(void *arg, unsigned int vol) {
+  SndioAudioOutputStream* self = static_cast<SndioAudioOutputStream*>(arg);
+
+  self->vol = vol;
+}
+
+void *sndio_threadstart(void *arg) {
+  SndioAudioOutputStream* self = static_cast<SndioAudioOutputStream*>(arg);
+
+  self->RealTimeThread();
+  return NULL;
+}
+
+SndioAudioOutputStream::SndioAudioOutputStream(const AudioParameters& params,
+                                               AudioManagerBase* manager)
+    : manager(manager),
+      params(params),
+      audio_bus(AudioBus::Create(params)),
+      bytes_per_frame(params.GetBytesPerFrame()),
+      state(kClosed),
+      mutex(PTHREAD_MUTEX_INITIALIZER) {
+}
+
+SndioAudioOutputStream::~SndioAudioOutputStream() {
+  if (state != kClosed)
+    Close();
+}
+
+bool SndioAudioOutputStream::Open() {
+  struct sio_par par;
+  int sig;
+
+  if (params.format() != AudioParameters::AUDIO_PCM_LINEAR &&
+      params.format() != AudioParameters::AUDIO_PCM_LOW_LATENCY) {
+    LOG(WARNING) << "Unsupported audio format.";
+    return false;
+  }
+  sio_initpar(&par);
+  par.rate = params.sample_rate();
+  par.pchan = params.channels();
+  par.bits = params.bits_per_sample();
+  par.bps = par.bits / 8;
+  par.sig = sig = par.bits != 8 ? 1 : 0;
+  par.le = SIO_LE_NATIVE;
+  par.appbufsz = params.frames_per_buffer();
+
+  hdl = sio_open(SIO_DEVANY, SIO_PLAY, 0);
+  if (hdl == NULL) {
+    LOG(ERROR) << "Couldn't open audio device.";
+    return false;
+  }
+  if (!sio_setpar(hdl, &par) || !sio_getpar(hdl, &par)) {
+    LOG(ERROR) << "Couldn't set audio parameters.";
+    goto bad_close;
+  }
+  if (par.rate  != (unsigned int)params.sample_rate() ||
+      par.pchan != (unsigned int)params.channels() ||
+      par.bits  != (unsigned int)params.bits_per_sample() ||
+      par.sig   != (unsigned int)sig ||
+      (par.bps > 1 && par.le != SIO_LE_NATIVE) ||
+      (par.bits != par.bps * 8)) {
+    LOG(ERROR) << "Unsupported audio parameters.";
+    goto bad_close;
+  }
+  state = kStopped;
+  volpending = 0;
+  vol = 0;
+  buffer = new char[audio_bus->frames() * params.GetBytesPerFrame()];
+  sio_onmove(hdl, sndio_onmove, this);
+  sio_onvol(hdl, sndio_onvol, this);
+  return true;
+ bad_close:
+  sio_close(hdl);
+  return false;
+}
+
+void SndioAudioOutputStream::Close() {
+  if (state == kClosed)
+    return;
+  if (state == kRunning)
+    Stop();
+  state = kClosed;
+  delete [] buffer;
+  sio_close(hdl);
+  manager->ReleaseOutputStream(this);  // Calls the destructor
+}
+
+void SndioAudioOutputStream::Start(AudioSourceCallback* callback) {
+  state = kRunning;
+  hw_delay = 0;
+  source = callback;
+  sio_start(hdl);
+  if (pthread_create(&thread, NULL, sndio_threadstart, this) != 0) {
+    LOG(ERROR) << "Failed to create real-time thread.";
+    sio_stop(hdl);
+    state = kStopped;
+  }
+}
+
+void SndioAudioOutputStream::Stop() {
+  if (state == kStopped)
+    return;
+  state = kStopWait;
+  pthread_join(thread, NULL);
+  sio_stop(hdl);
+  state = kStopped;
+}
+
+void SndioAudioOutputStream::SetVolume(double v) {
+  pthread_mutex_lock(&mutex);
+  vol = v * SIO_MAXVOL;
+  volpending = 1;
+  pthread_mutex_unlock(&mutex);
+}
+
+void SndioAudioOutputStream::GetVolume(double* v) {
+  pthread_mutex_lock(&mutex);
+  *v = vol * (1. / SIO_MAXVOL);
+  pthread_mutex_unlock(&mutex);
+}
+
+void SndioAudioOutputStream::RealTimeThread(void) {
+  int avail, count;
+
+  while (state == kRunning) {
+    // Update volume if needed
+    pthread_mutex_lock(&mutex);
+    if (volpending) {
+      volpending = 0;
+      sio_setvol(hdl, vol);
+    }
+    pthread_mutex_unlock(&mutex);
+
+    // Get data to play
+    const base::TimeDelta delay = AudioTimestampHelper::FramesToTime(hw_delay, params.sample_rate() * 1000);
+    count = source->OnMoreData(delay, base::TimeTicks::Now(), 0, audio_bus.get());
+    audio_bus->ToInterleaved(count, params.bits_per_sample() / 8, buffer);
+    if (count == 0) {
+      // We have to submit something to the device
+      count = audio_bus->frames();
+      memset(buffer, 0, count * params.GetBytesPerFrame());
+      LOG(WARNING) << "No data to play, running empty cycle.";
+    }
+
+    // Submit data to the device
+    avail = count * params.GetBytesPerFrame();
+    count = sio_write(hdl, buffer, avail);
+    if (count == 0) {
+      LOG(WARNING) << "Audio device disconnected.";
+      break;
+    }
+
+    // Update hardware pointer
+    hw_delay += count;
+  }
+}
+
+}  // namespace media

Copied: head/www/qt5-webengine/files/sndio_output.h (from r474875, head/www/iridium/files/sndio_output.h)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/www/qt5-webengine/files/sndio_output.h	Sun Jul 22 04:16:38 2018	(r475084, copy of r474875, head/www/iridium/files/sndio_output.h)
@@ -0,0 +1,92 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MEDIA_AUDIO_SNDIO_SNDIO_OUTPUT_H_
+#define MEDIA_AUDIO_SNDIO_SNDIO_OUTPUT_H_
+
+#include <pthread.h>
+#include <sndio.h>
+
+#include "base/time/tick_clock.h"
+#include "base/time/time.h"
+#include "media/audio/audio_io.h"
+
+
+namespace media {
+
+class AudioParameters;
+class AudioManagerBase;
+
+// call-backs invoked from C libraries, thus requiring C linkage
+extern "C" {
+  // Invoked (on the real-time thread) at each sound card clock tick
+  void sndio_onmove(void *arg, int delta);
+  // Invoked (on the real-time thread) whenever the volume changes
+  void sndio_onvol(void *arg, unsigned int vol);
+  // Real-time thread entry point
+  void *sndio_threadstart(void *arg);
+}
+
+// Implementation of AudioOutputStream using sndio(7)
+class SndioAudioOutputStream : public AudioOutputStream {
+ public:
+  // The manager is creating this object
+  SndioAudioOutputStream(const AudioParameters& params,
+                         AudioManagerBase* manager);
+  virtual ~SndioAudioOutputStream();
+
+  // Implementation of AudioOutputStream.
+  virtual bool Open() override;
+  virtual void Close() override;
+  virtual void Start(AudioSourceCallback* callback) override;
+  virtual void Stop() override;
+  virtual void SetVolume(double volume) override;
+  virtual void GetVolume(double* volume) override;
+
+  // C-linkage call-backs are friends to access private data
+  friend void sndio_onmove(void *arg, int delta);
+  friend void sndio_onvol(void *arg, unsigned int vol);
+  friend void *sndio_threadstart(void *arg);
+
+ private:
+  enum StreamState {
+    kClosed,            // Not opened yet
+    kStopped,           // Device opened, but not started yet
+    kRunning,           // Started, device playing
+    kStopWait           // Stopping, waiting for the real-time thread to exit
+  };
+  // Continuously moves data from the audio bus to the device
+  void RealTimeThread(void);
+  // Our creator, the audio manager needs to be notified when we close.
+  AudioManagerBase* manager;
+  // Parameters of the source
+  AudioParameters params;
+  // Source stores data here
+  std::unique_ptr<AudioBus> audio_bus;
+  int bytes_per_frame;
+  // Call-back that produces data to play
+  AudioSourceCallback* source;
+  // Handle of the audio device
+  struct sio_hdl* hdl;
+  // Current state of the stream
+  enum StreamState state;
+  // High priority thread running RealTimeThread()
+  pthread_t thread;
+  // Protects vol, volpending and hw_delay
+  pthread_mutex_t mutex;
+  // Current volume in the 0..SIO_MAXVOL range
+  int vol;
+  // Set to 1 if volumes must be refreshed in the realtime thread
+  int volpending;
+  // Number of bytes buffered in the hardware
+  int hw_delay;
+  // Temporary buffer where data is stored sndio-compatible format
+  char* buffer;
+
+  DISALLOW_COPY_AND_ASSIGN(SndioAudioOutputStream);
+};
+
+}  // namespace media
+
+#endif  // MEDIA_AUDIO_SNDIO_SNDIO_OUTPUT_H_



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201807220416.w6M4GcSr064977>