Files
vimix/Timeline.h
Bruno e3578df8a0 Player: move up timeline and adjust size
keep play button bar at the bottom for all configurations, avoid text and buttons overlay when Player is small. Fix cut timing in selection
2021-06-19 00:49:20 +02:00

165 lines
4.7 KiB
C++

#ifndef TIMELINE_H
#define TIMELINE_H
#include <string>
#include <sstream>
#include <set>
#include <list>
#include <gst/pbutils/pbutils.h>
#define MAX_TIMELINE_ARRAY 2000
struct TimeInterval
{
GstClockTime begin;
GstClockTime end;
TimeInterval()
{
reset();
}
TimeInterval(GstClockTime a, GstClockTime b) : TimeInterval()
{
if ( a != GST_CLOCK_TIME_NONE && b != GST_CLOCK_TIME_NONE) {
begin = MIN(a, b);
end = MAX(a, b);
}
}
inline void reset()
{
begin = GST_CLOCK_TIME_NONE;
end = GST_CLOCK_TIME_NONE;
}
inline GstClockTime duration() const
{
return is_valid() ? (end - begin) : GST_CLOCK_TIME_NONE;
}
inline bool is_valid() const
{
return begin != GST_CLOCK_TIME_NONE && end != GST_CLOCK_TIME_NONE && begin < end;
}
inline bool operator < (const TimeInterval b) const
{
return (this->is_valid() && b.is_valid() && this->end < b.begin);
}
inline bool operator == (const TimeInterval b) const
{
return (this->begin == b.begin && this->end == b.end);
}
inline bool operator != (const TimeInterval b) const
{
return (this->begin != b.begin || this->end != b.end);
}
inline TimeInterval& operator = (const TimeInterval& b)
{
if (this != &b) {
this->begin = b.begin;
this->end = b.end;
}
return *this;
}
inline bool includes(const GstClockTime t) const
{
return (is_valid() && t != GST_CLOCK_TIME_NONE && !(t < this->begin) && !(t > this->end) );
}
inline bool includes(const TimeInterval& b) const
{
return (is_valid() && b.is_valid() && includes(b.begin) && includes(b.end) );
}
};
struct order_comparator
{
inline bool operator () (const TimeInterval a, const TimeInterval b) const
{
return (a < b || a.begin < b.begin);
}
};
typedef std::set<TimeInterval, order_comparator> TimeIntervalSet;
class Timeline
{
public:
Timeline();
~Timeline();
Timeline& operator = (const Timeline& b);
bool is_valid();
void update();
void refresh();
// global properties of the timeline
// timeline is valid only if all 3 are set
void setFirst(GstClockTime first); // TODO : do we really use FIRST ?
void setEnd(GstClockTime end);
void setStep(GstClockTime dt);
void setTiming(TimeInterval interval, GstClockTime step = GST_CLOCK_TIME_NONE);
// Timing manipulation
inline GstClockTime begin() const { return timing_.begin; }
inline GstClockTime end() const { return timing_.end; }
inline GstClockTime first() const { return first_; }
inline GstClockTime last() const { return timing_.end - step_; }
inline GstClockTime step() const { return step_; }
inline GstClockTime duration() const { return timing_.duration(); }
inline size_t numFrames() const { if (step_) return duration() / step_; else return 1; }
inline TimeInterval interval() const { return timing_; }
GstClockTime next(GstClockTime time) const;
GstClockTime previous(GstClockTime time) const;
// Manipulation of gaps
inline TimeIntervalSet gaps() const { return gaps_; }
inline size_t numGaps() const { return gaps_.size(); }
float *gapsArray();
void clearGaps();
void setGaps(const TimeIntervalSet &g);
bool addGap(TimeInterval s);
bool addGap(GstClockTime begin, GstClockTime end);
bool cut(GstClockTime t, bool left, bool join_extremity);
bool removeGaptAt(GstClockTime t);
bool gapAt(const GstClockTime t) const;
bool getGapAt(const GstClockTime t, TimeInterval &gap) const;
// inverse of gaps: sections of play areas
TimeIntervalSet sections() const;
GstClockTime sectionsDuration() const;
GstClockTime sectionsTimeAt(GstClockTime t) const;
size_t fillSectionsArrays(float * const gaps, float * const fading);
// Manipulation of Fading
float fadingAt(const GstClockTime t) const;
size_t fadingIndexAt(const GstClockTime t) const;
inline float *fadingArray() { return fadingArray_; }
void clearFading();
// Edit
void smoothFading(uint N = 1);
void autoFading(uint milisecond = 100);
bool autoCut();
private:
void reset();
// global information on the timeline
TimeInterval timing_;
GstClockTime first_;
GstClockTime step_;
// main data structure containing list of gaps in the timeline
TimeIntervalSet gaps_;
float gapsArray_[MAX_TIMELINE_ARRAY];
bool gaps_array_need_update_;
// synchronize data structures
void updateGapsFromArray(float *array, size_t array_size);
void fillArrayFromGaps(float *array, size_t array_size);
float fadingArray_[MAX_TIMELINE_ARRAY];
};
#endif // TIMELINE_H