Ticket #255: smarter-scheduling.diff

File smarter-scheduling.diff, 5.1 KB (added by Max Barry <mythtv@…>, 16 years ago)

Patch against r7110

  • programs/mythbackend/scheduler.cpp

     
    268268    retrylist.sort(comp_retry);
    269269    VERBOSE(VB_SCHEDULE, "MoveHigherRecords...");
    270270    MoveHigherRecords();
     271    VERBOSE(VB_SCHEDULE, "Clear retrylist...");
    271272    retrylist.clear();
    272273
     274    // If user has a global setting to start recordings early or finish
     275    // them late, we'll see if we can better honour this by assigning
     276    // some recordings to an idle card.
     277    if (gContext->GetNumSetting("RecordOverTime") > 0 ||
     278        gContext->GetNumSetting("RecordPreRoll") > 0)
     279    {
     280        VERBOSE(VB_SCHEDULE, "Sort by time...");
     281        reclist.sort(comp_recstart);
     282       
     283        VERBOSE(VB_SCHEDULE, "ShuffleForOverrecord...");
     284        ShuffleForOverrecord();
     285    }
     286   
    273287    VERBOSE(VB_SCHEDULE, "ClearListMaps...");
    274288    ClearListMaps();
    275289
     
    485499    recordidlistmap.clear();
    486500}
    487501
    488 bool Scheduler::FindNextConflict(RecList &cardlist, ProgramInfo *p, RecIter &j)
     502bool Scheduler::FindNextConflict(RecList &cardlist, ProgramInfo *p, RecIter &j, bool findSoftConflicts)
    489503{
     504
     505    int prerollseconds;
     506    int overrecordseconds;
     507
     508    // A "soft conflict" is when two programs overlap only when the
     509    // global underrecord and overrecord settings are taken into
     510    // consideration. These settings are considered "soft" in the sense
     511    // that MythTV will ignore them when it's necessary to do so in
     512    // order to record everything scheduled.
     513    if (findSoftConflicts)
     514    {
     515      prerollseconds    = gContext->GetNumSetting("RecordPreRoll");
     516      overrecordseconds = gContext->GetNumSetting("RecordOverTime");
     517    }
     518
    490519    for ( ; j != cardlist.end(); j++)
    491520    {
    492521        ProgramInfo *q = *j;
     
    497526            continue;
    498527        if (p->cardid != 0 && p->cardid != q->cardid)
    499528            continue;
    500         if (p->recendts <= q->recstartts || p->recstartts >= q->recendts)
    501             continue;
     529        if (findSoftConflicts)
     530        {
     531            if (p->recendts.addSecs(overrecordseconds) <=
     532                        q->recstartts.addSecs((-1) * prerollseconds)
     533               || p->recstartts.addSecs((-1) * prerollseconds) >=
     534                        q->recendts.addSecs(overrecordseconds))
     535                continue;
     536        }
     537        else
     538        {
     539            if (p->recendts <= q->recstartts || p->recstartts >= q->recendts)
     540                continue;
     541        }
    502542        if (p->inputid == q->inputid && p->shareable)
    503543            continue;
    504544
     
    734774    }
    735775}
    736776
     777void Scheduler::ShuffleForOverrecord(void)
     778{
     779    VERBOSE(VB_SCHEDULE, "Trying to accommodate pre-roll / overrecord:");
     780
     781    RecIter i = reclist.begin();
     782
     783    for ( ; i != reclist.end(); i++)
     784    {
     785        ProgramInfo *p = *i;
     786
     787        if (p->recstatus != rsRecording && p->recstatus != rsWillRecord)
     788            continue;
     789
     790        // Look for soft conflicts with any other scheduled program
     791        RecIter k = reclist.begin();
     792        if (FindNextConflict(reclist, p, k, true))
     793        {
     794            // There's a soft conflict, so let's see if a different
     795            // showing would give us no conflicts at all.
     796
     797            // Get list of alternative showings
     798            RecList &showinglist = titlelistmap[p->title];
     799            RecIter j = showinglist.begin();
     800
     801            // Cycle through showings, looking for one that won't conflict
     802            for ( ; j != showinglist.end(); j++)
     803            {
     804                ProgramInfo *q = *j;
     805
     806                // No need to re-check the same showing
     807                if (q == p)
     808                    continue;
     809
     810                k = reclist.begin();
     811                if (!FindNextConflict(reclist, q, k, true))
     812                {
     813                    // This showing is completely conflict-free, so
     814                    // substitute it.
     815
     816                    q->recstatus = rsWillRecord;
     817                    MarkOtherShowings(q);
     818                    PrintRec(p, "  -");
     819                    PrintRec(q, "  +");
     820                    break;
     821                }
     822            }
     823        }
     824    }
     825}
     826
    737827void Scheduler::getConflicting(ProgramInfo *pginfo, QStringList &strlist)
    738828{
    739829    QMutexLocker lockit(reclist_lock);
  • programs/mythbackend/scheduler.h

     
    6868    void PruneOverlaps(void);
    6969    void BuildListMaps(void);
    7070    void ClearListMaps(void);
    71     bool FindNextConflict(RecList &cardlist, ProgramInfo *p, RecIter &iter);
     71    bool FindNextConflict(RecList &cardlist, ProgramInfo *p, RecIter &iter, bool findSoftConflicts = false);
    7272    void MarkOtherShowings(ProgramInfo *p);
    7373    void MarkShowingsList(RecList &showinglist, ProgramInfo *p);
    7474    void BackupRecStatus(void);
     
    7777    void SchedNewRecords(void);
    7878    void MoveHigherRecords(void);
    7979    void PruneRedundants(void);
     80    void ShuffleForOverrecord(void);
    8081
    8182
    8283    void findAllScheduledPrograms(list<ProgramInfo *> &proglist);