diff --git a/aegisub/build/libaegisub_vs2008/libaegisub_vs2008.vcproj b/aegisub/build/libaegisub_vs2008/libaegisub_vs2008.vcproj index e06fa785d..ab1a64920 100644 --- a/aegisub/build/libaegisub_vs2008/libaegisub_vs2008.vcproj +++ b/aegisub/build/libaegisub_vs2008/libaegisub_vs2008.vcproj @@ -457,10 +457,6 @@ RelativePath="..\..\libaegisub\include\libaegisub\mru.h" > - - diff --git a/aegisub/build/msbuild/libaegisub/libaegisub.vcxproj b/aegisub/build/msbuild/libaegisub/libaegisub.vcxproj index a262bd495..8055a8eff 100644 --- a/aegisub/build/msbuild/libaegisub/libaegisub.vcxproj +++ b/aegisub/build/msbuild/libaegisub/libaegisub.vcxproj @@ -60,11 +60,9 @@ - - @@ -97,7 +95,6 @@ - diff --git a/aegisub/build/msbuild/libaegisub/libaegisub.vcxproj.filters b/aegisub/build/msbuild/libaegisub/libaegisub.vcxproj.filters index 0ad646cf3..697d6f0b0 100644 --- a/aegisub/build/msbuild/libaegisub/libaegisub.vcxproj.filters +++ b/aegisub/build/msbuild/libaegisub/libaegisub.vcxproj.filters @@ -59,9 +59,6 @@ Header Files - - Header Files - Header Files @@ -116,9 +113,6 @@ Header Files - - Header Files - Header Files @@ -187,9 +181,6 @@ Source Files\Windows - - Source Files\Common - Source Files\Common diff --git a/aegisub/configure.in b/aegisub/configure.in index 75490c984..faa3632fe 100644 --- a/aegisub/configure.in +++ b/aegisub/configure.in @@ -206,18 +206,6 @@ AC_SUBST(DMG_STRING) ACX_PTHREAD([], [AC_MSG_FAILURE([You must have working pthreads.])]) CC="$PTHREAD_CC" -AC_AGI_COMPILE([pthread_rwlock_*], [pthread_rwlock], [$PTHREAD_CFLAGS], [$PTHREAD_LIBS],[ -#include -#define _XOPEN_SOURCE 500 -int main(void) { - pthread_rwlock_t l; pthread_rwlock_init(&l, NULL); - pthread_rwlock_rdlock(&l); - return 0; -}]) - -AS_IF([test x$agi_cv_with_pthread_rwlock = xyes], - [AC_DEFINE(HAVE_RWLOCK,1,[define if the compiler implements pthread_rwlock_*])]) - ###################### # Check compiler flags ###################### diff --git a/aegisub/libaegisub/Makefile b/aegisub/libaegisub/Makefile index aec294110..32ee0a468 100644 --- a/aegisub/libaegisub/Makefile +++ b/aegisub/libaegisub/Makefile @@ -32,7 +32,6 @@ SRC = \ common/option.cpp \ common/option_visit.cpp \ common/path.cpp \ - common/progress.cpp \ common/keyframe.cpp \ common/util.cpp \ common/log.cpp \ diff --git a/aegisub/libaegisub/common/progress.cpp b/aegisub/libaegisub/common/progress.cpp deleted file mode 100644 index bd8de8bea..000000000 --- a/aegisub/libaegisub/common/progress.cpp +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright (c) 2011, Niels Martin Hansen -// -// Permission to use, copy, modify, and distribute this software for any -// purpose with or without fee is hereby granted, provided that the above -// copyright notice and this permission notice appear in all copies. -// -// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -// -// $Id$ - -/// @file progress.cpp -/// @brief Progress bars. -/// @ingroup libaegisub - -#ifndef LAG_PRE -#include - -#include -#include -#include -#include -#endif - -#include "libaegisub/progress.h" - - -namespace agi { - - -class NullProgressSink : public ProgressSink { -public: - virtual void set_progress(int steps, int max) { } - virtual void set_operation(const std::string &operation) { } - virtual bool get_cancelled() const { return false; } -}; - -ProgressSink * NullProgressSinkFactory::create_progress_sink(const std::string &title) const { - return new NullProgressSink; -} - - -class StdioProgressSink : public ProgressSink { -private: - std::string operation; - float progress; - - void print(); - -public: - StdioProgressSink(const std::string &title); - virtual ~StdioProgressSink(); - virtual void set_progress(int steps, int max); - virtual void set_operation(const std::string &operation); - virtual bool get_cancelled() const { return false; } // or maybe see if there is an ESC waiting or get a ^C sent flag -}; - -ProgressSink * StdioProgressSinkFactory::create_progress_sink(const std::string &title) const { - return new StdioProgressSink(title); -} - - -StdioProgressSink::StdioProgressSink(const std::string &title) -: operation(title) -, progress(0) { - std::cout << title << ": "; - print(); -} - -StdioProgressSink::~StdioProgressSink() -{ - std::cout << "end" << std::endl; -} - - -void StdioProgressSink::set_progress(int steps, int max) { - assert(steps >= 0); - assert(steps <= max); - - float old_progress = progress; - progress = (100.f * steps)/max; - - if (std::fabs(progress-old_progress) > 0.8) - { - print(); - } -} - - -void StdioProgressSink::set_operation(const std::string &operation) { - this->operation = operation; - print(); -} - - -void StdioProgressSink::print() { - std::cout << operation << ": " << std::setprecision(2) << progress << std::endl; -} - - - -} // namespace agi diff --git a/aegisub/libaegisub/include/libaegisub/mutex.h b/aegisub/libaegisub/include/libaegisub/mutex.h deleted file mode 100644 index dab895799..000000000 --- a/aegisub/libaegisub/include/libaegisub/mutex.h +++ /dev/null @@ -1,325 +0,0 @@ -// Copyright (c) 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * 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. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER 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. -// -// --- -// Author: Craig Silverstein. -// -// A simple mutex wrapper, supporting locks and read-write locks. -// You should assume the locks are *not* re-entrant. -// -// To use: you should define the following macros in your configure.ac: -// ACX_PTHREAD -// AC_RWLOCK -// The latter is defined in ../autoconf. -// -// This class is meant to be internal-only and should be wrapped by an -// internal namespace. Before you use this module, please give the -// name of your internal namespace for this module. Or, if you want -// to expose it, you'll want to move it to the Google namespace. We -// cannot put this class in global namespace because there can be some -// problems when we have multiple versions of Mutex in each shared object. -// -// NOTE: by default, we have #ifdef'ed out the TryLock() method. -// This is for two reasons: -// 1) TryLock() under Windows is a bit annoying (it requires a -// #define to be defined very early). -// 2) TryLock() is broken for NO_THREADS mode, at least in NDEBUG -// mode. -// If you need TryLock(), and either these two caveats are not a -// problem for you, or you're willing to work around them, then -// feel free to #define GMUTEX_TRYLOCK, or to remove the #ifdefs -// in the code below. -// -// CYGWIN NOTE: Cygwin support for rwlock seems to be buggy: -// http://www.cygwin.com/ml/cygwin/2008-12/msg00017.html -// Because of that, we might as well use windows locks for -// cygwin. They seem to be more reliable than the cygwin pthreads layer. -// -// TRICKY IMPLEMENTATION NOTE: -// This class is designed to be safe to use during -// dynamic-initialization -- that is, by global constructors that are -// run before main() starts. The issue in this case is that -// dynamic-initialization happens in an unpredictable order, and it -// could be that someone else's dynamic initializer could call a -// function that tries to acquire this mutex -- but that all happens -// before this mutex's constructor has run. (This can happen even if -// the mutex and the function that uses the mutex are in the same .cc -// file.) Basically, because Mutex does non-trivial work in its -// constructor, it's not, in the naive implementation, safe to use -// before dynamic initialization has run on it. -// -// The solution used here is to pair the actual mutex primitive with a -// bool that is set to true when the mutex is dynamically initialized. -// (Before that it's false.) Then we modify all mutex routines to -// look at the bool, and not try to lock/unlock until the bool makes -// it to true (which happens after the Mutex constructor has run.) -// -// This works because before main() starts -- particularly, during -// dynamic initialization -- there are no threads, so a) it's ok that -// the mutex operations are a no-op, since we don't need locking then -// anyway; and b) we can be quite confident our bool won't change -// state between a call to Lock() and a call to Unlock() (that would -// require a global constructor in one translation unit to call Lock() -// and another global constructor in another translation unit to call -// Unlock() later, which is pretty perverse). -// -// That said, it's tricky, and can conceivably fail; it's safest to -// avoid trying to acquire a mutex in a global constructor, if you -// can. One way it can fail is that a really smart compiler might -// initialize the bool to true at static-initialization time (too -// early) rather than at dynamic-initialization time. To discourage -// that, we set is_safe_ to true in code (not the constructor -// colon-initializer) and set it to true via a function that always -// evaluates to true, but that the compiler can't know always -// evaluates to true. This should be good enough. - -#ifndef GOOGLE_MUTEX_H_ -#define GOOGLE_MUTEX_H_ - -#if defined(NO_THREADS) - typedef int MutexType; // to keep a lock-count -#elif defined(_WIN32) || defined(__CYGWIN32__) || defined(__CYGWIN64__) -# define WIN32_LEAN_AND_MEAN // We only need minimal includes -# ifdef GMUTEX_TRYLOCK - // We need Windows NT or later for TryEnterCriticalSection(). If you - // don't need that functionality, you can remove these _WIN32_WINNT - // lines, and change TryLock() to assert(0) or something. -# ifndef _WIN32_WINNT -# define _WIN32_WINNT 0x0400 -# endif -# endif -// To avoid macro definition of ERROR. -# define NOGDI -// To avoid macro definition of min/max. -# ifndef NOMINMAX -# define NOMINMAX -# endif // NOMINMAX -# include - typedef CRITICAL_SECTION MutexType; -#elif defined(HAVE_PTHREAD) && defined(HAVE_RWLOCK) - // Needed for pthread_rwlock_*. If it causes problems, you could take it - // out, but then you'd have to unset HAVE_RWLOCK (at least on linux -- it - // *does* cause problems for FreeBSD, or MacOSX, but isn't needed - // for locking there.) -# ifdef __linux__ -# define _XOPEN_SOURCE 500 // may be needed to get the rwlock calls -# endif -# include - typedef pthread_rwlock_t MutexType; -#elif defined(HAVE_PTHREAD) -# include - typedef pthread_mutex_t MutexType; -#else -# error Need to implement mutex.h for your architecture, or #define NO_THREADS -#endif - -// We need to include these header files after defining _XOPEN_SOURCE -// as they may define the _XOPEN_SOURCE macro. -#include -#include // for abort() - -#define MUTEX_NAMESPACE agi - -namespace MUTEX_NAMESPACE { - -class Mutex { - public: - // Create a Mutex that is not held by anybody. This constructor is - // typically used for Mutexes allocated on the heap or the stack. - // See below for a recommendation for constructing global Mutex - // objects. - inline Mutex(); - - // Destructor - inline ~Mutex(); - - inline void Lock(); // Block if needed until free then acquire exclusively - inline void Unlock(); // Release a lock acquired via Lock() -#ifdef GMUTEX_TRYLOCK - inline bool TryLock(); // If free, Lock() and return true, else return false -#endif - // Note that on systems that don't support read-write locks, these may - // be implemented as synonyms to Lock() and Unlock(). So you can use - // these for efficiency, but don't use them anyplace where being able - // to do shared reads is necessary to avoid deadlock. - inline void ReaderLock(); // Block until free or shared then acquire a share - inline void ReaderUnlock(); // Release a read share of this Mutex - inline void WriterLock() { Lock(); } // Acquire an exclusive lock - inline void WriterUnlock() { Unlock(); } // Release a lock from WriterLock() - - // TODO(hamaji): Do nothing, implement correctly. - inline void AssertHeld() {} - - private: - MutexType mutex_; - // We want to make sure that the compiler sets is_safe_ to true only - // when we tell it to, and never makes assumptions is_safe_ is - // always true. volatile is the most reliable way to do that. - volatile bool is_safe_; - - inline void SetIsSafe() { is_safe_ = true; } - - // Catch the error of writing Mutex when intending MutexLock. - Mutex(Mutex* /*ignored*/) {} - // Disallow "evil" constructors - Mutex(const Mutex&); - void operator=(const Mutex&); -}; - -// Now the implementation of Mutex for various systems -#if defined(NO_THREADS) - -// When we don't have threads, we can be either reading or writing, -// but not both. We can have lots of readers at once (in no-threads -// mode, that's most likely to happen in recursive function calls), -// but only one writer. We represent this by having mutex_ be -1 when -// writing and a number > 0 when reading (and 0 when no lock is held). -// -// In debug mode, we assert these invariants, while in non-debug mode -// we do nothing, for efficiency. That's why everything is in an -// assert. - -Mutex::Mutex() : mutex_(0) { } -Mutex::~Mutex() { assert(mutex_ == 0); } -void Mutex::Lock() { assert(--mutex_ == -1); } -void Mutex::Unlock() { assert(mutex_++ == -1); } -#ifdef GMUTEX_TRYLOCK -bool Mutex::TryLock() { if (mutex_) return false; Lock(); return true; } -#endif -void Mutex::ReaderLock() { assert(++mutex_ > 0); } -void Mutex::ReaderUnlock() { assert(mutex_-- > 0); } - -#elif defined(_WIN32) || defined(__CYGWIN32__) || defined(__CYGWIN64__) - -Mutex::Mutex() { InitializeCriticalSection(&mutex_); SetIsSafe(); } -Mutex::~Mutex() { DeleteCriticalSection(&mutex_); } -void Mutex::Lock() { if (is_safe_) EnterCriticalSection(&mutex_); } -void Mutex::Unlock() { if (is_safe_) LeaveCriticalSection(&mutex_); } -#ifdef GMUTEX_TRYLOCK -bool Mutex::TryLock() { return is_safe_ ? - TryEnterCriticalSection(&mutex_) != 0 : true; } -#endif -void Mutex::ReaderLock() { Lock(); } // we don't have read-write locks -void Mutex::ReaderUnlock() { Unlock(); } - -#elif defined(HAVE_PTHREAD) && defined(HAVE_RWLOCK) - -#define SAFE_PTHREAD(fncall) do { /* run fncall if is_safe_ is true */ \ - if (is_safe_ && fncall(&mutex_) != 0) abort(); \ -} while (0) - -Mutex::Mutex() { - SetIsSafe(); - if (is_safe_ && pthread_rwlock_init(&mutex_, NULL) != 0) abort(); -} -Mutex::~Mutex() { SAFE_PTHREAD(pthread_rwlock_destroy); } -void Mutex::Lock() { SAFE_PTHREAD(pthread_rwlock_wrlock); } -void Mutex::Unlock() { SAFE_PTHREAD(pthread_rwlock_unlock); } -#ifdef GMUTEX_TRYLOCK -bool Mutex::TryLock() { return is_safe_ ? - pthread_rwlock_trywrlock(&mutex_) == 0 : - true; } -#endif -void Mutex::ReaderLock() { SAFE_PTHREAD(pthread_rwlock_rdlock); } -void Mutex::ReaderUnlock() { SAFE_PTHREAD(pthread_rwlock_unlock); } -#undef SAFE_PTHREAD - -#elif defined(HAVE_PTHREAD) - -#define SAFE_PTHREAD(fncall) do { /* run fncall if is_safe_ is true */ \ - if (is_safe_ && fncall(&mutex_) != 0) abort(); \ -} while (0) - -Mutex::Mutex() { - SetIsSafe(); - if (is_safe_ && pthread_mutex_init(&mutex_, NULL) != 0) abort(); -} -Mutex::~Mutex() { SAFE_PTHREAD(pthread_mutex_destroy); } -void Mutex::Lock() { SAFE_PTHREAD(pthread_mutex_lock); } -void Mutex::Unlock() { SAFE_PTHREAD(pthread_mutex_unlock); } -#ifdef GMUTEX_TRYLOCK -bool Mutex::TryLock() { return is_safe_ ? - pthread_mutex_trylock(&mutex_) == 0 : true; } -#endif -void Mutex::ReaderLock() { Lock(); } -void Mutex::ReaderUnlock() { Unlock(); } -#undef SAFE_PTHREAD - -#endif - -// -------------------------------------------------------------------------- -// Some helper classes - -// MutexLock(mu) acquires mu when constructed and releases it when destroyed. -class MutexLock { - public: - explicit MutexLock(Mutex *mu) : mu_(mu) { mu_->Lock(); } - ~MutexLock() { mu_->Unlock(); } - private: - Mutex * const mu_; - // Disallow "evil" constructors - MutexLock(const MutexLock&); - void operator=(const MutexLock&); -}; - -// ReaderMutexLock and WriterMutexLock do the same, for rwlocks -class ReaderMutexLock { - public: - explicit ReaderMutexLock(Mutex *mu) : mu_(mu) { mu_->ReaderLock(); } - ~ReaderMutexLock() { mu_->ReaderUnlock(); } - private: - Mutex * const mu_; - // Disallow "evil" constructors - ReaderMutexLock(const ReaderMutexLock&); - void operator=(const ReaderMutexLock&); -}; - -class WriterMutexLock { - public: - explicit WriterMutexLock(Mutex *mu) : mu_(mu) { mu_->WriterLock(); } - ~WriterMutexLock() { mu_->WriterUnlock(); } - private: - Mutex * const mu_; - // Disallow "evil" constructors - WriterMutexLock(const WriterMutexLock&); - void operator=(const WriterMutexLock&); -}; - -// Catch bug where variable name is omitted, e.g. MutexLock (&mu); -#define MutexLock(x) COMPILE_ASSERT(0, mutex_lock_decl_missing_var_name) -#define ReaderMutexLock(x) COMPILE_ASSERT(0, rmutex_lock_decl_missing_var_name) -#define WriterMutexLock(x) COMPILE_ASSERT(0, wmutex_lock_decl_missing_var_name) - -} // namespace MUTEX_NAMESPACE - -using namespace MUTEX_NAMESPACE; - -#undef MUTEX_NAMESPACE - -#endif /* #define GOOGLE_MUTEX_H__ */ diff --git a/aegisub/libaegisub/include/libaegisub/progress.h b/aegisub/libaegisub/include/libaegisub/progress.h deleted file mode 100644 index 9402b4728..000000000 --- a/aegisub/libaegisub/include/libaegisub/progress.h +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (c) 2011, Niels Martin Hansen -// -// Permission to use, copy, modify, and distribute this software for any -// purpose with or without fee is hereby granted, provided that the above -// copyright notice and this permission notice appear in all copies. -// -// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -// -// $Id$ - -/// @file progress.h -/// @brief Progress bars. -/// @ingroup libaegisub - -#ifndef LAG_PRE -#include -#endif - -namespace agi { - -class ProgressSink; - -class ProgressSinkFactory { -public: - virtual ~ProgressSinkFactory() { } - virtual ProgressSink * create_progress_sink(const std::string &title) const = 0; -}; - - -class ProgressSink { -public: - virtual ~ProgressSink() { } - virtual void set_progress(int steps, int max) = 0; - virtual void set_operation(const std::string &operation) = 0; - virtual bool get_cancelled() const = 0; -}; - - -class NullProgressSinkFactory : public ProgressSinkFactory { -public: - virtual ProgressSink * create_progress_sink(const std::string &title) const; -}; - - -class StdioProgressSinkFactory : public ProgressSinkFactory { -private: - -public: - StdioProgressSinkFactory(); - virtual ProgressSink * create_progress_sink(const std::string &title) const; -}; - -} // namespace agi diff --git a/aegisub/libmedia/Makefile b/aegisub/libmedia/Makefile deleted file mode 100644 index 7e6097340..000000000 --- a/aegisub/libmedia/Makefile +++ /dev/null @@ -1,46 +0,0 @@ -# $Id$ -include ../Makefile.inc - - -LIB_SHARED = libmedia_aegisub-3.0.so -LIB_SHARED_INSTALL = yes -LIB_VERSION = 3 - -CXXFLAGS = -Iinclude -I../libaegisub/include -I../src -I.. -DMAGI -fPIC -Wno-variadic-macros - -PRECOMPILED_HEADER_NAME = magi_pre.h -magi_pre.h.gch: CXXFLAGS := $(CXXFLAGS) - -####################### -# AUDIO / VIDEO SUPPORT -####################### -ifeq (yes, $(HAVE_PROVIDER_FFMPEGSOURCE)) -SRC_OPT += audio/ffms_audio.cpp common/ffms_common.cpp video/ffms_video.cpp -common/ffms_common.o: CXXFLAGS += $(CFLAGS_FFMPEGSOURCE) $(CFLAGS_LIBAVFORMAT) $(CFLAGS_LIBAVCODEC) $(CFLAGS_LIBSWSCALE) $(CFLAGS_LIBAVUTIL) $(CFLAGS_LIBPOSTPROC) -audio/ffms_audio.o: CXXFLAGS += $(CFLAGS_FFMPEGSOURCE) $(CFLAGS_LIBAVFORMAT) $(CFLAGS_LIBAVCODEC) $(CFLAGS_LIBSWSCALE) $(CFLAGS_LIBAVUTIL) $(CFLAGS_LIBPOSTPROC) -video/ffms_video.o: CXXFLAGS += $(CFLAGS_FFMPEGSOURCE) $(CFLAGS_LIBAVFORMAT) $(CFLAGS_LIBAVCODEC) $(CFLAGS_LIBSWSCALE) $(CFLAGS_LIBAVUTIL) $(CFLAGS_LIBPOSTPROC) -LDFLAGS_POST += $(LDFLAGS_FFMPEGSOURCE) -endif - - -SRC = \ - audio/downmix.cpp \ - audio/convert.cpp \ - audio/dummy_audio.cpp \ - audio/pcm.cpp \ - cache/audio_ram.cpp \ - cache/audio_hd.cpp \ - cache/video_cache.cpp \ - common/audio_manager.cpp \ - common/video_frame.cpp \ - common/video_manager.cpp \ - video/yuv4mpeg.cpp \ - $(SRC_OPT) - -HEADERS = \ - */*.h \ - include/libmedia/*.h \ - - -include ../Makefile.target --include */*.d diff --git a/aegisub/libmedia/audio/avs_audio.cpp b/aegisub/libmedia/audio/avs_audio.cpp deleted file mode 100644 index 035a420dc..000000000 --- a/aegisub/libmedia/audio/avs_audio.cpp +++ /dev/null @@ -1,174 +0,0 @@ -// Copyright (c) 2005-2006, Rodrigo Braz Monteiro, Fredrik Mellbin -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * 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. -// * Neither the name of the Aegisub Group nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. -// -// Aegisub Project http://www.aegisub.org/ -// -// $Id$ - -/// @file audio_provider_avs.cpp -/// @brief Avisynth-based audio provider -/// @ingroup audio_input -/// - -#include "config.h" - -#ifdef WITH_AVISYNTH - -#ifndef AGI_PRE -#include -#include - -#include -#endif - -#include "audio_provider_avs.h" -#include "charset_conv.h" -#include "compat.h" -#include "main.h" -#include "standard_paths.h" -#include "utils.h" - -namespace media { - -/// @brief Constructor -/// @param _filename -/// -AvisynthAudioProvider::AvisynthAudioProvider(wxString filename) try : filename(filename) { - AVSValue script; - wxMutexLocker lock(AviSynthMutex); - - wxFileName fn(filename); - if (!fn.FileExists()) - throw agi::FileNotFoundError(STD_STR(filename)); - - // Include - if (filename.EndsWith(_T(".avs"))) { - char *fname = env->SaveString(fn.GetShortPath().mb_str(csConvLocal)); - script = env->Invoke("Import", fname); - } - - // Use DirectShowSource - else { - const char * argnames[3] = { 0, "video", "audio" }; - AVSValue args[3] = { env->SaveString(fn.GetShortPath().mb_str(csConvLocal)), false, true }; - - // Load DirectShowSource.dll from app dir if it exists - wxFileName dsspath(StandardPaths::DecodePath(_T("?data/DirectShowSource.dll"))); - if (dsspath.FileExists()) { - env->Invoke("LoadPlugin",env->SaveString(dsspath.GetShortPath().mb_str(csConvLocal))); - } - - // Load audio with DSS if it exists - if (env->FunctionExists("DirectShowSource")) { - script = env->Invoke("DirectShowSource", AVSValue(args,3),argnames); - } - // Otherwise fail - else { - throw AudioOpenError("No suitable audio source filter found. Try placing DirectShowSource.dll in the Aegisub application directory."); - } - } - - LoadFromClip(script); -} -catch (AvisynthError &err) { - throw AudioOpenError("Avisynth error: " + std::string(err.msg)); -} - -/// @brief Read from environment -/// @param _clip -/// -void AvisynthAudioProvider::LoadFromClip(AVSValue _clip) { - AVSValue script; - - // Check if it has audio - VideoInfo vi = _clip.AsClip()->GetVideoInfo(); - if (!vi.HasAudio()) throw AudioOpenError("No audio found."); - - // Convert to one channel - char buffer[1024]; - strcpy(buffer,lagi_wxString(OPT_GET("Audio/Downmixer")->GetString()).mb_str(csConvLocal)); - script = env->Invoke(buffer, _clip); - - // Convert to 16 bits per sample - script = env->Invoke("ConvertAudioTo16bit", script); - vi = script.AsClip()->GetVideoInfo(); - - // Convert sample rate - int setsample = OPT_GET("Provider/Audio/AVS/Sample Rate")->GetInt(); - if (vi.SamplesPerSecond() < 32000) setsample = 44100; - if (setsample != 0) { - AVSValue args[2] = { script, setsample }; - script = env->Invoke("ResampleAudio", AVSValue(args,2)); - } - - // Set clip - PClip tempclip = script.AsClip(); - vi = tempclip->GetVideoInfo(); - - // Read properties - channels = vi.AudioChannels(); - num_samples = vi.num_audio_samples; - sample_rate = vi.SamplesPerSecond(); - bytes_per_sample = vi.BytesPerAudioSample(); - - clip = tempclip; -} - -/// @brief Get audio -/// @param buf -/// @param start -/// @param count -/// -void AvisynthAudioProvider::GetAudio(void *buf, int64_t start, int64_t count) const { - // Requested beyond the length of audio - if (start+count > num_samples) { - int64_t oldcount = count; - count = num_samples-start; - if (count < 0) count = 0; - - // Fill beyond with zero - if (bytes_per_sample == 1) { - char *temp = (char *) buf; - for (int i=count;iGetAudio(buf,start,count,env); - } -} -#endif - -} // namespace diff --git a/aegisub/libmedia/audio/avs_audio.h b/aegisub/libmedia/audio/avs_audio.h deleted file mode 100644 index 9c7fb0d51..000000000 --- a/aegisub/libmedia/audio/avs_audio.h +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright (c) 2005-2006, Rodrigo Braz Monteiro, Fredrik Mellbin -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * 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. -// * Neither the name of the Aegisub Group nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. -// -// Aegisub Project http://www.aegisub.org/ -// -// $Id$ - -/// @file audio_provider_avs.h -/// @see audio_provider_avs.cpp -/// @ingroup audio_input -/// - -#ifdef WITH_AVISYNTH -#include "include/aegisub/audio_provider.h" -#include "avisynth_wrap.h" - - -namespace media { - -/// DOCME -/// @class AvisynthAudioProvider -/// @brief DOCME -/// -/// DOCME -class AvisynthAudioProvider : public AudioProvider, public AviSynthWrapper { - /// DOCME - wxString filename; - - /// DOCME - PClip clip; - - void LoadFromClip(AVSValue clip); - void SetFile(); - -public: - AvisynthAudioProvider(wxString _filename); - - wxString GetFilename() const { return filename; } - - bool AreSamplesNativeEndian() const { return true; } - bool NeedsCache() const { return true; } - - void GetAudio(void *buf, int64_t start, int64_t count) const; - void GetWaveForm(int *min,int *peak,int64_t start,int w,int h,int samples,float scale); -}; -#endif - -} // namespace - diff --git a/aegisub/libmedia/audio/convert.cpp b/aegisub/libmedia/audio/convert.cpp deleted file mode 100644 index 435921449..000000000 --- a/aegisub/libmedia/audio/convert.cpp +++ /dev/null @@ -1,225 +0,0 @@ -// Copyright (c) 2008, Rodrigo Braz Monteiro -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * 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. -// * Neither the name of the Aegisub Group nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. -// -// Aegisub Project http://www.aegisub.org/ -// -// $Id$ - -/// @file audio_provider_convert.cpp -/// @brief Intermediate sample format-converting audio provider -/// @ingroup audio_input -/// - -#include "config.h" - -#include "aegisub_endian.h" -#include "convert.h" -#include "downmix.h" - - -namespace media { - -/// @brief Constructor -/// @param src -/// -ConvertAudioProvider::ConvertAudioProvider(AudioProvider *src) : source(src) { - channels = source->GetChannels(); - num_samples = source->GetNumSamples(); - sample_rate = source->GetSampleRate(); - bytes_per_sample = 2; - - sampleMult = 1; - if (sample_rate < 16000) sampleMult = 4; - else if (sample_rate < 32000) sampleMult = 2; - sample_rate *= sampleMult; - num_samples *= sampleMult; -} - -/// @brief Convert to 16-bit -/// @param src -/// @param dst -/// @param count -/// -void ConvertAudioProvider::Make16Bit(const char *src, short *dst, int64_t count) const { - for (int64_t i=0;i - -/// @brief DOCME -/// @param src -/// @param dst -/// @param count -/// @param converter -/// -void ConvertAudioProvider::ChangeSampleRate(const short *src, short *dst, int64_t count, const SampleConverter &converter) const { - // Upsample by 2 - if (sampleMult == 2) { - int64_t size = count/2; - short cur; - short next = 0; - for (int64_t i=0;i 0) { - *dst++ = converter(*src++); - } - } -} - -/// DOCME -struct NullSampleConverter { - inline short operator()(const short val) const { - return val; - } -}; - -/// DOCME -struct EndianSwapSampleConverter { - inline short operator()(const short val) const { - return (short)Endian::Reverse((uint16_t)val); - }; -}; - - -/// @brief Get audio -/// @param destination -/// @param start -/// @param count -/// -void ConvertAudioProvider::GetAudio(void *destination, int64_t start, int64_t count) const { - // Bits per sample - int srcBps = source->GetBytesPerSample(); - - // Nothing to do - if (sampleMult == 1 && srcBps == 2) { - source->GetAudio(destination,start,count); - } - - // Convert - else { - // Allocate buffers with sufficient size for the entire operation - size_t fullSize = count; - int64_t srcCount = count / sampleMult; - short *buffer1 = NULL; - short *buffer2 = NULL; - short *last = NULL; - - // Read audio - buffer1 = new short[fullSize * channels]; - source->GetAudio(buffer1,start/sampleMult,srcCount); - - // Convert from 8-bit to 16-bit - if (srcBps == 1) { - if (sampleMult == 1) { - Make16Bit((const char*)buffer1,(short*)destination,srcCount * channels); - } - else { - buffer2 = new short[fullSize * channels]; - Make16Bit((const char*)buffer1,buffer2,srcCount * channels); - last = buffer2; - } - } - - // Already 16-bit - else if (srcBps == 2) last = buffer1; - - // Convert sample rate - if (sampleMult != 1 && source->AreSamplesNativeEndian()) { - ChangeSampleRate(last,(short*)destination,count * channels, NullSampleConverter()); - } - else if (!source->AreSamplesNativeEndian()) { - ChangeSampleRate(last,(short*)destination,count * channels, EndianSwapSampleConverter()); - } - - delete [] buffer1; - delete [] buffer2; - } -} - - -/// @brief See if we need to downmix the number of channels -/// @param source_provider -/// -AudioProvider *CreateConvertAudioProvider(AudioProvider *source_provider) { - AudioProvider *provider = source_provider; - - // Aegisub requires 16 bit samples, - // some audio players break with low samplerates, - // everything breaks with wrong-ended samples. - if (provider->GetBytesPerSample() != 2 || - provider->GetSampleRate() < 32000 || - !provider->AreSamplesNativeEndian()) - { - // @todo add support for more bitdepths (i.e. 24- and 32-bit audio) - if (provider->GetBytesPerSample() > 2) - throw AudioOpenError("Audio format converter: audio with bitdepths greater than 16 bits/sample is currently unsupported"); - - provider = new ConvertAudioProvider(provider); - } - - // We also require mono audio for historical reasons - if (provider->GetChannels() != 1) - { - provider = new DownmixingAudioProvider(provider); - } - - return provider; -} - -} // namespace - diff --git a/aegisub/libmedia/audio/convert.h b/aegisub/libmedia/audio/convert.h deleted file mode 100644 index d66c6d9c8..000000000 --- a/aegisub/libmedia/audio/convert.h +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright (c) 2008, Rodrigo Braz Monteiro -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * 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. -// * Neither the name of the Aegisub Group nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. -// -// Aegisub Project http://www.aegisub.org/ -// -// $Id$ - -/// @file audio_provider_convert.h -/// @see audio_provider_convert.cpp -/// @ingroup audio_input -/// - -#include "libmedia/audio.h" - -#ifndef AGI_PRE -#include -#endif - -namespace media { - -/// DOCME -/// @class ConvertAudioProvider -/// @brief DOCME -/// -/// DOCME -class ConvertAudioProvider : public AudioProvider { - /// DOCME - int sampleMult; - - /// DOCME - std::tr1::shared_ptr source; - void Make16Bit(const char *src, short *dst, int64_t count) const; - template - void ChangeSampleRate(const short *src, short *dst, int64_t count, const SampleConverter &converter) const; - -public: - ConvertAudioProvider(AudioProvider *source); - - /// By its nature, the ConvertAudioProvider always delivers machine endian. - /// That's one of the points of it! - bool AreSamplesNativeEndian() const { return true; } - - void GetAudio(void *buf, int64_t start, int64_t count) const; - - std::string GetFilename() const { return source->GetFilename(); } -}; - -AudioProvider *CreateConvertAudioProvider(AudioProvider *source_provider); - -} // namespace - diff --git a/aegisub/libmedia/audio/downmix.cpp b/aegisub/libmedia/audio/downmix.cpp deleted file mode 100644 index 9c2ac6614..000000000 --- a/aegisub/libmedia/audio/downmix.cpp +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright (c) 2007-2008, Niels Martin Hansen -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * 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. -// * Neither the name of the Aegisub Group nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. -// -// Aegisub Project http://www.aegisub.org/ -// -// $Id$ - -/// @file audio_provider_downmix.cpp -/// @brief Intermediate audio provider downmixing the signal to mono -/// @ingroup audio_input -/// - - -////////////////// -// Headers -#include "config.h" - -#include "downmix.h" - - -namespace media { - -/// @brief Constructor -/// @param source -/// -DownmixingAudioProvider::DownmixingAudioProvider(AudioProvider *source) : provider(source) { - filename = source->GetFilename(); - channels = 1; // target - src_channels = source->GetChannels(); - num_samples = source->GetNumSamples(); - bytes_per_sample = source->GetBytesPerSample(); - sample_rate = source->GetSampleRate(); - - if (!(bytes_per_sample == 1 || bytes_per_sample == 2)) - throw AudioOpenError("Downmixing Audio Provider: Can only downmix 8 and 16 bit audio"); - if (!source->AreSamplesNativeEndian()) - throw AudioOpenError("Downmixing Audio Provider: Source must have machine endian samples"); -} - -/// @brief Actual work happens here -/// @param buf -/// @param start -/// @param count -/// -void DownmixingAudioProvider::GetAudio(void *buf, int64_t start, int64_t count) const { - if (count == 0) return; - - // We can do this ourselves - if (start >= num_samples) { - if (bytes_per_sample == 1) - // 8 bit formats are usually unsigned with bias 127 - memset(buf, 127, count); - else - // While everything else is signed - memset(buf, 0, count*bytes_per_sample); - - return; - } - - // So alloc some temporary memory for this - // Depending on use, this might be made faster by using - // a pre-allocced block of memory...? - char *tmp = new char[count*bytes_per_sample*src_channels]; - - try { - provider->GetAudio(tmp, start, count); - } - catch (...) { - delete tmp; - throw; - } - - // Now downmix - // Just average the samples over the channels (really bad if they're out of phase!) - // XXX: Assuming here that sample data are in machine endian, an upstream provider should ensure that - if (bytes_per_sample == 1) { - uint8_t *src = (uint8_t *)tmp; - uint8_t *dst = (uint8_t *)buf; - - while (count > 0) { - int sum = 0; - for (int c = 0; c < src_channels; c++) - sum += *(src++); - *(dst++) = (uint8_t)(sum / src_channels); - count--; - } - } - else if (bytes_per_sample == 2) { - int16_t *src = (int16_t *)tmp; - int16_t *dst = (int16_t *)buf; - - while (count > 0) { - int sum = 0; - for (int c = 0; c < src_channels; c++) - sum += *(src++); - *(dst++) = (int16_t)(sum / src_channels); - count--; - } - } - - // Done downmixing, free the work buffer - delete[] tmp; -} - -} // namespace - diff --git a/aegisub/libmedia/audio/downmix.h b/aegisub/libmedia/audio/downmix.h deleted file mode 100644 index 88fe3d6a7..000000000 --- a/aegisub/libmedia/audio/downmix.h +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) 2007-2008, Niels Martin Hansen -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * 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. -// * Neither the name of the Aegisub Group nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. -// -// Aegisub Project http://www.aegisub.org/ -// -// $Id$ - -/// @file audio_provider_downmix.h -/// @see audio_provider_downmix.cpp -/// @ingroup audio_input -/// - -#include "libmedia/audio.h" - -#ifndef AGI_PRE -#include -#endif - -namespace media { - -/// DOCME -/// @class DownmixingAudioProvider -/// @brief DOCME -/// -/// DOCME -class DownmixingAudioProvider : public AudioProvider { - std::tr1::shared_ptr provider; - - /// DOCME - int src_channels; -public: - DownmixingAudioProvider(AudioProvider *source); - - /// @brief Downmixing requires samples to be native endian beforehand - /// - bool AreSamplesNativeEndian() const { return true; } - - void GetAudio(void *buf, int64_t start, int64_t count) const; -}; - -} // namespace - diff --git a/aegisub/libmedia/audio/dummy_audio.cpp b/aegisub/libmedia/audio/dummy_audio.cpp deleted file mode 100644 index 501b6c20b..000000000 --- a/aegisub/libmedia/audio/dummy_audio.cpp +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright (c) 2005-2006, Rodrigo Braz Monteiro, Fredrik Mellbin -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * 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. -// * Neither the name of the Aegisub Group nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. -// -// Aegisub Project http://www.aegisub.org/ -// -// $Id$ - -/// @file audio_provider_dummy.cpp -/// @brief Dummy (silence or noise) audio provider -/// @ingroup audio_input -/// - -#include "config.h" - -#include "dummy_audio.h" - - -namespace media { - -/// @brief Constructor -/// @param dur_ms -/// @param _noise -/// -DummyAudioProvider::DummyAudioProvider(unsigned long dur_ms, bool _noise) { - noise = _noise; - channels = 1; - sample_rate = 44100; - bytes_per_sample = 2; - num_samples = (int64_t)dur_ms * sample_rate / 1000; -} - -/// @brief Destructor -/// -DummyAudioProvider::~DummyAudioProvider() { -} - -/// @brief Get audio -/// @param buf -/// @param start -/// @param count -/// -void DummyAudioProvider::GetAudio(void *buf, int64_t start, int64_t count) const { - short *workbuf = (short*)buf; - - if (noise) { - while (--count > 0) - *workbuf++ = (rand() - RAND_MAX/2) * 10000 / RAND_MAX; - } - else { - while (--count > 0) - *workbuf++ = 0; - } -} - -} // namespace - diff --git a/aegisub/libmedia/audio/dummy_audio.h b/aegisub/libmedia/audio/dummy_audio.h deleted file mode 100644 index 0f40d8ed5..000000000 --- a/aegisub/libmedia/audio/dummy_audio.h +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (c) 2006, Niels Martin Hansen -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * 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. -// * Neither the name of the Aegisub Group nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. -// -// Aegisub Project http://www.aegisub.org/ -// -// $Id$ - -/// @file audio_provider_dummy.h -/// @see audio_provider_dummy.cpp -/// @ingroup audio_input -/// - -#include "libmedia/audio.h" - -namespace media { - -/// DOCME -/// @class DummyAudioProvider -/// @brief DOCME -/// -/// DOCME -class DummyAudioProvider : public AudioProvider { - /// DOCME - bool noise; - -public: - DummyAudioProvider(unsigned long dur_ms, bool _noise); - ~DummyAudioProvider(); - - bool AreSamplesNativeEndian() const { return true; } - void GetAudio(void *buf, int64_t start, int64_t count) const; -}; - -} // namespace - diff --git a/aegisub/libmedia/audio/ffms_audio.cpp b/aegisub/libmedia/audio/ffms_audio.cpp deleted file mode 100644 index c1eb0e7f7..000000000 --- a/aegisub/libmedia/audio/ffms_audio.cpp +++ /dev/null @@ -1,225 +0,0 @@ -// Copyright (c) 2008-2009, Karl Blomster -// -// Permission to use, copy, modify, and distribute this software for any -// purpose with or without fee is hereby granted, provided that the above -// copyright notice and this permission notice appear in all copies. -// -// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -// -// $Id$ - -/// @file ffms_audio.cpp -/// @brief FFmpegSource Audio support. -/// @ingroup fmms audio - - -#include "config.h" - -#ifndef AGI_PRE -#endif - -#include "ffms_audio.h" -#include "libmedia/audio.h" - - -namespace media { - namespace ffms { - - -/// @brief Constructor -/// @param filename -/// -FFmpegSourceAudioProvider::FFmpegSourceAudioProvider(std::string filename) -: AudioSource(NULL) -, COMInited(false) -{ -#ifdef WIN32 - HRESULT res; - res = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); - if (SUCCEEDED(res)) - COMInited = true; - else if (res != RPC_E_CHANGED_MODE) - throw AudioOpenError("COM initialization failure"); -#endif - // initialize ffmpegsource - // FIXME: CPU detection? -#if FFMS_VERSION >= ((2 << 24) | (14 << 16) | (0 << 8) | 0) - FFMS_Init(0, 1); -#else - FFMS_Init(0); -#endif - - ErrInfo.Buffer = FFMSErrMsg; - ErrInfo.BufferSize = sizeof(FFMSErrMsg); - ErrInfo.ErrorType = FFMS_ERROR_SUCCESS; - ErrInfo.SubType = FFMS_ERROR_SUCCESS; -// SetLogLevel(); - - try { - LoadAudio(filename); - } catch (...) { - Close(); - throw; - } -} - -/// @brief Load audio file -/// @param filename -/// -void FFmpegSourceAudioProvider::LoadAudio(std::string filename) { -// wxString FileNameShort = wxFileName(filename).GetShortPath(); - - FFMS_Indexer *Indexer = FFMS_CreateIndexer(filename.c_str(), &ErrInfo); - if (Indexer == NULL) { - throw agi::FileNotFoundError(ErrInfo.Buffer); - } - - std::map TrackList = GetTracksOfType(Indexer, FFMS_TYPE_AUDIO); - if (TrackList.size() <= 0) - throw AudioOpenError("no audio tracks found"); - - // initialize the track number to an invalid value so we can detect later on - // whether the user actually had to choose a track or not - int TrackNumber = -1; - if (TrackList.size() > 1) { - TrackNumber = AskForTrackSelection(TrackList, FFMS_TYPE_AUDIO); - // if it's still -1 here, user pressed cancel - if (TrackNumber == -1) - throw agi::UserCancelException("audio loading cancelled by user"); - } - - // generate a name for the cache file - std::string CacheName = GetCacheFilename(filename); - - // try to read index - FFMS_Index *Index = NULL; - Index = FFMS_ReadIndex(CacheName.c_str(), &ErrInfo); - bool IndexIsValid = false; - if (Index != NULL) { - if (FFMS_IndexBelongsToFile(Index, filename.c_str(), &ErrInfo)) { - FFMS_DestroyIndex(Index); - Index = NULL; - } - else - IndexIsValid = true; - } - - // index valid but track number still not set? - if (IndexIsValid) { - // track number not set? just grab the first track - if (TrackNumber < 0) - TrackNumber = FFMS_GetFirstTrackOfType(Index, FFMS_TYPE_AUDIO, &ErrInfo); - if (TrackNumber < 0) { - FFMS_DestroyIndex(Index); - Index = NULL; - throw AudioOpenError(std::string("Couldn't find any audio tracks: ") + ErrInfo.Buffer); - } - - // index is valid and track number is now set, - // but do we have indexing info for the desired audio track? - FFMS_Track *TempTrackData = FFMS_GetTrackFromIndex(Index, TrackNumber); - if (FFMS_GetNumFrames(TempTrackData) <= 0) { - IndexIsValid = false; - FFMS_DestroyIndex(Index); - Index = NULL; - } - } - // no valid index exists and the file only has one audio track, index it - else if (TrackNumber < 0) - TrackNumber = FFMS_TRACKMASK_ALL; - // else: do nothing (keep track mask as it is) - - // moment of truth - if (!IndexIsValid) { - int TrackMask; -// if (OPT_GET("Provider/FFmpegSource/Index All Tracks")->GetBool() || TrackNumber == FFMS_TRACKMASK_ALL) - if (TrackNumber == FFMS_TRACKMASK_ALL) - TrackMask = FFMS_TRACKMASK_ALL; - else - TrackMask = (1 << TrackNumber); - - try { - Index = DoIndexing(Indexer, CacheName, TrackMask, GetErrorHandlingMode()); - } - catch (std::string const& err) { - throw AudioOpenError(err); - } - - // if tracknumber still isn't set we need to set it now - if (TrackNumber == FFMS_TRACKMASK_ALL) - TrackNumber = FFMS_GetFirstTrackOfType(Index, FFMS_TYPE_AUDIO, &ErrInfo); - } - - // update access time of index file so it won't get cleaned away -///XXX: Add something to libaegisub to support this. -// if (!wxFileName(CacheName).Touch()) { - // warn user? -// } - -#if FFMS_VERSION >= ((2 << 24) | (14 << 16) | (1 << 8) | 0) - AudioSource = FFMS_CreateAudioSource(filename.c_str(), TrackNumber, Index, -1, &ErrInfo); -#else - AudioSource = FFMS_CreateAudioSource(filename.c_str(), TrackNumber, Index, &ErrInfo); -#endif - FFMS_DestroyIndex(Index); - Index = NULL; - if (!AudioSource) { - throw AudioOpenError(std::string("Failed to open audio track: %s") + ErrInfo.Buffer); - } - - const FFMS_AudioProperties AudioInfo = *FFMS_GetAudioProperties(AudioSource); - - channels = AudioInfo.Channels; - sample_rate = AudioInfo.SampleRate; - num_samples = AudioInfo.NumSamples; - if (channels <= 0 || sample_rate <= 0 || num_samples <= 0) - throw AudioOpenError("sanity check failed, consult your local psychiatrist"); - - // FIXME: use the actual sample format too? - // why not just bits_per_sample/8? maybe there's some oddball format with half bytes out there somewhere... - switch (AudioInfo.BitsPerSample) { - case 8: bytes_per_sample = 1; break; - case 16: bytes_per_sample = 2; break; - case 24: bytes_per_sample = 3; break; - case 32: bytes_per_sample = 4; break; - default: - throw AudioOpenError("unknown or unsupported sample format"); - } -} - -/// @brief Destructor -/// -FFmpegSourceAudioProvider::~FFmpegSourceAudioProvider() { - Close(); -} - -/// @brief Clean up -/// -void FFmpegSourceAudioProvider::Close() { - if (AudioSource) FFMS_DestroyAudioSource(AudioSource); -#ifdef WIN32 - if (COMInited) - CoUninitialize(); -#endif -} - -/// @brief Get audio -/// @param Buf -/// @param Start -/// @param Count -/// -void FFmpegSourceAudioProvider::GetAudio(void *Buf, int64_t Start, int64_t Count) const { - if (FFMS_GetAudio(AudioSource, Buf, Start, Count, &ErrInfo)) { - throw AudioDecodeError(std::string("Failed to get audio samples: ") + ErrInfo.Buffer); - } -} - } // namespace ffms -} // namespace media - - diff --git a/aegisub/libmedia/audio/ffms_audio.h b/aegisub/libmedia/audio/ffms_audio.h deleted file mode 100644 index fa34d29ea..000000000 --- a/aegisub/libmedia/audio/ffms_audio.h +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (c) 2008-2009, Karl Blomster -// -// Permission to use, copy, modify, and distribute this software for any -// purpose with or without fee is hereby granted, provided that the above -// copyright notice and this permission notice appear in all copies. -// -// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -// -// $Id$ - -/// @file ffms_audio.h -/// @brief FFmpegSource Audio support. -/// @ingroup fmms audio - -#include "../../libffms/include/ffms.h" -#include - -#ifndef AGI_PRE -#ifdef WIN32 -#include -#endif - -#include -#endif - -#include "../common/ffms_common.h" -namespace media { - namespace ffms { - -/// @class Audio -/// Audio file support. -class FFmpegSourceAudioProvider : public AudioProvider, FFmpegSourceProvider { - FFMS_AudioSource *AudioSource; ///< audio source object - bool COMInited; ///< COM initialization state - - mutable char FFMSErrMsg[1024]; ///< FFMS error message - mutable FFMS_ErrorInfo ErrInfo; ///< FFMS error codes/messages - - void Close(); - void LoadAudio(std::string filename); - -public: - FFmpegSourceAudioProvider(std::string filename); - virtual ~FFmpegSourceAudioProvider(); - - /// @brief Checks sample endianness - /// @return Returns true. - /// FFMS always delivers native endian samples. - bool AreSamplesNativeEndian() const { return true; } - bool NeedsCache() const { return true; } - - virtual void GetAudio(void *buf, int64_t start, int64_t count) const; - -}; - - } // namespace ffms -} // namespace media diff --git a/aegisub/libmedia/audio/pcm.cpp b/aegisub/libmedia/audio/pcm.cpp deleted file mode 100644 index c0637ec58..000000000 --- a/aegisub/libmedia/audio/pcm.cpp +++ /dev/null @@ -1,633 +0,0 @@ -// Copyright (c) 2007-2008, Niels Martin Hansen -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * 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. -// * Neither the name of the Aegisub Group nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. -// -// Aegisub Project http://www.aegisub.org/ -// -// $Id$ - -/// @file audio_provider_pcm.cpp -/// @brief PCM WAV and WAV64 audio provider -/// @ingroup audio_input -/// - - -#include "config.h" - -#ifndef AGI_PRE -#include -#include -#ifndef __WINDOWS__ -#include -#include -#include -#endif - -#endif - -#include - -#include "aegisub_endian.h" -#include "pcm.h" -//#include "compat.h" -//#include "utils.h" - - -namespace media { - -/// @brief DOCME -/// @param filename -/// -PCMAudioProvider::PCMAudioProvider(const std::string &filename) -{ -#ifdef _WIN32 - file_handle = CreateFile( - filename.c_str(), - FILE_READ_DATA, - FILE_SHARE_READ|FILE_SHARE_WRITE, - 0, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL|FILE_FLAG_RANDOM_ACCESS, - 0); - - if (file_handle == INVALID_HANDLE_VALUE) { - throw agi::FileNotFoundError(STD_STR(filename)); - } - - LARGE_INTEGER li_file_size = {0}; - if (!GetFileSizeEx(file_handle, &li_file_size)) { - CloseHandle(file_handle); - throw AudioOpenError("Failed getting file size"); - } - file_size = li_file_size.QuadPart; - - file_mapping = CreateFileMapping( - file_handle, - 0, - PAGE_READONLY, - 0, 0, - 0); - - if (file_mapping == 0) { - CloseHandle(file_handle); - throw AudioOpenError("Failed creating file mapping"); - } - - current_mapping = 0; - -#else - - file_handle = open(filename.c_str(), O_RDONLY); - - if (file_handle == -1) { - throw agi::FileNotFoundError(filename); - } - - struct stat filestats; - memset(&filestats, 0, sizeof(filestats)); - if (fstat(file_handle, &filestats)) { - close(file_handle); - throw AudioOpenError("Could not stat file to get size"); - } - file_size = filestats.st_size; - - current_mapping = 0; -#endif -} - -/// @brief DOCME -/// -PCMAudioProvider::~PCMAudioProvider() -{ -#ifdef _WIN32 - if (current_mapping) { - UnmapViewOfFile(current_mapping); - } - - CloseHandle(file_mapping); - CloseHandle(file_handle); -#else - if (current_mapping) { - munmap(current_mapping, mapping_length); - } - - close(file_handle); -#endif -} - -/// @brief DOCME -/// @param range_start -/// @param range_length -/// @return -/// -char * PCMAudioProvider::EnsureRangeAccessible(int64_t range_start, int64_t range_length) const -{ - if (range_start + range_length > file_size) { - throw AudioDecodeError("Attempted to map beyond end of file"); - } - - // Check whether the requested range is already visible - if (!current_mapping || range_start < mapping_start || range_start+range_length > mapping_start+(int64_t)mapping_length) { - // It's not visible, change the current mapping - if (current_mapping) { -#ifdef _WIN32 - UnmapViewOfFile(current_mapping); -#else - munmap(current_mapping, mapping_length); -#endif - } - - // Align range start on a 1 MB boundary and go 16 MB back - mapping_start = (range_start & ~0xFFFFF) - 0x1000000; - if (mapping_start < 0) mapping_start = 0; - - if (sizeof(void*) > 4) - // Large address space, use a 2 GB mapping - mapping_length = 0x80000000; - else - // Small (32 bit) address space, use a 256 MB mapping - mapping_length = 0x10000000; - - // Make sure to always make a mapping at least as large as the requested range - if ((int64_t)mapping_length < range_length) { - if (range_length > (int64_t)(~(size_t)0)) - throw AudioDecodeError("Requested range larger than max size_t, cannot create view of file"); - mapping_length = range_length; - } - // But also make sure we don't try to make a mapping larger than the file - if (mapping_start + (int64_t)mapping_length > file_size) - mapping_length = (size_t)(file_size - mapping_start); - // We already checked that the requested range doesn't extend over the end of the file - // Hopefully this should ensure that small files are always mapped in their entirety - -#ifdef _WIN32 - LARGE_INTEGER mapping_start_li; - mapping_start_li.QuadPart = mapping_start; - current_mapping = MapViewOfFile( - file_mapping, // Mapping handle - FILE_MAP_READ, // Access type - mapping_start_li.HighPart, // Offset high-part - mapping_start_li.LowPart, // Offset low-part - mapping_length); // Length of view -#else - current_mapping = mmap(0, mapping_length, PROT_READ, MAP_PRIVATE, file_handle, mapping_start); -#endif - - if (!current_mapping) { - throw AudioDecodeError("Failed mapping a view of the file"); - } - } - - assert(current_mapping); - assert(range_start >= mapping_start); - - // Difference between actual current mapping start and requested range start - ptrdiff_t rel_ofs = (ptrdiff_t)(range_start - mapping_start); - - // Calculate a pointer into current mapping for the requested range - return ((char*)current_mapping) + rel_ofs; -} - -/// @brief DOCME -/// @param buf -/// @param start -/// @param count -/// -void PCMAudioProvider::GetAudio(void *buf, int64_t start, int64_t count) const -{ - // Read blocks from the file - size_t index = 0; - while (count > 0 && index < index_points.size()) { - // Check if this index contains the samples we're looking for - const IndexPoint &ip = index_points[index]; - if (ip.start_sample <= start && ip.start_sample+ip.num_samples > start) { - - // How many samples we can maximum take from this block - int64_t samples_can_do = ip.num_samples - start + ip.start_sample; - if (samples_can_do > count) samples_can_do = count; - - // Read as many samples we can - char *src = EnsureRangeAccessible( - ip.start_byte + (start - ip.start_sample) * bytes_per_sample * channels, - samples_can_do * bytes_per_sample * channels); - memcpy(buf, src, samples_can_do * bytes_per_sample * channels); - - // Update data - buf = (char*)buf + samples_can_do * bytes_per_sample * channels; - start += samples_can_do; - count -= samples_can_do; - } - index++; - } - - // If we exhausted all sample sections zerofill the rest - if (count > 0) { - if (bytes_per_sample == 1) - // 8 bit formats are usually unsigned with bias 127 - memset(buf, 127, count*channels); - else - // While everything else is signed - memset(buf, 0, count*bytes_per_sample*channels); - } -} - -/// DOCME -/// @class RiffWavPCMAudioProvider -/// @brief RIFF WAV PCM provider -/// -/// Overview of RIFF WAV: -class RiffWavPCMAudioProvider : public PCMAudioProvider { - /// DOCME - struct ChunkHeader { - /// Always "RIFF" - char type[4]; - /// File size minus sizeof(ChunkHeader) (i.e. 8) - uint32_t size; - }; - - /// DOCME - struct RIFFChunk { - - /// DOCME - ChunkHeader ch; - - /// Always "WAVE" - char format[4]; - }; - - /// DOCME - struct fmtChunk { - - /// compression format used - /// We support only PCM (0x1) - uint16_t compression; - - /// Number of channels - uint16_t channels; - - /// Samples per second - uint32_t samplerate; - - /// Bytes per second - /// can't always be trusted - uint32_t avg_bytes_sec; - - /// Bytes per sample - uint16_t block_align; - - /// Bits per sample that are actually used; rest should be ignored - uint16_t significant_bits_sample; - // Here was supposed to be some more fields but we don't need them - // and just skipping by the size of the struct wouldn't be safe - // either way, as the fields can depend on the compression. - }; - - - /// @brief DOCME - /// @param str1[] - /// @param str2[] - /// @return - /// - static bool CheckFourcc(const char str1[], const char str2[]) - { - assert(str1); - assert(str2); - return - (str1[0] == str2[0]) && - (str1[1] == str2[1]) && - (str1[2] == str2[2]) && - (str1[3] == str2[3]); - } - -public: - - /// @brief DOCME - /// @param _filename - /// - RiffWavPCMAudioProvider(const std::string &_filename) - : PCMAudioProvider(_filename) - { - filename = _filename; - - // Read header - void *filestart = EnsureRangeAccessible(0, sizeof(RIFFChunk)); - RIFFChunk &header = *(RIFFChunk*)filestart; - - // Check magic values - if (!CheckFourcc(header.ch.type, "RIFF")) - throw AudioOpenError("File is not a RIFF file"); - if (!CheckFourcc(header.format, "WAVE")) - throw AudioOpenError("File is not a RIFF WAV file"); - - // Count how much more data we can have in the entire file - // The first 4 bytes are already eaten by the header.format field - uint32_t data_left = Endian::LittleToMachine(header.ch.size) - 4; - // How far into the file we have processed. - // Must be incremented by the riff chunk size fields. - uint32_t filepos = sizeof(header); - - bool got_fmt_header = false; - - // Inherited from AudioProvider - num_samples = 0; - - // Continue reading chunks until out of data - while (data_left) { - ChunkHeader &ch = *(ChunkHeader*)EnsureRangeAccessible(filepos, sizeof(ChunkHeader)); - - // Update counters - data_left -= sizeof(ch); - filepos += sizeof(ch); - - if (CheckFourcc(ch.type, "fmt ")) { - if (got_fmt_header) throw AudioOpenError("Invalid file, multiple 'fmt ' chunks"); - got_fmt_header = true; - - fmtChunk &fmt = *(fmtChunk*)EnsureRangeAccessible(filepos, sizeof(fmtChunk)); - - if (Endian::LittleToMachine(fmt.compression) != 1) - throw AudioOpenError("Can't use file, not PCM encoding"); - - // Set stuff inherited from the AudioProvider class - sample_rate = Endian::LittleToMachine(fmt.samplerate); - channels = Endian::LittleToMachine(fmt.channels); - bytes_per_sample = (Endian::LittleToMachine(fmt.significant_bits_sample) + 7) / 8; // round up to nearest whole byte - } - - else if (CheckFourcc(ch.type, "data")) { - // This won't pick up 'data' chunks inside 'wavl' chunks - // since the 'wavl' chunks wrap those. - - if (!got_fmt_header) throw AudioOpenError("Found 'data' chunk before 'fmt ' chunk, file is invalid."); - - int64_t samples = Endian::LittleToMachine(ch.size) / bytes_per_sample; - int64_t frames = samples / channels; - - IndexPoint ip; - ip.start_sample = num_samples; - ip.num_samples = frames; - ip.start_byte = filepos; - index_points.push_back(ip); - - num_samples += frames; - } - - // Support wavl (wave list) chunks too? - - // Update counters - // Make sure they're word aligned - data_left -= (Endian::LittleToMachine(ch.size) + 1) & ~1; - filepos += (Endian::LittleToMachine(ch.size) + 1) & ~1; - } - } - - /// @brief DOCME - /// @return - /// - bool AreSamplesNativeEndian() const - { - // 8 bit samples don't consider endianness - if (bytes_per_sample < 2) return true; - // Otherwise test whether we're little endian - uint32_t testvalue = 0x008800ff; - return testvalue == Endian::LittleToMachine(testvalue); - } -}; - -/// DOCME -static const uint8_t w64GuidRIFF[16] = { - // {66666972-912E-11CF-A5D6-28DB04C10000} - 0x72, 0x69, 0x66, 0x66, 0x2E, 0x91, 0xCF, 0x11, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 -}; - - -/// DOCME -static const uint8_t w64GuidWAVE[16] = { - // {65766177-ACF3-11D3-8CD1-00C04F8EDB8A} - 0x77, 0x61, 0x76, 0x65, 0xF3, 0xAC, 0xD3, 0x11, 0x8C, 0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A -}; - - -/// DOCME -static const uint8_t w64Guidfmt[16] = { - // {20746D66-ACF3-11D3-8CD1-00C04F8EDB8A} - 0x66, 0x6D, 0x74, 0x20, 0xF3, 0xAC, 0xD3, 0x11, 0x8C, 0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A -}; - - -/// DOCME -static const uint8_t w64Guiddata[16] = { - // {61746164-ACF3-11D3-8CD1-00C04F8EDB8A} - 0x64, 0x61, 0x74, 0x61, 0xF3, 0xAC, 0xD3, 0x11, 0x8C, 0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A -}; - - -/// DOCME -/// @class Wave64AudioProvider -/// @brief Sony Wave64 audio provider -/// -/// http://www.vcs.de/fileadmin/user_upload/MBS/PDF/Whitepaper/Informations_about_Sony_Wave64.pdf -class Wave64AudioProvider : public PCMAudioProvider { - // Here's some copy-paste from the FFmpegSource2 code - - /// http://msdn.microsoft.com/en-us/library/dd757720(VS.85).aspx - struct WaveFormatEx { - uint16_t wFormatTag; - uint16_t nChannels; - uint32_t nSamplesPerSec; - uint32_t nAvgBytesPerSec; - uint16_t nBlockAlign; - uint16_t wBitsPerSample; - uint16_t cbSize; - }; - - /// DOCME - struct RiffChunk { - /// DOCME - uint8_t riff_guid[16]; - - /// DOCME - uint64_t file_size; - - /// DOCME - uint8_t format_guid[16]; - }; - - - /// DOCME - struct FormatChunk { - /// DOCME - uint8_t chunk_guid[16]; - - /// DOCME - uint64_t chunk_size; - - /// DOCME - WaveFormatEx format; - - /// DOCME - uint8_t padding[6]; - }; - - - /// DOCME - struct DataChunk { - /// DOCME - uint8_t chunk_guid[16]; - - /// DOCME - uint64_t chunk_size; - }; - - /// @brief DOCME - /// @param guid1 - /// @param guid2 - /// @return - /// - inline bool CheckGuid(const uint8_t *guid1, const uint8_t *guid2) - { - return memcmp(guid1, guid2, 16) == 0; - } - -public: - - /// @brief DOCME - /// @param _filename - /// - Wave64AudioProvider(const std::string &_filename) - : PCMAudioProvider(_filename) - { - filename = _filename; - - int64_t smallest_possible_file = sizeof(RiffChunk) + sizeof(FormatChunk) + sizeof(DataChunk); - - if (file_size < smallest_possible_file) - throw AudioOpenError("File is too small to be a Wave64 file"); - - // Read header - // This should throw an exception if the mapping fails - void *filestart = EnsureRangeAccessible(0, sizeof(RiffChunk)); - assert(filestart); - RiffChunk &header = *(RiffChunk*)filestart; - - // Check magic values - if (!CheckGuid(header.riff_guid, w64GuidRIFF)) - throw AudioOpenError("File is not a Wave64 RIFF file"); - if (!CheckGuid(header.format_guid, w64GuidWAVE)) - throw AudioOpenError("File is not a Wave64 WAVE file"); - - // Count how much more data we can have in the entire file - uint64_t data_left = Endian::LittleToMachine(header.file_size) - sizeof(RiffChunk); - // How far into the file we have processed. - // Must be incremented by the riff chunk size fields. - uint64_t filepos = sizeof(header); - - bool got_fmt_header = false; - - // Inherited from AudioProvider - num_samples = 0; - - // Continue reading chunks until out of data - while (data_left) { - uint8_t *chunk_guid = (uint8_t*)EnsureRangeAccessible(filepos, 16); - uint64_t chunk_size = Endian::LittleToMachine(*(uint64_t*)EnsureRangeAccessible(filepos+16, sizeof(uint64_t))); - - if (CheckGuid(chunk_guid, w64Guidfmt)) { - if (got_fmt_header) - throw AudioOpenError("Bad file, found more than one 'fmt' chunk"); - - FormatChunk &fmt = *(FormatChunk*)EnsureRangeAccessible(filepos, sizeof(FormatChunk)); - got_fmt_header = true; - - if (Endian::LittleToMachine(fmt.format.wFormatTag) == 3) - throw AudioOpenError("File is IEEE 32 bit float format which isn't supported. Bug the developers if this matters."); - if (Endian::LittleToMachine(fmt.format.wFormatTag) != 1) - throw AudioOpenError("Can't use file, not PCM encoding"); - - // Set stuff inherited from the AudioProvider class - sample_rate = Endian::LittleToMachine(fmt.format.nSamplesPerSec); - channels = Endian::LittleToMachine(fmt.format.nChannels); - bytes_per_sample = (Endian::LittleToMachine(fmt.format.wBitsPerSample) + 7) / 8; // round up to nearest whole byte - } - else if (CheckGuid(chunk_guid, w64Guiddata)) { - if (!got_fmt_header) - throw AudioOpenError("Found 'data' chunk before 'fmt ' chunk, file is invalid."); - - int64_t samples = chunk_size / bytes_per_sample; - int64_t frames = samples / channels; - - IndexPoint ip; - ip.start_sample = num_samples; - ip.num_samples = frames; - ip.start_byte = filepos; - index_points.push_back(ip); - - num_samples += frames; - } - - // Update counters - // Make sure they're 64 bit aligned - data_left -= (chunk_size + 7) & ~7; - filepos += (chunk_size + 7) & ~7; - } - } - - /// @brief DOCME - /// @return - /// - bool AreSamplesNativeEndian() const - { - // 8 bit samples don't consider endianness - if (bytes_per_sample < 2) return true; - // Otherwise test whether we're little endian - uint32_t testvalue = 0x008800ff; - return testvalue == Endian::LittleToMachine(testvalue); - } -}; - -/// @brief DOCME -/// @param filename -/// -AudioProvider *CreatePCMAudioProvider(const std::string &filename) -{ - std::string msg; - try { - return new RiffWavPCMAudioProvider(filename); - } - catch (AudioOpenError const& err) { - msg = "RIFF PCM WAV audio provider: " + err.GetMessage(); - } - try { - return new Wave64AudioProvider(filename); - } - catch (AudioOpenError const& err) { - msg += "\nWave64 audio provider: " + err.GetMessage(); - throw AudioOpenError(msg); - } -} - -} // namespace - diff --git a/aegisub/libmedia/audio/pcm.h b/aegisub/libmedia/audio/pcm.h deleted file mode 100644 index 1732b4f60..000000000 --- a/aegisub/libmedia/audio/pcm.h +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright (c) 2007-2008, Niels Martin Hansen -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * 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. -// * Neither the name of the Aegisub Group nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. -// -// Aegisub Project http://www.aegisub.org/ -// -// $Id$ - -/// @file audio_provider_pcm.h -/// @see audio_provider_pcm.cpp -/// @ingroup audio_input -/// - -#ifndef AGI_PRE -#include -#endif - -#ifdef _WIN32 -#include -#endif - -#include "libmedia/audio.h" - - -namespace media { - -/// DOCME -/// @class PCMAudioProvider -/// @brief DOCME -/// -/// DOCME -class PCMAudioProvider : public AudioProvider { -private: -#ifdef _WIN32 - - /// DOCME - HANDLE file_handle; - - /// DOCME - HANDLE file_mapping; - - /// DOCME - mutable void *current_mapping; - - /// DOCME - mutable int64_t mapping_start; - - /// DOCME - mutable size_t mapping_length; -#else - int file_handle; - mutable void *current_mapping; - mutable off_t mapping_start; - mutable size_t mapping_length; -#endif - -protected: - PCMAudioProvider(const std::string &filename); // Create base object and open the file mapping - virtual ~PCMAudioProvider(); // Closes the file mapping - char * EnsureRangeAccessible(int64_t range_start, int64_t range_length) const; // Ensure that the given range of bytes are accessible in the file mapping and return a pointer to the first byte of the requested range - - - /// DOCME - int64_t file_size; // Size of the opened file - - - /// DOCME - struct IndexPoint { - - /// DOCME - int64_t start_byte; - - /// DOCME - int64_t start_sample; - - /// DOCME - int64_t num_samples; - }; - - /// DOCME - typedef std::vector IndexVector; - - /// DOCME - IndexVector index_points; - -public: - virtual void GetAudio(void *buf, int64_t start, int64_t count) const; -}; - -// Construct the right PCM audio provider (if any) for the file -AudioProvider *CreatePCMAudioProvider(const std::string &filename); - -} // namespace - diff --git a/aegisub/libmedia/cache/audio_hd.cpp b/aegisub/libmedia/cache/audio_hd.cpp deleted file mode 100644 index 0fb009782..000000000 --- a/aegisub/libmedia/cache/audio_hd.cpp +++ /dev/null @@ -1,180 +0,0 @@ -// Copyright (c) 2005-2006, Rodrigo Braz Monteiro, Fredrik Mellbin -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * 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. -// * Neither the name of the Aegisub Group nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. -// -// Aegisub Project http://www.aegisub.org/ -// -// $Id$ - -/// @file audio_provider_hd.cpp -/// @brief Caching audio provider using a file for backing -/// @ingroup audio_input -/// - -#include "config.h" - -#ifndef AGI_PRE -#endif - -#include - -#include "audio_hd.h" - - -namespace media { - -/// @brief Constructor -/// @param source -/// -HDAudioProvider::HDAudioProvider(AudioProvider *src, agi::ProgressSinkFactory *progress_factory) { - std::auto_ptr source(src); - // Copy parameters - bytes_per_sample = source->GetBytesPerSample(); - num_samples = source->GetNumSamples(); - channels = source->GetChannels(); - sample_rate = source->GetSampleRate(); - filename = source->GetFilename(); - samples_native_endian = source->AreSamplesNativeEndian(); - - // Check free space - uint64_t freespace; -// XXX: fixme (add diskspace method to agi::util) -// if (wxGetDiskSpace(DiskCachePath(), NULL, &freespace)) { -// if (num_samples * channels * bytes_per_sample > freespace) { -// throw AudioOpenError("Not enough free disk space in " + STD_STR(DiskCachePath()) + " to cache the audio"); -// } -// } - - // Open output file - diskCacheFilename = DiskCacheName(); -// file_cache.Create(diskCacheFilename,true,wxS_DEFAULT); - io::Save file(diskCacheFilename); - std::ofstream& file_cache = file.Get(); -// file_cache.Open(diskCacheFilename,wxFile::read_write); - if (!file_cache.is_open()) throw AudioOpenError("Unable to write to audio disk cache."); - - // Start progress - ProgressSink *progress = progress_factory->create_progress_sink("Reading to Hard Disk cache"); - - volatile bool canceled = progress->get_cancelled(); - - // Write to disk - int block = 4096; - data = new char[block * channels * bytes_per_sample]; - for (int64_t i=0;i num_samples) block = num_samples - i; - source->GetAudio(data,i,block); - file_cache.write(data,block * channels * bytes_per_sample); - progress->set_progress(i,num_samples); - } - file_cache.seekp(0); - - // Finish - if (canceled) { -// file_cache.Close(); - delete[] data; - throw agi::UserCancelException("Audio loading cancelled by user"); - } - - delete progress; -} - -/// @brief Destructor -/// -HDAudioProvider::~HDAudioProvider() { -//XXX wxRemoveFile(diskCacheFilename); - delete[] data; -} - -/// @brief Get audio -/// @param buf -/// @param start -/// @param count -/// -void HDAudioProvider::GetAudio(void *buf, int64_t start, int64_t count) const { - // Requested beyond the length of audio - if (start+count > num_samples) { - int64_t oldcount = count; - count = num_samples-start; - if (count < 0) count = 0; - - // Fill beyond with zero - if (bytes_per_sample == 1) { - char *temp = (char *) buf; - for (int i=count;iGetString()); - if (path == _T("default")) return StandardPaths::DecodePath(_T("?temp/")); - - // Specified - return DecodeRelativePath(path,StandardPaths::DecodePath(_T("?user/"))); -*/ - return "XXX: fixme"; -} - -/// @brief Get disk cache filename -/// -std::string HDAudioProvider::DiskCacheName() { -/* -XXX: fixme - // Get pattern - std::string pattern = lagi_wxString(OPT_GET("Audio/Cache/HD/Name")->GetString()); - if (pattern.Find(_T("%02i")) == wxNOT_FOUND) pattern = _T("audio%02i.tmp"); - - // Try from 00 to 99 - for (int i=0;i<100;i++) { - // File exists? - wxString curStringTry = DiskCachePath() + wxString::Format(pattern.c_str(),i); - if (!wxFile::Exists(curStringTry)) return curStringTry; - } -*/ - return ""; -} - -} // namespace media diff --git a/aegisub/libmedia/cache/audio_hd.h b/aegisub/libmedia/cache/audio_hd.h deleted file mode 100644 index 2d398fc5c..000000000 --- a/aegisub/libmedia/cache/audio_hd.h +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright (c) 2006, Rodrigo Braz Monteiro -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * 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. -// * Neither the name of the Aegisub Group nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. -// -// Aegisub Project http://www.aegisub.org/ -// -// $Id$ - -/// @file audio_provider_hd.h -/// @see audio_provider_hd.cpp -/// @ingroup audio_input -/// - -#ifndef AGI_PRE -#endif - -#include - -#include "libmedia/audio.h" - -namespace media { -/// DOCME -/// @class HDAudioProvider -/// @brief DOCME -/// -/// DOCME -class HDAudioProvider : public AudioProvider { - /// DOCME - mutable agi::Mutex diskmutex; - - /// DOCME - mutable std::fstream file_cache; - - /// DOCME - std::string diskCacheFilename; - - /// DOCME - bool samples_native_endian; - - /// DOCME - char *data; - - static std::string DiskCachePath(); - static std::string DiskCacheName(); - -public: - HDAudioProvider(AudioProvider *source, agi::ProgressSinkFactory *progress_factory); - ~HDAudioProvider(); - - bool AreSamplesNativeEndian() const { return samples_native_endian; } - - void GetAudio(void *buf, int64_t start, int64_t count) const; -}; - -} // namespace media diff --git a/aegisub/libmedia/cache/audio_ram.cpp b/aegisub/libmedia/cache/audio_ram.cpp deleted file mode 100644 index 448fe3d3d..000000000 --- a/aegisub/libmedia/cache/audio_ram.cpp +++ /dev/null @@ -1,179 +0,0 @@ -// Copyright (c) 2005-2006, Rodrigo Braz Monteiro, Fredrik Mellbin -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * 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. -// * Neither the name of the Aegisub Group nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. -// -// Aegisub Project http://www.aegisub.org/ -// -// $Id$ - -/// @file audio_provider_ram.cpp -/// @brief Caching audio provider using heap memory for backing -/// @ingroup audio_input -/// - -#include "config.h" - -#include "audio_ram.h" -//#include "dialog_progress.h" -//#include "frame_main.h" -//#include "main.h" -//#include "utils.h" - -namespace media { - -/// DOCME -#define CacheBits ((22)) - -/// DOCME -#define CacheBlockSize ((1 << CacheBits)) - -/// @brief Constructor -/// @param source -/// -RAMAudioProvider::RAMAudioProvider(AudioProvider *src) { - std::auto_ptr source(src); - // Init - blockcache = NULL; - blockcount = 0; - samples_native_endian = source->AreSamplesNativeEndian(); - - // Allocate cache - int64_t ssize = source->GetNumSamples() * source->GetBytesPerSample(); - blockcount = (ssize + CacheBlockSize - 1) >> CacheBits; - blockcache = new char*[blockcount]; - for (int i = 0; i < blockcount; i++) { - blockcache[i] = NULL; - } - - // Allocate cache blocks - try { - for (int i = 0; i < blockcount; i++) { - blockcache[i] = new char[std::min(CacheBlockSize,ssize-i*CacheBlockSize)]; - } - } - catch (...) { - Clear(); - throw AudioOpenError("Couldn't open audio, not enough ram available."); - } - - // Copy parameters - bytes_per_sample = source->GetBytesPerSample(); - num_samples = source->GetNumSamples(); - channels = source->GetChannels(); - sample_rate = source->GetSampleRate(); - filename = source->GetFilename(); - - // Start progress -//XXX fixme: - volatile bool canceled = false; -// DialogProgress *progress = new DialogProgress(AegisubApp::Get()->frame,_("Load audio"),&canceled,_("Reading into RAM"),0,source->GetNumSamples()); -// progress->Show(); -// progress->SetProgress(0,1); - - // Read cache - int readsize = CacheBlockSize / source->GetBytesPerSample(); - for (int i=0;iGetAudio((char*)blockcache[i],i*readsize, i == blockcount-1 ? (source->GetNumSamples() - i*readsize) : readsize); -// progress->SetProgress(i,blockcount-1); - } - - // Clean up progress - if (canceled) { - Clear(); - throw agi::UserCancelException("Audio loading cancelled by user"); - } -// progress->Destroy(); -} - -/// @brief Destructor -/// -RAMAudioProvider::~RAMAudioProvider() { - Clear(); -} - -/// @brief Clear -/// -void RAMAudioProvider::Clear() { - // Free ram cache - if (blockcache) { - for (int i = 0; i < blockcount; i++) { - delete [] blockcache[i]; - } - delete [] blockcache; - } - blockcache = NULL; - blockcount = 0; -} - -/// @brief Get audio -/// @param buf -/// @param start -/// @param count -/// -void RAMAudioProvider::GetAudio(void *buf, int64_t start, int64_t count) const { - // Requested beyond the length of audio - if (start+count > num_samples) { - int64_t oldcount = count; - count = num_samples-start; - if (count < 0) count = 0; - - // Fill beyond with zero - if (bytes_per_sample == 1) { - char *temp = (char *) buf; - for (int i=count;i> CacheBits; - int start_offset = (start*bytes_per_sample) & (CacheBlockSize-1); - int64_t bytesremaining = count*bytes_per_sample; - - // Copy - while (bytesremaining) { - int readsize = std::min(bytesremaining, CacheBlockSize - start_offset); - - memcpy(charbuf,(char *)(blockcache[i++]+start_offset),readsize); - - charbuf+=readsize; - - start_offset=0; - bytesremaining-=readsize; - } - } -} - -} // namespace media diff --git a/aegisub/libmedia/cache/audio_ram.h b/aegisub/libmedia/cache/audio_ram.h deleted file mode 100644 index 6fec9b981..000000000 --- a/aegisub/libmedia/cache/audio_ram.h +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (c) 2006, Rodrigo Braz Monteiro -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * 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. -// * Neither the name of the Aegisub Group nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. -// -// Aegisub Project http://www.aegisub.org/ -// -// $Id$ - -/// @file audio_provider_ram.h -/// @see audio_provider_ram.cpp -/// @ingroup audio_input -/// - -#include "libmedia/audio.h" - -namespace media { -/// DOCME -/// @class RAMAudioProvider -/// @brief DOCME -/// -/// DOCME -class RAMAudioProvider : public AudioProvider { - /// DOCME - char** blockcache; - - /// DOCME - int blockcount; - - /// DOCME - bool samples_native_endian; - - void Clear(); - -public: - RAMAudioProvider(AudioProvider *source); - ~RAMAudioProvider(); - - bool AreSamplesNativeEndian() const { return samples_native_endian; } - void GetAudio(void *buf, int64_t start, int64_t count) const; -}; - -} // namespace media diff --git a/aegisub/libmedia/cache/video_cache.cpp b/aegisub/libmedia/cache/video_cache.cpp deleted file mode 100644 index 5b35096a5..000000000 --- a/aegisub/libmedia/cache/video_cache.cpp +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright (c) 2008, Rodrigo Braz Monteiro -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * 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. -// * Neither the name of the Aegisub Group nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. -// -// Aegisub Project http://www.aegisub.org/ -// -// $Id$ - -/// @file video_provider_cache.cpp -/// @brief Aggregate video provider caching previously requested frames -/// @ingroup video_input -/// - -#include "config.h" -//#include "main.h" - -#include "video_cache.h" - -namespace media { - -/// DOCME -/// @class CachedFrame -/// @brief DOCME -/// -/// DOCME -struct CachedFrame { - /// DOCME - AegiVideoFrame frame; - - /// DOCME - int n; -}; - -/// @brief Constructor -/// @param parent -/// -VideoProviderCache::VideoProviderCache(VideoProvider *parent) -: master(parent) -//XXX: , cacheMax(OPT_GET("Provider/Video/Cache/Size")->GetInt() << 20) // convert MB to bytes -{ -} - -/// @brief Destructor -/// -VideoProviderCache::~VideoProviderCache() { - while (cache.size()) { - cache.front().frame.Clear(); - cache.pop_front(); - } -} - -/// @brief Get frame -/// @param n -/// @return -/// -const AegiVideoFrame VideoProviderCache::GetFrame(int n) { - // See if frame is cached - CachedFrame cached; - for (std::list::iterator cur=cache.begin();cur!=cache.end();cur++) { - cached = *cur; - if (cached.n == n) { - cache.erase(cur); - cache.push_back(cached); - return cached.frame; - } - } - - // Not cached, retrieve it - const AegiVideoFrame frame = master->GetFrame(n); - const AegiVideoFrame *srcFrame = &frame; - - // Cache frame - Cache(n,*srcFrame); - return *srcFrame; -} - -/// @brief Add to cache -/// @param n -/// @param frame -void VideoProviderCache::Cache(int n,const AegiVideoFrame frame) { - // Cache full, use frame at front - if (GetCurCacheSize() >= cacheMax) { - cache.push_back(cache.front()); - cache.pop_front(); - } - - // Cache not full, insert new one - else { - cache.push_back(CachedFrame()); - } - - // Cache - cache.back().n = n; - cache.back().frame.CopyFrom(frame); -} - -/// @brief Get the current size of the cache -/// @return Returns the size in bytes -unsigned VideoProviderCache::GetCurCacheSize() { - int sz = 0; - for (std::list::iterator i = cache.begin(); i != cache.end(); i++) - sz += i->frame.memSize; - return sz; -} - -} // namespace media diff --git a/aegisub/libmedia/cache/video_cache.h b/aegisub/libmedia/cache/video_cache.h deleted file mode 100644 index eff7733b6..000000000 --- a/aegisub/libmedia/cache/video_cache.h +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright (c) 2008, Rodrigo Braz Monteiro, Fredrik Mellbin -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * 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. -// * Neither the name of the Aegisub Group nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. -// -// Aegisub Project http://www.aegisub.org/ -// -// $Id$ - -/// @file video_provider_cache.h -/// @see video_provider_cache.cpp -/// @ingroup video_input -/// - -#ifndef AGI_PRE -#include -#include -#endif - -#include "libmedia/video.h" - -namespace media { - -struct CachedFrame; - -/// DOCME -/// @class VideoProviderCache -/// @brief DOCME -/// -/// DOCME -class VideoProviderCache : public VideoProvider { - /// DOCME - std::auto_ptr master; - - /// DOCME - unsigned int cacheMax; - - /// DOCME - std::list cache; - - void Cache(int n,const AegiVideoFrame frame); - AegiVideoFrame GetCachedFrame(int n); - - // Cache functions - unsigned GetCurCacheSize(); - -public: - // Base methods - const AegiVideoFrame GetFrame(int n); - VideoProviderCache(VideoProvider *master); - virtual ~VideoProviderCache(); - - // Override the following methods: - virtual int GetPosition() const { return master->GetPosition(); } - virtual int GetFrameCount() const { return master->GetFrameCount(); } - virtual int GetWidth() const { return master->GetWidth(); } - virtual int GetHeight() const { return master->GetHeight(); } - virtual agi::vfr::Framerate GetFPS() const { return master->GetFPS(); } - virtual std::vector GetKeyFrames() const { return master->GetKeyFrames(); } - virtual std::string GetWarning() const { return master->GetWarning(); } - virtual std::string GetDecoderName() const { return master->GetDecoderName(); } -}; - -} // namespace media diff --git a/aegisub/libmedia/common/audio_manager.cpp b/aegisub/libmedia/common/audio_manager.cpp deleted file mode 100644 index b07654043..000000000 --- a/aegisub/libmedia/common/audio_manager.cpp +++ /dev/null @@ -1,193 +0,0 @@ -// Copyright (c) 2005-2006, Rodrigo Braz Monteiro -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * 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. -// * Neither the name of the Aegisub Group nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. -// -// Aegisub Project http://www.aegisub.org/ -// -// $Id$ - -/// @file audio_provider.cpp -/// @brief Baseclass for audio providers -/// @ingroup audio_input -/// - - -#include "config.h" - -#ifndef AGI_PRE -#endif - -#ifdef WITH_AVISYNTH -#include "../audio/avs_audio.h" -#endif -#include "../audio/convert.h" -#ifdef WITH_FFMPEGSOURCE -#include "../audio/ffms_audio.h" -#endif -#include "../cache/audio_hd.h" -#include "../cache/audio_ram.h" -#include "../audio/pcm.h" - - -//#include "compat.h" -//#include "main.h" - -namespace media { - -/// @brief Constructor -/// -AudioProvider::AudioProvider() : raw(NULL) { -} - -/// @brief Destructor -/// -AudioProvider::~AudioProvider() { - delete[] raw; -} - -/// @brief Get audio with volume -/// @param buf -/// @param start -/// @param count -/// @param volume -/// @return -/// -void AudioProvider::GetAudioWithVolume(void *buf, int64_t start, int64_t count, double volume) const { - try { - GetAudio(buf,start,count); - } - catch (...) { - // FIXME: Poor error handling though better than none, to patch issue #800. - // Just return blank audio if real provider fails. - memset(buf, 0, count*bytes_per_sample); - return; - } - - if (volume == 1.0) return; - - if (bytes_per_sample == 2) { - // Read raw samples - short *buffer = (short*) buf; - int value; - - // Modify - for (int64_t i=0;i 0x7FFF) value = 0x7FFF; - buffer[i] = value; - } - } -} - -/// @brief Get provider -/// @param filename -/// @param cache -/// @return -/// -AudioProvider *AudioProviderFactory::GetProvider(std::string filename, agi::ProgressSinkFactory *progress_factory, int cache) { - AudioProvider *provider = NULL; - bool found = false; - std::string msg; - -//XXX if (!OPT_GET("Provider/Audio/PCM/Disable")->GetBool()) { - if (1) { - // Try a PCM provider first - try { - provider = CreatePCMAudioProvider(filename); - } - catch (agi::FileNotFoundError const& err) { - msg = "PCM audio provider: " + err.GetMessage() + " not found.\n"; - } - catch (AudioOpenError const& err) { - found = true; - msg += err.GetMessage(); - } - } - if (!provider) { -//XXX std::vector list = GetClasses(OPT_GET("Audio/Provider")->GetString()); - std::vector list = GetClasses("ffmpegsource"); - - if (list.empty()) throw AudioOpenError("No audio providers are available."); - - for (unsigned int i=0;iNeedsCache(); - - // Give it a converter if needed - if (provider->GetBytesPerSample() != 2 || provider->GetSampleRate() < 32000 || provider->GetChannels() != 1) - provider = CreateConvertAudioProvider(provider); - - // Change provider to RAM/HD cache if needed -//XXX if (cache == -1) cache = OPT_GET("Audio/Cache/Type")->GetInt(); - if (cache == -1) cache = 1; - if (!cache || !needsCache) { - return provider; - } - - // Convert to RAM - if (cache == 1) return new RAMAudioProvider(provider); - - // Convert to HD - if (cache == 2) return new HDAudioProvider(provider, progress_factory); - - throw AudioOpenError("Unknown caching method"); -} - -/// @brief Register all providers -/// -void AudioProviderFactory::RegisterProviders() { -#ifdef WITH_AVISYNTH - Register("Avisynth"); -#endif -#ifdef WITH_FFMPEGSOURCE - Register("FFmpegSource"); -#endif -} - -template<> AudioProviderFactory::map *FactoryBase::classes = NULL; - -} // namespace media diff --git a/aegisub/libmedia/common/colourspace.cpp b/aegisub/libmedia/common/colourspace.cpp deleted file mode 100644 index 96dac402f..000000000 --- a/aegisub/libmedia/common/colourspace.cpp +++ /dev/null @@ -1,499 +0,0 @@ -// Copyright (c) 2005, Niels Martin Hansen, Rodrigo Braz Monteiro -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * 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. -// * Neither the name of the Aegisub Group nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. -// -// Aegisub Project http://www.aegisub.org/ -// -// $Id$ - -/// @file colorspace.cpp -/// @brief Functions for converting colours between different representations -/// @ingroup utility -/// - -#include "config.h" - -#include "libmedia/colourspace.h" -//#include "utils.h" - -namespace media { - -/// @brief matrix from http://forum.doom9.org/showthread.php?p=684080#post684080 -/// @param Y -/// @param U -/// @param V -/// @param R -/// @param G -/// @param B -/// -void yuv_to_rgb(int Y, int U, int V, unsigned char *R, unsigned char *G, unsigned char *B) -{ - U = U - 128; - V = V - 128; - *R = clip_colorval((Y*65536 + int(1.140*65536) * V) / 65536); - *G = clip_colorval((Y*65536 - int(0.395*65536) * U - int(0.581*65536) * V) / 65536); - *B = clip_colorval((Y*65536 + int(2.032*65536) * U ) / 65536); -} - - - -/// @brief making every value into 0..255 range though algorithm from http://130.113.54.154/~monger/hsl-rgb.html -/// @param H -/// @param S -/// @param L -/// @param R -/// @param G -/// @param B -/// @return -/// -void hsl_to_rgb(int H, int S, int L, unsigned char *R, unsigned char *G, unsigned char *B) -{ - if (S == 0) { - *R = L; - *G = L; - *B = L; - return; - } - - if (L == 128 && S == 255) { - switch (H) { - case 0: - case 255: // actually this is wrong, since this is more like 359 degrees... but it's what you'd expect (sadly :) - *R = 255; - *G = 0; - *B = 0; - return; - case 43: - *R = 255; - *G = 255; - *B = 0; - return; - case 85: - *R = 0; - *G = 255; - *B = 0; - return; - case 128: - *R = 0; - *G = 255; - *B = 255; - return; - case 171: - *R = 0; - *G = 0; - *B = 255; - return; - case 213: - *R = 255; - *G = 0; - *B = 255; - return; - } - } - - float h, s, l, r, g, b; - h = H / 255.f; - s = S / 255.f; - l = L / 255.f; - - float temp2; - if (l < .5) { - temp2 = l * (1. + s); - } else { - temp2 = l + s - l*s; - } - - float temp1 = 2.f * l - temp2; - - // assume h is in range [0;1] - float temp3[3]; - temp3[0] = h + 1.f/3.f; - if (temp3[0] > 1.f) temp3[0] -= 1.f; - temp3[1] = h; - temp3[2] = h - 1.f/3.f; - if (temp3[2] < 0.f) temp3[2] += 1.f; - - if (6.f * temp3[0] < 1.f) - r = temp1 + (temp2 - temp1) * 6.f * temp3[0]; - else if (2.f * temp3[0] < 1.f) - r = temp2; - else if (3.f * temp3[0] < 2.f) - r = temp1 + (temp2 - temp1) * ((2.f/3.f) - temp3[0]) * 6.f; - else - r = temp1; - - if (6.f * temp3[1] < 1.f) - g = temp1 + (temp2 - temp1) * 6.f * temp3[1]; - else if (2.f * temp3[1] < 1.f) - g = temp2; - else if (3.f * temp3[1] < 2.f) - g = temp1 + (temp2 - temp1) * ((2.f/3.f) - temp3[1]) * 6.f; - else - g = temp1; - - if (6.f * temp3[2] < 1.f) - b = temp1 + (temp2 - temp1) * 6.f * temp3[2]; - else if (2.f * temp3[2] < 1.f) - b = temp2; - else if (3.f * temp3[2] < 2.f) - b = temp1 + (temp2 - temp1) * ((2.f/3.f) - temp3[2]) * 6.f; - else - b = temp1; - - *R = clip_colorval((int)(r*255)); - *G = clip_colorval((int)(g*255)); - *B = clip_colorval((int)(b*255)); -} - - - -/// @brief the range for H is 0..255 instead of 0..359, so 60 degrees has been translated to 256/6 here formulas taken from wikipedia: http://en.wikipedia.org/wiki/HSV_color_space -/// @param H -/// @param S -/// @param V -/// @param R -/// @param G -/// @param B -/// @return -/// -void hsv_to_rgb(int H, int S, int V, unsigned char *R, unsigned char *G, unsigned char *B) -{ - *R = *G = *B = 0; - - // some special cases... oh yeah baby! - if (S == 255) { - switch (H) { - case 0: - case 255: // actually this is wrong, since this is more like 359 degrees... but it's what you'd expect (sadly :) - *R = V; - *G = 0; - *B = 0; - return; - case 43: - *R = V; - *G = V; - *B = 0; - return; - case 85: - *R = 0; - *G = V; - *B = 0; - return; - case 128: - *R = 0; - *G = V; - *B = V; - return; - case 171: - *R = 0; - *G = 0; - *B = V; - return; - case 213: - *R = V; - *G = 0; - *B = V; - return; - } - } - - // Cap values - unsigned int h = H * 360; - unsigned int s = clip_colorval(S)*256; - unsigned int v = clip_colorval(V)*256; - - // Saturation is zero, make grey - if (S == 0) { - *R = V; - *G = V; - *B = V; - return; - } - - unsigned int r, g, b; - - // Else, calculate color - unsigned int Hi = h / 60 / 256; - unsigned int f = h / 60 - Hi * 256; - unsigned int p = v * (65535 - s) / 65536; - unsigned int q = v * (65535 - (f * s)/256) / 65536; - unsigned int t = v * (65535 - ((255 - f) * s)/256) / 65536; - switch (Hi) { - case 0: - r = v; - g = t; - b = p; - break; - case 1: - r = q; - g = v; - b = p; - break; - case 2: - r = p; - g = v; - b = t; - break; - case 3: - r = p; - g = q; - b = v; - break; - case 4: - r = t; - g = p; - b = v; - break; - case 5: - default: - r = v; - g = p; - b = q; - break; - } - - *R = clip_colorval(r/256); - *G = clip_colorval(g/256); - *B = clip_colorval(b/256); -} - - - -/// @brief matrix from http://forum.doom9.org/showthread.php?p=684080#post684080 -/// @param R -/// @param G -/// @param B -/// @param Y -/// @param U -/// @param V -/// -void rgb_to_yuv(int R, int G, int B, unsigned char *Y, unsigned char *U, unsigned char *V) -{ - *Y = clip_colorval(( int(0.299*65536) * R + int(0.587*65536) * G + int(0.114*65536) * B) / 65536); - *U = clip_colorval((-int(0.147*65536) * R - int(0.289*65536) * G + int(0.436*65536) * B) / 65536 + 128); - *V = clip_colorval(( int(0.615*65536) * R - int(0.515*65536) * G - int(0.100*65536) * B) / 65536 + 128); -} - - - -/// @brief still keeping everything integer also from http://130.113.54.154/~monger/hsl-rgb.html -/// @param R -/// @param G -/// @param B -/// @param H -/// @param S -/// @param L -/// -void rgb_to_hsl(int R, int G, int B, unsigned char *H, unsigned char *S, unsigned char *L) -{ - float r = R/255.f, g = G/255.f, b = B/255.f; - float h, s, l; - - float maxrgb = std::max(r, std::max(g, b)), minrgb = std::min(r, std::min(g, b)); - - l = (minrgb + maxrgb) / 2; - - if (minrgb == maxrgb) { - h = 0; - s = 0; - } else { - if (l < 0.5) { - s = (maxrgb - minrgb) / (maxrgb + minrgb); - } else { - s = (maxrgb - minrgb) / (2.f - maxrgb - minrgb); - } - if (r == maxrgb) { - h = (g-b) / (maxrgb-minrgb) + 0; - } else if (g == maxrgb) { - h = (b-r) / (maxrgb-minrgb) + 2; - } else { // if b == maxrgb - h = (r-g) / (maxrgb-minrgb) + 4; - } - } - - if (h < 0) h += 6; - if (h >= 6) h -= 6; - - *H = clip_colorval(int(h*256/6)); - *S = clip_colorval(int(s*255)); - *L = clip_colorval(int(l*255)); -} - - - -/// @brief formulas from http://en.wikipedia.org/wiki/HSV_color_space -/// @param R -/// @param G -/// @param B -/// @param H -/// @param S -/// @param V -/// -void rgb_to_hsv(int R, int G, int B, unsigned char *H, unsigned char *S, unsigned char *V) -{ - float r = R/255.f, g = G/255.f, b = B/255.f; - float h, s, v; - - float maxrgb = std::max(r, std::max(g, b)), minrgb = std::min(r, std::min(g, b)); - - v = maxrgb; - - if (maxrgb < .001f) { - s = 1; - } else { - s = (maxrgb - minrgb) / maxrgb; - } - - if (minrgb == maxrgb) { - h = 0; - } else if (maxrgb == r) { - h = (g-b) / (maxrgb-minrgb) + 0; - } else if (maxrgb == g) { - h = (b-r) / (maxrgb-minrgb) + 2; - } else { // if maxrgb == b - h = (r-g) / (maxrgb-minrgb) + 4; - } - - if (h < 0) h += 6; - if (h >= 6) h -= 6; - - *H = clip_colorval(int(h*256/6)); - *S = clip_colorval(int(s*255)); - *V = clip_colorval(int(v*255)); -} - - - -/// @brief DOCME -/// @param iH -/// @param iS -/// @param iV -/// @param oH -/// @param oS -/// @param oL -/// -void hsv_to_hsl(int iH, int iS, int iV, unsigned char *oH, unsigned char *oS, unsigned char *oL) -{ - int p = iV * (255 - iS); - *oH = iH; - *oL = clip_colorval((p + iV*255)/255/2); - if (*oL == 0) { - *oS = iS; // oS is actually undefined, so any value should work ;) - } else if (*oL <= 128) { - *oS = clip_colorval((iV*255 - p) / (2 * *oL)); - } else { - *oS = clip_colorval((iV*255 - p) / (511 - 2 * *oL)); - } -} - - - -/// @brief DOCME -/// @param iH -/// @param iS -/// @param iL -/// @param oH -/// @param oS -/// @param oV -/// @return -/// -void hsl_to_hsv(int iH, int iS, int iL, unsigned char *oH, unsigned char *oS, unsigned char *oV) -{ - *oH = iH; - - if (iS == 0) { - *oS = 0; - *oV = iL; - return; - } - - if (iL < 128) { - *oV = iL * (255 + iS) / 255; - *oS = 2 * 255 * iS / (255 + iS); - } else { - *oV = (iL*255 + iS*255 - iL*iS)/255; - *oS = 2 * 255 * iS * (255 - iL) / (iL*255 + iS*255 - iL*iS); - } -} - - - -/// @brief DOCME -/// @param color -/// @return -/// -std::string color_to_html(agi::Colour color) -{ -// return wxString::Format(_T("#%02X%02X%02X"), color.Red(), color.Green(), color.Blue()); - return "broken"; -} - - - -/// @brief DOCME -/// @param html -/// -std::string html_to_color(agi::Colour html) -{ -/* - html.Trim(true); - html.Trim(false); - if (html.StartsWith(_T("#"))) { - html.Remove(0, 1); - } - if (html.size() == 6) { - // 8 bit per channel - long r, g, b; - wxString sr, sg, sb; - sr = html.Mid(0, 2); - sg = html.Mid(2, 2); - sb = html.Mid(4, 2); - if (sr.ToLong(&r, 16) && sg.ToLong(&g, 16) && sb.ToLong(&b, 16)) { - return wxColour(r, g, b); - } else { - return wxColour(*wxBLACK); - } - } else if (html.size() == 3) { - // 4 bit per channel - long r, g, b; - wxString sr, sg, sb; - sr = html.Mid(0, 1); - sg = html.Mid(1, 1); - sb = html.Mid(2, 1); - if (sr.ToLong(&r, 16) && sg.ToLong(&g, 16) && sb.ToLong(&b, 16)) { - return wxColour(r*16+r, g*16+g, b*16+b); - } else { - return wxColour(*wxBLACK); - } - } else { - // only care about valid colors - return wxColour(*wxBLACK); - } -*/ -return "XXX: fixme"; -} - -} // namespace media diff --git a/aegisub/libmedia/common/ffms_common.cpp b/aegisub/libmedia/common/ffms_common.cpp deleted file mode 100644 index 463b85b19..000000000 --- a/aegisub/libmedia/common/ffms_common.cpp +++ /dev/null @@ -1,270 +0,0 @@ -// Copyright (c) 2008-2009, Karl Blomster -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * 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. -// * Neither the name of the Aegisub Group nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. -// -// Aegisub Project http://www.aegisub.org/ -// -// $Id$ - -/// @file ffmpegsource_common.cpp -/// @brief Shared code for ffms video and audio providers -/// @ingroup video_input audio_input ffms -/// - -#include "config.h" - -#ifdef WITH_FFMPEGSOURCE - -#ifndef AGI_PRE -#include -#include - -//#include -//#include // Keep this last so wxUSE_CHOICEDLG is set. -#endif - -#include - -#include "ffms_common.h" - -//#include "compat.h" -//#include "ffmpegsource_common.h" -//#include "frame_main.h" -//#include "main.h" -//#include "md5.h" -//#include "standard_paths.h" - -namespace media { - namespace ffms { - -/// @brief Callback function that updates the indexing progress dialog -/// @param Current The current file positition in bytes -/// @param Total The total file size in bytes -/// @param Private A pointer to the progress dialog box to update -/// @return Returns non-0 if indexing is cancelled, 0 otherwise. -/// -int FFMS_CC FFmpegSourceProvider::UpdateIndexingProgress(int64_t Current, int64_t Total, void *Private) { - IndexingProgressDialog *Progress = (IndexingProgressDialog *)Private; - - if (Progress->IndexingCanceled) - return 1; - - // no one cares about a little bit of a rounding error here anyway -// Progress->ProgressDialog->SetProgress(((int64_t)1000*Current)/Total, 1000); - - return 0; -} - - - -/// @brief Does indexing of a source file -/// @param Indexer A pointer to the indexer object representing the file to be indexed -/// @param CacheName The filename of the output index file -/// @param Trackmask A binary mask of the track numbers to index -/// @param IgnoreDecodeErrors True if audio decoding errors will be tolerated, false otherwise -/// @return Returns the index object on success, NULL otherwise -/// -FFMS_Index *FFmpegSourceProvider::DoIndexing(FFMS_Indexer *Indexer, const std::string &CacheName, int Trackmask, FFMS_IndexErrorHandling IndexEH) { - char FFMSErrMsg[1024]; - FFMS_ErrorInfo ErrInfo; - ErrInfo.Buffer = FFMSErrMsg; - ErrInfo.BufferSize = sizeof(FFMSErrMsg); - ErrInfo.ErrorType = FFMS_ERROR_SUCCESS; - ErrInfo.SubType = FFMS_ERROR_SUCCESS; - std::string MsgString; -/* - // set up progress dialog callback - IndexingProgressDialog Progress; - Progress.IndexingCanceled = false; - Progress.ProgressDialog = new DialogProgress(AegisubApp::Get()->frame, - _("Indexing"), &Progress.IndexingCanceled, - _("Reading timecodes and frame/sample data"), 0, 1); - Progress.ProgressDialog->Show(); - Progress.ProgressDialog->SetProgress(0,1); - - // index all audio tracks - FFMS_Index *Index = FFMS_DoIndexing(Indexer, Trackmask, FFMS_TRACKMASK_NONE, NULL, NULL, IndexEH, - FFmpegSourceProvider::UpdateIndexingProgress, &Progress, &ErrInfo); - Progress.ProgressDialog->Destroy(); - if (Progress.IndexingCanceled) { - throw agi::UserCancelException("indexing cancelled by user"); - } - if (Index == NULL) { - MsgString.append("Failed to index: ").append(ErrInfo.Buffer); - throw MsgString; - } - - // write index to disk for later use - // ignore write errors for now - FFMS_WriteIndex(CacheName.c_str(), Index, &ErrInfo); -// if (FFMS_WriteIndex(CacheName.char_str(), Index, FFMSErrMsg, MsgSize)) { -// wxString temp(FFMSErrMsg, wxConvUTF8); -// MsgString << _T("Failed to write index: ") << temp; -// throw MsgString; -// } -*/ -FFMS_Index *Index; - return Index; -} - -/// @brief Finds all tracks of the given type and return their track numbers and respective codec names -/// @param Indexer The indexer object representing the source file -/// @param Type The track type to look for -/// @return Returns a std::map with the track numbers as keys and the codec names as values. -std::map FFmpegSourceProvider::GetTracksOfType(FFMS_Indexer *Indexer, FFMS_TrackType Type) { - std::map TrackList; - int NumTracks = FFMS_GetNumTracksI(Indexer); - - for (int i=0; i(i, CodecName)); - } - } - return TrackList; -} - -/// @brief Ask user for which track he wants to load -/// @param TrackList A std::map with the track numbers as keys and codec names as values -/// @param Type The track type to ask about -/// @return Returns the track number chosen (an integer >= 0) on success, or a negative integer if the user cancelled. -int FFmpegSourceProvider::AskForTrackSelection(const std::map &TrackList, FFMS_TrackType Type) { -/* - std::vector TrackNumbers; - wxArrayString Choices; - std::string TypeName = ""; - if (Type == FFMS_TYPE_VIDEO) - TypeName = _("video"); - else if (Type == FFMS_TYPE_AUDIO) - TypeName = _("audio"); - - for (std::map::const_iterator i = TrackList.begin(); i != TrackList.end(); i++) { - istream str; -//XXX Choices.Add(ng::Format(_("Track %02d: %s"), i->first, i->second.c_str())); - TrackNumbers.push_back(i->first); - } - - int Choice = wxGetSingleChoiceIndex(wxString::Format(_("Multiple %s tracks detected, please choose the one you wish to load:"), TypeName.c_str()), - wxString::Format(_("Choose %s track"), TypeName.c_str()), Choices); - - if (Choice < 0) - return Choice; - else - return TrackNumbers[Choice]; -*/ -} - - -/// @brief Set ffms2 log level according to setting in config.dat -void FFmpegSourceProvider::SetLogLevel() { -/* - wxString LogLevel = lagi_wxString(OPT_GET("Provider/FFmpegSource/Log Level")->GetString()); - if (!LogLevel.CmpNoCase("panic")) - FFMS_SetLogLevel(FFMS_LOG_PANIC); - else if (!LogLevel.CmpNoCase("fatal")) - FFMS_SetLogLevel(FFMS_LOG_FATAL); - else if (!LogLevel.CmpNoCase("error")) - FFMS_SetLogLevel(FFMS_LOG_ERROR); - else if (!LogLevel.CmpNoCase("warning")) - FFMS_SetLogLevel(FFMS_LOG_WARNING); - else if (!LogLevel.CmpNoCase("info")) - FFMS_SetLogLevel(FFMS_LOG_INFO); - else if (!LogLevel.CmpNoCase("verbose")) - FFMS_SetLogLevel(FFMS_LOG_VERBOSE); - else if (!LogLevel.CmpNoCase("debug")) - FFMS_SetLogLevel(FFMS_LOG_DEBUG); - else */ - FFMS_SetLogLevel(FFMS_LOG_QUIET); -} - - -FFMS_IndexErrorHandling FFmpegSourceProvider::GetErrorHandlingMode() { -// std::string Mode = lagi_wxString(OPT_GET("Provider/Audio/FFmpegSource/Decode Error Handling")->GetString()); -std::string mode = "ignore"; - - if (mode == "ignore") - return FFMS_IEH_IGNORE; - else if (mode == "clear") - return FFMS_IEH_CLEAR_TRACK; - else if (mode == "stop") - return FFMS_IEH_STOP_TRACK; - else if (mode == "abort") - return FFMS_IEH_ABORT; - else - return FFMS_IEH_STOP_TRACK; // questionable default? -} - -#include -/// @brief Generates an unique name for the ffms2 index file and prepares the cache folder if it doesn't exist -/// @param filename The name of the source file -/// @return Returns the generated filename. -std::string FFmpegSourceProvider::GetCacheFilename(const std::string& _filename) -{ -/* - // Get the size of the file to be hashed - wxFileOffset len = 0; - { - wxFile file(_filename,wxFile::read); - if (file.IsOpened()) len = file.Length(); - } - - wxFileName filename(_filename); - - // Generate string to be hashed -// std::string toHash = wxString::Format("%s %" PRId64 " %" PRId64, filename.GetFullName(), len, (int64_t)filename.GetModificationTime().GetTicks()); -std::string toHash = "XXX"; - - // Get the MD5 digest of the string - const wchar_t *tmp = toHash.wc_str(); - md5_state_t state; - md5_byte_t digest[16]; - md5_init(&state); - md5_append(&state,(md5_byte_t*)tmp,toHash.Length()*sizeof(wchar_t)); - md5_finish(&state,digest); - - // Generate the filename - unsigned int *md5 = (unsigned int*) digest; - wxString result = wxString::Format("?user/ffms2cache/%08X%08X%08X%08X.ffindex",md5[0],md5[1],md5[2],md5[3]); - result = StandardPaths::DecodePath(result); - - // Ensure that folder exists - wxFileName fn(result); - wxString dir = fn.GetPath(); - if (!wxFileName::DirExists(dir)) { - wxFileName::Mkdir(dir); - } - - wxFileName dirfn(dir); - return dirfn.GetShortPath() + "/" + fn.GetFullName(); -*/ -return "XXX"; -} - -#endif // WITH_FFMPEGSOURCE - - - } // namespace ffms -} // namespace media diff --git a/aegisub/libmedia/common/ffms_common.h b/aegisub/libmedia/common/ffms_common.h deleted file mode 100644 index 581433892..000000000 --- a/aegisub/libmedia/common/ffms_common.h +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright (c) 2008-2009, Karl Blomster -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * 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. -// * Neither the name of the Aegisub Group nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. -// -// Aegisub Project http://www.aegisub.org/ -// -// $Id$ - -/// @file ffmpegsource_common.h -/// @see ffmpegsource_common.cpp -/// @ingroup video_input audio_input ffms -/// - -#ifdef WITH_FFMPEGSOURCE - -#ifndef AGI_PRE -#include - -//#include -//#include -#endif - -#include "../../libffms/include/ffms.h" - -namespace media { - namespace ffms { - -//#include "dialog_progress.h" - -/// Index all tracks -#define FFMS_TRACKMASK_ALL -1 -/// Index no tracks -#define FFMS_TRACKMASK_NONE 0 - -/// @class FFmpegSourceProvider -/// @brief Base class for FFMS2 source providers; contains common functions etc -class FFmpegSourceProvider { -public: - /// Logging level constants from avutil/log.h - enum FFMS_LogLevel { - /// nothing printed - FFMS_LOG_QUIET = -8, - FFMS_LOG_PANIC = 0, - FFMS_LOG_FATAL = 8, - FFMS_LOG_ERROR = 16, - FFMS_LOG_WARNING = 24, - FFMS_LOG_INFO = 32, - FFMS_LOG_VERBOSE = 40, - FFMS_LOG_DEBUG = 48, - }; - - /// Indexing progress report dialog - struct IndexingProgressDialog { - volatile bool IndexingCanceled; -// DialogProgress *ProgressDialog; - }; - - static int FFMS_CC UpdateIndexingProgress(int64_t Current, int64_t Total, void *Private); - - FFMS_Index *DoIndexing(FFMS_Indexer *Indexer, const std::string& Cachename, int Trackmask, FFMS_IndexErrorHandling IndexEH); - std::map GetTracksOfType(FFMS_Indexer *Indexer, FFMS_TrackType Type); - int AskForTrackSelection(const std::map& TrackList, FFMS_TrackType Type); - std::string GetCacheFilename(const std::string& filename); - void SetLogLevel(); - FFMS_IndexErrorHandling GetErrorHandlingMode(); - - virtual ~FFmpegSourceProvider() {} -}; - -#endif /* WITH_FFMPEGSOURCE */ - - } // namespace ffms -} // namespace media diff --git a/aegisub/libmedia/common/subtitle.cpp b/aegisub/libmedia/common/subtitle.cpp deleted file mode 100644 index 11ba3d8d7..000000000 --- a/aegisub/libmedia/common/subtitle.cpp +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright (c) 2007, Rodrigo Braz Monteiro -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * 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. -// * Neither the name of the Aegisub Group nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. -// -// Aegisub Project http://www.aegisub.org/ -// -// $Id$ - -/// @file subtitles_provider.cpp -/// @brief Base class for subtitle renderers -/// @ingroup subtitle_rendering -/// - -#include "config.h" - -#include "compat.h" -#include "main.h" -#ifdef WITH_CSRI -#include "subtitles_provider_csri.h" -#endif -#ifdef WITH_LIBASS -#include "subtitles_provider_libass.h" -#endif -#if !defined(WITH_CSRI) && !defined(WITH_LIBASS) -#include "include/aegisub/subtitles_provider.h" -#endif - -/// @brief Get provider -/// @return -/// -SubtitlesProvider* SubtitlesProviderFactory::GetProvider() { - std::vector list = GetClasses(OPT_GET("Subtitle/Provider")->GetString()); - if (list.empty()) throw _T("No subtitle providers are available."); - - // Get provider - wxString error; - for (unsigned int i=0;i("CSRI", false, CSRISubtitlesProvider::GetSubTypes()); -#endif -#ifdef WITH_LIBASS - Register("libass"); - LibassSubtitlesProvider::CacheFonts(); -#endif -} - -template<> SubtitlesProviderFactory::map *FactoryBase::classes = NULL; diff --git a/aegisub/libmedia/common/video_frame.cpp b/aegisub/libmedia/common/video_frame.cpp deleted file mode 100644 index 043dc9581..000000000 --- a/aegisub/libmedia/common/video_frame.cpp +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright (c) 2007, Rodrigo Braz Monteiro -// -// Permission to use, copy, modify, and distribute this software for any -// purpose with or without fee is hereby granted, provided that the above -// copyright notice and this permission notice appear in all copies. -// -// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -// -// $Id$ - -/// @file video_frame.cpp -/// @brief Wrapper around a frame of video data -/// @ingroup video -/// - -#include "config.h" - -#include "libmedia/video_frame.h" - -#ifndef LAGI_PRE -#include -#include -#endif - -namespace media { - -void AegiVideoFrame::Reset() { - // Zero variables - data = 0; - pitch = 0; - memSize = 0; - w = 0; - h = 0; - - // Set properties - flipped = false; - invertChannels = true; - ownMem = true; -} - -AegiVideoFrame::AegiVideoFrame() { - Reset(); -} - -/// @brief Create a solid black frame of the request size and format -/// @param width -/// @param height -AegiVideoFrame::AegiVideoFrame(unsigned int width, unsigned int height) { - assert(width > 0 && width < 10000); - assert(height > 0 && height < 10000); - - Reset(); - - // Set format - w = width; - h = height; - pitch = w * GetBpp(); - - Allocate(); - memset(data, 0, pitch * height); -} - -void AegiVideoFrame::Allocate() { - assert(pitch > 0 && pitch < 10000); - assert(w > 0 && w < 10000); - assert(h > 0 && h < 10000); - - unsigned int size = pitch * h; - - // Reallocate, if necessary - if (memSize != size || !ownMem) { - if (ownMem) { - delete[] data; - } - data = new unsigned char[size]; - memSize = size; - } - - ownMem = true; -} - -void AegiVideoFrame::Clear() { - if (ownMem) delete[] data; - Reset(); -} - -void AegiVideoFrame::CopyFrom(const AegiVideoFrame &source) { - w = source.w; - h = source.h; - pitch = source.pitch; - Allocate(); - memcpy(data, source.data, memSize); - flipped = source.flipped; - invertChannels = source.invertChannels; -} - -void AegiVideoFrame::SetTo(const unsigned char *source, unsigned int width, unsigned int height, unsigned int pitch) { - assert(pitch > 0 && pitch < 10000); - assert(width > 0 && width < 10000); - assert(height > 0 && height < 10000); - - ownMem = false; - w = width; - h = height; - // Note that despite this cast, the contents of data should still never be modified - data = const_cast(source); - this->pitch = pitch; -} - -} // namespace media diff --git a/aegisub/libmedia/common/video_manager.cpp b/aegisub/libmedia/common/video_manager.cpp deleted file mode 100644 index cebbc55ab..000000000 --- a/aegisub/libmedia/common/video_manager.cpp +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright (c) 2006, Rodrigo Braz Monteiro -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * 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. -// * Neither the name of the Aegisub Group nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. -// -// Aegisub Project http://www.aegisub.org/ -// -// $Id$ - -/// @file video_provider_manager.cpp -/// @brief Keep track of installed video providers -/// @ingroup video_input -/// - -#include "config.h" - -#ifndef MAGI_PRE -#include -#endif - -#include - -#include "libmedia/video.h" - -#ifdef WITH_AVISYNTH -#include "../video/avs_video.h" -#endif -#include "../cache/video_cache.h" -//XXX: needs fixing. #include "../video/dummy_video.h" -#ifdef WITH_FFMPEGSOURCE -#include "../video/ffms_video.h" -#endif -//XXX: needs fixing. #include "../video/yuv4mpeg.h" - -namespace media { - -/// @brief Get provider -/// @param video -/// @return -/// -VideoProvider *VideoProviderFactory::GetProvider(std::string video) { -//XXX std::vector list = GetClasses(OPT_GET("Video/Provider")->GetString()); - std::vector list = GetClasses("ffmpegsource"); - if (video.find("?dummy") == 0) list.insert(list.begin(), "Dummy"); - list.insert(list.begin(), "YUV4MPEG"); - - bool fileFound = false; - bool fileSupported = false; - std::string errors; - errors.reserve(1024); - for (int i = 0; i < (signed)list.size(); ++i) { - std::string err; - try { - VideoProvider *provider = Create(list[i], video); - LOG_I("manager/video/provider") << list[i] << ": opened " << video; - if (provider->WantsCaching()) { - return new VideoProviderCache(provider); - } - return provider; - } - catch (agi::FileNotFoundError const&) { - err = list[i] + ": file not found."; - // Keep trying other providers as this one may just not be able to - // open a valid path - } - catch (VideoNotSupported const&) { - fileFound = true; - err = list[i] + ": video is not in a supported format."; - } - catch (VideoOpenError const& ex) { - fileSupported = true; - err = list[i] + ": " + ex.GetMessage(); - } - catch (agi::vfr::Error const& ex) { - fileSupported = true; - err = list[i] + ": " + ex.GetMessage(); - } - errors += err; - errors += "\n"; - LOG_D("manager/video/provider") << err; - } - - // No provider could open the file - LOG_E("manager/video/provider") << "Could not open " << video; - std::string msg = "Could not open " + video + ":\n" + errors; - - if (!fileFound) throw agi::FileNotFoundError(video); - if (!fileSupported) throw VideoNotSupported(msg); - throw VideoOpenError(msg); -} - -/// @brief Register all providers -/// -void VideoProviderFactory::RegisterProviders() { -#ifdef WITH_AVISYNTH - Register("Avisynth"); -#endif -#ifdef WITH_FFMPEGSOURCE - Register("FFmpegSource"); -#endif -//XXX Register("Dummy", true); -//XXX Register("YUV4MPEG", true); -} - -template<> VideoProviderFactory::map *FactoryBase::classes = NULL; - -} // namespace media diff --git a/aegisub/libmedia/common/video_manager.h b/aegisub/libmedia/common/video_manager.h deleted file mode 100644 index 774856e73..000000000 --- a/aegisub/libmedia/common/video_manager.h +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (c) 2006-2008, Rodrigo Braz Monteiro, Fredrik Mellbin -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * 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. -// * Neither the name of the Aegisub Group nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. -// -// Aegisub Project http://www.aegisub.org/ -// -// $Id$ - -/// @file video_provider_manager.h -/// @see video_provider_manager.cpp -/// @ingroup video_input -/// - -#include "factory_manager.h" -#include "include/aegisub/video_provider.h" - -class VideoProviderFactory : public Factory1 { -public: - static VideoProvider *GetProvider(wxString video); - static void RegisterProviders(); -}; diff --git a/aegisub/libmedia/include/libmedia/audio.h b/aegisub/libmedia/include/libmedia/audio.h deleted file mode 100644 index de5cbdf67..000000000 --- a/aegisub/libmedia/include/libmedia/audio.h +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright (c) 2006, Rodrigo Braz Monteiro -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * 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. -// * Neither the name of the Aegisub Group nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. -// -// Aegisub Project http://www.aegisub.org/ -// -// $Id$ - -/// @file audio_provider.h -/// @brief Declaration of base-class for audio providers -/// @ingroup main_headers audio_input -/// - -#pragma once - -#include -#include -#include - -namespace media { - -/// @class AudioProvider -/// @brief DOCME -/// -/// DOCME -class AudioProvider { -private: - - /// DOCME - char *raw; - - /// DOCME - int raw_len; - -protected: - - /// DOCME - int channels; - - /// DOCME - int64_t num_samples; // for one channel, ie. number of PCM frames - - /// DOCME - int sample_rate; - - /// DOCME - int bytes_per_sample; - - - /// DOCME - std::string filename; - -public: - AudioProvider(); - virtual ~AudioProvider(); - - virtual std::string GetFilename() const { return filename; }; - virtual void GetAudio(void *buf, int64_t start, int64_t count) const = 0; - void GetAudioWithVolume(void *buf, int64_t start, int64_t count, double volume) const; - - int64_t GetNumSamples() const { return num_samples; } - int GetSampleRate() const { return sample_rate; } - int GetBytesPerSample() const { return bytes_per_sample; } - int GetChannels() const { return channels; } - virtual bool AreSamplesNativeEndian() const = 0; - - /// @brief Does this provider benefit from external caching? - virtual bool NeedsCache() const { return false; } -}; - -/// DOCME -/// @class AudioProviderFactory -/// @brief DOCME -/// -/// DOCME -class AudioProviderFactory : public Factory1 { -public: - static void RegisterProviders(); - static AudioProvider *GetProvider(std::string filename, agi::ProgressSinkFactory *progress_factory, int cache=-1); -}; - -DEFINE_BASE_EXCEPTION_NOINNER(AudioProviderError, agi::Exception); -DEFINE_SIMPLE_EXCEPTION_NOINNER(AudioOpenError, AudioProviderError, "audio/open/failed"); - -/// Error of some sort occurred while decoding a frame -DEFINE_SIMPLE_EXCEPTION_NOINNER(AudioDecodeError, AudioProviderError, "audio/error"); - -} // namespace media diff --git a/aegisub/libmedia/include/libmedia/colourspace.h b/aegisub/libmedia/include/libmedia/colourspace.h deleted file mode 100644 index cf28dc764..000000000 --- a/aegisub/libmedia/include/libmedia/colourspace.h +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright (c) 2005, Niels Martin Hansen -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * 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. -// * Neither the name of the Aegisub Group nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. -// -// Aegisub Project http://www.aegisub.org/ -// -// $Id$ - -/// @file colorspace.h -/// @see colorspace.cpp -/// @ingroup utility -/// - - -#ifndef AGI_PRE -#include -#endif - -namespace media { - -/// @brief DOCME -/// @param val -/// -inline unsigned int clip_colorval(int val) -{ - if (val < 0) return 0; - if (val > 255) return 255; - return val; -} - - -// Convert an YUV color to RGB; all values are expected to be in range 0..255 -void yuv_to_rgb(int Y, int U, int V, unsigned char *R, unsigned char *G, unsigned char *B); - -// Convert a HSL color to RGB; all values are expected to be in range 0..255 -void hsl_to_rgb(int H, int S, int L, unsigned char *R, unsigned char *G, unsigned char *B); - -// Convert a HSV color to RGB; all values are expected to be in range 0..255 -void hsv_to_rgb(int H, int S, int V, unsigned char *R, unsigned char *G, unsigned char *B); - -// Convert an RGB color to YUV; all values are expected to be in range 0..255 -void rgb_to_yuv(int R, int G, int B, unsigned char *Y, unsigned char *U, unsigned char *V); - -// Convert an RGB color to HSL; all values are expected to be in range 0..255 -void rgb_to_hsl(int R, int G, int B, unsigned char *H, unsigned char *S, unsigned char *L); - -// Convert an RGB color to HSV; all values are expected to be in range 0..255 -void rgb_to_hsv(int R, int G, int B, unsigned char *H, unsigned char *S, unsigned char *V); - -void hsv_to_hsl(int iH, int iS, int iV, unsigned char *oH, unsigned char *oS, unsigned char *oL); - -void hsl_to_hsv(int iH, int iS, int iL, unsigned char *oH, unsigned char *oS, unsigned char *oV); - - -// Convert a wxColour to a HTML hex string -std::string color_to_html(agi::Colour color); - -// Convert a HTML hex string to a wxColour -std::string html_to_color(agi::Colour html); - -} // namespace media diff --git a/aegisub/libmedia/include/libmedia/factory_manager.h b/aegisub/libmedia/include/libmedia/factory_manager.h deleted file mode 100644 index 9fdccc628..000000000 --- a/aegisub/libmedia/include/libmedia/factory_manager.h +++ /dev/null @@ -1,147 +0,0 @@ -// Copyright (c) 2010, Thomas Goyne -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * 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. -// * Neither the name of the Aegisub Group nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. -// -// Aegisub Project http://www.aegisub.org/ -// -// $Id$ - -/// @file factory_manager.h -/// @brief Template/base-class for factory classes -/// @ingroup utility -/// - -#pragma once - -#ifndef MAGI_PRE -#include -#include -#include -#include -#endif - -namespace media { - -template -class FactoryBase { -protected: - typedef std::map > map; - typedef typename map::iterator iterator; - - static map *classes; - - static void DoRegister(func function, std::string name, bool hide, std::vector &subtypes) { - if (!classes) classes = new map; - - if (subtypes.empty()) { - classes->insert(std::make_pair(name, std::make_pair(hide, function))); - } - else { - for (size_t i = 0; i < subtypes.size(); i++) { - classes->insert(std::make_pair(name + '/' + subtypes[i], std::make_pair(hide, function))); - } - } - } - - static func Find(std::string name) { - if (!classes) return NULL; - - iterator factory = classes->find(name); - if (factory != classes->end()) return factory->second.second; - return NULL; - } - -public: - static void Clear() { - delete classes; - } - static std::vector GetClasses(std::string favourite="") { - std::vector list; - if (!classes) return list; - std::string cmp; - std::transform(favourite.begin(), favourite.end(), favourite.begin(), ::tolower); - for (iterator cur=classes->begin();cur!=classes->end();cur++) { - cmp.clear(); - std::transform(cur->first.begin(), cur->first.end(), std::back_inserter(cmp), ::tolower); - if (cmp == favourite) list.insert(list.begin(), cur->first); - else if (!cur->second.first) list.push_back(cur->first); - } - return list; - } - virtual ~FactoryBase() { - delete classes; - } -}; - -template -class Factory0 : public FactoryBase { - typedef Base *(*func)(); - template - static Base* create() { - return new T; - } -public: - static Base* Create(std::string name) { - func factory = FactoryBase::Find(name); - if (factory) { - return factory(); - } - else { - return NULL; - } - } - - template - static void Register(std::string name, bool hide = false, std::vector subTypes = std::vector()) { - DoRegister(&Factory0::template create, name, hide, subTypes); - } -}; - -template -class Factory1 : public FactoryBase { - typedef Base *(*func)(Arg1); - template - static Base* create(Arg1 a1) { - return new T(a1); - } -public: - static Base* Create(std::string name, Arg1 a1) { - func factory = FactoryBase::Find(name); - if (factory) { - return factory(a1); - } - else { - return NULL; - } - } - - template - static void Register(std::string name, bool hide = false, std::vector subTypes = std::vector()) { - DoRegister(&Factory1::template create, name, hide, subTypes); - } -}; - -} // namespace media diff --git a/aegisub/libmedia/include/libmedia/video.h b/aegisub/libmedia/include/libmedia/video.h deleted file mode 100644 index 8df9b34d9..000000000 --- a/aegisub/libmedia/include/libmedia/video.h +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright (c) 2006-2008, Rodrigo Braz Monteiro, Fredrik Mellbin -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * 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. -// * Neither the name of the Aegisub Group nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. -// -// Aegisub Project http://www.aegisub.org/ -// -// $Id$ - -/// @file video_provider.h -/// @brief Declaration of base-class for video providers -/// @ingroup main_headers video_input -/// - -#pragma once - -#ifndef MAGI_PRE -#include -#endif - -#include -#include -#include -#include - - -namespace media { - -/// @class VideoProvider -/// @brief DOCME -/// -/// DOCME -class VideoProvider { -public: - virtual ~VideoProvider() {} - - // Override this method to actually get frames - virtual const AegiVideoFrame GetFrame(int n)=0; - - // Override the following methods to get video information: - virtual int GetPosition() const=0; ///< Get the number of the last frame loaded - virtual int GetFrameCount() const=0; ///< Get total number of frames - virtual int GetWidth() const=0; ///< Returns the video width in pixels - virtual int GetHeight() const=0; ///< Returns the video height in pixels - virtual agi::vfr::Framerate GetFPS() const=0; ///< Get frame rate - virtual std::vector GetKeyFrames() const=0;///< Returns list of keyframes - - - /// @brief Use this to set any post-loading warnings, such as "being loaded with unreliable seeking" - virtual std::string GetWarning() const { return ""; } - - /// @brief Name of decoder, e.g. "Avisynth/FFMpegSource" - virtual std::string GetDecoderName() const = 0; - - /// @brief Does this provider want Aegisub to cache video frames? - /// @return Returns true if caching is desired, false otherwise. - virtual bool WantsCaching() const { return false; } -}; - - -class VideoProviderFactory : public Factory1 { -public: - static VideoProvider *GetProvider(std::string video); - static void RegisterProviders(); -}; - - -DEFINE_BASE_EXCEPTION_NOINNER(VideoProviderError, agi::Exception); -/// File could be opened, but is not a supported format -DEFINE_SIMPLE_EXCEPTION_NOINNER(VideoNotSupported, VideoProviderError, "video/open/notsupported"); -/// File appears to be a supported format, but could not be opened -DEFINE_SIMPLE_EXCEPTION_NOINNER(VideoOpenError, VideoProviderError, "video/open/failed"); - -/// Error of some sort occurred while decoding a frame -DEFINE_SIMPLE_EXCEPTION_NOINNER(VideoDecodeError, VideoProviderError, "video/error"); - - -} // namespace media - diff --git a/aegisub/libmedia/include/libmedia/video_frame.h b/aegisub/libmedia/include/libmedia/video_frame.h deleted file mode 100644 index 906dbe4a4..000000000 --- a/aegisub/libmedia/include/libmedia/video_frame.h +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright (c) 2007, Rodrigo Braz Monteiro -// -// Permission to use, copy, modify, and distribute this software for any -// purpose with or without fee is hereby granted, provided that the above -// copyright notice and this permission notice appear in all copies. -// -// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -// -// $Id$ - -/// @file media_video_frame.h -/// @see media_video_frame.cpp -/// @ingroup video -/// - -#ifndef LAGI_PRE -#endif - -namespace media { - -/// DOCME -/// @class AegiVideoFrame -/// @brief DOCME -/// -/// DOCME -class AegiVideoFrame { - /// Whether the object owns its buffer. If this is false, **data should never be modified - bool ownMem; - /// @brief Reset values to the defaults - /// - /// Note that this function DOES NOT deallocate memory. - /// Use Clear() for that - void Reset(); - -public: - /// @brief Allocate memory if needed - void Allocate(); - - /// The size in bytes of the frame buffer - unsigned int memSize; - - /// Pointer to the data planes - unsigned char *data; - - /// Width in pixels - unsigned int w; - - /// Height in pixels - unsigned int h; - - // Pitch, that is, the number of bytes used by each row. - unsigned int pitch; - - /// First row is actually the bottom one - bool flipped; - - /// Swap Red and Blue channels (controls RGB versus BGR ordering etc) - bool invertChannels; - - AegiVideoFrame(); - AegiVideoFrame(unsigned int width, unsigned int height); - - // @brief Clear this frame, freeing its memory if nessesary - void Clear(); - - /// @brief Copy from an AegiVideoFrame - /// @param source The frame to copy from - void CopyFrom(const AegiVideoFrame &source); - - /// @brief Set the frame to an externally allocated block of memory - /// @param source Target frame data - /// @param width The frame width in pixels - /// @param height The frame height in pixels - /// @param pitch The frame's pitch - /// @param format The frame's format - void SetTo(const unsigned char *source, unsigned int width, unsigned int height, unsigned int pitch); - - int GetBpp() const { return 4; }; -}; - -} // namespace media diff --git a/aegisub/libmedia/magi_pre.h b/aegisub/libmedia/magi_pre.h deleted file mode 100644 index 545cfe945..000000000 --- a/aegisub/libmedia/magi_pre.h +++ /dev/null @@ -1,57 +0,0 @@ -#define LAGI_PRE - -#include "config.h" - -// Common C -#include -#include -#include -#include -#include -#include -#include -#ifdef HAVE_SYS_TIME_H -# include -#else -# include -#endif - -// Windows C -#ifdef _WIN32 -#define WIN32_LEAN_AND_MEAN -#include -#include -#endif - -// Common C++ -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef _WIN32 -#include -#include -#else -#include -#include -#endif - -#ifdef __DEPRECATED // Dodge GCC warnings -# undef __DEPRECATED -# include -# define __DEPRECATED -#else -# include -#endif - -// Cajun -#include "libaegisub/cajun/elements.h" -#include "libaegisub/cajun/reader.h" -#include "libaegisub/cajun/visitor.h" -#include "libaegisub/cajun/writer.h" - diff --git a/aegisub/libmedia/subtitle/csri.cpp b/aegisub/libmedia/subtitle/csri.cpp deleted file mode 100644 index 47a0482ce..000000000 --- a/aegisub/libmedia/subtitle/csri.cpp +++ /dev/null @@ -1,147 +0,0 @@ -// Copyright (c) 2007, Rodrigo Braz Monteiro -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * 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. -// * Neither the name of the Aegisub Group nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. -// -// Aegisub Project http://www.aegisub.org/ -// -// $Id$ - -/// @file subtitles_provider_csri.cpp -/// @brief Wrapper for CSRI-based subtitle renderers -/// @ingroup subtitle_rendering -/// - -#include "config.h" - -#ifdef WITH_CSRI - -#include "ass_file.h" -#include "subtitles_provider_csri.h" -#include "text_file_writer.h" -#include "video_context.h" -#include "video_frame.h" - -/// @brief Constructor -/// @param type -/// -CSRISubtitlesProvider::CSRISubtitlesProvider(std::string type) : subType(type) { -} - -/// @brief Destructor -/// -CSRISubtitlesProvider::~CSRISubtitlesProvider() { - if (!tempfile.empty()) wxRemoveFile(tempfile); -} - -/// @brief Load subtitles -/// @param subs -/// -void CSRISubtitlesProvider::LoadSubtitles(AssFile *subs) { - // CSRI variables - csri_rend *cur,*renderer=NULL; - - // Select renderer - bool canOpenMem = true; - for (cur = csri_renderer_default();cur;cur=csri_renderer_next(cur)) { - std::string name(csri_renderer_info(cur)->name); - if (name == subType) { - renderer = cur; - if (name.find("vsfilter") != name.npos) canOpenMem = false; - break; - } - } - - // Matching renderer not found, fallback to default - if (!renderer) { - renderer = csri_renderer_default(); - if (!renderer) { - throw _T("No CSRI renderer available, cannot show subtitles. Try installing one or switch to another subtitle provider."); - } - } - - // Open from memory - if (canOpenMem) { - std::vector data; - subs->SaveMemory(data,wxSTRING_ENCODING); - instance.reset(csri_open_mem(renderer,&data[0],data.size(),NULL), &csri_close); - } - - // Open from disk - else { - if (tempfile.empty()) { - tempfile = wxFileName::CreateTempFileName(_T("aegisub")); - wxRemoveFile(tempfile); - tempfile += L".ass"; - } - subs->Save(tempfile,false,false,wxSTRING_ENCODING); - instance.reset(csri_open_file(renderer,tempfile.utf8_str(),NULL), &csri_close); - } -} - -/// @brief Draw subtitles -/// @param dst -/// @param time -/// @return -/// -void CSRISubtitlesProvider::DrawSubtitles(AegiVideoFrame &dst,double time) { - // Check if CSRI loaded properly - if (!instance.get()) return; - - // Load data into frame - csri_frame frame; - if (dst.flipped) { - frame.planes[0] = dst.data + (dst.h-1) * dst.pitch; - frame.strides[0] = -(signed)dst.pitch; - } - else { - frame.planes[0] = dst.data; - frame.strides[0] = dst.pitch; - } - frame.pixfmt = CSRI_F_BGR_; - - // Set format - csri_fmt format; - format.width = dst.w; - format.height = dst.h; - format.pixfmt = frame.pixfmt; - int error = csri_request_fmt(instance.get(),&format); - if (error) return; - - // Render - csri_render(instance.get(),&frame,time); -} - -/// @brief Get CSRI subtypes -/// -std::vector CSRISubtitlesProvider::GetSubTypes() { - std::vector final; - for (csri_rend *cur = csri_renderer_default();cur;cur = csri_renderer_next(cur)) { - final.push_back(csri_renderer_info(cur)->name); - } - return final; -} - -#endif // WITH_CSRI diff --git a/aegisub/libmedia/subtitle/csri.h b/aegisub/libmedia/subtitle/csri.h deleted file mode 100644 index 8800d5046..000000000 --- a/aegisub/libmedia/subtitle/csri.h +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright (c) 2007, Rodrigo Braz Monteiro -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * 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. -// * Neither the name of the Aegisub Group nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. -// -// Aegisub Project http://www.aegisub.org/ -// -// $Id$ - -/// @file subtitles_provider_csri.h -/// @see subtitles_provider_csri.cpp -/// @ingroup subtitle_rendering -/// - -#ifdef WITH_CSRI - -#ifndef AGI_PRE -#include -#include -#endif - -#include "include/aegisub/subtitles_provider.h" -#ifdef WIN32 -#define CSRIAPI -#include "../../contrib/csri/include/csri/csri.h" -#else -#include -#endif - -/// DOCME -/// @class CSRISubtitlesProvider -/// @brief DOCME -/// -/// DOCME -class CSRISubtitlesProvider : public SubtitlesProvider { - /// DOCME - std::string subType; - - /// DOCME - std::tr1::shared_ptr instance; - - wxString tempfile; -public: - CSRISubtitlesProvider(std::string subType); - ~CSRISubtitlesProvider(); - - void LoadSubtitles(AssFile *subs); - void DrawSubtitles(AegiVideoFrame &dst,double time); - - static std::vector GetSubTypes(); -}; -#endif diff --git a/aegisub/libmedia/subtitle/libass.cpp b/aegisub/libmedia/subtitle/libass.cpp deleted file mode 100644 index c01208b25..000000000 --- a/aegisub/libmedia/subtitle/libass.cpp +++ /dev/null @@ -1,252 +0,0 @@ -// Copyright (c) 2006-2007, Rodrigo Braz Monteiro, Evgeniy Stepanov -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * 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. -// * Neither the name of the Aegisub Group nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. -// -// Aegisub Project http://www.aegisub.org/ -// -// $Id$ - -/// @file subtitles_provider_libass.cpp -/// @brief libass-based subtitle renderer -/// @ingroup subtitle_rendering -/// - -#include "config.h" - -#ifdef WITH_LIBASS - -#ifndef AGI_PRE -#include -#include -#endif - -#ifdef __APPLE__ -#include -#include -#endif - -#include - -#include "ass_file.h" -#include "dialog_progress.h" -#include "frame_main.h" -#include "main.h" -#include "standard_paths.h" -#include "subtitles_provider_libass.h" -#include "utils.h" -#include "video_context.h" -#include "video_frame.h" - - -/// @brief Handle libass messages -/// -static void msg_callback(int level, const char *fmt, va_list args, void *) { - if (level >= 7) return; - char buf[1024]; -#ifdef _WIN32 - vsprintf_s(buf, sizeof(buf), fmt, args); -#else - vsnprintf(buf, sizeof(buf), fmt, args); -#endif - - if (level < 2) // warning/error - LOG_I("subtitle/provider/libass") << buf; - else // verbose - LOG_D("subtitle/provider/libass") << buf; -} - -class FontConfigCacheThread : public wxThread { - ASS_Library *ass_library; - ASS_Renderer *ass_renderer; - FontConfigCacheThread** thisPtr; - ExitCode Entry() { -#ifdef __APPLE__ - char config_path[MAXPATHLEN]; - char *config_dir; - - config_dir = agi::util::OSX_GetBundleResourcesDirectory(); - snprintf(config_path, MAXPATHLEN, "%s/etc/fonts/fonts.conf", config_dir); - free(config_dir); -#else - const char *config_path = NULL; -#endif - - if (ass_library) ass_renderer = ass_renderer_init(ass_library); - ass_set_fonts(ass_renderer, NULL, "Sans", 1, config_path, true); - if (ass_library) ass_renderer_done(ass_renderer); - *thisPtr = NULL; - return EXIT_SUCCESS; - } -public: - FontConfigCacheThread(ASS_Library *ass_library, FontConfigCacheThread **thisPtr) - : ass_library(ass_library) - , ass_renderer(NULL) - , thisPtr(thisPtr) - { - *thisPtr = this; - Create(); - Run(); - } - FontConfigCacheThread(ASS_Renderer *ass_renderer, FontConfigCacheThread **thisPtr) - : ass_library(NULL) - , ass_renderer(ass_renderer) - , thisPtr(thisPtr) - { - *thisPtr = this; - Create(); - Run(); - } -}; - -static void wait_for_cache_thread(FontConfigCacheThread const * const * const cache_worker) { - if (!*cache_worker) return; - - bool canceled; - DialogProgress *progress = new DialogProgress(AegisubApp::Get()->frame, L"", &canceled, L"Caching fonts", 0, 1); - progress->Show(); - while (*cache_worker) { - if (canceled) throw agi::UserCancelException("Font caching cancelled"); - progress->Pulse(); - wxYield(); - wxMilliSleep(100); - } - progress->Destroy(); -} - -/// @brief Constructor -/// -LibassSubtitlesProvider::LibassSubtitlesProvider(std::string) { - wait_for_cache_thread(&cache_worker); - - // Initialize renderer - ass_track = NULL; - ass_renderer = ass_renderer_init(ass_library); - if (!ass_renderer) throw _T("ass_renderer_init failed"); - ass_set_font_scale(ass_renderer, 1.); - new FontConfigCacheThread(ass_renderer, &cache_worker); - wait_for_cache_thread(&cache_worker); -} - -/// @brief Destructor -/// -LibassSubtitlesProvider::~LibassSubtitlesProvider() { - if (ass_track) ass_free_track(ass_track); - if (ass_renderer) ass_renderer_done(ass_renderer); -} - -/// @brief Load subtitles -/// @param subs -/// -void LibassSubtitlesProvider::LoadSubtitles(AssFile *subs) { - // Prepare subtitles - std::vector data; - subs->SaveMemory(data,_T("UTF-8")); - - // Load file - if (ass_track) ass_free_track(ass_track); - ass_track = ass_read_memory(ass_library, &data[0], data.size(),(char *)"UTF-8"); - if (!ass_track) throw _T("libass failed to load subtitles."); -} - -/// DOCME -#define _r(c) ((c)>>24) - -/// DOCME -#define _g(c) (((c)>>16)&0xFF) - -/// DOCME -#define _b(c) (((c)>>8)&0xFF) - -/// DOCME -#define _a(c) ((c)&0xFF) - - -/// @brief Draw subtitles -/// @param frame -/// @param time -/// @return -/// -void LibassSubtitlesProvider::DrawSubtitles(AegiVideoFrame &frame,double time) { - // Set size - ass_set_frame_size(ass_renderer, frame.w, frame.h); - - // Get frame - ASS_Image* img = ass_render_frame(ass_renderer, ass_track, int(time * 1000), NULL); - - // libass actually returns several alpha-masked monochrome images. - // Here, we loop through their linked list, get the colour of the current, and blend into the frame. - // This is repeated for all of them. - while (img) { - // Get colours - unsigned int opacity = 255 - ((unsigned int)_a(img->color)); - unsigned int r = (unsigned int)_r(img->color); - unsigned int g = (unsigned int)_g(img->color); - unsigned int b = (unsigned int) _b(img->color); - - // Prepare copy - int src_stride = img->stride; - int dst_stride = frame.pitch; - int dst_delta = dst_stride - img->w*4; - //int stride = std::min(src_stride,dst_stride); - const unsigned char *src = img->bitmap; - unsigned char *dst = frame.data + (img->dst_y * dst_stride + img->dst_x * 4); - unsigned int k,ck,t; - - // Copy image to destination frame - for (int y=0;yh;y++) { - //memcpy(dst,src,stride); - for (int x = 0; x < img->w; ++x) { - k = ((unsigned)src[x]) * opacity / 255; - ck = 255 - k; - t = *dst; - *dst++ = (k*b + ck*t) / 255; - t = *dst; - *dst++ = (k*g + ck*t) / 255; - t = *dst; - *dst++ = (k*r + ck*t) / 255; - dst++; - } - - dst += dst_delta; - src += src_stride; - } - - // Next image - img = img->next; - } -} - -void LibassSubtitlesProvider::CacheFonts() { - ass_library = ass_library_init(); - ass_set_message_cb(ass_library, msg_callback, NULL); - new FontConfigCacheThread(ass_library, &cache_worker); -} - -/// DOCME -ASS_Library* LibassSubtitlesProvider::ass_library; -FontConfigCacheThread* LibassSubtitlesProvider::cache_worker = NULL; - -#endif // WITH_LIBASS diff --git a/aegisub/libmedia/subtitle/libass.h b/aegisub/libmedia/subtitle/libass.h deleted file mode 100644 index d093bea59..000000000 --- a/aegisub/libmedia/subtitle/libass.h +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright (c) 2006-2007, Rodrigo Braz Monteiro, Evgeniy Stepanov -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * 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. -// * Neither the name of the Aegisub Group nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. -// -// Aegisub Project http://www.aegisub.org/ -// -// $Id$ - -/// @file subtitles_provider_libass.h -/// @see subtitles_provider_libass.cpp -/// @ingroup subtitle_rendering -/// - -#ifdef WITH_LIBASS - -#include "include/aegisub/subtitles_provider.h" -extern "C" { -#ifdef __VISUALC__ -#include "stdint.h" -#endif - -#include "../libass/ass.h" -} - -class FontConfigCacheThread; - -/// DOCME -/// @class LibassSubtitlesProvider -/// @brief DOCME -/// -/// DOCME -class LibassSubtitlesProvider : public SubtitlesProvider { - /// DOCME - static ASS_Library* ass_library; - - /// DOCME - ASS_Renderer* ass_renderer; - - /// DOCME - ASS_Track* ass_track; - - static FontConfigCacheThread *cache_worker; - -public: - LibassSubtitlesProvider(std::string); - ~LibassSubtitlesProvider(); - - void LoadSubtitles(AssFile *subs); - void DrawSubtitles(AegiVideoFrame &dst,double time); - - static void CacheFonts(); -}; -#endif diff --git a/aegisub/libmedia/video/avs_video.cpp b/aegisub/libmedia/video/avs_video.cpp deleted file mode 100644 index b06c6ca6d..000000000 --- a/aegisub/libmedia/video/avs_video.cpp +++ /dev/null @@ -1,295 +0,0 @@ -// Copyright (c) 2006, Fredrik Mellbin -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * 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. -// * Neither the name of the Aegisub Group nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. -// -// Aegisub Project http://www.aegisub.org/ -// -// $Id$ - -/// @file video_provider_avs.cpp -/// @brief Avisynth-based video provider -/// @ingroup video_input -/// - -#include "config.h" - -#ifdef WITH_AVISYNTH -#ifndef AGI_PRE -#include -#include -#endif - -#include "charset_conv.h" -#include "compat.h" -#include "gl_wrap.h" -#include -#include "mkv_wrap.h" -#include "standard_paths.h" -#include "vfw_wrap.h" -#include "video_context.h" -#include "video_provider_avs.h" - -namespace media { - -/// @brief Constructor -/// @param _filename -/// -AvisynthVideoProvider::AvisynthVideoProvider(wxString filename) try -: usedDirectShow(false) -, decoderName(_("Unknown")) -, num_frames(0) -, last_fnum(-1) -, RGB32Video(NULL) -{ - RGB32Video = OpenVideo(filename); - - vi = RGB32Video->GetVideoInfo(); -} -catch (AvisynthError const& err) { - throw VideoOpenError("Avisynth error: " + std::string(err.msg)); -} - -/// @brief Destructor -AvisynthVideoProvider::~AvisynthVideoProvider() { - iframe.Clear(); -} - -AVSValue AvisynthVideoProvider::Open(wxFileName const& fname, wxString const& extension) { - char *videoFilename = env->SaveString(fname.GetShortPath().mb_str(csConvLocal)); - - // Avisynth file, just import it - if (extension == L".avs") { - LOG_I("avisynth/video") << "Opening .avs file with Import"; - decoderName = L"Import"; - return env->Invoke("Import", videoFilename); - } - - // Open avi file with AviSource - if (extension == L".avi") { - LOG_I("avisynth/video") << "Opening .avi file with AviSource"; - try { - const char *argnames[2] = { 0, "audio" }; - AVSValue args[2] = { videoFilename, false }; - decoderName = L"AviSource"; - return env->Invoke("AviSource", AVSValue(args,2), argnames); - } - - // On Failure, fallback to DSS - catch (AvisynthError &) { - LOG_I("avisynth/video") << "Failed to open .avi file with AviSource, switching to DirectShowSource"; - } - } - - // Open d2v with mpeg2dec3 - if (extension == L".d2v" && env->FunctionExists("Mpeg2Dec3_Mpeg2Source")) { - LOG_I("avisynth/video") << "Opening .d2v file with Mpeg2Dec3_Mpeg2Source"; - AVSValue script = env->Invoke("Mpeg2Dec3_Mpeg2Source", videoFilename); - decoderName = L"Mpeg2Dec3_Mpeg2Source"; - - //if avisynth is 2.5.7 beta 2 or newer old mpeg2decs will crash without this - if (env->FunctionExists("SetPlanarLegacyAlignment")) { - AVSValue args[2] = { script, true }; - script = env->Invoke("SetPlanarLegacyAlignment", AVSValue(args,2)); - } - return script; - } - - // If that fails, try opening it with DGDecode - if (extension == L".d2v" && env->FunctionExists("DGDecode_Mpeg2Source")) { - LOG_I("avisynth/video") << "Opening .d2v file with DGDecode_Mpeg2Source"; - decoderName = L"DGDecode_Mpeg2Source"; - return env->Invoke("Mpeg2Source", videoFilename); - - //note that DGDecode will also have issues like if the version is too ancient but no sane person - //would use that anyway - } - - if (extension == L".d2v" && env->FunctionExists("Mpeg2Source")) { - LOG_I("avisynth/video") << "Opening .d2v file with other Mpeg2Source"; - AVSValue script = env->Invoke("Mpeg2Source", videoFilename); - decoderName = L"Mpeg2Source"; - - //if avisynth is 2.5.7 beta 2 or newer old mpeg2decs will crash without this - if (env->FunctionExists("SetPlanarLegacyAlignment")) - script = env->Invoke("SetPlanarLegacyAlignment", script); - - return script; - } - - // Try loading DirectShowSource2 - if (!env->FunctionExists("dss2")) { - wxFileName dss2path(StandardPaths::DecodePath(_T("?data/avss.dll"))); - if (dss2path.FileExists()) { - env->Invoke("LoadPlugin",env->SaveString(dss2path.GetFullPath().mb_str(csConvLocal))); - } - } - - // If DSS2 loaded properly, try using it - if (env->FunctionExists("dss2")) { - LOG_I("avisynth/video") << "Opening file with DSS2"; - decoderName = L"DSS2"; - return env->Invoke("DSS2", videoFilename); - } - - // Try DirectShowSource - // Load DirectShowSource.dll from app dir if it exists - wxFileName dsspath(StandardPaths::DecodePath(_T("?data/DirectShowSource.dll"))); - if (dsspath.FileExists()) { - env->Invoke("LoadPlugin",env->SaveString(dsspath.GetFullPath().mb_str(csConvLocal))); - } - - // Then try using DSS - if (env->FunctionExists("DirectShowSource")) { - const char *argnames[3] = { 0, "video", "audio" }; - AVSValue args[3] = { videoFilename, true, false }; - usedDirectShow = true; - decoderName = L"DirectShowSource"; - LOG_I("avisynth/video") << "Opening file with DirectShowSource"; - return env->Invoke("DirectShowSource", AVSValue(args,3), argnames); - } - - // Failed to find a suitable function - LOG_E("avisynth/video") << "DSS function not found"; - throw VideoNotSupported("No function suitable for opening the video found"); -} - -/// @brief Actually open the video into Avisynth -/// @param _filename -/// @return -/// -PClip AvisynthVideoProvider::OpenVideo(wxString filename) { - wxMutexLocker lock(AviSynthMutex); - - wxFileName fname(filename); - if (!fname.FileExists()) - throw agi::FileNotFoundError(STD_STR(filename)); - - AVSValue script; - wxString extension = filename.Right(4).Lower(); - try { - script = Open(fname, extension); - } - catch (AvisynthError const& err) { - throw VideoOpenError("Avisynth error: " + std::string(err.msg)); - } - - // Check if video was loaded properly - if (!script.IsClip() || !script.AsClip()->GetVideoInfo().HasVideo()) { - throw VideoNotSupported("No usable video found"); - } - - // Read keyframes and timecodes from MKV file - bool mkvOpen = MatroskaWrapper::wrapper.IsOpen(); - KeyFrames.clear(); - if (extension == L".mkv" || mkvOpen) { - // Parse mkv - if (!mkvOpen) MatroskaWrapper::wrapper.Open(filename); - - // Get keyframes - KeyFrames = MatroskaWrapper::wrapper.GetKeyFrames(); - - MatroskaWrapper::wrapper.SetToTimecodes(vfr_fps); - - // Close mkv - MatroskaWrapper::wrapper.Close(); - } -// check if we have windows, if so we can load keyframes from AVI files using VFW -#ifdef __WINDOWS__ - else if (extension == L".avi") { - KeyFrames.clear(); - KeyFrames = VFWWrapper::GetKeyFrames(filename); - } -#endif /* __WINDOWS__ */ - - // Check if the file is all keyframes - bool isAllKeyFrames = true; - for (unsigned int i=1; iInvoke("ConvertToRGB32", script); - - // Cache - return (env->Invoke("Cache", script)).AsClip(); -} - -/// @brief Actually get a frame -/// @param _n -/// @return -/// -const AegiVideoFrame AvisynthVideoProvider::GetFrame(int n) { - if (vfr_fps.IsLoaded()) { - n = real_fps.FrameAtTime(vfr_fps.TimeAtFrame(n)); - } - // Get avs frame - wxMutexLocker lock(AviSynthMutex); - PVideoFrame frame = RGB32Video->GetFrame(n,env); - int Bpp = vi.BitsPerPixel() / 8; - - // Aegisub's video frame - AegiVideoFrame &final = iframe; - final.flipped = true; - final.invertChannels = true; - - // Set size properties - final.pitch = frame->GetPitch(); - final.w = frame->GetRowSize() / Bpp; - final.h = frame->GetHeight(); - - // Allocate - final.Allocate(); - - // Copy - memcpy(final.data,frame->GetReadPtr(),final.pitch * final.h); - - // Set last number - last_fnum = n; - return final; -} - -/// @brief Get warning -/// -wxString AvisynthVideoProvider::GetWarning() const { - if (usedDirectShow) return L"Warning! The file is being opened using Avisynth's DirectShowSource, which has unreliable seeking. Frame numbers might not match the real number. PROCEED AT YOUR OWN RISK!"; - else return L""; -} - -#endif - -} // namespace media diff --git a/aegisub/libmedia/video/avs_video.h b/aegisub/libmedia/video/avs_video.h deleted file mode 100644 index 358fbe054..000000000 --- a/aegisub/libmedia/video/avs_video.h +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright (c) 2006, Fredrik Mellbin -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * 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. -// * Neither the name of the Aegisub Group nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. -// -// Aegisub Project http://www.aegisub.org/ -// -// $Id$ - -/// @file video_provider_avs.h -/// @see video_provider_avs.cpp -/// @ingroup video_input -/// - -#ifdef WITH_AVISYNTH -#include "avisynth_wrap.h" -#include "include/aegisub/video_provider.h" - -namespace media { - -/// DOCME -/// @class AvisynthVideoProvider -/// @brief DOCME -/// -/// DOCME -class AvisynthVideoProvider: public VideoProvider, AviSynthWrapper { - /// DOCME - VideoInfo vi; - - /// DOCME - AegiVideoFrame iframe; - - - /// DOCME - bool usedDirectShow; - - /// DOCME - wxString rendererCallString; - - /// DOCME - wxString decoderName; - - - /// DOCME - int num_frames; - - /// DOCME - int last_fnum; - - - /// DOCME - agi::vfr::Framerate real_fps; - agi::vfr::Framerate vfr_fps; - - /// DOCME - std::vector KeyFrames; - - /// DOCME - PClip RGB32Video; - - PClip OpenVideo(wxString filename); - AVSValue Open(wxFileName const& fname, wxString const& extension); - -public: - AvisynthVideoProvider(wxString filename); - ~AvisynthVideoProvider(); - - const AegiVideoFrame GetFrame(int n); - - int GetPosition() const { return last_fnum; }; - int GetFrameCount() const { return num_frames? num_frames: vi.num_frames; }; - agi::vfr::Framerate GetFPS() const { return vfr_fps.IsLoaded() ? vfr_fps : real_fps; }; - int GetWidth() const { return vi.width; }; - int GetHeight() const { return vi.height; }; - std::vector GetKeyFrames() const { return KeyFrames; }; - wxString GetWarning() const; - wxString GetDecoderName() const { return wxString(L"Avisynth/") + decoderName; } -}; -#endif - -} // namespace media - diff --git a/aegisub/libmedia/video/dummy_video.cpp b/aegisub/libmedia/video/dummy_video.cpp deleted file mode 100644 index f715e4441..000000000 --- a/aegisub/libmedia/video/dummy_video.cpp +++ /dev/null @@ -1,223 +0,0 @@ -// Copyright (c) 2007, Rodrigo Braz Monteiro -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * 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. -// * Neither the name of the Aegisub Group nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. -// -// Aegisub Project http://www.aegisub.org/ -// -// $Id$ - -/// @file video_provider_dummy.cpp -/// @brief Video provider returning a constant frame -/// @ingroup video_input -/// - -#include "config.h" - -#ifndef AGI_PRE -#include -#endif - -#include "colorspace.h" -#include "video_provider_dummy.h" - -namespace media { - -/// @brief Constructor -/// @param _fps -/// @param frames -/// @param _width -/// @param _height -/// @param colour -/// @param pattern -/// -void DummyVideoProvider::Create(double _fps, int frames, int _width, int _height, const wxColour &colour, bool pattern) { - lastFrame = -1; - framecount = frames; - fps = _fps; - width = _width; - height = _height; - - frame = AegiVideoFrame(width,height); - unsigned char *dst = frame.data; - unsigned char r = colour.Red(), g = colour.Green(), b = colour.Blue(); - - unsigned char h, s, l, lr, lg, lb; // light variants - rgb_to_hsl(r, g, b, &h, &s, &l); - l += 24; - if (l < 24) l -= 48; - hsl_to_rgb(h, s, l, &lr, &lg, &lb); - - if (pattern) { - int ppitch = frame.pitch / frame.GetBpp(); - for (unsigned int y = 0; y < frame.h; ++y) { - if ((y / 8) & 1) { - for (int x = 0; x < ppitch; ++x) { - if ((x / 8) & 1) { - *dst++ = b; - *dst++ = g; - *dst++ = r; - *dst++ = 0; - } - else { - *dst++ = lb; - *dst++ = lg; - *dst++ = lr; - *dst++ = 0; - } - } - } - else { - for (int x = 0; x < ppitch; ++x) { - if ((x / 8) & 1) { - *dst++ = lb; - *dst++ = lg; - *dst++ = lr; - *dst++ = 0; - } - else { - *dst++ = b; - *dst++ = g; - *dst++ = r; - *dst++ = 0; - } - } - } - } - } - else { - for (int i=frame.pitch*frame.h/frame.GetBpp();--i>=0;) { - *dst++ = b; - *dst++ = g; - *dst++ = r; - *dst++ = 0; - } - } -} - -/// @brief Parsing constructor -/// @param filename -/// -DummyVideoProvider::DummyVideoProvider(wxString filename) -{ - wxString params; - if (!filename.StartsWith(_T("?dummy:"), ¶ms)) { - throw agi::FileNotFoundError("Attempted creating dummy video provider with non-dummy filename"); - } - - wxStringTokenizer t(params, _T(":")); - if (t.CountTokens() < 7) { - throw VideoOpenError("Too few fields in dummy video parameter list"); - } - - double fps; - long _frames, _width, _height, red, green, blue; - bool pattern = false; - - wxString field = t.GetNextToken(); - if (!field.ToDouble(&fps)) { - throw VideoOpenError("Unable to parse fps field in dummy video parameter list"); - } - - field = t.GetNextToken(); - if (!field.ToLong(&_frames)) { - throw VideoOpenError("Unable to parse framecount field in dummy video parameter list"); - } - - field = t.GetNextToken(); - if (!field.ToLong(&_width)) { - throw VideoOpenError("Unable to parse width field in dummy video parameter list"); - } - - field = t.GetNextToken(); - if (!field.ToLong(&_height)) { - throw VideoOpenError("Unable to parse height field in dummy video parameter list"); - } - - field = t.GetNextToken(); - if (!field.ToLong(&red)) { - throw VideoOpenError("Unable to parse red colour field in dummy video parameter list"); - } - - field = t.GetNextToken(); - if (!field.ToLong(&green)) { - throw VideoOpenError("Unable to parse green colour field in dummy video parameter list"); - } - - field = t.GetNextToken(); - if (!field.ToLong(&blue)) { - throw VideoOpenError("Unable to parse blue colour field in dummy video parameter list"); - } - - field = t.GetNextToken(); - if (field == _T("c")) { - pattern = true; - } - - Create(fps, _frames, _width, _height, wxColour(red, green, blue), pattern); -} - -/// @brief Direct constructor -/// @param _fps -/// @param frames -/// @param _width -/// @param _height -/// @param colour -/// @param pattern -/// -DummyVideoProvider::DummyVideoProvider(double _fps, int frames, int _width, int _height, const wxColour &colour, bool pattern) { - Create(_fps, frames, _width, _height, colour, pattern); -} - -/// @brief Destructor -/// -DummyVideoProvider::~DummyVideoProvider() { - frame.Clear(); -} - -/// @brief Construct a fake filename describing the video -/// @param fps -/// @param frames -/// @param _width -/// @param _height -/// @param colour -/// @param pattern -/// @return -/// -wxString DummyVideoProvider::MakeFilename(double fps, int frames, int _width, int _height, const wxColour &colour, bool pattern) { - return wxString::Format(_T("?dummy:%f:%d:%d:%d:%d:%d:%d:%s"), fps, frames, _width, _height, colour.Red(), colour.Green(), colour.Blue(), pattern?_T("c"):_T("")); -} - -/// @brief Get frame -/// @param n -/// @return -/// -const AegiVideoFrame DummyVideoProvider::GetFrame(int n) { - lastFrame = n; - return frame; -} - -} // namespace media - diff --git a/aegisub/libmedia/video/dummy_video.h b/aegisub/libmedia/video/dummy_video.h deleted file mode 100644 index a3ddfa408..000000000 --- a/aegisub/libmedia/video/dummy_video.h +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright (c) 2007, Niels Martin Hansen -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * 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. -// * Neither the name of the Aegisub Group nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. -// -// Aegisub Project http://www.aegisub.org/ -// -// $Id$ - -/// @file video_provider_dummy.h -/// @see video_provider_dummy.cpp -/// @ingroup video_input -/// - -// The dummy video provider needs a header, since it needs to be created directly as a special case - -#ifndef AGI_PRE -#include -#endif - -#include "include/aegisub/video_provider.h" - -namespace media { - -/// DOCME -/// @class DummyVideoProvider -/// @brief DOCME -/// -/// DOCME -class DummyVideoProvider : public VideoProvider { - /// DOCME - int lastFrame; - - /// DOCME - int framecount; - - /// DOCME - agi::vfr::Framerate fps; - - /// DOCME - int width; - - /// DOCME - int height; - - /// DOCME - AegiVideoFrame frame; - - void Create(double fps, int frames, int _width, int _height, const wxColour &colour, bool pattern); - -public: - DummyVideoProvider(wxString filename); - DummyVideoProvider(double fps, int frames, int _width, int _height, const wxColour &colour, bool pattern); - ~DummyVideoProvider(); - - const AegiVideoFrame GetFrame(int n); - static wxString MakeFilename(double fps, int frames, int _width, int _height, const wxColour &colour, bool pattern); - - int GetPosition() const { return lastFrame; } - int GetFrameCount() const { return framecount; } - int GetWidth() const { return width; } - int GetHeight() const { return height; } - agi::vfr::Framerate GetFPS() const { return fps; } - std::vector GetKeyFrames() const { return std::vector(); }; - wxString GetDecoderName() const { return L"Dummy Video Provider"; } -}; - -} // namespace media - diff --git a/aegisub/libmedia/video/ffms_video.cpp b/aegisub/libmedia/video/ffms_video.cpp deleted file mode 100644 index 2aaa49d24..000000000 --- a/aegisub/libmedia/video/ffms_video.cpp +++ /dev/null @@ -1,277 +0,0 @@ -// Copyright (c) 2008-2009, Karl Blomster -// -// Permission to use, copy, modify, and distribute this software for any -// purpose with or without fee is hereby granted, provided that the above -// copyright notice and this permission notice appear in all copies. -// -// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -// -// $Id$ - -/// @file ffms_video.h -/// @brief FFmpegSource Video support. -/// @ingroup fmms video - -#include "config.h" - -#ifdef WITH_FFMPEGSOURCE - -#ifndef AGI_PRE -#ifdef __WINDOWS__ -#include -#endif - -#include - -//#include -//#include -//#include -#endif - -#include "ffms_video.h" -#include "libaegisub/util.h" - -//#include "aegisub_endian.h" -//#include "compat.h" -//#include "main.h" -//#include "utils.h" -//#include "video_context.h" -//#include "video_provider_ffmpegsource.h" - -namespace media { - namespace ffms { - -/// @brief Constructor -/// @param filename The filename to open -FFmpegSourceVideoProvider::FFmpegSourceVideoProvider(std::string filename) -: VideoSource(NULL) -, VideoInfo(NULL) -, Width(-1) -, Height(-1) -, FrameNumber(-1) -, COMInited(false) -{ -#ifdef WIN32 - HRESULT res = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); - if (SUCCEEDED(res)) - COMInited = true; - else if (res != RPC_E_CHANGED_MODE) - throw VideoOpenError("COM initialization failure"); -#endif - // initialize ffmpegsource - // FIXME: CPU detection? -#if FFMS_VERSION >= ((2 << 24) | (14 << 16) | (0 << 8) | 0) - FFMS_Init(0, 1); -#else - FFMS_Init(0); -#endif - - ErrInfo.Buffer = FFMSErrMsg; - ErrInfo.BufferSize = sizeof(FFMSErrMsg); - ErrInfo.ErrorType = FFMS_ERROR_SUCCESS; - ErrInfo.SubType = FFMS_ERROR_SUCCESS; - -// SetLogLevel(); - - // and here we go - try { - LoadVideo(filename); - } - catch (std::string const& err) { - Close(); - throw VideoOpenError(err); - } - catch (...) { - Close(); - throw; - } -} - - -/// @brief Destructor -FFmpegSourceVideoProvider::~FFmpegSourceVideoProvider() { - Close(); -} - - -/// @brief Opens video -/// @param filename The filename to open -void FFmpegSourceVideoProvider::LoadVideo(std::string filename) { - - FFMS_Indexer *Indexer = FFMS_CreateIndexer(filename.c_str(), &ErrInfo); - if (Indexer == NULL) { - throw agi::FileNotFoundError(ErrInfo.Buffer); - } - - std::map TrackList = GetTracksOfType(Indexer, FFMS_TYPE_VIDEO); - if (TrackList.size() <= 0) - throw VideoNotSupported("no video tracks found"); - - // initialize the track number to an invalid value so we can detect later on - // whether the user actually had to choose a track or not - int TrackNumber = -1; - if (TrackList.size() > 1) { - TrackNumber = AskForTrackSelection(TrackList, FFMS_TYPE_VIDEO); - // if it's still -1 here, user pressed cancel - if (TrackNumber == -1) - throw agi::UserCancelException("video loading cancelled by user"); - } - - // generate a name for the cache file - std::string CacheName = GetCacheFilename(filename); - - // try to read index - FFMS_Index *Index = NULL; - Index = FFMS_ReadIndex(CacheName.c_str(), &ErrInfo); - bool IndexIsValid = false; - if (Index != NULL) { - if (FFMS_IndexBelongsToFile(Index, filename.c_str(), &ErrInfo)) { - FFMS_DestroyIndex(Index); - Index = NULL; - } - else - IndexIsValid = true; - } - - // time to examine the index and check if the track we want is indexed - // technically this isn't really needed since all video tracks should always be indexed, - // but a bit of sanity checking never hurt anyone - if (IndexIsValid && TrackNumber >= 0) { - FFMS_Track *TempTrackData = FFMS_GetTrackFromIndex(Index, TrackNumber); - if (FFMS_GetNumFrames(TempTrackData) <= 0) { - IndexIsValid = false; - FFMS_DestroyIndex(Index); - Index = NULL; - } - } - - // moment of truth - if (!IndexIsValid) { -// int TrackMask = OPT_GET("Provider/FFmpegSource/Index All Tracks")->GetBool() ? FFMS_TRACKMASK_ALL : FFMS_TRACKMASK_NONE; - int TrackMask = 1 ? FFMS_TRACKMASK_ALL : FFMS_TRACKMASK_NONE; - try { - // ignore audio decoding errors here, we don't care right now - Index = DoIndexing(Indexer, CacheName, TrackMask, FFMS_IEH_IGNORE); - } - catch (std::string err) { - throw VideoOpenError(err); - } - } - - // update access time of index file so it won't get cleaned away -//XXX: wxFileName(CacheName).Touch(); - - // track number still not set? - if (TrackNumber < 0) { - // just grab the first track - TrackNumber = FFMS_GetFirstIndexedTrackOfType(Index, FFMS_TYPE_VIDEO, &ErrInfo); - if (TrackNumber < 0) { - FFMS_DestroyIndex(Index); - Index = NULL; - throw VideoNotSupported(std::string("Couldn't find any video tracks: ") + ErrInfo.Buffer); - } - } - - // set thread count -// int Threads = OPT_GET("Provider/Video/FFmpegSource/Decoding Threads")->GetInt(); - int Threads = 1; - if (Threads < 1) - throw VideoOpenError("invalid decoding thread count"); - - // set seekmode - // TODO: give this its own option? - int SeekMode; -// if (OPT_GET("Provider/Video/FFmpegSource/Unsafe Seeking")->GetBool()) -// SeekMode = FFMS_SEEK_UNSAFE; -// else - SeekMode = FFMS_SEEK_NORMAL; - - VideoSource = FFMS_CreateVideoSource(filename.c_str(), TrackNumber, Index, Threads, SeekMode, &ErrInfo); - FFMS_DestroyIndex(Index); - Index = NULL; - if (VideoSource == NULL) { - throw VideoOpenError(std::string("Failed to open video track: ") + ErrInfo.Buffer); - } - - // load video properties - VideoInfo = FFMS_GetVideoProperties(VideoSource); - - const FFMS_Frame *TempFrame = FFMS_GetFrame(VideoSource, 0, &ErrInfo); - if (TempFrame == NULL) { - throw VideoOpenError(std::string("Failed to decode first frame: ") + ErrInfo.Buffer); - } - Width = TempFrame->EncodedWidth; - Height = TempFrame->EncodedHeight; - - if (FFMS_SetOutputFormatV(VideoSource, 1LL << FFMS_GetPixFmt("bgra"), Width, Height, FFMS_RESIZER_BICUBIC, &ErrInfo)) { - throw VideoOpenError(std::string("Failed to set output format: ") + ErrInfo.Buffer); - } - - // get frame info data - FFMS_Track *FrameData = FFMS_GetTrackFromVideo(VideoSource); - if (FrameData == NULL) - throw VideoOpenError("failed to get frame data"); - const FFMS_TrackTimeBase *TimeBase = FFMS_GetTimeBase(FrameData); - if (TimeBase == NULL) - throw VideoOpenError("failed to get track time base"); - - const FFMS_FrameInfo *CurFrameData; - - // build list of keyframes and timecodes - std::vector TimecodesVector; - for (int CurFrameNum = 0; CurFrameNum < VideoInfo->NumFrames; CurFrameNum++) { - CurFrameData = FFMS_GetFrameInfo(FrameData, CurFrameNum); - if (CurFrameData == NULL) { -//XXX throw VideoOpenError(STD_STR(wxString::Format(L"Couldn't get info about frame %d", CurFrameNum))); - throw VideoOpenError("Couldn't get info about frame %d"); - } - - // keyframe? - if (CurFrameData->KeyFrame) - KeyFramesList.push_back(CurFrameNum); - - // calculate timestamp and add to timecodes vector - int Timestamp = (int)((CurFrameData->PTS * TimeBase->Num) / TimeBase->Den); - TimecodesVector.push_back(Timestamp); - } - Timecodes = agi::vfr::Framerate(TimecodesVector); - - FrameNumber = 0; -} - -/// @brief Close video -/// -void FFmpegSourceVideoProvider::Close() { - if (VideoSource) FFMS_DestroyVideoSource(VideoSource); -#ifdef WIN32 - if (COMInited) - CoUninitialize(); -#endif -} - -/// @brief Get frame -/// @param _n -/// @return -/// -const media::AegiVideoFrame FFmpegSourceVideoProvider::GetFrame(int n) { - FrameNumber = agi::util::mid(0, n, GetFrameCount() - 1); - - // decode frame - const FFMS_Frame *SrcFrame = FFMS_GetFrame(VideoSource, FrameNumber, &ErrInfo); - if (SrcFrame == NULL) { - throw VideoDecodeError(std::string("Failed to retrieve frame:") + ErrInfo.Buffer); - } - - CurFrame.SetTo(SrcFrame->Data[0], Width, Height, SrcFrame->Linesize[0]); - return CurFrame; -} -#endif /* WITH_FFMPEGSOURCE */ - - } // namespace ffms -} // namespace media diff --git a/aegisub/libmedia/video/ffms_video.h b/aegisub/libmedia/video/ffms_video.h deleted file mode 100644 index 3b7ac0f62..000000000 --- a/aegisub/libmedia/video/ffms_video.h +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright (c) 2008-2009, Karl Blomster -// -// Permission to use, copy, modify, and distribute this software for any -// purpose with or without fee is hereby granted, provided that the above -// copyright notice and this permission notice appear in all copies. -// -// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -// -// $Id$ - -/// @file ffms_video.h -/// @brief FFmpegSource Video support. -/// @ingroup fmms video - -#ifndef AGI_PRE -#include -#endif - -#include - -#include "../../libffms/include/ffms.h" -#include "libaegisub/vfr.h" -#include "../common/ffms_common.h" -#include "libmedia/video.h" - -namespace media { - namespace ffms { - -/// @class FFmpegSourceVideoProvider -/// @brief Implements video loading through the FFMS library. -class FFmpegSourceVideoProvider : public VideoProvider, FFmpegSourceProvider { -private: - FFMS_VideoSource *VideoSource; /// video source object - const FFMS_VideoProperties *VideoInfo; /// video properties - - int Width; /// width in pixels - int Height; /// height in pixels - int FrameNumber; /// current framenumber - std::vector KeyFramesList; /// list of keyframes - agi::vfr::Framerate Timecodes; /// vfr object - bool COMInited; /// COM initialization state - - media::AegiVideoFrame CurFrame; /// current video frame - - char FFMSErrMsg[1024]; /// FFMS error message - FFMS_ErrorInfo ErrInfo; /// FFMS error codes/messages - - void LoadVideo(std::string filename); - void Close(); - -public: - FFmpegSourceVideoProvider(std::string filename); - ~FFmpegSourceVideoProvider(); - - const media::AegiVideoFrame GetFrame(int n); - - int GetPosition() const { return FrameNumber; } - int GetFrameCount() const { return VideoInfo->NumFrames; } - int GetWidth() const { return Width; } - int GetHeight() const { return Height; } - agi::vfr::Framerate GetFPS() const { return Timecodes; } - - /// @brief Gets a list of keyframes - /// @return Returns a vector of keyframes. - std::vector GetKeyFrames() const { return KeyFramesList; }; - std::string GetDecoderName() const { return "FFmpegSource"; } - /// @brief Gets the desired cache behavior. - /// @return Returns true. - bool WantsCaching() const { return true; } -}; - - - } // namespace ffms -} // namespace media diff --git a/aegisub/libmedia/video/yuv4mpeg.cpp b/aegisub/libmedia/video/yuv4mpeg.cpp deleted file mode 100644 index af1e4fb31..000000000 --- a/aegisub/libmedia/video/yuv4mpeg.cpp +++ /dev/null @@ -1,433 +0,0 @@ -// Copyright (c) 2009, Karl Blomster -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * 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. -// * Neither the name of the Aegisub Group nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. -// -// Aegisub Project http://www.aegisub.org/ -// -// $Id$ - -/// @file video_provider_yuv4mpeg.cpp -/// @brief Video provider reading YUV4MPEG files directly without depending on external libraries -/// @ingroup video_input -/// - -#include "config.h" - -#include -#include - -#include "yuv4mpeg.h" - -namespace media { - -// All of this cstdio bogus is because of one reason and one reason only: -// MICROSOFT'S IMPLEMENTATION OF STD::FSTREAM DOES NOT SUPPORT FILES LARGER THAN 2 GB. -// (yes, really) -// With cstdio it's at least possible to work around the problem... -#ifdef _MSC_VER -#define fseeko _fseeki64 -#define ftello _ftelli64 -#endif - -/// @brief Constructor -/// @param filename The filename to open -YUV4MPEGVideoProvider::YUV4MPEGVideoProvider(std::string filename) -: sf(NULL) -, inited(false) -, w (0) -, h (0) -, num_frames(-1) -, cur_fn(-1) -, pixfmt(Y4M_PIXFMT_NONE) -, imode(Y4M_ILACE_NOTSET) -{ - fps_rat.num = -1; - fps_rat.den = 1; - - try { - -#ifdef WIN32 - sf = _wfopen(filename.c_str(), L"rb"); -#else - sf = fopen(filename.c_str(), "rb"); -#endif - - if (sf == NULL) throw agi::FileNotFoundError(filename); - - CheckFileFormat(); - - ParseFileHeader(ReadHeader(0, false)); - - if (w <= 0 || h <= 0) - throw VideoOpenError("Invalid resolution"); - if (fps_rat.num <= 0 || fps_rat.den <= 0) { - fps_rat.num = 25; - fps_rat.den = 1; - LOG_D("provider/video/yuv4mpeg") << "framerate info unavailable, assuming 25fps"; - } - if (pixfmt == Y4M_PIXFMT_NONE) - pixfmt = Y4M_PIXFMT_420JPEG; - if (imode == Y4M_ILACE_NOTSET) - imode = Y4M_ILACE_UNKNOWN; - - luma_sz = w * h; - switch (pixfmt) { - case Y4M_PIXFMT_420JPEG: - case Y4M_PIXFMT_420MPEG2: - case Y4M_PIXFMT_420PALDV: - chroma_sz = (w * h) >> 2; break; - case Y4M_PIXFMT_422: - chroma_sz = (w * h) >> 1; break; - /// @todo add support for more pixel formats - default: - throw VideoOpenError("Unsupported pixel format"); - } - frame_sz = luma_sz + chroma_sz*2; - - num_frames = IndexFile(); - if (num_frames <= 0 || seek_table.empty()) - throw VideoOpenError("Unable to determine file length"); - cur_fn = 0; - - fseeko(sf, 0, SEEK_SET); - } - catch (...) { - if (sf) fclose(sf); - throw; - } -} - - -/// @brief Destructor -YUV4MPEGVideoProvider::~YUV4MPEGVideoProvider() { - if (sf) fclose(sf); -} - -/// @brief Checks if the file is an YUV4MPEG file or not -/// Note that it reports the error by throwing an exception, -/// not by returning a false value. -void YUV4MPEGVideoProvider::CheckFileFormat() { - char buf[10]; - if (fread(buf, 10, 1, sf) != 1) - throw VideoNotSupported("CheckFileFormat: Failed reading header"); - if (strncmp("YUV4MPEG2 ", buf, 10)) - throw VideoNotSupported("CheckFileFormat: File is not a YUV4MPEG file (bad magic)"); - - fseeko(sf, 0, SEEK_SET); -} - -/// @brief Read a frame or file header at a given file position -/// @param startpos The byte offset at where to start reading -/// @param reset_pos If true, the function will reset the file position to what it was before the function call before returning -/// @return A list of parameters -std::vector YUV4MPEGVideoProvider::ReadHeader(int64_t startpos, bool reset_pos) { - int64_t oldpos = ftello(sf); - std::vector tags; - std::string curtag; - int bytesread = 0; - int buf; - - if (fseeko(sf, startpos, SEEK_SET)) - throw VideoOpenError("YUV4MPEG video provider: ReadHeader: failed seeking to position %d"); //XXX:, startpos))); - - // read header until terminating newline (0x0A) is found - while ((buf = fgetc(sf)) != 0x0A) { - if (ferror(sf)) - throw VideoOpenError("ReadHeader: Failed to read from file"); - if (feof(sf)) { - // you know, this is one of the places where it would be really nice - // to be able to throw an exception object that tells the caller that EOF was reached - LOG_D("provider/video/yuv4mpeg") << "ReadHeader: Reached EOF, returning"; - break; - } - - // some basic low-effort sanity checking - if (buf == 0x00) - throw VideoOpenError("ReadHeader: Malformed header (unexpected NUL)"); - if (++bytesread >= YUV4MPEG_HEADER_MAXLEN) - throw VideoOpenError("ReadHeader: Malformed header (no terminating newline found)"); - - // found a new tag - if (buf == 0x20) { - tags.push_back(curtag); - curtag.clear(); - } - else - curtag.append((const char*)buf); - } - // if only one tag with no trailing space was found (possible in the - // FRAME header case), make sure we get it - if (!curtag.empty()) { - tags.push_back(curtag); - curtag.clear(); - } - - if (reset_pos) - fseeko(sf, oldpos, SEEK_SET); - - return tags; -} - - - -/// @brief Parses a list of parameters and sets reader state accordingly -/// @param tags The list of parameters to parse -void YUV4MPEGVideoProvider::ParseFileHeader(const std::vector& tags) { - if (tags.size() <= 1) - throw VideoOpenError("ParseFileHeader: contentless header"); - if (tags.front() == "YUV4MPEG2") - throw VideoOpenError("ParseFileHeader: malformed header (bad magic)"); - - // temporary stuff - int t_w = -1; - int t_h = -1; - int t_fps_num = -1; - int t_fps_den = -1; - Y4M_InterlacingMode t_imode = Y4M_ILACE_NOTSET; - Y4M_PixelFormat t_pixfmt = Y4M_PIXFMT_NONE; - - for (unsigned i = 1; i < tags.size(); i++) { - std::string tag; - tag = tags[i]; - - if (tag.find("W") == 0) { - tag.erase(0,1); - t_w = agi::util::strtoi(tag); - if (t_w == 0) - throw VideoOpenError("ParseFileHeader: invalid width"); - } - else if (tag.find("H") == 0) { - tag.erase(0,1); - t_h = agi::util::strtoi(tag); - if (t_h == 0) - throw VideoOpenError("ParseFileHeader: invalid height"); - } - else if (tag.find("F") == 0) { - tag.erase(0,1); - int i = tag.find(":"); - std::string num(tag.substr(0,i)); - std::string den(tag.substr(i+1,den.size())); - t_fps_num = agi::util::strtoi(num); - t_fps_den = agi::util::strtoi(den); - if ((t_fps_num == 0) || (t_fps_den == 0)) - throw VideoOpenError("ParseFileHeader: invalid framerate"); - } - else if (tag.find("C") == 0) { - tag.erase(0,1); - // technically this should probably be case sensitive, - // but being liberal in what you accept doesn't hurt - agi::util::str_lower(tag); - if (tag == "420") t_pixfmt = Y4M_PIXFMT_420JPEG; // is this really correct? - else if (tag == "420jpeg") t_pixfmt = Y4M_PIXFMT_420JPEG; - else if (tag == "420mpeg2") t_pixfmt = Y4M_PIXFMT_420MPEG2; - else if (tag == "420paldv") t_pixfmt = Y4M_PIXFMT_420PALDV; - else if (tag == "411") t_pixfmt = Y4M_PIXFMT_411; - else if (tag == "422") t_pixfmt = Y4M_PIXFMT_422; - else if (tag == "444") t_pixfmt = Y4M_PIXFMT_444; - else if (tag == "444alpha") t_pixfmt = Y4M_PIXFMT_444ALPHA; - else if (tag == "mono") t_pixfmt = Y4M_PIXFMT_MONO; - else - throw VideoOpenError("ParseFileHeader: invalid or unknown colorspace"); - } - else if (tag.find("I") == 0) { - tag.erase(0,1); - agi::util::str_lower(tag); - if (tag == "p") t_imode = Y4M_ILACE_PROGRESSIVE; - else if (tag == "t") t_imode = Y4M_ILACE_TFF; - else if (tag == "b") t_imode = Y4M_ILACE_BFF; - else if (tag == "m") t_imode = Y4M_ILACE_MIXED; - else if (tag == "?") t_imode = Y4M_ILACE_UNKNOWN; - else - throw VideoOpenError("ParseFileHeader: invalid or unknown interlacing mode"); - } - else - LOG_D("provider/video/yuv4mpeg") << "Unparsed tag: " << tags[i].c_str(); - } - - // The point of all this is to allow multiple YUV4MPEG2 headers in a single file - // (can happen if you concat several files) as long as they have identical - // header flags. The spec doesn't explicitly say you have to allow this, - // but the "reference implementation" (mjpegtools) does, so I'm doing it too. - if (inited) { - if (t_w > 0 && t_w != w) - throw VideoOpenError("ParseFileHeader: illegal width change"); - if (t_h > 0 && t_h != h) - throw VideoOpenError("ParseFileHeader: illegal height change"); - if ((t_fps_num > 0 && t_fps_den > 0) && (t_fps_num != fps_rat.num || t_fps_den != fps_rat.den)) - throw VideoOpenError("ParseFileHeader: illegal framerate change"); - if (t_pixfmt != Y4M_PIXFMT_NONE && t_pixfmt != pixfmt) - throw VideoOpenError("ParseFileHeader: illegal colorspace change"); - if (t_imode != Y4M_ILACE_NOTSET && t_imode != imode) - throw VideoOpenError("ParseFileHeader: illegal interlacing mode change"); - } - else { - w = t_w; - h = t_h; - fps_rat.num = t_fps_num; - fps_rat.den = t_fps_den; - pixfmt = t_pixfmt != Y4M_PIXFMT_NONE ? t_pixfmt : Y4M_PIXFMT_420JPEG; - imode = t_imode != Y4M_ILACE_NOTSET ? t_imode : Y4M_ILACE_UNKNOWN; - fps = double(fps_rat.num) / fps_rat.den; - inited = true; - } -} - -/// @brief Parses a frame header -/// @param tags The list of parameters to parse -/// @return The flags set, as a binary mask -/// This function is currently unimplemented (it will always return Y4M_FFLAG_NONE). -YUV4MPEGVideoProvider::Y4M_FrameFlags YUV4MPEGVideoProvider::ParseFrameHeader(const std::vector& tags) { - if (tags.front() == "FRAME") - throw VideoOpenError("ParseFrameHeader: malformed frame header (bad magic)"); - - /// @todo implement parsing of frame flags - - return Y4M_FFLAG_NONE; -} - -/// @brief Indexes the file -/// @return The number of frames found in the file -/// This function goes through the file, finds and parses all file and frame headers, -/// and creates a seek table that lists the byte positions of all frames so seeking -/// can easily be done. -int YUV4MPEGVideoProvider::IndexFile() { - int framecount = 0; - int64_t curpos = ftello(sf); - - // the ParseFileHeader() call in LoadVideo() will already have read - // the file header for us and set the seek position correctly - while (true) { - curpos = ftello(sf); // update position - // continue reading headers until no more are found - std::vector tags = ReadHeader(curpos, false); - curpos = ftello(sf); - - if (tags.empty()) - break; // no more headers - - Y4M_FrameFlags flags = Y4M_FFLAG_NOTSET; - if (tags.front() != "YUV4MPEG2") { - ParseFileHeader(tags); - continue; - } - else if (tags.front() != "FRAME") - flags = ParseFrameHeader(tags); - - if (flags == Y4M_FFLAG_NONE) { - framecount++; - seek_table.push_back(curpos); - // seek to next frame header start position - if (fseeko(sf, frame_sz, SEEK_CUR)) - throw VideoOpenError("IndexFile: failed seeking to position %d"); //XXX: , curpos + frame_sz))); - } - else { - /// @todo implement rff flags etc - } - } - - return framecount; -} - -// http://bob.allegronetwork.com/prog/tricks.html#clamp -static inline int clamp(int x) { - x &= (~x) >> 31; - x -= 255; - x &= x >> 31; - x += 255; - return x; -} - -/// @brief Gets a given frame -/// @param n The frame number to return -/// @return The video frame -const AegiVideoFrame YUV4MPEGVideoProvider::GetFrame(int n) { - cur_fn = agi::util::mid(0, n, num_frames - 1); - - int uv_width = w / 2; - switch (pixfmt) { - case Y4M_PIXFMT_420JPEG: - case Y4M_PIXFMT_420MPEG2: - case Y4M_PIXFMT_420PALDV: - break; - /// @todo add support for more pixel formats - default: - throw "YUV4MPEG video provider: GetFrame: Unsupported source colorspace"; - } - - std::vector planes[3]; - planes[0].resize(luma_sz); - planes[1].resize(chroma_sz); - planes[2].resize(chroma_sz); - - fseeko(sf, seek_table[n], SEEK_SET); - size_t ret; - ret = fread(&planes[0][0], luma_sz, 1, sf); - if (ret != 1 || feof(sf) || ferror(sf)) - throw "YUV4MPEG video provider: GetFrame: failed to read luma plane"; - for (int i = 1; i <= 2; i++) { - ret = fread(&planes[i][0], chroma_sz, 1, sf); - if (ret != 1 || feof(sf) || ferror(sf)) - throw "YUV4MPEG video provider: GetFrame: failed to read chroma planes"; - } - - AegiVideoFrame dst_frame; - dst_frame.invertChannels = true; - dst_frame.w = w; - dst_frame.h = h; - dst_frame.pitch = w * 4; - dst_frame.Allocate(); - - const unsigned char *src_y = &planes[0][0]; - const unsigned char *src_u = &planes[1][0]; - const unsigned char *src_v = &planes[2][0]; - unsigned char *dst = dst_frame.data; - - for (int py = 0; py < h; ++py) { - for (int px = 0; px < w / 2; ++px) { - const int u = *src_u++ - 128; - const int v = *src_v++ - 128; - for (unsigned int i = 0; i < 2; ++i) { - const int y = (*src_y++ - 16) * 298; - - *dst++ = clamp((y + 516 * u + 128) >> 8); // Blue - *dst++ = clamp((y - 100 * u - 208 * v + 128) >> 8); // Green - *dst++ = clamp((y + 409 * v + 128) >> 8); // Red - *dst++ = 0; // Alpha - } - } - - // Roll back u/v on even lines - if (!(py & 1)) { - src_u -= uv_width; - src_v -= uv_width; - } - } - - return dst_frame; -} - -} // namespace media - diff --git a/aegisub/libmedia/video/yuv4mpeg.h b/aegisub/libmedia/video/yuv4mpeg.h deleted file mode 100644 index efa224ad8..000000000 --- a/aegisub/libmedia/video/yuv4mpeg.h +++ /dev/null @@ -1,158 +0,0 @@ -// Copyright (c) 2009, Karl Blomster -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * 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. -// * Neither the name of the Aegisub Group nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. -// -// Aegisub Project http://www.aegisub.org/ -// -// $Id$ - -/// @file video_provider_yuv4mpeg.h -/// @see video_provider_yuv4mpeg.cpp -/// @ingroup video_input -/// - - -#ifndef MAGI_PRE -#include - -#include -#endif - -#include "libmedia/video.h" - -namespace media { - -/// the maximum allowed header length, in bytes -#define YUV4MPEG_HEADER_MAXLEN 128 - -/// @class YUV4MPEGVideoProvider -/// @brief Implements reading of YUV4MPEG uncompressed video files -class YUV4MPEGVideoProvider : public VideoProvider { - /// Pixel formats - enum Y4M_PixelFormat { - Y4M_PIXFMT_NONE = -1, /// not set/unknown - - /// 4:2:0 sampling variants. - /// afaict the only difference between these three - /// is the chroma sample location, and nobody cares about that. - Y4M_PIXFMT_420JPEG, /// 4:2:0, H/V centered, for JPEG/MPEG-1 - Y4M_PIXFMT_420MPEG2, /// 4:2:0, H cosited, for MPEG-2 - Y4M_PIXFMT_420PALDV, /// 4:2:0, alternating Cb/Cr, for PAL-DV - - Y4M_PIXFMT_411, /// 4:1:1, H cosited - Y4M_PIXFMT_422, /// 4:2:2, H cosited - Y4M_PIXFMT_444, /// 4:4:4, i.e. no chroma subsampling - Y4M_PIXFMT_444ALPHA, /// 4:4:4 plus alpha channel - - Y4M_PIXFMT_MONO, /// luma only (grayscale) - }; - - - /// Interlacing mode for an entire stream - enum Y4M_InterlacingMode { - Y4M_ILACE_NOTSET = -1, /// undefined - Y4M_ILACE_PROGRESSIVE, /// progressive (no interlacing) - - Y4M_ILACE_TFF, /// interlaced, top field first - Y4M_ILACE_BFF, /// interlaced, bottom field first - - Y4M_ILACE_MIXED, /// mixed interlaced/progressive, possibly with RFF flags - Y4M_ILACE_UNKNOWN, /// unknown interlacing mode (not the same as undefined) - }; - - - /// Frame information flags - enum Y4M_FrameFlags { - Y4M_FFLAG_NOTSET = -1, /// undefined - Y4M_FFLAG_NONE = 0x0000, /// no flags set - - /// field order/repeat field flags - Y4M_FFLAG_R_TFF = 0x0001, /// top field first - Y4M_FFLAG_R_TFF_R = 0x0002, /// top field first, and repeat that field - Y4M_FFLAG_R_BFF = 0x0004, /// bottom field first - Y4M_FFLAG_R_BFF_R = 0x0008, /// bottom field first, and repeat that field - Y4M_FFLAG_R_P = 0x0010, /// progressive - Y4M_FFLAG_R_P_R = 0x0020, /// progressive, and repeat frame once - Y4M_FFLAG_R_P_RR = 0x0040, /// progressive, and repeat frame twice - - /// temporal sampling flags - Y4M_FFLAG_T_P = 0x0080, /// progressive (fields sampled at the same time) - Y4M_FFLAG_T_I = 0x0100, /// interlaced (fields sampled at different times) - - /// chroma subsampling flags - Y4M_FFLAG_C_P = 0x0200, /// progressive (whole frame subsampled) - Y4M_FFLAG_C_I = 0x0400, /// interlaced (fields subsampled independently) - Y4M_FFLAG_C_UNKNOWN = 0x0800, /// unknown (only allowed for non-4:2:0 sampling) - }; - - - FILE *sf; /// source file - bool inited; /// initialization state - - int w, h; /// frame width/height - int num_frames; /// length of file in frames - int frame_sz; /// size of each frame in bytes - int luma_sz; /// size of the luma plane of each frame, in bytes - int chroma_sz; /// size of one of the two chroma planes of each frame, in bytes - int cur_fn; /// current frame number - - Y4M_PixelFormat pixfmt; /// colorspace/pixel format - Y4M_InterlacingMode imode; /// interlacing mode (for the entire stream) - struct { - int num; /// numerator - int den; /// denominator - } fps_rat; /// framerate - - agi::vfr::Framerate fps; - - /// a list of byte positions detailing where in the file - /// each frame header can be found - std::vector seek_table; - - void CheckFileFormat(); - void ParseFileHeader(const std::vector& tags); - Y4M_FrameFlags ParseFrameHeader(const std::vector& tags); - std::vector ReadHeader(int64_t startpos, bool reset_pos=false); - int IndexFile(); - -public: - YUV4MPEGVideoProvider(std::string filename); - ~YUV4MPEGVideoProvider(); - - const AegiVideoFrame GetFrame(int n); - - int GetPosition() const { return cur_fn; } - int GetFrameCount() const { return num_frames; } - int GetWidth() const { return w; } - int GetHeight() const { return h; } - agi::vfr::Framerate GetFPS() const { return fps; } - std::vector GetKeyFrames() const { return std::vector(); }; - std::string GetDecoderName() const { return "YU4MPEG"; }; - bool WantsCaching() const { return true; }; -}; - -} // namespace media -