Ticket #5570: 5570-mhi-v4.patch
File 5570-mhi-v4.patch, 17.7 KB (added by , 16 years ago) |
---|
-
libs/libmythtv/mhi.h
8 8 #include <ft2build.h> 9 9 #include FT_FREETYPE_H 10 10 11 // STL headers 12 #include <list> 13 using namespace std; 14 11 15 // 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> 22 21 23 22 // MythTV headers 24 23 #include "../libmythfreemheg/freemheg.h" … … 28 27 #include "mythcontext.h" 29 28 #include "mythdbcon.h" 30 29 #include "NuppelVideoPlayer.h" 30 #include "mythdeque.h" 31 31 32 32 extern "C" { 33 33 #include "../libavcodec/avcodec.h" // to decode single MPEG I-frames … … 143 143 void RunMHEGEngine(void); 144 144 void ProcessDSMCCQueue(void); 145 145 void NetworkBootRequested(void); 146 void ClearDisplay(void); 147 void ClearQueue(void); 146 148 147 149 InteractiveTV *m_parent; 148 150 149 151 Dsmcc *m_dsmcc; // Pointer to the DSMCC object carousel. 150 152 QMutex m_dsmccLock; 151 Q3PtrQueue<DSMCCPacket> m_dsmccQueue;153 MythDeque<DSMCCPacket*> m_dsmccQueue; 152 154 153 155 QMutex m_keyLock; 154 Q3ValueList<int>m_keyQueue;156 MythDeque<int> m_keyQueue; 155 157 int m_keyProfile; 156 158 157 159 MHEG *m_engine; // Pointer to the MHEG engine … … 165 167 int m_displayHeight; 166 168 167 169 168 Q3PtrList<MHIImageData> m_display; // List of items to display170 list<MHIImageData*> m_display; // List of items to display 169 171 170 172 FT_Face m_face; 171 173 bool m_face_loaded; … … 181 183 int m_tuningTo; 182 184 183 185 uint m_lastNbiVersion; 184 Q3MemArray<unsigned char> m_nbiData;186 vector<unsigned char> m_nbiData; 185 187 }; 186 188 187 189 // Object for drawing text. -
libs/libmythtv/mhi.cpp
1 1 #include <unistd.h> 2 2 3 #include <QRegion> 3 4 #include <qbitarray.h> 4 5 5 6 #include "mhi.h" … … 39 40 m_audioTag(-1), m_videoTag(-1), 40 41 m_tuningTo(-1), m_lastNbiVersion(NBI_VERSION_UNSET) 41 42 { 42 m_display.setAutoDelete(true);43 m_dsmccQueue.setAutoDelete(true);44 45 43 if (!ft_loaded) 46 44 { 47 45 FT_Error error = FT_Init_FreeType(&ft_library); … … 94 92 delete(m_engine); 95 93 delete(m_dsmcc); 96 94 if (m_face_loaded) FT_Done_Face(m_face); 95 96 ClearDisplay(); 97 ClearQueue(); 97 98 } 98 99 100 void 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 108 void 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 99 116 // Ask the engine to stop and block until it has. 100 117 void MHIContext::StopEngine() 101 118 { … … 129 146 { 130 147 QMutexLocker locker(&m_dsmccLock); 131 148 m_dsmcc->Reset(); 132 m_dsmccQueue.clear();149 ClearQueue(); 133 150 } 134 151 } 135 152 else … … 142 159 { 143 160 QMutexLocker locker(&m_dsmccLock); 144 161 m_dsmcc->Reset(); 145 m_dsmccQueue.clear();162 ClearQueue(); 146 163 } 147 164 148 165 { … … 154 171 m_engine = MHCreateEngine(this); 155 172 156 173 m_engine->SetBooting(); 157 m_display.clear();174 ClearDisplay(); 158 175 m_updated = true; 159 176 m_stop = false; 160 177 m_isLive = isLive; … … 196 213 ProcessDSMCCQueue(); 197 214 { 198 215 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(); 206 217 } 207 218 208 219 if (key != 0) … … 268 279 if (length < 2) return; // Temporary hack? -- dtk May 5th, 2008. 269 280 QMutexLocker locker(&m_dsmccLock); 270 281 // 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); 272 285 // If there is no Network Boot Info or we're setting it 273 286 // for the first time just update the "last version". 274 287 if (length < 2) … … 289 302 { 290 303 m_dsmcc->Reset(); 291 304 m_engine->SetBooting(); 292 m_display.clear();305 ClearDisplay(); 293 306 m_updated = true; 294 307 } 295 308 // TODO: else if it is 2 generate an EngineEvent. … … 404 417 405 418 if (action != 0) 406 419 { 407 m_keyQueue. push_front(action);420 m_keyQueue.enqueue(action); 408 421 VERBOSE(VB_IMPORTANT, "Adding MHEG key "<<key<<":"<<action 409 422 <<":"<<m_keyQueue.size()); 410 423 m_engine_wait.wakeAll(); … … 435 448 m_updated = false; 436 449 osdSet->Clear(); 437 450 // 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) 440 453 { 454 MHIImageData *data = *it; 441 455 OSDTypeImage* image = new OSDTypeImage(); 442 456 image->SetPosition(QPoint(data->m_x, data->m_y), 1.0, 1.0); 443 457 image->Load(data->m_image); … … 458 472 void MHIContext::RequireRedraw(const QRegion &) 459 473 { 460 474 m_display_lock.lock(); 461 m_display.clear();475 ClearDisplay(); 462 476 m_display_lock.unlock(); 463 477 // Always redraw the whole screen 464 478 m_engine->DrawDisplay(QRegion(0, 0, StdDisplayWidth, StdDisplayHeight)); … … 472 486 data->m_x = x; 473 487 data->m_y = y; 474 488 QMutexLocker locker(&m_display_lock); 475 m_display. append(data);489 m_display.push_back(data); 476 490 } 477 491 478 492 // In MHEG the video is just another item in the display stack … … 494 508 dispRect.width() * m_displayWidth/StdDisplayWidth, 495 509 dispRect.height() * m_displayHeight/StdDisplayHeight); 496 510 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) 498 513 { 499 MHIImageData *data = m_display.at(i);514 MHIImageData *data = *it; 500 515 QRect imageRect(data->m_x, data->m_y, 501 516 data->m_image.width(), data->m_image.height()); 502 517 if (displayRect.intersects(imageRect)) 503 518 { 504 519 // 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++) 509 525 { 510 526 QRect &rect = rects[j]; 511 527 QImage image = … … 515 531 newData->m_image = image; 516 532 newData->m_x = rect.x(); 517 533 newData->m_y = rect.y(); 518 m_display.insert(++i, newData); 534 m_display.insert(it, newData); 535 ++it; 519 536 } 520 delete (data);537 delete data; 521 538 } 522 539 } 523 540 } -
libs/libmythtv/dsmccobjcarousel.cpp
22 22 m_moduleSize(info->module_size), m_receivedData(0), 23 23 m_completed(false) 24 24 { 25 m_blocks.setAutoDelete(true);26 27 25 // The number of blocks needed to hold this module. 28 26 int num_blocks = (m_moduleSize + dii->block_size - 1) / dii->block_size; 29 m_blocks. fill(NULL, num_blocks); // Set it to all zeros27 m_blocks.resize(num_blocks, NULL); // Set it to all zeros 30 28 31 29 // Copy the descriptor information. 32 30 m_descriptorData = info->modinfo.descriptorData; 33 31 } 34 32 33 DSMCCCacheModuleData::~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 35 41 /** \fn DSMCCCacheModuleData::AddModuleData(DsmccDb*,const unsigned char*) 36 42 * \brief Add block to the module and create the module if it's now complete. 37 43 * \return data for the module if it is complete, NULL otherwise. … … 64 70 QByteArray *block = new QByteArray; 65 71 block->duplicate((char*) data, ddb->len); 66 72 // Add this to our set of blocks. 67 m_blocks .insert(ddb->block_number, block);73 m_blocks[ddb->block_number] = block; 68 74 m_receivedData += ddb->len; 69 75 } 70 76 … … 90 96 uint size = block->size(); 91 97 memcpy(tmp_data + curp, block->data(), size); 92 98 curp += size; 99 delete block; 93 100 } 94 101 m_blocks.clear(); // No longer required: free the space. 95 102 … … 126 133 ObjCarousel::ObjCarousel(Dsmcc *dsmcc) 127 134 : filecache(dsmcc), m_id(0) 128 135 { 129 m_Cache.setAutoDelete(true);130 136 } 131 137 138 ObjCarousel::~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 132 146 void ObjCarousel::AddModuleInfo(DsmccDii *dii, Dsmcc *status, 133 147 unsigned short streamTag) 134 148 { 135 149 for (int i = 0; i < dii->number_modules; i++) 136 150 { 137 DSMCCCacheModuleData *cachep;138 151 DsmccModuleInfo *info = &(dii->modules[i]); 139 152 // Do we already know this module? 140 153 // If so and it is the same version we don't need to do anything. 141 154 // 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) 143 157 { 158 DSMCCCacheModuleData *cachep = *it; 144 159 if (cachep->CarouselId() == dii->download_id && 145 160 cachep->ModuleId() == info->module_id) 146 161 { … … 168 183 .arg(info->module_id)); 169 184 170 185 // Remove and delete the cache object. 171 m_Cache.remove(); 186 m_Cache.erase(it); 187 delete cachep; 172 188 break; 173 189 } 174 190 } … … 177 193 .arg(dii->modules[i].module_id)); 178 194 179 195 // Create a new cache module data object. 180 cachep = new DSMCCCacheModuleData(dii, info, streamTag);196 DSMCCCacheModuleData *cachep = new DSMCCCacheModuleData(dii, info, streamTag); 181 197 182 198 int tag = info->modinfo.tap.assoc_tag; 183 199 VERBOSE(VB_DSMCC, QString("[dsmcc] Module info tap " … … 203 219 VERBOSE(VB_DSMCC, QString("[dsmcc] Data block on carousel %1").arg(m_id)); 204 220 205 221 // Search the saved module info for this module 206 Q 3PtrListIterator<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) 209 225 { 226 cachep = *it; 210 227 if (cachep->CarouselId() == carousel && 211 228 (cachep->ModuleId() == ddb->module_id)) 212 229 { -
libs/libmythtv/dsmccobjcarousel.h
5 5 #ifndef DSMCC_OBJCAROUSEL_H 6 6 #define DSMCC_OBJCAROUSEL_H 7 7 8 #include <QLinkedList> 8 9 9 #include <q3ptrlist.h> 10 #include <q3valuevector.h> 11 #include <q3cstring.h> 12 #include <q3ptrvector.h> 10 #include <vector> 11 using namespace std; 13 12 14 13 class DsmccDii; 15 14 class Dsmcc; … … 28 27 public: 29 28 DSMCCCacheModuleData(DsmccDii *dii, DsmccModuleInfo *info, 30 29 unsigned short streamTag); 30 ~DSMCCCacheModuleData(); 31 31 32 32 unsigned char *AddModuleData(DsmccDb *ddb, const unsigned char *Data); 33 33 … … 55 55 unsigned long m_receivedData; ///< Size received so far. 56 56 57 57 /// Block table. As blocks are received they are added to this table. 58 Q3PtrVector<QByteArray> m_blocks;58 vector<QByteArray*> m_blocks; 59 59 /// True if we have completed this module. 60 60 bool m_completed; 61 61 ModuleDescriptorData m_descriptorData; … … 65 65 { 66 66 public: 67 67 ObjCarousel(Dsmcc*); 68 ~ObjCarousel(); 68 69 void AddModuleInfo(DsmccDii *dii, Dsmcc *status, unsigned short streamTag); 69 70 void AddModuleData(unsigned long carousel, DsmccDb *ddb, 70 71 const unsigned char *data); 71 72 72 73 DSMCCCache filecache; 73 Q 3PtrList<DSMCCCacheModuleData> m_Cache;74 QLinkedList<DSMCCCacheModuleData*> m_Cache; 74 75 /// Component tags matched to this carousel. 75 Q3ValueVector<unsigned short>m_Tags;76 vector<unsigned short> m_Tags; 76 77 unsigned long m_id; 77 78 }; 78 79 -
libs/libmythtv/dsmcc.h
5 5 #ifndef LIBDSMCC_H 6 6 #define LIBDSMCC_H 7 7 8 #include < q3ptrlist.h>9 #include < qstringlist.h>8 #include <QLinkedList> 9 #include <QStringList> 10 10 11 11 #include "dsmccreceiver.h" 12 12 #include "dsmccobjcarousel.h" … … 76 76 { 77 77 public: 78 78 Dsmcc(); 79 ~Dsmcc(); 79 80 // Reset the object carousel and clear the caches. 80 81 void Reset(); 81 82 // Process an incoming DSMCC carousel table … … 107 108 ObjCarousel *GetCarouselById(unsigned int carId); 108 109 109 110 // Known carousels. 110 Q 3PtrList<ObjCarousel> carousels;111 QLinkedList<ObjCarousel*> carousels; 111 112 112 113 // Initial stream 113 114 unsigned short m_startTag; -
libs/libmythtv/dsmcc.cpp
35 35 36 36 Dsmcc::Dsmcc() 37 37 { 38 carousels.setAutoDelete(true);39 38 m_startTag = 0; 40 39 } 41 40 41 Dsmcc::~Dsmcc() 42 { 43 Reset(); 44 } 45 42 46 /** \fn Dsmcc::GetCarouselById(unsigned int) 43 47 * \brief Returns a carousel with the given ID. 44 48 */ 45 49 ObjCarousel *Dsmcc::GetCarouselById(unsigned int carouselId) 46 50 { 47 Q3PtrListIterator<ObjCarousel> it(carousels); 48 ObjCarousel *car; 51 QLinkedList<ObjCarousel*>::iterator it = carousels.begin(); 49 52 50 for (; (car = it.current()) != NULL; ++it)53 for (; it != carousels.end(); ++it) 51 54 { 52 if (car->m_id == carouselId) 55 ObjCarousel *car = *it; 56 if (car && car->m_id == carouselId) 53 57 return car; 54 58 } 55 59 return NULL; … … 77 81 } 78 82 79 83 // Add this only if it's not already there. 80 Q3ValueVector<unsigned short>::iterator it;84 vector<unsigned short>::iterator it; 81 85 for (it = car->m_Tags.begin(); it != car->m_Tags.end(); ++it) 82 86 { 83 87 if (*it == componentTag) … … 86 90 87 91 if (it == car->m_Tags.end()) 88 92 { // Not there. 89 car->m_Tags. append(componentTag);93 car->m_Tags.push_back(componentTag); 90 94 VERBOSE(VB_DSMCC, QString("[dsmcc] Adding tap for stream " 91 95 "tag %1 with carousel %2") 92 96 .arg(componentTag).arg(carouselId)); … … 385 389 int dataBroadcastId) 386 390 { 387 391 // Does this component tag match one of our carousels? 388 Q 3PtrListIterator<ObjCarousel> it(carousels);389 ObjCarousel *car ;392 QLinkedList<ObjCarousel*>::iterator it = carousels.begin(); 393 ObjCarousel *car = NULL; 390 394 391 395 VERBOSE(VB_DSMCC, QString("[dsmcc] Read block size %1 from tag %2 " 392 396 "carousel id %3 data broadcast Id %4") … … 394 398 .arg(carouselId).arg(dataBroadcastId)); 395 399 396 400 bool found = false; 397 for (; (car = it.current()) != NULL; ++it)401 for (; it != carousels.end(); ++it) 398 402 { 403 car = *it; 399 404 // 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) 402 407 { 403 if (*it == componentTag)408 if (*it2 == componentTag) 404 409 { 405 410 found = true; 406 411 break; … … 467 472 void Dsmcc::Reset() 468 473 { 469 474 VERBOSE(VB_DSMCC, "Resetting carousel"); 475 QLinkedList<ObjCarousel*>::iterator it = carousels.begin(); 476 for (; it != carousels.end(); ++it) 477 delete *it; 470 478 carousels.clear(); 471 479 } 472 480 473 481 int Dsmcc::GetDSMCCObject(QStringList &objectPath, QByteArray &result) 474 482 { 475 ObjCarousel *car; 476 Q3PtrListIterator<ObjCarousel> it(carousels); 483 QLinkedList<ObjCarousel*>::iterator it = carousels.begin(); 477 484 478 if ( carousels.isEmpty())485 if (it == carousels.end()) 479 486 return 1; // Not yet loaded. 480 487 481 488 // Can we actually have more than one carousel? 482 for (; (car = it.current()) != NULL; ++it)489 for (; it != carousels.end(); ++it) 483 490 { 484 int res = car->filecache.GetDSMObject(objectPath, result);491 int res = (*it)->filecache.GetDSMObject(objectPath, result); 485 492 if (res != -1) 486 493 return res; 487 494 }