From 52abcc29decdce8a85755753a1a69ba921af9965 Mon Sep 17 00:00:00 2001 From: dridri Date: Wed, 10 Jul 2013 01:23:56 +0000 Subject: [PATCH 01/43] Added Equalizer support on AudioEngine class Two public methods added : * int equalizerBandCount() * bool setEqualizerBand(int band, int value) One private method : * void initEqualizer() Settings and GUI must be made in an external plugin --- src/libtomahawk/audio/AudioEngine.cpp | 29 +++++++++++++-------------- src/libtomahawk/audio/AudioEngine.h | 3 ++- src/libtomahawk/audio/AudioEngine_p.h | 5 +++-- 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/libtomahawk/audio/AudioEngine.cpp b/src/libtomahawk/audio/AudioEngine.cpp index 4efec2257..a14a0284d 100644 --- a/src/libtomahawk/audio/AudioEngine.cpp +++ b/src/libtomahawk/audio/AudioEngine.cpp @@ -224,8 +224,6 @@ AudioEngine::AudioEngine() d->mediaObject = new Phonon::MediaObject( this ); d->audioOutput = new Phonon::AudioOutput( Phonon::MusicCategory, this ); - d->audioDataOutput = new Phonon::AudioDataOutput( this ); - d->audioPath = Phonon::createPath( d->mediaObject, d->audioOutput ); d->mediaObject->setTickInterval( 150 ); @@ -238,7 +236,7 @@ AudioEngine::AudioEngine() onVolumeChanged( d->audioOutput->volume() ); setVolume( TomahawkSettings::instance()->volume() ); - // initEqualizer(); + initEqualizer(); } @@ -1390,13 +1388,14 @@ AudioEngine::initEqualizer() { Q_D( AudioEngine ); - QList< Phonon::EffectDescription > effectDescriptions = Phonon::BackendCapabilities::availableAudioEffects(); - foreach ( Phonon::EffectDescription effectDesc, effectDescriptions ) + QList effectDescriptions = Phonon::BackendCapabilities::availableAudioEffects(); + d->audioEffect = NULL; + foreach(Phonon::EffectDescription effectDesc, effectDescriptions) { - if ( effectDesc.name().toLower().contains( "eq" ) ) + if(effectDesc.name().contains("Eq") || effectDesc.name().contains("eq")) { - d->audioEffect = new Phonon::Effect( effectDesc ); - d->audioPath.insertEffect( d->audioEffect ); + d->audioEffect = new Phonon::Effect(effectDesc); + d->audioPath.insertEffect(d->audioEffect); break; } } @@ -1408,9 +1407,9 @@ AudioEngine::equalizerBandCount() { Q_D( AudioEngine ); - if ( d->audioEffect ) + if (d->audioEffect) { - QList< Phonon::EffectParameter > params = d->audioEffect->parameters(); + QList params = d->audioEffect->parameters(); return params.size(); } @@ -1419,16 +1418,16 @@ AudioEngine::equalizerBandCount() bool -AudioEngine::setEqualizerBand( int band, int value ) +AudioEngine::setEqualizerBand(int band, int value) { Q_D( AudioEngine ); - if ( d->audioEffect ) + if (d->audioEffect) { - QList< Phonon::EffectParameter > params = d->audioEffect->parameters(); - if ( band < params.size() ) + QList params = d->audioEffect->parameters(); + if (band < params.size()) { - d->audioEffect->setParameterValue( params.at( band ), value ); + d->audioEffect->setParameterValue(params.at(band), value); return true; } } diff --git a/src/libtomahawk/audio/AudioEngine.h b/src/libtomahawk/audio/AudioEngine.h index d8363334e..f04a4b877 100644 --- a/src/libtomahawk/audio/AudioEngine.h +++ b/src/libtomahawk/audio/AudioEngine.h @@ -110,7 +110,7 @@ public: qint64 currentTrackTotalTime() const; int equalizerBandCount(); - bool setEqualizerBand( int band, int value ); + bool setEqualizerBand(int band, int value); public slots: void playPause(); @@ -200,6 +200,7 @@ private slots: private: void setState( AudioState state ); void setCurrentTrackPlaylist( const Tomahawk::playlistinterface_ptr& playlist ); + void initEqualizer(); void initEqualizer(); void audioDataArrived( QMap< AudioEngine::AudioChannel, QVector< qint16 > >& data ); diff --git a/src/libtomahawk/audio/AudioEngine_p.h b/src/libtomahawk/audio/AudioEngine_p.h index cfe1f3695..0ce7b57f5 100644 --- a/src/libtomahawk/audio/AudioEngine_p.h +++ b/src/libtomahawk/audio/AudioEngine_p.h @@ -1,9 +1,8 @@ #include #include -#include -#include #include +#include #include #include @@ -44,6 +43,8 @@ private: Phonon::MediaObject* mediaObject; Phonon::AudioOutput* audioOutput; + Phonon::Path audioPath; + Phonon::Effect* audioEffect; Phonon::Path audioPath; Phonon::Effect* audioEffect; From db7b2a310f34268163595484fa76ff8b4bb50e01 Mon Sep 17 00:00:00 2001 From: dridri Date: Wed, 10 Jul 2013 01:48:04 +0000 Subject: [PATCH 02/43] Fixed minor things --- src/libtomahawk/audio/AudioEngine.cpp | 3 +-- src/libtomahawk/audio/AudioEngine_p.h | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/libtomahawk/audio/AudioEngine.cpp b/src/libtomahawk/audio/AudioEngine.cpp index a14a0284d..bcc73af3f 100644 --- a/src/libtomahawk/audio/AudioEngine.cpp +++ b/src/libtomahawk/audio/AudioEngine.cpp @@ -1389,10 +1389,9 @@ AudioEngine::initEqualizer() Q_D( AudioEngine ); QList effectDescriptions = Phonon::BackendCapabilities::availableAudioEffects(); - d->audioEffect = NULL; foreach(Phonon::EffectDescription effectDesc, effectDescriptions) { - if(effectDesc.name().contains("Eq") || effectDesc.name().contains("eq")) + if(effectDesc.name().toLower().contains("eq")) { d->audioEffect = new Phonon::Effect(effectDesc); d->audioPath.insertEffect(d->audioEffect); diff --git a/src/libtomahawk/audio/AudioEngine_p.h b/src/libtomahawk/audio/AudioEngine_p.h index 0ce7b57f5..be87094fa 100644 --- a/src/libtomahawk/audio/AudioEngine_p.h +++ b/src/libtomahawk/audio/AudioEngine_p.h @@ -44,7 +44,7 @@ private: Phonon::MediaObject* mediaObject; Phonon::AudioOutput* audioOutput; Phonon::Path audioPath; - Phonon::Effect* audioEffect; + Phonon::Effect* audioEffect; Phonon::Path audioPath; Phonon::Effect* audioEffect; From 3fd8939297be9a11d2b52235c4c94b4a54f1f08e Mon Sep 17 00:00:00 2001 From: dridri Date: Wed, 10 Jul 2013 01:53:54 +0000 Subject: [PATCH 03/43] Code now should fit Tomahawk's standard --- src/libtomahawk/audio/AudioEngine.cpp | 24 ++++++++++++------------ src/libtomahawk/audio/AudioEngine.h | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/libtomahawk/audio/AudioEngine.cpp b/src/libtomahawk/audio/AudioEngine.cpp index bcc73af3f..f298ffd68 100644 --- a/src/libtomahawk/audio/AudioEngine.cpp +++ b/src/libtomahawk/audio/AudioEngine.cpp @@ -1388,13 +1388,13 @@ AudioEngine::initEqualizer() { Q_D( AudioEngine ); - QList effectDescriptions = Phonon::BackendCapabilities::availableAudioEffects(); - foreach(Phonon::EffectDescription effectDesc, effectDescriptions) + QList< Phonon::EffectDescription > effectDescriptions = Phonon::BackendCapabilities::availableAudioEffects(); + foreach ( Phonon::EffectDescription effectDesc, effectDescriptions ) { - if(effectDesc.name().toLower().contains("eq")) + if ( effectDesc.name().toLower().contains( "eq" ) ) { - d->audioEffect = new Phonon::Effect(effectDesc); - d->audioPath.insertEffect(d->audioEffect); + d->audioEffect = new Phonon::Effect( effectDesc ); + d->audioPath.insertEffect( d->audioEffect ); break; } } @@ -1406,9 +1406,9 @@ AudioEngine::equalizerBandCount() { Q_D( AudioEngine ); - if (d->audioEffect) + if ( d->audioEffect ) { - QList params = d->audioEffect->parameters(); + QList< Phonon::EffectParameter > params = d->audioEffect->parameters(); return params.size(); } @@ -1417,16 +1417,16 @@ AudioEngine::equalizerBandCount() bool -AudioEngine::setEqualizerBand(int band, int value) +AudioEngine::setEqualizerBand( int band, int value ) { Q_D( AudioEngine ); - if (d->audioEffect) + if ( d->audioEffect ) { - QList params = d->audioEffect->parameters(); - if (band < params.size()) + QList< Phonon::EffectParameter > params = d->audioEffect->parameters(); + if ( band < params.size() ) { - d->audioEffect->setParameterValue(params.at(band), value); + d->audioEffect->setParameterValue( params.at(band), value ); return true; } } diff --git a/src/libtomahawk/audio/AudioEngine.h b/src/libtomahawk/audio/AudioEngine.h index f04a4b877..25a0c5c07 100644 --- a/src/libtomahawk/audio/AudioEngine.h +++ b/src/libtomahawk/audio/AudioEngine.h @@ -110,7 +110,7 @@ public: qint64 currentTrackTotalTime() const; int equalizerBandCount(); - bool setEqualizerBand(int band, int value); + bool setEqualizerBand( int band, int value ); public slots: void playPause(); From 736f6fefb60eaaa3086a096fb43a79d75402d6b3 Mon Sep 17 00:00:00 2001 From: dridri Date: Wed, 10 Jul 2013 01:56:43 +0000 Subject: [PATCH 04/43] Now it really should fit standard :P --- src/libtomahawk/audio/AudioEngine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libtomahawk/audio/AudioEngine.cpp b/src/libtomahawk/audio/AudioEngine.cpp index f298ffd68..c844229cc 100644 --- a/src/libtomahawk/audio/AudioEngine.cpp +++ b/src/libtomahawk/audio/AudioEngine.cpp @@ -1426,7 +1426,7 @@ AudioEngine::setEqualizerBand( int band, int value ) QList< Phonon::EffectParameter > params = d->audioEffect->parameters(); if ( band < params.size() ) { - d->audioEffect->setParameterValue( params.at(band), value ); + d->audioEffect->setParameterValue( params.at( band ), value ); return true; } } From 9bb7a06256dd3fc1682b43c3d3cfb383adf8961f Mon Sep 17 00:00:00 2001 From: dridri Date: Sun, 28 Sep 2014 13:36:32 +0200 Subject: [PATCH 05/43] Added DSP callback support for VLC phonon --- src/libtomahawk/audio/AudioEngine.cpp | 53 ++++++++------------------- src/libtomahawk/audio/AudioEngine.h | 7 ++-- src/libtomahawk/audio/AudioEngine_p.h | 4 +- 3 files changed, 20 insertions(+), 44 deletions(-) diff --git a/src/libtomahawk/audio/AudioEngine.cpp b/src/libtomahawk/audio/AudioEngine.cpp index c844229cc..64e9d220e 100644 --- a/src/libtomahawk/audio/AudioEngine.cpp +++ b/src/libtomahawk/audio/AudioEngine.cpp @@ -215,6 +215,7 @@ AudioEngine::AudioEngine() d->state = Stopped; d->coverTempFile = 0; d->audioEffect = 0; + d->dspPluginCallback = 0; d->s_instance = this; tDebug() << "Init AudioEngine"; @@ -236,7 +237,7 @@ AudioEngine::AudioEngine() onVolumeChanged( d->audioOutput->volume() ); setVolume( TomahawkSettings::instance()->volume() ); - initEqualizer(); + d->mediaObject->setCurrentSource(Phonon::MediaSource("PhononDSP::effectCallback=" + QString::number((qulonglong)&AudioEngine::dspCallback, 16))); } @@ -1384,52 +1385,28 @@ AudioEngine::setCurrentTrackPlaylist( const playlistinterface_ptr& playlist ) void -AudioEngine::initEqualizer() +AudioEngine::dspCallback( signed short* samples, int nb_channels, int nb_samples ) +{ + AudioEngine::instance()->dspCallbackInternal( samples, nb_channels, nb_samples ); +} + + +void +AudioEngine::dspCallbackInternal( signed short* samples, int nb_channels, int nb_samples ) { Q_D( AudioEngine ); - QList< Phonon::EffectDescription > effectDescriptions = Phonon::BackendCapabilities::availableAudioEffects(); - foreach ( Phonon::EffectDescription effectDesc, effectDescriptions ) + if ( d->dspPluginCallback != 0 ) { - if ( effectDesc.name().toLower().contains( "eq" ) ) - { - d->audioEffect = new Phonon::Effect( effectDesc ); - d->audioPath.insertEffect( d->audioEffect ); - break; - } + d->dspPluginCallback( samples, nb_channels, nb_samples ); } } -int -AudioEngine::equalizerBandCount() +void +AudioEngine::setDspCallback( void ( *cb ) ( signed short*, int, int ) ) { Q_D( AudioEngine ); - if ( d->audioEffect ) - { - QList< Phonon::EffectParameter > params = d->audioEffect->parameters(); - return params.size(); - } - - return 0; -} - - -bool -AudioEngine::setEqualizerBand( int band, int value ) -{ - Q_D( AudioEngine ); - - if ( d->audioEffect ) - { - QList< Phonon::EffectParameter > params = d->audioEffect->parameters(); - if ( band < params.size() ) - { - d->audioEffect->setParameterValue( params.at( band ), value ); - return true; - } - } - - return false; + d->dspPluginCallback = cb; } diff --git a/src/libtomahawk/audio/AudioEngine.h b/src/libtomahawk/audio/AudioEngine.h index 25a0c5c07..db9ca1884 100644 --- a/src/libtomahawk/audio/AudioEngine.h +++ b/src/libtomahawk/audio/AudioEngine.h @@ -109,8 +109,7 @@ public: */ qint64 currentTrackTotalTime() const; - int equalizerBandCount(); - bool setEqualizerBand( int band, int value ); + void setDspCallback( void ( *cb ) ( signed short* samples, int nb_channels, int nb_samples ) ); public slots: void playPause(); @@ -200,9 +199,9 @@ private slots: private: void setState( AudioState state ); void setCurrentTrackPlaylist( const Tomahawk::playlistinterface_ptr& playlist ); - void initEqualizer(); - void initEqualizer(); + static void dspCallback( signed short* samples, int nb_channels, int nb_samples ); + void dspCallbackInternal( signed short* samples, int nb_channels, int nb_samples ); void audioDataArrived( QMap< AudioEngine::AudioChannel, QVector< qint16 > >& data ); diff --git a/src/libtomahawk/audio/AudioEngine_p.h b/src/libtomahawk/audio/AudioEngine_p.h index be87094fa..b03338634 100644 --- a/src/libtomahawk/audio/AudioEngine_p.h +++ b/src/libtomahawk/audio/AudioEngine_p.h @@ -43,8 +43,6 @@ private: Phonon::MediaObject* mediaObject; Phonon::AudioOutput* audioOutput; - Phonon::Path audioPath; - Phonon::Effect* audioEffect; Phonon::Path audioPath; Phonon::Effect* audioEffect; @@ -68,5 +66,7 @@ private: QTemporaryFile* coverTempFile; + void (* dspPluginCallback )( signed short* samples, int nb_channels, int nb_samples ); + static AudioEngine* s_instance; }; From f25a3715dae61916512c91d7ccd9200a4ef08c17 Mon Sep 17 00:00:00 2001 From: dridri Date: Mon, 29 Sep 2014 23:22:39 +0200 Subject: [PATCH 06/43] first draft to get rid of phonon and directly use LibVLC --- CMakeLists.txt | 19 +- CMakeModules/FindLIBVLC.cmake | 93 ++++++ src/libtomahawk/CMakeLists.txt | 4 + src/libtomahawk/audio/AudioEngine.cpp | 183 ++++------- src/libtomahawk/audio/AudioEngine.h | 6 +- src/libtomahawk/audio/AudioEngine_p.h | 12 +- src/libtomahawk/audio/AudioOutput.cpp | 320 +++++++++++++++++++ src/libtomahawk/audio/AudioOutput.h | 87 +++++ src/libtomahawk/utils/MediaStream.cpp | 128 ++++++++ src/libtomahawk/utils/MediaStream.h | 63 ++++ src/libtomahawk/utils/Qnr_IoDeviceStream.cpp | 57 ++-- src/libtomahawk/utils/Qnr_IoDeviceStream.h | 12 +- 12 files changed, 802 insertions(+), 182 deletions(-) create mode 100644 CMakeModules/FindLIBVLC.cmake create mode 100644 src/libtomahawk/audio/AudioOutput.cpp create mode 100644 src/libtomahawk/audio/AudioOutput.h create mode 100644 src/libtomahawk/utils/MediaStream.cpp create mode 100644 src/libtomahawk/utils/MediaStream.h diff --git a/CMakeLists.txt b/CMakeLists.txt index c8154c256..99f3111d2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -346,6 +346,9 @@ endif() macro_log_feature(LIBSNORE_FOUND "Libsnore" "Library for notifications" "https://github.com/TheOneRing/Snorenotify" FALSE "" "") endif() +find_package(LIBVLC REQUIRED) +macro_log_feature(LIBVLC_FOUND "LibVLC" "Provides audio output" TRUE "" "") + set(QXTWEB_FOUND TRUE) set(QXTWEB_LIBRARIES qxtweb-standalone) set(QXTWEB_INCLUDE_DIRS ${THIRDPARTY_DIR}/qxt/qxtweb-standalone/web ${THIRDPARTY_DIR}/qxt/qxtweb-standalone/network ${THIRDPARTY_DIR}/qxt/qxtweb-standalone/core ${CMAKE_CURRENT_BINARY_DIR}) @@ -377,15 +380,15 @@ if (WITH_KDE4) endif(WITH_KDE4) macro_log_feature(KDE4_FOUND "KDE4" "Provides support for configuring Telepathy Accounts from inside Tomahawk" "https://www.kde.org" FALSE "" "") -if(NOT Phonon_FOUND) - macro_optional_find_package(Phonon 4.5.0) -endif() -macro_log_feature(Phonon_FOUND "Phonon" "The Phonon multimedia library" "http://phonon.kde.org" TRUE "" "") - -if(Phonon_FOUND) - message(STATUS "Phonon found; ensure that phonon-vlc is at least 0.4") -endif() +# if(NOT Phonon_FOUND) +# macro_optional_find_package(Phonon 4.5.0) +# endif() +# macro_log_feature(Phonon_FOUND "Phonon" "The Phonon multimedia library" "http://phonon.kde.org" TRUE "" "") +# if(Phonon_FOUND) +# message(STATUS "Phonon found; ensure that phonon-vlc is at least 0.4") +# endif() +# IF( KDE4_FOUND OR Phonon_FOUND ) IF( CMAKE_C_FLAGS ) # KDE4 adds and removes some compiler flags that we don't like diff --git a/CMakeModules/FindLIBVLC.cmake b/CMakeModules/FindLIBVLC.cmake new file mode 100644 index 000000000..2a31e9128 --- /dev/null +++ b/CMakeModules/FindLIBVLC.cmake @@ -0,0 +1,93 @@ + +# CMake module to search for LIBVLC (VLC library) +# Authors: Rohit Yadav +# Harald Sitter +# +# If it's found it sets LIBVLC_FOUND to TRUE +# and following variables are set: +# LIBVLC_INCLUDE_DIR +# LIBVLC_LIBRARY +# LIBVLC_VERSION + +if(NOT LIBVLC_MIN_VERSION) + set(LIBVLC_MIN_VERSION "0.0") +endif(NOT LIBVLC_MIN_VERSION) + +# find_path and find_library normally search standard locations +# before the specified paths. To search non-standard paths first, +# FIND_* is invoked first with specified paths and NO_DEFAULT_PATH +# and then again with no specified paths to search the default +# locations. When an earlier FIND_* succeeds, subsequent FIND_*s +# searching for the same item do nothing. + +if (NOT WIN32) + find_package(PkgConfig) + pkg_check_modules(PC_LIBVLC libvlc) + set(LIBVLC_DEFINITIONS ${PC_LIBVLC_CFLAGS_OTHER}) +endif (NOT WIN32) + +#Put here path to custom location +#example: /home/user/vlc/include etc.. +find_path(LIBVLC_INCLUDE_DIR vlc/vlc.h +HINTS "$ENV{LIBVLC_INCLUDE_PATH}" +PATHS + "$ENV{LIB_DIR}/include" + "$ENV{LIB_DIR}/include/vlc" + "/usr/include" + "/usr/include/vlc" + "/usr/local/include" + "/usr/local/include/vlc" + #mingw + c:/msys/local/include +) +find_path(LIBVLC_INCLUDE_DIR PATHS "${CMAKE_INCLUDE_PATH}/vlc" NAMES vlc.h + HINTS ${PC_LIBVLC_INCLUDEDIR} ${PC_LIBVLC_INCLUDE_DIRS}) + +#Put here path to custom location +#example: /home/user/vlc/lib etc.. +find_library(LIBVLC_LIBRARY NAMES vlc libvlc +HINTS "$ENV{LIBVLC_LIBRARY_PATH}" ${PC_LIBVLC_LIBDIR} ${PC_LIBVLC_LIBRARY_DIRS} +PATHS + "$ENV{LIB_DIR}/lib" + #mingw + c:/msys/local/lib +) +find_library(LIBVLC_LIBRARY NAMES vlc libvlc) +find_library(LIBVLCCORE_LIBRARY NAMES vlccore libvlccore +HINTS "$ENV{LIBVLC_LIBRARY_PATH}" ${PC_LIBVLC_LIBDIR} ${PC_LIBVLC_LIBRARY_DIRS} +PATHS + "$ENV{LIB_DIR}/lib" + #mingw + c:/msys/local/lib +) +find_library(LIBVLCCORE_LIBRARY NAMES vlccore libvlccore) + +set(LIBVLC_VERSION ${PC_LIBVLC_VERSION}) +if (NOT LIBVLC_VERSION) +# TODO: implement means to detect version on windows (vlc --version && regex? ... ultimately we would get it from a header though...) +endif (NOT LIBVLC_VERSION) + +if (LIBVLC_INCLUDE_DIR AND LIBVLC_LIBRARY AND LIBVLCCORE_LIBRARY) +set(LIBVLC_FOUND TRUE) +endif (LIBVLC_INCLUDE_DIR AND LIBVLC_LIBRARY AND LIBVLCCORE_LIBRARY) + +if (LIBVLC_VERSION STRLESS "${LIBVLC_MIN_VERSION}") + message(WARNING "LibVLC version not found: version searched: ${LIBVLC_MIN_VERSION}, found ${LIBVLC_VERSION}\nUnless you are on Windows this is bound to fail.") +# TODO: only activate once version detection can be garunteed (which is currently not the case on windows) +# set(LIBVLC_FOUND FALSE) +endif (LIBVLC_VERSION STRLESS "${LIBVLC_MIN_VERSION}") + +if (LIBVLC_FOUND) + if (NOT LIBVLC_FIND_QUIETLY) + message(STATUS "Found LibVLC include-dir path: ${LIBVLC_INCLUDE_DIR}") + message(STATUS "Found LibVLC library path:${LIBVLC_LIBRARY}") + message(STATUS "Found LibVLCcore library path:${LIBVLCCORE_LIBRARY}") + message(STATUS "Found LibVLC version: ${LIBVLC_VERSION} (searched for: ${LIBVLC_MIN_VERSION})") + endif (NOT LIBVLC_FIND_QUIETLY) +else (LIBVLC_FOUND) + if (LIBVLC_FIND_REQUIRED) + message(FATAL_ERROR "Could not find LibVLC") + endif (LIBVLC_FIND_REQUIRED) +endif (LIBVLC_FOUND) + + diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt index a6ea0d840..d4b05cb3c 100644 --- a/src/libtomahawk/CMakeLists.txt +++ b/src/libtomahawk/CMakeLists.txt @@ -214,6 +214,7 @@ list(APPEND libSources accounts/spotify/SpotifyInfoPlugin.cpp audio/AudioEngine.cpp + audio/AudioOutput.cpp collection/Collection.cpp collection/ArtistsRequest.cpp @@ -353,6 +354,7 @@ list(APPEND libSources utils/WeakObjectHash.cpp utils/WeakObjectList.cpp utils/PluginLoader.cpp + utils/MediaStream.cpp ) add_subdirectory( accounts/configstorage ) @@ -390,6 +392,7 @@ include_directories( ${ECHONEST_INCLUDE_DIR} ${LUCENEPP_INCLUDE_DIRS} ${PHONON_INCLUDES} + ${LIBVLC_INCLUDES} ${Boost_INCLUDE_DIR} ${LIBPORTFWD_INCLUDE_DIR} @@ -502,6 +505,7 @@ ENDIF( UNIX AND NOT APPLE ) TARGET_LINK_LIBRARIES( tomahawklib LINK_PRIVATE ${PHONON_LIBRARY} + ${LIBVLC_LIBRARY} # Thirdparty shipped with tomahawk ${LIBPORTFWD_LIBRARIES} diff --git a/src/libtomahawk/audio/AudioEngine.cpp b/src/libtomahawk/audio/AudioEngine.cpp index 64e9d220e..8e221c729 100644 --- a/src/libtomahawk/audio/AudioEngine.cpp +++ b/src/libtomahawk/audio/AudioEngine.cpp @@ -53,16 +53,16 @@ static QString s_aeInfoIdentifier = QString( "AUDIOENGINE" ); void -AudioEnginePrivate::onStateChanged( Phonon::State newState, Phonon::State oldState ) +AudioEnginePrivate::onStateChanged( AudioOutput::AudioState newState, AudioOutput::AudioState oldState ) { - tDebug( LOGVERBOSE ) << Q_FUNC_INFO << oldState << newState << expectStop << q_ptr->state(); + tDebug() << Q_FUNC_INFO << oldState << newState << expectStop << q_ptr->state(); - if ( newState == Phonon::LoadingState ) + if ( newState == AudioOutput::Loading ) { // We don't emit this state to listeners - yet. state = AudioEngine::Loading; } - if ( newState == Phonon::BufferingState ) + if ( newState == AudioOutput::Buffering ) { if ( underrunCount > UNDERRUNTHRESHOLD && !underrunNotified ) { @@ -72,16 +72,16 @@ AudioEnginePrivate::onStateChanged( Phonon::State newState, Phonon::State oldSta else underrunCount++; } - if ( newState == Phonon::ErrorState ) + if ( newState == AudioOutput::Error ) { q_ptr->stop( AudioEngine::UnknownError ); - tDebug() << "Phonon Error:" << mediaObject->errorString() << mediaObject->errorType(); +//TODO tDebug() << "Phonon Error:" << audioOutput->errorString() << audioOutput->errorType(); emit q_ptr->error( AudioEngine::UnknownError ); q_ptr->setState( AudioEngine::Error ); } - if ( newState == Phonon::PlayingState ) + if ( newState == AudioOutput::Playing ) { bool emitSignal = false; if ( q_ptr->state() != AudioEngine::Paused && q_ptr->state() != AudioEngine::Playing ) @@ -95,23 +95,23 @@ AudioEnginePrivate::onStateChanged( Phonon::State newState, Phonon::State oldSta if ( emitSignal ) emit q_ptr->started( currentTrack ); } - if ( newState == Phonon::StoppedState && oldState == Phonon::PausedState ) + if ( newState == AudioOutput::Stopped && oldState == AudioOutput::Paused ) { // GStreamer backend hack: instead of going from PlayingState to StoppedState, it traverses PausedState q_ptr->setState( AudioEngine::Stopped ); } - if ( oldState == Phonon::PlayingState ) + if ( oldState == AudioOutput::Playing ) { bool stopped = false; switch ( newState ) { - case Phonon::PausedState: + case AudioOutput::Paused: { - if ( mediaObject && currentTrack ) - { - qint64 duration = mediaObject->totalTime() > 0 ? mediaObject->totalTime() : currentTrack->track()->duration() * 1000; - stopped = ( duration - 1000 < mediaObject->currentTime() ); + if ( audioOutput && currentTrack ) + {/* TODO + qint64 duration = audioOutput->totalTime() > 0 ? audioOutput->totalTime() : currentTrack->track()->duration() * 1000; + stopped = ( duration - 1000 < audioOutput->currentTime() ); */ } else stopped = true; @@ -121,7 +121,7 @@ AudioEnginePrivate::onStateChanged( Phonon::State newState, Phonon::State oldSta break; } - case Phonon::StoppedState: + case AudioOutput::Stopped: { stopped = true; break; @@ -158,40 +158,12 @@ AudioEnginePrivate::onStateChanged( Phonon::State newState, Phonon::State oldSta } } - +/* void AudioEnginePrivate::onAudioDataArrived( QMap > data ) { - QMap< AudioEngine::AudioChannel, QVector< qint16 > > result; - - if( data.contains( Phonon::AudioDataOutput::LeftChannel ) ) - { - result[ AudioEngine::LeftChannel ] = QVector< qint16 >( data[ Phonon::AudioDataOutput::LeftChannel ] ); - } - if( data.contains( Phonon::AudioDataOutput::LeftSurroundChannel ) ) - { - result[ AudioEngine::LeftChannel ] = QVector< qint16 >( data[ Phonon::AudioDataOutput::LeftSurroundChannel ] ); - } - if( data.contains( Phonon::AudioDataOutput::RightChannel ) ) - { - result[ AudioEngine::RightChannel ] = QVector< qint16 >( data[ Phonon::AudioDataOutput::RightChannel ] ); - } - if( data.contains( Phonon::AudioDataOutput::RightSurroundChannel ) ) - { - result[ AudioEngine::LeftChannel ] = QVector< qint16 >( data[ Phonon::AudioDataOutput::RightSurroundChannel ] ); - } - if( data.contains( Phonon::AudioDataOutput::CenterChannel ) ) - { - result[ AudioEngine::LeftChannel ] = QVector< qint16 >( data[ Phonon::AudioDataOutput::CenterChannel ] ); - } - if( data.contains( Phonon::AudioDataOutput::SubwooferChannel ) ) - { - result[ AudioEngine::LeftChannel ] = QVector< qint16 >( data[ Phonon::AudioDataOutput::SubwooferChannel ] ); - } - - s_instance->audioDataArrived( result ); } - +*/ AudioEngine* AudioEnginePrivate::s_instance = 0; @@ -214,30 +186,16 @@ AudioEngine::AudioEngine() d->waitingOnNewTrack = false; d->state = Stopped; d->coverTempFile = 0; - d->audioEffect = 0; - d->dspPluginCallback = 0; d->s_instance = this; tDebug() << "Init AudioEngine"; + d->audioOutput = new AudioOutput(this); + + QObject::connect( d->audioOutput, SIGNAL( stateChanged( AudioOutput::AudioState, AudioOutput::AudioState ) ), d, SLOT( onStateChanged( AudioOutput::AudioState, AudioOutput::AudioState ) ) ); +getchar(); qRegisterMetaType< AudioErrorCode >("AudioErrorCode"); qRegisterMetaType< AudioState >("AudioState"); - - d->mediaObject = new Phonon::MediaObject( this ); - d->audioOutput = new Phonon::AudioOutput( Phonon::MusicCategory, this ); - d->audioPath = Phonon::createPath( d->mediaObject, d->audioOutput ); - - d->mediaObject->setTickInterval( 150 ); - connect( d->mediaObject, SIGNAL( stateChanged( Phonon::State, Phonon::State ) ), d_func(), SLOT( onStateChanged( Phonon::State, Phonon::State ) ) ); - connect( d->mediaObject, SIGNAL( tick( qint64 ) ), SLOT( timerTriggered( qint64 ) ) ); - connect( d->mediaObject, SIGNAL( aboutToFinish() ), SLOT( onAboutToFinish() ) ); - connect( d->audioOutput, SIGNAL( volumeChanged( qreal ) ), SLOT( onVolumeChanged( qreal ) ) ); - connect( d->audioOutput, SIGNAL( mutedChanged( bool ) ), SIGNAL( mutedChanged( bool ) ) ); - - onVolumeChanged( d->audioOutput->volume() ); - setVolume( TomahawkSettings::instance()->volume() ); - - d->mediaObject->setCurrentSource(Phonon::MediaSource("PhononDSP::effectCallback=" + QString::number((qulonglong)&AudioEngine::dspCallback, 16))); } @@ -245,7 +203,6 @@ AudioEngine::~AudioEngine() { tDebug() << Q_FUNC_INFO; - d_func()->mediaObject->stop(); TomahawkSettings::instance()->setVolume( volume() ); @@ -258,13 +215,11 @@ AudioEngine::supportedMimeTypes() const { if ( d_func()->supportedMimeTypes.isEmpty() ) { - d_func()->supportedMimeTypes = Phonon::BackendCapabilities::availableMimeTypes(); + d_func()->supportedMimeTypes << "audio/*"; d_func()->supportedMimeTypes << "audio/basic"; - - return d_func()->supportedMimeTypes; } - else - return d_func()->supportedMimeTypes; + + return d_func()->supportedMimeTypes; } @@ -300,7 +255,7 @@ AudioEngine::play() if ( isPaused() ) { - d->mediaObject->play(); + d->audioOutput->play(); emit resumed(); sendNowPlayingNotification( Tomahawk::InfoSystem::InfoNowResumed ); @@ -330,7 +285,7 @@ AudioEngine::pause() tDebug( LOGEXTRA ) << Q_FUNC_INFO; - d->mediaObject->pause(); + d->audioOutput->pause(); emit paused(); Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( Tomahawk::InfoSystem::InfoPushData( s_aeInfoIdentifier, Tomahawk::InfoSystem::InfoNowPaused, QVariant(), Tomahawk::InfoSystem::PushNoFlag ) ); @@ -358,8 +313,8 @@ AudioEngine::stop( AudioErrorCode errorCode ) else setState( Error ); - if ( d->mediaObject->state() != Phonon::StoppedState ) - d->mediaObject->stop(); + if ( d->audioOutput->state() != AudioOutput::Stopped ) + d->audioOutput->stop(); emit stopped(); @@ -382,11 +337,7 @@ bool AudioEngine::activateDataOutput() { Q_D( AudioEngine ); - d->audioDataPath = Phonon::createPath( d->mediaObject, d->audioDataOutput ); - connect( d->audioDataOutput, SIGNAL( dataReady( QMap< Phonon::AudioDataOutput::Channel, QVector< qint16 > > ) ), - d_func(), SLOT( onAudioDataArrived( QMap< Phonon::AudioDataOutput::Channel, QVector< qint16 > > ) ) ); - - return d->audioDataPath.isValid(); + return true; } @@ -395,15 +346,9 @@ bool AudioEngine::deactivateDataOutput() { Q_D( AudioEngine ); - return d->audioDataPath.disconnect(); + return true; } -void AudioEngine::audioDataArrived( QMap< AudioEngine::AudioChannel, QVector< qint16 > >& data ) -{ - emit audioDataReady( data ); -} - - void AudioEngine::previous() { @@ -490,16 +435,11 @@ bool AudioEngine::canSeek() { Q_D( AudioEngine ); - - bool phononCanSeek = true; - /* TODO: When phonon properly reports this, re-enable it - if ( d->mediaObject && d->mediaObject->isValid() ) - phononCanSeek = d->mediaObject->isSeekable(); - */ +/* if ( d->playlist.isNull() ) - return phononCanSeek; - - return !d->playlist.isNull() && ( d->playlist.data()->seekRestrictions() != PlaylistModes::NoSeek ) && phononCanSeek; + return true; +*/ + return !d->playlist.isNull() && ( d->playlist.data()->seekRestrictions() != PlaylistModes::NoSeek ); } @@ -517,7 +457,7 @@ AudioEngine::seek( qint64 ms ) if ( isPlaying() || isPaused() ) { tDebug( LOGVERBOSE ) << Q_FUNC_INFO << ms; - d->mediaObject->seek( ms ); + d->audioOutput->seek( ms ); emit seeked( ms ); } } @@ -542,6 +482,7 @@ AudioEngine::setVolume( int percentage ) if ( percentage > 0 && d->audioOutput->isMuted() ) d->audioOutput->setMuted( false ); + emit volumeChanged( percentage ); } @@ -564,6 +505,7 @@ bool AudioEngine::isMuted() const { return d_func()->audioOutput->isMuted(); + return 0; } @@ -766,18 +708,22 @@ AudioEngine::performLoadTrack( const Tomahawk::result_ptr result, const QString QSharedPointer qnr = io.objectCast(); if ( !qnr.isNull() ) { - d->mediaObject->setCurrentSource( new QNR_IODeviceStream( qnr, this ) ); + tLog() << "CASE 1"; + d->audioOutput->setCurrentSource( new QNR_IODeviceStream( qnr, this ) ); // We keep track of the QNetworkReply in QNR_IODeviceStream // and Phonon handles the deletion of the // QNR_IODeviceStream object ioToKeep.clear(); - d->mediaObject->currentSource().setAutoDelete( true ); + // TODO d->audioOutput->setAutoDelete( true ); } else { - d->mediaObject->setCurrentSource( io.data() ); + tLog() << "CASE 2"; +/* TODO + d->audioOutput->setCurrentSource( io.data() ); // We handle the deletion via tracking in d->input - d->mediaObject->currentSource().setAutoDelete( false ); + d->audioOutput->setAutoDelete( false ); +*/ } } else @@ -788,6 +734,7 @@ AudioEngine::performLoadTrack( const Tomahawk::result_ptr result, const QString */ if ( !TomahawkUtils::isLocalResult( url ) ) { + tLog() << "CASE 3"; QUrl furl = url; if ( url.contains( "?" ) ) { @@ -796,19 +743,22 @@ AudioEngine::performLoadTrack( const Tomahawk::result_ptr result, const QString } tLog( LOGVERBOSE ) << "Passing to Phonon:" << furl; - d->mediaObject->setCurrentSource( furl ); + d->audioOutput->setCurrentSource( furl ); } else { + tLog() << "CASE 4"; QString furl = url; if ( furl.startsWith( "file://" ) ) furl = furl.right( furl.length() - 7 ); tLog( LOGVERBOSE ) << "Passing to Phonon:" << QUrl::fromLocalFile( furl ); - d->mediaObject->setCurrentSource( QUrl::fromLocalFile( furl ) ); + d->audioOutput->setCurrentSource( QUrl::fromLocalFile( furl ) ); } - d->mediaObject->currentSource().setAutoDelete( true ); +/* TODO + d->audioOutput->setAutoDelete( true ); +*/ } if ( !d->input.isNull() ) @@ -817,7 +767,7 @@ AudioEngine::performLoadTrack( const Tomahawk::result_ptr result, const QString d->input.clear(); } d->input = ioToKeep; - d->mediaObject->play(); + d->audioOutput->play(); if ( TomahawkSettings::instance()->privateListeningMode() != TomahawkSettings::FullyPrivate ) { @@ -1290,14 +1240,16 @@ AudioEngine::setState( AudioState state ) qint64 AudioEngine::currentTime() const { - return d_func()->mediaObject->currentTime(); +// TODO return d_func()->mediaObject->currentTime(); + return 0; } qint64 AudioEngine::currentTrackTotalTime() const { - return d_func()->mediaObject->totalTime(); +// TODO return d_func()->mediaObject->totalTime(); + return 0; } @@ -1384,29 +1336,10 @@ AudioEngine::setCurrentTrackPlaylist( const playlistinterface_ptr& playlist ) } -void -AudioEngine::dspCallback( signed short* samples, int nb_channels, int nb_samples ) -{ - AudioEngine::instance()->dspCallbackInternal( samples, nb_channels, nb_samples ); -} - - -void -AudioEngine::dspCallbackInternal( signed short* samples, int nb_channels, int nb_samples ) -{ - Q_D( AudioEngine ); - - if ( d->dspPluginCallback != 0 ) - { - d->dspPluginCallback( samples, nb_channels, nb_samples ); - } -} - - void AudioEngine::setDspCallback( void ( *cb ) ( signed short*, int, int ) ) { Q_D( AudioEngine ); - d->dspPluginCallback = cb; + d->audioOutput->setDspCallback( cb ); } diff --git a/src/libtomahawk/audio/AudioEngine.h b/src/libtomahawk/audio/AudioEngine.h index db9ca1884..eb3d0862f 100644 --- a/src/libtomahawk/audio/AudioEngine.h +++ b/src/libtomahawk/audio/AudioEngine.h @@ -156,7 +156,7 @@ signals: void paused(); void resumed(); - void audioDataReady( QMap< AudioEngine::AudioChannel, QVector > data ); +// void audioDataReady( QMap< AudioEngine::AudioChannel, QVector > data ); void stopAfterTrackChanged(); @@ -200,9 +200,7 @@ private: void setState( AudioState state ); void setCurrentTrackPlaylist( const Tomahawk::playlistinterface_ptr& playlist ); - static void dspCallback( signed short* samples, int nb_channels, int nb_samples ); - void dspCallbackInternal( signed short* samples, int nb_channels, int nb_samples ); - void audioDataArrived( QMap< AudioEngine::AudioChannel, QVector< qint16 > >& data ); +// void audioDataArrived( QMap< AudioEngine::AudioChannel, QVector< qint16 > >& data ); Q_DECLARE_PRIVATE( AudioEngine ) diff --git a/src/libtomahawk/audio/AudioEngine_p.h b/src/libtomahawk/audio/AudioEngine_p.h index b03338634..4d2f275a4 100644 --- a/src/libtomahawk/audio/AudioEngine_p.h +++ b/src/libtomahawk/audio/AudioEngine_p.h @@ -1,10 +1,12 @@ - +/* #include #include #include #include #include #include +*/ +#include "AudioOutput.h" #include @@ -29,8 +31,8 @@ public: public slots: - void onStateChanged( Phonon::State newState, Phonon::State oldState ); - void onAudioDataArrived( QMap< Phonon::AudioDataOutput::Channel, QVector< qint16 > > data ); + void onStateChanged( AudioOutput::AudioState newState, AudioOutput::AudioState oldState ); +// void onAudioDataArrived( QMap< Phonon::AudioDataOutput::Channel, QVector< qint16 > > data ); private: QSharedPointer input; @@ -41,6 +43,8 @@ private: Tomahawk::playlistinterface_ptr currentTrackPlaylist; Tomahawk::playlistinterface_ptr queue; + AudioOutput* audioOutput; +/* Phonon::MediaObject* mediaObject; Phonon::AudioOutput* audioOutput; @@ -49,7 +53,7 @@ private: Phonon::AudioDataOutput* audioDataOutput; Phonon::Path audioDataPath; - +*/ unsigned int timeElapsed; bool expectStop; diff --git a/src/libtomahawk/audio/AudioOutput.cpp b/src/libtomahawk/audio/AudioOutput.cpp new file mode 100644 index 000000000..34b97854d --- /dev/null +++ b/src/libtomahawk/audio/AudioOutput.cpp @@ -0,0 +1,320 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2014, Christian Muehlhaeuser + * Copyright 2010-2012, Jeff Mitchell + * Copyright 2013, Teo Mrnjavac + * + * Tomahawk is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Tomahawk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . + */ + +#include "AudioOutput.h" + +#include "utils/Logger.h" + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +static QString s_aeInfoIdentifier = QString( "AUDIOOUTPUT" ); + + +AudioOutput* AudioOutput::s_instance = 0; + + +AudioOutput* +AudioOutput::instance() +{ + return AudioOutput::s_instance; +} + + +AudioOutput::AudioOutput( QObject* parent ) + : QObject( parent ) + , dspPluginCallback( 0 ) + , currentState( Stopped ) + , muted( false ) + , m_volume( 1.0 ) +{ + tDebug() << Q_FUNC_INFO; + + AudioOutput::s_instance = this; + currentStream = 0; + + QList args; + + args << "--ignore-config"; + args << "--verbose=11111"; + args << "--no-plugins-cache"; + args << "--extraintf=logger"; + args << "--no-media-library"; + args << "--no-osd"; + args << "--no-stats"; + args << "--no-video-title-show"; + args << "--no-snapshot-preview"; + args << "--no-xlib"; + args << "--services-discovery=''"; + args << "--no-one-instance"; + args << "--no-video"; +// args << "--audio-filter=dsp"; +// args << QString("--dsp-callback=%1").arg((quint64)&AudioOutput::s_dspCallback, 0, 16).toAscii(); + + QVarLengthArray< const char * , 64 > vlcArgs( args.size() ); + for ( int i = 0 ; i < args.size() ; ++i ) { + vlcArgs[i] = args.at( i ).constData(); + tDebug() << args.at( i ); + } + + // Create and initialize a libvlc instance (it should be done only once) + if ( !( vlcInstance = libvlc_new( vlcArgs.size(), vlcArgs.constData() ) ) ) { + tDebug() << "libVLC: could not initialize"; + } + vlcPlayer = libvlc_media_player_new( vlcInstance ); + + getchar(); + tDebug() << "AudioOutput::AudioOutput OK !\n"; +} + + +AudioOutput::~AudioOutput() +{ + tDebug() << Q_FUNC_INFO; +} + +void +AudioOutput::setCurrentSource(MediaStream stream) +{ + setCurrentSource( new MediaStream(stream) ); +} + +void +AudioOutput::setCurrentSource(MediaStream* stream) +{ + tDebug() << Q_FUNC_INFO; + currentStream = stream; + + currentState = Loading; + + QByteArray url; + switch (stream->type()) { + case MediaStream::Unknown: + tDebug() << "MediaStream Type is Invalid:" << stream->type(); + break; + + case MediaStream::Empty: + tDebug() << "MediaStream is empty."; + break; + + case MediaStream::Url: + tDebug() << "MediaStream::Url:" << stream->url(); + if (stream->url().scheme().isEmpty()) { + url = "file:///"; + if (stream->url().isRelative()) + url.append(QFile::encodeName(QDir::currentPath()) + '/'); + } + url += stream->url().toEncoded(); + break; + + case MediaStream::Stream: + url = QByteArray("imem://"); + break; + } + + tDebug() << "MediaStream::Final Url:" << url; + + vlcMedia = libvlc_media_new_location( vlcInstance, url.constData() ); + + libvlc_media_player_set_media( vlcPlayer, vlcMedia ); + + if ( stream->type() == MediaStream::Stream ) { + libvlc_media_add_option_flag(vlcMedia, "imem-cat=4", libvlc_media_option_trusted); + libvlc_media_add_option_flag(vlcMedia, (QString("imem-data=") + QString::number((quint64)stream)).toUtf8().data(), libvlc_media_option_trusted); + libvlc_media_add_option_flag(vlcMedia, (QString("imem-get=") + QString::number((quint64)&MediaStream::readCallback)).toUtf8().data(), libvlc_media_option_trusted); + libvlc_media_add_option_flag(vlcMedia, (QString("imem-release=") + QString::number((quint64)&MediaStream::readDoneCallback)).toUtf8().data(), libvlc_media_option_trusted); + libvlc_media_add_option_flag(vlcMedia, (QString("imem-seek=") + QString::number((quint64)&MediaStream::seekCallback)).toUtf8().data(), libvlc_media_option_trusted); + } + libvlc_media_add_option(vlcMedia, "audio-filter=dsp"); + libvlc_media_add_option(vlcMedia, ":audio-filter=dsp"); + libvlc_media_add_option(vlcMedia, "--audio-filter=dsp"); + libvlc_media_add_option(vlcMedia, "audio-filter dsp"); + libvlc_media_add_option(vlcMedia, ":audio-filter dsp"); + libvlc_media_add_option(vlcMedia, "--audio-filter dsp"); + + currentState = Stopped; +} + + +AudioOutput::AudioState +AudioOutput::state() +{ + tDebug() << Q_FUNC_INFO; + return currentState; +} + + +void +AudioOutput::setState( AudioState state ) +{ + tDebug() << Q_FUNC_INFO; + emit stateChanged ( state, currentState ); + currentState = state; +} + + +void +AudioOutput::play() +{ + tDebug() << Q_FUNC_INFO; + if ( libvlc_media_player_is_playing ( vlcPlayer ) ) { + libvlc_media_player_set_pause ( vlcPlayer, 0 ); + } else { + libvlc_media_player_play ( vlcPlayer ); + } + + setState( Playing ); +} + + +void +AudioOutput::pause() +{ + tDebug() << Q_FUNC_INFO; +// libvlc_media_player_pause( vlcPlayer ); + libvlc_media_player_set_pause ( vlcPlayer, 1 ); + + setState( Paused ); +} + + +void +AudioOutput::stop() +{ + tDebug() << Q_FUNC_INFO; + libvlc_media_player_stop ( vlcPlayer ); + + setState( Stopped ); +} + + +void +AudioOutput::seek( qint64 milliseconds ) +{ + tDebug() << Q_FUNC_INFO; + + switch ( currentState ) { + case Playing: + case Paused: + case Loading: + case Buffering: + break; + default: + // Seeking while not being in a playingish state is cached for later. +// TODO m_seekpoint = milliseconds; + return; + } + + tDebug() << "AudioOutput:: seeking" << milliseconds << "msec"; + + libvlc_media_player_set_time ( vlcPlayer, milliseconds ); +/* + const qint64 time = currentTime(); + const qint64 total = totalTime(); +*/ +/* + // Reset last tick marker so we emit time even after seeking + if (time < m_lastTick) + m_lastTick = time; + if (time < total - m_prefinishMark) + m_prefinishEmitted = false; + if (time < total - ABOUT_TO_FINISH_TIME) + m_aboutToFinishEmitted = false; +*/ +} + + +bool +AudioOutput::isMuted() +{ + tDebug() << Q_FUNC_INFO; + + return muted; +} + + +void +AudioOutput::setMuted(bool m) +{ + tDebug() << Q_FUNC_INFO; + + muted = m; + if ( muted == true ) { + libvlc_audio_set_volume( vlcPlayer, 0 ); + } else { + libvlc_audio_set_volume( vlcPlayer, m_volume * 100.0 ); + } +} + + +qreal +AudioOutput::volume() +{ + tDebug() << Q_FUNC_INFO; + + return muted ? 0 : m_volume; +} + + +void +AudioOutput::setVolume(qreal vol) +{ + tDebug() << Q_FUNC_INFO; + + m_volume = vol; + if ( !muted ) { + libvlc_audio_set_volume( vlcPlayer, m_volume * 100.0 ); + } +} + + +void +AudioOutput::s_dspCallback( signed short* samples, int nb_channels, int nb_samples ) +{ + tDebug() << Q_FUNC_INFO; + + AudioOutput::instance()->dspCallback( samples, nb_channels, nb_samples ); +} + + +void +AudioOutput::dspCallback( signed short* samples, int nb_channels, int nb_samples ) +{ + if ( dspPluginCallback != 0 ) + { + dspPluginCallback( samples, nb_channels, nb_samples ); + } +} + + +void +AudioOutput::setDspCallback( void ( *cb ) ( signed short*, int, int ) ) +{ + dspPluginCallback = cb; +} diff --git a/src/libtomahawk/audio/AudioOutput.h b/src/libtomahawk/audio/AudioOutput.h new file mode 100644 index 000000000..b231b565e --- /dev/null +++ b/src/libtomahawk/audio/AudioOutput.h @@ -0,0 +1,87 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2014, Christian Muehlhaeuser + * Copyright 2010-2012, Jeff Mitchell + * Copyright 2013, Teo Mrnjavac + * + * Tomahawk is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Tomahawk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . + */ + +#ifndef AUDIOOUTPUT_H +#define AUDIOOUTPUT_H + +#include "../Typedefs.h" + +#include "DllMacro.h" + +#include "utils/MediaStream.h" + +struct libvlc_instance_t; +struct libvlc_media_player_t; +struct libvlc_media_t; + +class DLLEXPORT AudioOutput : public QObject +{ +Q_OBJECT + +public: + enum AudioState { Stopped = 0, Playing = 1, Paused = 2, Error = 3, Loading = 4, Buffering = 5 }; + + explicit AudioOutput(QObject* parent = 0); + ~AudioOutput(); + + AudioState state(); + + void setCurrentSource(MediaStream stream); + void setCurrentSource(MediaStream* stream); + + void play(); + void pause(); + void stop(); + void seek(qint64 milliseconds); + + bool isMuted(); + void setMuted(bool m); + void setVolume(qreal vol); + qreal volume(); + + void setDspCallback( void ( *cb ) ( signed short*, int, int ) ); + + static AudioOutput* instance(); + +public slots: + +signals: + void stateChanged( AudioOutput::AudioState, AudioOutput::AudioState ); + +private: + void setState( AudioState state ); + + static void s_dspCallback( signed short* samples, int nb_channels, int nb_samples ); + void dspCallback( signed short* samples, int nb_channels, int nb_samples ); + + void ( *dspPluginCallback ) ( signed short* samples, int nb_channels, int nb_samples ); + + static AudioOutput* s_instance; + AudioState currentState; + MediaStream* currentStream; + bool muted; + qreal m_volume; + + libvlc_instance_t* vlcInstance; + libvlc_media_player_t* vlcPlayer; + libvlc_media_t* vlcMedia; +}; + +#endif // AUDIOOUTPUT_H diff --git a/src/libtomahawk/utils/MediaStream.cpp b/src/libtomahawk/utils/MediaStream.cpp new file mode 100644 index 000000000..f400e812b --- /dev/null +++ b/src/libtomahawk/utils/MediaStream.cpp @@ -0,0 +1,128 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2014, Christian Muehlhaeuser + * Copyright 2010-2012, Jeff Mitchell + * Copyright 2013, Teo Mrnjavac + * + * Tomahawk is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Tomahawk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . + */ + +#include "MediaStream.h" + +#include "utils/Logger.h" + + +static QString s_aeInfoIdentifier = QString( "MEDIASTREAM" ); + + +MediaStream::MediaStream() + : m_type( Unknown ) + , m_url( QUrl() ) + , m_pos( 0 ) + , m_streamSize( 0 ) +{ + tDebug() << Q_FUNC_INFO; +} + + +MediaStream::MediaStream( const QUrl &url ) + : m_type(Url) +{ + tDebug() << Q_FUNC_INFO; + + m_url = url; +} + + +MediaStream::~MediaStream() +{ + tDebug() << Q_FUNC_INFO; +} + + +MediaStream::MediaType +MediaStream::type() +{ + tDebug() << Q_FUNC_INFO; + return m_type; +} + + +QUrl +MediaStream::url() +{ + tDebug() << Q_FUNC_INFO; + return m_url; +} + + +qint64 +MediaStream::streamSize() +{ + return m_streamSize; +} + + +void +MediaStream::setStreamSize( qint64 size ) +{ + m_streamSize = size; +} + + +int +MediaStream::readCallback ( void* data, const char* cookie, int64_t* dts, int64_t* pts, unsigned* flags, size_t* bufferSize, void** buffer ) +{ + tDebug() << Q_FUNC_INFO; + + Q_UNUSED(cookie); + Q_UNUSED(dts); + Q_UNUSED(pts); + Q_UNUSED(flags); + + MediaStream* that = static_cast < MediaStream * > ( data ); + + *bufferSize = that->needData(buffer); + return 0; +} + + +int +MediaStream::readDoneCallback ( void *data, const char *cookie, size_t bufferSize, void *buffer ) +{ + tDebug() << Q_FUNC_INFO; + + Q_UNUSED(data); + Q_UNUSED(cookie); + Q_UNUSED(bufferSize); + delete static_cast(buffer); + + return 0; +} + + +int +MediaStream::seekCallback ( void *data, const uint64_t pos ) +{ + tDebug() << Q_FUNC_INFO; + + MediaStream* that = static_cast < MediaStream * > ( data ); + if ( static_cast < int64_t > ( pos ) > that->streamSize() ) { + return -1; + } + + that->m_pos = pos; + + return 0; +} diff --git a/src/libtomahawk/utils/MediaStream.h b/src/libtomahawk/utils/MediaStream.h new file mode 100644 index 000000000..28000c4ca --- /dev/null +++ b/src/libtomahawk/utils/MediaStream.h @@ -0,0 +1,63 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2014, Christian Muehlhaeuser + * Copyright 2010-2012, Jeff Mitchell + * Copyright 2013, Teo Mrnjavac + * + * Tomahawk is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Tomahawk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . + */ + +#ifndef MEDIASTREAM_H +#define MEDIASTREAM_H + +#include "../Typedefs.h" + +#include "DllMacro.h" +#include "utils/Logger.h" +#include + +#include + +class DLLEXPORT MediaStream +{ + +public: + enum MediaType { Unknown = -1, Empty = 0, Url = 1, Stream = 2 }; + + MediaStream(); + MediaStream( const QUrl &url ); + virtual ~MediaStream(); + + MediaType type(); + QUrl url(); + + void setStreamSize( qint64 size ); + qint64 streamSize(); + + virtual void seekStream( qint64 offset ) { (void)offset; } + virtual size_t needData ( void** buffer ) { (void)buffer; tDebug() << Q_FUNC_INFO; return 0; } + + static int readCallback ( void* data, const char* cookie, int64_t* dts, int64_t* pts, unsigned* flags, size_t* bufferSize, void** buffer ); + static int readDoneCallback ( void *data, const char *cookie, size_t bufferSize, void *buffer ); + static int seekCallback ( void *data, const uint64_t pos ); + +protected: + MediaType m_type; + QUrl m_url; + + qint64 m_pos; + qint64 m_streamSize; +}; + +#endif // MEDIASTREAM_H diff --git a/src/libtomahawk/utils/Qnr_IoDeviceStream.cpp b/src/libtomahawk/utils/Qnr_IoDeviceStream.cpp index 0176f452d..ed72c4463 100644 --- a/src/libtomahawk/utils/Qnr_IoDeviceStream.cpp +++ b/src/libtomahawk/utils/Qnr_IoDeviceStream.cpp @@ -33,11 +33,15 @@ using namespace Tomahawk; #define BLOCK_SIZE 1048576 QNR_IODeviceStream::QNR_IODeviceStream( const QSharedPointer& reply, QObject* parent ) - : Phonon::AbstractMediaStream( parent ) + : QObject( parent ) + , MediaStream() , m_networkReply( reply ) - , m_pos( 0 ) , m_timer( new QTimer( this ) ) { + tDebug() << Q_FUNC_INFO; + + m_type = MediaStream::Stream; + if ( !m_networkReply->isOpen() ) { m_networkReply->open(QIODevice::ReadOnly); } @@ -50,7 +54,7 @@ QNR_IODeviceStream::QNR_IODeviceStream( const QSharedPointer& rep // All data is ready, read it! m_data = m_networkReply->readAll(); Q_ASSERT( m_networkReply->atEnd() ); - setStreamSeekable( true ); +//TODO setStreamSeekable( true ); setStreamSize( m_data.size() ); } else @@ -59,7 +63,7 @@ QNR_IODeviceStream::QNR_IODeviceStream( const QSharedPointer& rep QVariant contentLength = m_networkReply->header( QNetworkRequest::ContentLengthHeader ); if ( contentLength.isValid() && contentLength.toLongLong() > 0 ) { - setStreamSize( contentLength.toLongLong() ); +//TODO setStreamSize( contentLength.toLongLong() ); } // Just consume all data that is already available. m_data = m_networkReply->readAll(); @@ -73,54 +77,39 @@ QNR_IODeviceStream::QNR_IODeviceStream( const QSharedPointer& rep QNR_IODeviceStream::~QNR_IODeviceStream() { -} - - -void -QNR_IODeviceStream::enoughData() -{ - m_timer->stop(); -} - - -void -QNR_IODeviceStream::needData() -{ - m_timer->start(); - moreData(); -} - -void -QNR_IODeviceStream::reset() -{ - m_pos = 0; + tDebug() << Q_FUNC_INFO; } void QNR_IODeviceStream::seekStream( qint64 offset ) { + tDebug() << Q_FUNC_INFO; + m_pos = offset; } -void -QNR_IODeviceStream::moreData() + +size_t +QNR_IODeviceStream::needData ( void** buffer ) { +// tDebug() << Q_FUNC_INFO; + QByteArray data = m_data.mid( m_pos, BLOCK_SIZE ); m_pos += data.size(); if ( ( data.size() == 0 ) && m_networkReply->atEnd() && m_networkReply->isFinished() ) { // We're done. - endOfData(); - m_timer->stop(); - } - else - { - writeData( data ); +//TODO endOfData(); + return 0; } + + *buffer = new char[data.size()]; + memcpy(*buffer, data.data(), data.size()); + tDebug() << Q_FUNC_INFO << " Returning buffer with size " << data.size(); + return data.size(); } - void QNR_IODeviceStream::readyRead() { diff --git a/src/libtomahawk/utils/Qnr_IoDeviceStream.h b/src/libtomahawk/utils/Qnr_IoDeviceStream.h index 27f5d9ad4..e43a6437a 100644 --- a/src/libtomahawk/utils/Qnr_IoDeviceStream.h +++ b/src/libtomahawk/utils/Qnr_IoDeviceStream.h @@ -25,37 +25,35 @@ #include "DllMacro.h" -#include +//#include #include #include #include +#include "MediaStream.h" + class QIODevice; class QTimer; namespace Tomahawk { -class DLLEXPORT QNR_IODeviceStream : public Phonon::AbstractMediaStream +class DLLEXPORT QNR_IODeviceStream : public QObject, public MediaStream { Q_OBJECT public: explicit QNR_IODeviceStream( const QSharedPointer& reply, QObject *parent = 0 ); ~QNR_IODeviceStream(); - virtual void enoughData(); - virtual void needData(); - virtual void reset(); virtual void seekStream( qint64 offset ); + virtual size_t needData ( void** buffer ); private slots: - void moreData(); void readyRead(); private: QByteArray m_data; QSharedPointer m_networkReply; - qint64 m_pos; QTimer* m_timer; }; From 5daca7f0e7a10e9e51398cb131f59cac9195ab92 Mon Sep 17 00:00:00 2001 From: dridri Date: Tue, 30 Sep 2014 00:29:29 +0200 Subject: [PATCH 07/43] totalTime and currentTime impl --- src/libtomahawk/audio/AudioEngine.cpp | 11 ++- src/libtomahawk/audio/AudioOutput.cpp | 111 +++++++++++++++++++++++--- src/libtomahawk/audio/AudioOutput.h | 13 ++- src/libtomahawk/utils/MediaStream.cpp | 4 + 4 files changed, 121 insertions(+), 18 deletions(-) diff --git a/src/libtomahawk/audio/AudioEngine.cpp b/src/libtomahawk/audio/AudioEngine.cpp index 8e221c729..5a177c08e 100644 --- a/src/libtomahawk/audio/AudioEngine.cpp +++ b/src/libtomahawk/audio/AudioEngine.cpp @@ -192,8 +192,9 @@ AudioEngine::AudioEngine() d->audioOutput = new AudioOutput(this); - QObject::connect( d->audioOutput, SIGNAL( stateChanged( AudioOutput::AudioState, AudioOutput::AudioState ) ), d, SLOT( onStateChanged( AudioOutput::AudioState, AudioOutput::AudioState ) ) ); -getchar(); + connect( d->audioOutput, SIGNAL( stateChanged( AudioOutput::AudioState, AudioOutput::AudioState ) ), d_func(), SLOT( onStateChanged( AudioOutput::AudioState, AudioOutput::AudioState ) ) ); + connect( d->audioOutput, SIGNAL( tick( qint64 ) ), SLOT( timerTriggered( qint64 ) ) ); + qRegisterMetaType< AudioErrorCode >("AudioErrorCode"); qRegisterMetaType< AudioState >("AudioState"); } @@ -1240,16 +1241,14 @@ AudioEngine::setState( AudioState state ) qint64 AudioEngine::currentTime() const { -// TODO return d_func()->mediaObject->currentTime(); - return 0; + return d_func()->audioOutput->currentTime(); } qint64 AudioEngine::currentTrackTotalTime() const { -// TODO return d_func()->mediaObject->totalTime(); - return 0; + return d_func()->audioOutput->totalTime(); } diff --git a/src/libtomahawk/audio/AudioOutput.cpp b/src/libtomahawk/audio/AudioOutput.cpp index 34b97854d..c5dcfee14 100644 --- a/src/libtomahawk/audio/AudioOutput.cpp +++ b/src/libtomahawk/audio/AudioOutput.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include static QString s_aeInfoIdentifier = QString( "AUDIOOUTPUT" ); @@ -49,10 +50,12 @@ AudioOutput::instance() AudioOutput::AudioOutput( QObject* parent ) : QObject( parent ) - , dspPluginCallback( 0 ) , currentState( Stopped ) , muted( false ) , m_volume( 1.0 ) + , m_currentTime( 0 ) + , m_totalTime( 0 ) + , dspPluginCallback( 0 ) { tDebug() << Q_FUNC_INFO; @@ -87,8 +90,38 @@ AudioOutput::AudioOutput( QObject* parent ) if ( !( vlcInstance = libvlc_new( vlcArgs.size(), vlcArgs.constData() ) ) ) { tDebug() << "libVLC: could not initialize"; } + + vlcPlayer = libvlc_media_player_new( vlcInstance ); + libvlc_event_manager_t *manager = libvlc_media_player_event_manager( vlcPlayer ); + libvlc_event_type_t events[] = { + libvlc_MediaPlayerMediaChanged, + libvlc_MediaPlayerNothingSpecial, + libvlc_MediaPlayerOpening, + libvlc_MediaPlayerBuffering, + libvlc_MediaPlayerPlaying, + libvlc_MediaPlayerPaused, + libvlc_MediaPlayerStopped, + libvlc_MediaPlayerForward, + libvlc_MediaPlayerBackward, + libvlc_MediaPlayerEndReached, + libvlc_MediaPlayerEncounteredError, + libvlc_MediaPlayerTimeChanged, + libvlc_MediaPlayerPositionChanged, + libvlc_MediaPlayerSeekableChanged, + libvlc_MediaPlayerPausableChanged, + libvlc_MediaPlayerTitleChanged, + libvlc_MediaPlayerSnapshotTaken, + libvlc_MediaPlayerLengthChanged, + libvlc_MediaPlayerVout + }; + const int eventCount = sizeof(events) / sizeof( *events ); + for ( int i = 0 ; i < eventCount ; i++ ) { + libvlc_event_attach( manager, events[ i ], &AudioOutput::vlcEventCallback, this ); + } + + getchar(); tDebug() << "AudioOutput::AudioOutput OK !\n"; } @@ -144,7 +177,10 @@ AudioOutput::setCurrentSource(MediaStream* stream) libvlc_media_player_set_media( vlcPlayer, vlcMedia ); - if ( stream->type() == MediaStream::Stream ) { + if ( stream->type() == MediaStream::Url ) { + m_totalTime = libvlc_media_get_duration( vlcMedia ); + } + else if ( stream->type() == MediaStream::Stream ) { libvlc_media_add_option_flag(vlcMedia, "imem-cat=4", libvlc_media_option_trusted); libvlc_media_add_option_flag(vlcMedia, (QString("imem-data=") + QString::number((quint64)stream)).toUtf8().data(), libvlc_media_option_trusted); libvlc_media_add_option_flag(vlcMedia, (QString("imem-get=") + QString::number((quint64)&MediaStream::readCallback)).toUtf8().data(), libvlc_media_option_trusted); @@ -179,6 +215,28 @@ AudioOutput::setState( AudioState state ) } +qint64 +AudioOutput::currentTime() +{ + return m_currentTime; +} + + +void +AudioOutput::setCurrentTime( qint64 time ) +{ + m_currentTime = time; + emit tick( time ); +} + + +qint64 +AudioOutput::totalTime() +{ + return m_totalTime; +} + + void AudioOutput::play() { @@ -295,20 +353,55 @@ AudioOutput::setVolume(qreal vol) void -AudioOutput::s_dspCallback( signed short* samples, int nb_channels, int nb_samples ) +AudioOutput::vlcEventCallback( const libvlc_event_t* event, void* opaque ) { - tDebug() << Q_FUNC_INFO; +// tDebug() << Q_FUNC_INFO; - AudioOutput::instance()->dspCallback( samples, nb_channels, nb_samples ); + AudioOutput* that = reinterpret_cast < AudioOutput * > ( opaque ); + Q_ASSERT( that ); + + switch (event->type) { + case libvlc_MediaPlayerTimeChanged: + that->setCurrentTime( event->u.media_player_time_changed.new_time ); + break; + case libvlc_MediaPlayerSeekableChanged: + //TODO, bool event->u.media_player_seekable_changed.new_seekable + break; + case libvlc_MediaPlayerLengthChanged: + that->m_totalTime = event->u.media_player_length_changed.new_length; + break; + case libvlc_MediaPlayerNothingSpecial: + case libvlc_MediaPlayerOpening: + case libvlc_MediaPlayerBuffering: + case libvlc_MediaPlayerPlaying: + case libvlc_MediaPlayerPaused: + case libvlc_MediaPlayerStopped: + case libvlc_MediaPlayerEndReached: + break; + case libvlc_MediaPlayerEncounteredError: + // TODO emit Error + break; + case libvlc_MediaPlayerVout: + case libvlc_MediaPlayerMediaChanged: + case libvlc_MediaPlayerForward: + case libvlc_MediaPlayerBackward: + case libvlc_MediaPlayerPositionChanged: + case libvlc_MediaPlayerPausableChanged: + case libvlc_MediaPlayerTitleChanged: + case libvlc_MediaPlayerSnapshotTaken: + default: + break; + } } void -AudioOutput::dspCallback( signed short* samples, int nb_channels, int nb_samples ) +AudioOutput::s_dspCallback( signed short* samples, int nb_channels, int nb_samples ) { - if ( dspPluginCallback != 0 ) - { - dspPluginCallback( samples, nb_channels, nb_samples ); + tDebug() << Q_FUNC_INFO; + + if ( AudioOutput::instance()->dspPluginCallback ) { + AudioOutput::instance()->dspPluginCallback( samples, nb_channels, nb_samples ); } } diff --git a/src/libtomahawk/audio/AudioOutput.h b/src/libtomahawk/audio/AudioOutput.h index b231b565e..175c4c4bb 100644 --- a/src/libtomahawk/audio/AudioOutput.h +++ b/src/libtomahawk/audio/AudioOutput.h @@ -30,6 +30,7 @@ struct libvlc_instance_t; struct libvlc_media_player_t; struct libvlc_media_t; +struct libvlc_event_t; class DLLEXPORT AudioOutput : public QObject { @@ -55,6 +56,8 @@ public: void setMuted(bool m); void setVolume(qreal vol); qreal volume(); + qint64 currentTime(); + qint64 totalTime(); void setDspCallback( void ( *cb ) ( signed short*, int, int ) ); @@ -64,20 +67,24 @@ public slots: signals: void stateChanged( AudioOutput::AudioState, AudioOutput::AudioState ); + void tick( qint64 ); private: void setState( AudioState state ); + void setCurrentTime( qint64 time ); + static void vlcEventCallback( const libvlc_event_t *event, void *opaque ); static void s_dspCallback( signed short* samples, int nb_channels, int nb_samples ); - void dspCallback( signed short* samples, int nb_channels, int nb_samples ); - - void ( *dspPluginCallback ) ( signed short* samples, int nb_channels, int nb_samples ); static AudioOutput* s_instance; AudioState currentState; MediaStream* currentStream; bool muted; qreal m_volume; + qint64 m_currentTime; + qint64 m_totalTime; + + void ( *dspPluginCallback ) ( signed short* samples, int nb_channels, int nb_samples ); libvlc_instance_t* vlcInstance; libvlc_media_player_t* vlcPlayer; diff --git a/src/libtomahawk/utils/MediaStream.cpp b/src/libtomahawk/utils/MediaStream.cpp index f400e812b..5b7dc7ad1 100644 --- a/src/libtomahawk/utils/MediaStream.cpp +++ b/src/libtomahawk/utils/MediaStream.cpp @@ -70,6 +70,8 @@ MediaStream::url() qint64 MediaStream::streamSize() { + tDebug() << Q_FUNC_INFO; + return m_streamSize; } @@ -77,6 +79,8 @@ MediaStream::streamSize() void MediaStream::setStreamSize( qint64 size ) { + tDebug() << Q_FUNC_INFO; + m_streamSize = size; } From ce3d37274975ea23cf9810bcfa891c3ccc679f87 Mon Sep 17 00:00:00 2001 From: dridri Date: Tue, 30 Sep 2014 01:30:44 +0200 Subject: [PATCH 08/43] More track duration calculation and seeking --- src/libtomahawk/audio/AudioEngine.cpp | 12 +++- src/libtomahawk/audio/AudioOutput.cpp | 68 +++++++++++++++++--- src/libtomahawk/audio/AudioOutput.h | 3 + src/libtomahawk/utils/MediaStream.cpp | 18 +++++- src/libtomahawk/utils/MediaStream.h | 3 + src/libtomahawk/utils/Qnr_IoDeviceStream.cpp | 2 +- 6 files changed, 93 insertions(+), 13 deletions(-) diff --git a/src/libtomahawk/audio/AudioEngine.cpp b/src/libtomahawk/audio/AudioEngine.cpp index 5a177c08e..1a2d0ae08 100644 --- a/src/libtomahawk/audio/AudioEngine.cpp +++ b/src/libtomahawk/audio/AudioEngine.cpp @@ -109,9 +109,9 @@ AudioEnginePrivate::onStateChanged( AudioOutput::AudioState newState, AudioOutpu case AudioOutput::Paused: { if ( audioOutput && currentTrack ) - {/* TODO + { qint64 duration = audioOutput->totalTime() > 0 ? audioOutput->totalTime() : currentTrack->track()->duration() * 1000; - stopped = ( duration - 1000 < audioOutput->currentTime() ); */ + stopped = ( duration - 1000 < audioOutput->currentTime() ); } else stopped = true; @@ -133,7 +133,7 @@ AudioEnginePrivate::onStateChanged( AudioOutput::AudioState newState, AudioOutpu if ( stopped && expectStop ) { expectStop = false; - tDebug( LOGVERBOSE ) << "Finding next track."; + tDebug() << "Finding next track."; if ( q_ptr->canGoNext() ) { q_ptr->loadNextTrack(); @@ -194,6 +194,7 @@ AudioEngine::AudioEngine() connect( d->audioOutput, SIGNAL( stateChanged( AudioOutput::AudioState, AudioOutput::AudioState ) ), d_func(), SLOT( onStateChanged( AudioOutput::AudioState, AudioOutput::AudioState ) ) ); connect( d->audioOutput, SIGNAL( tick( qint64 ) ), SLOT( timerTriggered( qint64 ) ) ); + connect( d->audioOutput, SIGNAL( aboutToFinish() ), SLOT( onAboutToFinish() ) ); qRegisterMetaType< AudioErrorCode >("AudioErrorCode"); qRegisterMetaType< AudioState >("AudioState"); @@ -1248,6 +1249,11 @@ AudioEngine::currentTime() const qint64 AudioEngine::currentTrackTotalTime() const { + // TODO : This is too hacky. The problem is that I don't know why + // libVLC doesn't report total duration for stream data (imem://) + if ( d_func()->currentTrack && d_func()->currentTrack->track() ) { + return d_func()->currentTrack->track()->duration() * 1000 + 1000; + } return d_func()->audioOutput->totalTime(); } diff --git a/src/libtomahawk/audio/AudioOutput.cpp b/src/libtomahawk/audio/AudioOutput.cpp index c5dcfee14..f45f573a4 100644 --- a/src/libtomahawk/audio/AudioOutput.cpp +++ b/src/libtomahawk/audio/AudioOutput.cpp @@ -18,6 +18,7 @@ * along with Tomahawk. If not, see . */ +#include "AudioEngine.h" #include "AudioOutput.h" #include "utils/Logger.h" @@ -37,6 +38,7 @@ static QString s_aeInfoIdentifier = QString( "AUDIOOUTPUT" ); +static const int ABOUT_TO_FINISH_TIME = 2000; AudioOutput* AudioOutput::s_instance = 0; @@ -55,12 +57,15 @@ AudioOutput::AudioOutput( QObject* parent ) , m_volume( 1.0 ) , m_currentTime( 0 ) , m_totalTime( 0 ) + , m_aboutToFinish( false ) , dspPluginCallback( 0 ) { tDebug() << Q_FUNC_INFO; AudioOutput::s_instance = this; currentStream = 0; + + qRegisterMetaType("AudioOutput::AudioState"); QList args; @@ -94,7 +99,7 @@ AudioOutput::AudioOutput( QObject* parent ) vlcPlayer = libvlc_media_player_new( vlcInstance ); - libvlc_event_manager_t *manager = libvlc_media_player_event_manager( vlcPlayer ); + libvlc_event_manager_t* manager = libvlc_media_player_event_manager( vlcPlayer ); libvlc_event_type_t events[] = { libvlc_MediaPlayerMediaChanged, libvlc_MediaPlayerNothingSpecial, @@ -113,7 +118,7 @@ AudioOutput::AudioOutput( QObject* parent ) libvlc_MediaPlayerPausableChanged, libvlc_MediaPlayerTitleChanged, libvlc_MediaPlayerSnapshotTaken, - libvlc_MediaPlayerLengthChanged, + //libvlc_MediaPlayerLengthChanged, libvlc_MediaPlayerVout }; const int eventCount = sizeof(events) / sizeof( *events ); @@ -142,9 +147,12 @@ void AudioOutput::setCurrentSource(MediaStream* stream) { tDebug() << Q_FUNC_INFO; - currentStream = stream; - currentState = Loading; + setState(Loading); + + currentStream = stream; + m_totalTime = 0; + m_currentTime = 0; QByteArray url; switch (stream->type()) { @@ -173,10 +181,21 @@ AudioOutput::setCurrentSource(MediaStream* stream) tDebug() << "MediaStream::Final Url:" << url; + vlcMedia = libvlc_media_new_location( vlcInstance, url.constData() ); + libvlc_event_manager_t* manager = libvlc_media_event_manager( vlcMedia ); + libvlc_event_type_t events[] = { + libvlc_MediaDurationChanged, + }; + const int eventCount = sizeof(events) / sizeof( *events ); + for ( int i = 0 ; i < eventCount ; i++ ) { + libvlc_event_attach( manager, events[ i ], &AudioOutput::vlcEventCallback, this ); + } + libvlc_media_player_set_media( vlcPlayer, vlcMedia ); + if ( stream->type() == MediaStream::Url ) { m_totalTime = libvlc_media_get_duration( vlcMedia ); } @@ -194,7 +213,8 @@ AudioOutput::setCurrentSource(MediaStream* stream) libvlc_media_add_option(vlcMedia, ":audio-filter dsp"); libvlc_media_add_option(vlcMedia, "--audio-filter dsp"); - currentState = Stopped; + m_aboutToFinish = false; + setState(Stopped); } @@ -210,8 +230,9 @@ void AudioOutput::setState( AudioState state ) { tDebug() << Q_FUNC_INFO; - emit stateChanged ( state, currentState ); + AudioState last = currentState; currentState = state; + emit stateChanged ( state, last ); } @@ -226,7 +247,20 @@ void AudioOutput::setCurrentTime( qint64 time ) { m_currentTime = time; + if ( m_totalTime <= 0 ) { + m_totalTime = AudioEngine::instance()->currentTrackTotalTime(); + } emit tick( time ); + + tDebug() << "Current time : " << m_currentTime << " / " << m_totalTime; + + if ( time < m_totalTime - ABOUT_TO_FINISH_TIME ) { + m_aboutToFinish = false; + } + if ( !m_aboutToFinish && m_totalTime > 0 && time >= m_totalTime - ABOUT_TO_FINISH_TIME ) { + m_aboutToFinish = true; + emit aboutToFinish(); + } } @@ -237,6 +271,17 @@ AudioOutput::totalTime() } +void +AudioOutput::setTotalTime( qint64 time ) +{ + if ( time > 0 ) { + m_totalTime = time; + // emit current time to refresh total time + emit tick( m_currentTime ); + } +} + + void AudioOutput::play() { @@ -367,16 +412,23 @@ AudioOutput::vlcEventCallback( const libvlc_event_t* event, void* opaque ) case libvlc_MediaPlayerSeekableChanged: //TODO, bool event->u.media_player_seekable_changed.new_seekable break; - case libvlc_MediaPlayerLengthChanged: - that->m_totalTime = event->u.media_player_length_changed.new_length; + case libvlc_MediaDurationChanged: + that->setTotalTime( event->u.media_duration_changed.new_duration ); break; + /* + case libvlc_MediaPlayerLengthChanged: + that->setTotalTime( event->u.media_player_length_changed.new_length ); + break; + */ case libvlc_MediaPlayerNothingSpecial: case libvlc_MediaPlayerOpening: case libvlc_MediaPlayerBuffering: case libvlc_MediaPlayerPlaying: case libvlc_MediaPlayerPaused: case libvlc_MediaPlayerStopped: + break; case libvlc_MediaPlayerEndReached: + that->setState(Stopped); break; case libvlc_MediaPlayerEncounteredError: // TODO emit Error diff --git a/src/libtomahawk/audio/AudioOutput.h b/src/libtomahawk/audio/AudioOutput.h index 175c4c4bb..d5610f923 100644 --- a/src/libtomahawk/audio/AudioOutput.h +++ b/src/libtomahawk/audio/AudioOutput.h @@ -68,10 +68,12 @@ public slots: signals: void stateChanged( AudioOutput::AudioState, AudioOutput::AudioState ); void tick( qint64 ); + void aboutToFinish(); private: void setState( AudioState state ); void setCurrentTime( qint64 time ); + void setTotalTime( qint64 time ); static void vlcEventCallback( const libvlc_event_t *event, void *opaque ); static void s_dspCallback( signed short* samples, int nb_channels, int nb_samples ); @@ -83,6 +85,7 @@ private: qreal m_volume; qint64 m_currentTime; qint64 m_totalTime; + bool m_aboutToFinish; void ( *dspPluginCallback ) ( signed short* samples, int nb_channels, int nb_samples ); diff --git a/src/libtomahawk/utils/MediaStream.cpp b/src/libtomahawk/utils/MediaStream.cpp index 5b7dc7ad1..ac2cee4ab 100644 --- a/src/libtomahawk/utils/MediaStream.cpp +++ b/src/libtomahawk/utils/MediaStream.cpp @@ -29,6 +29,7 @@ static QString s_aeInfoIdentifier = QString( "MEDIASTREAM" ); MediaStream::MediaStream() : m_type( Unknown ) , m_url( QUrl() ) + , m_eos( false ) , m_pos( 0 ) , m_streamSize( 0 ) { @@ -85,6 +86,15 @@ MediaStream::setStreamSize( qint64 size ) } +void +MediaStream::endOfData() +{ + tDebug() << Q_FUNC_INFO; + + m_eos = true; +} + + int MediaStream::readCallback ( void* data, const char* cookie, int64_t* dts, int64_t* pts, unsigned* flags, size_t* bufferSize, void** buffer ) { @@ -97,6 +107,10 @@ MediaStream::readCallback ( void* data, const char* cookie, int64_t* dts, int64_ MediaStream* that = static_cast < MediaStream * > ( data ); + if ( that->m_eos == true ) { + return -1; + } + *bufferSize = that->needData(buffer); return 0; } @@ -110,7 +124,9 @@ MediaStream::readDoneCallback ( void *data, const char *cookie, size_t bufferSiz Q_UNUSED(data); Q_UNUSED(cookie); Q_UNUSED(bufferSize); - delete static_cast(buffer); + +// TODO : causes segfault +// delete static_cast(buffer); return 0; } diff --git a/src/libtomahawk/utils/MediaStream.h b/src/libtomahawk/utils/MediaStream.h index 28000c4ca..b7dd67987 100644 --- a/src/libtomahawk/utils/MediaStream.h +++ b/src/libtomahawk/utils/MediaStream.h @@ -53,9 +53,12 @@ public: static int seekCallback ( void *data, const uint64_t pos ); protected: + void endOfData(); + MediaType m_type; QUrl m_url; + bool m_eos; qint64 m_pos; qint64 m_streamSize; }; diff --git a/src/libtomahawk/utils/Qnr_IoDeviceStream.cpp b/src/libtomahawk/utils/Qnr_IoDeviceStream.cpp index ed72c4463..8c80fa3c2 100644 --- a/src/libtomahawk/utils/Qnr_IoDeviceStream.cpp +++ b/src/libtomahawk/utils/Qnr_IoDeviceStream.cpp @@ -100,7 +100,7 @@ QNR_IODeviceStream::needData ( void** buffer ) if ( ( data.size() == 0 ) && m_networkReply->atEnd() && m_networkReply->isFinished() ) { // We're done. -//TODO endOfData(); + endOfData(); return 0; } From 82acc6b60e0fc5c5c566b268690d7e01d22bd9fa Mon Sep 17 00:00:00 2001 From: dridri Date: Tue, 30 Sep 2014 01:32:26 +0200 Subject: [PATCH 09/43] little fix for duration bug --- src/libtomahawk/audio/AudioEngine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libtomahawk/audio/AudioEngine.cpp b/src/libtomahawk/audio/AudioEngine.cpp index 1a2d0ae08..ba4456e17 100644 --- a/src/libtomahawk/audio/AudioEngine.cpp +++ b/src/libtomahawk/audio/AudioEngine.cpp @@ -1251,7 +1251,7 @@ AudioEngine::currentTrackTotalTime() const { // TODO : This is too hacky. The problem is that I don't know why // libVLC doesn't report total duration for stream data (imem://) - if ( d_func()->currentTrack && d_func()->currentTrack->track() ) { + if ( d_func()->audioOutput->totalTime() == 0 && d_func()->currentTrack && d_func()->currentTrack->track() ) { return d_func()->currentTrack->track()->duration() * 1000 + 1000; } return d_func()->audioOutput->totalTime(); From 439335ecef7c46ffdfc99e37033210cea6f11d96 Mon Sep 17 00:00:00 2001 From: dridri Date: Tue, 30 Sep 2014 15:21:29 +0200 Subject: [PATCH 10/43] First version using libvlc instead of phonon - added QIODevice support, less debug, no more segfault --- src/libtomahawk/audio/AudioEngine.cpp | 8 ++-- src/libtomahawk/audio/AudioEngine_p.h | 10 ----- src/libtomahawk/audio/AudioOutput.cpp | 63 ++++++++++++++------------- src/libtomahawk/audio/AudioOutput.h | 2 + src/libtomahawk/utils/MediaStream.cpp | 42 +++++++++++++++--- src/libtomahawk/utils/MediaStream.h | 5 ++- 6 files changed, 77 insertions(+), 53 deletions(-) diff --git a/src/libtomahawk/audio/AudioEngine.cpp b/src/libtomahawk/audio/AudioEngine.cpp index ba4456e17..01b05e463 100644 --- a/src/libtomahawk/audio/AudioEngine.cpp +++ b/src/libtomahawk/audio/AudioEngine.cpp @@ -716,16 +716,14 @@ AudioEngine::performLoadTrack( const Tomahawk::result_ptr result, const QString // and Phonon handles the deletion of the // QNR_IODeviceStream object ioToKeep.clear(); - // TODO d->audioOutput->setAutoDelete( true ); + d->audioOutput->setAutoDelete( true ); } else { tLog() << "CASE 2"; -/* TODO d->audioOutput->setCurrentSource( io.data() ); // We handle the deletion via tracking in d->input d->audioOutput->setAutoDelete( false ); -*/ } } else @@ -758,9 +756,7 @@ AudioEngine::performLoadTrack( const Tomahawk::result_ptr result, const QString d->audioOutput->setCurrentSource( QUrl::fromLocalFile( furl ) ); } -/* TODO d->audioOutput->setAutoDelete( true ); -*/ } if ( !d->input.isNull() ) @@ -1251,6 +1247,8 @@ AudioEngine::currentTrackTotalTime() const { // TODO : This is too hacky. The problem is that I don't know why // libVLC doesn't report total duration for stream data (imem://) + // But it's not a real problem for playback, since + // EndOfStream is emitted by libVLC itself if ( d_func()->audioOutput->totalTime() == 0 && d_func()->currentTrack && d_func()->currentTrack->track() ) { return d_func()->currentTrack->track()->duration() * 1000 + 1000; } diff --git a/src/libtomahawk/audio/AudioEngine_p.h b/src/libtomahawk/audio/AudioEngine_p.h index 4d2f275a4..1bf5b9b1c 100644 --- a/src/libtomahawk/audio/AudioEngine_p.h +++ b/src/libtomahawk/audio/AudioEngine_p.h @@ -44,16 +44,6 @@ private: Tomahawk::playlistinterface_ptr queue; AudioOutput* audioOutput; -/* - Phonon::MediaObject* mediaObject; - Phonon::AudioOutput* audioOutput; - - Phonon::Path audioPath; - Phonon::Effect* audioEffect; - - Phonon::AudioDataOutput* audioDataOutput; - Phonon::Path audioDataPath; -*/ unsigned int timeElapsed; bool expectStop; diff --git a/src/libtomahawk/audio/AudioOutput.cpp b/src/libtomahawk/audio/AudioOutput.cpp index f45f573a4..3be3a0aba 100644 --- a/src/libtomahawk/audio/AudioOutput.cpp +++ b/src/libtomahawk/audio/AudioOutput.cpp @@ -54,11 +54,15 @@ AudioOutput::AudioOutput( QObject* parent ) : QObject( parent ) , currentState( Stopped ) , muted( false ) + , m_autoDelete ( true ) , m_volume( 1.0 ) , m_currentTime( 0 ) , m_totalTime( 0 ) , m_aboutToFinish( false ) , dspPluginCallback( 0 ) + , vlcInstance( 0 ) + , vlcPlayer( 0 ) + , vlcMedia( 0 ) { tDebug() << Q_FUNC_INFO; @@ -126,8 +130,6 @@ AudioOutput::AudioOutput( QObject* parent ) libvlc_event_attach( manager, events[ i ], &AudioOutput::vlcEventCallback, this ); } - - getchar(); tDebug() << "AudioOutput::AudioOutput OK !\n"; } @@ -137,6 +139,13 @@ AudioOutput::~AudioOutput() tDebug() << Q_FUNC_INFO; } + +void +AudioOutput::setAutoDelete ( bool ad ) +{ + m_autoDelete = ad; +} + void AudioOutput::setCurrentSource(MediaStream stream) { @@ -150,6 +159,15 @@ AudioOutput::setCurrentSource(MediaStream* stream) setState(Loading); + if ( vlcMedia != 0 ) { + // Ensure playback is stopped, then release media + libvlc_media_player_stop( vlcPlayer ); + libvlc_media_release( vlcMedia ); + vlcMedia = 0; + } + if ( m_autoDelete && currentStream != 0 ) { + delete currentStream; + } currentStream = stream; m_totalTime = 0; m_currentTime = 0; @@ -166,16 +184,18 @@ AudioOutput::setCurrentSource(MediaStream* stream) case MediaStream::Url: tDebug() << "MediaStream::Url:" << stream->url(); - if (stream->url().scheme().isEmpty()) { + if ( stream->url().scheme().isEmpty() ) { url = "file:///"; - if (stream->url().isRelative()) - url.append(QFile::encodeName(QDir::currentPath()) + '/'); + if ( stream->url().isRelative() ) { + url.append( QFile::encodeName( QDir::currentPath() ) + '/' ); + } } url += stream->url().toEncoded(); break; case MediaStream::Stream: - url = QByteArray("imem://"); + case MediaStream::IODevice: + url = QByteArray( "imem://" ); break; } @@ -199,19 +219,13 @@ AudioOutput::setCurrentSource(MediaStream* stream) if ( stream->type() == MediaStream::Url ) { m_totalTime = libvlc_media_get_duration( vlcMedia ); } - else if ( stream->type() == MediaStream::Stream ) { + else if ( stream->type() == MediaStream::Stream || stream->type() == MediaStream::IODevice ) { libvlc_media_add_option_flag(vlcMedia, "imem-cat=4", libvlc_media_option_trusted); libvlc_media_add_option_flag(vlcMedia, (QString("imem-data=") + QString::number((quint64)stream)).toUtf8().data(), libvlc_media_option_trusted); libvlc_media_add_option_flag(vlcMedia, (QString("imem-get=") + QString::number((quint64)&MediaStream::readCallback)).toUtf8().data(), libvlc_media_option_trusted); libvlc_media_add_option_flag(vlcMedia, (QString("imem-release=") + QString::number((quint64)&MediaStream::readDoneCallback)).toUtf8().data(), libvlc_media_option_trusted); libvlc_media_add_option_flag(vlcMedia, (QString("imem-seek=") + QString::number((quint64)&MediaStream::seekCallback)).toUtf8().data(), libvlc_media_option_trusted); } - libvlc_media_add_option(vlcMedia, "audio-filter=dsp"); - libvlc_media_add_option(vlcMedia, ":audio-filter=dsp"); - libvlc_media_add_option(vlcMedia, "--audio-filter=dsp"); - libvlc_media_add_option(vlcMedia, "audio-filter dsp"); - libvlc_media_add_option(vlcMedia, ":audio-filter dsp"); - libvlc_media_add_option(vlcMedia, "--audio-filter dsp"); m_aboutToFinish = false; setState(Stopped); @@ -246,13 +260,16 @@ AudioOutput::currentTime() void AudioOutput::setCurrentTime( qint64 time ) { - m_currentTime = time; + // TODO : This is a bit hacky, but m_totalTime is only used to determine + // if we are about to finish if ( m_totalTime <= 0 ) { m_totalTime = AudioEngine::instance()->currentTrackTotalTime(); } + + m_currentTime = time; emit tick( time ); - tDebug() << "Current time : " << m_currentTime << " / " << m_totalTime; +// tDebug() << "Current time : " << m_currentTime << " / " << m_totalTime; if ( time < m_totalTime - ABOUT_TO_FINISH_TIME ) { m_aboutToFinish = false; @@ -329,27 +346,13 @@ AudioOutput::seek( qint64 milliseconds ) case Buffering: break; default: - // Seeking while not being in a playingish state is cached for later. -// TODO m_seekpoint = milliseconds; return; } tDebug() << "AudioOutput:: seeking" << milliseconds << "msec"; libvlc_media_player_set_time ( vlcPlayer, milliseconds ); -/* - const qint64 time = currentTime(); - const qint64 total = totalTime(); -*/ -/* - // Reset last tick marker so we emit time even after seeking - if (time < m_lastTick) - m_lastTick = time; - if (time < total - m_prefinishMark) - m_prefinishEmitted = false; - if (time < total - ABOUT_TO_FINISH_TIME) - m_aboutToFinishEmitted = false; -*/ + setCurrentTime( milliseconds ); } diff --git a/src/libtomahawk/audio/AudioOutput.h b/src/libtomahawk/audio/AudioOutput.h index d5610f923..564515e58 100644 --- a/src/libtomahawk/audio/AudioOutput.h +++ b/src/libtomahawk/audio/AudioOutput.h @@ -58,6 +58,7 @@ public: qreal volume(); qint64 currentTime(); qint64 totalTime(); + void setAutoDelete ( bool ad ); void setDspCallback( void ( *cb ) ( signed short*, int, int ) ); @@ -82,6 +83,7 @@ private: AudioState currentState; MediaStream* currentStream; bool muted; + bool m_autoDelete; qreal m_volume; qint64 m_currentTime; qint64 m_totalTime; diff --git a/src/libtomahawk/utils/MediaStream.cpp b/src/libtomahawk/utils/MediaStream.cpp index ac2cee4ab..927f9f877 100644 --- a/src/libtomahawk/utils/MediaStream.cpp +++ b/src/libtomahawk/utils/MediaStream.cpp @@ -22,6 +22,7 @@ #include "utils/Logger.h" +#define BLOCK_SIZE 1048576 static QString s_aeInfoIdentifier = QString( "MEDIASTREAM" ); @@ -29,6 +30,7 @@ static QString s_aeInfoIdentifier = QString( "MEDIASTREAM" ); MediaStream::MediaStream() : m_type( Unknown ) , m_url( QUrl() ) + , m_ioDevice ( 0 ) , m_eos( false ) , m_pos( 0 ) , m_streamSize( 0 ) @@ -46,6 +48,15 @@ MediaStream::MediaStream( const QUrl &url ) } +MediaStream::MediaStream( QIODevice* device ) + : m_type(IODevice) +{ + tDebug() << Q_FUNC_INFO; + + m_ioDevice = device; +} + + MediaStream::~MediaStream() { tDebug() << Q_FUNC_INFO; @@ -98,7 +109,7 @@ MediaStream::endOfData() int MediaStream::readCallback ( void* data, const char* cookie, int64_t* dts, int64_t* pts, unsigned* flags, size_t* bufferSize, void** buffer ) { - tDebug() << Q_FUNC_INFO; +// tDebug() << Q_FUNC_INFO; Q_UNUSED(cookie); Q_UNUSED(dts); @@ -111,7 +122,16 @@ MediaStream::readCallback ( void* data, const char* cookie, int64_t* dts, int64_ return -1; } - *bufferSize = that->needData(buffer); + if ( that->m_type == Stream ) { + *bufferSize = that->needData(buffer); + } + else if ( that->m_type == IODevice ) { + QByteArray data = that->m_ioDevice->read(BLOCK_SIZE); + *buffer = new char[data.size()]; + memcpy(*buffer, data.data(), data.size()); + *bufferSize = data.size(); + } + return 0; } @@ -121,12 +141,16 @@ MediaStream::readDoneCallback ( void *data, const char *cookie, size_t bufferSiz { tDebug() << Q_FUNC_INFO; - Q_UNUSED(data); Q_UNUSED(cookie); Q_UNUSED(bufferSize); -// TODO : causes segfault -// delete static_cast(buffer); + MediaStream* that = static_cast < MediaStream * > ( data ); + + if ( ( that->m_type == Stream || that->m_type == IODevice ) && buffer != 0 && bufferSize > 0 ) { +// TODO : causes segfault + tDebug() << "buffer : " << buffer; + delete static_cast(buffer); + } return 0; } @@ -135,14 +159,18 @@ MediaStream::readDoneCallback ( void *data, const char *cookie, size_t bufferSiz int MediaStream::seekCallback ( void *data, const uint64_t pos ) { - tDebug() << Q_FUNC_INFO; +// tDebug() << Q_FUNC_INFO; MediaStream* that = static_cast < MediaStream * > ( data ); - if ( static_cast < int64_t > ( pos ) > that->streamSize() ) { + + if ( that->m_type == Stream && static_cast < int64_t > ( pos ) > that->streamSize() ) { return -1; } that->m_pos = pos; + if ( that->m_type == IODevice ) { + that->m_ioDevice->seek(pos); + } return 0; } diff --git a/src/libtomahawk/utils/MediaStream.h b/src/libtomahawk/utils/MediaStream.h index b7dd67987..66e5c2fdf 100644 --- a/src/libtomahawk/utils/MediaStream.h +++ b/src/libtomahawk/utils/MediaStream.h @@ -28,15 +28,17 @@ #include #include +#include class DLLEXPORT MediaStream { public: - enum MediaType { Unknown = -1, Empty = 0, Url = 1, Stream = 2 }; + enum MediaType { Unknown = -1, Empty = 0, Url = 1, Stream = 2, IODevice = 3 }; MediaStream(); MediaStream( const QUrl &url ); + MediaStream( QIODevice* device ); virtual ~MediaStream(); MediaType type(); @@ -57,6 +59,7 @@ protected: MediaType m_type; QUrl m_url; + QIODevice* m_ioDevice; bool m_eos; qint64 m_pos; From 5fb5bc4f820fe8e6a2c49bdcdb391119c4fdb5ad Mon Sep 17 00:00:00 2001 From: dridri Date: Wed, 1 Oct 2014 13:30:48 +0200 Subject: [PATCH 11/43] less debug for libvlc output --- src/libtomahawk/utils/MediaStream.cpp | 2 +- src/libtomahawk/utils/Qnr_IoDeviceStream.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libtomahawk/utils/MediaStream.cpp b/src/libtomahawk/utils/MediaStream.cpp index 927f9f877..6d304582c 100644 --- a/src/libtomahawk/utils/MediaStream.cpp +++ b/src/libtomahawk/utils/MediaStream.cpp @@ -139,7 +139,7 @@ MediaStream::readCallback ( void* data, const char* cookie, int64_t* dts, int64_ int MediaStream::readDoneCallback ( void *data, const char *cookie, size_t bufferSize, void *buffer ) { - tDebug() << Q_FUNC_INFO; +// tDebug() << Q_FUNC_INFO; Q_UNUSED(cookie); Q_UNUSED(bufferSize); diff --git a/src/libtomahawk/utils/Qnr_IoDeviceStream.cpp b/src/libtomahawk/utils/Qnr_IoDeviceStream.cpp index 8c80fa3c2..1199db759 100644 --- a/src/libtomahawk/utils/Qnr_IoDeviceStream.cpp +++ b/src/libtomahawk/utils/Qnr_IoDeviceStream.cpp @@ -106,7 +106,7 @@ QNR_IODeviceStream::needData ( void** buffer ) *buffer = new char[data.size()]; memcpy(*buffer, data.data(), data.size()); - tDebug() << Q_FUNC_INFO << " Returning buffer with size " << data.size(); +// tDebug() << Q_FUNC_INFO << " Returning buffer with size " << data.size(); return data.size(); } From ebf58c1a57a8e57d678720f9ad3a8c3556f1a273 Mon Sep 17 00:00:00 2001 From: dridri Date: Wed, 1 Oct 2014 13:48:06 +0200 Subject: [PATCH 12/43] --no-one-instance nor recognized by libvlc new version --- src/libtomahawk/audio/AudioOutput.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libtomahawk/audio/AudioOutput.cpp b/src/libtomahawk/audio/AudioOutput.cpp index 3be3a0aba..ebc8a29e8 100644 --- a/src/libtomahawk/audio/AudioOutput.cpp +++ b/src/libtomahawk/audio/AudioOutput.cpp @@ -74,7 +74,7 @@ AudioOutput::AudioOutput( QObject* parent ) QList args; args << "--ignore-config"; - args << "--verbose=11111"; + args << "--verbose=42"; args << "--no-plugins-cache"; args << "--extraintf=logger"; args << "--no-media-library"; @@ -84,7 +84,7 @@ AudioOutput::AudioOutput( QObject* parent ) args << "--no-snapshot-preview"; args << "--no-xlib"; args << "--services-discovery=''"; - args << "--no-one-instance"; +// args << "--no-one-instance"; args << "--no-video"; // args << "--audio-filter=dsp"; // args << QString("--dsp-callback=%1").arg((quint64)&AudioOutput::s_dspCallback, 0, 16).toAscii(); From 667996715af4d5d35ba7de7ab40047107206309c Mon Sep 17 00:00:00 2001 From: dridri Date: Wed, 1 Oct 2014 16:26:10 +0200 Subject: [PATCH 13/43] QIODevice (playing from peers) should be ok now --- src/libtomahawk/utils/MediaStream.cpp | 93 +++++++++++++++++--- src/libtomahawk/utils/MediaStream.h | 16 +++- src/libtomahawk/utils/Qnr_IoDeviceStream.cpp | 5 +- src/libtomahawk/utils/Qnr_IoDeviceStream.h | 5 +- 4 files changed, 97 insertions(+), 22 deletions(-) diff --git a/src/libtomahawk/utils/MediaStream.cpp b/src/libtomahawk/utils/MediaStream.cpp index 6d304582c..8b98f4360 100644 --- a/src/libtomahawk/utils/MediaStream.cpp +++ b/src/libtomahawk/utils/MediaStream.cpp @@ -27,20 +27,31 @@ static QString s_aeInfoIdentifier = QString( "MEDIASTREAM" ); -MediaStream::MediaStream() - : m_type( Unknown ) +MediaStream::MediaStream( QObject* parent ) + : QObject( parent ) + , m_type( Unknown ) , m_url( QUrl() ) , m_ioDevice ( 0 ) + , m_started( false ) + , m_bufferingFinished( false ) , m_eos( false ) , m_pos( 0 ) , m_streamSize( 0 ) { tDebug() << Q_FUNC_INFO; + } MediaStream::MediaStream( const QUrl &url ) - : m_type(Url) + : QObject( 0 ) + , m_type(Url) + , m_ioDevice ( 0 ) + , m_started( false ) + , m_bufferingFinished( false ) + , m_eos( false ) + , m_pos( 0 ) + , m_streamSize( 0 ) { tDebug() << Q_FUNC_INFO; @@ -49,11 +60,38 @@ MediaStream::MediaStream( const QUrl &url ) MediaStream::MediaStream( QIODevice* device ) - : m_type(IODevice) + : QObject( 0 ) + , m_type(IODevice) + , m_url( QUrl() ) + , m_ioDevice ( 0 ) + , m_started( false ) + , m_bufferingFinished( false ) + , m_eos( false ) + , m_pos( 0 ) + , m_streamSize( 0 ) { tDebug() << Q_FUNC_INFO; m_ioDevice = device; + QObject::connect( m_ioDevice, SIGNAL( readChannelFinished() ), this, SLOT( bufferingFinished() ) ); +} + + +MediaStream::MediaStream( const MediaStream& copy ) + : QObject( copy.parent() ) +{ + m_type = copy.m_type; + m_url = copy.m_url; + m_ioDevice = copy.m_ioDevice; + m_started = copy.m_started; + m_bufferingFinished = copy.m_bufferingFinished; + m_eos = copy.m_eos; + m_pos = copy.m_pos; + m_streamSize = copy.m_streamSize; + + if ( m_type == IODevice ) { + QObject::connect( m_ioDevice, SIGNAL( readChannelFinished() ), this, SLOT( bufferingFinished() ) ); + } } @@ -106,32 +144,58 @@ MediaStream::endOfData() } +void MediaStream::bufferingFinished() +{ + tDebug() << Q_FUNC_INFO; + + m_bufferingFinished = true; +} + + int MediaStream::readCallback ( void* data, const char* cookie, int64_t* dts, int64_t* pts, unsigned* flags, size_t* bufferSize, void** buffer ) { -// tDebug() << Q_FUNC_INFO; - Q_UNUSED(cookie); Q_UNUSED(dts); Q_UNUSED(pts); Q_UNUSED(flags); MediaStream* that = static_cast < MediaStream * > ( data ); + qint64 bufsize = 0; + *bufferSize = 0; + +// tDebug() << Q_FUNC_INFO << " ---- type : " << that->m_type; if ( that->m_eos == true ) { return -1; } if ( that->m_type == Stream ) { - *bufferSize = that->needData(buffer); + bufsize = that->needData(buffer); } else if ( that->m_type == IODevice ) { - QByteArray data = that->m_ioDevice->read(BLOCK_SIZE); - *buffer = new char[data.size()]; - memcpy(*buffer, data.data(), data.size()); - *bufferSize = data.size(); + /* + *buffer = new char[BLOCK_SIZE]; + bufsize = that->m_ioDevice->read( (char*)*buffer, BLOCK_SIZE ); + */ + bufsize = that->m_ioDevice->read( that->m_buffer, BLOCK_SIZE ); + *buffer = that->m_buffer; +// tDebug() << "readCallback(QIODevice) returning bufsize : " << bufsize; } + if ( bufsize > 0 ) { + that->m_started = true; + } + if ( bufsize == 0 && that->m_started && that->m_bufferingFinished == true ) { + that->m_eos = true; + return -1; + } + if ( bufsize < 0 ) { + that->m_eos = true; + return -1; + } + + *bufferSize = bufsize; return 0; } @@ -146,9 +210,9 @@ MediaStream::readDoneCallback ( void *data, const char *cookie, size_t bufferSiz MediaStream* that = static_cast < MediaStream * > ( data ); - if ( ( that->m_type == Stream || that->m_type == IODevice ) && buffer != 0 && bufferSize > 0 ) { + if ( ( that->m_type == Stream/* || that->m_type == IODevice*/ ) && buffer != 0 && bufferSize > 0 ) { // TODO : causes segfault - tDebug() << "buffer : " << buffer; +// tDebug() << "buffer : " << buffer; delete static_cast(buffer); } @@ -159,7 +223,7 @@ MediaStream::readDoneCallback ( void *data, const char *cookie, size_t bufferSiz int MediaStream::seekCallback ( void *data, const uint64_t pos ) { -// tDebug() << Q_FUNC_INFO; + tDebug() << Q_FUNC_INFO; MediaStream* that = static_cast < MediaStream * > ( data ); @@ -167,6 +231,7 @@ MediaStream::seekCallback ( void *data, const uint64_t pos ) return -1; } + that->m_started = false; that->m_pos = pos; if ( that->m_type == IODevice ) { that->m_ioDevice->seek(pos); diff --git a/src/libtomahawk/utils/MediaStream.h b/src/libtomahawk/utils/MediaStream.h index 66e5c2fdf..e1f7b0f9f 100644 --- a/src/libtomahawk/utils/MediaStream.h +++ b/src/libtomahawk/utils/MediaStream.h @@ -27,16 +27,19 @@ #include "utils/Logger.h" #include +#include #include #include -class DLLEXPORT MediaStream +class DLLEXPORT MediaStream : public QObject { + Q_OBJECT public: enum MediaType { Unknown = -1, Empty = 0, Url = 1, Stream = 2, IODevice = 3 }; - MediaStream(); + MediaStream( QObject* parent = 0 ); + MediaStream( const MediaStream& copy ); MediaStream( const QUrl &url ); MediaStream( QIODevice* device ); virtual ~MediaStream(); @@ -48,12 +51,15 @@ public: qint64 streamSize(); virtual void seekStream( qint64 offset ) { (void)offset; } - virtual size_t needData ( void** buffer ) { (void)buffer; tDebug() << Q_FUNC_INFO; return 0; } + virtual qint64 needData ( void** buffer ) { (void)buffer; tDebug() << Q_FUNC_INFO; return 0; } static int readCallback ( void* data, const char* cookie, int64_t* dts, int64_t* pts, unsigned* flags, size_t* bufferSize, void** buffer ); static int readDoneCallback ( void *data, const char *cookie, size_t bufferSize, void *buffer ); static int seekCallback ( void *data, const uint64_t pos ); +public slots: + void bufferingFinished(); + protected: void endOfData(); @@ -61,9 +67,13 @@ protected: QUrl m_url; QIODevice* m_ioDevice; + bool m_started; + bool m_bufferingFinished; bool m_eos; qint64 m_pos; qint64 m_streamSize; + + char m_buffer[1048576]; }; #endif // MEDIASTREAM_H diff --git a/src/libtomahawk/utils/Qnr_IoDeviceStream.cpp b/src/libtomahawk/utils/Qnr_IoDeviceStream.cpp index 1199db759..fca6de94b 100644 --- a/src/libtomahawk/utils/Qnr_IoDeviceStream.cpp +++ b/src/libtomahawk/utils/Qnr_IoDeviceStream.cpp @@ -33,8 +33,7 @@ using namespace Tomahawk; #define BLOCK_SIZE 1048576 QNR_IODeviceStream::QNR_IODeviceStream( const QSharedPointer& reply, QObject* parent ) - : QObject( parent ) - , MediaStream() + : MediaStream( parent ) , m_networkReply( reply ) , m_timer( new QTimer( this ) ) { @@ -90,7 +89,7 @@ QNR_IODeviceStream::seekStream( qint64 offset ) } -size_t +qint64 QNR_IODeviceStream::needData ( void** buffer ) { // tDebug() << Q_FUNC_INFO; diff --git a/src/libtomahawk/utils/Qnr_IoDeviceStream.h b/src/libtomahawk/utils/Qnr_IoDeviceStream.h index e43a6437a..ef3b89263 100644 --- a/src/libtomahawk/utils/Qnr_IoDeviceStream.h +++ b/src/libtomahawk/utils/Qnr_IoDeviceStream.h @@ -38,15 +38,16 @@ class QTimer; namespace Tomahawk { -class DLLEXPORT QNR_IODeviceStream : public QObject, public MediaStream +class DLLEXPORT QNR_IODeviceStream : public MediaStream { Q_OBJECT + public: explicit QNR_IODeviceStream( const QSharedPointer& reply, QObject *parent = 0 ); ~QNR_IODeviceStream(); virtual void seekStream( qint64 offset ); - virtual size_t needData ( void** buffer ); + virtual qint64 needData ( void** buffer ); private slots: void readyRead(); From a1e7af361edfc19a94f5212ef8c538d590af4323 Mon Sep 17 00:00:00 2001 From: dridri Date: Wed, 1 Oct 2014 18:24:25 +0200 Subject: [PATCH 14/43] added seek-ability detection --- src/libtomahawk/audio/AudioEngine.cpp | 11 ++++--- src/libtomahawk/audio/AudioOutput.cpp | 44 ++++++++++++++++++++++----- src/libtomahawk/audio/AudioOutput.h | 2 ++ src/libtomahawk/utils/MediaStream.cpp | 10 ++---- 4 files changed, 46 insertions(+), 21 deletions(-) diff --git a/src/libtomahawk/audio/AudioEngine.cpp b/src/libtomahawk/audio/AudioEngine.cpp index 01b05e463..149cab3fd 100644 --- a/src/libtomahawk/audio/AudioEngine.cpp +++ b/src/libtomahawk/audio/AudioEngine.cpp @@ -437,10 +437,11 @@ bool AudioEngine::canSeek() { Q_D( AudioEngine ); -/* - if ( d->playlist.isNull() ) - return true; -*/ + + if ( !d->audioOutput->isSeekable() ) { + return false; + } + return !d->playlist.isNull() && ( d->playlist.data()->seekRestrictions() != PlaylistModes::NoSeek ); } @@ -1249,7 +1250,7 @@ AudioEngine::currentTrackTotalTime() const // libVLC doesn't report total duration for stream data (imem://) // But it's not a real problem for playback, since // EndOfStream is emitted by libVLC itself - if ( d_func()->audioOutput->totalTime() == 0 && d_func()->currentTrack && d_func()->currentTrack->track() ) { + if ( d_func()->audioOutput->totalTime() <= 0 && d_func()->currentTrack && d_func()->currentTrack->track() ) { return d_func()->currentTrack->track()->duration() * 1000 + 1000; } return d_func()->audioOutput->totalTime(); diff --git a/src/libtomahawk/audio/AudioOutput.cpp b/src/libtomahawk/audio/AudioOutput.cpp index ebc8a29e8..35371029e 100644 --- a/src/libtomahawk/audio/AudioOutput.cpp +++ b/src/libtomahawk/audio/AudioOutput.cpp @@ -53,6 +53,7 @@ AudioOutput::instance() AudioOutput::AudioOutput( QObject* parent ) : QObject( parent ) , currentState( Stopped ) + , seekable( true ) , muted( false ) , m_autoDelete ( true ) , m_volume( 1.0 ) @@ -168,9 +169,11 @@ AudioOutput::setCurrentSource(MediaStream* stream) if ( m_autoDelete && currentStream != 0 ) { delete currentStream; } + currentStream = stream; m_totalTime = 0; m_currentTime = 0; + seekable = true; QByteArray url; switch (stream->type()) { @@ -262,8 +265,9 @@ AudioOutput::setCurrentTime( qint64 time ) { // TODO : This is a bit hacky, but m_totalTime is only used to determine // if we are about to finish - if ( m_totalTime <= 0 ) { + if ( m_totalTime == 0 ) { m_totalTime = AudioEngine::instance()->currentTrackTotalTime(); + seekable = true; } m_currentTime = time; @@ -271,10 +275,15 @@ AudioOutput::setCurrentTime( qint64 time ) // tDebug() << "Current time : " << m_currentTime << " / " << m_totalTime; - if ( time < m_totalTime - ABOUT_TO_FINISH_TIME ) { + qint64 total = m_totalTime; + if ( total <= 0 ) { + total = AudioEngine::instance()->currentTrackTotalTime(); + } + + if ( time < total - ABOUT_TO_FINISH_TIME ) { m_aboutToFinish = false; } - if ( !m_aboutToFinish && m_totalTime > 0 && time >= m_totalTime - ABOUT_TO_FINISH_TIME ) { + if ( !m_aboutToFinish && total > 0 && time >= total - ABOUT_TO_FINISH_TIME ) { m_aboutToFinish = true; emit aboutToFinish(); } @@ -291,10 +300,15 @@ AudioOutput::totalTime() void AudioOutput::setTotalTime( qint64 time ) { - if ( time > 0 ) { + tDebug() << Q_FUNC_INFO << " " << time; + + if ( time <= 0 ) { + seekable = false; + } else { m_totalTime = time; + seekable = true; // emit current time to refresh total time - emit tick( m_currentTime ); + emit tick( time ); } } @@ -303,6 +317,7 @@ void AudioOutput::play() { tDebug() << Q_FUNC_INFO; + if ( libvlc_media_player_is_playing ( vlcPlayer ) ) { libvlc_media_player_set_pause ( vlcPlayer, 0 ); } else { @@ -339,6 +354,10 @@ AudioOutput::seek( qint64 milliseconds ) { tDebug() << Q_FUNC_INFO; + if ( !seekable ) { + return; + } + switch ( currentState ) { case Playing: case Paused: @@ -356,6 +375,15 @@ AudioOutput::seek( qint64 milliseconds ) } +bool +AudioOutput::isSeekable() +{ + tDebug() << Q_FUNC_INFO; + + return seekable; +} + + bool AudioOutput::isMuted() { @@ -413,16 +441,16 @@ AudioOutput::vlcEventCallback( const libvlc_event_t* event, void* opaque ) that->setCurrentTime( event->u.media_player_time_changed.new_time ); break; case libvlc_MediaPlayerSeekableChanged: + // tDebug() << Q_FUNC_INFO << " : seekable changed : " << event->u.media_player_seekable_changed.new_seekable; //TODO, bool event->u.media_player_seekable_changed.new_seekable break; case libvlc_MediaDurationChanged: that->setTotalTime( event->u.media_duration_changed.new_duration ); break; - /* case libvlc_MediaPlayerLengthChanged: - that->setTotalTime( event->u.media_player_length_changed.new_length ); + // tDebug() << Q_FUNC_INFO << " : length changed : " << event->u.media_player_length_changed.new_length; + // that->setTotalTime( event->u.media_player_length_changed.new_length ); break; - */ case libvlc_MediaPlayerNothingSpecial: case libvlc_MediaPlayerOpening: case libvlc_MediaPlayerBuffering: diff --git a/src/libtomahawk/audio/AudioOutput.h b/src/libtomahawk/audio/AudioOutput.h index 564515e58..0a0ff7e3c 100644 --- a/src/libtomahawk/audio/AudioOutput.h +++ b/src/libtomahawk/audio/AudioOutput.h @@ -52,6 +52,7 @@ public: void stop(); void seek(qint64 milliseconds); + bool isSeekable(); bool isMuted(); void setMuted(bool m); void setVolume(qreal vol); @@ -82,6 +83,7 @@ private: static AudioOutput* s_instance; AudioState currentState; MediaStream* currentStream; + bool seekable; bool muted; bool m_autoDelete; qreal m_volume; diff --git a/src/libtomahawk/utils/MediaStream.cpp b/src/libtomahawk/utils/MediaStream.cpp index 8b98f4360..fc9315852 100644 --- a/src/libtomahawk/utils/MediaStream.cpp +++ b/src/libtomahawk/utils/MediaStream.cpp @@ -174,10 +174,6 @@ MediaStream::readCallback ( void* data, const char* cookie, int64_t* dts, int64_ bufsize = that->needData(buffer); } else if ( that->m_type == IODevice ) { - /* - *buffer = new char[BLOCK_SIZE]; - bufsize = that->m_ioDevice->read( (char*)*buffer, BLOCK_SIZE ); - */ bufsize = that->m_ioDevice->read( that->m_buffer, BLOCK_SIZE ); *buffer = that->m_buffer; // tDebug() << "readCallback(QIODevice) returning bufsize : " << bufsize; @@ -186,7 +182,7 @@ MediaStream::readCallback ( void* data, const char* cookie, int64_t* dts, int64_ if ( bufsize > 0 ) { that->m_started = true; } - if ( bufsize == 0 && that->m_started && that->m_bufferingFinished == true ) { + if ( that->m_type == IODevice && bufsize == 0 && that->m_started && that->m_bufferingFinished == true ) { that->m_eos = true; return -1; } @@ -210,9 +206,7 @@ MediaStream::readDoneCallback ( void *data, const char *cookie, size_t bufferSiz MediaStream* that = static_cast < MediaStream * > ( data ); - if ( ( that->m_type == Stream/* || that->m_type == IODevice*/ ) && buffer != 0 && bufferSize > 0 ) { -// TODO : causes segfault -// tDebug() << "buffer : " << buffer; + if ( ( that->m_type == Stream ) && buffer != 0 && bufferSize > 0 ) { delete static_cast(buffer); } From abba474373a919d82297e41c1acad21245c22ce5 Mon Sep 17 00:00:00 2001 From: dridri Date: Wed, 1 Oct 2014 19:20:46 +0200 Subject: [PATCH 15/43] let's clean it a bit --- src/libtomahawk/audio/AudioEngine_p.h | 1 - src/libtomahawk/audio/AudioOutput.cpp | 8 ++++---- src/libtomahawk/utils/MediaStream.cpp | 7 ------- 3 files changed, 4 insertions(+), 12 deletions(-) diff --git a/src/libtomahawk/audio/AudioEngine_p.h b/src/libtomahawk/audio/AudioEngine_p.h index 1bf5b9b1c..b7c736626 100644 --- a/src/libtomahawk/audio/AudioEngine_p.h +++ b/src/libtomahawk/audio/AudioEngine_p.h @@ -32,7 +32,6 @@ public: public slots: void onStateChanged( AudioOutput::AudioState newState, AudioOutput::AudioState oldState ); -// void onAudioDataArrived( QMap< Phonon::AudioDataOutput::Channel, QVector< qint16 > > data ); private: QSharedPointer input; diff --git a/src/libtomahawk/audio/AudioOutput.cpp b/src/libtomahawk/audio/AudioOutput.cpp index 35371029e..f41cd6ce4 100644 --- a/src/libtomahawk/audio/AudioOutput.cpp +++ b/src/libtomahawk/audio/AudioOutput.cpp @@ -263,7 +263,7 @@ AudioOutput::currentTime() void AudioOutput::setCurrentTime( qint64 time ) { - // TODO : This is a bit hacky, but m_totalTime is only used to determine + // FIXME : This is a bit hacky, but m_totalTime is only used to determine // if we are about to finish if ( m_totalTime == 0 ) { m_totalTime = AudioEngine::instance()->currentTrackTotalTime(); @@ -275,6 +275,8 @@ AudioOutput::setCurrentTime( qint64 time ) // tDebug() << "Current time : " << m_currentTime << " / " << m_totalTime; + // FIXME pt 2 : we use temporary variable to avoid overriding m_totalTime + // in the case it is < 0 (which means that the media is not seekable) qint64 total = m_totalTime; if ( total <= 0 ) { total = AudioEngine::instance()->currentTrackTotalTime(); @@ -332,7 +334,7 @@ void AudioOutput::pause() { tDebug() << Q_FUNC_INFO; -// libvlc_media_player_pause( vlcPlayer ); + libvlc_media_player_set_pause ( vlcPlayer, 1 ); setState( Paused ); @@ -442,14 +444,12 @@ AudioOutput::vlcEventCallback( const libvlc_event_t* event, void* opaque ) break; case libvlc_MediaPlayerSeekableChanged: // tDebug() << Q_FUNC_INFO << " : seekable changed : " << event->u.media_player_seekable_changed.new_seekable; - //TODO, bool event->u.media_player_seekable_changed.new_seekable break; case libvlc_MediaDurationChanged: that->setTotalTime( event->u.media_duration_changed.new_duration ); break; case libvlc_MediaPlayerLengthChanged: // tDebug() << Q_FUNC_INFO << " : length changed : " << event->u.media_player_length_changed.new_length; - // that->setTotalTime( event->u.media_player_length_changed.new_length ); break; case libvlc_MediaPlayerNothingSpecial: case libvlc_MediaPlayerOpening: diff --git a/src/libtomahawk/utils/MediaStream.cpp b/src/libtomahawk/utils/MediaStream.cpp index fc9315852..c5c1335b9 100644 --- a/src/libtomahawk/utils/MediaStream.cpp +++ b/src/libtomahawk/utils/MediaStream.cpp @@ -164,8 +164,6 @@ MediaStream::readCallback ( void* data, const char* cookie, int64_t* dts, int64_ qint64 bufsize = 0; *bufferSize = 0; -// tDebug() << Q_FUNC_INFO << " ---- type : " << that->m_type; - if ( that->m_eos == true ) { return -1; } @@ -176,7 +174,6 @@ MediaStream::readCallback ( void* data, const char* cookie, int64_t* dts, int64_ else if ( that->m_type == IODevice ) { bufsize = that->m_ioDevice->read( that->m_buffer, BLOCK_SIZE ); *buffer = that->m_buffer; -// tDebug() << "readCallback(QIODevice) returning bufsize : " << bufsize; } if ( bufsize > 0 ) { @@ -199,8 +196,6 @@ MediaStream::readCallback ( void* data, const char* cookie, int64_t* dts, int64_ int MediaStream::readDoneCallback ( void *data, const char *cookie, size_t bufferSize, void *buffer ) { -// tDebug() << Q_FUNC_INFO; - Q_UNUSED(cookie); Q_UNUSED(bufferSize); @@ -217,8 +212,6 @@ MediaStream::readDoneCallback ( void *data, const char *cookie, size_t bufferSiz int MediaStream::seekCallback ( void *data, const uint64_t pos ) { - tDebug() << Q_FUNC_INFO; - MediaStream* that = static_cast < MediaStream * > ( data ); if ( that->m_type == Stream && static_cast < int64_t > ( pos ) > that->streamSize() ) { From eb1ef86452553cfe6b8136dbe420b7c4b218713f Mon Sep 17 00:00:00 2001 From: dridri Date: Thu, 2 Oct 2014 22:34:19 +0200 Subject: [PATCH 16/43] First attempt to add DSP support --- src/libtomahawk/CMakeLists.txt | 2 + src/libtomahawk/audio/AudioEngine.cpp | 2 +- src/libtomahawk/audio/AudioEngine.h | 2 +- src/libtomahawk/audio/AudioOutput.cpp | 20 +++-- src/libtomahawk/audio/AudioOutput.h | 6 +- src/libtomahawk/audio/VlcDspHack.cpp | 24 ++++++ src/libtomahawk/audio/VlcDspHack.h | 28 +++++++ src/libtomahawk/audio/VlcDspHack_p.h | 107 ++++++++++++++++++++++++++ 8 files changed, 180 insertions(+), 11 deletions(-) create mode 100644 src/libtomahawk/audio/VlcDspHack.cpp create mode 100644 src/libtomahawk/audio/VlcDspHack.h create mode 100644 src/libtomahawk/audio/VlcDspHack_p.h diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt index d4b05cb3c..ccb03f607 100644 --- a/src/libtomahawk/CMakeLists.txt +++ b/src/libtomahawk/CMakeLists.txt @@ -215,6 +215,7 @@ list(APPEND libSources audio/AudioEngine.cpp audio/AudioOutput.cpp + audio/VlcDspHack.cpp collection/Collection.cpp collection/ArtistsRequest.cpp @@ -506,6 +507,7 @@ TARGET_LINK_LIBRARIES( tomahawklib LINK_PRIVATE ${PHONON_LIBRARY} ${LIBVLC_LIBRARY} + ${LIBVLCCORE_LIBRARY} # Thirdparty shipped with tomahawk ${LIBPORTFWD_LIBRARIES} diff --git a/src/libtomahawk/audio/AudioEngine.cpp b/src/libtomahawk/audio/AudioEngine.cpp index 149cab3fd..649ca150d 100644 --- a/src/libtomahawk/audio/AudioEngine.cpp +++ b/src/libtomahawk/audio/AudioEngine.cpp @@ -1341,7 +1341,7 @@ AudioEngine::setCurrentTrackPlaylist( const playlistinterface_ptr& playlist ) void -AudioEngine::setDspCallback( void ( *cb ) ( signed short*, int, int ) ) +AudioEngine::setDspCallback( void ( *cb ) ( float*, int, int ) ) { Q_D( AudioEngine ); diff --git a/src/libtomahawk/audio/AudioEngine.h b/src/libtomahawk/audio/AudioEngine.h index eb3d0862f..f00ea04a7 100644 --- a/src/libtomahawk/audio/AudioEngine.h +++ b/src/libtomahawk/audio/AudioEngine.h @@ -109,7 +109,7 @@ public: */ qint64 currentTrackTotalTime() const; - void setDspCallback( void ( *cb ) ( signed short* samples, int nb_channels, int nb_samples ) ); + void setDspCallback( void ( *cb ) ( float* samples, int nb_channels, int nb_samples ) ); public slots: void playPause(); diff --git a/src/libtomahawk/audio/AudioOutput.cpp b/src/libtomahawk/audio/AudioOutput.cpp index f41cd6ce4..e893524d5 100644 --- a/src/libtomahawk/audio/AudioOutput.cpp +++ b/src/libtomahawk/audio/AudioOutput.cpp @@ -20,6 +20,7 @@ #include "AudioEngine.h" #include "AudioOutput.h" +#include "VlcDspHack.h" #include "utils/Logger.h" @@ -85,10 +86,11 @@ AudioOutput::AudioOutput( QObject* parent ) args << "--no-snapshot-preview"; args << "--no-xlib"; args << "--services-discovery=''"; -// args << "--no-one-instance"; args << "--no-video"; -// args << "--audio-filter=dsp"; -// args << QString("--dsp-callback=%1").arg((quint64)&AudioOutput::s_dspCallback, 0, 16).toAscii(); +#ifdef VLC_DSP_PLUGIN_ENABLED + args << "--audio-filter=dsp"; + args << QString("--dsp-callback=%1").arg((quint64)&AudioOutput::s_dspCallback, 0, 16).toAscii(); +#endif QVarLengthArray< const char * , 64 > vlcArgs( args.size() ); for ( int i = 0 ; i < args.size() ; ++i ) { @@ -138,6 +140,8 @@ AudioOutput::AudioOutput( QObject* parent ) AudioOutput::~AudioOutput() { tDebug() << Q_FUNC_INFO; + + // TODO } @@ -218,6 +222,10 @@ AudioOutput::setCurrentSource(MediaStream* stream) libvlc_media_player_set_media( vlcPlayer, vlcMedia ); +#ifdef VLC_DSP_PLUGIN_ENABLED + // This is very, very tricky + VlcDspHackInstall( vlcPlayer ); +#endif if ( stream->type() == MediaStream::Url ) { m_totalTime = libvlc_media_get_duration( vlcMedia ); @@ -479,9 +487,9 @@ AudioOutput::vlcEventCallback( const libvlc_event_t* event, void* opaque ) void -AudioOutput::s_dspCallback( signed short* samples, int nb_channels, int nb_samples ) +AudioOutput::s_dspCallback( float* samples, int nb_channels, int nb_samples ) { - tDebug() << Q_FUNC_INFO; +// tDebug() << Q_FUNC_INFO; if ( AudioOutput::instance()->dspPluginCallback ) { AudioOutput::instance()->dspPluginCallback( samples, nb_channels, nb_samples ); @@ -490,7 +498,7 @@ AudioOutput::s_dspCallback( signed short* samples, int nb_channels, int nb_sampl void -AudioOutput::setDspCallback( void ( *cb ) ( signed short*, int, int ) ) +AudioOutput::setDspCallback( void ( *cb ) ( float*, int, int ) ) { dspPluginCallback = cb; } diff --git a/src/libtomahawk/audio/AudioOutput.h b/src/libtomahawk/audio/AudioOutput.h index 0a0ff7e3c..3d2388031 100644 --- a/src/libtomahawk/audio/AudioOutput.h +++ b/src/libtomahawk/audio/AudioOutput.h @@ -61,7 +61,7 @@ public: qint64 totalTime(); void setAutoDelete ( bool ad ); - void setDspCallback( void ( *cb ) ( signed short*, int, int ) ); + void setDspCallback( void ( *cb ) ( float*, int, int ) ); static AudioOutput* instance(); @@ -78,7 +78,7 @@ private: void setTotalTime( qint64 time ); static void vlcEventCallback( const libvlc_event_t *event, void *opaque ); - static void s_dspCallback( signed short* samples, int nb_channels, int nb_samples ); + static void s_dspCallback( float* samples, int nb_channels, int nb_samples ); static AudioOutput* s_instance; AudioState currentState; @@ -91,7 +91,7 @@ private: qint64 m_totalTime; bool m_aboutToFinish; - void ( *dspPluginCallback ) ( signed short* samples, int nb_channels, int nb_samples ); + void ( *dspPluginCallback ) ( float* samples, int nb_channels, int nb_samples ); libvlc_instance_t* vlcInstance; libvlc_media_player_t* vlcPlayer; diff --git a/src/libtomahawk/audio/VlcDspHack.cpp b/src/libtomahawk/audio/VlcDspHack.cpp new file mode 100644 index 000000000..56f2952b8 --- /dev/null +++ b/src/libtomahawk/audio/VlcDspHack.cpp @@ -0,0 +1,24 @@ +#include "VlcDspHack_p.h" + +#ifdef VLC_DSP_PLUGIN_ENABLED + +void +VlcDspHackInstall( libvlc_media_player_t* vlcPlayer ) +{ + if ( vlcPlayer->input.p_resource != 0 ) { + audio_output_t *aout = input_resource_GetAout( vlcPlayer->input.p_resource ); + if ( aout != 0 ) { + var_Create( (vlc_object_t*)aout, "audio-filter", 0x0040 /*VLC_VAR_STRING*/ ); + + vlc_value_t val; + val.psz_string = (char*)"dsp"; + var_SetChecked( (vlc_object_t*)aout, "audio-filter", 0x0040 /*VLC_VAR_STRING*/, val ); + + aout->event.restart_request( aout, 1 /*AOUT_RESTART_FILTERS*/ ); + + input_resource_PutAout( vlcPlayer->input.p_resource, aout ); + } + } +} + +#endif // VLC_DSP_PLUGIN_ENABLED diff --git a/src/libtomahawk/audio/VlcDspHack.h b/src/libtomahawk/audio/VlcDspHack.h new file mode 100644 index 000000000..1c8a05cc2 --- /dev/null +++ b/src/libtomahawk/audio/VlcDspHack.h @@ -0,0 +1,28 @@ +#ifndef VLCDSPHACK_H +#define VLCDSPHACK_H + +/* + * Very tricky technique to enable DSP plugin support + * There is no other way to do this with libvlc for the moment + * + * A VLC audio filter plugin specificaly made for Tomahawk + * is necessary to get it functionning + * + * TODO : Check thoroughly if both libvlc_media_player_t and audio_output + * structures are identical to those in the running libvlccore.so + * (checking if libVLC version is >= than the one used to compile Tomahawk + * and verifying pointers integrity should be enough. + * + check if audio filter "dsp" is present in libVLC plugins list) +*/ + +//#define VLC_DSP_PLUGIN_ENABLED + +#ifdef VLC_DSP_PLUGIN_ENABLED + +struct libvlc_media_player_t; + +void VlcDspHackInstall( libvlc_media_player_t* vlcPlayer ); + +#endif // VLC_DSP_PLUGIN_ENABLED + +#endif // VLCDSPHACK_H \ No newline at end of file diff --git a/src/libtomahawk/audio/VlcDspHack_p.h b/src/libtomahawk/audio/VlcDspHack_p.h new file mode 100644 index 000000000..0a54f152d --- /dev/null +++ b/src/libtomahawk/audio/VlcDspHack_p.h @@ -0,0 +1,107 @@ +#ifndef VLCDSPHACK_P_H +#define VLCDSPHACK_P_H + +#include "VlcDspHack.h" + +#ifdef VLC_DSP_PLUGIN_ENABLED + +#include + +#include +#include +#include +#include +#include + +// TODO : Replace all these copy-pasted strutures by vlc/plugins/?.h includes + +typedef struct audio_output audio_output_t; +typedef struct input_resource_t input_resource_t; +typedef struct vlc_object_t vlc_object_t; +typedef struct vlc_list_t vlc_list_t; +typedef int64_t mtime_t; +typedef pthread_mutex_t vlc_mutex_t; + +typedef union +{ + int64_t i_int; + bool b_bool; + float f_float; + char * psz_string; + void * p_address; + vlc_object_t * p_object; + vlc_list_t * p_list; + mtime_t i_time; + struct { int32_t x; int32_t y; } coords; + +} vlc_value_t; + +struct audio_output +{ + const char *psz_object_type; + char *psz_header; + int i_flags; + bool b_force; + void *p_libvlc; + void * p_parent; + + void *sys; + int (*start)(audio_output_t *, void *fmt); + void (*stop)(audio_output_t *); + int (*time_get)(audio_output_t *, void *delay); + void (*play)(audio_output_t *, void *); + void (*pause)( audio_output_t *, bool pause, mtime_t date); + void (*flush)( audio_output_t *, bool wait); + int (*volume_set)(audio_output_t *, float volume); + int (*mute_set)(audio_output_t *, bool mute); + int (*device_select)(audio_output_t *, const char *id); + struct { + void (*volume_report)(audio_output_t *, float); + void (*mute_report)(audio_output_t *, bool); + void (*policy_report)(audio_output_t *, bool); + void (*device_report)(audio_output_t *, const char *); + void (*hotplug_report)(audio_output_t *, const char *, const char *); + int (*gain_request)(audio_output_t *, float); + void (*restart_request)(audio_output_t *, unsigned); + } event; +}; + + +struct libvlc_media_player_t +{ + const char *psz_object_type; + char *psz_header; + int i_flags; + bool b_force; + void *p_libvlc; + void *p_parent; + + int i_refcount; + vlc_mutex_t object_lock; + + struct + { + void *p_thread; + input_resource_t *p_resource; + vlc_mutex_t lock; + } input; + + void *p_libvlc_instance; + void *p_md; + void *p_event_manager; + int state; +}; + +extern "C" { + audio_output_t* input_resource_GetAout(input_resource_t*); + void input_resource_PutAout(input_resource_t*, audio_output_t*); + int var_Create(vlc_object_t *, const char *, int ); + int var_SetChecked( vlc_object_t *, const char *, int, vlc_value_t ); + static inline void aout_RestartRequest(audio_output_t *aout, unsigned mode){ + aout->event.restart_request(aout, mode); + } +}; + +#endif // VLC_DSP_PLUGIN_ENABLED + +#endif // VLCDSPHACK_P_H From ead0ecc80873a92e8efe4520c4a66ae3a854b8fd Mon Sep 17 00:00:00 2001 From: dridri Date: Sat, 18 Oct 2014 20:02:27 +0200 Subject: [PATCH 17/43] clean code, use boost::function for callbacks --- CMakeModules/FindLIBVLC.cmake | 11 ++- src/libtomahawk/CMakeLists.txt | 5 +- src/libtomahawk/audio/AudioEngine.cpp | 10 +-- src/libtomahawk/audio/AudioEngine.h | 3 +- src/libtomahawk/audio/AudioEngine_p.h | 2 - src/libtomahawk/audio/AudioOutput.cpp | 20 +++-- src/libtomahawk/audio/AudioOutput.h | 12 +-- src/libtomahawk/audio/VlcDsp.cpp | 38 +++++++++ src/libtomahawk/audio/VlcDsp.h | 47 +++++++++++ src/libtomahawk/audio/VlcDspHack.cpp | 24 ------ src/libtomahawk/audio/VlcDspHack.h | 28 ------- src/libtomahawk/audio/VlcDspHack_p.h | 107 -------------------------- src/libtomahawk/audio/VlcDsp_p.h | 62 +++++++++++++++ 13 files changed, 185 insertions(+), 184 deletions(-) create mode 100644 src/libtomahawk/audio/VlcDsp.cpp create mode 100644 src/libtomahawk/audio/VlcDsp.h delete mode 100644 src/libtomahawk/audio/VlcDspHack.cpp delete mode 100644 src/libtomahawk/audio/VlcDspHack.h delete mode 100644 src/libtomahawk/audio/VlcDspHack_p.h create mode 100644 src/libtomahawk/audio/VlcDsp_p.h diff --git a/CMakeModules/FindLIBVLC.cmake b/CMakeModules/FindLIBVLC.cmake index 2a31e9128..cd597f04b 100644 --- a/CMakeModules/FindLIBVLC.cmake +++ b/CMakeModules/FindLIBVLC.cmake @@ -10,7 +10,7 @@ # LIBVLC_VERSION if(NOT LIBVLC_MIN_VERSION) - set(LIBVLC_MIN_VERSION "0.0") + set(LIBVLC_MIN_VERSION "2.1") endif(NOT LIBVLC_MIN_VERSION) # find_path and find_library normally search standard locations @@ -43,6 +43,15 @@ PATHS find_path(LIBVLC_INCLUDE_DIR PATHS "${CMAKE_INCLUDE_PATH}/vlc" NAMES vlc.h HINTS ${PC_LIBVLC_INCLUDEDIR} ${PC_LIBVLC_INCLUDE_DIRS}) +find_path(LIBVLCCORE_INCLUDE_DIR vlc_plugin.h +PATHS + "$ENV{LIB_DIR}/include/vlc/plugins" + "/usr/include/vlc/plugins" + "/usr/local/include/vlc/plugins" + #mingw + c:/msys/local/include/vlc/plugins +) + #Put here path to custom location #example: /home/user/vlc/lib etc.. find_library(LIBVLC_LIBRARY NAMES vlc libvlc diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt index ccb03f607..a110b024d 100644 --- a/src/libtomahawk/CMakeLists.txt +++ b/src/libtomahawk/CMakeLists.txt @@ -215,7 +215,7 @@ list(APPEND libSources audio/AudioEngine.cpp audio/AudioOutput.cpp - audio/VlcDspHack.cpp + audio/VlcDsp.cpp collection/Collection.cpp collection/ArtistsRequest.cpp @@ -393,7 +393,8 @@ include_directories( ${ECHONEST_INCLUDE_DIR} ${LUCENEPP_INCLUDE_DIRS} ${PHONON_INCLUDES} - ${LIBVLC_INCLUDES} + ${LIBVLC_INCLUDE_DIR} + ${LIBVLCCORE_INCLUDE_DIR} ${Boost_INCLUDE_DIR} ${LIBPORTFWD_INCLUDE_DIR} diff --git a/src/libtomahawk/audio/AudioEngine.cpp b/src/libtomahawk/audio/AudioEngine.cpp index 649ca150d..97e1838f1 100644 --- a/src/libtomahawk/audio/AudioEngine.cpp +++ b/src/libtomahawk/audio/AudioEngine.cpp @@ -76,7 +76,7 @@ AudioEnginePrivate::onStateChanged( AudioOutput::AudioState newState, AudioOutpu { q_ptr->stop( AudioEngine::UnknownError ); -//TODO tDebug() << "Phonon Error:" << audioOutput->errorString() << audioOutput->errorType(); +//TODO tDebug() << "AudioOutput Error:" << audioOutput->errorString() << audioOutput->errorType(); emit q_ptr->error( AudioEngine::UnknownError ); q_ptr->setState( AudioEngine::Error ); @@ -97,7 +97,6 @@ AudioEnginePrivate::onStateChanged( AudioOutput::AudioState newState, AudioOutpu } if ( newState == AudioOutput::Stopped && oldState == AudioOutput::Paused ) { - // GStreamer backend hack: instead of going from PlayingState to StoppedState, it traverses PausedState q_ptr->setState( AudioEngine::Stopped ); } @@ -508,7 +507,6 @@ bool AudioEngine::isMuted() const { return d_func()->audioOutput->isMuted(); - return 0; } @@ -1248,8 +1246,8 @@ AudioEngine::currentTrackTotalTime() const { // TODO : This is too hacky. The problem is that I don't know why // libVLC doesn't report total duration for stream data (imem://) - // But it's not a real problem for playback, since - // EndOfStream is emitted by libVLC itself + // But it's not a real problem for playback, since EndOfStream is emitted by libVLC itself + // This value is only used by AudioOutput to evaluate if it's close to end of stream if ( d_func()->audioOutput->totalTime() <= 0 && d_func()->currentTrack && d_func()->currentTrack->track() ) { return d_func()->currentTrack->track()->duration() * 1000 + 1000; } @@ -1341,7 +1339,7 @@ AudioEngine::setCurrentTrackPlaylist( const playlistinterface_ptr& playlist ) void -AudioEngine::setDspCallback( void ( *cb ) ( float*, int, int ) ) +AudioEngine::setDspCallback( boost::function< void( int state, int frameNumber, float* samples, int nb_channels, int nb_samples ) > cb ) { Q_D( AudioEngine ); diff --git a/src/libtomahawk/audio/AudioEngine.h b/src/libtomahawk/audio/AudioEngine.h index f00ea04a7..28570cc23 100644 --- a/src/libtomahawk/audio/AudioEngine.h +++ b/src/libtomahawk/audio/AudioEngine.h @@ -24,6 +24,7 @@ #include "../Typedefs.h" #include +#include #include "DllMacro.h" @@ -109,7 +110,7 @@ public: */ qint64 currentTrackTotalTime() const; - void setDspCallback( void ( *cb ) ( float* samples, int nb_channels, int nb_samples ) ); + void setDspCallback( boost::function< void( int state, int frameNumber, float* samples, int nb_channels, int nb_samples ) > cb ); public slots: void playPause(); diff --git a/src/libtomahawk/audio/AudioEngine_p.h b/src/libtomahawk/audio/AudioEngine_p.h index b7c736626..c2e5edf76 100644 --- a/src/libtomahawk/audio/AudioEngine_p.h +++ b/src/libtomahawk/audio/AudioEngine_p.h @@ -59,7 +59,5 @@ private: QTemporaryFile* coverTempFile; - void (* dspPluginCallback )( signed short* samples, int nb_channels, int nb_samples ); - static AudioEngine* s_instance; }; diff --git a/src/libtomahawk/audio/AudioOutput.cpp b/src/libtomahawk/audio/AudioOutput.cpp index e893524d5..3b8b82c11 100644 --- a/src/libtomahawk/audio/AudioOutput.cpp +++ b/src/libtomahawk/audio/AudioOutput.cpp @@ -2,7 +2,7 @@ * * Copyright 2010-2014, Christian Muehlhaeuser * Copyright 2010-2012, Jeff Mitchell - * Copyright 2013, Teo Mrnjavac + * Copyright 2014, Adrien Aubry * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,7 +20,7 @@ #include "AudioEngine.h" #include "AudioOutput.h" -#include "VlcDspHack.h" +#include "VlcDsp.h" #include "utils/Logger.h" @@ -61,6 +61,7 @@ AudioOutput::AudioOutput( QObject* parent ) , m_currentTime( 0 ) , m_totalTime( 0 ) , m_aboutToFinish( false ) + , m_justSeeked( false ) , dspPluginCallback( 0 ) , vlcInstance( 0 ) , vlcPlayer( 0 ) @@ -177,6 +178,7 @@ AudioOutput::setCurrentSource(MediaStream* stream) currentStream = stream; m_totalTime = 0; m_currentTime = 0; + m_justSeeked = false; seekable = true; QByteArray url; @@ -223,8 +225,7 @@ AudioOutput::setCurrentSource(MediaStream* stream) libvlc_media_player_set_media( vlcPlayer, vlcMedia ); #ifdef VLC_DSP_PLUGIN_ENABLED - // This is very, very tricky - VlcDspHackInstall( vlcPlayer ); + VlcDspSetup( vlcPlayer ); #endif if ( stream->type() == MediaStream::Url ) { @@ -378,8 +379,9 @@ AudioOutput::seek( qint64 milliseconds ) return; } - tDebug() << "AudioOutput:: seeking" << milliseconds << "msec"; +// tDebug() << "AudioOutput:: seeking" << milliseconds << "msec"; + m_justSeeked = true; libvlc_media_player_set_time ( vlcPlayer, milliseconds ); setCurrentTime( milliseconds ); } @@ -487,18 +489,20 @@ AudioOutput::vlcEventCallback( const libvlc_event_t* event, void* opaque ) void -AudioOutput::s_dspCallback( float* samples, int nb_channels, int nb_samples ) +AudioOutput::s_dspCallback( int frameNumber, float* samples, int nb_channels, int nb_samples ) { // tDebug() << Q_FUNC_INFO; + int state = AudioOutput::instance()->m_justSeeked ? 1 : 0; + AudioOutput::instance()->m_justSeeked = false; if ( AudioOutput::instance()->dspPluginCallback ) { - AudioOutput::instance()->dspPluginCallback( samples, nb_channels, nb_samples ); + AudioOutput::instance()->dspPluginCallback( state, frameNumber, samples, nb_channels, nb_samples ); } } void -AudioOutput::setDspCallback( void ( *cb ) ( float*, int, int ) ) +AudioOutput::setDspCallback( boost::function< void( int, int, float*, int, int ) > cb ) { dspPluginCallback = cb; } diff --git a/src/libtomahawk/audio/AudioOutput.h b/src/libtomahawk/audio/AudioOutput.h index 3d2388031..91df31c57 100644 --- a/src/libtomahawk/audio/AudioOutput.h +++ b/src/libtomahawk/audio/AudioOutput.h @@ -2,7 +2,7 @@ * * Copyright 2010-2014, Christian Muehlhaeuser * Copyright 2010-2012, Jeff Mitchell - * Copyright 2013, Teo Mrnjavac + * Copyright 2014, Adrien Aubry * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -24,9 +24,10 @@ #include "../Typedefs.h" #include "DllMacro.h" - #include "utils/MediaStream.h" +#include + struct libvlc_instance_t; struct libvlc_media_player_t; struct libvlc_media_t; @@ -61,7 +62,7 @@ public: qint64 totalTime(); void setAutoDelete ( bool ad ); - void setDspCallback( void ( *cb ) ( float*, int, int ) ); + void setDspCallback( boost::function< void( int, int, float*, int, int ) > cb ); static AudioOutput* instance(); @@ -78,7 +79,7 @@ private: void setTotalTime( qint64 time ); static void vlcEventCallback( const libvlc_event_t *event, void *opaque ); - static void s_dspCallback( float* samples, int nb_channels, int nb_samples ); + static void s_dspCallback( int frameNumber, float* samples, int nb_channels, int nb_samples ); static AudioOutput* s_instance; AudioState currentState; @@ -90,8 +91,9 @@ private: qint64 m_currentTime; qint64 m_totalTime; bool m_aboutToFinish; + bool m_justSeeked; - void ( *dspPluginCallback ) ( float* samples, int nb_channels, int nb_samples ); + boost::function< void( int state, int frameNumber, float* samples, int nb_channels, int nb_samples ) > dspPluginCallback; libvlc_instance_t* vlcInstance; libvlc_media_player_t* vlcPlayer; diff --git a/src/libtomahawk/audio/VlcDsp.cpp b/src/libtomahawk/audio/VlcDsp.cpp new file mode 100644 index 000000000..b5ebeaf6f --- /dev/null +++ b/src/libtomahawk/audio/VlcDsp.cpp @@ -0,0 +1,38 @@ +/* === This file is part of Tomahawk Player - === + * + * Tomahawk is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Tomahawk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . + */ + +#include "VlcDsp_p.h" + +#ifdef VLC_DSP_PLUGIN_ENABLED + +void +VlcDspSetup( libvlc_media_player_t* vlcPlayer ) +{ + vlc_value_t val; + + if ( vlcPlayer->input.p_resource != 0 ) { + audio_output_t *aout = input_resource_GetAout( vlcPlayer->input.p_resource ); + if ( aout != 0 ) { + var_Create( ( vlc_object_t* )aout, "audio-filter", VLC_VAR_STRING ); + val.psz_string = (char*)"dsp"; + var_SetChecked( ( vlc_object_t* )aout, "audio-filter", VLC_VAR_STRING, val ); + aout->event.restart_request( aout, AOUT_RESTART_FILTERS ); + input_resource_PutAout( vlcPlayer->input.p_resource, aout ); + } + } +} + +#endif // VLC_DSP_PLUGIN_ENABLED diff --git a/src/libtomahawk/audio/VlcDsp.h b/src/libtomahawk/audio/VlcDsp.h new file mode 100644 index 000000000..2b2d6da0c --- /dev/null +++ b/src/libtomahawk/audio/VlcDsp.h @@ -0,0 +1,47 @@ +/* === This file is part of Tomahawk Player - === + * + * Tomahawk is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Tomahawk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . + */ + +#ifndef VLCDSP_H +#define VLCDSP_H + +/* + * Very tricky technique to enable DSP plugin support + * There is no other way to do this with libvlc for the moment + * + * A VLC audio filter plugin specificaly made for Tomahawk + * is necessary to get it functionning + * + * TODO : Check thoroughly if libvlc_media_player_t + * structure is identical to the one in running libvlccore.so + * (checking if libVLC version is >= than the one used to compile Tomahawk + * and verifying pointers integrity should be enough. + * + check if audio filter "dsp" is present in libVLC plugins list) + * + * The define 'VLC_DSP_PLUGIN_ENABLED' better should be a CMake option +*/ + +// Maybe later :) +//#define VLC_DSP_PLUGIN_ENABLED + +#ifdef VLC_DSP_PLUGIN_ENABLED + +struct libvlc_media_player_t; + +void VlcDspSetup( libvlc_media_player_t* vlcPlayer ); + +#endif // VLC_DSP_PLUGIN_ENABLED + +#endif // VLCDSP_H \ No newline at end of file diff --git a/src/libtomahawk/audio/VlcDspHack.cpp b/src/libtomahawk/audio/VlcDspHack.cpp deleted file mode 100644 index 56f2952b8..000000000 --- a/src/libtomahawk/audio/VlcDspHack.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include "VlcDspHack_p.h" - -#ifdef VLC_DSP_PLUGIN_ENABLED - -void -VlcDspHackInstall( libvlc_media_player_t* vlcPlayer ) -{ - if ( vlcPlayer->input.p_resource != 0 ) { - audio_output_t *aout = input_resource_GetAout( vlcPlayer->input.p_resource ); - if ( aout != 0 ) { - var_Create( (vlc_object_t*)aout, "audio-filter", 0x0040 /*VLC_VAR_STRING*/ ); - - vlc_value_t val; - val.psz_string = (char*)"dsp"; - var_SetChecked( (vlc_object_t*)aout, "audio-filter", 0x0040 /*VLC_VAR_STRING*/, val ); - - aout->event.restart_request( aout, 1 /*AOUT_RESTART_FILTERS*/ ); - - input_resource_PutAout( vlcPlayer->input.p_resource, aout ); - } - } -} - -#endif // VLC_DSP_PLUGIN_ENABLED diff --git a/src/libtomahawk/audio/VlcDspHack.h b/src/libtomahawk/audio/VlcDspHack.h deleted file mode 100644 index 1c8a05cc2..000000000 --- a/src/libtomahawk/audio/VlcDspHack.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef VLCDSPHACK_H -#define VLCDSPHACK_H - -/* - * Very tricky technique to enable DSP plugin support - * There is no other way to do this with libvlc for the moment - * - * A VLC audio filter plugin specificaly made for Tomahawk - * is necessary to get it functionning - * - * TODO : Check thoroughly if both libvlc_media_player_t and audio_output - * structures are identical to those in the running libvlccore.so - * (checking if libVLC version is >= than the one used to compile Tomahawk - * and verifying pointers integrity should be enough. - * + check if audio filter "dsp" is present in libVLC plugins list) -*/ - -//#define VLC_DSP_PLUGIN_ENABLED - -#ifdef VLC_DSP_PLUGIN_ENABLED - -struct libvlc_media_player_t; - -void VlcDspHackInstall( libvlc_media_player_t* vlcPlayer ); - -#endif // VLC_DSP_PLUGIN_ENABLED - -#endif // VLCDSPHACK_H \ No newline at end of file diff --git a/src/libtomahawk/audio/VlcDspHack_p.h b/src/libtomahawk/audio/VlcDspHack_p.h deleted file mode 100644 index 0a54f152d..000000000 --- a/src/libtomahawk/audio/VlcDspHack_p.h +++ /dev/null @@ -1,107 +0,0 @@ -#ifndef VLCDSPHACK_P_H -#define VLCDSPHACK_P_H - -#include "VlcDspHack.h" - -#ifdef VLC_DSP_PLUGIN_ENABLED - -#include - -#include -#include -#include -#include -#include - -// TODO : Replace all these copy-pasted strutures by vlc/plugins/?.h includes - -typedef struct audio_output audio_output_t; -typedef struct input_resource_t input_resource_t; -typedef struct vlc_object_t vlc_object_t; -typedef struct vlc_list_t vlc_list_t; -typedef int64_t mtime_t; -typedef pthread_mutex_t vlc_mutex_t; - -typedef union -{ - int64_t i_int; - bool b_bool; - float f_float; - char * psz_string; - void * p_address; - vlc_object_t * p_object; - vlc_list_t * p_list; - mtime_t i_time; - struct { int32_t x; int32_t y; } coords; - -} vlc_value_t; - -struct audio_output -{ - const char *psz_object_type; - char *psz_header; - int i_flags; - bool b_force; - void *p_libvlc; - void * p_parent; - - void *sys; - int (*start)(audio_output_t *, void *fmt); - void (*stop)(audio_output_t *); - int (*time_get)(audio_output_t *, void *delay); - void (*play)(audio_output_t *, void *); - void (*pause)( audio_output_t *, bool pause, mtime_t date); - void (*flush)( audio_output_t *, bool wait); - int (*volume_set)(audio_output_t *, float volume); - int (*mute_set)(audio_output_t *, bool mute); - int (*device_select)(audio_output_t *, const char *id); - struct { - void (*volume_report)(audio_output_t *, float); - void (*mute_report)(audio_output_t *, bool); - void (*policy_report)(audio_output_t *, bool); - void (*device_report)(audio_output_t *, const char *); - void (*hotplug_report)(audio_output_t *, const char *, const char *); - int (*gain_request)(audio_output_t *, float); - void (*restart_request)(audio_output_t *, unsigned); - } event; -}; - - -struct libvlc_media_player_t -{ - const char *psz_object_type; - char *psz_header; - int i_flags; - bool b_force; - void *p_libvlc; - void *p_parent; - - int i_refcount; - vlc_mutex_t object_lock; - - struct - { - void *p_thread; - input_resource_t *p_resource; - vlc_mutex_t lock; - } input; - - void *p_libvlc_instance; - void *p_md; - void *p_event_manager; - int state; -}; - -extern "C" { - audio_output_t* input_resource_GetAout(input_resource_t*); - void input_resource_PutAout(input_resource_t*, audio_output_t*); - int var_Create(vlc_object_t *, const char *, int ); - int var_SetChecked( vlc_object_t *, const char *, int, vlc_value_t ); - static inline void aout_RestartRequest(audio_output_t *aout, unsigned mode){ - aout->event.restart_request(aout, mode); - } -}; - -#endif // VLC_DSP_PLUGIN_ENABLED - -#endif // VLCDSPHACK_P_H diff --git a/src/libtomahawk/audio/VlcDsp_p.h b/src/libtomahawk/audio/VlcDsp_p.h new file mode 100644 index 000000000..67e8a6482 --- /dev/null +++ b/src/libtomahawk/audio/VlcDsp_p.h @@ -0,0 +1,62 @@ +/* === This file is part of Tomahawk Player - === + * + * Tomahawk is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Tomahawk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . + */ + +#ifndef VLCDSP_P_H +#define VLCDSP_P_H + +#include "VlcDsp.h" + +#ifdef VLC_DSP_PLUGIN_ENABLED + +#include + +#include +#include +#include +#include +#include + +#define restrict +#define _(s) s + +#include +#include + +typedef struct libvlc_media_player_t +{ + const char *psz_object_type; + char *psz_header; + int i_flags; + bool b_force; + void *p_libvlc; + void *p_parent; + int i_refcount; + vlc_mutex_t object_lock; + struct + { + void *p_thread; + input_resource_t *p_resource; + vlc_mutex_t lock; + } input; + void *p_libvlc_instance; + void *p_md; + void *p_event_manager; + int state; +} libvlc_media_player_t; + +#endif // VLC_DSP_PLUGIN_ENABLED + +#endif // VLCDSP_P_H From dadfd20000b52e6114787ddf659aa502c9ef39bd Mon Sep 17 00:00:00 2001 From: dridri Date: Sat, 18 Oct 2014 20:25:27 +0200 Subject: [PATCH 18/43] no more boost --- src/libtomahawk/audio/AudioEngine.cpp | 2 +- src/libtomahawk/audio/AudioEngine.h | 4 ++-- src/libtomahawk/audio/AudioOutput.cpp | 5 +---- src/libtomahawk/audio/AudioOutput.h | 6 +++--- 4 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/libtomahawk/audio/AudioEngine.cpp b/src/libtomahawk/audio/AudioEngine.cpp index 97e1838f1..8db3a599f 100644 --- a/src/libtomahawk/audio/AudioEngine.cpp +++ b/src/libtomahawk/audio/AudioEngine.cpp @@ -1339,7 +1339,7 @@ AudioEngine::setCurrentTrackPlaylist( const playlistinterface_ptr& playlist ) void -AudioEngine::setDspCallback( boost::function< void( int state, int frameNumber, float* samples, int nb_channels, int nb_samples ) > cb ) +AudioEngine::setDspCallback( std::function< void( int state, int frameNumber, float* samples, int nb_channels, int nb_samples ) > cb ) { Q_D( AudioEngine ); diff --git a/src/libtomahawk/audio/AudioEngine.h b/src/libtomahawk/audio/AudioEngine.h index 28570cc23..4753afc60 100644 --- a/src/libtomahawk/audio/AudioEngine.h +++ b/src/libtomahawk/audio/AudioEngine.h @@ -24,7 +24,7 @@ #include "../Typedefs.h" #include -#include +#include #include "DllMacro.h" @@ -110,7 +110,7 @@ public: */ qint64 currentTrackTotalTime() const; - void setDspCallback( boost::function< void( int state, int frameNumber, float* samples, int nb_channels, int nb_samples ) > cb ); + void setDspCallback( std::function< void( int state, int frameNumber, float* samples, int nb_channels, int nb_samples ) > cb ); public slots: void playPause(); diff --git a/src/libtomahawk/audio/AudioOutput.cpp b/src/libtomahawk/audio/AudioOutput.cpp index 3b8b82c11..ead7c3c30 100644 --- a/src/libtomahawk/audio/AudioOutput.cpp +++ b/src/libtomahawk/audio/AudioOutput.cpp @@ -28,9 +28,6 @@ #include #include -#include -#include - #include #include #include @@ -502,7 +499,7 @@ AudioOutput::s_dspCallback( int frameNumber, float* samples, int nb_channels, in void -AudioOutput::setDspCallback( boost::function< void( int, int, float*, int, int ) > cb ) +AudioOutput::setDspCallback( std::function< void( int, int, float*, int, int ) > cb ) { dspPluginCallback = cb; } diff --git a/src/libtomahawk/audio/AudioOutput.h b/src/libtomahawk/audio/AudioOutput.h index 91df31c57..883f1e8aa 100644 --- a/src/libtomahawk/audio/AudioOutput.h +++ b/src/libtomahawk/audio/AudioOutput.h @@ -26,7 +26,7 @@ #include "DllMacro.h" #include "utils/MediaStream.h" -#include +#include struct libvlc_instance_t; struct libvlc_media_player_t; @@ -62,7 +62,7 @@ public: qint64 totalTime(); void setAutoDelete ( bool ad ); - void setDspCallback( boost::function< void( int, int, float*, int, int ) > cb ); + void setDspCallback( std::function< void( int, int, float*, int, int ) > cb ); static AudioOutput* instance(); @@ -93,7 +93,7 @@ private: bool m_aboutToFinish; bool m_justSeeked; - boost::function< void( int state, int frameNumber, float* samples, int nb_channels, int nb_samples ) > dspPluginCallback; + std::function< void( int state, int frameNumber, float* samples, int nb_channels, int nb_samples ) > dspPluginCallback; libvlc_instance_t* vlcInstance; libvlc_media_player_t* vlcPlayer; From 45c3eae10c77bfc15ae7b2ae154c2f5e8cc07c8d Mon Sep 17 00:00:00 2001 From: dridri Date: Mon, 20 Oct 2014 16:41:44 +0200 Subject: [PATCH 19/43] removed useless/causing crashes with youtube streams libvlc flags --- src/libtomahawk/audio/AudioOutput.cpp | 12 +++++++++--- src/libtomahawk/audio/AudioOutput.h | 1 + src/libtomahawk/audio/VlcDsp.h | 2 +- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/libtomahawk/audio/AudioOutput.cpp b/src/libtomahawk/audio/AudioOutput.cpp index ead7c3c30..10dfe45fc 100644 --- a/src/libtomahawk/audio/AudioOutput.cpp +++ b/src/libtomahawk/audio/AudioOutput.cpp @@ -2,6 +2,7 @@ * * Copyright 2010-2014, Christian Muehlhaeuser * Copyright 2010-2012, Jeff Mitchell + * Copyright 2013, Teo Mrnjavac * Copyright 2014, Adrien Aubry * * Tomahawk is free software: you can redistribute it and/or modify @@ -24,6 +25,7 @@ #include "utils/Logger.h" +#include #include #include #include @@ -74,17 +76,21 @@ AudioOutput::AudioOutput( QObject* parent ) QList args; args << "--ignore-config"; - args << "--verbose=42"; - args << "--no-plugins-cache"; args << "--extraintf=logger"; + if ( qApp->arguments().contains( "--verbose" ) ) { + args << "--verbose=3"; + } +/* + args << "--no-plugins-cache"; args << "--no-media-library"; args << "--no-osd"; args << "--no-stats"; args << "--no-video-title-show"; args << "--no-snapshot-preview"; - args << "--no-xlib"; args << "--services-discovery=''"; +*/ args << "--no-video"; + args << "--no-xlib"; #ifdef VLC_DSP_PLUGIN_ENABLED args << "--audio-filter=dsp"; args << QString("--dsp-callback=%1").arg((quint64)&AudioOutput::s_dspCallback, 0, 16).toAscii(); diff --git a/src/libtomahawk/audio/AudioOutput.h b/src/libtomahawk/audio/AudioOutput.h index 883f1e8aa..768da5a0d 100644 --- a/src/libtomahawk/audio/AudioOutput.h +++ b/src/libtomahawk/audio/AudioOutput.h @@ -2,6 +2,7 @@ * * Copyright 2010-2014, Christian Muehlhaeuser * Copyright 2010-2012, Jeff Mitchell + * Copyright 2013, Teo Mrnjavac * Copyright 2014, Adrien Aubry * * Tomahawk is free software: you can redistribute it and/or modify diff --git a/src/libtomahawk/audio/VlcDsp.h b/src/libtomahawk/audio/VlcDsp.h index 2b2d6da0c..a57c85394 100644 --- a/src/libtomahawk/audio/VlcDsp.h +++ b/src/libtomahawk/audio/VlcDsp.h @@ -44,4 +44,4 @@ void VlcDspSetup( libvlc_media_player_t* vlcPlayer ); #endif // VLC_DSP_PLUGIN_ENABLED -#endif // VLCDSP_H \ No newline at end of file +#endif // VLCDSP_H From d9b5fdf0b11436070cdf0b8e1d345caf89373f85 Mon Sep 17 00:00:00 2001 From: dridri Date: Mon, 20 Oct 2014 19:56:05 +0200 Subject: [PATCH 20/43] removed too unstable dsp, done remaning TODOs for vlc --- src/libtomahawk/CMakeLists.txt | 1 - src/libtomahawk/audio/AudioEngine.cpp | 10 ++--- src/libtomahawk/audio/AudioOutput.cpp | 28 +++++++----- src/libtomahawk/audio/VlcDsp.cpp | 38 ---------------- src/libtomahawk/audio/VlcDsp.h | 47 -------------------- src/libtomahawk/audio/VlcDsp_p.h | 62 --------------------------- src/libtomahawk/utils/MediaStream.cpp | 6 +-- 7 files changed, 24 insertions(+), 168 deletions(-) delete mode 100644 src/libtomahawk/audio/VlcDsp.cpp delete mode 100644 src/libtomahawk/audio/VlcDsp.h delete mode 100644 src/libtomahawk/audio/VlcDsp_p.h diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt index a110b024d..33079a431 100644 --- a/src/libtomahawk/CMakeLists.txt +++ b/src/libtomahawk/CMakeLists.txt @@ -215,7 +215,6 @@ list(APPEND libSources audio/AudioEngine.cpp audio/AudioOutput.cpp - audio/VlcDsp.cpp collection/Collection.cpp collection/ArtistsRequest.cpp diff --git a/src/libtomahawk/audio/AudioEngine.cpp b/src/libtomahawk/audio/AudioEngine.cpp index 8db3a599f..2ab83fb3f 100644 --- a/src/libtomahawk/audio/AudioEngine.cpp +++ b/src/libtomahawk/audio/AudioEngine.cpp @@ -31,7 +31,7 @@ #include "playlist/SingleTrackPlaylistInterface.h" #include "utils/Closure.h" #include "utils/Logger.h" -#include "utils/Qnr_IoDeviceStream.h" +#include "utils/Qnr_IoDeviceSFtream.h" #include "Album.h" #include "Artist.h" @@ -75,9 +75,7 @@ AudioEnginePrivate::onStateChanged( AudioOutput::AudioState newState, AudioOutpu if ( newState == AudioOutput::Error ) { q_ptr->stop( AudioEngine::UnknownError ); - -//TODO tDebug() << "AudioOutput Error:" << audioOutput->errorString() << audioOutput->errorType(); - + tDebug() << "AudioOutput Error"; emit q_ptr->error( AudioEngine::UnknownError ); q_ptr->setState( AudioEngine::Error ); } @@ -1244,8 +1242,8 @@ AudioEngine::currentTime() const qint64 AudioEngine::currentTrackTotalTime() const { - // TODO : This is too hacky. The problem is that I don't know why - // libVLC doesn't report total duration for stream data (imem://) + // FIXME : This is too hacky. The problem is that I don't know why + // libVLC doesn't report total duration for stream data (imem://) // But it's not a real problem for playback, since EndOfStream is emitted by libVLC itself // This value is only used by AudioOutput to evaluate if it's close to end of stream if ( d_func()->audioOutput->totalTime() <= 0 && d_func()->currentTrack && d_func()->currentTrack->track() ) { diff --git a/src/libtomahawk/audio/AudioOutput.cpp b/src/libtomahawk/audio/AudioOutput.cpp index 10dfe45fc..3fe7d91e2 100644 --- a/src/libtomahawk/audio/AudioOutput.cpp +++ b/src/libtomahawk/audio/AudioOutput.cpp @@ -21,7 +21,6 @@ #include "AudioEngine.h" #include "AudioOutput.h" -#include "VlcDsp.h" #include "utils/Logger.h" @@ -91,10 +90,6 @@ AudioOutput::AudioOutput( QObject* parent ) */ args << "--no-video"; args << "--no-xlib"; -#ifdef VLC_DSP_PLUGIN_ENABLED - args << "--audio-filter=dsp"; - args << QString("--dsp-callback=%1").arg((quint64)&AudioOutput::s_dspCallback, 0, 16).toAscii(); -#endif QVarLengthArray< const char * , 64 > vlcArgs( args.size() ); for ( int i = 0 ; i < args.size() ; ++i ) { @@ -145,7 +140,18 @@ AudioOutput::~AudioOutput() { tDebug() << Q_FUNC_INFO; - // TODO + if ( vlcPlayer != 0 ) { + libvlc_media_player_stop( vlcPlayer ); + libvlc_media_player_release( vlcPlayer ); + vlcPlayer = 0; + } + if ( vlcMedia != 0 ) { + libvlc_media_release( vlcMedia ); + vlcMedia = 0; + } + if ( vlcInstance != 0 ) { + libvlc_release( vlcInstance ); + } } @@ -227,10 +233,6 @@ AudioOutput::setCurrentSource(MediaStream* stream) libvlc_media_player_set_media( vlcPlayer, vlcMedia ); -#ifdef VLC_DSP_PLUGIN_ENABLED - VlcDspSetup( vlcPlayer ); -#endif - if ( stream->type() == MediaStream::Url ) { m_totalTime = libvlc_media_get_duration( vlcMedia ); } @@ -475,7 +477,11 @@ AudioOutput::vlcEventCallback( const libvlc_event_t* event, void* opaque ) that->setState(Stopped); break; case libvlc_MediaPlayerEncounteredError: - // TODO emit Error + tDebug() << "LibVLC error : MediaPlayerEncounteredError. Stopping"; + if ( that->vlcPlayer != 0 ) { + that->stop(); + } + that->setState( Error ); break; case libvlc_MediaPlayerVout: case libvlc_MediaPlayerMediaChanged: diff --git a/src/libtomahawk/audio/VlcDsp.cpp b/src/libtomahawk/audio/VlcDsp.cpp deleted file mode 100644 index b5ebeaf6f..000000000 --- a/src/libtomahawk/audio/VlcDsp.cpp +++ /dev/null @@ -1,38 +0,0 @@ -/* === This file is part of Tomahawk Player - === - * - * Tomahawk is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Tomahawk is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Tomahawk. If not, see . - */ - -#include "VlcDsp_p.h" - -#ifdef VLC_DSP_PLUGIN_ENABLED - -void -VlcDspSetup( libvlc_media_player_t* vlcPlayer ) -{ - vlc_value_t val; - - if ( vlcPlayer->input.p_resource != 0 ) { - audio_output_t *aout = input_resource_GetAout( vlcPlayer->input.p_resource ); - if ( aout != 0 ) { - var_Create( ( vlc_object_t* )aout, "audio-filter", VLC_VAR_STRING ); - val.psz_string = (char*)"dsp"; - var_SetChecked( ( vlc_object_t* )aout, "audio-filter", VLC_VAR_STRING, val ); - aout->event.restart_request( aout, AOUT_RESTART_FILTERS ); - input_resource_PutAout( vlcPlayer->input.p_resource, aout ); - } - } -} - -#endif // VLC_DSP_PLUGIN_ENABLED diff --git a/src/libtomahawk/audio/VlcDsp.h b/src/libtomahawk/audio/VlcDsp.h deleted file mode 100644 index a57c85394..000000000 --- a/src/libtomahawk/audio/VlcDsp.h +++ /dev/null @@ -1,47 +0,0 @@ -/* === This file is part of Tomahawk Player - === - * - * Tomahawk is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Tomahawk is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Tomahawk. If not, see . - */ - -#ifndef VLCDSP_H -#define VLCDSP_H - -/* - * Very tricky technique to enable DSP plugin support - * There is no other way to do this with libvlc for the moment - * - * A VLC audio filter plugin specificaly made for Tomahawk - * is necessary to get it functionning - * - * TODO : Check thoroughly if libvlc_media_player_t - * structure is identical to the one in running libvlccore.so - * (checking if libVLC version is >= than the one used to compile Tomahawk - * and verifying pointers integrity should be enough. - * + check if audio filter "dsp" is present in libVLC plugins list) - * - * The define 'VLC_DSP_PLUGIN_ENABLED' better should be a CMake option -*/ - -// Maybe later :) -//#define VLC_DSP_PLUGIN_ENABLED - -#ifdef VLC_DSP_PLUGIN_ENABLED - -struct libvlc_media_player_t; - -void VlcDspSetup( libvlc_media_player_t* vlcPlayer ); - -#endif // VLC_DSP_PLUGIN_ENABLED - -#endif // VLCDSP_H diff --git a/src/libtomahawk/audio/VlcDsp_p.h b/src/libtomahawk/audio/VlcDsp_p.h deleted file mode 100644 index 67e8a6482..000000000 --- a/src/libtomahawk/audio/VlcDsp_p.h +++ /dev/null @@ -1,62 +0,0 @@ -/* === This file is part of Tomahawk Player - === - * - * Tomahawk is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Tomahawk is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Tomahawk. If not, see . - */ - -#ifndef VLCDSP_P_H -#define VLCDSP_P_H - -#include "VlcDsp.h" - -#ifdef VLC_DSP_PLUGIN_ENABLED - -#include - -#include -#include -#include -#include -#include - -#define restrict -#define _(s) s - -#include -#include - -typedef struct libvlc_media_player_t -{ - const char *psz_object_type; - char *psz_header; - int i_flags; - bool b_force; - void *p_libvlc; - void *p_parent; - int i_refcount; - vlc_mutex_t object_lock; - struct - { - void *p_thread; - input_resource_t *p_resource; - vlc_mutex_t lock; - } input; - void *p_libvlc_instance; - void *p_md; - void *p_event_manager; - int state; -} libvlc_media_player_t; - -#endif // VLC_DSP_PLUGIN_ENABLED - -#endif // VLCDSP_P_H diff --git a/src/libtomahawk/utils/MediaStream.cpp b/src/libtomahawk/utils/MediaStream.cpp index c5c1335b9..dde1147f9 100644 --- a/src/libtomahawk/utils/MediaStream.cpp +++ b/src/libtomahawk/utils/MediaStream.cpp @@ -45,7 +45,7 @@ MediaStream::MediaStream( QObject* parent ) MediaStream::MediaStream( const QUrl &url ) : QObject( 0 ) - , m_type(Url) + , m_type( Url ) , m_ioDevice ( 0 ) , m_started( false ) , m_bufferingFinished( false ) @@ -61,7 +61,7 @@ MediaStream::MediaStream( const QUrl &url ) MediaStream::MediaStream( QIODevice* device ) : QObject( 0 ) - , m_type(IODevice) + , m_type( IODevice ) , m_url( QUrl() ) , m_ioDevice ( 0 ) , m_started( false ) @@ -202,7 +202,7 @@ MediaStream::readDoneCallback ( void *data, const char *cookie, size_t bufferSiz MediaStream* that = static_cast < MediaStream * > ( data ); if ( ( that->m_type == Stream ) && buffer != 0 && bufferSize > 0 ) { - delete static_cast(buffer); + delete static_cast< char* >( buffer ); } return 0; From 68f608ac1a64d57e8a354d01d7065fcdd16a73b8 Mon Sep 17 00:00:00 2001 From: "Uwe L. Korn" Date: Tue, 21 Oct 2014 10:35:11 +0200 Subject: [PATCH 21/43] Fix typo --- src/libtomahawk/audio/AudioEngine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libtomahawk/audio/AudioEngine.cpp b/src/libtomahawk/audio/AudioEngine.cpp index 2ab83fb3f..f88c60daa 100644 --- a/src/libtomahawk/audio/AudioEngine.cpp +++ b/src/libtomahawk/audio/AudioEngine.cpp @@ -31,7 +31,7 @@ #include "playlist/SingleTrackPlaylistInterface.h" #include "utils/Closure.h" #include "utils/Logger.h" -#include "utils/Qnr_IoDeviceSFtream.h" +#include "utils/Qnr_IoDeviceStream.h" #include "Album.h" #include "Artist.h" From a17a0e154c4a7a1a3421e82df32bd655b91e9724 Mon Sep 17 00:00:00 2001 From: "Uwe L. Korn" Date: Tue, 21 Oct 2014 20:46:44 +0200 Subject: [PATCH 22/43] Remove Phonon traces --- CMakeLists.txt | 11 +---------- CMakeModules/FindPhonon.cmake | 24 ------------------------ src/libtomahawk/CMakeLists.txt | 2 -- src/libtomahawk/audio/AudioEngine_p.h | 8 -------- 4 files changed, 1 insertion(+), 44 deletions(-) delete mode 100644 CMakeModules/FindPhonon.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 99f3111d2..68da1ba3b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -380,16 +380,7 @@ if (WITH_KDE4) endif(WITH_KDE4) macro_log_feature(KDE4_FOUND "KDE4" "Provides support for configuring Telepathy Accounts from inside Tomahawk" "https://www.kde.org" FALSE "" "") -# if(NOT Phonon_FOUND) -# macro_optional_find_package(Phonon 4.5.0) -# endif() -# macro_log_feature(Phonon_FOUND "Phonon" "The Phonon multimedia library" "http://phonon.kde.org" TRUE "" "") - -# if(Phonon_FOUND) -# message(STATUS "Phonon found; ensure that phonon-vlc is at least 0.4") -# endif() -# -IF( KDE4_FOUND OR Phonon_FOUND ) +IF( KDE4_FOUND ) IF( CMAKE_C_FLAGS ) # KDE4 adds and removes some compiler flags that we don't like # (only for gcc not for clang e.g.) diff --git a/CMakeModules/FindPhonon.cmake b/CMakeModules/FindPhonon.cmake deleted file mode 100644 index ff7fd8e49..000000000 --- a/CMakeModules/FindPhonon.cmake +++ /dev/null @@ -1,24 +0,0 @@ -# Find libphonon -# Once done this will define -# -# PHONON_FOUND - system has Phonon Library -# PHONON_INCLUDES - the Phonon include directory -# PHONON_LIBS - link these to use Phonon -# PHONON_VERSION - the version of the Phonon Library - -# Copyright (c) 2008, Matthias Kretz -# -# Redistribution and use is allowed according to the terms of the BSD license. -# For details see the accompanying COPYING-CMAKE-SCRIPTS file. - -include(FindPackageHandleStandardArgs) - -if( TOMAHAWK_QT5 ) - find_package(Phonon4Qt5 NO_MODULE) - set(Phonon_FOUND ${Phonon4Qt5_FOUND}) - set(Phonon_DIR ${Phonon4Qt5_DIR}) -else() - find_package(Phonon NO_MODULE) -endif() - -find_package_handle_standard_args(Phonon DEFAULT_MSG Phonon_DIR ) diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt index 33079a431..0459c62ba 100644 --- a/src/libtomahawk/CMakeLists.txt +++ b/src/libtomahawk/CMakeLists.txt @@ -391,7 +391,6 @@ include_directories( ${QJSON_INCLUDE_DIR} ${ECHONEST_INCLUDE_DIR} ${LUCENEPP_INCLUDE_DIRS} - ${PHONON_INCLUDES} ${LIBVLC_INCLUDE_DIR} ${LIBVLCCORE_INCLUDE_DIR} ${Boost_INCLUDE_DIR} @@ -505,7 +504,6 @@ ENDIF( UNIX AND NOT APPLE ) TARGET_LINK_LIBRARIES( tomahawklib LINK_PRIVATE - ${PHONON_LIBRARY} ${LIBVLC_LIBRARY} ${LIBVLCCORE_LIBRARY} diff --git a/src/libtomahawk/audio/AudioEngine_p.h b/src/libtomahawk/audio/AudioEngine_p.h index c2e5edf76..59e90c851 100644 --- a/src/libtomahawk/audio/AudioEngine_p.h +++ b/src/libtomahawk/audio/AudioEngine_p.h @@ -1,11 +1,3 @@ -/* -#include -#include -#include -#include -#include -#include -*/ #include "AudioOutput.h" #include From 08101197aeab807a2935d4bffa9b071d9c93a57e Mon Sep 17 00:00:00 2001 From: "Uwe L. Korn" Date: Tue, 21 Oct 2014 20:57:40 +0200 Subject: [PATCH 23/43] Simplfy FindVLC --- CMakeModules/FindLIBVLC.cmake | 71 ++++++++++------------------------- 1 file changed, 20 insertions(+), 51 deletions(-) diff --git a/CMakeModules/FindLIBVLC.cmake b/CMakeModules/FindLIBVLC.cmake index cd597f04b..69d81cce9 100644 --- a/CMakeModules/FindLIBVLC.cmake +++ b/CMakeModules/FindLIBVLC.cmake @@ -1,4 +1,3 @@ - # CMake module to search for LIBVLC (VLC library) # Authors: Rohit Yadav # Harald Sitter @@ -13,71 +12,41 @@ if(NOT LIBVLC_MIN_VERSION) set(LIBVLC_MIN_VERSION "2.1") endif(NOT LIBVLC_MIN_VERSION) -# find_path and find_library normally search standard locations -# before the specified paths. To search non-standard paths first, -# FIND_* is invoked first with specified paths and NO_DEFAULT_PATH -# and then again with no specified paths to search the default -# locations. When an earlier FIND_* succeeds, subsequent FIND_*s -# searching for the same item do nothing. +find_package(PkgConfig QUIET) +pkg_check_modules(PC_LIBVLC QUIET libvlc) +set(LIBVLC_DEFINITIONS ${PC_LIBVLC_CFLAGS_OTHER}) -if (NOT WIN32) - find_package(PkgConfig) - pkg_check_modules(PC_LIBVLC libvlc) - set(LIBVLC_DEFINITIONS ${PC_LIBVLC_CFLAGS_OTHER}) -endif (NOT WIN32) - -#Put here path to custom location -#example: /home/user/vlc/include etc.. find_path(LIBVLC_INCLUDE_DIR vlc/vlc.h -HINTS "$ENV{LIBVLC_INCLUDE_PATH}" -PATHS - "$ENV{LIB_DIR}/include" - "$ENV{LIB_DIR}/include/vlc" - "/usr/include" - "/usr/include/vlc" - "/usr/local/include" - "/usr/local/include/vlc" - #mingw - c:/msys/local/include + HINTS + ${PC_LIBVLC_INCLUDEDIR} + ${PC_LIBVLC_INCLUDE_DIRS} ) -find_path(LIBVLC_INCLUDE_DIR PATHS "${CMAKE_INCLUDE_PATH}/vlc" NAMES vlc.h - HINTS ${PC_LIBVLC_INCLUDEDIR} ${PC_LIBVLC_INCLUDE_DIRS}) find_path(LIBVLCCORE_INCLUDE_DIR vlc_plugin.h -PATHS - "$ENV{LIB_DIR}/include/vlc/plugins" - "/usr/include/vlc/plugins" - "/usr/local/include/vlc/plugins" - #mingw - c:/msys/local/include/vlc/plugins + HINTS + ${PC_LIBVLC_INCLUDEDIR} + ${PC_LIBVLC_INCLUDE_DIRS} ) -#Put here path to custom location -#example: /home/user/vlc/lib etc.. find_library(LIBVLC_LIBRARY NAMES vlc libvlc -HINTS "$ENV{LIBVLC_LIBRARY_PATH}" ${PC_LIBVLC_LIBDIR} ${PC_LIBVLC_LIBRARY_DIRS} -PATHS - "$ENV{LIB_DIR}/lib" - #mingw - c:/msys/local/lib + HINTS + ${PC_LIBVLC_LIBDIR} + ${PC_LIBVLC_LIBRARY_DIRS} ) -find_library(LIBVLC_LIBRARY NAMES vlc libvlc) + find_library(LIBVLCCORE_LIBRARY NAMES vlccore libvlccore -HINTS "$ENV{LIBVLC_LIBRARY_PATH}" ${PC_LIBVLC_LIBDIR} ${PC_LIBVLC_LIBRARY_DIRS} -PATHS - "$ENV{LIB_DIR}/lib" - #mingw - c:/msys/local/lib + HINTS + ${PC_LIBVLC_LIBDIR} + ${PC_LIBVLC_LIBRARY_DIRS} ) -find_library(LIBVLCCORE_LIBRARY NAMES vlccore libvlccore) set(LIBVLC_VERSION ${PC_LIBVLC_VERSION}) if (NOT LIBVLC_VERSION) -# TODO: implement means to detect version on windows (vlc --version && regex? ... ultimately we would get it from a header though...) + # TODO: implement means to detect version on windows (vlc --version && regex? ... ultimately we would get it from a header though...) endif (NOT LIBVLC_VERSION) if (LIBVLC_INCLUDE_DIR AND LIBVLC_LIBRARY AND LIBVLCCORE_LIBRARY) -set(LIBVLC_FOUND TRUE) + set(LIBVLC_FOUND TRUE) endif (LIBVLC_INCLUDE_DIR AND LIBVLC_LIBRARY AND LIBVLCCORE_LIBRARY) if (LIBVLC_VERSION STRLESS "${LIBVLC_MIN_VERSION}") @@ -89,8 +58,8 @@ endif (LIBVLC_VERSION STRLESS "${LIBVLC_MIN_VERSION}") if (LIBVLC_FOUND) if (NOT LIBVLC_FIND_QUIETLY) message(STATUS "Found LibVLC include-dir path: ${LIBVLC_INCLUDE_DIR}") - message(STATUS "Found LibVLC library path:${LIBVLC_LIBRARY}") - message(STATUS "Found LibVLCcore library path:${LIBVLCCORE_LIBRARY}") + message(STATUS "Found LibVLC library: ${LIBVLC_LIBRARY}") + message(STATUS "Found LibVLCcore library: ${LIBVLCCORE_LIBRARY}") message(STATUS "Found LibVLC version: ${LIBVLC_VERSION} (searched for: ${LIBVLC_MIN_VERSION})") endif (NOT LIBVLC_FIND_QUIETLY) else (LIBVLC_FOUND) From 51d2ca2247aa8551a7304543198bad03d18f1f19 Mon Sep 17 00:00:00 2001 From: "Uwe L. Korn" Date: Tue, 21 Oct 2014 21:01:38 +0200 Subject: [PATCH 24/43] Use Q_D instead of d_func --- src/libtomahawk/audio/AudioEngine.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/libtomahawk/audio/AudioEngine.cpp b/src/libtomahawk/audio/AudioEngine.cpp index f88c60daa..1764545de 100644 --- a/src/libtomahawk/audio/AudioEngine.cpp +++ b/src/libtomahawk/audio/AudioEngine.cpp @@ -212,13 +212,15 @@ AudioEngine::~AudioEngine() QStringList AudioEngine::supportedMimeTypes() const { - if ( d_func()->supportedMimeTypes.isEmpty() ) + Q_D( const AudioEngine ); + + if ( d->supportedMimeTypes.isEmpty() ) { - d_func()->supportedMimeTypes << "audio/*"; - d_func()->supportedMimeTypes << "audio/basic"; + d->supportedMimeTypes << "audio/*"; + d->supportedMimeTypes << "audio/basic"; } - return d_func()->supportedMimeTypes; + return d->supportedMimeTypes; } From accc2b5197b96f48161b16a3bb1a83fdf8cf131e Mon Sep 17 00:00:00 2001 From: "Uwe L. Korn" Date: Tue, 21 Oct 2014 21:05:53 +0200 Subject: [PATCH 25/43] Use find_package_handle_standard_args --- CMakeModules/FindLIBVLC.cmake | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/CMakeModules/FindLIBVLC.cmake b/CMakeModules/FindLIBVLC.cmake index 69d81cce9..ee97ae486 100644 --- a/CMakeModules/FindLIBVLC.cmake +++ b/CMakeModules/FindLIBVLC.cmake @@ -45,9 +45,7 @@ if (NOT LIBVLC_VERSION) # TODO: implement means to detect version on windows (vlc --version && regex? ... ultimately we would get it from a header though...) endif (NOT LIBVLC_VERSION) -if (LIBVLC_INCLUDE_DIR AND LIBVLC_LIBRARY AND LIBVLCCORE_LIBRARY) - set(LIBVLC_FOUND TRUE) -endif (LIBVLC_INCLUDE_DIR AND LIBVLC_LIBRARY AND LIBVLCCORE_LIBRARY) +find_package_handle_standard_args(LibVLC DEFAULT_MSG LIBVLC_LIBRARY LIBVLCCORE_LIBRARY LIBVLC_INCLUDE_DIR) if (LIBVLC_VERSION STRLESS "${LIBVLC_MIN_VERSION}") message(WARNING "LibVLC version not found: version searched: ${LIBVLC_MIN_VERSION}, found ${LIBVLC_VERSION}\nUnless you are on Windows this is bound to fail.") @@ -55,6 +53,7 @@ if (LIBVLC_VERSION STRLESS "${LIBVLC_MIN_VERSION}") # set(LIBVLC_FOUND FALSE) endif (LIBVLC_VERSION STRLESS "${LIBVLC_MIN_VERSION}") + if (LIBVLC_FOUND) if (NOT LIBVLC_FIND_QUIETLY) message(STATUS "Found LibVLC include-dir path: ${LIBVLC_INCLUDE_DIR}") From f0d3b11ded7691333bf40eb8b02f28be833e1e95 Mon Sep 17 00:00:00 2001 From: "Uwe L. Korn" Date: Tue, 21 Oct 2014 21:10:30 +0200 Subject: [PATCH 26/43] Seek even if VLC reports we can't Yep, sometimes we can seek even though VLC says no. --- src/libtomahawk/audio/AudioEngine.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libtomahawk/audio/AudioEngine.cpp b/src/libtomahawk/audio/AudioEngine.cpp index 1764545de..556a68ff0 100644 --- a/src/libtomahawk/audio/AudioEngine.cpp +++ b/src/libtomahawk/audio/AudioEngine.cpp @@ -450,11 +450,11 @@ AudioEngine::seek( qint64 ms ) { Q_D( AudioEngine ); - if ( !canSeek() ) + /*if ( !canSeek() ) { tDebug( LOGEXTRA ) << "Could not seek!"; return; - } + }*/ if ( isPlaying() || isPaused() ) { From c986506605f68177fbdf32ed7d7512a4062672e7 Mon Sep 17 00:00:00 2001 From: "Uwe L. Korn" Date: Tue, 21 Oct 2014 21:13:19 +0200 Subject: [PATCH 27/43] Use Q_D instead of d_func --- src/libtomahawk/audio/AudioEngine.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/libtomahawk/audio/AudioEngine.cpp b/src/libtomahawk/audio/AudioEngine.cpp index 556a68ff0..fece820a4 100644 --- a/src/libtomahawk/audio/AudioEngine.cpp +++ b/src/libtomahawk/audio/AudioEngine.cpp @@ -1244,14 +1244,16 @@ AudioEngine::currentTime() const qint64 AudioEngine::currentTrackTotalTime() const { + Q_D( const AudioEngine ); + // FIXME : This is too hacky. The problem is that I don't know why // libVLC doesn't report total duration for stream data (imem://) // But it's not a real problem for playback, since EndOfStream is emitted by libVLC itself // This value is only used by AudioOutput to evaluate if it's close to end of stream - if ( d_func()->audioOutput->totalTime() <= 0 && d_func()->currentTrack && d_func()->currentTrack->track() ) { - return d_func()->currentTrack->track()->duration() * 1000 + 1000; + if ( d->audioOutput->totalTime() <= 0 && d->currentTrack && d->currentTrack->track() ) { + return d->currentTrack->track()->duration() * 1000 + 1000; } - return d_func()->audioOutput->totalTime(); + return d->audioOutput->totalTime(); } From b6f92013bda27beb8afbc6cf481b53888c518254 Mon Sep 17 00:00:00 2001 From: "Uwe L. Korn" Date: Tue, 21 Oct 2014 22:55:55 +0200 Subject: [PATCH 28/43] Use nullptr instead of 0 --- src/libtomahawk/audio/AudioOutput.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libtomahawk/audio/AudioOutput.cpp b/src/libtomahawk/audio/AudioOutput.cpp index 3fe7d91e2..9d93b4084 100644 --- a/src/libtomahawk/audio/AudioOutput.cpp +++ b/src/libtomahawk/audio/AudioOutput.cpp @@ -52,6 +52,7 @@ AudioOutput::instance() AudioOutput::AudioOutput( QObject* parent ) : QObject( parent ) , currentState( Stopped ) + , currentStream( nullptr ) , seekable( true ) , muted( false ) , m_autoDelete ( true ) @@ -60,15 +61,14 @@ AudioOutput::AudioOutput( QObject* parent ) , m_totalTime( 0 ) , m_aboutToFinish( false ) , m_justSeeked( false ) - , dspPluginCallback( 0 ) - , vlcInstance( 0 ) - , vlcPlayer( 0 ) - , vlcMedia( 0 ) + , dspPluginCallback( nullptr ) + , vlcInstance( nullptr ) + , vlcPlayer( nullptr ) + , vlcMedia( nullptr ) { tDebug() << Q_FUNC_INFO; AudioOutput::s_instance = this; - currentStream = 0; qRegisterMetaType("AudioOutput::AudioState"); From f0e2ddcdf09a0850b550a803574797706d546fdf Mon Sep 17 00:00:00 2001 From: "Uwe L. Korn" Date: Tue, 21 Oct 2014 22:57:05 +0200 Subject: [PATCH 29/43] Use constant c-style array instead of fancy Qt data structures --- src/libtomahawk/audio/AudioOutput.cpp | 41 +++++++++++---------------- 1 file changed, 16 insertions(+), 25 deletions(-) diff --git a/src/libtomahawk/audio/AudioOutput.cpp b/src/libtomahawk/audio/AudioOutput.cpp index 9d93b4084..8d3d2df4d 100644 --- a/src/libtomahawk/audio/AudioOutput.cpp +++ b/src/libtomahawk/audio/AudioOutput.cpp @@ -72,33 +72,24 @@ AudioOutput::AudioOutput( QObject* parent ) qRegisterMetaType("AudioOutput::AudioState"); - QList args; - - args << "--ignore-config"; - args << "--extraintf=logger"; - if ( qApp->arguments().contains( "--verbose" ) ) { - args << "--verbose=3"; - } -/* - args << "--no-plugins-cache"; - args << "--no-media-library"; - args << "--no-osd"; - args << "--no-stats"; - args << "--no-video-title-show"; - args << "--no-snapshot-preview"; - args << "--services-discovery=''"; -*/ - args << "--no-video"; - args << "--no-xlib"; - - QVarLengthArray< const char * , 64 > vlcArgs( args.size() ); - for ( int i = 0 ; i < args.size() ; ++i ) { - vlcArgs[i] = args.at( i ).constData(); - tDebug() << args.at( i ); - } + const char* vlcArgs[] = { + "--ignore-config", + "--extraintf=logger", + qApp->arguments().contains( "--verbose" ) ? "--verbose=3" : "", + // "--no-plugins-cache", + // "--no-media-library", + // "--no-osd", + // "--no-stats", + // "--no-video-title-show", + // "--no-snapshot-preview", + // "--services-discovery=''", + "--no-video", + "--no-xlib" + }; // Create and initialize a libvlc instance (it should be done only once) - if ( !( vlcInstance = libvlc_new( vlcArgs.size(), vlcArgs.constData() ) ) ) { + vlcInstance = libvlc_new( sizeof(vlcArgs) / sizeof(*vlcArgs), vlcArgs ); + if ( !vlcInstance ) { tDebug() << "libVLC: could not initialize"; } From dfd3715051e3f8997299ad9ac0934fcdc602e163 Mon Sep 17 00:00:00 2001 From: "Uwe L. Korn" Date: Tue, 21 Oct 2014 23:02:00 +0200 Subject: [PATCH 30/43] Use nullptr instead of 0 --- src/libtomahawk/audio/AudioOutput.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/libtomahawk/audio/AudioOutput.cpp b/src/libtomahawk/audio/AudioOutput.cpp index 8d3d2df4d..b3c6fd011 100644 --- a/src/libtomahawk/audio/AudioOutput.cpp +++ b/src/libtomahawk/audio/AudioOutput.cpp @@ -131,16 +131,16 @@ AudioOutput::~AudioOutput() { tDebug() << Q_FUNC_INFO; - if ( vlcPlayer != 0 ) { + if ( vlcPlayer != nullptr ) { libvlc_media_player_stop( vlcPlayer ); libvlc_media_player_release( vlcPlayer ); - vlcPlayer = 0; + vlcPlayer = nullptr; } - if ( vlcMedia != 0 ) { + if ( vlcMedia != nullptr ) { libvlc_media_release( vlcMedia ); - vlcMedia = 0; + vlcMedia = nullptr; } - if ( vlcInstance != 0 ) { + if ( vlcInstance != nullptr ) { libvlc_release( vlcInstance ); } } @@ -165,13 +165,13 @@ AudioOutput::setCurrentSource(MediaStream* stream) setState(Loading); - if ( vlcMedia != 0 ) { + if ( vlcMedia != nullptr ) { // Ensure playback is stopped, then release media libvlc_media_player_stop( vlcPlayer ); libvlc_media_release( vlcMedia ); - vlcMedia = 0; + vlcMedia = nullptr; } - if ( m_autoDelete && currentStream != 0 ) { + if ( m_autoDelete && currentStream != nullptr ) { delete currentStream; } From eeff358e1d493c90a7449c1ae5f38c9fa771f371 Mon Sep 17 00:00:00 2001 From: "Uwe L. Korn" Date: Tue, 21 Oct 2014 23:03:16 +0200 Subject: [PATCH 31/43] Style fixes --- src/libtomahawk/audio/AudioOutput.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libtomahawk/audio/AudioOutput.cpp b/src/libtomahawk/audio/AudioOutput.cpp index b3c6fd011..c84da9363 100644 --- a/src/libtomahawk/audio/AudioOutput.cpp +++ b/src/libtomahawk/audio/AudioOutput.cpp @@ -152,14 +152,16 @@ AudioOutput::setAutoDelete ( bool ad ) m_autoDelete = ad; } + void -AudioOutput::setCurrentSource(MediaStream stream) +AudioOutput::setCurrentSource( MediaStream stream ) { setCurrentSource( new MediaStream(stream) ); } + void -AudioOutput::setCurrentSource(MediaStream* stream) +AudioOutput::setCurrentSource( MediaStream* stream ) { tDebug() << Q_FUNC_INFO; From c9adcf6bd7793ed819214711a51498f59d356793 Mon Sep 17 00:00:00 2001 From: "Uwe L. Korn" Date: Tue, 21 Oct 2014 23:23:04 +0200 Subject: [PATCH 32/43] Don't copy MediaStream instances With the large char-buffer, a copy of them will be very inefficent. Explicitly add functions for the conversion to a MediaStream but do not allow a copy constructor. --- src/libtomahawk/audio/AudioOutput.cpp | 11 +++++++++-- src/libtomahawk/audio/AudioOutput.h | 5 +++-- src/libtomahawk/utils/MediaStream.cpp | 18 ------------------ src/libtomahawk/utils/MediaStream.h | 7 ++++--- 4 files changed, 16 insertions(+), 25 deletions(-) diff --git a/src/libtomahawk/audio/AudioOutput.cpp b/src/libtomahawk/audio/AudioOutput.cpp index c84da9363..61b0a07da 100644 --- a/src/libtomahawk/audio/AudioOutput.cpp +++ b/src/libtomahawk/audio/AudioOutput.cpp @@ -154,9 +154,16 @@ AudioOutput::setAutoDelete ( bool ad ) void -AudioOutput::setCurrentSource( MediaStream stream ) +AudioOutput::setCurrentSource( const QUrl& stream ) { - setCurrentSource( new MediaStream(stream) ); + setCurrentSource( new MediaStream( stream ) ); +} + + +void +AudioOutput::setCurrentSource( QIODevice* stream ) +{ + setCurrentSource( new MediaStream( stream ) ); } diff --git a/src/libtomahawk/audio/AudioOutput.h b/src/libtomahawk/audio/AudioOutput.h index 768da5a0d..2c3d7ce24 100644 --- a/src/libtomahawk/audio/AudioOutput.h +++ b/src/libtomahawk/audio/AudioOutput.h @@ -46,8 +46,9 @@ public: AudioState state(); - void setCurrentSource(MediaStream stream); - void setCurrentSource(MediaStream* stream); + void setCurrentSource( const QUrl& stream); + void setCurrentSource( QIODevice* stream); + void setCurrentSource( MediaStream* stream ); void play(); void pause(); diff --git a/src/libtomahawk/utils/MediaStream.cpp b/src/libtomahawk/utils/MediaStream.cpp index dde1147f9..9d71d61c4 100644 --- a/src/libtomahawk/utils/MediaStream.cpp +++ b/src/libtomahawk/utils/MediaStream.cpp @@ -77,24 +77,6 @@ MediaStream::MediaStream( QIODevice* device ) } -MediaStream::MediaStream( const MediaStream& copy ) - : QObject( copy.parent() ) -{ - m_type = copy.m_type; - m_url = copy.m_url; - m_ioDevice = copy.m_ioDevice; - m_started = copy.m_started; - m_bufferingFinished = copy.m_bufferingFinished; - m_eos = copy.m_eos; - m_pos = copy.m_pos; - m_streamSize = copy.m_streamSize; - - if ( m_type == IODevice ) { - QObject::connect( m_ioDevice, SIGNAL( readChannelFinished() ), this, SLOT( bufferingFinished() ) ); - } -} - - MediaStream::~MediaStream() { tDebug() << Q_FUNC_INFO; diff --git a/src/libtomahawk/utils/MediaStream.h b/src/libtomahawk/utils/MediaStream.h index e1f7b0f9f..c35a74eaf 100644 --- a/src/libtomahawk/utils/MediaStream.h +++ b/src/libtomahawk/utils/MediaStream.h @@ -39,9 +39,8 @@ public: enum MediaType { Unknown = -1, Empty = 0, Url = 1, Stream = 2, IODevice = 3 }; MediaStream( QObject* parent = 0 ); - MediaStream( const MediaStream& copy ); - MediaStream( const QUrl &url ); - MediaStream( QIODevice* device ); + explicit MediaStream( const QUrl &url ); + explicit MediaStream( QIODevice* device ); virtual ~MediaStream(); MediaType type(); @@ -74,6 +73,8 @@ protected: qint64 m_streamSize; char m_buffer[1048576]; +private: + Q_DISABLE_COPY( MediaStream ); }; #endif // MEDIASTREAM_H From 14e264cf601f35ac9e22c50de1557f5f3442c117 Mon Sep 17 00:00:00 2001 From: "Uwe L. Korn" Date: Wed, 22 Oct 2014 09:05:30 +0200 Subject: [PATCH 33/43] Style fixes --- src/libtomahawk/audio/AudioOutput.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libtomahawk/audio/AudioOutput.cpp b/src/libtomahawk/audio/AudioOutput.cpp index 61b0a07da..7a94cce04 100644 --- a/src/libtomahawk/audio/AudioOutput.cpp +++ b/src/libtomahawk/audio/AudioOutput.cpp @@ -233,10 +233,12 @@ AudioOutput::setCurrentSource( MediaStream* stream ) libvlc_media_player_set_media( vlcPlayer, vlcMedia ); - if ( stream->type() == MediaStream::Url ) { + if ( stream->type() == MediaStream::Url ) + { m_totalTime = libvlc_media_get_duration( vlcMedia ); } - else if ( stream->type() == MediaStream::Stream || stream->type() == MediaStream::IODevice ) { + else if ( stream->type() == MediaStream::Stream || stream->type() == MediaStream::IODevice ) + { libvlc_media_add_option_flag(vlcMedia, "imem-cat=4", libvlc_media_option_trusted); libvlc_media_add_option_flag(vlcMedia, (QString("imem-data=") + QString::number((quint64)stream)).toUtf8().data(), libvlc_media_option_trusted); libvlc_media_add_option_flag(vlcMedia, (QString("imem-get=") + QString::number((quint64)&MediaStream::readCallback)).toUtf8().data(), libvlc_media_option_trusted); From b8fe5ad218a29162d9231e9e2454e85d9ff2d255 Mon Sep 17 00:00:00 2001 From: "Uwe L. Korn" Date: Wed, 22 Oct 2014 09:05:37 +0200 Subject: [PATCH 34/43] Use uintptr_t --- src/libtomahawk/audio/AudioOutput.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libtomahawk/audio/AudioOutput.cpp b/src/libtomahawk/audio/AudioOutput.cpp index 7a94cce04..f7a5b7c34 100644 --- a/src/libtomahawk/audio/AudioOutput.cpp +++ b/src/libtomahawk/audio/AudioOutput.cpp @@ -240,10 +240,10 @@ AudioOutput::setCurrentSource( MediaStream* stream ) else if ( stream->type() == MediaStream::Stream || stream->type() == MediaStream::IODevice ) { libvlc_media_add_option_flag(vlcMedia, "imem-cat=4", libvlc_media_option_trusted); - libvlc_media_add_option_flag(vlcMedia, (QString("imem-data=") + QString::number((quint64)stream)).toUtf8().data(), libvlc_media_option_trusted); - libvlc_media_add_option_flag(vlcMedia, (QString("imem-get=") + QString::number((quint64)&MediaStream::readCallback)).toUtf8().data(), libvlc_media_option_trusted); - libvlc_media_add_option_flag(vlcMedia, (QString("imem-release=") + QString::number((quint64)&MediaStream::readDoneCallback)).toUtf8().data(), libvlc_media_option_trusted); - libvlc_media_add_option_flag(vlcMedia, (QString("imem-seek=") + QString::number((quint64)&MediaStream::seekCallback)).toUtf8().data(), libvlc_media_option_trusted); + libvlc_media_add_option_flag(vlcMedia, (QString("imem-data=") + QString::number((uintptr_t)stream)).toUtf8().data(), libvlc_media_option_trusted); + libvlc_media_add_option_flag(vlcMedia, (QString("imem-get=") + QString::number((uintptr_t)&MediaStream::readCallback)).toUtf8().data(), libvlc_media_option_trusted); + libvlc_media_add_option_flag(vlcMedia, (QString("imem-release=") + QString::number((uintptr_t)&MediaStream::readDoneCallback)).toUtf8().data(), libvlc_media_option_trusted); + libvlc_media_add_option_flag(vlcMedia, (QString("imem-seek=") + QString::number((uintptr_t)&MediaStream::seekCallback)).toUtf8().data(), libvlc_media_option_trusted); } m_aboutToFinish = false; From a324ff14f6afd0adaf0125f8a092a834baea8025 Mon Sep 17 00:00:00 2001 From: "Uwe L. Korn" Date: Wed, 22 Oct 2014 09:15:32 +0200 Subject: [PATCH 35/43] Construct arguments using QString::arg --- src/libtomahawk/audio/AudioOutput.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/libtomahawk/audio/AudioOutput.cpp b/src/libtomahawk/audio/AudioOutput.cpp index f7a5b7c34..a99ba7279 100644 --- a/src/libtomahawk/audio/AudioOutput.cpp +++ b/src/libtomahawk/audio/AudioOutput.cpp @@ -240,10 +240,14 @@ AudioOutput::setCurrentSource( MediaStream* stream ) else if ( stream->type() == MediaStream::Stream || stream->type() == MediaStream::IODevice ) { libvlc_media_add_option_flag(vlcMedia, "imem-cat=4", libvlc_media_option_trusted); - libvlc_media_add_option_flag(vlcMedia, (QString("imem-data=") + QString::number((uintptr_t)stream)).toUtf8().data(), libvlc_media_option_trusted); - libvlc_media_add_option_flag(vlcMedia, (QString("imem-get=") + QString::number((uintptr_t)&MediaStream::readCallback)).toUtf8().data(), libvlc_media_option_trusted); - libvlc_media_add_option_flag(vlcMedia, (QString("imem-release=") + QString::number((uintptr_t)&MediaStream::readDoneCallback)).toUtf8().data(), libvlc_media_option_trusted); - libvlc_media_add_option_flag(vlcMedia, (QString("imem-seek=") + QString::number((uintptr_t)&MediaStream::seekCallback)).toUtf8().data(), libvlc_media_option_trusted); + const char* imemData = QString( "imem-data=%1" ).arg( (uintptr_t)stream ).toLatin1().constData(); + libvlc_media_add_option_flag(vlcMedia, imemData, libvlc_media_option_trusted); + const char* imemGet = QString( "imem-get=%1" ).arg( (uintptr_t)&MediaStream::readCallback ).toLatin1().constData(); + libvlc_media_add_option_flag(vlcMedia, imemGet, libvlc_media_option_trusted); + const char* imemRelease = QString( "imem-release=%1" ).arg( (uintptr_t)&MediaStream::readDoneCallback ).toLatin1().constData(); + libvlc_media_add_option_flag(vlcMedia, imemRelease, libvlc_media_option_trusted); + const char* imemSeek = QString( "imem-seek=%1" ).arg( (uintptr_t)&MediaStream::seekCallback ).toLatin1().constData(); + libvlc_media_add_option_flag(vlcMedia, imemSeek, libvlc_media_option_trusted); } m_aboutToFinish = false; From fd39191d6ad988ebc01614f9c1a8dc9d09458a6e Mon Sep 17 00:00:00 2001 From: "Uwe L. Korn" Date: Wed, 22 Oct 2014 09:31:53 +0200 Subject: [PATCH 36/43] Always seek independent of what VLC says --- src/libtomahawk/audio/AudioOutput.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/libtomahawk/audio/AudioOutput.cpp b/src/libtomahawk/audio/AudioOutput.cpp index a99ba7279..f6c63fe48 100644 --- a/src/libtomahawk/audio/AudioOutput.cpp +++ b/src/libtomahawk/audio/AudioOutput.cpp @@ -376,9 +376,11 @@ AudioOutput::seek( qint64 milliseconds ) { tDebug() << Q_FUNC_INFO; - if ( !seekable ) { - return; - } + // Even seek if reported as not seekable. VLC can seek in some cases where + // it tells us it can't. + // if ( !seekable ) { + // return; + // } switch ( currentState ) { case Playing: From 3a8d23c5b1efa6949056590e3589dacc031c4606 Mon Sep 17 00:00:00 2001 From: "Uwe L. Korn" Date: Wed, 22 Oct 2014 09:42:54 +0200 Subject: [PATCH 37/43] Style fixes --- src/libtomahawk/audio/AudioOutput.h | 15 +++++++-------- src/libtomahawk/utils/MediaStream.cpp | 13 ++++--------- src/libtomahawk/utils/MediaStream.h | 9 +++------ 3 files changed, 14 insertions(+), 23 deletions(-) diff --git a/src/libtomahawk/audio/AudioOutput.h b/src/libtomahawk/audio/AudioOutput.h index 2c3d7ce24..3fbb70742 100644 --- a/src/libtomahawk/audio/AudioOutput.h +++ b/src/libtomahawk/audio/AudioOutput.h @@ -22,9 +22,8 @@ #ifndef AUDIOOUTPUT_H #define AUDIOOUTPUT_H -#include "../Typedefs.h" - #include "DllMacro.h" +#include "Typedefs.h" #include "utils/MediaStream.h" #include @@ -41,24 +40,24 @@ Q_OBJECT public: enum AudioState { Stopped = 0, Playing = 1, Paused = 2, Error = 3, Loading = 4, Buffering = 5 }; - explicit AudioOutput(QObject* parent = 0); + explicit AudioOutput( QObject* parent = nullptr ); ~AudioOutput(); AudioState state(); - void setCurrentSource( const QUrl& stream); - void setCurrentSource( QIODevice* stream); + void setCurrentSource( const QUrl& stream ); + void setCurrentSource( QIODevice* stream ); void setCurrentSource( MediaStream* stream ); void play(); void pause(); void stop(); - void seek(qint64 milliseconds); + void seek( qint64 milliseconds ); bool isSeekable(); bool isMuted(); - void setMuted(bool m); - void setVolume(qreal vol); + void setMuted( bool m ); + void setVolume( qreal vol ); qreal volume(); qint64 currentTime(); qint64 totalTime(); diff --git a/src/libtomahawk/utils/MediaStream.cpp b/src/libtomahawk/utils/MediaStream.cpp index 9d71d61c4..3827656b9 100644 --- a/src/libtomahawk/utils/MediaStream.cpp +++ b/src/libtomahawk/utils/MediaStream.cpp @@ -30,8 +30,7 @@ static QString s_aeInfoIdentifier = QString( "MEDIASTREAM" ); MediaStream::MediaStream( QObject* parent ) : QObject( parent ) , m_type( Unknown ) - , m_url( QUrl() ) - , m_ioDevice ( 0 ) + , m_ioDevice ( nullptr ) , m_started( false ) , m_bufferingFinished( false ) , m_eos( false ) @@ -39,14 +38,14 @@ MediaStream::MediaStream( QObject* parent ) , m_streamSize( 0 ) { tDebug() << Q_FUNC_INFO; - } MediaStream::MediaStream( const QUrl &url ) : QObject( 0 ) , m_type( Url ) - , m_ioDevice ( 0 ) + , m_url( url ) + , m_ioDevice ( nullptr ) , m_started( false ) , m_bufferingFinished( false ) , m_eos( false ) @@ -54,16 +53,13 @@ MediaStream::MediaStream( const QUrl &url ) , m_streamSize( 0 ) { tDebug() << Q_FUNC_INFO; - - m_url = url; } MediaStream::MediaStream( QIODevice* device ) : QObject( 0 ) , m_type( IODevice ) - , m_url( QUrl() ) - , m_ioDevice ( 0 ) + , m_ioDevice ( device ) , m_started( false ) , m_bufferingFinished( false ) , m_eos( false ) @@ -72,7 +68,6 @@ MediaStream::MediaStream( QIODevice* device ) { tDebug() << Q_FUNC_INFO; - m_ioDevice = device; QObject::connect( m_ioDevice, SIGNAL( readChannelFinished() ), this, SLOT( bufferingFinished() ) ); } diff --git a/src/libtomahawk/utils/MediaStream.h b/src/libtomahawk/utils/MediaStream.h index c35a74eaf..a893e6cb9 100644 --- a/src/libtomahawk/utils/MediaStream.h +++ b/src/libtomahawk/utils/MediaStream.h @@ -21,13 +21,10 @@ #ifndef MEDIASTREAM_H #define MEDIASTREAM_H -#include "../Typedefs.h" - #include "DllMacro.h" +#include "Typedefs.h" #include "utils/Logger.h" -#include -#include #include #include @@ -38,7 +35,7 @@ class DLLEXPORT MediaStream : public QObject public: enum MediaType { Unknown = -1, Empty = 0, Url = 1, Stream = 2, IODevice = 3 }; - MediaStream( QObject* parent = 0 ); + MediaStream( QObject* parent = nullptr ); explicit MediaStream( const QUrl &url ); explicit MediaStream( QIODevice* device ); virtual ~MediaStream(); @@ -74,7 +71,7 @@ protected: char m_buffer[1048576]; private: - Q_DISABLE_COPY( MediaStream ); + Q_DISABLE_COPY( MediaStream ) }; #endif // MEDIASTREAM_H From dc50191f34805bcaf5242408d3fbb968e38e9b76 Mon Sep 17 00:00:00 2001 From: "Uwe L. Korn" Date: Wed, 22 Oct 2014 10:45:02 +0200 Subject: [PATCH 38/43] Further simplify FindVLC --- CMakeLists.txt | 2 +- CMakeModules/FindLIBVLC.cmake | 48 +++------------------------------- src/libtomahawk/CMakeLists.txt | 1 - 3 files changed, 5 insertions(+), 46 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 68da1ba3b..07becd9c2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -346,7 +346,7 @@ endif() macro_log_feature(LIBSNORE_FOUND "Libsnore" "Library for notifications" "https://github.com/TheOneRing/Snorenotify" FALSE "" "") endif() -find_package(LIBVLC REQUIRED) +find_package(LIBVLC REQUIRED 2.1.0) macro_log_feature(LIBVLC_FOUND "LibVLC" "Provides audio output" TRUE "" "") set(QXTWEB_FOUND TRUE) diff --git a/CMakeModules/FindLIBVLC.cmake b/CMakeModules/FindLIBVLC.cmake index ee97ae486..3e15769dc 100644 --- a/CMakeModules/FindLIBVLC.cmake +++ b/CMakeModules/FindLIBVLC.cmake @@ -1,17 +1,3 @@ -# CMake module to search for LIBVLC (VLC library) -# Authors: Rohit Yadav -# Harald Sitter -# -# If it's found it sets LIBVLC_FOUND to TRUE -# and following variables are set: -# LIBVLC_INCLUDE_DIR -# LIBVLC_LIBRARY -# LIBVLC_VERSION - -if(NOT LIBVLC_MIN_VERSION) - set(LIBVLC_MIN_VERSION "2.1") -endif(NOT LIBVLC_MIN_VERSION) - find_package(PkgConfig QUIET) pkg_check_modules(PC_LIBVLC QUIET libvlc) set(LIBVLC_DEFINITIONS ${PC_LIBVLC_CFLAGS_OTHER}) @@ -22,12 +8,6 @@ find_path(LIBVLC_INCLUDE_DIR vlc/vlc.h ${PC_LIBVLC_INCLUDE_DIRS} ) -find_path(LIBVLCCORE_INCLUDE_DIR vlc_plugin.h - HINTS - ${PC_LIBVLC_INCLUDEDIR} - ${PC_LIBVLC_INCLUDE_DIRS} -) - find_library(LIBVLC_LIBRARY NAMES vlc libvlc HINTS ${PC_LIBVLC_LIBDIR} @@ -41,30 +21,10 @@ find_library(LIBVLCCORE_LIBRARY NAMES vlccore libvlccore ) set(LIBVLC_VERSION ${PC_LIBVLC_VERSION}) -if (NOT LIBVLC_VERSION) - # TODO: implement means to detect version on windows (vlc --version && regex? ... ultimately we would get it from a header though...) -endif (NOT LIBVLC_VERSION) -find_package_handle_standard_args(LibVLC DEFAULT_MSG LIBVLC_LIBRARY LIBVLCCORE_LIBRARY LIBVLC_INCLUDE_DIR) - -if (LIBVLC_VERSION STRLESS "${LIBVLC_MIN_VERSION}") - message(WARNING "LibVLC version not found: version searched: ${LIBVLC_MIN_VERSION}, found ${LIBVLC_VERSION}\nUnless you are on Windows this is bound to fail.") -# TODO: only activate once version detection can be garunteed (which is currently not the case on windows) -# set(LIBVLC_FOUND FALSE) -endif (LIBVLC_VERSION STRLESS "${LIBVLC_MIN_VERSION}") - - -if (LIBVLC_FOUND) - if (NOT LIBVLC_FIND_QUIETLY) - message(STATUS "Found LibVLC include-dir path: ${LIBVLC_INCLUDE_DIR}") - message(STATUS "Found LibVLC library: ${LIBVLC_LIBRARY}") - message(STATUS "Found LibVLCcore library: ${LIBVLCCORE_LIBRARY}") - message(STATUS "Found LibVLC version: ${LIBVLC_VERSION} (searched for: ${LIBVLC_MIN_VERSION})") - endif (NOT LIBVLC_FIND_QUIETLY) -else (LIBVLC_FOUND) - if (LIBVLC_FIND_REQUIRED) - message(FATAL_ERROR "Could not find LibVLC") - endif (LIBVLC_FIND_REQUIRED) -endif (LIBVLC_FOUND) +find_package_handle_standard_args(LibVLC + REQUIRED_VARS LIBVLC_LIBRARY LIBVLCCORE_LIBRARY LIBVLC_INCLUDE_DIR + VERSION_VAR LIBVLC_VERSION +) diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt index 0459c62ba..1afa607c3 100644 --- a/src/libtomahawk/CMakeLists.txt +++ b/src/libtomahawk/CMakeLists.txt @@ -392,7 +392,6 @@ include_directories( ${ECHONEST_INCLUDE_DIR} ${LUCENEPP_INCLUDE_DIRS} ${LIBVLC_INCLUDE_DIR} - ${LIBVLCCORE_INCLUDE_DIR} ${Boost_INCLUDE_DIR} ${LIBPORTFWD_INCLUDE_DIR} From fdbb5947349e3f439fe5d3fd49add7d27546afbd Mon Sep 17 00:00:00 2001 From: "Uwe L. Korn" Date: Wed, 22 Oct 2014 10:51:11 +0200 Subject: [PATCH 39/43] Restore volume restoring --- src/libtomahawk/audio/AudioEngine.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libtomahawk/audio/AudioEngine.cpp b/src/libtomahawk/audio/AudioEngine.cpp index fece820a4..ac18c570c 100644 --- a/src/libtomahawk/audio/AudioEngine.cpp +++ b/src/libtomahawk/audio/AudioEngine.cpp @@ -193,6 +193,9 @@ AudioEngine::AudioEngine() connect( d->audioOutput, SIGNAL( tick( qint64 ) ), SLOT( timerTriggered( qint64 ) ) ); connect( d->audioOutput, SIGNAL( aboutToFinish() ), SLOT( onAboutToFinish() ) ); + onVolumeChanged( d->audioOutput->volume() ); + setVolume( TomahawkSettings::instance()->volume() ); + qRegisterMetaType< AudioErrorCode >("AudioErrorCode"); qRegisterMetaType< AudioState >("AudioState"); } From 7f93604dbed63871d8f649e96f5170e1680eaafb Mon Sep 17 00:00:00 2001 From: "Uwe L. Korn" Date: Wed, 22 Oct 2014 10:53:54 +0200 Subject: [PATCH 40/43] Remove redundant code --- src/libtomahawk/audio/AudioEngine.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libtomahawk/audio/AudioEngine.cpp b/src/libtomahawk/audio/AudioEngine.cpp index ac18c570c..39c714357 100644 --- a/src/libtomahawk/audio/AudioEngine.cpp +++ b/src/libtomahawk/audio/AudioEngine.cpp @@ -193,7 +193,6 @@ AudioEngine::AudioEngine() connect( d->audioOutput, SIGNAL( tick( qint64 ) ), SLOT( timerTriggered( qint64 ) ) ); connect( d->audioOutput, SIGNAL( aboutToFinish() ), SLOT( onAboutToFinish() ) ); - onVolumeChanged( d->audioOutput->volume() ); setVolume( TomahawkSettings::instance()->volume() ); qRegisterMetaType< AudioErrorCode >("AudioErrorCode"); From a9e247d3d06e0249f9a50d8afd76c07e1d1b5de3 Mon Sep 17 00:00:00 2001 From: "Uwe L. Korn" Date: Wed, 22 Oct 2014 11:07:36 +0200 Subject: [PATCH 41/43] Remove supportedMimeTypes --- src/libtomahawk/audio/AudioEngine.cpp | 15 --------------- src/libtomahawk/audio/AudioEngine_p.h | 2 -- 2 files changed, 17 deletions(-) diff --git a/src/libtomahawk/audio/AudioEngine.cpp b/src/libtomahawk/audio/AudioEngine.cpp index 39c714357..f3a464def 100644 --- a/src/libtomahawk/audio/AudioEngine.cpp +++ b/src/libtomahawk/audio/AudioEngine.cpp @@ -211,21 +211,6 @@ AudioEngine::~AudioEngine() } -QStringList -AudioEngine::supportedMimeTypes() const -{ - Q_D( const AudioEngine ); - - if ( d->supportedMimeTypes.isEmpty() ) - { - d->supportedMimeTypes << "audio/*"; - d->supportedMimeTypes << "audio/basic"; - } - - return d->supportedMimeTypes; -} - - void AudioEngine::playPause() { diff --git a/src/libtomahawk/audio/AudioEngine_p.h b/src/libtomahawk/audio/AudioEngine_p.h index 59e90c851..824b85a53 100644 --- a/src/libtomahawk/audio/AudioEngine_p.h +++ b/src/libtomahawk/audio/AudioEngine_p.h @@ -40,8 +40,6 @@ private: bool expectStop; bool waitingOnNewTrack; - mutable QStringList supportedMimeTypes; - AudioState state; QQueue< AudioState > stateQueue; QTimer stateQueueTimer; From 271c68cd8f66dd16c56adb8e23bd2ab47a27d7b7 Mon Sep 17 00:00:00 2001 From: "Uwe L. Korn" Date: Wed, 22 Oct 2014 11:17:04 +0200 Subject: [PATCH 42/43] Remove ADO functions --- src/libtomahawk/audio/AudioEngine.cpp | 23 ----------------------- src/libtomahawk/audio/AudioEngine.h | 3 --- 2 files changed, 26 deletions(-) diff --git a/src/libtomahawk/audio/AudioEngine.cpp b/src/libtomahawk/audio/AudioEngine.cpp index f3a464def..0bdb7fdd0 100644 --- a/src/libtomahawk/audio/AudioEngine.cpp +++ b/src/libtomahawk/audio/AudioEngine.cpp @@ -155,12 +155,6 @@ AudioEnginePrivate::onStateChanged( AudioOutput::AudioState newState, AudioOutpu } } -/* -void -AudioEnginePrivate::onAudioDataArrived( QMap > data ) -{ -} -*/ AudioEngine* AudioEnginePrivate::s_instance = 0; @@ -206,7 +200,6 @@ AudioEngine::~AudioEngine() TomahawkSettings::instance()->setVolume( volume() ); - delete d_ptr; } @@ -321,22 +314,6 @@ AudioEngine::stop( AudioErrorCode errorCode ) } -bool AudioEngine::activateDataOutput() -{ - Q_D( AudioEngine ); - - return true; - -} - - -bool AudioEngine::deactivateDataOutput() -{ - Q_D( AudioEngine ); - - return true; -} - void AudioEngine::previous() { diff --git a/src/libtomahawk/audio/AudioEngine.h b/src/libtomahawk/audio/AudioEngine.h index 4753afc60..84058efed 100644 --- a/src/libtomahawk/audio/AudioEngine.h +++ b/src/libtomahawk/audio/AudioEngine.h @@ -118,9 +118,6 @@ public slots: void pause(); void stop( AudioErrorCode errorCode = NoError ); - bool activateDataOutput(); - bool deactivateDataOutput(); - void previous(); void next(); From 193df0743d722af3b1309c8369e32f9fee2745ca Mon Sep 17 00:00:00 2001 From: "Uwe L. Korn" Date: Wed, 22 Oct 2014 11:19:49 +0200 Subject: [PATCH 43/43] Debug-- --- src/libtomahawk/audio/AudioEngine.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/libtomahawk/audio/AudioEngine.cpp b/src/libtomahawk/audio/AudioEngine.cpp index 0bdb7fdd0..94ba4a4a4 100644 --- a/src/libtomahawk/audio/AudioEngine.cpp +++ b/src/libtomahawk/audio/AudioEngine.cpp @@ -673,7 +673,6 @@ AudioEngine::performLoadTrack( const Tomahawk::result_ptr result, const QString QSharedPointer qnr = io.objectCast(); if ( !qnr.isNull() ) { - tLog() << "CASE 1"; d->audioOutput->setCurrentSource( new QNR_IODeviceStream( qnr, this ) ); // We keep track of the QNetworkReply in QNR_IODeviceStream // and Phonon handles the deletion of the @@ -683,7 +682,6 @@ AudioEngine::performLoadTrack( const Tomahawk::result_ptr result, const QString } else { - tLog() << "CASE 2"; d->audioOutput->setCurrentSource( io.data() ); // We handle the deletion via tracking in d->input d->audioOutput->setAutoDelete( false ); @@ -697,7 +695,6 @@ AudioEngine::performLoadTrack( const Tomahawk::result_ptr result, const QString */ if ( !TomahawkUtils::isLocalResult( url ) ) { - tLog() << "CASE 3"; QUrl furl = url; if ( url.contains( "?" ) ) { @@ -710,7 +707,6 @@ AudioEngine::performLoadTrack( const Tomahawk::result_ptr result, const QString } else { - tLog() << "CASE 4"; QString furl = url; if ( furl.startsWith( "file://" ) ) furl = furl.right( furl.length() - 7 );