Ticket #5570: 5570-mhi-v4.patch

File 5570-mhi-v4.patch, 17.7 KB (added by danielk, 16 years ago)

MHEG portion remaining

  • libs/libmythtv/mhi.h

     
    88#include <ft2build.h>
    99#include FT_FREETYPE_H
    1010
     11// STL headers
     12#include <list>
     13using namespace std;
     14
    1115// Qt headers
    12 #include <qmutex.h>
    13 #include <q3cstring.h>
    14 #include <qstring.h>
    15 #include <q3ptrlist.h>
    16 #include <qwaitcondition.h>
    17 #include <qimage.h>
    18 #include <q3valuelist.h>
    19 #include <q3ptrqueue.h>
    20 #include <Q3PointArray>
    21 #include <Q3MemArray>
     16#include <QMutex>
     17#include <QString>
     18#include <QWaitCondition>
     19#include <QImage>
     20#include <q3pointarray.h>
    2221
    2322// MythTV headers
    2423#include "../libmythfreemheg/freemheg.h"
     
    2827#include "mythcontext.h"
    2928#include "mythdbcon.h"
    3029#include "NuppelVideoPlayer.h"
     30#include "mythdeque.h"
    3131
    3232extern "C" {
    3333#include "../libavcodec/avcodec.h" // to decode single MPEG I-frames
     
    143143    void RunMHEGEngine(void);
    144144    void ProcessDSMCCQueue(void);
    145145    void NetworkBootRequested(void);
     146    void ClearDisplay(void);
     147    void ClearQueue(void);
    146148
    147149    InteractiveTV   *m_parent;
    148150
    149151    Dsmcc           *m_dsmcc;  // Pointer to the DSMCC object carousel.
    150152    QMutex           m_dsmccLock;
    151     Q3PtrQueue<DSMCCPacket> m_dsmccQueue;
     153    MythDeque<DSMCCPacket*> m_dsmccQueue;
    152154
    153155    QMutex           m_keyLock;
    154     Q3ValueList<int>  m_keyQueue;
     156    MythDeque<int>   m_keyQueue;
    155157    int              m_keyProfile;
    156158
    157159    MHEG            *m_engine; // Pointer to the MHEG engine
     
    165167    int              m_displayHeight;
    166168
    167169
    168     Q3PtrList<MHIImageData> m_display; // List of items to display
     170    list<MHIImageData*> m_display; // List of items to display
    169171
    170172    FT_Face          m_face;
    171173    bool             m_face_loaded;
     
    181183    int              m_tuningTo;
    182184
    183185    uint             m_lastNbiVersion;
    184     Q3MemArray<unsigned char> m_nbiData;
     186    vector<unsigned char> m_nbiData;
    185187};
    186188
    187189// Object for drawing text.
  • libs/libmythtv/mhi.cpp

     
    11#include <unistd.h>
    22
     3#include <QRegion>
    34#include <qbitarray.h>
    45
    56#include "mhi.h"
     
    3940      m_audioTag(-1),       m_videoTag(-1),
    4041      m_tuningTo(-1),       m_lastNbiVersion(NBI_VERSION_UNSET)
    4142{
    42     m_display.setAutoDelete(true);
    43     m_dsmccQueue.setAutoDelete(true);
    44 
    4543    if (!ft_loaded)
    4644    {
    4745        FT_Error error = FT_Init_FreeType(&ft_library);
     
    9492    delete(m_engine);
    9593    delete(m_dsmcc);
    9694    if (m_face_loaded) FT_Done_Face(m_face);
     95
     96    ClearDisplay();
     97    ClearQueue();
    9798}
    9899
     100void MHIContext::ClearDisplay(void)
     101{
     102    list<MHIImageData*>::iterator it = m_display.begin();
     103    for (; it != m_display.end(); ++it)
     104        delete *it;
     105    m_display.clear();
     106}
     107
     108void MHIContext::ClearQueue(void)
     109{
     110    MythDeque<DSMCCPacket*>::iterator it = m_dsmccQueue.begin();
     111    for (; it != m_dsmccQueue.end(); ++it)
     112        delete *it;
     113    m_dsmccQueue.clear();
     114}
     115
    99116// Ask the engine to stop and block until it has.
    100117void MHIContext::StopEngine()
    101118{
     
    129146        {
    130147            QMutexLocker locker(&m_dsmccLock);
    131148            m_dsmcc->Reset();
    132             m_dsmccQueue.clear();
     149            ClearQueue();
    133150        }
    134151    }
    135152    else
     
    142159        {
    143160            QMutexLocker locker(&m_dsmccLock);
    144161            m_dsmcc->Reset();
    145             m_dsmccQueue.clear();
     162            ClearQueue();
    146163        }
    147164
    148165        {
     
    154171            m_engine = MHCreateEngine(this);
    155172
    156173        m_engine->SetBooting();
    157         m_display.clear();
     174        ClearDisplay();
    158175        m_updated = true;
    159176        m_stop = false;
    160177        m_isLive = isLive;
     
    196213            ProcessDSMCCQueue();
    197214            {
    198215                QMutexLocker locker(&m_keyLock);
    199                 if (m_keyQueue.empty())
    200                     key = 0;
    201                 else
    202                 {
    203                     key = m_keyQueue.last();
    204                     m_keyQueue.pop_back();
    205                 }
     216                key = m_keyQueue.dequeue();
    206217            }
    207218
    208219            if (key != 0)
     
    268279    if (length < 2) return; // Temporary hack? -- dtk May 5th, 2008.
    269280    QMutexLocker locker(&m_dsmccLock);
    270281    // Save the data from the descriptor.
    271     m_nbiData.duplicate(data, length);
     282    m_nbiData.resize(0);
     283    m_nbiData.reserve(length);
     284    m_nbiData.insert(m_nbiData.begin(), data, data+length);
    272285    // If there is no Network Boot Info or we're setting it
    273286    // for the first time just update the "last version".
    274287    if (length < 2)
     
    289302        {
    290303            m_dsmcc->Reset();
    291304            m_engine->SetBooting();
    292             m_display.clear();
     305            ClearDisplay();
    293306            m_updated = true;
    294307        }
    295308        // TODO: else if it is 2 generate an EngineEvent.
     
    404417
    405418    if (action != 0)
    406419    {
    407         m_keyQueue.push_front(action);
     420        m_keyQueue.enqueue(action);
    408421        VERBOSE(VB_IMPORTANT, "Adding MHEG key "<<key<<":"<<action
    409422                <<":"<<m_keyQueue.size());
    410423        m_engine_wait.wakeAll();
     
    435448    m_updated = false;
    436449    osdSet->Clear();
    437450    // Copy all the display items into the display.
    438     for (MHIImageData *data = m_display.first(); data;
    439          data = m_display.next())
     451    list<MHIImageData*>::iterator it = m_display.begin();
     452    for (; it != m_display.end(); ++it)
    440453    {
     454        MHIImageData *data = *it;
    441455        OSDTypeImage* image = new OSDTypeImage();
    442456        image->SetPosition(QPoint(data->m_x, data->m_y), 1.0, 1.0);
    443457        image->Load(data->m_image);
     
    458472void MHIContext::RequireRedraw(const QRegion &)
    459473{
    460474    m_display_lock.lock();
    461     m_display.clear();
     475    ClearDisplay();
    462476    m_display_lock.unlock();
    463477    // Always redraw the whole screen
    464478    m_engine->DrawDisplay(QRegion(0, 0, StdDisplayWidth, StdDisplayHeight));
     
    472486    data->m_x = x;
    473487    data->m_y = y;
    474488    QMutexLocker locker(&m_display_lock);
    475     m_display.append(data);
     489    m_display.push_back(data);
    476490}
    477491
    478492// In MHEG the video is just another item in the display stack
     
    494508                      dispRect.width() * m_displayWidth/StdDisplayWidth,
    495509                      dispRect.height() * m_displayHeight/StdDisplayHeight);
    496510
    497     for (uint i = 0; i < m_display.count(); i++)
     511    list<MHIImageData*>::iterator it = m_display.begin();
     512    for (; it != m_display.end(); ++it)
    498513    {
    499         MHIImageData *data = m_display.at(i);
     514        MHIImageData *data = *it;
    500515        QRect imageRect(data->m_x, data->m_y,
    501516                        data->m_image.width(), data->m_image.height());
    502517        if (displayRect.intersects(imageRect))
    503518        {
    504519            // Replace this item with a set of cut-outs.
    505             (void)m_display.take(i--);
    506             Q3MemArray<QRect> rects = (QRegion(imageRect)
    507                                       - QRegion(displayRect)).rects();
    508             for (uint j = 0; j < rects.size(); j++)
     520            it = m_display.erase(it);
     521
     522            QVector<QRect> rects =
     523                (QRegion(imageRect) - QRegion(displayRect)).rects();
     524            for (uint j = 0; j < (uint)rects.size(); j++)
    509525            {
    510526                QRect &rect = rects[j];
    511527                QImage image =
     
    515531                newData->m_image = image;
    516532                newData->m_x = rect.x();
    517533                newData->m_y = rect.y();
    518                 m_display.insert(++i, newData);
     534                m_display.insert(it, newData);
     535                ++it;
    519536            }
    520             delete(data);
     537            delete data;
    521538        }
    522539    }
    523540}
  • libs/libmythtv/dsmccobjcarousel.cpp

     
    2222      m_moduleSize(info->module_size), m_receivedData(0),
    2323      m_completed(false)
    2424{
    25     m_blocks.setAutoDelete(true);
    26 
    2725    // The number of blocks needed to hold this module.
    2826    int num_blocks = (m_moduleSize + dii->block_size - 1) / dii->block_size;
    29     m_blocks.fill(NULL, num_blocks); // Set it to all zeros
     27    m_blocks.resize(num_blocks, NULL); // Set it to all zeros
    3028
    3129    // Copy the descriptor information.
    3230    m_descriptorData = info->modinfo.descriptorData;
    3331}
    3432
     33DSMCCCacheModuleData::~DSMCCCacheModuleData()
     34{
     35    vector<QByteArray*>::iterator it = m_blocks.begin();
     36    for (; it != m_blocks.end(); ++it)
     37        delete *it;
     38    m_blocks.clear();
     39}
     40
    3541/** \fn DSMCCCacheModuleData::AddModuleData(DsmccDb*,const unsigned char*)
    3642 *  \brief Add block to the module and create the module if it's now complete.
    3743 *  \return data for the module if it is complete, NULL otherwise.
     
    6470        QByteArray *block = new QByteArray;
    6571        block->duplicate((char*) data, ddb->len);
    6672        // Add this to our set of blocks.
    67         m_blocks.insert(ddb->block_number, block);
     73        m_blocks[ddb->block_number] = block;
    6874        m_receivedData += ddb->len;
    6975    }
    7076
     
    9096        uint size = block->size();
    9197        memcpy(tmp_data + curp, block->data(), size);
    9298        curp += size;
     99        delete block;
    93100    }
    94101    m_blocks.clear(); // No longer required: free the space.
    95102
     
    126133ObjCarousel::ObjCarousel(Dsmcc *dsmcc)
    127134    : filecache(dsmcc), m_id(0)
    128135{
    129     m_Cache.setAutoDelete(true);
    130136}
    131137
     138ObjCarousel::~ObjCarousel()
     139{
     140    QLinkedList<DSMCCCacheModuleData*>::iterator it = m_Cache.begin();
     141    for (; it != m_Cache.end(); ++it)
     142        delete *it;
     143    m_Cache.clear();
     144}
     145
    132146void ObjCarousel::AddModuleInfo(DsmccDii *dii, Dsmcc *status,
    133147                                unsigned short streamTag)
    134148{
    135149    for (int i = 0; i < dii->number_modules; i++)
    136150    {
    137         DSMCCCacheModuleData *cachep;
    138151        DsmccModuleInfo *info = &(dii->modules[i]);
    139152        // Do we already know this module?
    140153        // If so and it is the same version we don't need to do anything.
    141154        // If the version has changed we have to replace it.
    142         for (cachep = m_Cache.first(); cachep; cachep = m_Cache.next())
     155        QLinkedList<DSMCCCacheModuleData*>::iterator it = m_Cache.begin();
     156        for ( ; it != m_Cache.end(); ++it)
    143157        {
     158            DSMCCCacheModuleData *cachep = *it;
    144159            if (cachep->CarouselId() == dii->download_id &&
    145160                    cachep->ModuleId() == info->module_id)
    146161            {
     
    168183                        .arg(info->module_id));
    169184
    170185                // Remove and delete the cache object.
    171                 m_Cache.remove();
     186                m_Cache.erase(it);
     187                delete cachep;
    172188                break;
    173189            }
    174190        }
     
    177193                .arg(dii->modules[i].module_id));
    178194
    179195        // Create a new cache module data object.
    180         cachep = new DSMCCCacheModuleData(dii, info, streamTag);
     196        DSMCCCacheModuleData *cachep = new DSMCCCacheModuleData(dii, info, streamTag);
    181197
    182198        int tag = info->modinfo.tap.assoc_tag;
    183199        VERBOSE(VB_DSMCC, QString("[dsmcc] Module info tap "
     
    203219    VERBOSE(VB_DSMCC, QString("[dsmcc] Data block on carousel %1").arg(m_id));
    204220
    205221    // Search the saved module info for this module
    206     Q3PtrListIterator<DSMCCCacheModuleData> it(m_Cache);
    207     DSMCCCacheModuleData *cachep;
    208     for (; (cachep = it.current()) != 0; ++it)
     222    QLinkedList<DSMCCCacheModuleData*>::iterator it = m_Cache.begin();
     223    DSMCCCacheModuleData *cachep = NULL;
     224    for (; it != m_Cache.end(); ++it)
    209225    {
     226        cachep = *it;
    210227        if (cachep->CarouselId() == carousel &&
    211228            (cachep->ModuleId() == ddb->module_id))
    212229        {
  • libs/libmythtv/dsmccobjcarousel.h

     
    55#ifndef DSMCC_OBJCAROUSEL_H
    66#define DSMCC_OBJCAROUSEL_H
    77
     8#include <QLinkedList>
    89
    9 #include <q3ptrlist.h>
    10 #include <q3valuevector.h>
    11 #include <q3cstring.h>
    12 #include <q3ptrvector.h>
     10#include <vector>
     11using namespace std;
    1312
    1413class DsmccDii;
    1514class Dsmcc;
     
    2827  public:
    2928    DSMCCCacheModuleData(DsmccDii *dii, DsmccModuleInfo *info,
    3029                    unsigned short streamTag);
     30    ~DSMCCCacheModuleData();
    3131
    3232    unsigned char *AddModuleData(DsmccDb *ddb, const unsigned char *Data);
    3333
     
    5555    unsigned long  m_receivedData; ///< Size received so far.
    5656
    5757    /// Block table.  As blocks are received they are added to this table.
    58     Q3PtrVector<QByteArray> m_blocks;
     58    vector<QByteArray*> m_blocks;
    5959    /// True if we have completed this module.
    6060    bool                   m_completed;
    6161    ModuleDescriptorData   m_descriptorData;
     
    6565{
    6666  public:
    6767    ObjCarousel(Dsmcc*);
     68    ~ObjCarousel();
    6869    void AddModuleInfo(DsmccDii *dii, Dsmcc *status, unsigned short streamTag);
    6970    void AddModuleData(unsigned long carousel, DsmccDb *ddb,
    7071                       const unsigned char *data);
    7172
    7273    DSMCCCache                     filecache;
    73     Q3PtrList<DSMCCCacheModuleData> m_Cache;
     74    QLinkedList<DSMCCCacheModuleData*> m_Cache;
    7475    /// Component tags matched to this carousel.
    75     Q3ValueVector<unsigned short>   m_Tags;
     76    vector<unsigned short>         m_Tags;
    7677    unsigned long                  m_id;
    7778};
    7879
  • libs/libmythtv/dsmcc.h

     
    55#ifndef LIBDSMCC_H
    66#define LIBDSMCC_H
    77
    8 #include <q3ptrlist.h>
    9 #include <qstringlist.h>
     8#include <QLinkedList>
     9#include <QStringList>
    1010
    1111#include "dsmccreceiver.h"
    1212#include "dsmccobjcarousel.h"
     
    7676{
    7777  public:
    7878    Dsmcc();
     79    ~Dsmcc();
    7980    // Reset the object carousel and clear the caches.
    8081    void Reset();
    8182    // Process an incoming DSMCC carousel table
     
    107108    ObjCarousel *GetCarouselById(unsigned int carId);
    108109
    109110    // Known carousels.
    110     Q3PtrList<ObjCarousel> carousels;
     111    QLinkedList<ObjCarousel*> carousels;
    111112
    112113    // Initial stream
    113114    unsigned short m_startTag;
  • libs/libmythtv/dsmcc.cpp

     
    3535
    3636Dsmcc::Dsmcc()
    3737{
    38     carousels.setAutoDelete(true);
    3938    m_startTag = 0;
    4039}
    4140
     41Dsmcc::~Dsmcc()
     42{
     43    Reset();
     44}
     45
    4246/** \fn Dsmcc::GetCarouselById(unsigned int)
    4347 *  \brief Returns a carousel with the given ID.
    4448 */
    4549ObjCarousel *Dsmcc::GetCarouselById(unsigned int carouselId)
    4650{
    47     Q3PtrListIterator<ObjCarousel> it(carousels);
    48     ObjCarousel *car;
     51    QLinkedList<ObjCarousel*>::iterator it = carousels.begin();
    4952
    50     for (; (car = it.current()) != NULL; ++it)
     53    for (; it != carousels.end(); ++it)
    5154    {
    52         if (car->m_id == carouselId)
     55        ObjCarousel *car = *it;
     56        if (car && car->m_id == carouselId)
    5357            return car;
    5458    }
    5559    return NULL;
     
    7781    }
    7882
    7983    // Add this only if it's not already there.
    80     Q3ValueVector<unsigned short>::iterator it;
     84    vector<unsigned short>::iterator it;
    8185    for (it = car->m_Tags.begin(); it != car->m_Tags.end(); ++it)
    8286    {
    8387        if (*it == componentTag)
     
    8690
    8791    if (it == car->m_Tags.end())
    8892    { // Not there.
    89         car->m_Tags.append(componentTag);
     93        car->m_Tags.push_back(componentTag);
    9094        VERBOSE(VB_DSMCC, QString("[dsmcc] Adding tap for stream "
    9195                                  "tag %1 with carousel %2")
    9296                .arg(componentTag).arg(carouselId));
     
    385389                           int dataBroadcastId)
    386390{
    387391    // Does this component tag match one of our carousels?
    388     Q3PtrListIterator<ObjCarousel> it(carousels);
    389     ObjCarousel *car;
     392    QLinkedList<ObjCarousel*>::iterator it = carousels.begin();
     393    ObjCarousel *car = NULL;
    390394
    391395    VERBOSE(VB_DSMCC, QString("[dsmcc] Read block size %1 from tag %2 "
    392396                              "carousel id %3 data broadcast Id %4")
     
    394398            .arg(carouselId).arg(dataBroadcastId));
    395399
    396400    bool found = false;
    397     for (; (car = it.current()) != NULL; ++it)
     401    for (; it != carousels.end(); ++it)
    398402    {
     403        car = *it;
    399404        // Is the component tag one of the ones we know?
    400         Q3ValueVector<unsigned short>::iterator it;
    401         for (it = car->m_Tags.begin(); it != car->m_Tags.end(); ++it)
     405        vector<unsigned short>::iterator it2;
     406        for (it2 = car->m_Tags.begin(); it2 != car->m_Tags.end(); ++it2)
    402407        {
    403             if (*it == componentTag)
     408            if (*it2 == componentTag)
    404409            {
    405410                found = true;
    406411                break;
     
    467472void Dsmcc::Reset()
    468473{
    469474    VERBOSE(VB_DSMCC, "Resetting carousel");
     475    QLinkedList<ObjCarousel*>::iterator it = carousels.begin();
     476    for (; it != carousels.end(); ++it)
     477        delete *it;
    470478    carousels.clear();
    471479}
    472480
    473481int Dsmcc::GetDSMCCObject(QStringList &objectPath, QByteArray &result)
    474482{
    475     ObjCarousel *car;
    476     Q3PtrListIterator<ObjCarousel> it(carousels);
     483    QLinkedList<ObjCarousel*>::iterator it = carousels.begin();
    477484
    478     if (carousels.isEmpty())
     485    if (it == carousels.end())
    479486        return 1; // Not yet loaded.
    480487
    481488    // Can we actually have more than one carousel?
    482     for (; (car = it.current()) != NULL; ++it)
     489    for (; it != carousels.end(); ++it)
    483490    {
    484         int res = car->filecache.GetDSMObject(objectPath, result);
     491        int res = (*it)->filecache.GetDSMObject(objectPath, result);
    485492        if (res != -1)
    486493            return res;
    487494    }