diff options
Diffstat (limited to 'avmedia/source/vlc')
27 files changed, 2254 insertions, 0 deletions
diff --git a/avmedia/source/vlc/avmediavlc.component b/avmedia/source/vlc/avmediavlc.component new file mode 100644 index 000000000..cbdba1d03 --- /dev/null +++ b/avmedia/source/vlc/avmediavlc.component @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * +--> +<component loader="com.sun.star.loader.SharedLibrary" environment="@CPPU_ENV@" + prefix="avmediavlc" xmlns="http://openoffice.org/2010/uno-components"> + <implementation name="com.sun.star.comp.media.Manager_VLC"> + <service name="com.sun.star.comp.avmedia.Manager_VLC"/> + </implementation> +</component> diff --git a/avmedia/source/vlc/inc/wrapper/Common.hxx b/avmedia/source/vlc/inc/wrapper/Common.hxx new file mode 100644 index 000000000..c9b7f9682 --- /dev/null +++ b/avmedia/source/vlc/inc/wrapper/Common.hxx @@ -0,0 +1,29 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +namespace avmedia +{ +namespace vlc +{ +namespace wrapper +{ + class Common + { + public: + static bool LoadSymbols(); + static const char* Version(); + static const char* LastErrorMessage(); + }; +} +} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/avmedia/source/vlc/inc/wrapper/EventHandler.hxx b/avmedia/source/vlc/inc/wrapper/EventHandler.hxx new file mode 100644 index 000000000..955c83478 --- /dev/null +++ b/avmedia/source/vlc/inc/wrapper/EventHandler.hxx @@ -0,0 +1,42 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include <functional> +#include <salhelper/thread.hxx> +#include <wrapper/ThreadsafeQueue.hxx> + +namespace avmedia +{ +namespace vlc +{ +namespace wrapper +{ + class EventHandler : public ::osl::Thread + { + public: + EventHandler(const EventHandler&) = delete; + const EventHandler& operator=(const EventHandler&) = delete; + + EventHandler(); + void stop(); + + protected: + virtual void SAL_CALL run() override; + + public: + typedef std::function< void() > TCallback; + ThreadsafeQueue< TCallback > mCallbackQueue; + }; +} +} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/avmedia/source/vlc/inc/wrapper/EventManager.hxx b/avmedia/source/vlc/inc/wrapper/EventManager.hxx new file mode 100644 index 000000000..9a8515483 --- /dev/null +++ b/avmedia/source/vlc/inc/wrapper/EventManager.hxx @@ -0,0 +1,55 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include <functional> +#include <wrapper/Player.hxx> + +struct libvlc_event_manager_t; +struct libvlc_event_t; + +namespace avmedia +{ +namespace vlc +{ +namespace wrapper +{ + class EventHandler; + class EventManager + { + + public: + EventManager(const EventManager&) = delete; + const EventManager& operator=(const EventManager&) = delete; + + static bool LoadSymbols(); + typedef std::function<void()> Callback; + + EventManager( Player& player, EventHandler& eh ); + + void onPaused( const Callback& callback = Callback() ); + void onEndReached( const Callback& callback = Callback() ); + + private: + EventHandler& mEventHandler; + typedef std::function< void() > TCallback; + libvlc_event_manager_t *mManager; + TCallback mOnPaused; + TCallback mOnEndReached; + + void registerSignal( int signal, const Callback& callback ); + + static void Handler( const libvlc_event_t *event, void *pData ); + }; +} +} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/avmedia/source/vlc/inc/wrapper/Instance.hxx b/avmedia/source/vlc/inc/wrapper/Instance.hxx new file mode 100644 index 000000000..7e4ba7741 --- /dev/null +++ b/avmedia/source/vlc/inc/wrapper/Instance.hxx @@ -0,0 +1,41 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +struct libvlc_instance_t; + +namespace avmedia +{ +namespace vlc +{ +namespace wrapper +{ + class Instance + { + public: + static bool LoadSymbols(); + Instance( int argc, const char * const argv[] ); + Instance( const Instance& other ); + Instance& operator=( const Instance& other ); + ~Instance(); + + operator libvlc_instance_t*() + { + return mInstance; + } + + private: + libvlc_instance_t *mInstance; + }; +} +} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/avmedia/source/vlc/inc/wrapper/Media.hxx b/avmedia/source/vlc/inc/wrapper/Media.hxx new file mode 100644 index 000000000..288bb0d43 --- /dev/null +++ b/avmedia/source/vlc/inc/wrapper/Media.hxx @@ -0,0 +1,47 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +struct libvlc_media_t; + +namespace rtl { class OUString; } + +namespace avmedia +{ +namespace vlc +{ +namespace wrapper +{ + class Instance; + class Media + { + public: + static bool LoadSymbols(); + Media( const rtl::OUString& url, Instance& instance ); + Media( const Media& other ); + Media& operator=( const Media& other ); + + int getDuration() const; + + ~Media(); + + operator libvlc_media_t*() + { + return mMedia; + } + + private: + libvlc_media_t *mMedia; + }; +} +} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/avmedia/source/vlc/inc/wrapper/Player.hxx b/avmedia/source/vlc/inc/wrapper/Player.hxx new file mode 100644 index 000000000..a41e01b10 --- /dev/null +++ b/avmedia/source/vlc/inc/wrapper/Player.hxx @@ -0,0 +1,73 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once +#if defined UNX +# include <stdint.h> +#endif + +struct libvlc_media_player_t; + +namespace rtl +{ + class OUString; +} + +namespace avmedia +{ +namespace vlc +{ +namespace wrapper +{ + class Media; + class Player + { + public: + static bool LoadSymbols(); + explicit Player( Media& media ); + Player( const Player& other ); + Player& operator=( const Player& other ); + ~Player(); + + bool play(); + void pause(); + void stop(); + void setTime( int time ); + int getTime() const; + bool isPlaying() const; + + void setVolume( int volume ); + int getVolume() const; + + void setMute( bool mute); + bool getMute() const; + + void setWindow( intptr_t id ); + + void takeSnapshot(const rtl::OUString& file); + + bool hasVout() const; + + void setScale( float factor ); + void setVideoSize( unsigned width, unsigned height ); + + operator libvlc_media_player_t*() + { + return mPlayer; + } + + void setMouseHandling(bool flag); + private: + libvlc_media_player_t *mPlayer; + }; +} +} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/avmedia/source/vlc/inc/wrapper/ThreadsafeQueue.hxx b/avmedia/source/vlc/inc/wrapper/ThreadsafeQueue.hxx new file mode 100644 index 000000000..f8eb480dd --- /dev/null +++ b/avmedia/source/vlc/inc/wrapper/ThreadsafeQueue.hxx @@ -0,0 +1,81 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#pragma once +#include <queue> +#include <iostream> +#include <osl/mutex.hxx> +#include <osl/conditn.hxx> + +namespace avmedia +{ +namespace vlc +{ +namespace wrapper +{ +template<class T> +class ThreadsafeQueue +{ +public: + ThreadsafeQueue(const ThreadsafeQueue&) = delete; + const ThreadsafeQueue& operator=(const ThreadsafeQueue&) = delete; + + ThreadsafeQueue(); + + void push( const T& data ); + void pop( T& data ); + +private: + std::queue< T > mQueue; + mutable ::osl::Mutex mMutex; + ::osl::Condition mCondition; +}; + +template<class T> +ThreadsafeQueue<T>::ThreadsafeQueue() +{ +} + +template<class T> +void ThreadsafeQueue<T>::push( const T& data ) +{ + ::osl::MutexGuard guard( mMutex ); + mQueue.push( data ); + mMutex.release(); + mCondition.set(); +} + +template<class T> +void ThreadsafeQueue<T>::pop( T& data ) +{ + mCondition.wait(); + ::osl::MutexGuard guard( mMutex ); + while ( mQueue.empty() ) + { + mMutex.release(); + mCondition.wait(); + mMutex.acquire(); + } + data = mQueue.front(); + mQueue.pop(); +} +} +} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/avmedia/source/vlc/inc/wrapper/Wrapper.hxx b/avmedia/source/vlc/inc/wrapper/Wrapper.hxx new file mode 100644 index 000000000..c381ea8db --- /dev/null +++ b/avmedia/source/vlc/inc/wrapper/Wrapper.hxx @@ -0,0 +1,19 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include <wrapper/Common.hxx> +#include <wrapper/EventHandler.hxx> +#include <wrapper/EventManager.hxx> +#include <wrapper/Instance.hxx> +#include <wrapper/Media.hxx> +#include <wrapper/Player.hxx> + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/avmedia/source/vlc/vlccommon.hxx b/avmedia/source/vlc/vlccommon.hxx new file mode 100644 index 000000000..13719516b --- /dev/null +++ b/avmedia/source/vlc/vlccommon.hxx @@ -0,0 +1,40 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#pragma once + +#include <osl/mutex.hxx> +#include <tools/stream.hxx> +#include <tools/urlobj.hxx> +#include <cppuhelper/weak.hxx> +#include <cppuhelper/factory.hxx> + +#include <com/sun/star/uno/Reference.h> +#include <com/sun/star/uno/RuntimeException.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/registry/XRegistryKey.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/awt/Rectangle.hpp> +#include <com/sun/star/awt/KeyModifier.hpp> +#include <com/sun/star/awt/MouseButton.hpp> +#include <com/sun/star/media/XManager.hpp> +#include <com/sun/star/media/XPlayerWindow.hpp> + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/avmedia/source/vlc/vlcframegrabber.cxx b/avmedia/source/vlc/vlcframegrabber.cxx new file mode 100644 index 000000000..034de4511 --- /dev/null +++ b/avmedia/source/vlc/vlcframegrabber.cxx @@ -0,0 +1,131 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <chrono> +#include <iostream> +#include <osl/conditn.hxx> +#include <osl/file.hxx> +#include <vcl/graph.hxx> +#include <vcl/bitmapaccess.hxx> +#include <vcl/pngread.hxx> +#include <avmedia/mediawindow.hxx> +#include <unotools/tempfile.hxx> +#include <unotools/ucbstreamhelper.hxx> +#include <tools/stream.hxx> +#include <cppuhelper/supportsservice.hxx> +#include <sal/log.hxx> + +#include "vlcframegrabber.hxx" +#include "vlcplayer.hxx" +#include <wrapper/Player.hxx> +#include <wrapper/EventManager.hxx> + +using namespace ::com::sun::star; + +namespace avmedia::vlc { + +namespace +{ + const OUString AVMEDIA_VLC_GRABBER_IMPLEMENTATIONNAME = "com.sun.star.comp.avmedia.VLCFrameGrabber_VLC"; + const OUString AVMEDIA_VLC_GRABBER_SERVICENAME = "com.sun.star.media.VLCFrameGrabber_VLC"; + const int MSEC_IN_SEC = 1000; + + const char * const VLC_ARGS[] = { + "-Vdummy", + "--demux", + "ffmpeg", + "--snapshot-format=png", + "--ffmpeg-threads", /* Is deprecated in 2.1.0 */ + "--verbose=-1", + "--no-audio" + }; +} + +VLCFrameGrabber::VLCFrameGrabber( wrapper::EventHandler& eh, const OUString& url ) + : FrameGrabber_BASE() + , mInstance( SAL_N_ELEMENTS(VLC_ARGS), VLC_ARGS ) + , mMedia( url, mInstance ) + , mPlayer( mMedia ) + , mEventHandler( eh ) +{ +} + +::uno::Reference< css::graphic::XGraphic > SAL_CALL VLCFrameGrabber::grabFrame( double fMediaTime ) +{ + osl::Condition condition; + + const OUString& fileName = utl::TempFile::CreateTempName(); + { + wrapper::EventManager manager( mPlayer, mEventHandler ); + manager.onPaused([&condition](){ condition.set(); }); + + if ( !mPlayer.play() ) + { + SAL_WARN("avmedia", "Couldn't play when trying to grab frame"); + return ::uno::Reference< css::graphic::XGraphic >(); + } + + mPlayer.setTime( std::max(fMediaTime, 0.0) * MSEC_IN_SEC ); + mPlayer.pause(); + + condition.wait(std::chrono::seconds(2)); + + if ( !mPlayer.hasVout() ) + { + SAL_WARN("avmedia", "Couldn't grab frame"); + manager.onPaused(); + return ::uno::Reference< css::graphic::XGraphic >(); + } + + mPlayer.takeSnapshot( fileName ); + mPlayer.stop(); + + manager.onPaused(); + } + + OUString url; + osl::FileBase::getFileURLFromSystemPath( fileName, url ); + std::unique_ptr<SvStream> stream( utl::UcbStreamHelper::CreateStream( url, + StreamMode::STD_READ ) ); + + vcl::PNGReader reader( *stream ); + + const BitmapEx& bitmap = reader.Read(); + + return Graphic( bitmap ).GetXGraphic(); +} + +OUString SAL_CALL VLCFrameGrabber::getImplementationName() +{ + return AVMEDIA_VLC_GRABBER_IMPLEMENTATIONNAME; +} + +sal_Bool SAL_CALL VLCFrameGrabber::supportsService( const OUString& serviceName ) +{ + return cppu::supportsService(this, serviceName); +} + +::uno::Sequence< OUString > SAL_CALL VLCFrameGrabber::getSupportedServiceNames() +{ + return { AVMEDIA_VLC_GRABBER_SERVICENAME }; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/avmedia/source/vlc/vlcframegrabber.hxx b/avmedia/source/vlc/vlcframegrabber.hxx new file mode 100644 index 000000000..77684d6b9 --- /dev/null +++ b/avmedia/source/vlc/vlcframegrabber.hxx @@ -0,0 +1,52 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#pragma once + +#include <com/sun/star/media/XFrameGrabber.hpp> +#include <cppuhelper/implbase.hxx> +#include "vlccommon.hxx" +#include <wrapper/Wrapper.hxx> + +namespace avmedia { +namespace vlc { + +typedef ::cppu::WeakImplHelper< css::media::XFrameGrabber, + css::lang::XServiceInfo > FrameGrabber_BASE; + +class VLCFrameGrabber : public FrameGrabber_BASE +{ + wrapper::Instance mInstance; + wrapper::Media mMedia; + wrapper::Player mPlayer; + wrapper::EventHandler& mEventHandler; +public: + VLCFrameGrabber( wrapper::EventHandler& eh, const OUString& url ); + + css::uno::Reference< css::graphic::XGraphic > SAL_CALL grabFrame( double fMediaTime ) override; + + OUString SAL_CALL getImplementationName() override; + sal_Bool SAL_CALL supportsService( const OUString& serviceName ) override; + css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override; +}; + +} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/avmedia/source/vlc/vlcmanager.cxx b/avmedia/source/vlc/vlcmanager.cxx new file mode 100644 index 000000000..60c02b259 --- /dev/null +++ b/avmedia/source/vlc/vlcmanager.cxx @@ -0,0 +1,124 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <boost/algorithm/string.hpp> +#include <boost/lexical_cast.hpp> +#include <com/sun/star/uno/Exception.hpp> +#include <cppuhelper/supportsservice.hxx> +#include <sal/log.hxx> +#include "vlcmanager.hxx" +#include "vlcplayer.hxx" +#include <wrapper/Instance.hxx> +#include <wrapper/EventManager.hxx> +#include <wrapper/Media.hxx> +#include <wrapper/Player.hxx> +#include <wrapper/Common.hxx> + +using namespace ::com::sun::star; + +namespace avmedia::vlc { + +namespace +{ + const OUString VLC_IMPLEMENTATION_NAME = "com.sun.star.comp.avmedia.Manager_VLC"; + const OUString VLC_SERVICENAME = "com.sun.star.media.Manager_VLC"; + + const char * const VLC_ARGS[] = { + "--demux", + "ffmpeg", + "--no-mouse-events", + "--verbose=-1" + }; +} + +Manager::Manager() + : mEventHandler() +{ + using namespace wrapper; + static bool success = Instance::LoadSymbols() && EventManager::LoadSymbols() + && Media::LoadSymbols() && Player::LoadSymbols() + && Common::LoadSymbols(); + + m_is_vlc_found = success; + if (m_is_vlc_found) + { + mInstance.reset(new Instance( SAL_N_ELEMENTS(VLC_ARGS), VLC_ARGS )); + //Check VLC version + std::vector<std::string> verComponents; + const std::string str(Common::Version()); + + boost::split(verComponents, + str, + boost::is_any_of(". ")); + if (verComponents.size() < 3 + || boost::lexical_cast<int>(verComponents[0]) < 2 + || (boost::lexical_cast<int>(verComponents[1]) == 0 + && boost::lexical_cast<int>(verComponents[2]) < 8)) + { + SAL_WARN("avmedia", "VLC version '" << str << "' is too old"); + m_is_vlc_found = false; + } + else + SAL_INFO("avmedia", "VLC version '" << str << "' is acceptable"); + } + else + SAL_WARN("avmedia", "Cannot load symbols"); + + if (m_is_vlc_found) + { + mEventHandler.create(); + } +} + +Manager::~Manager() +{ + mEventHandler.stop(); +} + +uno::Reference< media::XPlayer > SAL_CALL Manager::createPlayer( const OUString& rURL ) +{ + if ( !m_is_vlc_found ) + throw uno::RuntimeException("VLC not found", nullptr); + + if ( !rURL.isEmpty() ) + { + if (mURL == rURL) + return mPlayer; + + mURL = rURL; + } + else + return mPlayer; + + VLCPlayer* pPlayer( new VLCPlayer( mURL, + *mInstance, + mEventHandler /*, mxMgr */ ) ); + mPlayer.set( pPlayer ); + + return mPlayer; +} + +OUString SAL_CALL Manager::getImplementationName() +{ + return VLC_IMPLEMENTATION_NAME; +} + +sal_Bool SAL_CALL Manager::supportsService( const OUString& serviceName ) +{ + return cppu::supportsService(this, serviceName); +} + +uno::Sequence< OUString > SAL_CALL Manager::getSupportedServiceNames() +{ + return { VLC_SERVICENAME }; +} + +} // end namespace + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/avmedia/source/vlc/vlcmanager.hxx b/avmedia/source/vlc/vlcmanager.hxx new file mode 100644 index 000000000..3615ab17d --- /dev/null +++ b/avmedia/source/vlc/vlcmanager.hxx @@ -0,0 +1,54 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#pragma once +#include <com/sun/star/media/XManager.hpp> +#include "vlccommon.hxx" +#include <wrapper/Wrapper.hxx> +#include <memory> +#include <cppuhelper/implbase.hxx> + +namespace avmedia { +namespace vlc { + +class Manager : public ::cppu::WeakImplHelper< css::media::XManager, + css::lang::XServiceInfo > +{ + std::unique_ptr<wrapper::Instance> mInstance; + wrapper::EventHandler mEventHandler; +public: + explicit Manager(); + virtual ~Manager() override; + + css::uno::Reference< css::media::XPlayer > SAL_CALL createPlayer( const OUString& aURL ) override; + + OUString SAL_CALL getImplementationName() override; + sal_Bool SAL_CALL supportsService( const OUString& serviceName ) override; + css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override; + +private: + css::uno::Reference< css::media::XPlayer > mPlayer; + OUString mURL; + bool m_is_vlc_found; +}; + +} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/avmedia/source/vlc/vlcplayer.cxx b/avmedia/source/vlc/vlcplayer.cxx new file mode 100644 index 000000000..bd2cc92ba --- /dev/null +++ b/avmedia/source/vlc/vlcplayer.cxx @@ -0,0 +1,251 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <vcl/syschild.hxx> +#include <vcl/sysdata.hxx> +#include <cppuhelper/supportsservice.hxx> + +#include "vlcplayer.hxx" +#include "vlcwindow.hxx" +#include "vlcframegrabber.hxx" +#include <wrapper/Instance.hxx> + +using namespace ::com::sun::star; + +namespace avmedia::vlc { + +namespace +{ + const OUString AVMEDIA_VLC_PLAYER_IMPLEMENTATIONNAME = "com.sun.star.comp.avmedia.Player_VLC"; + const OUString AVMEDIA_VLC_PLAYER_SERVICENAME = "com.sun.star.media.Player_VLC"; + + const int MS_IN_SEC = 1000; // Millisec in sec +} + +VLCPlayer::VLCPlayer( const OUString& url, + wrapper::Instance& instance, + wrapper::EventHandler& eh ) + : VLC_Base( m_aMutex ) + , mEventHandler( eh ) + , mMedia( url, instance ) + , mPlayer( mMedia ) + , mEventManager( mPlayer, mEventHandler ) + , mUrl( url ) + , mPlaybackLoop( false ) + , mPrevWinID( 0 ) +{ + mPlayer.setMouseHandling( false ); +} + +void SAL_CALL VLCPlayer::start() +{ + ::osl::MutexGuard aGuard(m_aMutex); + if (!mPlayer.play()) + { + // TODO: Error + } +} + +void SAL_CALL VLCPlayer::stop() +{ + ::osl::MutexGuard aGuard(m_aMutex); + mPlayer.pause(); +} + +sal_Bool SAL_CALL VLCPlayer::isPlaying() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return mPlayer.isPlaying(); +} + +double SAL_CALL VLCPlayer::getDuration() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return static_cast<double>( mMedia.getDuration() ) / MS_IN_SEC; +} + +void SAL_CALL VLCPlayer::setMediaTime( double fTime ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + if ( fTime < 0.00000001 && !mPlayer.isPlaying() ) + { + mPlayer.stop(); + } + + mPlayer.setTime( fTime * MS_IN_SEC ); +} + +double SAL_CALL VLCPlayer::getMediaTime() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return static_cast<double>( mPlayer.getTime() ) / MS_IN_SEC; +} + +void VLCPlayer::replay() +{ + setPlaybackLoop( false ); + stop(); + setMediaTime( 0 ); + start(); +} + +void SAL_CALL VLCPlayer::setPlaybackLoop( sal_Bool bSet ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + mPlaybackLoop = bSet; + + if ( bSet ) + mEventManager.onEndReached([this](){ this->replay(); }); + else + mEventManager.onEndReached(); +} + +sal_Bool SAL_CALL VLCPlayer::isPlaybackLoop() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return mPlaybackLoop; +} + +void SAL_CALL VLCPlayer::setVolumeDB( ::sal_Int16 nDB ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + mPlayer.setVolume( static_cast<sal_Int16>( ( nDB + 40 ) * 10.0 / 4 ) ); +} + +::sal_Int16 SAL_CALL VLCPlayer::getVolumeDB() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return static_cast<sal_Int16>( mPlayer.getVolume() / 10.0 * 4 - 40 ); +} + +void SAL_CALL VLCPlayer::setMute( sal_Bool bSet ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + mPlayer.setMute( bSet ); +} + +sal_Bool SAL_CALL VLCPlayer::isMute() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return mPlayer.getMute(); +} + +css::awt::Size SAL_CALL VLCPlayer::getPreferredPlayerWindowSize() +{ + return css::awt::Size( 480, 360 ); +} + +namespace +{ + // TODO: Move this function to the common space for avoiding duplication with + // gstreamer/gstwindow::createPlayerWindow functionality + intptr_t GetWindowID( const uno::Sequence< uno::Any >& arguments ) + { + if (arguments.getLength() <= 2) + return -1; + + sal_IntPtr pIntPtr = 0; + + arguments[ 2 ] >>= pIntPtr; + + SystemChildWindow *pParentWindow = reinterpret_cast< SystemChildWindow* >( pIntPtr ); + + const SystemEnvData* pEnvData = pParentWindow ? pParentWindow->GetSystemData() : nullptr; + + if (pEnvData == nullptr) + return -1; + +#if defined MACOSX + const intptr_t id = reinterpret_cast<intptr_t>( pEnvData->mpNSView ); +#elif defined _WIN32 + const intptr_t id = reinterpret_cast<intptr_t>( pEnvData->hWnd ); +#else + const intptr_t id = static_cast<intptr_t>( pEnvData->aWindow ); +#endif + + return id; + } +} + +void VLCPlayer::setWindowID( const intptr_t windowID ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + mPlayer.stop(); + mPlayer.setWindow( windowID ); +} + +void VLCPlayer::setVideoSize( unsigned width, unsigned height ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + mPlayer.setVideoSize( width, height ); +} + +uno::Reference< css::media::XPlayerWindow > SAL_CALL VLCPlayer::createPlayerWindow( const uno::Sequence< uno::Any >& aArguments ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + const intptr_t winID = GetWindowID( aArguments ); + VLCWindow * window; + if ( mPrevWinID == 0 ) + { + mPrevWinID = winID; + window = new VLCWindow( *this, 0 ); + } + else + window = new VLCWindow( *this, mPrevWinID ); + + if ( winID != -1 ) + { + setWindowID( winID ); + } + + return css::uno::Reference< css::media::XPlayerWindow >( window ); +} + +uno::Reference< css::media::XFrameGrabber > SAL_CALL VLCPlayer::createFrameGrabber() +{ + ::osl::MutexGuard aGuard(m_aMutex); + + if ( !mrFrameGrabber.is() ) + { + VLCFrameGrabber *frameGrabber = new VLCFrameGrabber( mEventHandler, mUrl ); + mrFrameGrabber.set( frameGrabber ); + } + + return mrFrameGrabber; +} + +OUString SAL_CALL VLCPlayer::getImplementationName() +{ + return AVMEDIA_VLC_PLAYER_IMPLEMENTATIONNAME; +} + +sal_Bool SAL_CALL VLCPlayer::supportsService( const OUString& serviceName ) +{ + return cppu::supportsService(this, serviceName); +} + +::uno::Sequence< OUString > SAL_CALL VLCPlayer::getSupportedServiceNames() +{ + return { AVMEDIA_VLC_PLAYER_SERVICENAME }; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/avmedia/source/vlc/vlcplayer.hxx b/avmedia/source/vlc/vlcplayer.hxx new file mode 100644 index 000000000..4c3c03d0b --- /dev/null +++ b/avmedia/source/vlc/vlcplayer.hxx @@ -0,0 +1,86 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#pragma once + +#include "vlccommon.hxx" +#include <cppuhelper/compbase.hxx> +#include <com/sun/star/media/XPlayer.hpp> +#include <cppuhelper/basemutex.hxx> + +#include <wrapper/Instance.hxx> +#include <wrapper/Media.hxx> +#include <wrapper/Player.hxx> +#include <wrapper/EventManager.hxx> + +namespace avmedia { +namespace vlc { + +typedef ::cppu::WeakComponentImplHelper< css::media::XPlayer, + css::lang::XServiceInfo > VLC_Base; + +class VLCPlayer : public ::cppu::BaseMutex, + public VLC_Base +{ + wrapper::EventHandler& mEventHandler; + + wrapper::Media mMedia; + wrapper::Player mPlayer; + wrapper::EventManager mEventManager; + const OUString mUrl; + bool mPlaybackLoop; + css::uno::Reference< css::media::XFrameGrabber > mrFrameGrabber; + intptr_t mPrevWinID; +public: + VLCPlayer( const OUString& url, + wrapper::Instance& instance, + wrapper::EventHandler& eh ); + + void setVideoSize( unsigned width, unsigned height ); + + void setWindowID( const intptr_t windowID ); + + void SAL_CALL start() override; + void SAL_CALL stop() override; + sal_Bool SAL_CALL isPlaying() override; + double SAL_CALL getDuration() override; + void SAL_CALL setMediaTime( double fTime ) override; + double SAL_CALL getMediaTime() override; + void SAL_CALL setPlaybackLoop( sal_Bool bSet ) override; + sal_Bool SAL_CALL isPlaybackLoop() override; + void SAL_CALL setVolumeDB( ::sal_Int16 nDB ) override; + ::sal_Int16 SAL_CALL getVolumeDB() override; + void SAL_CALL setMute( sal_Bool bSet ) override; + sal_Bool SAL_CALL isMute() override; + css::awt::Size SAL_CALL getPreferredPlayerWindowSize() override; + css::uno::Reference< css::media::XPlayerWindow > SAL_CALL createPlayerWindow( const css::uno::Sequence< css::uno::Any >& aArguments ) override; + css::uno::Reference< css::media::XFrameGrabber > SAL_CALL createFrameGrabber() override; + + OUString SAL_CALL getImplementationName() override; + sal_Bool SAL_CALL supportsService( const OUString& serviceName ) override; + css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override; + +private: + void replay(); +}; + +} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/avmedia/source/vlc/vlcuno.cxx b/avmedia/source/vlc/vlcuno.cxx new file mode 100644 index 000000000..dba992eb9 --- /dev/null +++ b/avmedia/source/vlc/vlcuno.cxx @@ -0,0 +1,76 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <sal/config.h> + +#include <com/sun/star/lang/XSingleServiceFactory.hpp> +#include <comphelper/processfactory.hxx> +#include <officecfg/Office/Common.hxx> +#include <sal/log.hxx> + +#include "vlccommon.hxx" +#include "vlcmanager.hxx" + +using namespace ::com::sun::star; + +#define IMPL_NAME "com.sun.star.comp.media.Manager_VLC" +#define SERVICE_NAME "com.sun.star.comp.avmedia.Manager_VLC" + +static uno::Reference< uno::XInterface > create_MediaPlayer( const uno::Reference< lang::XMultiServiceFactory >& /*rxFact*/ ) +{ + SAL_INFO("avmedia", "create VLC Media player !"); + + // Experimental for now - code is neither elegant nor well tested. + uno::Reference< uno::XComponentContext > xContext = comphelper::getProcessComponentContext(); + if (!xContext.is() || !officecfg::Office::Common::Misc::ExperimentalMode::get(xContext)) + return nullptr; + + static uno::Reference< uno::XInterface > manager( *new ::avmedia::vlc::Manager ); + return manager; +} + +extern "C" SAL_DLLPUBLIC_EXPORT void* avmediavlc_component_getFactory( const char* pImplName, void* pServiceManager, void* /*pRegistryKey*/ ) +{ + uno::Reference< lang::XSingleServiceFactory > xFactory; + void* pRet = nullptr; + + // Experimental for now - code is neither elegant nor well tested. + uno::Reference< uno::XComponentContext > xContext = comphelper::getProcessComponentContext(); + if (!xContext.is() || !officecfg::Office::Common::Misc::ExperimentalMode::get(xContext)) + return nullptr; + + SAL_INFO("avmedia", "Create VLC Media component: " << pImplName); + if( rtl_str_compare( pImplName, IMPL_NAME ) == 0 ) + { + const OUString aServiceName( SERVICE_NAME ); + xFactory.set( ::cppu::createSingleFactory( + static_cast< lang::XMultiServiceFactory* >( pServiceManager ), + IMPL_NAME, create_MediaPlayer, uno::Sequence< OUString >( &aServiceName, 1 ) ) ); + } + + if( xFactory.is() ) + { + xFactory->acquire(); + pRet = xFactory.get(); + } + + return pRet; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/avmedia/source/vlc/vlcwindow.cxx b/avmedia/source/vlc/vlcwindow.cxx new file mode 100644 index 000000000..1cd0e1306 --- /dev/null +++ b/avmedia/source/vlc/vlcwindow.cxx @@ -0,0 +1,197 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <iostream> +#include <cppuhelper/supportsservice.hxx> +#include "vlcwindow.hxx" +#include "vlcplayer.hxx" + +using namespace ::com::sun::star; + +namespace avmedia::vlc { + +namespace +{ + const OUString AVMEDIA_VLC_WINDOW_IMPLEMENTATIONNAME = "com.sun.star.comp.avmedia.Window_VLC"; + const OUString AVMEDIA_VLC_WINDOW_SERVICENAME = "com.sun.star.media.Window_VLC"; +} + +VLCWindow::VLCWindow( VLCPlayer& player, const intptr_t prevWinID ) + : mPlayer( player ) + , mPrevWinID( prevWinID ) + , meZoomLevel( media::ZoomLevel_ORIGINAL ) +{ +} + +VLCWindow::~VLCWindow() +{ + if ( mPrevWinID != 0 ) + mPlayer.setWindowID( mPrevWinID ); +} + +void SAL_CALL VLCWindow::update() +{ +} + +sal_Bool SAL_CALL VLCWindow::setZoomLevel( css::media::ZoomLevel eZoomLevel ) +{ + bool bRet = false; + + if( media::ZoomLevel_NOT_AVAILABLE != meZoomLevel && + media::ZoomLevel_NOT_AVAILABLE != eZoomLevel ) + { + if( eZoomLevel != meZoomLevel ) + { + meZoomLevel = eZoomLevel; + } + + switch ( eZoomLevel ) + { + case media::ZoomLevel_ORIGINAL: + case media::ZoomLevel_FIT_TO_WINDOW_FIXED_ASPECT: + mPlayer.setVideoSize( mSize.Width, mSize.Height ); + break; + case media::ZoomLevel_ZOOM_1_TO_2: + mPlayer.setVideoSize( mSize.Width / 2, mSize.Height / 2 ); + break; + case media::ZoomLevel_ZOOM_2_TO_1: + mPlayer.setVideoSize( mSize.Width * 2, mSize.Height * 2 ); + break; + default: + break; + } + + bRet = true; + } + + return bRet; +} + +css::media::ZoomLevel SAL_CALL VLCWindow::getZoomLevel() +{ + return meZoomLevel; +} + +void SAL_CALL VLCWindow::setPointerType( ::sal_Int32 ) +{ +} + +OUString SAL_CALL VLCWindow::getImplementationName() +{ + return AVMEDIA_VLC_WINDOW_IMPLEMENTATIONNAME; +} + +sal_Bool SAL_CALL VLCWindow::supportsService( const OUString& serviceName ) +{ + return cppu::supportsService(this, serviceName); +} + +uno::Sequence< OUString > SAL_CALL VLCWindow::getSupportedServiceNames() +{ + return { AVMEDIA_VLC_WINDOW_SERVICENAME }; +} + +void SAL_CALL VLCWindow::dispose() +{ +} + +void SAL_CALL VLCWindow::addEventListener( const uno::Reference< lang::XEventListener >& ) +{ +} + +void SAL_CALL VLCWindow::removeEventListener( const uno::Reference< lang::XEventListener >& ) +{ +} + +void SAL_CALL VLCWindow::setPosSize( sal_Int32 X, sal_Int32 Y, sal_Int32 Width, sal_Int32 Height, sal_Int16 /* Flags */ ) +{ + mSize.X = X; + mSize.Y = Y; + mSize.Width = Width; + mSize.Height = Height; +} + +awt::Rectangle SAL_CALL VLCWindow::getPosSize() +{ + return mSize; +} + +void SAL_CALL VLCWindow::setVisible( sal_Bool ) +{ +} + +void SAL_CALL VLCWindow::setEnable( sal_Bool ) +{ +} + +void SAL_CALL VLCWindow::setFocus() +{ +} + +void SAL_CALL VLCWindow::addWindowListener( const uno::Reference< awt::XWindowListener >& ) +{ +} + +void SAL_CALL VLCWindow::removeWindowListener( const uno::Reference< awt::XWindowListener >& ) +{ +} + +void SAL_CALL VLCWindow::addFocusListener( const uno::Reference< awt::XFocusListener >& ) +{ +} + +void SAL_CALL VLCWindow::removeFocusListener( const uno::Reference< awt::XFocusListener >& ) +{ +} + +void SAL_CALL VLCWindow::addKeyListener( const uno::Reference< awt::XKeyListener >& ) +{ +} + +void SAL_CALL VLCWindow::removeKeyListener( const uno::Reference< awt::XKeyListener >& ) +{ +} + +void SAL_CALL VLCWindow::addMouseListener( const uno::Reference< awt::XMouseListener >& ) +{ +} + +void SAL_CALL VLCWindow::removeMouseListener( const uno::Reference< awt::XMouseListener >& ) +{ +} + +void SAL_CALL VLCWindow::addMouseMotionListener( const uno::Reference< awt::XMouseMotionListener >& ) +{ +} + +void SAL_CALL VLCWindow::removeMouseMotionListener( const uno::Reference< awt::XMouseMotionListener >& ) +{ +} + +void SAL_CALL VLCWindow::addPaintListener( const uno::Reference< awt::XPaintListener >& ) +{ +} + +void SAL_CALL VLCWindow::removePaintListener( const uno::Reference< awt::XPaintListener >& ) +{ +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/avmedia/source/vlc/vlcwindow.hxx b/avmedia/source/vlc/vlcwindow.hxx new file mode 100644 index 000000000..e70c8e80f --- /dev/null +++ b/avmedia/source/vlc/vlcwindow.hxx @@ -0,0 +1,74 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#pragma once + +#include "vlccommon.hxx" +#include <cppuhelper/implbase.hxx> + +namespace avmedia { +namespace vlc { +class VLCPlayer; + +class VLCWindow : public ::cppu::WeakImplHelper< css::media::XPlayerWindow, + css::lang::XServiceInfo > +{ + VLCPlayer& mPlayer; + const intptr_t mPrevWinID; + css::media::ZoomLevel meZoomLevel; + css::awt::Rectangle mSize; +public: + VLCWindow( VLCPlayer& player, const intptr_t prevWinID ); + virtual ~VLCWindow() override; + + void SAL_CALL update() override; + sal_Bool SAL_CALL setZoomLevel( css::media::ZoomLevel ZoomLevel ) override; + css::media::ZoomLevel SAL_CALL getZoomLevel() override; + void SAL_CALL setPointerType( ::sal_Int32 SystemPointerType ) override; + + OUString SAL_CALL getImplementationName() override; + sal_Bool SAL_CALL supportsService( const OUString& serviceName ) override; + css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override; + + void SAL_CALL dispose() override; + void SAL_CALL addEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener ) override; + void SAL_CALL removeEventListener( const css::uno::Reference< css::lang::XEventListener >& aListener ) override; + + void SAL_CALL setPosSize( sal_Int32 X, sal_Int32 Y, sal_Int32 Width, sal_Int32 Height, sal_Int16 Flags ) override; + css::awt::Rectangle SAL_CALL getPosSize() override; + void SAL_CALL setVisible( sal_Bool Visible ) override; + void SAL_CALL setEnable( sal_Bool Enable ) override; + void SAL_CALL setFocus() override; + void SAL_CALL addWindowListener( const css::uno::Reference< css::awt::XWindowListener >& xListener ) override; + void SAL_CALL removeWindowListener( const css::uno::Reference< css::awt::XWindowListener >& xListener ) override; + void SAL_CALL addFocusListener( const css::uno::Reference< css::awt::XFocusListener >& xListener ) override; + void SAL_CALL removeFocusListener( const css::uno::Reference< css::awt::XFocusListener >& xListener ) override; + void SAL_CALL addKeyListener( const css::uno::Reference< css::awt::XKeyListener >& xListener ) override; + void SAL_CALL removeKeyListener( const css::uno::Reference< css::awt::XKeyListener >& xListener ) override; + void SAL_CALL addMouseListener( const css::uno::Reference< css::awt::XMouseListener >& xListener ) override; + void SAL_CALL removeMouseListener( const css::uno::Reference< css::awt::XMouseListener >& xListener ) override; + void SAL_CALL addMouseMotionListener( const css::uno::Reference< css::awt::XMouseMotionListener >& xListener ) override; + void SAL_CALL removeMouseMotionListener( const css::uno::Reference< css::awt::XMouseMotionListener >& xListener ) override; + void SAL_CALL addPaintListener( const css::uno::Reference< css::awt::XPaintListener >& xListener ) override; + void SAL_CALL removePaintListener( const css::uno::Reference< css::awt::XPaintListener >& xListener ) override; +}; + +} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/avmedia/source/vlc/wrapper/Common.cxx b/avmedia/source/vlc/wrapper/Common.cxx new file mode 100644 index 000000000..4ee3a2977 --- /dev/null +++ b/avmedia/source/vlc/wrapper/Common.cxx @@ -0,0 +1,45 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +#include <wrapper/Common.hxx> +#include "SymbolLoader.hxx" + +namespace +{ + const char AVMEDIA_NO_ERROR[] = "No error"; + + const char* ( *libvlc_get_version ) (); + char * ( * libvlc_errmsg ) (); +} + +namespace avmedia::vlc::wrapper +{ +bool Common::LoadSymbols() +{ + static ApiMap const VLC_COMMON_API[] = + { + SYM_MAP( libvlc_get_version ), + SYM_MAP( libvlc_errmsg ) + }; + + return InitApiMap( VLC_COMMON_API ); +} + +const char* Common::Version() +{ + return libvlc_get_version(); +} + +const char* Common::LastErrorMessage() +{ + const char *errorMsg = libvlc_errmsg(); + return errorMsg == nullptr ? AVMEDIA_NO_ERROR : errorMsg; +} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/avmedia/source/vlc/wrapper/EventHandler.cxx b/avmedia/source/vlc/wrapper/EventHandler.cxx new file mode 100644 index 000000000..a2a0db16e --- /dev/null +++ b/avmedia/source/vlc/wrapper/EventHandler.cxx @@ -0,0 +1,42 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <wrapper/EventHandler.hxx> + +namespace avmedia::vlc::wrapper +{ +EventHandler::EventHandler() + : ::osl::Thread() +{ +} + +void EventHandler::stop() +{ + mCallbackQueue.push(TCallback()); + join(); +} + +void EventHandler::run() +{ + osl_setThreadName("VLC EventHandler"); + + TCallback callback; + do + { + mCallbackQueue.pop( callback ); + + if ( !callback ) + return; + + callback(); + } while ( true ); +} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/avmedia/source/vlc/wrapper/EventManager.cxx b/avmedia/source/vlc/wrapper/EventManager.cxx new file mode 100644 index 000000000..27e56603e --- /dev/null +++ b/avmedia/source/vlc/wrapper/EventManager.cxx @@ -0,0 +1,84 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <wrapper/EventManager.hxx> +#include "SymbolLoader.hxx" +#include <wrapper/EventHandler.hxx> +#include "Types.hxx" + +namespace +{ + libvlc_event_manager_t* ( *libvlc_media_player_event_manager ) ( libvlc_media_player_t *p_mi ); + int ( *libvlc_event_attach ) ( libvlc_event_manager_t *p_event_manager, + libvlc_event_type_t i_event_type, + libvlc_callback_t f_callback, + void *user_data ); + void ( *libvlc_event_detach ) ( libvlc_event_manager_t *p_event_manager, + libvlc_event_type_t i_event_type, + libvlc_callback_t f_callback, + void *p_user_data ); +} + +namespace avmedia::vlc::wrapper +{ +void EventManager::Handler( const libvlc_event_t *event, void *pData ) +{ + EventManager *instance = static_cast<EventManager*>( pData ); + switch ( event->type ) + { + case libvlc_MediaPlayerPaused: + instance->mEventHandler.mCallbackQueue.push( instance->mOnPaused ); + break; + case libvlc_MediaPlayerEndReached: + instance->mEventHandler.mCallbackQueue.push( instance->mOnEndReached ); + break; + } +} + +bool EventManager::LoadSymbols() +{ + static ApiMap const VLC_EVENT_MANAGER_API[] = + { + SYM_MAP( libvlc_media_player_event_manager ), + SYM_MAP( libvlc_event_attach ), + SYM_MAP( libvlc_event_detach ) + }; + + return InitApiMap( VLC_EVENT_MANAGER_API ); +} + +EventManager::EventManager( Player& player, EventHandler& eh ) + : mEventHandler( eh ) + , mManager( libvlc_media_player_event_manager( player ) ) +{ + +} + +void EventManager::registerSignal( int signal, const Callback& callback ) +{ + if ( !callback ) + libvlc_event_detach( mManager, signal, Handler, this ); + else + libvlc_event_attach( mManager, signal, Handler, this ); +} + +void EventManager::onPaused( const EventManager::Callback& callback ) +{ + mOnPaused = callback; + registerSignal( libvlc_MediaPlayerPaused, callback ); +} + +void EventManager::onEndReached( const Callback& callback ) +{ + mOnEndReached = callback; + registerSignal( libvlc_MediaPlayerEndReached, callback ); +} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/avmedia/source/vlc/wrapper/Instance.cxx b/avmedia/source/vlc/wrapper/Instance.cxx new file mode 100644 index 000000000..1226cb7ea --- /dev/null +++ b/avmedia/source/vlc/wrapper/Instance.cxx @@ -0,0 +1,62 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <wrapper/Instance.hxx> +#include "SymbolLoader.hxx" + +namespace +{ + libvlc_instance_t* ( *libvlc_new ) ( int argc, const char * const *argv ); + void ( *libvlc_release ) ( libvlc_instance_t *p_instance ); + void ( *libvlc_retain ) ( libvlc_instance_t *p_instance ); +} + +namespace avmedia::vlc::wrapper +{ + bool Instance::LoadSymbols() + { + static ApiMap const VLC_INSTANCE_API[] = + { + SYM_MAP( libvlc_new ), + SYM_MAP( libvlc_release ), + SYM_MAP( libvlc_retain ) + }; + + return InitApiMap( VLC_INSTANCE_API ); + } + + Instance::Instance( int argc, const char * const argv[] ) + : mInstance( libvlc_new( argc, argv ) ) + { + if ( mInstance == nullptr) + { + //TODO: error + } + } + + Instance::Instance( const Instance& other ) + { + operator=( other ); + } + + Instance& Instance::operator=( const Instance& other ) + { + libvlc_release( mInstance ); + mInstance = other.mInstance; + libvlc_retain( mInstance ); + return *this; + } + + Instance::~Instance() + { + libvlc_release( mInstance ); + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/avmedia/source/vlc/wrapper/Media.cxx b/avmedia/source/vlc/wrapper/Media.cxx new file mode 100644 index 000000000..f09aecd76 --- /dev/null +++ b/avmedia/source/vlc/wrapper/Media.cxx @@ -0,0 +1,109 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <rtl/ustring.h> +#include <wrapper/Media.hxx> +#include "SymbolLoader.hxx" +#include <wrapper/Instance.hxx> +#include "Types.hxx" +#include <wrapper/Common.hxx> +#include <sal/log.hxx> + +struct libvlc_instance_t; + +namespace avmedia::vlc::wrapper +{ +namespace +{ + libvlc_media_t* ( *libvlc_media_new_path ) ( libvlc_instance_t *p_instance, const char *path ); + libvlc_media_t* ( *libvlc_media_new_location ) (libvlc_instance_t *p_instance, const char *psz_mrl); + void ( *libvlc_media_release ) ( libvlc_media_t *p_md ); + void ( *libvlc_media_retain ) ( libvlc_media_t *p_md ); + libvlc_time_t ( *libvlc_media_get_duration ) ( libvlc_media_t *p_md ); + void ( *libvlc_media_parse ) ( libvlc_media_t *p_md ); + int ( *libvlc_media_is_parsed ) ( libvlc_media_t *p_md ); + char* ( *libvlc_media_get_mrl )(libvlc_media_t *p_md); + + + libvlc_media_t* InitMedia( const OUString& url, Instance& instance ) + { + OString dest; + url.convertToString(&dest, RTL_TEXTENCODING_UTF8, 0); + + return libvlc_media_new_location(instance, dest.getStr()); + } +} + +bool Media::LoadSymbols() +{ + static ApiMap const VLC_MEDIA_API[] = + { + SYM_MAP( libvlc_media_new_path ), + SYM_MAP( libvlc_media_release ), + SYM_MAP( libvlc_media_retain ), + SYM_MAP( libvlc_media_get_duration ), + SYM_MAP( libvlc_media_parse ), + SYM_MAP( libvlc_media_is_parsed ), + SYM_MAP( libvlc_media_get_mrl ), + SYM_MAP( libvlc_media_new_location ) + }; + + return InitApiMap( VLC_MEDIA_API ); +} + +Media::Media( const OUString& url, Instance& instance ) + : mMedia( InitMedia( url, instance ) ) +{ + if (mMedia == nullptr) + { + // TODO: Error + } +} + +Media::Media( const Media& other ) +{ + operator=( other ); +} + +Media& Media::operator=( const Media& other ) +{ + libvlc_media_release( mMedia ); + mMedia = other.mMedia; + + libvlc_media_retain( mMedia ); + return *this; +} + +int Media::getDuration() const +{ + if ( !libvlc_media_is_parsed( mMedia ) ) + libvlc_media_parse( mMedia ); + + const int duration = libvlc_media_get_duration( mMedia ); + if (duration == -1) + { + SAL_WARN("avmedia", Common::LastErrorMessage()); + return 0; + } + else if (duration == 0) + { + // A duration must be greater than 0 + return 1; + } + + return duration; +} + +Media::~Media() +{ + libvlc_media_release( mMedia ); +} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/avmedia/source/vlc/wrapper/Player.cxx b/avmedia/source/vlc/wrapper/Player.cxx new file mode 100644 index 000000000..27e63a21a --- /dev/null +++ b/avmedia/source/vlc/wrapper/Player.cxx @@ -0,0 +1,241 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <rtl/ustring.h> +#include "Types.hxx" +#include <wrapper/Player.hxx> +#include <wrapper/Media.hxx> +#include "SymbolLoader.hxx" +#include <wrapper/Common.hxx> + +struct libvlc_media_t; + +namespace { extern "C" { + void ( *libvlc_media_player_retain ) ( libvlc_media_player_t *p_mi ); + libvlc_media_player_t * ( *libvlc_media_player_new_from_media ) ( libvlc_media_t *p_md ); + void ( *libvlc_media_player_release ) ( libvlc_media_player_t *p_mi ); + int ( *libvlc_media_player_play ) ( libvlc_media_player_t *p_mi ); + void ( *libvlc_media_player_pause ) ( libvlc_media_player_t *p_mi ); + int ( *libvlc_media_player_is_playing ) ( libvlc_media_player_t *p_mi ); + void ( *libvlc_media_player_stop ) ( libvlc_media_player_t *p_mi ); + void ( *libvlc_media_player_set_time ) ( libvlc_media_player_t *p_mi, libvlc_time_t i_time ); + libvlc_time_t ( *libvlc_media_player_get_time ) ( libvlc_media_player_t *p_mi ); + float ( *libvlc_media_player_get_rate )( libvlc_media_player_t *p_mi ); + int ( *libvlc_audio_set_volume ) ( libvlc_media_player_t *p_mi, int i_volume ); + int ( *libvlc_audio_get_volume ) ( libvlc_media_player_t *p_mi ); + int ( *libvlc_audio_get_mute ) ( libvlc_media_player_t *p_mi ); + void ( *libvlc_audio_set_mute ) ( libvlc_media_player_t *p_mi, int status ); + int ( *libvlc_video_take_snapshot ) ( libvlc_media_player_t *p_mi, + unsigned num, + const char *psz_filepath, + unsigned int i_width, + unsigned int i_height ); +#if defined MACOSX + void ( *libvlc_media_player_set_nsobject ) ( libvlc_media_player_t *p_mi, void *drawable ); +#elif defined UNX + void ( *libvlc_media_player_set_xwindow ) ( libvlc_media_player_t *p_mi, uint32_t drawable ); +#elif defined _WIN32 + void ( *libvlc_media_player_set_hwnd ) ( libvlc_media_player_t *p_mi, void *drawable ); +#else +#error unknown OS +#endif + unsigned ( *libvlc_media_player_has_vout ) ( libvlc_media_player_t *p_mi ); + void ( *libvlc_video_set_mouse_input ) ( libvlc_media_player_t *p_mi, unsigned on ); + void ( *libvlc_video_set_scale ) ( libvlc_media_player_t *p_mi, float f_factor ); + int ( *libvlc_video_get_size ) ( libvlc_media_player_t *p_mi, unsigned num, + unsigned *px, unsigned *py ); + int ( *libvlc_video_get_track_count ) ( libvlc_media_player_t *p_mi ); + int ( *libvlc_video_set_track ) ( libvlc_media_player_t *p_mi, int i_track ); + libvlc_track_description_t* ( *libvlc_video_get_track_description ) ( libvlc_media_player_t *p_mi ); + + int ( *libvlc_audio_get_track ) ( libvlc_media_player_t *p_mi ); + libvlc_track_description_t * ( *libvlc_audio_get_track_description ) (libvlc_media_player_t *p_mi ); + int ( *libvlc_audio_set_track ) (libvlc_media_player_t *p_mi, int i_track); +} } + +namespace avmedia::vlc::wrapper +{ + bool Player::LoadSymbols() + { + static ApiMap const VLC_PLAYER_API[] = + { + SYM_MAP( libvlc_media_player_new_from_media ), + SYM_MAP( libvlc_media_player_release ), + SYM_MAP( libvlc_media_player_play ), + SYM_MAP( libvlc_media_player_pause ), + SYM_MAP( libvlc_media_player_is_playing ), + SYM_MAP( libvlc_media_player_stop ), + SYM_MAP( libvlc_media_player_set_time ), + SYM_MAP( libvlc_media_player_get_time ), + SYM_MAP( libvlc_media_player_get_rate ), + SYM_MAP( libvlc_audio_set_volume ), + SYM_MAP( libvlc_audio_get_volume ), + SYM_MAP( libvlc_audio_set_mute ), + SYM_MAP( libvlc_audio_get_mute ), + SYM_MAP( libvlc_video_take_snapshot ), +#if defined MACOSX + SYM_MAP( libvlc_media_player_set_nsobject ), +#elif defined UNX + SYM_MAP( libvlc_media_player_set_xwindow ), +#elif defined _WIN32 + SYM_MAP( libvlc_media_player_set_hwnd ), +#endif + SYM_MAP( libvlc_media_player_has_vout ), + SYM_MAP( libvlc_video_set_mouse_input ), + SYM_MAP( libvlc_media_player_retain ), + SYM_MAP( libvlc_video_set_scale ), + SYM_MAP( libvlc_video_get_size ), + SYM_MAP( libvlc_video_get_track_count ), + SYM_MAP( libvlc_video_set_track ), + SYM_MAP( libvlc_video_get_track_description ), + SYM_MAP( libvlc_audio_get_track ), + SYM_MAP( libvlc_audio_get_track_description ), + SYM_MAP( libvlc_audio_set_track ) + }; + + return InitApiMap( VLC_PLAYER_API ); + } + + Player::Player( Media& media ) + : mPlayer( libvlc_media_player_new_from_media( media ) ) + { + } + + Player::Player( const Player& other ) + { + operator=( other ); + } + + Player& Player::operator=( const Player& other ) + { + libvlc_media_player_release( mPlayer ); + mPlayer = other.mPlayer; + libvlc_media_player_retain( mPlayer ); + return *this; + } + + Player::~Player() + { + libvlc_media_player_release( mPlayer ); + } + + bool Player::play() + { + const bool status = ( libvlc_media_player_play( mPlayer ) == 0 ); + if ( libvlc_video_get_track_count( mPlayer ) > 0 ) + { + const libvlc_track_description_t *description = libvlc_video_get_track_description( mPlayer ); + + for ( ; description->p_next != nullptr; description = description->p_next ); + + libvlc_video_set_track( mPlayer, description->i_id ); + } + + if ( libvlc_audio_get_track( mPlayer ) > 0 ) + { + const libvlc_track_description_t *description = libvlc_audio_get_track_description( mPlayer ); + + for ( ; description->p_next != nullptr; description = description->p_next ); + + libvlc_audio_set_track( mPlayer, description->i_id ); + } + + return status; + } + + void Player::pause() + { + libvlc_media_player_pause( mPlayer ); + } + + void Player::stop() + { + libvlc_media_player_stop( mPlayer ); + } + + void Player::setTime( int time ) + { + libvlc_media_player_set_time( mPlayer, time ); + } + + int Player::getTime() const + { + const int time = libvlc_media_player_get_time( mPlayer ); + + return ( time == -1 ? 0 : time ); + } + + void Player::setScale( float factor ) + { + libvlc_video_set_scale( mPlayer, factor ); + } + + void Player::setMouseHandling(bool flag) + { + libvlc_video_set_mouse_input( mPlayer, flag ); + } + + bool Player::isPlaying() const + { + return libvlc_media_player_is_playing( mPlayer ) == 1; + } + + void Player::setVolume( int volume ) + { + libvlc_audio_set_volume( mPlayer, volume ); + } + + int Player::getVolume() const + { + return libvlc_audio_get_volume( mPlayer ); + } + + void Player::setMute( bool mute) + { + libvlc_audio_set_mute( mPlayer, mute ); + } + + bool Player::getMute() const + { + return libvlc_audio_get_mute( mPlayer ); + } + + void Player::setVideoSize( unsigned width, unsigned ) + { + unsigned currentWidth, currentHeight; + libvlc_video_get_size( mPlayer, 0, ¤tWidth, ¤tHeight ); + if ( currentWidth != 0 ) + setScale( static_cast<float>( width ) / currentWidth ); + } + + void Player::setWindow( intptr_t id ) + { +#if defined MACOSX + libvlc_media_player_set_nsobject( mPlayer, reinterpret_cast<void*>( id ) ); +#elif defined UNX + libvlc_media_player_set_xwindow( mPlayer, static_cast<uint32_t>(id) ); +#elif defined _WIN32 + libvlc_media_player_set_hwnd( mPlayer, reinterpret_cast<void*>( id ) ); +#endif + } + + void Player::takeSnapshot( const OUString& file ) + { + OString dest; + file.convertToString( &dest, RTL_TEXTENCODING_UTF8, 0 ); + libvlc_video_take_snapshot( mPlayer, 0, dest.getStr(), 480, 360 ); + } + + bool Player::hasVout() const + { + return libvlc_media_player_has_vout( mPlayer ); + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/avmedia/source/vlc/wrapper/SymbolLoader.hxx b/avmedia/source/vlc/wrapper/SymbolLoader.hxx new file mode 100644 index 000000000..64789b326 --- /dev/null +++ b/avmedia/source/vlc/wrapper/SymbolLoader.hxx @@ -0,0 +1,126 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once +#if defined(_WIN32) +#if !defined WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +#endif +# include <windows.h> +# include <winreg.h> +#endif +#include <osl/module.h> +#include <rtl/ustring.hxx> +#include <sal/log.hxx> + +#define SYM_MAP(a) { #a, reinterpret_cast<SymbolFunc *>(&a) } + +namespace avmedia +{ +namespace vlc +{ +namespace wrapper +{ +typedef void (*SymbolFunc) (void); + +struct ApiMap +{ + OUStringLiteral symName; + SymbolFunc *refValue; +}; + +#if defined( LINUX ) + const char LibName[] = "libvlc.so.5"; +#elif defined( MACOSX ) + const char LibName[] = "/Applications/VLC.app/Contents/MacOS/lib/libvlc.dylib"; +#elif defined( _WIN32 ) + const char LibName[] = "libvlc.dll"; + + inline OUString GetVLCPath() + { + HKEY hKey; + sal_Unicode arCurrent[MAX_PATH]; + DWORD dwType, dwCurrentSize = sizeof( arCurrent ); + + //TODO: This one will work only with LibreOffice 32-bit + VLC 32-bit on Win x86_64. + const LONG errorCore = ::RegOpenKeyExW( HKEY_LOCAL_MACHINE, L"SOFTWARE\\Wow6432Node\\VideoLAN\\VLC", 0, KEY_READ | KEY_WOW64_64KEY, &hKey ); + if ( errorCore == ERROR_SUCCESS ) + { + if ( ::RegQueryValueExW( hKey, L"InstallDir", nullptr, &dwType, reinterpret_cast<LPBYTE>(arCurrent), &dwCurrentSize ) == ERROR_SUCCESS && + dwType == REG_SZ ) + { + ::RegCloseKey( hKey ); + dwCurrentSize -= 2; + dwCurrentSize /= 2; + + return OUString( arCurrent, dwCurrentSize ) + "\\"; + } + + ::RegCloseKey( hKey ); + } + + return OUString(); + } +#endif + + template<size_t N> + bool tryLink( oslModule &aModule, const ApiMap ( &pMap )[N] ) + { + for (size_t i = 0; i < N; ++i) + { + SymbolFunc aMethod = reinterpret_cast<SymbolFunc>(osl_getFunctionSymbol + ( aModule, OUString( pMap[ i ].symName ).pData )); + if ( !aMethod ) + { + SAL_WARN("avmedia", "Cannot load method " << pMap[ i ].symName); + *pMap[ i ].refValue = nullptr; + return false; + } + else + *pMap[ i ].refValue = aMethod; + } + + return true; + } + + template<size_t N> + bool InitApiMap( const ApiMap ( &pMap )[N] ) + { +#if defined( LINUX ) || defined( MACOSX ) + OUString const fullPath(LibName); +#elif defined( _WIN32 ) + OUString const fullPath(GetVLCPath() + LibName); +#endif + SAL_INFO("avmedia", fullPath); + + oslModule aModule = osl_loadModule( fullPath.pData, + SAL_LOADMODULE_DEFAULT ); + + + if( aModule == nullptr) + { + SAL_WARN("avmedia", "Cannot load libvlc"); + return false; + } + + if (tryLink( aModule, pMap )) + { + return true; + } + + SAL_WARN("avmedia", "Cannot load libvlc"); + osl_unloadModule( aModule ); + + return false; + } +} +} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/avmedia/source/vlc/wrapper/Types.hxx b/avmedia/source/vlc/wrapper/Types.hxx new file mode 100644 index 000000000..c66a88bdc --- /dev/null +++ b/avmedia/source/vlc/wrapper/Types.hxx @@ -0,0 +1,58 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +/* Typedefs and structures that represent the libvlc API / ABI */ + +#pragma once + +#include <sal/config.h> + +#if defined(_WIN32) + typedef __int64 libvlc_time_t; +#else +#include <stdint.h> + typedef int64_t libvlc_time_t; +#endif + +extern "C" { + +// basic callback / event types we use +typedef int libvlc_event_type_t; +typedef struct libvlc_event_manager_t libvlc_event_manager_t; +typedef void ( *libvlc_callback_t ) ( const struct libvlc_event_t *, void * ); + +// the enumeration values we use cf. libvlc_events.h +#define libvlc_MediaPlayerPaused 0x105 +#define libvlc_MediaPlayerEndReached 0x109 + +// event structure pieces we use +struct libvlc_event_t +{ + int type; // event type + void *p_obj; // object emitting that event + + union // so far we don't need this. + { + struct { + const char *dummy1; + const char *dummy2; + } padding; + } u; +}; + +struct libvlc_track_description_t +{ + int i_id; + char *psz_name; + libvlc_track_description_t *p_next; +}; + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |