diff --git a/CMakeLists.txt b/CMakeLists.txt index 0bbc520..a13603c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,129 +1,137 @@ cmake_minimum_required(VERSION 3.0) set(KF5_VERSION "5.47.0") # handled by release scripts set(KF5_DEP_VERSION "5.47.0") # handled by release scripts project(KFileMetaData VERSION ${KF5_VERSION}) include(FeatureSummary) find_package(ECM 5.47.0 NO_MODULE) set_package_properties(ECM PROPERTIES TYPE REQUIRED DESCRIPTION "Extra CMake Modules." URL "https://projects.kde.org/projects/kdesupport/extra-cmake-modules") feature_summary(WHAT REQUIRED_PACKAGES_NOT_FOUND FATAL_ON_MISSING_REQUIRED_PACKAGES) set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR}) include(KDEInstallDirs) include(KDEFrameworkCompilerSettings NO_POLICY_SCOPE) include(KDECMakeSettings) include(ECMAddTests) include(GenerateExportHeader) include(ECMSetupVersion) include(ECMGenerateHeaders) include(ECMAddQch) include(ECMQtDeclareLoggingCategory) +include(CheckStructHasMember) option(BUILD_QCH "Build API documentation in QCH format (for e.g. Qt Assistant, Qt Creator & KDevelop)" OFF) add_feature_info(QCH ${BUILD_QCH} "API documentation in QCH format (for e.g. Qt Assistant, Qt Creator & KDevelop)") ecm_setup_version(PROJECT VARIABLE_PREFIX KFILEMETADATA PACKAGE_VERSION_FILE "${CMAKE_CURRENT_BINARY_DIR}/KF5FileMetaDataConfigVersion.cmake" SOVERSION 3) # Dependencies set(REQUIRED_QT_VERSION 5.8.0) find_package(Qt5 ${REQUIRED_QT_VERSION} REQUIRED NO_MODULE COMPONENTS Xml) find_package(KF5 ${KF5_DEP_VERSION} COMPONENTS Archive) set_package_properties(KF5Archive PROPERTIES DESCRIPTION "KDE Frameworks 5: Archive Framework" URL "https://download.kde.org/stable/frameworks/" TYPE OPTIONAL PURPOSE "Archive is needed to build ODF and OOXML 2007 extractors") find_package(KF5 ${KF5_DEP_VERSION} REQUIRED COMPONENTS I18n) find_package(Poppler 0.12.1 COMPONENTS Qt5) set_package_properties(Poppler PROPERTIES DESCRIPTION "A PDF rendering library" URL "http://poppler.freedesktop.org" TYPE OPTIONAL PURPOSE "Support for PDF files") find_package(Taglib 1.9) set_package_properties(Taglib PROPERTIES DESCRIPTION "Id3 tag reader" URL "http://developer.kde.org/~wheeler/taglib.html" TYPE OPTIONAL PURPOSE "Support for music metadata") find_package(Exiv2 0.21) set_package_properties(Exiv2 PROPERTIES DESCRIPTION "Image Tag reader" URL "http://www.exiv2.org" TYPE OPTIONAL PURPOSE "Support for image metadata") -find_package(FFmpeg 3.1) +find_package(FFmpeg 57.48 COMPONENTS AVCODEC) +find_package(FFmpeg 57.40 COMPONENTS AVFORMAT) +find_package(FFmpeg 55.27 COMPONENTS AVUTIL) set_package_properties(FFmpeg PROPERTIES DESCRIPTION "Video Tag reader" URL "http://ffmpeg.org" TYPE OPTIONAL PURPOSE "Support for video metadata") +if (FFmpeg_AVFORMAT_FOUND) + set(CMAKE_REQUIRED_INCLUDES ${AVCODEC_INCLUDE_DIRS}) + CHECK_STRUCT_HAS_MEMBER(AVStream codecpar "stdint.h;libavformat/avformat.h" HAVE_AVSTREAM_CODECPAR LANGUAGE CXX) +endif() + find_package(EPub) set_package_properties(EPub PROPERTIES DESCRIPTION "Ebook epub reader" URL "http://sourceforge.net/projects/ebook-tools" TYPE OPTIONAL PURPOSE "Support for epub metadata") find_package(CatDoc) set_package_properties(CatDoc PROPERTIES DESCRIPTION "catdoc executable" URL "http://www.wagner.pp.ru/~vitus/software/catdoc/" TYPE RUNTIME PURPOSE "Extract text from office 98 files - RUNTIME dependency") if ( CMAKE_SYSTEM_NAME MATCHES "Linux" ) find_package(Xattr) set_package_properties(Xattr PROPERTIES DESCRIPTION "library libattr " URL "http://savannah.nongnu.org/projects/attr" TYPE REQUIRED PURPOSE "Extended attribute shared library") endif() #find_package(QMobipocket) #set_package_properties(QMobipocket PROPERTIES DESCRIPTION "Mobipocket epub reader" # URL "https://projects.kde.org/projects/kde/kdegraphics/kdegraphics-mobipocket" # TYPE OPTIONAL PURPOSE "Support for mobi metadata") add_definitions(-DTRANSLATION_DOMAIN=\"kfilemetadata5\") add_subdirectory(src) if (BUILD_TESTING) add_subdirectory(autotests) add_subdirectory(tests) endif() # Config files set(CMAKECONFIG_INSTALL_DIR "${CMAKECONFIG_INSTALL_PREFIX}/KF5FileMetaData") if (IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/po") ki18n_install(po) endif() if (BUILD_QCH) ecm_install_qch_export( TARGETS KF5FileMetaData_QCH FILE KF5FileMetaDataQchTargets.cmake DESTINATION "${CMAKECONFIG_INSTALL_DIR}" COMPONENT Devel ) set(PACKAGE_INCLUDE_QCHTARGETS "include(\"\${CMAKE_CURRENT_LIST_DIR}/KF5FileMetaDataQchTargets.cmake\")") endif() include(CMakePackageConfigHelpers) configure_package_config_file( "${CMAKE_CURRENT_SOURCE_DIR}/KF5FileMetaDataConfig.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/KF5FileMetaDataConfig.cmake" INSTALL_DESTINATION ${CMAKECONFIG_INSTALL_DIR} ) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/KF5FileMetaDataConfig.cmake" "${CMAKE_CURRENT_BINARY_DIR}/KF5FileMetaDataConfigVersion.cmake" DESTINATION "${CMAKECONFIG_INSTALL_DIR}" COMPONENT devel ) # contains list of debug categories, for kdebugsettings install(FILES kfilemetadata.categories DESTINATION ${KDE_INSTALL_CONFDIR}) feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES) diff --git a/cmake/FindFFmpeg.cmake b/cmake/FindFFmpeg.cmake index aa1d088..5217f93 100644 --- a/cmake/FindFFmpeg.cmake +++ b/cmake/FindFFmpeg.cmake @@ -1,169 +1,174 @@ # vim: ts=2 sw=2 # - Try to find the required ffmpeg components(default: AVFORMAT, AVUTIL, AVCODEC) # # Once done this will define # FFMPEG_FOUND - System has the all required components. # FFMPEG_INCLUDE_DIRS - Include directory necessary for using the required components headers. # FFMPEG_LIBRARIES - Link these to use the required ffmpeg components. # FFMPEG_DEFINITIONS - Compiler switches required for using the required ffmpeg components. # # For each of the components it will additionally set. # - AVCODEC # - AVDEVICE # - AVFORMAT # - AVUTIL # - POSTPROCESS # - SWSCALE # the following variables will be defined # _FOUND - System has # _INCLUDE_DIRS - Include directory necessary for using the headers # _LIBRARIES - Link these to use # _DEFINITIONS - Compiler switches required for using # _VERSION - The components version # # Copyright (c) 2006, Matthias Kretz, # Copyright (c) 2008, Alexander Neundorf, # Copyright (c) 2011, Michael Jansen, # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # 3. Neither the name of the University nor the names of its contributors # may be used to endorse or promote products derived from this software # without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. include(FindPackageHandleStandardArgs) # The default components were taken from a survey over other FindFFMPEG.cmake files if (NOT FFmpeg_FIND_COMPONENTS) set(FFmpeg_FIND_COMPONENTS AVCODEC AVFORMAT AVUTIL) endif () # ### Macro: set_component_found # # Marks the given component as found if both *_LIBRARIES AND *_INCLUDE_DIRS is present. # macro(set_component_found _component ) if (${_component}_LIBRARIES AND ${_component}_INCLUDE_DIRS) # message(STATUS " - ${_component} found.") set(${_component}_FOUND TRUE) + set(FFmpeg_${_component}_FOUND TRUE) else () # message(STATUS " - ${_component} not found.") endif () endmacro() # ### Macro: find_component # # Checks for the given component by invoking pkgconfig and then looking up the libraries and # include directories. # -macro(find_component _component _pkgconfig _library _header) +macro(find_component _component _pkgconfig _library _header _version) if (NOT WIN32) # use pkg-config to get the directories and then use these values # in the FIND_PATH() and FIND_LIBRARY() calls find_package(PkgConfig) if (PKG_CONFIG_FOUND) - pkg_check_modules(PC_${_component} ${_pkgconfig}) + pkg_check_modules(PC_${_component} ${_pkgconfig}>=${_version}) endif () endif (NOT WIN32) find_path(${_component}_INCLUDE_DIRS ${_header} HINTS ${PC_LIB${_component}_INCLUDEDIR} ${PC_LIB${_component}_INCLUDE_DIRS} PATH_SUFFIXES ffmpeg ) find_library(${_component}_LIBRARIES NAMES ${_library} HINTS ${PC_LIB${_component}_LIBDIR} ${PC_LIB${_component}_LIBRARY_DIRS} ) set(${_component}_DEFINITIONS ${PC_${_component}_CFLAGS_OTHER} CACHE STRING "The ${_component} CFLAGS.") set(${_component}_VERSION ${PC_${_component}_VERSION} CACHE STRING "The ${_component} version number.") set_component_found(${_component}) mark_as_advanced( ${_component}_INCLUDE_DIRS ${_component}_LIBRARIES ${_component}_DEFINITIONS ${_component}_VERSION) endmacro() - # Check for cached results. If there are skip the costly part. if (NOT FFMPEG_LIBRARIES) # Check for all possible component. - find_component(AVCODEC libavcodec avcodec libavcodec/avcodec.h) - find_component(AVFORMAT libavformat avformat libavformat/avformat.h) - find_component(AVDEVICE libavdevice avdevice libavdevice/avdevice.h) - find_component(AVUTIL libavutil avutil libavutil/avutil.h) - find_component(SWSCALE libswscale swscale libswscale/swscale.h) - find_component(POSTPROCESS libpostproc postproc libpostproc/postprocess.h) + find_component(AVCODEC libavcodec avcodec libavcodec/avcodec.h ${FFmpeg_FIND_VERSION}) + find_component(AVFORMAT libavformat avformat libavformat/avformat.h ${FFmpeg_FIND_VERSION}) + find_component(AVDEVICE libavdevice avdevice libavdevice/avdevice.h ${FFmpeg_FIND_VERSION}) + find_component(AVUTIL libavutil avutil libavutil/avutil.h ${FFmpeg_FIND_VERSION}) + find_component(SWSCALE libswscale swscale libswscale/swscale.h ${FFmpeg_FIND_VERSION}) + find_component(POSTPROCESS libpostproc postproc libpostproc/postprocess.h ${FFmpeg_FIND_VERSION}) # Check if the required components were found and add their stuff to the FFMPEG_* vars. foreach (_component ${FFmpeg_FIND_COMPONENTS}) if (${_component}_FOUND) # message(STATUS "Required component ${_component} present.") set(FFMPEG_LIBRARIES ${FFMPEG_LIBRARIES} ${${_component}_LIBRARIES}) set(FFMPEG_DEFINITIONS ${FFMPEG_DEFINITIONS} ${${_component}_DEFINITIONS}) list(APPEND FFMPEG_INCLUDE_DIRS ${${_component}_INCLUDE_DIRS}) else () # message(STATUS "Required component ${_component} missing.") endif () endforeach () # Build the include path with duplicates removed. if (FFMPEG_INCLUDE_DIRS) list(REMOVE_DUPLICATES FFMPEG_INCLUDE_DIRS) endif () # cache the vars. set(FFMPEG_INCLUDE_DIRS ${FFMPEG_INCLUDE_DIRS} CACHE STRING "The FFmpeg include directories." FORCE) set(FFMPEG_LIBRARIES ${FFMPEG_LIBRARIES} CACHE STRING "The FFmpeg libraries." FORCE) set(FFMPEG_DEFINITIONS ${FFMPEG_DEFINITIONS} CACHE STRING "The FFmpeg cflags." FORCE) mark_as_advanced(FFMPEG_INCLUDE_DIRS FFMPEG_LIBRARIES FFMPEG_DEFINITIONS) endif () # Now set the noncached _FOUND vars for the components. foreach (_component AVCODEC AVDEVICE AVFORMAT AVUTIL POSTPROCESS SWSCALE) set_component_found(${_component}) endforeach () # Compile the list of required vars set(_FFmpeg_REQUIRED_VARS FFMPEG_LIBRARIES FFMPEG_INCLUDE_DIRS) foreach (_component ${FFmpeg_FIND_COMPONENTS}) list(APPEND _FFmpeg_REQUIRED_VARS ${_component}_LIBRARIES ${_component}_INCLUDE_DIRS) endforeach () + + # Give a nice error message if some of the required vars are missing. -find_package_handle_standard_args(FFmpeg DEFAULT_MSG ${_FFmpeg_REQUIRED_VARS}) +find_package_handle_standard_args(FFmpeg + REQUIRED_VARS ${_FFmpeg_REQUIRED_VARS} + HANDLE_COMPONENTS) + diff --git a/src/config-kfilemetadata.h.in b/src/config-kfilemetadata.h.in index 90b7433..febdbf6 100644 --- a/src/config-kfilemetadata.h.in +++ b/src/config-kfilemetadata.h.in @@ -1,5 +1,7 @@ #ifndef CONFIGKFILEMETADATA_H #define CONFIGKFILEMETADATA_H #define LIBEXEC_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/${KF5_LIBEXEC_INSTALL_DIR}" +#cmakedefine01 HAVE_AVSTREAM_CODECPAR + #endif // CONFIGKFILEMETADATA_H diff --git a/src/extractors/CMakeLists.txt b/src/extractors/CMakeLists.txt index 3888d1d..97b8afc 100644 --- a/src/extractors/CMakeLists.txt +++ b/src/extractors/CMakeLists.txt @@ -1,177 +1,179 @@ if(Poppler_Qt5_FOUND) add_library(kfilemetadata_popplerextractor MODULE popplerextractor.cpp) target_link_libraries(kfilemetadata_popplerextractor KF5::FileMetaData Poppler::Qt5 ) set_target_properties(kfilemetadata_popplerextractor PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/kf5/kfilemetadata") install( TARGETS kfilemetadata_popplerextractor DESTINATION ${PLUGIN_INSTALL_DIR}/kf5/kfilemetadata) endif() if(TAGLIB_FOUND) add_library(kfilemetadata_taglibextractor MODULE taglibextractor.cpp ) target_include_directories(kfilemetadata_taglibextractor SYSTEM PRIVATE ${TAGLIB_INCLUDES}) target_link_libraries( kfilemetadata_taglibextractor KF5::FileMetaData ${TAGLIB_LIBRARIES} ) set_target_properties(kfilemetadata_taglibextractor PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/kf5/kfilemetadata") install( TARGETS kfilemetadata_taglibextractor DESTINATION ${PLUGIN_INSTALL_DIR}/kf5/kfilemetadata) endif() if(EXIV2_FOUND) add_library(kfilemetadata_exiv2extractor MODULE exiv2extractor.cpp) target_include_directories(kfilemetadata_exiv2extractor SYSTEM PRIVATE ${EXIV2_INCLUDE_DIR}) kde_target_enable_exceptions(kfilemetadata_exiv2extractor PRIVATE) target_link_libraries(kfilemetadata_exiv2extractor KF5::FileMetaData ${EXIV2_LIBRARIES} ) set_target_properties(kfilemetadata_exiv2extractor PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/kf5/kfilemetadata") install( TARGETS kfilemetadata_exiv2extractor DESTINATION ${PLUGIN_INSTALL_DIR}/kf5/kfilemetadata) endif() if(FFMPEG_FOUND) add_library(kfilemetadata_ffmpegextractor MODULE ffmpegextractor.cpp) - target_include_directories(kfilemetadata_ffmpegextractor SYSTEM PRIVATE ${FFMPEG_INCLUDE_DIRS}) + target_include_directories(kfilemetadata_ffmpegextractor SYSTEM PRIVATE ${AVCODEC_INCLUDE_DIRS} ${AVFORMAT_INCLUDE_DIRS} ${AVUTIL_INCLUDE_DIRS}) target_link_libraries(kfilemetadata_ffmpegextractor KF5::FileMetaData - ${FFMPEG_LIBRARIES} + ${AVCODEC_LIBRARIES} + ${AVFORMAT_LIBRARIES} + ${AVUTIL_LIBRARIES} ) set_target_properties(kfilemetadata_ffmpegextractor PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/kf5/kfilemetadata") install( TARGETS kfilemetadata_ffmpegextractor DESTINATION ${PLUGIN_INSTALL_DIR}/kf5/kfilemetadata) endif() if(EPUB_FOUND) add_library(kfilemetadata_epubextractor MODULE epubextractor.cpp) target_include_directories(kfilemetadata_epubextractor SYSTEM PRIVATE ${EPUB_INCLUDE_DIR}) target_link_libraries(kfilemetadata_epubextractor KF5::FileMetaData ${EPUB_LIBRARIES} ) set_target_properties(kfilemetadata_epubextractor PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/kf5/kfilemetadata") install( TARGETS kfilemetadata_epubextractor DESTINATION ${PLUGIN_INSTALL_DIR}/kf5/kfilemetadata) endif() # # Plain Text # add_library(kfilemetadata_plaintextextractor MODULE plaintextextractor.cpp) target_link_libraries( kfilemetadata_plaintextextractor KF5::FileMetaData ) set_target_properties(kfilemetadata_plaintextextractor PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/kf5/kfilemetadata") install( TARGETS kfilemetadata_plaintextextractor DESTINATION ${PLUGIN_INSTALL_DIR}/kf5/kfilemetadata) # # PO # add_library(kfilemetadata_poextractor MODULE poextractor.cpp) target_link_libraries( kfilemetadata_poextractor KF5::FileMetaData ) set_target_properties(kfilemetadata_poextractor PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/kf5/kfilemetadata") install( TARGETS kfilemetadata_poextractor DESTINATION ${PLUGIN_INSTALL_DIR}/kf5/kfilemetadata) # # ODF # if(KF5Archive_FOUND) add_library(kfilemetadata_odfextractor MODULE odfextractor.cpp) target_link_libraries(kfilemetadata_odfextractor KF5::FileMetaData Qt5::Core Qt5::Xml KF5::Archive ) set_target_properties(kfilemetadata_odfextractor PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/kf5/kfilemetadata") install( TARGETS kfilemetadata_odfextractor DESTINATION ${PLUGIN_INSTALL_DIR}/kf5/kfilemetadata) endif() # # Office 2007 # if(KF5Archive_FOUND) add_library(kfilemetadata_office2007extractor MODULE office2007extractor.cpp) target_link_libraries(kfilemetadata_office2007extractor KF5::FileMetaData Qt5::Core Qt5::Xml KF5::Archive ) set_target_properties(kfilemetadata_office2007extractor PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/kf5/kfilemetadata") install( TARGETS kfilemetadata_office2007extractor DESTINATION ${PLUGIN_INSTALL_DIR}/kf5/kfilemetadata) endif() # # Office (binary formats) # add_library(kfilemetadata_officeextractor MODULE officeextractor.cpp) target_link_libraries(kfilemetadata_officeextractor KF5::FileMetaData ) set_target_properties(kfilemetadata_officeextractor PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/kf5/kfilemetadata") install( TARGETS kfilemetadata_officeextractor DESTINATION ${PLUGIN_INSTALL_DIR}/kf5/kfilemetadata) # # Mobipocket # if (QMOBIPOCKET_FOUND) add_library(kfilemetadata_mobiextractor MODULE mobiextractor.cpp) target_include_directories(kfilemetadata_mobiextractor SYSTEM PRIVATE ${QMOBIPOCKET_INCLUDE_DIR}) target_link_libraries(kfilemetadata_mobiextractor KF5::FileMetaData ${QMOBIPOCKET_LIBRARIES} ) set_target_properties(kfilemetadata_mobiextractor PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/kf5/kfilemetadata") install( TARGETS kfilemetadata_mobiextractor DESTINATION ${PLUGIN_INSTALL_DIR}/kf5/kfilemetadata) endif() diff --git a/src/extractors/ffmpegextractor.cpp b/src/extractors/ffmpegextractor.cpp index 3a7cd7f..9d9a23a 100644 --- a/src/extractors/ffmpegextractor.cpp +++ b/src/extractors/ffmpegextractor.cpp @@ -1,179 +1,185 @@ /* Copyright (C) 2012-2014 Vishesh Handa Code adapted from Strigi FFmpeg Analyzer - Copyright (C) 2010 Evgeny Egorochkin Copyright (C) 2011 Tirtha Chatterjee 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 of the License, or (at your option) any later version. 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "ffmpegextractor.h" +#include "config-kfilemetadata.h" + #ifdef __cplusplus #define __STDC_CONSTANT_MACROS #ifdef _STDINT_H #undef _STDINT_H #endif # include #endif extern "C" { #include #include #include } #include #include using namespace KFileMetaData; FFmpegExtractor::FFmpegExtractor(QObject* parent) : ExtractorPlugin(parent) { } QStringList FFmpegExtractor::mimetypes() const { QStringList types; types << QStringLiteral("video/x-ms-asf"); types << QStringLiteral("video/x-msvideo"); types << QStringLiteral("video/x-flv"); types << QStringLiteral("video/quicktime"); types << QStringLiteral("video/mpeg"); types << QStringLiteral("video/x-ms-wmv"); types << QStringLiteral("video/mp4"); types << QStringLiteral("video/x-matroska"); types << QStringLiteral("video/webm"); return types; } void FFmpegExtractor::extract(ExtractionResult* result) { AVFormatContext* fmt_ctx = NULL; av_register_all(); QByteArray arr = result->inputUrl().toUtf8(); fmt_ctx = avformat_alloc_context(); if (int ret = avformat_open_input(&fmt_ctx, arr.data(), NULL, NULL)) { qWarning() << "avformat_open_input error: " << ret; return; } int ret = avformat_find_stream_info(fmt_ctx, NULL); if (ret < 0) { qWarning() << "avform_find_stream_info error: " << ret; return; } result->addType(Type::Video); int totalSecs = fmt_ctx->duration / AV_TIME_BASE; int bitrate = fmt_ctx->bit_rate; result->add(Property::Duration, totalSecs); result->add(Property::BitRate, bitrate); for (uint i = 0; i < fmt_ctx->nb_streams; i++) { const AVStream* stream = fmt_ctx->streams[i]; +#if defined HAVE_AVSTREAM_CODECPAR && HAVE_AVSTREAM_CODECPAR const AVCodecParameters* codec = stream->codecpar; +#else + const AVCodecContext* codec = stream->codec; +#endif if (codec->codec_type == AVMEDIA_TYPE_AUDIO || codec->codec_type == AVMEDIA_TYPE_VIDEO) { /* if( codec->codec_type == AVMEDIA_TYPE_AUDIO ) { subRes.addType( NFO::Audio() ); subRes.addProperty( NFO::sampleRate(), codec->sample_rate ); subRes.addProperty( NFO::channels(), codec->channels ); //TODO: Fetch Sample Format }*/ if (codec->codec_type == AVMEDIA_TYPE_VIDEO) { int aspectRatio = codec->sample_aspect_ratio.num; int frameRate = stream->avg_frame_rate.num; if (codec->sample_aspect_ratio.den) aspectRatio /= codec->sample_aspect_ratio.den; if (stream->avg_frame_rate.den) frameRate /= stream->avg_frame_rate.den; result->add(Property::Width, codec->width); result->add(Property::Height, codec->height); if (aspectRatio) result->add(Property::AspectRatio, aspectRatio); if (frameRate) result->add(Property::FrameRate, frameRate); } } } AVDictionary* dict = fmt_ctx->metadata; AVDictionaryEntry* entry; entry = av_dict_get(dict, "title", NULL, 0); if (entry) { result->add(Property::Title, QString::fromUtf8(entry->value)); } entry = av_dict_get(dict, "author", NULL, 0); if (entry) { result->add(Property::Author, QString::fromUtf8(entry->value)); } entry = av_dict_get(dict, "copyright", NULL, 0); if (entry) { result->add(Property::Copyright, QString::fromUtf8(entry->value)); } entry = av_dict_get(dict, "comment", NULL, 0); if (entry) { result->add(Property::Comment, QString::fromUtf8(entry->value)); } entry = av_dict_get(dict, "album", NULL, 0); if (entry) { result->add(Property::Album, QString::fromUtf8(entry->value)); } entry = av_dict_get(dict, "genre", NULL, 0); if (entry) { result->add(Property::Genre, QString::fromUtf8(entry->value)); } entry = av_dict_get(dict, "track", NULL, 0); if (entry) { QString value = QString::fromUtf8(entry->value); bool ok = false; int track = value.toInt(&ok); if (ok && track) result->add(Property::TrackNumber, track); } entry = av_dict_get(dict, "year", NULL, 0); if (entry) { int year = QString::fromUtf8(entry->value).toInt(); result->add(Property::ReleaseYear, year); } avformat_close_input(&fmt_ctx); }