mirror of
https://github.com/brunoherbelin/vimix.git
synced 2025-12-13 19:29:58 +01:00
New Timeline class to manage segments of media player.
This commit is contained in:
87
Timeline.cpp
Normal file
87
Timeline.cpp
Normal 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
98
Timeline.h
Normal 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
|
||||
Reference in New Issue
Block a user