예제 #1
0
bool DVBStreamHandler::UpdateFiltersFromStreamData(void)
{
    UpdateListeningForEIT();

    pid_map_t pids;

    {
        QMutexLocker read_locker(&_listener_lock);

        for (uint i = 0; i < _stream_data_list.size(); i++)
            _stream_data_list[i]->GetPIDs(pids);
    }

    QMap<uint, PIDInfo*> add_pids;
    vector<uint>         del_pids;

    {
        QMutexLocker read_locker(&_pid_lock);

        // PIDs that need to be added..
        pid_map_t::const_iterator lit = pids.constBegin();
        for (; lit != pids.constEnd(); ++lit)
        {
            if (*lit && (_pid_info.find(lit.key()) == _pid_info.end()))
            {
                add_pids[lit.key()] = new PIDInfo(
                    lit.key(), StreamID::PrivSec,  DMX_PES_OTHER);
            }
        }

        // PIDs that need to be removed..
        PIDInfoMap::const_iterator fit = _pid_info.begin();
        for (; fit != _pid_info.end(); ++fit)
        {
            bool in_pids = pids.find(fit.key()) != pids.end();
            if (!in_pids)
                del_pids.push_back(fit.key());
        }
    }

    // Remove PIDs
    bool ok = true;
    vector<uint>::iterator dit = del_pids.begin();
    for (; dit != del_pids.end(); ++dit)
        ok &= RemovePIDFilter(*dit);

    // Add PIDs
    QMap<uint, PIDInfo*>::iterator ait = add_pids.begin();
    for (; ait != add_pids.end(); ++ait)
        ok &= AddPIDFilter(*ait);

    // Cycle filters if it's been a while
    if (_cycle_timer.elapsed() > 1000)
        CycleFiltersByPriority();

    return ok;
}
예제 #2
0
void DVBStreamHandler::UpdateListeningForEIT(void)
{
    vector<uint> add_eit, del_eit;

    QMutexLocker read_locker(&_listener_lock);

    for (uint i = 0; i < _stream_data_list.size(); i++)
    {
        MPEGStreamData *sd = _stream_data_list[i];
        if (sd->HasEITPIDChanges(_eit_pids) &&
            sd->GetEITPIDChanges(_eit_pids, add_eit, del_eit))
        {
            for (uint i = 0; i < del_eit.size(); i++)
            {
                uint_vec_t::iterator it;
                it = find(_eit_pids.begin(), _eit_pids.end(), del_eit[i]);
                if (it != _eit_pids.end())
                    _eit_pids.erase(it);
                sd->RemoveListeningPID(del_eit[i]);
            }

            for (uint i = 0; i < add_eit.size(); i++)
            {
                _eit_pids.push_back(add_eit[i]);
                sd->AddListeningPID(add_eit[i]);
            }
        }
    }
}
예제 #3
0
void StreamHandler::UpdateListeningForEIT(void)
{
    vector<uint> add_eit, del_eit;

    QMutexLocker read_locker(&m_listener_lock);

    StreamDataList::const_iterator it1 = m_stream_data_list.begin();
    for (; it1 != m_stream_data_list.end(); ++it1)
    {
        MPEGStreamData *sd = it1.key();
        if (sd->HasEITPIDChanges(m_eit_pids) &&
            sd->GetEITPIDChanges(m_eit_pids, add_eit, del_eit))
        {
            for (uint i = 0; i < del_eit.size(); i++)
            {
                uint_vec_t::iterator it2;
                it2 = find(m_eit_pids.begin(), m_eit_pids.end(), del_eit[i]);
                if (it2 != m_eit_pids.end())
                    m_eit_pids.erase(it2);
                sd->RemoveListeningPID(del_eit[i]);
            }

            for (uint i = 0; i < add_eit.size(); i++)
            {
                m_eit_pids.push_back(add_eit[i]);
                sd->AddListeningPID(add_eit[i]);
            }
        }
    }
}
예제 #4
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");
}
예제 #5
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)
        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");
}
예제 #6
0
bool HDHRStreamHandler::UpdateFiltersFromStreamData(void)
{
    UpdateListeningForEIT();

    pid_map_t pids;

    {
        QMutexLocker read_locker(&_listener_lock);

        for (uint i = 0; i < _stream_data_list.size(); i++)
            _stream_data_list[i]->GetPIDs(pids);
    }

    uint_vec_t           add_pids;
    vector<uint>         del_pids;

    {
        QMutexLocker read_locker(&_pid_lock);

        // PIDs that need to be added..
        pid_map_t::const_iterator lit = pids.constBegin();
        for (; lit != pids.constEnd(); ++lit)
        {
            vector<uint>::iterator it;
            it = lower_bound(_pid_info.begin(), _pid_info.end(), lit.key());
            if (it == _pid_info.end() || *it != lit.key())
                add_pids.push_back(lit.key());
        }

        // PIDs that need to be removed..
        vector<uint>::const_iterator fit = _pid_info.begin();
        for (; fit != _pid_info.end(); ++fit)
        {
            bool in_pids = pids.find(*fit) != pids.end();
            if (!in_pids)
                del_pids.push_back(*fit);
        }
    }

    bool need_update = false;

    // Remove PIDs
    bool ok = true;
    vector<uint>::iterator dit = del_pids.begin();
    for (; dit != del_pids.end(); ++dit)
    {
        need_update = true;
        ok &= RemovePIDFilter(*dit, false);
    }

    // Add PIDs
    vector<uint>::iterator ait = add_pids.begin();
    for (; ait != add_pids.end(); ++ait)
    {
        need_update = true;
        ok &= AddPIDFilter(*ait, false);
    }

    if (need_update)
        return UpdateFilters() && ok;

    return ok;
}
예제 #7
0
/**
 * @brief process instance from actual to expect.
 *    expect         actual          action
 *    yes            no              Install
 *    yes            yes     same    Nothing
 *    yes            yes     no-same Update
 *    no             yes             remove
 */
void MatrixManager::process_instance_expect()
{
    if (!_host_info.is_ready()) {
        LOG.info("HostInfo is INVALID, ignore processing");
        return;
    }
    
    if (_expect_list == NULL) {
        LOG.info("No EXPECT received. ignore processing");
        return;
    }
    
    ::sailor::ReadLocker read_locker(&_expect_lock);
    ::sailor::WriteLocker write_locker(&_instance_lock);
    
    // generate tmp_instance_list, to find diff between _expect_list and _instance_list.
    std::map<std::string, Instance *> tmp_instace_list(_instance_list);
    
    for (std::vector<InstanceInfo>::iterator expect = _expect_list->begin();
         expect != _expect_list->end(); ++ expect)
    {
        std::map<std::string, Instance *>::iterator iter = _instance_list.find(expect->get_instance_name());
        if (iter == _instance_list.end()) {
            // not in local
            InstanceMeta meta = expect->get_instance_meta();
            // has enough resource
            if (!_host_info.has_enough_resource(meta._resource)) {
                LOG.warn("MatrixManager: no enough resource or for instance[%s], \nneed resource: %s, \nhost info: %s",
                         expect->get_instance_name().c_str(), meta._resource.to_json().toStyledString().c_str(),
                         _host_info.to_json().toStyledString().c_str());
                continue;
            }
            Instance * slot = new Instance(_current_generation, expect->get_service_name(), expect->get_offset());
            // do state transformation
            if (!slot->do_install(meta)) {
                LOG.warn("MatrixManager: ignore install");
                delete slot;
                continue;
            }
            _instance_list.insert(std::pair<std::string, Instance *>(expect->get_instance_name(), slot));
            _host_info.use_resource(expect->get_instance_meta()._resource);
            ++ _current_generation;
            // call executor to install
            _executor.install(slot->get_instance_info(), slot->get_generation());
            LOG.trace("MatrixManager: add new Instance [%s] success.", slot->get_instance_info().get_instance_name().c_str());
        }
        else {
            // instance is already in local
            tmp_instace_list.erase(expect->get_instance_name());
            
            Instance * slot = iter->second;
            const InstanceInfo& instance_info = slot->get_instance_info();
            if (instance_info.get_meta_version() == expect->get_meta_version()) {
                // local and expect is same, ignore it.
                continue;
            }
            
            // local and expect is not same, update it.
            if (!slot->do_update(expect->get_instance_meta())) {
                 LOG.info("MatrixManager: ignore update of instance %s.", iter->first.c_str());
                 continue;
            }
            
            // call executor to do update.
            _executor.update(slot->get_instance_info(), slot->get_generation());
            
            LOG.trace("MatrixManager: update Instance [%s] success.", slot->get_instance_info().get_instance_name().c_str());
        }
    }
    
    // find instances that in local but not in expect. and then remove it.
    for (std::map<std::string, Instance *>::iterator iter = tmp_instace_list.begin();
        iter != tmp_instace_list.end(); ++ iter)
    {
        Instance * slot = iter->second;
        if (!slot->do_remove()) {
            continue;
        }
        
        _executor.remove(slot->get_instance_info(), slot->get_generation());
        
        LOG.trace("MatrixManager: remove Instance [%s] success.", slot->get_instance_info().get_instance_name().c_str());
    }
    
    
}