Ticket #11808: boxer-eitfixup-v2.patch

File boxer-eitfixup-v2.patch, 24.5 KB (added by torbjorn.jansson@…, 13 years ago)

the patch

  • mythtv/libs/libmythtv/eitfixup.cpp

    diff --git a/mythtv/libs/libmythtv/eitfixup.cpp b/mythtv/libs/libmythtv/eitfixup.cpp
    index d61e72c..5f054e9 100644
    a b  
    11// C++ headers
    22#include <algorithm>
    33
     4// Qt headers
     5#include <QCoreApplication>
     6
    47// MythTV headers
    58#include "eitfixup.h"
    69#include "dvbdescriptors.h" // for MythCategoryType
     
    912#include "programinfo.h" // for subtitle types and audio and video properties
    1013#include "dishdescriptors.h" // for dish_theme_type_to_string
    1114
     15#include "mythlogging.h"
     16
    1217/*------------------------------------------------------------------------
    1318 * Event Fix Up Scripts - Turned on by entry in dtv_privatetype table
    1419 *------------------------------------------------------------------------*/
    EITFixUp::EITFixUp()  
    122127                        "NRK2s historiekveld|Detektimen|Nattkino|Filmklassiker|Film|Kortfilm|P.skemorg[eo]n|"
    123128                        "Radioteatret|Opera|P2-Akademiet|Nyhetsmorg[eo]n i P2 og Alltid Nyheter:): (.+)"),
    124129      m_noPremiere("\\s+-\\s+(Sesongpremiere|Premiere|premiere)!?$"),
    125       m_Stereo("\\b\\(?[sS]tereo\\)?\\b")
     130      m_Stereo("\\b\\(?[sS]tereo\\)?\\b"),
     131      m_boxerYear("[0-9]{4}"),
     132      m_boxerCountryCode("[A-Z]{3}")
    126133
    127134{
    128135}
    void EITFixUp::Fix(DBEventEIT &event) const  
    180187    if (kFixNO & event.fixup)
    181188        FixNO(event);
    182189
     190    if (kFixBoxer & event.fixup)
     191        FixBoxer(event);
     192
     193    if (kFixBoxerDescCo & event.fixup)
     194        FixBoxerDescriptionCompact(event);
     195
     196    //this one needs to be after kFixBoxerDescCo
     197    if (kFixBoxerDesc & event.fixup)
     198        FixBoxerDescription(event);
     199
    183200    if (kFixNRK_DVBT & event.fixup)
    184201        FixNRK_DVBT(event);
    185202
    void EITFixUp::FixNRK_DVBT(DBEventEIT &event) const  
    17671784    }
    17681785}
    17691786
     1787/** \fn EITFixUp::FixBoxer(DBEventEIT&) const
     1788 *  \brief Use this to clean DVB-T guide in Sweden
     1789 */
     1790void EITFixUp::FixBoxer(DBEventEIT &event) const
     1791{
     1792        if (event.subtitle.length() > 0)
     1793        {
     1794                event.description = event.subtitle + event.description;
     1795                event.subtitle = "";
     1796        }
     1797
     1798        int position = event.title.indexOf("(HD)");
     1799        if (position != -1)
     1800        {
     1801                event.title = event.title.replace("(HD)", "").trimmed();
     1802                event.videoProps |= VID_HDTV;
     1803        }
     1804       
     1805        QStringList strListDesc=event.description.split(".");
     1806        for(int i=0;i<strListDesc.count();i++)
     1807        {
     1808                if(strListDesc[i].contains("HD"))
     1809                {
     1810                        event.videoProps |= VID_HDTV;
     1811                }
     1812                if(strListDesc[i].contains("Textat sid"))
     1813                {
     1814                        event.subtitleType |= SUB_NORMAL;
     1815                }
     1816                if(strListDesc[i].contains(QString::fromUtf8("SÀnds med 5.1 ljud")))
     1817                {
     1818                        event.audioProps |= AUD_DOLBY;
     1819                }
     1820        }
     1821       
     1822        //create seriesId and programId just like mythfilldatabase does with xmltv data
     1823        //this works well because we have good data about season and episodes thanks to the crex boxer infotag descriptor
     1824        CreateProgramID(event);
     1825}
     1826/** \fn EITFixUp::FixBoxerDescriptionCompact(DBEventEIT&) const
     1827 * \brief Extract compact form of category, country, year and possibly subtitle from the description
     1828 */
     1829void EITFixUp::FixBoxerDescriptionCompact(DBEventEIT &event) const
     1830{
     1831        enum descPart
     1832        {
     1833                category,
     1834                country,
     1835                year
     1836        };
     1837
     1838        //needed because it is mostly series that have a subtitle
     1839        //this will also reduce the possibility of a picking bad subtitle
     1840        bool isSeries = (event.syndicatedepisodenumber.contains("E") && event.syndicatedepisodenumber.contains("S"));
     1841       
     1842        //format of the "compact subtitle" at the beginning of the description is
     1843        //a comma separated list have the following fields in this order:
     1844        //zero or more categories
     1845        //one or more 3 character country codes that always is in upper case
     1846        //exactly one 4 digit year
     1847        //optionally a subtitle
     1848       
     1849        QStringList strListCategories;
     1850        //most likely production country
     1851        QStringList strListCountries;
     1852        uint16_t airdate=0;
     1853        QString subtitle="";
     1854
     1855        descPart state=category;
     1856        QStringList strListDescParts=event.description.split(",");
     1857        //character position in description, used to know where to cut the description when we are done
     1858        int pos=0;
     1859        for(int i=0;i<strListDescParts.count();i++)
     1860        {
     1861                pos++;
     1862                pos+=strListDescParts[i].length();
     1863                if(strListDescParts[i].trimmed().isEmpty())
     1864                {
     1865                        continue;
     1866                }
     1867
     1868                //country code and year is easy to detect
     1869                if(strListDescParts[i].trimmed().indexOf(m_boxerCountryCode)==0)
     1870                {
     1871                        strListCountries.append(strListDescParts[i].trimmed());
     1872                        state=country;
     1873                }
     1874                else if(strListDescParts[i].trimmed().indexOf(m_boxerYear)==0)
     1875                {
     1876                        airdate=strListDescParts[i].trimmed().toUShort();
     1877                        state=year;
     1878                }
     1879                else
     1880                {
     1881                        if(state==category)
     1882                        {
     1883                                //this part must be a category
     1884                                strListCategories.append(strListDescParts[i].trimmed());
     1885                                LOG(VB_EIT, LOG_DEBUG, QString("EITFixUp::FixBoxerDescriptionCompact Category: '%1'").arg(strListDescParts[i].trimmed()));
     1886                        }
     1887                        else if(state==year)
     1888                        {
     1889                                //the only thing after the year is the optional subtitle
     1890                                //and there is nothing more to do after this
     1891                                //make sure subtitle is 55 characters or less to avoid
     1892                                //accidentally picking the first sentence of the description
     1893                                if(isSeries && strListDescParts[i].trimmed().length()<=55)
     1894                                {
     1895                                        subtitle=strListDescParts[i].trimmed();
     1896                                }
     1897                                else
     1898                                {
     1899                                        //if we didn't pick up any subtitle at this point we need to move back pos
     1900                                        //so we don't remove this part of the description
     1901                                        pos--;
     1902                                        pos-=strListDescParts[i].length();
     1903                                }
     1904                                break;
     1905                        }
     1906                }
     1907        }
     1908       
     1909        if(!event.description.isEmpty())
     1910        {
     1911                event.description.remove(0,pos+1);
     1912        }
     1913        if(!subtitle.isEmpty())
     1914        {
     1915                event.subtitle=subtitle;
     1916        }
     1917        if(airdate>0 && event.airdate==0)
     1918        {
     1919                event.airdate=airdate;
     1920        }
     1921
     1922        //translate the swedish categories so colour coding in the guide works properly
     1923        QString newCategory="";
     1924        if(strListCategories.count()>0 && event.category.isEmpty())
     1925        {
     1926                for(int i=0;i<strListCategories.count();i++)
     1927                {
     1928                        QString tmp=TranslateBoxerCategory(strListCategories[i].trimmed());
     1929                        if(!tmp.isEmpty())
     1930                        {
     1931                                if(i!=0)
     1932                                {
     1933                                        newCategory+="/";
     1934                                }
     1935                                newCategory+=tmp;
     1936                        }
     1937                       
     1938                }
     1939                event.category=newCategory;
     1940        }
     1941}
     1942QString EITFixUp::TranslateBoxerCategory(QString category) const
     1943{
     1944        QString result="";
     1945        QString tempCategory=category.toLower();
     1946       
     1947        //conversion table from eit categories to something that mythtv uses
     1948        QMap<QString,QString> lookup;
     1949        lookup.insert("action","Action");
     1950        lookup.insert("barn","Kids");
     1951        lookup.insert(QString::fromUtf8("dokumentÀr"),"Documentary");
     1952        lookup.insert("drama","Drama");
     1953        lookup.insert("erotik","Erotica");
     1954        lookup.insert("familjefilm","Family/Children");
     1955        lookup.insert("fotboll","Football");
     1956        lookup.insert("komedi","Comedy");
     1957        lookup.insert("romantik","Romance");
     1958        lookup.insert("sci-fi","Science fiction");
     1959        lookup.insert(QString::fromUtf8("skrÀck"),"Horror");
     1960        lookup.insert("sport","Sports");
     1961        lookup.insert("thriller","Detective/Thriller");
     1962        lookup.insert("animerad","Animated");
     1963        lookup.insert("fiske","Fishing");
     1964        lookup.insert(QString::fromUtf8("frÃ¥gesport"),"Game show");
     1965        lookup.insert("historiskt drama","Historical drama");
     1966        lookup.insert("jakt","Hunting");
     1967        lookup.insert("kriminaldrama","Crime drama");
     1968        lookup.insert("kriminal","Crime");
     1969        lookup.insert("mat","Food");
     1970        lookup.insert("motorsports","Motorsports");
     1971        lookup.insert("motor","Automobile");
     1972        lookup.insert(QString::fromUtf8("nöjesmagasin"),"Variety Show");
     1973        lookup.insert("natur","Nature");
     1974        lookup.insert("pratshow","Talk Show");
     1975        lookup.insert("reality","Reality");
     1976        lookup.insert("romantisk komedi","Romance-comedy");
     1977        lookup.insert("rysare","Horror");
     1978        lookup.insert("sport","Sports");
     1979        lookup.insert(QString::fromUtf8("tÀvlingsprogram"),"Game show");
     1980        lookup.insert(QString::fromUtf8("trÀdgÃ¥rdsprogram"),"Gardening");
     1981        lookup.insert(QString::fromUtf8("underhÃ¥llning"),"Entertainment");
     1982        lookup.insert(QString::fromUtf8("vÀstern"),"Adventure/Western/War");
     1983
     1984        QMap<QString,QString>::const_iterator i=lookup.constBegin();
     1985        while(i!=lookup.constEnd())
     1986        {
     1987                if(tempCategory.contains(i.key()))
     1988                {
     1989                        if(!result.isEmpty())
     1990                        {
     1991                                result+="/";
     1992                        }
     1993                        result+=QCoreApplication::translate("(Categories)",i.value().toUtf8());
     1994                        tempCategory=tempCategory.replace(i.key(),"");
     1995                }
     1996                ++i;
     1997        }
     1998        //no translation for the category? if so use the untranslated text instead
     1999        if(result.isEmpty() && !category.isEmpty())
     2000        {
     2001                result=category;
     2002        }
     2003        return result;
     2004}
     2005
     2006/** \fn EITFixUp::FixBoxerDescription(DBEventEIT&) const
     2007 * \brief Extract country, category, and year from the description
     2008 */
     2009void EITFixUp::FixBoxerDescription(DBEventEIT &event) const
     2010{
     2011        //this function is not as reliable as FixBoxerDescriptionCompact but instead works on most channels
     2012        //idealy this code should only run on all channels except those already handled by FixBoxerDescriptionCompact
     2013        //but since that is not easily doable it will only update fields if they are missing and this one should be run last
     2014
     2015        //borrow regex from swedish dvb-c comhem fixup, it is exatly what is needed
     2016        QRegExp tmpCountry = m_comHemCountry;
     2017        int pos = tmpCountry.indexIn(event.description);
     2018        if (pos != -1)
     2019        {
     2020                QStringList list = tmpCountry.capturedTexts();
     2021                QString replacement;
     2022
     2023                // Original title, usually english title
     2024                // note: list[1] contains extra () around the text that needs removing
     2025                if (list[1].length() > 0)
     2026                {
     2027                        replacement = list[1] + " ";
     2028                        //store it somewhere?
     2029                }
     2030
     2031                // Countr(y|ies)
     2032                if (list[2].length() > 0)
     2033                {
     2034                        replacement += list[2] + " ";
     2035                        //store it somewhere?
     2036                }
     2037
     2038                // Category
     2039                if (list[3].length() > 0)
     2040                {
     2041                        replacement += list[3] + ".";
     2042                        if(event.category.isEmpty())
     2043                        {
     2044                                event.category = TranslateBoxerCategory(list[3]);
     2045                                if(list[3].indexOf("serie")!=-1)
     2046                                {
     2047                                        event.categoryType = kCategorySeries;
     2048                                }
     2049                        }
     2050                        LOG(VB_EIT, LOG_DEBUG, QString("EITFixUp::FixBoxerDescription Category: '%1'").arg(list[3]));
     2051                }
     2052
     2053                // Year
     2054                if (list[4].length() > 0 && event.airdate==0)
     2055                {
     2056                        bool ok;
     2057                        uint y = list[4].trimmed().toUInt(&ok);
     2058                        if (ok)
     2059                                event.airdate = y;
     2060                }
     2061
     2062                // Remove year and actors.
     2063                // The reason category is left in the description is because otherwise
     2064                // the country would look wierd like "Amerikansk. Rest of description."
     2065                event.description = event.description.replace(list[0],replacement);
     2066        }
     2067}
     2068
     2069static uint ELFHash(const QByteArray &ba)
     2070{
     2071    const uchar *k = (const uchar *)ba.data();
     2072    uint h = 0;
     2073    uint g;
     2074
     2075    if (k)
     2076    {
     2077        while (*k)
     2078        {
     2079            h = (h << 4) + *k++;
     2080            if ((g = (h & 0xf0000000)) != 0)
     2081                h ^= g >> 24;
     2082            h &= ~g;
     2083        }
     2084    }
     2085
     2086    return h;
     2087}
     2088
     2089void EITFixUp::CreateProgramID(DBEventEIT &event) const
     2090{
     2091        QString season;
     2092        QString episode;
     2093        if(!event.syndicatedepisodenumber.isEmpty())
     2094        {
     2095                QRegExp epnum("E([0-9]+)S([0-9]+)");
     2096                if(epnum.indexIn(event.syndicatedepisodenumber)!=-1)
     2097                {
     2098                        episode=epnum.cap(1);
     2099                        season=epnum.cap(2);
     2100                }
     2101        }
     2102        CreateProgramID(event,season,episode);
     2103}
     2104
     2105/** \fn EITFixUp::CreateProgramID(DBEventEIT&, QString season, QString episode) const
     2106 *  \brief Create seriesId and programId in the same way mythfilldatabase does.
     2107 */
     2108void EITFixUp::CreateProgramID(DBEventEIT &event, QString season, QString episode) const
     2109{
     2110        QString seriesid=QString::number(ELFHash(event.title.toUtf8()));
     2111        event.seriesId=seriesid;
     2112       
     2113        QString programid;
     2114        if(event.categoryType==kCategoryMovie)
     2115        {
     2116                programid="MV";
     2117        }
     2118        else if(event.categoryType==kCategorySeries)
     2119        {
     2120                programid="EP";
     2121        }
     2122        else if(event.categoryType==kCategorySports)
     2123        {
     2124                programid="SP";
     2125        }
     2126        else
     2127        {
     2128                programid="SH";
     2129        }
     2130        programid.append(seriesid);
     2131        if(!episode.isEmpty() && !season.isEmpty())
     2132        {
     2133                int season_int=season.toInt();
     2134                if(season_int > 35)
     2135                {
     2136                        if(event.categoryType!=kCategoryMovie)
     2137                        {
     2138                                programid.clear();
     2139                        }
     2140                }
     2141                else
     2142                {
     2143                        programid.append(episode);
     2144                        programid.append(QString::number(season_int, 36));
     2145                        if(event.partnumber && event.parttotal)
     2146                        {
     2147                                programid+=QString::number(event.partnumber);
     2148                                programid+=QString::number(event.parttotal);
     2149                        }
     2150                }
     2151        }
     2152        else
     2153        {
     2154                if(event.categoryType!=kCategoryMovie)
     2155                {
     2156                        programid.clear();
     2157                }
     2158        }
     2159        //the function AddDVBEITAuthority() converts this string to lower case :-(
     2160        //perhaps it doesn't matter
     2161        event.programId=programid;
     2162}
     2163 No newline at end of file
  • mythtv/libs/libmythtv/eitfixup.h

    diff --git a/mythtv/libs/libmythtv/eitfixup.h b/mythtv/libs/libmythtv/eitfixup.h
    index 3a9b6ef..f3ab90e 100644
    a b class EITFixUp  
    5151        kFixNO         = 0x10000,
    5252        kFixNRK_DVBT   = 0x20000,
    5353        kFixDish       = 0x40000,
     54        kFixBoxer      = 0x80000,
     55        kFixBoxerDescCo = 0x100000,
     56        kFixBoxerDesc   = 0x200000,
    5457
    5558        // Early fixups
    5659        kEFixForceISO8859_1  = 0x2000,
    class EITFixUp  
    9093    void FixCategory(DBEventEIT &event) const;      // Generic Category fixes
    9194    void FixNO(DBEventEIT &event) const;            // Norwegian DVB-S
    9295    void FixNRK_DVBT(DBEventEIT &event) const;      // Norwegian NRK DVB-T
     96    void FixBoxer(DBEventEIT &event) const;         // Swedish DVB-T
     97    void FixBoxerDescriptionCompact(DBEventEIT &event) const;
     98    void FixBoxerDescription(DBEventEIT &event) const;
     99    QString TranslateBoxerCategory(QString) const;
     100    void CreateProgramID(DBEventEIT &event) const;
     101    void CreateProgramID(DBEventEIT &event, QString season, QString episode) const;
    93102
    94103    static QString AddDVBEITAuthority(uint chanid, const QString &id);
    95104
    class EITFixUp  
    195204    const QRegExp m_noNRKCategories;
    196205    const QRegExp m_noPremiere;
    197206    const QRegExp m_Stereo;
     207    const QRegExp m_boxerYear;
     208    const QRegExp m_boxerCountryCode;
    198209};
    199210
    200211#endif // EITFIXUP_H
  • mythtv/libs/libmythtv/eithelper.cpp

    diff --git a/mythtv/libs/libmythtv/eithelper.cpp b/mythtv/libs/libmythtv/eithelper.cpp
    index 289062e..f139673 100644
    a b  
    33// Std C headers
    44#include <time.h>
    55
     6// Qt headers
     7#include <QCoreApplication>
     8
    69// Std C++ headers
    710#include <algorithm>
    811using namespace std;
    using namespace std;  
    1720#include "premieretables.h"
    1821#include "dishdescriptors.h"
    1922#include "premieredescriptors.h"
     23#include "boxerinfotagdescriptors.h"
    2024#include "mythdate.h"
    2125#include "programdata.h"
    2226#include "programinfo.h" // for subtitle types and audio and video properties
    void EITHelper::AddEIT(const DVBEventInformationTable *eit)  
    488492            video_props, stars,
    489493            seriesId,  programId);
    490494
     495                const unsigned char *boxer_crex_infotag_desc=MPEGDescriptor::Find(list,PrivateDescriptorID::boxer_crex_infotag);
     496                if(boxer_crex_infotag_desc)
     497                {
     498                        BoxerCrexInfoTagDescriptor cbi(boxer_crex_infotag_desc);
     499                        cbi.Dump();
     500                        LOG(VB_EIT, LOG_DEBUG, LOC + QString("BoxerCrexInfoTag EIT: SeriesID: %1 Episode: %2 EpisodeTotal: %3 Season: %4 ProductionYear: %5")
     501                                .arg(QString::number(cbi.SeriesID()),QString::number(cbi.Episode()),QString::number(cbi.EpisodeTotal()),QString::number(cbi.Season()),QString::number(cbi.ProductionYear())));
     502                        LOG(VB_EIT, LOG_DEBUG, LOC + QString("BoxerCrexInfoTag EIT: Director: %1 ProdCountry: %2 SpokenLang: %3")
     503                                .arg(cbi.Director(),cbi.ProdCountry(),cbi.SpokenLang()));
     504
     505                        //unfortunately the data contained in SeriesID is of too bad quality to be of use for mythtv
     506                        //same series have multiple different seriesid and even the same episode have different values :(
     507                        //according to spec the seriesid is only guaranteed  to be unique within the same service
     508                        /*if(cbi.SeriesID()>0)
     509                        {
     510                                event->seriesId=QString::number(cbi.SeriesID());
     511                        }*/
     512                        if(cbi.Episode()>0)
     513                        {
     514                                QString episodenum;
     515                                if(cbi.Season()>0)
     516                                {
     517                                        episodenum=QString("E%1S%2").arg(QString::number(cbi.Episode()),QString::number(cbi.Season()));
     518                                       
     519                                        event->categoryType=kCategorySeries;
     520                                        //category cannot be Movie if this is a series, so category is clearly wrong
     521                                        //this is a common error in the guide data
     522                                        if(event->category==QCoreApplication::translate("(Categories)", "Movie"))
     523                                        {
     524                                                event->category="";
     525                                        }
     526                                }
     527                                else
     528                                {
     529                                        episodenum=QString("E%1").arg(QString::number(cbi.Episode()));
     530                                }
     531                                event->syndicatedepisodenumber=episodenum;
     532                        }
     533                        //multipart program?
     534                        if(cbi.Season()==0 && cbi.Episode()>0 && cbi.EpisodeTotal()>0)
     535                        {
     536                                event->partnumber=cbi.Episode();
     537                                event->parttotal=cbi.EpisodeTotal();
     538                        }
     539
     540                        event->previouslyshown=cbi.IsRerun();
     541                        //there no place to put cbi.IsLiveBroadcast() flag
     542                        event->airdate=cbi.ProductionYear();
     543                        if(!cbi.Director().isEmpty())
     544                        {
     545                                QStringList directors=cbi.Director().split(",");
     546                                for(int i=0;i<directors.count();i++)
     547                                {
     548                                        event->AddPerson(DBPerson::kDirector,directors[i]);
     549                                }
     550                        }
     551                }
     552
    491553        db_events.enqueue(event);
    492554    }
    493555}
    static void init_fixup(QMap<uint64_t,uint> &fix)  
    830892    fix[40999U << 16 | 1068] = EITFixUp::kFixSubtitle;
    831893    fix[40999U << 16 | 1069] = EITFixUp::kFixSubtitle;
    832894
     895        // Boxer Sweden (DVB-T)
     896        fix[ 8945U << 16 ] = EITFixUp::kFixBoxer|EITFixUp::kFixBoxerDesc;
     897        fix[ 8945U << 16 |  910] = EITFixUp::kFixBoxerDescCo;   //C More First
     898        fix[ 8945U << 16 |  970] = EITFixUp::kFixBoxerDescCo;   //C More Hits
     899        fix[ 8945U << 16 |  900] = EITFixUp::kFixBoxerDescCo;   //C More Sport/SF-Kanalen
     900        fix[ 8945U << 16 | 3460] = EITFixUp::kFixBoxerDescCo;   //C More Live HD/First HD
     901        //too many false positives on the subtitle (mainly kid programs)
     902        //fix[ 8945U << 16 | 3340] = EITFixUp::kFixBoxerDescCo; //C More Fotboll/Hockey/Kids
     903        fix[ 8945U << 16 | 3280] = EITFixUp::kFixBoxerDescCo;   //C More Series
     904
    833905    // Australia
    834906    fix[ 4096U << 16] = EITFixUp::kFixAUStar;
    835907    fix[ 4096U << 16] = EITFixUp::kFixAUStar;
  • mythtv/libs/libmythtv/libmythtv.pro

    diff --git a/mythtv/libs/libmythtv/libmythtv.pro b/mythtv/libs/libmythtv/libmythtv.pro
    index c815431..d462fc7 100644
    a b HEADERS += mpeg/freesat_huffman.h mpeg/freesat_tables.h  
    183183HEADERS += mpeg/iso6937tables.h
    184184HEADERS += mpeg/tsstats.h           mpeg/streamlisteners.h
    185185HEADERS += mpeg/H264Parser.h
     186HEADERS += mpeg/boxerinfotagdescriptors.h
    186187
    187188SOURCES += mpeg/tspacket.cpp        mpeg/pespacket.cpp
    188189SOURCES += mpeg/mpegtables.cpp      mpeg/atsctables.cpp
    SOURCES += mpeg/atsc_huffman.cpp  
    198199SOURCES += mpeg/freesat_huffman.cpp
    199200SOURCES += mpeg/iso6937tables.cpp
    200201SOURCES += mpeg/H264Parser.cpp
     202SOURCES += mpeg/boxerinfotagdescriptors.cpp
    201203
    202204# Channels, and the multiplexes that transmit them
    203205HEADERS += frequencies.h            frequencytables.h
  • new file mythtv/libs/libmythtv/mpeg/boxerinfotagdescriptors.cpp

    diff --git a/mythtv/libs/libmythtv/mpeg/boxerinfotagdescriptors.cpp b/mythtv/libs/libmythtv/mpeg/boxerinfotagdescriptors.cpp
    new file mode 100644
    index 0000000..60ccc5e
    - +  
     1#include "boxerinfotagdescriptors.h"
     2#include "dvbdescriptors.h"
     3#include "mythlogging.h"
     4
     5bool BoxerCrexInfoTagDescriptor::Parse(void)
     6{
     7        if(DescriptorLength() < 3)
     8        {
     9                return false;
     10        }
     11       
     12        //encoding override for dvb_decode_text
     13        //spec says strings are encoded according to character table 5 (latin/turkish) from DVB/ETSI EN 300 468 annex A
     14        unsigned char enc[] = {0x05};
     15        uint enc_len=1;
     16
     17        unsigned char *dataptr=const_cast<unsigned char *>(_data);
     18        dataptr+=2;
     19       
     20        uint8_t cbi_type=dataptr[0];
     21        dataptr+=1;
     22        //Basic info
     23        if(cbi_type==0x01)
     24        {
     25                _seriesid=        ((uint32_t)dataptr[0]  << 24) | ((uint32_t)dataptr[1] << 16) | ((uint32_t)dataptr[2] << 8) | dataptr[3];
     26                dataptr+=4;
     27                _episode=         ((uint16_t)dataptr[0]  << 8) | dataptr[1];
     28                dataptr+=2;
     29                _episode_total=   ((uint16_t)dataptr[0]  << 8) | dataptr[1];
     30                dataptr+=2;
     31                _season=          ((uint16_t)dataptr[0]  << 8) | dataptr[1];
     32                dataptr+=2;
     33                _status=          dataptr[0];
     34                dataptr+=1;
     35                _production_year= ((uint16_t)dataptr[0]  << 8) | dataptr[1];
     36                dataptr+=2;
     37
     38                if(dataptr<(_data+DescriptorLength()))
     39                {
     40                        uint8_t prod_country_length=dataptr[0];
     41                        dataptr+=1;
     42                        //LOG(VB_EIT, LOG_DEBUG, QString("BoxerCrexInfoTagDescriptor::Parse: prod_country_length=%1").arg(QString::number(prod_country_length)));
     43                        if(prod_country_length>0)
     44                        {
     45                                _prod_country=dvb_decode_text(dataptr,prod_country_length,enc,enc_len);
     46                        }
     47                        dataptr+=prod_country_length;
     48                }
     49
     50                if(dataptr<(_data+DescriptorLength()))
     51                {
     52                        uint8_t spoken_lang_length=dataptr[0];
     53                        dataptr+=1;
     54                        //LOG(VB_EIT, LOG_DEBUG, QString("BoxerCrexInfoTagDescriptor::Parse: spoken_lang_length=%1").arg(QString::number(spoken_lang_length)));
     55                        if(spoken_lang_length>0)
     56                        {
     57                                _spoken_lang=dvb_decode_text(dataptr,spoken_lang_length,enc,enc_len);
     58                        }
     59                        dataptr+=spoken_lang_length;
     60                }
     61
     62                if(dataptr<(_data+DescriptorLength()))
     63                {
     64                        uint8_t director_length=dataptr[0];
     65                        dataptr+=1;
     66                        //LOG(VB_EIT, LOG_DEBUG, QString("BoxerCrexInfoTagDescriptor::Parse: director_length=%1").arg(QString::number(director_length)));
     67                        if(director_length>0)
     68                        {
     69                                _director=dvb_decode_text(dataptr,director_length,enc,enc_len);
     70                        }
     71                        dataptr+=director_length;
     72                }
     73
     74                return true;
     75        }
     76        //Credits
     77        /*else if(cbi_type==0x02)
     78        {
     79                //not implemented since it is not transmitted (yet?)
     80        }
     81        //Keywords
     82        else if(cbi_type==0x03)
     83        {
     84                //not implemented since it is not transmitted (yet?)
     85        }*/
     86        return false;
     87}
     88void BoxerCrexInfoTagDescriptor::Dump()
     89{
     90        QString data;
     91        for(uint8_t i=0;i<_data[1];i++)
     92        {
     93                data+=QString(" %1").arg(_data[i],0,16);
     94        }
     95        LOG(VB_EIT, LOG_DEBUG, QString("BoxerCrexInfoTagDescriptor: Dump:%1").arg(data));
     96}
     97 No newline at end of file
  • new file mythtv/libs/libmythtv/mpeg/boxerinfotagdescriptors.h

    diff --git a/mythtv/libs/libmythtv/mpeg/boxerinfotagdescriptors.h b/mythtv/libs/libmythtv/mpeg/boxerinfotagdescriptors.h
    new file mode 100644
    index 0000000..8041d48
    - +  
     1#ifndef _BOXERINFOTAG_DESCRIPTORS_H_
     2#define _BOXERINFOTAG_DESCRIPTORS_H_
     3
     4#include <stdint.h>
     5#include <inttypes.h>
     6
     7// C++ headers
     8#include <vector>
     9using namespace std;
     10
     11// Qt headers
     12#include <QString>
     13#include <QDateTime>
     14
     15// MythTV headers
     16#include "mpegdescriptors.h"
     17
     18class BoxerCrexInfoTagDescriptor : public MPEGDescriptor
     19{
     20public:
     21        BoxerCrexInfoTagDescriptor(const unsigned char *data, int len = 300)
     22                : MPEGDescriptor(data, len, PrivateDescriptorID::boxer_crex_infotag),
     23                _seriesid(0),_episode(0),_episode_total(0),_season(0),_status(0),_production_year(0),
     24                _prod_country(""),_spoken_lang(""),_director("")
     25        {
     26                if (_data && !Parse())
     27                        _data = NULL;
     28        }
     29        uint32_t SeriesID()
     30        {
     31                return _seriesid;
     32        }
     33        uint16_t Episode()
     34        {
     35                return _episode;
     36        }
     37        uint16_t EpisodeTotal()
     38        {
     39                return _episode_total;
     40        }
     41        uint16_t Season()
     42        {
     43                return _season;
     44        }
     45       
     46        //status
     47        bool IsLiveBroadcast()
     48        {
     49                return _status & 0x01;
     50        }
     51        bool IsRerun()
     52        {
     53                return _status & 0x02;
     54        }
     55
     56        uint16_t ProductionYear()
     57        {
     58                return _production_year;
     59        }
     60       
     61        QString Director()
     62        {
     63                return _director;
     64        }
     65        QString ProdCountry()
     66        {
     67                return _prod_country;
     68        }
     69        QString SpokenLang()
     70        {
     71                return _spoken_lang;
     72        }
     73
     74        //debugging
     75        void Dump();
     76
     77private:
     78        virtual bool Parse(void);
     79       
     80        uint32_t _seriesid;
     81        uint16_t _episode;
     82        uint16_t _episode_total;
     83        uint16_t _season;
     84        uint8_t _status;
     85        uint16_t _production_year;
     86       
     87        QString _prod_country;
     88        QString _spoken_lang;
     89        QString _director;
     90
     91};
     92#endif // _BOXERINFOTAG_DESCRIPTORS_H_
  • mythtv/libs/libmythtv/mpeg/mpegdescriptors.cpp

    diff --git a/mythtv/libs/libmythtv/mpeg/mpegdescriptors.cpp b/mythtv/libs/libmythtv/mpeg/mpegdescriptors.cpp
    index 87c2c96..95735a9 100644
    a b QString MPEGDescriptor::DescriptorTagString(void) const  
    365365        case PrivateDescriptorID::premiere_content_transmission: /* 0xF2 */
    366366            comma_list_append(str, "Possibly Premiere DE Content Transmission");
    367367            break;
     368        case PrivateDescriptorID::boxer_crex_infotag: /* 0xBC */
     369            comma_list_append(str, "Possibly Boxer Crex infotag");
     370            break;
    368371    }
    369372
    370373    if (str.isEmpty())
  • mythtv/libs/libmythtv/mpeg/mpegdescriptors.h

    diff --git a/mythtv/libs/libmythtv/mpeg/mpegdescriptors.h b/mythtv/libs/libmythtv/mpeg/mpegdescriptors.h
    index 0e7a448..d355175 100644
    a b class PrivateDescriptorID  
    194194        premiere_content_order        = 0xF0,
    195195        premiere_parental_information = 0xF1,
    196196        premiere_content_transmission = 0xF2,
     197
     198        // Private -- Boxer
     199        boxer_crex_infotag = 0xBC,
    197200    };
    198201};
    199202