From: Jean-Baptiste Kempf Date: Sat, 8 Aug 2009 19:28:12 +0000 (+0200) Subject: Phonon Backend using VLC X-Git-Tag: 1.1.0-ff~4486 X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=b7e641261d19c238dcf4b917db41d765b1ec8c95;hp=4d748cb87a9c18e77d4912f35adfd33115f65ea6;p=vlc Phonon Backend using VLC 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 --- diff --git a/bindings/phonon/.gitignore b/bindings/phonon/.gitignore new file mode 100644 index 0000000000..dc81908f63 --- /dev/null +++ b/bindings/phonon/.gitignore @@ -0,0 +1,3 @@ +.svn +Makefile +CMakeTmp diff --git a/bindings/phonon/cmake/modules/FindAutomoc4.cmake b/bindings/phonon/cmake/modules/FindAutomoc4.cmake new file mode 100644 index 0000000000..2b88e09195 --- /dev/null +++ b/bindings/phonon/cmake/modules/FindAutomoc4.cmake @@ -0,0 +1,81 @@ +# - 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( ) +# Use this to run automoc4 on all files contained in the list . +# +# AUTOMOC4_MOC_HEADERS( header1.h header2.h ...) +# Use this to add more header files to be processed with automoc4. +# +# AUTOMOC4_ADD_EXECUTABLE( src1 src2 ...) +# This macro does the same as ADD_EXECUTABLE, but additionally +# adds automoc4 handling for all source files. +# +# AUTOMOC4_ADD_LIBRARY( 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( ) +# +# 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( ) +# _AUTOMOC4_KDE4_POST_TARGET_HANDLING() + + +# Copyright (c) 2008-2009, Alexander Neundorf, +# +# 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) diff --git a/bindings/phonon/cmake/modules/FindPackageHandleStandardArgs.cmake b/bindings/phonon/cmake/modules/FindPackageHandleStandardArgs.cmake new file mode 100644 index 0000000000..9613b3d6ee --- /dev/null +++ b/bindings/phonon/cmake/modules/FindPackageHandleStandardArgs.cmake @@ -0,0 +1,60 @@ +# 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 _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) diff --git a/bindings/phonon/cmake/modules/FindVLC.cmake b/bindings/phonon/cmake/modules/FindVLC.cmake new file mode 100644 index 0000000000..5d2b379182 --- /dev/null +++ b/bindings/phonon/cmake/modules/FindVLC.cmake @@ -0,0 +1,54 @@ +# - 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 +# Copyright (C) 2008, Lukas Durfina +# Copyright (c) 2009, Fathi Boudra +# +# 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) diff --git a/bindings/phonon/cmake/modules/MacroEnsureVersion.cmake b/bindings/phonon/cmake/modules/MacroEnsureVersion.cmake new file mode 100644 index 0000000000..6797e5b7db --- /dev/null +++ b/bindings/phonon/cmake/modules/MacroEnsureVersion.cmake @@ -0,0 +1,117 @@ +# 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, +# Copyright (c) 2007, Will Stephenson +# +# 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 +# +# 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, +# Copyright (c) 2007, Will Stephenson +# +# 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 +# +# 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) + + diff --git a/bindings/phonon/cmake/modules/MacroLogFeature.cmake b/bindings/phonon/cmake/modules/MacroLogFeature.cmake new file mode 100644 index 0000000000..0cc87078e2 --- /dev/null +++ b/bindings/phonon/cmake/modules/MacroLogFeature.cmake @@ -0,0 +1,125 @@ +# 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, +# Copyright (c) 2006, Allen Winter, +# +# 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) diff --git a/bindings/phonon/cmake/modules/MacroOptionalFindPackage.cmake b/bindings/phonon/cmake/modules/MacroOptionalFindPackage.cmake new file mode 100644 index 0000000000..816cdb7e87 --- /dev/null +++ b/bindings/phonon/cmake/modules/MacroOptionalFindPackage.cmake @@ -0,0 +1,28 @@ +# - MACRO_OPTIONAL_FIND_PACKAGE() combines FIND_PACKAGE() with an OPTION() +# MACRO_OPTIONAL_FIND_PACKAGE( [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_, which can be disabled via the cmake GUI. +# or via -DWITH_=OFF +# The standard _FOUND variables can be used in the same way +# as when using the normal FIND_PACKAGE() + +# Copyright (c) 2006, Alexander Neundorf, +# +# 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) + diff --git a/bindings/phonon/cmake/modules/PhononMacros.cmake b/bindings/phonon/cmake/modules/PhononMacros.cmake new file mode 100644 index 0000000000..2ef05a5f70 --- /dev/null +++ b/bindings/phonon/cmake/modules/PhononMacros.cmake @@ -0,0 +1,206 @@ + +# 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) + diff --git a/bindings/phonon/vlc/.gitignore b/bindings/phonon/vlc/.gitignore new file mode 100644 index 0000000000..773218f116 --- /dev/null +++ b/bindings/phonon/vlc/.gitignore @@ -0,0 +1,4 @@ +.svn +Makefile +moc_* +phonon_vlc_* diff --git a/bindings/phonon/vlc/AUTHORS b/bindings/phonon/vlc/AUTHORS new file mode 100644 index 0000000000..ea17ee886a --- /dev/null +++ b/bindings/phonon/vlc/AUTHORS @@ -0,0 +1,3 @@ +Fathi Boudra (current maintainer) +Lukas Durfina +Tanguy Krotoff diff --git a/bindings/phonon/vlc/audiooutput.cpp b/bindings/phonon/vlc/audiooutput.cpp new file mode 100644 index 0000000000..e06b0d6fa8 --- /dev/null +++ b/bindings/phonon/vlc/audiooutput.cpp @@ -0,0 +1,103 @@ +/***************************************************************************** + * VLC backend for the Phonon library * + * Copyright (C) 2007-2008 Tanguy Krotoff * + * Copyright (C) 2008 Lukas Durfina * + * Copyright (C) 2009 Fathi Boudra * + * * + * 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 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 diff --git a/bindings/phonon/vlc/audiooutput.h b/bindings/phonon/vlc/audiooutput.h new file mode 100644 index 0000000000..54b738ae08 --- /dev/null +++ b/bindings/phonon/vlc/audiooutput.h @@ -0,0 +1,69 @@ +/***************************************************************************** + * VLC backend for the Phonon library * + * Copyright (C) 2007-2008 Tanguy Krotoff * + * Copyright (C) 2008 Lukas Durfina * + * Copyright (C) 2009 Fathi Boudra * + * * + * 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 + +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 diff --git a/bindings/phonon/vlc/backend.cpp b/bindings/phonon/vlc/backend.cpp new file mode 100644 index 0000000000..a907e6ea81 --- /dev/null +++ b/bindings/phonon/vlc/backend.cpp @@ -0,0 +1,395 @@ +/***************************************************************************** + * VLC backend for the Phonon library * + * Copyright (C) 2007-2008 Tanguy Krotoff * + * Copyright (C) 2008 Lukas Durfina * + * Copyright (C) 2009 Fathi Boudra * + * * + * 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 +#include +#include + +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 &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(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(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 Backend::objectDescriptionIndexes(ObjectDescriptionType type) const +{ + QList list; + + switch (type) { + case Phonon::AudioOutputDeviceType: { + QList deviceList = deviceManager()->audioOutputDevices(); + for (int dev = 0 ; dev < deviceList.size() ; ++dev) + list.append(deviceList[dev].id); + break; + } + break; + case Phonon::EffectType: { + QList effectList = effectManager()->effects(); + for (int eff = 0; eff < effectList.size(); ++eff) + list.append(eff); + break; + } + break; + default: + break; + } + + return list; +} + +QHash Backend::objectDescriptionProperties(ObjectDescriptionType type, int index) const +{ + QHash ret; + + switch (type) { + case Phonon::AudioOutputDeviceType: { + QList 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 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 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(sink); + if (sinkNode) { + PrivateMediaObject *mediaObject = qobject_cast(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(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(sink); + if (sinkNode) { + PrivateMediaObject *mediaObject = qobject_cast(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(source); + return true; + } + } + + return false; +} + +bool Backend::endConnectionChange(QSet 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 diff --git a/bindings/phonon/vlc/backend.h b/bindings/phonon/vlc/backend.h new file mode 100644 index 0000000000..4cb5c91c4f --- /dev/null +++ b/bindings/phonon/vlc/backend.h @@ -0,0 +1,96 @@ +/***************************************************************************** + * VLC backend for the Phonon library * + * Copyright (C) 2007-2008 Tanguy Krotoff * + * Copyright (C) 2008 Lukas Durfina * + * Copyright (C) 2009 Fathi Boudra * + * * + * 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 +#include + +#include +#include +#include + +#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 &args); + + bool supportsVideo() const; + bool supportsOSD() const; + bool supportsFourcc(quint32 fourcc) const; + bool supportsSubtitles() const; + QStringList availableMimeTypes() const; + + QList objectDescriptionIndexes(ObjectDescriptionType type) const; + QHash objectDescriptionProperties(ObjectDescriptionType type, int index) const; + + bool startConnectionChange(QSet); + bool connectNodes(QObject *, QObject *); + bool disconnectNodes(QObject *, QObject *); + bool endConnectionChange(QSet); + + 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 > m_audioOutputs; + + DeviceManager *m_deviceManager; + EffectManager *m_effectManager; + DebugLevel m_debugLevel; +}; + +} +} // namespace Phonon::VLC + +#endif // Phonon_VLC_BACKEND_H diff --git a/bindings/phonon/vlc/devicemanager.cpp b/bindings/phonon/vlc/devicemanager.cpp new file mode 100644 index 0000000000..3bea98c709 --- /dev/null +++ b/bindings/phonon/vlc/devicemanager.cpp @@ -0,0 +1,152 @@ +/* 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 . +*/ + +#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 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 DeviceManager::audioOutputDevices() const +{ + return m_audioDeviceList; +} + +} +} + +QT_END_NAMESPACE diff --git a/bindings/phonon/vlc/devicemanager.h b/bindings/phonon/vlc/devicemanager.h new file mode 100644 index 0000000000..73a20d673c --- /dev/null +++ b/bindings/phonon/vlc/devicemanager.h @@ -0,0 +1,74 @@ +/* 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 . +*/ + +#ifndef Phonon_VLC_DEVICEMANAGER_H +#define Phonon_VLC_DEVICEMANAGER_H + +#include + +#include + +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 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 m_audioDeviceList; +}; +} +} // namespace Phonon::VLC + +QT_END_NAMESPACE + +#endif // Phonon_VLC_DEVICEMANAGER_H diff --git a/bindings/phonon/vlc/effect.cpp b/bindings/phonon/vlc/effect.cpp new file mode 100644 index 0000000000..f918fe1a76 --- /dev/null +++ b/bindings/phonon/vlc/effect.cpp @@ -0,0 +1,223 @@ +/***************************************************************************** + * VLC backend for the Phonon library * + * Copyright (C) 2007-2008 Tanguy Krotoff * + * Copyright (C) 2008 Lukas Durfina * + * Copyright (C) 2009 Fathi Boudra * + * * + * 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 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 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 diff --git a/bindings/phonon/vlc/effect.h b/bindings/phonon/vlc/effect.h new file mode 100644 index 0000000000..760aa0a4ec --- /dev/null +++ b/bindings/phonon/vlc/effect.h @@ -0,0 +1,67 @@ +/***************************************************************************** + * VLC backend for the Phonon library * + * Copyright (C) 2007-2008 Tanguy Krotoff * + * Copyright (C) 2008 Lukas Durfina * + * Copyright (C) 2009 Fathi Boudra * + * * + * 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 +#include + +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 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 parameterList; +}; + +} +} // Namespace Phonon::VLC + +#endif // PHONON_VLC_EFFECT_H diff --git a/bindings/phonon/vlc/effectmanager.cpp b/bindings/phonon/vlc/effectmanager.cpp new file mode 100644 index 0000000000..e71c21aa7c --- /dev/null +++ b/bindings/phonon/vlc/effectmanager.cpp @@ -0,0 +1,230 @@ +/***************************************************************************** + * VLC backend for the Phonon library * + * Copyright (C) 2007-2008 Tanguy Krotoff * + * Copyright (C) 2008 Lukas Durfina * + * Copyright (C) 2009 Fathi Boudra * + * * + * 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 ")); + +// videoEffectList.append(new EffectInfo("(Video) Color threshold", COLORTHRESHOLD, EffectInfo::VideoEffect, +// "Color threshold filter", "Sigmund Augdal ")); + +// videoEffectList.append(new EffectInfo("(Video) Deinterlace", DEINTERLACE, EffectInfo::VideoEffect, +// "Deinterlacing video filter", "Sam Hocevar ")); + +// videoEffectList.append(new EffectInfo("(Video) Extract", EXTRACT, EffectInfo::VideoEffect, +// "Extract RGB component video filter", +// "Antoine Cellerier ")); + +// videoEffectList.append(new EffectInfo("(Video) Gaussian blur", GAUSSIAN_BLUR, EffectInfo::VideoEffect, +// "Erase video filter", "Antoine Cellerier ")); + +// videoEffectList.append(new EffectInfo("(Video) Gradient", GRADIENT, EffectInfo::VideoEffect, +// "Gradient video filter", +// "Samuel Hocevar , " +// "Antoine Cellerier ")); + +// videoEffectList.append(new EffectInfo("(Video) Grain", GRAIN, EffectInfo::VideoEffect, +// "Grain video filter", "Antoine Cellerier ")); + +// videoEffectList.append(new EffectInfo("(Video) Invert", INVERT, EffectInfo::VideoEffect, +// "Invert video filter - color inversion", +// "Samuel Hocevar ")); + +// videoEffectList.append(new EffectInfo("(Video) Motion blur", MOTIONBLUR, EffectInfo::VideoEffect, +// "Motion blur filter", +// "Sigmund Augdal Helberg , " +// "Antoine Cellerier ")); + +// videoEffectList.append(new EffectInfo("(Video) Motion detect", MOTIONDETECT, EffectInfo::VideoEffect, +// "Motion detect video filter", +// "Antoine Cellerier ")); + +// videoEffectList.append(new EffectInfo("(Video) Noise", NOISE, EffectInfo::VideoEffect, +// "Noise video filter - add noise to image", +// "Antoine Cellerier ")); + +// videoEffectList.append(new EffectInfo("(Video) Postprocess", POSTPROCESS, EffectInfo::VideoEffect, +// "Video post processing filter", +// "Laurent Aimar , " +// "Gildas Bazin , " +// "Antoine Cellerier ")); + +// videoEffectList.append(new EffectInfo("(Video) Psychedelic", PSYCHEDELIC, EffectInfo::VideoEffect, +// "Psychedelic video filter", +// "Samuel Hocevar , " +// "Antoine Cellerier ")); + +// videoEffectList.append(new EffectInfo("(Video) Ripple", RIPPLE, EffectInfo::VideoEffect, +// "Ripple video filter", +// "Samuel Hocevar , " +// "Antoine Cellerier ")); + +// videoEffectList.append(new EffectInfo("(Video) Rotate", ROTATE, EffectInfo::VideoEffect, +// "Rotate video filter", +// "Antoine Cellerier ")); + +// videoEffectList.append(new EffectInfo("(Video) Seam carving", SEAM_CARVING, EffectInfo::VideoEffect, +// "Seam Carving for Content-Aware Image Resizing", +// "Antoine Cellerier ")); + +// videoEffectList.append(new EffectInfo("(Video) Sharpen", SHARPEN, EffectInfo::VideoEffect, +// "Sharpen video filter - Augment contrast between contours.", +// "Jérémy DEMEULE , " +// "Jean-Baptiste Kempf ")); + +// videoEffectList.append(new EffectInfo("(Video) Wave", WAVE, EffectInfo::VideoEffect, +// "Wave video filter", +// "Samuel Hocevar , " +// "Antoine Cellerier ")); + + 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 EffectManager::audioEffects() const +{ + return m_audioEffectList; +} + +/** + * Returns a list of available video effects + */ +const QList EffectManager::videoEffects() const +{ + return m_videoEffectList; +} + +/** + * Returns a list of available effects + */ +const QList EffectManager::effects() const +{ + return m_effectList; +} + +void EffectManager::updateEffects() +{ + m_effectList.clear(); + m_effectList += m_audioEffectList; + m_effectList += m_videoEffectList; +} + +} +} // namespace Phonon::VLC diff --git a/bindings/phonon/vlc/effectmanager.h b/bindings/phonon/vlc/effectmanager.h new file mode 100644 index 0000000000..4724b38d40 --- /dev/null +++ b/bindings/phonon/vlc/effectmanager.h @@ -0,0 +1,101 @@ +/***************************************************************************** + * VLC backend for the Phonon library * + * Copyright (C) 2007-2008 Tanguy Krotoff * + * Copyright (C) 2008 Lukas Durfina * + * Copyright (C) 2009 Fathi Boudra * + * * + * 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 +#include + +#include + +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 audioEffects() const; + const QList videoEffects() const; + const QList effects() const; + +private: + void updateEffects(); + + Backend *m_backend; + QList m_effectList; + QList m_audioEffectList; + QList m_videoEffectList; + bool m_equalizerEnabled; +}; + +} +} // namespace Phonon::VLC + +#endif // Phonon_VLC_EFFECTMANAGER_H diff --git a/bindings/phonon/vlc/mediacontroller.cpp b/bindings/phonon/vlc/mediacontroller.cpp new file mode 100644 index 0000000000..f38909be99 --- /dev/null +++ b/bindings/phonon/vlc/mediacontroller.cpp @@ -0,0 +1,223 @@ +/***************************************************************************** + * VLC backend for the Phonon library * + * Copyright (C) 2007-2008 Tanguy Krotoff * + * Copyright (C) 2008 Lukas Durfina * + * Copyright (C) 2009 Fathi Boudra * + * * + * 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 & arguments) +{ + switch (iface) { + case AddonInterface::ChapterInterface: + switch (static_cast(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()) { +// qCritical() << __FUNCTION__ << "Error: arguments invalid"; +// return false; +// } +// setCurrentChapter(arguments.first().value()); +// 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(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()) { +// qCritical() << __FUNCTION__ << "Error: arguments invalid"; +// return false; +// } +// setCurrentTitle(arguments.first().value()); +// 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(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(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()) { + qCritical() << __FUNCTION__ << "Error: arguments invalid"; + return false; + } + setCurrentSubtitle(arguments.first().value()); + return true; + default: + qCritical() << __FUNCTION__ + << "Error: unsupported AddonInterface::SubtitleInterface command:" + << i_command; + } + break; + case AddonInterface::AudioChannelInterface: + switch (static_cast(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()) { + qCritical() << __FUNCTION__ << "Error: arguments invalid"; + return false; + } + setCurrentAudioChannel(arguments.first().value()); + 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 diff --git a/bindings/phonon/vlc/mediacontroller.h b/bindings/phonon/vlc/mediacontroller.h new file mode 100644 index 0000000000..853e559388 --- /dev/null +++ b/bindings/phonon/vlc/mediacontroller.h @@ -0,0 +1,139 @@ +/***************************************************************************** + * VLC backend for the Phonon library * + * Copyright (C) 2007-2008 Tanguy Krotoff * + * Copyright (C) 2008 Lukas Durfina * + * Copyright (C) 2009 Fathi Boudra * + * * + * 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 +#include + +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 & arguments = QList()); + + // 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 availableAudioChannels() const = 0; + virtual Phonon::AudioChannelDescription currentAudioChannel() const = 0; + + // Subtitle + virtual void setCurrentSubtitle(const Phonon::SubtitleDescription & subtitle) = 0; + virtual QList 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 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 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 available_audio_channels; + + Phonon::SubtitleDescription current_subtitle; + QList available_subtitles; + +// Phonon::ChapterDescription current_chapter; +// QList available_chapters; + int current_chapter; + int available_chapters; + +// Phonon::TitleDescription current_title; +// QList 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 diff --git a/bindings/phonon/vlc/mediaobject.cpp b/bindings/phonon/vlc/mediaobject.cpp new file mode 100644 index 0000000000..aad5103e42 --- /dev/null +++ b/bindings/phonon/vlc/mediaobject.cpp @@ -0,0 +1,291 @@ +/***************************************************************************** + * VLC backend for the Phonon library * + * Copyright (C) 2007-2008 Tanguy Krotoff * + * Copyright (C) 2008 Lukas Durfina * + * Copyright (C) 2009 Fathi Boudra * + * * + * 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 +#include +#include + +//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"); + + 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 diff --git a/bindings/phonon/vlc/mediaobject.h b/bindings/phonon/vlc/mediaobject.h new file mode 100644 index 0000000000..01fdc6f95c --- /dev/null +++ b/bindings/phonon/vlc/mediaobject.h @@ -0,0 +1,126 @@ +/***************************************************************************** + * VLC backend for the Phonon library * + * Copyright (C) 2007-2008 Tanguy Krotoff * + * Copyright (C) 2008 Lukas Durfina * + * Copyright (C) 2009 Fathi Boudra * + * * + * 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 + +#include + +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 & 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 diff --git a/bindings/phonon/vlc/seekstack.cpp b/bindings/phonon/vlc/seekstack.cpp new file mode 100644 index 0000000000..a2eb145bc5 --- /dev/null +++ b/bindings/phonon/vlc/seekstack.cpp @@ -0,0 +1,86 @@ +/***************************************************************************** + * VLC backend for the Phonon library * + * Copyright (C) 2007-2008 Tanguy Krotoff * + * Copyright (C) 2008 Lukas Durfina * + * Copyright (C) 2009 Fathi Boudra * + * * + * 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 +#include + +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 diff --git a/bindings/phonon/vlc/seekstack.h b/bindings/phonon/vlc/seekstack.h new file mode 100644 index 0000000000..595b41a41d --- /dev/null +++ b/bindings/phonon/vlc/seekstack.h @@ -0,0 +1,70 @@ +/***************************************************************************** + * VLC backend for the Phonon library * + * Copyright (C) 2007-2008 Tanguy Krotoff * + * Copyright (C) 2008 Lukas Durfina * + * Copyright (C) 2009 Fathi Boudra * + * * + * 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 +#include + +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 stack; +}; + +} +} // Namespace Phonon::VLC + +#endif // PHONON_VLC_SEEKSTACK_H diff --git a/bindings/phonon/vlc/sinknode.cpp b/bindings/phonon/vlc/sinknode.cpp new file mode 100644 index 0000000000..dbba04c8e2 --- /dev/null +++ b/bindings/phonon/vlc/sinknode.cpp @@ -0,0 +1,56 @@ +/***************************************************************************** + * VLC backend for the Phonon library * + * Copyright (C) 2007-2008 Tanguy Krotoff * + * Copyright (C) 2008 Lukas Durfina * + * Copyright (C) 2009 Fathi Boudra * + * * + * 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 diff --git a/bindings/phonon/vlc/sinknode.h b/bindings/phonon/vlc/sinknode.h new file mode 100644 index 0000000000..10990e892f --- /dev/null +++ b/bindings/phonon/vlc/sinknode.h @@ -0,0 +1,59 @@ +/***************************************************************************** + * VLC backend for the Phonon library * + * Copyright (C) 2007-2008 Tanguy Krotoff * + * Copyright (C) 2008 Lukas Durfina * + * Copyright (C) 2009 Fathi Boudra * + * * + * 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 +#include + +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 diff --git a/bindings/phonon/vlc/videowidget.cpp b/bindings/phonon/vlc/videowidget.cpp new file mode 100644 index 0000000000..2afef533f3 --- /dev/null +++ b/bindings/phonon/vlc/videowidget.cpp @@ -0,0 +1,239 @@ +/***************************************************************************** + * VLC backend for the Phonon library * + * Copyright (C) 2007-2008 Tanguy Krotoff * + * Copyright (C) 2008 Lukas Durfina * + * Copyright (C) 2009 Fathi Boudra * + * * + * 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 +#include +#include +#include + +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(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 diff --git a/bindings/phonon/vlc/videowidget.h b/bindings/phonon/vlc/videowidget.h new file mode 100644 index 0000000000..89286c9360 --- /dev/null +++ b/bindings/phonon/vlc/videowidget.h @@ -0,0 +1,91 @@ +/***************************************************************************** + * VLC backend for the Phonon library * + * Copyright (C) 2007-2008 Tanguy Krotoff * + * Copyright (C) 2008 Lukas Durfina * + * Copyright (C) 2009 Fathi Boudra * + * * + * 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 + +#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 diff --git a/bindings/phonon/vlc/vlc.desktop b/bindings/phonon/vlc/vlc.desktop new file mode 100644 index 0000000000..e274edb0f0 --- /dev/null +++ b/bindings/phonon/vlc/vlc.desktop @@ -0,0 +1,30 @@ +[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 diff --git a/bindings/phonon/vlc/vlcloader.cpp b/bindings/phonon/vlc/vlcloader.cpp new file mode 100644 index 0000000000..d3856b30c1 --- /dev/null +++ b/bindings/phonon/vlc/vlcloader.cpp @@ -0,0 +1,203 @@ +/***************************************************************************** + * VLC backend for the Phonon library * + * Copyright (C) 2007-2008 Tanguy Krotoff * + * Copyright (C) 2008 Lukas Durfina * + * Copyright (C) 2009 Fathi Boudra * + * * + * 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 +#include +#include +#include +#include +#include + +// 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 diff --git a/bindings/phonon/vlc/vlcloader.h b/bindings/phonon/vlc/vlcloader.h new file mode 100644 index 0000000000..e47175a8c8 --- /dev/null +++ b/bindings/phonon/vlc/vlcloader.h @@ -0,0 +1,84 @@ +/***************************************************************************** + * VLC backend for the Phonon library * + * Copyright (C) 2007-2008 Tanguy Krotoff * + * Copyright (C) 2008 Lukas Durfina * + * Copyright (C) 2009 Fathi Boudra * + * * + * 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 + +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 diff --git a/bindings/phonon/vlc/vlcmediacontroller.cpp b/bindings/phonon/vlc/vlcmediacontroller.cpp new file mode 100644 index 0000000000..fea7939e39 --- /dev/null +++ b/bindings/phonon/vlc/vlcmediacontroller.cpp @@ -0,0 +1,295 @@ +/***************************************************************************** + * VLC backend for the Phonon library * + * Copyright (C) 2007-2008 Tanguy Krotoff * + * Copyright (C) 2008 Lukas Durfina * + * Copyright (C) 2009 Fathi Boudra * + * * + * 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 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 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 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 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 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 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 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 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 diff --git a/bindings/phonon/vlc/vlcmediacontroller.h b/bindings/phonon/vlc/vlcmediacontroller.h new file mode 100644 index 0000000000..bc41346c3f --- /dev/null +++ b/bindings/phonon/vlc/vlcmediacontroller.h @@ -0,0 +1,95 @@ +/***************************************************************************** + * VLC backend for the Phonon library * + * Copyright (C) 2007-2008 Tanguy Krotoff * + * Copyright (C) 2008 Lukas Durfina * + * Copyright (C) 2009 Fathi Boudra * + * * + * 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 availableAudioChannels() const; + Phonon::AudioChannelDescription currentAudioChannel() const; + void refreshAudioChannels(); + + // Subtitle + void setCurrentSubtitle(const Phonon::SubtitleDescription & subtitle); + QList 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 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 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 diff --git a/bindings/phonon/vlc/vlcmediaobject.cpp b/bindings/phonon/vlc/vlcmediaobject.cpp new file mode 100644 index 0000000000..3c2286fa39 --- /dev/null +++ b/bindings/phonon/vlc/vlcmediaobject.cpp @@ -0,0 +1,435 @@ +/***************************************************************************** + * VLC backend for the Phonon library * + * Copyright (C) 2007-2008 Tanguy Krotoff * + * Copyright (C) 2008 Lukas Durfina * + * Copyright (C) 2009 Fathi Boudra * + * * + * 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 +#include + +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 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 diff --git a/bindings/phonon/vlc/vlcmediaobject.h b/bindings/phonon/vlc/vlcmediaobject.h new file mode 100644 index 0000000000..0972fbd2fb --- /dev/null +++ b/bindings/phonon/vlc/vlcmediaobject.h @@ -0,0 +1,160 @@ +/***************************************************************************** + * VLC backend for the Phonon library * + * Copyright (C) 2007-2008 Tanguy Krotoff * + * Copyright (C) 2008 Lukas Durfina * + * Copyright (C) 2009 Fathi Boudra * + * * + * 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 +#include + +#include +#include +#include + +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 diff --git a/bindings/phonon/vlc/vlcvideowidget.cpp b/bindings/phonon/vlc/vlcvideowidget.cpp new file mode 100644 index 0000000000..e21767ea38 --- /dev/null +++ b/bindings/phonon/vlc/vlcvideowidget.cpp @@ -0,0 +1,66 @@ +/***************************************************************************** + * VLC backend for the Phonon library * + * Copyright (C) 2007-2008 Tanguy Krotoff * + * Copyright (C) 2008 Lukas Durfina * + * Copyright (C) 2009 Fathi Boudra * + * * + * 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 +#include + +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 diff --git a/bindings/phonon/vlc/vlcvideowidget.h b/bindings/phonon/vlc/vlcvideowidget.h new file mode 100644 index 0000000000..d8e9d216a8 --- /dev/null +++ b/bindings/phonon/vlc/vlcvideowidget.h @@ -0,0 +1,65 @@ +/***************************************************************************** + * VLC backend for the Phonon library * + * Copyright (C) 2007-2008 Tanguy Krotoff * + * Copyright (C) 2008 Lukas Durfina * + * Copyright (C) 2009 Fathi Boudra * + * * + * 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 + +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 diff --git a/bindings/phonon/vlc/widgetnopaintevent.cpp b/bindings/phonon/vlc/widgetnopaintevent.cpp new file mode 100644 index 0000000000..4f6931ebfa --- /dev/null +++ b/bindings/phonon/vlc/widgetnopaintevent.cpp @@ -0,0 +1,63 @@ +/***************************************************************************** + * VLC backend for the Phonon library * + * Copyright (C) 2007-2008 Tanguy Krotoff * + * Copyright (C) 2008 Lukas Durfina * + * Copyright (C) 2009 Fathi Boudra * + * * + * 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 + +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 diff --git a/bindings/phonon/vlc/widgetnopaintevent.h b/bindings/phonon/vlc/widgetnopaintevent.h new file mode 100644 index 0000000000..1e876914b0 --- /dev/null +++ b/bindings/phonon/vlc/widgetnopaintevent.h @@ -0,0 +1,58 @@ +/***************************************************************************** + * VLC backend for the Phonon library * + * Copyright (C) 2007-2008 Tanguy Krotoff * + * Copyright (C) 2008 Lukas Durfina * + * Copyright (C) 2009 Fathi Boudra * + * * + * 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 + +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