<commit_before>/*
    Copyright (C) 2012  David Edmundson <kde@davidedmundson.co.uk>
    Copyright (C) 2013  Dan Vrátil <dvratil@redhat.com>

    This library is free software; you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published
    by the Free Software Foundation; either version 2.1 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "tubechannelapprover.h"

#include <KService>
#include <KServiceTypeTrader>
#include <KStatusNotifierItem>
#include <KDebug>
#include <KAboutData>
#include <KIcon>
#include <KMenu>

#include <TelepathyQt/TubeChannel>
#include <TelepathyQt/StreamTubeChannel>
#include <TelepathyQt/DBusTubeChannel>
#include <TelepathyQt/Contact>

#include "approverdaemon.h"

TubeChannelApprover::TubeChannelApprover(const Tp::TubeChannelPtr& channel, QObject* parent):
    ChannelApprover(0),
    m_channel(channel)
{
    Q_UNUSED(parent);

    kDebug() << "Incomming tube channel";
    kDebug() << "\tTube Type:" << channel->channelType();

    connect(m_channel.data(), SIGNAL(invalidated(Tp::DBusProxy*,QString,QString)), SLOT(onChannelInvalidated()));

    QString serviceName;
    if (Tp::StreamTubeChannelPtr streamTube = Tp::StreamTubeChannelPtr::dynamicCast(channel)) {
        kDebug() << "\tService:" << streamTube->service();
        serviceName = streamTube->service();
    } else if (Tp::DBusTubeChannelPtr dbusTube = Tp::DBusTubeChannelPtr::dynamicCast(channel)) {
        kDebug() << "\tService name:" << dbusTube->serviceName();
        serviceName = dbusTube->serviceName();
    }

    KService::List services = KServiceTypeTrader::self()->query(QLatin1String("KTpApprover"));
    kDebug() << "Found" << services.count() << "KTpApprover services";
    if (!services.isEmpty()) {
        Q_FOREACH(const KService::Ptr &service, services) {
            if ((service->property(QLatin1String("X-KTp-ChannelType")) != channel->channelType()) ||
                (service->property(QLatin1String("X-KTp-Service")) != serviceName)) {

                continue;
            }
            m_service = service;
        }
    }

    if (!m_service) {
        kDebug() << "No service to match" << channel->channelType() << "," << serviceName;
        showNotification(i18n("Unknown Incoming Connection"),
                         i18n("%1 wants to start an unknown service with you", channel->initiatorContact()->alias()),
                         QLatin1String("dialog-warning"),
                         channel->initiatorContact());

        return;
    }

    showNotification(m_service->name(), m_service->comment(), m_service->icon(), channel->initiatorContact());
}

TubeChannelApprover::~TubeChannelApprover()
{
    kDebug();

    //destroy the notification
    if (m_notification) {
        m_notification.data()->close();
    }

    if (m_notifierItem) {
        m_notifierItem.data()->deleteLater();
    }
}

void TubeChannelApprover::showNotification(const QString& title, const QString& comment, const QString& icon, const Tp::ContactPtr& sender)
{
    // incoming_file_transfer = defines notification sound & user preferences
    m_notification = new KNotification(QLatin1String("incoming_file_transfer"));
    KAboutData aboutData("ktelepathy", 0, KLocalizedString(), 0);
    m_notification.data()->setComponentData(KComponentData(aboutData));
    m_notification.data()->setTitle(title);
    if (comment.contains(QLatin1String("%1"))) {
        Q_ASSERT(sender);
        m_notification.data()->setText(comment.arg(sender->alias()));
    } else {
        m_notification.data()->setText(comment);
    }
    m_notification.data()->setPixmap(KIcon(icon).pixmap(32, 32));
    m_notification.data()->setActions(QStringList() << i18n("Accept") << i18n("Reject"));
    connect(m_notification.data(), SIGNAL(action1Activated()), SIGNAL(channelAccepted()));
    connect(m_notification.data(), SIGNAL(action2Activated()), SIGNAL(channelRejected()));

    m_notification.data()->sendEvent();

    //tray icon
    m_notifierItem = new KStatusNotifierItem;
    m_notifierItem.data()->setCategory(KStatusNotifierItem::Communications);
    m_notifierItem.data()->setStatus(KStatusNotifierItem::NeedsAttention);
    m_notifierItem.data()->setIconByName(icon);
    m_notifierItem.data()->setStandardActionsEnabled(false);
    m_notifierItem.data()->setTitle(title);
    m_notifierItem.data()->setToolTip(QLatin1String("document-save"),
                               i18n("Incoming %1 request from %2", title, sender->alias()),
                               QString());

    m_notifierItem.data()->contextMenu()->clear(); //calling clear removes the pointless title
    m_notifierItem.data()->contextMenu()->addAction(i18n("Accept"), this, SIGNAL(channelAccepted()));
    m_notifierItem.data()->contextMenu()->addAction(i18n("Reject"), this, SIGNAL(channelRejected()));
    connect(this, SIGNAL(channelAccepted()), SLOT(onChannelAccepted()));
}

void TubeChannelApprover::onChannelAccepted()
{
    //destroy the notification
    if (m_notification) {
        m_notification.data()->close();
    }

    if (!m_service.isNull() && m_service->property(QLatin1String("X-KTp-Cancellable")).toBool()) {
        m_notifierItem.data()->setTitle(i18n("%1 share with %2", m_service->name(), m_channel->initiatorContact()->alias()));
        //set new menu to an entry to close the channel
        m_notifierItem.data()->contextMenu()->clear();
        m_notifierItem.data()->contextMenu()->addAction(KIcon("dialog-close"), i18n("Stop %1 Sharing", m_service->name()),
                                                 this, SLOT(onChannelCloseRequested()));
    } else {
        m_notifierItem.data()->deleteLater();
    }
}

void TubeChannelApprover::onChannelCloseRequested()
{
    m_channel->requestClose();
}

void TubeChannelApprover::onChannelInvalidated()
{
    deleteLater();
}
<commit_msg>Fix typo in debug line<commit_after>/*
    Copyright (C) 2012  David Edmundson <kde@davidedmundson.co.uk>
    Copyright (C) 2013  Dan Vrátil <dvratil@redhat.com>

    This library is free software; you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published
    by the Free Software Foundation; either version 2.1 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "tubechannelapprover.h"

#include <KService>
#include <KServiceTypeTrader>
#include <KStatusNotifierItem>
#include <KDebug>
#include <KAboutData>
#include <KIcon>
#include <KMenu>

#include <TelepathyQt/TubeChannel>
#include <TelepathyQt/StreamTubeChannel>
#include <TelepathyQt/DBusTubeChannel>
#include <TelepathyQt/Contact>

#include "approverdaemon.h"

TubeChannelApprover::TubeChannelApprover(const Tp::TubeChannelPtr& channel, QObject* parent):
    ChannelApprover(0),
    m_channel(channel)
{
    Q_UNUSED(parent);

    kDebug() << "Incoming tube channel";
    kDebug() << "\tTube Type:" << channel->channelType();

    connect(m_channel.data(), SIGNAL(invalidated(Tp::DBusProxy*,QString,QString)), SLOT(onChannelInvalidated()));

    QString serviceName;
    if (Tp::StreamTubeChannelPtr streamTube = Tp::StreamTubeChannelPtr::dynamicCast(channel)) {
        kDebug() << "\tService:" << streamTube->service();
        serviceName = streamTube->service();
    } else if (Tp::DBusTubeChannelPtr dbusTube = Tp::DBusTubeChannelPtr::dynamicCast(channel)) {
        kDebug() << "\tService name:" << dbusTube->serviceName();
        serviceName = dbusTube->serviceName();
    }

    KService::List services = KServiceTypeTrader::self()->query(QLatin1String("KTpApprover"));
    kDebug() << "Found" << services.count() << "KTpApprover services";
    if (!services.isEmpty()) {
        Q_FOREACH(const KService::Ptr &service, services) {
            if ((service->property(QLatin1String("X-KTp-ChannelType")) != channel->channelType()) ||
                (service->property(QLatin1String("X-KTp-Service")) != serviceName)) {

                continue;
            }
            m_service = service;
        }
    }

    if (!m_service) {
        kDebug() << "No service to match" << channel->channelType() << "," << serviceName;
        showNotification(i18n("Unknown Incoming Connection"),
                         i18n("%1 wants to start an unknown service with you", channel->initiatorContact()->alias()),
                         QLatin1String("dialog-warning"),
                         channel->initiatorContact());

        return;
    }

    showNotification(m_service->name(), m_service->comment(), m_service->icon(), channel->initiatorContact());
}

TubeChannelApprover::~TubeChannelApprover()
{
    kDebug();

    //destroy the notification
    if (m_notification) {
        m_notification.data()->close();
    }

    if (m_notifierItem) {
        m_notifierItem.data()->deleteLater();
    }
}

void TubeChannelApprover::showNotification(const QString& title, const QString& comment, const QString& icon, const Tp::ContactPtr& sender)
{
    // incoming_file_transfer = defines notification sound & user preferences
    m_notification = new KNotification(QLatin1String("incoming_file_transfer"));
    KAboutData aboutData("ktelepathy", 0, KLocalizedString(), 0);
    m_notification.data()->setComponentData(KComponentData(aboutData));
    m_notification.data()->setTitle(title);
    if (comment.contains(QLatin1String("%1"))) {
        Q_ASSERT(sender);
        m_notification.data()->setText(comment.arg(sender->alias()));
    } else {
        m_notification.data()->setText(comment);
    }
    m_notification.data()->setPixmap(KIcon(icon).pixmap(32, 32));
    m_notification.data()->setActions(QStringList() << i18n("Accept") << i18n("Reject"));
    connect(m_notification.data(), SIGNAL(action1Activated()), SIGNAL(channelAccepted()));
    connect(m_notification.data(), SIGNAL(action2Activated()), SIGNAL(channelRejected()));

    m_notification.data()->sendEvent();

    //tray icon
    m_notifierItem = new KStatusNotifierItem;
    m_notifierItem.data()->setCategory(KStatusNotifierItem::Communications);
    m_notifierItem.data()->setStatus(KStatusNotifierItem::NeedsAttention);
    m_notifierItem.data()->setIconByName(icon);
    m_notifierItem.data()->setStandardActionsEnabled(false);
    m_notifierItem.data()->setTitle(title);
    m_notifierItem.data()->setToolTip(QLatin1String("document-save"),
                               i18n("Incoming %1 request from %2", title, sender->alias()),
                               QString());

    m_notifierItem.data()->contextMenu()->clear(); //calling clear removes the pointless title
    m_notifierItem.data()->contextMenu()->addAction(i18n("Accept"), this, SIGNAL(channelAccepted()));
    m_notifierItem.data()->contextMenu()->addAction(i18n("Reject"), this, SIGNAL(channelRejected()));
    connect(this, SIGNAL(channelAccepted()), SLOT(onChannelAccepted()));
}

void TubeChannelApprover::onChannelAccepted()
{
    //destroy the notification
    if (m_notification) {
        m_notification.data()->close();
    }

    if (!m_service.isNull() && m_service->property(QLatin1String("X-KTp-Cancellable")).toBool()) {
        m_notifierItem.data()->setTitle(i18n("%1 share with %2", m_service->name(), m_channel->initiatorContact()->alias()));
        //set new menu to an entry to close the channel
        m_notifierItem.data()->contextMenu()->clear();
        m_notifierItem.data()->contextMenu()->addAction(KIcon("dialog-close"), i18n("Stop %1 Sharing", m_service->name()),
                                                 this, SLOT(onChannelCloseRequested()));
    } else {
        m_notifierItem.data()->deleteLater();
    }
}

void TubeChannelApprover::onChannelCloseRequested()
{
    m_channel->requestClose();
}

void TubeChannelApprover::onChannelInvalidated()
{
    deleteLater();
}
<|endoftext|>


<commit_before>
#include <qvaluelist.h>
#include <qpair.h>
#include <qhostaddress.h>
#include <kapabilities.h>
#include "opiekonnector.h"

OpiePlugin::OpiePluginPrivate{
 public:
  OpiePluginPrivate(){
    connection = false;
  }
  QString udi;
  bool connection;
  QStringList retrFiles;
};

OpiePlugin::OpiePlugin(QObject *obj, const char *name, const QStringList )
  : KonnectorPlugin(obj, name )
{
  d = new OpiePluginPrivate;

}
void OpiePlugin::setUDI(const QString &udi )
{
  d->udi = udi;
}

QString OpiePlugin::udi()const
{
  return d->udi;
}

Kapabilities OpiePlugin::capabilities( )
{
  // create the capabilities Apply
  Kapabilities caps;
  caps.setSupportsPushSync( true );
  caps.setNeedsConnection( true );
  caps.setSupportListDir( false );
  caps.setNeedsIPs( true );
  caps.setNeedsSrcIP( false );
  caps.setNeedsDestIP( true );
  caps.setAutoHandle( false );
  caps.setNeedAuthentication( true );
  QValueList<QPair<QString,QString> > user;
  user.append(qMakePair("root", "test123" ) );
  user.append(qMakePair("ich", "test321" ) );
  caps.setUserProposals( user );
  QValueList< QPair<QHostAddress, QHostAddress> > ips;
  QHostAddress src;
  QHostAddress dest;
  src.setAddress("192.168.1.100" );
  dest.setAddress("192.168.1.201");
  ips.append( qMakePair(src, dest ) );
  src.setAddress("127.0.0.1" );
  dest.setAddress("127.0.0.1");
  ips.append( qMakePair(src, dest ) );
}

void OpiePlugin::setCapabilities( const Kapabilities &kaps )
{
  // create
  //->setSrcIP( kaps.srcIP() );
  //->setDestIP( kaps.destIP() );
  //->setUser( kaps.user() );
  //->setPassword( kaps.password() );
}
bool OpiePlugin::startSync()
{
  //return ->startSync();
}
bool OpiePlugin::isConnected()
{
  //return ->isConnected();
}
bool OpiePlugin::insertFile(const QString &fileName )
{

}
QByteArray OpiePlugin::retrFile(const QString &path )
{

}
void OpiePlugin::slotWrite(const QString &, const QByteArray & )
{

}
void OpiePlugin::slotWrite(QPtrList<KSyncEntry> )
{

}
void OpiePlugin::slotWrite(QValueList<KOperations> )
{

}

<commit_msg><commit_after>
#include <qvaluelist.h>
#include <qpair.h>
#include <qhostaddress.h>
#include <kapabilities.h>
#include "opiekonnector.h"

OpiePlugin::OpiePluginPrivate{
 public:
  OpiePluginPrivate(){
    connection = false;
  }
  QString udi;
  bool connection;
  QStringList retrFiles;
};

OpiePlugin::OpiePlugin(QObject *obj, const char *name, const QStringList )
  : KonnectorPlugin(obj, name )
{
  d = new OpiePluginPrivate;

}
void OpiePlugin::setUDI(const QString &udi )
{
  d->udi = udi;
}

QString OpiePlugin::udi()const
{
  return d->udi;
}

Kapabilities OpiePlugin::capabilities( )
{
  // create the capabilities Apply
  Kapabilities caps;
  caps.setSupportsPushSync( true );
  caps.setNeedsConnection( true );
  caps.setSupportListDir( false );
  caps.setNeedsIPs( true );
  caps.setNeedsSrcIP( false );
  caps.setNeedsDestIP( true );
  caps.setAutoHandle( false );
  caps.setNeedAuthentication( true );
  QValueList<QPair<QString,QString> > user;
  user.append(qMakePair("root", "test123" ) );
  user.append(qMakePair("ich", "test321" ) );
  caps.setUserProposals( user );
  QValueList< QPair<QHostAddress, QHostAddress> > ips;
  QHostAddress src;
  QHostAddress dest;
  src.setAddress("192.168.1.100" );
  dest.setAddress("192.168.1.201");
  ips.append( qMakePair(src, dest ) );
  src.setAddress("127.0.0.1" );
  dest.setAddress("127.0.0.1");
  ips.append( qMakePair(src, dest ) );
}

void OpiePlugin::setCapabilities( const Kapabilities &kaps )
{
  // create
  //->setSrcIP( kaps.srcIP() );
  //->setDestIP( kaps.destIP() );
  //->setUser( kaps.user() );
  //->setPassword( kaps.password() );
}
bool OpiePlugin::startSync()
{
  //return ->startSync();
}
bool OpiePlugin::isConnected()
{
  //return ->isConnected();
}
bool OpiePlugin::insertFile(const QString &fileName )
{

}
QByteArray OpiePlugin::retrFile(const QString &path )
{

}
void OpiePlugin::slotWrite(const QString &, const QByteArray & )
{

}
void OpiePlugin::slotWrite(QPtrList<KSyncEntry> )
{

}
void OpiePlugin::slotWrite(QValueList<KOperations> )
{

}

<|endoftext|>


<commit_before>/*
 * gst-droid
 *
 * Copyright (C) 2014 Mohammed Sameer <msameer@foolab.org>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include "videoplayer.h"
#include <QQmlInfo>
#include <QTimer>
#include "renderer.h"
#include <QPainter>
#include <QMatrix4x4>
#include <cmath>

VideoPlayer::VideoPlayer(QQuickItem *parent) :
  QQuickPaintedItem(parent),
  m_renderer(0),
  m_bin(0),
  m_state(VideoPlayer::StateStopped),
  m_timer(new QTimer(this)),
  m_pos(0),
  m_created(false) {

  m_timer->setSingleShot(false);
  m_timer->setInterval(500);
  QObject::connect(m_timer, SIGNAL(timeout()), this, SIGNAL(positionChanged()));

  setRenderTarget(QQuickPaintedItem::FramebufferObject);
  setSmooth(false);
  setAntialiasing(false);
}

VideoPlayer::~VideoPlayer() {
  stop();

  if (m_bin) {
    gst_object_unref(m_bin);
    m_bin = 0;
  }
}

void VideoPlayer::componentComplete() {
  QQuickPaintedItem::componentComplete();
}

void VideoPlayer::classBegin() {
  QQuickPaintedItem::classBegin();

  m_bin = gst_element_factory_make ("playbin", "VideoPlayerBin");
  if (!m_bin) {
    qmlInfo(this) << "Failed to create playbin";
    return;
  }

  g_signal_connect (G_OBJECT (m_bin), "notify::volume", G_CALLBACK (on_volume_changed), this);

  GstElement *elem = gst_element_factory_make("pulsesink", "VideoPlayerPulseSink");
  if (!elem) {
    qmlInfo(this) << "Failed to create pulsesink";
  }
  else {
    g_object_set (m_bin, "audio-sink", elem, NULL);
  }

  GstBus *bus = gst_element_get_bus(m_bin);
  gst_bus_add_watch(bus, bus_call, this);
  gst_object_unref(bus);
}

QUrl VideoPlayer::source() const {
  return m_url;
}

void VideoPlayer::setSource(const QUrl& source) {
  if (m_url != source) {
    m_url = source;
    emit sourceChanged();
  }
}

qint64 VideoPlayer::duration() const {
  if (!m_bin) {
    return 0;
  }

  qint64 dur = 0;
  if (!gst_element_query_duration(m_bin, GST_FORMAT_TIME, &dur)) {
    return 0;
  }

  dur /= 1000000;

  return dur;
}

qint64 VideoPlayer::position() {
  if (!m_bin) {
    return 0;
  }

  qint64 pos = 0;
  if (!gst_element_query_position(m_bin, GST_FORMAT_TIME, &pos)) {
    return m_pos;
  }

  pos /= 1000000;

  m_pos = pos;

  return pos;
}

void VideoPlayer::setPosition(qint64 position) {
  seek(position);
}

bool VideoPlayer::pause() {
  return setState(VideoPlayer::StatePaused);
}

bool VideoPlayer::play() {
  if (!m_renderer) {
    m_renderer = QtCamViewfinderRenderer::create(this);
    if (!m_renderer) {
      qmlInfo(this) << "Failed to create viewfinder renderer";
      return false;
    }

    QObject::connect(m_renderer, SIGNAL(updateRequested()), this, SLOT(updateRequested()));
  }

  m_renderer->resize(QSizeF(width(), height()));

  if (!m_bin) {
    qmlInfo(this) << "no playbin";
    return false;
  }

  g_object_set(m_bin, "video-sink", m_renderer->sinkElement(), NULL);

  return setState(VideoPlayer::StatePlaying);
}

bool VideoPlayer::seek(qint64 offset) {
  if (!m_bin) {
    qmlInfo(this) << "no playbin2";
    return false;
  }

  qint64 pos = offset;

  offset *= 1000000;

  GstSeekFlags flags = (GstSeekFlags)(GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE);
  gboolean ret = gst_element_seek_simple (m_bin, GST_FORMAT_TIME,
					  flags, offset);

  if (ret) {
    m_pos = pos;

    return TRUE;
  }

  return FALSE;
}

bool VideoPlayer::stop() {
  return setState(VideoPlayer::StateStopped);
}

void VideoPlayer::geometryChanged(const QRectF& newGeometry, const QRectF& oldGeometry) {
  QQuickPaintedItem::geometryChanged(newGeometry, oldGeometry);

  if (m_renderer) {
    m_renderer->resize(newGeometry.size());
  }
}

void VideoPlayer::paint(QPainter *painter) {
  painter->fillRect(contentsBoundingRect(), Qt::black);

  if (!m_renderer) {
    return;
  }

  bool needsNativePainting = m_renderer->needsNativePainting();

  if (needsNativePainting) {
    painter->beginNativePainting();
  }

  m_renderer->paint(QMatrix4x4(painter->combinedTransform()), painter->viewport());

  if (needsNativePainting) {
    painter->endNativePainting();
  }
}

VideoPlayer::State VideoPlayer::state() const {
  return m_state;
}

bool VideoPlayer::setPaused(int flags) {
  g_object_set (m_bin, "flags", flags, NULL);

  if (gst_element_set_state(m_bin, GST_STATE_PAUSED) == GST_STATE_CHANGE_FAILURE) {
    qmlInfo(this) << "error setting pipeline to PAUSED";
    return false;
  }

  GstBus *bus = gst_element_get_bus(m_bin);
  GstMessage *message =
    gst_bus_timed_pop_filtered(bus, GST_CLOCK_TIME_NONE,
			       (GstMessageType)(GST_MESSAGE_ASYNC_DONE | GST_MESSAGE_ERROR));

  if (GST_MESSAGE_TYPE(message) == GST_MESSAGE_ERROR) {
    gst_message_unref (message);
    gst_object_unref(bus);
    gst_element_set_state(m_bin, GST_STATE_NULL);
    return false;
  }

  gst_message_unref (message);
  gst_object_unref(bus);
  return true;
}

bool VideoPlayer::setState(const VideoPlayer::State& state) {
  if (state == m_state) {
    return true;
  }

  if (!m_bin) {
    qmlInfo(this) << "no playbin2";
    return false;
  }

  if (state == VideoPlayer::StatePaused) {
    m_timer->stop();

    if (gst_element_set_state(m_bin, GST_STATE_PAUSED) == GST_STATE_CHANGE_FAILURE) {
      qmlInfo(this) << "error setting pipeline to PAUSED";
      return false;
    }

    GstState st;
    if (gst_element_get_state(m_bin, &st, NULL, GST_CLOCK_TIME_NONE)
	== GST_STATE_CHANGE_FAILURE) {
      qmlInfo(this) << "setting pipeline to PAUSED failed";
      return false;
    }

    if (st != GST_STATE_PAUSED) {
      qmlInfo(this) << "pipeline failed to transition to to PAUSED state";
      return false;
    }

    m_state = state;
    emit stateChanged();

    return true;
  }
  else if (state == VideoPlayer::StatePlaying) {
    // Set uri if needed:
    if (m_state == VideoPlayer::StateStopped) {
      const char *uri = m_url.toString().toUtf8().constData();
      g_object_set(m_bin, "uri", uri, NULL);
    }

    if (!setPaused (0x00000001 | 0x00000002 | 0x00000010 | 0x00000020 |  0x00000200)) {

      if (!setPaused (0x00000001 | 0x00000002 | 0x00000010 | 0x00000020 |  0x00000200 | 0x00000040)) {
	qmlInfo(this) << "error setting pipeline to PAUSED";
	return false;
      }

    }

    if (gst_element_set_state(m_bin, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) {
      qmlInfo(this) << "error setting pipeline to PLAYING";
      return false;
    }

    m_state = state;
    emit stateChanged();

    emit durationChanged();
    emit positionChanged();

    m_timer->start();
    return true;
  }
  else {
    m_timer->stop();
    m_pos = 0;

    delete m_renderer;
    m_renderer = 0;

    if (gst_element_set_state(m_bin, GST_STATE_NULL) == GST_STATE_CHANGE_FAILURE) {
      qmlInfo(this) << "error setting pipeline to NULL";
      return false;
    }

    GstState st;
    if (gst_element_get_state(m_bin, &st, NULL, GST_CLOCK_TIME_NONE)
	== GST_STATE_CHANGE_FAILURE) {
      qmlInfo(this) << "setting pipeline to NULL failed";
      return false;
    }

    if (st != GST_STATE_NULL) {
      qmlInfo(this) << "pipeline failed to transition to to NULL state";
      return false;
    }

    m_state = state;
    emit stateChanged();

    emit durationChanged();
    emit positionChanged();

    return true;
  }
}

gboolean VideoPlayer::bus_call(GstBus *bus, GstMessage *msg, gpointer data) {
  Q_UNUSED(bus);

  VideoPlayer *that = (VideoPlayer *) data;

  gchar *debug = NULL;
  GError *err = NULL;

  switch (GST_MESSAGE_TYPE(msg)) {
  case GST_MESSAGE_EOS:
    that->stop();
    break;

  case GST_MESSAGE_ERROR:
    gst_message_parse_error (msg, &err, &debug);

    emit that->error(err->message, err->code, debug);
    that->stop();
    qWarning() << "Error" << err->message;
    if (err) {
      g_error_free (err);
    }

    if (debug) {
      g_free (debug);
    }

    break;

  default:
    break;
  }

  return TRUE;
}

void VideoPlayer::updateRequested() {
  update();
}

quint32 VideoPlayer::volume() {
  double vol = 1.0;
  g_object_get (m_bin, "volume", &vol, NULL);

  qint32 res = (int)round(vol * 100.0);

  return res;
}

void VideoPlayer::setVolume(quint32 volume) {
  if (VideoPlayer::volume() != volume) {
    double vol = volume / 100.0;
    g_object_set (m_bin, "volume", vol, NULL);
    emit volumeChanged();
  }
}

void VideoPlayer::on_volume_changed(GObject *object, GParamSpec *pspec, gpointer user_data) {
  Q_UNUSED(object);
  Q_UNUSED(pspec);

  VideoPlayer *player = (VideoPlayer *) user_data;

  QMetaObject::invokeMethod(player, "volumeChanged", Qt::QueuedConnection);
}
<commit_msg>avoid accessing invalid memory while assigning uri for playbin<commit_after>/*
 * gst-droid
 *
 * Copyright (C) 2014 Mohammed Sameer <msameer@foolab.org>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include "videoplayer.h"
#include <QQmlInfo>
#include <QTimer>
#include "renderer.h"
#include <QPainter>
#include <QMatrix4x4>
#include <cmath>

VideoPlayer::VideoPlayer(QQuickItem *parent) :
  QQuickPaintedItem(parent),
  m_renderer(0),
  m_bin(0),
  m_state(VideoPlayer::StateStopped),
  m_timer(new QTimer(this)),
  m_pos(0),
  m_created(false) {

  m_timer->setSingleShot(false);
  m_timer->setInterval(500);
  QObject::connect(m_timer, SIGNAL(timeout()), this, SIGNAL(positionChanged()));

  setRenderTarget(QQuickPaintedItem::FramebufferObject);
  setSmooth(false);
  setAntialiasing(false);
}

VideoPlayer::~VideoPlayer() {
  stop();

  if (m_bin) {
    gst_object_unref(m_bin);
    m_bin = 0;
  }
}

void VideoPlayer::componentComplete() {
  QQuickPaintedItem::componentComplete();
}

void VideoPlayer::classBegin() {
  QQuickPaintedItem::classBegin();

  m_bin = gst_element_factory_make ("playbin", "VideoPlayerBin");
  if (!m_bin) {
    qmlInfo(this) << "Failed to create playbin";
    return;
  }

  g_signal_connect (G_OBJECT (m_bin), "notify::volume", G_CALLBACK (on_volume_changed), this);

  GstElement *elem = gst_element_factory_make("pulsesink", "VideoPlayerPulseSink");
  if (!elem) {
    qmlInfo(this) << "Failed to create pulsesink";
  }
  else {
    g_object_set (m_bin, "audio-sink", elem, NULL);
  }

  GstBus *bus = gst_element_get_bus(m_bin);
  gst_bus_add_watch(bus, bus_call, this);
  gst_object_unref(bus);
}

QUrl VideoPlayer::source() const {
  return m_url;
}

void VideoPlayer::setSource(const QUrl& source) {
  if (m_url != source) {
    m_url = source;
    emit sourceChanged();
  }
}

qint64 VideoPlayer::duration() const {
  if (!m_bin) {
    return 0;
  }

  qint64 dur = 0;
  if (!gst_element_query_duration(m_bin, GST_FORMAT_TIME, &dur)) {
    return 0;
  }

  dur /= 1000000;

  return dur;
}

qint64 VideoPlayer::position() {
  if (!m_bin) {
    return 0;
  }

  qint64 pos = 0;
  if (!gst_element_query_position(m_bin, GST_FORMAT_TIME, &pos)) {
    return m_pos;
  }

  pos /= 1000000;

  m_pos = pos;

  return pos;
}

void VideoPlayer::setPosition(qint64 position) {
  seek(position);
}

bool VideoPlayer::pause() {
  return setState(VideoPlayer::StatePaused);
}

bool VideoPlayer::play() {
  if (!m_renderer) {
    m_renderer = QtCamViewfinderRenderer::create(this);
    if (!m_renderer) {
      qmlInfo(this) << "Failed to create viewfinder renderer";
      return false;
    }

    QObject::connect(m_renderer, SIGNAL(updateRequested()), this, SLOT(updateRequested()));
  }

  m_renderer->resize(QSizeF(width(), height()));

  if (!m_bin) {
    qmlInfo(this) << "no playbin";
    return false;
  }

  g_object_set(m_bin, "video-sink", m_renderer->sinkElement(), NULL);

  return setState(VideoPlayer::StatePlaying);
}

bool VideoPlayer::seek(qint64 offset) {
  if (!m_bin) {
    qmlInfo(this) << "no playbin2";
    return false;
  }

  qint64 pos = offset;

  offset *= 1000000;

  GstSeekFlags flags = (GstSeekFlags)(GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE);
  gboolean ret = gst_element_seek_simple (m_bin, GST_FORMAT_TIME,
					  flags, offset);

  if (ret) {
    m_pos = pos;

    return TRUE;
  }

  return FALSE;
}

bool VideoPlayer::stop() {
  return setState(VideoPlayer::StateStopped);
}

void VideoPlayer::geometryChanged(const QRectF& newGeometry, const QRectF& oldGeometry) {
  QQuickPaintedItem::geometryChanged(newGeometry, oldGeometry);

  if (m_renderer) {
    m_renderer->resize(newGeometry.size());
  }
}

void VideoPlayer::paint(QPainter *painter) {
  painter->fillRect(contentsBoundingRect(), Qt::black);

  if (!m_renderer) {
    return;
  }

  bool needsNativePainting = m_renderer->needsNativePainting();

  if (needsNativePainting) {
    painter->beginNativePainting();
  }

  m_renderer->paint(QMatrix4x4(painter->combinedTransform()), painter->viewport());

  if (needsNativePainting) {
    painter->endNativePainting();
  }
}

VideoPlayer::State VideoPlayer::state() const {
  return m_state;
}

bool VideoPlayer::setPaused(int flags) {
  g_object_set (m_bin, "flags", flags, NULL);

  if (gst_element_set_state(m_bin, GST_STATE_PAUSED) == GST_STATE_CHANGE_FAILURE) {
    qmlInfo(this) << "error setting pipeline to PAUSED";
    return false;
  }

  GstBus *bus = gst_element_get_bus(m_bin);
  GstMessage *message =
    gst_bus_timed_pop_filtered(bus, GST_CLOCK_TIME_NONE,
			       (GstMessageType)(GST_MESSAGE_ASYNC_DONE | GST_MESSAGE_ERROR));

  if (GST_MESSAGE_TYPE(message) == GST_MESSAGE_ERROR) {
    gst_message_unref (message);
    gst_object_unref(bus);
    gst_element_set_state(m_bin, GST_STATE_NULL);
    return false;
  }

  gst_message_unref (message);
  gst_object_unref(bus);
  return true;
}

bool VideoPlayer::setState(const VideoPlayer::State& state) {
  if (state == m_state) {
    return true;
  }

  if (!m_bin) {
    qmlInfo(this) << "no playbin2";
    return false;
  }

  if (state == VideoPlayer::StatePaused) {
    m_timer->stop();

    if (gst_element_set_state(m_bin, GST_STATE_PAUSED) == GST_STATE_CHANGE_FAILURE) {
      qmlInfo(this) << "error setting pipeline to PAUSED";
      return false;
    }

    GstState st;
    if (gst_element_get_state(m_bin, &st, NULL, GST_CLOCK_TIME_NONE)
	== GST_STATE_CHANGE_FAILURE) {
      qmlInfo(this) << "setting pipeline to PAUSED failed";
      return false;
    }

    if (st != GST_STATE_PAUSED) {
      qmlInfo(this) << "pipeline failed to transition to to PAUSED state";
      return false;
    }

    m_state = state;
    emit stateChanged();

    return true;
  }
  else if (state == VideoPlayer::StatePlaying) {
    // Set uri if needed:
    if (m_state == VideoPlayer::StateStopped) {
      QString string = m_url.toString();
      QByteArray array = string.toUtf8();
      g_object_set(m_bin, "uri", array.constData(), NULL);
    }

    if (!setPaused (0x00000001 | 0x00000002 | 0x00000010 | 0x00000020 |  0x00000200)) {

      if (!setPaused (0x00000001 | 0x00000002 | 0x00000010 | 0x00000020 |  0x00000200 | 0x00000040)) {
	qmlInfo(this) << "error setting pipeline to PAUSED";
	return false;
      }

    }

    if (gst_element_set_state(m_bin, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) {
      qmlInfo(this) << "error setting pipeline to PLAYING";
      return false;
    }

    m_state = state;
    emit stateChanged();

    emit durationChanged();
    emit positionChanged();

    m_timer->start();
    return true;
  }
  else {
    m_timer->stop();
    m_pos = 0;

    delete m_renderer;
    m_renderer = 0;

    if (gst_element_set_state(m_bin, GST_STATE_NULL) == GST_STATE_CHANGE_FAILURE) {
      qmlInfo(this) << "error setting pipeline to NULL";
      return false;
    }

    GstState st;
    if (gst_element_get_state(m_bin, &st, NULL, GST_CLOCK_TIME_NONE)
	== GST_STATE_CHANGE_FAILURE) {
      qmlInfo(this) << "setting pipeline to NULL failed";
      return false;
    }

    if (st != GST_STATE_NULL) {
      qmlInfo(this) << "pipeline failed to transition to to NULL state";
      return false;
    }

    m_state = state;
    emit stateChanged();

    emit durationChanged();
    emit positionChanged();

    return true;
  }
}

gboolean VideoPlayer::bus_call(GstBus *bus, GstMessage *msg, gpointer data) {
  Q_UNUSED(bus);

  VideoPlayer *that = (VideoPlayer *) data;

  gchar *debug = NULL;
  GError *err = NULL;

  switch (GST_MESSAGE_TYPE(msg)) {
  case GST_MESSAGE_EOS:
    that->stop();
    break;

  case GST_MESSAGE_ERROR:
    gst_message_parse_error (msg, &err, &debug);

    emit that->error(err->message, err->code, debug);
    that->stop();
    qWarning() << "Error" << err->message;
    if (err) {
      g_error_free (err);
    }

    if (debug) {
      g_free (debug);
    }

    break;

  default:
    break;
  }

  return TRUE;
}

void VideoPlayer::updateRequested() {
  update();
}

quint32 VideoPlayer::volume() {
  double vol = 1.0;
  g_object_get (m_bin, "volume", &vol, NULL);

  qint32 res = (int)round(vol * 100.0);

  return res;
}

void VideoPlayer::setVolume(quint32 volume) {
  if (VideoPlayer::volume() != volume) {
    double vol = volume / 100.0;
    g_object_set (m_bin, "volume", vol, NULL);
    emit volumeChanged();
  }
}

void VideoPlayer::on_volume_changed(GObject *object, GParamSpec *pspec, gpointer user_data) {
  Q_UNUSED(object);
  Q_UNUSED(pspec);

  VideoPlayer *player = (VideoPlayer *) user_data;

  QMetaObject::invokeMethod(player, "volumeChanged", Qt::QueuedConnection);
}
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkGlobeSource.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/

/*-------------------------------------------------------------------------
  Copyright 2008 Sandia Corporation.
  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
  the U.S. Government retains certain rights in this software.
-------------------------------------------------------------------------*/

#include "vtkGlobeSource.h"

#include "vtkCellArray.h"
#include "vtkFloatArray.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkMath.h"
#include "vtkObjectFactory.h"
#include "vtkPointData.h"
#include "vtkPoints.h"
#include "vtkPolyData.h"
#include "vtkStreamingDemandDrivenPipeline.h"
#include "vtkGeoMath.h"
#include "vtkTimerLog.h"

#include <math.h>

vtkCxxRevisionMacro(vtkGlobeSource, "1.5");
vtkStandardNewMacro(vtkGlobeSource);

  // 0=NE, 1=SE, 2=SW, 3=NW

//----------------------------------------------------------------------------
vtkGlobeSource::vtkGlobeSource()
{
  this->Origin[0] = this->Origin[1] = this->Origin[2] = 0.0;
  this->Radius = 6356750.0; // Radius in meters.
  this->CurtainHeight = 1000.0;

  this->LongitudeResolution = 10;
  this->LatitudeResolution = 10;
  this->StartLongitude = 0.0;
  this->EndLongitude = 360.0;
  this->StartLatitude = 0.0;
  this->EndLatitude = 180.0;
  this->QuadrilateralTessellation = 0;

  this->SetNumberOfInputPorts(0);
}

//----------------------------------------------------------------------------
void vtkGlobeSource::ComputeGlobePoint(
  double theta, double phi, double radius, double* x, double* normal)
{
  double mynormal[3];

  double* n = normal ? normal : mynormal;

  // Lets keep this conversion code in a single place.
  double tmp;
  tmp = cos(phi*vtkMath::DegreesToRadians());
  n[0] = -tmp * sin(theta*vtkMath::DegreesToRadians());
  n[1] = tmp * cos(theta*vtkMath::DegreesToRadians());
  n[2] = sin(phi*vtkMath::DegreesToRadians());

  x[0] = n[0]*radius;
  x[1] = n[1]*radius;
  x[2] = n[2]*radius;
}

//----------------------------------------------------------------------------
void vtkGlobeSource::ComputeLatitudeLongitude(
  double* x, double& theta, double& phi)
{
  double rho = sqrt(x[0]*x[0] + x[1]*x[1] + x[2]*x[2]);
  double S = sqrt(x[0]*x[0] + x[1]*x[1]);
  phi = acos(x[2] / rho);
  if (x[0] >= 0)
    {
    theta = asin(x[1] / S);
    }
  else
    {
    theta = vtkMath::Pi() - asin(x[1] / S);
    }
  phi = (vtkMath::Pi()/2.0 - phi)*vtkMath::RadiansToDegrees();
  theta = (theta - vtkMath::Pi()/2.0)*vtkMath::RadiansToDegrees();
}

//----------------------------------------------------------------------------
void vtkGlobeSource::AddPoint(
  double theta, double phi, double radius,
  vtkPoints* newPoints, vtkFloatArray* newNormals,
  vtkFloatArray* newLongitudeArray, vtkFloatArray* newLatitudeArray)
{
  double x[3], n[3];

  vtkGlobeSource::ComputeGlobePoint(theta, phi, radius, x, n);

  x[0] -= this->Origin[0];
  x[1] -= this->Origin[1];
  x[2] -= this->Origin[2];

  newPoints->InsertNextPoint(x);
  newNormals->InsertNextTuple(n);

  newLongitudeArray->InsertNextValue(theta);
  newLatitudeArray->InsertNextValue(phi);
}

//----------------------------------------------------------------------------
int vtkGlobeSource::RequestData(
  vtkInformation *vtkNotUsed(request),
  vtkInformationVector **vtkNotUsed(inputVector),
  vtkInformationVector *outputVector)
{
  // get the info object
  vtkInformation *outInfo = outputVector->GetInformationObject(0);

  // I used this to see if the background thread was really
  // operating asynchronously.
  //Sleep(2000);

  // I am going to compute the curtain height based on the level of the
  // terrain patch.
  this->CurtainHeight = (this->EndLongitude-this->StartLongitude)
    * this->Radius / 3600.0;

  // get the ouptut
  vtkPolyData *output = vtkPolyData::SafeDownCast(
    outInfo->Get(vtkDataObject::DATA_OBJECT()));

  int i, j;
  int numPts, numPolys;
  vtkPoints *newPoints;
  vtkFloatArray *newLongitudeArray;
  vtkFloatArray *newLatitudeArray;
  vtkFloatArray *newNormals;
  vtkCellArray *newPolys;
  double phi, theta;
  vtkIdType pts[4];

  // Set things up; allocate memory
  //
  numPts = this->LatitudeResolution * this->LongitudeResolution;
  // creating triangles
  numPolys = (this->LatitudeResolution-1)*(this->LongitudeResolution-1) * 2;

  // Add more for curtains.
  numPts += 2*(this->LatitudeResolution + this->LongitudeResolution);

  newPoints = vtkPoints::New();
  newPoints->Allocate(numPts);
  newNormals = vtkFloatArray::New();
  newNormals->SetNumberOfComponents(3);
  newNormals->Allocate(3*numPts);
  newNormals->SetName("Normals");

  newLongitudeArray = vtkFloatArray::New();
  newLongitudeArray->SetNumberOfComponents(1);
  newLongitudeArray->Allocate(numPts);
  newLongitudeArray->SetName("Longitude");

  newLatitudeArray = vtkFloatArray::New();
  newLatitudeArray->SetNumberOfComponents(1);
  newLatitudeArray->Allocate(numPts);
  newLatitudeArray->SetName("Latitude");

  newPolys = vtkCellArray::New();
  newPolys->Allocate(newPolys->EstimateSize(numPolys, 3));

  // Create sphere
  //

  double deltaLongitude;
  double deltaLatitude;

  // Check data, determine increments, and convert to radians
  deltaLongitude = (this->EndLongitude - this->StartLongitude)
                 / static_cast<double>(this->LongitudeResolution-1);

  deltaLatitude = (this->EndLatitude - this->StartLatitude)
                 / static_cast<double>(this->LatitudeResolution-1);

  // Create points and point data.
  for (j=0; j<this->LatitudeResolution; j++)
    {
    phi = this->StartLatitude + j*deltaLatitude;
    for (i=0; i < this->LongitudeResolution; i++)
      {
      theta = this->StartLongitude + i*deltaLongitude;
      this->AddPoint(theta, phi, this->Radius,
                     newPoints, newNormals,
                     newLongitudeArray, newLatitudeArray);
      }
    this->UpdateProgress(
      0.10 + 0.50*j/static_cast<float>(this->LatitudeResolution));
    }

  // Create the extra points for the curtains.
  for (i=0; i < this->LongitudeResolution; i++)
    {
    theta = this->StartLongitude + i*deltaLongitude;
    phi = this->StartLatitude;
    this->AddPoint(theta, phi, this->Radius-this->CurtainHeight,
                   newPoints, newNormals,
                   newLongitudeArray, newLatitudeArray);
    }
  for (i=0; i < this->LongitudeResolution; i++)
    {
    theta = this->StartLongitude + i*deltaLongitude;
    phi = this->EndLatitude;
    this->AddPoint(theta, phi, this->Radius-this->CurtainHeight,
                   newPoints, newNormals,
                   newLongitudeArray, newLatitudeArray);
    }
  for (j=0; j < this->LatitudeResolution; j++)
    {
    theta = this->StartLongitude;
    phi = this->StartLatitude + j*deltaLatitude;
    this->AddPoint(theta, phi, this->Radius-this->CurtainHeight,
                   newPoints, newNormals,
                   newLongitudeArray, newLatitudeArray);
    }
  for (j=0; j < this->LatitudeResolution; j++)
    {
    theta = this->EndLongitude;
    phi = this->StartLatitude + j*deltaLatitude;
    this->AddPoint(theta, phi, this->Radius-this->CurtainHeight,
                   newPoints, newNormals,
                   newLongitudeArray, newLatitudeArray);
    }

  // Generate mesh connectivity
  vtkIdType rowId = 0;
  vtkIdType cornerId;
  for (j=1; j < this->LatitudeResolution; ++j)
    {
    cornerId = rowId;
    for (i=1; i < this->LongitudeResolution; ++i)
      {
      pts[0] = cornerId;
      pts[2] = cornerId + this->LongitudeResolution;
      pts[1] = pts[2] + 1;
      newPolys->InsertNextCell(3, pts);
      pts[2] = pts[1];
      pts[1] = cornerId + 1;
      newPolys->InsertNextCell(3, pts);
      ++cornerId;
      }
    rowId += this->LongitudeResolution;
    this->UpdateProgress(
      0.70 + 0.30*j/static_cast<double>(this->LatitudeResolution));
    }

  // Create curtain quads.
  vtkIdType curtainPointId =
    this->LongitudeResolution * this->LatitudeResolution;
  vtkIdType edgeOffset;
  edgeOffset = 0;
  for (i=1; i < this->LongitudeResolution; ++i)
    {
    pts[0] = edgeOffset + i; // i starts at 1.
    pts[1] = pts[0] - 1;
    pts[2] = curtainPointId;
    pts[3] = curtainPointId + 1;
    newPolys->InsertNextCell(4, pts);
    ++curtainPointId;
    }
  ++curtainPointId; // Skip 2 to the next edge.
  edgeOffset = (this->LongitudeResolution)*(this->LatitudeResolution-1);
  for (i=1; i < this->LongitudeResolution; ++i)
    {
    pts[0] = edgeOffset + i - 1; // i starts at 1
    pts[1] = pts[0] + 1;
    pts[2] = curtainPointId + 1;
    pts[3] = curtainPointId;
    newPolys->InsertNextCell(4, pts);
    ++curtainPointId;
    }
  ++curtainPointId;
  edgeOffset = 0;
  for (j=1; j < this->LatitudeResolution; ++j)
    {
    pts[0] = edgeOffset + j*this->LongitudeResolution;
    pts[1] = pts[0] - this->LongitudeResolution;
    pts[2] = curtainPointId;
    pts[3] = curtainPointId + 1;
    newPolys->InsertNextCell(4, pts);
    ++curtainPointId;
    }
  ++curtainPointId;
  edgeOffset = (this->LongitudeResolution-1);
  for (j=1; j < this->LatitudeResolution; ++j)
    {
    pts[0] = edgeOffset + (j-1)*this->LongitudeResolution;
    pts[1] = pts[0] + this->LongitudeResolution;
    pts[2] = curtainPointId + 1;
    pts[3] = curtainPointId;
    newPolys->InsertNextCell(4, pts);
    ++curtainPointId;
    }

  // Update ourselves and release memeory
  //
  newPoints->Squeeze();
  output->SetPoints(newPoints);
  newPoints->Delete();

  newNormals->Squeeze();
  output->GetPointData()->SetNormals(newNormals);
  newNormals->Delete();

  newLongitudeArray->Squeeze();
  output->GetPointData()->AddArray(newLongitudeArray);
  newLongitudeArray->Delete();

  newLatitudeArray->Squeeze();
  output->GetPointData()->AddArray(newLatitudeArray);
  newLatitudeArray->Delete();

  newPolys->Squeeze();
  output->SetPolys(newPolys);
  newPolys->Delete();

  return 1;
}

//----------------------------------------------------------------------------
int vtkGlobeSource::RequestInformation(
  vtkInformation *vtkNotUsed(request),
  vtkInformationVector **vtkNotUsed(inputVector),
  vtkInformationVector *outputVector)
{
  // get the info object
  vtkInformation *outInfo = outputVector->GetInformationObject(0);

  outInfo->Set(vtkStreamingDemandDrivenPipeline::MAXIMUM_NUMBER_OF_PIECES(),
               -1);

  outInfo->Set(vtkStreamingDemandDrivenPipeline::WHOLE_BOUNDING_BOX(),
               -this->Radius, this->Radius,
               -this->Radius, this->Radius,
               -this->Radius, this->Radius);

  return 1;
}

//----------------------------------------------------------------------------
void vtkGlobeSource::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);

  os << indent << "CurtainHeight: " << this->CurtainHeight << "\n";
  os << indent << "Longitude Resolution: " << this->LongitudeResolution << "\n";
  os << indent << "Latitude Resolution: " << this->LatitudeResolution << "\n";
  os << indent << "Longitude Start: " << this->StartLongitude << "\n";
  os << indent << "Latitude Start: " << this->StartLatitude << "\n";
  os << indent << "Longitude End: " << this->EndLongitude << "\n";
  os << indent << "Latitude End: " << this->EndLatitude << "\n";
  os << indent << "Radius: " << this->Radius << "\n";
  os << indent << "Origin: " << this->Origin << "\n";
  os << indent
     << "Quadrilateral Tessellation: "
     << this->QuadrilateralTessellation << "\n";
}
<commit_msg>COMP: Fix AIX error by printing origin components, not the pointer.<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkGlobeSource.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/

/*-------------------------------------------------------------------------
  Copyright 2008 Sandia Corporation.
  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
  the U.S. Government retains certain rights in this software.
-------------------------------------------------------------------------*/

#include "vtkGlobeSource.h"

#include "vtkCellArray.h"
#include "vtkFloatArray.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkMath.h"
#include "vtkObjectFactory.h"
#include "vtkPointData.h"
#include "vtkPoints.h"
#include "vtkPolyData.h"
#include "vtkStreamingDemandDrivenPipeline.h"
#include "vtkGeoMath.h"
#include "vtkTimerLog.h"

#include <math.h>

vtkCxxRevisionMacro(vtkGlobeSource, "1.6");
vtkStandardNewMacro(vtkGlobeSource);

  // 0=NE, 1=SE, 2=SW, 3=NW

//----------------------------------------------------------------------------
vtkGlobeSource::vtkGlobeSource()
{
  this->Origin[0] = this->Origin[1] = this->Origin[2] = 0.0;
  this->Radius = 6356750.0; // Radius in meters.
  this->CurtainHeight = 1000.0;

  this->LongitudeResolution = 10;
  this->LatitudeResolution = 10;
  this->StartLongitude = 0.0;
  this->EndLongitude = 360.0;
  this->StartLatitude = 0.0;
  this->EndLatitude = 180.0;
  this->QuadrilateralTessellation = 0;

  this->SetNumberOfInputPorts(0);
}

//----------------------------------------------------------------------------
void vtkGlobeSource::ComputeGlobePoint(
  double theta, double phi, double radius, double* x, double* normal)
{
  double mynormal[3];

  double* n = normal ? normal : mynormal;

  // Lets keep this conversion code in a single place.
  double tmp;
  tmp = cos(phi*vtkMath::DegreesToRadians());
  n[0] = -tmp * sin(theta*vtkMath::DegreesToRadians());
  n[1] = tmp * cos(theta*vtkMath::DegreesToRadians());
  n[2] = sin(phi*vtkMath::DegreesToRadians());

  x[0] = n[0]*radius;
  x[1] = n[1]*radius;
  x[2] = n[2]*radius;
}

//----------------------------------------------------------------------------
void vtkGlobeSource::ComputeLatitudeLongitude(
  double* x, double& theta, double& phi)
{
  double rho = sqrt(x[0]*x[0] + x[1]*x[1] + x[2]*x[2]);
  double S = sqrt(x[0]*x[0] + x[1]*x[1]);
  phi = acos(x[2] / rho);
  if (x[0] >= 0)
    {
    theta = asin(x[1] / S);
    }
  else
    {
    theta = vtkMath::Pi() - asin(x[1] / S);
    }
  phi = (vtkMath::Pi()/2.0 - phi)*vtkMath::RadiansToDegrees();
  theta = (theta - vtkMath::Pi()/2.0)*vtkMath::RadiansToDegrees();
}

//----------------------------------------------------------------------------
void vtkGlobeSource::AddPoint(
  double theta, double phi, double radius,
  vtkPoints* newPoints, vtkFloatArray* newNormals,
  vtkFloatArray* newLongitudeArray, vtkFloatArray* newLatitudeArray)
{
  double x[3], n[3];

  vtkGlobeSource::ComputeGlobePoint(theta, phi, radius, x, n);

  x[0] -= this->Origin[0];
  x[1] -= this->Origin[1];
  x[2] -= this->Origin[2];

  newPoints->InsertNextPoint(x);
  newNormals->InsertNextTuple(n);

  newLongitudeArray->InsertNextValue(theta);
  newLatitudeArray->InsertNextValue(phi);
}

//----------------------------------------------------------------------------
int vtkGlobeSource::RequestData(
  vtkInformation *vtkNotUsed(request),
  vtkInformationVector **vtkNotUsed(inputVector),
  vtkInformationVector *outputVector)
{
  // get the info object
  vtkInformation *outInfo = outputVector->GetInformationObject(0);

  // I used this to see if the background thread was really
  // operating asynchronously.
  //Sleep(2000);

  // I am going to compute the curtain height based on the level of the
  // terrain patch.
  this->CurtainHeight = (this->EndLongitude-this->StartLongitude)
    * this->Radius / 3600.0;

  // get the ouptut
  vtkPolyData *output = vtkPolyData::SafeDownCast(
    outInfo->Get(vtkDataObject::DATA_OBJECT()));

  int i, j;
  int numPts, numPolys;
  vtkPoints *newPoints;
  vtkFloatArray *newLongitudeArray;
  vtkFloatArray *newLatitudeArray;
  vtkFloatArray *newNormals;
  vtkCellArray *newPolys;
  double phi, theta;
  vtkIdType pts[4];

  // Set things up; allocate memory
  //
  numPts = this->LatitudeResolution * this->LongitudeResolution;
  // creating triangles
  numPolys = (this->LatitudeResolution-1)*(this->LongitudeResolution-1) * 2;

  // Add more for curtains.
  numPts += 2*(this->LatitudeResolution + this->LongitudeResolution);

  newPoints = vtkPoints::New();
  newPoints->Allocate(numPts);
  newNormals = vtkFloatArray::New();
  newNormals->SetNumberOfComponents(3);
  newNormals->Allocate(3*numPts);
  newNormals->SetName("Normals");

  newLongitudeArray = vtkFloatArray::New();
  newLongitudeArray->SetNumberOfComponents(1);
  newLongitudeArray->Allocate(numPts);
  newLongitudeArray->SetName("Longitude");

  newLatitudeArray = vtkFloatArray::New();
  newLatitudeArray->SetNumberOfComponents(1);
  newLatitudeArray->Allocate(numPts);
  newLatitudeArray->SetName("Latitude");

  newPolys = vtkCellArray::New();
  newPolys->Allocate(newPolys->EstimateSize(numPolys, 3));

  // Create sphere
  //

  double deltaLongitude;
  double deltaLatitude;

  // Check data, determine increments, and convert to radians
  deltaLongitude = (this->EndLongitude - this->StartLongitude)
                 / static_cast<double>(this->LongitudeResolution-1);

  deltaLatitude = (this->EndLatitude - this->StartLatitude)
                 / static_cast<double>(this->LatitudeResolution-1);

  // Create points and point data.
  for (j=0; j<this->LatitudeResolution; j++)
    {
    phi = this->StartLatitude + j*deltaLatitude;
    for (i=0; i < this->LongitudeResolution; i++)
      {
      theta = this->StartLongitude + i*deltaLongitude;
      this->AddPoint(theta, phi, this->Radius,
                     newPoints, newNormals,
                     newLongitudeArray, newLatitudeArray);
      }
    this->UpdateProgress(
      0.10 + 0.50*j/static_cast<float>(this->LatitudeResolution));
    }

  // Create the extra points for the curtains.
  for (i=0; i < this->LongitudeResolution; i++)
    {
    theta = this->StartLongitude + i*deltaLongitude;
    phi = this->StartLatitude;
    this->AddPoint(theta, phi, this->Radius-this->CurtainHeight,
                   newPoints, newNormals,
                   newLongitudeArray, newLatitudeArray);
    }
  for (i=0; i < this->LongitudeResolution; i++)
    {
    theta = this->StartLongitude + i*deltaLongitude;
    phi = this->EndLatitude;
    this->AddPoint(theta, phi, this->Radius-this->CurtainHeight,
                   newPoints, newNormals,
                   newLongitudeArray, newLatitudeArray);
    }
  for (j=0; j < this->LatitudeResolution; j++)
    {
    theta = this->StartLongitude;
    phi = this->StartLatitude + j*deltaLatitude;
    this->AddPoint(theta, phi, this->Radius-this->CurtainHeight,
                   newPoints, newNormals,
                   newLongitudeArray, newLatitudeArray);
    }
  for (j=0; j < this->LatitudeResolution; j++)
    {
    theta = this->EndLongitude;
    phi = this->StartLatitude + j*deltaLatitude;
    this->AddPoint(theta, phi, this->Radius-this->CurtainHeight,
                   newPoints, newNormals,
                   newLongitudeArray, newLatitudeArray);
    }

  // Generate mesh connectivity
  vtkIdType rowId = 0;
  vtkIdType cornerId;
  for (j=1; j < this->LatitudeResolution; ++j)
    {
    cornerId = rowId;
    for (i=1; i < this->LongitudeResolution; ++i)
      {
      pts[0] = cornerId;
      pts[2] = cornerId + this->LongitudeResolution;
      pts[1] = pts[2] + 1;
      newPolys->InsertNextCell(3, pts);
      pts[2] = pts[1];
      pts[1] = cornerId + 1;
      newPolys->InsertNextCell(3, pts);
      ++cornerId;
      }
    rowId += this->LongitudeResolution;
    this->UpdateProgress(
      0.70 + 0.30*j/static_cast<double>(this->LatitudeResolution));
    }

  // Create curtain quads.
  vtkIdType curtainPointId =
    this->LongitudeResolution * this->LatitudeResolution;
  vtkIdType edgeOffset;
  edgeOffset = 0;
  for (i=1; i < this->LongitudeResolution; ++i)
    {
    pts[0] = edgeOffset + i; // i starts at 1.
    pts[1] = pts[0] - 1;
    pts[2] = curtainPointId;
    pts[3] = curtainPointId + 1;
    newPolys->InsertNextCell(4, pts);
    ++curtainPointId;
    }
  ++curtainPointId; // Skip 2 to the next edge.
  edgeOffset = (this->LongitudeResolution)*(this->LatitudeResolution-1);
  for (i=1; i < this->LongitudeResolution; ++i)
    {
    pts[0] = edgeOffset + i - 1; // i starts at 1
    pts[1] = pts[0] + 1;
    pts[2] = curtainPointId + 1;
    pts[3] = curtainPointId;
    newPolys->InsertNextCell(4, pts);
    ++curtainPointId;
    }
  ++curtainPointId;
  edgeOffset = 0;
  for (j=1; j < this->LatitudeResolution; ++j)
    {
    pts[0] = edgeOffset + j*this->LongitudeResolution;
    pts[1] = pts[0] - this->LongitudeResolution;
    pts[2] = curtainPointId;
    pts[3] = curtainPointId + 1;
    newPolys->InsertNextCell(4, pts);
    ++curtainPointId;
    }
  ++curtainPointId;
  edgeOffset = (this->LongitudeResolution-1);
  for (j=1; j < this->LatitudeResolution; ++j)
    {
    pts[0] = edgeOffset + (j-1)*this->LongitudeResolution;
    pts[1] = pts[0] + this->LongitudeResolution;
    pts[2] = curtainPointId + 1;
    pts[3] = curtainPointId;
    newPolys->InsertNextCell(4, pts);
    ++curtainPointId;
    }

  // Update ourselves and release memeory
  //
  newPoints->Squeeze();
  output->SetPoints(newPoints);
  newPoints->Delete();

  newNormals->Squeeze();
  output->GetPointData()->SetNormals(newNormals);
  newNormals->Delete();

  newLongitudeArray->Squeeze();
  output->GetPointData()->AddArray(newLongitudeArray);
  newLongitudeArray->Delete();

  newLatitudeArray->Squeeze();
  output->GetPointData()->AddArray(newLatitudeArray);
  newLatitudeArray->Delete();

  newPolys->Squeeze();
  output->SetPolys(newPolys);
  newPolys->Delete();

  return 1;
}

//----------------------------------------------------------------------------
int vtkGlobeSource::RequestInformation(
  vtkInformation *vtkNotUsed(request),
  vtkInformationVector **vtkNotUsed(inputVector),
  vtkInformationVector *outputVector)
{
  // get the info object
  vtkInformation *outInfo = outputVector->GetInformationObject(0);

  outInfo->Set(vtkStreamingDemandDrivenPipeline::MAXIMUM_NUMBER_OF_PIECES(),
               -1);

  outInfo->Set(vtkStreamingDemandDrivenPipeline::WHOLE_BOUNDING_BOX(),
               -this->Radius, this->Radius,
               -this->Radius, this->Radius,
               -this->Radius, this->Radius);

  return 1;
}

//----------------------------------------------------------------------------
void vtkGlobeSource::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);

  os << indent << "CurtainHeight: " << this->CurtainHeight << "\n";
  os << indent << "Longitude Resolution: " << this->LongitudeResolution << "\n";
  os << indent << "Latitude Resolution: " << this->LatitudeResolution << "\n";
  os << indent << "Longitude Start: " << this->StartLongitude << "\n";
  os << indent << "Latitude Start: " << this->StartLatitude << "\n";
  os << indent << "Longitude End: " << this->EndLongitude << "\n";
  os << indent << "Latitude End: " << this->EndLatitude << "\n";
  os << indent << "Radius: " << this->Radius << "\n";
  os << indent << "Origin: " << this->Origin[0] << ","
                             << this->Origin[1] << ","
                             << this->Origin[2] << "\n";
  os << indent
     << "Quadrilateral Tessellation: "
     << this->QuadrilateralTessellation << "\n";
}
<|endoftext|>


<commit_before>#include "iopin.h"

#include "schedulerbase.h" //for SchedulerBase::registerExitHandler
#include "common/logging.h"

namespace drv {

std::set<IoPin*> IoPin::livingPins; //allocate storage for static variables.
IoPin::null IoPin::null::_null;

void IoPin::deactivateAll() {
    LOG("IoPin::deactivateAll()\n");
    for (auto p : livingPins) {
        p->setToDefault();
    }
}

void IoPin::registerExitHandler() {
    //install exit handler to leave pins in a safe state post-execution.
    LOG("IoPin::registerExitHandler()\n");
    static bool doOnce(SchedulerBase::registerExitHandler((void(*)())&deactivateAll, SCHED_IO_EXIT_LEVEL));
    (void)doOnce; //destroy 'unused' warning
}

IoPin::~IoPin() {
    setToDefault();
    livingPins.erase(this);
}

//move constructor:
IoPin::IoPin(IoPin &&other) : _pin(PrimitiveIoPin::null()) {
	*this = std::move(other);
}

IoPin& IoPin::operator=(IoPin &&other) {
	_invertReads = other._invertReads;
    _invertWrites = other._invertWrites;
    _defaultState = other._defaultState;
	_pin = other._pin;
	other._pin = IoPin::null::ref()._pin;
	livingPins.insert(this);
    livingPins.erase(&other);
    return *this;
}

}<commit_msg>less logging<commit_after>#include "iopin.h"

#include "schedulerbase.h" //for SchedulerBase::registerExitHandler
#include "common/logging.h"

namespace drv {

std::set<IoPin*> IoPin::livingPins; //allocate storage for static variables.
IoPin::null IoPin::null::_null;

void IoPin::deactivateAll() {
    LOG("IoPin::deactivateAll()\n");
    for (auto p : livingPins) {
        p->setToDefault();
    }
}

void IoPin::registerExitHandler() {
    //install exit handler to leave pins in a safe state post-execution.
    static bool doOnce(SchedulerBase::registerExitHandler((void(*)())&deactivateAll, SCHED_IO_EXIT_LEVEL));
    (void)doOnce; //destroy 'unused' warning
}

IoPin::~IoPin() {
    setToDefault();
    livingPins.erase(this);
}

//move constructor:
IoPin::IoPin(IoPin &&other) : _pin(PrimitiveIoPin::null()) {
	*this = std::move(other);
}

IoPin& IoPin::operator=(IoPin &&other) {
	_invertReads = other._invertReads;
    _invertWrites = other._invertWrites;
    _defaultState = other._defaultState;
	_pin = other._pin;
	other._pin = IoPin::null::ref()._pin;
	livingPins.insert(this);
    livingPins.erase(&other);
    return *this;
}

}<|endoftext|>


<commit_before>#include "Mp3Player.hpp"
#include <wait.h>
#include <iostream>
#include <algorithm>
#include <boost/algorithm/string/trim.hpp>
#include <boost/bind.hpp>
#include <boost/asio.hpp>
#include <boost/filesystem.hpp>
#include <boost/date_time/posix_time/posix_time_duration.hpp>

using std::ostringstream;
using std::istringstream;
using std::string;
using std::endl;
using std::getline;
using std::vector;
using std::remove_if;
using std::cout;
using boost::bind;
using boost::algorithm::trim_copy;
using boost::optional;
using boost::asio::io_service;
using boost::asio::async_read_until;
using boost::asio::deadline_timer;
using boost::asio::buffer;
using boost::asio::placeholders::error;
using boost::asio::placeholders::bytes_transferred;
using boost::filesystem::path;
using boost::posix_time::milliseconds;
using boost::system::error_code;

Mp3Player::Mp3Player(const std::string& executable,
        io_service& ioService)
: _waitForId3TagsTimer (ioService)
, _mpg123Program (executable, vector<string>{"-R"}, ioService)
, _in (_mpg123Program.in())
, _out(_mpg123Program.out())
, _err(_mpg123Program.err()) {
    bindHandleInputMethod();
}
void Mp3Player::addListener (IListener* listener) {
    _listeners.push_back(listener);
}
void Mp3Player::removeListener (IListener* listener) {
    remove_if (_listeners.begin(), _listeners.end(),
            [listener](IListener* l){return l==listener;});
}
void Mp3Player::load(const path& mp3File) {
    ostringstream oss;
    oss << "LOAD " << mp3File.string() << endl;
    string command = oss.str();
    _in.write_some (buffer(command.c_str(), command.size()));
}
void Mp3Player::pause() {
    static const string command = "PAUSE\n";
    _in.write_some (buffer(command.c_str(), command.size()));
}
void Mp3Player::jumpToBegin() {
    static const string command = "JUMP 0\n";
    _in.write_some (buffer(command.c_str(), command.size()));
}
void Mp3Player::jumpTo(int frameCount) {
    ostringstream command;
    command << "JUMP " << frameCount << endl;
    _in.write_some (buffer(command.str().c_str(), command.str().size()));
}
void Mp3Player::jumpBackward (int frames) {
    ostringstream command;
    command << "JUMP -" << frames << endl;
    _in.write_some (buffer(command.str().c_str(), command.str().size()));
}
void Mp3Player::jumpForward (int frames) {
    ostringstream command;
    command << "JUMP +" << frames << endl;
    _in.write_some (buffer(command.str().c_str(), command.str().size()));
}
void Mp3Player::bindHandleInputMethod() {
    async_read_until(_out, _inputBuffer, '\n',
            bind(&Mp3Player::handleReadInput, this, error,
            bytes_transferred));
}
void Mp3Player::handleReadInput(const error_code& error, size_t length) {
    if (!error) {
        boost::asio::streambuf::const_buffers_type bufs = _inputBuffer.data();
        string input (boost::asio::buffers_begin(bufs),
                boost::asio::buffers_end(bufs));
        _inputBuffer.consume(_inputBuffer.size());
        istringstream issInput (input);
        vector<string> messages;
        string line;
        while (getline (issInput, line, '\n')) {
            messages.push_back(line);
        }
        for (string message : messages) {
            size_t messagePos = string::npos;
            if (message.length() < 3) {
                continue;
            }
            if (messagePos = message.find(string ("@F")) != string::npos) {
                istringstream iss (message.substr(messagePos+2));
                int framecount;
                int framesLeft;
                float seconds;
                float secondsLeft;
                iss >> framecount;
                iss >> framesLeft;
                iss >> seconds;
                iss >> secondsLeft;
                for (auto l : _listeners) {
                    l->playStatus(framecount, framesLeft, seconds, secondsLeft);
                }
            } else if (messagePos = message.find(string ("@P")) != string::npos) {
                istringstream iss (message.substr(messagePos+2));
                int playingStatusCode = 0;
                string reason;
                iss >> playingStatusCode;
                iss >> reason;
                switch (playingStatusCode) {
                    case 0:
                        if (reason == "EOF") {
                            for (auto l : _listeners) {
                                l->playingStopped(true);
                            }
                        } else {
                            for (auto l : _listeners) {
                                l->playingStopped(false);
                            }
                        }
                        break;
                    case 1:
                        for (auto l : _listeners) {
                            l->playingPaused();
                        }
                        break;
                    case 2:
                        for (auto l : _listeners) {
                            l->playingUnpaused();
                        }
                        break;
                }
            } else if (messagePos = message.find(string ("@I")) != string::npos) {
                if (!_id3TagParser.isParsingStarted()) {
                    // After the first status message has been received give
                    // mpg123 200 milliseconds to send the rest of ID3 tags...
                    _waitForId3TagsTimer.expires_from_now (milliseconds(200));
                    _waitForId3TagsTimer.async_wait(bind(
                            &Mp3Player::handleStatusMessages, this, error));
                }
                _id3TagParser.parse(message.substr(messagePos+2));
            } else if (messagePos = message.find(string ("@R")) != string::npos) {
                istringstream iss (message.substr(messagePos+2));
                string mpg123;
                string version;
                iss >> mpg123;
                iss >> version;
                for (auto l : _listeners) {
                    l->mpg123Version(version);
                }
            } else if (messagePos = message.find(string ("@E")) != string::npos) {
                istringstream iss (message.substr(messagePos+2));
                string errorMessage;
                iss >> errorMessage;
                for (auto l : _listeners) {
                    l->playingErrorOccurred(errorMessage);
                }
            } else if (messagePos = message.find(string ("@S")) != string::npos) {
                istringstream iss (message.substr(messagePos+2));
            }
        }
        bindHandleInputMethod();
    } else {
        if (error == boost::asio::error::misc_errors::eof) {
            int returnStatus;
            waitpid(_mpg123Program.pid(), &returnStatus, 0);
            for (auto l : _listeners) {
                l->mpg123Terminated(returnStatus);
            }
        } else {
            for (auto l : _listeners) {
                l->mpg123CommunicationProblem(error);
            }
        }
    }
}
void Mp3Player::handleStatusMessages(const error_code& error) {
    if (!error) {
        Mp3Title mp3Title = _id3TagParser.getMp3Title();
        for (auto l : _listeners) {
            l->titleLoaded(mp3Title);
        }
        // Reset the tag parser by a clean one.
        _id3TagParser = Id3TagParser();
    }
}
<commit_msg>FixID #8: Now playing always mono.<commit_after>#include "Mp3Player.hpp"
#include <wait.h>
#include <iostream>
#include <algorithm>
#include <boost/algorithm/string/trim.hpp>
#include <boost/bind.hpp>
#include <boost/asio.hpp>
#include <boost/filesystem.hpp>
#include <boost/date_time/posix_time/posix_time_duration.hpp>

using std::ostringstream;
using std::istringstream;
using std::string;
using std::endl;
using std::getline;
using std::vector;
using std::remove_if;
using std::cout;
using boost::bind;
using boost::algorithm::trim_copy;
using boost::optional;
using boost::asio::io_service;
using boost::asio::async_read_until;
using boost::asio::deadline_timer;
using boost::asio::buffer;
using boost::asio::placeholders::error;
using boost::asio::placeholders::bytes_transferred;
using boost::filesystem::path;
using boost::posix_time::milliseconds;
using boost::system::error_code;

Mp3Player::Mp3Player(const std::string& executable,
        io_service& ioService)
: _waitForId3TagsTimer (ioService)
, _mpg123Program (executable, vector<string>{"-m", "-R"}, ioService)
, _in (_mpg123Program.in())
, _out(_mpg123Program.out())
, _err(_mpg123Program.err()) {
    bindHandleInputMethod();
}
void Mp3Player::addListener (IListener* listener) {
    _listeners.push_back(listener);
}
void Mp3Player::removeListener (IListener* listener) {
    remove_if (_listeners.begin(), _listeners.end(),
            [listener](IListener* l){return l==listener;});
}
void Mp3Player::load(const path& mp3File) {
    ostringstream oss;
    oss << "LOAD " << mp3File.string() << endl;
    string command = oss.str();
    _in.write_some (buffer(command.c_str(), command.size()));
}
void Mp3Player::pause() {
    static const string command = "PAUSE\n";
    _in.write_some (buffer(command.c_str(), command.size()));
}
void Mp3Player::jumpToBegin() {
    static const string command = "JUMP 0\n";
    _in.write_some (buffer(command.c_str(), command.size()));
}
void Mp3Player::jumpTo(int frameCount) {
    ostringstream command;
    command << "JUMP " << frameCount << endl;
    _in.write_some (buffer(command.str().c_str(), command.str().size()));
}
void Mp3Player::jumpBackward (int frames) {
    ostringstream command;
    command << "JUMP -" << frames << endl;
    _in.write_some (buffer(command.str().c_str(), command.str().size()));
}
void Mp3Player::jumpForward (int frames) {
    ostringstream command;
    command << "JUMP +" << frames << endl;
    _in.write_some (buffer(command.str().c_str(), command.str().size()));
}
void Mp3Player::bindHandleInputMethod() {
    async_read_until(_out, _inputBuffer, '\n',
            bind(&Mp3Player::handleReadInput, this, error,
            bytes_transferred));
}
void Mp3Player::handleReadInput(const error_code& error, size_t length) {
    if (!error) {
        boost::asio::streambuf::const_buffers_type bufs = _inputBuffer.data();
        string input (boost::asio::buffers_begin(bufs),
                boost::asio::buffers_end(bufs));
        _inputBuffer.consume(_inputBuffer.size());
        istringstream issInput (input);
        vector<string> messages;
        string line;
        while (getline (issInput, line, '\n')) {
            messages.push_back(line);
        }
        for (string message : messages) {
            size_t messagePos = string::npos;
            if (message.length() < 3) {
                continue;
            }
            if (messagePos = message.find(string ("@F")) != string::npos) {
                istringstream iss (message.substr(messagePos+2));
                int framecount;
                int framesLeft;
                float seconds;
                float secondsLeft;
                iss >> framecount;
                iss >> framesLeft;
                iss >> seconds;
                iss >> secondsLeft;
                for (auto l : _listeners) {
                    l->playStatus(framecount, framesLeft, seconds, secondsLeft);
                }
            } else if (messagePos = message.find(string ("@P")) != string::npos) {
                istringstream iss (message.substr(messagePos+2));
                int playingStatusCode = 0;
                string reason;
                iss >> playingStatusCode;
                iss >> reason;
                switch (playingStatusCode) {
                    case 0:
                        if (reason == "EOF") {
                            for (auto l : _listeners) {
                                l->playingStopped(true);
                            }
                        } else {
                            for (auto l : _listeners) {
                                l->playingStopped(false);
                            }
                        }
                        break;
                    case 1:
                        for (auto l : _listeners) {
                            l->playingPaused();
                        }
                        break;
                    case 2:
                        for (auto l : _listeners) {
                            l->playingUnpaused();
                        }
                        break;
                }
            } else if (messagePos = message.find(string ("@I")) != string::npos) {
                if (!_id3TagParser.isParsingStarted()) {
                    // After the first status message has been received give
                    // mpg123 200 milliseconds to send the rest of ID3 tags...
                    _waitForId3TagsTimer.expires_from_now (milliseconds(200));
                    _waitForId3TagsTimer.async_wait(bind(
                            &Mp3Player::handleStatusMessages, this, error));
                }
                _id3TagParser.parse(message.substr(messagePos+2));
            } else if (messagePos = message.find(string ("@R")) != string::npos) {
                istringstream iss (message.substr(messagePos+2));
                string mpg123;
                string version;
                iss >> mpg123;
                iss >> version;
                for (auto l : _listeners) {
                    l->mpg123Version(version);
                }
            } else if (messagePos = message.find(string ("@E")) != string::npos) {
                istringstream iss (message.substr(messagePos+2));
                string errorMessage;
                iss >> errorMessage;
                for (auto l : _listeners) {
                    l->playingErrorOccurred(errorMessage);
                }
            } else if (messagePos = message.find(string ("@S")) != string::npos) {
                istringstream iss (message.substr(messagePos+2));
            }
        }
        bindHandleInputMethod();
    } else {
        if (error == boost::asio::error::misc_errors::eof) {
            int returnStatus;
            waitpid(_mpg123Program.pid(), &returnStatus, 0);
            for (auto l : _listeners) {
                l->mpg123Terminated(returnStatus);
            }
        } else {
            for (auto l : _listeners) {
                l->mpg123CommunicationProblem(error);
            }
        }
    }
}
void Mp3Player::handleStatusMessages(const error_code& error) {
    if (!error) {
        Mp3Title mp3Title = _id3TagParser.getMp3Title();
        for (auto l : _listeners) {
            l->titleLoaded(mp3Title);
        }
        // Reset the tag parser by a clean one.
        _id3TagParser = Id3TagParser();
    }
}
<|endoftext|>


<commit_before>#include "Halide.h"
#include <stdio.h>

using namespace Halide;

int main(int argc, char **argv) {
    if (!get_jit_target_from_environment().has_gpu_feature()) {
        printf("No gpu target enabled. Skipping test.\n");
        return 0;
    }

    if (1) {
        // Test a tuple reduction on the gpu
        Func f;
        Var x, y;

        f(x, y) = Tuple(x + y, x - y);

        // Updates to a reduction are atomic.
        f(x, y) = Tuple(f(x, y)[1]*2, f(x, y)[0]*2);
        // now equals ((x - y)*2, (x + y)*2)

        f.gpu_tile(x, y, 16, 16);
        f.update().gpu_tile(x, y, 16, 16);

        Realization result = f.realize(1024, 1024);

        Image<int> a = result[0], b = result[1];

        for (int y = 0; y < a.height(); y++) {
            for (int x = 0; x < a.width(); x++) {
                int correct_a = (x - y)*2;
                int correct_b = (x + y)*2;
                if (a(x, y) != correct_a || b(x, y) != correct_b) {
                    printf("result(%d, %d) = (%d, %d) instead of (%d, %d)\n",
                           x, y, a(x, y), b(x, y), correct_a, correct_b);
                    return -1;
                }
            }
        }
    }

    if (1) {
        // Now test one that alternates between cpu and gpu per update step
        Func f;
        Var x, y;

        f(x, y) = Tuple(x + y, x - y);

        for (size_t i = 0; i < 10; i++) {
            // Swap the tuple elements and increment both
            f(x, y) = Tuple(f(x, y)[1] + 1, f(x, y)[0] + 1);
        }

        // Schedule the pure step and the odd update steps on the gpu
        f.gpu_tile(x, y, 16, 16);
        for (int i = 0; i < 10; i ++) {
	    if (i & 1) {
		f.update(i).gpu_tile(x, y, 16, 16);
	    } else {
		f.update(i);
	    }
        }

        Realization result = f.realize(1024, 1024);

        Image<int> a = result[0], b = result[1];

        for (int y = 0; y < a.height(); y++) {
            for (int x = 0; x < a.width(); x++) {
                int correct_a = (x + y) + 10;
                int correct_b = (x - y) + 10;
                if (a(x, y) != correct_a || b(x, y) != correct_b) {
                    printf("result(%d, %d) = (%d, %d) instead of (%d, %d)\n",
                           x, y, a(x, y), b(x, y), correct_a, correct_b);
                    return -1;
                }
            }
        }

    }

    if (1) {
        // Same as above, but switches which steps are gpu and cpu
        Func f;
        Var x, y;

        f(x, y) = Tuple(x + y, x - y);

        for (size_t i = 0; i < 10; i++) {
            // Swap the tuple elements and increment both
            f(x, y) = Tuple(f(x, y)[1] + 1, f(x, y)[0] + 1);
        }

        // Schedule the even update steps on the gpu
        for (int i = 0; i < 10; i ++) {
            if (i & 1) {
                f.update(i).gpu_tile(x, y, 16, 16);
            } else {
                f.update(i);
            }
        }

        Realization result = f.realize(1024, 1024);

        Image<int> a = result[0], b = result[1];

        for (int y = 0; y < a.height(); y++) {
            for (int x = 0; x < a.width(); x++) {
                int correct_a = (x + y) + 10;
                int correct_b = (x - y) + 10;
                if (a(x, y) != correct_a || b(x, y) != correct_b) {
                    printf("result(%d, %d) = (%d, %d) instead of (%d, %d)\n",
                           x, y, a(x, y), b(x, y), correct_a, correct_b);
                    return -1;
                }
            }
        }

    }

    if (1) {
        // In this one, each step only uses one of the tuple elements
        // of the previous step, so only that buffer should get copied
        // back to host or copied to device.
        Func f;
        Var x, y;

        f(x, y) = Tuple(x + y - 1000, x - y + 1000);

        for (size_t i = 0; i < 10; i++) {
            f(x, y) = Tuple(f(x, y)[1] - 1, f(x, y)[1] + 1);
        }

        // Schedule the even update steps on the gpu
        for (int i = 0; i < 10; i++) {
            if (i & 1) {
                f.update(i);
            } else {
                f.update(i).gpu_tile(x, y, 16, 16);
            }
        }

        Realization result = f.realize(1024, 1024);

        Image<int> a = result[0], b = result[1];

        for (int y = 0; y < a.height(); y++) {
            for (int x = 0; x < a.width(); x++) {
                int correct_a = (x - y + 1000) + 8;
                int correct_b = (x - y + 1000) + 10;
                if (a(x, y) != correct_a || b(x, y) != correct_b) {
                    printf("result(%d, %d) = (%d, %d) instead of (%d, %d)\n",
                           x, y, a(x, y), b(x, y), correct_a, correct_b);
                    return -1;
                }
            }
        }

    }

    return 0;
}
<commit_msg>Added hexagon schedule to tuple_reduction test<commit_after>#include "Halide.h"
#include <stdio.h>

using namespace Halide;

int main(int argc, char **argv) {
    Target target = get_jit_target_from_environment();

    if (1) {
        // Test a tuple reduction on the gpu
        Func f;
        Var x, y;

        f(x, y) = Tuple(x + y, x - y);

        // Updates to a reduction are atomic.
        f(x, y) = Tuple(f(x, y)[1]*2, f(x, y)[0]*2);
        // now equals ((x - y)*2, (x + y)*2)

        if (target.has_gpu_feature()) {
            f.gpu_tile(x, y, 16, 16);
            f.update().gpu_tile(x, y, 16, 16);
        } else if (target.features_any_of({Target::HVX_64, Target::HVX_128})) {
            f.hexagon(y).vectorize(x, 32);
            f.update().hexagon(y).vectorize(x, 32);
        }

        Realization result = f.realize(1024, 1024);

        Image<int> a = result[0], b = result[1];

        for (int y = 0; y < a.height(); y++) {
            for (int x = 0; x < a.width(); x++) {
                int correct_a = (x - y)*2;
                int correct_b = (x + y)*2;
                if (a(x, y) != correct_a || b(x, y) != correct_b) {
                    printf("result(%d, %d) = (%d, %d) instead of (%d, %d)\n",
                           x, y, a(x, y), b(x, y), correct_a, correct_b);
                    return -1;
                }
            }
        }
    }

    if (1) {
        // Now test one that alternates between cpu and gpu per update step
        Func f;
        Var x, y;

        f(x, y) = Tuple(x + y, x - y);

        for (size_t i = 0; i < 10; i++) {
            // Swap the tuple elements and increment both
            f(x, y) = Tuple(f(x, y)[1] + 1, f(x, y)[0] + 1);
        }

        // Schedule the pure step and the odd update steps on the gpu
        if (target.has_gpu_feature()) {
            f.gpu_tile(x, y, 16, 16);
        } else if (target.features_any_of({Target::HVX_64, Target::HVX_128})) {
            f.hexagon(y).vectorize(x, 32);
        }
        for (int i = 0; i < 10; i ++) {
	    if (i & 1) {
                if (target.has_gpu_feature()) {
                    f.update(i).gpu_tile(x, y, 16, 16);
                } else if (target.features_any_of({Target::HVX_64, Target::HVX_128})) {
                    f.update(i).hexagon(y).vectorize(x, 32);
                }
	    } else {
		f.update(i);
	    }
        }

        Realization result = f.realize(1024, 1024);

        Image<int> a = result[0], b = result[1];

        for (int y = 0; y < a.height(); y++) {
            for (int x = 0; x < a.width(); x++) {
                int correct_a = (x + y) + 10;
                int correct_b = (x - y) + 10;
                if (a(x, y) != correct_a || b(x, y) != correct_b) {
                    printf("result(%d, %d) = (%d, %d) instead of (%d, %d)\n",
                           x, y, a(x, y), b(x, y), correct_a, correct_b);
                    return -1;
                }
            }
        }

    }

    if (1) {
        // Same as above, but switches which steps are gpu and cpu
        Func f;
        Var x, y;

        f(x, y) = Tuple(x + y, x - y);

        for (size_t i = 0; i < 10; i++) {
            // Swap the tuple elements and increment both
            f(x, y) = Tuple(f(x, y)[1] + 1, f(x, y)[0] + 1);
        }

        // Schedule the even update steps on the gpu
        for (int i = 0; i < 10; i ++) {
            if (i & 1) {
                if (target.has_gpu_feature()) {
                    f.update(i).gpu_tile(x, y, 16, 16);
                } else if (target.features_any_of({Target::HVX_64, Target::HVX_128})) {
                    f.update(i).hexagon(y).vectorize(x, 32);
                }
            } else {
                f.update(i);
            }
        }

        Realization result = f.realize(1024, 1024);

        Image<int> a = result[0], b = result[1];

        for (int y = 0; y < a.height(); y++) {
            for (int x = 0; x < a.width(); x++) {
                int correct_a = (x + y) + 10;
                int correct_b = (x - y) + 10;
                if (a(x, y) != correct_a || b(x, y) != correct_b) {
                    printf("result(%d, %d) = (%d, %d) instead of (%d, %d)\n",
                           x, y, a(x, y), b(x, y), correct_a, correct_b);
                    return -1;
                }
            }
        }

    }

    if (1) {
        // In this one, each step only uses one of the tuple elements
        // of the previous step, so only that buffer should get copied
        // back to host or copied to device.
        Func f;
        Var x, y;

        f(x, y) = Tuple(x + y - 1000, x - y + 1000);

        for (size_t i = 0; i < 10; i++) {
            f(x, y) = Tuple(f(x, y)[1] - 1, f(x, y)[1] + 1);
        }

        // Schedule the even update steps on the gpu
        for (int i = 0; i < 10; i++) {
            if (i & 1) {
                f.update(i);
            } else {
                if (target.has_gpu_feature()) {
                    f.update(i).gpu_tile(x, y, 16, 16);
                } else if (target.features_any_of({Target::HVX_64, Target::HVX_128})) {
                    f.update(i).hexagon(y).vectorize(x, 32);
                }
            }
        }

        Realization result = f.realize(1024, 1024);

        Image<int> a = result[0], b = result[1];

        for (int y = 0; y < a.height(); y++) {
            for (int x = 0; x < a.width(); x++) {
                int correct_a = (x - y + 1000) + 8;
                int correct_b = (x - y + 1000) + 10;
                if (a(x, y) != correct_a || b(x, y) != correct_b) {
                    printf("result(%d, %d) = (%d, %d) instead of (%d, %d)\n",
                           x, y, a(x, y), b(x, y), correct_a, correct_b);
                    return -1;
                }
            }
        }

    }

    return 0;
}
<|endoftext|>