From 862c5fc8f6bd48d7104b2160bfa56c8c656e8f6b Mon Sep 17 00:00:00 2001 From: cc9cii Date: Thu, 11 Sep 2014 16:47:00 +1000 Subject: [PATCH] Add libavresample support. Tested on windows x64 only. --- .travis.yml | 2 +- CMakeLists.txt | 19 ++++++-- apps/openmw/mwrender/videoplayer.cpp | 66 ++++++++++++++++++++++++++-- cmake/FindFFmpeg.cmake | 3 +- 4 files changed, 81 insertions(+), 9 deletions(-) diff --git a/.travis.yml b/.travis.yml index b5c113af0..9308ccf87 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,7 @@ before_install: - sudo apt-get update -qq - sudo apt-get install -qq libgtest-dev google-mock - sudo apt-get install -qq libboost-filesystem-dev libboost-program-options-dev libboost-system-dev libboost-thread-dev libboost-wave-dev - - sudo apt-get install -qq libavcodec-dev libavformat-dev libavutil-dev libswscale-dev + - sudo apt-get install -qq libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libavresample-dev - sudo apt-get install -qq libbullet-dev libogre-1.9-dev libmygui-dev libsdl2-dev libunshield-dev libtinyxml-dev libopenal-dev libqt4-dev - sudo mkdir /usr/src/gtest/build - cd /usr/src/gtest/build diff --git a/CMakeLists.txt b/CMakeLists.txt index b89844a52..df134f9c0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -139,10 +139,23 @@ set(OPENMW_LIBS ${OENGINE_ALL}) set(OPENMW_LIBS_HEADER) # Sound setup -set(FFmpeg_FIND_COMPONENTS AVCODEC AVFORMAT AVUTIL SWSCALE SWRESAMPLE) -find_package(FFmpeg REQUIRED) +set(FFmpeg_FIND_COMPONENTS AVCODEC AVFORMAT AVUTIL SWSCALE SWRESAMPLE AVRESAMPLE) +find_package(FFmpeg) +if ( NOT AVCODEC_FOUND OR NOT AVFORMAT_FOUND OR NOT AVUTIL_FOUND OR NOT SWSCALE_FOUND ) + message(FATAL_ERROR "FFmpeg component required, but not found!") +endif() set(SOUND_INPUT_INCLUDES ${FFMPEG_INCLUDE_DIRS}) -set(SOUND_INPUT_LIBRARY ${FFMPEG_LIBRARIES} ${SWSCALE_LIBRARIES} ${SWRESAMPLE_LIBRARIES}) +set(SOUND_INPUT_LIBRARY ${FFMPEG_LIBRARIES} ${SWSCALE_LIBRARIES}) +if( SWRESAMPLE_FOUND ) + add_definitions(-DHAVE_LIBSWRESAMPLE) + set(SOUND_INPUT_LIBRARY ${FFMPEG_LIBRARIES} ${SWRESAMPLE_LIBRARIES}) +else() + if( AVRESAMPLE_FOUND) + set(SOUND_INPUT_LIBRARY ${FFMPEG_LIBRARIES} ${AVRESAMPLE_LIBRARIES}) + else() + message(FATAL_ERROR "FFmpeg component required, but not found!") + endif() +endif() # TinyXML option(USE_SYSTEM_TINYXML "Use system TinyXML library instead of internal." OFF) diff --git a/apps/openmw/mwrender/videoplayer.cpp b/apps/openmw/mwrender/videoplayer.cpp index 2b1612675..9c918814a 100644 --- a/apps/openmw/mwrender/videoplayer.cpp +++ b/apps/openmw/mwrender/videoplayer.cpp @@ -52,11 +52,69 @@ extern "C" #include #endif - // From version 54.56 binkaudio encoding format changed from S16 to FLTP. See: - // https://gitorious.org/ffmpeg/ffmpeg/commit/7bfd1766d1c18f07b0a2dd042418a874d49ea60d - // http://ffmpeg.zeranoe.com/forum/viewtopic.php?f=15&t=872 // WARNING: avcodec versions up to 54.54.100 potentially crashes on Windows 64bit. - #include +} + +// From version 54.56 binkaudio encoding format changed from S16 to FLTP. See: +// https://gitorious.org/ffmpeg/ffmpeg/commit/7bfd1766d1c18f07b0a2dd042418a874d49ea60d +// http://ffmpeg.zeranoe.com/forum/viewtopic.php?f=15&t=872 +extern "C" { +#ifdef HAVE_LIBSWRESAMPLE +#include +#else +/* nasty hack for systems without libswresample */ +#include +#include + +int swr_convert( + AVAudioResampleContext *avr, + uint8_t** output, + int out_samples, + const uint8_t** input, + int in_samples) +{ + // FIXME: potential performance hit + int out_plane_size = 0; + int in_plane_size = 0; + return avresample_convert(avr, output, out_plane_size, out_samples, + (uint8_t **)input, in_plane_size, in_samples); +} + +AVAudioResampleContext * swr_alloc_set_opts( + AVAudioResampleContext *avr, + int64_t out_ch_layout, + AVSampleFormat out_fmt, + int out_rate, + int64_t in_ch_layout, + AVSampleFormat in_fmt, + int in_rate, + int o, + void* l) +{ + avr = avresample_alloc_context(); + if(!avr) + return 0; + + if ((av_opt_set_int(avr, "out_channel_layout", out_ch_layout, 0) < 0) || + (av_opt_set_int(avr, "out_sample_fmt", out_fmt, 0) < 0) || + (av_opt_set_int(avr, "out_sample_rate", out_rate, 0) < 0) || + (av_opt_set_int(avr, "in_channel_layout", in_ch_layout, 0) < 0) || + (av_opt_set_int(avr, "in_sample_fmt", in_fmt, 0) < 0) || + (av_opt_set_int(avr, "in_sample_rate", in_rate, 0) < 0)) + { + return 0; + } + + if(avresample_open(avr) < 0) + return 0; + else + return avr; +} + +void swr_free(AVAudioResampleContext **avr) { avresample_free(avr); } +int swr_init(AVAudioResampleContext *avr) { return 1; } +#define SwrContext AVAudioResampleContext +#endif } #define MAX_AUDIOQ_SIZE (5 * 16 * 1024) diff --git a/cmake/FindFFmpeg.cmake b/cmake/FindFFmpeg.cmake index c3c25d2f9..74584bf31 100644 --- a/cmake/FindFFmpeg.cmake +++ b/cmake/FindFFmpeg.cmake @@ -114,6 +114,7 @@ if (NOT FFMPEG_LIBRARIES) find_component(SWSCALE libswscale swscale libswscale/swscale.h) find_component(POSTPROC libpostproc postproc libpostproc/postprocess.h) find_component(SWRESAMPLE libswresample swresample libswresample/swresample.h) + find_component(AVRESAMPLE libavresample avresample libavresample/avresample.h) # Check if the required components were found and add their stuff to the FFMPEG_* vars. foreach (_component ${FFmpeg_FIND_COMPONENTS}) @@ -144,7 +145,7 @@ if (NOT FFMPEG_LIBRARIES) endif () # Now set the noncached _FOUND vars for the components. -foreach (_component AVCODEC AVDEVICE AVFORMAT AVUTIL POSTPROCESS SWSCALE SWRESAMPLE) +foreach (_component AVCODEC AVDEVICE AVFORMAT AVUTIL POSTPROCESS SWSCALE SWRESAMPLE AVRESAMPLE) set_component_found(${_component}) endforeach ()