void WedgePlatform::initTransceiverMap(SwSwitch* sw) { const int MAX_WEDGE_MODULES = 16; // If we can't get access to the USB devices, don't bother to // create the QSFP objects; this is likely to be a permanent // error. try { wedgeI2CBusLock_ = make_unique<WedgeI2CBusLock>(); } catch (const LibusbError& ex) { LOG(ERROR) << "failed to initialize USB to I2C interface"; return; } // Wedge port 0 is the CPU port, so the first port associated with // a QSFP+ is port 1. We start the transceiver IDs with 0, though. for (int idx = 0; idx < MAX_WEDGE_MODULES; idx++) { std::unique_ptr<WedgeQsfp> qsfpImpl = make_unique<WedgeQsfp>(idx, wedgeI2CBusLock_.get()); for (int channel = 0; channel < QsfpModule::CHANNEL_COUNT; ++channel) { qsfpImpl->setChannelPort(ChannelID(channel), PortID(idx * QsfpModule::CHANNEL_COUNT + channel + 1)); } std::unique_ptr<QsfpModule> qsfp = make_unique<QsfpModule>(std::move(qsfpImpl)); sw->addTransceiver(TransceiverID(idx), std::move(qsfp)); LOG(INFO) << "making QSFP for " << idx; for (int channel = 0; channel < QsfpModule::CHANNEL_COUNT; ++channel) { sw->addTransceiverMapping(PortID(idx * QsfpModule::CHANNEL_COUNT + channel + 1), ChannelID(channel), TransceiverID(idx)); } } }
void Daemon::buildCache() { _cache.resize( channels() + 2 ); { std::vector< Channel > cache; for ( Line &line : connections().values() ) { cache.push_back( line->master() ); for ( auto &ch : line->data() ) { if ( ch ) cache.push_back( ch ); } } _cache[ ChannelID( ChannelType::All ).asIndex() ] = std::move( cache ); } { std::vector< Channel > cache; for ( Line &line : connections().values() ) { if ( line->masterChannel() ) cache.push_back( line->master() ); } _cache[ ChannelID( ChannelType::Master ).asIndex() ] = std::move( cache ); } for ( int chID = 0; chID < channels(); ++chID ) { std::vector< Channel > cache; std::lock_guard< std::mutex > _( connections().mutex() ); cache.reserve( connections().size() ); for ( Line &line : connections().values() ) { if ( line->dataChannel( chID ) ) cache.push_back( line->data( chID ) ); } _cache[ ChannelID( chID ).asIndex() ] = std::move( cache ); } }
CStdString MythProgramInfo::UID() { // Creates unique IDs from ChannelID, StartTime and RecordID like "100_2011-12-10T12:00:00_247" char buf[50] = ""; MythTimestamp time(RecordingStartTime()); sprintf(buf, "%u_%s_%u", ChannelID(), time.String().c_str(), RecordID()); return CStdString(buf); }
long long MythProgramInfo::uid() { long long retval=RecStart(); retval<<=32; retval+=ChannelID(); if(retval>0) retval=-retval; return retval; }
CStdString MythProgramInfo::StrUID() { // Creates unique IDs from ChannelID, RecordID and StartTime like "100_200_2011-12-10T12:00:00" char buf[40] = ""; sprintf(buf, "%d_%ld_", ChannelID(), RecordID()); time_t starttime = StartTime(); strftime(buf + strlen(buf), 20, "%Y-%m-%dT%H:%M:%S", localtime(&starttime)); return CStdString(buf); }
void FModSound::soundEnded(FMOD::Channel *channel) { UInt32 ChannelID(getChannelID(channel)); if(ChannelID != 0) { removeChannel(ChannelID); produceSoundEnded(ChannelID); } }
void Daemon::exit( int code ) { NOTE(); Line master = connections().lockedFind( 0 ); if ( !master ) { Logger::log( "inaccessible master" ); ::exit( -code ); } OutputMessage notification( MessageType::Control ); notification.tag( Code::Done ); master->master()->send( notification ); while ( !_quit ) { Communicator::probe( _cache.at( ChannelID( ChannelType::All ).asIndex() ), [this]( Channel channel ) { this->consumeMessage( channel ); }, -1, false ); } ::exit( code ); }
void cEvent::FixEpgBugs(void) { // VDR can't usefully handle newline characters in the title and shortText of EPG // data, so let's always convert them to blanks (independent of the setting of EPGBugfixLevel): strreplace(title, '\n', ' '); strreplace(shortText, '\n', ' '); // Same for control characters: strreplace(title, '\x86', ' '); strreplace(title, '\x87', ' '); strreplace(shortText, '\x86', ' '); strreplace(shortText, '\x87', ' '); strreplace(description, '\x86', ' '); strreplace(description, '\x87', ' '); if (isempty(title)) { // we don't want any "(null)" titles title = strcpyrealloc(title, tr("No title")); EpgBugFixStat(12, ChannelID()); } if (Setup.EPGBugfixLevel == 0) return; // Some TV stations apparently have their own idea about how to fill in the // EPG data. Let's fix their bugs as good as we can: // Some channels put the ShortText in quotes and use either the ShortText // or the Description field, depending on how long the string is: // // Title // "ShortText". Description // if ((shortText == NULL) != (description == NULL)) { char *p = shortText ? shortText : description; if (*p == '"') { const char *delim = "\"."; char *e = strstr(p + 1, delim); if (e) { *e = 0; char *s = strdup(p + 1); char *d = strdup(e + strlen(delim)); free(shortText); free(description); shortText = s; description = d; EpgBugFixStat(1, ChannelID()); } } } // Some channels put the Description into the ShortText (preceded // by a blank) if there is no actual ShortText and the Description // is short enough: // // Title // Description // if (shortText && !description) { if (*shortText == ' ') { memmove(shortText, shortText + 1, strlen(shortText)); description = shortText; shortText = NULL; EpgBugFixStat(2, ChannelID()); } } // Sometimes they repeat the Title in the ShortText: // // Title // Title // if (shortText && strcmp(title, shortText) == 0) { free(shortText); shortText = NULL; EpgBugFixStat(3, ChannelID()); } // Some channels put the ShortText between double quotes, which is nothing // but annoying (some even put a '.' after the closing '"'): // // Title // "ShortText"[.] // if (shortText && *shortText == '"') { int l = strlen(shortText); if (l > 2 && (shortText[l - 1] == '"' || (shortText[l - 1] == '.' && shortText[l - 2] == '"'))) { memmove(shortText, shortText + 1, l); char *p = strrchr(shortText, '"'); if (p) *p = 0; EpgBugFixStat(4, ChannelID()); } } if (Setup.EPGBugfixLevel <= 1) return; // Some channels apparently try to do some formatting in the texts, // which is a bad idea because they have no way of knowing the width // of the window that will actually display the text. // Remove excess whitespace: title = compactspace(title); shortText = compactspace(shortText); description = compactspace(description); #define MAX_USEFUL_EPISODE_LENGTH 40 // Some channels put a whole lot of information in the ShortText and leave // the Description totally empty. So if the ShortText length exceeds // MAX_USEFUL_EPISODE_LENGTH, let's put this into the Description // instead: if (!isempty(shortText) && isempty(description)) { if (strlen(shortText) > MAX_USEFUL_EPISODE_LENGTH) { free(description); description = shortText; shortText = NULL; EpgBugFixStat(6, ChannelID()); } } // Some channels put the same information into ShortText and Description. // In that case we delete one of them: if (shortText && description && strcmp(shortText, description) == 0) { if (strlen(shortText) > MAX_USEFUL_EPISODE_LENGTH) { free(shortText); shortText = NULL; } else { free(description); description = NULL; } EpgBugFixStat(7, ChannelID()); } // Some channels use the ` ("backtick") character, where a ' (single quote) // would be normally used. Actually, "backticks" in normal text don't make // much sense, so let's replace them: strreplace(title, '`', '\''); strreplace(shortText, '`', '\''); strreplace(description, '`', '\''); if (Setup.EPGBugfixLevel <= 2) return; // The stream components have a "description" field which some channels // apparently have no idea of how to set correctly: if (components) { for (int i = 0; i < components->NumComponents(); i++) { tComponent *p = components->Component(i); switch (p->stream) { case 0x01: { // video if (p->description) { if (strcasecmp(p->description, "Video") == 0 || strcasecmp(p->description, "Bildformat") == 0) { // Yes, we know it's video - that's what the 'stream' code // is for! But _which_ video is it? free(p->description); p->description = NULL; EpgBugFixStat(8, ChannelID()); } } if (!p->description) { switch (p->type) { case 0x01: case 0x05: p->description = strdup("4:3"); break; case 0x02: case 0x03: case 0x06: case 0x07: p->description = strdup("16:9"); break; case 0x04: case 0x08: p->description = strdup(">16:9"); break; case 0x09: case 0x0D: p->description = strdup("HD 4:3"); break; case 0x0A: case 0x0B: case 0x0E: case 0x0F: p->description = strdup("HD 16:9"); break; case 0x0C: case 0x10: p->description = strdup("HD >16:9"); break; } EpgBugFixStat(9, ChannelID()); } } break; case 0x02: { // audio if (p->description) { if (strcasecmp(p->description, "Audio") == 0) { // Yes, we know it's audio - that's what the 'stream' code // is for! But _which_ audio is it? free(p->description); p->description = NULL; EpgBugFixStat(10, ChannelID()); } } if (!p->description) { switch (p->type) { case 0x05: p->description = strdup("Dolby Digital"); break; // all others will just display the language } EpgBugFixStat(11, ChannelID()); } } break; } } } }