void Runner::run() { remoteProcessClient.writeToken(token); int teamSize = remoteProcessClient.readTeamSize(); remoteProcessClient.writeProtocolVersion(); Game game = remoteProcessClient.readGameContext(); vector<Strategy*> strategies; for (int strategyIndex = 0; strategyIndex < teamSize; ++strategyIndex) { Strategy* strategy = new MyStrategy; strategies.push_back(strategy); } PlayerContext* playerContext; while ((playerContext = remoteProcessClient.readPlayerContext()) != NULL) { Trooper playerTrooper = playerContext->getTrooper(); Move move; strategies[playerTrooper.getTeammateIndex()]->move(playerTrooper, playerContext->getWorld(), game, move); remoteProcessClient.writeMove(move); delete playerContext; } for (int strategyIndex = 0; strategyIndex < teamSize; ++strategyIndex) { delete strategies[strategyIndex]; } }
static int RebuildSeekTable(ProgramInfo *pginfo, int jobid) { QString filename = get_filename(pginfo); if (!DoesFileExist(pginfo)) { // file not found on local filesystem // assume file is in Video storage group on local backend // and try again filename = QString("myth://Videos@%1/%2") .arg(gCoreContext->GetHostName()).arg(filename); pginfo->SetPathname(filename); if (!DoesFileExist(pginfo)) { LOG(VB_GENERAL, LOG_ERR, "Unable to find file in defined storage paths."); return GENERIC_EXIT_PERMISSIONS_ERROR; } } // Update the file size since mythcommflag --rebuild is often used in user // scripts after transcoding or other size-changing operations UpdateFileSize(pginfo); RingBuffer *tmprbuf = RingBuffer::Create(filename, false); if (!tmprbuf) { LOG(VB_GENERAL, LOG_ERR, QString("Unable to create RingBuffer for %1").arg(filename)); return GENERIC_EXIT_PERMISSIONS_ERROR; } MythCommFlagPlayer *cfp = new MythCommFlagPlayer( (PlayerFlags)(kAudioMuted | kVideoIsNull | kDecodeNoDecode | kNoITV)); PlayerContext *ctx = new PlayerContext(kFlaggerInUseID); ctx->SetPlayingInfo(pginfo); ctx->SetRingBuffer(tmprbuf); ctx->SetPlayer(cfp); cfp->SetPlayerInfo(NULL, NULL, ctx); if (progress) { QString time = QDateTime::currentDateTime().toString(Qt::TextDate); cerr << "Rebuild started at " << qPrintable(time) << endl; } cfp->RebuildSeekTable(progress); if (progress) { QString time = QDateTime::currentDateTime().toString(Qt::TextDate); cerr << "Rebuild completed at " << qPrintable(time) << endl; } delete ctx; return GENERIC_EXIT_OK; }
static int RebuildSeekTable(ProgramInfo *pginfo, int jobid) { if (!DoesFileExist(pginfo)) return GENERIC_EXIT_PERMISSIONS_ERROR; QString filename = get_filename(pginfo); RingBuffer *tmprbuf = RingBuffer::Create(filename, false); if (!tmprbuf) { LOG(VB_GENERAL, LOG_ERR, QString("Unable to create RingBuffer for %1").arg(filename)); return GENERIC_EXIT_PERMISSIONS_ERROR; } MythCommFlagPlayer *cfp = new MythCommFlagPlayer(); PlayerContext *ctx = new PlayerContext(kFlaggerInUseID); AVSpecialDecode sp = (AVSpecialDecode) (kAVSpecialDecode_LowRes | kAVSpecialDecode_SingleThreaded | kAVSpecialDecode_NoLoopFilter); ctx->SetSpecialDecode(sp); ctx->SetPlayingInfo(pginfo); ctx->SetRingBuffer(tmprbuf); ctx->SetPlayer(cfp); cfp->SetPlayerInfo(NULL, NULL, true, ctx); time_t time_now; if (progress) { time_now = time(NULL); cerr << "Rebuild started at " << ctime(&time_now) << endl; } cfp->RebuildSeekTable(progress); if (progress) { time_now = time(NULL); cerr << "Rebuild completed at " << ctime(&time_now) << endl; } delete ctx; return GENERIC_EXIT_OK; }
static int BuildVideoMarkup(ProgramInfo *program_info, bool useDB) { QString filename; if (program_info->IsMythStream()) filename = program_info->GetPathname(); else filename = get_filename(program_info); RingBuffer *tmprbuf = RingBuffer::Create(filename, false); if (!tmprbuf) { LOG(VB_GENERAL, LOG_ERR, QString("Unable to create RingBuffer for %1").arg(filename)); return GENERIC_EXIT_PERMISSIONS_ERROR; } if (useDB && !MSqlQuery::testDBConnection()) { LOG(VB_GENERAL, LOG_ERR, "Unable to open DB connection for commercial flagging."); delete tmprbuf; return GENERIC_EXIT_DB_ERROR; } MythCommFlagPlayer *cfp = new MythCommFlagPlayer(); PlayerContext *ctx = new PlayerContext("seektable rebuilder"); ctx->SetSpecialDecode(kAVSpecialDecode_NoDecode); ctx->SetPlayingInfo(program_info); ctx->SetRingBuffer(tmprbuf); ctx->SetPlayer(cfp); cfp->SetPlayerInfo(NULL, NULL, true, ctx); cfp->RebuildSeekTable(progress); if (progress) cerr << "Rebuilt" << endl; delete ctx; return GENERIC_EXIT_OK; }
void Runner::run() { remoteProcessClient.writeTokenMessage(token); int teamSize = remoteProcessClient.readTeamSizeMessage(); remoteProcessClient.writeProtocolVersionMessage(); Game game = remoteProcessClient.readGameContextMessage(); vector<Strategy*> strategies; for (int strategyIndex = 0; strategyIndex < teamSize; ++strategyIndex) { Strategy* strategy = new MyStrategy; strategies.push_back(strategy); } PlayerContext* playerContext; while ((playerContext = remoteProcessClient.readPlayerContextMessage()) != NULL) { vector<Hockeyist> playerHockeyists = playerContext->getHockeyists(); if ((int) playerHockeyists.size() != teamSize) { break; } vector<Move> moves; for (int hockeyistIndex = 0; hockeyistIndex < teamSize; ++hockeyistIndex) { Hockeyist playerHockeyist = playerHockeyists[hockeyistIndex]; Move move; strategies[playerHockeyist.getTeammateIndex()] ->move(playerHockeyist, playerContext->getWorld(), game, move); moves.push_back(move); } remoteProcessClient.writeMovesMessage(moves); delete playerContext; } for (int strategyIndex = 0; strategyIndex < teamSize; ++strategyIndex) { delete strategies[strategyIndex]; } }
void RemoteProcessClient::writePlayerContext(const PlayerContext& playerContext) { writeBoolean(true); writeCars(playerContext.getCars()); writeWorld(playerContext.getWorld()); }
static int FlagCommercials(ProgramInfo *program_info, int jobid, const QString &outputfilename, bool useDB, bool fullSpeed) { global_program_info = program_info; int breaksFound = 0; // configure commercial detection method SkipTypes commDetectMethod = (SkipTypes)gCoreContext->GetNumSetting( "CommercialSkipMethod", COMM_DETECT_ALL); if (cmdline.toBool("commmethod")) { // pull commercial detection method from command line QString commmethod = cmdline.toString("commmethod"); // assume definition as integer value bool ok = true; commDetectMethod = (SkipTypes) commmethod.toInt(&ok); if (!ok) { // not an integer, attempt comma separated list commDetectMethod = COMM_DETECT_UNINIT; QMap<QString, SkipTypes>::const_iterator sit; QStringList list = commmethod.split(",", QString::SkipEmptyParts); QStringList::const_iterator it = list.begin(); for (; it != list.end(); ++it) { QString val = (*it).toLower(); if (val == "off") { commDetectMethod = COMM_DETECT_OFF; break; } if (!skipTypes->contains(val)) { cerr << "Failed to decode --method option '" << val.toLatin1().constData() << "'" << endl; return GENERIC_EXIT_INVALID_CMDLINE; } if (commDetectMethod == COMM_DETECT_UNINIT) { commDetectMethod = (SkipTypes) skipTypes->value(val); } else { commDetectMethod = (SkipTypes) ((int)commDetectMethod | (int)skipTypes->value(val)); } } } if (commDetectMethod == COMM_DETECT_UNINIT) return GENERIC_EXIT_INVALID_CMDLINE; } else if (useDB) { // if not manually specified, and we have a database to access // pull the commflag type from the channel MSqlQuery query(MSqlQuery::InitCon()); query.prepare("SELECT commmethod FROM channel " "WHERE chanid = :CHANID;"); query.bindValue(":CHANID", program_info->GetChanID()); if (!query.exec()) { // if the query fails, return with an error commDetectMethod = COMM_DETECT_UNINIT; MythDB::DBError("FlagCommercials", query); } else if (query.next()) { commDetectMethod = (enum SkipTypes)query.value(0).toInt(); if (commDetectMethod == COMM_DETECT_COMMFREE) { // if the channel is commercial free, drop to the default instead commDetectMethod = (enum SkipTypes)gCoreContext->GetNumSetting( "CommercialSkipMethod", COMM_DETECT_ALL); LOG(VB_COMMFLAG, LOG_INFO, QString("Chanid %1 is marked as being Commercial Free, " "we will use the default commercial detection " "method").arg(program_info->GetChanID())); } else if (commDetectMethod == COMM_DETECT_UNINIT) // no value set, so use the database default commDetectMethod = (enum SkipTypes)gCoreContext->GetNumSetting( "CommercialSkipMethod", COMM_DETECT_ALL); LOG(VB_COMMFLAG, LOG_INFO, QString("Using method: %1 from channel %2") .arg(commDetectMethod).arg(program_info->GetChanID())); } } else if (!useDB) { // default to a cheaper method for debugging purposes commDetectMethod = COMM_DETECT_BLANK; } // if selection has failed, or intentionally disabled, drop out if (commDetectMethod == COMM_DETECT_UNINIT) return GENERIC_EXIT_NOT_OK; else if (commDetectMethod == COMM_DETECT_OFF) return GENERIC_EXIT_OK; frm_dir_map_t blanks; recorder = NULL; /* * is there a purpose to this not fulfilled by --getskiplist? if (onlyDumpDBCommercialBreakList) { frm_dir_map_t commBreakList; program_info->QueryCommBreakList(commBreakList); print_comm_flag_output(program_info, commBreakList, 0, NULL, outputfilename); global_program_info = NULL; return GENERIC_EXIT_OK; } */ if (!DoesFileExist(program_info)) { LOG(VB_GENERAL, LOG_ERR, "Unable to find file in defined storage paths."); return GENERIC_EXIT_PERMISSIONS_ERROR; } QString filename = get_filename(program_info); RingBuffer *tmprbuf = RingBuffer::Create(filename, false); if (!tmprbuf) { LOG(VB_GENERAL, LOG_ERR, QString("Unable to create RingBuffer for %1").arg(filename)); global_program_info = NULL; return GENERIC_EXIT_PERMISSIONS_ERROR; } if (useDB) { if (!MSqlQuery::testDBConnection()) { LOG(VB_GENERAL, LOG_ERR, "Unable to open commflag DB connection"); delete tmprbuf; global_program_info = NULL; return GENERIC_EXIT_DB_ERROR; } } PlayerFlags flags = (PlayerFlags)(kAudioMuted | kVideoIsNull | kDecodeLowRes | kDecodeSingleThreaded | kDecodeNoLoopFilter | kNoITV); /* blank detector needs to be only sample center for this optimization. */ if ((COMM_DETECT_BLANKS == commDetectMethod) || (COMM_DETECT_2_BLANK == commDetectMethod)) { flags = (PlayerFlags) (flags | kDecodeFewBlocks); } MythCommFlagPlayer *cfp = new MythCommFlagPlayer(flags); PlayerContext *ctx = new PlayerContext(kFlaggerInUseID); ctx->SetPlayingInfo(program_info); ctx->SetRingBuffer(tmprbuf); ctx->SetPlayer(cfp); cfp->SetPlayerInfo(NULL, NULL, ctx); if (useDB) { if (program_info->GetRecordingEndTime() > MythDate::current()) { gCoreContext->ConnectToMasterServer(); recorder = RemoteGetExistingRecorder(program_info); if (recorder && (recorder->GetRecorderNumber() != -1)) { recorderNum = recorder->GetRecorderNumber(); watchingRecording = true; ctx->SetRecorder(recorder); LOG(VB_COMMFLAG, LOG_INFO, QString("mythcommflag will flag recording " "currently in progress on cardid %1") .arg(recorderNum)); } else { recorderNum = -1; watchingRecording = false; LOG(VB_GENERAL, LOG_ERR, "Unable to find active recorder for this " "recording, realtime flagging will not be enabled."); } cfp->SetWatchingRecording(watchingRecording); } } // TODO: Add back insertion of job if not in jobqueue breaksFound = DoFlagCommercials( program_info, progress, fullSpeed, jobid, cfp, commDetectMethod, outputfilename, useDB); if (progress) cerr << breaksFound << "\n"; LOG(VB_GENERAL, LOG_NOTICE, QString("Finished, %1 break(s) found.") .arg(breaksFound)); delete ctx; global_program_info = NULL; return breaksFound; }
static int RunCCExtract(const ProgramInfo &program_info) { QString filename = program_info.GetPlaybackURL(); if (filename.startsWith("myth://")) { QString msg = QString("Only locally accessible files are supported (%1).") .arg(program_info.GetPathname()); cerr << qPrintable(msg) << endl; return GENERIC_EXIT_INVALID_CMDLINE; } if (!QFile::exists(filename)) { cerr << qPrintable( QString("Could not open input file (%1).").arg(filename)) << endl; return GENERIC_EXIT_INVALID_CMDLINE; } RingBuffer *tmprbuf = RingBuffer::Create(filename, false); if (!tmprbuf) { cerr << qPrintable(QString("Unable to create RingBuffer for %1") .arg(filename)) << endl; return GENERIC_EXIT_PERMISSIONS_ERROR; } if (program_info.GetRecordingEndTime() > MythDate::current()) { cout << "Program will end @ " << qPrintable(program_info.GetRecordingEndTime(MythDate::ISODate)) << endl; tmprbuf->SetWaitForWrite(); } PlayerFlags flags = (PlayerFlags)(kVideoIsNull | kAudioMuted | kDecodeNoLoopFilter | kDecodeFewBlocks | kDecodeLowRes | kDecodeSingleThreaded | kDecodeNoDecode); MythCCExtractorPlayer *ccp = new MythCCExtractorPlayer(flags, true, filename); PlayerContext *ctx = new PlayerContext(kCCExtractorInUseID); ctx->SetPlayingInfo(&program_info); ctx->SetRingBuffer(tmprbuf); ctx->SetPlayer(ccp); ccp->SetPlayerInfo(NULL, NULL, ctx); if (ccp->OpenFile() < 0) { cerr << "Failed to open " << qPrintable(filename) << endl; return GENERIC_EXIT_NOT_OK; } if (!ccp->run()) { cerr << "Failed to decode " << qPrintable(filename) << endl; return GENERIC_EXIT_NOT_OK; } delete ctx; return GENERIC_EXIT_OK; }
/** * \brief Returns a PIX_FMT_RGBA32 buffer containg a frame from the video. * * \param pginfo Recording to grab from. * \param filename File containing recording. * \param seektime Seconds or frames into the video to seek before * capturing a frame. * \param time_in_secs if true time is in seconds, otherwise it is in frames. * \param bufferlen Returns size of buffer returned (in bytes). * \param video_width Returns width of frame grabbed. * \param video_height Returns height of frame grabbed. * \param video_aspect Returns aspect ratio of frame grabbed. * \return Buffer allocated with new containing frame in RGBA32 format if * successful, NULL otherwise. */ char *PreviewGenerator::GetScreenGrab( const ProgramInfo &pginfo, const QString &filename, long long seektime, bool time_in_secs, int &bufferlen, int &video_width, int &video_height, float &video_aspect) { (void) pginfo; (void) filename; (void) seektime; (void) time_in_secs; (void) bufferlen; (void) video_width; (void) video_height; char *retbuf = NULL; bufferlen = 0; if (!MSqlQuery::testDBConnection()) { LOG(VB_GENERAL, LOG_ERR, LOC + "Previewer could not connect to DB."); return NULL; } // pre-test local files for existence and size. 500 ms speed-up... if (filename.left(1)=="/") { QFileInfo info(filename); bool invalid = (!info.exists() || !info.isReadable() || (info.isFile() && (info.size() < 8*1024))); if (invalid) { LOG(VB_GENERAL, LOG_ERR, LOC + "Previewer file " + QString("'%1'").arg(filename) + " is not valid."); return NULL; } } RingBuffer *rbuf = RingBuffer::Create(filename, false, false, 0); if (!rbuf->IsOpen()) { LOG(VB_GENERAL, LOG_ERR, LOC + "Previewer could not open file: " + QString("'%1'").arg(filename)); delete rbuf; return NULL; } PlayerContext *ctx = new PlayerContext(kPreviewGeneratorInUseID); ctx->SetRingBuffer(rbuf); ctx->SetPlayingInfo(&pginfo); ctx->SetPlayer(new MythPlayer()); ctx->player->SetPlayerInfo(NULL, NULL, true, ctx); if (time_in_secs) retbuf = ctx->player->GetScreenGrab(seektime, bufferlen, video_width, video_height, video_aspect); else retbuf = ctx->player->GetScreenGrabAtFrame( seektime, true, bufferlen, video_width, video_height, video_aspect); delete ctx; if (retbuf) { LOG(VB_GENERAL, LOG_INFO, LOC + QString("Grabbed preview '%0' %1x%2@%3%4") .arg(filename).arg(video_width).arg(video_height) .arg(seektime).arg((time_in_secs) ? "s" : "f")); } return retbuf; }