// Copyright (c) 2007, Alysson Souza e Silva // 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 // /////////// // Headers #include "config.h" #include #include "video_context.h" #include "keyframe.h" #include "text_file_reader.h" #include "text_file_writer.h" #include "options.h" #include "vfr.h" ////////////////// // Load Keyframes void KeyFrameFile::Load(wxString filename) { // Load try { // Open file wxArrayInt keyFrames; keyFrames.Empty(); TextFileReader file(filename,_T("ASCII")); wxString cur = file.ReadLineFromFile(); // Detect type (Only Xvid, DivX, x264 and Aegisub's keyframe files are currently supported) if (cur == _T("# keyframe format v1")) { OpenAegiKeyFrames(file, keyFrames); } else if (cur.StartsWith(_T("# XviD 2pass stat file"))) { OpenXviDKeyFrames(file, keyFrames); } else if (cur.StartsWith(_T("##map version"))) { OpenDivXKeyFrames(file, keyFrames); } else if (cur.StartsWith(_T("#options:"))) { Openx264KeyFrames(file, keyFrames); } else { throw(_T("Invalid or unsupported keyframes file.")); } // Set keyframes VideoContext::Get()->SetOverKeyFrames(keyFrames); VideoContext::Get()->SetKeyFramesName(filename); // Add to recent Options.AddToRecentList(filename,_T("Recent keyframes")); } // Fail catch (const wchar_t *error) { wxString err(error); wxMessageBox(err, _T("Error opening keyframes file"), wxOK | wxICON_ERROR, NULL); } catch (...) { wxMessageBox(_T("Unknown error"), _T("Error opening keyframes file"), wxOK | wxICON_ERROR, NULL); } } ////////////////// // Save Keyframes void KeyFrameFile::Save(wxString filename) { // Get keyframes wxArrayInt keyFrames = VideoContext::Get()->GetKeyFrames(); // Write header TextFileWriter file(filename,_T("ASCII")); file.WriteLineToFile(_T("# keyframe format v1")); file.WriteLineToFile(wxString::Format(_T("fps %f"),VideoContext::Get()->GetFPS())); // Write keyframes for (unsigned int i=0;iIsLoaded()) { VideoContext::Get()->SetFPS(fps); VFR_Input.SetCFR(fps); if (!VFR_Output.IsLoaded()) VFR_Output.SetCFR(fps); } // Read lines while (file.HasMoreLines()) { cur = file.ReadLineFromFile(); if (!cur.IsEmpty() && !cur.StartsWith(_T("#")) && cur.IsNumber()) { long temp; cur.ToLong(&temp); keyFrames.Add(temp); } } } /////////////////// // XviD stats file void KeyFrameFile::OpenXviDKeyFrames(TextFileReader& file, wxArrayInt& keyFrames) { wxString cur = file.ReadLineFromFile(); unsigned int count = 0; // Read lines while (file.HasMoreLines()) { if (cur.StartsWith(_T("i"))) { keyFrames.Add(count); count++; } else if (cur.StartsWith(_T("p")) || cur.StartsWith(_T("b"))) { count++; } cur = file.ReadLineFromFile(); } } /////////////////// // DivX stats file void KeyFrameFile::OpenDivXKeyFrames(TextFileReader& file, wxArrayInt& keyFrames) { wxString cur = file.ReadLineFromFile(); unsigned int count = 0; // Read lines while (file.HasMoreLines()) { if (cur.Contains(_T("I"))) { keyFrames.Add(count); count++; } else if (cur.Contains(_T("P")) || cur.Contains(_T("B"))) { count++; } cur = file.ReadLineFromFile(); } } /////////////////// // x264 stats file void KeyFrameFile::Openx264KeyFrames(TextFileReader& file, wxArrayInt& keyFrames) { wxString cur = file.ReadLineFromFile(); unsigned int count = 0; size_t pos; // Read lines while (file.HasMoreLines()) { pos = cur.Find(_T("type:")); if (cur.Mid(pos,6).Right(1).Lower() == (_T("i"))) { keyFrames.Add(count); count++; } else if (cur.Mid(pos,6).Right(1).Lower() == (_T("p")) || cur.Mid(pos,6).Right(1).Lower() == (_T("b"))) { count++; } cur = file.ReadLineFromFile(); } }