Ticket #1043: mythdvd4.patch
File mythdvd4.patch, 62.9 KB (added by , 20 years ago) |
---|
-
libs/libmythtv/NuppelVideoPlayer.h
261 261 262 262 // DVD public stuff 263 263 void ChangeDVDTrack(bool ffw); 264 void ActivateDVDButton(void); 265 void GoToDVDMenu(QString str); 266 void GoToDVDProgram(bool direction); 264 267 265 268 protected: 266 269 void DisplayPauseFrame(void); … … 364 367 void SwitchToProgram(void); 365 368 void JumpToProgram(void); 366 369 370 // Private DVD stuff 371 void DisplayDVDButton(void); 372 367 373 private: 368 374 VideoOutputType forceVideoOutput; 369 375 … … 590 596 LiveTVChain *livetvchain; 591 597 TV *m_tv; 592 598 599 // DVD 600 bool indvdstillframe; 601 593 602 // Debugging variables 594 603 Jitterometer *output_jmeter; 595 604 }; -
libs/libmythtv/NuppelVideoPlayer.cpp
169 169 tc_avcheck_framecounter(0), tc_diff_estimate(0), 170 170 // LiveTVChain stuff 171 171 livetvchain(NULL), m_tv(NULL), 172 // DVD stuff 173 indvdstillframe(false), 172 174 // Debugging variables 173 175 output_jmeter(NULL) 174 176 { … … 481 483 vidExitLock.unlock(); 482 484 483 485 ClearAfterSeek(); 486 487 if (ringBuffer->InDVDMenuOrStillFrame()) 488 ringBuffer->Seek(ringBuffer->GetDVDCellStartPos(),SEEK_SET); 484 489 } 485 490 486 491 QString NuppelVideoPlayer::ReinitAudio(void) … … 814 819 deleteIter = deleteMap.begin(); 815 820 } 816 821 } 817 bookmarkseek = GetBookmark(); 822 823 if (!ringBuffer->isDVD()) // need this til proper DVD bookmarking is implemented 824 bookmarkseek = GetBookmark(); 818 825 819 826 return IsErrored() ? -1 : 0; 820 827 } … … 885 892 void NuppelVideoPlayer::ReleaseNextVideoFrame(VideoFrame *buffer, 886 893 long long timecode) 887 894 { 888 WrapTimecode(timecode, TC_VIDEO); 895 if (!ringBuffer->isDVD()) 896 WrapTimecode(timecode, TC_VIDEO); 889 897 buffer->timecode = timecode; 890 898 891 899 videoOutput->ReleaseFrame(buffer); … … 925 933 void NuppelVideoPlayer::AddTextData(char *buffer, int len, 926 934 long long timecode, char type) 927 935 { 928 WrapTimecode(timecode, TC_CC); 936 if (!ringBuffer->isDVD()) 937 WrapTimecode(timecode, TC_CC); 929 938 930 939 if (subtitlesOn) 931 940 { … … 1803 1812 return; 1804 1813 } 1805 1814 1815 if (ringBuffer->InDVDMenuOrStillFrame()) 1816 DisplayDVDButton(); 1817 1806 1818 videofiltersLock.lock(); 1807 1819 videoOutput->ProcessFrame(NULL, osd, videoFilters, pipplayer); 1808 1820 videofiltersLock.unlock(); … … 1817 1829 video_actually_paused = false; 1818 1830 resetvideo = false; 1819 1831 1832 if (ringBuffer->isDVD()) 1833 goto displayframe; 1834 1820 1835 prebuffering_lock.lock(); 1821 1836 if (prebuffering) 1822 1837 { … … 1878 1893 prebuffer_tries = 0; 1879 1894 prebuffering_lock.unlock(); 1880 1895 1896 displayframe: 1897 1881 1898 videoOutput->StartDisplayingFrame(); 1882 1899 1883 1900 VideoFrame *frame = videoOutput->GetLastShownFrame(); … … 1916 1933 yuv_wait.wakeAll(); 1917 1934 } 1918 1935 1936 if (ringBuffer->InDVDMenuOrStillFrame()) 1937 DisplayDVDButton(); 1938 1919 1939 if (subtitlesOn) 1920 1940 { 1921 1941 ShowText(); … … 2008 2028 needsetpipplayer = false; 2009 2029 } 2010 2030 2031 if (ringBuffer->isDVD()) 2032 { 2033 int nbframes = videoOutput->ValidVideoFrames(); 2034 if (nbframes < 2) 2035 { 2036 if (ringBuffer->IsDVDWaiting()) 2037 { 2038 ringBuffer->DVDWaitSkip(); 2039 usleep(100000); 2040 continue; 2041 } 2042 if (ringBuffer->InDVDMenuOrStillFrame()) 2043 { 2044 if (nbframes == 0) 2045 { 2046 // wait to confirm there is no other frames been decoded. 2047 usleep(100000); 2048 nbframes = videoOutput->ValidVideoFrames(); 2049 if (nbframes == 0) 2050 { 2051 ringBuffer->Seek(ringBuffer->GetDVDCellStartPos(),SEEK_SET); 2052 continue; 2053 } 2054 } 2055 indvdstillframe = true; 2056 if (!pausevideo && nbframes == 1) 2057 PauseVideo(false); 2058 } 2059 } 2060 // restart playing after skipping still frame 2061 if (indvdstillframe && nbframes > 1) 2062 { 2063 UnpauseVideo(); 2064 indvdstillframe = false; 2065 } 2066 } 2011 2067 if (pausevideo) 2012 2068 { 2013 2069 usleep(frame_interval); … … 2132 2188 { 2133 2189 ClearAfterSeek(); 2134 2190 2135 framesPlayed = 0; 2191 if (!ringBuffer->isDVD()) 2192 framesPlayed = 0; 2136 2193 2137 2194 GetDecoder()->Reset(); 2138 2195 errored |= GetDecoder()->IsErrored(); … … 2777 2834 */ 2778 2835 void NuppelVideoPlayer::AddAudioData(char *buffer, int len, long long timecode) 2779 2836 { 2780 WrapTimecode(timecode, TC_AUDIO); 2781 2837 if (!ringBuffer->isDVD()) 2838 WrapTimecode(timecode, TC_AUDIO); 2839 2782 2840 int samplesize = (audio_channels * audio_bits) / 8; // bytes per sample 2783 2841 if ((samplesize <= 0) || !audioOutput) 2784 2842 return; 2785 2843 2786 2844 int samples = len / samplesize; 2787 2845 2846 if (ringBuffer->isDVD()) 2847 { 2848 audioOutput->Pause(false); 2849 audioOutput->Drain(); 2850 } 2851 2788 2852 // If there is no warping, just send it to the audioOutput. 2789 2853 if (!usevideotimebase) 2790 2854 { … … 4551 4615 posInfo.progBefore = false; 4552 4616 posInfo.progAfter = false; 4553 4617 4554 if (ringBuffer-> isDVD())4618 if (ringBuffer->IsInDVDMenu()) 4555 4619 { 4556 4620 long long rPos = ringBuffer->GetReadPosition(); 4557 4621 long long tPos = 1;//ringBuffer->GetTotalReadPosition(); … … 4576 4640 playbackLen = 4577 4641 (int)(((float)nvr_enc->GetFramesWritten() / video_frame_rate)); 4578 4642 4579 float secsplayed = ((float)framesPlayed / video_frame_rate); 4643 float secsplayed; 4644 if (ringBuffer->isDVD()) 4645 { 4646 if (!ringBuffer->IsInDVDMenu()) 4647 secsplayed = ringBuffer->GetDVDCurrentTime(); 4648 } 4649 else 4650 secsplayed = ((float)framesPlayed / video_frame_rate); 4580 4651 playbackLen = max(playbackLen, 1); 4581 4652 secsplayed = min((float)playbackLen, max(secsplayed, 0.0f)); 4582 4653 … … 5120 5191 return; 5121 5192 5122 5193 GetDecoder()->ChangeDVDTrack(ffw); 5123 usleep(100000);5124 5194 ClearAfterSeek(); 5125 5195 } 5126 5196 5197 void NuppelVideoPlayer::DisplayDVDButton(void) 5198 { 5199 if (!ringBuffer->InDVDMenuOrStillFrame()) 5200 return; 5201 5202 long long spupts = ringBuffer->DVDMenuSpuPts(); 5203 long long ptslow = spupts - 100; 5204 long long ptshigh = spupts + 100; 5205 VideoFrame *buffer = videoOutput->GetLastShownFrame(); 5206 if (!osd->IsSetDisplaying("subtitles") && 5207 (buffer->timecode > 0) && 5208 ((buffer->timecode < ptslow) || 5209 (buffer->timecode > ptshigh))) 5210 { 5211 return; 5212 } 5213 AVSubtitleRect *highlightButton; 5214 OSDSet *subtitleOSD = NULL; 5215 highlightButton = ringBuffer->GetDVDMenuButton(); 5216 subtitleLock.lock(); 5217 if (highlightButton != NULL) 5218 { 5219 osd->HideSet("subtitles"); 5220 osd->ClearAll("subtitles"); 5221 int h = highlightButton->h; 5222 int w = highlightButton->w; 5223 int linesize = highlightButton->linesize; 5224 int x1 = highlightButton->x; 5225 int y1 = highlightButton->y; 5226 uint btnX = ringBuffer->DVDButtonPosX(); 5227 uint btnY = ringBuffer->DVDButtonPosY(); 5228 subtitleOSD = osd->GetSet("subtitles"); 5229 5230 QImage hl_button(w,h,32); 5231 hl_button.setAlphaBuffer(true); 5232 for (int y = 0; y < h; y++) 5233 { 5234 for (int x = 0; x < w; x++) 5235 { 5236 const uint8_t color = highlightButton->bitmap[(y+y1)*linesize+(x+x1)]; 5237 const uint32_t pixel = highlightButton->rgba_palette[color]; 5238 hl_button.setPixel(x,y,pixel); 5239 } 5240 } 5241 OSDTypeImage* image = new OSDTypeImage(); 5242 QImage scaledImage = hl_button.smoothScale(w+1,h+1); 5243 image->SetPosition(QPoint(btnX-1, btnY+1)); 5244 image->LoadFromQImage(scaledImage); 5245 subtitleOSD->AddType(image); 5246 osd->SetVisible(subtitleOSD,0); 5247 } 5248 subtitleLock.unlock(); 5249 } 5250 5251 void NuppelVideoPlayer::ActivateDVDButton(void) 5252 { 5253 if (!ringBuffer->isDVD()) 5254 return; 5255 5256 if (videoOutput->ValidVideoFrames() > 20) 5257 DiscardVideoFrames(true); 5258 ringBuffer->ActivateDVDButton(); 5259 ringBuffer->HideDVDMenuButton(true); 5260 } 5261 5262 void NuppelVideoPlayer::GoToDVDMenu(QString str) 5263 { 5264 if (!ringBuffer->isDVD()) 5265 return; 5266 5267 if (videoOutput->ValidVideoFrames() > 20) 5268 DiscardVideoFrames(true); 5269 ringBuffer->GoToDVDMenu(str); 5270 } 5271 5272 /** \fn NuppelVideoPlayer::GoToDVDProgram(bool direction) 5273 * \brief Go forward or back by one DVD program 5274 */ 5275 void NuppelVideoPlayer::GoToDVDProgram(bool direction) 5276 { 5277 if (!ringBuffer->isDVD()) 5278 return; 5279 5280 if (videoOutput->ValidVideoFrames() > 20) 5281 DiscardVideoFrames(true); 5282 if (direction == 0) 5283 ringBuffer->GoToDVDPreviousProgram(); 5284 else 5285 ringBuffer->GoToDVDNextProgram(); 5286 } 5287 -
libs/libmythtv/RingBuffer.cpp
1269 1269 return 0; 1270 1270 } 1271 1271 1272 /** \fn RingBuffer::InDVDStillFrame(void) 1273 * \brief Calls DVDRingBufferPriv::InStillFrame(void) 1274 */ 1275 bool RingBuffer::InDVDStillFrame(void) 1276 { 1277 if (dvdPriv) 1278 return dvdPriv->InStillFrame(); 1279 return false; 1280 } 1281 1282 /** \fn RingBuffer::DVDSkipStillFrame(void) 1283 * \brief Calls DVDRingBufferPriv::SkipStillFrame(void) 1284 */ 1285 void RingBuffer::DVDSkipStillFrame(void) 1286 { 1287 if (dvdPriv) 1288 dvdPriv->SkipStillFrame(); 1289 } 1290 1291 /** \fn RingBuffer::DVDWaitSkip(void) 1292 * \brief Calls DVDRingBufferPriv::WaitSkip(void) 1293 */ 1294 void RingBuffer::DVDWaitSkip(void) 1295 { 1296 if (dvdPriv) 1297 dvdPriv->WaitSkip(); 1298 } 1299 1300 /** \fn RingBuffer::IsDVDWaiting(void) 1301 * \brief Calls DVDRingBufferPriv::IsWaiting(void) 1302 */ 1303 bool RingBuffer::IsDVDWaiting(void) 1304 { 1305 if (dvdPriv) 1306 return dvdPriv->IsWaiting(); 1307 return false; 1308 } 1309 1310 /** \fn RingBuffer::IsInDVDMenu(void) 1311 * \brief Calls DVDRingBufferPriv::IsInMenu(void) 1312 */ 1313 bool RingBuffer::IsInDVDMenu(void) 1314 { 1315 if (dvdPriv) 1316 return dvdPriv->IsInMenu(); 1317 return false; 1318 } 1319 1320 /** \fn RingBuffer::GoToDVDMenu(QString str) 1321 * \brief Calls DVDRingBufferPriv::GoToMenu(str) 1322 */ 1323 void RingBuffer::GoToDVDMenu(QString str) 1324 { 1325 if (dvdPriv) 1326 dvdPriv->GoToMenu(str); 1327 } 1328 1329 /** \fn RingBuffer::GoToDVDNextProgram(void) 1330 * \brief Calls DVDRingBufferPriv::GoToNextProgram(void) 1331 */ 1332 void RingBuffer::GoToDVDNextProgram(void) 1333 { 1334 if (dvdPriv) 1335 dvdPriv->GoToNextProgram(); 1336 } 1337 1338 /** \fn RingBuffer::GoToDVDPreviousProgram(void) 1339 * \brief Calls DVDRingBufferPriv::GoToPreviousProgram(void) 1340 */ 1341 void RingBuffer::GoToDVDPreviousProgram(void) 1342 { 1343 if (dvdPriv) 1344 dvdPriv->GoToPreviousProgram(); 1345 } 1346 1347 /** \fn RingBuffer::MoveDVDButtonLeft(void) 1348 * \brief Calls DVDRingBufferPriv::MoveButtonLeft(void) 1349 */ 1350 void RingBuffer::MoveDVDButtonLeft(void) 1351 { 1352 if (dvdPriv) 1353 dvdPriv->MoveButtonLeft(); 1354 } 1355 1356 /** \fn RingBuffer::MoveDVDButtonRight(void) 1357 * \brief Calls DVDRingBufferPriv::MoveButtonRight(void) 1358 */ 1359 void RingBuffer::MoveDVDButtonRight(void) 1360 { 1361 if (dvdPriv) 1362 dvdPriv->MoveButtonRight(); 1363 } 1364 1365 /** \fn RingBuffer::MoveDVDButtonUp(void) 1366 * \brief Calls DVDRingBufferPriv::MoveButtonUp(void) 1367 */ 1368 void RingBuffer::MoveDVDButtonUp(void) 1369 { 1370 if (dvdPriv) 1371 dvdPriv->MoveButtonUp(); 1372 } 1373 1374 /** \fn RingBuffer::MoveDVDButtonDown(void) 1375 * \brief Calls DVDRingBufferPriv::MoveButtonDown(void) 1376 */ 1377 void RingBuffer::MoveDVDButtonDown(void) 1378 { 1379 if (dvdPriv) 1380 dvdPriv->MoveButtonDown(); 1381 } 1382 1383 /** \fn RingBuffer::ActivateDVDButton(void) 1384 * \brief Calls DVDRingBufferPriv::ActivateButton(void) 1385 */ 1386 void RingBuffer::ActivateDVDButton(void) 1387 { 1388 if (dvdPriv) 1389 dvdPriv->ActivateButton(); 1390 } 1391 1392 /** \fn RingBuffer::NumDVDMenuButtons(void) 1393 * \brief Calls DVDRingBufferPriv::NumMenuButtons(void) 1394 */ 1395 int RingBuffer::NumDVDMenuButtons(void) 1396 { 1397 if (dvdPriv) 1398 return dvdPriv->NumMenuButtons(); 1399 return 0; 1400 } 1401 1402 /** \fn RingBuffer::NumPartsInDVDTitle(void) 1403 * \brief Calls DVDRingBufferPriv::NumPartsInTitle(void) 1404 */ 1405 int RingBuffer::NumPartsInDVDTitle(void) 1406 { 1407 if (dvdPriv) 1408 return dvdPriv->NumPartsInTitle(); 1409 return 0; 1410 } 1411 1412 /** \fn RingBuffer::GetDVDMenuSPUPkt(uint8_t *buf, int buf_size,long long pts) 1413 * \brief Calls DVDRingBufferPriv::GetMenuSPUPkt() 1414 */ 1415 void RingBuffer::GetDVDMenuSPUPkt(uint8_t *buf, int buf_size,long long pts) 1416 { 1417 if (dvdPriv) 1418 dvdPriv->GetMenuSPUPkt(buf,buf_size,pts); 1419 } 1420 1421 /** \fn RingBuffer::GetDVDMenuButton(void) 1422 * \brief Calls DVDRingBufferPriv::GetMenuButton(void) 1423 */ 1424 AVSubtitleRect *RingBuffer::GetDVDMenuButton(void) 1425 { 1426 if (dvdPriv) 1427 return dvdPriv->GetMenuButton(); 1428 return NULL; 1429 } 1430 1431 /** \fn RingBuffer::IgnoringDVDStillorWait(void) 1432 * \brief Calls DVDRingBufferPriv::IgnoringStillorWait() 1433 */ 1434 bool RingBuffer::IgnoringDVDStillorWait(void) 1435 { 1436 if (dvdPriv) 1437 return dvdPriv->IgnoringStillorWait(); 1438 return false; 1439 } 1440 1441 /** \fn RingBuffer::IgnoreDVDStillOrWait(bool skip) 1442 * \brief Calls DVDRingBufferPriv::IgnoreStillOrWait() 1443 */ 1444 void RingBuffer::IgnoreDVDStillOrWait(bool skip) 1445 { 1446 if (dvdPriv) 1447 dvdPriv->IgnoreStillOrWait(skip); 1448 } 1449 1450 /** \fn RingBuffer::GetDVDCurrentTime(void) 1451 * \brief Calls DVDRingBufferPriv::GetCurrentTime(void) 1452 */ 1453 uint RingBuffer::GetDVDCurrentTime(void) 1454 { 1455 if (dvdPriv) 1456 return dvdPriv->GetCurrentTime(); 1457 return 0; 1458 } 1459 1460 /** \fn RingBuffer::GetDVDCellStartPos(void) 1461 * \brief Calls DVDRingBufferPriv::GetDVDCellStartPos(void) 1462 */ 1463 long long RingBuffer::GetDVDCellStartPos(void) 1464 { 1465 if (dvdPriv) 1466 return dvdPriv->GetCellStartPos(); 1467 return false; 1468 } 1469 1470 /** \fn RingBuffer::HideDVDMenuButton(bool hide) 1471 * \brief Calls DVDRingBufferPriv::HideMenuButton(bool hide) 1472 */ 1473 void RingBuffer::HideDVDMenuButton(bool hide) 1474 { 1475 if (dvdPriv) 1476 dvdPriv->HideMenuButton(hide); 1477 } 1478 1479 /** \fn RingBuffer::DVDButtonPosX(void) 1480 * \brief Calls DVDRingBufferPriv::ButtonPosX(void) 1481 */ 1482 uint RingBuffer::DVDButtonPosX(void) 1483 { 1484 if (dvdPriv) 1485 return dvdPriv->ButtonPosX(); 1486 return 0; 1487 } 1488 1489 /** \fn RingBuffer::DVDButtonPosY(void) 1490 * \brief Calls DVDRingBufferPriv::ButtonPosY(void) 1491 */ 1492 uint RingBuffer::DVDButtonPosY(void) 1493 { 1494 if (dvdPriv) 1495 return dvdPriv->ButtonPosY(); 1496 return 0; 1497 } 1498 1499 /** \fn RingBuffer::GetDVDAudioLanguage(int stream_id) 1500 * \brief Calls DVDRingBufferPriv::GetAudioLanguage(stream_id) 1501 */ 1502 uint RingBuffer::GetDVDAudioLanguage(int id) 1503 { 1504 if (dvdPriv) 1505 return dvdPriv->GetAudioLanguage(id); 1506 return 0; 1507 } 1508 1509 /** \fn RingBuffer::GetDVDSubtitleLanguage(int stream_id) 1510 * \brief Calls DVDRingBufferPriv::GetSubtitleLanguage(stream_id) 1511 */ 1512 uint RingBuffer::GetDVDSubtitleLanguage(int id) 1513 { 1514 if (dvdPriv) 1515 return dvdPriv->GetSubtitleLanguage(id); 1516 return 0; 1517 } 1518 1519 bool RingBuffer::InDVDMenuOrStillFrame(void) 1520 { 1521 if (dvdPriv) 1522 return (IsInDVDMenu() || InDVDStillFrame()); 1523 return false; 1524 } 1525 1526 /** \fn RingBuffer::DVDMenuSpuPts(void) 1527 * \brief Calls DVDRingBufferPriv::MenuSpuPts() 1528 */ 1529 long long RingBuffer::DVDMenuSpuPts(void) 1530 { 1531 if (dvdPriv) 1532 return dvdPriv->MenuSpuPts(); 1533 return 0; 1534 } 1535 1536 int RingBuffer::DVDCellChange(void) 1537 { 1538 if (dvdPriv) 1539 return dvdPriv->CellChange(); 1540 return 0; 1541 } 1542 -
libs/libmythtv/DVDRingBuffer.h
7 7 8 8 #include <qstring.h> 9 9 #include <qobject.h> 10 #include "util.h" 11 #include "avcodec.h" 10 12 11 13 #ifdef HAVE_DVDNAV 12 14 # include <dvdnav/dvdnav.h> … … 56 58 bool IsInMenu(void) const { return (title == 0); } 57 59 bool IsOpen(void) const { return dvdnav; } 58 60 long long GetReadPosition(void); 59 long long GetTotalReadPosition(void) ;61 long long GetTotalReadPosition(void) { return titleLength; } 60 62 void GetDescForPos(QString &desc) const; 61 63 void GetPartAndTitle(int &_part, int &_title) const 62 64 { _part = part; _title = _title; } 63 65 uint GetTotalTimeOfTitle(void); 64 66 uint GetCellStart(void); 67 bool InStillFrame(void) { return cellHasStillFrame; } 68 bool IsWaiting(void) { return dvdWaiting; } 69 int NumPartsInTitle(void) { return titleParts; } 70 void GetMenuSPUPkt(uint8_t *buf, int buf_size,long long pts); 71 AVSubtitleRect *GetMenuButton(void); 72 bool IgnoringStillorWait(void) { return skipstillorwait; } 73 long long GetCellStartPos(void) { return cellstartPos; } 74 void HideMenuButton(bool hide); 75 uint ButtonPosX(void) { return hl_startx; } 76 uint ButtonPosY(void) { return hl_starty; } 77 uint GetAudioLanguage(int id); 78 uint GetSubtitleLanguage(int id); 79 long long MenuSpuPts(void) { return menuspupts; } 80 int CellChange(void) { return cellChange; } 65 81 66 82 // commands 67 83 bool OpenFile(const QString &filename); … … 70 86 void prevTrack(void); 71 87 int safe_read(void *data, unsigned sz); 72 88 long long Seek(long long pos, int whence); 89 void SkipStillFrame(void); 90 void WaitSkip(void); 91 void GoToMenu(const QString str); 92 void GoToNextProgram(void); 93 void GoToPreviousProgram(void); 94 void MoveButtonLeft(void); 95 void MoveButtonRight(void); 96 void MoveButtonUp(void); 97 void MoveButtonDown(void); 98 void ActivateButton(void); 99 int NumMenuButtons(void); 100 void IgnoreStillOrWait(bool skip) { skipstillorwait = skip; } 101 uint GetCurrentTime(void); 73 102 74 103 protected: 75 104 dvdnav_t *dvdnav; … … 84 113 dvdnav_t *lastNav; // This really belongs in the player. 85 114 int part; 86 115 int title; 87 int maxPart; 88 int mainTitle; 116 int titleParts; 89 117 bool gotStop; 118 bool cellHasStillFrame; 119 bool dvdWaiting; 120 long long titleLength; 121 MythTimer stillFrameTimer; 122 uint32_t clut[16]; 123 uint8_t button_color[4]; 124 uint8_t button_alpha[4]; 125 uint16_t hl_startx; 126 uint16_t hl_width; 127 uint16_t hl_starty; 128 uint16_t hl_height; 129 bool spuchanged; 130 uint8_t *menuSpuPkt; 131 int menuBuflength; 132 uint8_t *buttonBitmap; 133 AVSubtitleRect *dvdMenuButton; 134 int buttonCoords; 135 bool skipstillorwait; 136 bool spuStreamLetterbox; 137 long long cellstartPos; 138 bool buttonSelected; 139 bool buttonExists; 140 long long menuspupts; 141 int cellChange; 142 143 bool DrawMenuButton(uint8_t *spu_pkt, int buf_size); 144 bool DVDButtonUpdate(bool b_mode); 145 void ClearMenuSPUParameters(void); 146 bool MenuButtonChanged(void); 147 uint ConvertLangCode(uint16_t code); // converts 2char key to 3char key 148 149 /* copied from dvdsub.c from ffmpeg */ 150 int get_nibble(const uint8_t *buf, int nibble_offset); 151 int decode_rle(uint8_t *bitmap, int linesize, int w, int h, 152 const uint8_t *buf, int nibble_offset, int buf_size); 153 void guess_palette(uint32_t *rgba_palette,uint8_t *palette, 154 uint8_t *alpha); 90 155 }; 91 156 #endif // HAVE_DVDNAV 92 157 #endif // DVD_RING_BUFFER_H_ -
libs/libmythtv/avformatdecoder.cpp
272 272 // Subtitle selection 273 273 wantedSubtitleStream(), selectedSubtitleStream(), 274 274 // language preference 275 languagePreference(iso639_get_language_key_list()) 275 languagePreference(iso639_get_language_key_list()), 276 // DVD 277 lastdvdtitle(0), lastdvdpart(0), 278 lastdvdcellchange(0) 276 279 { 277 280 bzero(¶ms, sizeof(AVFormatParameters)); 278 281 bzero(prvpkt, 3 * sizeof(char)); … … 424 427 void AvFormatDecoder::SeekReset(long long newKey, uint skipFrames, 425 428 bool doflush, bool discardFrames) 426 429 { 430 if (ringBuffer->isDVD()) 431 { 432 int totaltime = ringBuffer->GetTotalTimeOfTitle(); 433 if (totaltime < 30 || ringBuffer->InDVDMenuOrStillFrame()) 434 return; 435 } 436 427 437 VERBOSE(VB_PLAYBACK, LOC + 428 438 QString("SeekReset(%1, %2, %3 flush, %4 discard)") 429 439 .arg(newKey).arg(skipFrames) … … 478 488 479 489 prevgoppos = 0; 480 490 gopset = false; 481 framesPlayed = lastKey; 482 framesRead = lastKey; 491 if (!ringBuffer->isDVD()) 492 { 493 framesPlayed = lastKey; 494 framesRead = lastKey; 495 } 483 496 } 484 497 485 498 // Skip all the desired number of skipFrames … … 511 524 void AvFormatDecoder::Reset() 512 525 { 513 526 DecoderBase::Reset(); 527 if (ringBuffer->isDVD()) 528 { 529 posmapStarted = false; 530 SyncPositionMap(); 531 framesPlayed = DVDCurrentFrameNumber(); 532 framesRead = framesPlayed; 533 } 514 534 #if 0 515 535 // This is causing problems, and may not be needed anymore since 516 536 // we do not reuse the same file for different streams anymore. -- dtk … … 643 663 readcontext.max_packet_size = 0; 644 664 readcontext.priv_data = this; 645 665 646 ic->pb.buffer_size = 32768; 666 if (ringBuffer->isDVD()) 667 ic->pb.buffer_size = 2048; 668 else 669 ic->pb.buffer_size = 32768; 647 670 ic->pb.buffer = (unsigned char *)av_malloc(ic->pb.buffer_size); 648 671 ic->pb.buf_ptr = ic->pb.buffer; 649 672 ic->pb.write_flag = 0; … … 725 748 return -1; 726 749 } 727 750 728 int ret = av_find_stream_info(ic); 751 int ret; 752 if (ringBuffer->isDVD()) 753 { 754 AVPacket pkt1; 755 while (ic->nb_streams == 0) 756 ret = av_read_frame(ic,&pkt1); 757 av_free_packet(&pkt1); 758 ringBuffer->Seek(0,SEEK_SET); 759 ringBuffer->IgnoreDVDStillOrWait(false); 760 } 761 else 762 ret = av_find_stream_info(ic); 763 729 764 if (ret < 0) 730 765 { 731 766 VERBOSE(VB_IMPORTANT, LOC_ERR + "Could not find codec parameters. " + … … 739 774 740 775 fmt->flags &= ~AVFMT_NOFILE; 741 776 742 av_estimate_timings(ic); 777 if (!ringBuffer->isDVD()) 778 av_estimate_timings(ic); 779 743 780 av_read_frame_flush(ic); 744 781 745 782 // Scan for the initial A/V streams … … 1842 1879 1843 1880 for (uint i = 0; i < audioStreams.size(); i++) 1844 1881 { 1845 QString msg = iso639_key_toName(audioStreams[i].language); 1882 QString msg; 1883 if (ringBuffer->isDVD()) 1884 msg = iso639_key_toName(ringBuffer->GetDVDAudioLanguage(i)); 1885 else 1886 msg = iso639_key_toName(audioStreams[i].language); 1887 1846 1888 AVStream *s = ic->streams[audioStreams[i].av_stream_index]; 1847 1889 if (s) 1848 1890 { … … 2085 2127 2086 2128 for (uint i = 0; i < subtitleStreams.size(); i++) 2087 2129 { 2088 QString msg = iso639_key_toName(subtitleStreams[i].language); 2130 QString msg; 2131 if (ringBuffer->isDVD()) 2132 msg = iso639_key_toName(ringBuffer->GetDVDSubtitleLanguage(i)); 2133 else 2134 msg = iso639_key_toName(subtitleStreams[i].language); 2089 2135 list += QString("%1: %2").arg(i+1).arg(msg); 2090 2136 } 2091 2137 … … 2108 2154 */ 2109 2155 bool AvFormatDecoder::autoSelectSubtitleTrack(void) 2110 2156 { 2157 if (ringBuffer->InDVDMenuOrStillFrame()) 2158 return true; 2159 2111 2160 uint numStreams = subtitleStreams.size(); 2112 2161 2113 2162 if ((currentSubtitleTrack >= 0) && … … 2197 2246 2198 2247 bool allowedquit = false; 2199 2248 bool storevideoframes = false; 2249 bool dvdvideopause = false; 2200 2250 2201 2251 { 2202 2252 QMutexLocker locker(&avcodeclock); … … 2214 2264 // disable audio request if there are no audio streams anymore 2215 2265 onlyvideo = 1; 2216 2266 } 2217 2267 2268 if (ringBuffer->isDVD()) 2269 { 2270 int dvdtitle = 0; 2271 int dvdpart = 0; 2272 ringBuffer->getPartAndTitle(dvdtitle,dvdpart); 2273 int dvdcellchange = ringBuffer->DVDCellChange(); 2274 if ((dvdtitle != lastdvdtitle || dvdpart != lastdvdpart || 2275 dvdcellchange != lastdvdcellchange)) 2276 { 2277 GetNVP()->GetOSD()->HideSet("subtitles"); 2278 GetNVP()->GetOSD()->ClearAll("subtitles"); 2279 } 2280 if (dvdtitle != lastdvdtitle) 2281 { 2282 posmapStarted = false; 2283 m_positionMap.clear(); 2284 SyncPositionMap(); 2285 framesPlayed = DVDCurrentFrameNumber(); 2286 framesRead = framesPlayed; 2287 VERBOSE(VB_PLAYBACK, 2288 QString(LOC + "DVD Title Changed. Update framesPlayed: %1 ") 2289 .arg(framesPlayed)); 2290 } 2291 lastdvdtitle = dvdtitle; 2292 lastdvdpart = dvdpart; 2293 lastdvdcellchange = dvdcellchange; 2294 2295 if (storedPackets.count() < 2 && !dvdvideopause) 2296 storevideoframes = true; 2297 else 2298 storevideoframes = false; 2299 } 2300 2218 2301 if (gotvideo) 2219 2302 { 2220 2303 if (lowbuffers && onlyvideo == 0 && lastapts < lastvpts + 100 && 2221 lastapts > lastvpts - 10000 )2304 lastapts > lastvpts - 10000 && !ringBuffer->isDVD()) 2222 2305 { 2223 2306 //cout << "behind: " << lastapts << " " << lastvpts << endl; 2224 2307 storevideoframes = true; … … 2230 2313 } 2231 2314 } 2232 2315 2316 if (ringBuffer->InDVDStillFrame() && 2317 storedPackets.count() > 0) 2318 { 2319 storevideoframes = false; 2320 dvdvideopause = true; 2321 } 2322 2233 2323 if (!storevideoframes && storedPackets.count() > 0) 2234 2324 { 2235 2325 if (pkt) … … 2279 2369 if (pkt->dts != (int64_t)AV_NOPTS_VALUE) 2280 2370 pts = (long long)(av_q2d(curstream->time_base) * pkt->dts * 1000); 2281 2371 2372 if (ringBuffer->isDVD() && pkt->size == 4) 2373 { 2374 dvdvideopause = true; 2375 av_free_packet(pkt); 2376 continue; 2377 } 2378 2282 2379 if (storevideoframes && 2283 2380 curstream->codec->codec_type == CODEC_TYPE_VIDEO) 2284 2381 { … … 2481 2578 GetNVP()->AddAudioData((char *)audioSamples, data_size, 2482 2579 temppts); 2483 2580 2581 if (ringBuffer->isDVD()) 2582 allowedquit = true; 2583 2484 2584 break; 2485 2585 } 2486 2586 case CODEC_TYPE_VIDEO: … … 2510 2610 ret = d->DecodeMPEG2Video(context, &mpa_pic, 2511 2611 &gotpicture, ptr, len); 2512 2612 else 2613 { 2513 2614 ret = avcodec_decode_video(context, &mpa_pic, 2514 2615 &gotpicture, ptr, len); 2616 // Reparse it to not drop the DVD still frame // 2617 if (dvdvideopause && storedPackets.count() == 0) 2618 ret = avcodec_decode_video(context, &mpa_pic, 2619 &gotpicture, ptr, len); 2620 } 2515 2621 avcodeclock.unlock(); 2516 2622 2517 2623 if (ret < 0) … … 2610 2716 int gotSubtitles = 0; 2611 2717 AVSubtitle subtitle; 2612 2718 2613 if (pkt->stream_index == subIdx) 2719 if (ringBuffer->IsInDVDMenu()) 2720 ringBuffer->GetDVDMenuSPUPkt(ptr,len,pts); 2721 else if (pkt->stream_index == subIdx) 2614 2722 { 2615 2723 QMutexLocker locker(&avcodeclock); 2616 2724 avcodec_decode_subtitle(curstream->codec, -
libs/libmythtv/decoderbase.h
92 92 // DVD public stuff 93 93 void ChangeDVDTrack(bool ffw); 94 94 long long DVDFindPosition(long long desiredFrame); 95 long long DVDCurrentFrameNumber(void); 95 96 96 97 protected: 97 98 void FileChanged(void); -
libs/libmythtv/tv_play.cpp
150 150 REG_KEY("TV Playback", "PREVSUBTITLE", "Switch to the previous subtitle track", ""); 151 151 REG_KEY("TV Playback", "JUMPPREV", "Jump to previously played recording", ""); 152 152 REG_KEY("TV Playback", "SIGNALMON", "Monitor Signal Quality", "F7"); 153 153 REG_KEY("TV Playback", "JUMPTODVDROOTMENU", "Jump to the DVD Root Menu", ""); 154 154 155 REG_KEY("TV Editing", "CLEARMAP", "Clear editing cut points", "C,Q,Home"); 155 156 REG_KEY("TV Editing", "INVERTMAP", "Invert Begin/End cut points", "I"); 156 157 REG_KEY("TV Editing", "LOADCOMMSKIP", "Load cut list from commercial skips", … … 1163 1164 void TV::StopStuff(bool stopRingBuffers, bool stopPlayers, bool stopRecorders) 1164 1165 { 1165 1166 VERBOSE(VB_PLAYBACK, LOC + "StopStuff() -- begin"); 1167 1168 if (prbuffer->isDVD()) 1169 { 1170 VERBOSE(VB_PLAYBACK,LOC + " StopStuff() -- get dvd player out of still frame or wait status"); 1171 prbuffer->IgnoreDVDStillOrWait(true); 1172 } 1166 1173 if (stopRingBuffers) 1167 1174 { 1168 1175 VERBOSE(VB_PLAYBACK, LOC + "StopStuff(): stopping ring buffer[s]"); … … 2168 2175 AddKeyToInputQueue(0); 2169 2176 } 2170 2177 } 2171 else if (action == "SEEKFFWD") 2178 else if (action == "SEEKFFWD" && 2179 !prbuffer->InDVDMenuOrStillFrame()) 2172 2180 { 2173 2181 if (HasQueuedInput()) 2174 2182 DoArbSeek(ARBSEEK_FORWARD); … … 2184 2192 else 2185 2193 ChangeFFRew(1); 2186 2194 } 2187 else if (action == "FFWDSTICKY") 2195 else if (action == "FFWDSTICKY" && 2196 !prbuffer->InDVDMenuOrStillFrame()) 2188 2197 { 2189 2198 if (HasQueuedInput()) 2190 2199 DoArbSeek(ARBSEEK_END); … … 2193 2202 else 2194 2203 ChangeFFRew(1); 2195 2204 } 2196 else if (action == "SEEKRWND") 2205 else if (action == "SEEKRWND" && 2206 !prbuffer->InDVDMenuOrStillFrame()) 2197 2207 { 2198 2208 if (HasQueuedInput()) 2199 2209 DoArbSeek(ARBSEEK_REWIND); … … 2208 2218 else 2209 2219 ChangeFFRew(-1); 2210 2220 } 2211 else if (action == "RWNDSTICKY") 2221 else if (action == "RWNDSTICKY" && 2222 !prbuffer->InDVDMenuOrStillFrame()) 2212 2223 { 2213 2224 if (HasQueuedInput()) 2214 2225 DoArbSeek(ARBSEEK_SET); … … 2221 2232 { 2222 2233 if (prbuffer->isDVD()) 2223 2234 { 2224 nvp->ChangeDVDTrack(0); 2225 UpdateOSDSeekMessage(tr("Previous Chapter"), 2226 osd_general_timeout); 2235 if (prbuffer->NumPartsInDVDTitle() < 2) 2236 { 2237 nvp->GoToDVDProgram(0); 2238 UpdateOSDSeekMessage(tr("Previous Title/Chapter"), 2239 osd_general_timeout); 2240 } 2241 else 2242 { 2243 nvp->ChangeDVDTrack(0); 2244 UpdateOSDSeekMessage(tr("Previous Chapter"), 2245 osd_general_timeout); 2246 } 2227 2247 } 2228 2248 else 2229 2249 { … … 2234 2254 { 2235 2255 if (prbuffer->isDVD()) 2236 2256 { 2237 nvp->ChangeDVDTrack(1); 2238 UpdateOSDSeekMessage(tr("Next Chapter"), osd_general_timeout); 2257 if (prbuffer->InDVDStillFrame()) 2258 { 2259 prbuffer->DVDSkipStillFrame(); 2260 UpdateOSDSeekMessage(tr("Skip Still Frame"), 2261 osd_general_timeout); 2262 } 2263 else if (prbuffer->NumPartsInDVDTitle() > 2) 2264 { 2265 nvp->ChangeDVDTrack(1); 2266 UpdateOSDSeekMessage(tr("Next Chapter"), 2267 osd_general_timeout); 2268 } 2269 else 2270 { 2271 nvp->GoToDVDProgram(1); 2272 UpdateOSDSeekMessage(tr("Next Title"), 2273 osd_general_timeout); 2274 } 2239 2275 } 2240 2276 else 2241 2277 { … … 2513 2549 QString action = actions[i]; 2514 2550 handled = true; 2515 2551 2516 if ( action == "SELECT")2552 if (prbuffer->IsInDVDMenu()) 2517 2553 { 2554 int nb_buttons = prbuffer->NumDVDMenuButtons(); 2555 if (nb_buttons > 0) 2556 { 2557 if (action == "UP" || action == "CHANNELUP") 2558 prbuffer->MoveDVDButtonUp(); 2559 else if (action == "DOWN" || action == "CHANNELDOWN") 2560 prbuffer->MoveDVDButtonDown(); 2561 else if (action == "LEFT" || action == "SEEKRWND") 2562 prbuffer->MoveDVDButtonLeft(); 2563 else if (action == "RIGHT" || action == "SEEKFFWD") 2564 prbuffer->MoveDVDButtonRight(); 2565 else if (action == "SELECT") 2566 nvp->ActivateDVDButton(); 2567 } 2568 } 2569 else if (action == "SELECT") 2570 { 2518 2571 if (!was_doing_ff_rew) 2519 2572 { 2520 2573 if (gContext->GetNumSetting("AltClearSavedPosition", 1) … … 2536 2589 exitPlayer = true; 2537 2590 wantsToQuit = true; 2538 2591 } 2592 else if (action == "JUMPTODVDROOTMENU") 2593 nvp->GoToDVDMenu("menu"); 2539 2594 else if (action == "GUIDE") 2540 2595 LoadMenu(); 2541 2596 else if (action == "FINDER") … … 2546 2601 ShowOSDTreeMenu(); 2547 2602 else if (action == "CHANNELUP") 2548 2603 { 2549 if (prbuffer->isDVD()) 2604 if (prbuffer->isDVD() && 2605 !prbuffer->InDVDMenuOrStillFrame()) 2550 2606 { 2551 2607 nvp->ChangeDVDTrack(0); 2552 2608 UpdateOSDSeekMessage(tr("Previous Chapter"), … … 2559 2615 } 2560 2616 else if (action == "CHANNELDOWN") 2561 2617 { 2562 if (prbuffer->isDVD()) 2618 if (prbuffer->isDVD() && 2619 !prbuffer->InDVDMenuOrStillFrame()) 2563 2620 { 2564 2621 nvp->ChangeDVDTrack(1); 2565 2622 UpdateOSDSeekMessage(tr("Next Chapter"), … … 3034 3091 3035 3092 void TV::DoPause(void) 3036 3093 { 3094 if (prbuffer->InDVDMenuOrStillFrame()) 3095 return; 3096 3037 3097 speed_index = 0; 3038 3098 float time = 0.0; 3039 3099 … … 5525 5585 } 5526 5586 else if (StateIsPlaying(internalState)) 5527 5587 { 5528 if (action == "TOGGLEEDIT") 5588 if (action == "JUMPTODVDROOTMENU") 5589 nvp->GoToDVDMenu("menu"); 5590 else if (action == "TOGGLEEDIT") 5529 5591 DoEditMode(); 5530 5592 else if (action == "TOGGLEAUTOEXPIRE") 5531 5593 ToggleAutoExpire(); … … 5616 5678 } 5617 5679 else if (StateIsPlaying(internalState)) 5618 5680 { 5619 item = new OSDGenericTree(treeMenu, tr("Edit Recording"), "TOGGLEEDIT"); 5681 if (prbuffer->isDVD()) 5682 item = new OSDGenericTree(treeMenu,tr("DVD Root Menu"), "JUMPTODVDROOTMENU"); 5683 else if (!prbuffer->isDVD()) 5684 { 5685 item = new OSDGenericTree(treeMenu, tr("Edit Recording"), "TOGGLEEDIT"); 5620 5686 5621 if (lastProgram != NULL)5622 item = new OSDGenericTree(treeMenu, tr("Previous Recording"), "JUMPPREV");5687 if (lastProgram != NULL) 5688 item = new OSDGenericTree(treeMenu, tr("Previous Recording"), "JUMPPREV"); 5623 5689 5624 pbinfoLock.lock();5690 pbinfoLock.lock(); 5625 5691 5626 if (JobQueue::IsJobQueuedOrRunning(JOB_TRANSCODE,5692 if (JobQueue::IsJobQueuedOrRunning(JOB_TRANSCODE, 5627 5693 playbackinfo->chanid, playbackinfo->startts)) 5628 item = new OSDGenericTree(treeMenu, tr("Stop Transcoding"), "QUEUETRANSCODE");5629 else5630 item = new OSDGenericTree(treeMenu, tr("Begin Transcoding"), "QUEUETRANSCODE");5694 item = new OSDGenericTree(treeMenu, tr("Stop Transcoding"), "QUEUETRANSCODE"); 5695 else 5696 item = new OSDGenericTree(treeMenu, tr("Begin Transcoding"), "QUEUETRANSCODE"); 5631 5697 5632 5698 5633 item = new OSDGenericTree(treeMenu, tr("Commercial Auto-Skip"));5634 subitem = new OSDGenericTree(item, tr("Auto-Skip OFF"),5635 "TOGGLECOMMSKIP0",5636 (autoCommercialSkip == 0) ? 1 : 0, NULL,5637 "COMMSKIPGROUP");5638 subitem = new OSDGenericTree(item, tr("Auto-Skip Notify"),5639 "TOGGLECOMMSKIP2",5640 (autoCommercialSkip == 2) ? 1 : 0, NULL,5641 "COMMSKIPGROUP");5642 subitem = new OSDGenericTree(item, tr("Auto-Skip ON"),5643 "TOGGLECOMMSKIP1",5644 (autoCommercialSkip == 1) ? 1 : 0, NULL,5645 "COMMSKIPGROUP");5699 item = new OSDGenericTree(treeMenu, tr("Commercial Auto-Skip")); 5700 subitem = new OSDGenericTree(item, tr("Auto-Skip OFF"), 5701 "TOGGLECOMMSKIP0", 5702 (autoCommercialSkip == 0) ? 1 : 0, NULL, 5703 "COMMSKIPGROUP"); 5704 subitem = new OSDGenericTree(item, tr("Auto-Skip Notify"), 5705 "TOGGLECOMMSKIP2", 5706 (autoCommercialSkip == 2) ? 1 : 0, NULL, 5707 "COMMSKIPGROUP"); 5708 subitem = new OSDGenericTree(item, tr("Auto-Skip ON"), 5709 "TOGGLECOMMSKIP1", 5710 (autoCommercialSkip == 1) ? 1 : 0, NULL, 5711 "COMMSKIPGROUP"); 5646 5712 5647 if (playbackinfo->GetAutoExpireFromRecorded())5648 item = new OSDGenericTree(treeMenu, tr("Turn Auto-Expire OFF"),5649 "TOGGLEAUTOEXPIRE");5650 else5651 item = new OSDGenericTree(treeMenu, tr("Turn Auto-Expire ON"),5652 "TOGGLEAUTOEXPIRE");5713 if (playbackinfo->GetAutoExpireFromRecorded()) 5714 item = new OSDGenericTree(treeMenu, tr("Turn Auto-Expire OFF"), 5715 "TOGGLEAUTOEXPIRE"); 5716 else 5717 item = new OSDGenericTree(treeMenu, tr("Turn Auto-Expire ON"), 5718 "TOGGLEAUTOEXPIRE"); 5653 5719 5654 pbinfoLock.unlock(); 5720 pbinfoLock.unlock(); 5721 } 5655 5722 } 5656 5723 5657 5724 const QStringList atracks = activenvp->listAudioTracks(); -
libs/libmythtv/DVDRingBuffer.cpp
3 3 #include "DVDRingBuffer.h" 4 4 #include "mythcontext.h" 5 5 #include <dvdnav/nav_read.h> 6 #include "iso639.h" 6 7 7 8 #define LOC QString("DVDRB: ") 8 9 #define LOC_ERR QString("DVDRB, Error: ") … … 25 26 pgLength(0), pgcLength(0), 26 27 cellStart(0), pgStart(0), 27 28 lastNav(NULL), part(0), 28 title(0), maxPart(0), 29 mainTitle(0), gotStop(false) 29 title(0), gotStop(false), 30 cellHasStillFrame(false), dvdWaiting(false), 31 titleLength(0), spuchanged(false), 32 menuBuflength(0), buttonCoords(0), 33 skipstillorwait(true), spuStreamLetterbox(false), 34 cellstartPos(0), buttonSelected(false), 35 buttonExists(false), menuspupts(0), 36 cellChange(0) 30 37 { 38 dvdMenuButton = (AVSubtitleRect*)av_mallocz(sizeof(AVSubtitleRect)); 31 39 } 32 40 33 41 DVDRingBufferPriv::~DVDRingBufferPriv() … … 84 92 85 93 int numTitles = 0; 86 94 int titleParts = 0; 87 maxPart = 0;88 mainTitle = 0;89 95 dvdnav_title_play(dvdnav, 0); 90 96 dvdRet = dvdnav_get_number_of_titles(dvdnav, &numTitles); 91 97 if (numTitles == 0 ) … … 113 119 VERBOSE(VB_IMPORTANT, 114 120 QString("There are title %1 has %2 parts.") 115 121 .arg(curTitle).arg(titleParts)); 116 if (titleParts > maxPart)117 {118 maxPart = titleParts;119 mainTitle = curTitle;120 }121 122 } 122 VERBOSE(VB_IMPORTANT, QString("%1 selected as the main title.")123 .arg(mainTitle));124 123 } 125 124 126 dvdnav_title_play(dvdnav, mainTitle); 127 dvdnav_current_title_info(dvdnav, &title, &part); 125 dvdnav_current_title_info(dvdnav, &title, &part); 128 126 return true; 129 127 } 130 128 } … … 140 138 return pos * DVD_BLOCK_SIZE; 141 139 } 142 140 143 long long DVDRingBufferPriv::GetTotalReadPosition(void)144 {145 uint32_t pos;146 uint32_t length;147 148 if (dvdnav)149 dvdnav_get_position(dvdnav, &pos, &length);150 151 return length * DVD_BLOCK_SIZE;152 }153 154 141 int DVDRingBufferPriv::safe_read(void *data, unsigned sz) 155 142 { 156 143 dvdnav_status_t dvdStat; … … 214 201 .arg(pgLength).arg(pgcLength) 215 202 .arg(cellStart).arg(pgStart)); 216 203 217 dvdnav_current_title_info(dvdnav, &title, &part); 218 if (title == 0) 204 if (dvdnav_get_next_still_flag(dvdnav) > 0) 219 205 { 220 pci_t* pci = dvdnav_get_current_nav_pci(dvdnav); 221 dvdnav_button_select(dvdnav, pci, 1); 206 if (dvdnav_get_next_still_flag(dvdnav) < 0xff) 207 stillFrameTimer.restart(); 208 cellHasStillFrame = true; 222 209 } 210 else 211 cellHasStillFrame = false; 223 212 213 part = 0; 214 titleParts = 0; 215 uint32_t pos; 216 uint32_t length; 217 218 dvdnav_current_title_info(dvdnav, &title, &part); 219 dvdnav_get_number_of_parts(dvdnav, title, &titleParts); 220 dvdnav_get_position(dvdnav, &pos, &length); 221 titleLength = length *DVD_BLOCK_SIZE; 222 cellstartPos = GetReadPosition(); 223 buttonSelected = false; 224 if (cellChange == 100) 225 cellChange = 0; 226 else 227 cellChange++; 224 228 if (blockBuf != dvdBlockWriteBuf) 225 229 { 226 230 dvdnav_free_cache_block(dvdnav, blockBuf); … … 228 232 } 229 233 break; 230 234 case DVDNAV_SPU_CLUT_CHANGE: 235 { 236 memcpy(clut,blockBuf, 16 * sizeof (uint32_t)); 231 237 VERBOSE(VB_PLAYBACK, "DVDNAV_SPU_CLUT_CHANGE happened."); 232 break;233 238 } 239 break; 234 240 case DVDNAV_SPU_STREAM_CHANGE: 235 241 { 236 242 dvdnav_spu_stream_change_event_t* spu = … … 241 247 "physical_pan_scan==%3, logical==%4") 242 248 .arg(spu->physical_wide).arg(spu->physical_letterbox) 243 249 .arg(spu->physical_pan_scan).arg(spu->logical)); 244 250 251 if (spu->physical_letterbox) 252 spuStreamLetterbox = true; 253 else 254 spuStreamLetterbox = false; 255 spuchanged = true; 256 ClearMenuSPUParameters(); 245 257 if (blockBuf != dvdBlockWriteBuf) 246 258 { 247 259 dvdnav_free_cache_block(dvdnav, blockBuf); … … 264 276 } 265 277 break; 266 278 case DVDNAV_NAV_PACKET: 279 { 267 280 lastNav = (dvdnav_t *)blockBuf; 268 break; 281 if (IsInMenu() && NumMenuButtons() > 0 && 282 !buttonSelected) 283 { 284 int32_t button; 285 pci_t *pci = dvdnav_get_current_nav_pci(dvdnav); 286 dvdnav_get_current_highlight(dvdnav, &button); 287 288 if (button > NumMenuButtons() || button < 1) 289 dvdnav_button_select(dvdnav, pci,1); 290 else 291 dvdnav_button_select(dvdnav, pci, button); 292 buttonSelected = true; 293 spuchanged = false; 294 } 295 if (blockBuf != dvdBlockWriteBuf) 296 { 297 dvdnav_free_cache_block(dvdnav, blockBuf); 298 } 299 } 300 break; 269 301 case DVDNAV_HOP_CHANNEL: 270 302 VERBOSE(VB_PLAYBACK, "DVDNAV_HOP_CHANNEL happened."); 271 303 break; … … 303 335 dvdnav_free_cache_block(dvdnav, blockBuf); 304 336 } 305 337 338 if (DVDButtonUpdate(false)) 339 buttonExists = DrawMenuButton(menuSpuPkt,menuBuflength); 306 340 } 307 341 break; 308 342 case DVDNAV_STILL_FRAME: 309 343 { 310 344 dvdnav_still_event_t* still = 311 345 (dvdnav_still_event_t*)(blockBuf); 312 VERBOSE(VB_PLAYBACK, "DVDNAV_STILL_FRAME: " + 313 QString("needs displayed for %1 seconds") 314 .arg(still->length)); 346 usleep(10000); 347 if (skipstillorwait) 348 SkipStillFrame(); 349 else 350 { 351 int elapsedTime = 0; 352 if (still->length < 0xff) 353 { 354 elapsedTime = stillFrameTimer.elapsed() / 1000; // in seconds 355 if (elapsedTime == still->length) 356 SkipStillFrame(); 357 } 358 } 315 359 if (blockBuf != dvdBlockWriteBuf) 316 360 { 317 361 dvdnav_free_cache_block(dvdnav, blockBuf); 318 } 319 320 dvdnav_still_skip(dvdnav); 362 } 321 363 } 322 364 break; 323 365 case DVDNAV_WAIT: 324 VERBOSE(VB_PLAYBACK, "DVDNAV_WAIT recieved clearing it"); 325 dvdnav_wait_skip(dvdnav); 326 break; 366 { 367 if (skipstillorwait) 368 WaitSkip(); 369 else 370 { 371 dvdWaiting = true; 372 usleep(10000); 373 } 374 } 375 break; 327 376 case DVDNAV_STOP: 377 { 328 378 VERBOSE(VB_GENERAL, "DVDNAV_STOP"); 329 379 sz = tot; 330 380 gotStop = true; 331 break; 381 } 382 break; 332 383 default: 333 384 VERBOSE(VB_IMPORTANT, "Got DVD event "<<dvdEvent); 334 385 break; … … 344 395 bool DVDRingBufferPriv::nextTrack(void) 345 396 { 346 397 int newPart = part + 1; 347 if (newPart < maxPart)398 if (newPart < titleParts) 348 399 { 349 400 dvdnav_part_play(dvdnav, title, newPart); 350 401 gotStop = false; … … 374 425 return cellStart / 90000; 375 426 } 376 427 428 void DVDRingBufferPriv::SkipStillFrame(void) 429 { 430 dvdnav_still_skip(dvdnav); 431 cellHasStillFrame = false; 432 } 433 434 void DVDRingBufferPriv::WaitSkip(void) 435 { 436 dvdnav_wait_skip(dvdnav); 437 dvdWaiting = false; 438 } 439 440 void DVDRingBufferPriv::GoToMenu(const QString str) 441 { 442 DVDMenuID_t menuid; 443 if (str.compare("part") == 0) 444 menuid = DVD_MENU_Part; 445 else if (str.compare("menu") == 0) 446 menuid = DVD_MENU_Root; 447 dvdnav_menu_call(dvdnav,menuid); 448 } 449 450 void DVDRingBufferPriv::GoToNextProgram(void) 451 { 452 // if not in the menu feature, okay to skip allow to skip it. 453 // if (!dvdnav_is_domain_vts(dvdnav)) 454 dvdnav_next_pg_search(dvdnav); 455 } 456 457 void DVDRingBufferPriv::GoToPreviousProgram(void) 458 { 459 if (!dvdnav_is_domain_vts(dvdnav)) 460 dvdnav_prev_pg_search(dvdnav); 461 } 462 463 void DVDRingBufferPriv::MoveButtonLeft(void) 464 { 465 if (IsInMenu() && (NumMenuButtons() > 0)) 466 { 467 pci_t *pci = dvdnav_get_current_nav_pci(dvdnav); 468 dvdnav_left_button_select(dvdnav, pci); 469 } 470 } 471 472 void DVDRingBufferPriv::MoveButtonRight(void) 473 { 474 if (IsInMenu() &&(NumMenuButtons() > 0) ) 475 { 476 pci_t *pci = dvdnav_get_current_nav_pci(dvdnav); 477 dvdnav_right_button_select(dvdnav, pci); 478 } 479 } 480 481 void DVDRingBufferPriv::MoveButtonUp(void) 482 { 483 if (IsInMenu() && (NumMenuButtons() > 0)) 484 { 485 pci_t *pci = dvdnav_get_current_nav_pci(dvdnav); 486 dvdnav_upper_button_select(dvdnav, pci); 487 } 488 } 489 490 void DVDRingBufferPriv::MoveButtonDown(void) 491 { 492 if (IsInMenu() && (NumMenuButtons() > 0)) 493 { 494 pci_t *pci = dvdnav_get_current_nav_pci(dvdnav); 495 dvdnav_lower_button_select(dvdnav, pci); 496 } 497 } 498 499 void DVDRingBufferPriv::ActivateButton(void) 500 { 501 if (IsInMenu() && (NumMenuButtons() > 0)) 502 { 503 pci_t *pci = dvdnav_get_current_nav_pci(dvdnav); 504 dvdnav_button_activate(dvdnav, pci); 505 } 506 } 507 508 void DVDRingBufferPriv::GetMenuSPUPkt(uint8_t *buf, int buf_size,long long pts) 509 { 510 if (buf_size < 4) 511 return; 512 513 menuspupts = pts; 514 if (buf_size == menuBuflength) 515 return; 516 else if (spuStreamLetterbox) 517 { 518 if ((buf_size < menuBuflength) && menuBuflength > 0) 519 return; 520 } 521 else 522 { 523 if ((buf_size > menuBuflength) && (menuBuflength > 0)) 524 return; 525 } 526 ClearMenuSPUParameters(); 527 uint8_t *spu_pkt; 528 spu_pkt = (uint8_t*)av_malloc(buf_size); 529 memcpy(spu_pkt, buf, buf_size); 530 menuSpuPkt = spu_pkt; 531 menuBuflength = buf_size; 532 buttonCoords = 0; 533 if (DVDButtonUpdate(false)) 534 buttonExists = DrawMenuButton(menuSpuPkt,menuBuflength); 535 } 536 537 AVSubtitleRect *DVDRingBufferPriv::GetMenuButton(void) 538 { 539 if (MenuButtonChanged() && buttonExists) 540 return dvdMenuButton; 541 542 return NULL; 543 } 544 545 546 bool DVDRingBufferPriv::DrawMenuButton(uint8_t *spu_pkt, int buf_size) 547 { 548 #define GETBE16(p) (((p)[0] << 8) | (p)[1]) 549 550 int cmd_pos, pos,cmd,next_cmd_pos,offset1,offset2; 551 int x1,x2,y1,y2; 552 uint8_t alpha[4],palette[4]; 553 554 x1 = x2 = y1 = y2 = 0; 555 556 if (!spu_pkt) 557 return false; 558 559 for (int i = 0; i < 4 ; i++) 560 { 561 alpha[i] = button_alpha[i]; 562 palette[i] = button_color[i]; 563 } 564 565 if (buf_size < 4) 566 return false; 567 568 cmd_pos = GETBE16(spu_pkt + 2); 569 while ((cmd_pos + 4) < buf_size) 570 { 571 offset1 = -1; 572 offset2 = -1; 573 next_cmd_pos = GETBE16(spu_pkt + cmd_pos + 2); 574 pos = cmd_pos + 4; 575 while (pos < buf_size) 576 { 577 cmd = spu_pkt[pos++]; 578 switch(cmd) 579 { 580 case 0x00: 581 break; 582 case 0x01: 583 break; 584 case 0x02: 585 break; 586 case 0x03: 587 { 588 if ((buf_size - pos) < 2) 589 goto fail; 590 pos +=2; 591 } 592 break; 593 case 0x04: 594 { 595 if ((buf_size - pos) < 2) 596 goto fail; 597 pos +=2; 598 } 599 break; 600 case 0x05: 601 { 602 if ((buf_size - pos) < 6) 603 goto fail; 604 x1 = (spu_pkt[pos] << 4) | (spu_pkt[pos + 1] >> 4); 605 x2 = ((spu_pkt[pos + 1] & 0x0f) << 8) | spu_pkt[pos + 2]; 606 y1 = (spu_pkt[pos + 3] << 4) | (spu_pkt[pos + 4] >> 4); 607 y2 = ((spu_pkt[pos + 4] & 0x0f) << 8) | spu_pkt[pos + 5]; 608 pos +=6; 609 } 610 break; 611 case 0x06: 612 { 613 if ((buf_size - pos) < 4) 614 goto fail; 615 offset1 = GETBE16(spu_pkt + pos); 616 offset2 = GETBE16(spu_pkt + pos + 2); 617 pos +=4; 618 } 619 break; 620 case 0xff: 621 default: 622 goto the_end; 623 } 624 } 625 the_end: 626 if (offset1 >= 0) 627 { 628 int w, h; 629 uint8_t *bitmap; 630 w = x2 - x1 + 1; 631 if (w < 0) 632 w = 0; 633 h = y2 - y1; 634 if (h < 0) 635 h = 0; 636 if (w > 0 && h > 0) 637 { 638 bitmap = (uint8_t*) av_malloc(w * h); 639 dvdMenuButton->rgba_palette = (uint32_t*)av_malloc(4 *4); 640 decode_rle(bitmap, w * 2, w, h / 2, 641 spu_pkt, offset1 * 2, buf_size); 642 decode_rle(bitmap + w, w * 2, w, h / 2, 643 spu_pkt, offset2 * 2, buf_size); 644 guess_palette(dvdMenuButton->rgba_palette, palette, alpha); 645 dvdMenuButton->bitmap = bitmap; 646 if (hl_startx > x1) 647 dvdMenuButton->x = hl_startx - x1; 648 else 649 dvdMenuButton->x = 0; 650 if (hl_starty > y1) 651 dvdMenuButton->y = hl_starty - y1; 652 else 653 dvdMenuButton->y = 0; 654 dvdMenuButton->w = hl_width; 655 dvdMenuButton->h = hl_height; 656 dvdMenuButton->nb_colors = 4; 657 dvdMenuButton->linesize = w; 658 return true; 659 } 660 } 661 if (next_cmd_pos == cmd_pos) 662 break; 663 cmd_pos = next_cmd_pos; 664 } 665 fail: 666 return false; 667 } 668 669 bool DVDRingBufferPriv::DVDButtonUpdate(bool b_mode) 670 { 671 int32_t button; 672 pci_t *pci; 673 dvdnav_highlight_area_t hl; 674 dvdnav_get_current_highlight(dvdnav, &button); 675 pci = dvdnav_get_current_nav_pci(dvdnav); 676 dvdnav_get_highlight_area(pci,button, b_mode, &hl); 677 678 for (int i = 0 ; i < 4 ; i++) 679 { 680 button_alpha[i] = 0xf & (hl.palette >> (4 * i )); 681 button_color[i] = 0xf & (hl.palette >> (16+4 *i )); 682 } 683 684 hl_startx = hl.sx; 685 hl_width = hl.ex - hl.sx; 686 hl_starty = hl.sy; 687 hl_height = hl.ey - hl.sy; 688 689 int total_start_pos = hl.sx + hl.sy; 690 if ( total_start_pos == 0 || total_start_pos > (720 + 576 )) 691 return false; 692 693 return true; 694 } 695 696 void DVDRingBufferPriv::ClearMenuSPUParameters(void) 697 { 698 if (menuBuflength == 0) 699 return; 700 701 VERBOSE(VB_PLAYBACK,LOC + "Clearing Menu SPU Packet" ); 702 if (buttonExists) 703 { 704 av_free(dvdMenuButton->rgba_palette); 705 av_free(dvdMenuButton->bitmap); 706 buttonExists = false; 707 } 708 av_free(menuSpuPkt); 709 menuBuflength = 0; 710 dvdMenuButton->x = 0; 711 dvdMenuButton->y = 0; 712 hl_startx = hl_starty = 0; 713 hl_width = hl_height = 0; 714 buttonCoords = (720+480+100); 715 } 716 717 bool DVDRingBufferPriv::MenuButtonChanged(void) 718 { 719 if (menuBuflength < 4 || buttonCoords > (720+576)) 720 return false; 721 722 int x = hl_startx; 723 int y = hl_starty; 724 if (buttonCoords != (x+y)) 725 { 726 buttonCoords = (x+y); 727 return true; 728 } 729 return false; 730 } 731 732 int DVDRingBufferPriv::NumMenuButtons(void) 733 { 734 pci_t *pci = dvdnav_get_current_nav_pci(dvdnav); 735 int numButtons = pci->hli.hl_gi.btn_ns; 736 if (numButtons > 0 && numButtons < 36) 737 return numButtons; 738 else 739 return 0; 740 } 741 742 void DVDRingBufferPriv::HideMenuButton(bool hide) 743 { 744 if (hide) 745 buttonCoords = (720+480+100); 746 else 747 buttonCoords = 0; 748 } 749 750 uint DVDRingBufferPriv::GetCurrentTime(void) 751 { 752 // Macro to convert Binary Coded Decimal to Decimal 753 // Obtained from VLC Code. 754 #define BCD2D(__x__) (((__x__ & 0xf0) >> 4) * 10 + (__x__ & 0x0f)) 755 756 dsi_t *dvdnavDsi = dvdnav_get_current_nav_dsi(dvdnav); 757 dvd_time_t timeFromCellStart = dvdnavDsi->dsi_gi.c_eltm; 758 uint8_t hours = BCD2D(timeFromCellStart.hour); 759 uint8_t minutes = BCD2D(timeFromCellStart.minute); 760 uint8_t seconds = BCD2D(timeFromCellStart.second); 761 uint currentTime = GetCellStart() + (hours * 3600) + (minutes * 60) + seconds; 762 return currentTime; 763 } 764 765 uint DVDRingBufferPriv::GetAudioLanguage(int id) 766 { 767 int8_t channel = dvdnav_get_audio_logical_stream(dvdnav,id); 768 uint16_t lang = 0; 769 if (channel != -1) 770 lang = dvdnav_audio_stream_to_lang(dvdnav,channel); 771 return ConvertLangCode(lang); 772 } 773 774 uint DVDRingBufferPriv::GetSubtitleLanguage(int id) 775 { 776 int8_t channel = dvdnav_get_spu_logical_stream(dvdnav,id); 777 uint16_t lang = 0; 778 if (channel != -1) 779 lang = dvdnav_spu_stream_to_lang(dvdnav,channel); 780 return ConvertLangCode(lang); 781 } 782 783 uint DVDRingBufferPriv::ConvertLangCode(uint16_t code) 784 { 785 if (code == 0) 786 return 0; 787 788 QChar str2[2]; 789 str2[0] = QChar(code >> 8); 790 str2[1] = QChar(code & 0xff); 791 QString str3 = iso639_str2_to_str3(QString(str2,2)); 792 if (str3) 793 return iso639_str3_to_key(str3); 794 return 0; 795 } 796 797 void DVDRingBufferPriv::guess_palette(uint32_t *rgba_palette,uint8_t *palette, 798 uint8_t *alpha) 799 { 800 int i,r,g,b,y,cr,cb; 801 uint32_t yuv; 802 803 for(i = 0; i < 4; i++) 804 rgba_palette[i] = 0; 805 806 for ( i=0 ; i < 4 ; i++) 807 { 808 yuv = clut[palette[i]]; 809 y = ((yuv >> 16) & 0xff); 810 cr = ((yuv >> 8) & 0xff); 811 cb = ((yuv >> 0) & 0xff); 812 r = int(y + 1.4022 * (cr - 128)); 813 b = int(y + 1.7710 * (cb - 128)); 814 g = int(1.7047 * y - (0.1952 * b) - (0.5647 * r)) ; 815 if (r < 0) r = 0; 816 if (g < 0) g = 0; 817 if (b < 0) b = 0; 818 if (r > 0xff) r = 0xff; 819 if (g > 0xff) g = 0xff; 820 if (b > 0xff) b = 0xff; 821 rgba_palette[i] = ((alpha[i] * 17) << 24) | (r << 16 )| (g << 8) | b; 822 } 823 } 824 825 int DVDRingBufferPriv::decode_rle(uint8_t *bitmap, int linesize, int w, int h, 826 const uint8_t *buf, int nibble_offset, int buf_size) 827 { 828 unsigned int v; 829 int x, y, len, color, nibble_end; 830 uint8_t *d; 831 832 nibble_end = buf_size * 2; 833 x = 0; 834 y = 0; 835 d = bitmap; 836 for(;;) { 837 if (nibble_offset >= nibble_end) 838 return -1; 839 v = get_nibble(buf, nibble_offset++); 840 if (v < 0x4) { 841 v = (v << 4) | get_nibble(buf, nibble_offset++); 842 if (v < 0x10) { 843 v = (v << 4) | get_nibble(buf, nibble_offset++); 844 if (v < 0x040) { 845 v = (v << 4) | get_nibble(buf, nibble_offset++); 846 if (v < 4) { 847 v |= (w - x) << 2; 848 } 849 } 850 } 851 } 852 len = v >> 2; 853 if (len > (w - x)) 854 len = (w - x); 855 color = v & 0x03; 856 memset(d + x, color, len); 857 x += len; 858 if (x >= w) { 859 y++; 860 if (y >= h) 861 break; 862 d += linesize; 863 x = 0; 864 /* byte align */ 865 nibble_offset += (nibble_offset & 1); 866 } 867 } 868 return 0; 869 } 870 871 int DVDRingBufferPriv::get_nibble(const uint8_t *buf, int nibble_offset) 872 { 873 return (buf[nibble_offset >> 1] >> ((1 - (nibble_offset & 1)) << 2)) & 0xf; 874 } 875 377 876 #endif // HAVE_DVDNAV 877 -
libs/libmythtv/RingBuffer.h
7 7 #include <qwaitcondition.h> 8 8 #include <qmutex.h> 9 9 #include <pthread.h> 10 #include "avcodec.h" 10 11 11 12 class RemoteFile; 12 13 class RemoteEncoder; … … 89 90 uint GetTotalTimeOfTitle(void); 90 91 uint GetCellStart(void); 91 92 long long GetTotalReadPosition(void); 93 bool InDVDStillFrame(void); 94 void DVDSkipStillFrame(void); 95 void DVDWaitSkip(void); 96 bool IsDVDWaiting(void); 97 bool IsInDVDMenu(void); 98 void GoToDVDMenu(QString str); 99 void GoToDVDNextProgram(void); 100 void GoToDVDPreviousProgram(void); 101 void MoveDVDButtonLeft(void); 102 void MoveDVDButtonRight(void); 103 void MoveDVDButtonUp(void); 104 void MoveDVDButtonDown(void); 105 void ActivateDVDButton(void); 106 int NumDVDMenuButtons(void); 107 int NumPartsInDVDTitle(void); 108 void GetDVDMenuSPUPkt(uint8_t *buf, int buf_size,long long pts); 109 AVSubtitleRect *GetDVDMenuButton(void); 110 bool IgnoringDVDStillorWait(void); 111 void IgnoreDVDStillOrWait(bool skip); 112 uint GetDVDCurrentTime(void); 113 long long GetDVDCellStartPos(void); 114 void HideDVDMenuButton(bool hide); 115 uint DVDButtonPosX(void); 116 uint DVDButtonPosY(void); 117 uint GetDVDAudioLanguage(int id); 118 uint GetDVDSubtitleLanguage(int id); 119 bool InDVDMenuOrStillFrame(void); 120 long long DVDMenuSpuPts(void); 121 int DVDCellChange(void); 92 122 93 123 long long SetAdjustFilesize(void); 94 124 -
libs/libmythtv/decoderbase.cpp
720 720 return (long long)(desiredFrame * multiplier); 721 721 } 722 722 723 long long DecoderBase::DVDCurrentFrameNumber(void) 724 { 725 if (!ringBuffer->isDVD()) 726 return 0; 727 728 int size = m_positionMap.size() - 1; 729 long long currentpos = ringBuffer->GetReadPosition(); 730 long long multiplier = (currentpos * m_positionMap[size].index); 731 long long currentframe = multiplier / m_positionMap[size].pos; 732 return currentframe; 733 } 734 723 735 /* vim: set expandtab tabstop=4 shiftwidth=4: */ -
libs/libmythtv/avformatdecoder.h
254 254 255 255 // language preferences for auto-selection of streams 256 256 vector<int> languagePreference; 257 258 // DVD 259 int lastdvdtitle; 260 int lastdvdpart; 261 int lastdvdcellchange; 257 262 }; 258 263 259 264 #endif -
libs/libavcodec/parser.c
486 486 ParseContext *pc= &pc1->pc; 487 487 int next; 488 488 489 if( s->flags & PARSER_FLAG_COMPLETE_FRAMES){489 if((s->flags & PARSER_FLAG_COMPLETE_FRAMES) || buf_size == 4){ 490 490 next= buf_size; 491 491 }else{ 492 492 next= ff_mpeg1_find_frame_end(pc, buf, buf_size);