Ticket #368: mythtv_teletext_20060111.patch
File mythtv_teletext_20060111.patch, 75.5 KB (added by , 20 years ago) |
---|
-
libs/libmythtv/NuppelVideoPlayer.h
13 13 #include "jitterometer.h" 14 14 #include "recordingprofile.h" 15 15 #include "videooutbase.h" 16 #include "teletextdecoder.h" 16 17 #include "tv_play.h" 17 18 18 19 extern "C" { … … 158 159 char *GetScreenGrab(int secondsin, int &buflen, 159 160 int &vw, int &vh, float &ar); 160 161 LiveTVChain *GetTVChain(void) { return livetvchain; } 162 TeletextDecoder *GetTeletextDecoder(void); 161 163 162 164 // Start/Reset/Stop playing 163 165 void StartPlaying(void); … … 473 475 bool osdHasSubtitles; 474 476 long long osdSubtitlesExpireAt; 475 477 MythDeque<AVSubtitle> nonDisplayedSubtitles; 478 TeletextDecoder *tt_decoder; 476 479 477 480 // OSD stuff 478 481 OSD *osd; -
libs/libmythtv/NuppelVideoPlayer.cpp
117 117 wtxt(0), rtxt(0), text_size(0), ccline(""), cccol(0), ccrow(0), 118 118 // Support for captions, teletext, etc. decoded by libav 119 119 osdHasSubtitles(false), osdSubtitlesExpireAt(-1), 120 tt_decoder(NULL), 120 121 // OSD stuff 121 122 osd(NULL), timedisplay(NULL), 122 123 dialogname(""), dialogtype(0), … … 213 214 delete [] txtbuffers[i].buffer; 214 215 } 215 216 217 if (tt_decoder) 218 delete tt_decoder; 219 216 220 SetDecoder(NULL); 217 221 218 222 if (FiltMan) … … 228 232 delete videoOutput; 229 233 } 230 234 235 TeletextDecoder *NuppelVideoPlayer::GetTeletextDecoder(void) 236 { 237 if (!tt_decoder) 238 tt_decoder = new TeletextDecoder(); 239 return tt_decoder; 240 } 241 231 242 void NuppelVideoPlayer::SetWatchingRecording(bool mode) 232 243 { 233 244 watchingrecording = mode; -
libs/libmythtv/vbilut.h
17 17 extern const short hamm24err[]; 18 18 extern const int hamm24cor[]; 19 19 20 enum vbimode 21 { 22 VBI_IVTV, /// < IVTV packet 23 VBI_DVB, /// < DVB packet 24 VBI_DVB_SUBTITLE /// < DVB subtitle packet 25 }; 26 27 int hamm8(const uint8_t *p, int *err); 28 int hamm84(const uint8_t *p, int *err); 29 int hamm16(const uint8_t *p, int *err); 30 20 31 #endif // _VBILUT_H_ -
libs/libmythtv/teletextdecoder.cpp
1 /* ============================================================= 2 * File : vbidecoder.cpp 3 * Author: Frank Muenchow <beebof@gmx.de> 4 * Martin Barnasconi 5 * Date : 2005-10-25 6 * 7 * This program is free software; you can redistribute it 8 * and/or modify it under the terms of the GNU General 9 * Public License as published by the Free Software Foundation; 10 * either version 2, or (at your option) 11 * any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * ============================================================= */ 19 #include <cstring> 20 21 #include <stdint.h> 22 #include <ctype.h> 23 24 extern "C" { 25 #include <inttypes.h> 26 #include "ivtv_myth.h" 27 #include "vbitext/vt.h" 28 } 29 30 using namespace std; 31 32 #include "osd.h" 33 #include "teletextdecoder.h" 34 #include "vbilut.h" 35 #include "mythcontext.h" 36 #include "osdtypeteletext.h" 37 #include "ccdecoder.h" 38 39 /******************************************************************/ 40 //Decoder section 41 // 42 43 TeletextDecoder::TeletextDecoder() : 44 // private stuff 45 m_teletextviewer(NULL), m_decodertype(-1) 46 { 47 } 48 49 TeletextDecoder::~TeletextDecoder() 50 { 51 } 52 53 /** \fn TeletextDecoder::Decode(const uint8_t*, int) 54 * \brief Decodes teletext data 55 * 56 * \param buf Points to the teletext data 57 * \param vbimode VBI-Mode (as defined in vbilut.h) 58 */ 59 void TeletextDecoder::Decode(const uint8_t *buf, int vbimode) 60 { 61 int err = 0; 62 int latin1 = -1; 63 uint8_t magazine, packet, header; 64 int zahl1; 65 int pagenum, subpagenum; 66 int lang, flags; 67 68 if (m_teletextviewer == NULL) 69 { 70 VERBOSE(VB_VBI,QString("TeletextDecoder: No Teletext Viewer defined!")); 71 return; 72 } 73 74 m_decodertype = vbimode; 75 76 switch (vbimode) 77 { 78 case VBI_IVTV: 79 header = hamm16(buf, &err); 80 81 if (err & 0xf000) 82 return; // error in data header 83 84 magazine = header & 7; 85 packet = (header >> 3) & 0x1f; 86 87 buf += 2; 88 break; 89 90 case VBI_DVB: 91 case VBI_DVB_SUBTITLE: 92 zahl1 = hamm84(buf,&err) * 16 + hamm84(buf+1,&err); 93 94 magazine = 0; 95 if (buf[0] & 0x40) 96 magazine += 1; 97 if (buf[0] & 0x10) 98 magazine += 2; 99 if (buf[0] & 0x04) 100 magazine += 4; 101 102 packet = 0; 103 if (buf[0] & 0x01) 104 packet += 1; 105 if (buf[1] & 0x40) 106 packet += 2; 107 if (buf[1] & 0x10) 108 packet += 4; 109 if (buf[1] & 0x04) 110 packet += 8; 111 if (buf[1] & 0x01) 112 packet += 16; 113 114 if (err == 1) 115 return; // error in data header 116 117 buf += 2; 118 break; 119 120 default: 121 return; // error in vbimode 122 } 123 124 switch (packet) 125 { 126 case 0: // Page Header 127 int b1, b2, b3, b4; 128 switch (vbimode) 129 { 130 case VBI_IVTV: 131 b1 = hamm16(buf, &err);// page number 132 b2 = hamm16(buf+2, &err);// subpage number + flags 133 b3 = hamm16(buf+4, &err);// subpage number + flags 134 b4 = hamm16(buf+6, &err);// language code + more flags 135 if (err & 0xf000) 136 return; 137 138 break; 139 140 case VBI_DVB: 141 case VBI_DVB_SUBTITLE: 142 b1 = hamm84(buf+1, &err)*16+hamm84(buf, &err); 143 b2 = hamm84(buf+3, &err)*16+hamm84(buf+2, &err); 144 b3 = hamm84(buf+5, &err)*16+hamm84(buf+4, &err); 145 b4 = hamm84(buf+7, &err)*16+hamm84(buf+6, &err); 146 if (err == 1) 147 return; 148 149 break; 150 151 default: 152 return; // error in vbimode 153 } 154 155 VERBOSE(VB_VBI, QString("Page Header found: " 156 "Magazine %1, Page Number %2") 157 .arg(magazine).arg(b1)); 158 subpagenum= (b2 + b3 * 256) & 0x3f7f; 159 pagenum = (magazine?:8)*256 + b1; 160 161 lang = "\0\4\2\6\1\5\3\7"[b4 >> 5] + (latin1 ? 0 : 8); 162 flags = b4 & 0x1F; 163 flags |= b3 & 0xC0; 164 flags |= (b2 & 0x80) >> 2; 165 m_teletextviewer->AddPageHeader(pagenum,subpagenum,buf,vbimode,lang,flags); 166 167 break; 168 169 default: // Page Data 170 m_teletextviewer->AddTeletextData((magazine?:8), packet, buf, vbimode); 171 break; 172 } 173 return; 174 } 175 176 /** \fn TeletextDecoder::SetViewer(OSDTypeTeletext*) 177 * \brief Sets the Teletext Viewer Class 178 */ 179 void TeletextDecoder::SetViewer(OSDTypeTeletext *view) 180 { 181 m_teletextviewer = view; 182 } 183 184 /** \fn TeletextDecoder::GetDecoderType(void) const 185 * \brief returns the actual decoder type (DVB,IVTV,DVB_SUBTITLE...) 186 * At the moment, this is just for the decision in tv_play.cpp 187 * if to use the new TeletextDecoder class or the old one 188 */ 189 int TeletextDecoder::GetDecoderType(void) const 190 { 191 return m_decodertype; 192 } 193 -
libs/libmythtv/avformatdecoder.cpp
265 265 video_codec_id(kCodec_NONE), 266 266 maxkeyframedist(-1), 267 267 ccd(new CCDecoder(this)), 268 ttd(NULL), 268 269 // Audio 269 270 audioSamples(new short int[AVCODEC_MAX_AUDIO_FRAME_SIZE]), 270 271 allow_ac3_passthru(false), allow_dts_passthru(false), … … 290 291 #endif 291 292 292 293 audioIn.sample_size = -32; // force SetupAudioStream to run once 294 ttd = GetNVP()->GetTeletextDecoder(); 293 295 } 294 296 295 297 AvFormatDecoder::~AvFormatDecoder() … … 1719 1721 // SECAM lines 6-23 1720 1722 // PAL lines 6-22 1721 1723 // NTSC lines 10-21 (rare) 1722 //ttd->Decode(buf+1, VBI_IVTV);1724 ttd->Decode(buf+1, VBI_IVTV); 1723 1725 break; 1724 1726 case VBI_TYPE_CC: 1725 1727 // PAL line 22 (rare) … … 1756 1758 const uint8_t *buf = pkt->data; 1757 1759 const uint8_t *buf_end = pkt->data + pkt->size; 1758 1760 1759 while (buf < buf_end); 1761 1762 while (buf < buf_end) 1760 1763 { 1761 1764 if (*buf == 0x10) 1762 1765 buf++; // skip … … 1766 1769 if (*buf == 0x02) 1767 1770 { 1768 1771 buf += 3; 1769 //ttd->Decode(buf+1, VBI_DVB);1772 ttd->Decode(buf+1, VBI_DVB); 1770 1773 } 1771 1774 else if (*buf == 0x03) 1772 1775 { 1773 1776 buf += 3; 1774 //ttd->Decode(buf+1, VBI_DVB_SUBTITLE);1777 ttd->Decode(buf+1, VBI_DVB_SUBTITLE); 1775 1778 } 1776 1779 else 1777 1780 { 1778 1781 VERBOSE(VB_VBI, QString("VBI: Unknown descriptor: %1").arg(*buf)); 1779 1782 } 1780 1781 1783 buf += 43; 1782 1784 } 1783 1785 } … … 2331 2333 2332 2334 if (len > 0 && 2333 2335 curstream->codec->codec_type == CODEC_TYPE_DATA && 2334 curstream->codec->codec_id == CODEC_ID_ MPEG2VBI)2336 curstream->codec->codec_id == CODEC_ID_DVB_VBI) 2335 2337 { 2336 2338 ProcessDVBDataPacket(curstream, pkt); 2337 2338 2339 av_free_packet(pkt); 2339 2340 continue; 2340 2341 } -
libs/libmythtv/osdtypeteletext.cpp
1 /* ============================================================= 2 * File : osdtypeteletext.cpp 3 * Author: Frank Muenchow <beebof@gmx.de> 4 * Martin Barnasconi 5 * Date : 2005-10-25 6 * 7 * This program is free software; you can redistribute it 8 * and/or modify it under the terms of the GNU General 9 * Public License as published by the Free Software Foundation; 10 * either version 2, or (at your option) 11 * any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * ============================================================= */ 19 #include "osd.h" 20 #include "osdsurface.h" 21 #include "osdtypes.h" 22 #include "osdtypeteletext.h" 23 #include "ttfont.h" 24 #include "vbilut.h" 25 26 #include <qcolor.h> 27 #include <qapplication.h> 28 #include <iostream> 29 #include <cmath> 30 #include <qmutex.h> 31 32 using namespace std; 33 34 QColor m_color_black; 35 QColor m_color_red; 36 QColor m_color_green; 37 QColor m_color_yellow; 38 QColor m_color_blue; 39 QColor m_color_magenta; 40 QColor m_color_cyan; 41 QColor m_color_white; 42 43 /*****************************************************************************/ 44 OSDTypeTeletext::OSDTypeTeletext(const QString &name, QRect displayrect, 45 TTFFont *font) 46 : OSDType(name) 47 { 48 m_surface = NULL; 49 50 m_displayrect = displayrect; 51 m_font = font; 52 53 m_tt_colspace = m_displayrect.width() / COLS; 54 m_tt_rowspace = m_displayrect.height() / ROWS; 55 56 m_color_black = QColor( 0, 0, 0); 57 m_color_red = QColor(255, 0, 0); 58 m_color_green = QColor( 0,255, 0); 59 m_color_yellow = QColor(255,255, 0); 60 m_color_blue = QColor( 0, 0,255); 61 m_color_magenta = QColor(255, 0,255); 62 m_color_cyan = QColor( 0,255,255); 63 m_color_white = QColor(255,255,255); 64 65 Reset(); 66 67 m_curpage = 0x100; 68 m_cursubpage = -1; 69 m_curpage_showheader = true; 70 71 m_pageinput[0] = '1'; 72 m_pageinput[1] = '0'; 73 m_pageinput[2] = '0'; 74 75 m_displaying = false; 76 77 // fill Bitswap 78 for (int i = 0; i < 256; i++) 79 { 80 bitswap[i] = 0; 81 for (int bit = 0; bit < 8; bit++) 82 if (i & (1 << bit)) 83 bitswap[i] |= (1 << (7-bit)); 84 } 85 } 86 87 OSDTypeTeletext::OSDTypeTeletext(const OSDTypeTeletext &other) 88 : OSDType(other.m_name) 89 { 90 } 91 92 OSDTypeTeletext::~OSDTypeTeletext() 93 { 94 } 95 96 /** \fn OSDTypeTeletext::Reset() 97 * \brief Resets the teletext data cache 98 */ 99 void OSDTypeTeletext::Reset() 100 { 101 for (int mag = 0; mag < 8; ++mag) 102 { 103 QMutexLocker lock(&m_magazines[mag].lock); 104 105 // clear all sub pages in page 106 std::map<int, TeletextPage>::iterator iter; 107 iter = m_magazines[mag].pages.begin(); 108 while (iter != m_magazines[mag].pages.end()) 109 { 110 TeletextPage *page = &iter->second; 111 page->subpages.clear(); 112 ++iter; 113 } 114 115 // clear pages 116 m_magazines[mag].pages.clear(); 117 m_magazines[mag].current_page = 0; 118 m_magazines[mag].current_subpage = 0; 119 } 120 121 m_curpage = 0x100; 122 m_cursubpage = -1; 123 m_curpage_showheader = true; 124 } 125 126 /** \fn OSDTypeTeletext::CharConversion(char, int) 127 * \brief converts the given character to the given language 128 */ 129 char OSDTypeTeletext::CharConversion(char ch, int lang) 130 { 131 int c = 0; 132 for (int j = 0; j < 14; j++) 133 { 134 c = ch & 0x7F; 135 if (c == lang_chars[0][j]) 136 ch = lang_chars[lang + 1][j]; 137 } 138 return ch; 139 } 140 141 /** \fn OSDTypeTeletext::AddPageHeader(int, int, uint8_t*, int) 142 * \brief Adds a new page header 143 * (page=0 if none) 144 */ 145 void OSDTypeTeletext::AddPageHeader(int page, int subpage, const uint8_t* buf, int vbimode, int lang, int flags) 146 { 147 if (page < 256) 148 return; 149 150 int magazine = MAGAZINE(page); 151 int lastPage = m_magazines[magazine - 1].current_page; 152 int lastSubPage = m_magazines[magazine - 1].current_subpage; 153 154 // update the last fetched page if the magazine is the same 155 // and the page no. is different 156 if (page != lastPage || subpage != lastSubPage) 157 PageUpdated(lastPage, lastSubPage); 158 159 m_fetchpage = page; 160 m_fetchsubpage = subpage; 161 162 TeletextSubPage *ttpage = FindSubPage(page, subpage); 163 164 if (ttpage == NULL) 165 { 166 ttpage = &m_magazines[magazine - 1].pages[page].subpages[subpage]; 167 m_magazines[magazine - 1].pages[page].pagenum = page; 168 ttpage->subpagenum = subpage; 169 170 for (int i=0; i < 6; i++) 171 ttpage->floflink[i] = 0; 172 } 173 174 m_magazines[magazine - 1].current_page = page; 175 m_magazines[magazine - 1].current_subpage = subpage; 176 177 ttpage->lang = lang; 178 ttpage->flags = flags; 179 ttpage->flof = 0; 180 181 ttpage->subtitle = (vbimode == VBI_DVB_SUBTITLE); 182 183 for (int j = 0; j < 8; j++) 184 ttpage->data[0][j] = 32; 185 186 if (vbimode == VBI_DVB || vbimode == VBI_DVB_SUBTITLE) 187 { 188 for (int j = 8; j < 40; j++) 189 ttpage->data[0][j] = bitswap[buf[j]]; 190 } 191 else 192 { 193 memcpy(ttpage->data[0]+0, buf, 40); 194 memset(ttpage->data[0]+40, ' ', sizeof(ttpage->data)-40); 195 } 196 197 if ( !(ttpage->flags & TP_INTERRUPTED_SEQ)) 198 HeaderUpdated(ttpage->data[0],ttpage->lang); 199 } 200 201 /** \fn OSDTypeTeletext::AddTeletextData(int, int, uint8_t*) 202 * \brief Adds Teletext Data from TeletextDecoder 203 */ 204 void OSDTypeTeletext::AddTeletextData(int magazine, int row, 205 const uint8_t* buf, int vbimode) 206 { 207 int b1, b2, b3, err; 208 209 if (magazine < 1 || magazine > 8) 210 return; 211 212 int currentpage = m_magazines[magazine - 1].current_page; 213 int currentsubpage = m_magazines[magazine -1].current_subpage; 214 if (currentpage == 0) 215 return; 216 217 TeletextSubPage *ttpage = FindSubPage(currentpage, currentsubpage); 218 219 if (ttpage == NULL) 220 return; 221 222 switch (row) 223 { 224 case 1 ... 24: // Page Data 225 if (vbimode == VBI_DVB || vbimode == VBI_DVB_SUBTITLE) 226 { 227 for (int j = 0; j < 40; j++) 228 ttpage->data[row][j] = bitswap[buf[j]]; 229 } 230 else 231 { 232 memcpy(ttpage->data[row], buf, 40); 233 } 234 break; 235 case 26: 236 /* XXX TODO: Level 1.5, 2.5, 3.5 237 * Character location & override 238 * Level 2.5, 3.5 239 * Modifying display attributes 240 * All levels 241 * VCR Programming 242 * See 12.3 243 */ 244 break; 245 case 27: // FLOF data (FastText) 246 switch (vbimode) 247 { 248 case VBI_IVTV: 249 b1 = hamm8(buf, &err); 250 b2 = hamm8(buf + 37, & err); 251 if (err & 0xF00) 252 return; 253 break; 254 case VBI_DVB: 255 case VBI_DVB_SUBTITLE: 256 b1 = hamm84(buf, &err); 257 b2 = hamm84(buf + 37, &err); 258 if (err == 1) 259 return; 260 break; 261 default: 262 return; 263 } 264 if (b1 != 0 || not(b2 & 8)) 265 return; 266 267 for (int i = 0; i < 6; ++i) 268 { 269 err = 0; 270 switch (vbimode) 271 { 272 case VBI_IVTV: 273 b1 = hamm16(buf+1+6*i, &err); 274 b2 = hamm16(buf+3+6*i, &err); 275 b3 = hamm16(buf+5+6*i, &err); 276 if (err & 0xF000) 277 return; 278 break; 279 case VBI_DVB: 280 case VBI_DVB_SUBTITLE: 281 b1 = hamm84(buf+2+6*i, &err) * 16 + 282 hamm84(buf+1+6*i, &err); 283 b2 = hamm84(buf+4+6*i, &err) * 16 + 284 hamm84(buf+3+6*i, &err); 285 b3 = hamm84(buf+6+6*i, &err) * 16 + 286 hamm84(buf+5+6*i, &err); 287 if (err == 1) 288 return; 289 break; 290 default: 291 return; 292 } 293 294 int x = (b2 >> 7) | ((b3 >> 5) & 0x06); 295 ttpage->floflink[i] = ((magazine ^ x) ?: 8) * 256 + b1; 296 ttpage->flof = 1; 297 } 298 break; 299 300 case 31: // private streams 301 break; 302 303 default: /// other packet codes... 304 break; 305 } 306 } 307 308 /** \fn OSDTypeTeletext::PageUpdated(int) 309 * \brief Updates the page, if given pagenumber is the same 310 * as the current shown page 311 */ 312 void OSDTypeTeletext::PageUpdated(int page, int subpage) 313 { 314 if (!m_displaying) 315 return; 316 317 if (page != m_curpage) 318 return; 319 320 if (subpage != m_cursubpage && m_cursubpage != -1) 321 return; 322 323 324 if (m_surface != NULL) 325 { 326 m_surface->SetChanged(true); 327 m_surface->ClearUsed(); 328 DrawPage(); 329 } 330 } 331 332 /** \fn OSDTypeTeletext::HeaderUpdated(uint8_t*,int) 333 * \brief Updates the header (given in page with language lang) 334 * 335 * \param page Pointer to the header which should be displayed 336 * \param lang Language of the header 337 * 338 */ 339 void OSDTypeTeletext::HeaderUpdated(uint8_t *page, int lang) 340 { 341 if (!m_displaying) 342 return; 343 344 if (page == NULL) 345 return; 346 347 if (m_curpage_showheader == false) 348 return; 349 350 if (m_surface != NULL) 351 DrawHeader(page, lang); 352 } 353 354 /** \fn OSDTypeTeletext::FindPage(int, int) 355 * \brief Finds the given page 356 * 357 * \param page Page number 358 * \param direction find page before or after the given page 359 * \return TeletextPage (NULL if not found) 360 */ 361 TeletextPage* OSDTypeTeletext::FindPage(int page, int direction) 362 { 363 TeletextPage *res = NULL; 364 int mag = MAGAZINE(page); 365 366 if (mag > 8 || mag < 1) 367 return NULL; 368 369 QMutexLocker lock(&m_magazines[mag - 1].lock); 370 371 std::map<int, TeletextPage>::iterator pageIter; 372 pageIter = m_magazines[mag - 1].pages.find(page); 373 if (pageIter == m_magazines[mag - 1].pages.end()) 374 return NULL; 375 376 res = &pageIter->second; 377 if (direction == -1) 378 { 379 --pageIter; 380 if (pageIter == m_magazines[mag - 1].pages.end()) 381 { 382 std::map<int, TeletextPage>::reverse_iterator iter; 383 iter = m_magazines[mag - 1].pages.rbegin(); 384 res = &iter->second; 385 } 386 else 387 res = &pageIter->second; 388 } 389 390 if (direction == 1) 391 { 392 ++pageIter; 393 if (pageIter == m_magazines[mag - 1].pages.end()) 394 { 395 pageIter = m_magazines[mag - 1].pages.begin(); 396 res = &pageIter->second; 397 } 398 else 399 res = &pageIter->second; 400 } 401 402 return res; 403 } 404 405 /** \fn OSDTypeTeletext::FindSubPage(int, int, int) 406 * \brief Finds the given page 407 * 408 * \param page Page number 409 * \param subpage Subpage number (if set to -1, find the first subpage) 410 * \param direction find page before or after the given page (only if Subpage is not -1) 411 * \return TeletextSubPage (NULL if not found) 412 */ 413 TeletextSubPage* OSDTypeTeletext::FindSubPage(int page, int subpage, int direction) 414 { 415 TeletextSubPage *res = NULL; 416 int mag = MAGAZINE(page); 417 418 if (mag > 8 || mag < 1) 419 return NULL; 420 421 QMutexLocker lock(&m_magazines[mag - 1].lock); 422 423 if (subpage == -1) 424 { 425 // return the first subpage found 426 std::map<int, TeletextPage>::iterator pageIter; 427 pageIter = m_magazines[mag - 1].pages.find(page); 428 if (pageIter == m_magazines[mag - 1].pages.end()) 429 return NULL; 430 431 TeletextPage *page = &pageIter->second; 432 std::map<int, TeletextSubPage>::iterator subpageIter; 433 subpageIter = page->subpages.begin(); 434 if (subpageIter == page->subpages.end()) 435 return NULL; 436 437 return &subpageIter->second; 438 } 439 else 440 { 441 // try to find the subpage given 442 std::map<int, TeletextPage>::iterator pageIter; 443 pageIter = m_magazines[mag - 1].pages.find(page); 444 if (pageIter == m_magazines[mag - 1].pages.end()) 445 return NULL; 446 447 TeletextPage *page = &pageIter->second; 448 std::map<int, TeletextSubPage>::iterator subpageIter; 449 subpageIter = page->subpages.find(subpage); 450 if (subpageIter == page->subpages.end()) 451 return NULL; 452 453 res = &subpageIter->second; 454 if (direction == -1) 455 { 456 --subpageIter; 457 if (subpageIter == page->subpages.end()) 458 { 459 std::map<int, TeletextSubPage>::reverse_iterator iter; 460 iter = page->subpages.rbegin(); 461 res = &iter->second; 462 } 463 else 464 res = &subpageIter->second; 465 } 466 467 if (direction == 1) 468 { 469 ++subpageIter; 470 if (subpageIter == page->subpages.end()) 471 { 472 subpageIter = page->subpages.begin(); 473 res = &subpageIter->second; 474 } 475 else 476 res = &subpageIter->second; 477 } 478 } 479 480 return res; 481 } 482 483 /** \fn OSDTypeTeletext::KeyPress(uint) 484 * \brief What to do if a key is pressed 485 * 486 * \param key pressed key 487 * \sa TTKey 488 */ 489 void OSDTypeTeletext::KeyPress(uint key) 490 { 491 int newPage = m_curpage; 492 int newSubPage = m_cursubpage; 493 bool numeric_input = false; 494 495 TeletextSubPage *curpage = FindSubPage(m_curpage, m_cursubpage); 496 TeletextPage *page; 497 498 switch (key) 499 { 500 case TTKey::k0 ... TTKey::k9: 501 numeric_input = true; 502 m_curpage_showheader = true; 503 if (m_pageinput[0] == ' ') 504 m_pageinput[0] = '0' + static_cast<int> (key); 505 else if (m_pageinput[1] == ' ') 506 m_pageinput[1] = '0' + static_cast<int> (key); 507 else if (m_pageinput[2] == ' ') 508 { 509 m_pageinput[2] = '0' + static_cast<int> (key); 510 newPage = ((m_pageinput[0] - '0') * 256) + 511 ((m_pageinput[1] - '0') * 16) + 512 (m_pageinput[2] - '0'); 513 newSubPage = -1; 514 } 515 else 516 { 517 m_pageinput[0] = '0' + static_cast<int> (key); 518 m_pageinput[1] = ' '; 519 m_pageinput[2] = ' '; 520 } 521 522 break; 523 524 case TTKey::kNextPage: 525 { 526 TeletextPage *ttpage = FindPage(m_curpage, 1); 527 if (ttpage) 528 newPage = ttpage->pagenum; 529 newSubPage = -1; 530 m_curpage_showheader = true; 531 break; 532 } 533 534 case TTKey::kPrevPage: 535 { 536 TeletextPage *ttpage = FindPage(m_curpage, -1); 537 if (ttpage) 538 newPage = ttpage->pagenum; 539 newSubPage = -1; 540 m_curpage_showheader = true; 541 break; 542 } 543 544 case TTKey::kNextSubPage: 545 { 546 TeletextSubPage *ttpage = FindSubPage(m_curpage, m_cursubpage, 1); 547 if (ttpage) 548 newSubPage = ttpage->subpagenum; 549 m_curpage_showheader = true; 550 break; 551 } 552 553 case TTKey::kPrevSubPage: 554 { 555 TeletextSubPage *ttpage = FindSubPage(m_curpage, m_cursubpage, -1); 556 if (ttpage) 557 newSubPage = ttpage->subpagenum; 558 m_curpage_showheader = true; 559 break; 560 } 561 562 case TTKey::kHold: 563 break; 564 565 case TTKey::kTransparent: 566 m_transparent = !m_transparent; 567 PageUpdated(m_curpage, m_cursubpage); 568 break; 569 570 case TTKey::kRevealHidden: 571 m_revealHidden = !m_revealHidden; 572 PageUpdated(m_curpage, m_cursubpage); 573 break; 574 575 case TTKey::kFlofRed: 576 { 577 if (!curpage) 578 return; 579 580 if ((page = FindPage(curpage->floflink[0])) != NULL) 581 { 582 newPage = page->pagenum; 583 newSubPage = -1; 584 m_curpage_showheader = true; 585 } 586 break; 587 } 588 589 case TTKey::kFlofGreen: 590 { 591 if (!curpage) 592 return; 593 594 if ((page = FindPage(curpage->floflink[1])) != NULL) 595 { 596 newPage = page->pagenum; 597 newSubPage = -1; 598 m_curpage_showheader = true; 599 } 600 break; 601 } 602 603 case TTKey::kFlofYellow: 604 { 605 if (!curpage) 606 return; 607 608 if ((page = FindPage(curpage->floflink[2])) != NULL) 609 { 610 newPage = page->pagenum; 611 newSubPage = -1; 612 m_curpage_showheader = true; 613 } 614 break; 615 } 616 617 case TTKey::kFlofBlue: 618 { 619 if (!curpage) 620 return; 621 622 if ((page = FindPage(curpage->floflink[3])) != NULL) 623 { 624 newPage = page->pagenum; 625 newSubPage = -1; 626 m_curpage_showheader = true; 627 } 628 break; 629 } 630 631 case TTKey::kFlofWhite: 632 { 633 if (!curpage) 634 return; 635 636 if ((page = FindPage(curpage->floflink[4])) != NULL) 637 { 638 newPage = page->pagenum; 639 newSubPage = -1; 640 m_curpage_showheader = true; 641 } 642 break; 643 } 644 } 645 646 if (newPage < 0x100) 647 newPage = 0x100; 648 if (newPage > 0x899) 649 newPage = 0x899; 650 651 if (!numeric_input) 652 { 653 m_pageinput[0] = (newPage / 256) + '0'; 654 m_pageinput[1] = ((newPage % 256) / 16) + '0'; 655 m_pageinput[2] = (newPage % 16) + '0'; 656 } 657 658 if (newPage != m_curpage || newSubPage != m_cursubpage) 659 { 660 m_curpage = newPage; 661 m_cursubpage = newSubPage; 662 m_revealHidden = false; 663 PageUpdated(m_curpage, m_cursubpage); 664 } 665 } 666 667 /** \fn OSDTypeTeletext::SetForegroundColor(int) 668 * \brief Set the font color to the given color. 669 * 670 * NOTE: TTColor::TRANSPARENT does not do anything! 671 * \sa TTColor 672 */ 673 void OSDTypeTeletext::SetForegroundColor(int color) 674 { 675 switch (color & ~TTColor::TRANSPARENT) 676 { 677 case TTColor::BLACK: m_font->setColor(m_color_black); break; 678 case TTColor::RED: m_font->setColor(m_color_red); break; 679 case TTColor::GREEN: m_font->setColor(m_color_green); break; 680 case TTColor::YELLOW: m_font->setColor(m_color_yellow); break; 681 case TTColor::BLUE: m_font->setColor(m_color_blue); break; 682 case TTColor::MAGENTA: m_font->setColor(m_color_magenta); break; 683 case TTColor::CYAN: m_font->setColor(m_color_cyan); break; 684 case TTColor::WHITE: m_font->setColor(m_color_white); break; 685 } 686 687 m_font->setShadow(0,0); 688 m_font->setOutline(0); 689 } 690 691 /** \fn OSDTypeTeletext:SetBackgroundColor(int) 692 * \brief Set the background color to the given color 693 * 694 * \sa TTColor 695 */ 696 void OSDTypeTeletext::SetBackgroundColor(int ttcolor) 697 { 698 QColor color; 699 700 switch (ttcolor & ~TTColor::TRANSPARENT) 701 { 702 case TTColor::BLACK: color = m_color_black; break; 703 case TTColor::RED: color = m_color_red; break; 704 case TTColor::GREEN: color = m_color_green; break; 705 case TTColor::YELLOW: color = m_color_yellow; break; 706 case TTColor::BLUE: color = m_color_blue; break; 707 case TTColor::MAGENTA: color = m_color_magenta; break; 708 case TTColor::CYAN: color = m_color_cyan; break; 709 case TTColor::WHITE: color = m_color_white; break; 710 } 711 712 int r = color.red(); 713 int g = color.green(); 714 int b = color.blue(); 715 716 float y = (0.299*r) + (0.587*g) + (0.114*b); 717 float u = (0.564*(b - y)); // = -0.169R-0.331G+0.500B 718 float v = (0.713*(r - y)); // = 0.500R-0.419G-0.081B 719 720 m_bgcolor_y = (uint8_t)(y); 721 m_bgcolor_u = (uint8_t)(127 + u); 722 m_bgcolor_v = (uint8_t)(127 + v); 723 m_bgcolor_a = (ttcolor & TTColor::TRANSPARENT) ? 0x00 : 0xff; 724 } 725 726 /** \fn OSDTypeTeletext::DrawBackground(int, int) 727 * \brief draws background in the color set in setBackgroundColor 728 * 729 * \param x X position (40 cols) 730 * \param y Y position (25 rows) 731 */ 732 void OSDTypeTeletext::DrawBackground(int x, int y) 733 { 734 x *= m_tt_colspace; 735 x += m_displayrect.left(); 736 737 y *= m_tt_rowspace; 738 y += m_displayrect.top(); 739 740 DrawRect(x, y, m_tt_colspace, m_tt_rowspace); 741 } 742 743 /** \fn OSDTypeteletext::drawRect(int, int, int, int) 744 * \brief draws a Rectangle at position x and y (width dx, height dy) 745 * with the color set in setBackgroundColor 746 * 747 * \param x X position at the screen 748 * \param y Y position at the screen 749 * \param dx width 750 * \param dy height 751 */ 752 void OSDTypeTeletext::DrawRect(int x, int y, int dx, int dy) 753 { 754 QRect all(x, y, dx, dy); 755 m_surface->AddRect(all); 756 757 int luma_stride = m_surface->width; 758 int chroma_stride = m_surface->width >> 1; 759 int ye = y + dy; 760 761 unsigned char *buf_y = m_surface->y + (luma_stride * y) + x; 762 unsigned char *buf_u = m_surface->u + (chroma_stride * (y>>1)) + (x>>1); 763 unsigned char *buf_v = m_surface->v + (chroma_stride * (y>>1)) + (x>>1); 764 unsigned char *buf_a = m_surface->alpha + (luma_stride * y) + x; 765 766 for (; y<ye; ++y) 767 { 768 for (int i=0; i<dx; ++i) 769 { 770 buf_y[i] = m_bgcolor_y; 771 buf_a[i] = m_bgcolor_a; 772 } 773 774 if ((y & 1) == 0) 775 { 776 for (int i=0; i<dx; ++i) 777 { 778 buf_u[i>>1] = m_bgcolor_u; 779 buf_v[i>>1] = m_bgcolor_v; 780 } 781 782 buf_u += chroma_stride; 783 buf_v += chroma_stride; 784 } 785 786 buf_y += luma_stride; 787 buf_a += luma_stride; 788 } 789 } 790 791 /** \fn OSDTypeTeletext::DrawCharacter(int, int, QChar, int) 792 * \brief Draws a character at posistion x, y 793 * 794 * \param x X position (40 cols) 795 * \param y Y position (25 rows) 796 * \param ch Character 797 * \param doubleheight if different to 0, draw doubleheighted character 798 */ 799 void OSDTypeTeletext::DrawCharacter(int x, int y, QChar ch, int doubleheight) 800 { 801 if (!m_font) 802 return; 803 804 QString line = ch; 805 806 x *= m_tt_colspace; 807 x += m_displayrect.left(); 808 809 y *= m_tt_rowspace; 810 y += m_displayrect.top(); 811 812 m_font->DrawString(m_surface, x, y, line, 813 m_surface->width, m_surface->height, 814 255, doubleheight!=0); 815 } 816 817 /** \fn OSDTypeTeletext::DrawMosaic(int, int, code, int) 818 * \brief Draws a mosaic as defined in ETSI EN 300 706 819 * 820 * \param x X position (40 cols) 821 * \param y Y position (25 rows) 822 * \param code Code 823 * \param doubleheight if different to 0, draw doubleheighted mosaic) 824 */ 825 void OSDTypeTeletext::DrawMosaic(int x, int y, int code, int doubleheight) 826 { 827 (void)x; 828 (void)y; 829 (void)code; 830 831 x *= m_tt_colspace; 832 x += m_displayrect.left(); 833 834 y *= m_tt_rowspace; 835 y += m_displayrect.top(); 836 837 int dx = (int)round(m_tt_colspace / 2)+1; 838 int dy = (int)round(m_tt_rowspace / 3)+1; 839 840 if (doubleheight != 0) 841 { 842 dx *= 2; 843 dy *= 2; 844 } 845 846 if (code & 0x10) DrawRect(x, y + 2*dy, dx, dy); 847 if (code & 0x40) DrawRect(x + dx, y + 2*dy, dx, dy); 848 if (code & 0x01) DrawRect(x, y, dx, dy); 849 if (code & 0x02) DrawRect(x + dx, y, dx, dy); 850 if (code & 0x04) DrawRect(x, y + dy, dx, dy); 851 if (code & 0x08) DrawRect(x + dx, y + dy, dx, dy); 852 } 853 854 void OSDTypeTeletext::DrawLine(const uint8_t* page, uint row, int lang) 855 { 856 bool mosaic; 857 bool conceal; 858 bool seperation; 859 bool flash; 860 bool doubleheight; 861 bool blink; 862 bool hold; 863 bool endbox; 864 bool startbox; 865 866 char last_ch = ' '; 867 char ch; 868 869 uint fgcolor = TTColor::WHITE; 870 uint bgcolor = TTColor::BLACK; 871 uint newfgcolor = TTColor::WHITE; 872 uint newbgcolor = TTColor::BLACK; 873 874 if (m_curpage_issubtitle || m_transparent) 875 { 876 bgcolor = TTColor::TRANSPARENT; 877 newbgcolor = TTColor::TRANSPARENT; 878 } 879 880 SetForegroundColor(fgcolor); 881 SetBackgroundColor(bgcolor); 882 883 mosaic = false; 884 seperation = false; 885 conceal = false; 886 flash = false; 887 doubleheight = false; 888 blink = false; 889 hold = false; 890 endbox = false; 891 startbox = false; 892 893 if (row == 1) 894 { 895 for (uint x = 0; x < 8; x++) 896 DrawBackground(x, 1); 897 } 898 899 for (uint x = (row == 1 ? 8 : 0); x < COLS; ++x) 900 { 901 if (startbox) 902 { 903 bgcolor = bgcolor = TTColor::BLACK; 904 startbox = false; 905 } 906 907 if (endbox) 908 { 909 bgcolor = TTColor::TRANSPARENT; 910 endbox = false; 911 } 912 913 SetForegroundColor(fgcolor); 914 SetBackgroundColor(bgcolor); 915 916 ch = page[x] & 0x7F; 917 switch (ch) 918 { 919 case 0x00 ... 0x07: // alpha + foreground color 920 fgcolor = ch & 7; 921 mosaic = false; 922 conceal = false; 923 goto ctrl; 924 case 0x08: // flash 925 // XXX 926 goto ctrl; 927 case 0x09: // steady 928 flash = false; 929 goto ctrl; 930 case 0x0a: // end box 931 endbox = true; 932 goto ctrl; 933 case 0x0b: // start box 934 if (x < COLS - 1 && (page[x + 1] & 0x7F != 0x0b)) 935 startbox = true; 936 goto ctrl; 937 case 0x0c: // normal height 938 doubleheight = 0; 939 goto ctrl; 940 case 0x0d: // double height 941 doubleheight = row < ROWS-1; 942 goto ctrl; 943 case 0x10 ... 0x17: // graphics + foreground color 944 fgcolor = ch & 7; 945 mosaic = true; 946 conceal = false; 947 goto ctrl; 948 case 0x18: // conceal display 949 conceal = true; 950 goto ctrl; 951 case 0x19: // contiguous graphics 952 seperation = false; 953 goto ctrl; 954 case 0x1a: // separate graphics 955 seperation = true; 956 goto ctrl; 957 case 0x1c: // black background 958 bgcolor = TTColor::BLACK; 959 goto ctrl; 960 case 0x1d: // new background 961 bgcolor = fgcolor; 962 goto ctrl; 963 case 0x1e: // hold graphics 964 hold = true; 965 goto ctrl; 966 case 0x1f: // release graphics 967 hold = false; 968 goto ctrl; 969 case 0x0e: // SO (reserved, double width) 970 case 0x0f: // SI (reserved, double size) 971 case 0x1b: // ESC (reserved) 972 ch = ' '; 973 break; 974 ctrl: 975 ch = ' '; 976 if (hold && mosaic) 977 ch = last_ch; 978 break; 979 980 case 0x80 ... 0x9f: // these aren't used 981 ch = ' '; // BAD_CHAR; 982 break; 983 default: 984 if (conceal && !m_revealHidden) 985 ch = ' '; 986 break; 987 } 988 989 newfgcolor = fgcolor; 990 newbgcolor = bgcolor; 991 992 SetForegroundColor(newfgcolor); 993 SetBackgroundColor(newbgcolor); 994 if ((row != 0) || (x > 7)) 995 { 996 if (m_transparent) 997 SetBackgroundColor(TTColor::TRANSPARENT); 998 999 DrawBackground(x, row); 1000 if (doubleheight != 0) 1001 DrawBackground(x, row +1); 1002 1003 if ((mosaic) && (ch < 0x40 || ch > 0x5F)) 1004 { 1005 SetBackgroundColor(newfgcolor); 1006 DrawMosaic(x, row, ch, doubleheight); 1007 } 1008 else 1009 { 1010 if (doubleheight != 0) 1011 DrawCharacter(x, row+1, CharConversion(ch, lang), doubleheight); 1012 else 1013 DrawCharacter(x, row, CharConversion(ch, lang), doubleheight); 1014 } 1015 } 1016 } 1017 } 1018 1019 void OSDTypeTeletext::DrawHeader(const uint8_t* page, int lang) 1020 { 1021 if (!m_displaying) 1022 return; 1023 1024 DrawLine(page, 1, lang); 1025 StatusUpdated(); 1026 } 1027 1028 void OSDTypeTeletext::DrawPage(void) 1029 { 1030 if (!m_displaying) 1031 return; 1032 1033 TeletextSubPage *ttpage = FindSubPage(m_curpage, m_cursubpage); 1034 1035 if (ttpage == NULL) 1036 return; 1037 1038 m_cursubpage = ttpage->subpagenum; 1039 1040 int a = 0; 1041 if ((ttpage->subtitle) || (ttpage->flags & 1042 (TP_SUPPRESS_HEADER + TP_NEWSFLASH + TP_SUBTITLE))) 1043 { 1044 a = 1; 1045 m_curpage_showheader = false; 1046 m_curpage_issubtitle = true; 1047 } 1048 else 1049 { 1050 m_curpage_issubtitle = false; 1051 m_curpage_showheader = true; 1052 DrawHeader(ttpage->data[0], ttpage->lang); 1053 } 1054 1055 for (int y = ROWS-a; y >= 2; y--) 1056 DrawLine(ttpage->data[y-1], y, ttpage->lang); 1057 } 1058 1059 void OSDTypeTeletext::Reinit(float wchange, float hchange) 1060 { 1061 m_displayrect = QRect((int)(m_displayrect.x() * wchange), 1062 (int)(m_displayrect.y() * hchange), 1063 (int)(m_displayrect.width() * wchange), 1064 (int)(m_displayrect.height() * hchange)); 1065 1066 m_tt_colspace = m_displayrect.width() / COLS; 1067 m_tt_rowspace = m_displayrect.height() / ROWS; 1068 } 1069 1070 void OSDTypeTeletext::Draw(OSDSurface *surface, int fade, int maxfade, 1071 int xoff, int yoff) 1072 { 1073 (void)surface; 1074 (void)fade; 1075 (void)maxfade; 1076 (void)xoff; 1077 (void)yoff; 1078 1079 m_surface = surface; 1080 DrawPage(); 1081 } 1082 1083 void OSDTypeTeletext::StatusUpdated(void) 1084 { 1085 SetForegroundColor(TTColor::WHITE); 1086 SetBackgroundColor(TTColor::BLACK); 1087 1088 if (!m_transparent) 1089 for (int i = 0; i < 40; ++i) 1090 DrawBackground(i, 0); 1091 1092 DrawCharacter(1, 0, 'P', 0); 1093 DrawCharacter(2, 0, m_pageinput[0], 0); 1094 DrawCharacter(3, 0, m_pageinput[1], 0); 1095 DrawCharacter(4, 0, m_pageinput[2], 0); 1096 1097 TeletextSubPage *ttpage = FindSubPage(m_curpage, m_cursubpage); 1098 1099 if (ttpage == NULL) 1100 { 1101 SetBackgroundColor(TTColor::BLACK); 1102 SetForegroundColor(TTColor::WHITE); 1103 1104 if (!m_transparent) 1105 for (int i = 7; i < 40; i++) 1106 DrawBackground(i, 0); 1107 1108 char *str = "Page Not Available"; 1109 for (unsigned int i = 0; i < strlen(str); ++i) 1110 DrawCharacter(i+10, 0, str[i], 0); 1111 1112 return; 1113 } 1114 1115 // get list of available sub pages 1116 QString str = ""; 1117 int count = 1, selected = 0; 1118 TeletextPage *page = FindPage(m_curpage); 1119 if (page) 1120 { 1121 std::map<int, TeletextSubPage>::iterator subpageIter; 1122 subpageIter = page->subpages.begin(); 1123 while (subpageIter != page->subpages.end()) 1124 { 1125 TeletextSubPage *subpage = &subpageIter->second; 1126 1127 if (subpage->subpagenum == m_cursubpage) 1128 { 1129 selected = count; 1130 str += "*"; 1131 } 1132 else 1133 str += " "; 1134 1135 str += QString().sprintf("%02X", subpage->subpagenum); 1136 1137 ++subpageIter; 1138 ++count; 1139 } 1140 } 1141 1142 if (str != "") 1143 { 1144 // if there are less than 9 subpages fill the empty slots with spaces 1145 if (count < 10) 1146 { 1147 QString spaces; 1148 spaces.fill(' ', 27 - str.length()); 1149 str = " <" + str + spaces + " > "; 1150 } 1151 else 1152 { 1153 // try to centralize the selected sub page in the list 1154 int startPos = selected - 5; 1155 if (startPos < 0) 1156 startPos = 0; 1157 if (startPos + 9 >= count) 1158 startPos = count - 10; 1159 1160 str = " <" + str.mid(startPos * 3, 27) + " > "; 1161 } 1162 1163 SetForegroundColor(TTColor::WHITE); 1164 for (int x = 0; x < 11; x++) 1165 { 1166 if (m_transparent) 1167 SetBackgroundColor(TTColor::TRANSPARENT); 1168 else 1169 SetBackgroundColor(TTColor::BLACK); 1170 1171 DrawBackground(x * 3 + 7, 0); 1172 1173 if (str[x * 3] == '*') 1174 { 1175 str[x * 3] = ' '; 1176 SetBackgroundColor(TTColor::RED); 1177 } 1178 1179 DrawBackground(x * 3 + 8, 0); 1180 DrawBackground(x * 3 + 9, 0); 1181 1182 DrawCharacter(x * 3 + 7, 0, str[x * 3], 0); 1183 DrawCharacter(x * 3 + 8, 0, str[x * 3 + 1], 0); 1184 DrawCharacter(x * 3 + 9, 0, str[x * 3 + 2], 0); 1185 } 1186 } 1187 } 1188 -
libs/libmythtv/osdtypes.cpp
11 11 #include "ttfont.h" 12 12 #include "osdsurface.h" 13 13 #include "osdlistbtntype.h" 14 #include "osdtypeteletext.h" 14 15 15 16 #include "mythcontext.h" 16 17 … … 101 102 OSDTypeText *newtext = new OSDTypeText(*item); 102 103 AddType(newtext); 103 104 } 105 else if (OSDTypeTeletext *item = dynamic_cast<OSDTypeTeletext*>(type)) 106 { 107 OSDTypeTeletext *newtt = new OSDTypeTeletext(*item); 108 AddType(newtt); 109 } 104 110 else if (OSDTypePositionImage *item = 105 111 dynamic_cast<OSDTypePositionImage*>(type)) 106 112 { … … 180 186 { 181 187 item->Reinit(wchange, hchange); 182 188 } 189 else if (OSDTypeTeletext *item = dynamic_cast<OSDTypeTeletext*>(type)) 190 { 191 item->Reinit(wchange, hchange); 192 } 183 193 else if (OSDTypePositionImage *item = 184 194 dynamic_cast<OSDTypePositionImage*>(type)) 185 195 { … … 657 667 658 668 void OSDTypeText::DrawString(OSDSurface *surface, QRect rect, 659 669 const QString &text, int fade, int maxfade, 660 int xoff, int yoff )670 int xoff, int yoff, bool doubl) 661 671 { 662 672 if (m_centered || m_right) 663 673 { … … 694 704 if (m_usingalt && m_altfont) 695 705 font = m_altfont; 696 706 697 font->DrawString(surface, x, y, text, maxx, maxy, alphamod );707 font->DrawString(surface, x, y, text, maxx, maxy, alphamod, doubl); 698 708 } 699 709 700 710 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -
libs/libmythtv/tv_play.cpp
33 33 #include "config.h" 34 34 #include "livetvchain.h" 35 35 #include "playgroup.h" 36 #include "osdtypeteletext.h" 37 #include "teletextdecoder.h" 36 38 37 39 #ifndef HAVE_ROUND 38 40 #define round(x) ((int) ((x) + 0.5)) … … 119 121 "W"); 120 122 REG_KEY("TV Playback", "TOGGLECC", "Toggle Closed Captioning/Teletext", 121 123 "T"); 124 REG_KEY("TV Playback", "MENURED", "Menu Red", "F2"); 125 REG_KEY("TV Playback", "MENUGREEN", "Menu Green", "F3"); 126 REG_KEY("TV Playback", "MENUYELLOW", "Menu Yellow", "F4"); 127 REG_KEY("TV Playback", "MENUBLUE", "Menu Blue", "F5"); 128 REG_KEY("TV Playback", "MENUWHITE", "Menu White", "F6"); 129 REG_KEY("TV Playback", "REVEAL", "Teletext reveal hidden Text", "F7"); 122 130 REG_KEY("TV Playback", "DISPCC1", "Display CC1", ""); 123 131 REG_KEY("TV Playback", "DISPCC2", "Display CC2", ""); 124 132 REG_KEY("TV Playback", "DISPCC3", "Display CC3", ""); … … 179 187 Global: Return, Enter, Space, Esc 180 188 181 189 Global: F1, 182 Playback: Ctrl-B, F 7,F8,F9,F10,F11190 Playback: Ctrl-B, F2,F3,F4,F5,F6,F7,F8,F9,F10,F11 183 191 */ 184 192 } 185 193 … … 212 220 exitPlayer(false), paused(false), errored(false), 213 221 stretchAdjustment(false), 214 222 audiosyncAdjustment(false), audiosyncBaseline(LONG_LONG_MIN), 215 editmode(false), zoomMode(false), sigMonMode(false), 223 editmode(false), zoomMode(false), 224 teletextmode(false), sigMonMode(false), 216 225 update_osd_pos(false), endOfRecording(false), requestDelete(false), 217 226 doSmartForward(false), 218 227 queuedTranscode(false), getRecorderPlaybackInfo(false), … … 1084 1093 1085 1094 if (nvp->IsPlaying()) 1086 1095 { 1096 TeletextDecoder *tt_dec = nvp->GetTeletextDecoder(); 1097 1098 // This is needed because the OSDType does the decoding/caching of 1099 // the teletext pages 1100 OSDSet *oset = GetOSD()->GetSet("teletext"); 1101 if (oset) 1102 { 1103 OSDType *traw = oset->GetType("teletext"); 1104 OSDTypeTeletext *tt_view = dynamic_cast<OSDTypeTeletext*>(traw); 1105 tt_dec->SetViewer(tt_view); 1106 } 1107 1087 1108 activenvp = nvp; 1088 1109 activerbuffer = prbuffer; 1089 1110 StartOSD(); … … 1753 1774 return; 1754 1775 } 1755 1776 1777 //XXX ivtv/dvb teletext 1778 if (teletextmode) 1779 { 1780 int passThru = 0; 1781 1782 for (unsigned int i = 0; i < actions.size() && !handled; i++) 1783 { 1784 QString action = actions[i]; 1785 handled = true; 1786 if (action == "UP") 1787 TeletextNavigate(-1); 1788 else if (action == "DOWN") 1789 TeletextNavigate(-2); 1790 else if (action == "RIGHT") 1791 TeletextNavigate(-3); 1792 else if (action == "LEFT") 1793 TeletextNavigate(-4); 1794 else if (action == "TOGGLEASPECT") 1795 TeletextNavigate(-5); 1796 else if (action == "MENURED") 1797 TeletextNavigate(-6); 1798 else if (action == "MENUGREEN") 1799 TeletextNavigate(-7); 1800 else if (action == "MENUYELLOW") 1801 TeletextNavigate(-8); 1802 else if (action == "MENUBLUE") 1803 TeletextNavigate(-9); 1804 else if (action == "MENUWHITE") 1805 TeletextNavigate(-10); 1806 else if (action == "REVEAL") 1807 TeletextNavigate(-11); 1808 else if (action == "0" || action == "1" || action == "2" || 1809 action == "3" || action == "4" || action == "5" || 1810 action == "6" || action == "7" || action == "8" || 1811 action == "9") 1812 TeletextNavigate(action.toInt()); 1813 else if (action == "MENU" || action == "TOGGLECC" || 1814 action == "ESCAPE") 1815 TeletextStop(); 1816 else 1817 handled = false; 1818 } 1819 if (!passThru) 1820 return; 1821 } 1822 1756 1823 if (zoomMode) 1757 1824 { 1758 1825 int passThru = 0; … … 2001 2068 handled = true; 2002 2069 2003 2070 if (action == "TOGGLECC" && !browsemode) 2004 { 2005 if (vbimode == VBIMode::NTSC_CC) 2071 { 2072 int dec_type = nvp->GetTeletextDecoder()->GetDecoderType(); 2073 if (dec_type != -1) 2074 TeletextStart(); 2075 else if (vbimode == VBIMode::NTSC_CC) 2006 2076 nvp->ToggleCC(vbimode, 0); 2007 2077 else if (ccInputMode) 2008 2078 { … … 3233 3303 aud->ToggleMute(); 3234 3304 muted = true; 3235 3305 } 3306 OSDSet *oset = GetOSD()->GetSet("teletext"); 3307 if (oset) 3308 { 3309 OSDType *traw = oset->GetType("teletext"); 3310 OSDTypeTeletext *tt_view = dynamic_cast<OSDTypeTeletext*>(traw); 3311 if (tt_view) 3312 tt_view->Reset(); 3313 } 3236 3314 } 3237 3315 3238 3316 if (nvp && (activenvp == nvp) && paused) … … 3461 3539 aud->ToggleMute(); 3462 3540 muted = true; 3463 3541 } 3542 OSDSet *oset = GetOSD()->GetSet("teletext"); 3543 if (oset) 3544 { 3545 OSDType *traw = oset->GetType("teletext"); 3546 OSDTypeTeletext *tt_view = dynamic_cast<OSDTypeTeletext*>(traw); 3547 if (tt_view) 3548 tt_view->Reset(); 3549 } 3464 3550 } 3465 3551 3466 3552 if (nvp && (activenvp == nvp) && paused && GetOSD()) … … 4772 4858 GetOSD()->SetSettingsText(msg, 3); 4773 4859 } 4774 4860 4861 //XXX new teletext 4862 void TV::TeletextStart(void) 4863 { 4864 if (activenvp != nvp) 4865 return; 4866 4867 if (paused || !GetOSD()) 4868 return; 4869 4870 TeletextDecoder *tt_dec = nvp->GetTeletextDecoder(); 4871 OSDSet *oset = GetOSD()->GetSet("teletext"); 4872 if (!oset) 4873 { 4874 VERBOSE(VB_IMPORTANT, LOC_ERR + "No teletext set available"); 4875 return; 4876 } 4877 4878 OSDType *traw = oset->GetType("teletext"); 4879 OSDTypeTeletext *tt_view = dynamic_cast<OSDTypeTeletext*>(traw); 4880 if (!tt_view) 4881 { 4882 VERBOSE(VB_IMPORTANT, LOC_ERR + "No teletext type available"); 4883 return; 4884 } 4885 4886 tt_dec->SetViewer(tt_view); 4887 tt_view->SetDisplaying(true); 4888 4889 teletextmode = true; 4890 4891 oset->Display(); 4892 GetOSD()->SetVisible(oset, 0); 4893 } 4894 4895 void TV::TeletextNavigate(int page) 4896 { 4897 if (!GetOSD()) 4898 return; 4899 4900 OSDSet *oset = GetOSD()->GetSet("teletext"); 4901 if (!oset) 4902 { 4903 VERBOSE(VB_IMPORTANT, LOC_ERR + "No teletext set available"); 4904 return; 4905 } 4906 4907 OSDType *traw = oset->GetType("teletext"); 4908 OSDTypeTeletext *tt = dynamic_cast<OSDTypeTeletext*>(traw); 4909 if (!tt) 4910 { 4911 VERBOSE(VB_IMPORTANT, LOC_ERR + "No teletext type available"); 4912 return; 4913 } 4914 4915 switch (page) 4916 { 4917 case -1: 4918 tt->KeyPress(TTKey::kNextPage); 4919 break; 4920 case -2: 4921 tt->KeyPress(TTKey::kPrevPage); 4922 break; 4923 case -3: 4924 tt->KeyPress(TTKey::kNextSubPage); 4925 break; 4926 case -4: 4927 tt->KeyPress(TTKey::kPrevSubPage); 4928 break; 4929 case -5: 4930 tt->KeyPress(TTKey::kTransparent); 4931 break; 4932 case -6: 4933 tt->KeyPress(TTKey::kFlofRed); 4934 break; 4935 case -7: 4936 tt->KeyPress(TTKey::kFlofGreen); 4937 break; 4938 case -8: 4939 tt->KeyPress(TTKey::kFlofYellow); 4940 break; 4941 case -9: 4942 tt->KeyPress(TTKey::kFlofBlue); 4943 break; 4944 case -10: 4945 tt->KeyPress(TTKey::kFlofWhite); 4946 break; 4947 case -11: 4948 tt->KeyPress(TTKey::kRevealHidden); 4949 break; 4950 case 0 ... 9: 4951 tt->KeyPress(page); 4952 break; 4953 } 4954 } 4955 4956 void TV::TeletextStop(void) 4957 { 4958 if (!teletextmode || !GetOSD()) 4959 return; 4960 4961 OSDSet *oset = GetOSD()->GetSet("teletext"); 4962 if (oset) 4963 { 4964 OSDType *traw = oset->GetType("teletext"); 4965 OSDTypeTeletext *tt_view = dynamic_cast<OSDTypeTeletext*>(traw); 4966 if (tt_view) 4967 tt_view->SetDisplaying(false); 4968 } 4969 GetOSD()->HideSet("teletext"); 4970 4971 // nvp->GetTeletextDecoder()->SetViewer(NULL); 4972 4973 teletextmode = false; 4974 } 4975 4775 4976 void TV::BrowseChannel(const QString &chan) 4776 4977 { 4777 4978 if (!activerecorder->CheckChannel(chan)) … … 4966 5167 QString action = item->getAction(); 4967 5168 4968 5169 if (action == "TOGGLECC") 4969 nvp->ToggleCC(vbimode, 0); 5170 { 5171 if (nvp->GetTeletextDecoder()->GetDecoderType() != -1) 5172 TeletextStart(); 5173 else 5174 nvp->ToggleCC(vbimode, 0); 5175 } 4970 5176 else if (action.left(6) == "DISPCC") 4971 5177 nvp->ToggleCC(vbimode, action.right(1).toInt()); 4972 5178 else if (action.left(7) == "DISPTXT") … … 5694 5900 activerbuffer->IgnoreLiveEOF(false); 5695 5901 } 5696 5902 5903 //if (nvp) 5904 // nvp->GetTeletextDecoder()->Reset(); 5905 5697 5906 if (!nvp || (nvp && activenvp == nvp)) 5698 5907 { 5699 5908 UpdateOSDProgInfo("program_info"); -
libs/libmythtv/libmythtv.pro
188 188 SOURCES += progfind.cpp ttfont.cpp 189 189 190 190 # Teletext stuff 191 HEADERS += teletextdecoder.h osdtypeteletext.h 191 192 HEADERS += vbilut.h 193 SOURCES += teletextdecoder.cpp osdtypeteletext.cpp 192 194 SOURCES += vbilut.cpp 193 195 194 196 # C stuff -
libs/libmythtv/osdtypeteletext.h
1 #ifndef OSD_TYPE_TELETEXT_H_ 2 #define OSD_TYPE_TELETEXT_H_ 3 4 #include <vector> 5 using namespace std; 6 7 #include <qstring.h> 8 #include <qrect.h> 9 #include <qmap.h> 10 #include <qvaluelist.h> 11 #include <qobject.h> 12 #include <qcolor.h> 13 #include <qmutex.h> 14 15 #include "osdtypes.h" 16 #include "teletextdecoder.h" 17 18 class TTFFont; 19 class OSDType; 20 class OSDSurface; 21 class TV; 22 23 class TTColor 24 { 25 public: 26 static const uint BLACK = 0; 27 static const uint RED = 1; 28 static const uint GREEN = 2; 29 static const uint YELLOW = 3; 30 static const uint BLUE = 4; 31 static const uint MAGENTA = 5; 32 static const uint CYAN = 6; 33 static const uint WHITE = 7; 34 static const uint TRANSPARENT = 8; 35 }; 36 37 class TTKey 38 { 39 public: 40 static const uint k0 = 0; 41 static const uint k1 = 1; 42 static const uint k2 = 2; 43 static const uint k3 = 3; 44 static const uint k4 = 4; 45 static const uint k5 = 5; 46 static const uint k6 = 6; 47 static const uint k7 = 7; 48 static const uint k8 = 8; 49 static const uint k9 = 9; 50 static const uint kNextPage = 10; 51 static const uint kPrevPage = 11; 52 static const uint kNextSubPage = 12; 53 static const uint kPrevSubPage = 13; 54 static const uint kHold = 14; 55 static const uint kTransparent = 15; 56 static const uint kFlofRed = 16; 57 static const uint kFlofGreen = 17; 58 static const uint kFlofYellow = 18; 59 static const uint kFlofBlue = 19; 60 static const uint kFlofWhite = 20; 61 static const uint kRevealHidden = 21; 62 }; 63 64 #define TP_SUPPRESS_HEADER 0x01 65 #define TP_UPDATE_INDICATOR 0x02 66 #define TP_INTERRUPTED_SEQ 0x04 67 #define TP_INHIBIT_DISPLAY 0x08 68 #define TP_MAGAZINE_SERIAL 0x10 69 #define TP_ERASE_PAGE 0x20 70 #define TP_NEWSFLASH 0x40 71 #define TP_SUBTITLE 0x80 72 73 class TeletextSubPage 74 { 75 public: 76 int pagenum, subpagenum; ///< the wanted page number 77 int lang; ///< language code 78 int flags; ///< misc flags 79 uint8_t data[25][40]; ///< page data 80 int flof; ///< page has FastText links 81 int floflink[6]; ///< FastText links (FLOF) 82 bool subtitle; ///< page is subtitle page 83 }; 84 85 class TeletextPage 86 { 87 public: 88 int pagenum; 89 int current_subpage; 90 std::map<int, TeletextSubPage> subpages; 91 }; 92 93 #define MAGAZINE(page) page / 256 94 95 class TeletextMagazine 96 { 97 public: 98 QMutex lock; 99 int current_page; 100 int current_subpage; 101 std::map<int, TeletextPage> pages; 102 }; 103 104 class OSDTypeTeletext : public OSDType 105 { 106 Q_OBJECT 107 public: 108 OSDTypeTeletext(const QString &name, QRect displayrect, TTFFont *font); 109 OSDTypeTeletext(const OSDTypeTeletext &other); 110 ~OSDTypeTeletext(); 111 112 void Reset(); 113 114 void Reinit(float wchange, float hchange); 115 116 void Draw(OSDSurface *surface, int fade, int maxfade, int xoff, int yoff); 117 118 void SetForegroundColor(int color); 119 void SetBackgroundColor(int color); 120 121 void DrawBackground(int x, int y); 122 void DrawRect(int x, int y, int dx, int dy); 123 void DrawCharacter(int x, int y, QChar ch, int doubleheight = 0); 124 void DrawMosaic(int x, int y, int code, int doubleheight); 125 126 void DrawLine(const uint8_t* page, uint row, int lang); 127 void DrawHeader(const uint8_t* page, int lang); 128 void DrawPage(void); 129 130 void NewsFlash(void) {}; 131 132 void AddPageHeader(int page, int subpage, const uint8_t *buf, int vbimode, int lang, int flags); 133 void AddTeletextData(int magazine, int row, const uint8_t* buf, int vbimode); 134 135 void PageUpdated(int page, int subpage); 136 void HeaderUpdated(uint8_t* page, int lang); 137 void StatusUpdated(void); 138 139 void KeyPress(uint key); 140 141 void SetDisplaying(bool display) { m_displaying = display; }; 142 143 private: 144 QMutex m_lock; 145 QRect m_displayrect; 146 147 TTFFont *m_font; 148 OSDSurface *m_surface; 149 OSDTypeBox *m_box; 150 151 int m_tt_colspace; 152 int m_tt_rowspace; 153 154 uint8_t m_bgcolor_y; 155 uint8_t m_bgcolor_u; 156 uint8_t m_bgcolor_v; 157 uint8_t m_bgcolor_a; 158 159 // last fetched page 160 int m_fetchpage; 161 int m_fetchsubpage; 162 163 // currently displayed page: 164 int m_curpage; 165 int m_cursubpage; 166 int m_pageinput[3]; 167 bool m_curpage_showheader; 168 bool m_curpage_issubtitle; 169 170 bool m_transparent; 171 bool m_revealHidden; 172 173 bool m_displaying; 174 175 TeletextMagazine m_magazines[8]; 176 unsigned char bitswap[256]; 177 178 char CharConversion(char ch, int lang); 179 TeletextSubPage *FindSubPage(int page, int subpage, int direction = 0); 180 TeletextPage *FindPage(int page, int direction = 0); 181 182 static const uint COLS = 40; 183 static const uint ROWS = 26; 184 }; 185 186 #endif 187 -
libs/libmythtv/osdtypes.h
186 186 187 187 private: 188 188 void DrawString(OSDSurface *surface, QRect rect, const QString &text, 189 int fade, int maxfade, int xoff, int yoff); 189 int fade, int maxfade, int xoff, int yoff, 190 bool double_size=false); 190 191 191 192 QRect m_displaysize; 192 193 QRect m_screensize; -
libs/libmythtv/tv_play.h
257 257 void DoSkipCommercials(int direction); 258 258 void DoEditMode(void); 259 259 260 void TeletextStart(void); 261 void TeletextNavigate(int num); 262 void TeletextStop(void); 263 260 264 void DoQueueTranscode(void); 261 265 262 266 void SetAutoCommercialSkip(int skipMode = 0); … … 361 365 long long audiosyncBaseline; 362 366 bool editmode; ///< Are we in video editing mode 363 367 bool zoomMode; 368 bool teletextmode; ///< Are we in teletext switching mode? 364 369 bool sigMonMode; ///< Are we in signal monitoring mode? 365 370 bool update_osd_pos; ///< Redisplay osd? 366 371 bool endOfRecording; ///< !nvp->IsPlaying() && StateIsPlaying(internalState) -
libs/libmythtv/avformatdecoder.h
8 8 #include "format.h" 9 9 #include "decoderbase.h" 10 10 #include "ccdecoder.h" 11 #include "teletextdecoder.h" 12 #include "vbilut.h" 11 13 12 14 extern "C" { 13 15 #include "frame.h" … … 232 234 233 235 // Caption/Subtitle/Teletext decoders 234 236 CCDecoder *ccd; 237 TeletextDecoder *ttd; 235 238 236 239 // Audio 237 240 short int *audioSamples; -
libs/libmythtv/osdsurface.cpp
86 86 memset(u, 127, size / 4); 87 87 memset(v, 127, size / 4); 88 88 memset(alpha, 0, size); 89 usedRegionsLock.lock(); 89 90 usedRegions = QRegion(); 91 usedRegionsLock.unlock(); 90 92 } 91 93 92 94 void OSDSurface::ClearUsed(void) 93 95 { 96 usedRegionsLock.lock(); 94 97 QMemArray<QRect> rects = usedRegions.rects(); 95 98 QMemArray<QRect>::Iterator it = rects.begin(); 96 99 QRect drawRect; … … 129 132 } 130 133 131 134 usedRegions = QRegion(); 135 usedRegionsLock.unlock(); 132 136 } 133 137 134 138 bool OSDSurface::IntersectsDrawn(QRect &newrect) 135 139 { 140 QMutexLocker lock(&usedRegionsLock); 136 141 QMemArray<QRect> rects = usedRegions.rects(); 137 142 QMemArray<QRect>::Iterator it = rects.begin(); 138 143 for (; it != rects.end(); ++it) … … 143 148 144 149 void OSDSurface::AddRect(QRect &newrect) 145 150 { 151 usedRegionsLock.lock(); 146 152 usedRegions = usedRegions.unite(newrect); 153 usedRegionsLock.unlock(); 147 154 } 148 155 149 156 /////////////////////////////////////////////////////////////////////////// … … 551 558 */ 552 559 void OSDSurface::BlendToYV12(unsigned char *yuvptr) const 553 560 { 561 usedRegionsLock.lock(); 554 562 const OSDSurface *surface = this; 555 563 blendtoyv12_8_fun blender = blendtoyv12_8_init(surface); 556 564 … … 649 657 } 650 658 } 651 659 } 660 usedRegionsLock.unlock(); 652 661 } 653 662 654 663 static void BlendToBlack(unsigned char *argbptr, uint width, uint outheight) … … 686 695 uint outheight, bool blend_to_black, 687 696 uint threshold) const 688 697 { 698 usedRegionsLock.lock(); 689 699 const OSDSurface *surface = this; 690 700 blendtoargb_8_fun blender = blendtoargb_8_init(surface); 691 701 const unsigned char *cm = surface->cm; … … 756 766 } 757 767 if (blend_to_black) 758 768 BlendToBlack(argbptr, stride>>2, outheight); 769 770 usedRegionsLock.unlock(); 759 771 } 760 772 761 773 /** \fn OSDSurface::DitherToI44(unsigned char*,bool,uint,uint) const … … 772 784 void OSDSurface::DitherToI44(unsigned char *outbuf, bool ifirst, 773 785 uint stride, uint outheight) const 774 786 { 787 usedRegionsLock.lock(); 775 788 const OSDSurface *surface = this; 776 789 int ashift = ifirst ? 0 : 4; 777 790 int amask = ifirst ? 0x0f : 0xf0; … … 855 868 } 856 869 857 870 delete_dithertoia44_8_context(dcontext); 871 usedRegionsLock.unlock(); 858 872 } 859 873 860 874 /** \fn OSDSurface::DitherToIA44(unsigned char*,uint,uint) const -
libs/libmythtv/vbilut.cpp
325 325 0x00000, 0x00800, 0x01000, 0x02000, 0x04000, 0x08000, 0x10000, 0x20000, 326 326 0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 327 327 }; 328 329 int hamm8(const uint8_t *p, int *err) 330 { 331 int a =hammtab[p[0]]; 332 *err += a; 333 return a & 15; 334 } 335 336 int hamm84(const uint8_t *p, int *err) 337 { 338 int a = hamm84tab[p[0]]; 339 340 if (a == 255) 341 *err = 1; 342 343 return a; 344 } 345 346 int hamm16(const uint8_t *p, int *err) 347 { 348 int a = hammtab[p[0]]; 349 int b = hammtab[p[1]]; 350 *err += a; 351 *err += b; 352 return (a & 15) | (b & 15) * 16; 353 } -
libs/libmythtv/ttfont.cpp
157 157 delete rmap; 158 158 } 159 159 160 Raster_Map *TTFFont::calc_size(int *width, int *height, const QString &text) 160 Raster_Map *TTFFont::calc_size(int *width, int *height, 161 const QString &text, bool double_size) 161 162 { 162 163 unsigned int i, pw, ph; 163 164 Raster_Map *rtmp; … … 165 166 pw = 0; 166 167 ph = ((max_ascent) - max_descent) / 64; 167 168 169 if (double_size) 170 ph *= 2; 171 168 172 for (i = 0; i < text.length(); i++) 169 173 { 170 174 unsigned short j = text[i].unicode(); … … 200 204 } 201 205 202 206 void TTFFont::render_text(Raster_Map *rmap, Raster_Map *rchr, 203 const QString &text, int *xorblah, int *yor) 207 const QString &text, int *xorblah, int *yor, 208 bool double_size) 204 209 { 205 210 FT_F26Dot6 x, y, xmin, ymin, xmax, ymax; 206 211 FT_BBox bbox; 207 212 unsigned int i, ioff, iread; 208 char *off, * read, *_off, *_read;213 char *off, *off2, *read, *_off, *_off2, *_read; 209 214 int x_offset, y_offset; 210 215 unsigned short j, previous; 211 216 Raster_Map *rtmp; … … 326 331 327 332 _read = (char *)rtmp->bitmap + iread; 328 333 _off = (char *)rmap->bitmap + ioff; 329 334 _off2 = _off - rmap->cols; 335 330 336 for (y = ymin; y <= ymax; y++) 331 337 { 332 338 read = _read; 333 339 off = _off; 340 off2 = _off2; 334 341 335 342 for (x = xmin; x <= xmax; x++) 336 343 { 337 *off = *read; 344 *off = *read; 345 if (double_size) 346 { 347 *off2 = *read; 348 off2++; 349 } 338 350 off++; 339 351 read++; 340 352 } 341 353 _read -= rtmp->cols; 342 354 _off -= rmap->cols; 355 if (double_size) 356 { 357 _off -= rmap->cols; 358 _off2 -= rmap->cols; 359 _off2 -= rmap->cols; 360 } 343 361 } 344 362 if (glyphs[j]->advance.x == 0) 345 363 x_offset += 4; … … 413 431 414 432 void TTFFont::DrawString(OSDSurface *surface, int x, int y, 415 433 const QString &text, int maxx, int maxy, 416 int alphamod )434 int alphamod, bool double_size) 417 435 { 418 436 int width, height, w, h, inx, iny, clipx, clipy; 419 437 Raster_Map *rmap, *rtmp; … … 425 443 inx = 0; 426 444 iny = 0; 427 445 428 rtmp = calc_size(&w, &h, text );446 rtmp = calc_size(&w, &h, text, double_size); 429 447 if (w <= 0 || h <= 0) 430 448 { 431 449 destroy_font_raster(rtmp); … … 433 451 } 434 452 rmap = create_font_raster(w, h); 435 453 436 render_text(rmap, rtmp, text, &inx, &iny );454 render_text(rmap, rtmp, text, &inx, &iny, double_size); 437 455 438 456 is_pixmap = 1; 439 457 … … 442 460 width = maxx; 443 461 height = maxy; 444 462 463 if (double_size) 464 height *= 2; 465 445 466 clipx = 0; 446 467 clipy = 0; 447 468 -
libs/libmythtv/osd.cpp
26 26 #include "libmyth/oldsettings.h" 27 27 #include "udpnotify.h" 28 28 29 #include "osdtypeteletext.h" 29 30 #include "osdlistbtntype.h" 30 31 31 32 static float sq(float a) { return a*a; } … … 115 116 116 117 void OSD::SetDefaults(void) 117 118 { 119 OSDSet *container = NULL; 120 // TODO begin -- deleted in teletext patch 118 121 TTFFont *ccfont = GetFont("cc_font"); 119 122 if (!ccfont) 120 123 { … … 130 133 if (!ccfont) 131 134 return; 132 135 133 OSDSet *container = GetSet("cc_page"); 134 if (!container) 136 if (!GetSet("cc_page")) 135 137 { 136 138 QString name = "cc_page"; 137 139 container = new OSDSet(name, true, … … 157 159 sub_dispw, sub_disph); 158 160 container->AddType(ccpage); 159 161 } 162 // TODO end -- deleted in teletext patch 160 163 161 container = GetSet("menu"); 162 if (!container) 164 if (!GetSet("teletext")) 163 165 { 166 QString name = "teletext"; 167 container = new OSDSet(name, true, 168 osdBounds.width(), osdBounds.height(), 169 wmult, hmult, frameint); 170 container->SetAllowFade(false); 171 container->SetWantsUpdates(true); 172 AddSet(container, name); 173 QRect area = QRect(20, 20, 620, 440); 174 normalizeRect(area); 175 // XXX TODO use special teletextfont 176 QString fontname = "teletextfont"; 177 TTFFont *font = GetFont(fontname); 178 if (!font) 179 { 180 int fontsize = 440 / 26; 181 font = LoadFont(gContext->GetSetting("OSDCCFont"), fontsize); 182 183 if (font) 184 fontMap[fontname] = font; 185 } 186 187 OSDTypeTeletext *ttpage = new OSDTypeTeletext(name, area, font); 188 189 container->AddType(ttpage); 190 } 191 192 if (!GetSet("menu")) 193 { 164 194 QString name = "menu"; 165 195 container = new OSDSet(name, true, 166 196 osdBounds.width(), osdBounds.height(), -
libs/libmythtv/teletextdecoder.h
1 #ifndef VBIDECODER_H_ 2 #define VBIDECODER_H_ 3 4 #include <stdint.h> 5 6 #include <qwaitcondition.h> 7 #include <qobject.h> 8 #include <qmutex.h> 9 10 class OSDTypeTeletext; 11 class OSDType; 12 class CCDecoder; 13 14 class TeletextReader 15 { 16 public: 17 virtual ~TeletextReader() { } 18 virtual void AddTextData(unsigned char *buf, int len, 19 long long timecode, char type) = 0; 20 }; 21 22 class TeletextDecoder : public QObject 23 { 24 Q_OBJECT 25 public: 26 TeletextDecoder(); 27 ~TeletextDecoder(); 28 29 // Sets 30 void SetViewer(OSDTypeTeletext*); 31 32 // Gets 33 int GetDecoderType(void) const; 34 35 void Decode(const uint8_t *buf, int vbimode); 36 37 private: 38 39 OSDTypeTeletext *m_teletextviewer; 40 int m_decodertype; 41 }; 42 43 #endif -
libs/libmythtv/osdsurface.h
2 2 #define OSDSURFACE_H_ 3 3 4 4 #include <qregion.h> 5 #include <qmutex.h> 5 6 #include "blend.h" 6 7 7 8 #define MAX_NEG_CROP 1024 … … 61 62 int size; 62 63 63 64 QRegion usedRegions; 64 65 mutable QMutex usedRegionsLock; 65 66 #ifdef MMX 66 67 short int rec_lut[256]; 67 68 #else -
libs/libmythtv/ttfont.h
42 42 bool isValid(void) { return valid; } 43 43 44 44 void DrawString(OSDSurface *surface, int x, int y, const QString &text, 45 int maxx, int maxy, int alphamod = 255); 45 int maxx, int maxy, int alphamod = 255, 46 bool double_size = false); 46 47 void CalcWidth(const QString &text, int *width_return); 47 48 48 49 int SpaceWidth() { return spacewidth; } … … 58 59 Raster_Map *duplicate_raster(FT_BitmapGlyph bmap); 59 60 void clear_raster(Raster_Map *rmap); 60 61 void destroy_font_raster(Raster_Map *rmap); 61 Raster_Map *calc_size(int *width, int *height, const QString &text); 62 Raster_Map *calc_size(int *width, int *height, const QString &text, 63 bool double_size = false); 62 64 void render_text(Raster_Map *rmap, Raster_Map *rchr, const QString &text, 63 int *xorblah, int *yor );65 int *xorblah, int *yor, bool double_size = false); 64 66 void merge_text(OSDSurface *surface, Raster_Map *rmap, int offset_x, 65 67 int offset_y, int xstart, int ystart, int width, 66 68 int height, int alphamod, kTTF_Color k = kTTF_Normal); -
libs/libavformat/mpegts.c
55 55 int comp_page; 56 56 int anc_page; 57 57 int sub_id; 58 int txt_type; 58 59 } dvb_caption_info_t; 59 60 60 61 static int mpegts_parse_desc(dvb_caption_info_t *dvbci, … … 618 619 if (dvbci.sub_id && (stream_type == STREAM_TYPE_PRIVATE_DATA)) 619 620 stream_type = STREAM_TYPE_SUBTITLE_DVB; 620 621 622 if (dvbci.txt_type && (stream_type == STREAM_TYPE_PRIVATE_DATA)) 623 stream_type = STREAM_TYPE_VBI_DVB; 621 624 #ifdef DEBUG_SI 622 625 av_log(NULL, AV_LOG_DEBUG, "stream_type=%d pid=0x%x\n", stream_type, pid); 623 626 #endif … … 784 787 case STREAM_TYPE_AUDIO_AAC: 785 788 case STREAM_TYPE_AUDIO_AC3: 786 789 case STREAM_TYPE_AUDIO_DTS: 787 // case STREAM_TYPE_PRIVATE_DATA:790 case STREAM_TYPE_VBI_DVB: 788 791 case STREAM_TYPE_SUBTITLE_DVB: 789 792 val = 1; 790 793 break; … … 839 842 dvbci->language[2] = get8(p, desc_end); 840 843 dvbci->language[3] = 0; 841 844 break; 845 case DVB_VBI_DESCID: 846 dvbci->language[0] = get8(p, desc_end); 847 dvbci->language[1] = get8(p, desc_end); 848 dvbci->language[2] = get8(p, desc_end); 849 dvbci->txt_type = (get8(p, desc_end)) >> 3; 850 break; 842 851 default: 843 852 break; 844 853 } … … 1273 1282 codec_type = CODEC_TYPE_AUDIO; 1274 1283 codec_id = CODEC_ID_DTS; 1275 1284 break; 1276 // case STREAM_TYPE_PRIVATE_DATA:1277 //codec_type = CODEC_TYPE_DATA;1278 //codec_id = CODEC_ID_DVB_VBI;1279 //break;1285 case STREAM_TYPE_VBI_DVB: 1286 codec_type = CODEC_TYPE_DATA; 1287 codec_id = CODEC_ID_DVB_VBI; 1288 break; 1280 1289 case STREAM_TYPE_SUBTITLE_DVB: 1281 1290 codec_type = CODEC_TYPE_SUBTITLE; 1282 1291 codec_id = CODEC_ID_DVB_SUBTITLE; -
libs/libavformat/mpegts.h
37 37 #define SDT_TID 0x42 38 38 39 39 /* descriptor ids */ 40 #define DVB_VBI_DESCID 0x56 40 41 #define DVB_SUBT_DESCID 0x59 41 42 42 43 #define STREAM_TYPE_VIDEO_MPEG1 0x01 … … 53 54 #define STREAM_TYPE_AUDIO_DTS 0x8a 54 55 55 56 #define STREAM_TYPE_SUBTITLE_DVB 0x100 57 #define STREAM_TYPE_VBI_DVB 0x101 56 58 57 59 unsigned int mpegts_crc32(const uint8_t *data, int len); 58 60 extern AVOutputFormat mpegts_mux;