mirror of
https://github.com/mapmapteam/mapmap.git
synced 2026-06-16 12:33:19 +02:00
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:
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user