New Timeline class to manage segments of media player.

This commit is contained in:
brunoherbelin
2020-08-06 23:18:35 +02:00
parent 3f568f714a
commit 98f9f4a225
2 changed files with 185 additions and 0 deletions

87
Timeline.cpp Normal file
View File

@@ -0,0 +1,87 @@
#include <algorithm>
#include "defines.h"
#include "Log.h"
#include "Timeline.h"
#define SEGMENT_ARRAY_MAX_SIZE 1000
Timeline::Timeline() : array_(nullptr)
{
reset();
}
Timeline::~Timeline()
{
reset();
}
void Timeline::reset()
{
start_ = GST_CLOCK_TIME_NONE;
end_ = GST_CLOCK_TIME_NONE;
num_frames_ = 0;
array_size_ = 0;
// clear segment array
if (array_ != nullptr)
free(array_);
}
void Timeline::init(GstClockTime start, GstClockTime end, GstClockTime frame_duration)
{
reset();
start_ = start;
end_ = end;
num_frames_ = (size_t) end_ / (size_t) frame_duration;
array_size_ = MIN( SEGMENT_ARRAY_MAX_SIZE, num_frames_);
array_ = (float *) malloc(array_size_ * sizeof(float));
for (int i = 0; i < array_size_; ++i)
array_[i] = 1.f;
Log::Info("%d frames in timeline", array_size_);
}
bool Timeline::addPlaySegment(GstClockTime begin, GstClockTime end)
{
return addPlaySegment( MediaSegment(begin, end) );
}
bool Timeline::addPlaySegment(MediaSegment s)
{
if ( s.is_valid() )
return segments_.insert(s).second;
return false;
}
bool Timeline::removeAllPlaySegmentOverlap(MediaSegment s)
{
bool ret = removePlaySegmentAt(s.begin);
return removePlaySegmentAt(s.end) || ret;
}
bool Timeline::removePlaySegmentAt(GstClockTime t)
{
MediaSegmentSet::const_iterator s = std::find_if(segments_.begin(), segments_.end(), containsTime(t));
if ( s != segments_.end() ) {
segments_.erase(s);
return true;
}
return false;
}
std::list< std::pair<guint64, guint64> > Timeline::getPlaySegments() const
{
std::list< std::pair<guint64, guint64> > ret;
for (MediaSegmentSet::iterator it = segments_.begin(); it != segments_.end(); it++)
ret.push_back( std::make_pair( it->begin, it->end ) );
return ret;
}

98
Timeline.h Normal file
View File

@@ -0,0 +1,98 @@
#ifndef TIMELINE_H
#define TIMELINE_H
#include <string>
#include <sstream>
#include <set>
#include <list>
#include <gst/pbutils/pbutils.h>
struct MediaSegment
{
GstClockTime begin;
GstClockTime end;
MediaSegment()
{
begin = GST_CLOCK_TIME_NONE;
end = GST_CLOCK_TIME_NONE;
}
MediaSegment(GstClockTime b, GstClockTime e)
{
if ( b < e ) {
begin = b;
end = e;
} else {
begin = GST_CLOCK_TIME_NONE;
end = 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 MediaSegment b) const
{
return (this->is_valid() && b.is_valid() && this->end < b.begin);
}
inline bool operator == (const MediaSegment b) const
{
return (this->begin == b.begin && this->end == b.end);
}
inline bool operator != (const MediaSegment b) const
{
return (this->begin != b.begin || this->end != b.end);
}
};
struct containsTime: public std::unary_function<MediaSegment, bool>
{
inline bool operator()(const MediaSegment s) const
{
return ( s.is_valid() && _t > s.begin && _t < s.end );
}
containsTime(GstClockTime t) : _t(t) { }
private:
GstClockTime _t;
};
typedef std::set<MediaSegment> MediaSegmentSet;
class Timeline
{
public:
Timeline();
~Timeline();
void reset();
void init(GstClockTime start, GstClockTime end, GstClockTime frame_duration);
bool addPlaySegment(GstClockTime begin, GstClockTime end);
bool addPlaySegment(MediaSegment s);
bool removePlaySegmentAt(GstClockTime t);
bool removeAllPlaySegmentOverlap(MediaSegment s);
std::list< std::pair<guint64, guint64> > getPlaySegments() const;
inline float *Array() { return array_; }
inline size_t ArraySize() { return array_size_; }
private:
GstClockTime start_;
GstClockTime end_;
size_t num_frames_;
float *array_;
size_t array_size_;
MediaSegmentSet segments_;
MediaSegmentSet::iterator current_segment_;
};
#endif // TIMELINE_H