mirror of
https://github.com/brunoherbelin/vimix.git
synced 2025-12-11 10:19:59 +01:00
Unified class methods naming (lower case function names as other
classes)
This commit is contained in:
6
FrameBuffer.cpp
Normal file
6
FrameBuffer.cpp
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#include "FrameBuffer.h"
|
||||||
|
|
||||||
|
FrameBuffer::FrameBuffer()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
11
FrameBuffer.h
Normal file
11
FrameBuffer.h
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
#ifndef FRAMEBUFFER_H
|
||||||
|
#define FRAMEBUFFER_H
|
||||||
|
|
||||||
|
|
||||||
|
class FrameBuffer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FrameBuffer();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // FRAMEBUFFER_H
|
||||||
448
MediaPlayer.cpp
448
MediaPlayer.cpp
@@ -40,41 +40,41 @@ GLuint blackTexture()
|
|||||||
return tex_index_black;
|
return tex_index_black;
|
||||||
}
|
}
|
||||||
|
|
||||||
MediaPlayer::MediaPlayer(string name) : id(name)
|
MediaPlayer::MediaPlayer(string name) : id_(name)
|
||||||
{
|
{
|
||||||
if (std::empty(id))
|
if (std::empty(id_))
|
||||||
id = GstToolkit::date_time_string();
|
id_ = GstToolkit::date_time_string();
|
||||||
|
|
||||||
uri = "undefined";
|
uri_ = "undefined";
|
||||||
pipeline = nullptr;
|
pipeline_ = nullptr;
|
||||||
discoverer = nullptr;
|
discoverer_ = nullptr;
|
||||||
|
|
||||||
ready = false;
|
ready_ = false;
|
||||||
seekable = false;
|
seekable_ = false;
|
||||||
isimage = false;
|
isimage_ = false;
|
||||||
interlaced = false;
|
interlaced_ = false;
|
||||||
need_loop = false;
|
need_loop_ = false;
|
||||||
v_frame_is_full = false;
|
v_frame_is_full_ = false;
|
||||||
rate = 1.0;
|
rate_ = 1.0;
|
||||||
framerate = 0.0;
|
framerate_ = 0.0;
|
||||||
|
|
||||||
width = par_width = 640;
|
width_ = par_width_ = 640;
|
||||||
height = 480;
|
height_ = 480;
|
||||||
position = GST_CLOCK_TIME_NONE;
|
position_ = GST_CLOCK_TIME_NONE;
|
||||||
duration = GST_CLOCK_TIME_NONE;
|
duration_ = GST_CLOCK_TIME_NONE;
|
||||||
start_position = GST_CLOCK_TIME_NONE;
|
start_position_ = GST_CLOCK_TIME_NONE;
|
||||||
frame_duration = GST_CLOCK_TIME_NONE;
|
frame_duration_ = GST_CLOCK_TIME_NONE;
|
||||||
desired_state = GST_STATE_PAUSED;
|
desired_state_ = GST_STATE_PAUSED;
|
||||||
loop = LoopMode::LOOP_REWIND;
|
loop_ = LoopMode::LOOP_REWIND;
|
||||||
current_segment = segments.begin();
|
current_segment_ = segments_.begin();
|
||||||
v_frame.buffer = nullptr;
|
v_frame_.buffer = nullptr;
|
||||||
|
|
||||||
textureindex = 0;
|
textureindex_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
MediaPlayer::~MediaPlayer()
|
MediaPlayer::~MediaPlayer()
|
||||||
{
|
{
|
||||||
Close();
|
close();
|
||||||
// g_free(v_frame);
|
// g_free(v_frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,48 +82,48 @@ void MediaPlayer::accept(Visitor& v) {
|
|||||||
v.visit(*this);
|
v.visit(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MediaPlayer::Bind()
|
void MediaPlayer::bind()
|
||||||
{
|
{
|
||||||
glBindTexture(GL_TEXTURE_2D, Texture());
|
glBindTexture(GL_TEXTURE_2D, texture());
|
||||||
}
|
}
|
||||||
|
|
||||||
guint MediaPlayer::Texture() const
|
guint MediaPlayer::texture() const
|
||||||
{
|
{
|
||||||
if (textureindex == 0)
|
if (textureindex_ == 0)
|
||||||
return blackTexture();
|
return blackTexture();
|
||||||
|
|
||||||
return textureindex;
|
return textureindex_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MediaPlayer::Open(string uri)
|
void MediaPlayer::open(string uri)
|
||||||
{
|
{
|
||||||
// set uri to open
|
// set uri to open
|
||||||
this->uri = uri;
|
this->uri_ = uri;
|
||||||
|
|
||||||
// reset
|
// reset
|
||||||
ready = false;
|
ready_ = false;
|
||||||
|
|
||||||
/* Instantiate the Discoverer */
|
/* Instantiate the Discoverer */
|
||||||
GError *err = NULL;
|
GError *err = NULL;
|
||||||
discoverer = gst_discoverer_new (5 * GST_SECOND, &err);
|
discoverer_ = gst_discoverer_new (5 * GST_SECOND, &err);
|
||||||
if (!discoverer) {
|
if (!discoverer_) {
|
||||||
Log::Warning("MediaPlayer Error creating discoverer instance: %s\n", err->message);
|
Log::Warning("MediaPlayer Error creating discoverer instance: %s\n", err->message);
|
||||||
g_clear_error (&err);
|
g_clear_error (&err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// set callback for filling in information into this MediaPlayer
|
// set callback for filling in information into this MediaPlayer
|
||||||
g_signal_connect (discoverer, "discovered", G_CALLBACK (callback_discoverer_process), this);
|
g_signal_connect (discoverer_, "discovered", G_CALLBACK (callback_discoverer_process), this);
|
||||||
// set callback when finished discovering
|
// set callback when finished discovering
|
||||||
g_signal_connect (discoverer, "finished", G_CALLBACK (callback_discoverer_finished), this);
|
g_signal_connect (discoverer_, "finished", G_CALLBACK (callback_discoverer_finished), this);
|
||||||
|
|
||||||
// start discoverer
|
// start discoverer
|
||||||
gst_discoverer_start(discoverer);
|
gst_discoverer_start(discoverer_);
|
||||||
// Add the request to process asynchronously the URI
|
// Add the request to process asynchronously the URI
|
||||||
if (!gst_discoverer_discover_uri_async (discoverer, uri.c_str())) {
|
if (!gst_discoverer_discover_uri_async (discoverer_, uri.c_str())) {
|
||||||
Log::Warning("MediaPlayer %s Failed to start discovering URI '%s'\n", id.c_str(), uri.c_str());
|
Log::Warning("MediaPlayer %s Failed to start discovering URI '%s'\n", id_.c_str(), uri.c_str());
|
||||||
g_object_unref (discoverer);
|
g_object_unref (discoverer_);
|
||||||
discoverer = nullptr;
|
discoverer_ = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// and wait for discoverer to finish...
|
// and wait for discoverer to finish...
|
||||||
@@ -133,31 +133,31 @@ void MediaPlayer::Open(string uri)
|
|||||||
void MediaPlayer::execute_open()
|
void MediaPlayer::execute_open()
|
||||||
{
|
{
|
||||||
// build string describing pipeline
|
// build string describing pipeline
|
||||||
string description = "uridecodebin uri=" + uri + " name=decoder !";
|
string description = "uridecodebin uri=" + uri_ + " name=decoder !";
|
||||||
if (interlaced)
|
if (interlaced_)
|
||||||
description += " deinterlace !";
|
description += " deinterlace !";
|
||||||
description += " videoconvert ! appsink name=sink";
|
description += " videoconvert ! appsink name=sink";
|
||||||
|
|
||||||
// parse pipeline descriptor
|
// parse pipeline descriptor
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
pipeline = gst_parse_launch (description.c_str(), &error);
|
pipeline_ = gst_parse_launch (description.c_str(), &error);
|
||||||
if (error != NULL) {
|
if (error != NULL) {
|
||||||
Log::Warning("MediaPlayer %s Could not construct pipeline %s:\n%s", id.c_str(), description.c_str(), error->message);
|
Log::Warning("MediaPlayer %s Could not construct pipeline %s:\n%s", id_.c_str(), description.c_str(), error->message);
|
||||||
g_clear_error (&error);
|
g_clear_error (&error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
g_object_set(G_OBJECT(pipeline), "name", id.c_str(), NULL);
|
g_object_set(G_OBJECT(pipeline_), "name", id_.c_str(), NULL);
|
||||||
|
|
||||||
// GstCaps *caps = gst_static_caps_get (&frame_render_caps);
|
// GstCaps *caps = gst_static_caps_get (&frame_render_caps);
|
||||||
string capstring = "video/x-raw,format=RGBA,width="+ std::to_string(width) + ",height=" + std::to_string(height);
|
string capstring = "video/x-raw,format=RGBA,width="+ std::to_string(width_) + ",height=" + std::to_string(height_);
|
||||||
GstCaps *caps = gst_caps_from_string(capstring.c_str());
|
GstCaps *caps = gst_caps_from_string(capstring.c_str());
|
||||||
if (!gst_video_info_from_caps (&v_frame_video_info, caps)) {
|
if (!gst_video_info_from_caps (&v_frame_video_info_, caps)) {
|
||||||
Log::Warning("MediaPlayer %s Could not configure video frame info", id.c_str());
|
Log::Warning("MediaPlayer %s Could not configure video frame info", id_.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// setup appsink
|
// setup appsink
|
||||||
GstElement *sink = gst_bin_get_by_name (GST_BIN (pipeline), "sink");
|
GstElement *sink = gst_bin_get_by_name (GST_BIN (pipeline_), "sink");
|
||||||
if (sink) {
|
if (sink) {
|
||||||
|
|
||||||
// set all properties
|
// set all properties
|
||||||
@@ -177,7 +177,7 @@ void MediaPlayer::execute_open()
|
|||||||
gst_object_unref (sink);
|
gst_object_unref (sink);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Log::Warning("MediaPlayer %s Could not configure sink", id.c_str());
|
Log::Warning("MediaPlayer %s Could not configure sink", id_.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
gst_caps_unref (caps);
|
gst_caps_unref (caps);
|
||||||
@@ -186,226 +186,226 @@ void MediaPlayer::execute_open()
|
|||||||
//Rendering::LinkPipeline(GST_PIPELINE (pipeline));
|
//Rendering::LinkPipeline(GST_PIPELINE (pipeline));
|
||||||
|
|
||||||
// set to desired state (PLAY or PAUSE)
|
// set to desired state (PLAY or PAUSE)
|
||||||
GstStateChangeReturn ret = gst_element_set_state (pipeline, desired_state);
|
GstStateChangeReturn ret = gst_element_set_state (pipeline_, desired_state_);
|
||||||
if (ret == GST_STATE_CHANGE_FAILURE) {
|
if (ret == GST_STATE_CHANGE_FAILURE) {
|
||||||
Log::Warning("MediaPlayer %s Could not open %s", id.c_str(), uri.c_str());
|
Log::Warning("MediaPlayer %s Could not open %s", id_.c_str(), uri_.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// all good
|
// all good
|
||||||
Log::Info("MediaPlayer %s Open %s (%s %d x %d)", id.c_str(), uri.c_str(), codec_name.c_str(), width, height);
|
Log::Info("MediaPlayer %s Open %s (%s %d x %d)", id_.c_str(), uri_.c_str(), codec_name_.c_str(), width_, height_);
|
||||||
ready = true;
|
ready_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MediaPlayer::isOpen() const
|
bool MediaPlayer::isOpen() const
|
||||||
{
|
{
|
||||||
return ready;
|
return ready_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MediaPlayer::Close()
|
void MediaPlayer::close()
|
||||||
{
|
{
|
||||||
// stop discovering stream
|
// stop discovering stream
|
||||||
if (discoverer != nullptr) {
|
if (discoverer_ != nullptr) {
|
||||||
gst_discoverer_stop (discoverer);
|
gst_discoverer_stop (discoverer_);
|
||||||
g_object_unref (discoverer);
|
g_object_unref (discoverer_);
|
||||||
discoverer = nullptr;
|
discoverer_ = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ready)
|
if (!ready_)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// clean up GST
|
// clean up GST
|
||||||
if (pipeline != nullptr) {
|
if (pipeline_ != nullptr) {
|
||||||
gst_element_set_state (pipeline, GST_STATE_NULL);
|
gst_element_set_state (pipeline_, GST_STATE_NULL);
|
||||||
gst_object_unref (pipeline);
|
gst_object_unref (pipeline_);
|
||||||
pipeline = nullptr;
|
pipeline_ = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// nothing to display
|
// nothing to display
|
||||||
textureindex = blackTexture();
|
textureindex_ = blackTexture();
|
||||||
|
|
||||||
// un-ready the media player
|
// un-ready the media player
|
||||||
ready = false;
|
ready_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
GstClockTime MediaPlayer::Duration()
|
GstClockTime MediaPlayer::duration()
|
||||||
{
|
{
|
||||||
if (duration == GST_CLOCK_TIME_NONE && pipeline != nullptr) {
|
if (duration_ == GST_CLOCK_TIME_NONE && pipeline_ != nullptr) {
|
||||||
gint64 d = GST_CLOCK_TIME_NONE;
|
gint64 d = GST_CLOCK_TIME_NONE;
|
||||||
if ( gst_element_query_duration(pipeline, GST_FORMAT_TIME, &d) )
|
if ( gst_element_query_duration(pipeline_, GST_FORMAT_TIME, &d) )
|
||||||
duration = d;
|
duration_ = d;
|
||||||
}
|
}
|
||||||
|
|
||||||
return duration;
|
return duration_;
|
||||||
}
|
}
|
||||||
|
|
||||||
GstClockTime MediaPlayer::FrameDuration()
|
GstClockTime MediaPlayer::frameDuration()
|
||||||
{
|
{
|
||||||
return frame_duration;
|
return frame_duration_;
|
||||||
}
|
}
|
||||||
|
|
||||||
guint MediaPlayer::Width() const
|
guint MediaPlayer::width() const
|
||||||
{
|
{
|
||||||
return width;
|
return width_;
|
||||||
}
|
}
|
||||||
|
|
||||||
guint MediaPlayer::Height() const
|
guint MediaPlayer::height() const
|
||||||
{
|
{
|
||||||
return height;
|
return height_;
|
||||||
}
|
}
|
||||||
|
|
||||||
float MediaPlayer::AspectRatio() const
|
float MediaPlayer::aspectRatio() const
|
||||||
{
|
{
|
||||||
return static_cast<float>(par_width) / static_cast<float>(height);
|
return static_cast<float>(par_width_) / static_cast<float>(height_);
|
||||||
}
|
}
|
||||||
|
|
||||||
GstClockTime MediaPlayer::Position()
|
GstClockTime MediaPlayer::position()
|
||||||
{
|
{
|
||||||
GstClockTime pos = position;
|
GstClockTime pos = position_;
|
||||||
|
|
||||||
if (pos == GST_CLOCK_TIME_NONE && pipeline != nullptr) {
|
if (pos == GST_CLOCK_TIME_NONE && pipeline_ != nullptr) {
|
||||||
gint64 p = GST_CLOCK_TIME_NONE;
|
gint64 p = GST_CLOCK_TIME_NONE;
|
||||||
if ( gst_element_query_position (pipeline, GST_FORMAT_TIME, &p) )
|
if ( gst_element_query_position (pipeline_, GST_FORMAT_TIME, &p) )
|
||||||
pos = p;
|
pos = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
return pos - start_position;
|
return pos - start_position_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MediaPlayer::Play(bool on)
|
void MediaPlayer::play(bool on)
|
||||||
{
|
{
|
||||||
// cannot play an image
|
// cannot play an image
|
||||||
if (isimage)
|
if (isimage_)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// request state
|
// request state
|
||||||
GstState requested_state = on ? GST_STATE_PLAYING : GST_STATE_PAUSED;
|
GstState requested_state = on ? GST_STATE_PLAYING : GST_STATE_PAUSED;
|
||||||
// ignore if requesting twice same state
|
// ignore if requesting twice same state
|
||||||
if (desired_state == requested_state)
|
if (desired_state_ == requested_state)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// accept request to the desired state
|
// accept request to the desired state
|
||||||
desired_state = requested_state;
|
desired_state_ = requested_state;
|
||||||
|
|
||||||
// if not ready yet, the requested state will be handled later
|
// if not ready yet, the requested state will be handled later
|
||||||
if ( pipeline == nullptr )
|
if ( pipeline_ == nullptr )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// requesting to play, but stopped at end of stream : rewind first !
|
// requesting to play, but stopped at end of stream : rewind first !
|
||||||
if ( desired_state == GST_STATE_PLAYING) {
|
if ( desired_state_ == GST_STATE_PLAYING) {
|
||||||
if ( ( rate>0.0 ? duration - Position() : Position() ) < 2 * frame_duration )
|
if ( ( rate_>0.0 ? duration_ - position() : position() ) < 2 * frame_duration_ )
|
||||||
Rewind();
|
rewind();
|
||||||
}
|
}
|
||||||
|
|
||||||
// all ready, apply state change immediately
|
// all ready, apply state change immediately
|
||||||
GstStateChangeReturn ret = gst_element_set_state (pipeline, desired_state);
|
GstStateChangeReturn ret = gst_element_set_state (pipeline_, desired_state_);
|
||||||
if (ret == GST_STATE_CHANGE_FAILURE) {
|
if (ret == GST_STATE_CHANGE_FAILURE) {
|
||||||
Log::Warning("MediaPlayer %s Failed to start", gst_element_get_name(pipeline));
|
Log::Warning("MediaPlayer %s Failed to start", gst_element_get_name(pipeline_));
|
||||||
}
|
}
|
||||||
#ifdef MEDIA_PLAYER_DEBUG
|
#ifdef MEDIA_PLAYER_DEBUG
|
||||||
else if (on)
|
else if (on)
|
||||||
Log::Info("MediaPlayer %s Start", gst_element_get_name(pipeline));
|
Log::Info("MediaPlayer %s Start", gst_element_get_name(pipeline_));
|
||||||
else
|
else
|
||||||
Log::Info("MediaPlayer %s Stop", gst_element_get_name(pipeline));
|
Log::Info("MediaPlayer %s Stop", gst_element_get_name(pipeline_));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// reset time counter on stop
|
// reset time counter on stop
|
||||||
if (!on)
|
if (!on)
|
||||||
timecount.reset();
|
timecount_.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MediaPlayer::isPlaying() const
|
bool MediaPlayer::isPlaying() const
|
||||||
{
|
{
|
||||||
// image cannot play
|
// image cannot play
|
||||||
if (isimage)
|
if (isimage_)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// if not ready yet, answer with requested state
|
// if not ready yet, answer with requested state
|
||||||
if ( pipeline == nullptr )
|
if ( pipeline_ == nullptr )
|
||||||
return desired_state == GST_STATE_PLAYING;
|
return desired_state_ == GST_STATE_PLAYING;
|
||||||
|
|
||||||
// if ready, answer with actual state
|
// if ready, answer with actual state
|
||||||
GstState state;
|
GstState state;
|
||||||
gst_element_get_state (pipeline, &state, NULL, GST_CLOCK_TIME_NONE);
|
gst_element_get_state (pipeline_, &state, NULL, GST_CLOCK_TIME_NONE);
|
||||||
return state == GST_STATE_PLAYING;
|
return state == GST_STATE_PLAYING;
|
||||||
|
|
||||||
// return desired_state == GST_STATE_PLAYING;
|
// return desired_state == GST_STATE_PLAYING;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MediaPlayer::LoopMode MediaPlayer::Loop() const
|
MediaPlayer::LoopMode MediaPlayer::loop() const
|
||||||
{
|
{
|
||||||
return loop;
|
return loop_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MediaPlayer::setLoop(MediaPlayer::LoopMode mode)
|
void MediaPlayer::setLoop(MediaPlayer::LoopMode mode)
|
||||||
{
|
{
|
||||||
loop = mode;
|
loop_ = mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MediaPlayer::Rewind()
|
void MediaPlayer::rewind()
|
||||||
{
|
{
|
||||||
if (!seekable)
|
if (!seekable_)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (rate > 0.0)
|
if (rate_ > 0.0)
|
||||||
// playing forward, loop to begin
|
// playing forward, loop to begin
|
||||||
execute_seek_command(0);
|
execute_seek_command(0);
|
||||||
else
|
else
|
||||||
// playing backward, loop to end
|
// playing backward, loop to end
|
||||||
execute_seek_command(duration);
|
execute_seek_command(duration_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void MediaPlayer::SeekNextFrame()
|
void MediaPlayer::seekNextFrame()
|
||||||
{
|
{
|
||||||
// useful only when Paused
|
// useful only when Paused
|
||||||
if (isPlaying())
|
if (isPlaying())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ( loop != LOOP_NONE) {
|
if ( loop_ != LOOP_NONE) {
|
||||||
// eventually loop if mode allows
|
// eventually loop if mode allows
|
||||||
if ( ( rate>0.0 ? duration - Position() : Position() ) < 2 * frame_duration )
|
if ( ( rate_>0.0 ? duration_ - position() : position() ) < 2 * frame_duration_ )
|
||||||
need_loop = true;
|
need_loop_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// step
|
// step
|
||||||
gst_element_send_event (pipeline, gst_event_new_step (GST_FORMAT_BUFFERS, 1, ABS(rate), TRUE, FALSE));
|
gst_element_send_event (pipeline_, gst_event_new_step (GST_FORMAT_BUFFERS, 1, ABS(rate_), TRUE, FALSE));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MediaPlayer::SeekTo(GstClockTime pos)
|
void MediaPlayer::seekTo(GstClockTime pos)
|
||||||
{
|
{
|
||||||
if (!seekable)
|
if (!seekable_)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// remember pos
|
// remember pos
|
||||||
GstClockTime previous_pos = Position();
|
GstClockTime previous_pos = position();
|
||||||
|
|
||||||
// apply seek
|
// apply seek
|
||||||
GstClockTime target = CLAMP(pos, 0, duration);
|
GstClockTime target = CLAMP(pos, 0, duration_);
|
||||||
execute_seek_command(target);
|
execute_seek_command(target);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MediaPlayer::FastForward()
|
void MediaPlayer::fastForward()
|
||||||
{
|
{
|
||||||
if (!seekable)
|
if (!seekable_)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
double step = SIGN(rate) * 0.01 * static_cast<double>(duration);
|
double step = SIGN(rate_) * 0.01 * static_cast<double>(duration_);
|
||||||
GstClockTime target = Position() + static_cast<GstClockTime>(step);
|
GstClockTime target = position() + static_cast<GstClockTime>(step);
|
||||||
|
|
||||||
// manage loop
|
// manage loop
|
||||||
if ( target > duration ) {
|
if ( target > duration_ ) {
|
||||||
if (loop == LOOP_NONE)
|
if (loop_ == LOOP_NONE)
|
||||||
target = duration;
|
target = duration_;
|
||||||
else
|
else
|
||||||
target = target - duration;
|
target = target - duration_;
|
||||||
}
|
}
|
||||||
|
|
||||||
SeekTo(target);
|
seekTo(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -418,7 +418,7 @@ bool MediaPlayer::addPlaySegment(GstClockTime begin, GstClockTime end)
|
|||||||
bool MediaPlayer::addPlaySegment(MediaSegment s)
|
bool MediaPlayer::addPlaySegment(MediaSegment s)
|
||||||
{
|
{
|
||||||
if ( s.is_valid() )
|
if ( s.is_valid() )
|
||||||
return segments.insert(s).second;
|
return segments_.insert(s).second;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -431,10 +431,10 @@ bool MediaPlayer::removeAllPlaySegmentOverlap(MediaSegment s)
|
|||||||
|
|
||||||
bool MediaPlayer::removePlaySegmentAt(GstClockTime t)
|
bool MediaPlayer::removePlaySegmentAt(GstClockTime t)
|
||||||
{
|
{
|
||||||
MediaSegmentSet::const_iterator s = std::find_if(segments.begin(), segments.end(), containsTime(t));
|
MediaSegmentSet::const_iterator s = std::find_if(segments_.begin(), segments_.end(), containsTime(t));
|
||||||
|
|
||||||
if ( s != segments.end() ) {
|
if ( s != segments_.end() ) {
|
||||||
segments.erase(s);
|
segments_.erase(s);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -444,70 +444,70 @@ bool MediaPlayer::removePlaySegmentAt(GstClockTime t)
|
|||||||
std::list< std::pair<guint64, guint64> > MediaPlayer::getPlaySegments() const
|
std::list< std::pair<guint64, guint64> > MediaPlayer::getPlaySegments() const
|
||||||
{
|
{
|
||||||
std::list< std::pair<guint64, guint64> > ret;
|
std::list< std::pair<guint64, guint64> > ret;
|
||||||
for (MediaSegmentSet::iterator it = segments.begin(); it != segments.end(); it++)
|
for (MediaSegmentSet::iterator it = segments_.begin(); it != segments_.end(); it++)
|
||||||
ret.push_back( std::make_pair( it->begin, it->end ) );
|
ret.push_back( std::make_pair( it->begin, it->end ) );
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MediaPlayer::Update()
|
void MediaPlayer::update()
|
||||||
{
|
{
|
||||||
// discard
|
// discard
|
||||||
if (!ready)
|
if (!ready_)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// done discovering stream
|
// done discovering stream
|
||||||
if (discoverer != nullptr) {
|
if (discoverer_ != nullptr) {
|
||||||
gst_discoverer_stop (discoverer);
|
gst_discoverer_stop (discoverer_);
|
||||||
g_object_unref (discoverer);
|
g_object_unref (discoverer_);
|
||||||
discoverer = nullptr;
|
discoverer_ = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// apply texture
|
// apply texture
|
||||||
if (v_frame_is_full) {
|
if (v_frame_is_full_) {
|
||||||
// first occurence; create texture
|
// first occurence; create texture
|
||||||
if (textureindex==0) {
|
if (textureindex_==0) {
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glGenTextures(1, &textureindex);
|
glGenTextures(1, &textureindex_);
|
||||||
glBindTexture(GL_TEXTURE_2D, textureindex);
|
glBindTexture(GL_TEXTURE_2D, textureindex_);
|
||||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height,
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width_, height_,
|
||||||
0, GL_RGBA, GL_UNSIGNED_BYTE, v_frame.data[0]);
|
0, GL_RGBA, GL_UNSIGNED_BYTE, v_frame_.data[0]);
|
||||||
}
|
}
|
||||||
else // bind texture
|
else // bind texture
|
||||||
{
|
{
|
||||||
glBindTexture(GL_TEXTURE_2D, textureindex);
|
glBindTexture(GL_TEXTURE_2D, textureindex_);
|
||||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height,
|
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width_, height_,
|
||||||
GL_RGBA, GL_UNSIGNED_BYTE, v_frame.data[0]);
|
GL_RGBA, GL_UNSIGNED_BYTE, v_frame_.data[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// sync with callback_pull_last_sample_video
|
// sync with callback_pull_last_sample_video
|
||||||
v_frame_is_full = false;
|
v_frame_is_full_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// manage loop mode
|
// manage loop mode
|
||||||
if (need_loop && !isimage) {
|
if (need_loop_ && !isimage_) {
|
||||||
execute_loop_command();
|
execute_loop_command();
|
||||||
need_loop = false;
|
need_loop_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// all other updates below are only for playing mode
|
// all other updates below are only for playing mode
|
||||||
if (desired_state != GST_STATE_PLAYING)
|
if (desired_state_ != GST_STATE_PLAYING)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// test segments
|
// test segments
|
||||||
if ( segments.begin() != segments.end()) {
|
if ( segments_.begin() != segments_.end()) {
|
||||||
|
|
||||||
if ( current_segment == segments.end() )
|
if ( current_segment_ == segments_.end() )
|
||||||
current_segment = segments.begin();
|
current_segment_ = segments_.begin();
|
||||||
|
|
||||||
if ( Position() > current_segment->end) {
|
if ( position() > current_segment_->end) {
|
||||||
g_print("switch to next segment ");
|
g_print("switch to next segment ");
|
||||||
current_segment++;
|
current_segment_++;
|
||||||
if ( current_segment == segments.end() )
|
if ( current_segment_ == segments_.end() )
|
||||||
current_segment = segments.begin();
|
current_segment_ = segments_.begin();
|
||||||
SeekTo(current_segment->begin);
|
seekTo(current_segment_->begin);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -516,21 +516,21 @@ void MediaPlayer::Update()
|
|||||||
|
|
||||||
void MediaPlayer::execute_loop_command()
|
void MediaPlayer::execute_loop_command()
|
||||||
{
|
{
|
||||||
if (loop==LOOP_REWIND) {
|
if (loop_==LOOP_REWIND) {
|
||||||
Rewind();
|
rewind();
|
||||||
}
|
}
|
||||||
else if (loop==LOOP_BIDIRECTIONAL) {
|
else if (loop_==LOOP_BIDIRECTIONAL) {
|
||||||
rate *= - 1.f;
|
rate_ *= - 1.f;
|
||||||
execute_seek_command();
|
execute_seek_command();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Play(false);
|
play(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MediaPlayer::execute_seek_command(GstClockTime target)
|
void MediaPlayer::execute_seek_command(GstClockTime target)
|
||||||
{
|
{
|
||||||
if ( pipeline == nullptr || !seekable)
|
if ( pipeline_ == nullptr || !seekable_)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
GstEvent *seek_event = nullptr;
|
GstEvent *seek_event = nullptr;
|
||||||
@@ -541,12 +541,12 @@ void MediaPlayer::execute_seek_command(GstClockTime target)
|
|||||||
// no target given
|
// no target given
|
||||||
if (target == GST_CLOCK_TIME_NONE)
|
if (target == GST_CLOCK_TIME_NONE)
|
||||||
// create seek event with current position (rate changed ?)
|
// create seek event with current position (rate changed ?)
|
||||||
seek_pos = Position();
|
seek_pos = position();
|
||||||
// target is given but useless
|
// target is given but useless
|
||||||
else if ( ABS_DIFF(target, Position()) < frame_duration) {
|
else if ( ABS_DIFF(target, position()) < frame_duration_) {
|
||||||
// ignore request
|
// ignore request
|
||||||
#ifdef MEDIA_PLAYER_DEBUG
|
#ifdef MEDIA_PLAYER_DEBUG
|
||||||
Log::Info("MediaPlayer %s Ignored seek to current position", id.c_str());
|
Log::Info("MediaPlayer %s Ignored seek to current position", id_.c_str());
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -554,61 +554,61 @@ void MediaPlayer::execute_seek_command(GstClockTime target)
|
|||||||
// seek with flush (always)
|
// seek with flush (always)
|
||||||
int seek_flags = GST_SEEK_FLAG_FLUSH;
|
int seek_flags = GST_SEEK_FLAG_FLUSH;
|
||||||
// seek with trick mode if fast speed
|
// seek with trick mode if fast speed
|
||||||
if ( ABS(rate) > 2.0 )
|
if ( ABS(rate_) > 2.0 )
|
||||||
seek_flags |= GST_SEEK_FLAG_TRICKMODE;
|
seek_flags |= GST_SEEK_FLAG_TRICKMODE;
|
||||||
|
|
||||||
// create seek event depending on direction
|
// create seek event depending on direction
|
||||||
if (rate > 0) {
|
if (rate_ > 0) {
|
||||||
seek_event = gst_event_new_seek (rate, GST_FORMAT_TIME, (GstSeekFlags) seek_flags,
|
seek_event = gst_event_new_seek (rate_, GST_FORMAT_TIME, (GstSeekFlags) seek_flags,
|
||||||
GST_SEEK_TYPE_SET, seek_pos, GST_SEEK_TYPE_END, 0);
|
GST_SEEK_TYPE_SET, seek_pos, GST_SEEK_TYPE_END, 0);
|
||||||
} else {
|
} else {
|
||||||
seek_event = gst_event_new_seek (rate, GST_FORMAT_TIME, (GstSeekFlags) seek_flags,
|
seek_event = gst_event_new_seek (rate_, GST_FORMAT_TIME, (GstSeekFlags) seek_flags,
|
||||||
GST_SEEK_TYPE_SET, 0, GST_SEEK_TYPE_SET, seek_pos);
|
GST_SEEK_TYPE_SET, 0, GST_SEEK_TYPE_SET, seek_pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send the event (ASYNC)
|
// Send the event (ASYNC)
|
||||||
if (seek_event && !gst_element_send_event(pipeline, seek_event) )
|
if (seek_event && !gst_element_send_event(pipeline_, seek_event) )
|
||||||
Log::Warning("MediaPlayer %s Seek failed", gst_element_get_name(pipeline));
|
Log::Warning("MediaPlayer %s Seek failed", gst_element_get_name(pipeline_));
|
||||||
#ifdef MEDIA_PLAYER_DEBUG
|
#ifdef MEDIA_PLAYER_DEBUG
|
||||||
else
|
else
|
||||||
Log::Info("MediaPlayer %s Seek %ld %f", gst_element_get_name(pipeline), seek_pos, rate);
|
Log::Info("MediaPlayer %s Seek %ld %f", gst_element_get_name(pipeline_), seek_pos, rate_);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void MediaPlayer::SetPlaySpeed(double s)
|
void MediaPlayer::setPlaySpeed(double s)
|
||||||
{
|
{
|
||||||
if (isimage)
|
if (isimage_)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// bound to interval [-MAX_PLAY_SPEED MAX_PLAY_SPEED]
|
// bound to interval [-MAX_PLAY_SPEED MAX_PLAY_SPEED]
|
||||||
rate = CLAMP(s, -MAX_PLAY_SPEED, MAX_PLAY_SPEED);
|
rate_ = CLAMP(s, -MAX_PLAY_SPEED, MAX_PLAY_SPEED);
|
||||||
// skip interval [-MIN_PLAY_SPEED MIN_PLAY_SPEED]
|
// skip interval [-MIN_PLAY_SPEED MIN_PLAY_SPEED]
|
||||||
if (ABS(rate) < MIN_PLAY_SPEED)
|
if (ABS(rate_) < MIN_PLAY_SPEED)
|
||||||
rate = SIGN(rate) * MIN_PLAY_SPEED;
|
rate_ = SIGN(rate_) * MIN_PLAY_SPEED;
|
||||||
|
|
||||||
// apply with seek
|
// apply with seek
|
||||||
execute_seek_command();
|
execute_seek_command();
|
||||||
}
|
}
|
||||||
|
|
||||||
double MediaPlayer::PlaySpeed() const
|
double MediaPlayer::playSpeed() const
|
||||||
{
|
{
|
||||||
return rate;
|
return rate_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::string MediaPlayer::Codec() const
|
std::string MediaPlayer::codec() const
|
||||||
{
|
{
|
||||||
return codec_name;
|
return codec_name_;
|
||||||
}
|
}
|
||||||
|
|
||||||
double MediaPlayer::FrameRate() const
|
double MediaPlayer::frameRate() const
|
||||||
{
|
{
|
||||||
return framerate;
|
return framerate_;
|
||||||
}
|
}
|
||||||
|
|
||||||
double MediaPlayer::UpdateFrameRate() const
|
double MediaPlayer::updateFrameRate() const
|
||||||
{
|
{
|
||||||
return timecount.framerate();
|
return timecount_.frameRate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -617,33 +617,33 @@ double MediaPlayer::UpdateFrameRate() const
|
|||||||
bool MediaPlayer::fill_v_frame(GstBuffer *buf)
|
bool MediaPlayer::fill_v_frame(GstBuffer *buf)
|
||||||
{
|
{
|
||||||
// always empty frame before filling it again
|
// always empty frame before filling it again
|
||||||
if (v_frame.buffer)
|
if (v_frame_.buffer)
|
||||||
gst_video_frame_unmap(&v_frame);
|
gst_video_frame_unmap(&v_frame_);
|
||||||
|
|
||||||
// get the frame from buffer
|
// get the frame from buffer
|
||||||
if ( !gst_video_frame_map (&v_frame, &v_frame_video_info, buf, GST_MAP_READ ) ) {
|
if ( !gst_video_frame_map (&v_frame_, &v_frame_video_info_, buf, GST_MAP_READ ) ) {
|
||||||
Log::Info("MediaPlayer %s Failed to map the video buffer");
|
Log::Info("MediaPlayer %s Failed to map the video buffer");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// validate frame format
|
// validate frame format
|
||||||
if( GST_VIDEO_INFO_IS_RGB(&(v_frame).info) && GST_VIDEO_INFO_N_PLANES(&(v_frame).info) == 1) {
|
if( GST_VIDEO_INFO_IS_RGB(&(v_frame_).info) && GST_VIDEO_INFO_N_PLANES(&(v_frame_).info) == 1) {
|
||||||
|
|
||||||
// validate time
|
// validate time
|
||||||
if (position != buf->pts) {
|
if (position_ != buf->pts) {
|
||||||
|
|
||||||
// got a new RGB frame !
|
// got a new RGB frame !
|
||||||
v_frame_is_full = true;
|
v_frame_is_full_ = true;
|
||||||
|
|
||||||
// get presentation time stamp
|
// get presentation time stamp
|
||||||
position = buf->pts;
|
position_ = buf->pts;
|
||||||
|
|
||||||
// set start position (i.e. pts of first frame we got)
|
// set start position (i.e. pts of first frame we got)
|
||||||
if (start_position == GST_CLOCK_TIME_NONE)
|
if (start_position_ == GST_CLOCK_TIME_NONE)
|
||||||
start_position = position;
|
start_position_ = position_;
|
||||||
|
|
||||||
// keep update time (i.e. actual FPS of update)
|
// keep update time (i.e. actual FPS of update)
|
||||||
timecount.tic();
|
timecount_.tic();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -655,7 +655,7 @@ GstFlowReturn MediaPlayer::callback_pull_sample_video (GstElement *bin, MediaPla
|
|||||||
{
|
{
|
||||||
GstFlowReturn ret = GST_FLOW_OK;
|
GstFlowReturn ret = GST_FLOW_OK;
|
||||||
|
|
||||||
if (m && !m->v_frame_is_full) {
|
if (m && !m->v_frame_is_full_) {
|
||||||
|
|
||||||
// get last sample (non blocking)
|
// get last sample (non blocking)
|
||||||
GstSample *sample = nullptr;
|
GstSample *sample = nullptr;
|
||||||
@@ -692,7 +692,7 @@ void MediaPlayer::callback_end_of_video (GstElement *bin, MediaPlayer *m)
|
|||||||
{
|
{
|
||||||
if (m) {
|
if (m) {
|
||||||
// reached end of stream (eos) : might need to loop !
|
// reached end of stream (eos) : might need to loop !
|
||||||
m->need_loop = true;
|
m->need_loop_ = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -706,22 +706,22 @@ void MediaPlayer::callback_discoverer_process (GstDiscoverer *discoverer, GstDis
|
|||||||
GstDiscovererResult result = gst_discoverer_info_get_result (info);
|
GstDiscovererResult result = gst_discoverer_info_get_result (info);
|
||||||
switch (result) {
|
switch (result) {
|
||||||
case GST_DISCOVERER_URI_INVALID:
|
case GST_DISCOVERER_URI_INVALID:
|
||||||
m->discoverer_message << "Invalid URI: " << uri;
|
m->discoverer_message_ << "Invalid URI: " << uri;
|
||||||
break;
|
break;
|
||||||
case GST_DISCOVERER_ERROR:
|
case GST_DISCOVERER_ERROR:
|
||||||
m->discoverer_message << "Error: " << err->message;
|
m->discoverer_message_ << "Error: " << err->message;
|
||||||
break;
|
break;
|
||||||
case GST_DISCOVERER_TIMEOUT:
|
case GST_DISCOVERER_TIMEOUT:
|
||||||
m->discoverer_message << "Time out";
|
m->discoverer_message_ << "Time out";
|
||||||
break;
|
break;
|
||||||
case GST_DISCOVERER_BUSY:
|
case GST_DISCOVERER_BUSY:
|
||||||
m->discoverer_message << "Busy";
|
m->discoverer_message_ << "Busy";
|
||||||
break;
|
break;
|
||||||
case GST_DISCOVERER_MISSING_PLUGINS:
|
case GST_DISCOVERER_MISSING_PLUGINS:
|
||||||
{
|
{
|
||||||
const GstStructure *s = gst_discoverer_info_get_misc (info);
|
const GstStructure *s = gst_discoverer_info_get_misc (info);
|
||||||
gchar *str = gst_structure_to_string (s);
|
gchar *str = gst_structure_to_string (s);
|
||||||
m->discoverer_message << "Unknown file format / " << str;
|
m->discoverer_message_ << "Unknown file format / " << str;
|
||||||
g_free (str);
|
g_free (str);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -741,26 +741,26 @@ void MediaPlayer::callback_discoverer_process (GstDiscoverer *discoverer, GstDis
|
|||||||
{
|
{
|
||||||
// found a video / image stream : fill-in information
|
// found a video / image stream : fill-in information
|
||||||
GstDiscovererVideoInfo* vinfo = GST_DISCOVERER_VIDEO_INFO(tmpinf);
|
GstDiscovererVideoInfo* vinfo = GST_DISCOVERER_VIDEO_INFO(tmpinf);
|
||||||
m->width = gst_discoverer_video_info_get_width(vinfo);
|
m->width_ = gst_discoverer_video_info_get_width(vinfo);
|
||||||
m->height = gst_discoverer_video_info_get_height(vinfo);
|
m->height_ = gst_discoverer_video_info_get_height(vinfo);
|
||||||
m->isimage = gst_discoverer_video_info_is_image(vinfo);
|
m->isimage_ = gst_discoverer_video_info_is_image(vinfo);
|
||||||
m->interlaced = gst_discoverer_video_info_is_interlaced(vinfo);
|
m->interlaced_ = gst_discoverer_video_info_is_interlaced(vinfo);
|
||||||
guint parn = gst_discoverer_video_info_get_par_num(vinfo);
|
guint parn = gst_discoverer_video_info_get_par_num(vinfo);
|
||||||
guint pard = gst_discoverer_video_info_get_par_denom(vinfo);
|
guint pard = gst_discoverer_video_info_get_par_denom(vinfo);
|
||||||
m->par_width = (m->width * parn) / pard;
|
m->par_width_ = (m->width_ * parn) / pard;
|
||||||
// if its a video, it duration, framerate, etc.
|
// if its a video, it duration, framerate, etc.
|
||||||
if ( !m->isimage ) {
|
if ( !m->isimage_ ) {
|
||||||
m->duration = gst_discoverer_info_get_duration (info);
|
m->duration_ = gst_discoverer_info_get_duration (info);
|
||||||
m->seekable = gst_discoverer_info_get_seekable (info);
|
m->seekable_ = gst_discoverer_info_get_seekable (info);
|
||||||
guint frn = gst_discoverer_video_info_get_framerate_num(vinfo);
|
guint frn = gst_discoverer_video_info_get_framerate_num(vinfo);
|
||||||
guint frd = gst_discoverer_video_info_get_framerate_denom(vinfo);
|
guint frd = gst_discoverer_video_info_get_framerate_denom(vinfo);
|
||||||
m->framerate = static_cast<double>(frn) / static_cast<double>(frd);
|
m->framerate_ = static_cast<double>(frn) / static_cast<double>(frd);
|
||||||
m->frame_duration = (GST_SECOND * static_cast<guint64>(frd)) / (static_cast<guint64>(frn));
|
m->frame_duration_ = (GST_SECOND * static_cast<guint64>(frd)) / (static_cast<guint64>(frn));
|
||||||
}
|
}
|
||||||
// try to fill-in the codec information
|
// try to fill-in the codec information
|
||||||
GstCaps *caps = gst_discoverer_stream_info_get_caps (tmpinf);
|
GstCaps *caps = gst_discoverer_stream_info_get_caps (tmpinf);
|
||||||
if (caps) {
|
if (caps) {
|
||||||
m->codec_name = std::string( gst_pb_utils_get_codec_description(caps) );
|
m->codec_name_ = std::string( gst_pb_utils_get_codec_description(caps) );
|
||||||
gst_caps_unref (caps);
|
gst_caps_unref (caps);
|
||||||
}
|
}
|
||||||
// const GstTagList *tags = gst_discoverer_stream_info_get_tags(tmpinf);
|
// const GstTagList *tags = gst_discoverer_stream_info_get_tags(tmpinf);
|
||||||
@@ -780,7 +780,7 @@ void MediaPlayer::callback_discoverer_process (GstDiscoverer *discoverer, GstDis
|
|||||||
gst_discoverer_stream_info_list_free(streams);
|
gst_discoverer_stream_info_list_free(streams);
|
||||||
|
|
||||||
if (!foundvideostream) {
|
if (!foundvideostream) {
|
||||||
m->discoverer_message << "No video stream.";
|
m->discoverer_message_ << "No video stream.";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -791,11 +791,11 @@ void MediaPlayer::callback_discoverer_finished(GstDiscoverer *discoverer, MediaP
|
|||||||
// finished the discoverer : finalize open status
|
// finished the discoverer : finalize open status
|
||||||
if (m) {
|
if (m) {
|
||||||
// no error message, open media
|
// no error message, open media
|
||||||
if ( m->discoverer_message.str().empty())
|
if ( m->discoverer_message_.str().empty())
|
||||||
m->execute_open();
|
m->execute_open();
|
||||||
else {
|
else {
|
||||||
Log::Warning("MediaPlayer %s Failed to open %s\n%s", m->id.c_str(), m->uri.c_str(), m->discoverer_message.str().c_str());
|
Log::Warning("MediaPlayer %s Failed to open %s\n%s", m->id_.c_str(), m->uri_.c_str(), m->discoverer_message_.str().c_str());
|
||||||
m->discoverer_message.clear();
|
m->discoverer_message_.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -837,7 +837,7 @@ void TimeCounter::reset ()
|
|||||||
fps = 0.f;
|
fps = 0.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
float TimeCounter::framerate() const
|
float TimeCounter::frameRate() const
|
||||||
{
|
{
|
||||||
return fps;
|
return fps;
|
||||||
}
|
}
|
||||||
|
|||||||
108
MediaPlayer.h
108
MediaPlayer.h
@@ -28,7 +28,7 @@ public:
|
|||||||
TimeCounter();
|
TimeCounter();
|
||||||
void tic();
|
void tic();
|
||||||
void reset();
|
void reset();
|
||||||
float framerate() const;
|
float frameRate() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MediaSegment
|
struct MediaSegment
|
||||||
@@ -101,7 +101,7 @@ public:
|
|||||||
/**
|
/**
|
||||||
* Open a media using gstreamer URI
|
* Open a media using gstreamer URI
|
||||||
* */
|
* */
|
||||||
void Open( std::string uri);
|
void open( std::string uri_);
|
||||||
/**
|
/**
|
||||||
* True if a media was oppenned
|
* True if a media was oppenned
|
||||||
* */
|
* */
|
||||||
@@ -109,17 +109,17 @@ public:
|
|||||||
/**
|
/**
|
||||||
* Close the Media
|
* Close the Media
|
||||||
* */
|
* */
|
||||||
void Close();
|
void close();
|
||||||
/**
|
/**
|
||||||
* Update status
|
* Update status
|
||||||
* Must be called in update loop
|
* Must be called in update loop
|
||||||
* */
|
* */
|
||||||
void Update();
|
void update();
|
||||||
/**
|
/**
|
||||||
* Pause / Play
|
* Pause / Play
|
||||||
* Can play backward if play speed is negative
|
* Can play backward if play speed is negative
|
||||||
* */
|
* */
|
||||||
void Play(bool on);
|
void play(bool on);
|
||||||
/**
|
/**
|
||||||
* Get Pause / Play
|
* Get Pause / Play
|
||||||
* */
|
* */
|
||||||
@@ -128,12 +128,12 @@ public:
|
|||||||
* Speed factor for playing
|
* Speed factor for playing
|
||||||
* Can be negative.
|
* Can be negative.
|
||||||
* */
|
* */
|
||||||
double PlaySpeed() const;
|
double playSpeed() const;
|
||||||
/**
|
/**
|
||||||
* Set the speed factor for playing
|
* Set the speed factor for playing
|
||||||
* Can be negative.
|
* Can be negative.
|
||||||
* */
|
* */
|
||||||
void SetPlaySpeed(double s);
|
void setPlaySpeed(double s);
|
||||||
/**
|
/**
|
||||||
* True if the player will loop when at begin or end
|
* True if the player will loop when at begin or end
|
||||||
* */
|
* */
|
||||||
@@ -142,7 +142,7 @@ public:
|
|||||||
LOOP_REWIND = 1,
|
LOOP_REWIND = 1,
|
||||||
LOOP_BIDIRECTIONAL = 2
|
LOOP_BIDIRECTIONAL = 2
|
||||||
} LoopMode;
|
} LoopMode;
|
||||||
LoopMode Loop() const;
|
LoopMode loop() const;
|
||||||
/**
|
/**
|
||||||
* Set the player to loop
|
* Set the player to loop
|
||||||
* */
|
* */
|
||||||
@@ -150,58 +150,58 @@ public:
|
|||||||
/**
|
/**
|
||||||
* Restart from zero
|
* Restart from zero
|
||||||
* */
|
* */
|
||||||
void Rewind();
|
void rewind();
|
||||||
/**
|
/**
|
||||||
* Seek to next frame when paused
|
* Seek to next frame when paused
|
||||||
* Can go backward if play speed is negative
|
* Can go backward if play speed is negative
|
||||||
* */
|
* */
|
||||||
void SeekNextFrame();
|
void seekNextFrame();
|
||||||
/**
|
/**
|
||||||
* Seek to any position in media
|
* Seek to any position in media
|
||||||
* pos in nanoseconds.
|
* pos in nanoseconds.
|
||||||
* */
|
* */
|
||||||
void SeekTo(GstClockTime pos);
|
void seekTo(GstClockTime pos);
|
||||||
/**
|
/**
|
||||||
* Jump by 10% of the duration
|
* Jump by 10% of the duration
|
||||||
* */
|
* */
|
||||||
void FastForward();
|
void fastForward();
|
||||||
/**
|
/**
|
||||||
* Get position time
|
* Get position time
|
||||||
* */
|
* */
|
||||||
GstClockTime Position();
|
GstClockTime position();
|
||||||
/**
|
/**
|
||||||
* Get total duration time
|
* Get total duration time
|
||||||
* */
|
* */
|
||||||
GstClockTime Duration();
|
GstClockTime duration();
|
||||||
/**
|
/**
|
||||||
* Get duration of one frame
|
* Get duration of one frame
|
||||||
* */
|
* */
|
||||||
GstClockTime FrameDuration();
|
GstClockTime frameDuration();
|
||||||
/**
|
/**
|
||||||
* Get framerate of the media
|
* Get framerate of the media
|
||||||
* */
|
* */
|
||||||
double FrameRate() const;
|
double frameRate() const;
|
||||||
/**
|
/**
|
||||||
* Get name of Codec of the media
|
* Get name of Codec of the media
|
||||||
* */
|
* */
|
||||||
std::string Codec() const;
|
std::string codec() const;
|
||||||
/**
|
/**
|
||||||
* Get rendering update framerate
|
* Get rendering update framerate
|
||||||
* measured during play
|
* measured during play
|
||||||
* */
|
* */
|
||||||
double UpdateFrameRate() const;
|
double updateFrameRate() const;
|
||||||
/**
|
/**
|
||||||
* Bind / Get the OpenGL texture
|
* Bind / Get the OpenGL texture
|
||||||
* Must be called in OpenGL context
|
* Must be called in OpenGL context
|
||||||
* */
|
* */
|
||||||
void Bind();
|
void bind();
|
||||||
guint Texture() const;
|
guint texture() const;
|
||||||
/**
|
/**
|
||||||
* Get Image properties
|
* Get Image properties
|
||||||
* */
|
* */
|
||||||
guint Width() const;
|
guint width() const;
|
||||||
guint Height() const;
|
guint height() const;
|
||||||
float AspectRatio() const;
|
float aspectRatio() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Accept visitors
|
* Accept visitors
|
||||||
@@ -216,37 +216,37 @@ private:
|
|||||||
bool removeAllPlaySegmentOverlap(MediaSegment s);
|
bool removeAllPlaySegmentOverlap(MediaSegment s);
|
||||||
std::list< std::pair<guint64, guint64> > getPlaySegments() const;
|
std::list< std::pair<guint64, guint64> > getPlaySegments() const;
|
||||||
|
|
||||||
std::string id;
|
std::string id_;
|
||||||
std::string uri;
|
std::string uri_;
|
||||||
guint textureindex;
|
guint textureindex_;
|
||||||
guint width;
|
guint width_;
|
||||||
guint height;
|
guint height_;
|
||||||
guint par_width; // width to match pixel aspect ratio
|
guint par_width_; // width to match pixel aspect ratio
|
||||||
GstClockTime position;
|
GstClockTime position_;
|
||||||
GstClockTime start_position;
|
GstClockTime start_position_;
|
||||||
GstClockTime duration;
|
GstClockTime duration_;
|
||||||
GstClockTime frame_duration;
|
GstClockTime frame_duration_;
|
||||||
gdouble rate;
|
gdouble rate_;
|
||||||
LoopMode loop;
|
LoopMode loop_;
|
||||||
TimeCounter timecount;
|
TimeCounter timecount_;
|
||||||
gdouble framerate;
|
gdouble framerate_;
|
||||||
GstState desired_state;
|
GstState desired_state_;
|
||||||
GstElement *pipeline;
|
GstElement *pipeline_;
|
||||||
GstDiscoverer *discoverer;
|
GstDiscoverer *discoverer_;
|
||||||
std::stringstream discoverer_message;
|
std::stringstream discoverer_message_;
|
||||||
std::string codec_name;
|
std::string codec_name_;
|
||||||
GstVideoFrame v_frame;
|
GstVideoFrame v_frame_;
|
||||||
GstVideoInfo v_frame_video_info;
|
GstVideoInfo v_frame_video_info_;
|
||||||
std::atomic<bool> v_frame_is_full;
|
std::atomic<bool> v_frame_is_full_;
|
||||||
std::atomic<bool> need_loop;
|
std::atomic<bool> need_loop_;
|
||||||
|
|
||||||
MediaSegmentSet segments;
|
MediaSegmentSet segments_;
|
||||||
MediaSegmentSet::iterator current_segment;
|
MediaSegmentSet::iterator current_segment_;
|
||||||
|
|
||||||
bool ready;
|
bool ready_;
|
||||||
bool seekable;
|
bool seekable_;
|
||||||
bool isimage;
|
bool isimage_;
|
||||||
bool interlaced;
|
bool interlaced_;
|
||||||
|
|
||||||
void execute_open();
|
void execute_open();
|
||||||
void execute_loop_command();
|
void execute_loop_command();
|
||||||
@@ -255,8 +255,8 @@ private:
|
|||||||
|
|
||||||
static GstFlowReturn callback_pull_sample_video (GstElement *bin, MediaPlayer *m);
|
static GstFlowReturn callback_pull_sample_video (GstElement *bin, MediaPlayer *m);
|
||||||
static void callback_end_of_video (GstElement *bin, MediaPlayer *m);
|
static void callback_end_of_video (GstElement *bin, MediaPlayer *m);
|
||||||
static void callback_discoverer_process (GstDiscoverer *discoverer, GstDiscovererInfo *info, GError *err, MediaPlayer *m);
|
static void callback_discoverer_process (GstDiscoverer *discoverer_, GstDiscovererInfo *info, GError *err, MediaPlayer *m);
|
||||||
static void callback_discoverer_finished(GstDiscoverer *discoverer, MediaPlayer *m);
|
static void callback_discoverer_finished(GstDiscoverer *discoverer_, MediaPlayer *m);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user