This still uses CMake, because I am still lazy.
This has been tested on Linux, but I would like to port it to win32 (and so CMake might not be the best)
This is basically a copy of the KDE-playground code and started as the GSoC of last summer
--- /dev/null
+.svn
+Makefile
+CMakeTmp
--- /dev/null
+# - Try to find automoc4
+# Once done this will define
+#
+# AUTOMOC4_FOUND - automoc4 has been found
+# AUTOMOC4_EXECUTABLE - the automoc4 tool
+# AUTOMOC4_VERSION - the full version of automoc4
+# AUTOMOC4_VERSION_MAJOR, AUTOMOC4_VERSION_MINOR, AUTOMOC4_VERSION_PATCH - AUTOMOC4_VERSION
+# broken into its components
+#
+# It also adds the following macros
+# AUTOMOC4(<target> <SRCS_VAR>)
+# Use this to run automoc4 on all files contained in the list <SRCS_VAR>.
+#
+# AUTOMOC4_MOC_HEADERS(<target> header1.h header2.h ...)
+# Use this to add more header files to be processed with automoc4.
+#
+# AUTOMOC4_ADD_EXECUTABLE(<target_NAME> src1 src2 ...)
+# This macro does the same as ADD_EXECUTABLE, but additionally
+# adds automoc4 handling for all source files.
+#
+# AUTOMOC4_ADD_LIBRARY(<target_NAME> src1 src2 ...)
+# This macro does the same as ADD_LIBRARY, but additionally
+# adds automoc4 handling for all source files.
+
+# Internal helper macro, may change or be removed anytime:
+# _ADD_AUTOMOC4_TARGET(<target_NAME> <SRCS_VAR>)
+#
+# Since version 0.9.88:
+# The following two macros are only to be used for KDE4 projects
+# and do something which makes sure automoc4 works for KDE. Don't
+# use them anywhere else.
+# _AUTOMOC4_KDE4_PRE_TARGET_HANDLING(<target_NAME> <SRCS_VAR>)
+# _AUTOMOC4_KDE4_POST_TARGET_HANDLING(<target_NAME>)
+
+
+# Copyright (c) 2008-2009, Alexander Neundorf, <neundorf@kde.org>
+#
+# Redistribution and use is allowed according to the terms of the BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+
+
+# check if we are inside KDESupport and automoc is enabled
+if("${KDESupport_SOURCE_DIR}" STREQUAL "${CMAKE_SOURCE_DIR}")
+ # when building this project as part of kdesupport
+ set(AUTOMOC4_CONFIG_FILE "${KDESupport_SOURCE_DIR}/automoc/Automoc4Config.cmake")
+else("${KDESupport_SOURCE_DIR}" STREQUAL "${CMAKE_SOURCE_DIR}")
+ # when building this project outside kdesupport
+
+ # CMAKE_[SYSTEM_]PREFIX_PATH exists starting with cmake 2.6.0
+ file(TO_CMAKE_PATH "$ENV{CMAKE_PREFIX_PATH}" _env_CMAKE_PREFIX_PATH)
+ file(TO_CMAKE_PATH "$ENV{CMAKE_LIBRARY_PATH}" _env_CMAKE_LIBRARY_PATH)
+
+ find_file(AUTOMOC4_CONFIG_FILE NAMES Automoc4Config.cmake
+ PATH_SUFFIXES automoc4 lib/automoc4 lib64/automoc4
+ PATHS ${_env_CMAKE_PREFIX_PATH} ${CMAKE_PREFIX_PATH} ${CMAKE_SYSTEM_PREFIX_PATH}
+ ${_env_CMAKE_LIBRARY_PATH} ${CMAKE_LIBRARY_PATH} ${CMAKE_SYSTEM_LIBRARY_PATH}
+ ${CMAKE_INSTALL_PREFIX}
+ NO_DEFAULT_PATH )
+endif("${KDESupport_SOURCE_DIR}" STREQUAL "${CMAKE_SOURCE_DIR}")
+
+
+if(AUTOMOC4_CONFIG_FILE)
+ include(${AUTOMOC4_CONFIG_FILE})
+ set(AUTOMOC4_FOUND TRUE)
+else(AUTOMOC4_CONFIG_FILE)
+ set(AUTOMOC4_FOUND FALSE)
+endif(AUTOMOC4_CONFIG_FILE)
+
+if (AUTOMOC4_FOUND)
+ if (NOT Automoc4_FIND_QUIETLY)
+ message(STATUS "Found Automoc4: ${AUTOMOC4_EXECUTABLE}")
+ endif (NOT Automoc4_FIND_QUIETLY)
+else (AUTOMOC4_FOUND)
+ if (Automoc4_FIND_REQUIRED)
+ message(FATAL_ERROR "Did not find automoc4 (part of kdesupport).")
+ else (Automoc4_FIND_REQUIRED)
+ if (NOT Automoc4_FIND_QUIETLY)
+ message(STATUS "Did not find automoc4 (part of kdesupport).")
+ endif (NOT Automoc4_FIND_QUIETLY)
+ endif (Automoc4_FIND_REQUIRED)
+endif (AUTOMOC4_FOUND)
--- /dev/null
+# FIND_PACKAGE_HANDLE_STANDARD_ARGS(NAME (DEFAULT_MSG|"Custom failure message") VAR1 ... )
+#
+# This macro is intended to be used in FindXXX.cmake modules files.
+# It handles the REQUIRED and QUIET argument to FIND_PACKAGE() and
+# it also sets the <UPPERCASED_NAME>_FOUND variable.
+# The package is found if all variables listed are TRUE.
+# Example:
+#
+# FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibXml2 DEFAULT_MSG LIBXML2_LIBRARIES LIBXML2_INCLUDE_DIR)
+#
+# LibXml2 is considered to be found, if both LIBXML2_LIBRARIES and
+# LIBXML2_INCLUDE_DIR are valid. Then also LIBXML2_FOUND is set to TRUE.
+# If it is not found and REQUIRED was used, it fails with FATAL_ERROR,
+# independent whether QUIET was used or not.
+#
+# If it is found, the location is reported using the VAR1 argument, so
+# here a message "Found LibXml2: /usr/lib/libxml2.so" will be printed out.
+# If the second argument is DEFAULT_MSG, the message in the failure case will
+# be "Could NOT find LibXml2", if you don't like this message you can specify
+# your own custom failure message there.
+
+MACRO(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FAIL_MSG _VAR1 )
+
+ IF("${_FAIL_MSG}" STREQUAL "DEFAULT_MSG")
+ IF (${_NAME}_FIND_REQUIRED)
+ SET(_FAIL_MESSAGE "Could not find REQUIRED package ${_NAME}")
+ ELSE (${_NAME}_FIND_REQUIRED)
+ SET(_FAIL_MESSAGE "Could not find OPTIONAL package ${_NAME}")
+ ENDIF (${_NAME}_FIND_REQUIRED)
+ ELSE("${_FAIL_MSG}" STREQUAL "DEFAULT_MSG")
+ SET(_FAIL_MESSAGE "${_FAIL_MSG}")
+ ENDIF("${_FAIL_MSG}" STREQUAL "DEFAULT_MSG")
+
+ STRING(TOUPPER ${_NAME} _NAME_UPPER)
+
+ SET(${_NAME_UPPER}_FOUND TRUE)
+ IF(NOT ${_VAR1})
+ SET(${_NAME_UPPER}_FOUND FALSE)
+ ENDIF(NOT ${_VAR1})
+
+ FOREACH(_CURRENT_VAR ${ARGN})
+ IF(NOT ${_CURRENT_VAR})
+ SET(${_NAME_UPPER}_FOUND FALSE)
+ ENDIF(NOT ${_CURRENT_VAR})
+ ENDFOREACH(_CURRENT_VAR)
+
+ IF (${_NAME_UPPER}_FOUND)
+ IF (NOT ${_NAME}_FIND_QUIETLY)
+ MESSAGE(STATUS "Found ${_NAME}: ${${_VAR1}}")
+ ENDIF (NOT ${_NAME}_FIND_QUIETLY)
+ ELSE (${_NAME_UPPER}_FOUND)
+ IF (${_NAME}_FIND_REQUIRED)
+ MESSAGE(FATAL_ERROR "${_FAIL_MESSAGE}")
+ ELSE (${_NAME}_FIND_REQUIRED)
+ IF (NOT ${_NAME}_FIND_QUIETLY)
+ MESSAGE(STATUS "${_FAIL_MESSAGE}")
+ ENDIF (NOT ${_NAME}_FIND_QUIETLY)
+ ENDIF (${_NAME}_FIND_REQUIRED)
+ ENDIF (${_NAME_UPPER}_FOUND)
+ENDMACRO(FIND_PACKAGE_HANDLE_STANDARD_ARGS)
--- /dev/null
+# - Try to find VLC library
+# Once done this will define
+#
+# VLC_FOUND - system has VLC
+# VLC_INCLUDE_DIR - The VLC include directory
+# VLC_LIBRARIES - The libraries needed to use VLC
+# VLC_DEFINITIONS - Compiler switches required for using VLC
+#
+# Copyright (C) 2008, Tanguy Krotoff <tkrotoff@gmail.com>
+# Copyright (C) 2008, Lukas Durfina <lukas.durfina@gmail.com>
+# Copyright (c) 2009, Fathi Boudra <fboudra@gmail.com>
+#
+# Redistribution and use is allowed according to the terms of the BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+#
+
+if(VLC_INCLUDE_DIR AND VLC_LIBRARIES)
+ # in cache already
+ set(VLC_FIND_QUIETLY TRUE)
+endif(VLC_INCLUDE_DIR AND VLC_LIBRARIES)
+
+# use pkg-config to get the directories and then use these values
+# in the FIND_PATH() and FIND_LIBRARY() calls
+if(NOT WIN32)
+ find_package(PkgConfig)
+ pkg_check_modules(VLC libvlc>=1.0.0)
+ set(VLC_DEFINITIONS ${VLC_CFLAGS})
+endif(NOT WIN32)
+
+# TODO add argument support to pass version on find_package
+include(MacroEnsureVersion)
+macro_ensure_version(1.0.0 ${VLC_VERSION} VLC_VERSION_OK)
+if(VLC_VERSION_OK)
+ set(VLC_FOUND TRUE)
+ message(STATUS "VLC library found")
+else(VLC_VERSION_OK)
+ set(VLC_FOUND FALSE)
+ message(FATAL_ERROR "VLC library not found")
+endif(VLC_VERSION_OK)
+
+find_path(VLC_INCLUDE_DIR
+ NAMES vlc.h
+ PATHS ${VLC_INCLUDE_DIRS}
+ PATH_SUFFIXES vlc)
+
+find_library(VLC_LIBRARIES
+ NAMES vlc
+ PATHS ${VLC_LIBRARY_DIRS})
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(VLC DEFAULT_MSG VLC_INCLUDE_DIR VLC_LIBRARIES)
+
+# show the VLC_INCLUDE_DIR and VLC_LIBRARIES variables only in the advanced view
+mark_as_advanced(VLC_INCLUDE_DIR VLC_LIBRARIES)
--- /dev/null
+# This file defines the following macros for developers to use in ensuring
+# that installed software is of the right version:
+#
+# MACRO_ENSURE_VERSION - test that a version number is greater than
+# or equal to some minimum
+# MACRO_ENSURE_VERSION_RANGE - test that a version number is greater than
+# or equal to some minimum and less than some
+# maximum
+# MACRO_ENSURE_VERSION2 - deprecated, do not use in new code
+#
+
+# MACRO_ENSURE_VERSION
+# This macro compares version numbers of the form "x.y.z" or "x.y"
+# MACRO_ENSURE_VERSION( FOO_MIN_VERSION FOO_VERSION_FOUND FOO_VERSION_OK)
+# will set FOO_VERSION_OK to true if FOO_VERSION_FOUND >= FOO_MIN_VERSION
+# Leading and trailing text is ok, e.g.
+# MACRO_ENSURE_VERSION( "2.5.31" "flex 2.5.4a" VERSION_OK)
+# which means 2.5.31 is required and "flex 2.5.4a" is what was found on the system
+
+# Copyright (c) 2006, David Faure, <faure@kde.org>
+# Copyright (c) 2007, Will Stephenson <wstephenson@kde.org>
+#
+# Redistribution and use is allowed according to the terms of the BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+
+# MACRO_ENSURE_VERSION_RANGE
+# This macro ensures that a version number of the form
+# "x.y.z" or "x.y" falls within a range defined by
+# min_version <= found_version < max_version.
+# If this expression holds, FOO_VERSION_OK will be set TRUE
+#
+# Example: MACRO_ENSURE_VERSION_RANGE3( "0.1.0" ${FOOCODE_VERSION} "0.7.0" FOO_VERSION_OK )
+#
+# This macro will break silently if any of x,y,z are greater than 100.
+#
+# Copyright (c) 2007, Will Stephenson <wstephenson@kde.org>
+#
+# Redistribution and use is allowed according to the terms of the BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+
+# NORMALIZE_VERSION
+# Helper macro to convert version numbers of the form "x.y.z"
+# to an integer equal to 10^4 * x + 10^2 * y + z
+#
+# This macro will break silently if any of x,y,z are greater than 100.
+#
+# Copyright (c) 2006, David Faure, <faure@kde.org>
+# Copyright (c) 2007, Will Stephenson <wstephenson@kde.org>
+#
+# Redistribution and use is allowed according to the terms of the BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+
+# CHECK_RANGE_INCLUSIVE_LOWER
+# Helper macro to check whether x <= y < z
+#
+# Copyright (c) 2007, Will Stephenson <wstephenson@kde.org>
+#
+# Redistribution and use is allowed according to the terms of the BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+
+
+MACRO(NORMALIZE_VERSION _requested_version _normalized_version)
+ STRING(REGEX MATCH "[^0-9]*[0-9]+\\.[0-9]+\\.[0-9]+.*" _threePartMatch "${_requested_version}")
+ if (_threePartMatch)
+ # parse the parts of the version string
+ STRING(REGEX REPLACE "[^0-9]*([0-9]+)\\.[0-9]+\\.[0-9]+.*" "\\1" _major_vers "${_requested_version}")
+ STRING(REGEX REPLACE "[^0-9]*[0-9]+\\.([0-9]+)\\.[0-9]+.*" "\\1" _minor_vers "${_requested_version}")
+ STRING(REGEX REPLACE "[^0-9]*[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" _patch_vers "${_requested_version}")
+ else (_threePartMatch)
+ STRING(REGEX REPLACE "([0-9]+)\\.[0-9]+" "\\1" _major_vers "${_requested_version}")
+ STRING(REGEX REPLACE "[0-9]+\\.([0-9]+)" "\\1" _minor_vers "${_requested_version}")
+ set(_patch_vers "0")
+ endif (_threePartMatch)
+
+ # compute an overall version number which can be compared at once
+ MATH(EXPR ${_normalized_version} "${_major_vers}*10000 + ${_minor_vers}*100 + ${_patch_vers}")
+ENDMACRO(NORMALIZE_VERSION)
+
+MACRO(MACRO_CHECK_RANGE_INCLUSIVE_LOWER _lower_limit _value _upper_limit _ok)
+ if (${_value} LESS ${_lower_limit})
+ set( ${_ok} FALSE )
+ elseif (${_value} EQUAL ${_lower_limit})
+ set( ${_ok} TRUE )
+ elseif (${_value} EQUAL ${_upper_limit})
+ set( ${_ok} FALSE )
+ elseif (${_value} GREATER ${_upper_limit})
+ set( ${_ok} FALSE )
+ else (${_value} LESS ${_lower_limit})
+ set( ${_ok} TRUE )
+ endif (${_value} LESS ${_lower_limit})
+ENDMACRO(MACRO_CHECK_RANGE_INCLUSIVE_LOWER)
+
+MACRO(MACRO_ENSURE_VERSION requested_version found_version var_too_old)
+ NORMALIZE_VERSION( ${requested_version} req_vers_num )
+ NORMALIZE_VERSION( ${found_version} found_vers_num )
+
+ if (found_vers_num LESS req_vers_num)
+ set( ${var_too_old} FALSE )
+ else (found_vers_num LESS req_vers_num)
+ set( ${var_too_old} TRUE )
+ endif (found_vers_num LESS req_vers_num)
+
+ENDMACRO(MACRO_ENSURE_VERSION)
+
+MACRO(MACRO_ENSURE_VERSION2 requested_version2 found_version2 var_too_old2)
+ MACRO_ENSURE_VERSION( ${requested_version2} ${found_version2} ${var_too_old2})
+ENDMACRO(MACRO_ENSURE_VERSION2)
+
+MACRO(MACRO_ENSURE_VERSION_RANGE min_version found_version max_version var_ok)
+ NORMALIZE_VERSION( ${min_version} req_vers_num )
+ NORMALIZE_VERSION( ${found_version} found_vers_num )
+ NORMALIZE_VERSION( ${max_version} max_vers_num )
+
+ MACRO_CHECK_RANGE_INCLUSIVE_LOWER( ${req_vers_num} ${found_vers_num} ${max_vers_num} ${var_ok})
+ENDMACRO(MACRO_ENSURE_VERSION_RANGE)
+
+
--- /dev/null
+# This file defines the Feature Logging macros.
+#
+# MACRO_LOG_FEATURE(VAR FEATURE DESCRIPTION URL [REQUIRED [MIN_VERSION [COMMENTS]]])
+# Logs the information so that it can be displayed at the end
+# of the configure run
+# VAR : TRUE or FALSE, indicating whether the feature is supported
+# FEATURE: name of the feature, e.g. "libjpeg"
+# DESCRIPTION: description what this feature provides
+# URL: home page
+# REQUIRED: TRUE or FALSE, indicating whether the featue is required
+# MIN_VERSION: minimum version number. empty string if unneeded
+# COMMENTS: More info you may want to provide. empty string if unnecessary
+#
+# MACRO_DISPLAY_FEATURE_LOG()
+# Call this to display the collected results.
+# Exits CMake with a FATAL error message if a required feature is missing
+#
+# Example:
+#
+# INCLUDE(MacroLogFeature)
+#
+# FIND_PACKAGE(JPEG)
+# MACRO_LOG_FEATURE(JPEG_FOUND "libjpeg" "Support JPEG images" "http://www.ijg.org" TRUE "3.2a" "")
+# ...
+# MACRO_DISPLAY_FEATURE_LOG()
+
+# Copyright (c) 2006, Alexander Neundorf, <neundorf@kde.org>
+# Copyright (c) 2006, Allen Winter, <winter@kde.org>
+#
+# Redistribution and use is allowed according to the terms of the BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+
+IF (NOT _macroLogFeatureAlreadyIncluded)
+ SET(_file ${CMAKE_BINARY_DIR}/MissingRequirements.txt)
+ IF (EXISTS ${_file})
+ FILE(REMOVE ${_file})
+ ENDIF (EXISTS ${_file})
+
+ SET(_file ${CMAKE_BINARY_DIR}/EnabledFeatures.txt)
+ IF (EXISTS ${_file})
+ FILE(REMOVE ${_file})
+ ENDIF (EXISTS ${_file})
+
+ SET(_file ${CMAKE_BINARY_DIR}/DisabledFeatures.txt)
+ IF (EXISTS ${_file})
+ FILE(REMOVE ${_file})
+ ENDIF (EXISTS ${_file})
+
+ SET(_macroLogFeatureAlreadyIncluded TRUE)
+ENDIF (NOT _macroLogFeatureAlreadyIncluded)
+
+
+MACRO(MACRO_LOG_FEATURE _var _package _description _url ) # _required _minvers _comments)
+
+ SET(_required "${ARGV4}")
+ SET(_minvers "${ARGV5}")
+ SET(_comments "${ARGV6}")
+
+ IF (${_var})
+ SET(_LOGFILENAME ${CMAKE_BINARY_DIR}/EnabledFeatures.txt)
+ ELSE (${_var})
+ IF (${_required} MATCHES "[Tt][Rr][Uu][Ee]")
+ SET(_LOGFILENAME ${CMAKE_BINARY_DIR}/MissingRequirements.txt)
+ ELSE (${_required} MATCHES "[Tt][Rr][Uu][Ee]")
+ SET(_LOGFILENAME ${CMAKE_BINARY_DIR}/DisabledFeatures.txt)
+ ENDIF (${_required} MATCHES "[Tt][Rr][Uu][Ee]")
+ ENDIF (${_var})
+
+ SET(_logtext "+ ${_package}")
+
+ IF (NOT ${_var})
+ IF (${_minvers} MATCHES ".*")
+ SET(_logtext "${_logtext}, ${_minvers}")
+ ENDIF (${_minvers} MATCHES ".*")
+ SET(_logtext "${_logtext}: ${_description} <${_url}>")
+ IF (${_comments} MATCHES ".*")
+ SET(_logtext "${_logtext}\n${_comments}")
+ ENDIF (${_comments} MATCHES ".*")
+# SET(_logtext "${_logtext}\n") #double-space missing features?
+ ENDIF (NOT ${_var})
+ FILE(APPEND "${_LOGFILENAME}" "${_logtext}\n")
+
+ENDMACRO(MACRO_LOG_FEATURE)
+
+
+MACRO(MACRO_DISPLAY_FEATURE_LOG)
+
+ SET(_file ${CMAKE_BINARY_DIR}/MissingRequirements.txt)
+ IF (EXISTS ${_file})
+ FILE(READ ${_file} _requirements)
+ MESSAGE(STATUS "\n-----------------------------------------------------------------------------\n-- The following REQUIRED packages could NOT be located on your system.\n-- Please install them before continuing this software installation.\n-----------------------------------------------------------------------------\n${_requirements}-----------------------------------------------------------------------------")
+ FILE(REMOVE ${_file})
+ MESSAGE(FATAL_ERROR "Exiting: Missing Requirements")
+ ENDIF (EXISTS ${_file})
+
+ SET(_summary "\n")
+
+ SET(_elist 0)
+ SET(_file ${CMAKE_BINARY_DIR}/EnabledFeatures.txt)
+ IF (EXISTS ${_file})
+ SET(_elist 1)
+ FILE(READ ${_file} _enabled)
+ FILE(REMOVE ${_file})
+ SET(_summary "${_summary}-----------------------------------------------------------------------------\n-- The following external packages were located on your system.\n-- This installation will have the extra features provided by these packages.\n${_enabled}")
+ ENDIF (EXISTS ${_file})
+
+ SET(_dlist 0)
+ SET(_file ${CMAKE_BINARY_DIR}/DisabledFeatures.txt)
+ IF (EXISTS ${_file})
+ SET(_dlist 1)
+ FILE(READ ${_file} _disabled)
+ FILE(REMOVE ${_file})
+ SET(_summary "${_summary}-----------------------------------------------------------------------------\n-- The following OPTIONAL packages could NOT be located on your system.\n-- Consider installing them to enable more features from this software.\n${_disabled}")
+ ELSE (EXISTS ${_file})
+ IF (${_elist})
+ SET(_summary "${_summary}Congratulations! All external packages have been found.\n")
+ ENDIF (${_elist})
+ ENDIF (EXISTS ${_file})
+
+ IF (${_elist} OR ${_dlist})
+ SET(_summary "${_summary}-----------------------------------------------------------------------------\n")
+ ENDIF (${_elist} OR ${_dlist})
+ MESSAGE(STATUS "${_summary}")
+
+ENDMACRO(MACRO_DISPLAY_FEATURE_LOG)
--- /dev/null
+# - MACRO_OPTIONAL_FIND_PACKAGE() combines FIND_PACKAGE() with an OPTION()
+# MACRO_OPTIONAL_FIND_PACKAGE( <name> [QUIT] )
+# This macro is a combination of OPTION() and FIND_PACKAGE(), it
+# works like FIND_PACKAGE(), but additionally it automatically creates
+# an option name WITH_<name>, which can be disabled via the cmake GUI.
+# or via -DWITH_<name>=OFF
+# The standard <name>_FOUND variables can be used in the same way
+# as when using the normal FIND_PACKAGE()
+
+# Copyright (c) 2006, Alexander Neundorf, <neundorf@kde.org>
+#
+# Redistribution and use is allowed according to the terms of the BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+
+
+MACRO (MACRO_OPTIONAL_FIND_PACKAGE _name )
+ OPTION(WITH_${_name} "Search for ${_name} package" ON)
+ if (WITH_${_name})
+ FIND_PACKAGE(${_name} ${ARGN})
+ else (WITH_${_name})
+ set(${_name}_FOUND)
+ set(${_name}_INCLUDE_DIR)
+ set(${_name}_INCLUDES)
+ set(${_name}_LIBRARY)
+ set(${_name}_LIBRARIES)
+ endif (WITH_${_name})
+ENDMACRO (MACRO_OPTIONAL_FIND_PACKAGE)
+
--- /dev/null
+
+# Phonon helper macros:
+#
+# macro (phonon_add_executable _target)
+# macro (PHONON_ADD_UNIT_TEST _test_NAME)
+# macro (PHONON_UPDATE_ICONCACHE)
+# macro (PHONON_UPDATE_ICONCACHE)
+# macro (_PHONON_ADD_ICON_INSTALL_RULE _install_SCRIPT _install_PATH _group _orig_NAME _install_NAME _l10n_SUBDIR)
+# macro (PHONON_INSTALL_ICONS _defaultpath )
+
+set(_global_add_executable_param)
+if (Q_WS_MAC)
+ set(_global_add_executable_param MACOSX_BUNDLE)
+endif (Q_WS_MAC)
+if (WIN32)
+ # no WIN32 here - all executables are command line executables
+ set(_global_add_executable_param)
+endif (WIN32)
+
+macro(phonon_add_executable _target)
+ set(_srcs ${ARGN})
+ automoc4_add_executable(${_target} ${_global_add_executable_param} ${_srcs})
+endmacro(phonon_add_executable _target)
+
+macro (PHONON_ADD_UNIT_TEST _test_NAME)
+ set(_srcList ${ARGN})
+ set(_nogui)
+ list(GET ${_srcList} 0 first_PARAM)
+ set(_add_executable_param ${_global_add_executable_param})
+ if(${first_PARAM} STREQUAL "NOGUI")
+ set(_nogui "NOGUI")
+ set(_add_executable_param)
+ endif(${first_PARAM} STREQUAL "NOGUI")
+
+ if (NOT PHONON_BUILD_TESTS)
+ set(_add_executable_param ${_add_executable_param} EXCLUDE_FROM_ALL)
+ endif (NOT PHONON_BUILD_TESTS)
+
+ automoc4_add_executable(${_test_NAME} ${_add_executable_param} ${_srcList})
+
+ if(NOT PHONON_TEST_OUTPUT)
+ set(PHONON_TEST_OUTPUT plaintext)
+ endif(NOT PHONON_TEST_OUTPUT)
+ set(PHONON_TEST_OUTPUT ${PHONON_TEST_OUTPUT} CACHE STRING "The output to generate when running the QTest unit tests")
+
+ set(using_qtest "")
+ foreach(_filename ${_srcList})
+ if(NOT using_qtest)
+ if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${_filename}")
+ file(READ ${_filename} file_CONTENT)
+ string(REGEX MATCH "QTEST_(KDE)?MAIN" using_qtest "${file_CONTENT}")
+ endif(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${_filename}")
+ endif(NOT using_qtest)
+ endforeach(_filename)
+
+ set(_executable ${EXECUTABLE_OUTPUT_PATH}/${_test_NAME})
+ if (Q_WS_MAC AND NOT _nogui)
+ set(_executable ${EXECUTABLE_OUTPUT_PATH}/${_test_NAME}.app/Contents/MacOS/${_test_NAME})
+ else (Q_WS_MAC AND NOT _nogui)
+ # Use .shell wrapper where available, to use uninstalled libs.
+ #if (UNIX)
+ # set(_executable ${_executable}.shell)
+ #endif (UNIX)
+ endif (Q_WS_MAC AND NOT _nogui)
+
+ if (using_qtest AND PHONON_TEST_OUTPUT STREQUAL "xml")
+ add_test( ${_test_NAME} ${_executable} -xml -o ${_test_NAME}.tml)
+ else (using_qtest AND PHONON_TEST_OUTPUT STREQUAL "xml")
+ add_test( ${_test_NAME} ${_executable} )
+ endif (using_qtest AND PHONON_TEST_OUTPUT STREQUAL "xml")
+
+ if (NOT MSVC_IDE) #not needed for the ide
+ # if the tests are EXCLUDE_FROM_ALL, add a target "buildtests" to build all tests
+ if (NOT PHONON_BUILD_TESTS)
+ get_directory_property(_buildtestsAdded BUILDTESTS_ADDED)
+ if(NOT _buildtestsAdded)
+ add_custom_target(buildtests)
+ set_directory_properties(PROPERTIES BUILDTESTS_ADDED TRUE)
+ endif(NOT _buildtestsAdded)
+ add_dependencies(buildtests ${_test_NAME})
+ endif (NOT PHONON_BUILD_TESTS)
+ endif (NOT MSVC_IDE)
+endmacro (PHONON_ADD_UNIT_TEST)
+
+macro (PHONON_UPDATE_ICONCACHE)
+ # Update mtime of hicolor icon theme dir.
+ # We don't always have touch command (e.g. on Windows), so instead create
+ # and delete a temporary file in the theme dir.
+ install(CODE "
+ set(DESTDIR_VALUE \"\$ENV{DESTDIR}\")
+ if (NOT DESTDIR_VALUE)
+ file(WRITE \"${ICON_INSTALL_DIR}/hicolor/temp.txt\" \"update\")
+ file(REMOVE \"${ICON_INSTALL_DIR}/hicolor/temp.txt\")
+ endif (NOT DESTDIR_VALUE)
+ ")
+endmacro (PHONON_UPDATE_ICONCACHE)
+
+# a "map" of short type names to the directories
+# unknown names should give empty results
+# KDE 3 compatibility
+set(_PHONON_ICON_GROUP_mime "mimetypes")
+set(_PHONON_ICON_GROUP_filesys "places")
+set(_PHONON_ICON_GROUP_device "devices")
+set(_PHONON_ICON_GROUP_app "apps")
+set(_PHONON_ICON_GROUP_action "actions")
+# KDE 4 / icon naming specification compatibility
+set(_PHONON_ICON_GROUP_mimetypes "mimetypes")
+set(_PHONON_ICON_GROUP_places "places")
+set(_PHONON_ICON_GROUP_devices "devices")
+set(_PHONON_ICON_GROUP_apps "apps")
+set(_PHONON_ICON_GROUP_actions "actions")
+set(_PHONON_ICON_GROUP_categories "categories")
+set(_PHONON_ICON_GROUP_status "status")
+set(_PHONON_ICON_GROUP_emblems "emblems")
+set(_PHONON_ICON_GROUP_emotes "emotes")
+set(_PHONON_ICON_GROUP_animations "animations")
+set(_PHONON_ICON_GROUP_intl "intl")
+
+# a "map" of short theme names to the theme directory
+set(_PHONON_ICON_THEME_ox "oxygen")
+set(_PHONON_ICON_THEME_cr "crystalsvg")
+set(_PHONON_ICON_THEME_lo "locolor")
+set(_PHONON_ICON_THEME_hi "hicolor")
+
+macro (_PHONON_ADD_ICON_INSTALL_RULE _install_SCRIPT _install_PATH _group _orig_NAME _install_NAME _l10n_SUBDIR)
+
+ # if the string doesn't match the pattern, the result is the full string, so all three have the same content
+ if (NOT ${_group} STREQUAL ${_install_NAME} )
+ set(_icon_GROUP ${_PHONON_ICON_GROUP_${_group}})
+ if(NOT _icon_GROUP)
+ set(_icon_GROUP "actions")
+ endif(NOT _icon_GROUP)
+# message(STATUS "icon: ${_current_ICON} size: ${_size} group: ${_group} name: ${_name} l10n: ${_l10n_SUBDIR}")
+ install(FILES ${_orig_NAME} DESTINATION ${_install_PATH}/${_icon_GROUP}/${_l10n_SUBDIR}/ RENAME ${_install_NAME} )
+ endif (NOT ${_group} STREQUAL ${_install_NAME} )
+
+endmacro (_PHONON_ADD_ICON_INSTALL_RULE)
+
+
+macro (PHONON_INSTALL_ICONS _defaultpath )
+
+ # the l10n-subdir if language given as second argument (localized icon)
+ set(_lang ${ARGV1})
+ if(_lang)
+ set(_l10n_SUBDIR l10n/${_lang})
+ else(_lang)
+ set(_l10n_SUBDIR ".")
+ endif(_lang)
+
+ # first the png icons
+ file(GLOB _icons *.png)
+ foreach (_current_ICON ${_icons} )
+ # since CMake 2.6 regex matches are stored in special variables CMAKE_MATCH_x, if it didn't match, they are empty
+ string(REGEX MATCH "^.*/([a-zA-Z]+)([0-9]+)\\-([a-z]+)\\-(.+\\.png)$" _dummy "${_current_ICON}")
+ set(_type "${CMAKE_MATCH_1}")
+ set(_size "${CMAKE_MATCH_2}")
+ set(_group "${CMAKE_MATCH_3}")
+ set(_name "${CMAKE_MATCH_4}")
+
+ set(_theme_GROUP ${_PHONON_ICON_THEME_${_type}})
+ if( _theme_GROUP)
+ _PHONON_ADD_ICON_INSTALL_RULE(${CMAKE_CURRENT_BINARY_DIR}/install_icons.cmake
+ ${_defaultpath}/${_theme_GROUP}/${_size}x${_size}
+ ${_group} ${_current_ICON} ${_name} ${_l10n_SUBDIR})
+ endif( _theme_GROUP)
+ endforeach (_current_ICON)
+
+ # mng icons
+ file(GLOB _icons *.mng)
+ foreach (_current_ICON ${_icons} )
+ # since CMake 2.6 regex matches are stored in special variables CMAKE_MATCH_x, if it didn't match, they are empty
+ string(REGEX MATCH "^.*/([a-zA-Z]+)([0-9]+)\\-([a-z]+)\\-(.+\\.mng)$" _dummy "${_current_ICON}")
+ set(_type "${CMAKE_MATCH_1}")
+ set(_size "${CMAKE_MATCH_2}")
+ set(_group "${CMAKE_MATCH_3}")
+ set(_name "${CMAKE_MATCH_4}")
+
+ set(_theme_GROUP ${_PHONON_ICON_THEME_${_type}})
+ if( _theme_GROUP)
+ _PHONON_ADD_ICON_INSTALL_RULE(${CMAKE_CURRENT_BINARY_DIR}/install_icons.cmake
+ ${_defaultpath}/${_theme_GROUP}/${_size}x${_size}
+ ${_group} ${_current_ICON} ${_name} ${_l10n_SUBDIR})
+ endif( _theme_GROUP)
+ endforeach (_current_ICON)
+
+ # and now the svg icons
+ file(GLOB _icons *.svgz)
+ foreach (_current_ICON ${_icons} )
+ # since CMake 2.6 regex matches are stored in special variables CMAKE_MATCH_x, if it didn't match, they are empty
+ string(REGEX MATCH "^.*/([a-zA-Z]+)sc\\-([a-z]+)\\-(.+\\.svgz)$" _dummy "${_current_ICON}")
+ set(_type "${CMAKE_MATCH_1}")
+ set(_group "${CMAKE_MATCH_2}")
+ set(_name "${CMAKE_MATCH_3}")
+
+ set(_theme_GROUP ${_PHONON_ICON_THEME_${_type}})
+ if( _theme_GROUP)
+ _PHONON_ADD_ICON_INSTALL_RULE(${CMAKE_CURRENT_BINARY_DIR}/install_icons.cmake
+ ${_defaultpath}/${_theme_GROUP}/scalable
+ ${_group} ${_current_ICON} ${_name} ${_l10n_SUBDIR})
+ endif( _theme_GROUP)
+ endforeach (_current_ICON)
+
+ phonon_update_iconcache()
+
+endmacro (PHONON_INSTALL_ICONS)
+
--- /dev/null
+.svn
+Makefile
+moc_*
+phonon_vlc_*
--- /dev/null
+Fathi Boudra <fabo@kde.org> (current maintainer)
+Lukas Durfina <lukas.durfina@gmail.com>
+Tanguy Krotoff <tkrotoff@gmail.com>
--- /dev/null
+/*****************************************************************************
+ * VLC backend for the Phonon library *
+ * Copyright (C) 2007-2008 Tanguy Krotoff <tkrotoff@gmail.com> *
+ * Copyright (C) 2008 Lukas Durfina <lukas.durfina@gmail.com> *
+ * Copyright (C) 2009 Fathi Boudra <fabo@kde.org> *
+ * *
+ * This program is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 3 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 *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this package; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *
+ *****************************************************************************/
+
+#include "audiooutput.h"
+#include "devicemanager.h"
+#include "backend.h"
+
+#include "mediaobject.h"
+#include "vlcmediaobject.h"
+
+#include "vlcloader.h"
+
+namespace Phonon
+{
+namespace VLC {
+
+AudioOutput::AudioOutput(Backend *p_back, QObject * p_parent)
+ : SinkNode(p_parent),
+ f_volume(1.0),
+ p_backend(p_back)
+{
+ p_media_object = 0;
+}
+
+AudioOutput::~AudioOutput()
+{
+}
+
+qreal AudioOutput::volume() const
+{
+ return f_volume;
+}
+
+void AudioOutput::setVolume(qreal volume)
+{
+ if (vlc_instance) {
+ libvlc_audio_set_volume(vlc_instance, (int)(f_volume * 100), vlc_exception);
+ vlcExceptionRaised();
+ f_volume = volume;
+ emit volumeChanged(f_volume);
+ }
+}
+
+int AudioOutput::outputDevice() const
+{
+ return i_device;
+}
+
+bool AudioOutput::setOutputDevice(int device)
+{
+ if (i_device == device)
+ return true;
+
+ const QList<AudioDevice> deviceList = p_backend->deviceManager()->audioOutputDevices();
+ if (device >= 0 && device < deviceList.size()) {
+
+ i_device = device;
+ const QByteArray deviceName = deviceList.at(device).vlcId;
+ libvlc_audio_output_set(vlc_instance, (char *) deviceList.at(device).vlcId.data());
+ qDebug() << "set aout " << deviceList.at(device).vlcId.data();
+// if (deviceName == DEFAULT_ID) {
+// libvlc_audio_device_set(p_vlc_instance, DEFAULT, vlc_exception);
+// vlcExceptionRaised();
+// } else if (deviceName.startsWith(ALSA_ID)) {
+// qDebug() << "setting ALSA " << deviceList.at(device).hwId.data();
+// libvlc_audio_device_set(p_vlc_instance, ALSA, vlc_exception);
+// vlcExceptionRaised();
+// libvlc_audio_alsa_device_set(p_vlc_instance,
+// deviceList.at(device).hwId,
+// vlc_exception);
+// vlcExceptionRaised();
+ }
+
+ return true;
+}
+
+#if (PHONON_VERSION >= PHONON_VERSION_CHECK(4, 2, 0))
+bool AudioOutput::setOutputDevice(const Phonon::AudioOutputDevice & device)
+{
+ return true;
+}
+#endif
+
+}
+} // Namespace Phonon::VLC
--- /dev/null
+/*****************************************************************************
+ * VLC backend for the Phonon library *
+ * Copyright (C) 2007-2008 Tanguy Krotoff <tkrotoff@gmail.com> *
+ * Copyright (C) 2008 Lukas Durfina <lukas.durfina@gmail.com> *
+ * Copyright (C) 2009 Fathi Boudra <fabo@kde.org> *
+ * *
+ * This program is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 3 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 *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this package; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *
+ *****************************************************************************/
+
+#ifndef PHONON_VLC_AUDIOOUTPUT_H
+#define PHONON_VLC_AUDIOOUTPUT_H
+
+#include "sinknode.h"
+
+#include <phonon/audiooutputinterface.h>
+
+namespace Phonon
+{
+namespace VLC {
+class Backend;
+
+class AudioOutput : public SinkNode, public AudioOutputInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(Phonon::AudioOutputInterface)
+
+public:
+
+ AudioOutput(Backend *p_back, QObject * p_parent);
+ ~AudioOutput();
+
+ qreal volume() const;
+ void setVolume(qreal volume);
+
+ int outputDevice() const;
+ bool setOutputDevice(int);
+#if (PHONON_VERSION >= PHONON_VERSION_CHECK(4, 2, 0))
+ bool setOutputDevice(const AudioOutputDevice & device);
+#endif
+
+signals:
+
+ void volumeChanged(qreal volume);
+ void audioDeviceFailed();
+
+private:
+
+ qreal f_volume;
+ int i_device;
+ Backend *p_backend;
+
+};
+
+}
+} // Namespace Phonon::VLC
+
+#endif // PHONON_VLC_AUDIOOUTPUT_H
--- /dev/null
+/*****************************************************************************
+ * VLC backend for the Phonon library *
+ * Copyright (C) 2007-2008 Tanguy Krotoff <tkrotoff@gmail.com> *
+ * Copyright (C) 2008 Lukas Durfina <lukas.durfina@gmail.com> *
+ * Copyright (C) 2009 Fathi Boudra <fabo@kde.org> *
+ * *
+ * This program is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 3 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 *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this package; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *
+ *****************************************************************************/
+
+#include "backend.h"
+
+#include "audiooutput.h"
+#include "mediaobject.h"
+#include "videowidget.h"
+#include "devicemanager.h"
+#include "effectmanager.h"
+#include "effect.h"
+#include "sinknode.h"
+#include "vlcloader.h"
+#include "vlcmediaobject.h"
+
+#include <QtCore/QSet>
+#include <QtCore/QVariant>
+#include <QtCore/QtPlugin>
+
+Q_EXPORT_PLUGIN2(phonon_vlc, Phonon::VLC::Backend)
+
+namespace Phonon
+{
+namespace VLC {
+
+Backend::Backend(QObject *parent, const QVariantList &)
+ : QObject(parent)
+ , m_deviceManager(0)
+ , m_effectManager(0)
+ , m_debugLevel(Warning)
+{
+ bool wasInit = vlcInit();
+
+ setProperty("identifier", QLatin1String("phonon_vlc"));
+ setProperty("backendName", QLatin1String("VLC"));
+ setProperty("backendComment", QLatin1String("VLC plugin for Phonon"));
+ setProperty("backendVersion", QLatin1String("0.1"));
+ setProperty("backendWebsite", QLatin1String("http://multimedia.kde.org/"));
+
+ // Check if we should enable debug output
+ QString debugLevelString = qgetenv("PHONON_VLC_DEBUG");
+ int debugLevel = debugLevelString.toInt();
+ if (debugLevel > 3) // 3 is maximum
+ debugLevel = 3;
+ m_debugLevel = (DebugLevel)debugLevel;
+
+ if (wasInit) {
+ logMessage(QString("Using VLC version %0").arg(libvlc_get_version()));
+ } else {
+ qWarning("Phonon::VLC::vlcInit: Failed to initialize VLC");
+ }
+
+ m_deviceManager = new DeviceManager(this);
+ m_effectManager = new EffectManager(this);
+}
+
+Backend::~Backend()
+{
+// vlcRelease();
+}
+
+QObject *Backend::createObject(BackendInterface::Class c, QObject *parent, const QList<QVariant> &args)
+{
+ switch (c) {
+ case MediaObjectClass:
+ return new VLCMediaObject(parent);
+ case VolumeFaderEffectClass:
+// return new VolumeFaderEffect(parent);
+ logMessage("createObject() : VolumeFaderEffect not implemented");
+ break;
+ case AudioOutputClass: {
+ AudioOutput *ao = new AudioOutput(this, parent);
+ m_audioOutputs.append(ao);
+ return ao;
+ }
+ case AudioDataOutputClass:
+// return new AudioDataOutput(parent);
+ logMessage("createObject() : AudioDataOutput not implemented");
+ break;
+ case VisualizationClass:
+// return new Visualization(parent);
+ logMessage("createObject() : Visualization not implemented");
+ break;
+ case VideoDataOutputClass:
+// return new VideoDataOutput(parent);
+ logMessage("createObject() : VideoDataOutput not implemented");
+ break;
+ case EffectClass:
+ return new Effect(m_effectManager, args[0].toInt(), parent);
+ case VideoWidgetClass:
+ return new VideoWidget(qobject_cast<QWidget *>(parent));
+ default:
+ logMessage("createObject() : Backend object not available");
+ }
+ return 0;
+}
+
+bool Backend::supportsVideo() const
+{
+ return true;
+}
+
+bool Backend::supportsOSD() const
+{
+ return true;
+}
+
+bool Backend::supportsFourcc(quint32 fourcc) const
+{
+ return true;
+}
+
+bool Backend::supportsSubtitles() const
+{
+ return true;
+}
+
+QStringList Backend::availableMimeTypes() const
+{
+ if (m_supportedMimeTypes.isEmpty()) {
+ const_cast<Backend *>(this)->m_supportedMimeTypes
+ << QLatin1String("application/ogg")
+ << QLatin1String("application/vnd.rn-realmedia")
+ << QLatin1String("application/x-annodex")
+ << QLatin1String("application/x-flash-video")
+ << QLatin1String("application/x-quicktimeplayer")
+ << QLatin1String("audio/168sv")
+ << QLatin1String("audio/8svx")
+ << QLatin1String("audio/aiff")
+ << QLatin1String("audio/basic")
+ << QLatin1String("audio/mp3")
+ << QLatin1String("audio/mpeg")
+ << QLatin1String("audio/mpeg2")
+ << QLatin1String("audio/mpeg3")
+ << QLatin1String("audio/vnd.rn-realaudio")
+ << QLatin1String("audio/wav")
+ << QLatin1String("audio/x-16sv")
+ << QLatin1String("audio/x-8svx")
+ << QLatin1String("audio/x-aiff")
+ << QLatin1String("audio/x-basic")
+ << QLatin1String("audio/x-m4a")
+ << QLatin1String("audio/x-mp3")
+ << QLatin1String("audio/x-mpeg")
+ << QLatin1String("audio/x-mpeg2")
+ << QLatin1String("audio/x-mpeg3")
+ << QLatin1String("audio/x-mpegurl")
+ << QLatin1String("audio/x-ms-wma")
+ << QLatin1String("audio/x-ogg")
+ << QLatin1String("audio/x-pn-aiff")
+ << QLatin1String("audio/x-pn-au")
+ << QLatin1String("audio/x-pn-realaudio-plugin")
+ << QLatin1String("audio/x-pn-wav")
+ << QLatin1String("audio/x-pn-windows-acm")
+ << QLatin1String("audio/x-real-audio")
+ << QLatin1String("audio/x-realaudio")
+ << QLatin1String("audio/x-speex+ogg")
+ << QLatin1String("audio/x-wav")
+ << QLatin1String("image/ilbm")
+ << QLatin1String("image/png")
+ << QLatin1String("image/x-ilbm")
+ << QLatin1String("image/x-png")
+ << QLatin1String("video/anim")
+ << QLatin1String("video/avi")
+ << QLatin1String("video/mkv")
+ << QLatin1String("video/mng")
+ << QLatin1String("video/mp4")
+ << QLatin1String("video/mpeg")
+ << QLatin1String("video/mpg")
+ << QLatin1String("video/msvideo")
+ << QLatin1String("video/quicktime")
+ << QLatin1String("video/x-anim")
+ << QLatin1String("video/x-flic")
+ << QLatin1String("video/x-mng")
+ << QLatin1String("video/x-mpeg")
+ << QLatin1String("video/x-ms-asf")
+ << QLatin1String("video/x-ms-wmv")
+ << QLatin1String("video/x-msvideo")
+ << QLatin1String("video/x-quicktime");
+ }
+ return m_supportedMimeTypes;
+}
+
+QList<int> Backend::objectDescriptionIndexes(ObjectDescriptionType type) const
+{
+ QList<int> list;
+
+ switch (type) {
+ case Phonon::AudioOutputDeviceType: {
+ QList<AudioDevice> deviceList = deviceManager()->audioOutputDevices();
+ for (int dev = 0 ; dev < deviceList.size() ; ++dev)
+ list.append(deviceList[dev].id);
+ break;
+ }
+ break;
+ case Phonon::EffectType: {
+ QList<EffectInfo*> effectList = effectManager()->effects();
+ for (int eff = 0; eff < effectList.size(); ++eff)
+ list.append(eff);
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return list;
+}
+
+QHash<QByteArray, QVariant> Backend::objectDescriptionProperties(ObjectDescriptionType type, int index) const
+{
+ QHash<QByteArray, QVariant> ret;
+
+ switch (type) {
+ case Phonon::AudioOutputDeviceType: {
+ QList<AudioDevice> audioDevices = deviceManager()->audioOutputDevices();
+ if (index >= 0 && index < audioDevices.size()) {
+ ret.insert("name", audioDevices[index].vlcId);
+ ret.insert("description", audioDevices[index].description);
+ ret.insert("icon", QLatin1String("audio-card"));
+ }
+ }
+ break;
+ case Phonon::EffectType: {
+ QList<EffectInfo*> effectList = effectManager()->effects();
+ if (index >= 0 && index <= effectList.size()) {
+ const EffectInfo *effect = effectList[ index ];
+ ret.insert("name", effect->name());
+ ret.insert("description", effect->description());
+ ret.insert("author", effect->author());
+ } else {
+ Q_ASSERT(1); // Since we use list position as ID, this should not happen
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ return ret;
+}
+
+bool Backend::startConnectionChange(QSet<QObject *> objects)
+{
+ foreach(QObject *object, objects) {
+ logMessage(QString("Object: %0").arg(object->metaObject()->className()));
+ }
+
+ // There is nothing we can do but hope the connection changes will not take too long
+ // so that buffers would underrun
+ // But we should be pretty safe the way xine works by not doing anything here.
+ return true;
+}
+
+bool Backend::connectNodes(QObject *source, QObject *sink)
+{
+ logMessage(QString("Backend connected %0 to %1")
+ .arg(source->metaObject()->className())
+ .arg(sink->metaObject()->className()));
+
+ // Example:
+ // source = Phonon::VLC_MPlayer::MediaObject
+ // sink = Phonon::VLC_MPlayer::VideoWidget
+
+ // Example:
+ // source = Phonon::VLC_MPlayer::MediaObject
+ // sink = Phonon::VLC_MPlayer::AudioOutput
+
+ // Example:
+ // source = Phonon::VLC_MPlayer::MediaObject
+ // sink = Phonon::VLC_MPlayer::Effect
+
+ // Example:
+ // source = Phonon::VLC_MPlayer::Effect
+ // sink = Phonon::VLC_MPlayer::AudioOutput
+
+ SinkNode *sinkNode = qobject_cast<SinkNode *>(sink);
+ if (sinkNode) {
+ PrivateMediaObject *mediaObject = qobject_cast<PrivateMediaObject *>(source);
+ if (mediaObject) {
+ // Connect the SinkNode to a MediaObject
+ sinkNode->connectToMediaObject(mediaObject);
+ return true;
+ } else {
+ // FIXME try to find a better way...
+// Effect *effect = qobject_cast<Effect *>(source);
+ return true;
+ }
+ }
+
+ logMessage(QString("Linking %0 to %1 failed")
+ .arg(source->metaObject()->className())
+ .arg(sink->metaObject()->className()),
+ Warning);
+
+ return false;
+}
+
+bool Backend::disconnectNodes(QObject *source, QObject *sink)
+{
+ SinkNode *sinkNode = qobject_cast<SinkNode *>(sink);
+ if (sinkNode) {
+ PrivateMediaObject *mediaObject = qobject_cast<PrivateMediaObject *>(source);
+ if (mediaObject) {
+ // Disconnect the SinkNode from a MediaObject
+ sinkNode->disconnectFromMediaObject(mediaObject);
+ return true;
+ } else {
+ // FIXME try to find a better way...
+// Effect *effect = qobject_cast<Effect *>(source);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool Backend::endConnectionChange(QSet<QObject *> objects)
+{
+ foreach(QObject *object, objects) {
+ logMessage(QString("Object: %0").arg(object->metaObject()->className()));
+ }
+
+ return true;
+}
+
+DeviceManager* Backend::deviceManager() const
+{
+ return m_deviceManager;
+}
+
+EffectManager* Backend::effectManager() const
+{
+ return m_effectManager;
+}
+
+/**
+ * Return a debuglevel that is determined by the
+ * PHONON_VLC_DEBUG environment variable.
+ *
+ * Warning - important warnings
+ * Info - general info
+ * Debug - gives extra info
+ */
+Backend::DebugLevel Backend::debugLevel() const
+{
+ return m_debugLevel;
+}
+
+/**
+ * Print a conditional debug message based on the current debug level
+ * If obj is provided, classname and objectname will be printed as well
+ *
+ * see debugLevel()
+ */
+void Backend::logMessage(const QString &message, int priority, QObject *obj) const
+{
+ if (debugLevel() > 0) {
+ QString output;
+ if (obj) {
+ // Strip away namespace from className
+ QString className(obj->metaObject()->className());
+ int nameLength = className.length() - className.lastIndexOf(':') - 1;
+ className = className.right(nameLength);
+ output.sprintf("%s %s (%s %p)", message.toLatin1().constData(),
+ obj->objectName().toLatin1().constData(),
+ className.toLatin1().constData(), obj);
+ } else {
+ output = message;
+ }
+ if (priority <= (int)debugLevel()) {
+ qDebug() << QString("PVLC(%1): %2").arg(priority).arg(output);
+ }
+ }
+}
+
+}
+} // Namespace Phonon::VLC
--- /dev/null
+/*****************************************************************************
+ * VLC backend for the Phonon library *
+ * Copyright (C) 2007-2008 Tanguy Krotoff <tkrotoff@gmail.com> *
+ * Copyright (C) 2008 Lukas Durfina <lukas.durfina@gmail.com> *
+ * Copyright (C) 2009 Fathi Boudra <fabo@kde.org> *
+ * *
+ * This program is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 3 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 *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this package; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *
+ *****************************************************************************/
+
+#ifndef Phonon_VLC_BACKEND_H
+#define Phonon_VLC_BACKEND_H
+
+#include "devicemanager.h"
+#include "audiooutput.h"
+
+#include <phonon/objectdescription.h>
+#include <phonon/backendinterface.h>
+
+#include <QtCore/QList>
+#include <QtCore/QPointer>
+#include <QtCore/QStringList>
+
+#ifdef MAKE_PHONON_VLC_LIB // We are building this library
+# define PHONON_VLC_EXPORT Q_DECL_EXPORT
+#else // We are using this library
+# define PHONON_VLC_EXPORT Q_DECL_IMPORT
+#endif
+
+namespace Phonon
+{
+namespace VLC {
+class AudioOutput;
+class EffectManager;
+
+class Backend : public QObject, public BackendInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(Phonon::BackendInterface)
+
+public:
+
+ enum DebugLevel {NoDebug, Warning, Info, Debug};
+ Backend(QObject *parent = 0, const QVariantList & = QVariantList());
+ virtual ~Backend();
+
+ DeviceManager* deviceManager() const;
+ EffectManager* effectManager() const;
+
+ QObject *createObject(BackendInterface::Class, QObject *parent, const QList<QVariant> &args);
+
+ bool supportsVideo() const;
+ bool supportsOSD() const;
+ bool supportsFourcc(quint32 fourcc) const;
+ bool supportsSubtitles() const;
+ QStringList availableMimeTypes() const;
+
+ QList<int> objectDescriptionIndexes(ObjectDescriptionType type) const;
+ QHash<QByteArray, QVariant> objectDescriptionProperties(ObjectDescriptionType type, int index) const;
+
+ bool startConnectionChange(QSet<QObject *>);
+ bool connectNodes(QObject *, QObject *);
+ bool disconnectNodes(QObject *, QObject *);
+ bool endConnectionChange(QSet<QObject *>);
+
+ DebugLevel debugLevel() const;
+
+ void logMessage(const QString &message, int priority = 2, QObject *obj = 0) const;
+
+Q_SIGNALS:
+ void objectDescriptionChanged(ObjectDescriptionType);
+
+private:
+ mutable QStringList m_supportedMimeTypes;
+ QList<QPointer<AudioOutput> > m_audioOutputs;
+
+ DeviceManager *m_deviceManager;
+ EffectManager *m_effectManager;
+ DebugLevel m_debugLevel;
+};
+
+}
+} // namespace Phonon::VLC
+
+#endif // Phonon_VLC_BACKEND_H
--- /dev/null
+/* This file is part of the KDE project.
+
+ Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+
+ This library is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 2.1 or 3 of the License.
+
+ This library 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 Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this library. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "devicemanager.h"
+#include "backend.h"
+//#include "videowidget.h"
+//#include "widgetrenderer.h"
+#include "vlcloader.h"
+
+/**
+ * This class manages the list of currently active output devices.
+ */
+
+QT_BEGIN_NAMESPACE
+
+namespace Phonon
+{
+namespace VLC {
+
+AudioDevice::AudioDevice(DeviceManager *manager, const QByteArray &deviceId, const QByteArray &hw_id)
+{
+ // Get an id
+ static int counter = 0;
+ id = counter++;
+ // Get name from device
+ if (vlcId == "default") {
+ description = "Default audio device";
+ } else {
+ vlcId = deviceId;
+ description = "";
+ }
+ hwId = hw_id;
+}
+
+DeviceManager::DeviceManager(Backend *parent)
+ : QObject(parent)
+ , m_backend(parent)
+{
+ updateDeviceList();
+}
+
+DeviceManager::~DeviceManager()
+{
+ m_audioDeviceList.clear();
+}
+
+bool DeviceManager::canOpenDevice() const
+{
+ return true;
+}
+
+/**
+ * Return a positive device id or -1 if device does not exist.
+ */
+int DeviceManager::deviceId(const QByteArray &nameId) const
+{
+ for (int i = 0 ; i < m_audioDeviceList.size() ; ++i) {
+ if (m_audioDeviceList[i].vlcId == nameId)
+ return m_audioDeviceList[i].id;
+ }
+ return -1;
+}
+
+/**
+ * Get a human-readable description from a device id.
+ */
+QByteArray DeviceManager::deviceDescription(int i_id) const
+{
+ for (int i = 0 ; i < m_audioDeviceList.size() ; ++i) {
+ if (m_audioDeviceList[i].id == i_id)
+ return m_audioDeviceList[i].description;
+ }
+ return QByteArray();
+}
+
+/**
+ * Update the current list of active devices.
+ */
+void DeviceManager::updateDeviceList()
+{
+ QList<QByteArray> list, list_hw;
+ list.append("default");
+ list_hw.append("");
+
+ // Get the list of available audio outputs
+ libvlc_audio_output_t *p_ao_list = libvlc_audio_output_list_get(
+ vlc_instance, vlc_exception);
+ vlcExceptionRaised();
+ libvlc_audio_output_t *p_start = p_ao_list;
+
+ while (p_ao_list) {
+ list.append(p_ao_list->psz_name);
+ list_hw.append("");
+ p_ao_list = p_ao_list->p_next;
+ }
+ libvlc_audio_output_list_release(p_start);
+
+ for (int i = 0 ; i < list.size() ; ++i) {
+ QByteArray nameId = list.at(i);
+ QByteArray hwId = list_hw.at(i);
+ if (deviceId(nameId) == -1) {
+ // This is a new device, add it
+ qDebug() << "add aout " << nameId.data();
+ m_audioDeviceList.append(AudioDevice(this, nameId, hwId));
+ emit deviceAdded(deviceId(nameId));
+ }
+ }
+ if (list.size() < m_audioDeviceList.size()) {
+ // A device was removed
+ for (int i = m_audioDeviceList.size() - 1 ; i >= 0 ; --i) {
+ QByteArray currId = m_audioDeviceList[i].vlcId;
+ bool b_found = false;
+ for (int k = list.size() - 1 ; k >= 0 ; --k) {
+ if (currId == list[k]) {
+ b_found = true;
+ break;
+ }
+ }
+ if (!b_found) {
+ emit deviceRemoved(deviceId(currId));
+ m_audioDeviceList.removeAt(i);
+ }
+ }
+ }
+}
+
+/**
+ * Return a list of hardware id.
+ */
+const QList<AudioDevice> DeviceManager::audioOutputDevices() const
+{
+ return m_audioDeviceList;
+}
+
+}
+}
+
+QT_END_NAMESPACE
--- /dev/null
+/* This file is part of the KDE project.
+
+ Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+
+ This library is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 2.1 or 3 of the License.
+
+ This library 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 Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this library. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef Phonon_VLC_DEVICEMANAGER_H
+#define Phonon_VLC_DEVICEMANAGER_H
+
+#include <phonon/audiooutputinterface.h>
+
+#include <QtCore/QObject>
+
+QT_BEGIN_NAMESPACE
+
+namespace Phonon
+{
+namespace VLC {
+
+class Backend;
+class DeviceManager;
+class AbstractRenderer;
+class VideoWidget;
+
+class AudioDevice
+{
+public :
+ AudioDevice(DeviceManager *s, const QByteArray &deviceId, const QByteArray &hw_id = "");
+ int id;
+ QByteArray vlcId;
+ QByteArray description;
+ QByteArray hwId;
+};
+
+class DeviceManager : public QObject
+{
+ Q_OBJECT
+
+public:
+ DeviceManager(Backend *parent);
+ virtual ~DeviceManager();
+ const QList<AudioDevice> audioOutputDevices() const;
+ int deviceId(const QByteArray &vlcId) const;
+ QByteArray deviceDescription(int id) const;
+
+signals:
+ void deviceAdded(int);
+ void deviceRemoved(int);
+
+public slots:
+ void updateDeviceList();
+
+private:
+ bool canOpenDevice() const;
+ Backend *m_backend;
+ QList <AudioDevice> m_audioDeviceList;
+};
+}
+} // namespace Phonon::VLC
+
+QT_END_NAMESPACE
+
+#endif // Phonon_VLC_DEVICEMANAGER_H
--- /dev/null
+/*****************************************************************************
+ * VLC backend for the Phonon library *
+ * Copyright (C) 2007-2008 Tanguy Krotoff <tkrotoff@gmail.com> *
+ * Copyright (C) 2008 Lukas Durfina <lukas.durfina@gmail.com> *
+ * Copyright (C) 2009 Fathi Boudra <fabo@kde.org> *
+ * *
+ * This program is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 3 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 *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this package; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *
+ *****************************************************************************/
+
+#include "effect.h"
+
+#include "effectmanager.h"
+
+#include "mediaobject.h"
+
+namespace Phonon
+{
+namespace VLC {
+
+Effect::Effect(EffectManager *p_em, int i_effectId, QObject *p_parent)
+ : SinkNode(p_parent)
+{
+ p_effectManager = p_em;
+ QList<EffectInfo *> effects = p_effectManager->effects();
+
+ if (i_effectId >= 0 && i_effectId < effects.size()) {
+ i_effect_filter = effects[ i_effectId ]->filter();
+ effect_type = effects[ i_effectId ]->type();
+ setupEffectParams();
+ } else {
+ // effect ID out of range
+ Q_ASSERT(0);
+ }
+}
+
+Effect::~Effect()
+{
+ parameterList.clear();
+}
+
+void Effect::connectToMediaObject(PrivateMediaObject *p_media_object)
+{
+ SinkNode::connectToMediaObject(p_media_object);
+
+ switch (effect_type) {
+ case EffectInfo::AudioEffect:
+// libvlc_audio_filter_add(p_vlc_instance, (libvlc_audio_filter_names_t)i_effect_filter, vlc_exception);
+// vlcExceptionRaised();
+ break;
+ case EffectInfo::VideoEffect:
+// libvlc_video_filter_add(p_vlc_current_media_player, (libvlc_video_filter_names_t)i_effect_filter, vlc_exception);
+// vlcExceptionRaised();
+ break;
+ }
+}
+
+void Effect::disconnectFromMediaObject(PrivateMediaObject *p_media_object)
+{
+ SinkNode::disconnectFromMediaObject(p_media_object);
+
+ switch (effect_type) {
+ case EffectInfo::AudioEffect:
+// libvlc_audio_filter_remove(p_vlc_instance, (libvlc_audio_filter_names_t)i_effect_filter, vlc_exception);
+// vlcExceptionRaised();
+ break;
+ case EffectInfo::VideoEffect:
+// libvlc_video_filter_remove(p_vlc_current_media_player, (libvlc_video_filter_names_t)i_effect_filter, vlc_exception);
+// vlcExceptionRaised();
+ break;
+ }
+}
+
+void Effect::setupEffectParams()
+{
+// libvlc_filter_parameter_list_t *p_list;
+ switch (effect_type) {
+ case EffectInfo::AudioEffect:
+// p_list = libvlc_audio_filter_get_parameters(p_vlc_instance, (libvlc_audio_filter_names_t)i_effect_filter, vlc_exception );
+// vlcExceptionRaised();
+ break;
+ case EffectInfo::VideoEffect:
+// p_list = libvlc_video_filter_get_parameters(p_vlc_instance, (libvlc_video_filter_names_t)i_effect_filter, vlc_exception );
+// vlcExceptionRaised();
+ break;
+ }
+// if( !p_list )
+// return;
+
+ int i_index = 0;
+// libvlc_filter_parameter_list_t *p_parameter_list = p_list;
+// while (p_parameter_list) {
+// switch (p_parameter_list->var_type) {
+// case LIBVLC_BOOL: {
+// const QString description = p_parameter_list->psz_description;
+// parameterList.append(Phonon::EffectParameter(
+// i_index,
+// QString(p_parameter_list->psz_parameter_name),
+// Phonon::EffectParameter::ToggledHint, // hints
+// QVariant((bool) p_parameter_list->default_value.b_bool),
+// QVariant((bool) false),
+// QVariant((bool) true),
+// QVariantList(),
+// description));
+// break;
+// }
+// case LIBVLC_INT: {
+// const QString description = p_parameter_list->psz_description;
+// parameterList.append(Phonon::EffectParameter(
+// i_index,
+// QString(p_parameter_list->psz_parameter_name),
+// EffectParameter::IntegerHint, // hints
+// QVariant((int) p_parameter_list->default_value.i_int),
+// QVariant((int) p_parameter_list->min_value.i_int),
+// QVariant((int) p_parameter_list->max_value.i_int),
+// QVariantList(),
+// description));
+// break;
+// }
+// case LIBVLC_FLOAT: {
+// const QString description = p_parameter_list->psz_description;
+// parameterList.append(Phonon::EffectParameter(
+// i_index,
+// QString(p_parameter_list->psz_parameter_name),
+// 0, // hints
+// QVariant((double) p_parameter_list->default_value.f_float),
+// QVariant((double) p_parameter_list->min_value.f_float),
+// QVariant((double) p_parameter_list->max_value.f_float),
+// QVariantList(),
+// description));
+// break;
+// }
+// case LIBVLC_STRING: {
+// const QString description = p_parameter_list->psz_description;
+// parameterList.append(Phonon::EffectParameter(
+// i_index,
+// QString(p_parameter_list->psz_parameter_name),
+// 0, // hints
+// QVariant((const char *) p_parameter_list->default_value.psz_string),
+// NULL,
+// NULL,
+// QVariantList(),
+// description));
+// break;
+// }
+// }
+// i_index++;
+// p_parameter_list = p_parameter_list->p_next;
+// }
+// libvlc_filter_parameters_release(p_list);
+}
+
+QList<EffectParameter> Effect::parameters() const
+{
+ return parameterList;
+}
+
+QVariant Effect::parameterValue(const EffectParameter & param) const
+{
+ return QVariant();
+}
+
+void Effect::setParameterValue(const EffectParameter & param, const QVariant & newValue)
+{
+// libvlc_value_t value;
+// libvlc_var_type_t type;
+// switch (param.type()) {
+// case QVariant::Bool:
+// value.b_bool = newValue.toBool();
+// type = LIBVLC_BOOL;
+// break;
+// case QVariant::Int:
+// value.i_int = newValue.toInt();
+// type = LIBVLC_INT;
+// break;
+// case QVariant::Double:
+// value.f_float = (float) newValue.toDouble();
+// type = LIBVLC_FLOAT;
+// break;
+// case QVariant::String:
+// value.psz_string = newValue.toString().toAscii().data();
+// type = LIBVLC_STRING;
+// break;
+// default:
+// break;
+// }
+// switch (effect_type) {
+// case EffectInfo::AudioEffect:
+// libvlc_audio_filter_set_parameter(
+// p_vlc_instance,
+// // (libvlc_audio_filter_names_t) i_effect_filter,
+// param.name().toAscii().data(),
+// type,
+// value,
+// vlc_exception);
+// vlcExceptionRaised();
+// break;
+// case EffectInfo::VideoEffect:
+// libvlc_video_filter_set_parameter(
+// p_vlc_current_media_player,
+// (libvlc_video_filter_names_t) i_effect_filter,
+// param.name().toAscii().data(),
+// type,
+// value,
+// vlc_exception);
+// vlcExceptionRaised();
+// break;
+// }
+}
+
+}
+} // Namespace Phonon::VLC
--- /dev/null
+/*****************************************************************************
+ * VLC backend for the Phonon library *
+ * Copyright (C) 2007-2008 Tanguy Krotoff <tkrotoff@gmail.com> *
+ * Copyright (C) 2008 Lukas Durfina <lukas.durfina@gmail.com> *
+ * Copyright (C) 2009 Fathi Boudra <fabo@kde.org> *
+ * *
+ * This program is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 3 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 *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this package; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *
+ *****************************************************************************/
+
+#ifndef PHONON_VLC_EFFECT_H
+#define PHONON_VLC_EFFECT_H
+
+#include "sinknode.h"
+#include "effectmanager.h"
+
+#include <phonon/effectinterface.h>
+#include <phonon/effectparameter.h>
+
+namespace Phonon
+{
+namespace VLC {
+
+class EffectManager;
+
+
+class Effect : public SinkNode, public EffectInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(Phonon::EffectInterface)
+
+public:
+
+ Effect(EffectManager *p_em, int i_effectId, QObject *p_parent);
+ ~Effect();
+
+ void setupEffectParams();
+ QList<EffectParameter> parameters() const;
+ QVariant parameterValue(const EffectParameter & param) const;
+ void setParameterValue(const EffectParameter & param, const QVariant & newValue);
+
+ void connectToMediaObject(PrivateMediaObject *p_media_object);
+ void disconnectFromMediaObject(PrivateMediaObject *p_media_object);
+
+private:
+
+ EffectManager *p_effectManager;
+ int i_effect_filter;
+ EffectInfo::Type effect_type;
+ QList<Phonon::EffectParameter> parameterList;
+};
+
+}
+} // Namespace Phonon::VLC
+
+#endif // PHONON_VLC_EFFECT_H
--- /dev/null
+/*****************************************************************************
+ * VLC backend for the Phonon library *
+ * Copyright (C) 2007-2008 Tanguy Krotoff <tkrotoff@gmail.com> *
+ * Copyright (C) 2008 Lukas Durfina <lukas.durfina@gmail.com> *
+ * Copyright (C) 2009 Fathi Boudra <fabo@kde.org> *
+ * *
+ * This program is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 3 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 *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this package; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *
+ *****************************************************************************/
+
+#include "effectmanager.h"
+#include "backend.h"
+
+namespace Phonon
+{
+namespace VLC {
+
+EffectInfo::EffectInfo(const QString &name, const QString &description, const QString &author, int filter, Type type)
+ : m_name(name)
+ , m_description(description)
+ , m_author(author)
+ , m_filter(filter)
+ , m_type(type) {}
+
+EffectManager::EffectManager(Backend *backend)
+ : QObject(backend)
+ , m_backend(backend)
+{
+// m_equalizerEnabled = false;
+
+ // Audio effects - equalizer
+ // Only one of them can be used => last set
+ // It is clever used with combobox
+
+// audioEffectList.append(new EffectInfo("(Audio) Equalizer", EQUALIZER, EffectInfo::AudioEffect));
+
+// audioEffectList.append(new EffectInfo("(Audio) Headphone spalization",
+// HEADPHONE_SPALIZATION, EffectInfo::AudioEffect,
+// "This effect gives you the feeling that you are standing in a room "
+// "with a complete 7.1 speaker set when using only a headphone, "
+// "providing a more realistic sound experience. It should also be "
+// "more comfortable and less tiring when listening to music for "
+// "long periods of time.\nIt works with any source format from mono "
+// "to 7.1."));
+
+// audioEffectList.append(new EffectInfo("(Audio) Parametric equalizer",
+// PARAMETRIC_EQUALIZER, EffectInfo::AudioEffect));
+
+// audioEffectList.append(new EffectInfo("(Audio) Scaletempo",
+// SCALETEMPO, EffectInfo::AudioEffect,
+// "Scale audio tempo in sync with playback rate"));
+
+// audioEffectList.append(new EffectInfo("(Audio) Spatializer",
+// SPATIALIZER, EffectInfo::AudioEffect));
+
+// audioEffectList.append(new EffectInfo("(Audio) Volume normalizer",
+// VOLUME_NORMALIZER, EffectInfo::AudioEffect));
+
+// audioEffectList.append(new EffectInfo("(Audio) Flat", FLAT, EffectInfo::AudioEffect));
+// audioEffectList.append(new EffectInfo("(Audio) Classical", CLASSICAL, EffectInfo::AudioEffect));
+// audioEffectList.append(new EffectInfo("(Audio) Club", CLUB, EffectInfo::AudioEffect));
+// audioEffectList.append(new EffectInfo("(Audio) Dance", DANCE, EffectInfo::AudioEffect));
+// audioEffectList.append(new EffectInfo("(Audio) Fullbass", FULLBASS, EffectInfo::AudioEffect));
+// audioEffectList.append(new EffectInfo("(Audio) Fullbasstreble", FULLBASSTREBLE, EffectInfo::AudioEffect));
+// audioEffectList.append(new EffectInfo("(Audio) Fulltreble", FULLTREBLE, EffectInfo::AudioEffect));
+// audioEffectList.append(new EffectInfo("(Audio) Headphones", HEADPHONES, EffectInfo::AudioEffect));
+// audioEffectList.append(new EffectInfo("(Audio) Large hall", LARGEHALL, EffectInfo::AudioEffect));
+// audioEffectList.append(new EffectInfo("(Audio) Live", LIVE, EffectInfo::AudioEffect));
+// audioEffectList.append(new EffectInfo("(Audio) Party", PARTY, EffectInfo::AudioEffect));
+// audioEffectList.append(new EffectInfo("(Audio) Pop", POP, EffectInfo::AudioEffect));
+// audioEffectList.append(new EffectInfo("(Audio) Reggae", REGGAE, EffectInfo::AudioEffect));
+// audioEffectList.append(new EffectInfo("(Audio) Rock", ROCK, EffectInfo::AudioEffect));
+// audioEffectList.append(new EffectInfo("(Audio) Ska", SKA, EffectInfo::AudioEffect));
+// audioEffectList.append(new EffectInfo("(Audio) Soft", SOFT, EffectInfo::AudioEffect));
+// audioEffectList.append(new EffectInfo("(Audio) Softrock", SOFTROCK, EffectInfo::AudioEffect));
+// audioEffectList.append(new EffectInfo("(Audio) Techno", TECHNO, EffectInfo::AudioEffect));
+
+ // Video effects
+ // More than one can be used simultaneously
+ // It is clever used with checkbox
+
+// videoEffectList.append(new EffectInfo("(Video) Atmo light", ATMOLIGHT, EffectInfo::VideoEffect,
+// "AtmoLight Filter - "
+// "This module allows to control an so called AtmoLight device "
+// "connected to your computer.\n"
+// "AtmoLight is the homegrown version of what Philips calls AmbiLight.\n"
+// "If you need further information feel free to visit us at\n\n"
+// "http://www.vdr-wiki.de/wiki/index.php/Atmo-plugin\n "
+// "http://www.vdr-wiki.de/wiki/index.php/AtmoWin\n\n"
+// "You can find there detailed descriptions on how to build it for yourself "
+// "and where to get the required parts.\n"
+// "You can also have a look at pictures and some movies showing such a device "
+// "in live action.",
+// "André Weber (WeberAndre@gmx.de)"));
+
+// videoEffectList.append(new EffectInfo("(Video) Bluescreen", BLUESCREEN, EffectInfo::VideoEffect,
+// "Bluescreen video filter", "Antoine Cellerier <dionoea at videolan tod org>"));
+
+// videoEffectList.append(new EffectInfo("(Video) Color threshold", COLORTHRESHOLD, EffectInfo::VideoEffect,
+// "Color threshold filter", "Sigmund Augdal <dnumgis@videolan.org>"));
+
+// videoEffectList.append(new EffectInfo("(Video) Deinterlace", DEINTERLACE, EffectInfo::VideoEffect,
+// "Deinterlacing video filter", "Sam Hocevar <sam@zoy.org"));
+
+// videoEffectList.append(new EffectInfo("(Video) Erase", ERASE, EffectInfo::VideoEffect,
+// "Erase video filter", "Antoine Cellerier <dionoea at videolan dot org>"));
+
+// videoEffectList.append(new EffectInfo("(Video) Extract", EXTRACT, EffectInfo::VideoEffect,
+// "Extract RGB component video filter",
+// "Antoine Cellerier <dionoea at videolan dot org>"));
+
+// videoEffectList.append(new EffectInfo("(Video) Gaussian blur", GAUSSIAN_BLUR, EffectInfo::VideoEffect,
+// "Erase video filter", "Antoine Cellerier <dionoea at videolan dot org>"));
+
+// videoEffectList.append(new EffectInfo("(Video) Gradient", GRADIENT, EffectInfo::VideoEffect,
+// "Gradient video filter",
+// "Samuel Hocevar <sam@zoy.org>, "
+// "Antoine Cellerier <dionoea at videolan dot org>"));
+
+// videoEffectList.append(new EffectInfo("(Video) Grain", GRAIN, EffectInfo::VideoEffect,
+// "Grain video filter", "Antoine Cellerier <dionoea at videolan dot org>"));
+
+// videoEffectList.append(new EffectInfo("(Video) Invert", INVERT, EffectInfo::VideoEffect,
+// "Invert video filter - color inversion",
+// "Samuel Hocevar <sam@zoy.org>"));
+
+// videoEffectList.append(new EffectInfo("(Video) Motion blur", MOTIONBLUR, EffectInfo::VideoEffect,
+// "Motion blur filter",
+// "Sigmund Augdal Helberg <dnumgis@videolan.org>, "
+// "Antoine Cellerier <dionoea at videolan dot org>"));
+
+// videoEffectList.append(new EffectInfo("(Video) Motion detect", MOTIONDETECT, EffectInfo::VideoEffect,
+// "Motion detect video filter",
+// "Antoine Cellerier <dionoea at videolan dot org>"));
+
+// videoEffectList.append(new EffectInfo("(Video) Noise", NOISE, EffectInfo::VideoEffect,
+// "Noise video filter - add noise to image",
+// "Antoine Cellerier <dionoea at videolan dot org>"));
+
+// videoEffectList.append(new EffectInfo("(Video) Postprocess", POSTPROCESS, EffectInfo::VideoEffect,
+// "Video post processing filter",
+// "Laurent Aimar <fenrir@via.ecp.fr>, "
+// "Gildas Bazin <gbazin@netcourrier.com>, "
+// "Antoine Cellerier <dionoea at videolan dot org>"));
+
+// videoEffectList.append(new EffectInfo("(Video) Psychedelic", PSYCHEDELIC, EffectInfo::VideoEffect,
+// "Psychedelic video filter",
+// "Samuel Hocevar <sam@zoy.org>, "
+// "Antoine Cellerier <dionoea at videolan dot org>"));
+
+// videoEffectList.append(new EffectInfo("(Video) Ripple", RIPPLE, EffectInfo::VideoEffect,
+// "Ripple video filter",
+// "Samuel Hocevar <sam@zoy.org>, "
+// "Antoine Cellerier <dionoea at videolan dot org>"));
+
+// videoEffectList.append(new EffectInfo("(Video) Rotate", ROTATE, EffectInfo::VideoEffect,
+// "Rotate video filter",
+// "Antoine Cellerier <dionoea at videolan dot org>"));
+
+// videoEffectList.append(new EffectInfo("(Video) Seam carving", SEAM_CARVING, EffectInfo::VideoEffect,
+// "Seam Carving for Content-Aware Image Resizing",
+// "Antoine Cellerier <dionoea at videolan dot org>"));
+
+// videoEffectList.append(new EffectInfo("(Video) Sharpen", SHARPEN, EffectInfo::VideoEffect,
+// "Sharpen video filter - Augment contrast between contours.",
+// "Jérémy DEMEULE <dj_mulder at djduron dot no-ip dot org>, "
+// "Jean-Baptiste Kempf <jb at videolan dot org>"));
+
+// videoEffectList.append(new EffectInfo("(Video) Wave", WAVE, EffectInfo::VideoEffect,
+// "Wave video filter",
+// "Samuel Hocevar <sam@zoy.org>, "
+// "Antoine Cellerier <dionoea at videolan dot org>"));
+
+ updateEffects();
+}
+
+EffectManager::~EffectManager()
+{
+ qDeleteAll(m_audioEffectList);
+ m_audioEffectList.clear();
+ qDeleteAll(m_videoEffectList);
+ m_videoEffectList.clear();
+ qDeleteAll(m_effectList);
+ m_effectList.clear();
+}
+
+/**
+ * Returns a list of available audio effects
+ */
+const QList<EffectInfo *> EffectManager::audioEffects() const
+{
+ return m_audioEffectList;
+}
+
+/**
+ * Returns a list of available video effects
+ */
+const QList<EffectInfo *> EffectManager::videoEffects() const
+{
+ return m_videoEffectList;
+}
+
+/**
+ * Returns a list of available effects
+ */
+const QList<EffectInfo *> EffectManager::effects() const
+{
+ return m_effectList;
+}
+
+void EffectManager::updateEffects()
+{
+ m_effectList.clear();
+ m_effectList += m_audioEffectList;
+ m_effectList += m_videoEffectList;
+}
+
+}
+} // namespace Phonon::VLC
--- /dev/null
+/*****************************************************************************
+ * VLC backend for the Phonon library *
+ * Copyright (C) 2007-2008 Tanguy Krotoff <tkrotoff@gmail.com> *
+ * Copyright (C) 2008 Lukas Durfina <lukas.durfina@gmail.com> *
+ * Copyright (C) 2009 Fathi Boudra <fabo@kde.org> *
+ * *
+ * This program is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 3 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 *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this package; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *
+ *****************************************************************************/
+
+#ifndef Phonon_VLC_EFFECTMANAGER_H
+#define Phonon_VLC_EFFECTMANAGER_H
+
+#include <phonon/effectinterface.h>
+#include <phonon/effectparameter.h>
+
+#include <QtCore/QObject>
+
+namespace Phonon
+{
+namespace VLC {
+class Backend;
+class EffectManager;
+
+class EffectInfo
+{
+public:
+
+ enum Type {AudioEffect, VideoEffect};
+
+ EffectInfo(const QString &name,
+ const QString &description,
+ const QString &author,
+ int filter,
+ Type type);
+
+ QString name() const {
+ return m_name;
+ }
+
+ QString description() const {
+ return m_description;
+ }
+
+ QString author() const {
+ return m_author;
+ }
+
+ int filter() const {
+ return m_filter;
+ }
+
+ Type type() const {
+ return m_type;
+ }
+
+private:
+ QString m_name;
+ QString m_description;
+ QString m_author;
+ int m_filter;
+ Type m_type;
+};
+
+class EffectManager : public QObject
+{
+ Q_OBJECT
+
+public:
+ EffectManager(Backend *parent);
+ virtual ~EffectManager();
+
+ const QList<EffectInfo *> audioEffects() const;
+ const QList<EffectInfo *> videoEffects() const;
+ const QList<EffectInfo *> effects() const;
+
+private:
+ void updateEffects();
+
+ Backend *m_backend;
+ QList<EffectInfo *> m_effectList;
+ QList<EffectInfo *> m_audioEffectList;
+ QList<EffectInfo *> m_videoEffectList;
+ bool m_equalizerEnabled;
+};
+
+}
+} // namespace Phonon::VLC
+
+#endif // Phonon_VLC_EFFECTMANAGER_H
--- /dev/null
+/*****************************************************************************
+ * VLC backend for the Phonon library *
+ * Copyright (C) 2007-2008 Tanguy Krotoff <tkrotoff@gmail.com> *
+ * Copyright (C) 2008 Lukas Durfina <lukas.durfina@gmail.com> *
+ * Copyright (C) 2009 Fathi Boudra <fabo@kde.org> *
+ * *
+ * This program is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 3 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 *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this package; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *
+ *****************************************************************************/
+
+#include "mediacontroller.h"
+
+namespace Phonon
+{
+namespace VLC {
+
+MediaController::MediaController()
+{
+ clearMediaController();
+}
+
+MediaController::~MediaController()
+{
+}
+
+void MediaController::clearMediaController()
+{
+ current_audio_channel = Phonon::AudioChannelDescription();
+ available_audio_channels.clear();
+
+ current_subtitle = Phonon::SubtitleDescription();
+ available_subtitles.clear();
+
+// current_chapter = Phonon::ChapterDescription();
+// available_chapters.clear();
+ current_chapter = 0;
+ available_chapters = 0;
+
+// current_title = Phonon::TitleDescription();
+// available_titles.clear();
+ current_title = 0;
+ available_titles = 0;
+
+ i_current_angle = 0;
+ i_available_angles = 0;
+
+ b_autoplay_titles = false;
+}
+
+bool MediaController::hasInterface(Interface iface) const
+{
+ switch (iface) {
+ case AddonInterface::NavigationInterface:
+ return true;
+ break;
+ case AddonInterface::ChapterInterface:
+ return true;
+ break;
+ case AddonInterface::AngleInterface:
+ return true;
+ break;
+ case AddonInterface::TitleInterface:
+ return true;
+ break;
+ case AddonInterface::SubtitleInterface:
+ return true;
+ break;
+ case AddonInterface::AudioChannelInterface:
+ return true;
+ break;
+ default:
+ qCritical() << __FUNCTION__
+ << "Error: unsupported AddonInterface::Interface"
+ << iface;
+ }
+
+ return false;
+}
+
+QVariant MediaController::interfaceCall(Interface iface, int i_command, const QList<QVariant> & arguments)
+{
+ switch (iface) {
+ case AddonInterface::ChapterInterface:
+ switch (static_cast<AddonInterface::ChapterCommand>(i_command)) {
+// case AddonInterface::availableChapters:
+// return QVariant::fromValue(availableChapters());
+ case AddonInterface::availableChapters:
+ return availableChapters();
+// case AddonInterface::currentChapter:
+// return QVariant::fromValue(currentChapter());
+ case AddonInterface::chapter:
+ return currentChapter();
+// case AddonInterface::setCurrentChapter:
+// if( arguments.isEmpty() || !arguments.first().canConvert<ChapterDescription>()) {
+// qCritical() << __FUNCTION__ << "Error: arguments invalid";
+// return false;
+// }
+// setCurrentChapter(arguments.first().value<ChapterDescription>());
+// return true;
+ case AddonInterface::setChapter:
+ if (arguments.isEmpty() || !arguments.first().canConvert(QVariant::Int)) {
+ qCritical() << __FUNCTION__ << "Error: arguments invalid";
+ return false;
+ }
+ setCurrentChapter(arguments.first().toInt());
+ return true;
+ default:
+ qCritical() << __FUNCTION__
+ << "Error: unsupported AddonInterface::ChapterInterface command:"
+ << i_command;
+ }
+ break;
+ case AddonInterface::TitleInterface:
+ switch (static_cast<AddonInterface::TitleCommand>(i_command)) {
+// case AddonInterface::availableTitles:
+// return QVariant::fromValue(availableTitles());
+ case AddonInterface::availableTitles:
+ return availableTitles();
+// case AddonInterface::currentTitle:
+// return QVariant::fromValue(currentTitle());
+ case AddonInterface::title:
+ return currentTitle();
+// case AddonInterface::setCurrentTitle:
+// if( arguments.isEmpty() || !arguments.first().canConvert<TitleDescription>()) {
+// qCritical() << __FUNCTION__ << "Error: arguments invalid";
+// return false;
+// }
+// setCurrentTitle(arguments.first().value<TitleDescription>());
+// return true;
+ case AddonInterface::setTitle:
+ if (arguments.isEmpty() || !arguments.first().canConvert(QVariant::Int)) {
+ qCritical() << __FUNCTION__ << "Error: arguments invalid";
+ return false;
+ }
+ setCurrentTitle(arguments.first().toInt());
+ return true;
+ case AddonInterface::autoplayTitles:
+ return autoplayTitles();
+ case AddonInterface::setAutoplayTitles:
+ if (arguments.isEmpty() || !arguments.first().canConvert(QVariant::Bool)) {
+ qCritical() << __FUNCTION__ << "Error: arguments invalid";
+ return false;
+ }
+ setAutoplayTitles(arguments.first().toBool());
+ return true;
+ default:
+ qCritical() << __FUNCTION__
+ << "Error: unsupported AddonInterface::TitleInterface command:"
+ << i_command;
+ }
+ break;
+ case AddonInterface::AngleInterface:
+ switch (static_cast<AddonInterface::AngleCommand>(i_command)) {
+ case AddonInterface::availableAngles:
+ case AddonInterface::angle:
+ case AddonInterface::setAngle:
+ break;
+ default:
+ qCritical() << __FUNCTION__
+ << "Error: unsupported AddonInterface::AngleInterface command:"
+ << i_command;
+ }
+ break;
+ case AddonInterface::SubtitleInterface:
+ switch (static_cast<AddonInterface::SubtitleCommand>(i_command)) {
+ case AddonInterface::availableSubtitles:
+ return QVariant::fromValue(availableSubtitles());
+ case AddonInterface::currentSubtitle:
+ return QVariant::fromValue(currentSubtitle());
+ case AddonInterface::setCurrentSubtitle:
+ if (arguments.isEmpty() || !arguments.first().canConvert<SubtitleDescription>()) {
+ qCritical() << __FUNCTION__ << "Error: arguments invalid";
+ return false;
+ }
+ setCurrentSubtitle(arguments.first().value<SubtitleDescription>());
+ return true;
+ default:
+ qCritical() << __FUNCTION__
+ << "Error: unsupported AddonInterface::SubtitleInterface command:"
+ << i_command;
+ }
+ break;
+ case AddonInterface::AudioChannelInterface:
+ switch (static_cast<AddonInterface::AudioChannelCommand>(i_command)) {
+ case AddonInterface::availableAudioChannels:
+ return QVariant::fromValue(availableAudioChannels());
+ case AddonInterface::currentAudioChannel:
+ return QVariant::fromValue(currentAudioChannel());
+ case AddonInterface::setCurrentAudioChannel:
+ if (arguments.isEmpty() || !arguments.first().canConvert<AudioChannelDescription>()) {
+ qCritical() << __FUNCTION__ << "Error: arguments invalid";
+ return false;
+ }
+ setCurrentAudioChannel(arguments.first().value<AudioChannelDescription>());
+ return true;
+ default:
+ qCritical() << __FUNCTION__
+ << "Error: unsupported AddonInterface::AudioChannelInterface command:"
+ << i_command;
+ }
+ break;
+ default:
+ qCritical() << __FUNCTION__
+ << "Error: unsupported AddonInterface::Interface:"
+ << iface;
+ }
+
+ return QVariant();
+}
+
+}
+} // Namespace Phonon::VLC
--- /dev/null
+/*****************************************************************************
+ * VLC backend for the Phonon library *
+ * Copyright (C) 2007-2008 Tanguy Krotoff <tkrotoff@gmail.com> *
+ * Copyright (C) 2008 Lukas Durfina <lukas.durfina@gmail.com> *
+ * Copyright (C) 2009 Fathi Boudra <fabo@kde.org> *
+ * *
+ * This program is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 3 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 *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this package; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *
+ *****************************************************************************/
+
+#ifndef PHONON_VLC_MEDIACONTROLLER_H
+#define PHONON_VLC_MEDIACONTROLLER_H
+
+#include <phonon/addoninterface.h>
+#include <phonon/objectdescription.h>
+
+namespace Phonon
+{
+namespace VLC {
+
+/**
+ * Interface for AddonInterface.
+ *
+ * This class cannot inherit from QObject has MediaObject already inherit from QObject.
+ * This is a Qt limitation: there is no possibility to inherit virtual Qobject :/
+ * See http://doc.trolltech.com/qq/qq15-academic.html
+ * Phonon implementation got the same problem.
+ *
+ * @see VLCMediaController
+ * @see VLCMediaObject
+ * @see MediaObject
+ */
+class MediaController : public AddonInterface
+{
+public:
+
+ MediaController();
+ virtual ~MediaController();
+
+ bool hasInterface(Interface iface) const;
+
+ QVariant interfaceCall(Interface iface, int i_command, const QList<QVariant> & arguments = QList<QVariant>());
+
+ // MediaController signals
+ virtual void availableSubtitlesChanged() = 0;
+ virtual void availableAudioChannelsChanged() = 0;
+
+// virtual void availableChaptersChanged() = 0;
+// virtual void availableTitlesChanged() = 0;
+ virtual void availableChaptersChanged(int) = 0;
+ virtual void availableTitlesChanged(int) = 0;
+
+ virtual void availableAnglesChanged(int i_available_angles) = 0;
+ virtual void angleChanged(int i_angle_number) = 0;
+ virtual void chapterChanged(int i_chapter_number) = 0;
+ virtual void titleChanged(int i_title_number) = 0;
+
+protected:
+
+ // AudioChannel
+ virtual void setCurrentAudioChannel(const Phonon::AudioChannelDescription & audioChannel) = 0;
+ virtual QList<Phonon::AudioChannelDescription> availableAudioChannels() const = 0;
+ virtual Phonon::AudioChannelDescription currentAudioChannel() const = 0;
+
+ // Subtitle
+ virtual void setCurrentSubtitle(const Phonon::SubtitleDescription & subtitle) = 0;
+ virtual QList<Phonon::SubtitleDescription> availableSubtitles() const = 0;
+ virtual Phonon::SubtitleDescription currentSubtitle() const = 0;
+
+ // Angle
+ virtual void setCurrentAngle(int i_angle_number) = 0;
+ virtual int availableAngles() const = 0;
+ virtual int currentAngle() const = 0;
+
+ // Chapter
+// virtual void setCurrentChapter( const Phonon::ChapterDescription & chapter ) = 0;
+// virtual QList<Phonon::ChapterDescription> availableChapters() const = 0;
+// virtual Phonon::ChapterDescription currentChapter() const = 0;
+ virtual void setCurrentChapter(int chapterNumber) = 0;
+ virtual int availableChapters() const = 0;
+ virtual int currentChapter() const = 0;
+
+ // Title
+// virtual void setCurrentTitle( const Phonon::TitleDescription & title ) = 0;
+// virtual QList<Phonon::TitleDescription> availableTitles() const = 0;
+// virtual Phonon::TitleDescription currentTitle() const = 0;
+ virtual void setCurrentTitle(int titleNumber) = 0;
+ virtual int availableTitles() const = 0;
+ virtual int currentTitle() const = 0;
+
+ virtual void setAutoplayTitles(bool b_autoplay) = 0;
+ virtual bool autoplayTitles() const = 0;
+
+ /**
+ * Clear all (i.e availableSubtitles, availableChapters...).
+ *
+ * This is used each time we restart the video.
+ */
+ virtual void clearMediaController();
+
+ Phonon::AudioChannelDescription current_audio_channel;
+ QList<Phonon::AudioChannelDescription> available_audio_channels;
+
+ Phonon::SubtitleDescription current_subtitle;
+ QList<Phonon::SubtitleDescription> available_subtitles;
+
+// Phonon::ChapterDescription current_chapter;
+// QList<Phonon::ChapterDescription> available_chapters;
+ int current_chapter;
+ int available_chapters;
+
+// Phonon::TitleDescription current_title;
+// QList<Phonon::TitleDescription> available_titles;
+ int current_title;
+ int available_titles;
+
+ int i_current_angle;
+ int i_available_angles;
+
+ bool b_autoplay_titles;
+
+private:
+};
+
+}
+} // Namespace Phonon::VLC
+
+#endif // PHONON_VLC_MEDIACONTROLLER_H
--- /dev/null
+/*****************************************************************************
+ * VLC backend for the Phonon library *
+ * Copyright (C) 2007-2008 Tanguy Krotoff <tkrotoff@gmail.com> *
+ * Copyright (C) 2008 Lukas Durfina <lukas.durfina@gmail.com> *
+ * Copyright (C) 2009 Fathi Boudra <fabo@kde.org> *
+ * *
+ * This program is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 3 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 *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this package; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *
+ *****************************************************************************/
+
+#include "mediaobject.h"
+
+#include "seekstack.h"
+
+#include <QtCore/QUrl>
+#include <QtCore/QMetaType>
+#include <QtCore/QTimer>
+
+//Time in milliseconds before sending aboutToFinish() signal
+//2 seconds
+static const int ABOUT_TO_FINISH_TIME = 2000;
+
+namespace Phonon
+{
+namespace VLC {
+
+MediaObject::MediaObject(QObject *p_parent)
+ : QObject(p_parent)
+{
+ currentState = Phonon::LoadingState;
+ i_video_widget_id = 0;
+ b_prefinish_mark_reached_emitted = false;
+ b_about_to_finish_emitted = false;
+ i_transition_time = 0;
+
+ // By default, no tick() signal
+ // FIXME: Not implemented yet
+ i_tick_interval = 0;
+
+ qRegisterMetaType<QMultiMap<QString, QString> >("QMultiMap<QString, QString>");
+
+ connect(this, SIGNAL(stateChanged(Phonon::State)),
+ SLOT(stateChangedInternal(Phonon::State)));
+
+ connect(this, SIGNAL(tickInternal(qint64)),
+ SLOT(tickInternalSlot(qint64)));
+}
+
+MediaObject::~MediaObject()
+{
+}
+
+void MediaObject::setVideoWidgetId(int i_widget_id)
+{
+ i_video_widget_id = i_widget_id;
+}
+
+void MediaObject::play()
+{
+ qDebug() << __FUNCTION__;
+
+ if (currentState == Phonon::PausedState) {
+ resume();
+ } else {
+ // Play the file
+ playInternal();
+ }
+}
+
+void MediaObject::seek(qint64 milliseconds)
+{
+ static SeekStack *p_stack = new SeekStack(this);
+
+ p_stack->pushSeek(milliseconds);
+
+ qint64 currentTime = this->currentTime();
+ qint64 totalTime = this->totalTime();
+
+ if (currentTime < totalTime - i_prefinish_mark) {
+ b_prefinish_mark_reached_emitted = false;
+ }
+ if (currentTime < totalTime - ABOUT_TO_FINISH_TIME) {
+ b_about_to_finish_emitted = false;
+ }
+}
+
+void MediaObject::tickInternalSlot(qint64 currentTime)
+{
+ qint64 totalTime = this->totalTime();
+
+ if (i_tick_interval > 0) {
+ // If _tickInternal == 0 means tick() signal is disabled
+ // Default is _tickInternal = 0
+ emit tick(currentTime);
+ }
+
+ if (currentState == Phonon::PlayingState) {
+ if (currentTime >= totalTime - i_prefinish_mark) {
+ if (!b_prefinish_mark_reached_emitted) {
+ b_prefinish_mark_reached_emitted = true;
+ emit prefinishMarkReached(totalTime - currentTime);
+ }
+ }
+ if (currentTime >= totalTime - ABOUT_TO_FINISH_TIME) {
+ if (!b_about_to_finish_emitted) {
+ // Track is about to finish
+ b_about_to_finish_emitted = true;
+ emit aboutToFinish();
+ }
+ }
+ }
+}
+
+void MediaObject::loadMedia(const QString & filename)
+{
+ // Default MediaObject state is Phonon::LoadingState
+ currentState = Phonon::LoadingState;
+
+ // Load the media
+ loadMediaInternal(filename);
+}
+
+void MediaObject::resume()
+{
+ pause();
+}
+
+qint32 MediaObject::tickInterval() const
+{
+ return i_tick_interval;
+}
+
+void MediaObject::setTickInterval(qint32 tickInterval)
+{
+ i_tick_interval = tickInterval;
+// if (_tickInterval <= 0) {
+// _tickTimer->setInterval(50);
+// } else {
+// _tickTimer->setInterval(_tickInterval);
+// }
+}
+
+qint64 MediaObject::currentTime() const
+{
+ qint64 time = -1;
+ Phonon::State st = state();
+
+ switch (st) {
+ case Phonon::PausedState:
+ time = currentTimeInternal();
+ break;
+ case Phonon::BufferingState:
+ time = currentTimeInternal();
+ break;
+ case Phonon::PlayingState:
+ time = currentTimeInternal();
+ break;
+ case Phonon::StoppedState:
+ time = 0;
+ break;
+ case Phonon::LoadingState:
+ time = 0;
+ break;
+ case Phonon::ErrorState:
+ time = -1;
+ break;
+ default:
+ qCritical() << __FUNCTION__ << "Error: unsupported Phonon::State:" << st;
+ }
+
+ return time;
+}
+
+Phonon::State MediaObject::state() const
+{
+ return currentState;
+}
+
+Phonon::ErrorType MediaObject::errorType() const
+{
+ return Phonon::NormalError;
+}
+
+MediaSource MediaObject::source() const
+{
+ return mediaSource;
+}
+
+void MediaObject::setSource(const MediaSource & source)
+{
+ qDebug() << __FUNCTION__;
+
+ mediaSource = source;
+
+ switch (source.type()) {
+ case MediaSource::Invalid:
+ break;
+ case MediaSource::LocalFile:
+ loadMedia(mediaSource.fileName());
+ break;
+ case MediaSource::Url:
+ loadMedia(mediaSource.url().toString());
+ break;
+ case MediaSource::Disc:
+ switch (source.discType()) {
+ case Phonon::NoDisc:
+ qCritical() << __FUNCTION__
+ << "Error: the MediaSource::Disc doesn't specify which one (Phonon::NoDisc)";
+ return;
+ case Phonon::Cd:
+ loadMedia(mediaSource.deviceName());
+ break;
+ case Phonon::Dvd:
+ loadMedia("dvd://" + mediaSource.deviceName());
+ break;
+ case Phonon::Vcd:
+ loadMedia(mediaSource.deviceName());
+ break;
+ default:
+ qCritical() << __FUNCTION__ << "Error: unsupported MediaSource::Disc:" << source.discType();
+ break;
+ }
+ break;
+ case MediaSource::Stream:
+ break;
+ default:
+ qCritical() << __FUNCTION__
+ << "Error: unsupported MediaSource:"
+ << source.type();
+ break;
+ }
+}
+
+void MediaObject::setNextSource(const MediaSource & source)
+{
+ setSource(source);
+}
+
+qint32 MediaObject::prefinishMark() const
+{
+ return i_prefinish_mark;
+}
+
+void MediaObject::setPrefinishMark(qint32 msecToEnd)
+{
+ i_prefinish_mark = msecToEnd;
+ if (currentTime() < totalTime() - i_prefinish_mark) {
+ // Not about to finish
+ b_prefinish_mark_reached_emitted = false;
+ }
+}
+
+qint32 MediaObject::transitionTime() const
+{
+ return i_transition_time;
+}
+
+void MediaObject::setTransitionTime(qint32 time)
+{
+ i_transition_time = time;
+}
+
+void MediaObject::stateChangedInternal(Phonon::State newState)
+{
+ qDebug() << __FUNCTION__ << "newState:" << newState
+ << "previousState:" << currentState ;
+
+ if (newState == currentState) {
+ // State not changed
+ return;
+ }
+
+ // State changed
+ Phonon::State previousState = currentState;
+ currentState = newState;
+ emit stateChanged(currentState, previousState);
+}
+
+}
+} // Namespace Phonon::VLC
--- /dev/null
+/*****************************************************************************
+ * VLC backend for the Phonon library *
+ * Copyright (C) 2007-2008 Tanguy Krotoff <tkrotoff@gmail.com> *
+ * Copyright (C) 2008 Lukas Durfina <lukas.durfina@gmail.com> *
+ * Copyright (C) 2009 Fathi Boudra <fabo@kde.org> *
+ * *
+ * This program is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 3 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 *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this package; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *
+ *****************************************************************************/
+
+#ifndef PHONON_VLC_MEDIAOBJECT_H
+#define PHONON_VLC_MEDIAOBJECT_H
+
+#include <phonon/mediaobjectinterface.h>
+
+#include <QtCore/QObject>
+
+namespace Phonon
+{
+namespace VLC {
+
+class SeekStack;
+
+class MediaObject : public QObject, public MediaObjectInterface
+{
+ Q_OBJECT
+ friend class SeekStack;
+
+public:
+
+ MediaObject(QObject *p_parent);
+ virtual ~MediaObject();
+
+ /**
+ * Widget Id where VLC will show the videos.
+ */
+ void setVideoWidgetId(int i_widget_id);
+
+ void play();
+ void seek(qint64 milliseconds);
+
+ qint32 tickInterval() const;
+ void setTickInterval(qint32 tickInterval);
+
+ qint64 currentTime() const;
+ Phonon::State state() const;
+ Phonon::ErrorType errorType() const;
+ MediaSource source() const;
+ void setSource(const MediaSource & source);
+ void setNextSource(const MediaSource & source);
+
+ qint32 prefinishMark() const;
+ void setPrefinishMark(qint32 msecToEnd);
+
+ qint32 transitionTime() const;
+ void setTransitionTime(qint32);
+
+signals:
+
+ void aboutToFinish();
+// void bufferStatus( int i_percent_filled );
+// void currentSourceChanged( const MediaSource & newSource );
+ void finished();
+ void hasVideoChanged(bool b_has_video);
+ void metaDataChanged(const QMultiMap<QString, QString> & metaData);
+ void prefinishMarkReached(qint32 msecToEnd);
+ void seekableChanged(bool b_is_seekable);
+ void stateChanged(Phonon::State newState, Phonon::State oldState);
+ void tick(qint64 time);
+ void totalTimeChanged(qint64 newTotalTime);
+
+ // Signal from VLCMediaObject
+ void stateChanged(Phonon::State newState);
+
+ void tickInternal(qint64 time);
+
+protected:
+
+ virtual void loadMediaInternal(const QString & filename) = 0;
+ virtual void playInternal() = 0;
+ virtual void seekInternal(qint64 milliseconds) = 0;
+
+ virtual qint64 currentTimeInternal() const = 0;
+
+ int i_video_widget_id;
+
+private slots:
+
+ void stateChangedInternal(Phonon::State newState);
+
+ void tickInternalSlot(qint64 time);
+
+private:
+
+ void loadMedia(const QString & filename);
+
+ void resume();
+
+ MediaSource mediaSource;
+
+ Phonon::State currentState;
+
+ qint32 i_prefinish_mark;
+ bool b_prefinish_mark_reached_emitted;
+
+ bool b_about_to_finish_emitted;
+
+ qint32 i_tick_interval;
+ qint32 i_transition_time;
+};
+
+}
+} // Namespace Phonon::VLC
+
+#endif // PHONON_VLC_MEDIAOBJECT_H
--- /dev/null
+/*****************************************************************************
+ * VLC backend for the Phonon library *
+ * Copyright (C) 2007-2008 Tanguy Krotoff <tkrotoff@gmail.com> *
+ * Copyright (C) 2008 Lukas Durfina <lukas.durfina@gmail.com> *
+ * Copyright (C) 2009 Fathi Boudra <fabo@kde.org> *
+ * *
+ * This program is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 3 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 *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this package; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *
+ *****************************************************************************/
+
+#include "seekstack.h"
+
+#include <QtCore/QTimer>
+#include <QtCore/QDebug>
+
+namespace Phonon
+{
+namespace VLC {
+
+SeekStack::SeekStack(MediaObject *mediaObject)
+ : QObject(mediaObject)
+{
+ p_media_object = mediaObject;
+
+ p_timer = new QTimer(this);
+ connect(p_timer, SIGNAL(timeout()),
+ SLOT(popSeek()));
+ p_timer->setInterval(1000);
+}
+
+SeekStack::~SeekStack()
+{
+}
+
+void SeekStack::pushSeek(qint64 milliseconds)
+{
+ qDebug() << __FUNCTION__ << "seek:" << milliseconds;
+
+ disconnect(p_media_object, SIGNAL(tickInternal(qint64)),
+ p_media_object, SLOT(tickInternalSlot(qint64)));
+
+ stack.push(milliseconds);
+
+ if (!p_timer->isActive()) {
+ p_timer->start();
+ popSeek();
+ }
+}
+
+void SeekStack::popSeek()
+{
+ if (stack.isEmpty()) {
+ p_timer->stop();
+ reconnectTickSignal();
+ return;
+ }
+
+ int i_milliseconds = stack.pop();
+ stack.clear();
+
+ qDebug() << __FUNCTION__ << "real seek:" << i_milliseconds;
+
+ p_media_object->seekInternal(i_milliseconds);
+
+ reconnectTickSignal();
+}
+
+void SeekStack::reconnectTickSignal()
+{
+ connect(p_media_object, SIGNAL(tickInternal(qint64)),
+ p_media_object, SLOT(tickInternalSlot(qint64)));
+}
+
+}
+} // Namespace Phonon::VLC
--- /dev/null
+/*****************************************************************************
+ * VLC backend for the Phonon library *
+ * Copyright (C) 2007-2008 Tanguy Krotoff <tkrotoff@gmail.com> *
+ * Copyright (C) 2008 Lukas Durfina <lukas.durfina@gmail.com> *
+ * Copyright (C) 2009 Fathi Boudra <fabo@kde.org> *
+ * *
+ * This program is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 3 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 *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this package; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *
+ *****************************************************************************/
+
+#ifndef PHONON_VLC_SEEKSTACK_H
+#define PHONON_VLC_SEEKSTACK_H
+
+#include "mediaobject.h"
+
+#include <QtCore/QObject>
+#include <QtCore/QStack>
+
+class QTimer;
+
+namespace Phonon
+{
+namespace VLC {
+
+/**
+ * A queue of seek commands.
+ */
+class SeekStack : public QObject
+{
+ Q_OBJECT
+
+public:
+
+ SeekStack(MediaObject *mediaObject);
+ ~SeekStack();
+
+ void pushSeek(qint64 milliseconds);
+
+signals:
+
+private slots:
+
+ void popSeek();
+
+ void reconnectTickSignal();
+
+private:
+
+ MediaObject *p_media_object;
+
+ QTimer *p_timer;
+
+ QStack<qint64> stack;
+};
+
+}
+} // Namespace Phonon::VLC
+
+#endif // PHONON_VLC_SEEKSTACK_H
--- /dev/null
+/*****************************************************************************
+ * VLC backend for the Phonon library *
+ * Copyright (C) 2007-2008 Tanguy Krotoff <tkrotoff@gmail.com> *
+ * Copyright (C) 2008 Lukas Durfina <lukas.durfina@gmail.com> *
+ * Copyright (C) 2009 Fathi Boudra <fabo@kde.org> *
+ * *
+ * This program is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 3 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 *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this package; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *
+ *****************************************************************************/
+
+#include "sinknode.h"
+
+#include "mediaobject.h"
+
+namespace Phonon
+{
+namespace VLC {
+
+SinkNode::SinkNode(QObject *p_parent)
+ : QObject(p_parent)
+{
+ p_media_object = 0;
+}
+
+SinkNode::~SinkNode()
+{
+}
+
+void SinkNode::connectToMediaObject(PrivateMediaObject * mediaObject)
+{
+ if (p_media_object)
+ qCritical() << __FUNCTION__ << "p_media_object already connected";
+
+ p_media_object = mediaObject;
+}
+
+void SinkNode::disconnectFromMediaObject(PrivateMediaObject * mediaObject)
+{
+ if (p_media_object != mediaObject)
+ qCritical() << __FUNCTION__ << "SinkNode was not connected to mediaObject";
+}
+
+
+}
+} // Namespace Phonon::VLC_MPlayer
--- /dev/null
+/*****************************************************************************
+ * VLC backend for the Phonon library *
+ * Copyright (C) 2007-2008 Tanguy Krotoff <tkrotoff@gmail.com> *
+ * Copyright (C) 2008 Lukas Durfina <lukas.durfina@gmail.com> *
+ * Copyright (C) 2009 Fathi Boudra <fabo@kde.org> *
+ * *
+ * This program is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 3 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 *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this package; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *
+ *****************************************************************************/
+
+#ifndef PHONON_VLC_SINKNODE_H
+#define PHONON_VLC_SINKNODE_H
+
+#include <QtCore/QObject>
+#include <QtCore/QString>
+
+namespace Phonon
+{
+namespace VLC {
+
+class VLCMediaObject;
+typedef VLCMediaObject PrivateMediaObject;
+
+class SinkNode : public QObject
+{
+ Q_OBJECT
+
+public:
+
+ SinkNode(QObject *p_parent);
+ virtual ~SinkNode();
+
+ virtual void connectToMediaObject(PrivateMediaObject *mediaObject);
+
+ virtual void disconnectFromMediaObject(PrivateMediaObject *mediaObject);
+
+protected:
+
+ PrivateMediaObject *p_media_object;
+
+private:
+
+};
+
+}
+} // Namespace Phonon::VLC
+
+#endif // PHONON_VLC_SINKNODE_H
--- /dev/null
+/*****************************************************************************
+ * VLC backend for the Phonon library *
+ * Copyright (C) 2007-2008 Tanguy Krotoff <tkrotoff@gmail.com> *
+ * Copyright (C) 2008 Lukas Durfina <lukas.durfina@gmail.com> *
+ * Copyright (C) 2009 Fathi Boudra <fabo@kde.org> *
+ * *
+ * This program is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 3 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 *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this package; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *
+ *****************************************************************************/
+
+#include "videowidget.h"
+
+#include "mediaobject.h"
+#include "vlcmediaobject.h"
+
+#include "vlcloader.h"
+
+#include <QtGui/QWidget>
+#include <QtGui/QApplication>
+#include <QtGui/QDesktopWidget>
+#include <QtCore/QtDebug>
+
+namespace Phonon
+{
+namespace VLC {
+
+VideoWidget::VideoWidget(QWidget *p_parent)
+ : SinkNode(p_parent)
+{
+ p_video_widget = new Widget(p_parent);
+
+ aspect_ratio = Phonon::VideoWidget::AspectRatioAuto;
+ scale_mode = Phonon::VideoWidget::FitInView;
+
+ b_filter_adjust_activated = false;
+ f_brightness = 0.0;
+ f_contrast = 0.0;
+ f_hue = 0.0;
+ f_saturation = 0.0;
+}
+
+VideoWidget::~VideoWidget()
+{
+}
+
+void VideoWidget::connectToMediaObject(PrivateMediaObject *mediaObject)
+{
+ SinkNode::connectToMediaObject(mediaObject);
+
+ connect(mediaObject, SIGNAL(videoWidgetSizeChanged(int, int)),
+ SLOT(videoWidgetSizeChanged(int, int)));
+
+ mediaObject->setVideoWidgetId((int) p_video_widget->winId());
+}
+
+Phonon::VideoWidget::AspectRatio VideoWidget::aspectRatio() const
+{
+ return aspect_ratio;
+}
+
+// VLC accepted formats are x:y (4:3, 16:9, etc...) expressing the global image aspect
+void VideoWidget::setAspectRatio(Phonon::VideoWidget::AspectRatio aspect)
+{
+ // finish if no player
+ if (!vlc_current_media_player)
+ return;
+
+ aspect_ratio = aspect;
+
+ switch (aspect_ratio) {
+ case Phonon::VideoWidget::AspectRatioAuto: // Let the decoder find the aspect ratio automatically from the media file (this is the default)
+// p_libvlc_video_set_aspect_ratio(p_vlc_current_media_player, "", vlc_exception);
+ vlcExceptionRaised();
+ break;
+ case Phonon::VideoWidget::AspectRatioWidget: // Fit the video into the widget making the aspect ratio depend solely on the size of the widget
+ // This way the aspect ratio is freely resizeable by the user
+// p_libvlc_video_set_aspect_ratio(p_vlc_current_media_player, "", vlc_exception);
+ vlcExceptionRaised();
+ break;
+ case Phonon::VideoWidget::AspectRatio4_3:
+// p_libvlc_video_set_aspect_ratio(p_vlc_current_media_player, "4:3", vlc_exception);
+ vlcExceptionRaised();
+ break;
+ case Phonon::VideoWidget::AspectRatio16_9:
+// p_libvlc_video_set_aspect_ratio(p_vlc_current_media_player, "16:9", vlc_exception);
+ vlcExceptionRaised();
+ break;
+ default:
+ qCritical() << __FUNCTION__ << "error: unsupported AspectRatio:" << (int) aspect_ratio;
+ }
+}
+
+Phonon::VideoWidget::ScaleMode VideoWidget::scaleMode() const
+{
+ return scale_mode;
+}
+
+// The ScaleMode enumeration describes how to treat aspect ratio during resizing of video
+void VideoWidget::setScaleMode(Phonon::VideoWidget::ScaleMode scale)
+{
+ scale_mode = scale;
+ switch (scale_mode) {
+ case Phonon::VideoWidget::FitInView: // The video will be fitted to fill the view keeping aspect ratio
+ break;
+ case Phonon::VideoWidget::ScaleAndCrop: // The video is scaled
+ break;
+ default:
+ qWarning() << __FUNCTION__ << "unknow Phonon::VideoWidget::ScaleMode:" << scale_mode;
+ }
+}
+
+qreal VideoWidget::brightness() const
+{
+ return f_brightness;
+}
+
+void VideoWidget::setBrightness(qreal brightness)
+{
+ f_brightness = brightness;
+
+ // vlc takes brightness in range 0.0 - 2.0
+ if (vlc_current_media_player) {
+ if (!b_filter_adjust_activated) {
+// p_libvlc_video_filter_add(p_vlc_current_media_player, ADJUST, vlc_exception);
+// vlcExceptionRaised();
+ b_filter_adjust_activated = true;
+ }
+// p_libvlc_video_set_brightness(p_vlc_current_media_player, f_brightness + 1.0, vlc_exception);
+// vlcExceptionRaised();
+ }
+}
+
+qreal VideoWidget::contrast() const
+{
+ return f_contrast;
+}
+
+void VideoWidget::setContrast(qreal contrast)
+{
+ f_contrast = contrast;
+
+ // vlc takes contrast in range 0.0 - 2.0
+ float f_contrast = contrast;
+ if (vlc_current_media_player) {
+ if (!b_filter_adjust_activated) {
+// p_libvlc_video_filter_add(p_vlc_current_media_player, ADJUST, vlc_exception);
+// vlcExceptionRaised();
+ b_filter_adjust_activated = true;
+ }
+// p_libvlc_video_set_contrast(p_vlc_current_media_player, f_contrast + 1.0, vlc_exception);
+// vlcExceptionRaised();
+ }
+}
+
+qreal VideoWidget::hue() const
+{
+ return f_hue;
+}
+
+void VideoWidget::setHue(qreal hue)
+{
+ f_hue = hue;
+
+ // vlc takes hue in range 0 - 360 in integer
+ int i_hue = (f_hue + 1.0) * 180;
+ if (vlc_current_media_player) {
+ if (!b_filter_adjust_activated) {
+// p_libvlc_video_filter_add(p_vlc_current_media_player, ADJUST, vlc_exception);
+// vlcExceptionRaised();
+ b_filter_adjust_activated = true;
+ }
+// p_libvlc_video_set_hue(p_vlc_current_media_player, i_hue, vlc_exception);
+// vlcExceptionRaised();
+ }
+
+}
+
+qreal VideoWidget::saturation() const
+{
+ return f_saturation;
+}
+
+void VideoWidget::setSaturation(qreal saturation)
+{
+ f_saturation = saturation;
+
+ // vlc takes brightness in range 0.0 - 3.0
+ if (vlc_current_media_player) {
+ if (!b_filter_adjust_activated) {
+// p_libvlc_video_filter_add(p_vlc_current_media_player, ADJUST, vlc_exception);
+// vlcExceptionRaised();
+ b_filter_adjust_activated = true;
+ }
+// p_libvlc_video_set_saturation(p_vlc_current_media_player, (f_saturation + 1.0) * 1.5, vlc_exception);
+// vlcExceptionRaised();
+ }
+}
+
+Widget * VideoWidget::widget()
+{
+ return p_video_widget;
+}
+
+void VideoWidget::videoWidgetSizeChanged(int i_width, int i_height)
+{
+ qDebug() << __FUNCTION__ << "video width" << i_width << "height:" << i_height;
+
+ // It resizes dynamically the widget and the main window
+ // Note: I didn't find another way
+
+ QSize videoSize(i_width, i_height);
+ videoSize.boundedTo(QApplication::desktop()->availableGeometry().size());
+
+ p_video_widget->hide();
+ p_video_widget->setVideoSize(videoSize);
+#ifdef Q_OS_WIN
+ QWidget *p_parent = qobject_cast<QWidget *>(this->parent());
+ QSize previousSize = p_parent->minimumSize();
+ p_parent->setMinimumSize(videoSize);
+#endif
+ p_video_widget->show();
+#ifdef Q_OS_WIN
+ p_parent->setMinimumSize(previousSize);
+#endif
+}
+
+}
+} // Namespace Phonon::VLC
--- /dev/null
+/*****************************************************************************
+ * VLC backend for the Phonon library *
+ * Copyright (C) 2007-2008 Tanguy Krotoff <tkrotoff@gmail.com> *
+ * Copyright (C) 2008 Lukas Durfina <lukas.durfina@gmail.com> *
+ * Copyright (C) 2009 Fathi Boudra <fabo@kde.org> *
+ * *
+ * This program is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 3 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 *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this package; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *
+ *****************************************************************************/
+
+#ifndef PHONON_VLC_VIDEOWIDGET_H
+#define PHONON_VLC_VIDEOWIDGET_H
+
+#include "sinknode.h"
+
+#include <phonon/videowidgetinterface.h>
+
+#include "vlcvideowidget.h"
+typedef Phonon::VLC::VLCVideoWidget Widget;
+
+
+namespace Phonon
+{
+namespace VLC {
+
+
+class VideoWidget : public SinkNode, public VideoWidgetInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(Phonon::VideoWidgetInterface)
+public:
+
+ VideoWidget(QWidget *p_parent);
+ ~VideoWidget();
+
+ void connectToMediaObject(PrivateMediaObject * mediaObject);
+
+ Phonon::VideoWidget::AspectRatio aspectRatio() const;
+ void setAspectRatio(Phonon::VideoWidget::AspectRatio aspect);
+
+ Phonon::VideoWidget::ScaleMode scaleMode() const;
+ void setScaleMode(Phonon::VideoWidget::ScaleMode scale);
+
+ qreal brightness() const;
+ void setBrightness(qreal brightness);
+
+ qreal contrast() const;
+ void setContrast(qreal contrast);
+
+ qreal hue() const;
+ void setHue(qreal hue);
+
+ qreal saturation() const;
+ void setSaturation(qreal saturation);
+
+ Widget * widget();
+
+private slots:
+
+ void videoWidgetSizeChanged(int width, int height);
+
+private:
+
+ Widget *p_video_widget;
+
+ Phonon::VideoWidget::AspectRatio aspect_ratio;
+
+ Phonon::VideoWidget::ScaleMode scale_mode;
+
+ bool b_filter_adjust_activated;
+ qreal f_brightness;
+ qreal f_contrast;
+ qreal f_hue;
+ qreal f_saturation;
+};
+
+}
+} // Namespace Phonon::VLC
+
+#endif // PHONON_VLC_VIDEOWIDGET_H
--- /dev/null
+[Desktop Entry]
+Type=Service
+X-KDE-ServiceTypes=PhononBackend
+MimeType=application/x-annodex;video/quicktime;video/x-quicktime;audio/x-m4a;application/x-quicktimeplayer;video/mkv;video/msvideo;video/x-msvideo;video/x-flic;audio/x-aiff;audio/aiff;audio/x-pn-aiff;audio/x-realaudio;audio/basic;audio/x-basic;audio/x-pn-au;audio/x-8svx;audio/8svx;audio/x-16sv;audio/168sv;image/x-ilbm;image/ilbm;video/x-anim;video/anim;image/png;image/x-png;video/mng;video/x-mng;audio/x-ogg;audio/x-speex+ogg;application/ogg;application/ogg;audio/vnd.rn-realaudio;audio/x-pn-realaudio-plugin;audio/x-real-audio;application/vnd.rn-realmedia;video/mpeg;video/x-mpeg;audio/x-wav;audio/wav;audio/x-pn-wav;audio/x-pn-windows-acm;audio/mpeg2;audio/x-mpeg2;audio/mpeg3;audio/x-mpeg3;audio/mpeg;audio/x-mpeg;x-mpegurl;audio/x-mpegurl;audio/mp3;audio/mpeg;video/x-ms-asf;application/x-flash-video;
+X-KDE-Library=phonon_vlc
+X-KDE-PhononBackendInfo-InterfaceVersion=1
+X-KDE-PhononBackendInfo-Version=0.1
+X-KDE-PhononBackendInfo-Website=http://www.videolan.org/
+Icon=phonon-vlc
+InitialPreference=10
+
+Name=VLC
+Name[x-test]=xxVLCxx
+
+Comment=Phonon VLC backend
+Comment[el]=Σύστημα υποστήριξης Phonon του VLC
+Comment[et]=Phononi VLC taustaprogramm
+Comment[fr]=Système de gestion VLC pour Phonon
+Comment[ga]=Inneall VLC Phonon
+Comment[gl]=Infraestrutura de VLC para Phonon
+Comment[km]=កម្មវិធីខាងក្រោយរបស់ Phonon VLC
+Comment[nb]=Phonon VLC-motor
+Comment[nds]=Phonon-Hülpprogramm VLC
+Comment[nl]=VLC-backend (Phonon)
+Comment[pt]=Infra-estrutura do VLC para o Phonon
+Comment[pt_BR]=Infraestrutura Phonon VLC
+Comment[sv]=Phonon VLC-gränssnitt
+Comment[tr]=Phonon VLC arka ucu
+Comment[uk]=Сервер VLC Phonon
+Comment[x-test]=xxPhonon VLC backendxx
--- /dev/null
+/*****************************************************************************
+ * VLC backend for the Phonon library *
+ * Copyright (C) 2007-2008 Tanguy Krotoff <tkrotoff@gmail.com> *
+ * Copyright (C) 2008 Lukas Durfina <lukas.durfina@gmail.com> *
+ * Copyright (C) 2009 Fathi Boudra <fabo@kde.org> *
+ * *
+ * This program is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 3 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 *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this package; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *
+ *****************************************************************************/
+
+#include "vlcloader.h"
+
+#include <QtCore/QDebug>
+#include <QtCore/QDir>
+#include <QtCore/QLibrary>
+#include <QtCore/QSettings>
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+
+// Global variables
+libvlc_instance_t *vlc_instance = 0;
+libvlc_exception_t *vlc_exception = new libvlc_exception_t();
+libvlc_media_player_t *vlc_current_media_player = 0;
+
+namespace Phonon
+{
+namespace VLC {
+
+bool vlcInit()
+{
+ // Global variables
+ vlc_instance = 0;
+ vlc_exception = new libvlc_exception_t();
+
+ QString path = vlcPath();
+ if (!path.isEmpty()) {
+ QString pluginsPath = path;
+#if defined(Q_OS_UNIX)
+ pluginsPath.append("/vlc");
+#elif defined(Q_OS_WIN)
+ pluginsPath.append("\plugins");
+#endif
+ // VLC command line options. See vlc --full-help
+ const char *vlcArgs[] = {
+ path.toLatin1().constData(),
+ "--plugin-path=", pluginsPath.toAscii().constData(),
+ "--verbose=2",
+ "--intf=dummy",
+ "--extraintf=logger",
+ "--ignore-config",
+ "--reset-plugins-cache",
+ "--no-media-library",
+ "--no-one-instance",
+ "--no-osd",
+ "--no-stats",
+ "--no-video-title-show"
+ };
+
+ libvlc_exception_init(vlc_exception);
+
+ // Create and initialize a libvlc instance (it should be done only once)
+ vlc_instance = libvlc_new(sizeof(vlcArgs) / sizeof(*vlcArgs),
+ vlcArgs,
+ vlc_exception);
+ vlcExceptionRaised();
+
+ return true;
+ } else {
+ return false;
+ }
+}
+
+void vlcRelease()
+{
+ libvlc_release(vlc_instance);
+ vlcExceptionRaised();
+ vlcUnload();
+}
+
+void vlcExceptionRaised()
+{
+ if (libvlc_exception_raised(vlc_exception)) {
+ qDebug() << "libvlc exception:" << libvlc_exception_get_message(vlc_exception);
+ libvlc_exception_clear(vlc_exception);
+ }
+}
+
+#if defined(Q_OS_UNIX)
+static bool libGreaterThan(const QString &lhs, const QString &rhs)
+{
+ QStringList lhsparts = lhs.split(QLatin1Char('.'));
+ QStringList rhsparts = rhs.split(QLatin1Char('.'));
+ Q_ASSERT(lhsparts.count() > 1 && rhsparts.count() > 1);
+
+ for (int i = 1; i < rhsparts.count(); ++i) {
+ if (lhsparts.count() <= i)
+ // left hand side is shorter, so it's less than rhs
+ return false;
+
+ bool ok = false;
+ int b = 0;
+ int a = lhsparts.at(i).toInt(&ok);
+ if (ok)
+ b = rhsparts.at(i).toInt(&ok);
+ if (ok) {
+ // both toInt succeeded
+ if (a == b)
+ continue;
+ return a > b;
+ } else {
+ // compare as strings;
+ if (lhsparts.at(i) == rhsparts.at(i))
+ continue;
+ return lhsparts.at(i) > rhsparts.at(i);
+ }
+ }
+
+ // they compared strictly equally so far
+ // lhs cannot be less than rhs
+ return true;
+}
+#endif
+
+static QStringList findAllLibVlc()
+{
+ QStringList paths;
+#if defined(Q_OS_UNIX)
+ paths = QString::fromLatin1(qgetenv("LD_LIBRARY_PATH"))
+ .split(QLatin1Char(':'), QString::SkipEmptyParts);
+ paths << QLatin1String("/usr/lib") << QLatin1String("/usr/local/lib");
+
+ QStringList foundVlcs;
+ foreach (const QString &path, paths) {
+ QDir dir = QDir(path);
+ QStringList entryList = dir.entryList(QStringList() << QLatin1String("libvlc.*"), QDir::Files);
+
+ qSort(entryList.begin(), entryList.end(), libGreaterThan);
+ foreach (const QString &entry, entryList)
+ foundVlcs << path + QLatin1Char('/') + entry;
+ }
+
+ return foundVlcs;
+#elif defined(Q_OS_WIN)
+ // Read VLC version and installation directory from Windows registry
+ QSettings settings(QSettings::SystemScope, "VideoLAN", "VLC");
+ QString vlcVersion = settings.value("Version").toString();
+ QString vlcInstallDir = settings.value("InstallDir").toString();
+ if (vlcVersion.startsWith("1.0") && !vlcInstallDir.isEmpty()) {
+ paths << vlcInstallDir + QLatin1Char('\') + "libvlc";
+ return paths;
+ } else {
+ return QString();
+ }
+#endif
+}
+
+static QLibrary *vlcLibrary = 0;
+
+QString vlcPath()
+{
+ static QString path;
+ if (!path.isEmpty()) {
+ return path;
+ }
+
+ vlcLibrary = new QLibrary();
+ QStringList paths = findAllLibVlc();
+ foreach(path, paths) {
+ vlcLibrary->setFileName(path);
+
+ if (vlcLibrary->resolve("libvlc_exception_init")) {
+ return path;
+ } else {
+ qDebug("Cannot resolve the symbol or load VLC library");
+ }
+ qWarning() << vlcLibrary->errorString();
+ }
+
+ vlcUnload();
+
+ return QString();
+}
+
+void vlcUnload()
+{
+ vlcLibrary->unload();
+ delete vlcLibrary;
+ vlcLibrary = 0;
+}
+
+}
+} // Namespace Phonon::VLC
--- /dev/null
+/*****************************************************************************
+ * VLC backend for the Phonon library *
+ * Copyright (C) 2007-2008 Tanguy Krotoff <tkrotoff@gmail.com> *
+ * Copyright (C) 2008 Lukas Durfina <lukas.durfina@gmail.com> *
+ * Copyright (C) 2009 Fathi Boudra <fabo@kde.org> *
+ * *
+ * This program is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 3 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 *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this package; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *
+ *****************************************************************************/
+
+#ifndef PHONON_VLC_VLC_LOADER_H
+#define PHONON_VLC_VLC_LOADER_H
+
+#include <vlc/vlc.h>
+
+class QString;
+
+/**
+ * VLC library instance global variable.
+ */
+extern libvlc_instance_t *vlc_instance;
+
+/**
+ * VLC library exception handling global variable.
+ */
+extern libvlc_exception_t *vlc_exception;
+
+/**
+ * VLC library media player global variable.
+ */
+extern libvlc_media_player_t *vlc_current_media_player;
+
+namespace Phonon
+{
+namespace VLC {
+
+/**
+ * Get VLC path.
+ *
+ * @return the VLC path
+ */
+QString vlcPath();
+
+/**
+ * Unload VLC library.
+ */
+void vlcUnload();
+
+/**
+ * Check for a VLC library exception.
+ *
+ * show an error message when an exception has been raised.
+ */
+void vlcExceptionRaised();
+
+/**
+ * Initialize and launch VLC library.
+ *
+ * instance and exception handling global variables are initialized.
+ *
+ * @return VLC initialization result
+ */
+bool vlcInit();
+
+/**
+ * Stop VLC library.
+ */
+void vlcRelease();
+
+}
+} // Namespace Phonon::VLC
+
+#endif // PHONON_VLC_VLC_LOADER_H
--- /dev/null
+/*****************************************************************************
+ * VLC backend for the Phonon library *
+ * Copyright (C) 2007-2008 Tanguy Krotoff <tkrotoff@gmail.com> *
+ * Copyright (C) 2008 Lukas Durfina <lukas.durfina@gmail.com> *
+ * Copyright (C) 2009 Fathi Boudra <fabo@kde.org> *
+ * *
+ * This program is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 3 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 *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this package; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *
+ *****************************************************************************/
+
+#include "vlcmediacontroller.h"
+
+#include "vlcloader.h"
+
+namespace Phonon
+{
+namespace VLC {
+
+VLCMediaController::VLCMediaController()
+ : MediaController()
+{
+ p_vlc_media_player = 0;
+}
+
+VLCMediaController::~VLCMediaController()
+{
+}
+
+void VLCMediaController::clearMediaController()
+{
+ current_audio_channel = Phonon::AudioChannelDescription();
+ available_audio_channels.clear();
+
+ current_subtitle = Phonon::SubtitleDescription();
+ available_subtitles.clear();
+
+ i_current_angle = 0;
+ i_available_angles = 0;
+
+// current_chapter = Phonon::ChapterDescription();
+// available_chapters.clear();
+ current_chapter = 0;
+ available_chapters = 0;
+
+// current_title = Phonon::TitleDescription();
+// available_titles.clear();
+ current_title = 0;
+ available_titles = 0;
+
+ b_autoplay_titles = false;
+
+ emit availableAudioChannelsChanged();
+ emit availableSubtitlesChanged();
+ emit availableTitlesChanged(0);
+ emit availableChaptersChanged(0);
+}
+
+// Add audio channel -> in libvlc it is track, it means audio in another language
+void VLCMediaController::audioChannelAdded(int id, const QString & lang)
+{
+ QHash<QByteArray, QVariant> properties;
+ properties.insert("name", lang);
+ properties.insert("description", "");
+
+ available_audio_channels << Phonon::AudioChannelDescription(id, properties);
+ emit availableAudioChannelsChanged();
+}
+
+// Add subtitle
+void VLCMediaController::subtitleAdded(int id, const QString & lang, const QString & type)
+{
+ QHash<QByteArray, QVariant> properties;
+ properties.insert("name", lang);
+ properties.insert("description", "");
+ properties.insert("type", type);
+
+ available_subtitles << Phonon::SubtitleDescription(id, properties);
+ emit availableSubtitlesChanged();
+}
+
+// Add title
+void VLCMediaController::titleAdded(int id, const QString & name)
+{
+// QHash<QByteArray, QVariant> properties;
+// properties.insert("name", name);
+// properties.insert("description", "");
+
+// available_titles << Phonon::TitleDescription(id, properties);
+ available_titles++;
+ emit availableTitlesChanged(available_titles);
+}
+
+// Add chapter
+void VLCMediaController::chapterAdded(int titleId, const QString & name)
+{
+// QHash<QByteArray, QVariant> properties;
+// properties.insert("name", name);
+// properties.insert("description", "");
+
+// available_chapters << Phonon::ChapterDescription(titleId, properties);
+ available_chapters++;
+ emit availableChaptersChanged(available_chapters);
+}
+
+// Audio channel
+
+void VLCMediaController::setCurrentAudioChannel(const Phonon::AudioChannelDescription & audioChannel)
+{
+ current_audio_channel = audioChannel;
+ libvlc_audio_set_track(p_vlc_media_player, audioChannel.index(), vlc_exception);
+ vlcExceptionRaised();
+}
+
+QList<Phonon::AudioChannelDescription> VLCMediaController::availableAudioChannels() const
+{
+ return available_audio_channels;
+}
+
+Phonon::AudioChannelDescription VLCMediaController::currentAudioChannel() const
+{
+ return current_audio_channel;
+}
+
+void VLCMediaController::refreshAudioChannels()
+{
+ current_audio_channel = Phonon::AudioChannelDescription();
+ available_audio_channels.clear();
+
+ libvlc_track_description_t * p_info = libvlc_audio_get_track_description(
+ p_vlc_media_player, vlc_exception);
+ vlcExceptionRaised();
+ while (p_info) {
+ audioChannelAdded(p_info->i_id, p_info->psz_name);
+ p_info = p_info->p_next;
+ }
+ libvlc_track_description_release(p_info);
+}
+
+// Subtitle
+
+void VLCMediaController::setCurrentSubtitle(const Phonon::SubtitleDescription & subtitle)
+{
+ current_subtitle = subtitle;
+// int id = current_subtitle.index();
+ QString type = current_subtitle.property("type").toString();
+
+ if (type == "file") {
+ QString filename = current_subtitle.property("name").toString();
+ if (!filename.isEmpty()) {
+ libvlc_video_set_subtitle_file(p_vlc_media_player,
+ filename.toAscii().data(),
+ vlc_exception);
+ vlcExceptionRaised();
+
+ // There is no subtitle event inside libvlc so let's send our own event...
+ available_subtitles << current_subtitle;
+ emit availableSubtitlesChanged();
+ }
+ } else {
+ libvlc_video_set_spu(p_vlc_media_player, subtitle.index(), vlc_exception);
+ vlcExceptionRaised();
+ }
+}
+
+QList<Phonon::SubtitleDescription> VLCMediaController::availableSubtitles() const
+{
+ return available_subtitles;
+}
+
+Phonon::SubtitleDescription VLCMediaController::currentSubtitle() const
+{
+ return current_subtitle;
+}
+
+void VLCMediaController::refreshSubtitles()
+{
+ current_subtitle = Phonon::SubtitleDescription();
+ available_subtitles.clear();
+
+ libvlc_track_description_t *p_info = libvlc_video_get_spu_description(
+ p_vlc_media_player, vlc_exception);
+ vlcExceptionRaised();
+ while (p_info) {
+ subtitleAdded(p_info->i_id, p_info->psz_name, "");
+ p_info = p_info->p_next;
+ }
+ libvlc_track_description_release(p_info);
+}
+
+// Title
+
+//void VLCMediaController::setCurrentTitle( const Phonon::TitleDescription & title )
+void VLCMediaController::setCurrentTitle(int title)
+{
+ current_title = title;
+
+// libvlc_media_player_set_title(p_vlc_media_player, title.index(), vlc_exception);
+ libvlc_media_player_set_title(p_vlc_media_player, title, vlc_exception);
+ vlcExceptionRaised();
+}
+
+//QList<Phonon::TitleDescription> VLCMediaController::availableTitles() const
+int VLCMediaController::availableTitles() const
+{
+ return available_titles;
+}
+
+//Phonon::TitleDescription VLCMediaController::currentTitle() const
+int VLCMediaController::currentTitle() const
+{
+ return current_title;
+}
+
+void VLCMediaController::setAutoplayTitles(bool autoplay)
+{
+ b_autoplay_titles = autoplay;
+}
+
+bool VLCMediaController::autoplayTitles() const
+{
+ return b_autoplay_titles;
+}
+
+// Chapter
+
+//void VLCMediaController::setCurrentChapter(const Phonon::ChapterDescription &chapter)
+void VLCMediaController::setCurrentChapter(int chapter)
+{
+ current_chapter = chapter;
+// libvlc_media_player_set_chapter(p_vlc_media_player, chapter.index(), vlc_exception);
+ libvlc_media_player_set_chapter(p_vlc_media_player, chapter, vlc_exception);
+ vlcExceptionRaised();
+}
+
+//QList<Phonon::ChapterDescription> VLCMediaController::availableChapters() const
+int VLCMediaController::availableChapters() const
+{
+ return available_chapters;
+}
+
+//Phonon::ChapterDescription VLCMediaController::currentChapter() const
+int VLCMediaController::currentChapter() const
+{
+ return current_chapter;
+}
+
+// We need to rebuild available chapters when title is changed
+void VLCMediaController::refreshChapters(int i_title)
+{
+// current_chapter = Phonon::ChapterDescription();
+// available_chapters.clear();
+ current_chapter = 0;
+ available_chapters = 0;
+
+ // Get the description of available chapters for specific title
+ libvlc_track_description_t *p_info = libvlc_video_get_chapter_description(
+ p_vlc_media_player, i_title, vlc_exception);
+ vlcExceptionRaised();
+ while (p_info) {
+ chapterAdded(p_info->i_id, p_info->psz_name);
+ p_info = p_info->p_next;
+ }
+ libvlc_track_description_release(p_info);
+}
+
+// Angle
+
+void VLCMediaController::setCurrentAngle(int angleNumber)
+{
+ i_current_angle = angleNumber;
+}
+
+int VLCMediaController::availableAngles() const
+{
+ return i_available_angles;
+}
+
+int VLCMediaController::currentAngle() const
+{
+ return i_current_angle;
+}
+
+}
+} // Namespace Phonon::VLC
--- /dev/null
+/*****************************************************************************
+ * VLC backend for the Phonon library *
+ * Copyright (C) 2007-2008 Tanguy Krotoff <tkrotoff@gmail.com> *
+ * Copyright (C) 2008 Lukas Durfina <lukas.durfina@gmail.com> *
+ * Copyright (C) 2009 Fathi Boudra <fabo@kde.org> *
+ * *
+ * This program is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 3 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 *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this package; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *
+ *****************************************************************************/
+
+#ifndef PHONON_VLC_VLCMEDIA_CONTROLLER_H
+#define PHONON_VLC_VLCMEDIA_CONTROLLER_H
+
+#include "mediacontroller.h"
+#include "vlcloader.h"
+
+namespace Phonon
+{
+namespace VLC {
+
+/**
+ * MediaController specific code for VLC.
+ */
+class VLCMediaController : public MediaController
+{
+public:
+ VLCMediaController();
+ virtual ~VLCMediaController();
+
+ void audioChannelAdded(int id, const QString & lang);
+ void subtitleAdded(int id, const QString & lang, const QString & type);
+ void titleAdded(int id, const QString & name);
+ void chapterAdded(int titleId, const QString & name);
+
+protected:
+ virtual void clearMediaController();
+
+ // AudioChannel
+ void setCurrentAudioChannel(const Phonon::AudioChannelDescription & audioChannel);
+ QList<Phonon::AudioChannelDescription> availableAudioChannels() const;
+ Phonon::AudioChannelDescription currentAudioChannel() const;
+ void refreshAudioChannels();
+
+ // Subtitle
+ void setCurrentSubtitle(const Phonon::SubtitleDescription & subtitle);
+ QList<Phonon::SubtitleDescription> availableSubtitles() const;
+ Phonon::SubtitleDescription currentSubtitle() const;
+ void refreshSubtitles();
+
+ // Angle
+ void setCurrentAngle(int angleNumber);
+ int availableAngles() const;
+ int currentAngle() const;
+
+ // Chapter
+// void setCurrentChapter( const Phonon::ChapterDescription & chapter );
+// QList<Phonon::ChapterDescription> availableChapters() const;
+// Phonon::ChapterDescription currentChapter() const;
+ void setCurrentChapter(int chapterNumber);
+ int availableChapters() const;
+ int currentChapter() const;
+ void refreshChapters(int i_title);
+
+ // Title
+// void setCurrentTitle( const Phonon::TitleDescription & title );
+// QList<Phonon::TitleDescription> availableTitles() const;
+// Phonon::TitleDescription currentTitle() const;
+ void setCurrentTitle(int titleNumber);
+ int availableTitles() const;
+ int currentTitle() const;
+
+ void setAutoplayTitles(bool autoplay);
+ bool autoplayTitles() const;
+
+ // MediaPlayer
+ libvlc_media_player_t *p_vlc_media_player;
+
+private:
+};
+
+}
+} // Namespace Phonon::VLC
+
+#endif
--- /dev/null
+/*****************************************************************************
+ * VLC backend for the Phonon library *
+ * Copyright (C) 2007-2008 Tanguy Krotoff <tkrotoff@gmail.com> *
+ * Copyright (C) 2008 Lukas Durfina <lukas.durfina@gmail.com> *
+ * Copyright (C) 2009 Fathi Boudra <fabo@kde.org> *
+ * *
+ * This program is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 3 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 *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this package; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *
+ *****************************************************************************/
+
+#include "vlcmediaobject.h"
+
+#include "videowidget.h"
+
+#include "vlcloader.h"
+
+#include <QtCore/QTimer>
+#include <QtCore/QtDebug>
+
+namespace Phonon
+{
+namespace VLC {
+
+// VLC returns a strange position
+// We have to multiply by VLC_POSITION_RESOLUTION
+static const int vlcPositionResolution = 1000;
+
+VLCMediaObject::VLCMediaObject(QObject * parent)
+ : MediaObject(parent), VLCMediaController()
+{
+ // Create an empty Media Player object
+ p_vlc_media_player = libvlc_media_player_new(vlc_instance, vlc_exception);
+ vlcExceptionRaised();
+ p_vlc_media_player_event_manager = 0;
+
+ // Media
+ p_vlc_media = 0;
+ p_vlc_media_event_manager = 0;
+
+ // Media Discoverer
+ p_vlc_media_discoverer = 0;
+ p_vlc_media_discoverer_event_manager = 0;
+
+ i_total_time = 0;
+ b_has_video = false;
+ b_seekable = false;
+}
+
+VLCMediaObject::~VLCMediaObject()
+{
+// unloadMedia();
+ libvlc_media_player_release(p_vlc_media_player);
+}
+
+void VLCMediaObject::unloadMedia()
+{
+// if( p_vlc_media_player ) {
+// libvlc_media_player_release(p_vlc_media_player);
+// p_vlc_media_player = 0;
+// }
+
+ if (p_vlc_media) {
+ libvlc_media_release(p_vlc_media);
+ p_vlc_media = 0;
+ }
+}
+
+void VLCMediaObject::loadMediaInternal(const QString & filename)
+{
+ qDebug() << __FUNCTION__ << filename;
+
+ // Create a media with the given MRL
+ p_vlc_media = libvlc_media_new(vlc_instance, filename.toAscii(), vlc_exception);
+ vlcExceptionRaised();
+
+ // Set the media that will be used by the media player
+ libvlc_media_player_set_media(p_vlc_media_player, p_vlc_media, vlc_exception);
+ vlcExceptionRaised();
+
+ // No need to keep the media now
+// libvlc_media_release(p_vlc_media);
+
+ // connectToAllVLCEvents() at the end since it needs p_vlc_media_player
+ connectToAllVLCEvents();
+
+ b_play_request_reached = false;
+
+ // Optimization: wait to see if play() is run just after loadMedia()
+ // 100 milliseconds should be fine
+ QTimer::singleShot(100, this, SLOT(loadMediaInternal()));
+
+ // Get meta data (artist, title, etc...)
+ updateMetaData();
+
+ // Update available audio channels/subtitles/angles/chapters/etc...
+ // i.e everything from MediaController
+ // There is no audio channel/subtitle/angle/chapter events inside libvlc
+ // so let's send our own events...
+ // This will reset the GUI
+ clearMediaController();
+}
+
+void VLCMediaObject::loadMediaInternal()
+{
+ if (b_play_request_reached) {
+ // The media is playing, no need to load it
+ return;
+ }
+
+ emit stateChanged(Phonon::StoppedState);
+}
+
+void VLCMediaObject::setVLCWidgetId()
+{
+ // Get our media player to use our window
+#if defined(Q_OS_UNIX)
+ libvlc_media_player_set_xwindow(p_vlc_media_player, i_video_widget_id, vlc_exception);
+#elif defined(Q_OS_WIN)
+ libvlc_media_player_set_hwnd(p_vlc_media_player, i_video_widget_id, vlc_exception);
+#elif defined(Q_OS_MAC)
+ libvlc_media_player_set_agl(p_vlc_media_player, i_video_widget_id, vlc_exception);
+#endif
+ vlcExceptionRaised();
+}
+
+void VLCMediaObject::playInternal()
+{
+ b_play_request_reached = true;
+
+ // Clear subtitles/chapters/etc...
+ clearMediaController();
+
+ vlc_current_media_player = p_vlc_media_player;
+
+ setVLCWidgetId();
+
+ // Play
+ libvlc_media_player_play(p_vlc_media_player, vlc_exception);
+ vlcExceptionRaised();
+}
+
+void VLCMediaObject::pause()
+{
+ libvlc_media_player_pause(p_vlc_media_player, vlc_exception);
+ vlcExceptionRaised();
+}
+
+void VLCMediaObject::stop()
+{
+ libvlc_media_player_stop(p_vlc_media_player, vlc_exception);
+ vlcExceptionRaised();
+// unloadMedia();
+}
+
+void VLCMediaObject::seekInternal(qint64 milliseconds)
+{
+ qDebug() << __FUNCTION__ << milliseconds;
+ libvlc_media_player_set_time(p_vlc_media_player, milliseconds, vlc_exception);
+ vlcExceptionRaised();
+}
+
+QString VLCMediaObject::errorString() const
+{
+ return libvlc_exception_get_message(vlc_exception);
+}
+
+bool VLCMediaObject::hasVideo() const
+{
+ return b_has_video;
+}
+
+bool VLCMediaObject::isSeekable() const
+{
+ return b_seekable;
+}
+
+void VLCMediaObject::connectToAllVLCEvents()
+{
+ // Get the event manager from which the media player send event
+ p_vlc_media_player_event_manager = libvlc_media_player_event_manager(p_vlc_media_player, vlc_exception);
+ libvlc_event_type_t eventsMediaPlayer[] = {
+ libvlc_MediaPlayerPlaying,
+ libvlc_MediaPlayerPaused,
+ libvlc_MediaPlayerEndReached,
+ libvlc_MediaPlayerStopped,
+ libvlc_MediaPlayerEncounteredError,
+ libvlc_MediaPlayerTimeChanged,
+ libvlc_MediaPlayerTitleChanged,
+ libvlc_MediaPlayerPositionChanged,
+ libvlc_MediaPlayerSeekableChanged,
+ libvlc_MediaPlayerPausableChanged,
+ };
+ int i_nbEvents = sizeof(eventsMediaPlayer) / sizeof(*eventsMediaPlayer);
+ for (int i = 0; i < i_nbEvents; i++) {
+ libvlc_event_attach(p_vlc_media_player_event_manager, eventsMediaPlayer[i],
+ libvlc_callback, this, vlc_exception);
+ vlcExceptionRaised();
+ }
+
+
+ // Get event manager from media descriptor object
+ p_vlc_media_event_manager = libvlc_media_event_manager(p_vlc_media, vlc_exception);
+ libvlc_event_type_t eventsMedia[] = {
+ libvlc_MediaMetaChanged,
+ libvlc_MediaSubItemAdded,
+ libvlc_MediaDurationChanged,
+ // FIXME libvlc does not know this event
+// libvlc_MediaPreparsedChanged,
+ libvlc_MediaFreed,
+ libvlc_MediaStateChanged,
+ };
+ i_nbEvents = sizeof(eventsMedia) / sizeof(*eventsMedia);
+ for (int i = 0; i < i_nbEvents; i++) {
+ libvlc_event_attach(p_vlc_media_event_manager, eventsMedia[i], libvlc_callback, this, vlc_exception);
+ vlcExceptionRaised();
+ }
+
+ // Get event manager from media service discoverer object
+ // FIXME why libvlc_media_discoverer_event_manager() does not take a libvlc_exception_t ?
+// p_vlc_media_discoverer_event_manager = libvlc_media_discoverer_event_manager(p_vlc_media_discoverer);
+// libvlc_event_type_t eventsMediaDiscoverer[] = {
+// libvlc_MediaDiscovererStarted,
+// libvlc_MediaDiscovererEnded
+// };
+// nbEvents = sizeof(eventsMediaDiscoverer) / sizeof(*eventsMediaDiscoverer);
+// for (int i = 0; i < nbEvents; i++) {
+// libvlc_event_attach(p_vlc_media_discoverer_event_manager, eventsMediaDiscoverer[i], libvlc_callback, this, vlc_exception);
+// }
+}
+
+void VLCMediaObject::libvlc_callback(const libvlc_event_t *p_event, void *p_user_data)
+{
+ static int i_first_time_media_player_time_changed = 0;
+ static bool b_media_player_title_changed = false;
+
+ VLCMediaObject *p_vlc_mediaObject = (VLCMediaObject *) p_user_data;
+
+// qDebug() << (int)pp_vlc_mediaObject << "event:" << libvlc_event_type_name(event->type);
+
+ // Media player events
+ if (p_event->type == libvlc_MediaPlayerTimeChanged) {
+
+ i_first_time_media_player_time_changed++;
+
+ // FIXME It is ugly. It should be solved by some events in libvlc
+ if (i_first_time_media_player_time_changed == 15) {
+ // Update metadata
+ p_vlc_mediaObject->updateMetaData();
+
+ // Is this media player seekable
+ bool b_seekable = libvlc_media_player_is_seekable(p_vlc_mediaObject->p_vlc_media_player, vlc_exception);
+ vlcExceptionRaised();
+ if (b_seekable != p_vlc_mediaObject->b_seekable) {
+ qDebug() << "libvlc_callback(): isSeekable:" << b_seekable;
+ p_vlc_mediaObject->b_seekable = b_seekable;
+ emit p_vlc_mediaObject->seekableChanged(p_vlc_mediaObject->b_seekable);
+ }
+
+ // Get current video width
+ int i_width = libvlc_video_get_width(p_vlc_mediaObject->p_vlc_media_player, vlc_exception);
+ vlcExceptionRaised();
+
+ // Get current video height
+ int i_height = libvlc_video_get_height(p_vlc_mediaObject->p_vlc_media_player, vlc_exception);
+ vlcExceptionRaised();
+ emit p_vlc_mediaObject->videoWidgetSizeChanged(i_width, i_height);
+
+ // Does this media player have a video output
+ bool b_has_video = libvlc_media_player_has_vout(p_vlc_mediaObject->p_vlc_media_player, vlc_exception);
+ vlcExceptionRaised();
+ if (b_has_video != p_vlc_mediaObject->b_has_video) {
+ p_vlc_mediaObject->b_has_video = b_has_video;
+ emit p_vlc_mediaObject->hasVideoChanged(p_vlc_mediaObject->b_has_video);
+ }
+
+ if (b_has_video) {
+ // Give info about audio tracks
+ p_vlc_mediaObject->refreshAudioChannels();
+ // Give info about subtitle tracks
+ p_vlc_mediaObject->refreshSubtitles();
+
+ // Get movie chapter count
+ // It is not a title/chapter media if there is no chapter
+ if (libvlc_media_player_get_chapter_count(
+ p_vlc_mediaObject->p_vlc_media_player, vlc_exception) > 0) {
+ vlcExceptionRaised();
+ // Give info about title
+ // only first time, no when title changed
+ if (!b_media_player_title_changed) {
+ libvlc_track_description_t *p_info = libvlc_video_get_title_description(
+ p_vlc_mediaObject->p_vlc_media_player, vlc_exception);
+ vlcExceptionRaised();
+ while (p_info) {
+ p_vlc_mediaObject->titleAdded(p_info->i_id, p_info->psz_name);
+ p_info = p_info->p_next;
+ }
+ libvlc_track_description_release(p_info);
+ }
+
+ // Give info about chapters for actual title 0
+ if (b_media_player_title_changed)
+ p_vlc_mediaObject->refreshChapters(libvlc_media_player_get_title(
+ p_vlc_mediaObject->p_vlc_media_player, vlc_exception));
+ else
+ p_vlc_mediaObject->refreshChapters(0);
+ }
+ if (b_media_player_title_changed)
+ b_media_player_title_changed = false;
+ }
+
+ // Bugfix with Qt mediaplayer example
+ // Now we are in playing state
+ emit p_vlc_mediaObject->stateChanged(Phonon::PlayingState);
+ }
+
+ emit p_vlc_mediaObject->tickInternal(p_vlc_mediaObject->currentTime());
+ }
+
+ if (p_event->type == libvlc_MediaPlayerPlaying) {
+ if (p_vlc_mediaObject->state() != Phonon::LoadingState) {
+ // Bugfix with Qt mediaplayer example
+ emit p_vlc_mediaObject->stateChanged(Phonon::PlayingState);
+ }
+ }
+
+ if (p_event->type == libvlc_MediaPlayerPaused) {
+ emit p_vlc_mediaObject->stateChanged(Phonon::PausedState);
+ }
+
+ if (p_event->type == libvlc_MediaPlayerEndReached) {
+ i_first_time_media_player_time_changed = 0;
+ p_vlc_mediaObject->clearMediaController();
+ emit p_vlc_mediaObject->stateChanged(Phonon::StoppedState);
+ emit p_vlc_mediaObject->finished();
+ }
+
+ if (p_event->type == libvlc_MediaPlayerStopped) {
+ i_first_time_media_player_time_changed = 0;
+ p_vlc_mediaObject->clearMediaController();
+ emit p_vlc_mediaObject->stateChanged(Phonon::StoppedState);
+ }
+
+ if (p_event->type == libvlc_MediaPlayerTitleChanged) {
+ i_first_time_media_player_time_changed = 0;
+ b_media_player_title_changed = true;
+ }
+
+ // Media events
+
+ if (p_event->type == libvlc_MediaDurationChanged) {
+ // Get duration of media descriptor object item
+ libvlc_time_t totalTime = libvlc_media_get_duration(p_vlc_mediaObject->p_vlc_media, vlc_exception);
+ vlcExceptionRaised();
+ totalTime = totalTime / vlcPositionResolution;
+
+ if (totalTime != p_vlc_mediaObject->i_total_time) {
+ p_vlc_mediaObject->i_total_time = totalTime;
+ emit p_vlc_mediaObject->totalTimeChanged(p_vlc_mediaObject->i_total_time);
+ }
+ }
+
+ if (p_event->type == libvlc_MediaMetaChanged) {
+ }
+}
+
+void VLCMediaObject::updateMetaData()
+{
+ QMultiMap<QString, QString> metaDataMap;
+
+ metaDataMap.insert(QLatin1String("ARTIST"),
+ QString::fromUtf8(libvlc_media_get_meta(p_vlc_media, libvlc_meta_Artist, vlc_exception)));
+ vlcExceptionRaised();
+ metaDataMap.insert(QLatin1String("ALBUM"),
+ QString::fromUtf8(libvlc_media_get_meta(p_vlc_media, libvlc_meta_Album, vlc_exception)));
+ vlcExceptionRaised();
+ metaDataMap.insert(QLatin1String("TITLE"),
+ QString::fromUtf8(libvlc_media_get_meta(p_vlc_media, libvlc_meta_Title, vlc_exception)));
+ vlcExceptionRaised();
+ metaDataMap.insert(QLatin1String("DATE"),
+ QString::fromUtf8(libvlc_media_get_meta(p_vlc_media, libvlc_meta_Date, vlc_exception)));
+ vlcExceptionRaised();
+ metaDataMap.insert(QLatin1String("GENRE"),
+ QString::fromUtf8(libvlc_media_get_meta(p_vlc_media, libvlc_meta_Genre, vlc_exception)));
+ vlcExceptionRaised();
+ metaDataMap.insert(QLatin1String("TRACKNUMBER"),
+ QString::fromUtf8(libvlc_media_get_meta(p_vlc_media, libvlc_meta_TrackNumber, vlc_exception)));
+ vlcExceptionRaised();
+ metaDataMap.insert(QLatin1String("DESCRIPTION"),
+ QString::fromUtf8(libvlc_media_get_meta(p_vlc_media, libvlc_meta_Description, vlc_exception)));
+ vlcExceptionRaised();
+ metaDataMap.insert(QLatin1String("COPYRIGHT"),
+ QString::fromUtf8(libvlc_media_get_meta(p_vlc_media, libvlc_meta_TrackNumber, vlc_exception)));
+ vlcExceptionRaised();
+ metaDataMap.insert(QLatin1String("URL"),
+ QString::fromUtf8(libvlc_media_get_meta(p_vlc_media, libvlc_meta_URL, vlc_exception)));
+ vlcExceptionRaised();
+ metaDataMap.insert(QLatin1String("ENCODEDBY"),
+ QString::fromUtf8(libvlc_media_get_meta(p_vlc_media, libvlc_meta_EncodedBy, vlc_exception)));
+
+ qDebug() << "updateMetaData(): artist:"
+ << libvlc_media_get_meta(p_vlc_media, libvlc_meta_Artist, vlc_exception);
+ vlcExceptionRaised();
+ qDebug() << "updateMetaData(): title:"
+ << libvlc_media_get_meta(p_vlc_media, libvlc_meta_Title, vlc_exception);
+ vlcExceptionRaised();
+
+ emit metaDataChanged(metaDataMap);
+}
+
+qint64 VLCMediaObject::totalTime() const
+{
+ return i_total_time;
+}
+
+qint64 VLCMediaObject::currentTimeInternal() const
+{
+ libvlc_time_t time = libvlc_media_player_get_time(p_vlc_media_player, vlc_exception);
+ vlcExceptionRaised();
+
+ return time;
+}
+
+}
+} // Namespace Phonon::VLC
--- /dev/null
+/*****************************************************************************
+ * VLC backend for the Phonon library *
+ * Copyright (C) 2007-2008 Tanguy Krotoff <tkrotoff@gmail.com> *
+ * Copyright (C) 2008 Lukas Durfina <lukas.durfina@gmail.com> *
+ * Copyright (C) 2009 Fathi Boudra <fabo@kde.org> *
+ * *
+ * This program is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 3 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 *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this package; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *
+ *****************************************************************************/
+
+#ifndef PHONON_VLC_VLCMEDIAOBJECT_H
+#define PHONON_VLC_VLCMEDIAOBJECT_H
+
+#include "vlcmediacontroller.h"
+
+#include "mediaobject.h"
+
+#include <phonon/mediaobjectinterface.h>
+#include <phonon/addoninterface.h>
+
+#include <QtCore/QObject>
+#include <QtCore/QString>
+#include <QtCore/QMultiMap>
+
+namespace Phonon
+{
+namespace VLC {
+
+/**
+ * VLC MediaObject.
+ *
+ * This is the "brain" of the VLC backend.
+ * VLCMediaObject uses libvlc in order to send commands and receive events from the VLC.
+ *
+ * Encapsulates VLC specific code.
+ * Take care of libvlc events via libvlc_callback()
+ *
+ * @see MediaObject
+ */
+class VLCMediaObject : public MediaObject, public VLCMediaController
+{
+ Q_OBJECT
+ Q_INTERFACES(Phonon::MediaObjectInterface Phonon::AddonInterface)
+
+public:
+
+ VLCMediaObject(QObject * parent);
+ ~VLCMediaObject();
+
+ void pause();
+ void stop();
+
+ bool hasVideo() const;
+ bool isSeekable() const;
+
+ qint64 totalTime() const;
+
+ QString errorString() const;
+
+signals:
+
+ // MediaController signals
+ void availableSubtitlesChanged();
+ void availableAudioChannelsChanged();
+
+// void availableChaptersChanged();
+// void availableTitlesChanged();
+ void availableChaptersChanged(int);
+ void availableTitlesChanged(int);
+
+ void availableAnglesChanged(int availableAngles);
+ void angleChanged(int angleNumber);
+ void chapterChanged(int chapterNumber);
+ void titleChanged(int titleNumber);
+
+ /**
+ * New widget size computed by VLC.
+ *
+ * It should be applied to the widget that contains the VLC video.
+ */
+ void videoWidgetSizeChanged(int i_width, int i_height);
+
+protected:
+
+ void loadMediaInternal(const QString & filename);
+ void playInternal();
+ void seekInternal(qint64 milliseconds);
+
+ qint64 currentTimeInternal() const;
+
+private slots:
+
+ void loadMediaInternal();
+
+private:
+
+ /**
+ * Connect libvlc_callback() to all vlc events.
+ *
+ * @see libvlc_callback()
+ */
+ void connectToAllVLCEvents();
+
+ /**
+ * Retrieve meta data of a file (i.e ARTIST, TITLE, ALBUM, etc...).
+ */
+ void updateMetaData();
+
+ /**
+ * Libvlc callback.
+ *
+ * Receive all vlc events.
+ *
+ * Warning: owned by libvlc thread.
+ *
+ * @see connectToAllVLCEvents()
+ * @see libvlc_event_attach()
+ */
+ static void libvlc_callback(const libvlc_event_t *p_event, void *p_user_data);
+
+ void unloadMedia();
+
+ void setVLCWidgetId();
+
+ // MediaPlayer
+// libvlc_media_player_t * p_vlc_media_player;
+ libvlc_event_manager_t * p_vlc_media_player_event_manager;
+
+ // Media
+ libvlc_media_t * p_vlc_media;
+ libvlc_event_manager_t * p_vlc_media_event_manager;
+
+ // MediaDiscoverer
+ libvlc_media_discoverer_t * p_vlc_media_discoverer;
+ libvlc_event_manager_t * p_vlc_media_discoverer_event_manager;
+
+ bool b_play_request_reached;
+
+ qint64 i_total_time;
+
+ bool b_has_video;
+
+ bool b_seekable;
+};
+
+}
+} // Namespace Phonon::VLC
+
+#endif
--- /dev/null
+/*****************************************************************************
+ * VLC backend for the Phonon library *
+ * Copyright (C) 2007-2008 Tanguy Krotoff <tkrotoff@gmail.com> *
+ * Copyright (C) 2008 Lukas Durfina <lukas.durfina@gmail.com> *
+ * Copyright (C) 2009 Fathi Boudra <fabo@kde.org> *
+ * *
+ * This program is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 3 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 *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this package; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *
+ *****************************************************************************/
+
+#include "vlcvideowidget.h"
+
+#include <QtGui/QResizeEvent>
+#include <QtCore/QDebug>
+
+namespace Phonon
+{
+namespace VLC {
+
+VLCVideoWidget::VLCVideoWidget(QWidget *p_parent)
+ : WidgetNoPaintEvent(p_parent)
+{
+ // Set background color
+ setBackgroundColor(Qt::black);
+}
+
+VLCVideoWidget::~VLCVideoWidget()
+{
+}
+
+void VLCVideoWidget::resizeEvent(QResizeEvent *p_event)
+{
+ qDebug() << "resizeEvent" << p_event->size();
+}
+
+void VLCVideoWidget::setAspectRatio(double f_aspect_ratio)
+{
+}
+
+void VLCVideoWidget::setScaleAndCropMode(bool b_scale_and_crop)
+{
+}
+
+void VLCVideoWidget::setVideoSize(const QSize & size)
+{
+ videoSize = size;
+}
+
+QSize VLCVideoWidget::sizeHint() const
+{
+ return videoSize;
+}
+
+}
+} // Namespace Phonon::VLC
--- /dev/null
+/*****************************************************************************
+ * VLC backend for the Phonon library *
+ * Copyright (C) 2007-2008 Tanguy Krotoff <tkrotoff@gmail.com> *
+ * Copyright (C) 2008 Lukas Durfina <lukas.durfina@gmail.com> *
+ * Copyright (C) 2009 Fathi Boudra <fabo@kde.org> *
+ * *
+ * This program is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 3 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 *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this package; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *
+ *****************************************************************************/
+
+#ifndef PHONON_VLC_VLCVIDEOWIDGET_H
+#define PHONON_VLC_VLCVIDEOWIDGET_H
+
+#include "widgetnopaintevent.h"
+
+#include <QtGui/QWidget>
+
+class QResizeEvent;
+
+namespace Phonon
+{
+namespace VLC {
+
+/**
+ * Widget where to show VLC video.
+ */
+class VLCVideoWidget : public WidgetNoPaintEvent
+{
+ Q_OBJECT
+public:
+
+ VLCVideoWidget(QWidget *p_parent);
+ ~VLCVideoWidget();
+
+ void setVideoSize(const QSize & videoSize);
+ void setAspectRatio(double f_aspect_ratio);
+ void setScaleAndCropMode(bool b_scale_and_crop);
+
+ QSize sizeHint() const;
+
+private:
+
+ void resizeEvent(QResizeEvent *p_event);
+
+ /**
+ * Original size of the video, needed for sizeHint().
+ */
+ QSize videoSize;
+};
+
+}
+} // Namespace Phonon::VLC_MPlayer
+
+#endif // PHONON_VLC_MPLAYER_VLCVIDEOWIDGET_H
--- /dev/null
+/*****************************************************************************
+ * VLC backend for the Phonon library *
+ * Copyright (C) 2007-2008 Tanguy Krotoff <tkrotoff@gmail.com> *
+ * Copyright (C) 2008 Lukas Durfina <lukas.durfina@gmail.com> *
+ * Copyright (C) 2009 Fathi Boudra <fabo@kde.org> *
+ * *
+ * This program is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 3 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 *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this package; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *
+ *****************************************************************************/
+
+#include "widgetnopaintevent.h"
+
+#include <QtGui/QPainter>
+
+namespace Phonon
+{
+namespace VLC {
+
+WidgetNoPaintEvent::WidgetNoPaintEvent(QWidget *p_parent)
+ : QWidget(p_parent)
+{
+ // When resizing fill with black (backgroundRole color) the rest is done by paintEvent
+ setAttribute(Qt::WA_OpaquePaintEvent);
+
+ // Disable Qt composition management as MPlayer draws onto the widget directly
+ setAttribute(Qt::WA_PaintOnScreen);
+
+ // Indicates that the widget has no background,
+ // i.e. when the widget receives paint events, the background is not automatically repainted.
+ setAttribute(Qt::WA_NoSystemBackground);
+
+ // Required for dvdnav
+ setMouseTracking(true);
+}
+
+void WidgetNoPaintEvent::paintEvent(QPaintEvent *p_event)
+{
+ // FIXME this makes the video flicker
+ // Make everything backgroundRole color
+ QPainter painter(this);
+ painter.eraseRect(rect());
+}
+
+void WidgetNoPaintEvent::setBackgroundColor(const QColor & color)
+{
+ QPalette p = palette();
+ p.setColor(backgroundRole(), color);
+ setPalette(p);
+}
+
+}
+} // Namespace Phonon::VLC
--- /dev/null
+/*****************************************************************************
+ * VLC backend for the Phonon library *
+ * Copyright (C) 2007-2008 Tanguy Krotoff <tkrotoff@gmail.com> *
+ * Copyright (C) 2008 Lukas Durfina <lukas.durfina@gmail.com> *
+ * Copyright (C) 2009 Fathi Boudra <fabo@kde.org> *
+ * *
+ * This program is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 3 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 *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this package; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *
+ *****************************************************************************/
+
+#ifndef PHONON_VLC_WIDGETNOPAINTEVENT_H
+#define PHONON_VLC_WIDGETNOPAINTEVENT_H
+
+#include <QtGui/QWidget>
+
+namespace Phonon
+{
+namespace VLC {
+
+/**
+ * Utility class: special widget for playing videos.
+ *
+ * Does not handle paintEvent()
+ */
+class WidgetNoPaintEvent : public QWidget
+{
+ Q_OBJECT
+public:
+
+ WidgetNoPaintEvent(QWidget *p_parent);
+
+ /**
+ * Sets the background color.
+ *
+ * I don't know which one is best: 0x020202 or Qt::black...
+ */
+ void setBackgroundColor(const QColor & color);
+
+private:
+
+ void paintEvent(QPaintEvent *p_event);
+};
+
+}
+} // Namespace Phonon::VLC
+
+#endif // PHONON_VLC_WIDGETNOPAINTEVENT_H