Ticket #1043: mythdvd_v6.patch
File mythdvd_v6.patch, 35.4 KB (added by , 20 years ago) |
---|
-
libs/libmythtv/NuppelVideoPlayer.h
318 318 void ActivateDVDButton(void); 319 319 void GoToDVDMenu(QString str); 320 320 void GoToDVDProgram(bool direction); 321 void HideDVDButton(bool hide) { hidedvdbutton = hide; } 322 void SetSubtitleMode(bool setting) { subtitlesOn = setting; } 321 323 322 324 protected: 323 325 void DisplayPauseFrame(void); … … 664 666 665 667 // DVD 666 668 bool indvdstillframe; 669 bool hidedvdbutton; 667 670 668 671 // Debugging variables 669 672 Jitterometer *output_jmeter; -
libs/libmythtv/NuppelVideoPlayer.cpp
175 175 // LiveTVChain stuff 176 176 livetvchain(NULL), m_tv(NULL), 177 177 // DVD stuff 178 indvdstillframe(false), 178 indvdstillframe(false), hidedvdbutton(true), 179 179 // Debugging variables 180 180 output_jmeter(NULL) 181 181 { … … 509 509 510 510 ClearAfterSeek(); 511 511 512 if (ringBuffer-> InDVDMenuOrStillFrame())512 if (ringBuffer->isDVD()) 513 513 ringBuffer->Seek(ringBuffer->DVD()->GetCellStartPos(), SEEK_SET); 514 514 } 515 515 … … 967 967 void NuppelVideoPlayer::AddTextData(unsigned char *buffer, int len, 968 968 long long timecode, char type) 969 969 { 970 if (!ringBuffer->isDVD()) 971 WrapTimecode(timecode, TC_CC); 970 WrapTimecode(timecode, TC_CC); 972 971 973 if (subtitlesOn )972 if (subtitlesOn && !ringBuffer->isDVD()) 974 973 { 975 974 if (!tbuffer_numfree()) 976 975 { … … 1954 1953 video_actually_paused = false; 1955 1954 resetvideo = false; 1956 1955 1957 if (!ringBuffer-> isDVD())1956 if (!ringBuffer->InDVDMenuOrStillFrame()) 1958 1957 { 1959 1958 if (!PrebufferEnoughFrames()) 1960 1959 return; … … 2104 2103 if (ringBuffer->DVD()->IsWaiting()) 2105 2104 { 2106 2105 ringBuffer->DVD()->WaitSkip(); 2107 usleep(100000);2108 2106 continue; 2109 2107 } 2108 2110 2109 if (ringBuffer->InDVDMenuOrStillFrame()) 2111 2110 { 2112 2111 if (nbframes == 0) 2113 2112 { 2114 // wait to confirm there is no other frames been decoded. 2115 usleep(100000); 2116 nbframes = videoOutput->ValidVideoFrames(); 2117 if (nbframes == 0) 2118 { 2119 ringBuffer->Seek(ringBuffer->DVD()->GetCellStartPos(),SEEK_SET); 2120 continue; 2121 } 2113 if (pausevideo) 2114 UnpauseVideo(); 2115 continue; 2122 2116 } 2123 indvdstillframe = true;2124 2117 if (!pausevideo && nbframes == 1) 2118 { 2119 indvdstillframe = true; 2125 2120 PauseVideo(false); 2121 } 2126 2122 } 2127 2123 } 2128 2124 2129 // restart playing after skipping still frame2130 2125 if (indvdstillframe && nbframes > 1) 2131 2126 { 2132 2127 UnpauseVideo(); 2133 2128 indvdstillframe = false; 2129 continue; 2134 2130 } 2135 2131 } 2136 2132 … … 2925 2921 2926 2922 int samples = len / samplesize; 2927 2923 2928 if (ringBuffer-> isDVD())2924 if (ringBuffer->InDVDMenuOrStillFrame()) 2929 2925 { 2930 2926 audioOutput->Pause(false); 2931 2927 audioOutput->Drain(); 2932 } 2928 } 2933 2929 2934 2930 // If there is no warping, just send it to the audioOutput. 2935 2931 if (!usevideotimebase) … … 5317 5313 if (!ringBuffer->InDVDMenuOrStillFrame()) 5318 5314 return; 5319 5315 5320 long long spupts = ringBuffer->DVD()->MenuSpuPts();5321 long long ptslow = spupts - 1000;5322 long long ptshigh = spupts + 1000;5323 5316 VideoFrame *buffer = videoOutput->GetLastShownFrame(); 5324 5325 if (!osd->IsSetDisplaying("subtitles") && 5326 (buffer->timecode > 0) && 5327 ((buffer->timecode < ptslow) || 5328 (buffer->timecode > ptshigh))) 5317 int numbuttons = ringBuffer->DVD()->NumMenuButtons(); 5318 bool osdshown = osd->IsSetDisplaying("subtitles"); 5319 long long menupktpts = ringBuffer->DVD()->GetMenuPktPts(); 5320 5321 if ((numbuttons == 0) || 5322 (osdshown) || 5323 ((!osdshown) && (hidedvdbutton) && 5324 (buffer->timecode > 0) && (menupktpts != buffer->timecode))) 5329 5325 { 5330 return; 5326 return; 5331 5327 } 5332 5328 5329 hidedvdbutton = false; 5333 5330 AVSubtitleRect *highlightButton; 5334 5331 OSDSet *subtitleOSD = NULL; 5335 5332 highlightButton = ringBuffer->DVD()->GetMenuButton(); … … 5379 5376 if (!ringBuffer->isDVD()) 5380 5377 return; 5381 5378 5382 if (videoOutput->ValidVideoFrames() > 20)5383 DiscardVideoFrames(true);5384 5379 ringBuffer->DVD()->ActivateButton(); 5385 ringBuffer->DVD()->HideMenuButton(true);5386 5380 } 5387 5381 5388 5382 void NuppelVideoPlayer::GoToDVDMenu(QString str) … … 5390 5384 if (!ringBuffer->isDVD()) 5391 5385 return; 5392 5386 5393 if (videoOutput->ValidVideoFrames() > 20) 5394 DiscardVideoFrames(true); 5387 subtitlesOn = false; 5395 5388 ringBuffer->DVD()->GoToMenu(str); 5396 5389 } 5397 5390 … … 5402 5395 { 5403 5396 if (!ringBuffer->isDVD()) 5404 5397 return; 5405 5406 if (videoOutput->ValidVideoFrames() > 20) 5407 DiscardVideoFrames(true); 5398 5408 5399 if (direction == 0) 5409 5400 ringBuffer->DVD()->GoToPreviousProgram(); 5410 5401 else -
libs/libmythtv/DVDRingBuffer.h
45 45 bool InStillFrame(void) { return cellHasStillFrame; } 46 46 bool IsWaiting(void) { return dvdWaiting; } 47 47 int NumPartsInTitle(void) { return titleParts; } 48 void GetMenuSPUPkt(uint8_t *buf, int buf_size,long long pts);48 void GetMenuSPUPkt(uint8_t *buf, int len, int stream_id); 49 49 AVSubtitleRect *GetMenuButton(void); 50 50 bool IgnoringStillorWait(void) { return skipstillorwait; } 51 long long GetCellStartPos(void) { return cellstartPos; } 52 void HideMenuButton(bool hide); 51 long long GetCellStartPos(void); 53 52 uint ButtonPosX(void) { return hl_startx; } 54 53 uint ButtonPosY(void) { return hl_starty; } 55 54 uint GetAudioLanguage(int id); 56 55 uint GetSubtitleLanguage(int id); 57 long long MenuSpuPts(void) { return menuspupts; } 58 56 void SetMenuPktPts(long long pts) { menupktpts = pts; } 57 long long GetMenuPktPts(void) { return menupktpts; } 58 bool DecodeSubtitles(AVSubtitle * sub, int * gotSubtitles, 59 const uint8_t * buf, int buf_size); 60 59 61 // commands 60 62 bool OpenFile(const QString &filename); 61 63 void close(void); … … 76 78 int NumMenuButtons(void); 77 79 void IgnoreStillOrWait(bool skip) { skipstillorwait = skip; } 78 80 uint GetCurrentTime(void); 79 81 void SetAudioTrack(void); 82 void SetSubtitleTrack(void); 83 uint8_t GetNumAudioChannels(int id); 84 void AutoSelectAudio(bool setting) { autoselectaudio = setting; } 85 void AutoSelectSubtitle(bool setting) { autoselectsubtitle = setting; } 86 80 87 void SetParent(NuppelVideoPlayer *p) { parent = p; } 81 88 82 89 protected: … … 106 113 uint16_t hl_width; 107 114 uint16_t hl_starty; 108 115 uint16_t hl_height; 109 bool spuchanged;110 116 uint8_t *menuSpuPkt; 111 117 int menuBuflength; 112 118 uint8_t *buttonBitmap; 113 AVSubtitleRect *dvdMenuButton; 114 int buttonCoords; 119 AVSubtitle dvdMenuButton; 115 120 bool skipstillorwait; 116 bool spuStreamLetterbox;117 121 long long cellstartPos; 118 122 bool buttonSelected; 119 123 bool buttonExists; 120 long long menuspupts; 121 124 int cellid; 125 int lastcellid; 126 int vobid; 127 int lastvobid; 128 bool cellRepeated; 129 int buttonstreamid; 130 bool gotoCellStart; 131 long long menupktpts; 132 bool autoselectaudio; 133 bool autoselectsubtitle; 134 122 135 NuppelVideoPlayer *parent; 123 136 124 137 bool DrawMenuButton(uint8_t *spu_pkt, int buf_size); … … 126 139 void ClearMenuSPUParameters(void); 127 140 bool MenuButtonChanged(void); 128 141 uint ConvertLangCode(uint16_t code); // converts 2char key to 3char key 142 void SelectDefaultButton(void); 143 void ClearSubtitlesOSD(void); 129 144 130 145 /* copied from dvdsub.c from ffmpeg */ 131 146 int get_nibble(const uint8_t *buf, int nibble_offset); -
libs/libmythtv/avformatdecoder.cpp
278 278 // language preference 279 279 languagePreference(iso639_get_language_key_list()), 280 280 // DVD 281 lastdvdtitle(0) 281 lastdvdtitle(0), dvdmenupktseen(false) 282 282 { 283 283 bzero(¶ms, sizeof(AVFormatParameters)); 284 284 bzero(prvpkt, 3 * sizeof(char)); … … 431 431 void AvFormatDecoder::SeekReset(long long newKey, uint skipFrames, 432 432 bool doflush, bool discardFrames) 433 433 { 434 if (ringBuffer->isDVD()) 435 { 436 int totaltime = ringBuffer->DVD()->GetTotalTimeOfTitle(); 437 if (totaltime < 30 || ringBuffer->InDVDMenuOrStillFrame()) 438 return; 439 } 440 434 if (ringBuffer->InDVDMenuOrStillFrame()) 435 return; 436 441 437 VERBOSE(VB_PLAYBACK, LOC + 442 438 QString("SeekReset(%1, %2, %3 flush, %4 discard)") 443 439 .arg(newKey).arg(skipFrames) … … 1194 1191 lang_indx = lang_sub_cnt[lang]; 1195 1192 lang_sub_cnt[lang]++; 1196 1193 } 1197 subtitleStreams.push_back(StreamInfo(i, lang, lang_indx ));1194 subtitleStreams.push_back(StreamInfo(i, lang, lang_indx,ic->streams[i]->id)); 1198 1195 1199 1196 VERBOSE(VB_PLAYBACK, LOC + QString( 1200 1197 "Subtitle track #%1 is A/V stream #%2 " … … 1213 1210 lang_indx = lang_aud_cnt[lang]; 1214 1211 lang_aud_cnt[lang]++; 1215 1212 } 1216 audioStreams.push_back(StreamInfo(i, lang, lang_indx)); 1217 1213 audioStreams.push_back(StreamInfo(i, lang, lang_indx,ic->streams[i]->id)); 1218 1214 VERBOSE(VB_AUDIO, LOC + QString( 1219 1215 "Audio Track #%1 is A/V stream #%2 " 1220 1216 "and has %3 channels in the %4 language(%5).") … … 1235 1231 currentAudioTrack = -1; 1236 1232 currentSubtitleTrack = -1; 1237 1233 1234 if (ringBuffer->isDVD()) 1235 { 1236 if (audioStreams.size() > 1) 1237 { 1238 qBubbleSort(audioStreams); 1239 ringBuffer->DVD()->SetAudioTrack(); 1240 } 1241 if (subtitleStreams.size() > 1) 1242 { 1243 qBubbleSort(subtitleStreams); 1244 ringBuffer->DVD()->SetSubtitleTrack(); 1245 } 1246 } 1247 1238 1248 // We have to do this here to avoid the NVP getting stuck 1239 1249 // waiting on audio. 1240 1250 if (GetNVP()->HasAudioIn() && audioStreams.empty()) … … 1903 1913 { 1904 1914 QString msg; 1905 1915 if (ringBuffer->isDVD()) 1916 { 1906 1917 msg = iso639_key_toName(ringBuffer->DVD()->GetAudioLanguage(i)); 1918 if (msg.compare("Unknown") == 0) 1919 continue; 1920 } 1907 1921 else 1908 1922 msg = iso639_key_toName(audioStreams[i].language); 1923 1909 1924 AVStream *s = ic->streams[audioStreams[i].av_stream_index]; 1910 1925 if (s) 1911 1926 { … … 1914 1929 else 1915 1930 msg += QString(" %1").arg(s->codec->codec->name).upper(); 1916 1931 1917 if (!s->codec->channels) 1918 msg += QString(" ?ch"); 1919 else if ((s->codec->channels > 4) && !(s->codec->channels & 1)) 1920 msg += QString(" %1.1ch").arg(s->codec->channels - 1); 1932 int channels = 0; 1933 if (ringBuffer->isDVD()) 1934 channels = ringBuffer->DVD()->GetNumAudioChannels(i); 1935 else if (s->codec->channels) 1936 channels = s->codec->channels; 1937 1938 if (channels == 0) 1939 msg+= QString(" ?ch"); 1940 else if((channels > 4) && !(channels & 1)) 1941 msg += QString(" %1.1ch").arg(channels - 1); 1921 1942 else 1922 msg += QString(" %1ch").arg( s->codec->channels);1923 } 1943 msg += QString(" %1ch").arg(channels); 1944 } 1924 1945 list += QString("%1: %2").arg(i+1).arg(msg); 1925 1946 } 1926 1947 … … 2150 2171 { 2151 2172 QString msg; 2152 2173 if (ringBuffer->isDVD()) 2174 { 2153 2175 msg = iso639_key_toName(ringBuffer->DVD()->GetSubtitleLanguage(i)); 2176 if (msg.compare("Unknown") == 0) 2177 continue; 2178 } 2154 2179 else 2155 2180 msg = iso639_key_toName(subtitleStreams[i].language); 2156 2181 list += QString("%1: %2").arg(i+1).arg(msg); … … 2301 2326 VERBOSE(VB_PLAYBACK, 2302 2327 QString(LOC + "DVD Title Changed. Update framesPlayed: %1 ") 2303 2328 .arg(framesPlayed)); 2329 ScanStreams(false); 2304 2330 } 2305 2331 lastdvdtitle = dvdtitle; 2306 2332 … … 2313 2339 if (gotvideo) 2314 2340 { 2315 2341 if (lowbuffers && onlyvideo == 0 && lastapts < lastvpts + 100 && 2316 lastapts > lastvpts - 10000 && !ringBuffer-> isDVD())2342 lastapts > lastvpts - 10000 && !ringBuffer->InDVDMenuOrStillFrame()) 2317 2343 { 2318 2344 //cout << "behind: " << lastapts << " " << lastvpts << endl; 2319 2345 storevideoframes = true; … … 2325 2351 } 2326 2352 } 2327 2353 2328 if (ringBuffer->isDVD() && ringBuffer->DVD()->InStillFrame() &&2329 storedPackets.count() > 0)2354 if (ringBuffer->isDVD() && 2355 ringBuffer->DVD()->InStillFrame()) 2330 2356 { 2331 2357 storevideoframes = false; 2332 2358 dvdvideopause = true; … … 2720 2746 gotvideo = 1; 2721 2747 framesPlayed++; 2722 2748 2749 if (dvdmenupktseen) 2750 { 2751 ringBuffer->DVD()->SetMenuPktPts(pts); 2752 dvdmenupktseen = false; 2753 } 2754 2723 2755 lastvpts = temppts; 2724 2756 break; 2725 2757 } … … 2728 2760 int gotSubtitles = 0; 2729 2761 AVSubtitle subtitle; 2730 2762 2731 if (ringBuffer->isDVD() && ringBuffer->DVD()->IsInMenu()) 2732 ringBuffer->DVD()->GetMenuSPUPkt(ptr,len,pts); 2763 if (ringBuffer->isDVD()) 2764 { 2765 if (ringBuffer->DVD()->IsInMenu()) 2766 { 2767 dvdmenupktseen = true; 2768 ringBuffer->DVD()->GetMenuSPUPkt(ptr,len,curstream->id); 2769 } 2770 else 2771 { 2772 if (pkt->stream_index == subIdx) 2773 ringBuffer->DVD()->DecodeSubtitles(&subtitle, &gotSubtitles, 2774 ptr,len); 2775 } 2776 } 2733 2777 else if (pkt->stream_index == subIdx) 2734 2778 { 2735 2779 QMutexLocker locker(&avcodeclock); -
libs/libmythtv/tv_play.cpp
2321 2321 if (prbuffer->isDVD()) 2322 2322 { 2323 2323 if (prbuffer->InDVDMenuOrStillFrame()) 2324 UpdateOSDSeekMessage(tr("Skip pingBack Not Allowed"),2324 UpdateOSDSeekMessage(tr("Skip Back Not Allowed"), 2325 2325 osd_general_timeout); 2326 2326 else if (prbuffer->DVD()->NumPartsInTitle() < 2) 2327 2327 { … … 6187 6187 { 6188 6188 if (activenvp) 6189 6189 { 6190 if (prbuffer->isDVD()) 6191 prbuffer->DVD()->AutoSelectAudio(false); 6192 6190 6193 activenvp->setCurrentAudioTrack(track - 1); 6191 6194 6192 6195 if (activenvp->getCurrentAudioTrack()) … … 6226 6229 { 6227 6230 if (activenvp) 6228 6231 { 6232 if (prbuffer->isDVD()) 6233 prbuffer->DVD()->AutoSelectSubtitle(false); 6234 6229 6235 activenvp->setCurrentSubtitleTrack(track - 1); 6230 6236 6231 6237 if (activenvp->getCurrentSubtitleTrack()) -
libs/libmythtv/DVDRingBuffer.cpp
29 29 lastNav(NULL), part(0), 30 30 title(0), gotStop(false), 31 31 cellHasStillFrame(false), dvdWaiting(false), 32 titleLength(0), spuchanged(false), 33 menuBuflength(0), buttonCoords(0), 34 skipstillorwait(true), spuStreamLetterbox(false), 32 titleLength(0), menuBuflength(0), 33 skipstillorwait(true), 35 34 cellstartPos(0), buttonSelected(false), 36 buttonExists(false), menuspupts(0), 37 parent(0) 35 buttonExists(false), cellid(0), 36 lastcellid(0), vobid(0), 37 lastvobid(0), cellRepeated(false), 38 buttonstreamid(0), gotoCellStart(false), 39 menupktpts(0), autoselectaudio(true), 40 autoselectsubtitle(true), parent(0) 38 41 { 39 dvdMenuButton = (AVSubtitleRect*)av_mallocz(sizeof(AVSubtitleRect));40 42 } 41 43 42 44 DVDRingBufferPriv::~DVDRingBufferPriv() 43 45 { 44 46 close(); 45 av_free(dvdMenuButton);47 ClearMenuSPUParameters(); 46 48 } 47 49 48 50 void DVDRingBufferPriv::close(void) … … 119 121 { 120 122 dvdnav_get_number_of_parts(dvdnav, curTitle, &titleParts); 121 123 VERBOSE(VB_IMPORTANT, 122 QString("T here are title %1 has %2 parts.")124 QString("Title %1 has %2 parts.") 123 125 .arg(curTitle).arg(titleParts)); 124 126 } 125 127 } … … 222 224 dvdnav_get_position(dvdnav, &pos, &length); 223 225 titleLength = length *DVD_BLOCK_SIZE; 224 226 cellstartPos = GetReadPosition(); 225 buttonSelected = false; 226 227 if (parent && parent->GetOSD()) 227 buttonSelected = false; 228 if (gotoCellStart) 228 229 { 229 parent->GetOSD()->HideSet("subtitles");230 parent->GetOSD()->ClearAll("subtitles");230 lastvobid = lastcellid = 0; 231 gotoCellStart = false; 231 232 } 233 else 234 { 235 lastvobid = vobid; 236 lastcellid = cellid; 237 } 238 239 vobid = 0; 240 cellid = 0; 241 cellRepeated = false; 242 menupktpts = 0; 243 244 if (parent && IsInMenu()) 245 { 246 parent->HideDVDButton(true); 247 parent->SetSubtitleMode(false); 248 autoselectaudio = true; 249 autoselectsubtitle = true; 250 } 232 251 233 252 if (blockBuf != dvdBlockWriteBuf) 234 253 { … … 253 272 .arg(spu->physical_wide).arg(spu->physical_letterbox) 254 273 .arg(spu->physical_pan_scan).arg(spu->logical)); 255 274 256 if (spu->physical_letterbox)257 spuStreamLetterbox = true;258 else259 spuStreamLetterbox = false;260 spuchanged = true;261 275 ClearMenuSPUParameters(); 276 ClearSubtitlesOSD(); 262 277 263 278 if (blockBuf != dvdBlockWriteBuf) 264 279 { … … 284 299 case DVDNAV_NAV_PACKET: 285 300 { 286 301 lastNav = (dvdnav_t *)blockBuf; 287 if (IsInMenu() && NumMenuButtons() > 0 && 288 !buttonSelected) 302 if (vobid == 0 && cellid == 0) 289 303 { 290 pci_t *pci = dvdnav_get_current_nav_pci(dvdnav); 291 292 uint8_t button = pci->hli.hl_gi.fosl_btnn; 293 if (button > 0) 294 dvdnav_button_select(dvdnav,pci,button); 295 else 296 dvdnav_button_select(dvdnav,pci,1); 297 298 buttonSelected = true; 299 spuchanged = false; 304 dsi_t *dsi = dvdnav_get_current_nav_dsi(dvdnav); 305 vobid = dsi->dsi_gi.vobu_vob_idn; 306 cellid = dsi->dsi_gi.vobu_c_idn; 307 if ((lastvobid == vobid) && (lastcellid == cellid) 308 && IsInMenu()) 309 { 310 cellRepeated = true; 311 } 300 312 } 301 313 if (blockBuf != dvdBlockWriteBuf) 302 314 { … … 348 360 349 361 if (DVDButtonUpdate(false)) 350 362 buttonExists = DrawMenuButton(menuSpuPkt,menuBuflength); 351 363 ClearSubtitlesOSD(); 352 364 if (blockBuf != dvdBlockWriteBuf) 353 365 { 354 366 dvdnav_free_cache_block(dvdnav, blockBuf); … … 521 533 } 522 534 } 523 535 524 void DVDRingBufferPriv::GetMenuSPUPkt(uint8_t *buf, int buf_size, long long pts)525 { 536 void DVDRingBufferPriv::GetMenuSPUPkt(uint8_t *buf, int buf_size, int stream_id) 537 { 526 538 if (buf_size < 4) 527 539 return; 528 540 529 menuspupts = pts; 530 if (buf_size == menuBuflength) 541 542 if ((buttonstreamid < stream_id) && 543 (buttonstreamid > 0)) 531 544 return; 532 else if (spuStreamLetterbox) 533 { 534 if ((buf_size < menuBuflength) && menuBuflength > 0) 535 return; 536 } 537 else 538 { 539 if ((buf_size > menuBuflength) && (menuBuflength > 0)) 540 return; 541 } 545 546 buttonstreamid = stream_id; 542 547 ClearMenuSPUParameters(); 543 548 uint8_t *spu_pkt; 544 549 spu_pkt = (uint8_t*)av_malloc(buf_size); 545 550 memcpy(spu_pkt, buf, buf_size); 546 551 menuSpuPkt = spu_pkt; 547 552 menuBuflength = buf_size; 548 buttonCoords = 0; 553 if (!buttonSelected) 554 { 555 SelectDefaultButton(); 556 buttonSelected = true; 557 } 549 558 if (DVDButtonUpdate(false)) 550 559 buttonExists = DrawMenuButton(menuSpuPkt,menuBuflength); 560 551 561 } 552 562 553 563 AVSubtitleRect *DVDRingBufferPriv::GetMenuButton(void) 554 564 { 555 if ( MenuButtonChanged() && buttonExists)556 return dvdMenuButton;565 if ((menuBuflength > 4) && buttonExists) 566 return &(dvdMenuButton.rects[0]); 557 567 558 568 return NULL; 559 569 } 560 570 561 562 571 bool DVDRingBufferPriv::DrawMenuButton(uint8_t *spu_pkt, int buf_size) 563 572 { 573 int gotbutton = 0; 574 if (DecodeSubtitles(&dvdMenuButton,&gotbutton,spu_pkt,buf_size)) 575 { 576 int x1, y1; 577 x1 = dvdMenuButton.rects[0].x; 578 y1 = dvdMenuButton.rects[0].y; 579 dvdMenuButton.rects[0].w = hl_width; 580 dvdMenuButton.rects[0].h = hl_height; 581 if (hl_startx > x1) 582 dvdMenuButton.rects[0].x = hl_startx - x1; 583 else 584 dvdMenuButton.rects[0].x = 0; 585 if (hl_starty > y1) 586 dvdMenuButton.rects[0].y = hl_starty - y1; 587 else 588 dvdMenuButton.rects[0].y = 0; 589 } 590 return gotbutton; 591 } 592 593 bool DVDRingBufferPriv::DecodeSubtitles(AVSubtitle *sub, int *gotSubtitles, 594 const uint8_t *spu_pkt, int buf_size) 595 { 564 596 #define GETBE16(p) (((p)[0] << 8) | (p)[1]) 565 597 566 int cmd_pos, pos, cmd,next_cmd_pos,offset1,offset2;567 int x1, x2,y1,y2;568 uint8_t alpha[4], palette[4];569 570 x1 = x2 = y1 = y2 = 0;571 598 int cmd_pos, pos, cmd, next_cmd_pos, offset1, offset2; 599 int x1, x2, y1, y2; 600 uint8_t alpha[4], palette[4]; 601 uint i; 602 int date; 603 572 604 if (!spu_pkt) 573 605 return false; 574 606 575 for (int i = 0; i < 4 ; i++)576 {577 alpha[i] = button_alpha[i];578 palette[i] = button_color[i];579 }580 581 607 if (buf_size < 4) 582 608 return false; 583 609 610 sub->rects = NULL; 611 sub->num_rects = 0; 612 sub->start_display_time = 0; 613 sub->end_display_time = 0; 614 584 615 cmd_pos = GETBE16(spu_pkt + 2); 585 616 while ((cmd_pos + 4) < buf_size) 586 617 { 587 618 offset1 = -1; 588 619 offset2 = -1; 620 date = GETBE16(spu_pkt + cmd_pos); 589 621 next_cmd_pos = GETBE16(spu_pkt + cmd_pos + 2); 590 622 pos = cmd_pos + 4; 623 x1 = x2 = y1 = y2 = 0; 591 624 while (pos < buf_size) 592 625 { 593 626 cmd = spu_pkt[pos++]; … … 596 629 case 0x00: 597 630 break; 598 631 case 0x01: 632 sub->start_display_time = (date << 10) / 90; 599 633 break; 600 634 case 0x02: 635 sub->end_display_time = (date << 10) / 90; 601 636 break; 602 637 case 0x03: 603 638 { 604 639 if ((buf_size - pos) < 2) 605 640 goto fail; 641 if (!IsInMenu()) 642 { 643 palette[3] = spu_pkt[pos] >> 4; 644 palette[2] = spu_pkt[pos] & 0x0f; 645 palette[1] = spu_pkt[pos + 1] >> 4; 646 palette[0] = spu_pkt[pos + 1] & 0x0f; 647 } 606 648 pos +=2; 607 649 } 608 650 break; … … 610 652 { 611 653 if ((buf_size - pos) < 2) 612 654 goto fail; 655 if (!IsInMenu()) 656 { 657 alpha[3] = spu_pkt[pos] >> 4; 658 alpha[2] = spu_pkt[pos] & 0x0f; 659 alpha[1] = spu_pkt[pos + 1] >> 4; 660 alpha[0] = spu_pkt[pos + 1] >> 0x0f; 661 } 613 662 pos +=2; 614 663 } 615 664 break; … … 651 700 h = 0; 652 701 if (w > 0 && h > 0) 653 702 { 703 if (IsInMenu()) 704 { 705 for (int i = 0; i < 4 ; i++) 706 { 707 alpha[i] = button_alpha[i]; 708 palette[i] = button_color[i]; 709 } 710 } 711 if (sub->rects != NULL) 712 { 713 for (i = 0; i < sub->num_rects; i++) 714 { 715 av_free(sub->rects[i].bitmap); 716 av_free(sub->rects[i].rgba_palette); 717 } 718 av_freep(&sub->rects); 719 sub->num_rects = 0; 720 } 654 721 bitmap = (uint8_t*) av_malloc(w * h); 655 dvdMenuButton->rgba_palette = (uint32_t*)av_malloc(4 *4); 722 sub->rects = (AVSubtitleRect *)av_mallocz(sizeof(AVSubtitleRect)); 723 sub->num_rects = 1; 724 sub->rects[0].rgba_palette = (uint32_t*)av_malloc(4 *4); 656 725 decode_rle(bitmap, w * 2, w, h / 2, 657 726 spu_pkt, offset1 * 2, buf_size); 658 727 decode_rle(bitmap + w, w * 2, w, h / 2, 659 728 spu_pkt, offset2 * 2, buf_size); 660 guess_palette(dvdMenuButton->rgba_palette, palette, alpha); 661 dvdMenuButton->bitmap = bitmap; 662 if (hl_startx > x1) 663 dvdMenuButton->x = hl_startx - x1; 664 else 665 dvdMenuButton->x = 0; 666 if (hl_starty > y1) 667 dvdMenuButton->y = hl_starty - y1; 668 else 669 dvdMenuButton->y = 0; 670 dvdMenuButton->w = hl_width; 671 dvdMenuButton->h = hl_height; 672 dvdMenuButton->nb_colors = 4; 673 dvdMenuButton->linesize = w; 674 return true; 729 guess_palette(sub->rects[0].rgba_palette, palette, alpha); 730 sub->rects[0].bitmap = bitmap; 731 sub->rects[0].x = x1; 732 sub->rects[0].y = y1; 733 sub->rects[0].w = w; 734 sub->rects[0].h = h; 735 sub->rects[0].nb_colors = 4; 736 sub->rects[0].linesize = w; 737 *gotSubtitles = 1; 675 738 } 676 739 } 677 740 if (next_cmd_pos == cmd_pos) 678 741 break; 679 742 cmd_pos = next_cmd_pos; 680 743 } 681 fail: 682 return false; 744 if (sub->num_rects > 0) 745 return true; 746 fail: 747 return false; 683 748 } 684 749 685 750 bool DVDRingBufferPriv::DVDButtonUpdate(bool b_mode) 686 751 { 752 if (!parent) 753 return false; 754 int videoheight = parent->GetVideoHeight(); 755 int videowidth = parent->GetVideoWidth(); 687 756 int32_t button; 688 757 pci_t *pci; 689 758 dvdnav_highlight_area_t hl; … … 702 771 hl_starty = hl.sy; 703 772 hl_height = hl.ey - hl.sy; 704 773 705 i nt total_start_pos = hl.sx + hl.sy;706 if ( total_start_pos == 0 || total_start_pos > (720 + 576))707 return false;774 if (((hl.sx + hl.sy) > 0) && 775 (hl.sx < videowidth && hl.sy < videoheight)) 776 return true; 708 777 709 return true;778 return false; 710 779 } 711 780 712 781 void DVDRingBufferPriv::ClearMenuSPUParameters(void) … … 717 786 VERBOSE(VB_PLAYBACK,LOC + "Clearing Menu SPU Packet" ); 718 787 if (buttonExists) 719 788 { 720 av_free(dvdMenuButton->rgba_palette); 721 av_free(dvdMenuButton->bitmap); 789 av_free(dvdMenuButton.rects[0].rgba_palette); 790 av_free(dvdMenuButton.rects[0].bitmap); 791 av_free(dvdMenuButton.rects); 722 792 buttonExists = false; 723 793 } 724 794 av_free(menuSpuPkt); 725 795 menuBuflength = 0; 726 dvdMenuButton->x = 0;727 dvdMenuButton->y = 0;728 796 hl_startx = hl_starty = 0; 729 797 hl_width = hl_height = 0; 730 buttonCoords = (720+480+100);731 798 } 732 799 733 bool DVDRingBufferPriv::MenuButtonChanged(void)734 {735 if (menuBuflength < 4 || buttonCoords > (720+576))736 return false;737 738 int x = hl_startx;739 int y = hl_starty;740 if (buttonCoords != (x+y))741 {742 buttonCoords = (x+y);743 return true;744 }745 return false;746 }747 748 800 int DVDRingBufferPriv::NumMenuButtons(void) 749 801 { 750 802 pci_t *pci = dvdnav_get_current_nav_pci(dvdnav); … … 755 807 return 0; 756 808 } 757 809 758 void DVDRingBufferPriv::HideMenuButton(bool hide)759 {760 if (hide)761 buttonCoords = (720+480+100);762 else763 buttonCoords = 0;764 }765 766 810 uint DVDRingBufferPriv::GetCurrentTime(void) 767 811 { 768 812 // Macro to convert Binary Coded Decimal to Decimal … … 778 822 return currentTime; 779 823 } 780 824 825 long long DVDRingBufferPriv::GetCellStartPos(void) 826 { 827 gotoCellStart = true; 828 return cellstartPos; 829 } 830 781 831 uint DVDRingBufferPriv::GetAudioLanguage(int id) 782 832 { 783 833 int8_t channel = dvdnav_get_audio_logical_stream(dvdnav,id); … … 810 860 return 0; 811 861 } 812 862 863 void DVDRingBufferPriv::SelectDefaultButton(void) 864 { 865 pci_t *pci = dvdnav_get_current_nav_pci(dvdnav); 866 int button = pci->hli.hl_gi.fosl_btnn; 867 if (button > 0 && !cellRepeated) 868 { 869 dvdnav_button_select(dvdnav,pci,button); 870 return; 871 } 872 dvdnav_get_current_highlight(dvdnav,&button); 873 if (button > 0 && button <= NumMenuButtons()) 874 dvdnav_button_select(dvdnav,pci,button); 875 else 876 dvdnav_button_select(dvdnav,pci,1); 877 } 878 879 void DVDRingBufferPriv::SetAudioTrack(void) 880 { 881 if (!autoselectaudio) 882 return; 883 884 int track = dvdnav_get_active_audio_stream(dvdnav); 885 if (parent) 886 parent->setCurrentAudioTrack(track); 887 } 888 889 void DVDRingBufferPriv::SetSubtitleTrack(void) 890 { 891 if (!autoselectsubtitle) 892 return; 893 894 int track = dvdnav_get_active_spu_stream(dvdnav); 895 if (parent && track >=0 && !IsInMenu()) 896 { 897 parent->setCurrentSubtitleTrack(track); 898 parent->SetSubtitleMode(true); 899 } 900 } 901 902 uint8_t DVDRingBufferPriv::GetNumAudioChannels(int id) 903 { 904 unsigned char channels = dvdnav_audio_get_channels(dvdnav,id); 905 if (channels == 0xff) 906 return 0; 907 return (uint8_t)channels + 1; 908 } 909 910 void DVDRingBufferPriv::ClearSubtitlesOSD(void) 911 { 912 if (parent && parent->GetOSD()) 913 { 914 parent->GetOSD()->HideSet("subtitles"); 915 parent->GetOSD()->ClearAll("subtitles"); 916 } 917 } 918 813 919 void DVDRingBufferPriv::guess_palette(uint32_t *rgba_palette,uint8_t *palette, 814 920 uint8_t *alpha) 815 921 { -
libs/libmythtv/avformatdecoder.h
27 27 { 28 28 public: 29 29 StreamInfo() : av_stream_index(-1), language(-2), language_index(0) {} 30 StreamInfo(int a, int b, uint c )31 : av_stream_index(a), language(b), language_index(c) {}30 StreamInfo(int a, int b, uint c, int d) 31 : av_stream_index(a), language(b), language_index(c), stream_id(d) {} 32 32 public: 33 33 int av_stream_index; 34 34 int language; ///< ISO639 canonical language key 35 35 uint language_index; 36 int stream_id; 37 bool operator<(const StreamInfo& b) { return (this->stream_id < b.stream_id) ; } 36 38 }; 37 39 typedef vector<StreamInfo> sinfo_vec_t; 38 40 … … 266 268 267 269 // DVD 268 270 int lastdvdtitle; 271 bool dvdmenupktseen; 269 272 }; 270 273 271 274 #endif -
libs/libavformat/avformat.h
276 276 #define AVFMTCTX_NOHEADER 0x0001 /* signal that no header is present 277 277 (streams are added dynamically) */ 278 278 279 #define MAX_STREAMS 20279 #define MAX_STREAMS 40 280 280 281 281 /* format I/O context */ 282 282 typedef struct AVFormatContext { -
libs/libavcodec/mpeg12.c
3033 3033 } 3034 3034 } 3035 3035 3036 /* look for SEQ_END_CODE at the last data in this buffer*/ 3037 /* dvd's won't send the next frame start on still images*/ 3038 /* state should hold the last startcode if one was found above*/ 3039 /* i will point to the position after that startcode */ 3040 if(!pc->frame_start_found){ 3041 if(state == SEQ_END_CODE){ 3042 pc->state=-1; 3043 return i; 3044 } 3045 } 3046 3036 3047 if(pc->frame_start_found){ 3037 3048 /* EOF considered as end of frame */ 3038 3049 if (buf_size == 0) -
libs/libmythdvdnav/dvdnav.c
877 877 return attr.lang_code; 878 878 } 879 879 880 unsigned char dvdnav_audio_get_channels(dvdnav_t *this, uint8_t stream){ 881 audio_attr_t attr; 882 883 if(!this) { 884 printerr("Passed a NULL pointer."); 885 return 0xff; 886 } 887 if(!this->started) { 888 printerr("Virtual DVD machine not started."); 889 return 0xff; 890 } 891 892 pthread_mutex_lock(&this->vm_lock); 893 attr = vm_get_audio_attr(this->vm, stream); 894 pthread_mutex_unlock(&this->vm_lock); 895 896 return attr.channels; 897 898 } 899 880 900 uint16_t dvdnav_spu_stream_to_lang(dvdnav_t *this, uint8_t stream) { 881 901 subp_attr_t attr; 882 902 -
libs/libmythdvdnav/dvdnav.h
550 550 uint16_t dvdnav_audio_stream_to_lang(dvdnav_t *self, uint8_t stream); 551 551 552 552 /* 553 * Get number of audio channels. 554 * (1 -> 2 channels , 5 -> 6 channels) 555 * (returns 0xff if no such stream). 556 */ 557 unsigned char dvdnav_audio_get_channels(dvdnav_t *self, uint8_t stream); 558 559 /* 553 560 * Converts a *logical* subpicture stream id into country code 554 561 * (returns 0xffff if no such stream). 555 562 */