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