Ticket #8777: dish_descriptors2.diff

File dish_descriptors2.diff, 21.9 KB (added by Mark.Buechler@…, 16 years ago)

Decode DishNet descriptors.

  • libs/libmythtv/mpeg/dishdescriptors.cpp

     
    22
    33#include "dishdescriptors.h"
    44#include "atsc_huffman.h"
     5#include "programinfo.h" // for subtitle types and audio and video properties
    56
    67QString DishEventNameDescriptor::Name(uint compression_type) const
    78{
     
    4142
    4243    return QString::null;
    4344}
     45
     46bool DishEventPropertiesDescriptor::decompressed = false;
     47uint DishEventPropertiesDescriptor::subtitle_props = SUB_UNKNOWN;
     48uint DishEventPropertiesDescriptor::audio_props = AUD_UNKNOWN;
     49
     50uint DishEventPropertiesDescriptor::SubtitleProperties(uint compression_type) const
     51{
     52    decompress_properties(compression_type);
     53
     54    return subtitle_props;
     55}
     56
     57uint DishEventPropertiesDescriptor::AudioProperties(uint compression_type) const
     58{
     59    decompress_properties(compression_type);
     60
     61    return audio_props;
     62}
     63
     64void DishEventPropertiesDescriptor::decompress_properties(uint compression_type) const
     65{
     66    subtitle_props = SUB_UNKNOWN;
     67    audio_props = AUD_UNKNOWN;
     68
     69    if (HasProperties())
     70    {
     71        QString properties_raw = atsc_huffman2_to_string(
     72            _data + 4, DescriptorLength() - 2, compression_type);
     73
     74        if (properties_raw.contains("6|CC"))
     75            subtitle_props |= SUB_HARDHEAR;
     76
     77        if (properties_raw.contains("7|Stereo"))
     78            audio_props    |= AUD_STEREO;
     79    }
     80}
     81
     82QString DishEventTagsDescriptor::programid(void) const
     83{
     84    QString id;
     85
     86    if (DescriptorLength() != 8)
     87        return QString::null;
     88
     89    id.sprintf("%02x%02x%02x%02x%02x%02x%02x", _data[3], _data[4], _data[5],
     90                                               _data[6], _data[7], _data[8],
     91                                               _data[9]);
     92
     93    return id;
     94}
     95
     96QString DishEventTagsDescriptor::seriesid(void) const           
     97{
     98    QString id;
     99
     100    if (DescriptorLength() != 8)
     101        return QString::null;
     102
     103    id.sprintf("%02x%02x%02x%01x", _data[3], _data[4], _data[5],
     104                                   ((_data[6] & 0xf0) >> 0x04));
     105
     106    return id;
     107}
     108
     109QMutex            DishEventMPAADescriptor::mpaaRatingsLock;
     110map<uint,QString> DishEventMPAADescriptor::mpaaRatingsDesc;
     111bool              DishEventMPAADescriptor::mpaaRatingsExists = false;
     112
     113float DishEventMPAADescriptor::stars(void) const
     114{
     115    switch(stars_raw())
     116    {
     117        case 0x01: return 1.0 / 4;
     118        case 0x02: return 1.5 / 4;
     119        case 0x03: return 2.0 / 4;
     120        case 0x04: return 2.5 / 4;
     121        case 0x05: return 3.0 / 4;
     122        case 0x06: return 3.5 / 4;
     123        case 0x07: return 4.0 / 4;
     124    }
     125
     126    return 0.0;
     127}
     128
     129QString DishEventMPAADescriptor::rating(void) const
     130{
     131    if (!mpaaRatingsExists)
     132        Init();
     133
     134    QMutexLocker locker(&mpaaRatingsLock);
     135
     136    map<uint,QString>::const_iterator it = mpaaRatingsDesc.find(rating_raw());
     137    if (it != mpaaRatingsDesc.end())
     138    {
     139        QString ret = (*it).second;
     140        ret.detach();
     141        return ret;
     142    }
     143
     144    // Found nothing? Just return empty string.
     145    return "";
     146}
     147
     148QString DishEventMPAADescriptor::advisory(void) const
     149{
     150    int advisory = advisory_raw();
     151    QStringList advisories;
     152
     153    if (advisory & 0x01)
     154        advisories.append("S");
     155    if (advisory & 0x02)
     156        advisories.append("L");
     157    if (advisory & 0x04)
     158        advisories.append("mQ");
     159    if (advisory & 0x08)
     160        advisories.append("FV");
     161    if (advisory & 0x10)
     162        advisories.append("V");
     163    if (advisory & 0x20)
     164        advisories.append("mK");
     165    if (advisory & 0x40)
     166        advisories.append("N");
     167
     168    return advisories.join(",");
     169}
     170
     171void DishEventMPAADescriptor::Init(void)
     172{
     173    QMutexLocker locker(&mpaaRatingsLock);
     174
     175    if (mpaaRatingsExists)
     176        return;
     177
     178    mpaaRatingsDesc[0x01] = QObject::tr("G");
     179    mpaaRatingsDesc[0x02] = QObject::tr("PG");
     180    mpaaRatingsDesc[0x03] = QObject::tr("PG-13");
     181    mpaaRatingsDesc[0x04] = QObject::tr("R");
     182    mpaaRatingsDesc[0x05] = QObject::tr("NC-17");
     183    mpaaRatingsDesc[0x06] = QObject::tr("NR");
     184
     185    mpaaRatingsExists = true;
     186}
     187
     188QMutex            DishEventVCHIPDescriptor::vchipRatingsLock;
     189map<uint,QString> DishEventVCHIPDescriptor::vchipRatingsDesc;
     190bool              DishEventVCHIPDescriptor::vchipRatingsExists = false;
     191
     192QString DishEventVCHIPDescriptor::rating(void) const
     193{
     194    if (!vchipRatingsExists)
     195        Init();
     196
     197    QMutexLocker locker(&vchipRatingsLock);
     198
     199    map<uint,QString>::const_iterator it = vchipRatingsDesc.find(rating_raw());
     200    if (it != vchipRatingsDesc.end())
     201    {
     202        QString ret = (*it).second;
     203        ret.detach();
     204        return ret;
     205    }
     206
     207    // Found nothing? Just return empty string.
     208    return "";
     209}
     210
     211QString DishEventVCHIPDescriptor::advisory(void) const
     212{
     213    int advisory = advisory_raw();
     214    QStringList advisories;
     215
     216    if (advisory & 0x01)
     217        advisories.append("FV");
     218    if (advisory & 0x02)
     219        advisories.append("V");
     220    if (advisory & 0x04)
     221        advisories.append("S");
     222    if (advisory & 0x08)
     223        advisories.append("L");
     224    if (advisory & 0x10)
     225        advisories.append("D");
     226
     227    return advisories.join(",");
     228}
     229
     230void DishEventVCHIPDescriptor::Init(void)
     231{
     232    QMutexLocker locker(&vchipRatingsLock);
     233
     234    if (vchipRatingsExists)
     235        return;
     236
     237    vchipRatingsDesc[0x01] = QObject::tr("TV-Y");
     238    vchipRatingsDesc[0x02] = QObject::tr("TV-Y7");
     239    vchipRatingsDesc[0x03] = QObject::tr("TV-G");
     240    vchipRatingsDesc[0x04] = QObject::tr("TV-PG");
     241    vchipRatingsDesc[0x05] = QObject::tr("TV-14");
     242    vchipRatingsDesc[0x06] = QObject::tr("TV-MA");
     243
     244    vchipRatingsExists = true;
     245}
     246
     247QMutex            DishContentDescriptor::categoryLock;
     248map<uint,QString> DishContentDescriptor::themeDesc;
     249map<uint,QString> DishContentDescriptor::categoryDesc;
     250bool              DishContentDescriptor::categoriesExists = false;
     251
     252QString dish_theme_type_to_string(uint theme_type)
     253{
     254    static const char *themes[] =
     255        { "", "Movie", "Sports", "News/Business", "Family/Children", "Education",
     256          "Series/Special", "Music/Art", "Religious", "Off-Air" };
     257
     258    if ((theme_type > kThemeNone) && (theme_type < kThemeLast))
     259        return QString(themes[theme_type]);
     260
     261    return "";
     262}
     263
     264DishThemeType string_to_dish_theme_type(const QString &theme_type)
     265{
     266    static const char *themes[] =
     267        { "", "Movie", "Sports", "News/Business", "Family/Children", "Education",
     268          "Series/Special", "Music/Art", "Religious", "Off-Air" };
     269
     270    for (uint i = 1; i < 10; i++)
     271        if (theme_type == themes[i])
     272            return (DishThemeType) i;
     273
     274    return kThemeNone;
     275}
     276
     277DishThemeType DishContentDescriptor::GetTheme(void) const
     278{
     279    if (!categoriesExists)
     280        Init();
     281
     282    if (Nibble1() == 0x00)
     283        return kThemeOffAir;
     284
     285    map<uint,QString>::const_iterator it = themeDesc.find(Nibble2());
     286    if (it != themeDesc.end())
     287        return string_to_dish_theme_type((*it).second);
     288
     289    // Found nothing? Just return empty string.
     290    return kThemeNone;
     291}
     292
     293QString DishContentDescriptor::GetCategory(void) const
     294{
     295    if (!categoriesExists)
     296        Init();
     297
     298    QMutexLocker locker(&categoryLock);
     299
     300    // Try to get detailed description
     301    map<uint,QString>::const_iterator it = categoryDesc.find(UserNibble());
     302    if (it != categoryDesc.end())
     303    {
     304        QString ret = (*it).second;
     305        ret.detach();
     306        return ret;
     307    }
     308
     309    // Fallback to just the theme
     310    QString theme = dish_theme_type_to_string(GetTheme());
     311
     312    if (theme != "")
     313        return theme;
     314
     315    // Found nothing? Just return empty string.
     316    return "";
     317}
     318
     319QString DishContentDescriptor::toString() const
     320{
     321    QString tmp("");
     322    tmp += GetTheme() + " : " + GetCategory();
     323    return tmp;
     324}
     325
     326void DishContentDescriptor::Init(void)
     327{
     328    QMutexLocker locker(&categoryLock);
     329
     330    if (categoriesExists)
     331        return;
     332
     333    // Dish/BEV "Themes"
     334    themeDesc[kThemeMovie]     = QObject::tr("Movie");
     335    themeDesc[kThemeSports]    = QObject::tr("Sports");
     336    themeDesc[kThemeNews]      = QObject::tr("News/Business");
     337    themeDesc[kThemeFamily]    = QObject::tr("Family/Children");
     338    themeDesc[kThemeEducation] = QObject::tr("Education");
     339    themeDesc[kThemeSeries]    = QObject::tr("Series/Special");
     340    themeDesc[kThemeMusic]     = QObject::tr("Music/Art");
     341    themeDesc[kThemeReligious] = QObject::tr("Religious");
     342
     343    // Dish/BEV categories
     344    categoryDesc[0x01] = QObject::tr("Action");
     345    categoryDesc[0x02] = QObject::tr("Adults only");
     346    categoryDesc[0x03] = QObject::tr("Adventure");
     347    categoryDesc[0x04] = QObject::tr("Animals");
     348    categoryDesc[0x05] = QObject::tr("Animated");
     349    categoryDesc[0x07] = QObject::tr("Anthology");
     350    categoryDesc[0x08] = QObject::tr("Art");
     351    categoryDesc[0x09] = QObject::tr("Auto");
     352    categoryDesc[0x0a] = QObject::tr("Awards");
     353    categoryDesc[0x0b] = QObject::tr("Ballet");
     354    categoryDesc[0x0c] = QObject::tr("Baseball");
     355    categoryDesc[0x0d] = QObject::tr("Basketball");
     356    categoryDesc[0x11] = QObject::tr("Biography");
     357    categoryDesc[0x12] = QObject::tr("Boat");
     358    categoryDesc[0x14] = QObject::tr("Bowling");
     359    categoryDesc[0x15] = QObject::tr("Boxing");
     360    categoryDesc[0x16] = QObject::tr("Bus./financial");
     361    categoryDesc[0x1a] = QObject::tr("Children");
     362    categoryDesc[0x1b] = QObject::tr("Children-special");
     363    categoryDesc[0x1c] = QObject::tr("Children-news");
     364    categoryDesc[0x1d] = QObject::tr("Children-music");
     365    categoryDesc[0x1f] = QObject::tr("Collectibles");
     366    categoryDesc[0x20] = QObject::tr("Comedy");
     367    categoryDesc[0x21] = QObject::tr("Comedy-drama");
     368    categoryDesc[0x22] = QObject::tr("Computers");
     369    categoryDesc[0x23] = QObject::tr("Cooking");
     370    categoryDesc[0x24] = QObject::tr("Crime");
     371    categoryDesc[0x25] = QObject::tr("Crime drama");
     372    categoryDesc[0x27] = QObject::tr("Dance");
     373    categoryDesc[0x29] = QObject::tr("Docudrama");
     374    categoryDesc[0x2a] = QObject::tr("Documentary");
     375    categoryDesc[0x2b] = QObject::tr("Drama");
     376    categoryDesc[0x2c] = QObject::tr("Educational");
     377    categoryDesc[0x2f] = QObject::tr("Excercise");
     378    categoryDesc[0x31] = QObject::tr("Fantasy");
     379    categoryDesc[0x32] = QObject::tr("Fasion");
     380    categoryDesc[0x34] = QObject::tr("Fishing");
     381    categoryDesc[0x35] = QObject::tr("Football");
     382    categoryDesc[0x36] = QObject::tr("French");
     383    categoryDesc[0x37] = QObject::tr("Fundraiser");
     384    categoryDesc[0x38] = QObject::tr("Game show");
     385    categoryDesc[0x39] = QObject::tr("Golf");
     386    categoryDesc[0x3a] = QObject::tr("Gymnastics");
     387    categoryDesc[0x3b] = QObject::tr("Health");
     388    categoryDesc[0x3c] = QObject::tr("History");
     389    categoryDesc[0x3d] = QObject::tr("Historical drama");
     390    categoryDesc[0x3e] = QObject::tr("Hockey");
     391    categoryDesc[0x3f] = QObject::tr("Holiday");
     392    categoryDesc[0x40] = QObject::tr("Holiday-children");
     393    categoryDesc[0x41] = QObject::tr("Holiday-children special");
     394    categoryDesc[0x44] = QObject::tr("Holiday special");
     395    categoryDesc[0x45] = QObject::tr("Horror");
     396    categoryDesc[0x46] = QObject::tr("Horse racing");
     397    categoryDesc[0x47] = QObject::tr("House/garden");
     398    categoryDesc[0x49] = QObject::tr("How-to");
     399    categoryDesc[0x4b] = QObject::tr("Interview");
     400    categoryDesc[0x4d] = QObject::tr("Lacrosse");
     401    categoryDesc[0x4f] = QObject::tr("Martial Arts");
     402    categoryDesc[0x50] = QObject::tr("Medical");
     403    categoryDesc[0x51] = QObject::tr("Miniseries");
     404    categoryDesc[0x52] = QObject::tr("Motorsports");
     405    categoryDesc[0x53] = QObject::tr("Motorcycle");
     406    categoryDesc[0x54] = QObject::tr("Music");
     407    categoryDesc[0x55] = QObject::tr("Music special");
     408    categoryDesc[0x56] = QObject::tr("Music talk");
     409    categoryDesc[0x57] = QObject::tr("Musical");
     410    categoryDesc[0x58] = QObject::tr("Musical comedy");
     411    categoryDesc[0x5a] = QObject::tr("Mystery");
     412    categoryDesc[0x5b] = QObject::tr("Nature");
     413    categoryDesc[0x5c] = QObject::tr("News");
     414    categoryDesc[0x5f] = QObject::tr("Opera");
     415    categoryDesc[0x60] = QObject::tr("Outdoors");
     416    categoryDesc[0x63] = QObject::tr("Public affairs");
     417    categoryDesc[0x66] = QObject::tr("Reality");
     418    categoryDesc[0x67] = QObject::tr("Religious");
     419    categoryDesc[0x68] = QObject::tr("Rodeo");
     420    categoryDesc[0x69] = QObject::tr("Romance");
     421    categoryDesc[0x6a] = QObject::tr("Romance-comedy");
     422    categoryDesc[0x6b] = QObject::tr("Rugby");
     423    categoryDesc[0x6c] = QObject::tr("Running");
     424    categoryDesc[0x6e] = QObject::tr("Science");
     425    categoryDesc[0x6f] = QObject::tr("Science fiction");
     426    categoryDesc[0x70] = QObject::tr("Self improvement");
     427    categoryDesc[0x71] = QObject::tr("Shopping");
     428    categoryDesc[0x74] = QObject::tr("Skiing");
     429    categoryDesc[0x77] = QObject::tr("Soap");
     430    categoryDesc[0x7b] = QObject::tr("Soccor");
     431    categoryDesc[0x7c] = QObject::tr("Softball");
     432    categoryDesc[0x7d] = QObject::tr("Spanish");
     433    categoryDesc[0x7e] = QObject::tr("Special");
     434    categoryDesc[0x81] = QObject::tr("Sports non-event");
     435    categoryDesc[0x82] = QObject::tr("Sports talk");
     436    categoryDesc[0x83] = QObject::tr("Suspense");
     437    categoryDesc[0x85] = QObject::tr("Swimming");
     438    categoryDesc[0x86] = QObject::tr("Talk");
     439    categoryDesc[0x87] = QObject::tr("Tennis");
     440    categoryDesc[0x89] = QObject::tr("Track/field");
     441    categoryDesc[0x8a] = QObject::tr("Travel");
     442    categoryDesc[0x8b] = QObject::tr("Variety");
     443    categoryDesc[0x8c] = QObject::tr("Volleyball");
     444    categoryDesc[0x8d] = QObject::tr("War");
     445    categoryDesc[0x8e] = QObject::tr("Watersports");
     446    categoryDesc[0x8f] = QObject::tr("Weather");
     447    categoryDesc[0x90] = QObject::tr("Western");
     448    categoryDesc[0x92] = QObject::tr("Wrestling");
     449    categoryDesc[0x93] = QObject::tr("Yoga");
     450    categoryDesc[0x94] = QObject::tr("Agriculture");
     451    categoryDesc[0x95] = QObject::tr("Anime");
     452    categoryDesc[0x97] = QObject::tr("Arm Wrestling");
     453    categoryDesc[0x98] = QObject::tr("Arts/crafts");
     454    categoryDesc[0x99] = QObject::tr("Auction");
     455    categoryDesc[0x9a] = QObject::tr("Auto racing");
     456    categoryDesc[0x9b] = QObject::tr("Air racing");
     457    categoryDesc[0x9c] = QObject::tr("Badminton");
     458    categoryDesc[0xa0] = QObject::tr("Bicycle racing");
     459    categoryDesc[0xa1] = QObject::tr("Boat Racing");
     460    categoryDesc[0xa6] = QObject::tr("Community");
     461    categoryDesc[0xa7] = QObject::tr("Consumer");
     462    categoryDesc[0xaa] = QObject::tr("Debate");
     463    categoryDesc[0xac] = QObject::tr("Dog show");
     464    categoryDesc[0xad] = QObject::tr("Drag racing");
     465    categoryDesc[0xae] = QObject::tr("Entertainment");
     466    categoryDesc[0xaf] = QObject::tr("Environment");
     467    categoryDesc[0xb0] = QObject::tr("Equestrian");
     468    categoryDesc[0xb3] = QObject::tr("Field hockey");
     469    categoryDesc[0xb5] = QObject::tr("Football");
     470    categoryDesc[0xb6] = QObject::tr("Gay/lesbian");
     471    categoryDesc[0xb7] = QObject::tr("Handball");
     472    categoryDesc[0xb8] = QObject::tr("Home improvement");
     473    categoryDesc[0xb9] = QObject::tr("Hunting");
     474    categoryDesc[0xbb] = QObject::tr("Hydroplane racing");
     475    categoryDesc[0xc1] = QObject::tr("Law");
     476    categoryDesc[0xc3] = QObject::tr("Motorcycle racing");
     477    categoryDesc[0xc5] = QObject::tr("Newsmagazine");
     478    categoryDesc[0xc7] = QObject::tr("Paranormal");
     479    categoryDesc[0xc8] = QObject::tr("Parenting");
     480    categoryDesc[0xca] = QObject::tr("Performing arts");
     481    categoryDesc[0xcc] = QObject::tr("Politics");
     482    categoryDesc[0xcf] = QObject::tr("Pro wrestling");
     483    categoryDesc[0xd3] = QObject::tr("Sailing");
     484    categoryDesc[0xd4] = QObject::tr("Shooting");
     485    categoryDesc[0xd5] = QObject::tr("Sitcom");
     486    categoryDesc[0xd6] = QObject::tr("Skateboarding");
     487    categoryDesc[0xd9] = QObject::tr("Snowboarding");
     488    categoryDesc[0xdd] = QObject::tr("Standup");
     489    categoryDesc[0xdf] = QObject::tr("Surfing");
     490    categoryDesc[0xe0] = QObject::tr("Tennis");
     491    categoryDesc[0xe1] = QObject::tr("Triathlon");
     492    categoryDesc[0xe6] = QObject::tr("Card games");
     493    categoryDesc[0xe7] = QObject::tr("Poker");
     494    categoryDesc[0xea] = QObject::tr("Military");
     495    categoryDesc[0xeb] = QObject::tr("Technology");
     496    categoryDesc[0xec] = QObject::tr("Mixed martial arts");
     497    categoryDesc[0xed] = QObject::tr("Action sports");
     498    categoryDesc[0xff] = QObject::tr("Dish Network");
     499
     500    categoriesExists = true;
     501}
     502
     503
  • libs/libmythtv/mpeg/dishdescriptors.h

     
    44#define _DISH_DESCRIPTORS_H_
    55
    66#include <cassert>
     7#include <map>
    78
     9#include <qmutex.h>
    810#include <QString>
    911
    1012#include "atscdescriptors.h"
    1113
     14class DishEventMPAADescriptor : public MPEGDescriptor
     15{
     16  public:
     17    DishEventMPAADescriptor(const unsigned char* data)
     18        : MPEGDescriptor(data)
     19    {
     20    //       Name             bits  loc  expected value
     21    // descriptor_tag           8   0.0       0x89
     22        assert(DescriptorID::dish_event_mpaa == DescriptorTag());
     23    // descriptor_length        8   1.0
     24    }
     25    // stars                    3   2.0
     26    uint stars_raw(void) const { return (_data[2] & 0xe0) >> 0x05; }
     27    float stars(void) const;
     28
     29    // rating                   3   2.3
     30    uint rating_raw(void) const { return (_data[2] & 0x1c) >> 0x02; }
     31    QString rating(void) const;
     32
     33    // advisories               8   3.0
     34    uint advisory_raw(void) const { return _data[3]; }
     35    QString advisory(void) const;
     36
     37  private:
     38    static void Init(void);
     39
     40  private:
     41    static QMutex            mpaaRatingsLock;
     42    static map<uint,QString> mpaaRatingsDesc;
     43    static bool              mpaaRatingsExists;
     44};
     45
     46class DishEventVCHIPDescriptor : public MPEGDescriptor
     47{
     48  public:
     49    DishEventVCHIPDescriptor(const unsigned char* data)
     50        : MPEGDescriptor(data)               
     51    {
     52    //       Name             bits  loc  expected value
     53    // descriptor_tag           8   0.0       0x95
     54        assert(DescriptorID::dish_event_vchip == DescriptorTag());
     55    // descriptor_length        8   1.0
     56    }
     57    // rating                   8   2.0
     58    uint rating_raw(void) const { return _data[2]; }
     59    QString rating(void) const;
     60
     61    // advisory                 8   3.0
     62    uint advisory_raw(void) const { return _data[3]; }
     63    QString advisory(void) const;
     64
     65  private:
     66    static void Init(void);
     67
     68  private:
     69    static QMutex            vchipRatingsLock;
     70    static map<uint,QString> vchipRatingsDesc;
     71    static bool              vchipRatingsExists;
     72};
     73
    1274class DishEventNameDescriptor : public MPEGDescriptor
    1375{
    1476  public:
     
    45107    QString Description(uint) const;
    46108};
    47109
     110class DishEventPropertiesDescriptor : public MPEGDescriptor
     111{
     112  public:
     113    DishEventPropertiesDescriptor(const unsigned char* data)
     114        : MPEGDescriptor(data)
     115    {
     116    //       Name             bits  loc  expected value
     117    // descriptor_tag           8   0.0       0x94
     118        assert(DescriptorID::dish_event_properties == DescriptorTag());
     119    // descriptor_length        8   1.0
     120    }
     121    // unknown                  8   2.0
     122    // event_name            dlen-1 3.0
     123    bool HasProperties(void) const { return DescriptorLength() > 1; }
     124    uint SubtitleProperties(uint compression_type) const;
     125    uint AudioProperties(uint compression_type) const;
     126
     127  private:
     128    void decompress_properties(uint compression_type) const;
     129
     130  private:
     131    static uint subtitle_props;
     132    static uint audio_props;
     133    static bool decompressed;
     134};
     135
     136class DishEventTagsDescriptor : public MPEGDescriptor
     137{
     138  public:
     139    DishEventTagsDescriptor(const unsigned char* data)
     140        : MPEGDescriptor(data)
     141    {
     142    //       Name             bits  loc  expected value
     143    // descriptor_tag           8   0.0       0x96
     144        assert(DescriptorID::dish_event_tags == DescriptorTag());
     145    // descriptor_length        8   1.0
     146    }
     147    // unknown                  8   2.0
     148    // seriesid                 28  3.0
     149    QString seriesid(void) const;
     150
     151    // programid                42  3.0
     152    QString programid(void) const;
     153};
     154
     155typedef enum
     156{
     157    kThemeNone = 0,
     158    kThemeMovie,
     159    kThemeSports,
     160    kThemeNews,
     161    kThemeFamily,
     162    kThemeEducation,
     163    kThemeSeries,
     164    kThemeMusic,
     165    kThemeReligious,
     166    kThemeOffAir,
     167    kThemeLast,
     168} DishThemeType;
     169
     170QString dish_theme_type_to_string(uint category_type);
     171DishThemeType string_to_dish_theme_type(const QString &type);
     172
     173class DishContentDescriptor : public MPEGDescriptor
     174{
     175  public:
     176    DishContentDescriptor(const unsigned char* data) : MPEGDescriptor(data)
     177    {
     178    //       Name             bits  loc  expected value
     179    // descriptor_tag           8   0.0       0x54
     180        assert(DescriptorID::content == DescriptorTag());
     181    // descriptor_length        8   1.0
     182    }
     183
     184    //   content_nibble_level_1 4   0.0
     185    uint Nibble1(void)       const { return _data[2] >> 4; }
     186    //   content_nibble_level_2 4   0.4
     187    uint Nibble2(void)       const { return _data[2] & 0xf; }
     188
     189    uint Nibble(void)        const { return _data[2]; }
     190
     191    //   user_nibble            4   1.0
     192    uint UserNibble1(void)   const { return _data[3] >> 4; }
     193    //   user_nibble            4   1.4
     194    uint UserNibble2(void)   const { return _data[3] & 0xf; }
     195    uint UserNibble(void)    const { return _data[3]; }
     196    // }                            2.0
     197
     198    DishThemeType GetTheme(void) const;
     199    QString GetCategory(void) const;
     200    QString toString() const;
     201
     202  private:
     203    static void Init(void);
     204
     205  private:
     206    static QMutex            categoryLock;
     207    static map<uint,QString> themeDesc;
     208    static map<uint,QString> categoryDesc;
     209    static bool              categoriesExists;
     210};
     211
    48212#endif // _DISH_DESCRIPTORS_H_