コード例 #1
0
/** \fn DVBStreamHandler::RunSR(void)
 *  \brief Uses "Section" reader to read a DVB device for tables
 *
 *  This currently only supports DVB streams, ATSC and the raw MPEG
 *  streams used by some cable and satelite providers is not supported.
 */
void DVBStreamHandler::RunSR(void)
{
    int buffer_size = 4192;  // maximum size of Section we handle
    unsigned char *buffer = new unsigned char[buffer_size];
    if (!buffer)
    {
        _error = true;
        return;
    }

    SetRunning(true, _needs_buffering, true);

    LOG(VB_RECORD, LOG_INFO, LOC + "RunSR(): begin");

    while (_running_desired && !_error)
    {
        RetuneMonitor();
        UpdateFiltersFromStreamData();

        QMutexLocker read_locker(&_pid_lock);

        bool readSomething = false;
        PIDInfoMap::const_iterator fit = _pid_info.begin();
        for (; fit != _pid_info.end(); ++fit)
        {
            int len = read((*fit)->filter_fd, buffer, buffer_size);
            if (len <= 0)
                continue;

            readSomething = true;

            const PESPacket pes = PESPacket::ViewData(buffer);
            const PSIPTable psip(pes);

            if (psip.SectionSyntaxIndicator())
            {
                _listener_lock.lock();
                StreamDataList::const_iterator sit = _stream_data_list.begin();
                for (; sit != _stream_data_list.end(); ++sit)
                    sit.key()->HandleTables(fit.key() /* pid */, psip);
                _listener_lock.unlock();
            }
        }

        if (!readSomething)
            usleep(3000);
    }
    LOG(VB_RECORD, LOG_INFO, LOC + "RunSR(): " + "shutdown");

    RemoveAllPIDFilters();

    delete[] buffer;

    SetRunning(false, _needs_buffering, true);

    LOG(VB_RECORD, LOG_INFO, LOC + "RunSR(): " + "end");
}
コード例 #2
0
ファイル: dvbstreamhandler.cpp プロジェクト: scolbeck/mythtv
/** \fn DVBStreamHandler::RunSR(void)
 *  \brief Uses "Section" reader to read a DVB device for tables
 *
 *  This currently only supports DVB streams, ATSC and the raw MPEG
 *  streams used by some cable and satelite providers is not supported.
 */
void DVBStreamHandler::RunSR(void)
{
    int buffer_size = 4192;  // maximum size of Section we handle
    unsigned char *buffer = new unsigned char[buffer_size];
    if (!buffer)
        return;

    VERBOSE(VB_RECORD, LOC + "RunSR(): begin");

    while (IsRunning())
    {
        RetuneMonitor();
        UpdateFiltersFromStreamData();

        QMutexLocker read_locker(&_pid_lock);

        bool readSomething = false;
        PIDInfoMap::const_iterator fit = _pid_info.begin();
        for (; fit != _pid_info.end(); ++fit)
        {
            int len = read((*fit)->filter_fd, buffer, buffer_size);
            if (len <= 0)
                continue;

            readSomething = true;

            const PESPacket pes = PESPacket::ViewData(buffer);
            const PSIPTable psip(pes);

            if (psip.SectionSyntaxIndicator())
            {
                _listener_lock.lock();
                for (uint i = 0; i < _stream_data_list.size(); i++)
                {
                    _stream_data_list[i]->HandleTables(
                        fit.key() /* pid */, psip);
                }
                _listener_lock.unlock();
            }
        }

        if (!readSomething)
            usleep(3000);
    }
    VERBOSE(VB_RECORD, LOC + "RunSR(): " + "shutdown");

    RemoveAllPIDFilters();

    delete[] buffer;

    VERBOSE(VB_RECORD, LOC + "RunSR(): " + "end");
}
コード例 #3
0
ファイル: dvbstreamhandler.cpp プロジェクト: scolbeck/mythtv
/** \fn DVBStreamHandler::RunTS(void)
 *  \brief Uses TS filtering devices to read a DVB device for tables & data
 *
 *  This supports all types of MPEG based stream data, but is extreemely
 *  slow with DVB over USB 1.0 devices which for efficiency reasons buffer
 *  a stream until a full block transfer buffer full of the requested
 *  tables is available. This takes a very long time when you are just
 *  waiting for a PAT or PMT table, and the buffer is hundreds of packets
 *  in size.
 */
void DVBStreamHandler::RunTS(void)
{
    if (_needs_buffering)
        _device_read_buffer = new DeviceReadBuffer(this);

    int remainder = 0;
    int buffer_size = TSPacket::SIZE * 15000;
    unsigned char *buffer = new unsigned char[buffer_size];
    if (!buffer)
        return;
    memset(buffer, 0, buffer_size);

    QByteArray dvr_dev_path = _dvr_dev_path.toAscii();
    int dvr_fd;
    for (int tries = 1; ; ++tries)
    {
        dvr_fd = open(dvr_dev_path.constData(), O_RDONLY | O_NONBLOCK);
        if (dvr_fd >= 0)
            break;
        VERBOSE(VB_IMPORTANT, LOC_WARN +
                QString("Opening DVR device %1 failed : %2")
                .arg(_dvr_dev_path).arg(strerror(errno)));
        if (tries >= 20 || (errno != EBUSY && errno != EAGAIN))
        {
            VERBOSE(VB_IMPORTANT, LOC +
                    QString("Failed to open DVR device %1 : %2")
                    .arg(_dvr_dev_path).arg(strerror(errno)));
            delete[] buffer;
            return;
        }
        usleep(50000);
    }

    bool _error = false;
    if (_device_read_buffer)
    {
        bool ok = _device_read_buffer->Setup(_dvb_dev, dvr_fd);

        if (!ok)
        {
            VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to allocate DRB buffer");
            _error = true;
            delete[] buffer;
            return;
        }

        _device_read_buffer->Start();
    }

    VERBOSE(VB_RECORD, LOC + "RunTS(): begin");

    fd_set fd_select_set;
    FD_ZERO(        &fd_select_set);
    FD_SET (dvr_fd, &fd_select_set);
    while (IsRunning() && !_error)
    {
        RetuneMonitor();
        UpdateFiltersFromStreamData();

        ssize_t len = 0;

        if (_device_read_buffer)
        {
            len = _device_read_buffer->Read(
                &(buffer[remainder]), buffer_size - remainder);

            // Check for DRB errors
            if (_device_read_buffer->IsErrored())
            {
                VERBOSE(VB_IMPORTANT, LOC_ERR + "Device error detected");
                _error = true;
            }

            if (_device_read_buffer->IsEOF())
            {
                VERBOSE(VB_IMPORTANT, LOC_ERR + "Device EOF detected");
                _error = true;
            }
        }
        else
        {
            // timeout gets reset by select, so we need to create new one
            struct timeval timeout = { 0, 50 /* ms */ * 1000 /* -> usec */ };
            int ret = select(dvr_fd+1, &fd_select_set, NULL, NULL, &timeout);
            if (ret == -1 && errno != EINTR)
            {
                VERBOSE(VB_IMPORTANT, LOC_ERR + "select() failed" + ENO);
            }
            else
            {
                len = read(dvr_fd, &(buffer[remainder]),
                           buffer_size - remainder);
            }
        }

        if ((0 == len) || (-1 == len))
        {
            usleep(100);
            continue;
        }

        len += remainder;

        if (len < 10) // 10 bytes = 4 bytes TS header + 6 bytes PES header
        {
            remainder = len;
            continue;
        }

        _listener_lock.lock();

        if (_stream_data_list.empty())
        {
            _listener_lock.unlock();
            continue;
        }

        for (uint i = 0; i < _stream_data_list.size(); i++)
        {
            remainder = _stream_data_list[i]->ProcessData(buffer, len);
        }

        _listener_lock.unlock();

        if (remainder > 0 && (len > remainder)) // leftover bytes
            memmove(buffer, &(buffer[len - remainder]), remainder);
    }
    VERBOSE(VB_RECORD, LOC + "RunTS(): " + "shutdown");

    RemoveAllPIDFilters();

    if (_device_read_buffer)
    {
        if (_device_read_buffer->IsRunning())
            _device_read_buffer->Stop();

        delete _device_read_buffer;
        _device_read_buffer = NULL;
    }

    close(dvr_fd);
    delete[] buffer;

    VERBOSE(VB_RECORD, LOC + "RunTS(): " + "end");

    SetRunning(false);
}
コード例 #4
0
void ExternalStreamHandler::run(void)
{
    QString    cmd;
    QString    result;
    QString    xon;
    QByteArray buffer;
    uint       len;

    RunProlog();

    LOG(VB_RECORD, LOG_INFO, LOC + "run(): begin");

    SetRunning(true, true, false);

    if (m_poll_mode)
        xon = QString("SendBytes:%1").arg(PACKET_SIZE);
    else
        xon = "XON";

    uint remainder = 0;
    while (_running_desired && !_error)
    {
        if (!IsOpen())
        {
            if (!Open())
            {
                LOG(VB_RECORD, LOG_WARNING, LOC + QString("TS not open yet: %1")
                    .arg(m_error));
                usleep(750000);
                continue;
            }
        }

        if (StreamingCount() == 0)
        {
            usleep(5000);
            continue;
        }

        UpdateFiltersFromStreamData();

        ProcessCommand(xon, 1000, result);
        if (result.startsWith("ERR"))
        {
            LOG(VB_GENERAL, LOG_ERR, LOC + QString("Aborting: %1 -> %2")
                .arg(xon).arg(result));
            _error = true;
        }

        while ((len = m_IO->Read(buffer, PACKET_SIZE, 10)) > 0 ||
               buffer.size() > 188*50)
        {
            if (m_IO->Error())
            {
                m_error = m_IO->ErrorString();
                _error = true;
                LOG(VB_GENERAL, LOG_ERR, LOC +
                    QString("Failed to read from Extern recorder: %1")
                    .arg(m_error));
                break;
            }

            if (!_running_desired)
                break;

            if (!_listener_lock.tryLock())
                continue;

            if (_stream_data_list.empty())
            {
                LOG(VB_GENERAL, LOG_ERR, LOC + "_stream_data_list is empty");
                _listener_lock.unlock();
                continue;
            }

            if (!m_poll_mode)
            {
                ProcessCommand(QString("XOFF"), 50, result);
                if (result.startsWith("ERR"))
                {
                    LOG(VB_GENERAL, LOG_ERR, LOC + QString("Aborting: %1 -> %2")
                        .arg(xon).arg(result));
                    _error = true;
                }
            }

            StreamDataList::const_iterator sit = _stream_data_list.begin();
            for (; sit != _stream_data_list.end(); ++sit)
                remainder = sit.key()->ProcessData
                            (reinterpret_cast<const uint8_t *>
                             (buffer.constData()), buffer.size());

            _listener_lock.unlock();

            len = buffer.size();

            if (m_replay)
            {
                m_replay_buffer += buffer.left(len - remainder);
                if (m_replay_buffer.size() > (5000 * PACKET_SIZE))
                {
                    m_replay_buffer.remove(0, len - remainder);
                    LOG(VB_RECORD, LOG_WARNING, LOC +
                        QString("Replay size truncated to %1 bytes")
                        .arg(m_replay_buffer.size()));
                }
            }

            if (remainder > 0 && (len > remainder)) // leftover bytes
                buffer.remove(0, len - remainder);
            else
                buffer.clear();
        }
        usleep(10);
    }
    LOG(VB_RECORD, LOG_INFO, LOC + "run(): " + "shutdown");

    RemoveAllPIDFilters();
    SetRunning(false, true, false);

    LOG(VB_RECORD, LOG_INFO, LOC + "run(): " + "end");

    RunEpilog();
}
コード例 #5
0
ファイル: hdhrstreamhandler.cpp プロジェクト: awithers/mythtv
/** \fn HDHRStreamHandler::run(void)
 *  \brief Reads HDHomeRun socket for tables & data
 */
void HDHRStreamHandler::run(void)
{
    RunProlog();
    /* Create TS socket. */
    if (!hdhomerun_device_stream_start(_hdhomerun_device))
    {
        LOG(VB_GENERAL, LOG_ERR, LOC +
            "Starting recording (set target failed). Aborting.");
        _error = true;
        RunEpilog();
        return;
    }
    hdhomerun_device_stream_flush(_hdhomerun_device);

    SetRunning(true, false, false);

    LOG(VB_RECORD, LOG_INFO, LOC + "RunTS(): begin");

    int remainder = 0;
    QTime last_update;
    while (_running_desired && !_error)
    {
        int elapsed = !last_update.isValid() ? -1 : last_update.elapsed();
        elapsed = (elapsed < 0) ? 1000 : elapsed;
        if (elapsed > 100)
        {
            UpdateFiltersFromStreamData();
            if (_tune_mode != hdhrTuneModeVChannel)
                UpdateFilters();
            last_update.restart();
        }

        size_t read_size = 64 * 1024; // read about 64KB
        read_size /= VIDEO_DATA_PACKET_SIZE;
        read_size *= VIDEO_DATA_PACKET_SIZE;

        size_t data_length;
        unsigned char *data_buffer = hdhomerun_device_stream_recv(
            _hdhomerun_device, read_size, &data_length);

        if (!data_buffer)
        {
            usleep(20000);
            continue;
        }

        // Assume data_length is a multiple of 188 (packet size)

        _listener_lock.lock();

        if (_stream_data_list.empty())
        {
            _listener_lock.unlock();
            continue;
        }

        StreamDataList::const_iterator sit = _stream_data_list.begin();
        for (; sit != _stream_data_list.end(); ++sit)
            remainder = sit.key()->ProcessData(data_buffer, data_length);

        _listener_lock.unlock();
        if (remainder != 0)
        {
            LOG(VB_RECORD, LOG_INFO, LOC +
                QString("RunTS(): data_length = %1 remainder = %2")
                    .arg(data_length).arg(remainder));
        }
    }
    LOG(VB_RECORD, LOG_INFO, LOC + "RunTS(): " + "shutdown");

    RemoveAllPIDFilters();

    hdhomerun_device_stream_stop(_hdhomerun_device);
    LOG(VB_RECORD, LOG_INFO, LOC + "RunTS(): " + "end");

    SetRunning(false, false, false);
    RunEpilog();
}
コード例 #6
0
/** \fn HDHRStreamHandler::RunTS(void)
 *  \brief Uses TS filtering devices to read a DVB device for tables & data
 *
 *  This supports all types of MPEG based stream data, but is extreemely
 *  slow with DVB over USB 1.0 devices which for efficiency reasons buffer
 *  a stream until a full block transfer buffer full of the requested
 *  tables is available. This takes a very long time when you are just
 *  waiting for a PAT or PMT table, and the buffer is hundreds of packets
 *  in size.
 */
void HDHRStreamHandler::RunTS(void)
{
    int remainder = 0;

    /* Calculate buffer size */
    uint buffersize = gCoreContext->GetNumSetting(
        "HDRingbufferSize", 50 * TSPacket::SIZE) * 1024;
    buffersize /= VIDEO_DATA_PACKET_SIZE;
    buffersize *= VIDEO_DATA_PACKET_SIZE;

    // Buffer should be at least about 1MB..
    buffersize = max(49 * TSPacket::SIZE * 128, buffersize);

    /* Create TS socket. */
    if (!hdhomerun_device_stream_start(_hdhomerun_device))
    {
        VERBOSE(VB_IMPORTANT, LOC_ERR +
                "Starting recording (set target failed). Aborting.");
        return;
    }
    hdhomerun_device_stream_flush(_hdhomerun_device);

    bool _error = false;

    VERBOSE(VB_RECORD, LOC + "RunTS(): begin");

    while (IsRunning() && !_error)
    {
        UpdateFiltersFromStreamData();

        size_t read_size = 64 * 1024; // read about 64KB
        read_size /= VIDEO_DATA_PACKET_SIZE;
        read_size *= VIDEO_DATA_PACKET_SIZE;

        size_t data_length;
        unsigned char *data_buffer = hdhomerun_device_stream_recv(
            _hdhomerun_device, read_size, &data_length);

        if (!data_buffer)
        {
            usleep(5000);
            continue;
        }

        // Assume data_length is a multiple of 188 (packet size)

        _listener_lock.lock();

        if (_stream_data_list.empty())
        {
            _listener_lock.unlock();
            continue;
        }

        for (uint i = 0; i < _stream_data_list.size(); i++)
        {
            remainder = _stream_data_list[i]->ProcessData(
                data_buffer, data_length);
        }

        _listener_lock.unlock();
        if (remainder != 0)
        {
            VERBOSE(VB_RECORD, LOC +
                    QString("RunTS(): data_length = %1 remainder = %2")
                    .arg(data_length).arg(remainder));
        }
    }
    VERBOSE(VB_RECORD, LOC + "RunTS(): " + "shutdown");

    RemoveAllPIDFilters();

    hdhomerun_device_stream_stop(_hdhomerun_device);
    VERBOSE(VB_RECORD, LOC + "RunTS(): " + "end");

    SetRunning(false);
}
コード例 #7
0
void ASIStreamHandler::run(void)
{
    RunProlog();

    LOG(VB_RECORD, LOG_INFO, LOC + "run(): begin");

    if (!Open())
    {
        LOG(VB_GENERAL, LOG_ERR, LOC + QString("Failed to open device %1 : %2")
                .arg(_device).arg(strerror(errno)));
        _error = true;
        return;
    }

    DeviceReadBuffer *drb = new DeviceReadBuffer(this, true, false);
    bool ok = drb->Setup(_device, _fd, _packet_size, _buf_size);
    if (!ok)
    {
        LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to allocate DRB buffer");
        delete drb;
        drb = NULL;
        Close();
        _error = true;
        RunEpilog();
        return;
    }

    uint buffer_size = _packet_size * 15000;
    unsigned char *buffer = new unsigned char[buffer_size];
    if (!buffer)
    {
        LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to allocate buffer");
        delete drb;
        drb = NULL;
        Close();
        _error = true;
        RunEpilog();
        return;
    }
    memset(buffer, 0, buffer_size);

    SetRunning(true, true, false);

    drb->Start();

    {
        QMutexLocker locker(&_start_stop_lock);
        _drb = drb;
    }

    int remainder = 0;
    while (_running_desired && !_error)
    {
        UpdateFiltersFromStreamData();

        ssize_t len = 0;

        len = drb->Read(
            &(buffer[remainder]), buffer_size - remainder);

        if (!_running_desired)
            break;

        // Check for DRB errors
        if (drb->IsErrored())
        {
            LOG(VB_GENERAL, LOG_ERR, LOC + "Device error detected");
            _error = true;
        }

        if (drb->IsEOF())
        {
            LOG(VB_GENERAL, LOG_ERR, LOC + "Device EOF detected");
            _error = true;
        }

        if ((0 == len) || (-1 == len))
        {
            usleep(100);
            continue;
        }

        len += remainder;

        if (len < 10) // 10 bytes = 4 bytes TS header + 6 bytes PES header
        {
            remainder = len;
            continue;
        }

        if (!_listener_lock.tryLock())
        {
            remainder = len;
            continue;
        }

        if (_stream_data_list.empty())
        {
            _listener_lock.unlock();
            continue;
        }

        StreamDataList::const_iterator sit = _stream_data_list.begin();
        for (; sit != _stream_data_list.end(); ++sit)
            remainder = sit.key()->ProcessData(buffer, len);

        if (_mpts != NULL)
            _mpts->Write(buffer, len - remainder);

        _listener_lock.unlock();

        if (remainder > 0 && (len > remainder)) // leftover bytes
            memmove(buffer, &(buffer[len - remainder]), remainder);
    }
    LOG(VB_RECORD, LOG_INFO, LOC + "run(): " + "shutdown");

    RemoveAllPIDFilters();

    {
        QMutexLocker locker(&_start_stop_lock);
        _drb = NULL;
    }

    if (drb->IsRunning())
        drb->Stop();

    delete drb;
    delete[] buffer;
    Close();

    LOG(VB_RECORD, LOG_INFO, LOC + "run(): " + "end");

    SetRunning(false, true, false);
    RunEpilog();
}
コード例 #8
0
/** \fn DVBStreamHandler::RunTS(void)
 *  \brief Uses TS filtering devices to read a DVB device for tables & data
 *
 *  This supports all types of MPEG based stream data, but is extreemely
 *  slow with DVB over USB 1.0 devices which for efficiency reasons buffer
 *  a stream until a full block transfer buffer full of the requested
 *  tables is available. This takes a very long time when you are just
 *  waiting for a PAT or PMT table, and the buffer is hundreds of packets
 *  in size.
 */
void DVBStreamHandler::RunTS(void)
{
    QByteArray dvr_dev_path = _dvr_dev_path.toAscii();
    int dvr_fd;
    for (int tries = 1; ; ++tries)
    {
        dvr_fd = open(dvr_dev_path.constData(), O_RDONLY | O_NONBLOCK);
        if (dvr_fd >= 0)
            break;

        LOG(VB_GENERAL, LOG_WARNING, LOC +
            QString("Opening DVR device %1 failed : %2")
                .arg(_dvr_dev_path).arg(strerror(errno)));

        if (tries >= 20 || (errno != EBUSY && errno != EAGAIN))
        {
            LOG(VB_GENERAL, LOG_ERR, LOC +
                QString("Failed to open DVR device %1 : %2")
                    .arg(_dvr_dev_path).arg(strerror(errno)));
            _error = true;
            return;
        }
        usleep(50000);
    }

    int remainder = 0;
    int buffer_size = TSPacket::kSize * 15000;
    unsigned char *buffer = new unsigned char[buffer_size];
    if (!buffer)
    {
        LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to allocate memory");
        close(dvr_fd);
        _error = true;
        return;
    }
    memset(buffer, 0, buffer_size);

    DeviceReadBuffer *drb = NULL;
    if (_needs_buffering)
    {
        drb = new DeviceReadBuffer(this, true, false);
        if (!drb->Setup(_device, dvr_fd))
        {
            LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to allocate DRB buffer");
            delete drb;
            delete[] buffer;
            close(dvr_fd);
            _error = true;
            return;
        }

        drb->Start();
    }

    {
        // SetRunning() + set _drb
        QMutexLocker locker(&_start_stop_lock);
        _running = true;
        _using_buffering = _needs_buffering;
        _using_section_reader = false;
        _drb = drb;
    }

    LOG(VB_RECORD, LOG_INFO, LOC + "RunTS(): begin");

    fd_set fd_select_set;
    FD_ZERO(        &fd_select_set);
    FD_SET (dvr_fd, &fd_select_set);
    while (_running_desired && !_error)
    {
        RetuneMonitor();
        UpdateFiltersFromStreamData();

        ssize_t len = 0;

        if (drb)
        {
            len = drb->Read(
                &(buffer[remainder]), buffer_size - remainder);

            // Check for DRB errors
            if (drb->IsErrored())
            {
                LOG(VB_GENERAL, LOG_ERR, LOC + "Device error detected");
                _error = true;
            }

            if (drb->IsEOF() && _running_desired)
            {
                LOG(VB_GENERAL, LOG_ERR, LOC + "Device EOF detected");
                _error = true;
            }
        }
        else
        {
            // timeout gets reset by select, so we need to create new one
            struct timeval timeout = { 0, 50 /* ms */ * 1000 /* -> usec */ };
            int ret = select(dvr_fd+1, &fd_select_set, NULL, NULL, &timeout);
            if (ret == -1 && errno != EINTR)
            {
                LOG(VB_GENERAL, LOG_ERR, LOC + "select() failed" + ENO);
            }
            else
            {
                len = read(dvr_fd, &(buffer[remainder]),
                           buffer_size - remainder);
            }
        }

        if ((0 == len) || (-1 == len))
        {
            usleep(100);
            continue;
        }

        len += remainder;

        if (len < 10) // 10 bytes = 4 bytes TS header + 6 bytes PES header
        {
            remainder = len;
            continue;
        }

        _listener_lock.lock();

        if (_stream_data_list.empty())
        {
            _listener_lock.unlock();
            continue;
        }

        StreamDataList::const_iterator sit = _stream_data_list.begin();
        for (; sit != _stream_data_list.end(); ++sit)
            remainder = sit.key()->ProcessData(buffer, len);

        _listener_lock.unlock();

        if (remainder > 0 && (len > remainder)) // leftover bytes
            memmove(buffer, &(buffer[len - remainder]), remainder);
    }
    LOG(VB_RECORD, LOG_INFO, LOC + "RunTS(): " + "shutdown");

    RemoveAllPIDFilters();

    {
        QMutexLocker locker(&_start_stop_lock);
        _drb = NULL;
    }

    if (drb)
    {
        if (drb->IsRunning())
            drb->Stop();
        delete drb;
    }

    close(dvr_fd);
    delete[] buffer;

    LOG(VB_RECORD, LOG_INFO, LOC + "RunTS(): " + "end");

    SetRunning(false, _needs_buffering, false);
}
コード例 #9
0
ファイル: hdhrstreamhandler.cpp プロジェクト: Openivo/mythtv
/** \fn HDHRStreamHandler::run(void)
 *  \brief Reads HDHomeRun socket for tables & data
 */
void HDHRStreamHandler::run(void)
{
    threadRegister("HDHRStreamHandler");
    /* Create TS socket. */
    if (!hdhomerun_device_stream_start(_hdhomerun_device))
    {
        LOG(VB_GENERAL, LOG_ERR, LOC +
            "Starting recording (set target failed). Aborting.");
        _error = true;
	threadDeregister();
        return;
    }
    hdhomerun_device_stream_flush(_hdhomerun_device);

    SetRunning(true, false, false);

    /* Calculate buffer size */
    uint buffersize = gCoreContext->GetNumSetting(
        "HDRingbufferSize", 50 * TSPacket::kSize) * 1024;
    buffersize /= VIDEO_DATA_PACKET_SIZE;
    buffersize *= VIDEO_DATA_PACKET_SIZE;
    buffersize = max(49 * TSPacket::kSize * 128, buffersize);

    LOG(VB_RECORD, LOG_INFO, LOC + "RunTS(): begin");

    int remainder = 0;
    while (_running_desired && !_error)
    {
        UpdateFiltersFromStreamData();
        UpdateFilters();

        size_t read_size = 64 * 1024; // read about 64KB
        read_size /= VIDEO_DATA_PACKET_SIZE;
        read_size *= VIDEO_DATA_PACKET_SIZE;

        size_t data_length;
        unsigned char *data_buffer = hdhomerun_device_stream_recv(
            _hdhomerun_device, read_size, &data_length);

        if (!data_buffer)
        {
            usleep(5000);
            continue;
        }

        // Assume data_length is a multiple of 188 (packet size)

        _listener_lock.lock();

        if (_stream_data_list.empty())
        {
            _listener_lock.unlock();
            continue;
        }

        StreamDataList::const_iterator sit = _stream_data_list.begin();
        for (; sit != _stream_data_list.end(); ++sit)
            remainder = sit.key()->ProcessData(data_buffer, data_length);

        _listener_lock.unlock();
        if (remainder != 0)
        {
            LOG(VB_RECORD, LOG_INFO, LOC +
                QString("RunTS(): data_length = %1 remainder = %2")
                    .arg(data_length).arg(remainder));
        }
    }
    LOG(VB_RECORD, LOG_INFO, LOC + "RunTS(): " + "shutdown");

    RemoveAllPIDFilters();

    hdhomerun_device_stream_stop(_hdhomerun_device);
    LOG(VB_RECORD, LOG_INFO, LOC + "RunTS(): " + "end");

    SetRunning(false, false, false);
    threadDeregister();
}