2014-01-09 17:37:04 -06:00
|
|
|
/**
|
|
|
|
|
* @file
|
|
|
|
|
* @brief Source file for Profile class
|
|
|
|
|
* @author Jonathan Thomas <jonathan@openshot.org>
|
|
|
|
|
*
|
2019-06-09 08:31:04 -04:00
|
|
|
* @ref License
|
|
|
|
|
*/
|
|
|
|
|
|
2021-10-16 01:26:26 -04:00
|
|
|
// Copyright (c) 2008-2019 OpenShot Studios, LLC
|
|
|
|
|
//
|
|
|
|
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
2014-01-09 17:37:04 -06:00
|
|
|
|
Improved Profile Class (Helper methods, Sortable, Unit tests) (#895)
* Removing legacy profile property. Add new operators for Profile classes (for comparison). Also added new functions to generate different variations of the Profile data (key, short name, long name, long name w/description).
* Add empty constructor for Profile class, and new Profile unit tets
* Adding zero padding to profile Key function, for easier sorting: 01920x1080i2997_16:09
* Clear setfill flag after creating Key() output
* Updating example exe to load an *.osp project file via C++, which makes debugging complex broken projects much easier.
* - Add new unit test to FFmpegWriter to create an animated GIF and verify it can be wrapped with a FrameMapper (with no audio track)
- Improve FrameMapper to ignore missing audio data (i.e. when no audio samples present, don't try and find them or resample them)
* Fix some whitespace issues
* Fix inline documentation mistype
* Fixed missing reuse licensing on new example profile files
* Changing Profile::Key() format to exclude the : character, since Windows file names cannot contain that
* - Large memory leak fixed in FFmpegWriter when closing the video & audio contexts
- Reducing # of cached frames and rescalers to 1, since we no longer use OMP and this is unneeded - we need to refactor much of this code out eventually
* - Fixing whitespace issues
- Code clean-up / line wrapping / etc...
2023-02-02 16:29:38 -06:00
|
|
|
#include <iomanip>
|
2020-10-18 07:43:37 -04:00
|
|
|
#include "Profiles.h"
|
2021-01-26 10:52:04 -05:00
|
|
|
#include "Exceptions.h"
|
2014-01-09 17:37:04 -06:00
|
|
|
|
|
|
|
|
using namespace openshot;
|
|
|
|
|
|
Improved Profile Class (Helper methods, Sortable, Unit tests) (#895)
* Removing legacy profile property. Add new operators for Profile classes (for comparison). Also added new functions to generate different variations of the Profile data (key, short name, long name, long name w/description).
* Add empty constructor for Profile class, and new Profile unit tets
* Adding zero padding to profile Key function, for easier sorting: 01920x1080i2997_16:09
* Clear setfill flag after creating Key() output
* Updating example exe to load an *.osp project file via C++, which makes debugging complex broken projects much easier.
* - Add new unit test to FFmpegWriter to create an animated GIF and verify it can be wrapped with a FrameMapper (with no audio track)
- Improve FrameMapper to ignore missing audio data (i.e. when no audio samples present, don't try and find them or resample them)
* Fix some whitespace issues
* Fix inline documentation mistype
* Fixed missing reuse licensing on new example profile files
* Changing Profile::Key() format to exclude the : character, since Windows file names cannot contain that
* - Large memory leak fixed in FFmpegWriter when closing the video & audio contexts
- Reducing # of cached frames and rescalers to 1, since we no longer use OMP and this is unneeded - we need to refactor much of this code out eventually
* - Fixing whitespace issues
- Code clean-up / line wrapping / etc...
2023-02-02 16:29:38 -06:00
|
|
|
// default constructor
|
|
|
|
|
Profile::Profile() {
|
|
|
|
|
// Initialize info values
|
|
|
|
|
info.description = "";
|
|
|
|
|
info.height = 0;
|
|
|
|
|
info.width = 0;
|
|
|
|
|
info.pixel_format = 0;
|
|
|
|
|
info.fps.num = 0;
|
|
|
|
|
info.fps.den = 0;
|
|
|
|
|
info.pixel_ratio.num = 0;
|
|
|
|
|
info.pixel_ratio.den = 0;
|
|
|
|
|
info.display_ratio.num = 0;
|
|
|
|
|
info.display_ratio.den = 0;
|
|
|
|
|
info.interlaced_frame = false;
|
2025-05-20 16:02:23 -05:00
|
|
|
info.spherical = false; // Default to non-spherical (regular) video
|
Improved Profile Class (Helper methods, Sortable, Unit tests) (#895)
* Removing legacy profile property. Add new operators for Profile classes (for comparison). Also added new functions to generate different variations of the Profile data (key, short name, long name, long name w/description).
* Add empty constructor for Profile class, and new Profile unit tets
* Adding zero padding to profile Key function, for easier sorting: 01920x1080i2997_16:09
* Clear setfill flag after creating Key() output
* Updating example exe to load an *.osp project file via C++, which makes debugging complex broken projects much easier.
* - Add new unit test to FFmpegWriter to create an animated GIF and verify it can be wrapped with a FrameMapper (with no audio track)
- Improve FrameMapper to ignore missing audio data (i.e. when no audio samples present, don't try and find them or resample them)
* Fix some whitespace issues
* Fix inline documentation mistype
* Fixed missing reuse licensing on new example profile files
* Changing Profile::Key() format to exclude the : character, since Windows file names cannot contain that
* - Large memory leak fixed in FFmpegWriter when closing the video & audio contexts
- Reducing # of cached frames and rescalers to 1, since we no longer use OMP and this is unneeded - we need to refactor much of this code out eventually
* - Fixing whitespace issues
- Code clean-up / line wrapping / etc...
2023-02-02 16:29:38 -06:00
|
|
|
}
|
2014-01-09 17:37:04 -06:00
|
|
|
|
|
|
|
|
// @brief Constructor for Profile.
|
|
|
|
|
// @param path The folder path / location of a profile file
|
2019-08-04 22:56:52 -04:00
|
|
|
Profile::Profile(std::string path) {
|
2014-01-10 17:05:20 -06:00
|
|
|
|
|
|
|
|
bool read_file = false;
|
|
|
|
|
|
2025-05-20 16:02:23 -05:00
|
|
|
// Initialize all values to defaults (same as default constructor)
|
|
|
|
|
info.description = "";
|
|
|
|
|
info.height = 0;
|
|
|
|
|
info.width = 0;
|
|
|
|
|
info.pixel_format = 0;
|
|
|
|
|
info.fps.num = 0;
|
|
|
|
|
info.fps.den = 0;
|
|
|
|
|
info.pixel_ratio.num = 0;
|
|
|
|
|
info.pixel_ratio.den = 0;
|
|
|
|
|
info.display_ratio.num = 0;
|
|
|
|
|
info.display_ratio.den = 0;
|
|
|
|
|
info.interlaced_frame = false;
|
|
|
|
|
info.spherical = false; // Default to non-spherical (regular) video
|
Improved Profile Class (Helper methods, Sortable, Unit tests) (#895)
* Removing legacy profile property. Add new operators for Profile classes (for comparison). Also added new functions to generate different variations of the Profile data (key, short name, long name, long name w/description).
* Add empty constructor for Profile class, and new Profile unit tets
* Adding zero padding to profile Key function, for easier sorting: 01920x1080i2997_16:09
* Clear setfill flag after creating Key() output
* Updating example exe to load an *.osp project file via C++, which makes debugging complex broken projects much easier.
* - Add new unit test to FFmpegWriter to create an animated GIF and verify it can be wrapped with a FrameMapper (with no audio track)
- Improve FrameMapper to ignore missing audio data (i.e. when no audio samples present, don't try and find them or resample them)
* Fix some whitespace issues
* Fix inline documentation mistype
* Fixed missing reuse licensing on new example profile files
* Changing Profile::Key() format to exclude the : character, since Windows file names cannot contain that
* - Large memory leak fixed in FFmpegWriter when closing the video & audio contexts
- Reducing # of cached frames and rescalers to 1, since we no longer use OMP and this is unneeded - we need to refactor much of this code out eventually
* - Fixing whitespace issues
- Code clean-up / line wrapping / etc...
2023-02-02 16:29:38 -06:00
|
|
|
|
2014-01-09 17:37:04 -06:00
|
|
|
try
|
|
|
|
|
{
|
2017-05-16 17:07:06 -05:00
|
|
|
QFile inputFile(path.c_str());
|
|
|
|
|
if (inputFile.open(QIODevice::ReadOnly))
|
2014-01-09 17:37:04 -06:00
|
|
|
{
|
2017-05-16 17:07:06 -05:00
|
|
|
QTextStream in(&inputFile);
|
|
|
|
|
while (!in.atEnd())
|
2014-01-09 17:37:04 -06:00
|
|
|
{
|
2017-05-16 17:07:06 -05:00
|
|
|
QString line = in.readLine();
|
2014-01-09 17:37:04 -06:00
|
|
|
|
|
|
|
|
if (line.length() <= 0)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
// Split current line
|
2017-05-16 17:07:06 -05:00
|
|
|
QStringList parts = line.split( "=" );
|
2019-08-04 22:56:52 -04:00
|
|
|
std::string setting = parts[0].toStdString();
|
|
|
|
|
std::string value = parts[1].toStdString();
|
2014-01-09 17:37:04 -06:00
|
|
|
int value_int = 0;
|
|
|
|
|
|
|
|
|
|
// update struct (based on line number)
|
Improved Profile Class (Helper methods, Sortable, Unit tests) (#895)
* Removing legacy profile property. Add new operators for Profile classes (for comparison). Also added new functions to generate different variations of the Profile data (key, short name, long name, long name w/description).
* Add empty constructor for Profile class, and new Profile unit tets
* Adding zero padding to profile Key function, for easier sorting: 01920x1080i2997_16:09
* Clear setfill flag after creating Key() output
* Updating example exe to load an *.osp project file via C++, which makes debugging complex broken projects much easier.
* - Add new unit test to FFmpegWriter to create an animated GIF and verify it can be wrapped with a FrameMapper (with no audio track)
- Improve FrameMapper to ignore missing audio data (i.e. when no audio samples present, don't try and find them or resample them)
* Fix some whitespace issues
* Fix inline documentation mistype
* Fixed missing reuse licensing on new example profile files
* Changing Profile::Key() format to exclude the : character, since Windows file names cannot contain that
* - Large memory leak fixed in FFmpegWriter when closing the video & audio contexts
- Reducing # of cached frames and rescalers to 1, since we no longer use OMP and this is unneeded - we need to refactor much of this code out eventually
* - Fixing whitespace issues
- Code clean-up / line wrapping / etc...
2023-02-02 16:29:38 -06:00
|
|
|
if (setting == "description") {
|
2014-01-09 17:37:04 -06:00
|
|
|
info.description = value;
|
Improved Profile Class (Helper methods, Sortable, Unit tests) (#895)
* Removing legacy profile property. Add new operators for Profile classes (for comparison). Also added new functions to generate different variations of the Profile data (key, short name, long name, long name w/description).
* Add empty constructor for Profile class, and new Profile unit tets
* Adding zero padding to profile Key function, for easier sorting: 01920x1080i2997_16:09
* Clear setfill flag after creating Key() output
* Updating example exe to load an *.osp project file via C++, which makes debugging complex broken projects much easier.
* - Add new unit test to FFmpegWriter to create an animated GIF and verify it can be wrapped with a FrameMapper (with no audio track)
- Improve FrameMapper to ignore missing audio data (i.e. when no audio samples present, don't try and find them or resample them)
* Fix some whitespace issues
* Fix inline documentation mistype
* Fixed missing reuse licensing on new example profile files
* Changing Profile::Key() format to exclude the : character, since Windows file names cannot contain that
* - Large memory leak fixed in FFmpegWriter when closing the video & audio contexts
- Reducing # of cached frames and rescalers to 1, since we no longer use OMP and this is unneeded - we need to refactor much of this code out eventually
* - Fixing whitespace issues
- Code clean-up / line wrapping / etc...
2023-02-02 16:29:38 -06:00
|
|
|
}
|
2014-01-09 17:37:04 -06:00
|
|
|
else if (setting == "frame_rate_num") {
|
2019-08-04 22:56:52 -04:00
|
|
|
std::stringstream(value) >> value_int;
|
2014-01-09 17:37:04 -06:00
|
|
|
info.fps.num = value_int;
|
|
|
|
|
}
|
|
|
|
|
else if (setting == "frame_rate_den") {
|
2019-08-04 22:56:52 -04:00
|
|
|
std::stringstream(value) >> value_int;
|
2014-01-09 17:37:04 -06:00
|
|
|
info.fps.den = value_int;
|
|
|
|
|
}
|
|
|
|
|
else if (setting == "width") {
|
2019-08-04 22:56:52 -04:00
|
|
|
std::stringstream(value) >> value_int;
|
2014-01-09 17:37:04 -06:00
|
|
|
info.width = value_int;
|
|
|
|
|
}
|
|
|
|
|
else if (setting == "height") {
|
2019-08-04 22:56:52 -04:00
|
|
|
std::stringstream(value) >> value_int;
|
2014-01-09 17:37:04 -06:00
|
|
|
info.height = value_int;
|
|
|
|
|
}
|
|
|
|
|
else if (setting == "progressive") {
|
2019-08-04 22:56:52 -04:00
|
|
|
std::stringstream(value) >> value_int;
|
2014-01-09 17:37:04 -06:00
|
|
|
info.interlaced_frame = !(bool)value_int;
|
|
|
|
|
}
|
|
|
|
|
else if (setting == "sample_aspect_num") {
|
2019-08-04 22:56:52 -04:00
|
|
|
std::stringstream(value) >> value_int;
|
2014-01-09 17:37:04 -06:00
|
|
|
info.pixel_ratio.num = value_int;
|
|
|
|
|
}
|
|
|
|
|
else if (setting == "sample_aspect_den") {
|
2019-08-04 22:56:52 -04:00
|
|
|
std::stringstream(value) >> value_int;
|
2014-01-09 17:37:04 -06:00
|
|
|
info.pixel_ratio.den = value_int;
|
|
|
|
|
}
|
|
|
|
|
else if (setting == "display_aspect_num") {
|
2019-08-04 22:56:52 -04:00
|
|
|
std::stringstream(value) >> value_int;
|
2014-01-09 17:37:04 -06:00
|
|
|
info.display_ratio.num = value_int;
|
|
|
|
|
}
|
|
|
|
|
else if (setting == "display_aspect_den") {
|
2019-08-04 22:56:52 -04:00
|
|
|
std::stringstream(value) >> value_int;
|
2014-01-09 17:37:04 -06:00
|
|
|
info.display_ratio.den = value_int;
|
|
|
|
|
}
|
|
|
|
|
else if (setting == "colorspace") {
|
2019-08-04 22:56:52 -04:00
|
|
|
std::stringstream(value) >> value_int;
|
2014-01-09 17:37:04 -06:00
|
|
|
info.pixel_format = value_int;
|
|
|
|
|
}
|
2025-05-20 16:02:23 -05:00
|
|
|
else if (setting == "spherical") {
|
|
|
|
|
std::stringstream(value) >> value_int;
|
|
|
|
|
info.spherical = (bool)value_int;
|
|
|
|
|
}
|
2014-01-09 17:37:04 -06:00
|
|
|
}
|
Improved Profile Class (Helper methods, Sortable, Unit tests) (#895)
* Removing legacy profile property. Add new operators for Profile classes (for comparison). Also added new functions to generate different variations of the Profile data (key, short name, long name, long name w/description).
* Add empty constructor for Profile class, and new Profile unit tets
* Adding zero padding to profile Key function, for easier sorting: 01920x1080i2997_16:09
* Clear setfill flag after creating Key() output
* Updating example exe to load an *.osp project file via C++, which makes debugging complex broken projects much easier.
* - Add new unit test to FFmpegWriter to create an animated GIF and verify it can be wrapped with a FrameMapper (with no audio track)
- Improve FrameMapper to ignore missing audio data (i.e. when no audio samples present, don't try and find them or resample them)
* Fix some whitespace issues
* Fix inline documentation mistype
* Fixed missing reuse licensing on new example profile files
* Changing Profile::Key() format to exclude the : character, since Windows file names cannot contain that
* - Large memory leak fixed in FFmpegWriter when closing the video & audio contexts
- Reducing # of cached frames and rescalers to 1, since we no longer use OMP and this is unneeded - we need to refactor much of this code out eventually
* - Fixing whitespace issues
- Code clean-up / line wrapping / etc...
2023-02-02 16:29:38 -06:00
|
|
|
read_file = true;
|
2017-05-16 17:07:06 -05:00
|
|
|
inputFile.close();
|
2014-01-09 17:37:04 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
2019-07-03 12:58:02 -04:00
|
|
|
catch (const std::exception& e)
|
2014-01-09 17:37:04 -06:00
|
|
|
{
|
|
|
|
|
// Error parsing profile file
|
|
|
|
|
throw InvalidFile("Profile could not be found or loaded (or is invalid).", path);
|
|
|
|
|
}
|
2014-01-10 17:05:20 -06:00
|
|
|
|
|
|
|
|
// Throw error if file was not read
|
|
|
|
|
if (!read_file)
|
|
|
|
|
// Error parsing profile file
|
|
|
|
|
throw InvalidFile("Profile could not be found or loaded (or is invalid).", path);
|
2014-01-09 17:37:04 -06:00
|
|
|
}
|
|
|
|
|
|
Improved Profile Class (Helper methods, Sortable, Unit tests) (#895)
* Removing legacy profile property. Add new operators for Profile classes (for comparison). Also added new functions to generate different variations of the Profile data (key, short name, long name, long name w/description).
* Add empty constructor for Profile class, and new Profile unit tets
* Adding zero padding to profile Key function, for easier sorting: 01920x1080i2997_16:09
* Clear setfill flag after creating Key() output
* Updating example exe to load an *.osp project file via C++, which makes debugging complex broken projects much easier.
* - Add new unit test to FFmpegWriter to create an animated GIF and verify it can be wrapped with a FrameMapper (with no audio track)
- Improve FrameMapper to ignore missing audio data (i.e. when no audio samples present, don't try and find them or resample them)
* Fix some whitespace issues
* Fix inline documentation mistype
* Fixed missing reuse licensing on new example profile files
* Changing Profile::Key() format to exclude the : character, since Windows file names cannot contain that
* - Large memory leak fixed in FFmpegWriter when closing the video & audio contexts
- Reducing # of cached frames and rescalers to 1, since we no longer use OMP and this is unneeded - we need to refactor much of this code out eventually
* - Fixing whitespace issues
- Code clean-up / line wrapping / etc...
2023-02-02 16:29:38 -06:00
|
|
|
// Return a formatted FPS
|
|
|
|
|
std::string Profile::formattedFPS(bool include_decimal) {
|
|
|
|
|
// Format FPS to use 2 decimals (if needed)
|
|
|
|
|
float fps = info.fps.ToFloat();
|
|
|
|
|
std::stringstream fps_string;
|
|
|
|
|
if (info.fps.den == 1) {
|
|
|
|
|
// For example: 24.0 will become 24
|
|
|
|
|
fps_string << std::fixed << std::setprecision(0) << fps;
|
|
|
|
|
} else {
|
|
|
|
|
// For example: 29.97002997 will become 29.97
|
|
|
|
|
fps_string << std::fixed << std::setprecision(2) << fps;
|
|
|
|
|
// Remove decimal place using QString (for convenience)
|
|
|
|
|
if (!include_decimal) {
|
|
|
|
|
QString fps_qstring = QString::fromStdString(fps_string.str());
|
|
|
|
|
fps_qstring.replace(".", "");
|
|
|
|
|
fps_string.str(fps_qstring.toStdString());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return fps_string.str();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Return a unique key of this profile (01920x1080i2997_16-09)
|
|
|
|
|
std::string Profile::Key() {
|
|
|
|
|
std::stringstream output;
|
|
|
|
|
std::string progressive_str = "p";
|
|
|
|
|
if (info.interlaced_frame) {
|
|
|
|
|
progressive_str = "i";
|
|
|
|
|
}
|
|
|
|
|
std::string fps_string = formattedFPS(false);
|
|
|
|
|
output << std::setfill('0') << std::setw(5) << info.width << std::setfill('\0') << "x";
|
|
|
|
|
output << std::setfill('0') << std::setw(4) << info.height << std::setfill('\0') << progressive_str;
|
|
|
|
|
output << std::setfill('0') << std::setw(4) << fps_string << std::setfill('\0') << "_";
|
|
|
|
|
output << std::setfill('0') << std::setw(2) << info.display_ratio.num << std::setfill('\0') << "-";
|
|
|
|
|
output << std::setfill('0') << std::setw(2) << info.display_ratio.den << std::setfill('\0');
|
2025-05-20 16:02:23 -05:00
|
|
|
|
|
|
|
|
// Add spherical indicator
|
|
|
|
|
if (info.spherical) {
|
|
|
|
|
output << "_360";
|
|
|
|
|
}
|
|
|
|
|
|
Improved Profile Class (Helper methods, Sortable, Unit tests) (#895)
* Removing legacy profile property. Add new operators for Profile classes (for comparison). Also added new functions to generate different variations of the Profile data (key, short name, long name, long name w/description).
* Add empty constructor for Profile class, and new Profile unit tets
* Adding zero padding to profile Key function, for easier sorting: 01920x1080i2997_16:09
* Clear setfill flag after creating Key() output
* Updating example exe to load an *.osp project file via C++, which makes debugging complex broken projects much easier.
* - Add new unit test to FFmpegWriter to create an animated GIF and verify it can be wrapped with a FrameMapper (with no audio track)
- Improve FrameMapper to ignore missing audio data (i.e. when no audio samples present, don't try and find them or resample them)
* Fix some whitespace issues
* Fix inline documentation mistype
* Fixed missing reuse licensing on new example profile files
* Changing Profile::Key() format to exclude the : character, since Windows file names cannot contain that
* - Large memory leak fixed in FFmpegWriter when closing the video & audio contexts
- Reducing # of cached frames and rescalers to 1, since we no longer use OMP and this is unneeded - we need to refactor much of this code out eventually
* - Fixing whitespace issues
- Code clean-up / line wrapping / etc...
2023-02-02 16:29:38 -06:00
|
|
|
return output.str();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Return the name of this profile (1920x1080p29.97)
|
|
|
|
|
std::string Profile::ShortName() {
|
|
|
|
|
std::stringstream output;
|
|
|
|
|
std::string progressive_str = "p";
|
|
|
|
|
if (info.interlaced_frame) {
|
|
|
|
|
progressive_str = "i";
|
|
|
|
|
}
|
|
|
|
|
std::string fps_string = formattedFPS(true);
|
|
|
|
|
output << info.width << "x" << info.height << progressive_str << fps_string;
|
2025-05-20 16:02:23 -05:00
|
|
|
|
|
|
|
|
// Add 360° indicator for spherical videos
|
|
|
|
|
if (info.spherical) {
|
|
|
|
|
output << " 360°";
|
|
|
|
|
}
|
|
|
|
|
|
Improved Profile Class (Helper methods, Sortable, Unit tests) (#895)
* Removing legacy profile property. Add new operators for Profile classes (for comparison). Also added new functions to generate different variations of the Profile data (key, short name, long name, long name w/description).
* Add empty constructor for Profile class, and new Profile unit tets
* Adding zero padding to profile Key function, for easier sorting: 01920x1080i2997_16:09
* Clear setfill flag after creating Key() output
* Updating example exe to load an *.osp project file via C++, which makes debugging complex broken projects much easier.
* - Add new unit test to FFmpegWriter to create an animated GIF and verify it can be wrapped with a FrameMapper (with no audio track)
- Improve FrameMapper to ignore missing audio data (i.e. when no audio samples present, don't try and find them or resample them)
* Fix some whitespace issues
* Fix inline documentation mistype
* Fixed missing reuse licensing on new example profile files
* Changing Profile::Key() format to exclude the : character, since Windows file names cannot contain that
* - Large memory leak fixed in FFmpegWriter when closing the video & audio contexts
- Reducing # of cached frames and rescalers to 1, since we no longer use OMP and this is unneeded - we need to refactor much of this code out eventually
* - Fixing whitespace issues
- Code clean-up / line wrapping / etc...
2023-02-02 16:29:38 -06:00
|
|
|
return output.str();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Return a longer format name (1920x1080p @ 29.97 fps (16:9))
|
|
|
|
|
std::string Profile::LongName() {
|
|
|
|
|
std::stringstream output;
|
|
|
|
|
std::string progressive_str = "p";
|
|
|
|
|
if (info.interlaced_frame) {
|
|
|
|
|
progressive_str = "i";
|
|
|
|
|
}
|
|
|
|
|
std::string fps_string = formattedFPS(true);
|
|
|
|
|
output << info.width << "x" << info.height << progressive_str << " @ " << fps_string
|
|
|
|
|
<< " fps (" << info.display_ratio.num << ":" << info.display_ratio.den << ")";
|
2025-05-20 16:02:23 -05:00
|
|
|
|
|
|
|
|
// Add 360° indicator for spherical videos
|
|
|
|
|
if (info.spherical) {
|
|
|
|
|
output << " 360°";
|
|
|
|
|
}
|
|
|
|
|
|
Improved Profile Class (Helper methods, Sortable, Unit tests) (#895)
* Removing legacy profile property. Add new operators for Profile classes (for comparison). Also added new functions to generate different variations of the Profile data (key, short name, long name, long name w/description).
* Add empty constructor for Profile class, and new Profile unit tets
* Adding zero padding to profile Key function, for easier sorting: 01920x1080i2997_16:09
* Clear setfill flag after creating Key() output
* Updating example exe to load an *.osp project file via C++, which makes debugging complex broken projects much easier.
* - Add new unit test to FFmpegWriter to create an animated GIF and verify it can be wrapped with a FrameMapper (with no audio track)
- Improve FrameMapper to ignore missing audio data (i.e. when no audio samples present, don't try and find them or resample them)
* Fix some whitespace issues
* Fix inline documentation mistype
* Fixed missing reuse licensing on new example profile files
* Changing Profile::Key() format to exclude the : character, since Windows file names cannot contain that
* - Large memory leak fixed in FFmpegWriter when closing the video & audio contexts
- Reducing # of cached frames and rescalers to 1, since we no longer use OMP and this is unneeded - we need to refactor much of this code out eventually
* - Fixing whitespace issues
- Code clean-up / line wrapping / etc...
2023-02-02 16:29:38 -06:00
|
|
|
return output.str();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Return a longer format name (1920x1080p @ 29.97 fps (16:9) HD 1080i 29.97 fps)
|
|
|
|
|
std::string Profile::LongNameWithDesc() {
|
|
|
|
|
std::stringstream output;
|
|
|
|
|
std::string progressive_str = "p";
|
|
|
|
|
if (info.interlaced_frame) {
|
|
|
|
|
progressive_str = "i";
|
|
|
|
|
}
|
|
|
|
|
std::string fps_string = formattedFPS(true);
|
|
|
|
|
output << info.width << "x" << info.height << progressive_str << " @ " << fps_string
|
2025-05-20 16:02:23 -05:00
|
|
|
<< " fps (" << info.display_ratio.num << ":" << info.display_ratio.den << ")";
|
|
|
|
|
|
|
|
|
|
// Add 360° indicator for spherical videos
|
|
|
|
|
if (info.spherical) {
|
|
|
|
|
output << " 360°";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
output << " " << info.description;
|
Improved Profile Class (Helper methods, Sortable, Unit tests) (#895)
* Removing legacy profile property. Add new operators for Profile classes (for comparison). Also added new functions to generate different variations of the Profile data (key, short name, long name, long name w/description).
* Add empty constructor for Profile class, and new Profile unit tets
* Adding zero padding to profile Key function, for easier sorting: 01920x1080i2997_16:09
* Clear setfill flag after creating Key() output
* Updating example exe to load an *.osp project file via C++, which makes debugging complex broken projects much easier.
* - Add new unit test to FFmpegWriter to create an animated GIF and verify it can be wrapped with a FrameMapper (with no audio track)
- Improve FrameMapper to ignore missing audio data (i.e. when no audio samples present, don't try and find them or resample them)
* Fix some whitespace issues
* Fix inline documentation mistype
* Fixed missing reuse licensing on new example profile files
* Changing Profile::Key() format to exclude the : character, since Windows file names cannot contain that
* - Large memory leak fixed in FFmpegWriter when closing the video & audio contexts
- Reducing # of cached frames and rescalers to 1, since we no longer use OMP and this is unneeded - we need to refactor much of this code out eventually
* - Fixing whitespace issues
- Code clean-up / line wrapping / etc...
2023-02-02 16:29:38 -06:00
|
|
|
return output.str();
|
|
|
|
|
}
|
|
|
|
|
|
2024-10-09 16:18:35 -05:00
|
|
|
// Save profile to file system
|
|
|
|
|
void Profile::Save(const std::string& file_path) const {
|
|
|
|
|
std::ofstream file(file_path);
|
|
|
|
|
if (!file.is_open()) {
|
|
|
|
|
throw std::ios_base::failure("Failed to save profile.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
file << "description=" << info.description << "\n";
|
|
|
|
|
file << "frame_rate_num=" << info.fps.num << "\n";
|
|
|
|
|
file << "frame_rate_den=" << info.fps.den << "\n";
|
|
|
|
|
file << "width=" << info.width << "\n";
|
|
|
|
|
file << "height=" << info.height << "\n";
|
|
|
|
|
file << "progressive=" << !info.interlaced_frame << "\n"; // Correct the boolean value for progressive/interlaced
|
|
|
|
|
file << "sample_aspect_num=" << info.pixel_ratio.num << "\n";
|
|
|
|
|
file << "sample_aspect_den=" << info.pixel_ratio.den << "\n";
|
|
|
|
|
file << "display_aspect_num=" << info.display_ratio.num << "\n";
|
|
|
|
|
file << "display_aspect_den=" << info.display_ratio.den << "\n";
|
2025-05-20 16:02:23 -05:00
|
|
|
file << "pixel_format=" << info.pixel_format << "\n";
|
|
|
|
|
file << "spherical=" << info.spherical;
|
2024-10-09 16:18:35 -05:00
|
|
|
|
|
|
|
|
file.close();
|
|
|
|
|
}
|
|
|
|
|
|
2014-01-09 17:37:04 -06:00
|
|
|
// Generate JSON string of this object
|
2019-12-27 08:51:51 -05:00
|
|
|
std::string Profile::Json() const {
|
2014-01-09 17:37:04 -06:00
|
|
|
|
|
|
|
|
// Return formatted string
|
|
|
|
|
return JsonValue().toStyledString();
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-27 08:51:51 -05:00
|
|
|
// Generate Json::Value for this object
|
|
|
|
|
Json::Value Profile::JsonValue() const {
|
2014-01-09 17:37:04 -06:00
|
|
|
|
|
|
|
|
// Create root json object
|
|
|
|
|
Json::Value root;
|
2024-10-09 16:18:35 -05:00
|
|
|
root["description"] = info.description;
|
2014-01-09 17:37:04 -06:00
|
|
|
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;
|
2024-10-09 16:18:35 -05:00
|
|
|
root["progressive"] = !info.interlaced_frame;
|
2025-05-20 16:02:23 -05:00
|
|
|
root["spherical"] = info.spherical;
|
2014-01-09 17:37:04 -06:00
|
|
|
|
|
|
|
|
// return JsonValue
|
|
|
|
|
return root;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Load JSON string into this object
|
2019-12-27 08:51:51 -05:00
|
|
|
void Profile::SetJson(const std::string value) {
|
2014-01-09 17:37:04 -06:00
|
|
|
|
|
|
|
|
// Parse JSON string into JSON objects
|
|
|
|
|
try
|
|
|
|
|
{
|
2019-12-27 08:51:51 -05:00
|
|
|
const Json::Value root = openshot::stringToJson(value);
|
2014-01-09 17:37:04 -06:00
|
|
|
// Set all values that match
|
|
|
|
|
SetJsonValue(root);
|
|
|
|
|
}
|
2019-07-03 12:58:02 -04:00
|
|
|
catch (const std::exception& e)
|
2014-01-09 17:37:04 -06:00
|
|
|
{
|
|
|
|
|
// Error parsing JSON (or missing keys)
|
2019-08-27 15:47:39 -04:00
|
|
|
throw InvalidJSON("JSON is invalid (missing keys or invalid data types)");
|
2014-01-09 17:37:04 -06:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-27 08:51:51 -05:00
|
|
|
// Load Json::Value into this object
|
|
|
|
|
void Profile::SetJsonValue(const Json::Value root) {
|
2014-01-09 17:37:04 -06:00
|
|
|
|
2024-10-09 16:18:35 -05:00
|
|
|
if (!root["description"].isNull())
|
|
|
|
|
info.description = root["description"].asString();
|
2014-01-09 17:37:04 -06:00
|
|
|
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();
|
2024-10-09 16:18:35 -05:00
|
|
|
info.pixel_ratio.Reduce();
|
2014-01-09 17:37:04 -06:00
|
|
|
}
|
|
|
|
|
if (!root["display_ratio"].isNull()) {
|
|
|
|
|
info.display_ratio.num = root["display_ratio"]["num"].asInt();
|
|
|
|
|
info.display_ratio.den = root["display_ratio"]["den"].asInt();
|
2024-10-09 16:18:35 -05:00
|
|
|
info.display_ratio.Reduce();
|
2014-01-09 17:37:04 -06:00
|
|
|
}
|
2024-10-09 16:18:35 -05:00
|
|
|
if (!root["progressive"].isNull())
|
|
|
|
|
info.interlaced_frame = !root["progressive"].asBool();
|
2025-05-20 16:02:23 -05:00
|
|
|
if (!root["spherical"].isNull())
|
|
|
|
|
info.spherical = root["spherical"].asBool();
|
2014-01-09 17:37:04 -06:00
|
|
|
|
|
|
|
|
}
|