1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226
|
#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;
int type;
TimeInterval()
{
reset();
}
TimeInterval(const TimeInterval& b)
{
begin = b.begin;
end = b.end;
type = b.type;
}
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);
type = 0;
}
}
inline void reset()
{
begin = GST_CLOCK_TIME_NONE;
end = GST_CLOCK_TIME_NONE;
type = 0;
}
inline GstClockTime duration() const
{
return is_valid() ? (end - begin) : GST_CLOCK_TIME_NONE;
}
inline GstClockTime midpoint() const
{
return is_valid() ? (end - begin) / 2 + 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;
this->type = b.type;
}
return *this;
}
inline TimeInterval& operator %= (const GstClockTime& precision)
{
if (precision != GST_CLOCK_TIME_NONE && precision > 0) {
this->begin -= this->begin % precision;
this->end += precision - (this->end % precision) ;
}
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() const;
void update();
void refresh();
// global properties of the timeline
void setEnd(GstClockTime end);
void setStep(GstClockTime dt);
void setFirst(GstClockTime first);
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 duration() const { return timing_.duration(); }
inline GstClockTime first() const { return first_; }
inline GstClockTime last() const { return timing_.end - step_; }
inline GstClockTime step() const { return step_; }
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;
GstClockTime timeFromPercent(const float p) 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 = false);
bool removeGaptAt(GstClockTime t);
bool mergeGapstAt(GstClockTime t);
bool gapAt(const GstClockTime t) const;
bool getGapAt(const GstClockTime t, TimeInterval &gap) const;
// Manipulation of flags
inline TimeIntervalSet flags() const { return flags_; };
inline size_t numFlags() const { return flags_.size(); };
float *flagsArray();
bool addFlag(TimeInterval f);
bool replaceFlag(TimeInterval f);
bool addFlagAt(GstClockTime t, int type = 0);
bool removeFlagAt(GstClockTime t);
bool isFlagged(GstClockTime t) const;
int flagTypeAt(GstClockTime t) const;
void setFlagTypeAt(GstClockTime t, int type);
TimeInterval getFlagAt(GstClockTime t) const;
TimeInterval getNextFlag(GstClockTime t) const;
TimeInterval getPreviousFlag(GstClockTime t) const;
void clearFlags();
// 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();
bool fadingIsClear();
// Edit
typedef enum {
FADING_SHARP = 0,
FADING_LINEAR,
FADING_SMOOTH
} FadingCurve;
void smoothFading(uint N = 1, TimeInterval interval = TimeInterval());
void autoFading(const GstClockTime duration = 10000, FadingCurve curve = FADING_SHARP);
// void fadeIn(const GstClockTime duration = 100000, FadingCurve curve = FADING_LINEAR);
// void fadeOut(const GstClockTime duration = 100000, FadingCurve curve = FADING_LINEAR);
void fadeIn(const GstClockTime from, const GstClockTime duration, FadingCurve curve = FADING_SHARP);
void fadeOut(const GstClockTime to, const GstClockTime duration, FadingCurve curve = FADING_SHARP);
void fadeInOutRange(const GstClockTime t, const GstClockTime duration, bool in_and_out, FadingCurve curve = FADING_SHARP);
// link Fading and Gaps
bool autoGapInFade();
void autoFadeInGaps();
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];
bool fading_array_changed_, fading_array_allones_;
TimeIntervalSet flags_;
float flagsArray_[MAX_TIMELINE_ARRAY];
bool flags_array_need_update_;
// synchronize data structures
void fillArrayFromFlags(float *array, size_t array_size);
};
#endif // TIMELINE_H
|