Ticket #11808: boxer-eitfixup-v3-no-cat-conv.patch

File boxer-eitfixup-v3-no-cat-conv.patch, 23.6 KB (added by torbjorn.jansson@…, 13 years ago)
  • mythtv/libs/libmythbase/mythbaseutil.h

    diff --git a/mythtv/libs/libmythbase/mythbaseutil.h b/mythtv/libs/libmythbase/mythbaseutil.h
    index 2d74c02..6d9914c 100644
    a b static inline void setup_pipe(int mypipe[2], long myflags[2])  
    4949    }
    5050}
    5151#endif
     52static inline uint ELFHash(const QByteArray &ba)
     53{
     54    const uchar *k = (const uchar *)ba.data();
     55    uint h = 0;
     56    uint g;
     57
     58    if (k)
     59    {
     60        while (*k)
     61        {
     62            h = (h << 4) + *k++;
     63            if ((g = (h & 0xf0000000)) != 0)
     64                h ^= g >> 24;
     65            h &= ~g;
     66        }
     67    }
     68
     69    return h;
     70}
    5271
    5372#endif // _MYTH_DB_UTIL_H_
  • mythtv/libs/libmythtv/eitfixup.cpp

    diff --git a/mythtv/libs/libmythtv/eitfixup.cpp b/mythtv/libs/libmythtv/eitfixup.cpp
    index d61e72c..3a5b2fc 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#include <unistd.h>
     17#include "mythbaseutil.h"
     18
    1219/*------------------------------------------------------------------------
    1320 * Event Fix Up Scripts - Turned on by entry in dtv_privatetype table
    1421 *------------------------------------------------------------------------*/
    EITFixUp::EITFixUp()  
    122129                        "NRK2s historiekveld|Detektimen|Nattkino|Filmklassiker|Film|Kortfilm|P.skemorg[eo]n|"
    123130                        "Radioteatret|Opera|P2-Akademiet|Nyhetsmorg[eo]n i P2 og Alltid Nyheter:): (.+)"),
    124131      m_noPremiere("\\s+-\\s+(Sesongpremiere|Premiere|premiere)!?$"),
    125       m_Stereo("\\b\\(?[sS]tereo\\)?\\b")
     132      m_Stereo("\\b\\(?[sS]tereo\\)?\\b"),
     133      m_boxerYear("[0-9]{4}"),
     134      m_boxerCountryCode("[A-Z]{3}")
    126135
    127136{
    128137}
    void EITFixUp::Fix(DBEventEIT &event) const  
    180189    if (kFixNO & event.fixup)
    181190        FixNO(event);
    182191
     192    if (kFixBoxer & event.fixup)
     193        FixBoxer(event);
     194
     195    if (kFixBoxerDescCo & event.fixup)
     196        FixBoxerDescriptionCompact(event);
     197
     198    //this one needs to be after kFixBoxerDescCo
     199    if (kFixBoxerDesc & event.fixup)
     200        FixBoxerDescription(event);
     201
    183202    if (kFixNRK_DVBT & event.fixup)
    184203        FixNRK_DVBT(event);
    185204
    void EITFixUp::FixNRK_DVBT(DBEventEIT &event) const  
    17671786    }
    17681787}
    17691788
     1789/** \fn EITFixUp::FixBoxer(DBEventEIT&) const
     1790 *  \brief Use this to clean DVB-T guide in Sweden
     1791 */
     1792void EITFixUp::FixBoxer(DBEventEIT &event) const
     1793{
     1794        if (event.subtitle.length() > 0)
     1795        {
     1796                event.description = event.subtitle + event.description;
     1797                event.subtitle = "";
     1798        }
     1799
     1800        int position = event.title.indexOf("(HD)");
     1801        if (position != -1)
     1802        {
     1803                event.title = event.title.replace("(HD)", "").trimmed();
     1804                event.videoProps |= VID_HDTV;
     1805        }
     1806       
     1807        QStringList strListDesc=event.description.split(".");
     1808        for(int i=0;i<strListDesc.count();i++)
     1809        {
     1810                if(strListDesc[i].contains("HD"))
     1811                {
     1812                        event.videoProps |= VID_HDTV;
     1813                }
     1814                if(strListDesc[i].contains("Textat sid"))
     1815                {
     1816                        event.subtitleType |= SUB_NORMAL;
     1817                }
     1818                if(strListDesc[i].contains(QString::fromUtf8("SÀnds med 5.1 ljud")))
     1819                {
     1820                        event.audioProps |= AUD_DOLBY;
     1821                }
     1822        }
     1823       
     1824        //create seriesId and programId just like mythfilldatabase does with xmltv data
     1825        //this works well because we have good data about season and episodes thanks to the crex boxer infotag descriptor
     1826        CreateProgramID(event);
     1827}
     1828/** \fn EITFixUp::FixBoxerDescriptionCompact(DBEventEIT&) const
     1829 * \brief Extract compact form of category, country, year and possibly subtitle from the description
     1830 */
     1831void EITFixUp::FixBoxerDescriptionCompact(DBEventEIT &event) const
     1832{
     1833        enum descPart
     1834        {
     1835                category,
     1836                country,
     1837                year
     1838        };
     1839
     1840        //needed because it is mostly series that have a subtitle
     1841        //this will also reduce the possibility of a picking bad subtitle
     1842        bool isSeries = (event.syndicatedepisodenumber.contains("E") && event.syndicatedepisodenumber.contains("S"));
     1843       
     1844        //format of the "compact subtitle" at the beginning of the description is
     1845        //a comma separated list have the following fields in this order:
     1846        //zero or more categories
     1847        //one or more 3 character country codes that always is in upper case
     1848        //exactly one 4 digit year
     1849        //optionally a subtitle
     1850       
     1851        QStringList strListCategories;
     1852        //most likely production country
     1853        QStringList strListCountries;
     1854        uint16_t airdate=0;
     1855        QString subtitle="";
     1856
     1857        descPart state=category;
     1858        QStringList strListDescParts=event.description.split(",");
     1859        //character position in description, used to know where to cut the description when we are done
     1860        int pos=0;
     1861        for(int i=0;i<strListDescParts.count();i++)
     1862        {
     1863                pos++;
     1864                pos+=strListDescParts[i].length();
     1865                if(strListDescParts[i].trimmed().isEmpty())
     1866                {
     1867                        continue;
     1868                }
     1869
     1870                //country code and year is easy to detect
     1871                if(strListDescParts[i].trimmed().indexOf(m_boxerCountryCode)==0)
     1872                {
     1873                        strListCountries.append(strListDescParts[i].trimmed());
     1874                        state=country;
     1875                }
     1876                else if(strListDescParts[i].trimmed().indexOf(m_boxerYear)==0)
     1877                {
     1878                        airdate=strListDescParts[i].trimmed().toUShort();
     1879                        state=year;
     1880                }
     1881                else
     1882                {
     1883                        if(state==category)
     1884                        {
     1885                                //this part must be a category
     1886                                strListCategories.append(strListDescParts[i].trimmed());
     1887                                LOG(VB_EIT, LOG_DEBUG, QString("EITFixUp::FixBoxerDescriptionCompact Category: '%1'").arg(strListDescParts[i].trimmed()));
     1888                        }
     1889                        else if(state==year)
     1890                        {
     1891                                //the only thing after the year is the optional subtitle
     1892                                //and there is nothing more to do after this
     1893                                //make sure subtitle is 55 characters or less to avoid
     1894                                //accidentally picking the first sentence of the description
     1895                                if(isSeries && strListDescParts[i].trimmed().length()<=55)
     1896                                {
     1897                                        subtitle=strListDescParts[i].trimmed();
     1898                                }
     1899                                else
     1900                                {
     1901                                        //if we didn't pick up any subtitle at this point we need to move back pos
     1902                                        //so we don't remove this part of the description
     1903                                        pos--;
     1904                                        pos-=strListDescParts[i].length();
     1905                                }
     1906                                break;
     1907                        }
     1908                }
     1909        }
     1910       
     1911        if(!event.description.isEmpty())
     1912        {
     1913                event.description.remove(0,pos+1);
     1914        }
     1915        if(!subtitle.isEmpty())
     1916        {
     1917                event.subtitle=subtitle;
     1918        }
     1919        if(airdate>0 && event.airdate==0)
     1920        {
     1921                event.airdate=airdate;
     1922        }
     1923
     1924        //build the category string
     1925        QString newCategory="";
     1926        if(strListCategories.count()>0 && event.category.isEmpty())
     1927        {
     1928                for(int i=0;i<strListCategories.count();i++)
     1929                {
     1930                        QString tmp=strListCategories[i].trimmed();
     1931                        if(!tmp.isEmpty())
     1932                        {
     1933                                if(i!=0)
     1934                                {
     1935                                        newCategory+="/";
     1936                                }
     1937                                newCategory+=tmp;
     1938                        }
     1939                       
     1940                }
     1941                event.category=newCategory;
     1942        }
     1943}
     1944
     1945/** \fn EITFixUp::FixBoxerDescription(DBEventEIT&) const
     1946 * \brief Extract country, category, and year from the description
     1947 */
     1948void EITFixUp::FixBoxerDescription(DBEventEIT &event) const
     1949{
     1950        //this function is not as reliable as FixBoxerDescriptionCompact but instead works on most channels
     1951        //idealy this code should only run on all channels except those already handled by FixBoxerDescriptionCompact
     1952        //but since that is not easily doable it will only update fields if they are missing and this one should be run last
     1953
     1954        //borrow regex from swedish dvb-c comhem fixup, it is exatly what is needed
     1955        QRegExp tmpCountry = m_comHemCountry;
     1956        int pos = tmpCountry.indexIn(event.description);
     1957        if (pos != -1)
     1958        {
     1959                QStringList list = tmpCountry.capturedTexts();
     1960                QString replacement;
     1961
     1962                // Original title, usually english title
     1963                // note: list[1] contains extra () around the text that needs removing
     1964                if (list[1].length() > 0)
     1965                {
     1966                        replacement = list[1] + " ";
     1967                        //store it somewhere?
     1968                }
     1969
     1970                // Countr(y|ies)
     1971                if (list[2].length() > 0)
     1972                {
     1973                        replacement += list[2] + " ";
     1974                        //store it somewhere?
     1975                }
     1976
     1977                // Category
     1978                if (list[3].length() > 0)
     1979                {
     1980                        replacement += list[3] + ".";
     1981                        if(event.category.isEmpty())
     1982                        {
     1983                                event.category = list[3];
     1984                                if(list[3].indexOf("serie")!=-1)
     1985                                {
     1986                                        event.categoryType = kCategorySeries;
     1987                                }
     1988                        }
     1989                        LOG(VB_EIT, LOG_DEBUG, QString("EITFixUp::FixBoxerDescription Category: '%1'").arg(list[3]));
     1990                }
     1991
     1992                // Year
     1993                if (list[4].length() > 0 && event.airdate==0)
     1994                {
     1995                        bool ok;
     1996                        uint y = list[4].trimmed().toUInt(&ok);
     1997                        if (ok)
     1998                                event.airdate = y;
     1999                }
     2000
     2001                // Remove year and actors.
     2002                // The reason category is left in the description is because otherwise
     2003                // the country would look wierd like "Amerikansk. Rest of description."
     2004                event.description = event.description.replace(list[0],replacement);
     2005        }
     2006}
     2007
     2008void EITFixUp::CreateProgramID(DBEventEIT &event) const
     2009{
     2010        QString season;
     2011        QString episode;
     2012        if(!event.syndicatedepisodenumber.isEmpty())
     2013        {
     2014                QRegExp epnum("E([0-9]+)S([0-9]+)");
     2015                if(epnum.indexIn(event.syndicatedepisodenumber)!=-1)
     2016                {
     2017                        episode=epnum.cap(1);
     2018                        season=epnum.cap(2);
     2019                }
     2020        }
     2021        CreateProgramID(event,season,episode);
     2022}
     2023
     2024/** \fn EITFixUp::CreateProgramID(DBEventEIT&, QString season, QString episode) const
     2025 *  \brief Create seriesId and programId in the same way mythfilldatabase does.
     2026 */
     2027void EITFixUp::CreateProgramID(DBEventEIT &event, QString season, QString episode) const
     2028{
     2029        QString seriesid=QString::number(ELFHash(event.title.toUtf8()));
     2030        event.seriesId=seriesid;
     2031       
     2032        QString programid;
     2033        if(event.categoryType==kCategoryMovie)
     2034        {
     2035                programid="MV";
     2036        }
     2037        else if(event.categoryType==kCategorySeries)
     2038        {
     2039                programid="EP";
     2040        }
     2041        else if(event.categoryType==kCategorySports)
     2042        {
     2043                programid="SP";
     2044        }
     2045        else
     2046        {
     2047                programid="SH";
     2048        }
     2049        programid.append(seriesid);
     2050        if(!episode.isEmpty() && !season.isEmpty())
     2051        {
     2052                int season_int=season.toInt();
     2053                if(season_int > 35)
     2054                {
     2055                        if(event.categoryType!=kCategoryMovie)
     2056                        {
     2057                                programid.clear();
     2058                        }
     2059                }
     2060                else
     2061                {
     2062                        programid.append(episode);
     2063                        programid.append(QString::number(season_int, 36));
     2064                        if(event.partnumber && event.parttotal)
     2065                        {
     2066                                programid+=QString::number(event.partnumber);
     2067                                programid+=QString::number(event.parttotal);
     2068                        }
     2069                }
     2070        }
     2071        else
     2072        {
     2073                if(event.categoryType!=kCategoryMovie)
     2074                {
     2075                        programid.clear();
     2076                }
     2077        }
     2078        //the function AddDVBEITAuthority() converts this string to lower case :-(
     2079        //perhaps it doesn't matter
     2080        event.programId=programid;
     2081}
     2082 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
  • mythtv/programs/mythfilldatabase/xmltvparser.cpp

    diff --git a/mythtv/programs/mythfilldatabase/xmltvparser.cpp b/mythtv/programs/mythfilldatabase/xmltvparser.cpp
    index b3f4456..fdf6445 100644
    a b  
    1111#include <iostream>
    1212#include <cstdlib>
    1313
     14// libmythbase headers
     15#include <unistd.h>
     16#include "mythbaseutil.h"
     17
    1418// libmyth headers
    1519#include "exitcodes.h"
    1620#include "mythcorecontext.h"
    XMLTVParser::XMLTVParser() : isJapan(false), current_year(0)  
    3034    current_year = MythDate::current().date().toString("yyyy").toUInt();
    3135}
    3236
    33 static uint ELFHash(const QByteArray &ba)
    34 {
    35     const uchar *k = (const uchar *)ba.data();
    36     uint h = 0;
    37     uint g;
    38 
    39     if (k)
    40     {
    41         while (*k)
    42         {
    43             h = (h << 4) + *k++;
    44             if ((g = (h & 0xf0000000)) != 0)
    45                 h ^= g >> 24;
    46             h &= ~g;
    47         }
    48     }
    49 
    50     return h;
    51 }
    52 
    5337static QString getFirstText(QDomElement element)
    5438{
    5539    for (QDomNode dname = element.firstChild(); !dname.isNull();