summaryrefslogtreecommitdiffstats
path: root/avmedia/source/vlc
diff options
context:
space:
mode:
Diffstat (limited to 'avmedia/source/vlc')
-rw-r--r--avmedia/source/vlc/avmediavlc.component15
-rw-r--r--avmedia/source/vlc/inc/wrapper/Common.hxx29
-rw-r--r--avmedia/source/vlc/inc/wrapper/EventHandler.hxx42
-rw-r--r--avmedia/source/vlc/inc/wrapper/EventManager.hxx55
-rw-r--r--avmedia/source/vlc/inc/wrapper/Instance.hxx41
-rw-r--r--avmedia/source/vlc/inc/wrapper/Media.hxx47
-rw-r--r--avmedia/source/vlc/inc/wrapper/Player.hxx73
-rw-r--r--avmedia/source/vlc/inc/wrapper/ThreadsafeQueue.hxx81
-rw-r--r--avmedia/source/vlc/inc/wrapper/Wrapper.hxx19
-rw-r--r--avmedia/source/vlc/vlccommon.hxx40
-rw-r--r--avmedia/source/vlc/vlcframegrabber.cxx131
-rw-r--r--avmedia/source/vlc/vlcframegrabber.hxx52
-rw-r--r--avmedia/source/vlc/vlcmanager.cxx124
-rw-r--r--avmedia/source/vlc/vlcmanager.hxx54
-rw-r--r--avmedia/source/vlc/vlcplayer.cxx251
-rw-r--r--avmedia/source/vlc/vlcplayer.hxx86
-rw-r--r--avmedia/source/vlc/vlcuno.cxx76
-rw-r--r--avmedia/source/vlc/vlcwindow.cxx197
-rw-r--r--avmedia/source/vlc/vlcwindow.hxx74
-rw-r--r--avmedia/source/vlc/wrapper/Common.cxx45
-rw-r--r--avmedia/source/vlc/wrapper/EventHandler.cxx42
-rw-r--r--avmedia/source/vlc/wrapper/EventManager.cxx84
-rw-r--r--avmedia/source/vlc/wrapper/Instance.cxx62
-rw-r--r--avmedia/source/vlc/wrapper/Media.cxx109
-rw-r--r--avmedia/source/vlc/wrapper/Player.cxx241
-rw-r--r--avmedia/source/vlc/wrapper/SymbolLoader.hxx126
-rw-r--r--avmedia/source/vlc/wrapper/Types.hxx58
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, &currentWidth, &currentHeight );
+ 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: */