а индексировать кто будет долбаеб

This commit is contained in:
Andron666
2022-10-14 19:28:25 +05:00
parent 69a4ff648c
commit eda4d2a097
77 changed files with 11486 additions and 15 deletions
-1
View File
@@ -55,7 +55,6 @@ SourceArt/**/*.tga
# Binary Files
Binaries
Plugins/**/Binaries/*
# Builds
Build/**
+1 -1
View File
@@ -38,5 +38,5 @@ Version=1
+EngineTargetsSettings=(Name="Keywords",Guid=AE89AECB47475F420D0D69A5547515DC,TargetDependencies=(33482D004789784C9DA695A682ACCA1B,AC8BFD2A41A2FB2893BB8EA0AF903E6D),AdditionalManifestDependencies=,RequiredModuleNames=,GatherFromTextFiles=(IsEnabled=False,SearchDirectories=,ExcludePathWildcards=,FileExtensions=((Pattern="h"),(Pattern="cpp"),(Pattern="ini")),ShouldGatherFromEditorOnlyData=False),GatherFromPackages=(IsEnabled=False,IncludePathWildcards=,ExcludePathWildcards=,FileExtensions=((Pattern="umap"),(Pattern="uasset")),Collections=,ExcludeClasses=,ShouldExcludeDerivedClasses=False,ShouldGatherFromEditorOnlyData=True,SkipGatherCache=False),GatherFromMetaData=(IsEnabled=True,IncludePathWildcards=((Pattern="Source/Editor/*"),(Pattern="Source/Runtime/*"),(Pattern="Source/Developer/*")),ExcludePathWildcards=((Pattern="Source/Developer/NoRedist/CommunityPortalServices/*")),KeySpecifications=((MetaDataKey=(Name="Keywords"),TextNamespace="UObjectKeywords",TextKeyPattern=(Pattern="{FieldPath}"))),ShouldGatherFromEditorOnlyData=True),ExportSettings=(CollapseMode=IdenticalTextIdAndSource,ShouldPersistCommentsOnExport=False,ShouldAddSourceLocationsAsComments=True),CompileSettings=(SkipSourceCheck=False,ValidateFormatPatterns=True,ValidateSafeWhitespace=False),ImportDialogueSettings=(RawAudioPath=(Path=""),ImportedDialogueFolder="ImportedDialogue",bImportNativeAsSource=False),NativeCultureIndex=0,SupportedCulturesStatistics=((CultureName="en"),(CultureName="es"),(CultureName="ja"),(CultureName="ko"),(CultureName="pt-BR"),(CultureName="zh-CN")))
+EngineTargetsSettings=(Name="Category",Guid=14B8DEE642A6A7AFEB5A28B959EC373A,TargetDependencies=,AdditionalManifestDependencies=,RequiredModuleNames=,GatherFromTextFiles=(IsEnabled=False,SearchDirectories=,ExcludePathWildcards=,FileExtensions=((Pattern="h"),(Pattern="cpp"),(Pattern="ini")),ShouldGatherFromEditorOnlyData=False),GatherFromPackages=(IsEnabled=False,IncludePathWildcards=,ExcludePathWildcards=,FileExtensions=((Pattern="umap"),(Pattern="uasset")),Collections=,ExcludeClasses=,ShouldExcludeDerivedClasses=False,ShouldGatherFromEditorOnlyData=False,SkipGatherCache=False),GatherFromMetaData=(IsEnabled=True,IncludePathWildcards=((Pattern="Source/Editor/*"),(Pattern="Source/Runtime/*"),(Pattern="Source/Developer/*")),ExcludePathWildcards=((Pattern="Source/Developer/NoRedist/CommunityPortalServices/*")),KeySpecifications=((MetaDataKey=(Name="Category"),TextNamespace="UObjectCategory",TextKeyPattern=(Pattern="{FieldPath}"))),ShouldGatherFromEditorOnlyData=True),ExportSettings=(CollapseMode=IdenticalTextIdAndSource,ShouldPersistCommentsOnExport=False,ShouldAddSourceLocationsAsComments=True),CompileSettings=(SkipSourceCheck=False,ValidateFormatPatterns=True,ValidateSafeWhitespace=False),ImportDialogueSettings=(RawAudioPath=(Path=""),ImportedDialogueFolder="ImportedDialogue",bImportNativeAsSource=False),NativeCultureIndex=0,SupportedCulturesStatistics=((CultureName="en"),(CultureName="es"),(CultureName="ja"),(CultureName="ko"),(CultureName="pt-BR"),(CultureName="zh-CN")))
-GameTargetsSettings=(Name="Game",Guid=AE0EA34A45461A25BA65A391026F19F8,TargetDependencies=(33482D004789784C9DA695A682ACCA1B,AC8BFD2A41A2FB2893BB8EA0AF903E6D),AdditionalManifestDependencies=,RequiredModuleNames=,GatherFromTextFiles=(IsEnabled=False,SearchDirectories=,ExcludePathWildcards=,FileExtensions=((Pattern="h"),(Pattern="cpp"),(Pattern="ini"))),GatherFromPackages=(IsEnabled=False,IncludePathWildcards=,ExcludePathWildcards=,FileExtensions=((Pattern="umap"),(Pattern="uasset")),ShouldGatherFromEditorOnlyData=False),GatherFromMetaData=(IsEnabled=False,IncludePathWildcards=,ExcludePathWildcards=,KeySpecifications=,ShouldGatherFromEditorOnlyData=False),NativeCultureIndex=-1,SupportedCulturesStatistics=((CultureName="en")))
+GameTargetsSettings=(Name="Game",Guid=AE0EA34A45461A25BA65A391026F19F8,TargetDependencies=(33482D004789784C9DA695A682ACCA1B,AC8BFD2A41A2FB2893BB8EA0AF903E6D),AdditionalManifestDependencies=,RequiredModuleNames=,GatherFromTextFiles=(IsEnabled=False,SearchDirectories=,ExcludePathWildcards=,FileExtensions=((Pattern="h"),(Pattern="cpp"),(Pattern="ini")),ShouldGatherFromEditorOnlyData=False),GatherFromPackages=(IsEnabled=True,IncludePathWildcards=((PathRoot=Project,Pattern="*")),ExcludePathWildcards=,FileExtensions=((Pattern="umap"),(Pattern="uasset")),Collections=,ExcludeClasses=,ShouldExcludeDerivedClasses=False,ShouldGatherFromEditorOnlyData=False,SkipGatherCache=False),GatherFromMetaData=(IsEnabled=False,IncludePathWildcards=,ExcludePathWildcards=,KeySpecifications=,ShouldGatherFromEditorOnlyData=False),ExportSettings=(CollapseMode=IdenticalTextIdAndSource,ShouldPersistCommentsOnExport=False,ShouldAddSourceLocationsAsComments=True),CompileSettings=(SkipSourceCheck=False,ValidateFormatPatterns=True,ValidateSafeWhitespace=False),ImportDialogueSettings=(RawAudioPath=(Path=""),ImportedDialogueFolder="ImportedDialogue",bImportNativeAsSource=False),NativeCultureIndex=1,SupportedCulturesStatistics=((CultureName="en"),(CultureName="ar")))
+GameTargetsSettings=(Name="Game",Guid=AE0EA34A45461A25BA65A391026F19F8,TargetDependencies=(33482D004789784C9DA695A682ACCA1B,AC8BFD2A41A2FB2893BB8EA0AF903E6D),AdditionalManifestDependencies=,RequiredModuleNames=,GatherFromTextFiles=(IsEnabled=False,SearchDirectories=,ExcludePathWildcards=,FileExtensions=((Pattern="h"),(Pattern="cpp"),(Pattern="ini")),ShouldGatherFromEditorOnlyData=False),GatherFromPackages=(IsEnabled=True,IncludePathWildcards=((PathRoot=Project,Pattern="Content/*")),ExcludePathWildcards=,FileExtensions=((Pattern="umap"),(Pattern="uasset")),Collections=,ExcludeClasses=,ShouldExcludeDerivedClasses=False,ShouldGatherFromEditorOnlyData=False,SkipGatherCache=False),GatherFromMetaData=(IsEnabled=False,IncludePathWildcards=,ExcludePathWildcards=,KeySpecifications=,ShouldGatherFromEditorOnlyData=False),ExportSettings=(CollapseMode=IdenticalTextIdAndSource,ShouldPersistCommentsOnExport=False,ShouldAddSourceLocationsAsComments=True),CompileSettings=(SkipSourceCheck=False,ValidateFormatPatterns=True,ValidateSafeWhitespace=False),ImportDialogueSettings=(RawAudioPath=(Path=""),ImportedDialogueFolder="ImportedDialogue",bImportNativeAsSource=False),NativeCultureIndex=0,SupportedCulturesStatistics=((CultureName="en"),(CultureName="ar")))
+1 -1
View File
@@ -7,7 +7,7 @@ ResourceName=Game.locres
bSkipSourceCheck=false
bValidateFormatPatterns=true
bValidateSafeWhitespace=false
NativeCulture=ar
NativeCulture=en
CulturesToGenerate=en
CulturesToGenerate=ar
+1 -1
View File
@@ -1,7 +1,7 @@
[CommonSettings]
SourcePath=Content/Localization/Game
DestinationPath=Content/Localization/Game
NativeCulture=ar
NativeCulture=en
CulturesToGenerate=en
CulturesToGenerate=ar
ManifestName=Game.manifest
@@ -1,7 +1,7 @@
[CommonSettings]
SourcePath=Content/Localization/Game
DestinationPath=Content/Localization/Game
NativeCulture=ar
NativeCulture=en
CulturesToGenerate=en
CulturesToGenerate=ar
ManifestName=Game.manifest
+4 -4
View File
@@ -1,17 +1,17 @@
[CommonSettings]
ManifestDependencies=../../UE4/UE_4.25/Engine/Content/Localization/Engine/Engine.manifest
ManifestDependencies=../../UE4/UE_4.25/Engine/Content/Localization/Editor/Editor.manifest
ManifestDependencies=../../Engines/UE_4.25/Engine/Content/Localization/Engine/Engine.manifest
ManifestDependencies=../../Engines/UE_4.25/Engine/Content/Localization/Editor/Editor.manifest
SourcePath=Content/Localization/Game
DestinationPath=Content/Localization/Game
ManifestName=Game.manifest
ArchiveName=Game.archive
NativeCulture=ar
NativeCulture=en
CulturesToGenerate=en
CulturesToGenerate=ar
[GatherTextStep0]
CommandletClass=GatherTextFromAssets
IncludePathFilters=%LOCPROJECTROOT%*
IncludePathFilters=%LOCPROJECTROOT%Content/*
ExcludePathFilters=Content/Localization/*
PackageFileNameFilters=*.umap
PackageFileNameFilters=*.uasset
+1 -1
View File
@@ -1,7 +1,7 @@
[CommonSettings]
SourcePath=Content/Localization/Game
DestinationPath=Content/Localization/Game
NativeCulture=ar
NativeCulture=en
CulturesToGenerate=en
CulturesToGenerate=ar
ManifestName=Game.manifest
+1 -1
View File
@@ -2,7 +2,7 @@
SourcePath=Content/Localization/Game
ManifestName=Game.manifest
ArchiveName=Game.archive
NativeCulture=ar
NativeCulture=en
CulturesToGenerate=en
CulturesToGenerate=ar
@@ -1,7 +1,7 @@
[CommonSettings]
SourcePath=Content/Localization/Game
DestinationPath=Content/Localization/Game
NativeCulture=ar
NativeCulture=en
CulturesToGenerate=en
CulturesToGenerate=ar
ManifestName=Game.manifest
Binary file not shown.
+1 -1
View File
@@ -1 +1 @@
[{"id":1002,"name":"Reception","editable":false,"quickSearch":true},{"id":1003,"name":"Pharmacy","editable":false,"quickSearch":true},{"id":1004,"name":"Common area","editable":false,"quickSearch":true},{"id":1005,"name":"Prayer Room","editable":false,"quickSearch":true},{"id":1006,"name":"Catering","editable":false,"quickSearch":true},{"id":1007,"name":"Shops","editable":false,"quickSearch":true},{"id":1008,"name":"Toilets","editable":false,"quickSearch":true},{"id":1009,"name":"Patient rooms","editable":false,"quickSearch":true},{"id":1010,"name":"Medical rooms","editable":false,"quickSearch":true},{"id":1011,"name":"Staff rooms","editable":false,"quickSearch":true},{"id":1012,"name":"Tech rooms","editable":false,"quickSearch":true},{"id":1013,"name":"Utility rooms","editable":false,"quickSearch":true},{"id":1014,"name":"VIP rooms","editable":false,"quickSearch":true},{"id":1025,"name":"External buildings","editable":false,"quickSearch":true},{"id":100000,"name":"Elev. lobby","editable":false,"quickSearch":true},{"id":100001,"name":"Doctor on call","editable":false,"quickSearch":false},{"id":100002,"name":"Nurse station","editable":false,"quickSearch":false},{"id":100003,"name":"Lab","editable":false,"quickSearch":false},{"id":100004,"name":"Corridor","editable":false,"quickSearch":false},{"id":100005,"name":"Pantry","editable":false,"quickSearch":false},{"id":100006,"name":"Waiting area","editable":false,"quickSearch":true},{"id":100007,"name":"Store","editable":false,"quickSearch":false},{"id":100008,"name":"Anaesthetic room","editable":false,"quickSearch":false},{"id":100009,"name":"Dialysis room","editable":false,"quickSearch":false},{"id":100010,"name":"Treatment room","editable":false,"quickSearch":false},{"id":100011,"name":"Isolation room","editable":false,"quickSearch":false},{"id":100012,"name":"Vip suite","editable":false,"quickSearch":false},{"id":100013,"name":"Lobby","editable":false,"quickSearch":false},{"id":100014,"name":"Dinning area","editable":false,"quickSearch":true},{"id":100015,"name":"MRI room","editable":false,"quickSearch":false},{"id":100016,"name":"Chest pain unit","editable":false,"quickSearch":false},{"id":100017,"name":"Exam room","editable":false,"quickSearch":false},{"id":100018,"name":"Records room","editable":false,"quickSearch":false},{"id":100019,"name":"CT scan room","editable":false,"quickSearch":false},{"id":100020,"name":"Xray room","editable":false,"quickSearch":false},{"id":100021,"name":"Billing office","editable":false,"quickSearch":true},{"id":100022,"name":"Seminar room","editable":false,"quickSearch":false},{"id":100023,"name":"Auditorioum room","editable":false,"quickSearch":true},{"id":100024,"name":"Lecture room","editable":false,"quickSearch":false},{"id":100025,"name":"Warehouse","editable":false,"quickSearch":false},{"id":100026,"name":"Electrical room","editable":false,"quickSearch":false},{"id":100027,"name":"Wheel chair storage room","editable":false,"quickSearch":true},{"id":100028,"name":"Rehab room","editable":false,"quickSearch":false},{"id":100029,"name":"CCTV room","editable":false,"quickSearch":false},{"id":100030,"name":"Bakery","editable":false,"quickSearch":false}]
[{"id":1002,"name":"Reception","editable":false,"quickSearch":true},{"id":1003,"name":"Pharmacy","editable":false,"quickSearch":true},{"id":1004,"name":"Common area","editable":false,"quickSearch":true},{"id":1005,"name":"Prayer Room","editable":false,"quickSearch":true},{"id":1006,"name":"Catering","editable":false,"quickSearch":true},{"id":1007,"name":"Shops","editable":false,"quickSearch":true},{"id":1008,"name":"Toilets","editable":false,"quickSearch":true},{"id":1009,"name":"Patient rooms","editable":false,"quickSearch":true},{"id":1010,"name":"Medical rooms","editable":false,"quickSearch":true},{"id":1011,"name":"Staff rooms","editable":false,"quickSearch":true},{"id":1012,"name":"Tech rooms","editable":false,"quickSearch":true},{"id":1013,"name":"Utility rooms","editable":false,"quickSearch":true},{"id":1014,"name":"VIP rooms","editable":false,"quickSearch":true},{"id":1025,"name":"External buildings","editable":false,"quickSearch":true},{"id":1035,"name":"1234","editable":true,"quickSearch":false},{"id":100000,"name":"Elev. lobby","editable":false,"quickSearch":true},{"id":100001,"name":"Doctor on call","editable":false,"quickSearch":false},{"id":100002,"name":"Nurse station","editable":false,"quickSearch":false},{"id":100003,"name":"Lab","editable":false,"quickSearch":false},{"id":100004,"name":"Corridor","editable":false,"quickSearch":false},{"id":100005,"name":"Pantry","editable":false,"quickSearch":false},{"id":100006,"name":"Waiting area","editable":false,"quickSearch":true},{"id":100007,"name":"Store","editable":false,"quickSearch":false},{"id":100008,"name":"Anaesthetic room","editable":false,"quickSearch":false},{"id":100009,"name":"Dialysis room","editable":false,"quickSearch":false},{"id":100010,"name":"Treatment room","editable":false,"quickSearch":false},{"id":100011,"name":"Isolation room","editable":false,"quickSearch":false},{"id":100012,"name":"Vip suite","editable":false,"quickSearch":false},{"id":100013,"name":"Lobby","editable":false,"quickSearch":false},{"id":100014,"name":"Dinning area","editable":false,"quickSearch":true},{"id":100015,"name":"MRI room","editable":false,"quickSearch":false},{"id":100016,"name":"Chest pain unit","editable":false,"quickSearch":false},{"id":100017,"name":"Exam room","editable":false,"quickSearch":false},{"id":100018,"name":"Records room","editable":false,"quickSearch":false},{"id":100019,"name":"CT scan room","editable":false,"quickSearch":false},{"id":100020,"name":"Xray room","editable":false,"quickSearch":false},{"id":100021,"name":"Billing office","editable":false,"quickSearch":true},{"id":100022,"name":"Seminar room","editable":false,"quickSearch":false},{"id":100023,"name":"Auditorioum room","editable":false,"quickSearch":true},{"id":100024,"name":"Lecture room","editable":false,"quickSearch":false},{"id":100025,"name":"Warehouse","editable":false,"quickSearch":false},{"id":100026,"name":"Electrical room","editable":false,"quickSearch":false},{"id":100027,"name":"Wheel chair storage room","editable":false,"quickSearch":true},{"id":100028,"name":"Rehab room","editable":false,"quickSearch":false},{"id":100029,"name":"CCTV room","editable":false,"quickSearch":false},{"id":100030,"name":"Bakery","editable":false,"quickSearch":false}]
+1 -1
View File
@@ -1 +1 @@
[{"id":1,"name":"GM1","reception":"G-1C37F","idHIS":"11111","idQMS":"qqqqq","qmsSOW":"http://localhost:1234"},{"id":2,"name":"deparment 2","reception":"G-1C10","idHIS":"22222","idQMS":"qqqqq","qmsSOW":"http://localhost:1234"},{"id":4,"name":"deparment 4","reception":"000003","idHIS":"44444","idQMS":"qqqqq","qmsSOW":"http://localhost:1234"},{"id":5,"name":"deparment 5","reception":"G-1C40","idHIS":"55555","idQMS":"qqqqq","qmsSOW":"http://localhost:1234"},{"id":1002,"name":"DIT","reception":"G-3A06","idHIS":"","idQMS":"","qmsSOW":""},{"id":1003,"name":"General Medicine","reception":"G-1C40","idHIS":"77777","idQMS":"1111","qmsSOW":""}]
[{"id":1,"name":"GM1","reception":"G-1C37F","idHIS":"11111","idQMS":"qqqqq","qmsSOW":"http://localhost:1234"},{"id":2,"name":"deparment 2","reception":"G-1C10","idHIS":"22222","idQMS":"qqqqq","qmsSOW":"http://localhost:1234"},{"id":4,"name":"deparment 4","reception":"000003","idHIS":"44444","idQMS":"qqqqq","qmsSOW":"http://localhost:1234"},{"id":5,"name":"deparment 5","reception":"G-1C40","idHIS":"55555","idQMS":"qqqqq","qmsSOW":"http://localhost:1234"},{"id":1002,"name":"DIT","reception":"G-3A06","idHIS":"","idQMS":"","qmsSOW":""},{"id":1003,"name":"General Medicine","reception":"G-1C40","idHIS":"77777","idQMS":"1111","qmsSOW":""},{"id":1006,"name":"HR","reception":"000002","idHIS":"","idQMS":"","qmsSOW":""}]
Binary file not shown.
Binary file not shown.
+1 -1
View File
@@ -1,2 +1,2 @@
Date/Time,Word Count,ar,en
2021.10.25-16.13.48,440,440,0
2022.10.14-12.47.44,599,0,599
1 Date/Time Word Count ar en
2 2021.10.25-16.13.48 2022.10.14-12.47.44 440 599 440 0 0 599
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1
View File
@@ -0,0 +1 @@
rtsp://127.0.0.1:8554/
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+3
View File
@@ -0,0 +1,3 @@
Binaries/
Intermediate/
plugins.dat
@@ -0,0 +1,72 @@
#!/bin/bash
set -x
# Control if ./Plugins/VlcMedia/ folder exists.
if [ ! -d "./Plugins/VlcMedia/" ]; then
printf "./Plugins/VlcMedia/ folder doesn't exist.\nRun bash script from Project (GAME) folder\n"
exit 1
fi
# clean-up and configure the VlcMedia plugin
installDir=$PWD
installDir+="/Plugins/VlcMedia/ThirdParty/vlc/Linux/x86_64-unknown-linux-gnu/"
rm -rf $installDir
mkdir -p $installDir
rm -rf ./protobuf/
rm -rf ./vlc/
# update Ubuntu and remove vlc
sudo apt purge vlc
sudo snap remove vlc
sudo add-apt-repository --remove ppa:videolan/master-daily
sudo apt update
sudo apt upgrade
sudo apt autoremove
# To build vlc from source, the following tools are needed
sudo apt install autoconf automake libtool curl make g++ unzip
sudo apt install git build-essential pkg-config libtool autopoint gettext
sudo apt install subversion yasm cvs cmake ragel
sudo apt install gperf default-jdk ant flex flex-old bison
sudo apt install libcaca-dev libncursesw5-dev libasound2-dev lua5.2-dev libxcb-keysyms1-dev
sudo apt install lua5.2 openjdk-8-jdk ant nasm libxcb-composite0 libxcb-composite0-dev
sudo apt install libxcb-xv0 libxcb-xv0-dev wayland-protocols
# Protocol Buffers - Google's data interchange format
git clone git://github.com/google/protobuf.git
cd protobuf
./autogen.sh
./configure
make
make check
sudo make install
make clean
sudo ldconfig # refresh shared library cache
cd ..
# install vlc and make it available to the VlcMedia plugin
git clone git://git.videolan.org/vlc.git
cd vlc
git checkout tags/4.0.0-dev -b 4.0.0-dev
./bootstrap
# VLC contribs system, included in the VLC source
cd contrib
mkdir native
cd native
../bootstrap
make # Create VLC contribs system code to Hotfix it
# Hotfix for `ERROR: libmp3lame >= 3.98.3 not found` problem.
# CREDIT # https://stackoverflow.com/a/46756012/4510033
sed -i -e 's/\(3.98.3..lame.lame.h.lame.set.VBR.quality..lmp3lame\)/\1 -lm/' ./ffmpeg/configure
make
cd ..
cd ..
./configure --disable-srt --disable-dca --disable-libass --disable-css --disable-upnp --disable-chromaprint --disable-freetype --prefix=$installDir
make
make install
make clean
cd ..
@@ -0,0 +1,74 @@
#!/bin/bash
set -x
# Control if ./Plugins/VlcMedia/ folder exists.
if [ ! -d "./Plugins/VlcMedia/" ]; then
printf "./Plugins/VlcMedia/ folder doesn't exist.\nRun bash script from Project (GAME) folder\n"
exit 1
fi
# clean-up and configure the VlcMedia plugin
installDir=$PWD
installDir+="/Plugins/VlcMedia/ThirdParty/vlc/Linux/x86_64-unknown-linux-gnu/"
rm -rf $installDir
mkdir -p $installDir
#rm -rf ./protobuf/
#rm -rf ./vlc/
# update Ubuntu and remove vlc
sudo apt purge vlc
sudo snap remove vlc
sudo add-apt-repository --remove ppa:videolan/master-daily
sudo apt update
sudo apt upgrade
sudo apt autoremove
# To build vlc from source, the following tools are needed
sudo apt install autoconf automake libtool curl make g++ unzip
sudo apt install git build-essential pkg-config libtool autopoint gettext
sudo apt install subversion yasm cvs cmake ragel
sudo apt install gperf default-jdk ant flex flex-old bison
sudo apt install libcaca-dev libncursesw5-dev libasound2-dev lua5.2-dev libxcb-keysyms1-dev
sudo apt install lua5.2 openjdk-8-jdk ant nasm libxcb-composite0 libxcb-composite0-dev
sudo apt install libxcb-xv0 libxcb-xv0-dev wayland-protocols
# Protocol Buffers - Google's data interchange format
#git clone git://github.com/google/protobuf.git
cd protobuf
./autogen.sh
./configure
make clean
make
make check
sudo make install
make clean
sudo ldconfig # refresh shared library cache
cd ..
# install vlc and make it available to the VlcMedia plugin
#git clone git://git.videolan.org/vlc.git
cd vlc
#git checkout tags/4.0.0-dev -b 4.0.0-dev
./bootstrap
# VLC contribs system, included in the VLC source
cd contrib
mkdir native
cd native
../bootstrap
make # Create VLC contribs system code to Hotfix it
# Hotfix for `ERROR: libmp3lame >= 3.98.3 not found` problem.
# CREDIT # https://stackoverflow.com/a/46756012/4510033
sed -i -e 's/\(3.98.3..lame.lame.h.lame.set.VBR.quality..lmp3lame\)/\1 -lm/' ./ffmpeg/configure
make
cd ..
cd ..
./configure --disable-srt --disable-dca --disable-libass --disable-css --disable-upnp --disable-chromaprint --disable-freetype --prefix=$installDir
make clean
make
make install
make clean
cd ..
+11
View File
@@ -0,0 +1,11 @@
Copyright 2015 Epic Games, Inc.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+101
View File
@@ -0,0 +1,101 @@
# VlcMedia
Unreal Engine 4 Media Framework plug-in using the Video LAN Codec (libvlc).
## About
This plug-in is still under development and likely has a lot of remaining issues
to be fixed. Use in production is not yet recommended.
Make sure to pull the *Tag* that matches your Unreal Engine version. If you sync
to *Master* the code may not compile, because it may depend on Engine changes
that are not yet available in the UE4 Master branch.
## Supported Platforms
This plug-in was last built against **Unreal Engine 4.19** and tested
against the following platforms:
- Linux (Ubuntu 16.04)
- ~~Mac~~
- Windows
**IMPORTANT**: Please note that this repository contains pre-compiled binaries
for libvlc and its plug-ins, which are licensed under LGPL. This means that you
cannot create monolithic builds of your game without violating LGPL, the UE4
EULA or both. The libvlc libraries must remain dynamic libraries that are bound
at run-time - static linking is not allowed - and the licensing related files in
*/ThirdParty/vlc* must be retained.
This also means that this plug-in cannot work on platforms that do not support
dynamically linked libraries (i.e. iOS, HTML5) or do not currently implement
support for it (i.e. Android, XboxOne).
Epic is in the process of adding plug-in support to monolithic builds, but there
is no ETA yet. Once this is supported, you will be able to distribute monolithic
game and server builds with VlcMedia, provided that the libvlc libraries and
plug-ins remain as separate DLLs.
## Prerequisites
A relatively recent version of libvlc is required. The latest stable release
(currently 2.2.1) is not sufficient.
For Mac and Windows, the following nightly builds are currently included:
* macOS: vlc-4.0.0-20180319-0303-dev
* Win32: vlc-4.0.0-20180319-0303-dev-win32
* Win64: vlc-4.0.0-20180319-1331-dev-win64
Nightly builds can be downloaded from the VideoLAN web site (see below).
For debugging on Win32 and Win64, you can download debug builds and replace the
corresponding files and folders in the *VlcMedia/ThirdParty/vlc/* directory.
### Linux (Ubuntu 16.04)
A suitable version of **libvlc** must be installed or compiled from source. If
you ship your game on Linux, you will likely want to include libvlc with it, so
that users don't have to install it themselves. We will eventually include those
binaries in this repository, although it is not clear what distros should be
supported and where the builds are coming from. A better workflow needs to be
established for this (https://github.com/ue4plugins/VlcMedia/issues/17).
To clean up, clone, make and install VLC (including libvlc) into your project,
run the *VlcMedia/Build/Vlc4LinuxCloneMakeInstall.sh* script from within your
project's root folder. If you later need to make and re-install VLC from the
existing VLC code, run the *Vlc4LinuxMakeInstall.sh* script instead.
### Mac, Windows
All required libraries and plug-ins are included in the *ThirdParty* directory
and work out of the box.
## Dependencies
This plug-in requires Visual Studio and either a C++ code project or the full
Unreal Engine 4 source code from GitHub. If you are new to programming in UE4,
please see the official [Programming Guide](https://docs.unrealengine.com/latest/INT/Programming/index.html)!
## Usage
You can use this plug-in as a project plug-in, or an Engine plug-in.
If you use it as a project plug-in, clone this repository into your project's
*/Plugins* directory and compile your game in Visual Studio. A C++ code project
is required for this to work.
If you use it as an Engine plug-in, clone this repository into the
*/Engine/Plugins/Media* directory and compile your game. Full Unreal Engine 4
source code from GitHub is required for this.
## References
* [VideoLAN Homepage](http://videolan.org)
* [VideoLAN Nightly Builds](http://nightlies.videolan.org/)
* [Introduction to UE4 Plugins](https://wiki.unrealengine.com/An_Introduction_to_UE4_Plugins)
Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

@@ -0,0 +1,169 @@
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreTypes.h"
#include "IMediaAudioSample.h"
#include "MediaObjectPool.h"
#include "Misc/Timespan.h"
#include "Templates/SharedPointer.h"
/**
* Audio sample generated by VLC player.
*/
class FVlcMediaAudioSample
: public IMediaAudioSample
, public IMediaPoolable
{
public:
/** Default constructor. */
FVlcMediaAudioSample()
: Buffer(nullptr)
, BufferSize(0)
, Channels(0)
, Duration(FTimespan::Zero())
, Frames(0)
, SampleFormat(EMediaAudioSampleFormat::Undefined)
, SampleRate(0)
, Time(FTimespan::Zero())
{ }
/** Virtual destructor. */
virtual ~FVlcMediaAudioSample()
{
FreeBuffer();
}
public:
/**
* Initialize the sample.
*
* @param InBuffer The raw audio sample buffer.
* @param InBufferSize The size of the buffer (in bytes).
* @param InFrames Number of frames in the buffer.
* @param InChannels Number of audio channels.
* @param InSampleFormat The sample format.
* @param InSampleRate The sample rate.
* @param InTime The sample time (in the player's local clock).
* @param InDuration The duration for which the sample is valid.
* @return true on success, false otherwise.
*/
bool Initialize(
void* InBuffer,
uint32 InBufferSize,
uint32 InFrames,
uint32 InChannels,
EMediaAudioSampleFormat InSampleFormat,
uint32 InSampleRate,
FTimespan InTime,
FTimespan InDuration)
{
if ((InBuffer == nullptr) || (InBufferSize == 0) || (InSampleFormat == EMediaAudioSampleFormat::Undefined))
{
return false;
}
if (InBufferSize > BufferSize)
{
Buffer = FMemory::Realloc(Buffer, InBufferSize);
BufferSize = InBufferSize;
}
FMemory::Memcpy(Buffer, InBuffer, InBufferSize);
Channels = InChannels;
Duration = InDuration;
Frames = InFrames;
SampleFormat = InSampleFormat;
SampleRate = InSampleRate;
Time = InTime;
return true;
}
public:
//~ IMediaAudioSample interface
virtual const void* GetBuffer() override
{
return Buffer;
}
virtual uint32 GetChannels() const override
{
return Channels;
}
virtual uint32 GetFrames() const override
{
return Frames;
}
virtual FTimespan GetDuration() const override
{
return Duration;
}
virtual EMediaAudioSampleFormat GetFormat() const override
{
return SampleFormat;
}
virtual uint32 GetSampleRate() const override
{
return SampleRate;
}
virtual FTimespan GetTime() const override
{
return Time;
}
protected:
/** Free the sample buffer. */
void FreeBuffer()
{
if (Buffer != nullptr)
{
FMemory::Free(Buffer);
Buffer = nullptr;
BufferSize = 0;
}
}
private:
/** The sample's frame buffer. */
void* Buffer;
/** Allocated size of the buffer (in bytes). */
SIZE_T BufferSize;
/** Number of audio channels. */
uint32 Channels;
/** Duration for which the sample is valid. */
FTimespan Duration;
/** Number of frames in the buffer. */
uint32 Frames;
/** The sample format. */
EMediaAudioSampleFormat SampleFormat;
/** Audio sample rate (in samples per second). */
uint32 SampleRate;
/** Play time for which the sample was generated. */
FTimespan Time;
};
/** Implements a pool for VLC audio sample objects. */
class FVlcMediaAudioSamplePool : public TMediaObjectPool<FVlcMediaAudioSample> { };
@@ -0,0 +1,462 @@
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
#include "VlcMediaCallbacks.h"
#include "VlcMediaPrivate.h"
#include "IMediaAudioSample.h"
#include "IMediaOptions.h"
#include "IMediaTextureSample.h"
#include "MediaSamples.h"
#include "Vlc.h"
#include "VlcMediaAudioSample.h"
#include "VlcMediaTextureSample.h"
/* FVlcMediaOutput structors
*****************************************************************************/
FVlcMediaCallbacks::FVlcMediaCallbacks()
: AudioChannels(0)
, AudioSampleFormat(EMediaAudioSampleFormat::Int16)
, AudioSamplePool(new FVlcMediaAudioSamplePool)
, AudioSampleRate(0)
, AudioSampleSize(0)
, CurrentTime(FTimespan::Zero())
, Player(nullptr)
, Samples(new FMediaSamples)
, VideoBufferDim(FIntPoint::ZeroValue)
, VideoBufferStride(0)
, VideoFrameDuration(FTimespan::Zero())
, VideoOutputDim(FIntPoint::ZeroValue)
, VideoPreviousTime(FTimespan::MinValue())
, VideoSampleFormat(EMediaTextureSampleFormat::CharAYUV)
, VideoSamplePool(new FVlcMediaTextureSamplePool)
{ }
FVlcMediaCallbacks::~FVlcMediaCallbacks()
{
Shutdown();
delete AudioSamplePool;
AudioSamplePool = nullptr;
delete Samples;
Samples = nullptr;
delete VideoSamplePool;
VideoSamplePool = nullptr;
}
/* FVlcMediaOutput interface
*****************************************************************************/
IMediaSamples& FVlcMediaCallbacks::GetSamples()
{
return *Samples;
}
void FVlcMediaCallbacks::Initialize(FLibvlcMediaPlayer& InPlayer)
{
Shutdown();
Player = &InPlayer;
// register callbacks
FVlc::AudioSetFormatCallbacks(
Player,
&FVlcMediaCallbacks::StaticAudioSetupCallback,
&FVlcMediaCallbacks::StaticAudioCleanupCallback
);
FVlc::AudioSetCallbacks(
Player,
&FVlcMediaCallbacks::StaticAudioPlayCallback,
&FVlcMediaCallbacks::StaticAudioPauseCallback,
&FVlcMediaCallbacks::StaticAudioResumeCallback,
&FVlcMediaCallbacks::StaticAudioFlushCallback,
&FVlcMediaCallbacks::StaticAudioDrainCallback,
this
);
FVlc::VideoSetFormatCallbacks(
Player,
&FVlcMediaCallbacks::StaticVideoSetupCallback,
&FVlcMediaCallbacks::StaticVideoCleanupCallback
);
FVlc::VideoSetCallbacks(
Player,
&FVlcMediaCallbacks::StaticVideoLockCallback,
&FVlcMediaCallbacks::StaticVideoUnlockCallback,
&FVlcMediaCallbacks::StaticVideoDisplayCallback,
this
);
}
void FVlcMediaCallbacks::Shutdown()
{
if (Player == nullptr)
{
return;
}
// unregister callbacks
FVlc::AudioSetCallbacks(Player, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr);
FVlc::AudioSetFormatCallbacks(Player, nullptr, nullptr);
FVlc::VideoSetCallbacks(Player, nullptr, nullptr, nullptr, nullptr);
FVlc::VideoSetFormatCallbacks(Player, nullptr, nullptr);
AudioSamplePool->Reset();
VideoSamplePool->Reset();
CurrentTime = FTimespan::Zero();
Player = nullptr;
}
/* FVlcMediaOutput static functions
*****************************************************************************/
void FVlcMediaCallbacks::StaticAudioCleanupCallback(void* Opaque)
{
UE_LOG(LogVlcMedia, VeryVerbose, TEXT("Callbacks %llx: StaticAudioCleanupCallback"), Opaque);
}
void FVlcMediaCallbacks::StaticAudioDrainCallback(void* Opaque)
{
UE_LOG(LogVlcMedia, VeryVerbose, TEXT("Callbacks %llx: StaticAudioDrainCallback"), Opaque);
}
void FVlcMediaCallbacks::StaticAudioFlushCallback(void* Opaque, int64 Timestamp)
{
UE_LOG(LogVlcMedia, VeryVerbose, TEXT("Callbacks %llx: StaticAudioFlushCallback"), Opaque);
}
void FVlcMediaCallbacks::StaticAudioPauseCallback(void* Opaque, int64 Timestamp)
{
UE_LOG(LogVlcMedia, VeryVerbose, TEXT("Callbacks %llx: StaticAudioPauseCallback (Timestamp = %i)"), Opaque, Timestamp);
// do nothing; pausing is handled in Update
}
void FVlcMediaCallbacks::StaticAudioPlayCallback(void* Opaque, void* Samples, uint32 Count, int64 Timestamp)
{
auto Callbacks = (FVlcMediaCallbacks*)Opaque;
if (Callbacks == nullptr)
{
return;
}
UE_LOG(LogVlcMedia, VeryVerbose, TEXT("Callbacks %llx: StaticAudioPlayCallback (Count = %i, Timestamp = %i, Queue = %i)"),
Opaque,
Count,
Timestamp,
Callbacks->Samples->NumAudio()
);
// create & add sample to queue
auto AudioSample = Callbacks->AudioSamplePool->AcquireShared();
const FTimespan Delay = FTimespan::FromMicroseconds(FVlc::Delay(Timestamp));
const FTimespan Duration = FTimespan::FromMicroseconds((Count * 1000000) / Callbacks->AudioSampleRate);
const SIZE_T SamplesSize = Count * Callbacks->AudioSampleSize * Callbacks->AudioChannels;
if (AudioSample->Initialize(
Samples,
SamplesSize,
Count,
Callbacks->AudioChannels,
Callbacks->AudioSampleFormat,
Callbacks->AudioSampleRate,
Callbacks->CurrentTime + Delay,
Duration))
{
Callbacks->Samples->AddAudio(AudioSample);
}
}
void FVlcMediaCallbacks::StaticAudioResumeCallback(void* Opaque, int64 Timestamp)
{
UE_LOG(LogVlcMedia, VeryVerbose, TEXT("Callbacks %llx: StaticAudioResumeCallback (Timestamp = %i)"), Opaque, Timestamp);
// do nothing; resuming is handled in Update
}
int FVlcMediaCallbacks::StaticAudioSetupCallback(void** Opaque, ANSICHAR* Format, uint32* Rate, uint32* Channels)
{
auto Callbacks = *(FVlcMediaCallbacks**)Opaque;
if (Callbacks == nullptr)
{
return -1;
}
UE_LOG(LogVlcMedia, VeryVerbose, TEXT("Callbacks %llx: StaticAudioSetupCallback (Format = %s, Rate = %i, Channels = %i)"),
Opaque,
ANSI_TO_TCHAR(Format),
*Rate,
*Channels
);
// setup audio format
if (*Channels > 8)
{
*Channels = 8;
}
if (FMemory::Memcmp(Format, "S8 ", 4) == 0)
{
Callbacks->AudioSampleFormat = EMediaAudioSampleFormat::Int8;
Callbacks->AudioSampleSize = 1;
}
else if (FMemory::Memcmp(Format, "S16N", 4) == 0)
{
Callbacks->AudioSampleFormat = EMediaAudioSampleFormat::Int16;
Callbacks->AudioSampleSize = 2;
}
else if (FMemory::Memcmp(Format, "S32N", 4) == 0)
{
Callbacks->AudioSampleFormat = EMediaAudioSampleFormat::Int32;
Callbacks->AudioSampleSize = 4;
}
else if (FMemory::Memcmp(Format, "FL32", 4) == 0)
{
Callbacks->AudioSampleFormat = EMediaAudioSampleFormat::Float;
Callbacks->AudioSampleSize = 4;
}
else if (FMemory::Memcmp(Format, "FL64", 4) == 0)
{
Callbacks->AudioSampleFormat = EMediaAudioSampleFormat::Double;
Callbacks->AudioSampleSize = 8;
}
else if (FMemory::Memcmp(Format, "U8 ", 4) == 0)
{
// unsigned integer fall back
FMemory::Memcpy(Format, "S8 ", 4);
Callbacks->AudioSampleFormat = EMediaAudioSampleFormat::Int8;
Callbacks->AudioSampleSize = 1;
}
else
{
// unsupported format fall back
FMemory::Memcpy(Format, "S16N", 4);
Callbacks->AudioSampleFormat = EMediaAudioSampleFormat::Int16;
Callbacks->AudioSampleSize = 2;
}
Callbacks->AudioChannels = *Channels;
Callbacks->AudioSampleRate = *Rate;
return 0;
}
void FVlcMediaCallbacks::StaticVideoCleanupCallback(void *Opaque)
{
// do nothing
}
void FVlcMediaCallbacks::StaticVideoDisplayCallback(void* Opaque, void* Picture)
{
auto Callbacks = (FVlcMediaCallbacks*)Opaque;
auto VideoSample = (FVlcMediaTextureSample*)Picture;
if ((Callbacks == nullptr) || (VideoSample == nullptr))
{
return;
}
UE_LOG(LogVlcMedia, VeryVerbose, TEXT("Callbacks %llx: StaticVideoDisplayCallback (CurrentTime = %s, Queue = %i)"),
Opaque, *Callbacks->CurrentTime.ToString(),
Callbacks->Samples->NumVideoSamples()
);
VideoSample->SetTime(Callbacks->CurrentTime);
// add sample to queue
Callbacks->Samples->AddVideo(Callbacks->VideoSamplePool->ToShared(VideoSample));
}
void* FVlcMediaCallbacks::StaticVideoLockCallback(void* Opaque, void** Planes)
{
auto Callbacks = (FVlcMediaCallbacks*)Opaque;
check(Callbacks != nullptr);
FMemory::Memzero(Planes, FVlc::MaxPlanes * sizeof(void*));
// skip if already processed
if (Callbacks->VideoPreviousTime == Callbacks->CurrentTime)
{
// VLC currently requires a valid buffer or it will crash
Planes[0] = FMemory::Malloc(Callbacks->VideoBufferStride * Callbacks->VideoBufferDim.Y, 32);
return nullptr;
}
UE_LOG(LogVlcMedia, VeryVerbose, TEXT("Callbacks %llx: StaticVideoLockCallback (CurrentTime = %s)"),
Opaque,
*Callbacks->CurrentTime.ToString()
);
// create & initialize video sample
auto VideoSample = Callbacks->VideoSamplePool->Acquire();
if (VideoSample == nullptr)
{
// VLC currently requires a valid buffer or it will crash
Planes[0] = FMemory::Malloc(Callbacks->VideoBufferStride * Callbacks->VideoBufferDim.Y, 32);
return nullptr;
}
if (!VideoSample->Initialize(
Callbacks->VideoBufferDim,
Callbacks->VideoOutputDim,
Callbacks->VideoSampleFormat,
Callbacks->VideoBufferStride,
Callbacks->VideoFrameDuration))
{
// VLC currently requires a valid buffer or it will crash
Planes[0] = FMemory::Malloc(Callbacks->VideoBufferStride * Callbacks->VideoBufferDim.Y, 32);
return nullptr;
}
Callbacks->VideoPreviousTime = Callbacks->CurrentTime;
Planes[0] = VideoSample->GetMutableBuffer();
return VideoSample; // passed as Picture into unlock & display callbacks
}
unsigned FVlcMediaCallbacks::StaticVideoSetupCallback(void** Opaque, char* Chroma, unsigned* Width, unsigned* Height, unsigned* Pitches, unsigned* Lines)
{
auto Callbacks = *(FVlcMediaCallbacks**)Opaque;
if (Callbacks == nullptr)
{
return 0;
}
UE_LOG(LogVlcMedia, VeryVerbose, TEXT("Callbacks %llx: StaticVideoSetupCallback (Chroma = %s, Dim = %ix%i)"),
Opaque,
ANSI_TO_TCHAR(Chroma),
*Width,
*Height
);
// get video output size
if (FVlc::VideoGetSize(Callbacks->Player, 0, (uint32*)&Callbacks->VideoOutputDim.X, (uint32*)&Callbacks->VideoOutputDim.Y) != 0)
{
Callbacks->VideoBufferDim = FIntPoint::ZeroValue;
Callbacks->VideoOutputDim = FIntPoint::ZeroValue;
Callbacks->VideoBufferStride = 0;
return 0;
}
if (Callbacks->VideoOutputDim.GetMin() <= 0)
{
return 0;
}
// determine decoder & sample formats
Callbacks->VideoBufferDim = FIntPoint(*Width, *Height);
if (FCStringAnsi::Stricmp(Chroma, "AYUV") == 0)
{
Callbacks->VideoSampleFormat = EMediaTextureSampleFormat::CharAYUV;
Callbacks->VideoBufferStride = *Width * 4;
}
else if (FCStringAnsi::Stricmp(Chroma, "RV32") == 0)
{
Callbacks->VideoSampleFormat = EMediaTextureSampleFormat::CharBGRA;
Callbacks->VideoBufferStride = *Width * 4;
}
else if ((FCStringAnsi::Stricmp(Chroma, "UYVY") == 0) ||
(FCStringAnsi::Stricmp(Chroma, "Y422") == 0) ||
(FCStringAnsi::Stricmp(Chroma, "UYNV") == 0) ||
(FCStringAnsi::Stricmp(Chroma, "HDYC") == 0))
{
Callbacks->VideoSampleFormat = EMediaTextureSampleFormat::CharUYVY;
Callbacks->VideoBufferStride = *Width * 2;
}
else if ((FCStringAnsi::Stricmp(Chroma, "YUY2") == 0) ||
(FCStringAnsi::Stricmp(Chroma, "V422") == 0) ||
(FCStringAnsi::Stricmp(Chroma, "YUYV") == 0))
{
Callbacks->VideoSampleFormat = EMediaTextureSampleFormat::CharYUY2;
Callbacks->VideoBufferStride = *Width * 2;
}
else if (FCStringAnsi::Stricmp(Chroma, "YVYU") == 0)
{
Callbacks->VideoSampleFormat = EMediaTextureSampleFormat::CharYVYU;
Callbacks->VideoBufferStride = *Width * 2;
}
else
{
// reconfigure output for natively supported format
FLibvlcChromaDescription* ChromaDescr = FVlc::FourccGetChromaDescription(*(FLibvlcFourcc*)Chroma);
if (ChromaDescr->PlaneCount == 0)
{
return 0;
}
if (ChromaDescr->PlaneCount > 1)
{
FMemory::Memcpy(Chroma, "YUY2", 4);
Callbacks->VideoBufferDim = FIntPoint(Align(Callbacks->VideoOutputDim.X, 16) / 2, Align(Callbacks->VideoOutputDim.Y, 16));
Callbacks->VideoSampleFormat = EMediaTextureSampleFormat::CharYUY2;
Callbacks->VideoBufferStride = Callbacks->VideoBufferDim.X * 4;
*Height = Callbacks->VideoBufferDim.Y;
}
else
{
FMemory::Memcpy(Chroma, "RV32", 4);
Callbacks->VideoBufferDim = Callbacks->VideoOutputDim;
Callbacks->VideoSampleFormat = EMediaTextureSampleFormat::CharBGRA;
Callbacks->VideoBufferStride = Callbacks->VideoBufferDim.X * 4;
}
}
// get other video properties
//Callbacks->VideoFrameDuration = FTimespan::FromSeconds(1.0 / FVlc::MediaPlayerGetFps(Callbacks->Player));
Callbacks->VideoFrameDuration = FTimespan::FromMilliseconds(1);
// initialize decoder
Lines[0] = Callbacks->VideoBufferDim.Y;
Pitches[0] = Callbacks->VideoBufferStride;
return 1;
}
void FVlcMediaCallbacks::StaticVideoUnlockCallback(void* Opaque, void* Picture, void* const* Planes)
{
if ((Opaque != nullptr) && (Picture != nullptr))
{
UE_LOG(LogVlcMedia, VeryVerbose, TEXT("Callbacks %llx: StaticVideoUnlockCallback"), Opaque);
}
// discard temporary buffer for VLC crash workaround
if ((Picture == nullptr) && (Planes != nullptr) && (Planes[0] != nullptr))
{
FMemory::Free(Planes[0]);
}
}
@@ -0,0 +1,147 @@
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "IMediaAudioSample.h"
#include "IMediaTextureSample.h"
class FMediaSamples;
class FVlcMediaAudioSamplePool;
class FVlcMediaTextureSamplePool;
class IMediaOptions;
class IMediaAudioSink;
class IMediaOverlaySink;
class IMediaSamples;
class IMediaTextureSink;
struct FLibvlcMediaPlayer;
/**
* Handles VLC callbacks.
*/
class FVlcMediaCallbacks
{
public:
/** Default constructor. */
FVlcMediaCallbacks();
/** Virtual destructor. */
~FVlcMediaCallbacks();
public:
/**
* Get the output media samples.
*
* @return Media samples interface.
*/
IMediaSamples& GetSamples();
/**
* Initialize the handler for the specified media player.
*
* @param InPlayer The media player that owns this handler.
*/
void Initialize(FLibvlcMediaPlayer& InPlayer);
/**
* Set the player's current time.
*
* @param Time The player's play time.
*/
void SetCurrentTime(FTimespan Time)
{
CurrentTime = Time;
}
/** Shut down the callback handler. */
void Shutdown();
private:
/** Handles audio cleanup callbacks from VLC.*/
static void StaticAudioCleanupCallback(void* Opaque);
/** Handles audio drain callbacks from VLC. */
static void StaticAudioDrainCallback(void* Opaque);
/** Handles audio flush callbacks from VLC. */
static void StaticAudioFlushCallback(void* Opaque, int64 Timestamp);
/** Handles audio pause callbacks from VLC. */
static void StaticAudioPauseCallback(void* Opaque, int64 Timestamp);
/** Handles audio play callbacks from VLC. */
static void StaticAudioPlayCallback(void* Opaque, void* Samples, uint32 Count, int64 Timestamp);
/** Handles audio resume callbacks from VLC. */
static void StaticAudioResumeCallback(void* Opaque, int64 Timestamp);
/** Handles audio setup callbacks from VLC. */
static int StaticAudioSetupCallback(void** Opaque, ANSICHAR* Format, uint32* Rate, uint32* Channels);
/** Handles video cleanup callbacks from VLC. */
static void StaticVideoCleanupCallback(void *Opaque);
/** Handles display callbacks from VLC. */
static void StaticVideoDisplayCallback(void* Opaque, void* Picture);
/** Handles buffer lock callbacks from VLC. */
static void* StaticVideoLockCallback(void* Opaque, void** Planes);
/** Handles video setup callbacks from VLC. */
static unsigned StaticVideoSetupCallback(void** Opaque, char* Chroma, unsigned* Width, unsigned* Height, unsigned* Pitches, unsigned* Lines);
/** Handles buffer unlock callbacks from VLC. */
static void StaticVideoUnlockCallback(void* Opaque, void* Picture, void* const* Planes);
private:
/** Current number of channels in audio samples( accessed by VLC thread only). */
uint32 AudioChannels;
/** Current audio sample format (accessed by VLC thread only). */
EMediaAudioSampleFormat AudioSampleFormat;
/** Audio sample object pool. */
FVlcMediaAudioSamplePool* AudioSamplePool;
/** Current audio sample rate (accessed by VLC thread only). */
uint32 AudioSampleRate;
/** Size of a single audio sample (in bytes). */
SIZE_T AudioSampleSize;
/** The player's current time. */
FTimespan CurrentTime;
/** The VLC media player object. */
FLibvlcMediaPlayer* Player;
/** The output media samples. */
FMediaSamples* Samples;
/** Current video buffer dimensions (accessed by VLC thread only; may be larger than VideoOutputDim). */
FIntPoint VideoBufferDim;
/** Number of bytes per row of video pixels. */
uint32 VideoBufferStride;
/** Current duration of video frames. */
FTimespan VideoFrameDuration;
/** Current video output dimensions (accessed by VLC thread only). */
FIntPoint VideoOutputDim;
/** Play time of the previous frame. */
FTimespan VideoPreviousTime;
/** Current video sample format (accessed by VLC thread only). */
EMediaTextureSampleFormat VideoSampleFormat;
/** Video sample object pool. */
FVlcMediaTextureSamplePool* VideoSamplePool;
};
@@ -0,0 +1,534 @@
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
#include "VlcMediaPlayer.h"
#include "VlcMediaPrivate.h"
#include "IMediaEventSink.h"
#include "IMediaOptions.h"
#include "Misc/FileHelper.h"
#include "Serialization/ArrayReader.h"
#include "Vlc.h"
#include "VlcMediaUtils.h"
/* FVlcMediaPlayer structors
*****************************************************************************/
FVlcMediaPlayer::FVlcMediaPlayer(IMediaEventSink& InEventSink, FLibvlcInstance* InVlcInstance)
: CurrentRate(0.0f)
, CurrentTime(FTimespan::Zero())
, EventSink(InEventSink)
, MediaSource(InVlcInstance)
, Player(nullptr)
, ShouldLoop(false)
{ }
FVlcMediaPlayer::~FVlcMediaPlayer()
{
Close();
}
/* IMediaControls interface
*****************************************************************************/
bool FVlcMediaPlayer::CanControl(EMediaControl Control) const
{
if (Player == nullptr)
{
return false;
}
if (Control == EMediaControl::Pause)
{
return (FVlc::MediaPlayerCanPause(Player) != 0);
}
if (Control == EMediaControl::Resume)
{
return (FVlc::MediaPlayerGetState(Player) != ELibvlcState::Playing);
}
if ((Control == EMediaControl::Scrub) || (Control == EMediaControl::Seek))
{
return (FVlc::MediaPlayerIsSeekable(Player) != 0);
}
return false;
}
FTimespan FVlcMediaPlayer::GetDuration() const
{
return MediaSource.GetDuration();
}
float FVlcMediaPlayer::GetRate() const
{
return CurrentRate;
}
EMediaState FVlcMediaPlayer::GetState() const
{
if (Player == nullptr)
{
return EMediaState::Closed;
}
ELibvlcState State = FVlc::MediaPlayerGetState(Player);
switch (State)
{
case ELibvlcState::Error:
return EMediaState::Error;
case ELibvlcState::Buffering:
case ELibvlcState::Opening:
return EMediaState::Preparing;
case ELibvlcState::Paused:
return EMediaState::Paused;
case ELibvlcState::Playing:
return EMediaState::Playing;
case ELibvlcState::Ended:
case ELibvlcState::NothingSpecial:
case ELibvlcState::Stopped:
return EMediaState::Stopped;
}
return EMediaState::Error; // should never get here
}
EMediaStatus FVlcMediaPlayer::GetStatus() const
{
return (GetState() == EMediaState::Preparing) ? EMediaStatus::Buffering : EMediaStatus::None;
}
TRangeSet<float> FVlcMediaPlayer::GetSupportedRates(EMediaRateThinning Thinning) const
{
TRangeSet<float> Result;
if (Thinning == EMediaRateThinning::Thinned)
{
Result.Add(TRange<float>::Inclusive(0.0f, 10.0f));
}
else
{
Result.Add(TRange<float>::Inclusive(0.0f, 1.0f));
}
return Result;
}
FTimespan FVlcMediaPlayer::GetTime() const
{
return CurrentTime;
}
bool FVlcMediaPlayer::IsLooping() const
{
return ShouldLoop;
}
bool FVlcMediaPlayer::Seek(const FTimespan& Time)
{
ELibvlcState State = FVlc::MediaPlayerGetState(Player);
if ((State == ELibvlcState::Opening) ||
(State == ELibvlcState::Buffering) ||
(State == ELibvlcState::Error))
{
return false;
}
if (Time != CurrentTime)
{
FVlc::MediaPlayerSetTime(Player, Time.GetTotalMilliseconds());
CurrentTime = Time;
}
return true;
}
bool FVlcMediaPlayer::SetLooping(bool Looping)
{
ShouldLoop = Looping;
return true;
}
bool FVlcMediaPlayer::SetRate(float Rate)
{
if (Player == nullptr)
{
return false;
}
if ((FVlc::MediaPlayerSetRate(Player, Rate) == -1))
{
return false;
}
if (FMath::IsNearlyZero(Rate))
{
if (FVlc::MediaPlayerGetState(Player) == ELibvlcState::Playing)
{
if (FVlc::MediaPlayerCanPause(Player) == 0)
{
return false;
}
FVlc::MediaPlayerPause(Player);
}
}
else if (FVlc::MediaPlayerGetState(Player) != ELibvlcState::Playing)
{
if (FVlc::MediaPlayerPlay(Player) == -1)
{
return false;
}
}
return true;
}
/* IMediaPlayer interface
*****************************************************************************/
void FVlcMediaPlayer::Close()
{
if (Player == nullptr)
{
return;
}
// detach callback handlers
Callbacks.Shutdown();
Tracks.Shutdown();
View.Shutdown();
// release player
FVlc::MediaPlayerStop(Player);
FVlc::MediaPlayerRelease(Player);
Player = nullptr;
// reset fields
CurrentRate = 0.0f;
CurrentTime = FTimespan::Zero();
MediaSource.Close();
Info.Empty();
// notify listeners
EventSink.ReceiveMediaEvent(EMediaEvent::TracksChanged);
EventSink.ReceiveMediaEvent(EMediaEvent::MediaClosed);
}
IMediaCache& FVlcMediaPlayer::GetCache()
{
return *this;
}
IMediaControls& FVlcMediaPlayer::GetControls()
{
return *this;
}
FString FVlcMediaPlayer::GetInfo() const
{
return Info;
}
FName FVlcMediaPlayer::GetPlayerName() const
{
static FName PlayerName(TEXT("VlcMedia"));
return PlayerName;
}
IMediaSamples& FVlcMediaPlayer::GetSamples()
{
return Callbacks.GetSamples();
}
FString FVlcMediaPlayer::GetStats() const
{
FLibvlcMedia* Media = MediaSource.GetMedia();
if (Media == nullptr)
{
return TEXT("No media opened.");
}
FLibvlcMediaStats Stats;
if (!FVlc::MediaGetStats(Media, &Stats))
{
return TEXT("Stats currently not available.");
}
FString StatsString;
{
StatsString += TEXT("General\n");
StatsString += FString::Printf(TEXT(" Decoded Video: %i\n"), Stats.DecodedVideo);
StatsString += FString::Printf(TEXT(" Decoded Audio: %i\n"), Stats.DecodedAudio);
StatsString += FString::Printf(TEXT(" Displayed Pictures: %i\n"), Stats.DisplayedPictures);
StatsString += FString::Printf(TEXT(" Lost Pictures: %i\n"), Stats.LostPictures);
StatsString += FString::Printf(TEXT(" Played A-Buffers: %i\n"), Stats.PlayedAbuffers);
StatsString += FString::Printf(TEXT(" Lost Lost A-Buffers: %i\n"), Stats.LostAbuffers);
StatsString += TEXT("\n");
StatsString += TEXT("Input\n");
StatsString += FString::Printf(TEXT(" Bit Rate: %i\n"), Stats.InputBitrate);
StatsString += FString::Printf(TEXT(" Bytes Read: %i\n"), Stats.ReadBytes);
StatsString += TEXT("\n");
StatsString += TEXT("Demux\n");
StatsString += FString::Printf(TEXT(" Bit Rate: %f\n"), Stats.DemuxBitrate);
StatsString += FString::Printf(TEXT(" Bytes Read: %i\n"), Stats.DemuxReadBytes);
StatsString += FString::Printf(TEXT(" Corrupted: %i\n"), Stats.DemuxCorrupted);
StatsString += FString::Printf(TEXT(" Discontinuity: %i\n"), Stats.DemuxDiscontinuity);
StatsString += TEXT("\n");
StatsString += TEXT("Network\n");
StatsString += FString::Printf(TEXT(" Bitrate: %f\n"), Stats.SendBitrate);
StatsString += FString::Printf(TEXT(" Sent Bytes: %i\n"), Stats.SentBytes);
StatsString += FString::Printf(TEXT(" Sent Packets: %i\n"), Stats.SentPackets);
StatsString += TEXT("\n");
}
return StatsString;
}
IMediaTracks& FVlcMediaPlayer::GetTracks()
{
return Tracks;
}
FString FVlcMediaPlayer::GetUrl() const
{
return MediaSource.GetCurrentUrl();
}
IMediaView& FVlcMediaPlayer::GetView()
{
return View;
}
bool FVlcMediaPlayer::Open(const FString& Url, const IMediaOptions* Options)
{
Close();
if (Url.IsEmpty())
{
return false;
}
if (Url.StartsWith(TEXT("file://")))
{
// open local files via platform file system
TSharedPtr<FArchive, ESPMode::ThreadSafe> Archive;
const TCHAR* FilePath = &Url[7];
if ((Options != nullptr) && Options->GetMediaOption("PrecacheFile", false))
{
FArrayReader* Reader = new FArrayReader;
if (FFileHelper::LoadFileToArray(*Reader, FilePath))
{
Archive = MakeShareable(Reader);
}
else
{
delete Reader;
}
}
else
{
Archive = MakeShareable(IFileManager::Get().CreateFileReader(FilePath));
}
if (!Archive.IsValid())
{
UE_LOG(LogVlcMedia, Warning, TEXT("Failed to open media file: %s"), FilePath);
return false;
}
if (!MediaSource.OpenArchive(Archive.ToSharedRef(), Url))
{
return false;
}
}
else if (!MediaSource.OpenUrl(Url))
{
return false;
}
return InitializePlayer();
}
bool FVlcMediaPlayer::Open(const TSharedRef<FArchive, ESPMode::ThreadSafe>& Archive, const FString& OriginalUrl, const IMediaOptions* /*Options*/)
{
Close();
if (OriginalUrl.IsEmpty() || !MediaSource.OpenArchive(Archive, OriginalUrl))
{
return false;
}
return InitializePlayer();
}
void FVlcMediaPlayer::TickInput(FTimespan DeltaTime, FTimespan /*Timecode*/)
{
if (Player == nullptr)
{
return;
}
// process events
ELibvlcEventType Event;
while (Events.Dequeue(Event))
{
switch (Event)
{
case ELibvlcEventType::MediaParsedChanged:
Tracks.Initialize(*Player, Info);
Callbacks.Initialize(*Player);
View.Initialize(*Player);
EventSink.ReceiveMediaEvent(EMediaEvent::TracksChanged);
break;
case ELibvlcEventType::MediaPlayerEndReached:
// begin hack: this causes a short delay, but there seems to be no
// other way. looping via VLC Media List players is also broken :(
FVlc::MediaPlayerStop(Player);
// end hack
Callbacks.GetSamples().FlushSamples();
EventSink.ReceiveMediaEvent(EMediaEvent::PlaybackEndReached);
if (ShouldLoop && (CurrentRate != 0.0f))
{
CurrentTime = FTimespan::Zero();
SetRate(CurrentRate);
}
else
{
EventSink.ReceiveMediaEvent(EMediaEvent::PlaybackSuspended);
}
break;
case ELibvlcEventType::MediaPlayerPaused:
EventSink.ReceiveMediaEvent(EMediaEvent::PlaybackSuspended);
break;
case ELibvlcEventType::MediaPlayerPlaying:
EventSink.ReceiveMediaEvent(EMediaEvent::PlaybackResumed);
break;
default:
continue;
}
}
const ELibvlcState State = FVlc::MediaPlayerGetState(Player);
// update current time & rate
if (State == ELibvlcState::Playing)
{
CurrentRate = FVlc::MediaPlayerGetRate(Player);
CurrentTime += DeltaTime * CurrentRate;
}
else
{
CurrentRate = 0.0f;
}
Callbacks.SetCurrentTime(CurrentTime);
}
/* FVlcMediaPlayer implementation
*****************************************************************************/
bool FVlcMediaPlayer::InitializePlayer()
{
// create player for media source
Player = FVlc::MediaPlayerNewFromMedia(MediaSource.GetMedia());
if (Player == nullptr)
{
UE_LOG(LogVlcMedia, Warning, TEXT("Failed to initialize media player: %s"), ANSI_TO_TCHAR(FVlc::Errmsg()));
return false;
}
// attach to event managers
FLibvlcEventManager* MediaEventManager = FVlc::MediaEventManager(MediaSource.GetMedia());
FLibvlcEventManager* PlayerEventManager = FVlc::MediaPlayerEventManager(Player);
if ((MediaEventManager == nullptr) || (PlayerEventManager == nullptr))
{
FVlc::MediaPlayerRelease(Player);
Player = nullptr;
return false;
}
FVlc::EventAttach(MediaEventManager, ELibvlcEventType::MediaParsedChanged, &FVlcMediaPlayer::StaticEventCallback, this);
FVlc::EventAttach(PlayerEventManager, ELibvlcEventType::MediaPlayerEndReached, &FVlcMediaPlayer::StaticEventCallback, this);
FVlc::EventAttach(PlayerEventManager, ELibvlcEventType::MediaPlayerPlaying, &FVlcMediaPlayer::StaticEventCallback, this);
FVlc::EventAttach(PlayerEventManager, ELibvlcEventType::MediaPlayerPositionChanged, &FVlcMediaPlayer::StaticEventCallback, this);
FVlc::EventAttach(PlayerEventManager, ELibvlcEventType::MediaPlayerStopped, &FVlcMediaPlayer::StaticEventCallback, this);
// initialize player
CurrentRate = 0.0f;
CurrentTime = FTimespan::Zero();
EventSink.ReceiveMediaEvent(EMediaEvent::MediaOpened);
return true;
}
/* FVlcMediaPlayer static functions
*****************************************************************************/
void FVlcMediaPlayer::StaticEventCallback(FLibvlcEvent* Event, void* UserData)
{
if (Event == nullptr)
{
return;
}
UE_LOG(LogVlcMedia, Verbose, TEXT("Player %llx: Event [%s]"), UserData, *VlcMedia::EventToString(Event));
if (UserData != nullptr)
{
((FVlcMediaPlayer*)UserData)->Events.Enqueue(Event->Type);
}
}
@@ -0,0 +1,131 @@
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "Containers/Queue.h"
#include "IMediaCache.h"
#include "IMediaControls.h"
#include "IMediaPlayer.h"
#include "IMediaSamples.h"
#include "VlcMediaCallbacks.h"
#include "VlcMediaSource.h"
#include "VlcMediaTracks.h"
#include "VlcMediaView.h"
class IMediaEventSink;
class IMediaOutput;
enum class ELibvlcEventType;
struct FLibvlcEvent;
struct FLibvlcEventManager;
struct FLibvlcInstance;
struct FLibvlcMediaPlayer;
/**
* Implements a media player using the Video LAN Codec (VLC) framework.
*/
class FVlcMediaPlayer
: public IMediaPlayer
, protected IMediaCache
, protected IMediaControls
{
public:
/**
* Create and initialize a new instance.
*
* @param InEventSink The object that receives media events from this player.
* @param InInstance The LibVLC instance to use.
*/
FVlcMediaPlayer(IMediaEventSink& InEventSink, FLibvlcInstance* InInstance);
/** Virtual destructor. */
virtual ~FVlcMediaPlayer();
public:
//~ IMediaPlayer interface
virtual void Close() override;
virtual IMediaCache& GetCache() override;
virtual IMediaControls& GetControls() override;
virtual FString GetInfo() const override;
virtual FName GetPlayerName() const override;
virtual IMediaSamples& GetSamples() override;
virtual FString GetStats() const override;
virtual IMediaTracks& GetTracks() override;
virtual FString GetUrl() const override;
virtual IMediaView& GetView() override;
virtual bool Open(const FString& Url, const IMediaOptions* Options) override;
virtual bool Open(const TSharedRef<FArchive, ESPMode::ThreadSafe>& Archive, const FString& OriginalUrl, const IMediaOptions* Options) override;
virtual void TickInput(FTimespan DeltaTime, FTimespan Timecode) override;
protected:
/**
* Initialize the media player.
*
* @return true on success, false otherwise.
*/
bool InitializePlayer();
protected:
//~ IMediaControls interface
virtual bool CanControl(EMediaControl Control) const override;
virtual FTimespan GetDuration() const override;
virtual float GetRate() const override;
virtual EMediaState GetState() const override;
virtual EMediaStatus GetStatus() const override;
virtual TRangeSet<float> GetSupportedRates(EMediaRateThinning Thinning) const override;
virtual FTimespan GetTime() const override;
virtual bool IsLooping() const override;
virtual bool Seek(const FTimespan& Time) override;
virtual bool SetLooping(bool Looping) override;
virtual bool SetRate(float Rate) override;
private:
/** Handles event callbacks. */
static void StaticEventCallback(FLibvlcEvent* Event, void* UserData);
private:
/** VLC callback manager. */
FVlcMediaCallbacks Callbacks;
/** Current playback rate. */
float CurrentRate;
/** Current playback time (to work around VLC's broken time tracking). */
FTimespan CurrentTime;
/** The media event handler. */
IMediaEventSink& EventSink;
/** Collection of received player events. */
TQueue<ELibvlcEventType, EQueueMode::Mpsc> Events;
/** Media information string. */
FString Info;
/** The media source (from URL or archive). */
FVlcMediaSource MediaSource;
/** The VLC media player object. */
FLibvlcMediaPlayer* Player;
/** Whether playback should be looping. */
bool ShouldLoop;
/** Track collection. */
FVlcMediaTracks Tracks;
/** View settings. */
FVlcMediaView View;
};
@@ -0,0 +1,189 @@
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
#include "VlcMediaSource.h"
#include "VlcMediaPrivate.h"
#include "Vlc.h"
/* FVlcMediaReader structors
*****************************************************************************/
FVlcMediaSource::FVlcMediaSource(FLibvlcInstance* InVlcInstance)
: Media(nullptr)
, VlcInstance(InVlcInstance)
{ }
/* FVlcMediaReader interface
*****************************************************************************/
FTimespan FVlcMediaSource::GetDuration() const
{
if (Media == nullptr)
{
return FTimespan::Zero();
}
int64 Duration = FVlc::MediaGetDuration(Media);
if (Duration < 0)
{
return FTimespan::Zero();
}
return FTimespan(Duration * ETimespan::TicksPerMillisecond);
}
FLibvlcMedia* FVlcMediaSource::OpenArchive(const TSharedRef<FArchive, ESPMode::ThreadSafe>& Archive, const FString& OriginalUrl)
{
check(Media == nullptr);
if (Archive->TotalSize() > 0)
{
Data = Archive;
Media = FVlc::MediaNewCallbacks(
VlcInstance,
nullptr,
&FVlcMediaSource::HandleMediaRead,
&FVlcMediaSource::HandleMediaSeek,
&FVlcMediaSource::HandleMediaClose,
this
);
if (Media == nullptr)
{
UE_LOG(LogVlcMedia, Warning, TEXT("Failed to open media from archive: %s (%s)"), *OriginalUrl, ANSI_TO_TCHAR(FVlc::Errmsg()));
Data.Reset();
}
else
{
CurrentUrl = OriginalUrl;
}
}
return Media;
}
FLibvlcMedia* FVlcMediaSource::OpenUrl(const FString& Url)
{
check(Media == nullptr);
Media = FVlc::MediaNewLocation(VlcInstance, TCHAR_TO_ANSI(*Url));
if (Media == nullptr)
{
UE_LOG(LogVlcMedia, Warning, TEXT("Failed to open media from URL: %s (%s)"), *Url, ANSI_TO_TCHAR(FVlc::Errmsg()));
}
else
{
CurrentUrl = Url;
}
return Media;
}
void FVlcMediaSource::Close()
{
if (Media != nullptr)
{
FVlc::MediaRelease(Media);
Media = nullptr;
}
Data.Reset();
CurrentUrl.Reset();
}
/* FVlcMediaReader static functions
*****************************************************************************/
int FVlcMediaSource::HandleMediaOpen(void* Opaque, void** OutData, uint64* OutSize)
{
auto Reader = (FVlcMediaSource*)Opaque;
if ((Reader == nullptr) || !Reader->Data.IsValid())
{
return 0;
}
*OutSize = Reader->Data->TotalSize();
return 0;
}
SSIZE_T FVlcMediaSource::HandleMediaRead(void* Opaque, void* Buffer, SIZE_T Length)
{
auto Reader = (FVlcMediaSource*)Opaque;
if (Reader == nullptr)
{
return -1;
}
TSharedPtr<FArchive, ESPMode::ThreadSafe> Data = Reader->Data;
if (!Reader->Data.IsValid())
{
return -1;
}
SIZE_T DataSize = (SIZE_T)Data->TotalSize();
SIZE_T BytesToRead = FMath::Min(Length, DataSize);
SIZE_T DataPosition = Reader->Data->Tell();
if ((DataSize - BytesToRead) < DataPosition)
{
BytesToRead = DataSize - DataPosition;
}
if (BytesToRead > 0)
{
Data->Serialize(Buffer, BytesToRead);
}
return (SSIZE_T)BytesToRead;
}
int FVlcMediaSource::HandleMediaSeek(void* Opaque, uint64 Offset)
{
auto Reader = (FVlcMediaSource*)Opaque;
if (Reader == nullptr)
{
return -1;
}
TSharedPtr<FArchive, ESPMode::ThreadSafe> Data = Reader->Data;
if (!Reader->Data.IsValid())
{
return -1;
}
if ((uint64)Data->TotalSize() <= Offset)
{
return -1;
}
Reader->Data->Seek(Offset);
return 0;
}
void FVlcMediaSource::HandleMediaClose(void* Opaque)
{
auto Reader = (FVlcMediaSource*)Opaque;
if (Reader != nullptr)
{
Reader->Data->Seek(0);
}
}
@@ -0,0 +1,103 @@
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
struct FLibvlcInstance;
struct FLibvlcMedia;
/**
* Implements a media source, such as a movie file or URL.
*/
class FVlcMediaSource
{
public:
/**
* Create and initialize a new instance.
*
* @param InInstance The LibVLC instance to use.
*/
FVlcMediaSource(FLibvlcInstance* InVlcInstance);
public:
/** Get the media object. */
FLibvlcMedia* GetMedia() const
{
return Media;
}
/** Get the URL of the currently open media source. */
const FString& GetCurrentUrl() const
{
return CurrentUrl;
}
/**
* Get the duration of the media source.
*
* @return Media duration.
*/
FTimespan GetDuration() const;
/**
* Open a media source using the given archive.
*
* You must call Close() if this media source is open prior to calling this method.
*
* @param Archive The archive to read media data from.
* @return The media object.
* @see OpenUrl, Close
*/
FLibvlcMedia* OpenArchive(const TSharedRef<FArchive, ESPMode::ThreadSafe>& Archive, const FString& OriginalUrl);
/**
* Open a media source from the specified URL.
*
* You must call Close() if this media source is open prior to calling this method.
*
* @param Url The media resource locator.
* @return The media object.
* @see OpenArchive, Close
*/
FLibvlcMedia* OpenUrl(const FString& Url);
/**
* Close the media source.
*
* @see OpenArchive, OpenUrl
*/
void Close();
private:
/** Handles open callbacks from VLC. */
static int HandleMediaOpen(void* Opaque, void** OutData, uint64* OutSize);
/** Handles read callbacks from VLC. */
static SSIZE_T HandleMediaRead(void* Opaque, void* Buffer, SIZE_T Length);
/** Handles seek callbacks from VLC. */
static int HandleMediaSeek(void* Opaque, uint64 Offset);
/** Handles close callbacks from VLC. */
static void HandleMediaClose(void* Opaque);
private:
/** The file or memory archive to stream from (for local media only). */
TSharedPtr<FArchive, ESPMode::ThreadSafe> Data;
/** The media object. */
FLibvlcMedia* Media;
/** Currently opened media. */
FString CurrentUrl;
/** The LibVLC instance. */
FLibvlcInstance* VlcInstance;
};
@@ -0,0 +1,206 @@
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreTypes.h"
#include "IMediaTextureSample.h"
#include "MediaObjectPool.h"
#include "Math/IntPoint.h"
#include "Misc/Timespan.h"
#include "Templates/SharedPointer.h"
/**
* Texture sample generated by VlcMedia player.
*/
class FVlcMediaTextureSample
: public IMediaTextureSample
, public IMediaPoolable
{
public:
/** Default constructor. */
FVlcMediaTextureSample()
: Buffer(nullptr)
, BufferSize(0)
, Dim(FIntPoint::ZeroValue)
, Duration(FTimespan::Zero())
, OutputDim(FIntPoint::ZeroValue)
, SampleFormat(EMediaTextureSampleFormat::Undefined)
, Stride(0)
, Time(FTimespan::Zero())
{ }
/** Virtual destructor. */
virtual ~FVlcMediaTextureSample()
{
FreeBuffer();
}
public:
/**
* Get a writable pointer to the sample buffer.
*
* @return The buffer.
* @see Initialize
*/
void* GetMutableBuffer()
{
return Buffer;
}
/**
* Initialize the sample.
*
* @param InDim The sample buffer's width and height (in pixels).
* @param InOutputDim The sample's output width and height (in pixels).
* @param InSampleFormat The sample format.
* @param InStride Number of bytes per pixel row.
* @param InDuration The duration for which the sample is valid.
* @return true on success, false otherwise.
*/
bool Initialize(
const FIntPoint& InDim,
const FIntPoint& InOutputDim,
EMediaTextureSampleFormat InSampleFormat,
uint32 InStride,
FTimespan InDuration)
{
if (InSampleFormat == EMediaTextureSampleFormat::Undefined)
{
return false;
}
const SIZE_T RequiredBufferSize = InStride * InDim.Y;
if (RequiredBufferSize == 0)
{
return false;
}
if (RequiredBufferSize > BufferSize)
{
Buffer = FMemory::Realloc(Buffer, RequiredBufferSize, 32);
BufferSize = RequiredBufferSize;
}
Dim = InDim;
Duration = InDuration;
OutputDim = InOutputDim;
SampleFormat = InSampleFormat;
Stride = InStride;
return true;
}
/**
* Set the time for which the sample was generated.
*
* @param InTime The time to set (in the player's clock).
*/
void SetTime(FTimespan InTime)
{
Time = InTime;
}
public:
//~ IMediaTextureSample interface
virtual const void* GetBuffer() override
{
return Buffer;
}
virtual FIntPoint GetDim() const override
{
return Dim;
}
virtual FTimespan GetDuration() const override
{
return Duration;
}
virtual EMediaTextureSampleFormat GetFormat() const override
{
return SampleFormat;
}
virtual FIntPoint GetOutputDim() const override
{
return OutputDim;
}
virtual uint32 GetStride() const override
{
return Stride;
}
#if WITH_ENGINE
virtual FRHITexture* GetTexture() const override
{
return nullptr;
}
#endif //WITH_ENGINE
virtual FTimespan GetTime() const override
{
return Time;
}
virtual bool IsCacheable() const override
{
return true;
}
virtual bool IsOutputSrgb() const override
{
return true;
}
protected:
/** Free the sample buffer. */
void FreeBuffer()
{
if (Buffer != nullptr)
{
FMemory::Free(Buffer);
Buffer = nullptr;
BufferSize = 0;
}
}
private:
/** The sample's frame buffer. */
void* Buffer;
/** Allocated size of the buffer (in bytes). */
SIZE_T BufferSize;
/** Width and height of the texture sample. */
FIntPoint Dim;
/** Duration for which the sample is valid. */
FTimespan Duration;
/** Width and height of the output. */
FIntPoint OutputDim;
/** The sample format. */
EMediaTextureSampleFormat SampleFormat;
/** Number of bytes per pixel row. */
uint32 Stride;
/** Play time for which the sample was generated. */
FTimespan Time;
};
/** Implements a pool for VLC texture sample objects. */
class FVlcMediaTextureSamplePool : public TMediaObjectPool<FVlcMediaTextureSample> { };
@@ -0,0 +1,443 @@
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
#include "VlcMediaTracks.h"
#include "Vlc.h"
#include "MediaHelpers.h"
#define LOCTEXT_NAMESPACE "FVlcMediaTracks"
/* FVlcMediaTracks structors
*****************************************************************************/
FVlcMediaTracks::FVlcMediaTracks()
: Player(nullptr)
{ }
/* FVlcMediaTracks interface
*****************************************************************************/
void FVlcMediaTracks::Initialize(FLibvlcMediaPlayer& InPlayer, FString& OutInfo)
{
Shutdown();
UE_LOG(LogVlcMedia, Verbose, TEXT("Tracks: %p: Initializing tracks"), this);
Player = &InPlayer;
int32 Width = FVlc::VideoGetWidth(Player);
int32 Height = FVlc::VideoGetHeight(Player);
int32 StreamCount = 0;
// @todo gmp: fix audio specs
FVlc::AudioSetFormat(Player, "S16N", 44100, 2);
FVlc::VideoSetFormat(Player, "RV32", Width, Height, Width * 4);
// initialize audio tracks
FLibvlcTrackDescription* AudioTrackDescr = FVlc::AudioGetTrackDescription(Player);
{
while (AudioTrackDescr != nullptr)
{
if (AudioTrackDescr->Id != -1)
{
FTrack Track;
{
Track.Id = AudioTrackDescr->Id;
Track.Name = ANSI_TO_TCHAR(AudioTrackDescr->Name);
Track.DisplayName = Track.Name.IsEmpty()
? FText::Format(LOCTEXT("AudioTrackFormat", "Audio Track {0}"), FText::AsNumber(AudioTracks.Num()))
: FText::FromString(Track.Name);
}
AudioTracks.Add(Track);
OutInfo += FString::Printf(TEXT("Stream %i\n"), StreamCount);
OutInfo += TEXT(" Type: Audio\n");
OutInfo += FString::Printf(TEXT(" Name: %s\n"), *Track.Name);
OutInfo += TEXT("\n");
++StreamCount;
}
AudioTrackDescr = AudioTrackDescr->Next;
}
}
FVlc::TrackDescriptionListRelease(AudioTrackDescr);
// initialize caption tracks
FLibvlcTrackDescription* CaptionTrackDescr = FVlc::VideoGetSpuDescription(Player);
{
while (CaptionTrackDescr != nullptr)
{
if (CaptionTrackDescr->Id != -1)
{
FTrack Track;
{
Track.Id = CaptionTrackDescr->Id;
Track.Name = ANSI_TO_TCHAR(CaptionTrackDescr->Name);
Track.DisplayName = Track.Name.IsEmpty()
? FText::Format(LOCTEXT("CaptionTrackFormat", "Caption Track {0}"), FText::AsNumber(CaptionTracks.Num()))
: FText::FromString(Track.Name);
}
CaptionTracks.Add(Track);
OutInfo += FString::Printf(TEXT("Stream %i\n"), StreamCount);
OutInfo += TEXT(" Type: Caption\n");
OutInfo += FString::Printf(TEXT(" Name: %s\n"), *Track.Name);
OutInfo += TEXT("\n");
++StreamCount;
}
CaptionTrackDescr = CaptionTrackDescr->Next;
}
}
FVlc::TrackDescriptionListRelease(CaptionTrackDescr);
// initialize video tracks
FLibvlcTrackDescription* VideoTrackDescr = FVlc::VideoGetTrackDescription(Player);
{
while (VideoTrackDescr != nullptr)
{
if (VideoTrackDescr->Id != -1)
{
FTrack Track;
{
Track.Id = VideoTrackDescr->Id;
Track.Name = ANSI_TO_TCHAR(VideoTrackDescr->Name);
Track.DisplayName = Track.Name.IsEmpty()
? FText::Format(LOCTEXT("VideoTrackFormat", "Video Track {0}"), FText::AsNumber(VideoTracks.Num()))
: FText::FromString(Track.Name);
}
VideoTracks.Add(Track);
OutInfo += FString::Printf(TEXT("Stream %i\n"), StreamCount);
OutInfo += TEXT(" Type: Video\n");
OutInfo += FString::Printf(TEXT(" Name: %s\n"), *Track.Name);
OutInfo += TEXT("\n");
++StreamCount;
}
VideoTrackDescr = VideoTrackDescr->Next;
}
}
FVlc::TrackDescriptionListRelease(VideoTrackDescr);
UE_LOG(LogVlcMedia, Verbose, TEXT("Tracks %p: Found %i streams"), this, StreamCount);
}
void FVlcMediaTracks::Shutdown()
{
UE_LOG(LogVlcMedia, Verbose, TEXT("Tracks: %p: Shutting down tracks"), this);
if (Player != nullptr)
{
AudioTracks.Reset();
VideoTracks.Reset();
Player = nullptr;
}
}
/* IMediaTracks interface
*****************************************************************************/
bool FVlcMediaTracks::GetAudioTrackFormat(int32 TrackIndex, int32 FormatIndex, FMediaAudioTrackFormat& OutFormat) const
{
if (!AudioTracks.IsValidIndex(TrackIndex) || (FormatIndex != 0))
{
return false;
}
// @todo gmp: fix audio format
OutFormat.BitsPerSample = 0;
OutFormat.NumChannels = 2;
OutFormat.SampleRate = 44100;
OutFormat.TypeName = TEXT("PCM");
return true;
}
int32 FVlcMediaTracks::GetNumTracks(EMediaTrackType TrackType) const
{
switch (TrackType)
{
case EMediaTrackType::Audio:
return AudioTracks.Num();
case EMediaTrackType::Caption:
return CaptionTracks.Num();
case EMediaTrackType::Video:
return VideoTracks.Num();
default:
return 0;
}
}
int32 FVlcMediaTracks::GetNumTrackFormats(EMediaTrackType TrackType, int32 TrackIndex) const
{
return ((TrackIndex >= 0) && (TrackIndex < GetNumTracks(TrackType))) ? 1 : 0;
}
int32 FVlcMediaTracks::GetSelectedTrack(EMediaTrackType TrackType) const
{
if (Player == nullptr)
{
return INDEX_NONE;
}
const TArray<FTrack>* Tracks = nullptr;
int32 TrackId = INDEX_NONE;
switch (TrackType)
{
case EMediaTrackType::Audio:
Tracks = &AudioTracks;
TrackId = FVlc::AudioGetTrack(Player);
break;
case EMediaTrackType::Caption:
Tracks = &CaptionTracks;
TrackId = FVlc::VideoGetSpu(Player);
break;
case EMediaTrackType::Video:
Tracks = &VideoTracks;
TrackId = FVlc::VideoGetTrack(Player);
break;
}
if (TrackId != INDEX_NONE)
{
check(Tracks != nullptr);
for (int32 TrackIndex = 0; TrackIndex < Tracks->Num(); ++TrackIndex)
{
if ((*Tracks)[TrackIndex].Id == TrackId)
{
return TrackIndex;
}
}
}
return INDEX_NONE;
}
FText FVlcMediaTracks::GetTrackDisplayName(EMediaTrackType TrackType, int32 TrackIndex) const
{
switch (TrackType)
{
case EMediaTrackType::Audio:
if (AudioTracks.IsValidIndex(TrackIndex))
{
return AudioTracks[TrackIndex].DisplayName;
}
break;
case EMediaTrackType::Caption:
if (CaptionTracks.IsValidIndex(TrackIndex))
{
return CaptionTracks[TrackIndex].DisplayName;
}
break;
case EMediaTrackType::Video:
if (VideoTracks.IsValidIndex(TrackIndex))
{
return VideoTracks[TrackIndex].DisplayName;
}
default:
break;
}
return FText::GetEmpty();
}
int32 FVlcMediaTracks::GetTrackFormat(EMediaTrackType TrackType, int32 TrackIndex) const
{
return (GetSelectedTrack(TrackType) != INDEX_NONE) ? 0 : INDEX_NONE;
}
FString FVlcMediaTracks::GetTrackLanguage(EMediaTrackType TrackType, int32 TrackIndex) const
{
return TEXT("und"); // libvlc currently doesn't provide language codes
}
FString FVlcMediaTracks::GetTrackName(EMediaTrackType TrackType, int32 TrackIndex) const
{
switch (TrackType)
{
case EMediaTrackType::Audio:
if (AudioTracks.IsValidIndex(TrackIndex))
{
return AudioTracks[TrackIndex].Name;
}
break;
case EMediaTrackType::Caption:
if (CaptionTracks.IsValidIndex(TrackIndex))
{
return CaptionTracks[TrackIndex].Name;
}
break;
case EMediaTrackType::Video:
if (VideoTracks.IsValidIndex(TrackIndex))
{
return VideoTracks[TrackIndex].Name;
}
default:
break;
}
return FString();
}
bool FVlcMediaTracks::GetVideoTrackFormat(int32 TrackIndex, int32 FormatIndex, FMediaVideoTrackFormat& OutFormat) const
{
if (!VideoTracks.IsValidIndex(TrackIndex) || (FormatIndex != 0) || (Player == nullptr))
{
return false;
}
// @todo gmp: fix video specs
OutFormat.Dim = FIntPoint(FVlc::VideoGetWidth(Player), FVlc::VideoGetHeight(Player));
OutFormat.FrameRate = FVlc::MediaPlayerGetFps(Player);
OutFormat.FrameRates = TRange<float>(OutFormat.FrameRate);
OutFormat.TypeName = TEXT("Default");
return true;
}
bool FVlcMediaTracks::SelectTrack(EMediaTrackType TrackType, int32 TrackIndex)
{
if (Player == nullptr)
{
return false; // not initialized
}
UE_LOG(LogVlcMedia, Verbose, TEXT("Tracks %p: Selecting %s track %i"), this, *MediaUtils::TrackTypeToString(TrackType), TrackIndex);
int32 TrackId = INDEX_NONE;
switch (TrackType)
{
case EMediaTrackType::Audio:
if (AudioTracks.IsValidIndex(TrackIndex))
{
TrackId = AudioTracks[TrackIndex].Id;
}
else if (TrackIndex == INDEX_NONE)
{
TrackId = -1;
}
else
{
return false; // invalid track
}
if (FVlc::AudioSetTrack(Player, TrackId) != 0)
{
UE_LOG(LogVlcMedia, Verbose, TEXT("Tracks %p: Failed to %s audio track %i (id %i)"), this, (TrackId == -1) ? TEXT("disable") : TEXT("enable"), TrackIndex, TrackId);
return false;
}
case EMediaTrackType::Caption:
if (CaptionTracks.IsValidIndex(TrackIndex))
{
TrackId = CaptionTracks[TrackIndex].Id;
}
else if (TrackIndex == INDEX_NONE)
{
TrackId = -1;
}
else
{
return false; // invalid track
}
if (FVlc::VideoSetSpu(Player, TrackId) != 0)
{
UE_LOG(LogVlcMedia, Verbose, TEXT("Tracks %p: Failed to %s caption track %i (id %i)"), this, (TrackId == -1) ? TEXT("disable") : TEXT("enable"), TrackIndex, TrackId);
return false;
}
case EMediaTrackType::Video:
if (VideoTracks.IsValidIndex(TrackIndex))
{
TrackId = VideoTracks[TrackIndex].Id;
}
else if (TrackIndex == INDEX_NONE)
{
TrackId = -1;
}
else
{
return false; // invalid track
}
if ((TrackId != -1) && (FVlc::VideoSetTrack(Player, -1) != 0))
{
UE_LOG(LogVlcMedia, Verbose, TEXT("Tracks %p: Failed to disable video decoding"), this);
return false;
}
if (FVlc::VideoSetTrack(Player, TrackId) != 0)
{
UE_LOG(LogVlcMedia, Verbose, TEXT("Tracks %p: Failed to %s video track %i (id %i)"), this, (TrackId == -1) ? TEXT("disable") : TEXT("enable"), TrackIndex, TrackId);
return false;
}
default:
return false; // unsupported track type
}
return true;
}
bool FVlcMediaTracks::SetTrackFormat(EMediaTrackType TrackType, int32 TrackIndex, int32 FormatIndex)
{
if ((Player == nullptr) || (FormatIndex != 0))
{
return false;
}
switch (TrackType)
{
case EMediaTrackType::Audio:
return AudioTracks.IsValidIndex(TrackIndex);
case EMediaTrackType::Caption:
return CaptionTracks.IsValidIndex(TrackIndex);
case EMediaTrackType::Video:
return VideoTracks.IsValidIndex(TrackIndex);
default:
return false;
}
}
#undef LOCTEXT_NAMESPACE
@@ -0,0 +1,73 @@
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
#pragma once
#include "Containers/Array.h"
#include "Containers/UnrealString.h"
#include "IMediaTracks.h"
#include "Internationalization/Text.h"
struct FLibvlcMediaPlayer;
/**
* Implements the track collection for VLC based media players.
*/
class FVlcMediaTracks
: public IMediaTracks
{
struct FTrack
{
FText DisplayName;
int32 Id;
FString Name;
};
public:
/** Default constructor. */
FVlcMediaTracks();
public:
/**
* Initialize this object for the specified VLC media player.
*
* @param InPlayer The VLC media player.
* @param OutInfo Will contain information about the available media tracks.
*/
void Initialize(FLibvlcMediaPlayer& InPlayer, FString& OutInfo);
/** Shut down this object. */
void Shutdown();
public:
//~ IMediaTracks interface
virtual bool GetAudioTrackFormat(int32 TrackIndex, int32 FormatIndex, FMediaAudioTrackFormat& OutFormat) const override;
virtual int32 GetNumTracks(EMediaTrackType TrackType) const override;
virtual int32 GetNumTrackFormats(EMediaTrackType TrackType, int32 TrackIndex) const override;
virtual int32 GetSelectedTrack(EMediaTrackType TrackType) const override;
virtual FText GetTrackDisplayName(EMediaTrackType TrackType, int32 TrackIndex) const override;
virtual int32 GetTrackFormat(EMediaTrackType TrackType, int32 TrackIndex) const override;
virtual FString GetTrackLanguage(EMediaTrackType TrackType, int32 TrackIndex) const override;
virtual FString GetTrackName(EMediaTrackType TrackType, int32 TrackIndex) const override;
virtual bool GetVideoTrackFormat(int32 TrackIndex, int32 FormatIndex, FMediaVideoTrackFormat& OutFormat) const override;
virtual bool SelectTrack(EMediaTrackType TrackType, int32 TrackIndex) override;
virtual bool SetTrackFormat(EMediaTrackType TrackType, int32 TrackIndex, int32 FormatIndex) override;
private:
/** Audio track descriptors. */
TArray<FTrack> AudioTracks;
/** Caption track descriptors. */
TArray<FTrack> CaptionTracks;
/** The VLC media player object. */
FLibvlcMediaPlayer* Player;
/** Video track descriptors. */
TArray<FTrack> VideoTracks;
};
@@ -0,0 +1,138 @@
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
#include "VlcMediaView.h"
#include "VlcMediaPrivate.h"
#include "Vlc.h"
/* FVlcMediaView structors
*****************************************************************************/
FVlcMediaView::FVlcMediaView()
: CurrentFieldOfView(90.0f)
, CurrentOrientation(EForceInit::ForceInit)
, Player(nullptr)
{
Viewpoint = FVlc::VideoNewViewpoint();
if (Viewpoint == nullptr)
{
UE_LOG(LogVlcMedia, Warning, TEXT("Failed to create viewpoint structure; 360 view controls will be unavailable."));
}
}
FVlcMediaView::~FVlcMediaView()
{
if (Viewpoint != nullptr)
{
FVlc::Free(Viewpoint);
Viewpoint = nullptr;
}
}
/* FVlcMediaView interface
*****************************************************************************/
void FVlcMediaView::Initialize(FLibvlcMediaPlayer& InPlayer)
{
Player = &InPlayer;
}
void FVlcMediaView::Shutdown()
{
Player = nullptr;
}
/* IMediaView interface
*****************************************************************************/
bool FVlcMediaView::GetViewField(float& OutHorizontal, float& OutVertical) const
{
OutHorizontal = CurrentFieldOfView;
OutVertical = CurrentFieldOfView;
return true;
}
bool FVlcMediaView::GetViewOrientation(FQuat& OutOrientation) const
{
OutOrientation = CurrentOrientation;
return true;
}
bool FVlcMediaView::SetViewField(float Horizontal, float Vertical, bool Absolute)
{
if ((Player == nullptr) || (Viewpoint == nullptr))
{
return false;
}
if (!Absolute)
{
Horizontal = CurrentFieldOfView + Horizontal;
}
FVector Euler = CurrentOrientation.Euler();
Viewpoint->Roll = Euler.X;
Viewpoint->Pitch = Euler.Y;
Viewpoint->Yaw = Euler.Z;
Viewpoint->FieldOfView = FMath::ClampAngle(Horizontal, 10.0f, 360.0f);
UE_LOG(LogVlcMedia, VeryVerbose, TEXT("Setting viewpoint to %f %f %f / %f."), Viewpoint->Roll, Viewpoint->Pitch, Viewpoint->Roll, Viewpoint->FieldOfView);
if (FVlc::VideoUpdateViewpoint(Player, Viewpoint, true) != 0)
{
return false;
}
CurrentFieldOfView = Horizontal;
return true;
}
bool FVlcMediaView::SetViewOrientation(const FQuat& Orientation, bool Absolute)
{
if ((Player == nullptr) || (Viewpoint == nullptr))
{
return false;
}
FQuat NewOrientation;
if (Absolute)
{
NewOrientation = Orientation;
}
else
{
NewOrientation = Orientation * CurrentOrientation;
}
FVector Euler = NewOrientation.Euler();
Viewpoint->Roll = Euler.X;
Viewpoint->Pitch = Euler.Y;
Viewpoint->Yaw = Euler.Z;
Viewpoint->FieldOfView = CurrentFieldOfView;
UE_LOG(LogVlcMedia, VeryVerbose, TEXT("Setting viewpoint to %f %f %f / %f."), Viewpoint->Roll, Viewpoint->Pitch, Viewpoint->Roll, Viewpoint->FieldOfView);
if (FVlc::VideoUpdateViewpoint(Player, Viewpoint, true) != 0)
{
return false;
}
CurrentOrientation = NewOrientation;
return true;
}
@@ -0,0 +1,59 @@
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
#pragma once
#include "IMediaView.h"
struct FLibvlcMediaPlayer;
struct FLibvlcVideoViewpoint;
/**
* Implements VLC video view settings.
*/
class FVlcMediaView
: public IMediaView
{
public:
/** Default constructor. */
FVlcMediaView();
/** Virtual destructor. */
virtual ~FVlcMediaView();
public:
/**
* Initialize this object for the specified VLC media player.
*
* @param InPlayer The VLC media player.
*/
void Initialize(FLibvlcMediaPlayer& InPlayer);
/** Shut down this object. */
void Shutdown();
public:
//~ IMediaView interface
virtual bool GetViewField(float& OutHorizontal, float& OutVertical) const override;
virtual bool GetViewOrientation(FQuat& OutOrientation) const override;
virtual bool SetViewField(float Horizontal, float Vertical, bool Absolute) override;
virtual bool SetViewOrientation(const FQuat& Orientation, bool Absolute) override;
private:
/** The current field of view (horizontal & vertical). */
float CurrentFieldOfView;
/** The current view orientation. */
FQuat CurrentOrientation;
/** The VLC media player object. */
FLibvlcMediaPlayer* Player;
/** The VLC video viewpoint. */
FLibvlcVideoViewpoint* Viewpoint;
};
@@ -0,0 +1,97 @@
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
#include "VlcMediaUtils.h"
#include "VlcTypes.h"
namespace VlcMedia
{
FString EventToString(FLibvlcEvent* Event)
{
switch (Event->Type)
{
case ELibvlcEventType::MediaMetaChanged: return TEXT("Media Data Changed");
case ELibvlcEventType::MediaSubItemAdded: return TEXT("Media Sub Item Added");
case ELibvlcEventType::MediaDurationChanged: return TEXT("Media Duration Changed");
case ELibvlcEventType::MediaParsedChanged: return TEXT("Media Parsed Changed");
case ELibvlcEventType::MediaFreed: return TEXT("Media Freed");
case ELibvlcEventType::MediaStateChanged: return FString::Printf(TEXT("Media State Changed: %s"), *StateToString(Event->Descriptor.MediaStateChanged.NewState));
case ELibvlcEventType::MediaSubItemTreeAdded: return TEXT("Media Sub Item Tree Added");
case ELibvlcEventType::MediaPlayerMediaChanged: return TEXT("Player Media Changed");
case ELibvlcEventType::MediaPlayerNothingSpecial: return TEXT("Player Nothing Special");
case ELibvlcEventType::MediaPlayerOpening: return TEXT("Player Opening");
case ELibvlcEventType::MediaPlayerBuffering: return FString::Printf(TEXT("Player Buffering: %f"), Event->Descriptor.MediaPlayerBuffering.NewCache);
case ELibvlcEventType::MediaPlayerPlaying: return TEXT("Player Playing");
case ELibvlcEventType::MediaPlayerPaused: return TEXT("Player Paused");
case ELibvlcEventType::MediaPlayerStopped: return TEXT("Player Stopped");
case ELibvlcEventType::MediaPlayerForward: return TEXT("Player Forward");
case ELibvlcEventType::MediaPlayerBackward: return TEXT("Player Backward");
case ELibvlcEventType::MediaPlayerEndReached: return TEXT("Player End Reached");
case ELibvlcEventType::MediaPlayerEncounteredError: return TEXT("Player Encountered Error");
case ELibvlcEventType::MediaPlayerTimeChanged: return FString::Printf(TEXT("Player Time Changed: %s"), *FTimespan::FromMilliseconds(Event->Descriptor.MediaPlayerTimeChanged.NewTime).ToString());
case ELibvlcEventType::MediaPlayerPositionChanged: return FString::Printf(TEXT("Position Changed: %f"), Event->Descriptor.MediaPlayerPositionChanged.NewPosition);
case ELibvlcEventType::MediaPlayerSeekableChanged: return FString::Printf(TEXT("Player Seekable Changed: %s"), Event->Descriptor.MediaPlayerSeekableChanged.new_seekable ? *GTrue.ToString() : *GFalse.ToString());
case ELibvlcEventType::MediaPlayerPausableChanged: return FString::Printf(TEXT("Player Pausable Changed: %s"), Event->Descriptor.MediaPlayerPausableChanged.NewPausable ? *GTrue.ToString() : *GFalse.ToString());
case ELibvlcEventType::MediaPlayerTitleChanged: return FString::Printf(TEXT("Player Title Changed: %s"), Event->Descriptor.MediaPlayerTitleChanged.NewTitle);
case ELibvlcEventType::MediaPlayerSnapshotTaken: return TEXT("Player Snapshot Taken");
case ELibvlcEventType::MediaPlayerLengthChanged: return FString::Printf(TEXT("Player Length Changed: %i"), Event->Descriptor.MediaPlayerLengthChanged.NewLength);
case ELibvlcEventType::MediaPlayerVout: return FString::Printf(TEXT("Player Vout: %i"), Event->Descriptor.MediaPlayerVout.NewCount);
case ELibvlcEventType::MediaPlayerScrambledChanged: return FString::Printf(TEXT("Player Scambled Changed: %s"), Event->Descriptor.MediaPlayerScrambledChanged.NewScrambled ? *GTrue.ToString() : *GFalse.ToString());
case ELibvlcEventType::MediaPlayerESAdded: return TEXT("Player ES Added");
case ELibvlcEventType::MediaPlayerESDeleted: return TEXT("Player ES Deleted");
case ELibvlcEventType::MediaPlayerESSelected: return TEXT("Player ES Selected");
case ELibvlcEventType::MediaListItemAdded: return TEXT("Media List Item Added");
case ELibvlcEventType::MediaListWillAddItem: return TEXT("Media List Will Add Item");
case ELibvlcEventType::MediaListItemDeleted: return TEXT("Media List Item Deleted");
case ELibvlcEventType::MediaListWillDeleteItem: return TEXT("Media List Will Delete Item");
case ELibvlcEventType::MediaListEndReached: return TEXT("Media List End Reached");
case ELibvlcEventType::MediaListViewItemAdded: return TEXT("Media List View Item Added");
case ELibvlcEventType::MediaListViewWillAddItem: return TEXT("Media List View Will Add Item");
case ELibvlcEventType::MediaListViewItemDeleted: return TEXT("Media List View Item Deleted");
case ELibvlcEventType::MediaListViewWillDeleteItem: return TEXT("Media List View Will Delete Item");
case ELibvlcEventType::MediaListPlayerPlayed: return TEXT("Media List Player Played");
case ELibvlcEventType::MediaListPlayerNextItemSet: return TEXT("Media List Player Next Item Set");
case ELibvlcEventType::MediaListPlayerStopped: return TEXT("Media List Player Stopped");
case ELibvlcEventType::MediaDiscovererStarted: return TEXT("Media Discovery Started");
case ELibvlcEventType::MediaDiscovererEnded: return TEXT("Media Discovery Ended");
case ELibvlcEventType::VlmMediaAdded: return TEXT("VLM Media Added");
case ELibvlcEventType::VlmMediaRemoved: return TEXT("VLM Media Removed");
case ELibvlcEventType::VlmMediaChanged: return TEXT("VLM Media Changed");
case ELibvlcEventType::VlmMediaInstanceStarted: return TEXT("VLM Instance Started");
case ELibvlcEventType::VlmMediaInstanceStopped: return TEXT("VLM Instance Stopped");
case ELibvlcEventType::VlmMediaInstanceStatusInit: return TEXT("VLM Instance Status Init");
case ELibvlcEventType::VlmMediaInstanceStatusOpening: return TEXT("VLM Instance Status Opening");
case ELibvlcEventType::VlmMediaInstanceStatusPlaying: return TEXT("VLM Instance Status Playing");
case ELibvlcEventType::VlmMediaInstanceStatusPause: return TEXT("VLM Instance Status Paused");
case ELibvlcEventType::VlmMediaInstanceStatusEnd: return TEXT("VLM Instance Status End");
case ELibvlcEventType::VlmMediaInstanceStatusError: return TEXT("VLM Instance Status Error");
default:
return FString::Printf(TEXT("Unknown event %i"), (int32)Event->Type);
}
}
FString StateToString(ELibvlcState State)
{
switch (State)
{
case ELibvlcState::NothingSpecial: return TEXT("Nothing Special");
case ELibvlcState::Opening: return TEXT("Opening");
case ELibvlcState::Buffering: return TEXT("Buffering");
case ELibvlcState::Playing: return TEXT("Playing");
case ELibvlcState::Paused: return TEXT("Paused");
case ELibvlcState::Stopped: return TEXT("Stopped");
case ELibvlcState::Ended: return TEXT("Ended");
case ELibvlcState::Error: return TEXT("Error");
default:
return FString::Printf(TEXT("Unknown state %i"), (int32)State);
}
}
}
@@ -0,0 +1,29 @@
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
enum class ELibvlcState;
struct FLibvlcEvent;
namespace VlcMedia
{
/**
* Convert a LibVLC event to string.
*
* @param Event The event code to convert.
* @return The corresponding string.
*/
FString EventToString(FLibvlcEvent* Event);
/**
* Convert a LibVLC state to string.
*
* @param Event The state code to convert.
* @return The corresponding string.
*/
FString StateToString(ELibvlcState State);
}
@@ -0,0 +1,306 @@
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
#include "Vlc.h"
#include "VlcMediaPrivate.h"
#include "HAL/PlatformProcess.h"
#include "Interfaces/IPluginManager.h"
#include "Misc/Paths.h"
#define VLC_DEFINE(Func) \
FLibvlc##Func##Proc FVlc::Func = nullptr;
#define VLC_IMPORT(Name, Func) \
Func = (FLibvlc##Func##Proc)FPlatformProcess::GetDllExport(LibHandle, TEXT(#Name)); \
if (Func == nullptr) \
{ \
UE_LOG(LogVlcMedia, Warning, TEXT("Failed to import VLC function %s"), TEXT(#Name)); \
Shutdown(); \
return false; \
}
#define VLCCORE_IMPORT(Name, Func) \
Func = (FLibvlc##Func##Proc)FPlatformProcess::GetDllExport(CoreHandle, TEXT(#Name)); \
if (Func == nullptr) \
{ \
UE_LOG(LogVlcMedia, Warning, TEXT("Failed to import VLC Core function %s"), TEXT(#Name)); \
Shutdown(); \
return false; \
}
/* Static initialization
*****************************************************************************/
void* FVlc::CoreHandle = nullptr;
void* FVlc::LibHandle = nullptr;
FString FVlc::PluginDir;
VLC_DEFINE(New)
VLC_DEFINE(Release)
VLC_DEFINE(Retain)
VLC_DEFINE(Errmsg)
VLC_DEFINE(Clearerr)
VLC_DEFINE(EventAttach)
VLC_DEFINE(EventDetach)
VLC_DEFINE(EventTypeName)
VLC_DEFINE(LogGetContext)
VLC_DEFINE(LogSet)
VLC_DEFINE(LogUnset)
VLC_DEFINE(Free)
VLC_DEFINE(GetChangeset)
VLC_DEFINE(GetCompiler)
VLC_DEFINE(GetVersion)
VLC_DEFINE(Clock)
VLC_DEFINE(MediaEventManager)
VLC_DEFINE(MediaGetDuration)
VLC_DEFINE(MediaGetStats)
VLC_DEFINE(MediaNewCallbacks)
VLC_DEFINE(MediaNewLocation)
VLC_DEFINE(MediaNewPath)
VLC_DEFINE(MediaParseAsync)
VLC_DEFINE(MediaRelease)
VLC_DEFINE(MediaRetain)
VLC_DEFINE(MediaTracksGet)
VLC_DEFINE(MediaTracksRelease)
VLC_DEFINE(MediaPlayerEventManager)
VLC_DEFINE(MediaPlayerGetMedia)
VLC_DEFINE(MediaPlayerNew)
VLC_DEFINE(MediaPlayerNewFromMedia)
VLC_DEFINE(MediaPlayerRelease)
VLC_DEFINE(MediaPlayerRetain)
VLC_DEFINE(MediaPlayerSetMedia)
VLC_DEFINE(MediaPlayerCanPause)
VLC_DEFINE(MediaPlayerGetFps)
VLC_DEFINE(MediaPlayerGetLength)
VLC_DEFINE(MediaPlayerGetPosition)
VLC_DEFINE(MediaPlayerGetRate)
VLC_DEFINE(MediaPlayerGetState)
VLC_DEFINE(MediaPlayerGetTime)
VLC_DEFINE(MediaPlayerIsSeekable)
VLC_DEFINE(MediaPlayerSetPosition)
VLC_DEFINE(MediaPlayerSetRate)
VLC_DEFINE(MediaPlayerSetTime)
VLC_DEFINE(MediaPlayerIsPlaying)
VLC_DEFINE(MediaPlayerPause)
VLC_DEFINE(MediaPlayerPlay)
VLC_DEFINE(MediaPlayerSetPause)
VLC_DEFINE(MediaPlayerStop)
VLC_DEFINE(MediaPlayerWillPlay)
VLC_DEFINE(AudioGetTrack)
VLC_DEFINE(AudioSetCallbacks)
VLC_DEFINE(AudioSetFormat)
VLC_DEFINE(AudioSetFormatCallbacks)
VLC_DEFINE(AudioSetTrack)
VLC_DEFINE(VideoGetHeight)
VLC_DEFINE(VideoGetSize)
VLC_DEFINE(VideoGetSpu)
VLC_DEFINE(VideoGetSpuCount)
VLC_DEFINE(VideoGetTrack)
VLC_DEFINE(VideoNewViewpoint)
VLC_DEFINE(VideoGetWidth)
VLC_DEFINE(VideoSetCallbacks)
VLC_DEFINE(VideoSetFormat)
VLC_DEFINE(VideoSetFormatCallbacks)
VLC_DEFINE(VideoSetSpu)
VLC_DEFINE(VideoSetTrack)
VLC_DEFINE(VideoUpdateViewpoint)
VLC_DEFINE(AudioGetTrackDescription)
VLC_DEFINE(VideoGetSpuDescription)
VLC_DEFINE(VideoGetTrackDescription)
VLC_DEFINE(TrackDescriptionListRelease)
VLC_DEFINE(FourccGetChromaDescription)
/* FVlc static functions
*****************************************************************************/
FString FVlc::GetPluginDir()
{
return PluginDir;
}
bool FVlc::Initialize()
{
// determine directory paths
const FString BaseDir = IPluginManager::Get().FindPlugin("VlcMedia")->GetBaseDir();
const FString VlcDir = FPaths::Combine(*BaseDir, TEXT("ThirdParty"), TEXT("vlc"));
#if PLATFORM_LINUX
const FString LibDir = FPaths::Combine(*VlcDir, TEXT("Linux"), TEXT("x86_64-unknown-linux-gnu"), TEXT("lib"));
#elif PLATFORM_MAC
const FString LibDir = FPaths::Combine(*VlcDir, TEXT("Mac"));
#elif PLATFORM_WINDOWS
#if PLATFORM_64BITS
const FString LibDir = FPaths::Combine(*VlcDir, TEXT("Win64"));
#else
const FString LibDir = FPaths::Combine(*VlcDir, TEXT("Win32"));
#endif
#endif
// load required libraries in the correct order
if (!LoadDependency(LibDir, TEXT("libvlccore"), CoreHandle))
{
return false;
}
if (!LoadDependency(LibDir, TEXT("libvlc"), LibHandle))
{
FreeDependency(CoreHandle);
return false;
}
PluginDir = FPaths::ConvertRelativePathToFull(FPaths::Combine(*LibDir, TEXT("plugins")));
#if PLATFORM_LINUX
PluginDir = FPaths::ConvertRelativePathToFull(FPaths::Combine(*LibDir, TEXT("vlc"), TEXT("plugins")));
#endif
// import library functions
VLC_IMPORT(libvlc_new, New)
VLC_IMPORT(libvlc_release, Release)
VLC_IMPORT(libvlc_retain, Retain)
VLC_IMPORT(libvlc_errmsg, Errmsg)
VLC_IMPORT(libvlc_clearerr, Clearerr)
VLC_IMPORT(libvlc_event_attach, EventAttach)
VLC_IMPORT(libvlc_event_detach, EventDetach)
VLC_IMPORT(libvlc_event_type_name, EventTypeName)
VLC_IMPORT(libvlc_log_get_context, LogGetContext)
VLC_IMPORT(libvlc_log_set, LogSet)
VLC_IMPORT(libvlc_log_unset, LogUnset)
VLC_IMPORT(libvlc_free, Free)
VLC_IMPORT(libvlc_get_changeset, GetChangeset)
VLC_IMPORT(libvlc_get_compiler, GetCompiler)
VLC_IMPORT(libvlc_get_version, GetVersion)
VLC_IMPORT(libvlc_clock, Clock)
VLC_IMPORT(libvlc_media_event_manager, MediaEventManager)
VLC_IMPORT(libvlc_media_get_duration, MediaGetDuration)
VLC_IMPORT(libvlc_media_get_stats, MediaGetStats)
VLC_IMPORT(libvlc_media_new_callbacks, MediaNewCallbacks)
VLC_IMPORT(libvlc_media_new_location, MediaNewLocation)
VLC_IMPORT(libvlc_media_new_path, MediaNewPath)
VLC_IMPORT(libvlc_media_parse_async, MediaParseAsync)
VLC_IMPORT(libvlc_media_release, MediaRelease)
VLC_IMPORT(libvlc_media_retain, MediaRetain)
VLC_IMPORT(libvlc_media_tracks_get, MediaTracksGet)
VLC_IMPORT(libvlc_media_tracks_release, MediaTracksRelease)
VLC_IMPORT(libvlc_media_player_event_manager, MediaPlayerEventManager)
VLC_IMPORT(libvlc_media_player_get_media, MediaPlayerGetMedia)
VLC_IMPORT(libvlc_media_player_new, MediaPlayerNew)
VLC_IMPORT(libvlc_media_player_new_from_media, MediaPlayerNewFromMedia)
VLC_IMPORT(libvlc_media_player_release, MediaPlayerRelease)
VLC_IMPORT(libvlc_media_player_retain, MediaPlayerRetain)
VLC_IMPORT(libvlc_media_player_set_media, MediaPlayerSetMedia)
VLC_IMPORT(libvlc_media_player_can_pause, MediaPlayerCanPause)
VLC_IMPORT(libvlc_media_player_get_fps, MediaPlayerGetFps)
VLC_IMPORT(libvlc_media_player_get_length, MediaPlayerGetLength)
VLC_IMPORT(libvlc_media_player_get_position, MediaPlayerGetPosition)
VLC_IMPORT(libvlc_media_player_get_rate, MediaPlayerGetRate)
VLC_IMPORT(libvlc_media_player_get_state, MediaPlayerGetState)
VLC_IMPORT(libvlc_media_player_get_time, MediaPlayerGetTime)
VLC_IMPORT(libvlc_media_player_is_seekable, MediaPlayerIsSeekable)
VLC_IMPORT(libvlc_media_player_set_position, MediaPlayerSetPosition)
VLC_IMPORT(libvlc_media_player_set_rate, MediaPlayerSetRate)
VLC_IMPORT(libvlc_media_player_set_time, MediaPlayerSetTime)
VLC_IMPORT(libvlc_media_player_is_playing, MediaPlayerIsPlaying)
VLC_IMPORT(libvlc_media_player_pause, MediaPlayerPause)
VLC_IMPORT(libvlc_media_player_play, MediaPlayerPlay)
VLC_IMPORT(libvlc_media_player_set_pause, MediaPlayerSetPause)
VLC_IMPORT(libvlc_media_player_stop, MediaPlayerStop)
VLC_IMPORT(libvlc_media_player_will_play, MediaPlayerWillPlay)
VLC_IMPORT(libvlc_audio_get_track, AudioGetTrack)
VLC_IMPORT(libvlc_audio_set_callbacks, AudioSetCallbacks)
VLC_IMPORT(libvlc_audio_set_format, AudioSetFormat)
VLC_IMPORT(libvlc_audio_set_format_callbacks, AudioSetFormatCallbacks)
VLC_IMPORT(libvlc_audio_set_track, AudioSetTrack)
VLC_IMPORT(libvlc_video_get_height, VideoGetHeight)
VLC_IMPORT(libvlc_video_get_size, VideoGetSize)
VLC_IMPORT(libvlc_video_get_spu, VideoGetSpu)
VLC_IMPORT(libvlc_video_get_spu_count, VideoGetSpuCount)
VLC_IMPORT(libvlc_video_get_track, VideoGetTrack)
VLC_IMPORT(libvlc_video_get_width, VideoGetWidth)
VLC_IMPORT(libvlc_video_new_viewpoint, VideoNewViewpoint)
VLC_IMPORT(libvlc_video_set_callbacks, VideoSetCallbacks)
VLC_IMPORT(libvlc_video_set_format, VideoSetFormat)
VLC_IMPORT(libvlc_video_set_format_callbacks, VideoSetFormatCallbacks)
VLC_IMPORT(libvlc_video_set_spu, VideoSetSpu)
VLC_IMPORT(libvlc_video_set_track, VideoSetTrack)
VLC_IMPORT(libvlc_video_update_viewpoint, VideoUpdateViewpoint)
VLC_IMPORT(libvlc_audio_get_track_description, AudioGetTrackDescription)
VLC_IMPORT(libvlc_video_get_spu_description, VideoGetSpuDescription)
VLC_IMPORT(libvlc_video_get_track_description, VideoGetTrackDescription)
VLC_IMPORT(libvlc_track_description_release, TrackDescriptionListRelease)
// import core functions
VLCCORE_IMPORT(vlc_fourcc_GetChromaDescription, FourccGetChromaDescription)
return true;
}
void FVlc::Shutdown()
{
PluginDir.Empty();
FreeDependency(LibHandle);
FreeDependency(CoreHandle);
}
/* FVlc static functions
*****************************************************************************/
void FVlc::FreeDependency(void*& Handle)
{
if (Handle != nullptr)
{
FPlatformProcess::FreeDllHandle(Handle);
Handle = nullptr;
}
}
bool FVlc::LoadDependency(const FString& Dir, const FString& Name, void*& Handle)
{
FString Lib = Name + TEXT(".") + FPlatformProcess::GetModuleExtension();
FString Path = Dir.IsEmpty() ? *Lib : FPaths::Combine(*Dir, *Lib);
Handle = FPlatformProcess::GetDllHandle(*Path);
if (Handle == nullptr)
{
UE_LOG(LogVlcMedia, Warning, TEXT("Failed to load required library %s. Plug-in will not be functional."), *Lib);
return false;
}
return true;
}
@@ -0,0 +1,133 @@
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "VlcImports.h"
#include "VlcTypes.h"
class FVlc
{
public:
static const uint32 MaxPlanes = 5;
public:
static FString GetPluginDir();
static bool Initialize();
static void Shutdown();
public:
static FLibvlcNewProc New;
static FLibvlcReleaseProc Release;
static FLibvlcRetainProc Retain;
static FLibvlcErrmsgProc Errmsg;
static FLibvlcClearerrProc Clearerr;
static FLibvlcEventAttachProc EventAttach;
static FLibvlcEventAttachProc EventDetach;
static FLibvlcEventTypeNameProc EventTypeName;
static FLibvlcLogGetContextProc LogGetContext;
static FLibvlcLogSetProc LogSet;
static FLibvlcLogUnsetProc LogUnset;
static FLibvlcFreeProc Free;
static FLibvlcGetChangesetProc GetChangeset;
static FLibvlcGetCompilerProc GetCompiler;
static FLibvlcGetVersionProc GetVersion;
static FLibvlcClockProc Clock;
static FLibvlcMediaEventManagerProc MediaEventManager;
static FLibvlcMediaGetDurationProc MediaGetDuration;
static FLibvlcMediaGetStatsProc MediaGetStats;
static FLibvlcMediaNewCallbacksProc MediaNewCallbacks;
static FLibvlcMediaNewLocationProc MediaNewLocation;
static FLibvlcMediaNewPathProc MediaNewPath;
static FLibvlcMediaParseAsyncProc MediaParseAsync;
static FLibvlcMediaReleaseProc MediaRelease;
static FLibvlcMediaRetainProc MediaRetain;
static FLibvlcMediaTracksGetProc MediaTracksGet;
static FLibvlcMediaTracksReleaseProc MediaTracksRelease;
static FLibvlcMediaPlayerEventManagerProc MediaPlayerEventManager;
static FLibvlcMediaPlayerGetMediaProc MediaPlayerGetMedia;
static FLibvlcMediaPlayerNewProc MediaPlayerNew;
static FLibvlcMediaPlayerNewFromMediaProc MediaPlayerNewFromMedia;
static FLibvlcMediaPlayerReleaseProc MediaPlayerRelease;
static FLibvlcMediaPlayerRetainProc MediaPlayerRetain;
static FLibvlcMediaPlayerSetMediaProc MediaPlayerSetMedia;
static FLibvlcMediaPlayerCanPauseProc MediaPlayerCanPause;
static FLibvlcMediaPlayerGetFpsProc MediaPlayerGetFps;
static FLibvlcMediaPlayerGetLengthProc MediaPlayerGetLength;
static FLibvlcMediaPlayerGetPositionProc MediaPlayerGetPosition;
static FLibvlcMediaPlayerGetRateProc MediaPlayerGetRate;
static FLibvlcMediaPlayerGetStateProc MediaPlayerGetState;
static FLibvlcMediaPlayerGetTimeProc MediaPlayerGetTime;
static FLibvlcMediaPlayerIsSeekableProc MediaPlayerIsSeekable;
static FLibvlcMediaPlayerSetPositionProc MediaPlayerSetPosition;
static FLibvlcMediaPlayerSetRateProc MediaPlayerSetRate;
static FLibvlcMediaPlayerSetTimeProc MediaPlayerSetTime;
static FLibvlcMediaPlayerIsPlayingProc MediaPlayerIsPlaying;
static FLibvlcMediaPlayerPauseProc MediaPlayerPause;
static FLibvlcMediaPlayerPlayProc MediaPlayerPlay;
static FLibvlcMediaPlayerSetPauseProc MediaPlayerSetPause;
static FLibvlcMediaPlayerStopProc MediaPlayerStop;
static FLibvlcMediaPlayerWillPlayProc MediaPlayerWillPlay;
static FLibvlcAudioGetTrackProc AudioGetTrack;
static FLibvlcAudioSetCallbacksProc AudioSetCallbacks;
static FLibvlcAudioSetFormatProc AudioSetFormat;
static FLibvlcAudioSetFormatCallbacksProc AudioSetFormatCallbacks;
static FLibvlcAudioSetTrackProc AudioSetTrack;
static FLibvlcVideoGetHeightProc VideoGetHeight;
static FLibvlcVideoGetSizeProc VideoGetSize;
static FLibvlcVideoGetSpuProc VideoGetSpu;
static FLibvlcVideoGetSpuCountProc VideoGetSpuCount;
static FLibvlcVideoGetTrackProc VideoGetTrack;
static FLibvlcVideoGetWidthProc VideoGetWidth;
static FLibvlcVideoNewViewpointProc VideoNewViewpoint;
static FLibvlcVideoSetCallbacksProc VideoSetCallbacks;
static FLibvlcVideoSetFormatProc VideoSetFormat;
static FLibvlcVideoSetFormatCallbacksProc VideoSetFormatCallbacks;
static FLibvlcVideoSetSpuProc VideoSetSpu;
static FLibvlcVideoSetTrackProc VideoSetTrack;
static FLibvlcVideoUpdateViewpointProc VideoUpdateViewpoint;
static FLibvlcAudioGetTrackDescriptionProc AudioGetTrackDescription;
static FLibvlcVideoGetSpuDescriptionProc VideoGetSpuDescription;
static FLibvlcVideoGetTrackDescriptionProc VideoGetTrackDescription;
static FLibvlcTrackDescriptionListReleaseProc TrackDescriptionListRelease;
static FLibvlcFourccGetChromaDescriptionProc FourccGetChromaDescription;
public:
static int64 Delay(int64 Timestamp)
{
return Timestamp - Clock();
}
protected:
static void FreeDependency(void*& Handle);
static bool LoadDependency(const FString& Dir, const FString& Name, void*& Handle);
private:
static void* CoreHandle;
static void* LibHandle;
static FString PluginDir;
#if PLATFORM_WINDOWS
static void* GccHandle;
#endif
};
@@ -0,0 +1,175 @@
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "VlcTypes.h"
// library instance
typedef FLibvlcInstance* (*FLibvlcNewProc)(int32 /*Argc*/, const ANSICHAR* const* /*Argv*/);
typedef void (*FLibvlcReleaseProc)(FLibvlcInstance* /*Instance*/);
typedef void (*FLibvlcRetainProc)(FLibvlcInstance* /*Instance*/);
// error handling
typedef const char* (*FLibvlcErrmsgProc)();
typedef void (*FLibvlcClearerrProc)();
// events
typedef void (*FLibvlcCallback)(FLibvlcEvent* /*Event*/, void* /*UserData*/);
typedef int32 (*FLibvlcEventAttachProc)(FLibvlcEventManager* /*EventManager*/, ELibvlcEventType /*EventType*/, FLibvlcCallback /*Callback*/, void* /*UserData*/);
typedef int32 (*FLibvlcEventDetachProc)(FLibvlcEventManager* /*EventManager*/, ELibvlcEventType /*EventType*/, FLibvlcCallback /*Callback*/, void* /*UserData*/);
typedef const ANSICHAR* (*FLibvlcEventTypeNameProc)(ELibvlcEventType /*EventType*/);
// logging
typedef void (*FLibvlcLogCb)(void* /*Data*/, ELibvlcLogLevel /*Level*/, FLibvlcLog* /*Context*/, const char* /*Format*/, va_list /*Args*/);
typedef void (*FLibvlcLogGetContextProc)(FLibvlcLog* /*Context*/, const char** /*Module*/, const char** /*File*/, unsigned* /*Line*/);
typedef void (*FLibvlcLogSetProc)(FLibvlcInstance* /*Instance*/, FLibvlcLogCb /*Callback*/, void* /*Data*/);
typedef void (*FLibvlcLogUnsetProc)(FLibvlcInstance* /*Instance*/);
// misc
typedef void (*FLibvlcFreeProc)(void* /*Pointer*/);
typedef char* (*FLibvlcGetChangesetProc)();
typedef char* (*FLibvlcGetCompilerProc)();
typedef char* (*FLibvlcGetVersionProc)();
// time
typedef int64 (*FLibvlcClockProc)();
// media callbacks
typedef void (*FLibvlcMediaCloseCb)(void* /*Opaque*/);
typedef int32 (*FLibvlcMediaOpenCb)(void* /*Opaque*/, void** /*OutData*/, uint64* /*OutSize*/);
typedef SSIZE_T (*FLibvlcMediaReadCb)(void* /*Opaque*/, void* /*Buffer*/, SIZE_T /*Length*/);
typedef int32 (*FLibvlcMediaSeekCb)(void* /*Opaque*/, uint64 /*Offset*/);
// media
typedef FLibvlcEventManager* (*FLibvlcMediaEventManagerProc)(FLibvlcMedia* /*Media*/);
typedef int64 (*FLibvlcMediaGetDurationProc)(FLibvlcMedia* /*Media*/);
typedef int (*FLibvlcMediaGetStatsProc)(FLibvlcMedia* /*Media*/, FLibvlcMediaStats* /*Stats*/);
typedef FLibvlcMedia* (*FLibvlcMediaNewCallbacksProc)(
FLibvlcInstance* /*Instance*/,
FLibvlcMediaOpenCb /*OpenCb*/,
FLibvlcMediaReadCb /*ReadCb*/,
FLibvlcMediaSeekCb /*SeekCb*/,
FLibvlcMediaCloseCb /*CloseCb*/,
void* /*Opaque*/);
typedef FLibvlcMedia* (*FLibvlcMediaNewLocationProc)(FLibvlcInstance* /*Instance*/, const ANSICHAR* /*Location*/);
typedef FLibvlcMedia* (*FLibvlcMediaNewPathProc)(FLibvlcInstance* /*Instance*/, const ANSICHAR* /*Path*/);
typedef void (*FLibvlcMediaParseAsyncProc)(FLibvlcMedia* /*Media*/);
typedef void (*FLibvlcMediaReleaseProc)(FLibvlcMedia* /*Media*/);
typedef void (*FLibvlcMediaRetainProc)(FLibvlcMedia* /*Media*/);
typedef uint32 (*FLibvlcMediaTracksGetProc)(FLibvlcMedia* /*Media*/, FLibvlcMediaTrack*** /*OutTracks*/);
typedef void (*FLibvlcMediaTracksReleaseProc)(FLibvlcMediaTrack** /*Tracks*/, uint32 /*Count*/);
// media player
typedef FLibvlcEventManager* (*FLibvlcMediaPlayerEventManagerProc)(FLibvlcMediaPlayer* /*Player*/);
typedef FLibvlcMedia* (*FLibvlcMediaPlayerGetMediaProc)(FLibvlcMediaPlayer* /*Player*/);
typedef FLibvlcMediaPlayer* (*FLibvlcMediaPlayerNewProc)(FLibvlcInstance* /*Instance*/);
typedef FLibvlcMediaPlayer* (*FLibvlcMediaPlayerNewFromMediaProc)(FLibvlcMedia* /*Media*/);
typedef void (*FLibvlcMediaPlayerReleaseProc)(FLibvlcMediaPlayer* /*Player*/);
typedef void (*FLibvlcMediaPlayerRetainProc)(FLibvlcMediaPlayer* /*Player*/);
typedef void (*FLibvlcMediaPlayerSetMediaProc)(FLibvlcMediaPlayer* /*Player*/, FLibvlcMedia* /*Media*/);
// media player status
typedef int32 (*FLibvlcMediaPlayerCanPauseProc)(const FLibvlcMediaPlayer* /*Player*/);
typedef float (*FLibvlcMediaPlayerGetFpsProc)(const FLibvlcMediaPlayer* /*Player*/);
typedef int64 (*FLibvlcMediaPlayerGetLengthProc)(const FLibvlcMediaPlayer* /*Player*/);
typedef float (*FLibvlcMediaPlayerGetPositionProc)(const FLibvlcMediaPlayer* /*Player*/);
typedef float (*FLibvlcMediaPlayerGetRateProc)(const FLibvlcMediaPlayer* /*Player*/);
typedef ELibvlcState (*FLibvlcMediaPlayerGetStateProc)(const FLibvlcMediaPlayer* /*Player*/);
typedef int64 (*FLibvlcMediaPlayerGetTimeProc)(const FLibvlcMediaPlayer* /*Player*/);
typedef int32 (*FLibvlcMediaPlayerIsSeekableProc)(const FLibvlcMediaPlayer* /*Player*/);
typedef void (*FLibvlcMediaPlayerSetPositionProc)(FLibvlcMediaPlayer* /*Player*/, float /*Position*/);
typedef int32 (*FLibvlcMediaPlayerSetRateProc)(FLibvlcMediaPlayer* /*Player*/, float /*Rate*/);
typedef void (*FLibvlcMediaPlayerSetTimeProc)(FLibvlcMediaPlayer* /*Player*/, int64 /*Time*/);
// media player control
typedef int32 (*FLibvlcMediaPlayerIsPlayingProc)(const FLibvlcMediaPlayer* /*Player*/);
typedef void (*FLibvlcMediaPlayerPauseProc)(FLibvlcMediaPlayer* /*Player*/);
typedef int32 (*FLibvlcMediaPlayerPlayProc)(FLibvlcMediaPlayer* /*Player*/);
typedef void (*FLibvlcMediaPlayerSetPauseProc)(FLibvlcMediaPlayer* /*Player*/, int32 /*DoPause*/);
typedef void (*FLibvlcMediaPlayerStopProc)(FLibvlcMediaPlayer* /*Player*/);
typedef int32 (*FLibvlcMediaPlayerWillPlayProc)(FLibvlcMediaPlayer* /*Player*/);
// audio
typedef void (*FLibvlcAudioDrainCb)(void* /*Opaque*/);
typedef void (*FLibvlcAudioFlushCb)(void* /*Opaque*/, int64 /*Timestamp*/);
typedef void (*FLibvlcAudioPauseCb)(void* /*Opaque*/, int64 /*Timestamp*/);
typedef void (*FLibvlcAudioPlayCb)(void* /*Opaque*/, void* /*Samples*/, uint32 /*Count*/, int64 /*Timestamp*/);
typedef void (*FLibvlcAudioResumeCb)(void* /*Opaque*/, int64 /*Timestamp*/);
typedef void (*FLibvlcAudioSetCallbacksProc)(
FLibvlcMediaPlayer* /*Player*/,
FLibvlcAudioPlayCb /*Play*/,
FLibvlcAudioPauseCb /*Pause*/,
FLibvlcAudioResumeCb /*Resume*/,
FLibvlcAudioFlushCb /*Flush*/,
FLibvlcAudioDrainCb /*Drain*/,
void* /*Opaque*/);
typedef void (*FLibvlcAudioSetFormatProc)(
FLibvlcMediaPlayer* /*Player*/,
const ANSICHAR* /*Format*/,
uint32 Rate,
uint32 Channels);
typedef int32 (*FLibvlcAudioSetupCb)(void** /*Opaque*/, ANSICHAR* /*Format*/, uint32* /*Rate*/, uint32* /*Channels*/);
typedef void (*FLibvlcAudioCleanupCb)(void* /*Opaque*/);
typedef void (*FLibvlcAudioSetFormatCallbacksProc)(
FLibvlcMediaPlayer* /*Player*/,
FLibvlcAudioSetupCb /*Setup*/,
FLibvlcAudioCleanupCb /*Cleanup*/);
typedef int32 (*FLibvlcAudioGetTrackProc)(FLibvlcMediaPlayer* /*Player*/);
typedef int32 (*FLibvlcAudioSetTrackProc)(FLibvlcMediaPlayer* /*Player*/, int32 /*TrackId*/);
// video
typedef void* (*FLibvlcVideoLockCb)(void* /*Opaque*/, void** /*Planes*/);
typedef void (*FlibvlcVideoUnlockCb)(void* /*Opaque*/, void* /*Picture*/, void* const* /*Planes*/);
typedef void (*FlibvlcVideoDisplayCb)(void* /*Opaque*/, void* /*Picture*/);
typedef void (*FLibvlcVideoSetCallbacksProc)(
FLibvlcMediaPlayer* /*Player*/,
FLibvlcVideoLockCb /*Lock*/,
FlibvlcVideoUnlockCb /*Unlock*/,
FlibvlcVideoDisplayCb /*Display*/,
void* /*Opaque*/);
typedef void (*FLibvlcVideoSetFormatProc)(
FLibvlcMediaPlayer* /*Player*/,
const ANSICHAR* /*Chroma*/,
uint32 /*Width*/,
uint32 /*Height*/,
uint32 /*Pitch*/);
typedef void (*FLibvlcVideoCleanupCb)(void* /*Opaque*/);
typedef uint32 (*FLibvlcVideoFormatCb)(void** /*Opaque*/, ANSICHAR* /*Chroma*/, uint32* /*Width*/, uint32* /*Height*/, uint32* /*Pitches*/, uint32* /*Lines*/);
typedef void (*FLibvlcVideoSetFormatCallbacksProc)(
FLibvlcMediaPlayer* /*Player*/,
FLibvlcVideoFormatCb /*Setup*/,
FLibvlcVideoCleanupCb /*Cleanup*/
);
typedef int32 (*FLibvlcVideoGetHeightProc)(FLibvlcMediaPlayer* /*Player*/);
typedef int32 (*FLibvlcVideoGetSizeProc)(FLibvlcMediaPlayer* /*Player*/, uint32 /*VideoNum*/, uint32* /*Width*/, uint32* /*Height*/);
typedef int32 (*FLibvlcVideoGetSpuProc)(FLibvlcMediaPlayer* /*Player*/);
typedef int32 (*FLibvlcVideoGetSpuCountProc)(FLibvlcMediaPlayer* /*Player*/);
typedef int32 (*FLibvlcVideoGetTrackProc)(FLibvlcMediaPlayer* /*Player*/);
typedef int32(*FLibvlcVideoGetWidthProc)(FLibvlcMediaPlayer* /*Player*/);
typedef FLibvlcVideoViewpoint* (*FLibvlcVideoNewViewpointProc)();
typedef int32 (*FLibvlcVideoSetSpuProc)(FLibvlcMediaPlayer* /*Player*/, int32 /*SpuId*/);
typedef int32 (*FLibvlcVideoSetTrackProc)(FLibvlcMediaPlayer* /*Player*/, int32 /*TrackId*/);
typedef int32 (*FLibvlcVideoUpdateViewpointProc)(FLibvlcMediaPlayer* /*Player*/, FLibvlcVideoViewpoint* /*Viewpoint*/, bool /*Absolute*/);
// tracks
typedef FLibvlcTrackDescription* (*FLibvlcAudioGetTrackDescriptionProc)(FLibvlcMediaPlayer* /*Player*/);
typedef FLibvlcTrackDescription* (*FLibvlcVideoGetSpuDescriptionProc)(FLibvlcMediaPlayer* /*Player*/);
typedef FLibvlcTrackDescription* (*FLibvlcVideoGetTrackDescriptionProc)(FLibvlcMediaPlayer* /*Player*/);
typedef void(*FLibvlcTrackDescriptionListReleaseProc)(FLibvlcTrackDescription* /*Desription*/);
// FourCC
typedef FLibvlcChromaDescription* (*FLibvlcFourccGetChromaDescriptionProc)(FLibvlcFourcc /*Fourcc*/);
@@ -0,0 +1,392 @@
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
/** Enumerates event types. */
enum class ELibvlcEventType
{
MediaMetaChanged = 0,
MediaSubItemAdded,
MediaDurationChanged,
MediaParsedChanged,
MediaFreed,
MediaStateChanged,
MediaSubItemTreeAdded,
MediaPlayerMediaChanged = 0x100,
MediaPlayerNothingSpecial,
MediaPlayerOpening,
MediaPlayerBuffering,
MediaPlayerPlaying,
MediaPlayerPaused,
MediaPlayerStopped,
MediaPlayerForward,
MediaPlayerBackward,
MediaPlayerEndReached,
MediaPlayerEncounteredError,
MediaPlayerTimeChanged,
MediaPlayerPositionChanged,
MediaPlayerSeekableChanged,
MediaPlayerPausableChanged,
MediaPlayerTitleChanged,
MediaPlayerSnapshotTaken,
MediaPlayerLengthChanged,
MediaPlayerVout,
MediaPlayerScrambledChanged,
MediaPlayerESAdded,
MediaPlayerESDeleted,
MediaPlayerESSelected,
MediaListItemAdded = 0x200,
MediaListWillAddItem,
MediaListItemDeleted,
MediaListWillDeleteItem,
MediaListEndReached,
MediaListViewItemAdded = 0x300,
MediaListViewWillAddItem,
MediaListViewItemDeleted,
MediaListViewWillDeleteItem,
MediaListPlayerPlayed = 0x400,
MediaListPlayerNextItemSet,
MediaListPlayerStopped,
MediaDiscovererStarted = 0x500,
MediaDiscovererEnded,
VlmMediaAdded = 0x600,
VlmMediaRemoved,
VlmMediaChanged,
VlmMediaInstanceStarted,
VlmMediaInstanceStopped,
VlmMediaInstanceStatusInit,
VlmMediaInstanceStatusOpening,
VlmMediaInstanceStatusPlaying,
VlmMediaInstanceStatusPause,
VlmMediaInstanceStatusEnd,
VlmMediaInstanceStatusError
};
/** Enumerates logging levels. */
enum class ELibvlcLogLevel
{
Debug = 0,
Notice = 2,
Warning = 3,
Error = 4
};
/** Enumerates meta data types. */
enum class ELibvlcMeta
{
Title,
Artist,
Genre,
Copyright,
Album,
TrackNumber,
Description,
Rating,
Date,
Setting,
URL,
Language,
NowPlaying,
Publisher,
EncodedBy,
ArtworkURL,
TrackID,
TrackTotal,
Director,
Season,
Episode,
ShowName,
Actors,
AlbumArtist,
DiscNumber
};
/** Enumerates possible media player states. */
enum class ELibvlcState
{
NothingSpecial = 0,
Opening,
Buffering,
Playing,
Paused,
Stopped,
Ended,
Error
};
/** Enumerates known track types. */
enum class ELibvlcTrackType
{
Unknown,
Audio,
Video,
Text
};
/** Opaque structure representing a LibVLC event manager. */
typedef struct FLibvlcEventManager FLibvlcEventManager;
/** Opaque structure representing a LibVLC instance. */
typedef struct FLibvlcInstance FLibvlcInstance;
/** Opaque structure representing a LibVLC log context. */
typedef struct FLibvlcLog FLibvlcLog;
/** Opaque structure representing a media instance. */
typedef struct FLibvlcMedia FLibvlcMedia;
/** Opaque structure representing a LibVLC media player. */
typedef struct FLibvlcMediaPlayer FLibvlcMediaPlayer;
/** FourCC code type. */
typedef uint32 FLibvlcFourcc;
/**
* Structure for chroma format descriptions (libvlc_chroma_description_t).
*/
struct FLibvlcChromaDescription
{
uint32 PlaneCount;
struct
{
struct
{
uint32 Num;
uint32 Den;
} W;
struct
{
uint32 Num;
uint32 Den;
} H;
} P[4];
uint32 PixelSize;
uint32 PixelBits;
};
/**
* Structure for VLC events (libvlc_event_t).
*/
struct FLibvlcEvent
{
/** The type of event (see ELibvlcEvents) */
ELibvlcEventType Type;
/** The object emitting the event. */
void *Obj;
union
{
// media descriptor
struct
{
ELibvlcMeta MetaType;
} MediaMetaChanged;
struct
{
FLibvlcMedia* NewChild;
} MediaSubitemAdded;
struct
{
int64 NewDuration;
} MediaDurationChanged;
struct
{
int32 NewStatus;
} MediaParsedChanged;
struct
{
FLibvlcMedia* Md;
} MediaFreed;
struct
{
ELibvlcState NewState;
} MediaStateChanged;
struct
{
FLibvlcMedia* Item;
} MediaSubitemtreeAdded;
// media instance
struct
{
float NewCache;
} MediaPlayerBuffering;
struct
{
float NewPosition;
} MediaPlayerPositionChanged;
struct
{
int64 NewTime;
} MediaPlayerTimeChanged;
struct
{
int32 NewTitle;
} MediaPlayerTitleChanged;
struct
{
int32 new_seekable;
} MediaPlayerSeekableChanged;
struct
{
int32 NewPausable;
} MediaPlayerPausableChanged;
struct
{
int32 NewScrambled;
} MediaPlayerScrambledChanged;
struct
{
int32 NewCount;
} MediaPlayerVout;
// media list
struct
{
FLibvlcMedia* Item;
int32 Index;
} MediaListItemAdded;
struct
{
FLibvlcMedia* Item;
int32 Index;
} MediaListWillAddItem;
struct
{
FLibvlcMedia* Item;
int32 Index;
} MediaListItemDeleted;
struct
{
FLibvlcMedia* Item;
int32 Index;
} MediaListWillDeleteItem;
// media list player
struct
{
FLibvlcMedia* Item;
} MediaListPlayerNextItemSet;
// snapshot taken
struct
{
ANSICHAR* Filename;
} MediaPlayerSnapshotTaken;
// Length changed
struct
{
int64 NewLength;
} MediaPlayerLengthChanged;
// VLM media
struct
{
const ANSICHAR* MediaName;
const ANSICHAR* InstanceName;
} VlmMediaEvent;
// extra MediaPlayer
struct
{
FLibvlcMedia* NewMedia;
} MediaPlayerMediaChanged;
} Descriptor;
};
/**
* Structure for VLC media statistics (libvlc_media_stats).
*/
struct FLibvlcMediaStats
{
int32 ReadBytes;
float InputBitrate;
int32 DemuxReadBytes;
float DemuxBitrate;
int32 DemuxCorrupted;
int32 DemuxDiscontinuity;
int32 DecodedVideo;
int32 DecodedAudio;
int32 DisplayedPictures;
int32 LostPictures;
int32 PlayedAbuffers;
int32 LostAbuffers;
int32 SentPackets;
int32 SentBytes;
float SendBitrate;
};
/**
* Structure for VLC media tracks (libvlc_media_track).
*/
struct FLibvlcMediaTrack
{
uint32 Codec;
uint32 OriginalFourCC;
int32 Id;
ELibvlcTrackType Type;
int32 Profile;
int32 Level;
};
/**
* Structure for VLC media track descriptions (libvlc_track_t).
*/
struct FLibvlcTrackDescription
{
int32 Id;
ANSICHAR* Name;
FLibvlcTrackDescription* Next;
};
/**
* Structure for VLC video viewpoints (libvlc_video_viewpoint_t).
*/
struct FLibvlcVideoViewpoint
{
float Yaw;
float Pitch;
float Roll;
float FieldOfView;
};
@@ -0,0 +1,245 @@
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
#include "IVlcMediaModule.h"
#include "VlcMediaPrivate.h"
#include "HAL/FileManager.h"
#include "Misc/OutputDeviceFile.h"
#include "Misc/Paths.h"
#include "Modules/ModuleManager.h"
#include "UObject/Class.h"
#include "UObject/UObjectGlobals.h"
#include "UObject/WeakObjectPtr.h"
#include "Vlc.h"
#include "VlcMediaPlayer.h"
DEFINE_LOG_CATEGORY(LogVlcMedia);
#define LOCTEXT_NAMESPACE "FVlcMediaModule"
/**
* Implements the VlcMedia module.
*/
class FVlcMediaModule
: public IVlcMediaModule
{
public:
/** Default constructor. */
FVlcMediaModule()
: Initialized(false)
{ }
public:
//~ IVlcMediaModule interface
virtual TSharedPtr<IMediaPlayer, ESPMode::ThreadSafe> CreatePlayer(IMediaEventSink& EventSink) override
{
if (!Initialized)
{
return nullptr;
}
return MakeShared<FVlcMediaPlayer, ESPMode::ThreadSafe>(EventSink, VlcInstance);
}
public:
//~ IModuleInterface interface
virtual void StartupModule() override
{
// initialize LibVLC
if (!FVlc::Initialize())
{
UE_LOG(LogVlcMedia, Error, TEXT("Failed to initialize LibVLC"));
return;
}
UE_LOG(LogVlcMedia, Log, TEXT("Initialized LibVLC %s (%s - %s)"),
ANSI_TO_TCHAR(FVlc::GetVersion()),
ANSI_TO_TCHAR(FVlc::GetChangeset()),
ANSI_TO_TCHAR(FVlc::GetCompiler())
);
#if UE_BUILD_DEBUG
// backup old log file
const FString LogFilePath = FPaths::Combine(FPaths::ProjectLogDir(), TEXT("vlc.log"));
FOutputDeviceFile::CreateBackupCopy(*LogFilePath);
IFileManager::Get().Delete(*LogFilePath);
#endif
const auto Settings = GetDefault<UVlcMediaSettings>();
// create LibVLC instance
const ANSICHAR* Args[] =
{
// caching
TCHAR_TO_ANSI(*(FString::Printf(TEXT("--disc-caching=%i"), (int32)Settings->DiscCaching.GetTotalMilliseconds()))),
TCHAR_TO_ANSI(*(FString::Printf(TEXT("--file-caching=%i"), (int32)Settings->FileCaching.GetTotalMilliseconds()))),
TCHAR_TO_ANSI(*(FString::Printf(TEXT("--live-caching=%i"), (int32)Settings->LiveCaching.GetTotalMilliseconds()))),
TCHAR_TO_ANSI(*(FString::Printf(TEXT("--network-caching=%i"), (int32)Settings->NetworkCaching.GetTotalMilliseconds()))),
// config
"--ignore-config",
// logging
#if UE_BUILD_DEBUG
"--file-logging",
TCHAR_TO_ANSI(*(FString(TEXT("--logfile=")) + LogFilePath)),
#endif
#if (UE_BUILD_DEBUG || UE_BUILD_DEVELOPMENT)
"--verbose=2",
#else
"--quiet",
#endif
// output
"--aout", "amem",
"--intf", "dummy",
"--text-renderer", "dummy",
"--vout", "vmem",
// performance
"--drop-late-frames",
// undesired features
"--no-disable-screensaver",
"--no-plugins-cache",
"--no-snapshot-preview",
"--no-video-title-show",
#if (UE_BUILD_SHIPPING || UE_BUILD_TEST)
"--no-stats",
#endif
#if PLATFORM_LINUX
"--no-xlib",
#endif
};
int Argc = sizeof(Args) / sizeof(*Args);
VlcInstance = FVlc::New(Argc, Args);
if (VlcInstance == nullptr)
{
UE_LOG(LogVlcMedia, Warning, TEXT("Failed to create VLC instance (%s)"), ANSI_TO_TCHAR(FVlc::Errmsg()));
FVlc::Shutdown();
return;
}
// register logging callback
FVlc::LogSet(VlcInstance, &FVlcMediaModule::HandleVlcLog, nullptr);
Initialized = true;
}
virtual void ShutdownModule() override
{
if (!Initialized)
{
return;
}
Initialized = false;
// unregister logging callback
FVlc::LogUnset(VlcInstance);
// release LibVLC instance
FVlc::Release((FLibvlcInstance*)VlcInstance);
VlcInstance = nullptr;
// shut down LibVLC
FVlc::Shutdown();
}
private:
/** Handles log messages from LibVLC. */
static void HandleVlcLog(void* /*Data*/, ELibvlcLogLevel Level, FLibvlcLog* Context, const char* Format, va_list Args)
{
#if (UE_BUILD_DEBUG || UE_BUILD_DEVELOPMENT)
const auto Settings = GetDefault<UVlcMediaSettings>();
// filter unwanted messages
if ((uint8)Level < (uint8)Settings->LogLevel)
{
return;
}
FString LogContext;
// get context information
if (Context != nullptr)
{
const char* Module = nullptr;
const char* File = nullptr;
unsigned Line = 0;
FVlc::LogGetContext(Context, &Module, &File, &Line);
LogContext = FString::Printf(TEXT("%s: "), (Module != nullptr) ? ANSI_TO_TCHAR(Module) : TEXT("unknown module"));
if (Settings->ShowLogContext)
{
LogContext += FString::Printf(TEXT("%s, line %s: "),
(File != nullptr) ? ANSI_TO_TCHAR(File) : TEXT("unknown file"),
(Line != 0) ? *FString::Printf(TEXT("%i"), Line) : TEXT("n/a")
);
}
}
else
{
LogContext = TEXT("generic: ");
}
// forward message to log
ANSICHAR Message[1024];
FCStringAnsi::GetVarArgs(Message, ARRAY_COUNT(Message), ARRAY_COUNT(Message) - 1, Format, Args);
switch (Level)
{
case ELibvlcLogLevel::Debug:
UE_LOG(LogVlcMedia, VeryVerbose, TEXT("%s%s"), *LogContext, ANSI_TO_TCHAR(Message));
break;
case ELibvlcLogLevel::Error:
UE_LOG(LogVlcMedia, Error, TEXT("%s%s"), *LogContext, ANSI_TO_TCHAR(Message));
break;
case ELibvlcLogLevel::Notice:
UE_LOG(LogVlcMedia, Verbose, TEXT("%s%s"), *LogContext, ANSI_TO_TCHAR(Message));
break;
case ELibvlcLogLevel::Warning:
UE_LOG(LogVlcMedia, Warning, TEXT("%s%s"), *LogContext, ANSI_TO_TCHAR(Message));
break;
default:
UE_LOG(LogVlcMedia, Log, TEXT("%s%s"), *LogContext, ANSI_TO_TCHAR(Message));
break;
}
#endif
}
private:
/** Whether the module has been initialized. */
bool Initialized;
/** The LibVLC instance. */
FLibvlcInstance* VlcInstance;
};
IMPLEMENT_MODULE(FVlcMediaModule, VlcMedia);
#undef LOCTEXT_NAMESPACE
@@ -0,0 +1,11 @@
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
#pragma once
#include "Logging/LogMacros.h"
#include "../../VlcMediaFactory/Public/VlcMediaSettings.h"
/** Declares a log category for this module. */
DECLARE_LOG_CATEGORY_EXTERN(LogVlcMedia, Log, All);
@@ -0,0 +1,32 @@
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
#pragma once
#include "Modules/ModuleInterface.h"
#include "Templates/SharedPointer.h"
class IMediaEventSink;
class IMediaPlayer;
/**
* Interface for the VlcMedia module.
*/
class IVlcMediaModule
: public IModuleInterface
{
public:
/**
* Create a VideoLAN based media player.
*
* @param EventSink The object that receives media events from the player.
* @return A new media player, or nullptr if a player couldn't be created.
*/
virtual TSharedPtr<IMediaPlayer, ESPMode::ThreadSafe> CreatePlayer(IMediaEventSink& EventSink) = 0;
public:
/** Virtual destructor. */
virtual ~IVlcMediaModule() { }
};
@@ -0,0 +1,92 @@
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
using System.IO;
namespace UnrealBuildTool.Rules
{
using System.IO;
public class VlcMedia : ModuleRules
{
public VlcMedia(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
DynamicallyLoadedModuleNames.AddRange(
new string[] {
"Media",
});
PrivateDependencyModuleNames.AddRange(
new string[] {
"Core",
"CoreUObject",
"MediaUtils",
"Projects",
"RenderCore",
"VlcMediaFactory",
});
PrivateIncludePathModuleNames.AddRange(
new string[] {
"Media",
});
PrivateIncludePaths.AddRange(
new string[] {
"VlcMedia/Private",
"VlcMedia/Private/Player",
"VlcMedia/Private/Shared",
"VlcMedia/Private/Vlc",
});
// add VLC libraries
string BaseDirectory = Path.GetFullPath(Path.Combine(ModuleDirectory, "..", ".."));
string VlcDirectory = Path.Combine(BaseDirectory, "ThirdParty", "vlc", Target.Platform.ToString());
if (Target.Platform == UnrealTargetPlatform.Linux)
{
VlcDirectory = Path.Combine(VlcDirectory, Target.Architecture, "lib");
RuntimeDependencies.Add(Path.Combine(VlcDirectory, "libvlc.so"));
RuntimeDependencies.Add(Path.Combine(VlcDirectory, "libvlc.so.5"));
RuntimeDependencies.Add(Path.Combine(VlcDirectory, "libvlc.so.5.6.0"));
RuntimeDependencies.Add(Path.Combine(VlcDirectory, "libvlccore.so"));
RuntimeDependencies.Add(Path.Combine(VlcDirectory, "libvlccore.so.9"));
RuntimeDependencies.Add(Path.Combine(VlcDirectory, "libvlccore.so.9.0.0"));
}
else if (Target.Platform == UnrealTargetPlatform.Mac)
{
RuntimeDependencies.Add(Path.Combine(VlcDirectory, "libvlc.dylib"));
RuntimeDependencies.Add(Path.Combine(VlcDirectory, "libvlc.5.dylib"));
RuntimeDependencies.Add(Path.Combine(VlcDirectory, "libvlccore.dylib"));
RuntimeDependencies.Add(Path.Combine(VlcDirectory, "libvlccore.9.dylib"));
}
else if (Target.Platform == UnrealTargetPlatform.Win32)
{
RuntimeDependencies.Add(Path.Combine(VlcDirectory, "libvlc.dll"));
RuntimeDependencies.Add(Path.Combine(VlcDirectory, "libvlccore.dll"));
}
else if (Target.Platform == UnrealTargetPlatform.Win64)
{
RuntimeDependencies.Add(Path.Combine(VlcDirectory, "libvlc.dll"));
RuntimeDependencies.Add(Path.Combine(VlcDirectory, "libvlccore.dll"));
}
// add VLC plug-ins
string PluginDirectory = Path.Combine(VlcDirectory, "plugins");
if (Target.Platform == UnrealTargetPlatform.Linux)
{
PluginDirectory = Path.Combine(VlcDirectory, "vlc", "plugins");
}
if (Directory.Exists(PluginDirectory))
{
foreach (string Plugin in Directory.EnumerateFiles(PluginDirectory, "*.*", SearchOption.AllDirectories))
{
RuntimeDependencies.Add(Path.Combine(PluginDirectory, Plugin));
}
}
}
}
}
@@ -0,0 +1,166 @@
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
#include "VlcFileMediaSourceFactory.h"
#include "FileMediaSource.h"
#include "Misc/Paths.h"
/* UVlcFileMediaSourceFactory structors
*****************************************************************************/
UVlcFileMediaSourceFactory::UVlcFileMediaSourceFactory(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
Formats.Add(TEXT("3g2;3GPP2 Multimedia"));
Formats.Add(TEXT("3ga;3GPP Audio"));
Formats.Add(TEXT("3gp;3GP Video Stream"));
Formats.Add(TEXT("3gp2;3GPP Multimedia"));
Formats.Add(TEXT("3gpp;3GPP Media"));
Formats.Add(TEXT("669;UNIS Composer 669 Module"));
Formats.Add(TEXT("a52;Dolby Digital AC-3 Audio"));
Formats.Add(TEXT("aac;MPEG-2 Advanced Audio Coding"));
Formats.Add(TEXT("ac3;Audio Codec 3"));
Formats.Add(TEXT("adt;Audio Data Transport Stream"));
Formats.Add(TEXT("adts;Audio Data Transport Stream"));
Formats.Add(TEXT("aif;Audio Interchange File Format"));
Formats.Add(TEXT("aifc;Compressed Audio Interchange File"));
Formats.Add(TEXT("aiff;Audio Interchange File Format"));
Formats.Add(TEXT("amb;Ambisonics B-Format"));
Formats.Add(TEXT("amr;Adaptive Multi-Rate Codec"));
Formats.Add(TEXT("amv;Anime Music Video"));
Formats.Add(TEXT("aob;DVD-Audio Audio Object"));
Formats.Add(TEXT("ape;AVS Plugin Effects File"));
Formats.Add(TEXT("asf;ASF Media"));
Formats.Add(TEXT("au;Sun Microsystems Audio"));
Formats.Add(TEXT("avi;Audio Video Interleave File"));
Formats.Add(TEXT("awb;AMR-WB Audio"));
Formats.Add(TEXT("bik;Bink Video"));
Formats.Add(TEXT("bin;Binary File"));
Formats.Add(TEXT("caf;Core Audio"));
Formats.Add(TEXT("crf;CRF Video"));
Formats.Add(TEXT("divx;DivX-Encoded Movie"));
Formats.Add(TEXT("drc;DRM Rights Object"));
Formats.Add(TEXT("dts;Digital Theater System"));
Formats.Add(TEXT("dv;Digital Video"));
Formats.Add(TEXT("evo;SeeVogh Player Video Recording"));
Formats.Add(TEXT("f4v;Flash MP4 Video"));
Formats.Add(TEXT("flac;Free Lossless Audio Codec"));
Formats.Add(TEXT("flv;Adobe Flash Video"));
Formats.Add(TEXT("gvi;Google Video"));
Formats.Add(TEXT("gxf;General eXchange Format"));
Formats.Add(TEXT("iso;Disc Image"));
Formats.Add(TEXT("it;Impulse Tracker Module"));
Formats.Add(TEXT("kar;Karaoke MIDI"));
Formats.Add(TEXT("m1v;MPEG-1 Video"));
Formats.Add(TEXT("m2t;HDV Video"));
Formats.Add(TEXT("m2ts;Blu-ray BDAV Video"));
Formats.Add(TEXT("m2v;MPEG-2 Video"));
Formats.Add(TEXT("m4a;MPEG-4 Audio"));
Formats.Add(TEXT("m4b;MPEG-4 Audio Book"));
Formats.Add(TEXT("m4p;iTunes Music Store Audio"));
Formats.Add(TEXT("m5p;MachFive Preset File"));
Formats.Add(TEXT("m4v;iTunes Video"));
Formats.Add(TEXT("mid;MIDI File"));
Formats.Add(TEXT("mka;Matroska Audio"));
Formats.Add(TEXT("mkv;Matroska Video"));
Formats.Add(TEXT("mlp;Meridian Lossless Packing Audio"));
Formats.Add(TEXT("mod;Amiga Music Module"));
Formats.Add(TEXT("mov;Apple QuickTime Movie"));
Formats.Add(TEXT("mp1;MPEG-1 Layer 1 Audio"));
Formats.Add(TEXT("mp2;MPEG-1 Audio"));
Formats.Add(TEXT("mp2v;MPEG-2 Video"));
Formats.Add(TEXT("mp3;MPEG-2 Audio"));
Formats.Add(TEXT("mp4;MPEG-4 Movie"));
Formats.Add(TEXT("mp4v;MPEG-4 Video"));
Formats.Add(TEXT("mpa;MPEG-2 Audio"));
Formats.Add(TEXT("mpc;Musepack Compressed Audio"));
Formats.Add(TEXT("mpe;MPEG Movie"));
Formats.Add(TEXT("mpeg;MPEG Movie"));
Formats.Add(TEXT("mpeg1;MPEG-1 Video"));
Formats.Add(TEXT("mpeg2;MPEG-2 Video"));
Formats.Add(TEXT("mpeg4;MPEG-4 Video"));
Formats.Add(TEXT("mpg;MPEG-2 Movie"));
Formats.Add(TEXT("mpga;MPEG-1 Layer 3 Audio"));
Formats.Add(TEXT("mpv2;MPEG-2 Video Stream"));
Formats.Add(TEXT("mts;AVCHD Video"));
Formats.Add(TEXT("mtv;MTV Video Format"));
Formats.Add(TEXT("mus;Finale Notation File"));
Formats.Add(TEXT("mxf;Material Exchange Format"));
Formats.Add(TEXT("mxg;Miinoto Exchangeable Group File"));
Formats.Add(TEXT("nsc;Windows Media Station"));
Formats.Add(TEXT("nsv;Nullsoft Streaming Video"));
Formats.Add(TEXT("nut;NUT Multimedia Container"));
Formats.Add(TEXT("nuv;NuppelVideo File"));
Formats.Add(TEXT("oga;Ogg Vorbis Audio"));
Formats.Add(TEXT("ogg;Ogg Multimedia"));
Formats.Add(TEXT("ogm;Ogg Multimedia"));
Formats.Add(TEXT("ogv;Ogg Video"));
Formats.Add(TEXT("ogx;Ogg Vorbis Multiplexed Media"));
Formats.Add(TEXT("oma;Sony OpenMG Music"));
Formats.Add(TEXT("opus;Opus Audio"));
Formats.Add(TEXT("qcp;PureVoice Audio"));
Formats.Add(TEXT("ps;Program Stream Container"));
Formats.Add(TEXT("ra;Real Audio"));
Formats.Add(TEXT("ram;Real Audio Metadata"));
Formats.Add(TEXT("rec;Topfield PVR Recording"));
Formats.Add(TEXT("rm;Real Media"));
Formats.Add(TEXT("rmi;RMID MIDI"));
Formats.Add(TEXT("rmvb;Real Media VBR"));
Formats.Add(TEXT("rpl;Toribash Replay File"));
Formats.Add(TEXT("rv;Real Video"));
Formats.Add(TEXT("s3m;ScreamTracker 3 Module"));
Formats.Add(TEXT("sdp;Session Description Protocol"));
Formats.Add(TEXT("sid;Commodore C64 SID File"));
Formats.Add(TEXT("spx;Speex Audio"));
Formats.Add(TEXT("ts;MPEG-2 Transport Stream"));
Formats.Add(TEXT("tak;Tom's Lossless Audio Kompressor"));
Formats.Add(TEXT("thd;Dolby TrueHD Audio Stream"));
Formats.Add(TEXT("thp;Wii/GameCube Video"));
Formats.Add(TEXT("tod;JVC Everio Video Capture"));
Formats.Add(TEXT("tta;True Audio Codec"));
Formats.Add(TEXT("tts;Telerik Trainer Session"));
Formats.Add(TEXT("txd;TXD File"));
Formats.Add(TEXT("ty;Tivo Container"));
Formats.Add(TEXT("vid;Generic Video"));
Formats.Add(TEXT("vob;DVD Video Object"));
Formats.Add(TEXT("voc;Creative Labs Audio"));
Formats.Add(TEXT("vqf;TwinVQ Audio"));
Formats.Add(TEXT("vro;DVD Video Recording Format"));
Formats.Add(TEXT("w64;Sony Wave64 Audio"));
Formats.Add(TEXT("wav;Wave Audio"));
Formats.Add(TEXT("webm;WebM Video"));
Formats.Add(TEXT("wm;Windows Media"));
Formats.Add(TEXT("wma;Windows Media Audio"));
Formats.Add(TEXT("wmv;Windows Media Video"));
Formats.Add(TEXT("wtv;Windows Recorded TV Show"));
Formats.Add(TEXT("wv;WavPack Audio"));
Formats.Add(TEXT("xa;PlayStation Audio"));
Formats.Add(TEXT("xesc;Expression Encoder Screen Capture"));
Formats.Add(TEXT("xm;Fasttracker 2 Extended Module"));
SupportedClass = UFileMediaSource::StaticClass();
bEditorImport = true;
}
/* UFactory overrides
*****************************************************************************/
bool UVlcFileMediaSourceFactory::FactoryCanImport(const FString& Filename)
{
// @hack: disable file extensions that are used in other factories
// @todo gmp: add support for multiple factories per file extension
const FString FileExtension = FPaths::GetExtension(Filename);
return (FileExtension.ToUpper() != FString("WAV"));
}
UObject* UVlcFileMediaSourceFactory::FactoryCreateFile(UClass* InClass, UObject* InParent, FName InName, EObjectFlags Flags, const FString& Filename, const TCHAR* Parms, FFeedbackContext* Warn, bool& bOutOperationCanceled)
{
UFileMediaSource* MediaSource = NewObject<UFileMediaSource>(InParent, InClass, InName, Flags);
MediaSource->SetFilePath(CurrentFilename);
return MediaSource;
}
@@ -0,0 +1,24 @@
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
#pragma once
#include "Factories/Factory.h"
#include "VlcFileMediaSourceFactory.generated.h"
/**
* Implements a factory for UFileMediaSource objects.
*/
UCLASS(hidecategories=Object)
class UVlcFileMediaSourceFactory
: public UFactory
{
GENERATED_UCLASS_BODY()
public:
//~ UFactory Interface
virtual bool FactoryCanImport(const FString& Filename) override;
virtual UObject* FactoryCreateFile(UClass* InClass, UObject* InParent, FName InName, EObjectFlags Flags, const FString& Filename, const TCHAR* Parms, FFeedbackContext* Warn, bool& bOutOperationCanceled) override;
};
@@ -0,0 +1,22 @@
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
#include "Modules/ModuleInterface.h"
#include "Modules/ModuleManager.h"
/**
* Implements the VlcMediaEditor module.
*/
class FVlcMediaEditorModule
: public IModuleInterface
{
public:
//~ IModuleInterface interface
virtual void StartupModule() override { }
virtual void ShutdownModule() override { }
};
IMPLEMENT_MODULE(FVlcMediaEditorModule, VlcMediaEditor);
@@ -0,0 +1,7 @@
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
#pragma once
#include "Runtime/Core/Public/Core.h"
#include "Runtime/CoreUObject/Public/CoreUObject.h"
#include "Runtime/MediaAssets/Public/FileMediaSource.h"
@@ -0,0 +1,25 @@
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
namespace UnrealBuildTool.Rules
{
public class VlcMediaEditor : ModuleRules
{
public VlcMediaEditor(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
PrivateDependencyModuleNames.AddRange(
new string[] {
"Core",
"CoreUObject",
"MediaAssets",
"UnrealEd",
});
PrivateIncludePaths.AddRange(
new string[] {
"VlcMediaEditor/Private",
});
}
}
}
@@ -0,0 +1,358 @@
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
#include "Containers/Array.h"
#include "Containers/UnrealString.h"
#include "IMediaPlayerFactory.h"
#include "IMediaModule.h"
#include "IMediaOptions.h"
#include "Internationalization/Internationalization.h"
#include "Misc/Paths.h"
#include "Modules/ModuleInterface.h"
#include "Modules/ModuleManager.h"
#include "UObject/Class.h"
#include "UObject/NameTypes.h"
#include "UObject/UObjectGlobals.h"
#include "UObject/WeakObjectPtr.h"
#if WITH_EDITOR
#include "ISettingsModule.h"
#include "ISettingsSection.h"
#include "VlcMediaSettings.h"
#endif
#include "../../VlcMedia/Public/IVlcMediaModule.h"
#define LOCTEXT_NAMESPACE "FVlcMediaFactoryModule"
/**
* Implements the VlcMediaFactory module.
*/
class FVlcMediaFactoryModule
: public IMediaPlayerFactory
, public IModuleInterface
{
public:
//~ IMediaPlayerFactory interface
virtual bool CanPlayUrl(const FString& Url, const IMediaOptions* Options, TArray<FText>* OutWarnings, TArray<FText>* OutErrors) const override
{
FString Scheme;
FString Location;
// check scheme
if (!Url.Split(TEXT("://"), &Scheme, &Location, ESearchCase::CaseSensitive))
{
if (OutErrors != nullptr)
{
OutErrors->Add(LOCTEXT("NoSchemeFound", "No URI scheme found"));
}
return false;
}
if (!SupportedUriSchemes.Contains(Scheme))
{
if (OutErrors != nullptr)
{
OutErrors->Add(FText::Format(LOCTEXT("SchemeNotSupported", "The URI scheme '{0}' is not supported"), FText::FromString(Scheme)));
}
return false;
}
// check file extension
if (Scheme == TEXT("file"))
{
const FString Extension = FPaths::GetExtension(Location, false);
if (!SupportedFileExtensions.Contains(Extension))
{
if (OutErrors != nullptr)
{
OutErrors->Add(FText::Format(LOCTEXT("ExtensionNotSupported", "The file extension '{0}' is not supported"), FText::FromString(Extension)));
}
return false;
}
}
// check options
if ((OutWarnings != nullptr) && (Options != nullptr))
{
if (Options->GetMediaOption("PrecacheFile", false) && (Scheme != TEXT("file")))
{
OutWarnings->Add(LOCTEXT("PrecacheFileWarning", "Precaching is supported for local files only"));
}
}
return true;
}
virtual TSharedPtr<IMediaPlayer, ESPMode::ThreadSafe> CreatePlayer(IMediaEventSink& EventSink) override
{
auto VlcMediaModule = FModuleManager::LoadModulePtr<IVlcMediaModule>("VlcMedia");
return (VlcMediaModule != nullptr) ? VlcMediaModule->CreatePlayer(EventSink) : nullptr;
}
virtual FText GetDisplayName() const override
{
return LOCTEXT("MediaPlayerDisplayName", "VideoLAN Player");
}
virtual FName GetPlayerName() const override
{
static FName PlayerName(TEXT("VlcMedia"));
return PlayerName;
}
virtual const TArray<FString>& GetSupportedPlatforms() const override
{
return SupportedPlatforms;
}
virtual bool SupportsFeature(EMediaFeature Feature) const override
{
return ((Feature == EMediaFeature::AudioSamples) ||
(Feature == EMediaFeature::AudioTracks) ||
(Feature == EMediaFeature::CaptionTracks) ||
(Feature == EMediaFeature::Video360) ||
(Feature == EMediaFeature::VideoSamples) ||
(Feature == EMediaFeature::VideoTracks));
}
public:
//~ IModuleInterface interface
virtual void StartupModule() override
{
// supported file extensions
SupportedFileExtensions.Add(TEXT("3g2"));
SupportedFileExtensions.Add(TEXT("3ga"));
SupportedFileExtensions.Add(TEXT("3gp"));
SupportedFileExtensions.Add(TEXT("3gp2"));
SupportedFileExtensions.Add(TEXT("3gpp"));
SupportedFileExtensions.Add(TEXT("669"));
SupportedFileExtensions.Add(TEXT("a52"));
SupportedFileExtensions.Add(TEXT("aac"));
SupportedFileExtensions.Add(TEXT("ac3"));
SupportedFileExtensions.Add(TEXT("adt"));
SupportedFileExtensions.Add(TEXT("adts"));
SupportedFileExtensions.Add(TEXT("aif"));
SupportedFileExtensions.Add(TEXT("aifc"));
SupportedFileExtensions.Add(TEXT("aiff"));
SupportedFileExtensions.Add(TEXT("amb"));
SupportedFileExtensions.Add(TEXT("amr"));
SupportedFileExtensions.Add(TEXT("amv"));
SupportedFileExtensions.Add(TEXT("aob"));
SupportedFileExtensions.Add(TEXT("ape"));
SupportedFileExtensions.Add(TEXT("asf"));
SupportedFileExtensions.Add(TEXT("au"));
SupportedFileExtensions.Add(TEXT("avi"));
SupportedFileExtensions.Add(TEXT("awb"));
SupportedFileExtensions.Add(TEXT("bik"));
SupportedFileExtensions.Add(TEXT("bin"));
SupportedFileExtensions.Add(TEXT("caf"));
SupportedFileExtensions.Add(TEXT("crf"));
SupportedFileExtensions.Add(TEXT("divx"));
SupportedFileExtensions.Add(TEXT("drc"));
SupportedFileExtensions.Add(TEXT("dts"));
SupportedFileExtensions.Add(TEXT("dv"));
SupportedFileExtensions.Add(TEXT("evo"));
SupportedFileExtensions.Add(TEXT("f4v"));
SupportedFileExtensions.Add(TEXT("flac"));
SupportedFileExtensions.Add(TEXT("flv"));
SupportedFileExtensions.Add(TEXT("gvi"));
SupportedFileExtensions.Add(TEXT("gxf"));
SupportedFileExtensions.Add(TEXT("iso"));
SupportedFileExtensions.Add(TEXT("it"));
SupportedFileExtensions.Add(TEXT("kar"));
SupportedFileExtensions.Add(TEXT("m1v"));
SupportedFileExtensions.Add(TEXT("m2t"));
SupportedFileExtensions.Add(TEXT("m2ts"));
SupportedFileExtensions.Add(TEXT("m2v"));
SupportedFileExtensions.Add(TEXT("m4a"));
SupportedFileExtensions.Add(TEXT("m4b"));
SupportedFileExtensions.Add(TEXT("m4p"));
SupportedFileExtensions.Add(TEXT("m4v"));
SupportedFileExtensions.Add(TEXT("m5p"));
SupportedFileExtensions.Add(TEXT("mid"));
SupportedFileExtensions.Add(TEXT("mka"));
SupportedFileExtensions.Add(TEXT("mkv"));
SupportedFileExtensions.Add(TEXT("mlp"));
SupportedFileExtensions.Add(TEXT("mod"));
SupportedFileExtensions.Add(TEXT("mov"));
SupportedFileExtensions.Add(TEXT("mp1"));
SupportedFileExtensions.Add(TEXT("mp2"));
SupportedFileExtensions.Add(TEXT("mp2v"));
SupportedFileExtensions.Add(TEXT("mp3"));
SupportedFileExtensions.Add(TEXT("mp4"));
SupportedFileExtensions.Add(TEXT("mp4v"));
SupportedFileExtensions.Add(TEXT("mpa"));
SupportedFileExtensions.Add(TEXT("mpc"));
SupportedFileExtensions.Add(TEXT("mpe"));
SupportedFileExtensions.Add(TEXT("mpeg"));
SupportedFileExtensions.Add(TEXT("mpeg1"));
SupportedFileExtensions.Add(TEXT("mpeg2"));
SupportedFileExtensions.Add(TEXT("mpeg4"));
SupportedFileExtensions.Add(TEXT("mpg"));
SupportedFileExtensions.Add(TEXT("mpga"));
SupportedFileExtensions.Add(TEXT("mpv2"));
SupportedFileExtensions.Add(TEXT("mts"));
SupportedFileExtensions.Add(TEXT("mtv"));
SupportedFileExtensions.Add(TEXT("mus"));
SupportedFileExtensions.Add(TEXT("mxf"));
SupportedFileExtensions.Add(TEXT("mxg"));
SupportedFileExtensions.Add(TEXT("nsc"));
SupportedFileExtensions.Add(TEXT("nsv"));
SupportedFileExtensions.Add(TEXT("nut"));
SupportedFileExtensions.Add(TEXT("nuv"));
SupportedFileExtensions.Add(TEXT("oga"));
SupportedFileExtensions.Add(TEXT("ogg"));
SupportedFileExtensions.Add(TEXT("ogm"));
SupportedFileExtensions.Add(TEXT("ogv"));
SupportedFileExtensions.Add(TEXT("ogx"));
SupportedFileExtensions.Add(TEXT("oma"));
SupportedFileExtensions.Add(TEXT("opus"));
SupportedFileExtensions.Add(TEXT("qcp"));
SupportedFileExtensions.Add(TEXT("ps"));
SupportedFileExtensions.Add(TEXT("ra"));
SupportedFileExtensions.Add(TEXT("ram"));
SupportedFileExtensions.Add(TEXT("rec"));
SupportedFileExtensions.Add(TEXT("rm"));
SupportedFileExtensions.Add(TEXT("rmi"));
SupportedFileExtensions.Add(TEXT("rmvb"));
SupportedFileExtensions.Add(TEXT("rpl"));
SupportedFileExtensions.Add(TEXT("rv"));
SupportedFileExtensions.Add(TEXT("s3m"));
SupportedFileExtensions.Add(TEXT("sdp"));
SupportedFileExtensions.Add(TEXT("sid"));
SupportedFileExtensions.Add(TEXT("spx"));
SupportedFileExtensions.Add(TEXT("ts"));
SupportedFileExtensions.Add(TEXT("tak"));
SupportedFileExtensions.Add(TEXT("thd"));
SupportedFileExtensions.Add(TEXT("thp"));
SupportedFileExtensions.Add(TEXT("tod"));
SupportedFileExtensions.Add(TEXT("tta"));
SupportedFileExtensions.Add(TEXT("rp"));
SupportedFileExtensions.Add(TEXT("rs"));
SupportedFileExtensions.Add(TEXT("tta"));
SupportedFileExtensions.Add(TEXT("tts"));
SupportedFileExtensions.Add(TEXT("txd"));
SupportedFileExtensions.Add(TEXT("ty"));
SupportedFileExtensions.Add(TEXT("vid"));
SupportedFileExtensions.Add(TEXT("vob"));
SupportedFileExtensions.Add(TEXT("voc"));
SupportedFileExtensions.Add(TEXT("vqf"));
SupportedFileExtensions.Add(TEXT("vro"));
SupportedFileExtensions.Add(TEXT("w64"));
SupportedFileExtensions.Add(TEXT("wav"));
SupportedFileExtensions.Add(TEXT("webm"));
SupportedFileExtensions.Add(TEXT("wm"));
SupportedFileExtensions.Add(TEXT("wma"));
SupportedFileExtensions.Add(TEXT("wmv"));
SupportedFileExtensions.Add(TEXT("wtv"));
SupportedFileExtensions.Add(TEXT("wv"));
SupportedFileExtensions.Add(TEXT("xa"));
SupportedFileExtensions.Add(TEXT("xesc"));
SupportedFileExtensions.Add(TEXT("xm"));
// supported platforms
SupportedPlatforms.Add(TEXT("Linux"));
SupportedPlatforms.Add(TEXT("Mac"));
SupportedPlatforms.Add(TEXT("Windows"));
SupportedPlatforms.Add(TEXT("WinRT"));
// supported schemes
SupportedUriSchemes.Add(TEXT("cdda"));
SupportedUriSchemes.Add(TEXT("dccp"));
SupportedUriSchemes.Add(TEXT("dshow"));
SupportedUriSchemes.Add(TEXT("dvd"));
SupportedUriSchemes.Add(TEXT("file"));
SupportedUriSchemes.Add(TEXT("dvd"));
SupportedUriSchemes.Add(TEXT("ftp"));
SupportedUriSchemes.Add(TEXT("http"));
SupportedUriSchemes.Add(TEXT("https"));
SupportedUriSchemes.Add(TEXT("icyx"));
SupportedUriSchemes.Add(TEXT("itpc"));
SupportedUriSchemes.Add(TEXT("mms"));
SupportedUriSchemes.Add(TEXT("mmsh"));
SupportedUriSchemes.Add(TEXT("mmst"));
SupportedUriSchemes.Add(TEXT("mmsu"));
SupportedUriSchemes.Add(TEXT("mtp"));
SupportedUriSchemes.Add(TEXT("pnm"));
SupportedUriSchemes.Add(TEXT("realrtsp"));
SupportedUriSchemes.Add(TEXT("rtmp"));
SupportedUriSchemes.Add(TEXT("rtp"));
SupportedUriSchemes.Add(TEXT("rtsp"));
SupportedUriSchemes.Add(TEXT("sap"));
SupportedUriSchemes.Add(TEXT("smb"));
SupportedUriSchemes.Add(TEXT("screen"));
SupportedUriSchemes.Add(TEXT("unsv"));
SupportedUriSchemes.Add(TEXT("v4l2"));
SupportedUriSchemes.Add(TEXT("vcd"));
#if WITH_EDITOR
// register settings
ISettingsModule* SettingsModule = FModuleManager::GetModulePtr<ISettingsModule>("Settings");
if (SettingsModule != nullptr)
{
ISettingsSectionPtr SettingsSection = SettingsModule->RegisterSettings("Project", "Plugins", "VlcMedia",
LOCTEXT("VlcMediaSettingsName", "VLC Media"),
LOCTEXT("VlcMediaSettingsDescription", "Configure the VLC Media plug-in."),
GetMutableDefault<UVlcMediaSettings>()
);
}
#endif //WITH_EDITOR
// register player factory
auto MediaModule = FModuleManager::LoadModulePtr<IMediaModule>("Media");
if (MediaModule != nullptr)
{
MediaModule->RegisterPlayerFactory(*this);
}
}
virtual void ShutdownModule() override
{
// unregister player factory
auto MediaModule = FModuleManager::GetModulePtr<IMediaModule>("Media");
if (MediaModule != nullptr)
{
MediaModule->UnregisterPlayerFactory(*this);
}
#if WITH_EDITOR
// unregister settings
ISettingsModule* SettingsModule = FModuleManager::GetModulePtr<ISettingsModule>("Settings");
if (SettingsModule != nullptr)
{
SettingsModule->UnregisterSettings("Project", "Plugins", "VlcMedia");
}
#endif //WITH_EDITOR
}
private:
/** List of supported media file types. */
TArray<FString> SupportedFileExtensions;
/** List of platforms that the media player support. */
TArray<FString> SupportedPlatforms;
/** List of supported URI schemes. */
TArray<FString> SupportedUriSchemes;
};
#undef LOCTEXT_NAMESPACE
IMPLEMENT_MODULE(FVlcMediaFactoryModule, VlcMediaFactory);
@@ -0,0 +1,16 @@
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
#pragma once
#if WITH_EDITOR
#include "Developer/Settings/Public/ISettingsModule.h"
#include "Developer/Settings/Public/ISettingsSection.h"
#endif
#include "Runtime/Core/Public/Core.h"
#include "Runtime/Core/Public/Modules/ModuleManager.h"
#include "Runtime/CoreUObject/Public/CoreUObject.h"
#include "Runtime/Media/Public/IMediaModule.h"
#include "Runtime/Media/Public/IMediaOptions.h"
#include "../../VlcMedia/Public/IVlcMediaModule.h"
@@ -0,0 +1,13 @@
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
#include "VlcMediaSettings.h"
UVlcMediaSettings::UVlcMediaSettings()
: DiscCaching(FTimespan::FromMilliseconds(300.0))
, FileCaching(FTimespan::FromMilliseconds(300.0))
, LiveCaching(FTimespan::FromMilliseconds(300.0))
, NetworkCaching(FTimespan::FromMilliseconds(1000.0))
, LogLevel(EVlcMediaLogLevel::Warning)
, ShowLogContext(false)
{ }
@@ -0,0 +1,75 @@
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreTypes.h"
#include "UObject/Object.h"
#include "UObject/ObjectMacros.h"
#include "VlcMediaSettings.generated.h"
/**
* Available levels for LibVLC log messages.
*/
UENUM()
enum class EVlcMediaLogLevel : uint8
{
/** Error messages. */
Error = 0,
/** Warnings and potential errors. */
Warning = 1,
/** Debug messages. */
Debug = 2,
};
/**
* Settings for the VlcMedia plug-in.
*/
UCLASS(config=Engine)
class VLCMEDIAFACTORY_API UVlcMediaSettings
: public UObject
{
GENERATED_BODY()
public:
/** Default constructor. */
UVlcMediaSettings();
public:
/** Caching duration for optical media (default = 300 ms). */
UPROPERTY(config, EditAnywhere, Category=Caching)
FTimespan DiscCaching;
/** Caching duration for local files (default = 300 ms). */
UPROPERTY(config, EditAnywhere, Category=Caching)
FTimespan FileCaching;
/** Caching duration for cameras and microphones (default = 300 ms). */
UPROPERTY(config, EditAnywhere, Category=Caching)
FTimespan LiveCaching;
/** Caching duration for network resources (default = 1000 ms). */
UPROPERTY(config, EditAnywhere, Category=Caching)
FTimespan NetworkCaching;
public:
/**
* Log level for LibVLC log messages to be forwarded to UE4 log file (default = Warning).
*
* This setting is used only in Debug and Development builds.
* No log entries will written in Shipping and Test builds.
*/
UPROPERTY(config, EditAnywhere, Category=Debugging)
EVlcMediaLogLevel LogLevel;
/** Whether to include file name & line number in LibVLC log messages. */
UPROPERTY(config, EditAnywhere, Category=Debugging)
bool ShowLogContext;
};
@@ -0,0 +1,53 @@
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
namespace UnrealBuildTool.Rules
{
public class VlcMediaFactory : ModuleRules
{
public VlcMediaFactory(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
DynamicallyLoadedModuleNames.AddRange(
new string[] {
"Media",
});
PrivateDependencyModuleNames.AddRange(
new string[] {
"MediaAssets",
});
PrivateIncludePathModuleNames.AddRange(
new string[] {
"Media",
"VlcMedia",
});
PrivateIncludePaths.AddRange(
new string[] {
"VlcMediaFactory/Private",
});
PublicDependencyModuleNames.AddRange(
new string[] {
"Core",
"CoreUObject",
});
if (Target.Type == TargetRules.TargetType.Editor)
{
DynamicallyLoadedModuleNames.Add("Settings");
PrivateIncludePathModuleNames.Add("Settings");
}
if ((Target.Platform == UnrealTargetPlatform.Mac) ||
(Target.Platform == UnrealTargetPlatform.Linux) ||
(Target.Platform == UnrealTargetPlatform.Win32) ||
(Target.Platform == UnrealTargetPlatform.Win64))
{
DynamicallyLoadedModuleNames.Add("VlcMedia");
}
}
}
}
+852
View File
@@ -0,0 +1,852 @@
VideoLAN and the VLC team would like to acknowledge the following contributors:
Programming
-----------
Rémi Denis-Courmont
Jean-Baptiste Kempf
Laurent Aimar
Gildas Bazin
Felix Paul Kühne
Rafaël Carré
Pierre d'Herbemont
Rémi Duraffort
Derk-Jan Hartman
Antoine Cellerier
Samuel Hocevar
Jean-Paul Saman
Christophe Mutricy
Clément Stenac
Christophe Massiot
Ilkka Ollakka
Pierre Ynard
François Cartegnie
Damien Fouilleul
Sigmund Augdal Helberg
Erwan Tulou
David Fuhrmann
Olivier Teulière
Cyril Deguet
Eric Petit
Filippo Carone
Rocky Bernstein
Hugo Beauzée-Luyssen
Olivier Aubert
Pavlov Konstantin
Jakob Leben
Benjamin Pracht
Jean-Philippe André
Steve Lhomme
Stéphane Borel
JP Dinger
Geoffroy Couprie
Martin Storsjö
Marian Ďurkovič
Ludovic Fauvet
Yoann Peronneau
Sébastien Escudier
Jon Lech Johansen
KO Myung-Hun
Edward Wang
Dennis van Amerongen
Faustino Osuna
Mirsal Ennaime
Denis Charmet
Jérôme Decoodt
Loïc Minier
David Flynn
Frédéric Yhuel
Kaarlo Raiha
Mark Moriarty
Christopher Mueller
Fabio Ritrovato
Tony Castley
Srikanth Raju
Michel Kaempf
Jean-Marc Dressler
Johan Bilien
Vincent Seguin
Simon Latapie
Bernie Purcell
Henri Fallon
Sebastien Zwickert
Christoph Miebach
Adrien Maglo
Emmanuel Puig
Renaud Dartus
Alexis de Lattre
Vincent Penquerc'h
Arnaud de Bossoreille de Ribou
Mohammed Adnène Trojette
Boris Dorès
Jai Menon
Anil Daoud
Daniel Mierswa
Naohiro Koriyama
Rob Jonson
Pierre Baillet
Dominique Leuenberger
Andre Pang
Zoran Turalija
Akash Mehrotra
André Weber
Anthony Loiseau
Lukas Durfina
Xavier Marchesini
Cyril Mathé
Devin Heitmueller
Juho Vähä-Herttua
Ken Self
Alexis Ballier
Juha Jeronen
Nicolas Chauvet
Richard Hosking
Éric Lassauge
Marc Ariberti
Sébastien Toque
Tobias Güntner
Benoit Steiner
Michel Lespinasse
Carlo Calabrò
Cheng Sun
Michał Trzebiatowski
Brad Smith
Brendon Justin
Alexey Sokolov
Basos G
Philippe Morin
Steinar H. Gunderson
Vicente Jimenez Aguilar
Yuval Tze
Yves Duret
Benjamin Drung
Michael Hanselmann
Alex Merry
Damien Lucas
Grigori Goronzy
Richard Shepherd
Gaël Hendryckx
Michael Feurstein
Stephan Assmus
Adrien Grand
Colin Guthrie
David Menestrina
Dominique Martinet
Gleb Pinigin
Jason Luka
Luc Saillard
Luca Barbato
Mario Speiß
Pankaj Yadav
Ramiro Polla
Ronald Wright
Rui Zhang
Can Wu
Christophe Courtaut
FUJISAWA Tooru
Hannes Domani
Manol Manolov
Timothy B. Terriberry
Antoine Lejeune
Arnaud Schauly
Branko Kokanovic
Dylan Yudaken
Florian G. Pflug
François Revol
G Finch
Keary Griffin
Konstanty Bialkowski
Ming Hu
Philippe Coent
Przemyslaw Fiala
Tanguy Krotoff
Vianney BOYER
Casian Andrei
Chris Smowton
David Kaplan
Eugenio Jarosiewicz
Fabian Keil
Guillaume Poussel
John Peterson
Justus Piater
Mark Lee
Martin T. H. Sandsmark
Rune Botten
Søren Bøg
Toralf Niebuhr
Tristan Matthews
Angelo Haller
Aurélien Nephtali
Austin Burrow
Bill C. Riemers
Colin Delacroix
Cristian Maglie
Elminster2031
Jakub Wieczorek
John Freed
Mark Hassman
Martin Briza
Mike Houben
Romain Goyet
Adrian Yanes
Alexander Lakhin
Anatoliy Anischovich
Barry Wardell
Ben Hutchings
Besnard Jean-Baptiste
Brian Weaver
Clement Chesnin
David Geldreich
Diego Elio Pettenò
Diego Fernando Nieto
Georgi Chorbadzhiyski
Jon Stacey
Jonathan Rosser
Joris van Rooij
Kaloyan Kovachev
Katsushi Kobayashi
Kelly Anderson
Loren Merritt
Maciej Blizinski
Mark Bidewell
Miguel Angel Cabrera Moya
Niles Bindel
Samuel Pitoiset
Scott Caudle
Sean Robinson
Sergey Radionov
Simon Hailes
Stephen Parry
Sukrit Sangwan
Thierry Reding
Xavier Martin
Alex Converse
Alexander Bethke
Alexandre Ratchov
Andres Krapf
Andrey Utkin
Andri Pálsson
Andy Chenee
Anuradha Suraparaju
Benjamin Poulain
Brieuc Jeunhomme
Chris Clayton
Clément Lecigne
Cédric Cocquebert
Daniel Peng
Danny Wood
David K
Edouard Gomez
Emmanuel de Roux
Frode Tennebø
GBX
Gaurav Narula
Geraud CONTINSOUZAS
Hugues Fruchet
Jan Winter
Jean-François Massol
Jean-Philippe Grimaldi
Josh Watzman
Kai Lauterbach
Konstantin Bogdanov
Kuan-Chung Chiu
Kuang Rufan
Matthias Dahl
Michael McEll
Michael Ploujnikov
Mike Schrag
Nickolai Zeldovich
Nicolas Bertrand
Niklas Hayer
Olafs Vandāns
Olivier Gambier
Paul Corke
Ron Frederick
Rov Juvano
Sabourin Gilles
Sam Lade
Sandeep Kumar
Sasha Koruga
Sreng Jean
Sven Petai
Tomas Krotil
Tomer Barletz
Tristan Leteurtre
Vittorio Giovara
Wang Bo
maxime Ripard
xxcv
Adam Hoka
Adrian Knoth
Adrien Cunin
Alan Fischer
Alan McCosh
Alex Helfet
Alexander Terentyev
Alexandre Ferreira
Alina Friedrichsen
An L. Ber
Andreas Schlick
Andrew Schubert
Andrey Makhnutin
Arnaud Vallat
Asad Mehmood
Ashok Bhat
Austin English
Baptiste Coudurier
Benoit Calvez
Björn Stenberg
Blake Livingston
Brandon Brooks
Brian Johnson
Brian Kurle
Cezar Elnazli
Chris White
Christian Masus
Christoph Pfister
Christoph Seibert
Christopher Key
Christopher Rath
Claudio Ortelli
Cody Russell
Cristian Morales Vega
Dan Rosenberg
Daniel Marth
Daniel Tisza
Detlef Schroeder
Diego Biurrun
Dominik 'Rathann' Mierzejewski
Duncan Salerno
Edward Sheldrake
Elliot Murphy
Eren Inan Canpolat
Ernest E. Teem III
Etienne Membrives
Fargier Sylvain
Fathi Boudra
Felix Geyer
Filipe Azevedo
Finn Hughes
Florian Hubold
Florian Roeske
Frank Enderle
Frédéric Crozat
Georg Seifert
Gertjan Van Droogenbroeck
Gilles Chanteperdrix
Greg Farrell
Gregory Maxwell
Gwenole Beauchesne
Götz Waschk
Hans-Kristian Arntzen
Harry Sintonen
Iain Wade
Ibraheem Paredath
Isamu Arimoto
Ismael Luceno
James Bates
James Bond
James Turner
Janne Grunau
Janne Kujanpää
Jarmo Torvinen
Jason Scheunemann
Jeff Lu
Jeroen Ost
Joe Taber
Johann Ransay
Johannes Weißl
John Hendrikx
John Stebbins
Jonas Gehring
Joseph S. Atkinson
Juergen Lock
Julien 'Lta' BALLET
Julien / Gellule
Julien Humbert
Kamil Baldyga
Kamil Klimek
Karlheinz Wohlmuth
Kevin Anthony
Kevin DuBois
Lari Natri
Lorenzo Pistone
Lucas C. Villa Real
Lukáš Lalinský
Mal Graty
Malte Tancred
Martin Pöhlmann
Martin Zeman
Marton Balint
Mathew King
Mathieu Sonet
Matthew A. Townsend
Matthias Bauer
Mika Tiainen
Mike Cardillo
Mounir Lamouri (volkmar)
Natanael Copa
Nathan Phillip Brink
Nick Briggs
Nick Pope
Nil Geiswiller
Pascal Thomet
Pere Orga
Peter Bak Nielsen
Phil Roffe and David Grellscheid
Philip Sequeira
Pierre Souchay
Piotr Fusik
Pádraig Brady
R.M
Ralph Giles
Ramon Gabarró
Robert Forsman
Robert Jedrzejczyk
Robert Paciorek
Rolf Ahrenberg
Roman Pen
Ruud Althuizen
Samuli Suominen
Scott Lyons
Sebastian Birk
Sergey Puzanov
Sergio Ammirata
Sharad Dixit
Song Ye Wen
Stephan Krempel
Steven Kramer
Steven Sheehy
Sveinung Kvilhaugsvik
Sylvain Cadhillac
Sylver Bruneau
Takahito HIRANO
Theron Lewis
Thijs Alkemade
Tillmann Karras
Timo Paulssen
Timo Rothenpieler
Tobias Rapp
Tomasen
Tony Vankrunkelsven
Tristan Heaven
Varphone Wong
Vasily Fomin
Vikram Narayanan
Yannick Bréhon
Yavor Doganov
Yohann Martineau
dharani.prabhu.s
suheaven
wucan
김정은
Adam Sampson
Alexander Gall
Alex Antropoff
Alexis Guillard
Alex Izvorski
Amir Gouini
Andrea Guzzo
Andrew Flintham
Andrew Zaikin
Andy Lindsay
Arai/Fujisawa Tooru
Arkadiusz Miskiewicz
Arnaud Gomes-do-Vale
Arwed v. Merkatz
Barak Ori
Basil Achermann
Benjamin Mironer
Bill
Bob Maguire
Brian C. Wiles
Brian Raymond
Brian Robb
Carsten Gottbehüt
Carsten Haitzler
Charles Hordis
Chris Clepper
Christian Henz
Christof Baumgaertner
Christophe Burgalat
Christopher Johnson
Cian Duffy
Colin Simmonds
Damian Ivereigh
Daniel Fischer
Daniel Stränger
Danko Dolch
Dennis Lou
Dermot McGahon
Douglas West
Dugal Harris
Emmanuel Blindauer
Enrico Gueli
Enrique Osuna
Eren Türkay
Eric Dudiak
Espen Skoglund
Ethan C. Baldridge
François Seingier
Frans van Veen
Frédéric Ruget
Gerald Hansink
Gisle Vanem
Glen Gray
Goetz Waschk
Gregory Hazel
Gustaf Neumann
Hang Su
Hans Lambermont
Hans-Peter Jansen
Harris Dugal
Heiko Panther
Igor Helman
Isaac Osunkunle
Jan David Mol
Jan Gerber
Jan Van Boghout
Jasper Alias
Jean-Alexis Montignies
Jean-Baptiste Le Stang
Jeffrey Baker
Jeroen Massar
Jérôme Guilbaud
Johannes Buchner
Johen Michael Zorko
Johnathan Rosser
John Dalgliesh
John Paul Lorenti
Jörg
Joseph Tulou
Julien Blache
Julien Plissonneau Duquène
Julien Robert
Kenneth Ostby
Kenneth Self
Kevin H. Patterson
Koehler, Vitally
K. Staring
Lahiru Lakmal Priyadarshana
Laurent Mutricy
Leo Spalteholz
Loox Thefuture
Marc Nolette
Marco Munderloh
Mark Gritter
Markus Kern
Markus Kuespert
Martin Hamrle
Martin Kahr
Mateus Krepsky Ludwich
Mathias Kretschmer
Mats Rojestal
Matthias P. Nowak
Matthieu Lochegnies
Michael Mondragon
Michael S. Feurstein
Michel Lanners
Mickael Hoerdt
Miguel Angel Cabrera
Mikko Hirvonen
Moritz Bunkus
Nilmoni Deb
Olivier Houchard
Olivier Pomel
Ondrej Kuda aka Albert
Øyvind Kolbu
Pascal Levesque
Patrick Horn
Patrick McLean
Pauline Castets
Paul Mackerras
Peter Surda
Petr Vacek
Philippe Van Hecke
Pierre-Luc Beaudoin
Pierre Marc Dumuid
Régis Duchesne
Remco Poortinga
Rene Gollent
Rob Casey
Robson Braga Araujo
Roine Gustafsson
Roman Bednarek
Rudolf Cornelissen
Sašo Kiselkov
Sebastian Jenny
Shane Harper
Stefán Freyr Stefánsson
Steve Brown
Steven M. Schultz
Tapio Hiltunen
Thomas L. Wood
Thomas Mühlgrabner
Thomas Parmelan
Tim 'O Callagha
Tim Schuerewegen
Tong Ka Man
Torsten Spindler
Udo Richter
Vincent Dimar
Vincent Penne
Vitalijus Slavinskas
Vitaly V. Bursov
Vladimir Chernyshov
Wade Majors
Wallace Wadge
Watanabe Go
William Hawkins
Xavier Maillard
Ye zhang
Yuehua Zhao
Artwork
-------
Damien Erambert
Daniel Dreibrodt, aka aLtgLasS
David Weber
Davor Orel
Dominic Spitaler
Eurodata Computer Club
Geoffrey Roussel
Joeri van Dooren
kty0ne
Max Rudberg
Richard Øiestad
Simon Damkjær Andersen
Tom Bigelajzen
Vincent van den Heuvel
Documentation
-------------
Bill Eldridge
Localization
------------
Abdul Fousan - Tamil
A. Decorte - Friulian
A. Regnander - Swedish
Adem Gunes - Turkish
Adi Nugroho - Tagalog
Adnan Memija - Bosnian
airplanez - Korean
Ajith Manjula - Sinhala
Aled Powell - Welsh
Alexander Didebulidze - Georgian
Alexander Henket - Dutch
Alexander Jansen - Norwegian Bokmål
Alexander Lakhin - Russian
Alexey Lugin - Ukrainian
Alexey Salmin - Russian
Alfred John - Acoli
Amanpreet Singh Alam - Punjabi
André de Barros Martins Ribeiro - Brazilian portuguese
Andrey Brilevskiy - Russian
Andrey Wolk - Russian
Andri Pálsson - Icelandic
Andriy Bandura - Ukrainian
Anh Phan - Vietnamese
Aniket Eknath Kudale - Marathi
Animesh Swar - Nepalese
Aputsiaĸ Niels Janussen - Danish
Ara Bextiyar - Sorani (Kurdish)
Ari Constâncio - Portuguese
Arkadiusz Lipiec - Polish
Ask Hjorth Larsen - Danish
Audrey Prevost - French
Auk Piseth - Khmer
Bayarsaikhan Enkhtaivan Баярсайхан Энхтайван - Mongolian
Biraj Karmakar - Bengali (India)
Bruno Queirós - Portuguese
Bruno Vella - Italian
Caner Başaran - Turkish
Carlo Calabrò - Italian
Chandan Kumar - Hindi
Chesús Daniel Trigo - Aragonese
Christoph Miebach - German
Chynggyz Jumaliev - Kirgyz
Circo Radu - Romanian
Cristian Secară - Romanian
Daniel Nylander - Swedish
Daniel Winzen - German
David González - Spanish
David Planella - Catalan
Dean Lee - Simplified Chinese
Denis Arnaud - Breton
Derk-Jan Hartman - Dutch
DirektX - Hungarian
Dominko Aždajić - Croatian
Dylan Aïssi - French
Đorđe Vasiljević - Serbian
Eduard Babayan - Armenian
Eero - Estonian
Eirik U. Birkeland - Norwegian Nynorsk
Elizabeth Da Conceicao Baptista - Tetum
Emilio Sepúlveda - Interlingua
Emin Mastizada - Azerbaijani
Éric Lassauge - French
Farzaneh Sarafraz - Persian
Florence Tushabe - Chiga
Fouzia Bourai - Arabic
Frank Chao - Traditional Chinese
Freyr Gunnar Ólafsson - Icelandic
Friedel Wolff - Afrikaans
Fumio Nakayama - Japanese
Gabor Kelemen - Hungarian
Gaurav Kumar - Hindi
Gaëtan Rousseaux - Walloon
Ghjuvan Pasquinu - Corsican
Goce Manevski - Macedonian
Golam Maruf Oovee - Bengali
Gonçalo Cordeiro - Galician
Gorana Milicevic - Serbian
Goswami Hardikpuri Kishorpuri - Gujarati
Haakon Meland Eriksen - Norwegian
Han HoJoong - Korean
Hardik Kishorpuri Goswami - Gujarati
Hemanta Nandi - Bengali (India)
Huw Waters - Welsh
H.Shalitha Vikum - Sinhala
Ibrahima Sarr - Fulah
Ingmārs Dīriņš - Latvian
Israt Jahan - Bengali
Ivar Smolin - Estonian
Iván Seoane Pardo - Galician
Ivo Ivanov - Bulgarian
Iñaki Larrañaga Murgoitio - Basque
Iñigo Varela - Asturian; Bable
Jakub Žáček - Czech
James Olweny - Ganda
Jamil Ahmed - Bengali
Javier Varela - Spanish
Jean-Pierre Kuypers - French
Jens Seidel - German
Joao Almeida - Portuguese
Joel Arvidsson - Swedish
jogijs - Latvian
Jonas Larsen - Danish
Jon Stødle - Norwegian Nynorsk
Jouni Kähkönen - Finnish
Juha Jeronen - Finnish
Julen Ruiz Aizpuru - Basque
Kai Hermann - German
Kamil Páral - Czech
Kang Jeong-Hee - Korean
Kasper Tvede - Danish
Kaya Zeren - Turkish
Kenneth Nielsen - Danish
Khin Mi Mi Aung - Burmese
Khoem Sokhem - Khmer
Kola - Albanian
Kypchak Kypchak - Kazakh
Laurent Jonqueres - Occitan
Loba Yeasmeen - Bengali
Lorena Gomes - Catalan
Lorenzo Porta - Italian
Luqman Hakim - Indonesian
L. Balasubramaniam - Hindi
Mahrazi Mohd Kamal - Malay
Manolis Stefanis - Modern Greek
Manuela Silva/Alfredo Silva - Portuguese
Marián Hikaník - Slovak
Mario Siegmann - German
Marko Uskokovic - Serbian
Martin Srebotnjak - Slovenian
Martin Zicha - Czech
Matej Urbančič - Slovenian
Mathias C. Berens, welcome-soft - German
Mattias Põldaru - Estonian
Md. Rezwan Shahid - Bengali
Meelad Zakaria - Persian
Michael Bauer - Scottish Gaelic
Michal Halenka - Czech
Michał Trzebiatowski - Polish
Miguel Sousa - Portuguese
Mihkel Kirjutas - Estonian
Mindaugas Baranauskas - Lithuanian
Miroslav Oujeský - Czech
Morten Brix Pedersen - Danish
Mustafa Sandal - Czech
Myckel Habets - Dutch
Namhyung Kim - Korean
Niels Fanøe - Danish
Niklas 'Nille' Åkerström - Swedish
Olav Dahlum - Norwegian Bokmål
Oleksandr Natalenko - Ukrainian
Omer Ensari - Kurmanji (Kurdish)
Osama Khalid - Arabic
Otto Kekäläinen - Finnish
Paras Nath Chaudhary - Nepali
Pasindu Kavinda - Sinhala
Pau Iranzo - Catalan
Paula Iglesias - Galician
Pedro Valadares - Portuguese
Peter Jespersen - Danish
Petr Šimáček - Czech
Phan Anh - Vietnamese
Philipp Weissenbacher - German
Pittayakom Saingtong - Thai
Prasannajit Acharya - Oriya
Praveen Illa - Telugu
Predrag Ljubenović - Serbian
Pyae Sone - Burmese
Rajnikant Kumbhar - Marathi
Ricardo Perdigão - Portuguese
Ricardo Pérez López - Spanish
Roustam Ghizdatov - Russian
Ruei-Yuan Lu - Traditional Chinese
Saad Liaquat Kiani - Urdu
Sadia Afroz - Bengali
Said Marjan Zazai - Pashto
Salar Khalilzadeh - Persian
Sam Askari - Spanish
Sam Hocevar - British
Samuel Hocevar - French
Saúl Ortega - Spanish
Savvas Nesseris - Modern Greek
Sayan Chowdhury - Hindi
Seanán Ó Coistín - Irish
Semsudin Abdic - Bosnian
Shambhu Kumar - Hindi
Shantanu Sarkar - Hindi
Shashi Ranjan - Hindi
Siarhei Daryichau Дар'ічаў Сяргей - Belarusian
Sidney Doria - Brazilian Portuguese
Sigmund Augdal - Norwegian Bokmål
Simos Xenitellis - Modern Greek
Sipho Sibiya - Zulu
Sok Sophea - Khmer
Solomon Gizaw - Amharic
Sreejith P - Malayalam
Suraj Kawade - Marathi
Stian Jørgensrud - Norwegian Bokmål
Sveinn í Felli - Icelandic
Tadashi Jokagi - Japanese
Tarsem Singh - Hindi
Thanakrit Chomphuming - Thai
Tero Pelander - Finnish
Thomas De Rocker - Dutch
Thomas Graf - gettext support, German
Tomáš Chvátal - Czech
Tòni Galhard - Occitan
Umesh Agarwal - Bengali (India)
Umidjon Almasov - Uzbek
Václav Pavlíček - Czech
Valek Filippov - Russian
Vicente Jimenez Aguilar - Spanish
Vincenzo Reale - Italian
Vít Pelčák - Czech
viyyer - Hindi
Vladimir Yermolayev - Russian
Vojtěch Smejkal - Czech
Wei Mingzhi - Simplified Chinese
Xènia Albà Cantero - Catalan
Xuacu Saturio - Asturian
Yaron Shahrabani - Hebrew
Yaşar Tay - Turkish
Yhal Htet Aung - Burmese
Yogesh K S - Kannada
Yoyo - Simplified Chinese
Yuksel Yildirim - Turkish
Zabeeh Khan - Pashto
Zhang Tong - Chinese
+339
View File
@@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.
File diff suppressed because it is too large Load Diff
+57
View File
@@ -0,0 +1,57 @@
README for the VLC media player
===============================
VLC is a popular libre and open source media player and multimedia engine,
used by a large number of individuals, professionals, companies and
institutions. Using open source technologies and libraries, VLC has been
ported to most computing platforms, including GNU/Linux, Windows, Mac OS X,
BSD, iOS and Android.
VLC can play most multimedia files, discs, streams, allows playback from
devices, and is able to convert to or stream in various formats.
The VideoLAN project was started at the university École Centrale Paris who
relicensed VLC under the GPLv2 license in February 2001. Since then, VLC has
been downloaded close to one billion times.
Links:
======
The VLC web site . . . . . http://www.videolan.org/
Support . . . . . . . . . . http://www.videolan.org/support/
Forums . . . . . . . . . . http://forum.videolan.org/
Wiki . . . . . . . . . . . http://wiki.videolan.org/
The Developers site . . . . http://wiki.videolan.org/Developers_Corner
VLC hacking guide . . . . . http://wiki.videolan.org/Hacker_Guide
Bugtracker . . . . . . . . http://trac.videolan.org/vlc/
The VideoLAN web site . . . http://www.videolan.org/
Source Code Content:
===================
ABOUT-NLS - Notes on the Free Translation Project.
AUTHORS - VLC authors.
COPYING - The GPL license.
COPYING.LIB - The LGPL license.
INSTALL - Installation and building instructions.
NEWS - Important modifications between the releases.
README - This file.
THANKS - VLC contributors.
bin/ - VLC binaries.
bindings/ - libVLC bindings to other languages.
compat/ - compatibility library for operating systems missing
essential functionalities.
contrib/ - Facilities for retrieving external libraries and building
them for systems that don't have the right versions.
doc/ - Miscellaneous documentation.
extras/analyser - Code analyser and editor specific files.
extras/buildsystem - different buildsystems specific files.
extras/misc - Files that don't fit in the other extras/ categories.
extras/package - VLC packaging specific files such as spec files.
extras/tools/ - Facilities for retrieving external building tools needed
for systems that don't have the right versions.
include/ - Header files.
lib/ - libVLC source code.
modules/ - VLC plugins and modules. Most of the code is here.
po/ - VLC translations.
share/ - Common Resources files.
src/ - libvlccore source code.
test/ - testing system.
+106
View File
@@ -0,0 +1,106 @@
Some VLC plugins use external libraries and make extensive use of the
following persons' or companies' code:
FAAD2 - Copyright (c) Nero AG, www.nero.com" - GPLv2 or later
FFmpeg - Copyright (c) 2000-2017 the FFmpeg developers - LGPLv2.1 or later
FluidLite - Copyright (c) 2016 Robin Lobel - LGPLv2.1 or later
FluidSynth - Copyright (c) 2003-2010 Peter Hanappe, Conrad Berhörster, Antoine
Schmitt, Pedro López-Cabanillas, Josh Green, David Henningsson - LGPLv2.1 or
later
Fontconfig - Copyright (c) 2000,2001,2002,2003,2004,2006,2007 Keith Packard,
(c) 2005 Patrick Lam, (c) 2009 Roozbeh Pournader, (c) 2008,2009 Red Hat,
Inc., (c) 2008 Danilo Šegan, (c) 2012 Google, Inc. - MIT License
freetype - David Turner, Robert Wilhelm, and Werner Lemberg - FreeType License
GSM - Copyright (c) 1992 - 1994, 2009 Jutta Degener & Carsten Bormann - GSM
permissive license
GNU FriBidi - Copyright (c) 2004-2012 Behdad Esfahbod, Dov Grobgeld, Roozbeh
Pournader - LGPLv2.1 or later
GnuTLS - Copyright (C) 2000-2012 Free Software Foundation, Inc. - LGPLv2.1 or
later
harfbuzz - Copyright (c) 2010, 2011, 2012 Google, Inc., (c) 2012 Mozilla
Foundation, (c) 2011 Codethink Limited, (c) 2008, 2010 Nokia Corporation
and/or its subsidiary(-ies), (c) 2009 Keith Stribley, (c) 2009 Martin Hosken
and SIL International, (c) 2007 Chris Wilson, (c) 2006 Behdad Esfahbod,
(c) 2005 David Turner, (c) 2004, 2007, 2008, 2009, 2010 Red Hat, Inc.,
(c) 1998-2004 David Turner and Werner Lemberg - Old MIT License
liba52 - Aaron Holtzman & Michel Lespinasse, et al. - GPLv2 or later
libav - Copyright (c) 2000 - 2015 the libav developers - LGPLv2.1 or later
libass - Copyright (c) 2006-2015 Grigori Goronzy et al. - ISC License
libbluray - Copyright (c) 2009-2015 VideoLAN and authors - LGPLv2.1 or later
libcaca - Copyright (c) 2004 Sam Hocevar - WTFPL / LGPLv2.1 or later /
GPLv2 or later / ISC
libdca - Copyright (c) 2004-2007 VideoLAN and authors - GPLv2 or later
libdvbpsi - Copyright (c) 2001-2017 VideoLAN and authors - LGPLv2.1 or later
libdvdcss - Copyright (c) 2001-2017 VideoLAN and authors - GPLv2 or later
libdvdread - GPLv2 or later
libdvdnav - GPLv2 or later
libebml - Copyright (c) 2002-2015 Steve Lhomme - LGPLv2.1 or later
libFLAC - Copyright (c) 2001 - 2014 Josh Coalson et al. - Xiph.org BSD license
libgme - LGPLv2.1 or later
libgpg-error - Copyright 2003, 2004, 2005, 2006, 2007, 2013 g10 Code GmbH
- LGPLv2.1 or later
libkate - Copyright (c) 2008-2011 Vincent Penquerc'h - 3-clause BSD License
liblive555 - Copyright (c) 1996-2015 Live Networks, Inc. - LGPLv2.1 or later
libmad - Copyright (c) 2000-2004 Robert Leslie, et al. - GPLv2 or later
libmatroska - Copyright (c) 2002-2015 Steve Lhomme - LGPLv2.1 or later
libmpeg2 - Aaron Holtzman & Michel Lespinasse, et al. - GPLv2 or later
libmodplug - Oliver Lapicque, Konstanty - Public domain
libogg, libvorbis - Copyright (c) 2002-2015 Xiph.org Foundation - Xiph.org BSD
license
libpostproc - Copyright (C) 2001-2015 Michael Niedermayer, et al. - GPLv2 or
later
libpng - Copyright (c) 2004, 2006-2014 Glenn Randers-Perhson, et al. - libpng
license
libsamplerate - Copyright (c) 2002-2011 Erik de Castro Lopo - GPLv2 or later
libschroedinger - Copyright (c) 2006 BBC and Fluendo - MIT License
libsdl - Copyright (c) 1997-2014 Sam Lantinga et al. - LGPLv2.1 or later
libshout - Copyright (c) 2012 - LGPLv2.1 or later
libtheora - Copyright (c) Xiph.org Foundation - Xiph.org BSD license
libtiff - Copyright (c) 1988-1997 Sam Leffler, (c) 1991-1997 Silicon Graphics,
Inc. - BSD-like
libtwolame - Copyright (c) 2001-2004 Michael Cheng, (c) 2004-2006 The TwoLAME
Project - LGPLv2.1 or later
libupnp - Copyright (c) 2000-2003 Intel Corporation - 3-clause BSD License
libvpx - Copyright (c) 2010-2015, Google Inc. - 3-clause BSD License
libxml2 - Copyright (c) 1998-2014 Daniel Veillard - MIT License
lua - Copyright (c) 1994-2008 Lua.org, PUC-Rio. - MIT License
Musepack decoder library - Copyright (c) 2005-2011, The Musepack Development
Team - 3-clause BSD License
OpenJPEG - Copyright (c) 2002-2014, Communcations and Remote Sensing
Laboratory, UCL, Belgium - ISC License
Opus - Copyright 2001-2013 Xiph.Org, Skype Limited, Octasic, Jean-Marc Valin,
Timothy B. Terriberry, CSIRO, Gregory Maxwell, Mark Borgerding,
Erik de Castro Lopo - Xiph.org BSD License
Sparkle — Andy Matuschak et al. - MIT License
Speex, Speexdsp - Copyright (c) 1992-2015 Xiph.org Foundation, Jean-Marc Valin,
Analog Devices Inc. Commonwealth Scientific and Industrial Research
Organisation, David Row, Jutta Degener, Carsten Bormann - 3-clause BSD
License
taglib - Copyright (c) 2004-2016 Scott Wheeler, et al. - LGPLv2.1 or later
x264 - Copyright (c) 2004-2017 VideoLAN and authors - GPLv2 or later
x265 - Copyright (c) 2004-2015 x265 project - GPLv2 or later
Zapping VBI library - Copyright (c) 2000-2003 Michael H. Schimek, Iñaki García
Etxebarria - LGPLv2.1 or later
zlib - Copyright (c) 1995-2017 Jean-loup Gailly and Mark Adler - zlib license
The VideoLAN team would like to thank the following donators:
Julian Cain, who made a $1000 donation
The French website MacBidouille gave €500 to help us buy a PowerMac G5
The French magazine à vos MAC gave €500 to help us buy a PowerMac G5
Laurent Dupuy, who made a €540 donation
The French company Cybervia (Actech) gave €2000 to pay for webserver hosting
Dennis Perov - Hardware donation
...the following active members of our user community:
Alan Wright
David J LaBarre "DJ"
Eric Adler
Julien Bouquillon
...and code auditors and testers:
David Thiel
Philippe A. aka "Lotesdelère"
Sebastien Chaumat
+42
View File
@@ -0,0 +1,42 @@
{
"FileVersion" : 3,
"FriendlyName" : "VLC Media Player",
"Version" : 14,
"VersionName" : "14.0",
"CreatedBy" : "Epic Games Inc",
"CreatedByURL" : "http://epicgames.com",
"DocsURL" : "https://github.com/ue4plugins/VlcMedia",
"Description" : "Implements a media player using the Video LAN Codec (libvlc).",
"Category" : "Media Players",
"EnabledByDefault" : true,
"IsBetaVersion": true,
"Modules" :
[
{
"Name" : "VlcMedia",
"Type" : "RuntimeNoCommandlet",
"LoadingPhase" : "PreLoadingScreen",
"WhitelistPlatforms" : [ "Linux", "Mac", "Win32", "Win64" ]
},
{
"Name" : "VlcMediaEditor",
"Type" : "Editor",
"LoadingPhase" : "PostEngineInit"
},
{
"Name" : "VlcMediaFactory",
"Type" : "Editor",
"LoadingPhase" : "PostEngineInit"
},
{
"Name": "VlcMediaFactory",
"Type": "RuntimeNoCommandlet",
"LoadingPhase" : "PostEngineInit",
"WhitelistPlatforms" : [ "Linux", "Mac", "Win32", "Win64" ]
}
],
"CanContainContent" : false
}