mirror of
https://github.com/yann64/haikuports.git
synced 2026-05-06 06:58:57 +02:00
905 lines
22 KiB
Plaintext
905 lines
22 KiB
Plaintext
From b8f87b0bf8795dbf815311f825a7f9f6ca5f42ff Mon Sep 17 00:00:00 2001
|
|
From: Gerasim Troeglazov <3dEyes@gmail.com>
|
|
Date: Sat, 18 Dec 2021 21:36:25 +1000
|
|
Subject: Add haiku support
|
|
|
|
|
|
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
|
index 210b1fa..7cfa9ee 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")
|
|
|
|
@@ -166,7 +169,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 1360cba..73d4cd8 100644
|
|
--- a/src/gui/Main.cpp
|
|
+++ b/src/gui/Main.cpp
|
|
@@ -606,6 +606,10 @@ int main(int argc, char *argv[])
|
|
|
|
qputenv("QT_QPA_UPDATE_IDLE_TIME", "0");
|
|
|
|
+#ifdef Q_OS_HAIKU
|
|
+ setenv("HOME", "/boot/home", 1);
|
|
+#endif
|
|
+
|
|
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
|
#ifndef USE_OPENGL
|
|
QGuiApplication::setAttribute(Qt::AA_ForceRasterWidgets);
|
|
@@ -707,7 +711,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"))
|
|
@@ -913,5 +917,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 7aa180a..a50e01c 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/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()));
|
|
diff --git a/src/qmplay2/QMPlay2Core.cpp b/src/qmplay2/QMPlay2Core.cpp
|
|
index 5cf15b9..aacaade 100644
|
|
--- a/src/qmplay2/QMPlay2Core.cpp
|
|
+++ b/src/qmplay2/QMPlay2Core.cpp
|
|
@@ -45,7 +45,7 @@
|
|
#include <powrprof.h>
|
|
#elif defined Q_OS_MACOS
|
|
#include <QOperatingSystemVersion>
|
|
-#elif !defined Q_OS_ANDROID
|
|
+#elif !defined Q_OS_ANDROID && !defined Q_OS_HAIKU
|
|
#include <QDBusConnection>
|
|
#include <QDBusInterface>
|
|
#endif
|
|
@@ -243,7 +243,7 @@ void QMPlay2CoreClass::init(bool loadModules, bool modulesInSubdirs, const QStri
|
|
}
|
|
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::AppDataLocation).value(0));
|
|
@@ -491,6 +491,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";
|
|
diff --git a/src/qmplay2/YouTubeDL.cpp b/src/qmplay2/YouTubeDL.cpp
|
|
index 5659018..63256fa 100644
|
|
--- a/src/qmplay2/YouTubeDL.cpp
|
|
+++ b/src/qmplay2/YouTubeDL.cpp
|
|
@@ -37,9 +37,13 @@ static QMutex g_mutex(QMutex::Recursive);
|
|
|
|
QString YouTubeDL::getFilePath()
|
|
{
|
|
+#ifdef Q_OS_HAIKU
|
|
+ return "/bin/yt-dlp"
|
|
+#else
|
|
return QMPlay2Core.getSettingsDir() + "yt-dlp"
|
|
#ifdef Q_OS_WIN
|
|
"_x86.exe"
|
|
+#endif
|
|
#endif
|
|
;
|
|
}
|
|
@@ -258,6 +262,9 @@ void YouTubeDL::abort()
|
|
|
|
bool YouTubeDL::prepare()
|
|
{
|
|
+#ifdef Q_OS_HAIKU
|
|
+ return true;
|
|
+#endif
|
|
#ifdef Q_OS_ANDROID
|
|
return false;
|
|
#endif
|
|
@@ -304,6 +311,9 @@ bool YouTubeDL::prepare()
|
|
|
|
bool YouTubeDL::download()
|
|
{
|
|
+#if defined(Q_OS_HAIKU)
|
|
+ return true;
|
|
+#endif
|
|
// Mutex must be locked here
|
|
|
|
const QString downloadUrl = "https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp"
|
|
@@ -357,6 +367,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";
|
|
@@ -408,7 +421,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
|
|
|
|
|
|
From ec53a2afe9e2e59c2322f591a65894bd2fecadd6 Mon Sep 17 00:00:00 2001
|
|
From: Jerome Duval <jerome.duval@gmail.com>
|
|
Date: Tue, 22 Feb 2022 16:52:40 +0100
|
|
Subject: ffmpeg5 build fix
|
|
|
|
|
|
diff --git a/src/modules/CUVID/CuvidDec.cpp b/src/modules/CUVID/CuvidDec.cpp
|
|
index 65a7b8d..b503ffb 100644
|
|
--- a/src/modules/CUVID/CuvidDec.cpp
|
|
+++ b/src/modules/CUVID/CuvidDec.cpp
|
|
@@ -431,7 +431,7 @@ bool CuvidDec::open(StreamInfo &streamInfo)
|
|
if (streamInfo.codec_type != AVMEDIA_TYPE_VIDEO)
|
|
return false;
|
|
|
|
- AVCodec *avCodec = avcodec_find_decoder_by_name(streamInfo.codec_name);
|
|
+ auto avCodec = const_cast<AVCodec *>(avcodec_find_decoder_by_name(streamInfo.codec_name));
|
|
if (!avCodec)
|
|
return false;
|
|
|
|
diff --git a/src/modules/CUVID/CuvidDec.hpp b/src/modules/CUVID/CuvidDec.hpp
|
|
index 972cbb5..6f7dc68 100644
|
|
--- a/src/modules/CUVID/CuvidDec.hpp
|
|
+++ b/src/modules/CUVID/CuvidDec.hpp
|
|
@@ -26,6 +26,9 @@
|
|
#include <QCoreApplication>
|
|
#include <QQueue>
|
|
|
|
+extern "C" {
|
|
+ #include <libavcodec/bsf.h>
|
|
+}
|
|
class CuvidHWInterop;
|
|
class VideoWriter;
|
|
|
|
diff --git a/src/modules/FFmpeg/FFDec.cpp b/src/modules/FFmpeg/FFDec.cpp
|
|
index 0b2dae2..571465a 100644
|
|
--- a/src/modules/FFmpeg/FFDec.cpp
|
|
+++ b/src/modules/FFmpeg/FFDec.cpp
|
|
@@ -70,7 +70,7 @@ void FFDec::clearFrames()
|
|
|
|
AVCodec *FFDec::init(StreamInfo &streamInfo)
|
|
{
|
|
- AVCodec *codec = avcodec_find_decoder_by_name(streamInfo.codec_name);
|
|
+ auto codec = const_cast<AVCodec*>(avcodec_find_decoder_by_name(streamInfo.codec_name));
|
|
if (codec)
|
|
{
|
|
codec_ctx = avcodec_alloc_context3(codec);
|
|
diff --git a/src/modules/FFmpeg/FormatContext.cpp b/src/modules/FFmpeg/FormatContext.cpp
|
|
index 0996f9a..c241e7b 100644
|
|
--- a/src/modules/FFmpeg/FormatContext.cpp
|
|
+++ b/src/modules/FFmpeg/FormatContext.cpp
|
|
@@ -687,7 +687,7 @@ bool FormatContext::open(const QString &_url, const QString ¶m)
|
|
if (scheme != "rtsp")
|
|
{
|
|
// It is needed for QMPlay2 schemes like "alsa://", "v4l2://", etc.
|
|
- inputFmt = av_find_input_format(scheme);
|
|
+ inputFmt = const_cast<AVInputFormat*>(av_find_input_format(scheme));
|
|
if (inputFmt)
|
|
url = _url.right(_url.length() - scheme.length() - 3);
|
|
}
|
|
--
|
|
2.30.2
|
|
|