File: Timeline.h

package info (click to toggle)
vimix 0.9.0%2Bgit20260228%2Bds-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 90,700 kB
  • sloc: cpp: 98,044; ansic: 34,427; makefile: 373; xml: 98; objc: 97; sh: 49; python: 20
file content (226 lines) | stat: -rw-r--r-- 7,226 bytes parent folder | download | duplicates (3)
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