示例#1
0
void ShoutCastIODevice::socketError(QAbstractSocket::SocketError error)
{
    switch (error)
    {
        case QAbstractSocket::ConnectionRefusedError:
            LOG(VB_NETWORK, LOG_ERR,
                "ShoutCastIODevice: Error Connection Refused");
            switchToState(CANT_CONNECT);
            break;
        case QAbstractSocket::RemoteHostClosedError:
            LOG(VB_NETWORK, LOG_ERR,
                "ShoutCastIODevice: Error Remote Host Closed The Connection");
            switchToState(CANT_CONNECT);
            break;
        case QAbstractSocket::HostNotFoundError:
            LOG(VB_NETWORK, LOG_ERR,
                "ShoutCastIODevice: Error Host Not Found");
            switchToState(CANT_RESOLVE);
            break;
        case QAbstractSocket::SocketTimeoutError:
            LOG(VB_NETWORK, LOG_ERR, "ShoutCastIODevice: Error Socket Timeout");
            switchToState(STOPPED);
            break;
        default:
            LOG(VB_NETWORK, LOG_ERR,
                QString("ShoutCastIODevice: Got socket error '%1'")
                    .arg(errorString()));
            switchToState(STOPPED);
            break;
    }
}
示例#2
0
void ShoutCastIODevice::socketConnected(void)
{
    LOG(VB_NETWORK, LOG_INFO, "ShoutCastIODevice: Connected");
    switchToState(CONNECTED);

    ShoutCastRequest request(m_url);
    qint64 written = m_socket->write(request.data(), request.size());
    LOG(VB_NETWORK, LOG_INFO,
        QString("ShoutCastIODevice: Sending Request, %1 of %2 bytes")
            .arg(written).arg(request.size()));

    if (written != request.size())
    {
        LOG(VB_NETWORK, LOG_INFO, "ShoutCastIODevice: buffering write");
        m_scratchpad = QByteArray(request.data() + written, request.size() - written);
        m_scratchpad_pos = 0;
        connect(m_socket, SIGNAL (bytesWritten(qint64)), SLOT(socketBytesWritten(qint64)));
        switchToState(WRITING_HEADER);
    }
    else
        switchToState(READING_HEADER);

    m_started = false;
    m_bytesDownloaded = 0;
    m_bytesTillNextMeta = 0;
    m_response_gotten = false;
}
示例#3
0
void ShoutCastIODevice::socketReadyRead(void)
{
    // only read enough data to fill our buffer
    int available = DecoderIOFactory::DefaultBufferSize - m_buffer->readBufAvail();

    QByteArray data = m_socket->read(available);

    m_bytesDownloaded += data.size();
    m_buffer->write(data);

    // send buffer status event
    emit bufferStatus(m_buffer->readBufAvail(), DecoderIOFactory::DefaultBufferSize);

    if (!m_started && m_bytesDownloaded > DecoderIOFactory::DefaultPrebufferSize)
    {
        m_socket->setReadBufferSize(DecoderIOFactory::DefaultPrebufferSize);
        m_started = true;
    }

    // if we are waiting for the HEADER and we have enough data process that
    if (m_state == READING_HEADER)
    {
        if (parseHeader())
        {
            if (m_response->getStatus() == 200)
            {
                switchToState(PLAYING);

                m_response_gotten = true;

                m_bytesTillNextMeta = m_response->getMetaint();

                switchToState(STREAMING);
            }
            else if (m_response->getStatus() == 302 || m_response->getStatus() == 301)
            {
                if (++m_redirects > MAX_REDIRECTS)
                {
                    LOG(VB_NETWORK, LOG_ERR, QString("Too many redirects"));
                    switchToState(STOPPED);
                }
                else
                {
                    LOG(VB_NETWORK, LOG_INFO, QString("Redirect to %1").arg(m_response->getLocation()));
                    m_socket->close();
                    QUrl redirectURL(m_response->getLocation());
                    connectToUrl(redirectURL);
                    return;
                }
            }
            else
            {
                LOG(VB_NETWORK, LOG_ERR, QString("Unknown response status %1")
                        .arg(m_response->getStatus()));
                switchToState(STOPPED);
            }
        }
    }
}
示例#4
0
bool ShoutCastIODevice::parseMeta(void)
{
    QByteArray data;
    m_buffer->read(data, 1);
    unsigned char ch = data[0];

    qint64 meta_size = 16 * ch;
    if (meta_size == 0)
        return true;

    // sanity check 
    if (meta_size > MAX_ALLOWED_META_SIZE)
    {
        LOG(VB_PLAYBACK, LOG_ERR,
            QString("ShoutCastIODevice: Error in stream, got a meta size of %1")
                .arg(meta_size));
        switchToState(STOPPED);
        return false;
    }

    LOG(VB_NETWORK, LOG_INFO,
        QString("ShoutCastIODevice: Reading %1 bytes of meta").arg(meta_size));

    // read metadata from our buffer
    data.clear();
    m_buffer->read(data, meta_size);

    // sanity check, check we have enough data
    if (meta_size > data.size())
    {
        LOG(VB_PLAYBACK, LOG_ERR,
            QString("ShoutCastIODevice: Not enough data, we have %1, but the "
                    "metadata size is %1")
                .arg(data.size()).arg(meta_size));
        switchToState(STOPPED);
        return false;
    }

    QString metadataString = QString::fromUtf8(data.constData());

    // avoid sending signals if the data hasn't changed
    if (m_last_metadata == metadataString)
        return true;

    m_last_metadata = metadataString;
    emit meta(metadataString);

    return true;
}
示例#5
0
qint64 ShoutCastIODevice::readData(char *data, qint64 maxlen)
{
    // the decoder wants more data from the stream
    // but first we must filter out any headers and metadata

    if (m_buffer->readBufAvail() == 0)
    {
        LOG(VB_PLAYBACK, LOG_ERR, "ShoutCastIODevice: No data in buffer!!");
        switchToState(STOPPED);
        return -1;
    }

    if (m_state == STREAMING_META && parseMeta())
        switchToState(STREAMING);

    if (m_state == STREAMING)
    {
        if (m_bytesTillNextMeta > 0)
        {
            // take maxlen or what ever is left till the next metadata
            if (maxlen > m_bytesTillNextMeta)
                maxlen = m_bytesTillNextMeta;

            maxlen = m_buffer->read(data, maxlen);

            m_bytesTillNextMeta -= maxlen;

            if (m_bytesTillNextMeta == 0)
                switchToState(STREAMING_META);
        }
        else
            maxlen = m_buffer->read(data, maxlen);
    }

    if (m_state != STOPPED) 
        LOG(VB_NETWORK, LOG_INFO,
            QString("ShoutCastIODevice: %1 kb in buffer, btnm=%2/%3 "
                    "state=%4, len=%5")
                .arg(m_buffer->readBufAvail() / 1024, 4)
                .arg(m_bytesTillNextMeta, 4)
                .arg(m_response->getMetaint())
                .arg(stateString (m_state))
                .arg(maxlen));
    else
        LOG(VB_NETWORK, LOG_INFO, QString("ShoutCastIODevice: stopped"));

    return maxlen;
}
示例#6
0
void StateManager::returnToTitle() {
    if (!dynamic_cast<FadeTransition*>(_currentState)) {
        switchToState(new FadeTransition([]() {
            return new TitleScreen;
        }));
    }
}
示例#7
0
void ShoutCastIODevice::connectToUrl(const QUrl &url)
{
    m_url = url;
    switchToState (RESOLVING);
    setOpenMode(ReadWrite);
    open(ReadWrite);
    return m_socket->connectToHost(m_url.host(), m_url.port() == -1 ? 80 : m_url.port());
}
示例#8
0
bool
HibernationManager::switchToLevel ( int level )
{
	HibernatorBase::SLEEP_STATE	state =
		m_hibernator->intToSleepState( level );
	if ( state == HibernatorBase::NONE ) {
		dprintf( D_ALWAYS, "Can't switch to invalid level '%d'\n", level );
		return false;
	}
	return switchToState( state );
}
示例#9
0
bool
HibernationManager::switchToState ( const char *name )
{
	HibernatorBase::SLEEP_STATE	state =
		m_hibernator->stringToSleepState( name );
	if ( state == HibernatorBase::NONE ) {
		dprintf( D_ALWAYS, "Can't switch to invalid state '%s'\n", name );
		return false;
	}
	return switchToState( state );
}
示例#10
0
void GStreamerPipeline::onBuffering( const QGst::BufferingMessagePtr &msg )
{
    int percent = msg->percent();
    QGst::ObjectPtr source = msg->source();

    int minPercent = 100;

    bool isFromRightSource = false;
    for( StreamInfo &info : mStreams ) {
        if( info.queue == source ) {
            isFromRightSource = true;
            if( percent <= 5 ) {
                info.isBuffering = true;
                switchToState( PS_Buffering );
            }
            if( percent == 100 ) {
                info.isBuffering = false;
            }
            info.percent = percent;
        }
        if( info.isBuffering ) {
            minPercent = std::min( minPercent, info.percent );
        }
    }
    if( !isFromRightSource ) return;


    qDebug() << "Buffering... " << minPercent << "Source: " << source->name();

    buffering( minPercent );
    if( minPercent == 100 ) {
        finnishedBuffering();
        if( mPlayAfterBuffering ) {
            switchToState( PS_Playing );
        }
        else {
            switchToState( PS_Paused );
        }
    }
}
示例#11
0
void ShoutCastIODevice::socketBytesWritten(qint64)
{
    qint64 written = m_socket->write(m_scratchpad.data() + m_scratchpad_pos,
                                     m_scratchpad.size() - m_scratchpad_pos);
    LOG(VB_NETWORK, LOG_INFO,
        QString("ShoutCastIO: %1 bytes written").arg(written));

    m_scratchpad_pos += written;
    if (m_scratchpad_pos == m_scratchpad.size())
    {
        m_scratchpad.truncate(0);
        disconnect (m_socket, SIGNAL(bytesWritten(qint64)), this, 0);
        switchToState(READING_HEADER);
    }
}
示例#12
0
ShoutCastIODevice::ShoutCastIODevice(void)
    :  m_redirects (0), 
       m_scratchpad_pos (0),
       m_state (NOT_CONNECTED)
{
    m_socket = new QTcpSocket;
    m_response = new ShoutCastResponse;

    connect(m_socket, SIGNAL(hostFound()), SLOT(socketHostFound()));
    connect(m_socket, SIGNAL(connected()), SLOT(socketConnected()));
    connect(m_socket, SIGNAL(disconnected()), SLOT(socketConnectionClosed()));
    connect(m_socket, SIGNAL(readyRead()), SLOT(socketReadyRead()));
    connect(m_socket, SIGNAL(error(QAbstractSocket::SocketError)), 
            SLOT(socketError(QAbstractSocket::SocketError)));

    switchToState(NOT_CONNECTED);

    setOpenMode(ReadWrite);
}
示例#13
0
bool
HibernationManager::switchToTargetState ( void )
{
	return switchToState( m_target_state );
}
示例#14
0
void GStreamerPipeline::play()
{
    switchToState( PS_Playing );
}
示例#15
0
void GStreamerPipeline::pause()
{
    switchToState( PS_Paused );
}
示例#16
0
void ShoutCastIODevice::socketConnectionClosed(void)
{
    LOG(VB_NETWORK, LOG_INFO, "ShoutCastIODevice: Connection Closed");
    switchToState(STOPPED);
}
示例#17
0
void GStreamerPipeline::onEos()
{
    switchToState( PS_Finnished );
}
示例#18
0
void ShoutCastIODevice::socketHostFound(void)
{
    LOG(VB_NETWORK, LOG_INFO, "ShoutCastIODevice: Host Found");
    switchToState(CONNECTING);
}