Ticket #255: smarter-scheduling.2.diff

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

second version of patch

  • libs/libmythtv/programinfo.cpp

     
    32083208        }
    32093209        message += "\n";
    32103210        delete confList;
     3211
     3212        if (gContext->GetNumSetting("OverTimePriority") == 3
     3213            && (gContext->GetNumSetting("RecordOverTime") > 0 ||
     3214                gContext->GetNumSetting("RecordPreRoll") > 0))
     3215            message +=  QObject::tr("\nYou may be able to eliminate "
     3216                    "conflicts by changing your OverTime setting from "
     3217                    "\"Always\" to something less stringent.\n");
    32113218    }
    32123219
    32133220    DialogBox diag(gContext->GetMainWindow(), message);
  • programs/mythfrontend/globalsettings.cpp

     
    566566    bs->setLabel(QObject::tr("Time to record before start of show "
    567567                 "(in seconds)"));
    568568    bs->setHelpText(QObject::tr("This global setting allows the recorder "
    569                     "to start before the scheduled start time. It does "
    570                     "not affect the scheduler. It is ignored when two shows "
    571                     "have been scheduled without enough time in between."));
     569                    "to start before the scheduled start time."));
    572570    bs->setValue(0);
    573571    return bs;
    574572}
     
    579577    bs->setLabel(QObject::tr("Time to record past end of show (in seconds)"));
    580578    bs->setValue(0);
    581579    bs->setHelpText(QObject::tr("This global setting allows the recorder "
    582                     "to record beyond the scheduled end time. It does "
    583                     "not affect the scheduler. It is ignored when two shows "
    584                     "have been scheduled without enough time in between."));
     580                    "to record beyond the scheduled end time."));
    585581    return bs;
    586582}
    587583
     
    592588    ge->setValue(QObject::tr("category name"));
    593589    ge->setHelpText(QObject::tr("For a specific category (e.g. "
    594590                                "\"Sports event\"), request that shows "
    595                                 "be autoextended.  Only works if a "
     591                                "be autoextended. Requires that the "
    596592                                "show's category can be determined."));
    597593    return ge;
    598594}
     
    603599                                          0, 180, 60, true);
    604600    bs->setLabel(QObject::tr("Record past end of show (in minutes)"));
    605601    bs->setValue(30);
    606     bs->setHelpText(QObject::tr("For the specified category, an attempt "
    607                                 "will be made to extend the recording "
    608                                 "by the specified time.  It is ignored "
    609                                 "when two shows have been scheduled "
    610                                 "without enough time in between."));
     602    bs->setHelpText(QObject::tr("For the specified category, attempt "
     603                                "to extend the recording "
     604                                "by the specified time."));
    611605    return bs;
    612606}
    613607
     
    616610    VerticalConfigurationGroup *vcg =
    617611        new VerticalConfigurationGroup(false, false);
    618612
    619     vcg->setLabel(QObject::tr("Category record over-time"));
     613    vcg->setLabel(QObject::tr("Category record OverTime"));
    620614    vcg->setUseLabel(true);
    621615    vcg->addChild(OverTimeCategory());
    622616    vcg->addChild(CategoryOverTime());
    623617    return vcg;
    624618}
    625619
     620
     621static HostComboBox *OverTimePriority()
     622{
     623    HostComboBox *gc = new HostComboBox("OverTimePriority");
     624    gc->setLabel(QObject::tr("Apply OverTime buffers"));
     625    gc->addSelection(QObject::tr("Unless conflict, tuner, or reschedule req'd"), "0");
     626    gc->addSelection(QObject::tr("Unless conflict or extra tuner req'd"), "1");
     627    gc->addSelection(QObject::tr("Unless conflict"), "2");
     628    gc->addSelection(QObject::tr("Always (may create conflicts)"), "3");
     629    gc->setHelpText(QObject::tr("When to record the OverTime buffer "
     630                            "specified above. If desired, "
     631                            "MythTV can assign recordings to an idle "
     632                            "tuner card, record an earlier/later showing, "
     633                            "or even cause a conflict "
     634                            "when necessary to honor the OverTime "
     635                            "settings."));
     636    return gc;
     637}
     638
    626639static HostCheckBox *PlayBoxOrdering()
    627640{
    628641    HostCheckBox *gc = new HostCheckBox("PlayBoxOrdering");
     
    30793092        jobs->addChild(AutoRunUserJob(i));
    30803093    addChild(jobs);
    30813094
     3095    VerticalConfigurationGroup* overtime = new VerticalConfigurationGroup(false);
     3096    overtime->setLabel(QObject::tr("General (OverTime Buffer)"));
     3097    overtime->addChild(RecordPreRoll());
     3098    overtime->addChild(RecordOverTime());
     3099    overtime->addChild(OverTimePriority());
     3100    overtime->addChild(CategoryOverTimeSettings());
     3101    addChild(overtime);
     3102
    30823103    VerticalConfigurationGroup* general2 = new VerticalConfigurationGroup(false);
    30833104    general2->setLabel(QObject::tr("General (Advanced)"));
    30843105    general2->addChild(AutoExpireExtraSpace());
    3085     general2->addChild(RecordPreRoll());
    3086     general2->addChild(RecordOverTime());
    3087     general2->addChild(CategoryOverTimeSettings());
    30883106    general2->addChild(ATSCCheckSignalThreshold());
    30893107    general2->addChild(ATSCCheckSignalWait());
    30903108    general2->addChild(HDRingbufferSize());
  • programs/mythfrontend/main.cpp

     
    434434    {
    435435        GeneralSettings settings;
    436436        settings.exec();
     437       
     438        // Required if user altered OverTime settings
     439        ScheduledRecording::signalChange(0);
    437440    }
    438441    else if (sel == "settings maingeneral")
    439442    {
  • 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 finding
     276    // alternate showings.
     277    if(gContext->GetNumSetting("OverTimePriority") > 0
     278       && (gContext->GetNumSetting("RecordOverTime") > 0 ||
     279           gContext->GetNumSetting("RecordPreRoll") > 0))
     280    {
     281        VERBOSE(VB_SCHEDULE, "Sort by time...");
     282        reclist.sort(comp_recstart);
     283       
     284        VERBOSE(VB_SCHEDULE, "ShuffleForOverrecord...");
     285        ShuffleForOverrecord();
     286    }
     287   
    273288    VERBOSE(VB_SCHEDULE, "ClearListMaps...");
    274289    ClearListMaps();
    275290
     
    588603    recordidlistmap.clear();
    589604}
    590605
    591 bool Scheduler::FindNextConflict(RecList &cardlist, ProgramInfo *p, RecIter &j)
     606bool Scheduler::FindNextConflict(RecList &cardlist, ProgramInfo *p, RecIter &j, bool findSoftConflicts)
    592607{
     608
     609    int prerollseconds;
     610    int overrecordseconds;
     611
     612    // A "soft conflict" is when two programs overlap only when the
     613    // global underrecord and overrecord settings are taken into
     614    // consideration.
     615    // We consider them if either:
     616    // (a) the user has specified that he ALWAYS wants the overrecord
     617    //     buffers honoured; or
     618    // (b) the user wants them honoured in some cases, and this is one
     619    //     of those as indicated by the findSoftConflicts flag
     620    if (gContext->GetNumSetting("OverTimePriority") == 3)
     621        findSoftConflicts = 1;
     622
     623    if (findSoftConflicts)
     624    {
     625      prerollseconds    = gContext->GetNumSetting("RecordPreRoll");
     626      overrecordseconds = gContext->GetNumSetting("RecordOverTime");
     627    }
     628
    593629    for ( ; j != cardlist.end(); j++)
    594630    {
    595631        ProgramInfo *q = *j;
     
    600636            continue;
    601637        if (p->cardid != 0 && p->cardid != q->cardid)
    602638            continue;
    603         if (p->recendts <= q->recstartts || p->recstartts >= q->recendts)
    604             continue;
     639        if (findSoftConflicts)
     640        {
     641            if (p->recendts.addSecs(overrecordseconds) <=
     642                        q->recstartts.addSecs((-1) * prerollseconds)
     643               || p->recstartts.addSecs((-1) * prerollseconds) >=
     644                        q->recendts.addSecs(overrecordseconds))
     645                continue;
     646        }
     647        else
     648        {
     649            if (p->recendts <= q->recstartts || p->recstartts >= q->recendts)
     650                continue;
     651        }
    605652        if (p->inputid == q->inputid && p->shareable)
    606653            continue;
    607654
     
    841888    }
    842889}
    843890
     891void Scheduler::ShuffleForOverrecord(void)
     892{
     893    VERBOSE(VB_SCHEDULE, "Trying to accommodate pre-roll / overrecord:");
     894
     895    RecIter i = reclist.begin();
     896
     897    for ( ; i != reclist.end(); i++)
     898    {
     899        ProgramInfo *p = *i;
     900
     901        if (p->recstatus != rsRecording && p->recstatus != rsWillRecord)
     902            continue;
     903
     904        // Look for soft conflicts with any other scheduled program
     905        RecIter k = reclist.begin();
     906        if (FindNextConflict(reclist, p, k, true))
     907        {
     908            // There's a soft conflict, so let's see if a different
     909            // showing would give us no conflicts at all.
     910
     911            // Get list of alternative showings
     912            RecList &showinglist = titlelistmap[p->title];
     913            RecIter j = showinglist.begin();
     914
     915            // Cycle through showings, looking for one that won't conflict
     916            for ( ; j != showinglist.end(); j++)
     917            {
     918                ProgramInfo *q = *j;
     919
     920                // No need to re-check the same showing
     921                if (q == p)
     922                    continue;
     923
     924                // Don't consider showings that use a different tuner
     925                // card if the user has specified he doesn't want this.
     926                if (gContext->GetNumSetting("OverTimePriority") < 2
     927                    && p->cardid != q->cardid)
     928                    continue;
     929                       
     930                k = reclist.begin();
     931                if (!FindNextConflict(reclist, q, k, true))
     932                {
     933                    // This showing is completely conflict-free, so
     934                    // substitute it.
     935
     936                    q->recstatus = rsWillRecord;
     937                    MarkOtherShowings(q);
     938                    PrintRec(p, "  -");
     939                    PrintRec(q, "  +");
     940                    break;
     941                }
     942            }
     943        }
     944    }
     945}
     946
    844947void Scheduler::getConflicting(ProgramInfo *pginfo, QStringList &strlist)
    845948{
    846949    QMutexLocker lockit(reclist_lock);
  • programs/mythbackend/scheduler.h

     
    7373    void PruneOverlaps(void);
    7474    void BuildListMaps(void);
    7575    void ClearListMaps(void);
    76     bool FindNextConflict(RecList &cardlist, ProgramInfo *p, RecIter &iter);
     76    bool FindNextConflict(RecList &cardlist, ProgramInfo *p, RecIter &iter, bool findSoftConflicts = false);
    7777    void MarkOtherShowings(ProgramInfo *p);
    7878    void MarkShowingsList(RecList &showinglist, ProgramInfo *p);
    7979    void BackupRecStatus(void);
     
    8282    void SchedNewRecords(void);
    8383    void MoveHigherRecords(void);
    8484    void PruneRedundants(void);
     85    void ShuffleForOverrecord(void);
    8586
    8687
    8788    void findAllScheduledPrograms(list<ProgramInfo *> &proglist);