diff --git a/include/OpenShot.h b/include/OpenShot.h index d7e9fe46..b5fe405e 100644 --- a/include/OpenShot.h +++ b/include/OpenShot.h @@ -119,6 +119,7 @@ #include "KeyFrame.h" #include "PlayerBase.h" #include "Point.h" +#include "Profile.h" #include "SDLPlayer.h" #include "Sleep.h" #include "TextReader.h" diff --git a/include/Profile.h b/include/Profile.h new file mode 100644 index 00000000..00305347 --- /dev/null +++ b/include/Profile.h @@ -0,0 +1,102 @@ +/** + * @file + * @brief Header file for Profile class + * @author Jonathan Thomas + * + * @section LICENSE + * + * Copyright (c) 2008-2013 OpenShot Studios, LLC + * (http://www.openshotstudios.com). This file is part of + * OpenShot Library (http://www.openshot.org), an open-source project + * dedicated to delivering high quality video editing and animation solutions + * to the world. + * + * OpenShot Library is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenShot Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenShot Library. If not, see . + */ + +#ifndef OPENSHOT_PROFILE_H +#define OPENSHOT_PROFILE_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "Exceptions.h" +#include "Fraction.h" +#include "Json.h" + +using namespace std; + +namespace openshot +{ + + /** + * @brief This struct holds profile data, typically loaded from a file + * + * Profile data contains common settings for Writers, such as frame rate, + * aspect ratios, width, and height combinations. + */ + struct ProfileInfo + { + string description; ///< The description of this profile. + int height; ///< The height of the video (in pixels) + int width; ///< The width of the video (in pixels) + int pixel_format; ///< The pixel format (i.e. YUV420P, RGB24, etc...) + Fraction fps; ///< Frames per second, as a fraction (i.e. 24/1 = 24 fps) + Fraction pixel_ratio; ///< The pixel ratio of the video stream as a fraction (i.e. some pixels are not square) + Fraction display_ratio; ///< The ratio of width to height of the video stream (i.e. 640x480 has a ratio of 4/3) + bool interlaced_frame; // Are the contents of this frame interlaced + }; + + /** + * @brief This class loads a special text-based file called a Profile. + * + * Profile data contains common video settings, such as framerate, height, width, + * aspect ratio, etc... All derived classes from openshot::WriterBase can load profile + * data using this class. + * + * \code + * // This example demonstrates how to load a profile with this class. + * Profile p("/home/jonathan/dv_ntsc_wide"); // Load the DV NTSC Widt profile data. + * + * \endcode + */ + class Profile + { + public: + /// Profile data stored here + ProfileInfo info; + + /// @brief Constructor for Profile. + /// @param path The folder path / location of a profile file + Profile(string path) throw(InvalidFile, InvalidJSON); + + /// Get and Set JSON methods + string Json(); ///< Generate JSON string of this object + Json::Value JsonValue(); ///< Generate Json::JsonValue for this object + void SetJson(string value) throw(InvalidJSON); ///< Load JSON string into this object + void SetJsonValue(Json::Value root); ///< Load Json::JsonValue into this object + }; + +} + +#endif diff --git a/include/WriterBase.h b/include/WriterBase.h index 05ca2510..24b4e923 100644 --- a/include/WriterBase.h +++ b/include/WriterBase.h @@ -51,7 +51,7 @@ namespace openshot float duration; ///< Length of time (in seconds) int file_size; ///< Size of file (in bytes) int height; ///< The height of the video (in pixels) - int width; ///< The width of the video (in pixesl) + int width; ///< The width of the video (in pixels) int pixel_format; ///< The pixel format (i.e. YUV420P, RGB24, etc...) Fraction fps; ///< Frames per second, as a fraction (i.e. 24/1 = 24 fps) int video_bit_rate; ///< The bit rate of the video stream (in bytes) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 87bd387e..8ff59222 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -159,6 +159,7 @@ SET ( OPENSHOT_SOURCE_FILES ImageReader.cpp PlayerBase.cpp Point.cpp + Profile.cpp SDLPlayer.cpp TextReader.cpp Timeline.cpp diff --git a/src/Main.cpp b/src/Main.cpp index eb4a4acc..7dd948d6 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -40,6 +40,8 @@ using namespace tr1; int main(int argc, char* argv[]) { + Profile p("/home/jonathan/Apps/openshot/openshot/profiles/atsc_1080p_25"); + return 0; Timeline t77(640, 480, Fraction(24,1), 44100, 2); t77.ApplyJsonDiff("[{\"type\":\"insert\",\"key\":[\"effects\",\"effect\"],\"value\":{\"end\":0,\"id\":\"e004\",\"layer\":0,\"order\":0,\"position\":0,\"start\":0,\"type\":\"Negate\"}}]"); diff --git a/src/Profile.cpp b/src/Profile.cpp new file mode 100644 index 00000000..19ad4854 --- /dev/null +++ b/src/Profile.cpp @@ -0,0 +1,192 @@ +/** + * @file + * @brief Source file for Profile class + * @author Jonathan Thomas + * + * @section LICENSE + * + * Copyright (c) 2008-2013 OpenShot Studios, LLC + * (http://www.openshotstudios.com). This file is part of + * OpenShot Library (http://www.openshot.org), an open-source project + * dedicated to delivering high quality video editing and animation solutions + * to the world. + * + * OpenShot Library is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenShot Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenShot Library. If not, see . + */ + +#include "../include/Profile.h" + +using namespace openshot; + + +// @brief Constructor for Profile. +// @param path The folder path / location of a profile file +Profile::Profile(string path) throw(InvalidFile, InvalidJSON) { + try + { + // Read the profile file + ifstream myfile (path.c_str()); + if (myfile.is_open()) + { + // Loop through each line + while (myfile.good()) + { + // read current line of file + string line = ""; + getline (myfile, line); + + if (line.length() <= 0) + continue; + + // Split current line + QString qline(line.c_str()); + QStringList parts = qline.split( "=" ); + string setting = parts[0].toStdString(); + string value = parts[1].toStdString(); + int value_int = 0; + + // update struct (based on line number) + if (setting == "description") + info.description = value; + else if (setting == "frame_rate_num") { + stringstream(value) >> value_int; + info.fps.num = value_int; + } + else if (setting == "frame_rate_den") { + stringstream(value) >> value_int; + info.fps.den = value_int; + } + else if (setting == "width") { + stringstream(value) >> value_int; + info.width = value_int; + } + else if (setting == "height") { + stringstream(value) >> value_int; + info.height = value_int; + } + else if (setting == "progressive") { + stringstream(value) >> value_int; + info.interlaced_frame = !(bool)value_int; + } + else if (setting == "sample_aspect_num") { + stringstream(value) >> value_int; + info.pixel_ratio.num = value_int; + } + else if (setting == "sample_aspect_den") { + stringstream(value) >> value_int; + info.pixel_ratio.den = value_int; + } + else if (setting == "display_aspect_num") { + stringstream(value) >> value_int; + info.display_ratio.num = value_int; + } + else if (setting == "display_aspect_den") { + stringstream(value) >> value_int; + info.display_ratio.den = value_int; + } + else if (setting == "colorspace") { + stringstream(value) >> value_int; + info.pixel_format = value_int; + } + } + myfile.close(); + } + + + } + catch (exception e) + { + // Error parsing profile file + throw InvalidFile("Profile could not be found or loaded (or is invalid).", path); + } +} + +// Generate JSON string of this object +string Profile::Json() { + + // Return formatted string + return JsonValue().toStyledString(); +} + +// Generate Json::JsonValue for this object +Json::Value Profile::JsonValue() { + + // Create root json object + Json::Value root; + root["height"] = info.height; + root["width"] = info.width; + root["pixel_format"] = info.pixel_format; + root["fps"] = Json::Value(Json::objectValue); + root["fps"]["num"] = info.fps.num; + root["fps"]["den"] = info.fps.den; + root["pixel_ratio"] = Json::Value(Json::objectValue); + root["pixel_ratio"]["num"] = info.pixel_ratio.num; + root["pixel_ratio"]["den"] = info.pixel_ratio.den; + root["display_ratio"] = Json::Value(Json::objectValue); + root["display_ratio"]["num"] = info.display_ratio.num; + root["display_ratio"]["den"] = info.display_ratio.den; + root["interlaced_frame"] = info.interlaced_frame; + + // return JsonValue + return root; +} + +// Load JSON string into this object +void Profile::SetJson(string value) throw(InvalidJSON) { + + // Parse JSON string into JSON objects + Json::Value root; + Json::Reader reader; + bool success = reader.parse( value, root ); + if (!success) + // Raise exception + throw InvalidJSON("JSON could not be parsed (or is invalid)", ""); + + try + { + // Set all values that match + SetJsonValue(root); + } + catch (exception e) + { + // Error parsing JSON (or missing keys) + throw InvalidJSON("JSON is invalid (missing keys or invalid data types)", ""); + } +} + +// Load Json::JsonValue into this object +void Profile::SetJsonValue(Json::Value root) { + + if (!root["height"].isNull()) + info.height = root["height"].asInt(); + if (!root["width"].isNull()) + info.width = root["width"].asInt(); + if (!root["pixel_format"].isNull()) + info.pixel_format = root["pixel_format"].asInt(); + if (!root["fps"].isNull()) { + info.fps.num = root["fps"]["num"].asInt(); + info.fps.den = root["fps"]["den"].asInt(); + } + if (!root["pixel_ratio"].isNull()) { + info.pixel_ratio.num = root["pixel_ratio"]["num"].asInt(); + info.pixel_ratio.den = root["pixel_ratio"]["den"].asInt(); + } + if (!root["display_ratio"].isNull()) { + info.display_ratio.num = root["display_ratio"]["num"].asInt(); + info.display_ratio.den = root["display_ratio"]["den"].asInt(); + } + if (!root["interlaced_frame"].isNull()) + info.interlaced_frame = root["interlaced_frame"].asBool(); + +} diff --git a/src/openshot.i b/src/openshot.i index 8a93c76a..c2c794e0 100644 --- a/src/openshot.i +++ b/src/openshot.i @@ -67,6 +67,7 @@ #include "../include/ImageReader.h" #include "../include/PlayerBase.h" #include "../include/Point.h" +#include "../include/Profile.h" #include "../include/KeyFrame.h" #include "../include/SDLPlayer.h" #include "../include/TextReader.h" @@ -111,6 +112,7 @@ %include "../include/ImageReader.h" %include "../include/PlayerBase.h" %include "../include/Point.h" +%include "../include/Profile.h" %include "../include/KeyFrame.h" %include "../include/SDLPlayer.h" %include "../include/TextReader.h"