diff --git a/aegisub/ffmpegsource_common.cpp b/aegisub/ffmpegsource_common.cpp new file mode 100644 index 000000000..ea82610bc --- /dev/null +++ b/aegisub/ffmpegsource_common.cpp @@ -0,0 +1,56 @@ +// Copyright (c) 2008, 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 +// +// Website: http://aegisub.cellosoft.com +// Contact: mailto:zeratul@cellosoft.com +// + +#ifdef WITH_FFMPEGSOURCE + +/////////// +// Headers +#include "ffmpegsource_common.h" + +/////////////// +// Update indexing progress +int __stdcall FFmpegSourceProvider::UpdateIndexingProgress(int State, int64_t Current, int64_t Total, void *Private) { + IndexingProgressDialog *Progress = (IndexingProgressDialog *)Private; + + if (Progress->IndexingCanceled) + return 1; + + // noone cares about a little bit of a rounding error here anyway + Progress->ProgressDialog->SetProgress((1000*Current)/Total, 1000); + + return 0; +} + +#endif WITH_FFMPEGSOURCE \ No newline at end of file diff --git a/aegisub/ffmpegsource_common.h b/aegisub/ffmpegsource_common.h new file mode 100644 index 000000000..b168f0d63 --- /dev/null +++ b/aegisub/ffmpegsource_common.h @@ -0,0 +1,60 @@ +// Copyright (c) 2008, 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 +// +// Website: http://aegisub.cellosoft.com +// Contact: mailto:zeratul@cellosoft.com +// + +#pragma once +#ifdef WITH_FFMPEGSOURCE + +/////////// +// Headers +#include "include/aegisub/aegisub.h" +#include "../FFmpegSource2/ffms.h" +#include "dialog_progress.h" + + +class FFmpegSourceProvider { +public: + static const int FFMSTrackMaskAll = -1; + static const int FFMSTrackMaskNone = 0; + static const int FFMSFirstSuitableTrack = -1; + + struct IndexingProgressDialog { + volatile bool IndexingCanceled; + DialogProgress *ProgressDialog; + }; + + static int __stdcall FFmpegSourceProvider::UpdateIndexingProgress(int State, int64_t Current, int64_t Total, void *Private); +}; + +#endif /* WITH_FFMPEGSOURCE */ \ No newline at end of file diff --git a/aegisub/video_provider_ffmpegsource.cpp b/aegisub/video_provider_ffmpegsource.cpp index 345fd0531..f1a7337f5 100644 --- a/aegisub/video_provider_ffmpegsource.cpp +++ b/aegisub/video_provider_ffmpegsource.cpp @@ -38,7 +38,6 @@ /////////// // Headers #include "video_provider_ffmpegsource.h" -#include "../FFmpegSource2/ffms.h" #include "video_context.h" #include "options.h" @@ -51,6 +50,7 @@ FFmpegSourceVideoProvider::FFmpegSourceVideoProvider(Aegisub::String filename, d // clean up variables VideoSource = NULL; + Index = NULL; DstFormat = FFMS_PIX_FMT_NONE; LastDstFormat = FFMS_PIX_FMT_NONE; KeyFramesLoaded = false; @@ -84,8 +84,6 @@ void FFmpegSourceVideoProvider::LoadVideo(Aegisub::String filename, double fps) wxString CacheName(filename.c_str()); CacheName.append(_T(".ffindex")); - FrameIndex *Index; - // try to read index Index = FFMS_ReadIndex(CacheName.char_str(), FFMSErrorMessage, MessageSize); if (Index == NULL) { @@ -97,7 +95,8 @@ void FFmpegSourceVideoProvider::LoadVideo(Aegisub::String filename, double fps) Progress.ProgressDialog->Show(); Progress.ProgressDialog->SetProgress(0,1); - Index = FFMS_MakeIndex(FileNameWX.char_str(), 1, NULL, FFmpegSourceVideoProvider::UpdateIndexingProgress, &Progress, FFMSErrorMessage, MessageSize); + // set trackmask to -1 (all) here but don't output any audio file, this allows the audio provider to reuse the index later + Index = FFMS_MakeIndex(FileNameWX.char_str(), FFMSTrackMaskAll, CacheName.char_str(), FFmpegSourceProvider::UpdateIndexingProgress, &Progress, FFMSErrorMessage, MessageSize); if (Index == NULL) { Progress.ProgressDialog->Destroy(); ErrorMsg.Printf(_T("FFmpegSource video provider: %s"), FFMSErrorMessage); @@ -125,8 +124,7 @@ void FFmpegSourceVideoProvider::LoadVideo(Aegisub::String filename, double fps) else SeekMode = 1; - // finally create the actual video source - VideoSource = FFMS_CreateVideoSource(FileNameWX.char_str(), -1, Index, "", Threads, SeekMode, FFMSErrorMessage, MessageSize); + VideoSource = FFMS_CreateVideoSource(FileNameWX.char_str(), FFMSFirstSuitableTrack, Index, "", Threads, SeekMode, FFMSErrorMessage, MessageSize); if (VideoSource == NULL) { ErrorMsg.Printf(_T("FFmpegSource video provider: %s"), FFMSErrorMessage); throw ErrorMsg; @@ -181,9 +179,6 @@ void FFmpegSourceVideoProvider::LoadVideo(Aegisub::String filename, double fps) VFR_Output.SetVFR(TimecodesVector); } - // we don't need this anymore - FFMS_DestroyFrameIndex(Index); - FrameNumber = 0; } @@ -193,6 +188,8 @@ void FFmpegSourceVideoProvider::Close() { if (VideoSource) FFMS_DestroyVideoSource(VideoSource); VideoSource = NULL; + if (Index) + FFMS_DestroyFrameIndex(Index); DstFormat = FFMS_PIX_FMT_NONE; LastDstFormat = FFMS_PIX_FMT_NONE; @@ -202,19 +199,6 @@ void FFmpegSourceVideoProvider::Close() { FrameNumber = -1; } -/////////////// -// Update indexing progress -int __stdcall FFmpegSourceVideoProvider::UpdateIndexingProgress(int State, int64_t Current, int64_t Total, void *Private) { - IndexingProgressDialog *Progress = (IndexingProgressDialog *)Private; - - if (Progress->IndexingCanceled) - return 1; - - // noone cares about a little bit of a rounding error here anyway - Progress->ProgressDialog->SetProgress((1000*Current)/Total, 1000); - - return 0; -} /////////////// // Get frame diff --git a/aegisub/video_provider_ffmpegsource.h b/aegisub/video_provider_ffmpegsource.h index 452b196fe..9e2b7f341 100644 --- a/aegisub/video_provider_ffmpegsource.h +++ b/aegisub/video_provider_ffmpegsource.h @@ -38,20 +38,18 @@ #include #ifdef WITH_FFMPEGSOURCE #include "include/aegisub/video_provider.h" -#include "include/aegisub/aegisub.h" -#include "dialog_progress.h" +#include "ffmpegsource_common.h" #include "vfr.h" #include -#include "../FFmpegSource2/ffms.h" - /////////////////////// -// FFmpegSource provider -class FFmpegSourceVideoProvider : public VideoProvider { +// FFmpegSource video provider +class FFmpegSourceVideoProvider : public VideoProvider, FFmpegSourceProvider { private: VideoBase *VideoSource; const VideoProperties *VideoInfo; + FrameIndex *Index; int FrameNumber; wxArrayInt KeyFramesList; @@ -67,16 +65,9 @@ private: unsigned MessageSize; wxString ErrorMsg; - struct IndexingProgressDialog { - volatile bool IndexingCanceled; - DialogProgress *ProgressDialog; - }; - void LoadVideo(Aegisub::String filename, double fps); void Close(); - static int __stdcall FFmpegSourceVideoProvider::UpdateIndexingProgress(int State, int64_t Current, int64_t Total, void *Private); - protected: public: