mirror of
https://github.com/yann64/haikuports.git
synced 2026-05-06 06:58:57 +02:00
886 lines
21 KiB
Plaintext
886 lines
21 KiB
Plaintext
From 34dc0d642c106ca26633d731de53bf4250436b46 Mon Sep 17 00:00:00 2001
|
|
From: Gerasim Troeglazov <3dEyes@gmail.com>
|
|
Date: Tue, 9 Mar 2021 12:01:25 +1000
|
|
Subject: Add haiku support
|
|
|
|
|
|
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
|
index f7b46f0..7212ab8 100644
|
|
--- a/CMakeLists.txt
|
|
+++ b/CMakeLists.txt
|
|
@@ -78,6 +78,9 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
|
elseif(ANDROID)
|
|
set(DEFAULT_ALSA OFF)
|
|
set(DEFAULT_PORTAUDIO OFF)
|
|
+elseif(HAIKU)
|
|
+ set(DEFAULT_ALSA OFF)
|
|
+ set(DEFAULT_PORTAUDIO OFF)
|
|
else()
|
|
set(DEFAULT_ALSA OFF)
|
|
set(DEFAULT_PORTAUDIO ON)
|
|
@@ -122,7 +125,7 @@ endif()
|
|
option(USE_GLSLC "Compile Vulkan shaders" OFF)
|
|
add_feature_info(GLSLC USE_GLSLC "Compile Vulkan shaders")
|
|
|
|
-if(NOT WIN32 AND NOT APPLE AND NOT ANDROID)
|
|
+if(NOT WIN32 AND NOT APPLE AND NOT ANDROID AND NOT HAIKU)
|
|
option(USE_FREEDESKTOP_NOTIFICATIONS "Use Freedesktop notifications" ON)
|
|
add_feature_info("Freedesktop notifications" USE_FREEDESKTOP_NOTIFICATIONS "Use Freedesktop notifications")
|
|
endif()
|
|
@@ -163,7 +166,7 @@ else()
|
|
set(USE_YOUTUBEDL OFF)
|
|
endif()
|
|
|
|
-if(USE_EXTENSIONS AND NOT WIN32 AND NOT APPLE AND NOT ANDROID)
|
|
+if(USE_EXTENSIONS AND NOT WIN32 AND NOT APPLE AND NOT ANDROID AND NOT HAIKU)
|
|
option(USE_MPRIS2 "Build Extensions with MPRIS2 support" ON)
|
|
add_feature_info(MPRIS2 USE_MPRIS2 "Build Extensions with MPRIS2 support")
|
|
endif()
|
|
diff --git a/src/gui/Main.cpp b/src/gui/Main.cpp
|
|
index 2ebd731..6513dba 100644
|
|
--- a/src/gui/Main.cpp
|
|
+++ b/src/gui/Main.cpp
|
|
@@ -610,6 +610,10 @@ int main(int argc, char *argv[])
|
|
checkForEGL();
|
|
#endif
|
|
|
|
+#ifdef Q_OS_HAIKU
|
|
+ setenv("HOME", "/boot/home", 1);
|
|
+#endif
|
|
+
|
|
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
|
#ifndef USE_OPENGL
|
|
QGuiApplication::setAttribute(Qt::AA_ForceRasterWidgets);
|
|
@@ -706,7 +710,7 @@ int main(int argc, char *argv[])
|
|
}
|
|
if (!cmakeBuildFound)
|
|
{
|
|
-#if !defined Q_OS_WIN && !defined Q_OS_MACOS && !defined Q_OS_ANDROID
|
|
+#if !defined Q_OS_WIN && !defined Q_OS_MACOS && !defined Q_OS_ANDROID && !defined Q_OS_HAIKU
|
|
sharePath = QCoreApplication::applicationDirPath() + "/../share/qmplay2";
|
|
libPath = QMPlay2CoreClass::getLibDir();
|
|
if (libPath.isEmpty() || !QDir(libPath).exists("qmplay2"))
|
|
@@ -912,5 +916,9 @@ int main(int argc, char *argv[])
|
|
if (canDeleteApp)
|
|
#endif
|
|
delete qApp;
|
|
+
|
|
+#ifdef Q_OS_HAIKU
|
|
+ kill(::getpid(), SIGKILL);
|
|
+#endif
|
|
return 0;
|
|
}
|
|
diff --git a/src/gui/MainWidget.cpp b/src/gui/MainWidget.cpp
|
|
index e75c98d..4333f23 100644
|
|
--- a/src/gui/MainWidget.cpp
|
|
+++ b/src/gui/MainWidget.cpp
|
|
@@ -150,7 +150,7 @@ MainWidget::MainWidget(QList<QPair<QString, QString>> &arguments)
|
|
setIconSize({22, 22});
|
|
|
|
SettingsWidget::InitSettings();
|
|
-#ifndef Q_OS_ANDROID
|
|
+#if !defined Q_OS_ANDROID && !defined Q_OS_HAIKU
|
|
settings.init("MainWidget/WidgetsLocked", false);
|
|
#else
|
|
settings.init("MainWidget/WidgetsLocked", true);
|
|
diff --git a/src/modules/CMakeLists.txt b/src/modules/CMakeLists.txt
|
|
index 832b774..216e162 100644
|
|
--- a/src/modules/CMakeLists.txt
|
|
+++ b/src/modules/CMakeLists.txt
|
|
@@ -7,6 +7,9 @@ if(WIN32)
|
|
elseif(APPLE)
|
|
set(MODULES_INSTALL_PATH "${CMAKE_INSTALL_LIBDIR}/modules")
|
|
set(QMPLAY2_MODULE SHARED) # otherwise CMake uses ".so" extension
|
|
+elseif(HAIKU)
|
|
+ set(MODULES_INSTALL_PATH "modules")
|
|
+ set(QMPLAY2_MODULE MODULE)
|
|
else()
|
|
set(MODULES_INSTALL_PATH "${CMAKE_INSTALL_LIBDIR}/qmplay2/modules")
|
|
set(QMPLAY2_MODULE MODULE)
|
|
@@ -58,6 +61,10 @@ if(USE_PIPEWIRE)
|
|
add_subdirectory(PipeWire)
|
|
endif()
|
|
|
|
+if(HAIKU)
|
|
+ add_subdirectory(MediaKit)
|
|
+endif()
|
|
+
|
|
if(USE_XVIDEO)
|
|
add_subdirectory(XVideo)
|
|
endif()
|
|
diff --git a/src/modules/MediaKit/CMakeLists.txt b/src/modules/MediaKit/CMakeLists.txt
|
|
new file mode 100644
|
|
index 0000000..f94e365
|
|
--- /dev/null
|
|
+++ b/src/modules/MediaKit/CMakeLists.txt
|
|
@@ -0,0 +1,36 @@
|
|
+cmake_minimum_required(VERSION 3.1)
|
|
+project(MediaKit)
|
|
+
|
|
+set(MediaKit_HDR
|
|
+ MediaKit.hpp
|
|
+ MediaKitWriter.hpp
|
|
+ RingBuffer.hpp
|
|
+ SndPlayer.hpp
|
|
+)
|
|
+
|
|
+set(MediaKit_SRC
|
|
+ MediaKit.cpp
|
|
+ MediaKitWriter.cpp
|
|
+ RingBuffer.cpp
|
|
+ SndPlayer.cpp
|
|
+)
|
|
+
|
|
+set(MediaKit_RESOURCES
|
|
+ icon.qrc
|
|
+)
|
|
+
|
|
+include_directories(../../qmplay2/headers)
|
|
+
|
|
+add_library(${PROJECT_NAME} ${QMPLAY2_MODULE}
|
|
+ ${MediaKit_HDR}
|
|
+ ${MediaKit_SRC}
|
|
+ ${MediaKit_RESOURCES}
|
|
+)
|
|
+
|
|
+target_link_libraries(${PROJECT_NAME}
|
|
+ be
|
|
+ media
|
|
+ libqmplay2
|
|
+)
|
|
+
|
|
+install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION ${MODULES_INSTALL_PATH})
|
|
diff --git a/src/modules/MediaKit/MediaKit.cpp b/src/modules/MediaKit/MediaKit.cpp
|
|
new file mode 100644
|
|
index 0000000..2fee2d5
|
|
--- /dev/null
|
|
+++ b/src/modules/MediaKit/MediaKit.cpp
|
|
@@ -0,0 +1,65 @@
|
|
+#include <MediaKit.hpp>
|
|
+#include <MediaKitWriter.hpp>
|
|
+
|
|
+MediaKit::MediaKit() :
|
|
+ Module( "MediaKit" )
|
|
+{
|
|
+ m_icon = QIcon( ":/MediaKit" );
|
|
+
|
|
+ init( "WriterEnabled", true );
|
|
+ init( "Delay", 0.2 );
|
|
+}
|
|
+
|
|
+QList< MediaKit::Info > MediaKit::getModulesInfo( const bool showDisabled ) const
|
|
+{
|
|
+ QList< Info > modulesInfo;
|
|
+ if ( showDisabled || getBool( "WriterEnabled" ) )
|
|
+ modulesInfo += Info( MediaKitWriterName, WRITER, QStringList( "audio" ) );
|
|
+ return modulesInfo;
|
|
+}
|
|
+void *MediaKit::createInstance( const QString &name )
|
|
+{
|
|
+ if ( name == MediaKitWriterName && getBool( "WriterEnabled" ) )
|
|
+ return new MediaKitWriter( *this );
|
|
+ return NULL;
|
|
+}
|
|
+
|
|
+MediaKit::SettingsWidget *MediaKit::getSettingsWidget()
|
|
+{
|
|
+ return new ModuleSettingsWidget( *this );
|
|
+}
|
|
+
|
|
+QMPLAY2_EXPORT_MODULE( MediaKit )
|
|
+
|
|
+/**/
|
|
+
|
|
+#include <QDoubleSpinBox>
|
|
+#include <QGridLayout>
|
|
+#include <QCheckBox>
|
|
+#include <QLabel>
|
|
+
|
|
+ModuleSettingsWidget::ModuleSettingsWidget( Module &module ) :
|
|
+ Module::SettingsWidget( module )
|
|
+{
|
|
+ enabledB = new QCheckBox( tr( "Enabled" ) );
|
|
+ enabledB->setChecked( sets().getBool( "WriterEnabled" ) );
|
|
+
|
|
+ QLabel *delayL = new QLabel( tr( "Delay" ) + ": " );
|
|
+
|
|
+ delayB = new QDoubleSpinBox;
|
|
+ delayB->setRange( 0.01, 1.0 );
|
|
+ delayB->setSingleStep( 0.01 );
|
|
+ delayB->setSuffix( " " + tr( "sec" ) );
|
|
+ delayB->setValue( sets().getDouble( "Delay" ) );
|
|
+
|
|
+ QGridLayout *layout = new QGridLayout( this );
|
|
+ layout->addWidget( enabledB, 0, 0, 1, 2 );
|
|
+ layout->addWidget( delayL, 1, 0, 1, 1 );
|
|
+ layout->addWidget( delayB, 1, 1, 1, 1 );
|
|
+}
|
|
+
|
|
+void ModuleSettingsWidget::saveSettings()
|
|
+{
|
|
+ sets().set( "WriterEnabled", enabledB->isChecked() );
|
|
+ sets().set( "Delay", delayB->value() );
|
|
+}
|
|
diff --git a/src/modules/MediaKit/MediaKit.hpp b/src/modules/MediaKit/MediaKit.hpp
|
|
new file mode 100644
|
|
index 0000000..ed89e32
|
|
--- /dev/null
|
|
+++ b/src/modules/MediaKit/MediaKit.hpp
|
|
@@ -0,0 +1,33 @@
|
|
+#pragma once
|
|
+
|
|
+#include <Module.hpp>
|
|
+
|
|
+class MediaKit : public Module
|
|
+{
|
|
+public:
|
|
+ MediaKit();
|
|
+private:
|
|
+ QList< Info > getModulesInfo( const bool ) const;
|
|
+ void *createInstance( const QString & );
|
|
+
|
|
+ SettingsWidget *getSettingsWidget();
|
|
+};
|
|
+
|
|
+/**/
|
|
+
|
|
+#include <QCoreApplication>
|
|
+
|
|
+class QDoubleSpinBox;
|
|
+class QCheckBox;
|
|
+
|
|
+class ModuleSettingsWidget : public Module::SettingsWidget
|
|
+{
|
|
+ Q_DECLARE_TR_FUNCTIONS( ModuleSettingsWidget )
|
|
+public:
|
|
+ ModuleSettingsWidget( Module & );
|
|
+private:
|
|
+ void saveSettings();
|
|
+
|
|
+ QCheckBox *enabledB;
|
|
+ QDoubleSpinBox *delayB;
|
|
+};
|
|
diff --git a/src/modules/MediaKit/MediaKitWriter.cpp b/src/modules/MediaKit/MediaKitWriter.cpp
|
|
new file mode 100644
|
|
index 0000000..a86e584
|
|
--- /dev/null
|
|
+++ b/src/modules/MediaKit/MediaKitWriter.cpp
|
|
@@ -0,0 +1,85 @@
|
|
+#include <MediaKitWriter.hpp>
|
|
+#include <QMPlay2Core.hpp>
|
|
+
|
|
+MediaKitWriter::MediaKitWriter( Module &module ) :
|
|
+ err( false )
|
|
+{
|
|
+ addParam( "delay" );
|
|
+ addParam( "chn" );
|
|
+ addParam( "rate" );
|
|
+
|
|
+ SetModule( module );
|
|
+}
|
|
+
|
|
+bool MediaKitWriter::set()
|
|
+{
|
|
+ if ( player.delay != sets().getDouble( "Delay" ) )
|
|
+ {
|
|
+ player.delay = sets().getDouble( "Delay" );
|
|
+ return false;
|
|
+ }
|
|
+ return sets().getBool( "WriterEnabled" );
|
|
+}
|
|
+
|
|
+bool MediaKitWriter::readyWrite() const
|
|
+{
|
|
+ return !err && player.isOpen();
|
|
+}
|
|
+
|
|
+bool MediaKitWriter::processParams( bool * )
|
|
+{
|
|
+ bool resetAudio = false;
|
|
+
|
|
+ uchar chn = getParam( "chn" ).toUInt();
|
|
+ if ( player.channels != chn )
|
|
+ {
|
|
+ resetAudio = true;
|
|
+ player.channels = chn;
|
|
+ }
|
|
+ uint rate = getParam( "rate" ).toUInt();
|
|
+ if ( player.sample_rate != rate )
|
|
+ {
|
|
+ resetAudio = true;
|
|
+ player.sample_rate = rate;
|
|
+ }
|
|
+
|
|
+ if ( resetAudio || err )
|
|
+ {
|
|
+ player.stop();
|
|
+ err = !player.start();
|
|
+ if ( !err )
|
|
+ modParam( "delay", player.delay );
|
|
+ else
|
|
+ QMPlay2Core.logError( "MediaKitWriter :: " + tr ( "Cannot open audio output stream" ) );
|
|
+ }
|
|
+
|
|
+ return readyWrite();
|
|
+}
|
|
+qint64 MediaKitWriter::write( const QByteArray &arr )
|
|
+{
|
|
+ if ( !arr.size() || !readyWrite() )
|
|
+ return 0;
|
|
+
|
|
+ err = !player.write( arr );
|
|
+ if ( err )
|
|
+ {
|
|
+ QMPlay2Core.logError( "MediaKitWriter :: " + tr ( "Playback error" ) );
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ return arr.size();
|
|
+}
|
|
+
|
|
+qint64 MediaKitWriter::size() const
|
|
+{
|
|
+ return -1;
|
|
+}
|
|
+QString MediaKitWriter::name() const
|
|
+{
|
|
+ return MediaKitWriterName;
|
|
+}
|
|
+
|
|
+bool MediaKitWriter::open()
|
|
+{
|
|
+ return player.isOK();
|
|
+}
|
|
diff --git a/src/modules/MediaKit/MediaKitWriter.hpp b/src/modules/MediaKit/MediaKitWriter.hpp
|
|
new file mode 100644
|
|
index 0000000..28fa249
|
|
--- /dev/null
|
|
+++ b/src/modules/MediaKit/MediaKitWriter.hpp
|
|
@@ -0,0 +1,30 @@
|
|
+#include <Writer.hpp>
|
|
+#include <SndPlayer.hpp>
|
|
+
|
|
+#include <QCoreApplication>
|
|
+
|
|
+class MediaKitWriter : public Writer
|
|
+{
|
|
+ Q_DECLARE_TR_FUNCTIONS( MediaKitWriter )
|
|
+public:
|
|
+ MediaKitWriter( Module & );
|
|
+private:
|
|
+ bool set();
|
|
+
|
|
+ bool readyWrite() const;
|
|
+
|
|
+ bool processParams( bool *paramsCorrected );
|
|
+ qint64 write( const QByteArray & );
|
|
+
|
|
+ qint64 size() const;
|
|
+ QString name() const;
|
|
+
|
|
+ bool open();
|
|
+
|
|
+ /**/
|
|
+
|
|
+ SndPlayer player;
|
|
+ bool err;
|
|
+};
|
|
+
|
|
+#define MediaKitWriterName "MediaKit Writer"
|
|
diff --git a/src/modules/MediaKit/RingBuffer.cpp b/src/modules/MediaKit/RingBuffer.cpp
|
|
new file mode 100644
|
|
index 0000000..915becc
|
|
--- /dev/null
|
|
+++ b/src/modules/MediaKit/RingBuffer.cpp
|
|
@@ -0,0 +1,129 @@
|
|
+#include <stdio.h>
|
|
+#include <stdlib.h>
|
|
+#include <string.h>
|
|
+
|
|
+#include "RingBuffer.hpp"
|
|
+
|
|
+RingBuffer::RingBuffer( int size )
|
|
+{
|
|
+ initialized = false;
|
|
+ Buffer = new unsigned char[size];
|
|
+ if(Buffer!=NULL) {
|
|
+ memset( Buffer, 0, size );
|
|
+ BufferSize = size;
|
|
+ } else {
|
|
+ BufferSize = 0;
|
|
+ }
|
|
+ reader = 0;
|
|
+ writer = 0;
|
|
+ writeBytesAvailable = size;
|
|
+ if((locker=create_sem(1,"locker")) >= B_OK) {
|
|
+ initialized = true;
|
|
+ } else {
|
|
+ if(Buffer!=NULL) {
|
|
+ delete[] Buffer;
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+RingBuffer::~RingBuffer( )
|
|
+{
|
|
+ if(initialized) {
|
|
+ delete[] Buffer;
|
|
+ delete_sem(locker);
|
|
+ }
|
|
+}
|
|
+
|
|
+bool
|
|
+RingBuffer::Empty( void )
|
|
+{
|
|
+ memset( Buffer, 0, BufferSize );
|
|
+ reader = 0;
|
|
+ writer = 0;
|
|
+ writeBytesAvailable = BufferSize;
|
|
+ return true;
|
|
+}
|
|
+
|
|
+int
|
|
+RingBuffer::Read( unsigned char *data, int size )
|
|
+{
|
|
+ acquire_sem(locker);
|
|
+
|
|
+ if( data == 0 || size <= 0 || writeBytesAvailable == BufferSize ) {
|
|
+ release_sem(locker);
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ int readBytesAvailable = BufferSize - writeBytesAvailable;
|
|
+
|
|
+ if( size > readBytesAvailable ) {
|
|
+ size = readBytesAvailable;
|
|
+ }
|
|
+
|
|
+ if(size > BufferSize - reader) {
|
|
+ int len = BufferSize - reader;
|
|
+ memcpy(data, Buffer + reader, len);
|
|
+ memcpy(data + len, Buffer, size-len);
|
|
+ } else {
|
|
+ memcpy(data, Buffer + reader, size);
|
|
+ }
|
|
+
|
|
+ reader = (reader + size) % BufferSize;
|
|
+ writeBytesAvailable += size;
|
|
+
|
|
+ release_sem(locker);
|
|
+ return size;
|
|
+}
|
|
+
|
|
+int
|
|
+RingBuffer::Write( unsigned char *data, int size )
|
|
+{
|
|
+ acquire_sem(locker);
|
|
+
|
|
+ if( data == 0 || size <= 0 || writeBytesAvailable == 0 ) {
|
|
+ release_sem(locker);
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ if( size > writeBytesAvailable ) {
|
|
+ size = writeBytesAvailable;
|
|
+ }
|
|
+
|
|
+ if(size > BufferSize - writer) {
|
|
+ int len = BufferSize - writer;
|
|
+ memcpy(Buffer + writer, data, len);
|
|
+ memcpy(Buffer, data+len, size-len);
|
|
+ } else {
|
|
+ memcpy(Buffer + writer, data, size);
|
|
+ }
|
|
+
|
|
+ writer = (writer + size) % BufferSize;
|
|
+ writeBytesAvailable -= size;
|
|
+
|
|
+ release_sem(locker);
|
|
+ return size;
|
|
+}
|
|
+
|
|
+int
|
|
+RingBuffer::GetSize( void )
|
|
+{
|
|
+ return BufferSize;
|
|
+}
|
|
+
|
|
+int
|
|
+RingBuffer::GetWriteAvailable( void )
|
|
+{
|
|
+ return writeBytesAvailable;
|
|
+}
|
|
+
|
|
+int
|
|
+RingBuffer::GetReadAvailable( void )
|
|
+{
|
|
+ return BufferSize - writeBytesAvailable;
|
|
+}
|
|
+
|
|
+status_t
|
|
+RingBuffer::InitCheck( void )
|
|
+{
|
|
+ return initialized?B_OK:B_ERROR;
|
|
+}
|
|
diff --git a/src/modules/MediaKit/RingBuffer.hpp b/src/modules/MediaKit/RingBuffer.hpp
|
|
new file mode 100644
|
|
index 0000000..4715632
|
|
--- /dev/null
|
|
+++ b/src/modules/MediaKit/RingBuffer.hpp
|
|
@@ -0,0 +1,31 @@
|
|
+#ifndef __RING_BUFFER_H__
|
|
+#define __RING_BUFFER_H__
|
|
+
|
|
+#include <OS.h>
|
|
+
|
|
+class RingBuffer {
|
|
+
|
|
+public:
|
|
+ RingBuffer(int size);
|
|
+ ~RingBuffer();
|
|
+ int Read( unsigned char* dataPtr, int numBytes );
|
|
+ int Write( unsigned char *dataPtr, int numBytes );
|
|
+
|
|
+ bool Empty( void );
|
|
+ int GetSize( );
|
|
+ int GetWriteAvailable( );
|
|
+ int GetReadAvailable( );
|
|
+ status_t InitCheck( );
|
|
+private:
|
|
+ unsigned char *Buffer;
|
|
+ int BufferSize;
|
|
+ int reader;
|
|
+ int writer;
|
|
+ int writeBytesAvailable;
|
|
+
|
|
+ sem_id locker;
|
|
+
|
|
+ bool initialized;
|
|
+};
|
|
+
|
|
+#endif
|
|
diff --git a/src/modules/MediaKit/SndPlayer.cpp b/src/modules/MediaKit/SndPlayer.cpp
|
|
new file mode 100644
|
|
index 0000000..dafa355
|
|
--- /dev/null
|
|
+++ b/src/modules/MediaKit/SndPlayer.cpp
|
|
@@ -0,0 +1,103 @@
|
|
+#include <SndPlayer.hpp>
|
|
+
|
|
+#include <string.h>
|
|
+#include <stdio.h>
|
|
+#include <stdlib.h>
|
|
+#include <SoundPlayer.h>
|
|
+
|
|
+
|
|
+static void proc(void *cookie, void *buffer, size_t len, const media_raw_audio_format &format)
|
|
+{
|
|
+ RingBuffer *ring = (RingBuffer*)cookie;
|
|
+ unsigned char* ptr = (unsigned char*)buffer;
|
|
+
|
|
+ int readed = ring->Read(ptr,len);
|
|
+
|
|
+ if(readed <len)
|
|
+ memset(ptr+readed, 0, len - readed);
|
|
+}
|
|
+
|
|
+SndPlayer::SndPlayer()
|
|
+{
|
|
+ channels = sample_rate = delay = 0;
|
|
+ player = NULL;
|
|
+ _isOK = true;
|
|
+}
|
|
+
|
|
+bool SndPlayer::start()
|
|
+{
|
|
+ size_t gSoundBufferSize = 8192 * sizeof(float);
|
|
+
|
|
+ media_raw_audio_format form = {
|
|
+ sample_rate,
|
|
+ channels,
|
|
+ media_raw_audio_format::B_AUDIO_FLOAT,
|
|
+ B_MEDIA_LITTLE_ENDIAN,
|
|
+ gSoundBufferSize
|
|
+ };
|
|
+
|
|
+ ring = new RingBuffer(gSoundBufferSize * 3);
|
|
+ if(ring->InitCheck() != B_OK) {
|
|
+ delete ring; ring = 0;
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ player = new BSoundPlayer(&form, "QMPlay2_BSoundPlayer", proc, NULL, (void*)ring);
|
|
+
|
|
+ if(player->InitCheck() != B_OK) {
|
|
+ delete player;
|
|
+ player = NULL;
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ player->Start();
|
|
+ player->SetHasData(true);
|
|
+
|
|
+ _isOK = true;
|
|
+
|
|
+ return player;
|
|
+}
|
|
+void SndPlayer::stop()
|
|
+{
|
|
+ if ( player )
|
|
+ {
|
|
+ if(player) {
|
|
+ player->Stop();
|
|
+ delete player;
|
|
+ delete ring;
|
|
+ }
|
|
+
|
|
+ player = NULL;
|
|
+ ring = NULL;
|
|
+ }
|
|
+}
|
|
+
|
|
+double SndPlayer::getLatency()
|
|
+{
|
|
+ double lat = player->Latency() / (ring->GetSize()*4.0);
|
|
+
|
|
+ return lat;
|
|
+}
|
|
+
|
|
+bool SndPlayer::write( const QByteArray &arr )
|
|
+{
|
|
+ int s = arr.size();
|
|
+ while ( s > 0 && s % 4 )
|
|
+ s--;
|
|
+ if ( s <= 0 )
|
|
+ return false;
|
|
+
|
|
+ int len=s;
|
|
+
|
|
+ unsigned char *src_ptr = (unsigned char *)arr.data();
|
|
+
|
|
+ for(;;) {
|
|
+ int len2 = ring->Write(src_ptr,len);
|
|
+ if(len2 == len)break;
|
|
+ len -= len2;
|
|
+ src_ptr += len2;
|
|
+ snooze(100);
|
|
+ }
|
|
+
|
|
+ return true;
|
|
+}
|
|
diff --git a/src/modules/MediaKit/SndPlayer.hpp b/src/modules/MediaKit/SndPlayer.hpp
|
|
new file mode 100644
|
|
index 0000000..63709b4
|
|
--- /dev/null
|
|
+++ b/src/modules/MediaKit/SndPlayer.hpp
|
|
@@ -0,0 +1,49 @@
|
|
+#ifndef PULSE_HPP
|
|
+#define PULSE_HPP
|
|
+
|
|
+#include <QByteArray>
|
|
+
|
|
+#include <SoundPlayer.h>
|
|
+
|
|
+#include <Window.h>
|
|
+#include <View.h>
|
|
+#include <TextControl.h>
|
|
+
|
|
+#include "RingBuffer.hpp"
|
|
+
|
|
+class SndPlayer
|
|
+{
|
|
+public:
|
|
+ SndPlayer();
|
|
+ inline ~SndPlayer()
|
|
+ {
|
|
+ stop();
|
|
+ }
|
|
+
|
|
+ inline bool isOK() const
|
|
+ {
|
|
+ return _isOK;
|
|
+ }
|
|
+ inline bool isOpen() const
|
|
+ {
|
|
+ return player;
|
|
+ }
|
|
+
|
|
+ bool start();
|
|
+ void stop();
|
|
+
|
|
+ double getLatency();
|
|
+
|
|
+ bool write( const QByteArray & );
|
|
+
|
|
+ double delay;
|
|
+ uchar channels;
|
|
+ float sample_rate;
|
|
+
|
|
+private:
|
|
+ bool _isOK;
|
|
+ BSoundPlayer *player;
|
|
+ RingBuffer *ring;
|
|
+};
|
|
+
|
|
+#endif
|
|
diff --git a/src/modules/MediaKit/icon.qrc b/src/modules/MediaKit/icon.qrc
|
|
new file mode 100644
|
|
index 0000000..24b4ebd
|
|
--- /dev/null
|
|
+++ b/src/modules/MediaKit/icon.qrc
|
|
@@ -0,0 +1,3 @@
|
|
+<RCC><qresource>
|
|
+ <file alias="MediaKit">MediaKit.png</file>
|
|
+</qresource></RCC>
|
|
diff --git a/src/qmplay2/QMPlay2Core.cpp b/src/qmplay2/QMPlay2Core.cpp
|
|
index 3685f2b..04bc1d4 100644
|
|
--- a/src/qmplay2/QMPlay2Core.cpp
|
|
+++ b/src/qmplay2/QMPlay2Core.cpp
|
|
@@ -215,7 +215,7 @@ void QMPlay2CoreClass::init(bool loadModules, bool modulesInSubdirs, const QStri
|
|
settingsDir = QCoreApplication::applicationDirPath() + "/settings/";
|
|
else
|
|
{
|
|
-#if defined(Q_OS_WIN)
|
|
+#if defined(Q_OS_WIN) || defined(Q_OS_HAIKU)
|
|
settingsDir = QFileInfo(QSettings(QSettings::IniFormat, QSettings::UserScope, QString()).fileName()).absolutePath() + "/QMPlay2/";
|
|
#elif defined(Q_OS_MACOS)
|
|
settingsDir = Functions::cleanPath(QStandardPaths::standardLocations(QStandardPaths::DataLocation).value(0, settingsDir));
|
|
@@ -472,6 +472,11 @@ QStringList QMPlay2CoreClass::getModules(const QString &type, int typeLen) const
|
|
#elif defined Q_OS_WIN
|
|
if (type == "videoWriters")
|
|
defaultModules << "OpenGL 2" << "DirectDraw";
|
|
+#elif defined Q_OS_HAIKU
|
|
+ if ( type == "videoWriters" )
|
|
+ defaultModules << "QPainter";
|
|
+ else if ( type == "audioWriters" )
|
|
+ defaultModules << "MediaKit";
|
|
#endif
|
|
if (type == "decoders")
|
|
defaultModules << "FFmpeg Decoder";
|
|
--
|
|
2.30.2
|
|
|
|
|
|
From 96c5a6eae78d74dd5a3dbfe2b520cb745e073a00 Mon Sep 17 00:00:00 2001
|
|
From: Gerasim Troeglazov <3dEyes@gmail.com>
|
|
Date: Sun, 16 May 2021 23:14:06 +1000
|
|
Subject: Remove const for fix build
|
|
|
|
|
|
diff --git a/src/qmplay2/IPC_Unix.cpp b/src/qmplay2/IPC_Unix.cpp
|
|
index bac1b16..2bc3175 100644
|
|
--- a/src/qmplay2/IPC_Unix.cpp
|
|
+++ b/src/qmplay2/IPC_Unix.cpp
|
|
@@ -98,7 +98,7 @@ bool IPCSocket::open(QIODevice::OpenMode mode)
|
|
|
|
if (m_priv->fd > 0)
|
|
{
|
|
- const unsigned long on = 1;
|
|
+ unsigned long on = 1;
|
|
ioctl(m_priv->fd, FIONBIO, &on);
|
|
m_priv->socketNotifier = new QSocketNotifier(m_priv->fd, QSocketNotifier::Read, this);
|
|
connect(m_priv->socketNotifier, SIGNAL(activated(int)), this, SLOT(socketReadActive()));
|
|
--
|
|
2.30.2
|
|
|
|
|
|
From 52aae66a0243e19c1d109bd0acfaf6fd47cbf4ef Mon Sep 17 00:00:00 2001
|
|
From: Simon Vogl <simon.vogl@gmx.net>
|
|
Date: Thu, 1 Apr 2021 21:56:04 +0000
|
|
Subject: Fix YouTube Search for QMPlay2.
|
|
|
|
This patch is required to fix QMPlay2's YouTube Search function by using an empty Cookie.
|
|
|
|
diff --git a/src/modules/Extensions/YouTube.cpp b/src/modules/Extensions/YouTube.cpp
|
|
index 78ee675..c67c343 100644
|
|
--- a/src/modules/Extensions/YouTube.cpp
|
|
+++ b/src/modules/Extensions/YouTube.cpp
|
|
@@ -501,7 +501,7 @@ void YouTube::search()
|
|
if (lastTitle != title || sender() == searchE || sender() == searchB || qobject_cast<QAction *>(sender()))
|
|
{
|
|
m_currPage = 1;
|
|
- searchReply = net.start(getYtUrl(title, m_sortByIdx));
|
|
+ searchReply = net.start(getYtUrl(title, m_sortByIdx), QByteArray(), "Cookie: \r\n");
|
|
}
|
|
else
|
|
{
|
|
@@ -886,7 +886,7 @@ void YouTube::setSearchResults(const QJsonObject &jsonObj, bool isContinuation)
|
|
{
|
|
tWI->setDisabled(true);
|
|
|
|
- auto linkReply = net.start(url);
|
|
+ auto linkReply = net.start(url, QByteArray(), "Cookie: \r\n");
|
|
linkReply->setProperty("tWI", QVariant::fromValue((void *)tWI));
|
|
linkReplies += linkReply;
|
|
}
|
|
--
|
|
2.30.2
|
|
|
|
|
|
From 6e6269e47145e20c2a5b6153e5ec2e85a96ad618 Mon Sep 17 00:00:00 2001
|
|
From: Gerasim Troeglazov <3dEyes@gmail.com>
|
|
Date: Sun, 16 May 2021 23:34:03 +1000
|
|
Subject: Use system youtube-dl
|
|
|
|
|
|
diff --git a/src/qmplay2/YouTubeDL.cpp b/src/qmplay2/YouTubeDL.cpp
|
|
index 3319df0..8f6567f 100644
|
|
--- a/src/qmplay2/YouTubeDL.cpp
|
|
+++ b/src/qmplay2/YouTubeDL.cpp
|
|
@@ -36,9 +36,13 @@ static QMutex g_mutex(QMutex::Recursive);
|
|
|
|
QString YouTubeDL::getFilePath()
|
|
{
|
|
+#ifdef Q_OS_HAIKU
|
|
+ return "/bin/youtube-dl"
|
|
+#else
|
|
return QMPlay2Core.getSettingsDir() + "youtube-dl"
|
|
#ifdef Q_OS_WIN
|
|
".exe"
|
|
+#endif
|
|
#endif
|
|
;
|
|
}
|
|
@@ -257,6 +261,9 @@ void YouTubeDL::abort()
|
|
|
|
bool YouTubeDL::prepare()
|
|
{
|
|
+#ifdef Q_OS_HAIKU
|
|
+ return true;
|
|
+#endif
|
|
#ifdef Q_OS_ANDROID
|
|
return false;
|
|
#endif
|
|
@@ -303,6 +310,9 @@ bool YouTubeDL::prepare()
|
|
|
|
bool YouTubeDL::download()
|
|
{
|
|
+#if defined(Q_OS_HAIKU)
|
|
+ return true;
|
|
+#endif
|
|
// Mutex must be locked here
|
|
|
|
const QString downloadUrl = "https://yt-dl.org/downloads/latest/youtube-dl"
|
|
@@ -356,6 +366,9 @@ bool YouTubeDL::download()
|
|
}
|
|
bool YouTubeDL::update()
|
|
{
|
|
+#if defined(Q_OS_HAIKU)
|
|
+ return true;
|
|
+#endif
|
|
// Mutex must be locked here
|
|
|
|
qDebug() << "\"youtube-dl\" updates will be checked";
|
|
@@ -425,7 +438,7 @@ bool YouTubeDL::update()
|
|
|
|
void YouTubeDL::ensureExecutable()
|
|
{
|
|
-#ifndef Q_OS_WIN
|
|
+#if !defined(Q_OS_WIN) && !defined(Q_OS_HAIKU)
|
|
if (!QFileInfo(m_ytDlPath).isExecutable())
|
|
{
|
|
QFile file(m_ytDlPath);
|
|
--
|
|
2.30.2
|
|
|