PageRenderTime 55ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 1ms

/mythtv/libs/libmythtv/mythplayer.cpp

http://github.com/MythTV/mythtv
C++ | 5631 lines | 4474 code | 724 blank | 433 comment | 1168 complexity | 7110c5f81af804cb5d2fabab6ecf7a6f MD5 | raw file
Possible License(s): CC-BY-SA-3.0, MIT, GPL-2.0, LGPL-2.0, BSD-3-Clause, GPL-3.0, LGPL-2.1, LGPL-3.0, MPL-2.0-no-copyleft-exception

Large files files are truncated, but you can click here to view the full file

  1. // -*- Mode: c++ -*-
  2. #undef HAVE_AV_CONFIG_H
  3. // C++ headers
  4. #include <algorithm>
  5. #include <cassert>
  6. #include <cmath> // for fabs, ceil, round, signbit
  7. #include <cstdint>
  8. #include <cstdio>
  9. #include <cstdlib>
  10. #include <unistd.h>
  11. using namespace std;
  12. // Qt headers
  13. #include <QCoreApplication>
  14. #include <QDir>
  15. #include <QHash> // for QHash
  16. #include <QMap> // for QMap<>::iterator, etc
  17. #include <QThread> // for QThread, etc
  18. #include <QtCore/qnumeric.h> // for qIsNaN
  19. #include <utility>
  20. // MythTV headers
  21. #include "mthread.h"
  22. #include "mythconfig.h"
  23. #include "mythplayer.h"
  24. #include "DetectLetterbox.h"
  25. #include "audioplayer.h"
  26. #include "interactivescreen.h"
  27. #include "programinfo.h"
  28. #include "mythcorecontext.h"
  29. #include "livetvchain.h"
  30. #include "decoderbase.h"
  31. #include "nuppeldecoder.h"
  32. #include "avformatdecoder.h"
  33. #include "dummydecoder.h"
  34. #include "tv_play.h"
  35. #include "interactivetv.h"
  36. #include "mythsystemevent.h"
  37. #include "mythlogging.h"
  38. #include "mythmiscutil.h"
  39. #include "io/mythinteractivebuffer.h"
  40. #include "audiooutput.h"
  41. #include "cardutil.h"
  42. #include "mythavutil.h"
  43. #include "jitterometer.h"
  44. #include "mythtimer.h"
  45. #include "mythuiactions.h"
  46. #include "io/mythmediabuffer.h"
  47. #include "tv_actions.h"
  48. #include "mythcodeccontext.h"
  49. // MythUI headers
  50. #include <mythmainwindow.h>
  51. extern "C" {
  52. #include "libavcodec/avcodec.h"
  53. }
  54. #include "remoteencoder.h"
  55. #if ! HAVE_ROUND
  56. #define round(x) ((int) ((x) + 0.5))
  57. #endif
  58. static unsigned dbg_ident(const MythPlayer* /*player*/);
  59. #define LOC QString("Player(%1): ").arg(dbg_ident(this),0,36)
  60. #define LOC_DEC QString("Player(%1): ").arg(dbg_ident(m_mp),0,36)
  61. const int MythPlayer::kNightModeBrightenssAdjustment = 10;
  62. const int MythPlayer::kNightModeContrastAdjustment = 10;
  63. // Exact frame seeking, no inaccuracy allowed.
  64. const double MythPlayer::kInaccuracyNone = 0;
  65. // By default, when seeking, snap to a keyframe if the keyframe's
  66. // distance from the target frame is less than 10% of the total seek
  67. // distance.
  68. const double MythPlayer::kInaccuracyDefault = 0.1;
  69. // Allow greater inaccuracy (50%) in the cutlist editor (unless the
  70. // editor seek distance is set to 1 frame or 1 keyframe).
  71. const double MythPlayer::kInaccuracyEditor = 0.5;
  72. // Any negative value means completely inexact, i.e. seek to the
  73. // keyframe that is closest to the target.
  74. const double MythPlayer::kInaccuracyFull = -1.0;
  75. void DecoderThread::run(void)
  76. {
  77. RunProlog();
  78. LOG(VB_PLAYBACK, LOG_INFO, LOC_DEC + "Decoder thread starting.");
  79. if (m_mp)
  80. m_mp->DecoderLoop(m_startPaused);
  81. LOG(VB_PLAYBACK, LOG_INFO, LOC_DEC + "Decoder thread exiting.");
  82. RunEpilog();
  83. }
  84. static int toCaptionType(int type)
  85. {
  86. if (kTrackTypeCC608 == type) return kDisplayCC608;
  87. if (kTrackTypeCC708 == type) return kDisplayCC708;
  88. if (kTrackTypeSubtitle == type) return kDisplayAVSubtitle;
  89. if (kTrackTypeTeletextCaptions == type) return kDisplayTeletextCaptions;
  90. if (kTrackTypeTextSubtitle == type) return kDisplayTextSubtitle;
  91. if (kTrackTypeRawText == type) return kDisplayRawTextSubtitle;
  92. return 0;
  93. }
  94. static int toTrackType(int type)
  95. {
  96. if (kDisplayCC608 == type) return kTrackTypeCC608;
  97. if (kDisplayCC708 == type) return kTrackTypeCC708;
  98. if (kDisplayAVSubtitle == type) return kTrackTypeSubtitle;
  99. if (kDisplayTeletextCaptions == type) return kTrackTypeTeletextCaptions;
  100. if (kDisplayTextSubtitle == type) return kTrackTypeTextSubtitle;
  101. if (kDisplayRawTextSubtitle == type) return kTrackTypeRawText;
  102. return kTrackTypeUnknown;
  103. }
  104. MythMultiLocker::MythMultiLocker(std::initializer_list<QMutex*> Locks)
  105. : m_locks(Locks)
  106. {
  107. Relock();
  108. }
  109. MythMultiLocker::~MythMultiLocker()
  110. {
  111. Unlock();
  112. }
  113. void MythMultiLocker::Unlock(void)
  114. {
  115. for (QVector<QMutex*>::const_reverse_iterator it = m_locks.crbegin(); it != m_locks.crend(); ++it)
  116. if (*it)
  117. (*it)->unlock();
  118. }
  119. void MythMultiLocker::Relock(void)
  120. {
  121. foreach (auto lock, m_locks)
  122. if (lock)
  123. lock->lock();
  124. }
  125. MythPlayer::MythPlayer(PlayerFlags flags)
  126. : m_playerFlags(flags),
  127. m_display((flags & kVideoIsNull) ? nullptr : MythDisplay::AcquireRelease()),
  128. // CC608/708
  129. m_cc608(this), m_cc708(this),
  130. // Audio
  131. m_audio(this, (flags & kAudioMuted) != 0),
  132. // Debugging variables
  133. m_outputJmeter(new Jitterometer(LOC))
  134. {
  135. m_playerThread = QThread::currentThread();
  136. #ifdef Q_OS_ANDROID
  137. m_playerThreadId = gettid();
  138. #endif
  139. // Playback (output) zoom control
  140. m_detectLetterBox = new DetectLetterbox(this);
  141. m_vbiMode = VBIMode::Parse(gCoreContext->GetSetting("VbiFormat"));
  142. m_captionsEnabledbyDefault = gCoreContext->GetBoolSetting("DefaultCCMode");
  143. m_itvEnabled = gCoreContext->GetBoolSetting("EnableMHEG", false);
  144. m_clearSavedPosition = gCoreContext->GetNumSetting("ClearSavedPosition", 1);
  145. m_endExitPrompt = gCoreContext->GetNumSetting("EndOfRecordingExitPrompt");
  146. m_pipDefaultLoc = (PIPLocation)gCoreContext->GetNumSetting("PIPLocation", kPIPTopLeft);
  147. // Get VBI page number
  148. QString mypage = gCoreContext->GetSetting("VBIpageNr", "888");
  149. bool valid = false;
  150. uint tmp = mypage.toInt(&valid, 16);
  151. m_ttPageNum = (valid) ? tmp : m_ttPageNum;
  152. m_cc608.SetTTPageNum(m_ttPageNum);
  153. m_avTimer.start();
  154. }
  155. MythPlayer::~MythPlayer(void)
  156. {
  157. // NB the interactiveTV thread is a client of OSD so must be deleted
  158. // before locking and deleting the OSD
  159. {
  160. QMutexLocker lk0(&m_itvLock);
  161. delete m_interactiveTV;
  162. m_interactiveTV = nullptr;
  163. }
  164. MythMultiLocker locker({&m_osdLock, &m_vidExitLock});
  165. delete m_osd;
  166. m_osd = nullptr;
  167. SetDecoder(nullptr);
  168. delete m_decoderThread;
  169. m_decoderThread = nullptr;
  170. delete m_videoOutput;
  171. m_videoOutput = nullptr;
  172. delete m_outputJmeter;
  173. m_outputJmeter = nullptr;
  174. delete m_detectLetterBox;
  175. m_detectLetterBox = nullptr;
  176. if (m_display)
  177. MythDisplay::AcquireRelease(false);
  178. }
  179. void MythPlayer::SetWatchingRecording(bool mode)
  180. {
  181. m_watchingRecording = mode;
  182. if (m_decoder)
  183. m_decoder->SetWatchingRecording(mode);
  184. }
  185. bool MythPlayer::IsWatchingInprogress(void) const
  186. {
  187. return m_watchingRecording && m_playerCtx->m_recorder &&
  188. m_playerCtx->m_recorder->IsValidRecorder();
  189. }
  190. void MythPlayer::PauseBuffer(void)
  191. {
  192. m_bufferPauseLock.lock();
  193. if (m_playerCtx->m_buffer)
  194. {
  195. m_playerCtx->m_buffer->Pause();
  196. m_playerCtx->m_buffer->WaitForPause();
  197. }
  198. m_bufferPaused = true;
  199. m_bufferPauseLock.unlock();
  200. }
  201. void MythPlayer::UnpauseBuffer(void)
  202. {
  203. m_bufferPauseLock.lock();
  204. if (m_playerCtx->m_buffer)
  205. m_playerCtx->m_buffer->Unpause();
  206. m_bufferPaused = false;
  207. m_bufferPauseLock.unlock();
  208. }
  209. bool MythPlayer::Pause(void)
  210. {
  211. while (!m_pauseLock.tryLock(100))
  212. {
  213. LOG(VB_PLAYBACK, LOG_INFO, LOC + "Waited 100ms to get pause lock.");
  214. DecoderPauseCheck();
  215. }
  216. bool already_paused = m_allPaused;
  217. if (already_paused)
  218. {
  219. m_pauseLock.unlock();
  220. return already_paused;
  221. }
  222. m_nextPlaySpeed = 0.0;
  223. m_nextNormalSpeed = false;
  224. PauseVideo();
  225. m_audio.Pause(true);
  226. PauseDecoder();
  227. PauseBuffer();
  228. if (!m_decoderPaused)
  229. PauseDecoder(); // Retry in case audio only stream
  230. m_allPaused = m_decoderPaused && m_videoPaused && m_bufferPaused;
  231. {
  232. if (FlagIsSet(kVideoIsNull) && m_decoder)
  233. m_decoder->UpdateFramesPlayed();
  234. else if (m_videoOutput && !FlagIsSet(kVideoIsNull))
  235. m_framesPlayed = m_videoOutput->GetFramesPlayed();
  236. }
  237. m_pauseLock.unlock();
  238. return already_paused;
  239. }
  240. bool MythPlayer::Play(float speed, bool normal, bool unpauseaudio)
  241. {
  242. m_pauseLock.lock();
  243. LOG(VB_PLAYBACK, LOG_INFO, LOC +
  244. QString("Play(%1, normal %2, unpause audio %3)")
  245. .arg(speed,5,'f',1).arg(normal).arg(unpauseaudio));
  246. if (m_deleteMap.IsEditing())
  247. {
  248. LOG(VB_GENERAL, LOG_ERR, LOC + "Ignoring Play(), in edit mode.");
  249. m_pauseLock.unlock();
  250. return false;
  251. }
  252. m_rtcBase = 0;
  253. m_priorAudioTimecode = 0;
  254. m_priorVideoTimecode = 0;
  255. m_lastFix = 0.0;
  256. SetEof(kEofStateNone);
  257. UnpauseBuffer();
  258. UnpauseDecoder();
  259. if (unpauseaudio)
  260. m_audio.Pause(false);
  261. UnpauseVideo();
  262. m_allPaused = false;
  263. m_nextPlaySpeed = speed;
  264. m_nextNormalSpeed = normal;
  265. m_pauseLock.unlock();
  266. return true;
  267. }
  268. void MythPlayer::PauseVideo(void)
  269. {
  270. m_videoPauseLock.lock();
  271. m_needNewPauseFrame = true;
  272. m_videoPaused = true;
  273. m_videoPauseLock.unlock();
  274. }
  275. void MythPlayer::UnpauseVideo(void)
  276. {
  277. m_videoPauseLock.lock();
  278. m_videoPaused = false;
  279. m_videoPauseLock.unlock();
  280. }
  281. void MythPlayer::SetPlayingInfo(const ProgramInfo &pginfo)
  282. {
  283. assert(m_playerCtx);
  284. if (!m_playerCtx)
  285. return;
  286. m_playerCtx->LockPlayingInfo(__FILE__, __LINE__);
  287. m_playerCtx->SetPlayingInfo(&pginfo);
  288. m_playerCtx->UnlockPlayingInfo(__FILE__, __LINE__);
  289. }
  290. void MythPlayer::SetPlaying(bool is_playing)
  291. {
  292. QMutexLocker locker(&m_playingLock);
  293. m_playing = is_playing;
  294. m_playingWaitCond.wakeAll();
  295. }
  296. bool MythPlayer::IsPlaying(uint wait_in_msec, bool wait_for) const
  297. {
  298. QMutexLocker locker(&m_playingLock);
  299. if (!wait_in_msec)
  300. return m_playing;
  301. MythTimer t;
  302. t.start();
  303. while ((wait_for != m_playing) && ((uint)t.elapsed() < wait_in_msec))
  304. {
  305. m_playingWaitCond.wait(
  306. &m_playingLock, max(0,(int)wait_in_msec - t.elapsed()));
  307. }
  308. return m_playing;
  309. }
  310. bool MythPlayer::InitVideo(void)
  311. {
  312. if (!m_playerCtx)
  313. return false;
  314. PIPState pipState = m_playerCtx->GetPIPState();
  315. if (!m_decoder)
  316. {
  317. LOG(VB_GENERAL, LOG_ERR, LOC +
  318. "Cannot create a video renderer without a decoder.");
  319. return false;
  320. }
  321. m_videoOutput = MythVideoOutput::Create(
  322. m_decoder->GetCodecDecoderName(),
  323. m_decoder->GetVideoCodecID(),
  324. pipState, m_videoDim, m_videoDispDim, m_videoAspect,
  325. m_parentWidget, m_embedRect,
  326. m_videoFrameRate, (uint)m_playerFlags, m_codecName, m_maxReferenceFrames);
  327. if (!m_videoOutput)
  328. {
  329. LOG(VB_GENERAL, LOG_ERR, LOC +
  330. "Couldn't create VideoOutput instance. Exiting..");
  331. SetErrored(tr("Failed to initialize video output"));
  332. return false;
  333. }
  334. if (m_embedding && pipState == kPIPOff)
  335. m_videoOutput->EmbedInWidget(m_embedRect);
  336. return true;
  337. }
  338. void MythPlayer::ReinitOSD(void)
  339. {
  340. if (m_videoOutput && !FlagIsSet(kVideoIsNull))
  341. {
  342. m_osdLock.lock();
  343. if (!is_current_thread(m_playerThread))
  344. {
  345. m_reinitOsd = true;
  346. m_osdLock.unlock();
  347. return;
  348. }
  349. QRect visible;
  350. QRect total;
  351. float aspect = NAN;
  352. float scaling = NAN;
  353. m_videoOutput->GetOSDBounds(total, visible, aspect,
  354. scaling, 1.0F);
  355. if (m_osd)
  356. {
  357. m_osd->SetPainter(m_videoOutput->GetOSDPainter());
  358. int stretch = lroundf(aspect * 100);
  359. if ((m_osd->Bounds() != visible) ||
  360. (m_osd->GetFontStretch() != stretch))
  361. {
  362. uint old = m_textDisplayMode;
  363. ToggleCaptions(old);
  364. m_osd->Reinit(visible, aspect);
  365. EnableCaptions(old, false);
  366. if (m_deleteMap.IsEditing())
  367. {
  368. bool const changed = m_deleteMap.IsChanged();
  369. m_deleteMap.SetChanged(true);
  370. m_deleteMap.UpdateOSD(m_framesPlayed, m_videoFrameRate, m_osd);
  371. m_deleteMap.SetChanged(changed);
  372. }
  373. }
  374. }
  375. #ifdef USING_MHEG
  376. if (GetInteractiveTV())
  377. {
  378. QMutexLocker locker(&m_itvLock);
  379. m_interactiveTV->Reinit(total, visible, aspect);
  380. m_itvVisible = false;
  381. }
  382. #endif // USING_MHEG
  383. m_reinitOsd = false;
  384. m_osdLock.unlock();
  385. }
  386. }
  387. void MythPlayer::ReinitVideo(bool ForceUpdate)
  388. {
  389. bool aspect_only = false;
  390. {
  391. MythMultiLocker locker({&m_osdLock, &m_vidExitLock});
  392. m_videoOutput->SetVideoFrameRate(static_cast<float>(m_videoFrameRate));
  393. float aspect = (m_forcedVideoAspect > 0) ? m_forcedVideoAspect : m_videoAspect;
  394. if (!m_videoOutput->InputChanged(m_videoDim, m_videoDispDim, aspect,
  395. m_decoder->GetVideoCodecID(), aspect_only, &locker,
  396. m_maxReferenceFrames, ForceUpdate))
  397. {
  398. LOG(VB_GENERAL, LOG_ERR, LOC +
  399. "Failed to Reinitialize Video. Exiting..");
  400. SetErrored(tr("Failed to reinitialize video output"));
  401. return;
  402. }
  403. if (m_osd)
  404. m_osd->SetPainter(m_videoOutput->GetOSDPainter());
  405. ReinitOSD();
  406. }
  407. if (!aspect_only)
  408. ClearAfterSeek();
  409. if (m_textDisplayMode)
  410. EnableSubtitles(true);
  411. AutoVisualise();
  412. }
  413. static inline QString toQString(FrameScanType scan) {
  414. switch (scan) {
  415. case kScan_Ignore: return QString("Ignore Scan");
  416. case kScan_Detect: return QString("Detect Scan");
  417. case kScan_Interlaced: return QString("Interlaced Scan");
  418. case kScan_Progressive: return QString("Progressive Scan");
  419. default: return QString("Unknown Scan");
  420. }
  421. }
  422. FrameScanType MythPlayer::detectInterlace(FrameScanType newScan,
  423. FrameScanType scan,
  424. float fps, int video_height) const
  425. {
  426. QString dbg = QString("detectInterlace(") + toQString(newScan) +
  427. QString(", ") + toQString(scan) + QString(", ") +
  428. QString("%1").arg(static_cast<double>(fps)) + QString(", ") +
  429. QString("%1").arg(video_height) + QString(") ->");
  430. if (kScan_Ignore != newScan || kScan_Detect == scan)
  431. {
  432. // The scanning mode should be decoded from the stream, but if it
  433. // isn't, we have to guess.
  434. scan = kScan_Interlaced; // default to interlaced
  435. if ((720 == video_height) || // ATSC 720p
  436. (fps > 45)) // software deinterlacing
  437. scan = kScan_Progressive;
  438. if (kScan_Detect != newScan)
  439. scan = newScan;
  440. };
  441. LOG(VB_PLAYBACK, LOG_INFO, LOC + dbg +toQString(scan));
  442. return scan;
  443. }
  444. void MythPlayer::SetKeyframeDistance(int keyframedistance)
  445. {
  446. m_keyframeDist = (keyframedistance > 0) ? static_cast<uint>(keyframedistance) : m_keyframeDist;
  447. }
  448. /*! \brief Check whether deinterlacing should be enabled
  449. *
  450. * If the user has triggered an override, this will always be used (until 'detect'
  451. * is requested to turn it off again).
  452. *
  453. * For H264 material, the decoder will signal when the current frame is on a new
  454. * GOP boundary and if the frame's interlaced flag does not match the current
  455. * scan type, the scan type is unlocked. This works well for all test clips
  456. * with mixed progressive/interlaced sequences.
  457. *
  458. * For all other material, we lock the scan type to interlaced when interlaced
  459. * frames are seen - and do not unlock if we see progressive frames. This is
  460. * primarily targetted at MPEG2 material where there is a lot of content where
  461. * the scan type changes frequently - and for no obvious reason. This will result
  462. * in 'false positives' in some cases but there is no clear approach that works
  463. * for all cases. The previous behaviour is preserved (i.e. lock to interlaced
  464. * if interlaced frames are seen) which results in less erratic playback (as the
  465. * deinterlacers are not continually switched on and off) and correctly deinterlaces
  466. * material that is not otherwise flagged correctly.
  467. */
  468. void MythPlayer::AutoDeint(VideoFrame *frame, bool allow_lock)
  469. {
  470. if (!frame)
  471. return;
  472. if ((m_scanOverride > kScan_Detect) && (m_scan != m_scanOverride))
  473. {
  474. LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Locking scan override to '%1'")
  475. .arg(ScanTypeToString(m_scanOverride, true)));
  476. SetScanType(m_scanOverride);
  477. }
  478. // This is currently only signalled for H264 content
  479. if (frame->new_gop)
  480. {
  481. if (m_scanOverride < kScan_Interlaced &&
  482. ((frame->interlaced_frame && !is_interlaced(m_scan)) ||
  483. (!frame->interlaced_frame && is_interlaced(m_scan))))
  484. {
  485. LOG(VB_PLAYBACK, LOG_INFO, LOC + "Unlocking frame scan");
  486. m_scanLocked = false;
  487. }
  488. }
  489. if (m_scanLocked)
  490. return;
  491. if (frame->interlaced_frame)
  492. {
  493. if (m_scanTracker < 0)
  494. {
  495. LOG(VB_PLAYBACK, LOG_INFO, LOC +
  496. QString("Interlaced frame seen after %1 progressive frames")
  497. .arg(abs(m_scanTracker)));
  498. m_scanTracker = 2;
  499. if (allow_lock)
  500. {
  501. LOG(VB_PLAYBACK, LOG_INFO, LOC + "Locking scan to Interlaced.");
  502. SetScanType(kScan_Interlaced);
  503. return;
  504. }
  505. }
  506. m_scanTracker++;
  507. }
  508. else
  509. {
  510. if (m_scanTracker > 0)
  511. {
  512. LOG(VB_PLAYBACK, LOG_INFO, LOC +
  513. QString("Progressive frame seen after %1 interlaced frames")
  514. .arg(m_scanTracker));
  515. m_scanTracker = 0;
  516. }
  517. m_scanTracker--;
  518. }
  519. int min_count = !allow_lock ? 0 : 2;
  520. if (abs(m_scanTracker) <= min_count)
  521. return;
  522. SetScanType((m_scanTracker > min_count) ? kScan_Interlaced : kScan_Progressive);
  523. m_scanLocked = false;
  524. }
  525. FrameScanType MythPlayer::NextScanOverride(void)
  526. {
  527. int next = m_scanOverride + 1;
  528. if (next > kScan_Progressive)
  529. next = kScan_Detect;
  530. return static_cast<FrameScanType>(next);
  531. }
  532. void MythPlayer::SetScanOverride(FrameScanType Scan)
  533. {
  534. if (m_scanOverride == Scan)
  535. return;
  536. m_scanOverride = Scan;
  537. if (m_scanOverride == kScan_Detect)
  538. {
  539. m_scanLocked = false;
  540. m_scanInitialized = false;
  541. LOG(VB_PLAYBACK, LOG_INFO, LOC + "Reverting to auto detection of scan");
  542. }
  543. }
  544. FrameScanType MythPlayer::GetScanType(void) const
  545. {
  546. if (m_scanOverride > kScan_Detect)
  547. return m_scanOverride;
  548. return m_scan;
  549. }
  550. void MythPlayer::SetScanType(FrameScanType Scan)
  551. {
  552. if (!is_current_thread(m_playerThread))
  553. {
  554. m_resetScan = Scan;
  555. return;
  556. }
  557. if (!m_videoOutput)
  558. return;
  559. m_resetScan = kScan_Ignore;
  560. if (m_scanInitialized && m_scan == Scan && m_frameIntervalPrev == m_frameInterval)
  561. return;
  562. m_scanLocked = (Scan != kScan_Detect);
  563. m_scanInitialized = true;
  564. m_frameIntervalPrev = m_frameInterval;
  565. if (is_interlaced(Scan))
  566. {
  567. MythDeintType forced = m_playerCtx->IsPiPOrSecondaryPBP() ? (DEINT_CPU | DEINT_MEDIUM) : DEINT_NONE;
  568. bool normal = m_playSpeed > 0.99F && m_playSpeed < 1.01F && m_normalSpeed;
  569. m_doubleFramerate = CanSupportDoubleRate() && normal && !forced;
  570. m_videoOutput->SetDeinterlacing(true, m_doubleFramerate, forced);
  571. }
  572. else if (kScan_Progressive == Scan)
  573. {
  574. m_doubleFramerate = false;
  575. m_videoOutput->SetDeinterlacing(false, false);
  576. }
  577. m_scan = Scan;
  578. }
  579. void MythPlayer::SetVideoParams(int width, int height, double fps,
  580. float aspect, bool ForceUpdate,
  581. int ReferenceFrames, FrameScanType scan, const QString& codecName)
  582. {
  583. bool paramsChanged = ForceUpdate;
  584. if (width >= 0 && height >= 0)
  585. {
  586. paramsChanged = true;
  587. m_videoDim = m_videoDispDim = QSize(width, height);
  588. m_videoAspect = aspect > 0.0F ? aspect : static_cast<float>(width) / height;
  589. }
  590. if (!qIsNaN(fps) && fps > 0.0 && fps < 121.0)
  591. {
  592. paramsChanged = true;
  593. m_videoFrameRate = fps;
  594. if (m_ffrewSkip != 0 && m_ffrewSkip != 1)
  595. {
  596. UpdateFFRewSkip();
  597. }
  598. else
  599. {
  600. float temp_speed = (m_playSpeed == 0.0F) ?
  601. m_audio.GetStretchFactor() : m_playSpeed;
  602. SetFrameInterval(kScan_Progressive,
  603. 1.0 / (m_videoFrameRate * static_cast<double>(temp_speed)));
  604. }
  605. }
  606. if (!codecName.isEmpty())
  607. {
  608. m_codecName = codecName;
  609. paramsChanged = true;
  610. }
  611. if (ReferenceFrames > 0)
  612. {
  613. m_maxReferenceFrames = ReferenceFrames;
  614. paramsChanged = true;
  615. }
  616. if (!paramsChanged)
  617. return;
  618. if (m_videoOutput)
  619. ReinitVideo(ForceUpdate);
  620. if (IsErrored())
  621. return;
  622. // ensure deinterlacers are correctly reset after a change
  623. m_scanInitialized = false;
  624. SetScanType(detectInterlace(scan, m_scan, static_cast<float>(m_videoFrameRate),
  625. m_videoDispDim.height()));
  626. m_scanLocked = false;
  627. m_scanTracker = (m_scan == kScan_Interlaced) ? 2 : 0;
  628. }
  629. void MythPlayer::SetFrameRate(double fps)
  630. {
  631. m_videoFrameRate = fps;
  632. float temp_speed = (m_playSpeed == 0.0F) ?
  633. m_audio.GetStretchFactor() : m_playSpeed;
  634. SetFrameInterval(kScan_Progressive,
  635. 1.0 / (m_videoFrameRate * static_cast<double>(temp_speed)));
  636. }
  637. void MythPlayer::SetFileLength(int total, int frames)
  638. {
  639. m_totalLength = total;
  640. m_totalFrames = frames;
  641. }
  642. void MythPlayer::SetDuration(int duration)
  643. {
  644. m_totalDuration = duration;
  645. }
  646. void MythPlayer::OpenDummy(void)
  647. {
  648. m_isDummy = true;
  649. if (!m_videoOutput)
  650. {
  651. SetKeyframeDistance(15);
  652. SetVideoParams(720, 576, 25.00, 1.25F, false, 2);
  653. }
  654. m_playerCtx->LockPlayingInfo(__FILE__, __LINE__);
  655. auto *dec = new DummyDecoder(this, *(m_playerCtx->m_playingInfo));
  656. m_playerCtx->UnlockPlayingInfo(__FILE__, __LINE__);
  657. SetDecoder(dec);
  658. }
  659. void MythPlayer::CreateDecoder(char *TestBuffer, int TestSize)
  660. {
  661. if (AvFormatDecoder::CanHandle(TestBuffer, m_playerCtx->m_buffer->GetFilename(), TestSize))
  662. {
  663. SetDecoder(new AvFormatDecoder(this, *m_playerCtx->m_playingInfo, m_playerFlags));
  664. return;
  665. }
  666. if (NuppelDecoder::CanHandle(TestBuffer, TestSize))
  667. SetDecoder(new NuppelDecoder(this, *m_playerCtx->m_playingInfo));
  668. }
  669. int MythPlayer::OpenFile(int Retries)
  670. {
  671. // Sanity check
  672. if (!m_playerCtx || (m_playerCtx && !m_playerCtx->m_buffer))
  673. return -1;
  674. LOG(VB_GENERAL, LOG_INFO, LOC + QString("Opening '%1'")
  675. .arg(m_playerCtx->m_buffer->GetSafeFilename()));
  676. // Disable hardware acceleration for second PBP
  677. if (m_playerCtx && (m_playerCtx->IsPBP() && !m_playerCtx->IsPrimaryPBP()) &&
  678. FlagIsSet(kDecodeAllowGPU))
  679. {
  680. m_playerFlags = static_cast<PlayerFlags>(m_playerFlags - kDecodeAllowGPU);
  681. }
  682. m_isDummy = false;
  683. m_liveTV = m_playerCtx->m_tvchain && m_playerCtx->m_buffer->LiveMode();
  684. // Dummy setup for livetv transtions. Can we get rid of this?
  685. if (m_playerCtx->m_tvchain)
  686. {
  687. int currentposition = m_playerCtx->m_tvchain->GetCurPos();
  688. if (m_playerCtx->m_tvchain->GetInputType(currentposition) == "DUMMY")
  689. {
  690. OpenDummy();
  691. return 0;
  692. }
  693. }
  694. // Start the RingBuffer read ahead thread
  695. m_playerCtx->m_buffer->Start();
  696. /// OSX has a small stack, so we put this buffer on the heap instead.
  697. char *testbuf = new char[kDecoderProbeBufferSize];
  698. UnpauseBuffer();
  699. // delete any pre-existing recorder
  700. SetDecoder(nullptr);
  701. int testreadsize = 2048;
  702. // Test the incoming buffer and create a suitable decoder
  703. MythTimer bigTimer;
  704. bigTimer.start();
  705. int timeout = max((Retries + 1) * 500, 30000);
  706. while (testreadsize <= kDecoderProbeBufferSize)
  707. {
  708. MythTimer peekTimer;
  709. peekTimer.start();
  710. while (m_playerCtx->m_buffer->Peek(testbuf, testreadsize) != testreadsize)
  711. {
  712. // NB need to allow for streams encountering network congestion
  713. if (peekTimer.elapsed() > 30000 || bigTimer.elapsed() > timeout
  714. || m_playerCtx->m_buffer->GetStopReads())
  715. {
  716. LOG(VB_GENERAL, LOG_ERR, LOC +
  717. QString("OpenFile(): Could not read first %1 bytes of '%2'")
  718. .arg(testreadsize)
  719. .arg(m_playerCtx->m_buffer->GetFilename()));
  720. delete[] testbuf;
  721. SetErrored(tr("Could not read first %1 bytes").arg(testreadsize));
  722. return -1;
  723. }
  724. LOG(VB_GENERAL, LOG_WARNING, LOC + "OpenFile() waiting on data");
  725. usleep(50 * 1000);
  726. }
  727. m_playerCtx->LockPlayingInfo(__FILE__, __LINE__);
  728. CreateDecoder(testbuf, testreadsize);
  729. m_playerCtx->UnlockPlayingInfo(__FILE__, __LINE__);
  730. if (m_decoder || (bigTimer.elapsed() > timeout))
  731. break;
  732. testreadsize <<= 1;
  733. }
  734. // Fail
  735. if (!m_decoder)
  736. {
  737. LOG(VB_GENERAL, LOG_ERR, LOC +
  738. QString("Couldn't find an A/V decoder for: '%1'")
  739. .arg(m_playerCtx->m_buffer->GetFilename()));
  740. SetErrored(tr("Could not find an A/V decoder"));
  741. delete[] testbuf;
  742. return -1;
  743. }
  744. if (m_decoder->IsErrored())
  745. {
  746. LOG(VB_GENERAL, LOG_ERR, LOC + "Could not initialize A/V decoder.");
  747. SetDecoder(nullptr);
  748. SetErrored(tr("Could not initialize A/V decoder"));
  749. delete[] testbuf;
  750. return -1;
  751. }
  752. // Pre-init the decoder
  753. m_decoder->SetSeekSnap(0);
  754. m_decoder->SetLiveTVMode(m_liveTV);
  755. m_decoder->SetWatchingRecording(m_watchingRecording);
  756. m_decoder->SetTranscoding(m_transcoding);
  757. // Open the decoder
  758. int result = m_decoder->OpenFile(m_playerCtx->m_buffer, false, testbuf, testreadsize);
  759. delete[] testbuf;
  760. if (result < 0)
  761. {
  762. LOG(VB_GENERAL, LOG_ERR, QString("Couldn't open decoder for: %1")
  763. .arg(m_playerCtx->m_buffer->GetFilename()));
  764. SetErrored(tr("Could not open decoder"));
  765. return -1;
  766. }
  767. // Disable audio if necessary
  768. m_audio.CheckFormat();
  769. // Livetv, recording or in-progress
  770. if (result > 0)
  771. {
  772. m_hasFullPositionMap = true;
  773. m_deleteMap.LoadMap();
  774. m_deleteMap.TrackerReset(0);
  775. }
  776. // Determine the initial bookmark and update it for the cutlist
  777. m_bookmarkSeek = GetBookmark();
  778. m_deleteMap.TrackerReset(m_bookmarkSeek);
  779. m_deleteMap.TrackerWantsToJump(m_bookmarkSeek, m_bookmarkSeek);
  780. if (!gCoreContext->IsDatabaseIgnored() &&
  781. m_playerCtx->m_playingInfo->QueryAutoExpire() == kLiveTVAutoExpire)
  782. {
  783. gCoreContext->SaveSetting("DefaultChanid",
  784. static_cast<int>(m_playerCtx->m_playingInfo->GetChanID()));
  785. QString callsign = m_playerCtx->m_playingInfo->GetChannelSchedulingID();
  786. QString channum = m_playerCtx->m_playingInfo->GetChanNum();
  787. gCoreContext->SaveSetting("DefaultChanKeys", callsign + "[]:[]" + channum);
  788. if (m_playerCtx->m_recorder && m_playerCtx->m_recorder->IsValidRecorder())
  789. {
  790. uint cardid = static_cast<uint>(m_playerCtx->m_recorder->GetRecorderNumber());
  791. CardUtil::SetStartChannel(cardid, channum);
  792. }
  793. }
  794. return IsErrored() ? -1 : 0;
  795. }
  796. void MythPlayer::SetFramesPlayed(uint64_t played)
  797. {
  798. m_framesPlayed = played;
  799. if (m_videoOutput)
  800. m_videoOutput->SetFramesPlayed(played);
  801. }
  802. /** \fn MythPlayer::GetFreeVideoFrames(void)
  803. * \brief Returns the number of frames available for decoding onto.
  804. */
  805. int MythPlayer::GetFreeVideoFrames(void) const
  806. {
  807. if (m_videoOutput)
  808. return m_videoOutput->FreeVideoFrames();
  809. return 0;
  810. }
  811. /// \brief Return a list of frame types that can be rendered directly.
  812. VideoFrameType* MythPlayer::DirectRenderFormats(void)
  813. {
  814. static VideoFrameType s_defaultFormats[] = { FMT_YV12, FMT_NONE };
  815. if (m_videoOutput)
  816. return m_videoOutput->DirectRenderFormats();
  817. return &s_defaultFormats[0];
  818. }
  819. /**
  820. * \brief Removes a frame from the available queue for decoding onto.
  821. *
  822. * This places the frame in the limbo queue, from which frames are
  823. * removed if they are added to another queue. Normally a frame is
  824. * freed from limbo either by a ReleaseNextVideoFrame() or
  825. * DiscardVideoFrame() call; but limboed frames are also freed
  826. * during a seek reset.
  827. */
  828. VideoFrame *MythPlayer::GetNextVideoFrame(void)
  829. {
  830. if (m_videoOutput)
  831. return m_videoOutput->GetNextFreeFrame();
  832. return nullptr;
  833. }
  834. /** \fn MythPlayer::ReleaseNextVideoFrame(VideoFrame*, int64_t)
  835. * \brief Places frame on the queue of frames ready for display.
  836. */
  837. void MythPlayer::ReleaseNextVideoFrame(VideoFrame *buffer,
  838. int64_t timecode,
  839. bool wrap)
  840. {
  841. if (wrap)
  842. WrapTimecode(timecode, TC_VIDEO);
  843. buffer->timecode = timecode;
  844. m_latestVideoTimecode = timecode;
  845. if (m_videoOutput)
  846. m_videoOutput->ReleaseFrame(buffer);
  847. m_detectLetterBox->Detect(buffer);
  848. if (m_allPaused)
  849. CheckAspectRatio(buffer);
  850. }
  851. /** \fn MythPlayer::DiscardVideoFrame(VideoFrame*)
  852. * \brief Places frame in the available frames queue.
  853. */
  854. void MythPlayer::DiscardVideoFrame(VideoFrame *buffer)
  855. {
  856. if (m_videoOutput)
  857. m_videoOutput->DiscardFrame(buffer);
  858. }
  859. /** \fn MythPlayer::DiscardVideoFrames(bool)
  860. * \brief Places frames in the available frames queue.
  861. *
  862. * If called with 'Keyframe' set to false then all frames
  863. * not in use by the decoder are made available for decoding. Otherwise,
  864. * all frames are made available for decoding; this is only safe if
  865. * the next frame is a keyframe.
  866. *
  867. * \param Keyframe if this is true all frames are placed
  868. * in the available queue.
  869. * \param Flushed indicates that the decoder has been flushed AND the decoder
  870. * requires ALL frames to be released (used for VAAPI and VDPAU pause frames)
  871. */
  872. void MythPlayer::DiscardVideoFrames(bool KeyFrame, bool Flushed)
  873. {
  874. if (m_videoOutput)
  875. m_videoOutput->DiscardFrames(KeyFrame, Flushed);
  876. }
  877. bool MythPlayer::HasReachedEof(void) const
  878. {
  879. EofState eof = GetEof();
  880. if (eof != kEofStateNone && !m_allPaused)
  881. return true;
  882. if (GetEditMode())
  883. return false;
  884. if (m_liveTV)
  885. return false;
  886. if (!m_deleteMap.IsEmpty() && m_framesPlayed >= m_deleteMap.GetLastFrame())
  887. return true;
  888. return false;
  889. }
  890. VideoFrame *MythPlayer::GetCurrentFrame(int &w, int &h)
  891. {
  892. w = m_videoDim.width();
  893. h = m_videoDim.height();
  894. VideoFrame *retval = nullptr;
  895. m_vidExitLock.lock();
  896. if (m_videoOutput)
  897. retval = m_videoOutput->GetLastShownFrame();
  898. if (!retval)
  899. m_vidExitLock.unlock();
  900. return retval;
  901. }
  902. void MythPlayer::DeLimboFrame(VideoFrame *frame)
  903. {
  904. if (m_videoOutput)
  905. m_videoOutput->DeLimboFrame(frame);
  906. }
  907. void MythPlayer::ReleaseCurrentFrame(VideoFrame *frame)
  908. {
  909. if (frame)
  910. m_vidExitLock.unlock();
  911. }
  912. void MythPlayer::EmbedInWidget(QRect rect)
  913. {
  914. if (m_videoOutput)
  915. m_videoOutput->EmbedInWidget(rect);
  916. else
  917. {
  918. m_embedRect = rect;
  919. m_embedding = true;
  920. }
  921. }
  922. void MythPlayer::StopEmbedding(void)
  923. {
  924. if (m_videoOutput)
  925. {
  926. m_videoOutput->StopEmbedding();
  927. ReinitOSD();
  928. }
  929. else
  930. {
  931. m_embedRect = QRect();
  932. m_embedding = false;
  933. }
  934. }
  935. void MythPlayer::WindowResized(const QSize &new_size)
  936. {
  937. if (m_videoOutput)
  938. m_videoOutput->WindowResized(new_size);
  939. ReinitOSD();
  940. }
  941. void MythPlayer::EnableTeletext(int page)
  942. {
  943. QMutexLocker locker(&m_osdLock);
  944. if (!m_osd)
  945. return;
  946. m_osd->EnableTeletext(true, page);
  947. m_prevTextDisplayMode = m_textDisplayMode;
  948. m_textDisplayMode = kDisplayTeletextMenu;
  949. }
  950. void MythPlayer::DisableTeletext(void)
  951. {
  952. QMutexLocker locker(&m_osdLock);
  953. if (!m_osd)
  954. return;
  955. m_osd->EnableTeletext(false, 0);
  956. m_textDisplayMode = kDisplayNone;
  957. /* If subtitles are enabled before the teletext menu was displayed,
  958. re-enabled them. */
  959. if (m_prevTextDisplayMode & kDisplayAllCaptions)
  960. EnableCaptions(m_prevTextDisplayMode, false);
  961. }
  962. void MythPlayer::ResetTeletext(void)
  963. {
  964. QMutexLocker locker(&m_osdLock);
  965. if (!m_osd)
  966. return;
  967. m_osd->TeletextReset();
  968. }
  969. /** \fn MythPlayer::SetTeletextPage(uint)
  970. * \brief Set Teletext NUV Caption page
  971. */
  972. void MythPlayer::SetTeletextPage(uint page)
  973. {
  974. m_osdLock.lock();
  975. DisableCaptions(m_textDisplayMode);
  976. m_ttPageNum = page;
  977. m_cc608.SetTTPageNum(m_ttPageNum);
  978. m_textDisplayMode &= ~kDisplayAllCaptions;
  979. m_textDisplayMode |= kDisplayNUVTeletextCaptions;
  980. m_osdLock.unlock();
  981. }
  982. bool MythPlayer::HandleTeletextAction(const QString &action)
  983. {
  984. if (!(m_textDisplayMode & kDisplayTeletextMenu) || !m_osd)
  985. return false;
  986. bool handled = true;
  987. m_osdLock.lock();
  988. if (action == "MENU" || action == ACTION_TOGGLETT || action == "ESCAPE")
  989. DisableTeletext();
  990. else if (m_osd)
  991. handled = m_osd->TeletextAction(action);
  992. m_osdLock.unlock();
  993. return handled;
  994. }
  995. void MythPlayer::ResetCaptions(void)
  996. {
  997. QMutexLocker locker(&m_osdLock);
  998. if (!m_osd)
  999. return;
  1000. if (((m_textDisplayMode & kDisplayAVSubtitle) ||
  1001. (m_textDisplayMode & kDisplayTextSubtitle) ||
  1002. (m_textDisplayMode & kDisplayRawTextSubtitle) ||
  1003. (m_textDisplayMode & kDisplayDVDButton) ||
  1004. (m_textDisplayMode & kDisplayCC608) ||
  1005. (m_textDisplayMode & kDisplayCC708)))
  1006. {
  1007. m_osd->ClearSubtitles();
  1008. }
  1009. else if ((m_textDisplayMode & kDisplayTeletextCaptions) ||
  1010. (m_textDisplayMode & kDisplayNUVTeletextCaptions))
  1011. {
  1012. m_osd->TeletextClear();
  1013. }
  1014. }
  1015. void MythPlayer::DisableCaptions(uint mode, bool osd_msg)
  1016. {
  1017. if (m_textDisplayMode)
  1018. m_prevNonzeroTextDisplayMode = m_textDisplayMode;
  1019. m_textDisplayMode &= ~mode;
  1020. ResetCaptions();
  1021. QMutexLocker locker(&m_osdLock);
  1022. bool newTextDesired = (m_textDisplayMode & kDisplayAllTextCaptions) != 0U;
  1023. // Only turn off textDesired if the Operator requested it.
  1024. if (osd_msg || newTextDesired)
  1025. m_textDesired = newTextDesired;
  1026. QString msg = "";
  1027. if (kDisplayNUVTeletextCaptions & mode)
  1028. msg += tr("TXT CAP");
  1029. if (kDisplayTeletextCaptions & mode)
  1030. {
  1031. if (m_decoder != nullptr)
  1032. msg += m_decoder->GetTrackDesc(kTrackTypeTeletextCaptions,
  1033. GetTrack(kTrackTypeTeletextCaptions));
  1034. DisableTeletext();
  1035. }
  1036. int preserve = m_textDisplayMode & (kDisplayCC608 | kDisplayTextSubtitle |
  1037. kDisplayAVSubtitle | kDisplayCC708 |
  1038. kDisplayRawTextSubtitle);
  1039. if ((kDisplayCC608 & mode) || (kDisplayCC708 & mode) ||
  1040. (kDisplayAVSubtitle & mode) || (kDisplayRawTextSubtitle & mode))
  1041. {
  1042. int type = toTrackType(mode);
  1043. if (m_decoder != nullptr)
  1044. msg += m_decoder->GetTrackDesc(type, GetTrack(type));
  1045. if (m_osd)
  1046. m_osd->EnableSubtitles(preserve);
  1047. }
  1048. if (kDisplayTextSubtitle & mode)
  1049. {
  1050. msg += tr("Text subtitles");
  1051. if (m_osd)
  1052. m_osd->EnableSubtitles(preserve);
  1053. }
  1054. if (!msg.isEmpty() && osd_msg)
  1055. {
  1056. msg += " " + tr("Off");
  1057. SetOSDMessage(msg, kOSDTimeout_Med);
  1058. }
  1059. }
  1060. void MythPlayer::EnableCaptions(uint mode, bool osd_msg)
  1061. {
  1062. QMutexLocker locker(&m_osdLock);
  1063. bool newTextDesired = (mode & kDisplayAllTextCaptions) != 0U;
  1064. // Only turn off textDesired if the Operator requested it.
  1065. if (osd_msg || newTextDesired)
  1066. m_textDesired = newTextDesired;
  1067. QString msg = "";
  1068. if ((kDisplayCC608 & mode) || (kDisplayCC708 & mode) ||
  1069. (kDisplayAVSubtitle & mode) || kDisplayRawTextSubtitle & mode)
  1070. {
  1071. int type = toTrackType(mode);
  1072. if (m_decoder != nullptr)
  1073. msg += m_decoder->GetTrackDesc(type, GetTrack(type));
  1074. if (m_osd)
  1075. m_osd->EnableSubtitles(mode);
  1076. }
  1077. if (kDisplayTextSubtitle & mode)
  1078. {
  1079. if (m_osd)
  1080. m_osd->EnableSubtitles(kDisplayTextSubtitle);
  1081. msg += tr("Text subtitles");
  1082. }
  1083. if (kDisplayNUVTeletextCaptions & mode)
  1084. msg += tr("TXT %1").arg(m_ttPageNum, 3, 16);
  1085. if ((kDisplayTeletextCaptions & mode) && (m_decoder != nullptr))
  1086. {
  1087. msg += m_decoder->GetTrackDesc(kTrackTypeTeletextCaptions,
  1088. GetTrack(kTrackTypeTeletextCaptions));
  1089. int page = m_decoder->GetTrackLanguageIndex(
  1090. kTrackTypeTeletextCaptions,
  1091. GetTrack(kTrackTypeTeletextCaptions));
  1092. EnableTeletext(page);
  1093. m_textDisplayMode = kDisplayTeletextCaptions;
  1094. }
  1095. msg += " " + tr("On");
  1096. LOG(VB_PLAYBACK, LOG_INFO, QString("EnableCaptions(%1) msg: %2")
  1097. .arg(mode).arg(msg));
  1098. m_textDisplayMode = mode;
  1099. if (m_textDisplayMode)
  1100. m_prevNonzeroTextDisplayMode = m_textDisplayMode;
  1101. if (osd_msg)
  1102. SetOSDMessage(msg, kOSDTimeout_Med);
  1103. }
  1104. bool MythPlayer::ToggleCaptions(void)
  1105. {
  1106. SetCaptionsEnabled(!((bool)m_textDisplayMode));
  1107. return m_textDisplayMode != 0U;
  1108. }
  1109. bool MythPlayer::ToggleCaptions(uint type)
  1110. {
  1111. QMutexLocker locker(&m_osdLock);
  1112. uint mode = toCaptionType(type);
  1113. uint origMode = m_textDisplayMode;
  1114. if (m_textDisplayMode)
  1115. DisableCaptions(m_textDisplayMode, (origMode & mode) != 0U);
  1116. if (origMode & mode)
  1117. return m_textDisplayMode != 0U;
  1118. if (mode)
  1119. EnableCaptions(mode);
  1120. return m_textDisplayMode != 0U;
  1121. }
  1122. void MythPlayer::SetCaptionsEnabled(bool enable, bool osd_msg)
  1123. {
  1124. QMutexLocker locker(&m_osdLock);
  1125. m_enableCaptions = m_disableCaptions = false;
  1126. uint origMode = m_textDisplayMode;
  1127. // Only turn off textDesired if the Operator requested it.
  1128. if (osd_msg || enable)
  1129. m_textDesired = enable;
  1130. if (!enable)
  1131. {
  1132. DisableCaptions(origMode, osd_msg);
  1133. return;
  1134. }
  1135. int mode = HasCaptionTrack(m_prevNonzeroTextDisplayMode) ?
  1136. m_prevNonzeroTextDisplayMode : NextCaptionTrack(kDisplayNone);
  1137. if (origMode != (uint)mode)
  1138. {
  1139. DisableCaptions(origMode, false);
  1140. if (kDisplayNone == mode)
  1141. {
  1142. if (osd_msg)
  1143. {
  1144. SetOSDMessage(tr("No captions",
  1145. "CC/Teletext/Subtitle text not available"),
  1146. kOSDTimeout_Med);
  1147. }
  1148. LOG(VB_PLAYBACK, LOG_INFO,
  1149. "No captions available yet to enable.");
  1150. }
  1151. else if (mode)
  1152. {
  1153. EnableCaptions(mode, osd_msg);
  1154. }
  1155. }
  1156. ResetCaptions();
  1157. }
  1158. bool MythPlayer::GetCaptionsEnabled(void) const
  1159. {
  1160. return (kDisplayNUVTeletextCaptions == m_textDisplayMode) ||
  1161. (kDisplayTeletextCaptions == m_textDisplayMode) ||
  1162. (kDisplayAVSubtitle == m_textDisplayMode) ||
  1163. (kDisplayCC608 == m_textDisplayMode) ||
  1164. (kDisplayCC708 == m_textDisplayMode) ||
  1165. (kDisplayTextSubtitle == m_textDisplayMode) ||
  1166. (kDisplayRawTextSubtitle == m_textDisplayMode) ||
  1167. (kDisplayTeletextMenu == m_textDisplayMode);
  1168. }
  1169. QStringList MythPlayer::GetTracks(uint type)
  1170. {
  1171. if (m_decoder)
  1172. return m_decoder->GetTracks(type);
  1173. return QStringList();
  1174. }
  1175. uint MythPlayer::GetTrackCount(uint type)
  1176. {
  1177. if (m_decoder)
  1178. return m_decoder->GetTrackCount(type);
  1179. return 0;
  1180. }
  1181. int MythPlayer::SetTrack(uint type, int trackNo)
  1182. {
  1183. int ret = -1;
  1184. if (!m_decoder)
  1185. return ret;
  1186. ret = m_decoder->SetTrack(type, trackNo);
  1187. if (kTrackTypeAudio == type)
  1188. {
  1189. QString msg = "";
  1190. if (m_decoder)
  1191. SetOSDMessage(m_decoder->GetTrackDesc(type, GetTrack(type)),
  1192. kOSDTimeout_Med);
  1193. return ret;
  1194. }
  1195. uint subtype = toCaptionType(type);
  1196. if (subtype)
  1197. {
  1198. DisableCaptions(m_textDisplayMode, false);
  1199. EnableCaptions(subtype, true);
  1200. if ((kDisplayCC708 == subtype || kDisplayCC608 == subtype) && m_decoder)
  1201. {
  1202. int sid = m_decoder->GetTrackInfo(type, trackNo).m_stream_id;
  1203. if (sid >= 0)
  1204. {
  1205. (kDisplayCC708 == subtype) ? m_cc708.SetCurrentService(sid) :
  1206. m_cc608.SetMode(sid);
  1207. }
  1208. }
  1209. }
  1210. return ret;
  1211. }
  1212. /** \fn MythPlayer::TracksChanged(uint)
  1213. * \brief This tries to re-enable captions/subtitles if the user
  1214. * wants them and one of the captions/subtitles tracks has
  1215. * changed.
  1216. */
  1217. void MythPlayer::TracksChanged(uint trackType)
  1218. {
  1219. if (trackType >= kTrackTypeSubtitle &&
  1220. trackType <= kTrackTypeTeletextCaptions && m_textDesired)
  1221. {
  1222. m_enableCaptions = true;
  1223. }
  1224. }
  1225. void MythPlayer::EnableSubtitles(bool enable)
  1226. {
  1227. if (enable)
  1228. m_enableCaptions = true;
  1229. else
  1230. m_disableCaptions = true;
  1231. }
  1232. void MythPlayer::EnableForcedSubtitles(bool enable)
  1233. {
  1234. if (enable)
  1235. m_enableForcedSubtitles = true;
  1236. else
  1237. m_disableForcedSubtitles = true;
  1238. }
  1239. void MythPlayer::SetAllowForcedSubtitles(bool allow)
  1240. {
  1241. m_allowForcedSubtitles = allow;
  1242. SetOSDMessage(m_allowForcedSubtitles ?
  1243. tr("Forced Subtitles On") :
  1244. tr("Forced Subtitles Off"),
  1245. kOSDTimeout_Med);
  1246. }
  1247. void MythPlayer::DoDisableForcedSubtitles(void)
  1248. {
  1249. m_disableForcedSubtitles = false;
  1250. m_osdLock.lock();
  1251. if (m_osd)
  1252. m_osd->DisableForcedSubtitles();
  1253. m_osdLock.unlock();
  1254. }
  1255. void MythPlayer::DoEnableForcedSubtitles(void)
  1256. {
  1257. m_enableForcedSubtitles = false;
  1258. if (!m_allowForcedSubtitles)
  1259. return;
  1260. m_osdLock.lock();
  1261. if (m_osd)
  1262. m_osd->EnableSubtitles(kDisplayAVSubtitle, true /*forced only*/);
  1263. m_osdLock.unlock();
  1264. }
  1265. int MythPlayer::GetTrack(uint type)
  1266. {
  1267. if (m_decoder)
  1268. return m_decoder->GetTrack(type);
  1269. return -1;
  1270. }
  1271. int MythPlayer::ChangeTrack(uint type, int dir)
  1272. {
  1273. if (!m_decoder)
  1274. return -1;
  1275. int retval = m_decoder->ChangeTrack(type, dir);
  1276. if (retval >= 0)
  1277. {
  1278. SetOSDMessage(m_decoder->GetTrackDesc(type, GetTrack(type)),
  1279. kOSDTimeout_Med);
  1280. return retval;
  1281. }
  1282. return -1;
  1283. }
  1284. void MythPlayer::ChangeCaptionTrack(int dir)
  1285. {
  1286. if (!m_decoder || (dir < 0))
  1287. return;
  1288. if (!((m_textDisplayMode == kDisplayTextSubtitle) ||
  1289. (m_textDisplayMode == kDisplayNUVTeletextCaptions) ||
  1290. (m_textDisplayMode == kDisplayNone)))
  1291. {
  1292. int tracktype = toTrackType(m_textDisplayMode);
  1293. if (GetTrack(tracktype) < m_decoder->NextTrack(tracktype))
  1294. {
  1295. SetTrack(tracktype, m_decoder->NextTrack(tracktype));
  1296. return;
  1297. }
  1298. }
  1299. int nextmode = NextCaptionTrack(m_textDisplayMode);
  1300. if ((nextmode == kDisplayTextSubtitle) ||
  1301. (nextmode == kDisplayNUVTeletextCaptions) ||
  1302. (nextmode == kDisplayNone))
  1303. {
  1304. DisableCaptions(m_textDisplayMode, true);
  1305. if (nextmode != kDisplayNone)
  1306. EnableCaptions(nextmode, true);
  1307. }
  1308. else
  1309. {
  1310. int tracktype = toTrackType(nextmode);
  1311. int tracks = m_decoder->GetTrackCount(tracktype);
  1312. if (tracks)
  1313. {
  1314. DisableCaptions(m_textDisplayMode, true);
  1315. SetTrack(tracktype, 0);
  1316. }
  1317. }
  1318. }
  1319. bool MythPlayer::HasCaptionTrack(int mode)
  1320. {
  1321. if (mode == kDisplayNone)
  1322. return false;
  1323. if (((mode == kDisplayTextSubtitle) && HasTextSubtitles()) ||
  1324. (mode == kDisplayNUVTeletextCaptions))
  1325. {
  1326. return true;
  1327. }
  1328. if (!(mode == kDisplayTextSubtitle) &&
  1329. m_decoder->GetTrackCount(toTrackType(mode)))
  1330. {
  1331. return true;
  1332. }
  1333. return false;
  1334. }
  1335. int MythPlayer::NextCaptionTrack(int mode)
  1336. {
  1337. // Text->TextStream->708->608->AVSubs->Teletext->NUV->None
  1338. // NUV only offerred if PAL
  1339. bool pal = (m_vbiMode == VBIMode::PAL_TT);
  1340. int nextmode = kDisplayNone;
  1341. if (kDisplayTextSubtitle == mode)
  1342. nextmode = kDisplayRawTextSubtitle;
  1343. else if (kDisplayRawTextSubtitle == mode)
  1344. nextmode = kDisplayCC708;
  1345. else if (kDisplayCC708 == mode)
  1346. nextmode = kDisplayCC608;
  1347. else if (kDisplayCC608 == mode)
  1348. nextmode = kDisplayAVSubtitle;
  1349. else if (kDisplayAVSubtitle == mode)
  1350. nextmode = kDisplayTeletextCaptions;
  1351. else if (kDisplayTeletextCaptions == mode)
  1352. nextmode = pal ? kDisplayNUVTeletextCaptions : kDisplayNone;
  1353. else if ((kDisplayNUVTeletextCaptions == mode) && pal)
  1354. nextmode = kDisplayNone;
  1355. else if (kDisplayNone == mode)
  1356. nextmode = kDisplayTextSubtitle;
  1357. if (nextmode == kDisplayNone || HasCaptionTrack(nextmode))
  1358. return nextmode;
  1359. return NextCaptionTrack(nextmode);
  1360. }
  1361. void MythPlayer::SetFrameInterval(FrameScanType scan, double frame_period)
  1362. {
  1363. if (m_decoder)
  1364. m_fpsMultiplier = m_decoder->GetfpsMultiplier();
  1365. m_frameInterval = static_cast<int>(lround(1000000.0 * frame_period) / m_fpsMultiplier);
  1366. LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("SetFrameInterval Interval:%1 Speed:%2 Scan:%3 (Multiplier: %4)")
  1367. .arg(m_frameInterval).arg(static_cast<double>(m_playSpeed)).arg(toQString(scan)).arg(m_fpsMultiplier));
  1368. }
  1369. void MythPlayer::ResetAVSync(void)
  1370. {
  1371. m_avsyncAvg = 0;
  1372. m_prevTc = 0;
  1373. m_rtcBase = 0;
  1374. m_priorAudioTimecode = 0;
  1375. m_priorVideoTimecode = 0;
  1376. m_lastFix = 0.0;
  1377. LOG(VB_PLAYBACK | VB_TIMESTAMP, LOG_INFO, LOC + "A/V sync reset");
  1378. }
  1379. void MythPlayer::InitAVSync(void)
  1380. {
  1381. m_rtcBase = 0;
  1382. m_priorAudioTimecode = 0;
  1383. m_priorVideoTimecode = 0;
  1384. m_lastFix = 0.0;
  1385. if (!FlagIsSet(kVideoIsNull))
  1386. {
  1387. LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Display Refresh Rate: %1 Video Frame Rate: %2")
  1388. .arg(1000000.0 / m_display->GetRefreshInterval(m_frameInterval), 0, 'f', 3)
  1389. .arg(1000000.0 / m_frameInterval, 0, 'f', 3));
  1390. SetFrameInterval(m_scan, 1.0 / (m_videoFrameRate * static_cast<double>(m_playSpeed)));
  1391. // try to get preferential scheduling, but ignore if we fail to.
  1392. myth_nice(-19);
  1393. }
  1394. }
  1395. void MythPlayer::WaitForTime(int64_t framedue)
  1396. {
  1397. int64_t unow = m_avTimer.nsecsElapsed() / 1000;
  1398. int64_t delay = framedue - unow;
  1399. if (delay > 0)
  1400. QThread::usleep(static_cast<unsigned long>(delay));
  1401. }
  1402. /*! \brief Keep PiP frame rate in sync with master framerate
  1403. *
  1404. * This is a simple frame rate tracker. If a frame is not due, then just keep
  1405. * the last displayed frame. Otherwise discard frame(s) that are too old.
  1406. */
  1407. bool MythPlayer::PipSync(void)
  1408. {
  1409. int maxtries = 6;
  1410. int64_t timenow = m_avTimer.nsecsElapsed() / 1000;
  1411. auto playspeed1000 = static_cast<int64_t>(1000.0F / m_playSpeed);
  1412. while (maxtries--)
  1413. {
  1414. if (!m_videoOutput->ValidVideoFrames())
  1415. return false;
  1416. m_videoOutput->StartDisplayingFrame();
  1417. VideoFrame *last = m_videoOutput->GetLastShownFrame();
  1418. if (!last)
  1419. return false;
  1420. m_videoOutput->ProcessFrame(last, nullptr, m_pipPlayers, m_scan);
  1421. int64_t videotimecode = last->timecode & 0x0000ffffffffffff;
  1422. if (videotimecode != last->timecode)
  1423. videotimecode = m_maxTcVal;
  1424. if (videotimecode == 0)
  1425. {
  1426. m_videoOutput->DoneDisplayingFrame(last);
  1427. return true;
  1428. }
  1429. m_maxTcVal = videotimecode;
  1430. if (m_rtcBase == 0)
  1431. m_rtcBase = timenow - (videotimecode * playspeed1000);
  1432. int64_t framedue = m_rtcBase + (videotimecode * playspeed1000);
  1433. if (framedue > timenow)
  1434. return true;
  1435. m_videoOutput->DoneDisplayingFrame(last);
  1436. }
  1437. return true;
  1438. }
  1439. #define AVSYNC_MAX_LATE 10000000
  1440. void MythPlayer::AVSync(VideoFrame *buffer)
  1441. {
  1442. if (m_videoOutput->IsErrored())
  1443. {
  1444. LOG(VB_GENERAL, LOG_ERR, LOC +
  1445. "AVSync: Unknown error in videoOutput, aborting playback.");
  1446. SetErrored(tr("Failed to initialize A/V Sync"));
  1447. return;
  1448. }
  1449. int64_t videotimecode = 0;
  1450. bool dropframe = false;
  1451. bool pause_audio = false;
  1452. int64_t framedue = 0;
  1453. int64_t audio_adjustment = 0;
  1454. int64_t unow = 0;
  1455. int64_t lateness = 0;
  1456. auto playspeed1000 = static_cast<int64_t>(1000.0F / m_playSpeed);
  1457. bool reset = false;
  1458. // controller gain
  1459. static float const s_av_control_gain = 0.4F;
  1460. // time weighted exponential filter coefficient
  1461. static float const s_sync_fc = 0.9F;
  1462. while (framedue == 0)
  1463. {
  1464. if (buffer)
  1465. {
  1466. videotimecode = buffer->timecode & 0x0000ffffffffffff;
  1467. // Detect bogus timecodes from DVD and ignore them.
  1468. if (videotimecode != buffer->timecode)
  1469. videotimecode = m_maxTcVal;
  1470. }
  1471. unow = m_avTimer.nsecsElapsed() / 1000;
  1472. if (!m_normalSpeed || FlagIsSet(kMusicChoice))
  1473. {
  1474. framedue = unow + m_frameInterval;
  1475. break;
  1476. }
  1477. // first time or after a seek - setup of m_rtcBase
  1478. if (m_rtcBase == 0)
  1479. {
  1480. // cater for DVB radio
  1481. if (videotimecode == 0)
  1482. videotimecode = m_audio.GetAudioTime();;
  1483. // cater for data only streams (i.e. MHEG)
  1484. bool dataonly = !m_audio.HasAudioIn() && m_videoDim.isEmpty();
  1485. // On first frame we get nothing, so exit out.…

Large files files are truncated, but you can click here to view the full file