From 771a250a81abba401cf1f97ef026396c7c0fe75b Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Sat, 22 Jun 2019 22:57:01 -0700 Subject: [PATCH] fleshed out footage class --- app/CMakeLists.txt | 2 + app/project/CMakeLists.txt | 6 +- app/project/item/CMakeLists.txt | 25 ++ app/project/item/folder/CMakeLists.txt | 23 ++ app/project/{ => item/folder}/folder.cpp | 0 app/project/{ => item/folder}/folder.h | 2 +- app/project/item/footage/CMakeLists.txt | 27 ++ app/project/item/footage/audiostream.cpp | 53 ++++ app/project/item/footage/audiostream.h | 33 ++ app/project/item/footage/footage.cpp | 21 ++ app/project/item/footage/footage.h | 27 ++ app/project/item/footage/videostream.cpp | 64 ++++ app/project/item/footage/videostream.h | 37 +++ app/project/{ => item}/item.cpp | 4 + app/project/{ => item}/item.h | 27 +- app/project/project.h | 2 +- app/rational.cpp | 377 +++++++++++++++++++++++ app/rational.h | 65 ++++ 18 files changed, 788 insertions(+), 7 deletions(-) create mode 100644 app/project/item/CMakeLists.txt create mode 100644 app/project/item/folder/CMakeLists.txt rename app/project/{ => item/folder}/folder.cpp (100%) rename app/project/{ => item/folder}/folder.h (83%) create mode 100644 app/project/item/footage/CMakeLists.txt create mode 100644 app/project/item/footage/audiostream.cpp create mode 100644 app/project/item/footage/audiostream.h create mode 100644 app/project/item/footage/footage.cpp create mode 100644 app/project/item/footage/footage.h create mode 100644 app/project/item/footage/videostream.cpp create mode 100644 app/project/item/footage/videostream.h rename app/project/{ => item}/item.cpp (88%) rename app/project/{ => item}/item.h (53%) create mode 100644 app/rational.cpp create mode 100644 app/rational.h diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 8abc90033..dbc42a041 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -19,6 +19,8 @@ set(OLIVE_SOURCES core.h core.cpp main.cpp + rational.h + rational.cpp ) #add_subdirectory(decoder) diff --git a/app/project/CMakeLists.txt b/app/project/CMakeLists.txt index bceeb1898..1b9763aba 100644 --- a/app/project/CMakeLists.txt +++ b/app/project/CMakeLists.txt @@ -14,12 +14,10 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +add_subdirectory(item) + set(OLIVE_SOURCES ${OLIVE_SOURCES} - project/folder.h - project/folder.cpp - project/item.h - project/item.cpp project/project.h project/project.cpp project/projectviewmodel.h diff --git a/app/project/item/CMakeLists.txt b/app/project/item/CMakeLists.txt new file mode 100644 index 000000000..457197f1b --- /dev/null +++ b/app/project/item/CMakeLists.txt @@ -0,0 +1,25 @@ +# Olive - Non-Linear Video Editor +# Copyright (C) 2019 Olive Team +# +# This program 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. +# +# This program 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 this program. If not, see . + +add_subdirectory(folder) +add_subdirectory(footage) + +set(OLIVE_SOURCES + ${OLIVE_SOURCES} + project/item/item.h + project/item/item.cpp + PARENT_SCOPE +) diff --git a/app/project/item/folder/CMakeLists.txt b/app/project/item/folder/CMakeLists.txt new file mode 100644 index 000000000..b055fbeb5 --- /dev/null +++ b/app/project/item/folder/CMakeLists.txt @@ -0,0 +1,23 @@ +# Olive - Non-Linear Video Editor +# Copyright (C) 2019 Olive Team +# +# This program 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. +# +# This program 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 this program. If not, see . + + +set(OLIVE_SOURCES + ${OLIVE_SOURCES} + project/item/folder/folder.h + project/item/folder/folder.cpp + PARENT_SCOPE +) diff --git a/app/project/folder.cpp b/app/project/item/folder/folder.cpp similarity index 100% rename from app/project/folder.cpp rename to app/project/item/folder/folder.cpp diff --git a/app/project/folder.h b/app/project/item/folder/folder.h similarity index 83% rename from app/project/folder.h rename to app/project/item/folder/folder.h index 24daf2da1..7a8bc07df 100644 --- a/app/project/folder.h +++ b/app/project/item/folder/folder.h @@ -1,7 +1,7 @@ #ifndef FOLDER_H #define FOLDER_H -#include "item.h" +#include "project/item/item.h" class Folder : public Item { diff --git a/app/project/item/footage/CMakeLists.txt b/app/project/item/footage/CMakeLists.txt new file mode 100644 index 000000000..a6972cbd0 --- /dev/null +++ b/app/project/item/footage/CMakeLists.txt @@ -0,0 +1,27 @@ +# Olive - Non-Linear Video Editor +# Copyright (C) 2019 Olive Team +# +# This program 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. +# +# This program 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 this program. If not, see . + + +set(OLIVE_SOURCES + ${OLIVE_SOURCES} + project/item/footage/audiostream.h + project/item/footage/audiostream.cpp + project/item/footage/footage.h + project/item/footage/footage.cpp + project/item/footage/videostream.h + project/item/footage/videostream.cpp + PARENT_SCOPE +) diff --git a/app/project/item/footage/audiostream.cpp b/app/project/item/footage/audiostream.cpp new file mode 100644 index 000000000..7174491e3 --- /dev/null +++ b/app/project/item/footage/audiostream.cpp @@ -0,0 +1,53 @@ +#include "audiostream.h" + +AudioStream::AudioStream(Footage* footage, + const int& channels, + const int& layout, + const int& sample_rate) : + footage_(footage), + channels_(channels), + layout_(layout), + sample_rate_(sample_rate) +{ + +} + +Footage *AudioStream::footage() +{ + return footage_; +} + +void AudioStream::set_footage(Footage *f) +{ + footage_ = f; +} + +const int &AudioStream::channels() +{ + return channels_; +} + +void AudioStream::set_channels(const int &channels) +{ + channels_ = channels; +} + +const int &AudioStream::layout() +{ + return layout_; +} + +void AudioStream::set_layout(const int &layout) +{ + layout_ = layout; +} + +const int &AudioStream::sample_rate() +{ + return sample_rate_; +} + +void AudioStream::set_sample_rate(const int &sample_rate) +{ + sample_rate_ = sample_rate; +} diff --git a/app/project/item/footage/audiostream.h b/app/project/item/footage/audiostream.h new file mode 100644 index 000000000..7c886f9b5 --- /dev/null +++ b/app/project/item/footage/audiostream.h @@ -0,0 +1,33 @@ +#ifndef AUDIOSTREAM_H +#define AUDIOSTREAM_H + +#include "rational.h" + +class Footage; + +class AudioStream +{ +public: + AudioStream(Footage* footage, const int& channels, const int& layout, const int& sample_rate); + + Footage* footage(); + void set_footage(Footage* f); + + const int& channels(); + void set_channels(const int& channels); + + const int& layout(); + void set_layout(const int& layout); + + const int& sample_rate(); + void set_sample_rate(const int& sample_rate); + +private: + Footage* footage_; + + int channels_; + int layout_; + int sample_rate_; +}; + +#endif // AUDIOSTREAM_H diff --git a/app/project/item/footage/footage.cpp b/app/project/item/footage/footage.cpp new file mode 100644 index 000000000..b83449d98 --- /dev/null +++ b/app/project/item/footage/footage.cpp @@ -0,0 +1,21 @@ +#include "footage.h" + +Footage::Footage() +{ + +} + +const QString &Footage::filename() +{ + return filename_; +} + +void Footage::set_filename(const QString &s) +{ + filename_ = s; +} + +Item::Type Footage::type() const +{ + return kFootage; +} diff --git a/app/project/item/footage/footage.h b/app/project/item/footage/footage.h new file mode 100644 index 000000000..9e169c04f --- /dev/null +++ b/app/project/item/footage/footage.h @@ -0,0 +1,27 @@ +#ifndef FOOTAGE_H +#define FOOTAGE_H + +#include "project/item/item.h" +#include "project/item/footage/audiostream.h" +#include "project/item/footage/videostream.h" + +#include + +class Footage : public Item +{ +public: + Footage(); + + const QString& filename(); + void set_filename(const QString& s); + + virtual Type type() const override; + +private: + QString filename_; + + QList video_streams_; + QList audio_streams_; +}; + +#endif // FOOTAGE_H diff --git a/app/project/item/footage/videostream.cpp b/app/project/item/footage/videostream.cpp new file mode 100644 index 000000000..ada80cff8 --- /dev/null +++ b/app/project/item/footage/videostream.cpp @@ -0,0 +1,64 @@ +#include "videostream.h" + +VideoStream::VideoStream(Footage *footage, + const int &index, + const int &width, + const int &height, + const rational &timebase) : + footage_(footage), + index_(index), + width_(width), + height_(height), + timebase_(timebase) +{ +} + +Footage *VideoStream::footage() +{ + return footage_; +} + +void VideoStream::set_footage(Footage *f) +{ + footage_ = f; +} + +const int &VideoStream::index() +{ + return index_; +} + +void VideoStream::set_index(const int &index) +{ + index_ = index; +} + +const int &VideoStream::width() +{ + return width_; +} + +void VideoStream::set_width(const int &width) +{ + width_ = width; +} + +const int &VideoStream::height() +{ + return height_; +} + +void VideoStream::set_height(const int &height) +{ + height_ = height; +} + +const rational &VideoStream::timebase() +{ + return timebase_; +} + +void VideoStream::set_timebase(const rational &timebase) +{ + timebase_ = timebase; +} diff --git a/app/project/item/footage/videostream.h b/app/project/item/footage/videostream.h new file mode 100644 index 000000000..e5a57ca61 --- /dev/null +++ b/app/project/item/footage/videostream.h @@ -0,0 +1,37 @@ +#ifndef VIDEOSTREAM_H +#define VIDEOSTREAM_H + +#include "rational.h" + +class Footage; + +class VideoStream +{ +public: + VideoStream(Footage* footage, const int& index, const int& width, const int& height, const rational& timebase); + + Footage* footage(); + void set_footage(Footage* f); + + const int& index(); + void set_index(const int& index); + + const int& width(); + void set_width(const int& width); + + const int& height(); + void set_height(const int& height); + + const rational& timebase(); + void set_timebase(const rational& timebase); + +private: + Footage* footage_; + + int index_; + int width_; + int height_; + rational timebase_; +}; + +#endif // VIDEOSTREAM_H diff --git a/app/project/item.cpp b/app/project/item/item.cpp similarity index 88% rename from app/project/item.cpp rename to app/project/item/item.cpp index 4814b0f95..2b82cf023 100644 --- a/app/project/item.cpp +++ b/app/project/item/item.cpp @@ -7,6 +7,10 @@ Item::Item() : Item::~Item() { + // Delete all children + for (int i=0;i #include -#include "folder.h" +#include "project/item/folder/folder.h" class Project : public QObject { diff --git a/app/rational.cpp b/app/rational.cpp new file mode 100644 index 000000000..e6df7a871 --- /dev/null +++ b/app/rational.cpp @@ -0,0 +1,377 @@ +#include "rational.h" + +rational::rational(const int64_t &numerator) : + numerator_(numerator), + denominator_(1) +{ + if (numerator_ == 0) { + denominator_ = 0; + } +} + +rational::rational(const int64_t &numerator, const int64_t &denominator) : + numerator_(numerator), + denominator_(denominator) +{ + if (denominator_ != 0) { + + if (numerator_ != 0) { + FixSigns(); + Reduce(); + } else { + denominator_ = 0; + } + + } else { + numerator_ = 0; + } +} + +rational::rational(const AVRational &r) : + numerator_(r.num), + denominator_(r.den) +{ +} + +rational::rational(const rational &r) : + numerator_(r.numerator_), + denominator_(r.denominator_) +{ +} + +const rational &rational::operator=(const rational &r) +{ + if (this != &r) { + numerator_ = r.numerator_; + denominator_ = r.denominator_; + } + + return *this; +} + +const rational &rational::operator+=(const rational &r) +{ + if (numerator_ * denominator_ == 0 && r.numerator_ * r.denominator_ == 0) { + numerator_ = 0; + denominator_ = 0; + } else { + if(numerator_ * denominator_ != 0 && r.numerator_ * r.denominator_ == 0) { + // The other rational == 0, no addition needs to be done + } else { + if(numerator_ * denominator_ == 0 && r.numerator_ * r.denominator_ != 0) + { + numerator_ = r.numerator_; + denominator_ = r.denominator_; + } + else + { + numerator_ = (numerator_ * r.denominator_) + (r.numerator_ * denominator_); + denominator_ = denominator_ * r.denominator_; + FixSigns(); + Reduce(); + } + } + } + return *this; +} + +const rational &rational::operator-=(const rational &r) +{ + if(numerator_ * denominator_ == 0 && r.numerator_ * r.numerator_ == 0) { + numerator_ = 0; + denominator_ = 0; + } else { + if(numerator_ * denominator_ != 0 && r.numerator_ * r.denominator_ == 0) { + + } else { + if(numerator_ * denominator_ == 0 && r.numerator_ * r.denominator_ != 0) { + numerator_ = -(r.numerator_); + denominator_ = r.denominator_; + } else { + numerator_ = (numerator_ * r.denominator_) - (r.numerator_ * denominator_); + numerator_ = denominator_ * r.denominator_; + FixSigns(); + Reduce(); + } + } + } + return *this; +} + +const rational &rational::operator/=(const rational &r) +{ + numerator_ = numerator_ * r.denominator_; + denominator_ = denominator_ * r.numerator_; + FixSigns(); + Reduce(); + return *this; +} + +const rational &rational::operator*=(const rational &r) +{ + numerator_ = numerator_ * r.numerator_; + denominator_ = denominator_ * r.denominator_; + FixSigns(); + Reduce(); + return *this; +} + +rational rational::operator+(const rational &r) const +{ + rational result(*this); + result += r; + return result; +} + +rational rational::operator-(const rational &r) const +{ + rational result(*this); + result -= r; + return result; +} + +rational rational::operator/(const rational &r) const +{ + rational result(*this); + result /= r; + return result; +} + +rational rational::operator*(const rational &r) const +{ + rational result(*this); + result *= r; + return result; +} + +bool rational::operator<(const rational &r) const +{ + if (numerator_ * denominator_ == 0 && r.numerator_ * r.denominator_ == 0) { + return false; + } else { + if (numerator_ * denominator_ != 0 && r.numerator_ * r.denominator_ == 0) { + if(numerator_ * denominator_ < 0) + return true; + else + return false; + } + else { + if (numerator_ * denominator_ == 0 && r.numerator_ * r.denominator_ != 0) { + if (r.numerator_ * r.denominator_ < 0) { + return false; + } else { + return true; + } + } else { + return ((numerator_ * r.denominator_) < (denominator_ * r.numerator_)); + } + } + } +} + +bool rational::operator<=(const rational &r) const +{ + if(numerator_ * denominator_ == 0 && r.numerator_ * r.denominator_ == 0) { + return true; + } else { + if(numerator_ * denominator_ != 0 && r.numerator_ * r.denominator_ == 0) { + if(numerator_ * denominator_ < 0) { + return true; + } else { + return false; + } + } else { + if(numerator_ * denominator_ == 0 && r.numerator_ * r.denominator_ != 0) { + if(r.numerator_ * r.denominator_ < 0) { + return false; + } else { + return true; + } + } else { + return ((numerator_ * r.denominator_) <= (denominator_ * r.numerator_)); + } + } + } +} + +bool rational::operator>(const rational &r) const +{ + if(numerator_ * denominator_ == 0 && r.numerator_ * r.denominator_ == 0) { + return false; + } else { + if(numerator_ * denominator_ != 0 && r.numerator_ * r.denominator_ == 0) { + if(numerator_ * denominator_ > 0) { + return true; + } else { + return false; + } + } else { + if(numerator_ * denominator_ == 0 && r.numerator_ * r.denominator_ != 0) { + if(r.numerator_ * r.denominator_ > 0) { + return false; + } else { + return true; + } + } else { + return ((numerator_ * r.denominator_) > (denominator_ * r.numerator_)); + } + } + } +} + +bool rational::operator>=(const rational &r) const +{ + if(numerator_ * denominator_ == 0 && r.numerator_ * r.denominator_ == 0) { + return true; + } else { + if(numerator_ * denominator_ != 0 && r.numerator_ * r.denominator_ == 0) { + if(numerator_ * denominator_ > 0) { + return true; + } else { + return false; + } + } else { + if(numerator_ * denominator_ == 0 && r.numerator_ * r.denominator_ != 0) { + if(r.numerator_ * r.denominator_ > 0) { + return false; + } else { + return true; + } + } else { + return ((numerator_ * r.denominator_) >= (denominator_ * r.numerator_)); + } + } + } +} + +bool rational::operator==(const rational &r) const +{ + return (numerator_ == r.numerator_ && denominator_ == r.denominator_); +} + +bool rational::operator!=(const rational &r) const +{ + return (numerator_ != r.numerator_) || (denominator_ != r.denominator_); +} + +const rational &rational::operator++() +{ + numerator_ += denominator_; + return *this; +} + +rational rational::operator++(int) +{ + rational tmp = *this; + numerator_ += denominator_; + return tmp; +} + +const rational &rational::operator--() +{ + numerator_ -= denominator_; + return *this; +} + +rational rational::operator--(int) +{ + rational tmp; + numerator_ -= denominator_; + return tmp; +} + +const rational &rational::operator+() const +{ + return *this; +} + +rational rational::operator-() const +{ + return rational(numerator_, -denominator_); +} + +bool rational::operator!() const +{ + return !numerator_; +} + +double rational::ToDouble() const +{ + if (denominator_ == 0) { + return 0; + } else { + return static_cast(numerator_)/static_cast(denominator_); + } +} + +void rational::FixSigns() +{ + // Ensures denominator is always positive (while numerator can be positive or negative) + if(denominator_ < 0) { + denominator_ = -denominator_; + numerator_ = -numerator_; + } + + // Ensures if either are zero, they're both zero + if(numerator_ == 0 || denominator_ == 0) { + numerator_ = 0; + denominator_ = 0; + } +} + +void rational::Reduce() +{ + int64_t d = 1; + + if(denominator_ != 0 && numerator_ != 0) { + d = GreatestCommonDenominator(numerator_, denominator_); + } + + if(d > 1) { + numerator_ /= d; + denominator_ /= d; + } +} + +int64_t rational::GreatestCommonDenominator(const int64_t& x, const int64_t& y) +{ + if (y == 0) { + return x; + } else { + int64_t tmp = x % y; + return GreatestCommonDenominator(y, tmp); + } +} + +std::ostream &operator<<(std::ostream &out, const rational &value) +{ + out << value.numerator_; + if(value.denominator_ != 1) + { + out << '/' << value.denominator_; + return out; + } + return out; +} + +std::istream &operator>>(std::istream &in, rational &value) +{ + in >> value.numerator_; + value.denominator_ = 1; + + char ch; + in.get(ch); + + if(!in.eof()) + { + if(ch == '/') + { + in >> value.denominator_; + value.FixSigns(); + value.Reduce(); + } + else + in.putback(ch); + } + return in; +} diff --git a/app/rational.h b/app/rational.h new file mode 100644 index 000000000..4a314757c --- /dev/null +++ b/app/rational.h @@ -0,0 +1,65 @@ +#ifndef RATIONAL_H +#define RATIONAL_H + +// Adapted from https://github.com/angularadam/Qt-Class-rational used in compliance with the GNU General Public License + +#include + +extern "C" { + #include +} + +class rational { +public: + // Constructors + rational(const int64_t& numerator = 0); + rational(const int64_t& numerator, const int64_t& denominator); + rational(const AVRational& r); // Auto-convert from an FFmpeg AVRational + rational(const rational& r); + + // Assignment Operators + const rational& operator=(const rational& r); + const rational& operator+=(const rational& r); + const rational& operator-=(const rational& r); + const rational& operator/=(const rational& r); + const rational& operator*=(const rational& r); + + // Math Operators + rational operator+(const rational& r) const; + rational operator-(const rational& r) const; + rational operator/(const rational& r) const; + rational operator*(const rational& r) const; + + // Relational and Equality Operators + bool operator<(const rational &r) const; + bool operator<=(const rational &r) const; + bool operator>(const rational &r) const; + bool operator>=(const rational &r) const; + bool operator==(const rational &r) const; + bool operator!=(const rational &r) const; + + //Unary operators + const rational& operator++(); //prefix + rational operator++(int); //postfix + const rational& operator--(); //prefix + rational operator--(int); //postfix + const rational& operator+() const; + rational operator-() const; + bool operator!() const; + + // IO + friend std::ostream& operator<<(std::ostream &out, const rational& value); + friend std::istream& operator>>(std::istream &in, rational& value); + + // Convert to double + double ToDouble() const; +private: + int64_t numerator_; + int64_t denominator_; + + void FixSigns(); + void Reduce(); + int64_t GreatestCommonDenominator(const int64_t &x, const int64_t &y); +}; + +#endif // RATIONAL_H