Merge branch 'feature/shmsrcbin-rebase-oct2014' of https://github.com/vliaskov/libremapping into feature-merge-vliaskov-shmsrcbin

Conflicts:
	MainWindow.cpp
	MainWindow.h
	MediaImpl.cpp
	ProjectReader.cpp
This commit is contained in:
Tats
2014-10-16 21:46:33 +00:00
8 changed files with 125 additions and 21 deletions
+1 -1
View File
@@ -21,7 +21,7 @@
const QString MM::VERSION = "0.1.1";
const QString MM::FILE_EXTENSION = "mmp";
const QString MM::VIDEO_FILES_FILTER = "*.mov *.mp4 *.avi *.ogg *.ogv *.mpeg *.mpeg1 *.mpeg4 *.mpg *.mpg2 *.mp2 *.mjpq *.mjp *.wmv";
const QString MM::VIDEO_FILES_FILTER = "*.mov *.mp4 *.avi *.ogg *.ogv *.mpeg *.mpeg1 *.mpeg4 *.mpg *.mpg2 *.mp2 *.mjpq *.mjp *.wmv *sock";
const QString MM::IMAGE_FILES_FILTER = "*.jpg *.jpeg *.gif *.png *.tiff *.tif *.bmp";
const QColor MM::WHITE("#f6f5f5");
+9 -3
View File
@@ -623,7 +623,8 @@ bool MainWindow::clearProject()
return true;
}
uid MainWindow::createMediaPaint(uid paintId, QString uri, float x, float y, bool isImage)
uid MainWindow::createMediaPaint(uid paintId, QString uri, float x, float y,
bool isImage, bool live)
{
// Cannot create image with already existing id.
if (Paint::getUidAllocator().exists(paintId))
@@ -635,7 +636,7 @@ uid MainWindow::createMediaPaint(uid paintId, QString uri, float x, float y, boo
if (isImage)
tex = new Image(uri, paintId);
else
tex = new Media(uri, paintId);
tex = new Media(uri, live, paintId);
// Create new image with corresponding ID.
tex->setPosition(x, y);
@@ -1467,18 +1468,23 @@ void MainWindow::setCurrentFile(const QString &fileName)
bool MainWindow::importMediaFile(const QString &fileName, bool isImage)
{
QFile file(fileName);
bool live = false;
if (!file.open(QIODevice::ReadOnly)) {
if (file.isSequential())
live = true;
else {
QMessageBox::warning(this, tr("MapMap Project"),
tr("Cannot read file %1:\n%2.")
.arg(file.fileName())
.arg(file.errorString()));
return false;
}
}
QApplication::setOverrideCursor(Qt::WaitCursor);
// Add media file to model.
uint mediaId = createMediaPaint(NULL_UID, fileName, 0, 0, isImage);
uint mediaId = createMediaPaint(NULL_UID, fileName, 0, 0, isImage, live);
// Initialize position (center).
std::tr1::shared_ptr<Media> media = std::tr1::static_pointer_cast<Media>(mappingManager->getPaintById(mediaId));
+1 -1
View File
@@ -115,7 +115,7 @@ public slots:
bool clearProject();
/// Create or replace a media paint (or image).
uid createMediaPaint(uid paintId, QString uri, float x, float y, bool isImage);
uid createMediaPaint(uid paintId, QString uri, float x, float y, bool isImage, bool live);
/// Create or replace a color paint.
uid createColorPaint(uid paintId, QColor color);
+99 -8
View File
@@ -57,6 +57,21 @@ const uchar* MediaImpl::getBits() const
return _data;
}
QString MediaImpl::getUri() const
{
return _uri;
}
bool MediaImpl::getAttached()
{
return _attached;
}
void MediaImpl::setAttached(bool attach)
{
_attached = attach;
}
void MediaImpl::build()
{
qDebug() << "Building video impl";
@@ -130,7 +145,7 @@ GstFlowReturn MediaImpl::gstNewSampleCallback(GstElement*, MediaImpl *p)
return GST_FLOW_OK;
}
MediaImpl::MediaImpl(const QString uri) :
MediaImpl::MediaImpl(const QString uri, bool live) :
_currentMovie(""),
_bus(NULL),
_pipeline(NULL),
@@ -145,6 +160,8 @@ _width(640),
_height(480),
_data(NULL),
_seekEnabled(false),
_live(live),
_attached(false),
_movieReady(false),
_uri(uri)
{
@@ -212,6 +229,21 @@ void MediaImpl::resetMovie()
}
}
gboolean
gstPollShmsrc (void *user_data)
{
MediaImpl *p = (MediaImpl*) user_data;
if (g_file_test(p->getUri().toUtf8().constData() , G_FILE_TEST_EXISTS) && !p->getAttached()) {
if (!p->setPlayState(true)) {
qDebug() << "tried to attach, but starting pipeline failed!" << endl;
return false;
}
//qDebug() << "attached, started pipeline!" << endl;
p->setAttached(true);
}
return true;
}
bool MediaImpl::loadMovie(QString filename)
{
_uri = filename;
@@ -256,6 +288,15 @@ bool MediaImpl::loadMovie(QString filename)
gst_bin_add_many (GST_BIN (_pipeline), _source,
_videoQueue, _videoColorSpace, videoScale, capsFilter, _videoSink, NULL);
if (_live) {
gst_bin_add (GST_BIN(_pipeline), _deserializer);
if (!gst_element_link_many (_source, _deserializer, _videoQueue, NULL)) {
g_printerr ("Video elements could not be linked.\n");
}
}
else if (!gst_element_link (_source, _videoQueue))
g_printerr ("Video elements could not be linked.\n");
if (!gst_element_link_many (_videoQueue, _videoColorSpace, capsFilter, videoScale, _videoSink, NULL)) {
g_printerr ("Video elements could not be linked.\n");
unloadMovie();
@@ -263,8 +304,9 @@ bool MediaImpl::loadMovie(QString filename)
}
// Process URI.
QByteArray ba = filename.toLocal8Bit();
gchar* uri = (gchar*) filename.toUtf8().constData();
if (!gst_uri_is_valid(uri))
if (!_live && !gst_uri_is_valid(uri))
{
// Try to convert filename to URI.
GError* error = NULL;
@@ -278,12 +320,39 @@ bool MediaImpl::loadMovie(QString filename)
}
}
if (_live)
uri = (gchar*) ba.data();
// Set URI to be played.
qDebug() << "URI for uridecodebin: " << uri;
// FIXME: sometimes it's just the path to the directory that is given, not the file itself.
g_object_set (_source, "uri", uri, NULL);
// Connect to the pad-added signal
g_signal_connect (_source, "pad-added", G_CALLBACK (MediaImpl::gstPadAddedCallback), &_padHandlerData);
if (!_live) {
g_object_set (_source, "uri", uri, NULL);
g_signal_connect (_source, "pad-added", G_CALLBACK (MediaImpl::gstPadAddedCallback), &_padHandlerData);
}
else {
//qDebug() << "LIVE mode" << uri;
g_object_set (_source, "socket-path", uri, NULL);
g_object_set (_source, "is-live", TRUE, NULL);
_padHandlerData.videoIsConnected = true;
}
// Configure audio appsink.
// TODO: change from mono to stereo
// gchar* audioCapsText = g_strdup_printf ("audio/x-raw-float,channels=1,rate=%d,signed=(boolean)true,width=%d,depth=%d,endianness=BYTE_ORDER",
// Engine::signalInfo().sampleRate(), (int)(sizeof(Signal_T)*8), (int)(sizeof(Signal_T)*8) );
// GstCaps* audioCaps = gst_caps_from_string (audioCapsText);
// g_object_set (_audioSink, "emit-signals", TRUE,
// "caps", audioCaps,
//// "max-buffers", 1, // only one buffer (the last) is maintained in the queue
//// "drop", TRUE, // ... other buffers are dropped
// NULL);
// g_signal_connect (_audioSink, "new-buffer", G_CALLBACK (VideoImpl::gstNewAudioBufferCallback), &_newAudioBufferHandlerData);
// gst_caps_unref (audioCaps);
// g_free (audioCapsText);
// Configure video appsink.
GstCaps *videoCaps = gst_caps_from_string ("video/x-raw,format=RGBA");
@@ -291,6 +360,7 @@ bool MediaImpl::loadMovie(QString filename)
g_object_set (_videoSink, "emit-signals", TRUE,
"max-buffers", 1, // only one buffer (the last) is maintained in the queue
"drop", TRUE, // ... other buffers are dropped
"sync", TRUE,
NULL);
g_signal_connect (_videoSink, "new-sample", G_CALLBACK (MediaImpl::gstNewSampleCallback), this);
gst_caps_unref (videoCaps);
@@ -299,7 +369,7 @@ bool MediaImpl::loadMovie(QString filename)
_bus = gst_element_get_bus (_pipeline);
// Start playing.
if (!setPlayState(true))
if (!_live && !setPlayState(true))
return false;
qDebug() << "Pipeline started.";
@@ -324,7 +394,6 @@ bool MediaImpl::runVideo() {
//std::cout << "VideoImpl::runVideo: read frame #" << _videoNewBufferCounter << std::endl;
}
/* TODO: This causes the texture to be loaded always in Mapper.cpp . The
* problem if this is not set is: When we have more than one shape, a
* shape that has a new buffer coming in will overdraw the old buffer of the
@@ -365,8 +434,12 @@ bool MediaImpl::_preRun()
{
// Check for end-of-stream or terminate.
if (_eos() || _terminate)
{
_setFinished(true);
resetMovie();
}
else
_setFinished(false);
if (!_movieReady ||
!_padHandlerData.videoIsConnected)
return false;
@@ -398,11 +471,21 @@ void MediaImpl::_postRun()
g_clear_error(&err);
g_free(debug_info);
_terminate = true;
if (!_live)
_terminate = true;
else {
_attached = false;
gst_element_set_state (_pipeline, GST_STATE_PAUSED);
gst_element_set_state (_pipeline, GST_STATE_NULL);
gst_element_set_state (_pipeline, GST_STATE_READY);
}
// _finish();
break;
case GST_MESSAGE_EOS:
g_print("End-Of-Stream reached.\n");
// _terminate = true;
// _finish();
break;
case GST_MESSAGE_STATE_CHANGED:
@@ -417,6 +500,9 @@ void MediaImpl::_postRun()
gst_element_state_get_name(oldState),
gst_element_state_get_name(newState));
// if (oldState == GST_STATE_PAUSED && newState == GST_STATE_READY)
// gst_adapter_clear(_audioBufferAdapter);
if (newState == GST_STATE_PLAYING)
{
// Check if seeking is allowed.
@@ -460,6 +546,11 @@ void MediaImpl::_setReady(bool ready)
_movieReady = ready;
}
void MediaImpl::_setFinished(bool finished) {
Q_UNUSED(finished);
// qDebug() << "Clip " << (finished ? "finished" : "not finished");
}
void MediaImpl::gstPadAddedCallback(GstElement *src, GstPad *newPad, MediaImpl::GstPadHandlerData* data) {
g_print ("Received new pad '%s' from '%s':\n", GST_PAD_NAME (newPad), GST_ELEMENT_NAME (src));
GstPad *sinkPad = NULL;
+11 -4
View File
@@ -45,7 +45,7 @@
class MediaImpl
{
public:
MediaImpl(const QString uri);
MediaImpl(const QString uri, bool live);
~MediaImpl();
// void setUri(const QString uri);
@@ -53,6 +53,8 @@ public:
void build();
int getWidth() const;
int getHeight() const;
QString getUri() const;
bool getAttached();
const uchar* getBits() const;
bool isReady() const { return _padHandlerData.videoIsConnected; }
@@ -61,8 +63,9 @@ public:
bool runVideo();
// void runAudio();
bool loadMovie(QString filename);
bool setPlayState(bool play);
void setAttached(bool attach);
void resetMovie();
protected:
@@ -78,7 +81,7 @@ private:
bool _preRun();
void _postRun();
void _setReady(bool ready);
// void _setFinished(bool finished);
void _setFinished(bool finished);
public:
// GStreamer callbacks.
@@ -112,7 +115,6 @@ public:
return &this->_queueOutputBuffer;
}
private:
//locals
QString _currentMovie;
@@ -121,6 +123,7 @@ private:
GstBus *_bus;
GstElement *_pipeline;
GstElement *_source;
GstElement *_deserializer;
GstElement *_audioQueue;
GstElement *_audioConvert;
GstElement *_audioResample;
@@ -130,6 +133,7 @@ private:
GstElement *_audioSink;
GstElement *_videoSink;
GstSample *_frame;
GSource *_pollSource;
GstPadHandlerData _padHandlerData;
@@ -138,6 +142,8 @@ private:
uchar *_data;
bool _seekEnabled;
bool _live;
bool _attached;
int _audioNewBufferCounter;
@@ -148,6 +154,7 @@ private:
private:
QString _uri;
};
#endif /* ifndef */
+2 -2
View File
@@ -51,12 +51,12 @@ bool Image::setUri(const QString &uri)
/* Implementation of the Video class */
Media::Media(const QString uri_, uid id):
Media::Media(const QString uri_, bool live, uid id):
Texture(id),
uri(uri_),
impl_(NULL)
{
impl_ = new MediaImpl(uri_);
impl_ = new MediaImpl(uri_, live);
}
// vertigo
+1 -1
View File
@@ -198,7 +198,7 @@ class Media : public Texture
protected:
QString uri;
public:
Media(const QString uri_, uid id=NULL_UID);
Media(const QString uri_, bool live, uid id=NULL_UID);
virtual ~Media();
const QString getUri() const
{
+1 -1
View File
@@ -96,7 +96,7 @@ void ProjectReader::parsePaint(const QDomElement& paint)
QString x = paint.firstChildElement("x").text();
QString y = paint.firstChildElement("y").text();
uid id = _window->createMediaPaint(paintAttrId.toInt(), uri, x.toFloat(), y.toFloat(), paintAttrType == "image");
uid id = _window->createMediaPaint(paintAttrId.toInt(), uri, x.toFloat(), y.toFloat(), paintAttrType == "image", false);
if (id == NULL_UID)
_xml.raiseError(QObject::tr("Cannot create media with uri %1.").arg(uri));
}