From 4d7939f4ce01c7fd6041d39cd9e58fa9ca738a0e Mon Sep 17 00:00:00 2001 From: Tai Chi Minh Ralph Eastwood Date: Sat, 13 Jun 2020 18:48:29 +0200 Subject: [PATCH 1/3] chromium: add sndio patch [ci skip] --- srcpkgs/chromium/patches/sndio.patch | 887 +++++++++++++++++++++++++++ srcpkgs/chromium/template | 21 +- 2 files changed, 902 insertions(+), 6 deletions(-) create mode 100644 srcpkgs/chromium/patches/sndio.patch diff --git a/srcpkgs/chromium/patches/sndio.patch b/srcpkgs/chromium/patches/sndio.patch new file mode 100644 index 00000000000..4fea926c239 --- /dev/null +++ b/srcpkgs/chromium/patches/sndio.patch @@ -0,0 +1,887 @@ +diff -Naur chromium-83.0.4103.97.orig/media/BUILD.gn chromium-83.0.4103.97/media/BUILD.gn +--- media/BUILD.gn.orig 2020-06-03 20:40:26.000000000 +0200 ++++ media/BUILD.gn 2020-06-13 17:32:28.510395975 +0200 +@@ -65,6 +65,9 @@ + defines += [ "DLOPEN_PULSEAUDIO" ] + } + } ++ if (use_sndio) { ++ defines += [ "USE_SNDIO" ] ++ } + if (use_cras) { + defines += [ "USE_CRAS" ] + } +diff -Naur chromium-83.0.4103.97.orig/media/audio/BUILD.gn chromium-83.0.4103.97/media/audio/BUILD.gn +--- media/audio/BUILD.gn.orig 2020-06-03 20:39:37.000000000 +0200 ++++ media/audio/BUILD.gn 2020-06-13 17:32:28.511395969 +0200 +@@ -236,6 +236,17 @@ + sources += [ "linux/audio_manager_linux.cc" ] + } + ++ if (use_sndio) { ++ libs += [ "sndio" ] ++ sources += [ ++ "sndio/audio_manager_sndio.cc", ++ "sndio/sndio_input.cc", ++ "sndio/sndio_input.h", ++ "sndio/sndio_output.cc", ++ "sndio/sndio_output.h" ++ ] ++ } ++ + if (use_alsa) { + libs += [ "asound" ] + sources += [ +diff -Naur chromium-83.0.4103.97.orig/media/audio/linux/audio_manager_linux.cc chromium-83.0.4103.97/media/audio/linux/audio_manager_linux.cc +--- media/audio/linux/audio_manager_linux.cc.orig 2020-06-03 20:39:37.000000000 +0200 ++++ media/audio/linux/audio_manager_linux.cc 2020-06-13 18:09:43.623333167 +0200 +@@ -19,6 +19,11 @@ + #include "media/audio/pulse/audio_manager_pulse.h" + #include "media/audio/pulse/pulse_util.h" + #endif ++#if defined(USE_SNDIO) ++#include "media/audio/sndio/audio_manager_sndio.h" ++#include "media/audio/sndio/sndio_input.h" ++#include "media/audio/sndio/sndio_output.h" ++#endif + + namespace media { + +@@ -26,7 +31,8 @@ + kPulse, + kAlsa, + kCras, +- kAudioIOMax = kCras // Must always be equal to largest logged entry. ++ kSndio, ++ kAudioIOMax = kSndio // Must always be equal to largest logged entry. + }; + + std::unique_ptr CreateAudioManager( +@@ -39,6 +45,16 @@ + audio_log_factory); + } + ++#if defined(USE_SNDIO) ++ struct sio_hdl *hdl = sio_open(SIO_DEVANY, SIO_PLAY, 0); ++ if (hdl != NULL) { ++ sio_close(hdl); ++ UMA_HISTOGRAM_ENUMERATION("Media.LinuxAudioIO", kSndio, kAudioIOMax + 1); ++ return std::make_unique(std::move(audio_thread), ++ audio_log_factory); ++ } ++#endif ++ + #if defined(USE_CRAS) + if (base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kUseCras)) { + UMA_HISTOGRAM_ENUMERATION("Media.LinuxAudioIO", kCras, kAudioIOMax + 1); +diff -Naur chromium-83.0.4103.97.orig/media/audio/sndio/audio_manager_sndio.cc chromium-83.0.4103.97/media/audio/sndio/audio_manager_sndio.cc +--- media/audio/sndio/audio_manager_sndio.cc.orig 1970-01-01 01:00:00.000000000 +0100 ++++ media/audio/sndio/audio_manager_sndio.cc 2020-06-13 17:32:28.511395969 +0200 +@@ -0,0 +1,148 @@ ++// 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 "media/audio/sndio/audio_manager_sndio.h" ++ ++#include "base/metrics/histogram_macros.h" ++#include "base/memory/ptr_util.h" ++#include "media/audio/audio_device_description.h" ++#include "media/audio/audio_output_dispatcher.h" ++#include "media/audio/sndio/sndio_input.h" ++#include "media/audio/sndio/sndio_output.h" ++#include "media/base/limits.h" ++#include "media/base/media_switches.h" ++ ++namespace media { ++ ++ ++// Maximum number of output streams that can be open simultaneously. ++static const int kMaxOutputStreams = 4; ++ ++// Default sample rate for input and output streams. ++static const int kDefaultSampleRate = 48000; ++ ++void AddDefaultDevice(AudioDeviceNames* device_names) { ++ DCHECK(device_names->empty()); ++ device_names->push_front(AudioDeviceName::CreateDefault()); ++} ++ ++bool AudioManagerSndio::HasAudioOutputDevices() { ++ return true; ++} ++ ++bool AudioManagerSndio::HasAudioInputDevices() { ++ return true; ++} ++ ++void AudioManagerSndio::GetAudioInputDeviceNames( ++ AudioDeviceNames* device_names) { ++ DCHECK(device_names->empty()); ++ AddDefaultDevice(device_names); ++} ++ ++void AudioManagerSndio::GetAudioOutputDeviceNames( ++ AudioDeviceNames* device_names) { ++ AddDefaultDevice(device_names); ++} ++ ++const char* AudioManagerSndio::GetName() { ++ return "SNDIO"; ++} ++ ++AudioParameters AudioManagerSndio::GetInputStreamParameters( ++ const std::string& device_id) { ++ static const int kDefaultInputBufferSize = 1024; ++ ++ int user_buffer_size = GetUserBufferSize(); ++ int buffer_size = user_buffer_size ? ++ user_buffer_size : kDefaultInputBufferSize; ++ ++ return AudioParameters( ++ AudioParameters::AUDIO_PCM_LOW_LATENCY, CHANNEL_LAYOUT_STEREO, ++ kDefaultSampleRate, buffer_size); ++} ++ ++AudioManagerSndio::AudioManagerSndio(std::unique_ptr audio_thread, ++ AudioLogFactory* audio_log_factory) ++ : AudioManagerBase(std::move(audio_thread), ++ audio_log_factory) { ++ DLOG(WARNING) << "AudioManagerSndio"; ++ SetMaxOutputStreamsAllowed(kMaxOutputStreams); ++} ++ ++AudioManagerSndio::~AudioManagerSndio() { ++ Shutdown(); ++} ++ ++AudioOutputStream* AudioManagerSndio::MakeLinearOutputStream( ++ const AudioParameters& params, ++ const LogCallback& log_callback) { ++ DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format()); ++ return MakeOutputStream(params); ++} ++ ++AudioOutputStream* AudioManagerSndio::MakeLowLatencyOutputStream( ++ const AudioParameters& params, ++ const std::string& device_id, ++ const LogCallback& log_callback) { ++ DLOG_IF(ERROR, !device_id.empty()) << "Not implemented!"; ++ DCHECK_EQ(AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format()); ++ return MakeOutputStream(params); ++} ++ ++AudioInputStream* AudioManagerSndio::MakeLinearInputStream( ++ const AudioParameters& params, ++ const std::string& device_id, ++ const LogCallback& log_callback) { ++ DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format()); ++ return MakeInputStream(params); ++} ++ ++AudioInputStream* AudioManagerSndio::MakeLowLatencyInputStream( ++ const AudioParameters& params, ++ const std::string& device_id, ++ const LogCallback& log_callback) { ++ DCHECK_EQ(AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format()); ++ return MakeInputStream(params); ++} ++ ++AudioParameters AudioManagerSndio::GetPreferredOutputStreamParameters( ++ const std::string& output_device_id, ++ const AudioParameters& input_params) { ++ // TODO(tommi): Support |output_device_id|. ++ DLOG_IF(ERROR, !output_device_id.empty()) << "Not implemented!"; ++ static const int kDefaultOutputBufferSize = 2048; ++ ++ ChannelLayout channel_layout = CHANNEL_LAYOUT_STEREO; ++ int sample_rate = kDefaultSampleRate; ++ int buffer_size = kDefaultOutputBufferSize; ++ if (input_params.IsValid()) { ++ sample_rate = input_params.sample_rate(); ++ channel_layout = input_params.channel_layout(); ++ buffer_size = std::min(buffer_size, input_params.frames_per_buffer()); ++ } ++ ++ int user_buffer_size = GetUserBufferSize(); ++ if (user_buffer_size) ++ buffer_size = user_buffer_size; ++ ++ return AudioParameters( ++ AudioParameters::AUDIO_PCM_LOW_LATENCY, channel_layout, ++ sample_rate, buffer_size); ++} ++ ++AudioInputStream* AudioManagerSndio::MakeInputStream( ++ const AudioParameters& params) { ++ DLOG(WARNING) << "MakeInputStream"; ++ return new SndioAudioInputStream(this, ++ AudioDeviceDescription::kDefaultDeviceId, params); ++} ++ ++AudioOutputStream* AudioManagerSndio::MakeOutputStream( ++ const AudioParameters& params) { ++ DLOG(WARNING) << "MakeOutputStream"; ++ return new SndioAudioOutputStream(params, this); ++} ++ ++} // namespace media +diff -Naur chromium-83.0.4103.97.orig/media/audio/sndio/audio_manager_sndio.h chromium-83.0.4103.97/media/audio/sndio/audio_manager_sndio.h +--- media/audio/sndio/audio_manager_sndio.h.orig 1970-01-01 01:00:00.000000000 +0100 ++++ media/audio/sndio/audio_manager_sndio.h 2020-06-13 17:32:28.511395969 +0200 +@@ -0,0 +1,65 @@ ++// 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_AUDIO_MANAGER_SNDIO_H_ ++#define MEDIA_AUDIO_SNDIO_AUDIO_MANAGER_SNDIO_H_ ++ ++#include ++ ++#include "base/compiler_specific.h" ++#include "base/macros.h" ++#include "base/memory/ref_counted.h" ++#include "base/threading/thread.h" ++#include "media/audio/audio_manager_base.h" ++ ++namespace media { ++ ++class MEDIA_EXPORT AudioManagerSndio : public AudioManagerBase { ++ public: ++ AudioManagerSndio(std::unique_ptr audio_thread, ++ AudioLogFactory* audio_log_factory); ++ ~AudioManagerSndio() override; ++ ++ // Implementation of AudioManager. ++ bool HasAudioOutputDevices() override; ++ bool HasAudioInputDevices() override; ++ void GetAudioInputDeviceNames(AudioDeviceNames* device_names) override; ++ void GetAudioOutputDeviceNames(AudioDeviceNames* device_names) override; ++ AudioParameters GetInputStreamParameters( ++ const std::string& device_id) override; ++ const char* GetName() override; ++ ++ // Implementation of AudioManagerBase. ++ AudioOutputStream* MakeLinearOutputStream( ++ const AudioParameters& params, ++ const LogCallback& log_callback) override; ++ AudioOutputStream* MakeLowLatencyOutputStream( ++ const AudioParameters& params, ++ const std::string& device_id, ++ const LogCallback& log_callback) override; ++ AudioInputStream* MakeLinearInputStream( ++ const AudioParameters& params, ++ const std::string& device_id, ++ const LogCallback& log_callback) override; ++ AudioInputStream* MakeLowLatencyInputStream( ++ const AudioParameters& params, ++ const std::string& device_id, ++ const LogCallback& log_callback) override; ++ ++ protected: ++ AudioParameters GetPreferredOutputStreamParameters( ++ const std::string& output_device_id, ++ const AudioParameters& input_params) override; ++ ++ private: ++ // Called by MakeLinearOutputStream and MakeLowLatencyOutputStream. ++ AudioOutputStream* MakeOutputStream(const AudioParameters& params); ++ AudioInputStream* MakeInputStream(const AudioParameters& params); ++ ++ DISALLOW_COPY_AND_ASSIGN(AudioManagerSndio); ++}; ++ ++} // namespace media ++ ++#endif // MEDIA_AUDIO_SNDIO_AUDIO_MANAGER_SNDIO_H_ +diff -Naur chromium-83.0.4103.97.orig/media/audio/sndio/sndio_input.cc chromium-83.0.4103.97/media/audio/sndio/sndio_input.cc +--- media/audio/sndio/sndio_input.cc.orig 1970-01-01 01:00:00.000000000 +0100 ++++ media/audio/sndio/sndio_input.cc 2020-06-13 17:32:28.511395969 +0200 +@@ -0,0 +1,201 @@ ++// 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 "base/bind.h" ++#include "base/logging.h" ++#include "base/macros.h" ++#include "base/message_loop/message_loop.h" ++#include "media/base/audio_timestamp_helper.h" ++#include "media/audio/sndio/audio_manager_sndio.h" ++#include "media/audio/audio_manager.h" ++#include "media/audio/sndio/sndio_input.h" ++ ++namespace media { ++ ++static const SampleFormat kSampleFormat = kSampleFormatS16; ++ ++void SndioAudioInputStream::OnMoveCallback(void *arg, int delta) ++{ ++ SndioAudioInputStream* self = static_cast(arg); ++ ++ self->hw_delay += delta; ++} ++ ++void *SndioAudioInputStream::ThreadEntry(void *arg) { ++ SndioAudioInputStream* self = static_cast(arg); ++ ++ self->ThreadLoop(); ++ return NULL; ++} ++ ++SndioAudioInputStream::SndioAudioInputStream(AudioManagerBase* manager, ++ const std::string& device_name, ++ const AudioParameters& params) ++ : manager(manager), ++ params(params), ++ audio_bus(AudioBus::Create(params)), ++ state(kClosed) { ++} ++ ++SndioAudioInputStream::~SndioAudioInputStream() { ++ if (state != kClosed) ++ Close(); ++} ++ ++bool SndioAudioInputStream::Open() { ++ struct sio_par par; ++ int sig; ++ ++ if (state != kClosed) ++ return false; ++ ++ 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.rchan = params.channels(); ++ par.bits = SampleFormatToBitsPerChannel(kSampleFormat); ++ 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_REC, 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.rchan != (unsigned int)params.channels() || ++ par.bits != (unsigned int)SampleFormatToBitsPerChannel(kSampleFormat) || ++ 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; ++ buffer = new char[audio_bus->frames() * params.GetBytesPerFrame(kSampleFormat)]; ++ sio_onmove(hdl, &OnMoveCallback, this); ++ return true; ++bad_close: ++ sio_close(hdl); ++ return false; ++} ++ ++void SndioAudioInputStream::Start(AudioInputCallback* cb) { ++ ++ StartAgc(); ++ ++ state = kRunning; ++ hw_delay = 0; ++ callback = cb; ++ sio_start(hdl); ++ if (pthread_create(&thread, NULL, &ThreadEntry, this) != 0) { ++ LOG(ERROR) << "Failed to create real-time thread for recording."; ++ sio_stop(hdl); ++ state = kStopped; ++ } ++} ++ ++void SndioAudioInputStream::Stop() { ++ ++ if (state == kStopped) ++ return; ++ ++ state = kStopWait; ++ pthread_join(thread, NULL); ++ sio_stop(hdl); ++ state = kStopped; ++ ++ StopAgc(); ++} ++ ++void SndioAudioInputStream::Close() { ++ ++ if (state == kClosed) ++ return; ++ ++ if (state == kRunning) ++ Stop(); ++ ++ state = kClosed; ++ delete [] buffer; ++ sio_close(hdl); ++ ++ manager->ReleaseInputStream(this); ++} ++ ++double SndioAudioInputStream::GetMaxVolume() { ++ // Not supported ++ return 0.0; ++} ++ ++void SndioAudioInputStream::SetVolume(double volume) { ++ // Not supported. Do nothing. ++} ++ ++double SndioAudioInputStream::GetVolume() { ++ // Not supported. ++ return 0.0; ++} ++ ++bool SndioAudioInputStream::IsMuted() { ++ // Not supported. ++ return false; ++} ++ ++void SndioAudioInputStream::SetOutputDeviceForAec( ++ const std::string& output_device_id) { ++ // Not supported. ++} ++ ++void SndioAudioInputStream::ThreadLoop(void) { ++ size_t todo, n; ++ char *data; ++ unsigned int nframes; ++ double normalized_volume = 0.0; ++ ++ nframes = audio_bus->frames(); ++ ++ while (state == kRunning && !sio_eof(hdl)) { ++ ++ GetAgcVolume(&normalized_volume); ++ ++ // read one block ++ todo = nframes * params.GetBytesPerFrame(kSampleFormat); ++ data = buffer; ++ while (todo > 0) { ++ n = sio_read(hdl, data, todo); ++ if (n == 0) ++ return; // unrecoverable I/O error ++ todo -= n; ++ data += n; ++ } ++ hw_delay -= nframes; ++ ++ // convert frames count to TimeDelta ++ const base::TimeDelta delay = AudioTimestampHelper::FramesToTime(hw_delay, ++ params.sample_rate()); ++ ++ // push into bus ++ audio_bus->FromInterleaved(buffer, nframes, SampleFormatToBytesPerChannel(kSampleFormat)); ++ ++ // invoke callback ++ callback->OnData(audio_bus.get(), base::TimeTicks::Now() - delay, 1.); ++ } ++} ++ ++} // namespace media +diff -Naur chromium-83.0.4103.97.orig/media/audio/sndio/sndio_input.h chromium-83.0.4103.97/media/audio/sndio/sndio_input.h +--- media/audio/sndio/sndio_input.h.orig 1970-01-01 01:00:00.000000000 +0100 ++++ media/audio/sndio/sndio_input.h 2020-06-13 17:32:28.511395969 +0200 +@@ -0,0 +1,91 @@ ++// 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 ++#include ++#include ++ ++#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; ++ ++// Implementation of AudioOutputStream using sndio(7) ++class SndioAudioInputStream : public AgcAudioStream { ++ 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; ++ void SetOutputDeviceForAec(const std::string& output_device_id) override; ++ ++ 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 ++ }; ++ ++ // C-style call-backs ++ static void OnMoveCallback(void *arg, int delta); ++ static void* ThreadEntry(void *arg); ++ ++ // Continuously moves data from the device to the consumer ++ void ThreadLoop(); ++ // Our creator, the audio manager needs to be notified when we close. ++ AudioManagerBase* manager; ++ // Parameters of the source ++ AudioParameters params; ++ // We store data here for consumer ++ std::unique_ptr audio_bus; ++ // Call-back that consumes recorded data ++ AudioInputCallback* callback; // Valid during a recording session. ++ // Handle of the audio device ++ struct sio_hdl* hdl; ++ // Current state of the stream ++ enum StreamState state; ++ // High priority thread running ThreadLoop() ++ pthread_t thread; ++ // Number of frames buffered in the hardware ++ int hw_delay; ++ // Temporary buffer where data is stored sndio-compatible format ++ char* buffer; ++ ++ DISALLOW_COPY_AND_ASSIGN(SndioAudioInputStream); ++}; ++ ++} // namespace media ++ ++#endif // MEDIA_AUDIO_SNDIO_SNDIO_INPUT_H_ +diff -Naur chromium-83.0.4103.97.orig/media/audio/sndio/sndio_output.cc chromium-83.0.4103.97/media/audio/sndio/sndio_output.cc +--- media/audio/sndio/sndio_output.cc.orig 1970-01-01 01:00:00.000000000 +0100 ++++ media/audio/sndio/sndio_output.cc 2020-06-13 17:32:28.511395969 +0200 +@@ -0,0 +1,183 @@ ++// 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 { ++ ++static const SampleFormat kSampleFormat = kSampleFormatS16; ++ ++void SndioAudioOutputStream::OnMoveCallback(void *arg, int delta) { ++ SndioAudioOutputStream* self = static_cast(arg); ++ ++ self->hw_delay -= delta; ++} ++ ++void SndioAudioOutputStream::OnVolCallback(void *arg, unsigned int vol) { ++ SndioAudioOutputStream* self = static_cast(arg); ++ ++ self->vol = vol; ++} ++ ++void *SndioAudioOutputStream::ThreadEntry(void *arg) { ++ SndioAudioOutputStream* self = static_cast(arg); ++ ++ self->ThreadLoop(); ++ return NULL; ++} ++ ++SndioAudioOutputStream::SndioAudioOutputStream(const AudioParameters& params, ++ AudioManagerBase* manager) ++ : manager(manager), ++ params(params), ++ audio_bus(AudioBus::Create(params)), ++ 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 = SampleFormatToBitsPerChannel(kSampleFormat); ++ 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)SampleFormatToBitsPerChannel(kSampleFormat) || ++ 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(kSampleFormat)]; ++ sio_onmove(hdl, &OnMoveCallback, this); ++ sio_onvol(hdl, &OnVolCallback, 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, &ThreadEntry, 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); ++} ++ ++// This stream is always used with sub second buffer sizes, where it's ++// sufficient to simply always flush upon Start(). ++void SndioAudioOutputStream::Flush() {} ++ ++void SndioAudioOutputStream::ThreadLoop(void) { ++ int avail, count, result; ++ ++ 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()); ++ count = source->OnMoreData(delay, base::TimeTicks::Now(), 0, audio_bus.get()); ++ audio_bus->ToInterleaved(count, SampleFormatToBytesPerChannel(kSampleFormat), buffer); ++ if (count == 0) { ++ // We have to submit something to the device ++ count = audio_bus->frames(); ++ memset(buffer, 0, count * params.GetBytesPerFrame(kSampleFormat)); ++ LOG(WARNING) << "No data to play, running empty cycle."; ++ } ++ ++ // Submit data to the device ++ avail = count * params.GetBytesPerFrame(kSampleFormat); ++ result = sio_write(hdl, buffer, avail); ++ if (result == 0) { ++ LOG(WARNING) << "Audio device disconnected."; ++ break; ++ } ++ ++ // Update hardware pointer ++ hw_delay += count; ++ } ++} ++ ++} // namespace media +diff -Naur chromium-83.0.4103.97.orig/media/audio/sndio/sndio_output.h chromium-83.0.4103.97/media/audio/sndio/sndio_output.h +--- media/audio/sndio/sndio_output.h.orig 1970-01-01 01:00:00.000000000 +0100 ++++ media/audio/sndio/sndio_output.h 2020-06-13 17:32:28.511395969 +0200 +@@ -0,0 +1,86 @@ ++// 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 ++#include ++ ++#include "base/time/tick_clock.h" ++#include "base/time/time.h" ++#include "media/audio/audio_io.h" ++ ++namespace media { ++ ++class AudioManagerBase; ++ ++// 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. ++ bool Open() override; ++ void Close() override; ++ void Start(AudioSourceCallback* callback) override; ++ void Stop() override; ++ void SetVolume(double volume) override; ++ void GetVolume(double* volume) override; ++ void Flush() override; ++ ++ 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 ++ }; ++ ++ // C-style call-backs ++ static void OnMoveCallback(void *arg, int delta); ++ static void OnVolCallback(void *arg, unsigned int vol); ++ static void* ThreadEntry(void *arg); ++ ++ // Continuously moves data from the producer to the device ++ void ThreadLoop(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 audio_bus; ++ // 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 ThreadLoop() ++ 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 frames 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_ +diff -Naur chromium-83.0.4103.97.orig/media/media_options.gni chromium-83.0.4103.97/media/media_options.gni +--- media/media_options.gni.orig 2020-06-03 20:40:26.000000000 +0200 ++++ media/media_options.gni 2020-06-13 17:32:28.512395963 +0200 +@@ -119,6 +119,9 @@ + # Enables runtime selection of ALSA library for audio. + use_alsa = false + ++ # Enable runtime selection of sndio(7) ++ 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. + if (is_posix && !is_android && !is_mac && diff --git a/srcpkgs/chromium/template b/srcpkgs/chromium/template index ac80f6b78fa..a7fed941ee1 100644 --- a/srcpkgs/chromium/template +++ b/srcpkgs/chromium/template @@ -15,10 +15,12 @@ lib32disabled=yes nodebug=yes nopie=yes # contains tools that are not PIE, enables PIE itself -build_options="clang js_optimize vaapi" +build_options="clang js_optimize vaapi pulseaudio sndio" desc_option_clang="Use clang to build" desc_option_js_optimize="Optimize the JS used for Chromium's UI" desc_option_vaapi="Enable support for VA-API" +desc_option_pulseaudio="Enable support for PulseAudio" +desc_option_sndio="Enable support for sndio" hostmakedepends="$(vopt_if clang clang) yasm python pkgconf perl gperf bison ninja nodejs hwids libatomic-devel libevent-devel libglib-devel $(vopt_if js_optimize openjdk)" @@ -26,15 +28,15 @@ makedepends="libpng-devel gtk+-devel gtk+3-devel nss-devel pciutils-devel libXi-devel libgcrypt-devel libgnome-keyring-devel cups-devel elfutils-devel libXcomposite-devel speech-dispatcher-devel libXrandr-devel mit-krb5-devel libXScrnSaver-devel alsa-lib-devel snappy-devel libdrm-devel - libxml2-devel libxslt-devel pulseaudio-devel libexif-devel + libxml2-devel libxslt-devel $(vopt_if pulseaudio pulseaudio-devel) libexif-devel libXcursor-devel libflac-devel speex-devel libmtp-devel libwebp-devel libjpeg-turbo-devel libevent-devel json-c-devel harfbuzz-devel minizip-devel jsoncpp-devel zlib-devel libcap-devel libXdamage-devel re2-devel fontconfig-devel freetype-devel opus-devel - ffmpeg-devel libva-devel python-setuptools" + ffmpeg-devel libva-devel python-setuptools $(vopt_if sndio sndio-devel)" depends="libexif hwids desktop-file-utils hicolor-icon-theme xdg-utils" -build_options_default="clang" +build_options_default="clang pulseaudio" case "${XBPS_TARGET_MACHINE}" in x86_64|i686) build_options_default+=" js_optimize" ;; @@ -154,7 +156,6 @@ do_configure() { 'use_allocator="none"' 'use_allocator_shim=false' 'use_cups=true' - 'use_pulseaudio=true' 'use_sysroot=false' 'use_system_harfbuzz=true' 'enable_widevine=true' @@ -170,6 +171,10 @@ do_configure() { "closure_compile=$(vopt_if js_optimize true false)" ) + conf+=( + "use_pulseaudio=$(vopt_if pulseaudio true false)" + ) + # Use explicit library dependencies instead of dlopen. # GN only has "link_pulseaudio", the other options used before are not available atm # linux_link_cups=true @@ -177,7 +182,11 @@ do_configure() { # linux_link_libpci=true # linux_link_libspeechd=true # libspeechd_h_prefix=\"speech-dispatcher/\"" - conf+=( 'link_pulseaudio=true' ) + conf+=( "link_pulseaudio=$(vopt_if pulseaudio true false)" ) + + conf+=( + "use_sndio=$(vopt_if sndio true false)" + ) # Never use bundled binutils/gold binary. conf+=( From 752d984cff6bc17933fcf8c8b0d9b4306c690df4 Mon Sep 17 00:00:00 2001 From: Peter Bui Date: Fri, 10 Jul 2020 11:34:30 -0400 Subject: [PATCH 2/3] chromium: update to 83.0.4103.116. [ci skip] - Built for x86_64 and x86_64-musl. - Tested on x86_64. - Turn on vaapi build option by default. With this build option, the chromium package now supports VA-API for Intel and AMD GPUs. However, users must opt-in to enabling this feature at run-time by enabling "Override software rendering list" in chrome://flags or by passing the --ignore-gpu-blacklist to chromium. Otherwise this feature is disabled and not used. This has been tested with YouTube with multiple Intel GPUs. --- .../patches/chromium-fix-vaapi-on-intel.patch | 40 +++++++++++++++++++ ...3-files-to-have-a-start-time-of-zero.patch | 38 ++++++++++++++++++ srcpkgs/chromium/template | 8 ++-- 3 files changed, 82 insertions(+), 4 deletions(-) create mode 100644 srcpkgs/chromium/patches/chromium-fix-vaapi-on-intel.patch create mode 100644 srcpkgs/chromium/patches/upstream-force-mp3-files-to-have-a-start-time-of-zero.patch diff --git a/srcpkgs/chromium/patches/chromium-fix-vaapi-on-intel.patch b/srcpkgs/chromium/patches/chromium-fix-vaapi-on-intel.patch new file mode 100644 index 00000000000..e01a6a97ef0 --- /dev/null +++ b/srcpkgs/chromium/patches/chromium-fix-vaapi-on-intel.patch @@ -0,0 +1,40 @@ +From 9ff06536caf7ea51aad9fd2bb649c858eaf7ee84 Mon Sep 17 00:00:00 2001 +From: Akarshan Biswas +Date: Sat, 26 Oct 2019 10:06:30 +0530 +Subject: [PATCH] Move offending function to chromeos only + +--- media/gpu/vaapi/vaapi_video_decode_accelerator.cc ++++ media/gpu/vaapi/vaapi_video_decode_accelerator.cc +@@ -66,6 +66,7 @@ void ReportToUMA(VAVDADecoderFailure fai + VAVDA_DECODER_FAILURES_MAX + 1); + } + ++#if defined(OS_ANDROID) || defined(OS_CHROMEOS) + // Returns true if the CPU is an Intel Gemini Lake or later (including Kaby + // Lake) Cpu platform id's are referenced from the following file in kernel + // source arch/x86/include/asm/intel-family.h +@@ -78,6 +79,7 @@ bool IsGeminiLakeOrLater() { + cpuid.model() >= kGeminiLakeModelId; + return is_geminilake_or_later; + } ++#endif + + } // namespace + +@@ -1155,6 +1157,8 @@ VaapiVideoDecodeAccelerator::DecideBuffe + if (output_mode_ == VideoDecodeAccelerator::Config::OutputMode::IMPORT) + return BufferAllocationMode::kNormal; + ++#if defined(OS_ANDROID) || defined(OS_CHROMEOS) ++ // Move this to chromeOs only as it is causing problem in some intel linux drivers + // On Gemini Lake, Kaby Lake and later we can pass to libva the client's + // PictureBuffers to decode onto, which skips the use of the Vpp unit and its + // associated format reconciliation copy, avoiding all internal buffer +@@ -1171,6 +1175,7 @@ VaapiVideoDecodeAccelerator::DecideBuffe + num_extra_pics_ = 3; + return BufferAllocationMode::kNone; + } ++#endif + + // If we're here, we have to use the Vpp unit and allocate buffers for + // |decoder_|; usually we'd have to allocate the |decoder_|s diff --git a/srcpkgs/chromium/patches/upstream-force-mp3-files-to-have-a-start-time-of-zero.patch b/srcpkgs/chromium/patches/upstream-force-mp3-files-to-have-a-start-time-of-zero.patch new file mode 100644 index 00000000000..7fc433fab8f --- /dev/null +++ b/srcpkgs/chromium/patches/upstream-force-mp3-files-to-have-a-start-time-of-zero.patch @@ -0,0 +1,38 @@ +From 192fc3899f76e9487d77895f31df8d2d13bf9619 Mon Sep 17 00:00:00 2001 +From: Dale Curtis +Date: Fri, 26 Jun 2020 01:10:55 +0000 +Subject: [PATCH] Force mp3 files to have a start time of zero. + +This will allow us to remove our custom patch which breaks upstream +ffmpeg functionality for unknown reasons. + +R=sandersd + +Fixed: 1062037 +Change-Id: I253011843dee4dd6a8c958b14990ad836a9f1dca +Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2268221 +Auto-Submit: Dale Curtis +Reviewed-by: Dan Sanders +Commit-Queue: Dale Curtis +Cr-Commit-Position: refs/heads/master@{#782792} +--- + media/filters/ffmpeg_demuxer.cc | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/media/filters/ffmpeg_demuxer.cc b/media/filters/ffmpeg_demuxer.cc +index 01266e1a072..a7ed542b5fc 100644 +--- media/filters/ffmpeg_demuxer.cc ++++ media/filters/ffmpeg_demuxer.cc +@@ -1522,6 +1522,12 @@ void FFmpegDemuxer::OnFindStreamInfoDone(int result) { + if (glue_->container() == container_names::CONTAINER_AVI) + format_context->flags |= AVFMT_FLAG_GENPTS; + ++ // FFmpeg will incorrectly adjust the start time of MP3 files into the future ++ // based on discard samples. We were unable to fix this upstream without ++ // breaking ffmpeg functionality. https://crbug.com/1062037 ++ if (glue_->container() == container_names::CONTAINER_MP3) ++ start_time_ = base::TimeDelta(); ++ + // For testing purposes, don't overwrite the timeline offset if set already. + if (timeline_offset_.is_null()) { + timeline_offset_ = diff --git a/srcpkgs/chromium/template b/srcpkgs/chromium/template index a7fed941ee1..5295224da83 100644 --- a/srcpkgs/chromium/template +++ b/srcpkgs/chromium/template @@ -1,15 +1,15 @@ # Template file for 'chromium' pkgname=chromium # See http://www.chromium.org/developers/calendar for the latest version -version=83.0.4103.106 -revision=2 +version=83.0.4103.116 +revision=1 archs="i686 x86_64*" short_desc="Google's attempt at creating a safer, faster, and more stable browser" maintainer="Enno Boland " license="BSD-3-Clause" homepage="https://www.chromium.org/" distfiles="https://commondatastorage.googleapis.com/chromium-browser-official/${pkgname}-${version}.tar.xz" -checksum=cfd153a2e10b0bb0fb3b7e6be543aef0915181f5fbdbea893d08465afd097e2f +checksum=bb0c7e8dfee9f3a5e30eca7f34fc9f21caefa82a86c058c552f52b1ae2da2ac3 lib32disabled=yes nodebug=yes @@ -36,7 +36,7 @@ makedepends="libpng-devel gtk+-devel gtk+3-devel nss-devel pciutils-devel ffmpeg-devel libva-devel python-setuptools $(vopt_if sndio sndio-devel)" depends="libexif hwids desktop-file-utils hicolor-icon-theme xdg-utils" -build_options_default="clang pulseaudio" +build_options_default="clang pulseaudio vaapi" case "${XBPS_TARGET_MACHINE}" in x86_64|i686) build_options_default+=" js_optimize" ;; From 17169fe986ce059192b0f5ff6c8607d73844014b Mon Sep 17 00:00:00 2001 From: Peter Bui Date: Fri, 10 Jul 2020 12:44:23 -0400 Subject: [PATCH 3/3] chromium-widevine: update to 83.0.4103.116. [ci skip] --- srcpkgs/chromium-widevine/template | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/srcpkgs/chromium-widevine/template b/srcpkgs/chromium-widevine/template index 9b119d90548..8a0e5b70ec4 100644 --- a/srcpkgs/chromium-widevine/template +++ b/srcpkgs/chromium-widevine/template @@ -6,7 +6,7 @@ _chromeVersion="current" _channel="stable" pkgname=chromium-widevine -version=83.0.4103.106 +version=83.0.4103.116 revision=1 archs="x86_64" create_wrksrc=yes @@ -17,7 +17,7 @@ depends="chromium binutils xz" homepage="https://www.google.com/chrome" repository=nonfree distfiles="https://dl.google.com/linux/direct/google-chrome-${_channel}_${_chromeVersion}_amd64.deb" -checksum=c6de3e4bd6bef493ebc1626c44922984881d65bd2fe67e0534fa33067cc91202 +checksum=861cc9c0ca8471f875e3413a8255c277c074d1a28064002fb694695096d8febd do_extract() { :