PageRenderTime 69ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 2ms

/client/AnyVODClient/src/media/MediaPresenter.cpp

https://bitbucket.org/chadr123/anyvod
C++ | 8316 lines | 6631 code | 1670 blank | 15 comment | 1083 complexity | 4488bebedeed7fa07cfa0faac6f830f4 MD5 | raw file

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

  1. /*************************************************************************
  2. Copyright (c) 2011-2017, DongRyeol Cha (chadr@dcple.com)
  3. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation, either version 3 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>
  13. *************************************************************************/
  14. #include <QGlobalStatic>
  15. #define GL_NV_geometry_program4
  16. #ifndef Q_OS_WIN
  17. #define GL_GLEXT_PROTOTYPES
  18. #endif
  19. #ifdef Q_OS_WIN
  20. #ifdef _WIN32_WINNT
  21. #undef _WIN32_WINNT
  22. #endif
  23. #define _WIN32_WINNT 0x0501
  24. #endif
  25. #ifndef UNICODE
  26. #define UNICODE
  27. #endif
  28. #ifndef _UNICODE
  29. #define _UNICODE
  30. #endif
  31. #include "MediaPresenter.h"
  32. #include "MediaState.h"
  33. #include "core/Utils.h"
  34. #include "video/Sphere.h"
  35. #include "media/FrameExtractor.h"
  36. #if !defined Q_OS_MOBILE
  37. #include "ui/MainWindow.h"
  38. #endif
  39. extern "C"
  40. {
  41. #include <libavutil/pixdesc.h>
  42. #include <libavutil/time.h>
  43. #include <libavutil/audio_fifo.h>
  44. #include <libavutil/imgutils.h>
  45. #include <libswresample/swresample.h>
  46. #include <libswscale/swscale.h>
  47. #if !defined Q_OS_MOBILE
  48. #include <libavdevice/avdevice.h>
  49. #endif
  50. }
  51. #include <ass/ass.h>
  52. #include <bass/bass_fx.h>
  53. #include <bass/bassmix.h>
  54. #ifndef Q_OS_MAC
  55. #include <omp.h>
  56. #endif
  57. #if !defined Q_OS_MOBILE
  58. #include <MediaInfoDLL/MediaInfoDLL.h>
  59. #endif
  60. #if !defined Q_OS_MOBILE
  61. #include <QApplication>
  62. #include <QDesktopWidget>
  63. #endif
  64. #include <algorithm>
  65. #include <QStringList>
  66. #include <QFileInfo>
  67. #include <qmath.h>
  68. #include <QTextStream>
  69. #include <QMutexLocker>
  70. #include <QRect>
  71. #include <QPainter>
  72. #include <QFile>
  73. #include <QDir>
  74. #include <QOpenGLFramebufferObject>
  75. #include <QTemporaryFile>
  76. #if defined Q_OS_MOBILE
  77. #include <QOpenGLFunctions>
  78. #endif
  79. #include <QDebug>
  80. #ifdef Q_OS_MAC
  81. #include <mach/task_info.h>
  82. #include <mach/task.h>
  83. #include <mach/mach_init.h>
  84. #include <mach/mach_traps.h>
  85. #include <mach/mach_port.h>
  86. #include <mach/vm_map.h>
  87. #include <mach/thread_act.h>
  88. #include <mach/host_info.h>
  89. #include <mach/mach_host.h>
  90. #endif
  91. using namespace std;
  92. #if !defined Q_OS_MOBILE
  93. using namespace MediaInfoDLL;
  94. #endif
  95. #ifdef Q_OS_WIN
  96. extern PFNGLBINDBUFFERARBPROC glBindBufferARB;
  97. extern PFNGLBUFFERDATAARBPROC glBufferDataARB;
  98. extern PFNGLMAPBUFFERARBPROC glMapBufferARB;
  99. extern PFNGLUNMAPBUFFERARBPROC glUnmapBufferARB;
  100. extern PFNGLACTIVETEXTUREPROC glActiveTextureARB;
  101. #endif
  102. const int MediaPresenter::DEFAULT_VIRT_SUBTITLE_RATIO = 10;
  103. const int MediaPresenter::DEFAULT_HORI_SUBTITLE_RATIO = 10;
  104. const int MediaPresenter::OPTION_DESC_TIME = 3000;
  105. const QString MediaPresenter::SUBTITLE_CODEC_FORMAT = "%1 (%2)";
  106. const QPoint MediaPresenter::DEFAULT_3D_SUBTITLE_OFFSET = QPoint(2, 0);
  107. const QPoint MediaPresenter::DEFAULT_VR_SUBTITLE_OFFSET = QPoint(-4, 0);
  108. const qreal MediaPresenter::DEFAULT_VIRTUAL_3D_DEPTH = 0.15;
  109. const AVPixelFormat MediaPresenter::DEFAULT_PIX_FORMAT = AV_PIX_FMT_BGR32;
  110. VirtualFile MediaPresenter::VIRTUAL_FILE;
  111. DTVReader MediaPresenter::DTV_READER;
  112. QDataStream& operator << (QDataStream &out, const MediaPresenter::Range &item)
  113. {
  114. out << item.start;
  115. out << item.end;
  116. out << item.enable;
  117. return out;
  118. }
  119. QDataStream& operator >> (QDataStream &in, MediaPresenter::Range &item)
  120. {
  121. in >> item.start;
  122. in >> item.end;
  123. in >> item.enable;
  124. return in;
  125. }
  126. #ifdef Q_OS_ANDROID
  127. static void ff_log_callback(void*, int level, const char *fmt, va_list vl)
  128. {
  129. if (level <= av_log_get_level())
  130. {
  131. char buf[1024];
  132. vsnprintf(buf, sizeof(buf), fmt, vl);
  133. }
  134. }
  135. #endif
  136. MediaPresenter::MediaPresenter(const int width, const int height) :
  137. QThread(),
  138. m_volume(this->getMaxVolume() / 2),
  139. m_width(width),
  140. m_height(height),
  141. m_state(nullptr),
  142. m_forceExit(false),
  143. m_format(DEFAULT_PIX_FORMAT),
  144. m_showDetail(false),
  145. m_isMute(false),
  146. m_subtitleFontSize(0),
  147. m_showSubtitle(true),
  148. m_showOptionDesc(false),
  149. m_showingOptionDesc(false),
  150. m_subtitleSync(0.0),
  151. m_audioSync(0.0),
  152. m_isRemoteFile(false),
  153. m_isRemoteProtocol(false),
  154. m_fontSize(0),
  155. m_fontOutlineSize(1),
  156. m_subtitleOutlineSize(0),
  157. m_subtitleMaxOutlineSize(0),
  158. m_lastAudioStream(-1),
  159. m_lastSubtitleStream(-1),
  160. m_vertPosition(0),
  161. m_horiPosition(0),
  162. m_texInfo(nullptr),
  163. m_isAudioExt(false),
  164. m_halign(AnyVODEnums::HAM_NONE),
  165. m_valign(AnyVODEnums::VAM_NONE),
  166. m_3dMethod(AnyVODEnums::V3M_NONE),
  167. m_3dSubtitleMethod(AnyVODEnums::S3M_NONE),
  168. m_vrInputSource(AnyVODEnums::VRI_NONE),
  169. m_seekKeyFrame(true),
  170. m_skipOpening(false),
  171. m_skipEnding(false),
  172. m_useSkipRange(false),
  173. m_subtitleOpaque(1.0f),
  174. m_subtitleSize(1.0f),
  175. #if defined Q_OS_MOBILE
  176. m_useHWDecoder(true),
  177. #else
  178. m_useHWDecoder(false),
  179. #endif
  180. m_useSPDIF(false),
  181. m_userSPDIFSampleRate(0),
  182. m_usePBO(false),
  183. m_enableSearchSubtitle(false),
  184. m_enableSearchLyrics(false),
  185. m_autoSaveSearchLyrics(false),
  186. m_showAlbumJacket(true),
  187. #if defined Q_OS_MOBILE
  188. m_useFrameDrop(true),
  189. #else
  190. m_useFrameDrop(false),
  191. #endif
  192. m_useBufferingMode(false),
  193. m_SPIDFEncodingMethod(AnyVODEnums::SEM_NONE),
  194. m_screenRotationDegree(AnyVODEnums::SRD_NONE),
  195. m_use3DFull(false),
  196. m_maxTextureSize(0),
  197. #if defined Q_OS_MOBILE
  198. m_useGPUConvert(true),
  199. #else
  200. m_useGPUConvert(false),
  201. #endif
  202. m_anaglyphFrameBuffer(nullptr),
  203. m_distortionFrameBuffer(nullptr),
  204. m_leftDistortionFrameBuffer(nullptr),
  205. m_rightDistortionFrameBuffer(nullptr),
  206. m_videoThread(this),
  207. m_subtitleThread(this),
  208. m_readThread(this),
  209. m_refreshThread(this),
  210. #if defined Q_OS_MOBILE
  211. m_gl(nullptr),
  212. #endif
  213. m_audioDevice(-1),
  214. m_rotation(0.0),
  215. m_sensorRotation(0.0),
  216. m_optionDescY(0),
  217. m_scheduleRecomputeSubtitleSize(false),
  218. m_useSubtitleCacheMode(false),
  219. m_devicePixelRatio(1.0),
  220. m_captureMode(false),
  221. m_useLowQualityMode(true),
  222. m_controlLocker(QMutex::Recursive),
  223. m_screenOffset(0, 0),
  224. m_useDistortion(true),
  225. m_barrelDistortionCoefficients(0.05f, 0.20f),
  226. m_pincushionDistortionCoefficients(0.075f, -0.005f),
  227. m_distortionLensCenter(0.0f, 0.0f),
  228. m_cameraLock(QMutex::Recursive),
  229. m_distortionAdjustMode(AnyVODEnums::DAM_NONE),
  230. m_virtual3DDepth(DEFAULT_VIRTUAL_3D_DEPTH),
  231. m_subtitleType(ST_NONE),
  232. m_isLive(false),
  233. m_bluetoothHeadsetConnected(false),
  234. m_bluetoothHeadsetSync(0.0)
  235. {
  236. this->reset3DSubtitleOffset();
  237. }
  238. MediaPresenter::~MediaPresenter()
  239. {
  240. this->close();
  241. this->clearFrameBuffers();
  242. }
  243. void MediaPresenter::init()
  244. {
  245. av_log_set_level(AV_LOG_QUIET);
  246. #ifdef Q_OS_ANDROID
  247. av_log_set_callback(ff_log_callback);
  248. #endif
  249. ffurl_append_protocol(DTV_READER.getProtocol());
  250. ffurl_append_protocol(VIRTUAL_FILE.getProtocol());
  251. #if !defined Q_OS_MOBILE
  252. avdevice_register_all();
  253. #endif
  254. avfilter_register_all();
  255. avcodec_register_all();
  256. av_register_all();
  257. avformat_network_init();
  258. Sphere::init();
  259. }
  260. void MediaPresenter::deInit()
  261. {
  262. avformat_network_deinit();
  263. Sphere::deInit();
  264. }
  265. bool MediaPresenter::open(const QString &filePath, const QString &title, const ExtraPlayData &data,
  266. const QString &fontFamily, const int fontSize, const int subtitleOutlineSize,
  267. const QString &audioPath)
  268. {
  269. this->m_filePath = filePath;
  270. this->m_audioPath = audioPath;
  271. this->m_isRemoteFile = Utils::determinRemoteFile(filePath);
  272. this->m_isRemoteProtocol = Utils::determinRemoteProtocol(filePath);
  273. this->m_isLive = filePath.startsWith("hls+");
  274. this->m_realFilePath = Utils::removeFFMpegSeparator(filePath);
  275. this->m_title = title;
  276. if (!data.isValid())
  277. {
  278. #if !defined Q_OS_MOBILE
  279. MediaInfo mi;
  280. bool isDevice = false;
  281. isDevice = Utils::determinDevice(filePath);
  282. if (!isDevice && mi.Open(filePath.toStdWString()) == 1)
  283. {
  284. QString totalTime = QString::fromStdWString(mi.Get(Stream_General, 0, __T("Duration")));
  285. QString totalFrame = QString::fromStdWString(mi.Get(Stream_Video, 0, __T("FrameCount")));
  286. if (totalTime.toDouble() < 0.0)
  287. this->m_playData.duration = 0.0;
  288. else
  289. this->m_playData.duration = totalTime.toDouble() / 1000.0;
  290. this->m_playData.totalFrame = totalFrame.toUInt();
  291. if (this->m_playData.totalFrame <= 0)
  292. {
  293. QString frameRate = QString::fromStdWString(mi.Get(Stream_Video, 0, __T("FrameRate")));
  294. if (frameRate.isEmpty())
  295. frameRate = QString::fromStdWString(mi.Get(Stream_Video, 0, __T("FrameRate_Original")));
  296. if (frameRate.toDouble() < 0)
  297. this->m_playData.totalFrame = 0;
  298. else
  299. this->m_playData.totalFrame = uint32_t(frameRate.toDouble() * this->m_playData.duration);
  300. }
  301. QString rotation = QString::fromStdWString(mi.Get(Stream_Video, 0, __T("Rotation")));
  302. this->m_rotation = rotation.toDouble();
  303. mi.Close();
  304. }
  305. #endif
  306. this->m_playData.userData = data.userData;
  307. }
  308. else
  309. {
  310. this->m_playData = data;
  311. }
  312. this->m_fontFamily = fontFamily;
  313. this->m_fontSize = fontSize * this->m_devicePixelRatio;
  314. this->m_fontOutlineSize = 1 * this->m_devicePixelRatio;
  315. this->m_subtitleMaxOutlineSize = subtitleOutlineSize * this->m_devicePixelRatio;
  316. QFileInfo fileInfo(this->m_realFilePath);
  317. this->m_isAudioExt = Utils::isExtension(fileInfo.suffix(), Utils::MT_AUDIO);
  318. return true;
  319. }
  320. void MediaPresenter::openRemoteSubtitle(const QString &filePath)
  321. {
  322. VIRTUAL_FILE.loadSubtitle(filePath, this);
  323. }
  324. bool MediaPresenter::saveSubtitleAs(const QString &filePath)
  325. {
  326. bool success = false;
  327. double sync = -this->m_subtitleSync;
  328. if (this->m_samiParser.isExist())
  329. success = this->m_samiParser.save(filePath, sync);
  330. else if (this->m_srtParser.isExist())
  331. success = this->m_srtParser.save(filePath, sync);
  332. else if (this->m_lrcParser.isExist())
  333. success = this->m_lrcParser.save(filePath, sync);
  334. else if (this->m_youtubeParser.isExist())
  335. success = this->m_youtubeParser.save(filePath, sync);
  336. return success;
  337. }
  338. bool MediaPresenter::saveSubtitle()
  339. {
  340. return this->saveSubtitleAs(this->m_subtitleFilePath);
  341. }
  342. QString MediaPresenter::getSubtitlePath() const
  343. {
  344. return this->m_subtitleFilePath;
  345. }
  346. bool MediaPresenter::openSubtitle(const QString &filePath, bool isExternal)
  347. {
  348. bool success = false;
  349. QFileInfo info(filePath);
  350. QString ext = info.suffix().toLower();
  351. if (ext == "smi" || ext == "sami")
  352. success = this->openSAMI(filePath) || this->openSRT(filePath);
  353. else if (ext == "ass" || ext == "ssa")
  354. success = this->openASS(filePath);
  355. else if (ext == "srt")
  356. success = this->openSRT(filePath) || this->openSAMI(filePath);
  357. else if (ext == "lrc")
  358. success = this->openLRC(filePath);
  359. if (!success)
  360. success = this->openAVParser(filePath);
  361. if (!success && isExternal)
  362. success = this->openYouTube(filePath);
  363. this->m_subtitleFilePath = filePath;
  364. return success;
  365. }
  366. bool MediaPresenter::openSAMI(const QString &filePath)
  367. {
  368. if (this->m_samiParser.open(filePath))
  369. {
  370. this->m_detail.subtitleCodec = "SAMI Parser";
  371. this->m_subtitleType = ST_SAMI;
  372. return true;
  373. }
  374. return false;
  375. }
  376. bool MediaPresenter::openASS(const QString &filePath)
  377. {
  378. if (this->m_assParser.open(filePath))
  379. {
  380. QFileInfo info(filePath);
  381. if (info.suffix().toLower() == "ass")
  382. this->m_detail.subtitleCodec = "ASS Parser";
  383. else if (info.suffix().toLower() == "ssa")
  384. this->m_detail.subtitleCodec = "SSA Parser";
  385. else
  386. this->m_detail.subtitleCodec = "Unknown Parser";
  387. this->m_assParser.setDefaultFont(this->m_assFontFamily);
  388. this->m_subtitleType = ST_ASS;
  389. return true;
  390. }
  391. return false;
  392. }
  393. bool MediaPresenter::openSRT(const QString &filePath)
  394. {
  395. if (this->m_srtParser.open(filePath))
  396. {
  397. this->m_detail.subtitleCodec = "SRT Parser";
  398. this->m_subtitleType = ST_SRT;
  399. return true;
  400. }
  401. return false;
  402. }
  403. bool MediaPresenter::openYouTube(const QString &id)
  404. {
  405. if (this->m_youtubeParser.open(id))
  406. {
  407. this->m_detail.subtitleCodec = "YouTube Parser";
  408. this->m_subtitleType = ST_YOUTUBE;
  409. return true;
  410. }
  411. return false;
  412. }
  413. bool MediaPresenter::openLRC(const QString &filePath)
  414. {
  415. if (this->m_lrcParser.open(filePath))
  416. {
  417. this->m_detail.subtitleCodec = "LRC Parser";
  418. this->m_subtitleType = ST_LRC;
  419. return true;
  420. }
  421. return false;
  422. }
  423. bool MediaPresenter::openAVParser(const QString &filePath)
  424. {
  425. QString fontPath;
  426. this->m_assParser.getFontPath(&fontPath);
  427. if (this->m_avParser.open(filePath, fontPath, this->m_fontFamily))
  428. {
  429. this->m_avParser.setCurrentIndex(0);
  430. this->m_detail.subtitleCodec = "AV Parser";
  431. this->m_subtitleType = ST_AV;
  432. return true;
  433. }
  434. return false;
  435. }
  436. void MediaPresenter::closeAllExternalSubtitles()
  437. {
  438. this->m_assParser.close();
  439. this->m_samiParser.close();
  440. this->m_srtParser.close();
  441. this->m_youtubeParser.close();
  442. this->m_lrcParser.close();
  443. this->m_avParser.close();
  444. this->m_subtitleFilePath.clear();
  445. this->m_subtitleType = ST_NONE;
  446. this->m_detail.subtitleBitmap = false;
  447. this->m_detail.subtitleValidColor = true;
  448. MediaState *ms = this->m_state;
  449. if (ms && ms->subtitle.stream.stream)
  450. {
  451. const AVCodec *codec = ms->subtitle.stream.ctx->codec;
  452. this->m_detail.subtitleCodec = QString(SUBTITLE_CODEC_FORMAT).arg(QString(codec->name).toUpper()).arg(codec->long_name);
  453. }
  454. }
  455. void MediaPresenter::close()
  456. {
  457. QMutexLocker locker(&this->m_controlLocker);
  458. this->m_forceExit = true;
  459. if (this->isRunning())
  460. this->wait();
  461. this->closeInternal();
  462. this->m_playData = ExtraPlayData();
  463. }
  464. void MediaPresenter::setDevicePixelRatio(double ratio)
  465. {
  466. this->m_devicePixelRatio = ratio;
  467. }
  468. void MediaPresenter::closeInternal()
  469. {
  470. if (this->m_state)
  471. this->m_state->quit = true;
  472. this->m_forceExit = false;
  473. this->closeStream();
  474. this->closeAllExternalSubtitles();
  475. this->callEmptyCallback(false);
  476. this->m_isRemoteFile = false;
  477. this->m_audioStreamInfo.clear();
  478. this->m_subtitleStreamInfo.clear();
  479. this->m_detail = Detail();
  480. this->m_repeatRange = Range();
  481. this->m_GOMSubtitleURL.clear();
  482. this->m_rotation = 0.0;
  483. this->m_optionDescY = 0;
  484. this->m_format = DEFAULT_PIX_FORMAT;
  485. this->m_scheduleRecomputeSubtitleSize = false;
  486. this->setSensorRotation(0.0);
  487. this->scheduleInitTextures();
  488. }
  489. #if defined Q_OS_MOBILE
  490. void MediaPresenter::setGL(QOpenGLFunctions *gl)
  491. {
  492. this->m_gl = gl;
  493. this->m_font.setGL(gl);
  494. this->m_subtitleFont.setGL(gl);
  495. }
  496. #endif
  497. void MediaPresenter::scheduleInitTextures()
  498. {
  499. if (this->m_texInfo)
  500. {
  501. for (int i = 0; i < TEX_COUNT; i++)
  502. {
  503. for (unsigned int j = 0; j < this->m_texInfo[i].textureCount; j++)
  504. this->m_texInfo[i].init[j] = false;
  505. }
  506. }
  507. }
  508. bool MediaPresenter::resetScreen(const int width, const int height, TextureInfo *texInfo, bool inContext)
  509. {
  510. this->m_width = width;
  511. this->m_height = height;
  512. this->m_texInfo = texInfo;
  513. this->m_ortho.setToIdentity();
  514. this->m_ortho.ortho(0.0f, (float)width, (float)height, 0.0f, -1.0f, 1.0f);
  515. this->m_font.setOrtho(this->m_ortho);
  516. this->m_subtitleFont.setOrtho(this->m_ortho);
  517. if (inContext)
  518. {
  519. this->initFrameBufferObject(&this->m_distortionFrameBuffer, width, height);
  520. this->initFrameBufferObject(&this->m_leftDistortionFrameBuffer, width, height);
  521. this->initFrameBufferObject(&this->m_rightDistortionFrameBuffer, width, height);
  522. }
  523. this->scheduleInitTextures();
  524. if (this->m_state && this->m_state->video.stream.stream)
  525. {
  526. this->computeFrameSize();
  527. return true;
  528. }
  529. else
  530. {
  531. return false;
  532. }
  533. }
  534. bool MediaPresenter::play()
  535. {
  536. QMutexLocker locker(&this->m_controlLocker);
  537. bool success = false;
  538. success = this->openStream();
  539. if (success)
  540. {
  541. this->start();
  542. }
  543. else
  544. {
  545. this->m_state->quit = true;
  546. this->closeStream();
  547. }
  548. return success;
  549. }
  550. void MediaPresenter::pause()
  551. {
  552. QMutexLocker locker(&this->m_controlLocker);
  553. MediaState *ms = this->m_state;
  554. if (ms && !ms->pause.pause)
  555. {
  556. ms->pause.pause = true;
  557. ms->pause.startTime = this->getAbsoluteClock();
  558. ms->pause.lastPausedTime = ms->frameTimer.lastPTS;
  559. if (this->m_spdif.isOpened())
  560. this->m_spdif.pause();
  561. else
  562. BASS_Pause();
  563. }
  564. }
  565. void MediaPresenter::resume()
  566. {
  567. QMutexLocker locker(&this->m_controlLocker);
  568. MediaState *ms = this->m_state;
  569. if (ms && ms->pause.pause)
  570. {
  571. ms->pause.driftTime += this->getAbsoluteClock() - ms->pause.startTime;
  572. ms->pause.pause = false;
  573. ms->seek.inc = 0.0;
  574. if (this->m_spdif.isOpened())
  575. this->m_spdif.resume();
  576. else
  577. BASS_Start();
  578. }
  579. if (ms)
  580. ms->willBeEnd = false;
  581. }
  582. void MediaPresenter::stop()
  583. {
  584. this->close();
  585. }
  586. bool MediaPresenter::isPlayUserDataEmpty() const
  587. {
  588. return this->m_playData.userData.isEmpty();
  589. }
  590. QString MediaPresenter::getTitle() const
  591. {
  592. return this->m_title;
  593. }
  594. void MediaPresenter::prevFrame(int count)
  595. {
  596. QMutexLocker locker(&this->m_controlLocker);
  597. MediaState *ms = this->m_state;
  598. if (ms)
  599. {
  600. double clock = ms->pause.pause ? ms->pause.lastPausedTime : ms->frameTimer.lastPTS;
  601. double frameTime = this->getDuration() / this->m_detail.videoTotalFrame;
  602. double target = clock - (count + 1) * frameTime;
  603. if (!ms->pause.pause)
  604. this->pause();
  605. this->seekStream(target, 0.0, AVSEEK_FLAG_ANY | AVSEEK_FLAG_BACKWARD);
  606. }
  607. }
  608. void MediaPresenter::nextFrame(int count)
  609. {
  610. MediaState *ms = this->m_state;
  611. if (ms)
  612. {
  613. ms->seek.requestPauseOnRender = true;
  614. ms->seek.pauseOnRenderCount = count;
  615. this->resume();
  616. }
  617. }
  618. bool MediaPresenter::render(ShaderCompositer &shader)
  619. {
  620. QMutexLocker locker(&this->m_controlLocker);
  621. return this->update(shader);
  622. }
  623. void MediaPresenter::setSubtitleSync(double value)
  624. {
  625. this->m_subtitleSync = value;
  626. }
  627. double MediaPresenter::getSubtitleSync() const
  628. {
  629. return this->m_subtitleSync;
  630. }
  631. void MediaPresenter::audioSync(double value)
  632. {
  633. this->m_audioSync = value;
  634. }
  635. double MediaPresenter::getAudioSync() const
  636. {
  637. return this->m_audioSync;
  638. }
  639. void MediaPresenter::showDetail(bool show)
  640. {
  641. this->m_showDetail = show;
  642. }
  643. bool MediaPresenter::isShowDetail() const
  644. {
  645. return this->m_showDetail;
  646. }
  647. const MediaPresenter::Detail& MediaPresenter::getDetail() const
  648. {
  649. return this->m_detail;
  650. }
  651. void MediaPresenter::getAudioDevices(QStringList *ret) const
  652. {
  653. BASS_DEVICEINFO info;
  654. for (int i = 0; BASS_GetDeviceInfo(i, &info); i++)
  655. ret->append(QString::fromLocal8Bit(info.name));
  656. }
  657. bool MediaPresenter::setAudioDevice(int device)
  658. {
  659. this->m_audioDevice = device;
  660. if (!this->m_spdif.isOpened())
  661. return this->setAudioDeviceAfter();
  662. else
  663. return true;
  664. }
  665. int MediaPresenter::getCurrentAudioDevice() const
  666. {
  667. return this->m_audioDevice;
  668. }
  669. bool MediaPresenter::setAudioDeviceAfter()
  670. {
  671. if (this->resetAudioStream())
  672. return true;
  673. if (this->m_state)
  674. this->m_state->audio.stream.index = this->m_lastAudioStream;
  675. return false;
  676. }
  677. void MediaPresenter::getSPDIFAudioDevices(QStringList *ret)
  678. {
  679. this->m_spdif.getDeviceList(ret);
  680. }
  681. bool MediaPresenter::setSPDIFAudioDevice(int device)
  682. {
  683. if (this->m_spdif.setDevice(device))
  684. {
  685. if (this->m_spdif.isOpened())
  686. return this->setAudioDeviceAfter();
  687. else
  688. return true;
  689. }
  690. return false;
  691. }
  692. int MediaPresenter::getCurrentSPDIFAudioDevice() const
  693. {
  694. return this->m_spdif.getDevice();
  695. }
  696. void MediaPresenter::showSubtitle(bool show)
  697. {
  698. this->m_showSubtitle = show;
  699. }
  700. bool MediaPresenter::isShowSubtitle() const
  701. {
  702. return this->m_showSubtitle;
  703. }
  704. bool MediaPresenter::existFileSubtitle()
  705. {
  706. return this->m_samiParser.isExist() ||
  707. this->m_srtParser.isExist() ||
  708. this->m_youtubeParser.isExist() ||
  709. this->m_lrcParser.isExist();
  710. }
  711. bool MediaPresenter::existSubtitle()
  712. {
  713. return (this->m_state && this->m_state->subtitle.stream.stream) ||
  714. this->m_samiParser.isExist() ||
  715. this->m_assParser.isExist() ||
  716. this->m_srtParser.isExist() ||
  717. this->m_youtubeParser.isExist() ||
  718. this->m_lrcParser.isExist() ||
  719. this->m_avParser.isExist();
  720. }
  721. bool MediaPresenter::existExternalSubtitle()
  722. {
  723. return this->m_samiParser.isExist() ||
  724. this->m_assParser.isExist() ||
  725. this->m_srtParser.isExist() ||
  726. this->m_youtubeParser.isExist() ||
  727. this->m_lrcParser.isExist() ||
  728. this->m_avParser.isExist();
  729. }
  730. double MediaPresenter::getRotation() const
  731. {
  732. return this->m_rotation;
  733. }
  734. void MediaPresenter::setSensorRotation(double rot)
  735. {
  736. QMutexLocker locker(&this->m_cameraLock);
  737. this->m_sensorRotation = rot;
  738. }
  739. double MediaPresenter::getSensorRotation()
  740. {
  741. double rot;
  742. this->m_cameraLock.lock();
  743. rot = this->m_sensorRotation;
  744. this->m_cameraLock.unlock();
  745. return rot;
  746. }
  747. bool MediaPresenter::isAlignable()
  748. {
  749. return (this->m_state && this->m_state->subtitle.stream.stream &&
  750. this->m_state->subtitle.stream.ctx->subtitle_header_size <= 0 &&
  751. this->m_state->subtitle.isBitmap == false) ||
  752. this->m_samiParser.isExist() ||
  753. this->m_youtubeParser.isExist() ||
  754. this->m_srtParser.isExist();
  755. }
  756. AnyVODEnums::HAlignMethod MediaPresenter::getHAlign() const
  757. {
  758. return this->m_halign;
  759. }
  760. void MediaPresenter::setHAlign(AnyVODEnums::HAlignMethod align)
  761. {
  762. this->m_halign = align;
  763. }
  764. AnyVODEnums::VAlignMethod MediaPresenter::getVAlign() const
  765. {
  766. return this->m_valign;
  767. }
  768. void MediaPresenter::setVAlign(AnyVODEnums::VAlignMethod align)
  769. {
  770. this->m_valign = align;
  771. }
  772. bool MediaPresenter::existAudioSubtitle()
  773. {
  774. return this->m_lrcParser.isExist();
  775. }
  776. bool MediaPresenter::existAudioSubtitleGender() const
  777. {
  778. return this->m_lrcParser.isGenderExist();
  779. }
  780. void MediaPresenter::setSubtitleURL(const QString &url)
  781. {
  782. this->m_GOMSubtitleURL = url;
  783. }
  784. void MediaPresenter::getSubtitleURL(QString *ret) const
  785. {
  786. *ret = this->m_GOMSubtitleURL;
  787. }
  788. void MediaPresenter::setASSFontPath(const QString &path)
  789. {
  790. this->m_assParser.setFontPath(path);
  791. }
  792. void MediaPresenter::setASSFontFamily(const QString &family)
  793. {
  794. this->m_assFontFamily = family;
  795. }
  796. void MediaPresenter::getSubtitleClasses(QStringList *classNames)
  797. {
  798. if (this->m_samiParser.isExist())
  799. {
  800. this->m_samiParser.getClassNames(classNames);
  801. }
  802. else if (this->m_youtubeParser.isExist())
  803. {
  804. this->m_youtubeParser.getLanguages(classNames);
  805. }
  806. else if (this->m_avParser.isExist())
  807. {
  808. QVector<SubtitleStreamInfo> infos;
  809. this->m_avParser.getStreamInfos(&infos);
  810. for (int i = 0; i < infos.count(); i++)
  811. classNames->append(infos[i].name);
  812. }
  813. else
  814. {
  815. for (int i = 0; i < this->m_subtitleStreamInfo.count(); i++)
  816. classNames->append(this->m_subtitleStreamInfo[i].name);
  817. }
  818. }
  819. void MediaPresenter::getCurrentSubtitleClass(QString *className)
  820. {
  821. if (this->m_samiParser.isExist())
  822. {
  823. this->m_samiParser.getDefaultClassName(className);
  824. }
  825. else if (this->m_youtubeParser.isExist())
  826. {
  827. this->m_youtubeParser.getDefaultLanguage(className);
  828. }
  829. else if (this->m_avParser.isExist())
  830. {
  831. this->m_avParser.getCurrentName(className);
  832. }
  833. else
  834. {
  835. if (!this->m_state)
  836. return;
  837. QString name;
  838. for (int i = 0; i < this->m_subtitleStreamInfo.count(); i++)
  839. {
  840. if (this->m_subtitleStreamInfo[i].index == this->m_state->subtitle.stream.index)
  841. {
  842. name = this->m_subtitleStreamInfo[i].name;
  843. break;
  844. }
  845. }
  846. *className = name;
  847. }
  848. }
  849. bool MediaPresenter::setCurrentSubtitleClass(const QString &className)
  850. {
  851. if (this->m_samiParser.isExist())
  852. {
  853. this->m_samiParser.setDefaultClassName(className);
  854. return true;
  855. }
  856. else if (this->m_youtubeParser.isExist())
  857. {
  858. this->m_youtubeParser.setDefaultLanguage(className);
  859. return true;
  860. }
  861. else if (this->m_avParser.isExist())
  862. {
  863. QVector<SubtitleStreamInfo> infos;
  864. unsigned int index = 0;
  865. this->m_avParser.getStreamInfos(&infos);
  866. for (int i = 0; i < infos.count(); i++)
  867. {
  868. if (infos[i].name == className)
  869. {
  870. index = infos[i].index;
  871. break;
  872. }
  873. }
  874. this->m_avParser.setCurrentIndex(index);
  875. return true;
  876. }
  877. else
  878. {
  879. if (!this->m_state)
  880. return false;
  881. int index = -1;
  882. for (int i = 0; i < this->m_subtitleStreamInfo.count(); i++)
  883. {
  884. if (this->m_subtitleStreamInfo[i].name == className)
  885. {
  886. index = this->m_subtitleStreamInfo[i].index;
  887. break;
  888. }
  889. }
  890. Subtitle &subtitle = this->m_state->subtitle;
  891. subtitle.stream.queue.flush();
  892. subtitle.requestReleaseQueue = true;
  893. return this->changeStream(index, subtitle.stream.index, false, &this->m_lastSubtitleStream, &subtitle.threadQuit);
  894. }
  895. }
  896. void MediaPresenter::resetSubtitlePosition()
  897. {
  898. this->m_vertPosition = 0;
  899. this->m_horiPosition = 0;
  900. }
  901. void MediaPresenter::setVerticalSubtitlePosition(int pos)
  902. {
  903. this->m_vertPosition += pos;
  904. }
  905. void MediaPresenter::setHorizontalSubtitlePosition(int pos)
  906. {
  907. this->m_horiPosition += pos;
  908. }
  909. void MediaPresenter::setVerticalSubtitleAbsolutePosition(int pos)
  910. {
  911. this->m_vertPosition = pos;
  912. }
  913. void MediaPresenter::setHorizontalSubtitleAbsolutePosition(int pos)
  914. {
  915. this->m_horiPosition = pos;
  916. }
  917. int MediaPresenter::getVerticalSubtitlePosition() const
  918. {
  919. return this->m_vertPosition;
  920. }
  921. int MediaPresenter::getHorizontalSubtitlePosition() const
  922. {
  923. return this->m_horiPosition;
  924. }
  925. void MediaPresenter::reset3DSubtitleOffset()
  926. {
  927. if (this->m_vrInputSource == AnyVODEnums::VRI_NONE)
  928. this->m_3dSubtitleOffset = DEFAULT_3D_SUBTITLE_OFFSET;
  929. else
  930. this->m_3dSubtitleOffset = DEFAULT_VR_SUBTITLE_OFFSET;
  931. }
  932. void MediaPresenter::setVertical3DSubtitleOffset(int pos)
  933. {
  934. this->m_3dSubtitleOffset.ry() += pos;
  935. }
  936. void MediaPresenter::setHorizontal3DSubtitleOffset(int pos)
  937. {
  938. this->m_3dSubtitleOffset.rx() += pos;
  939. }
  940. void MediaPresenter::setVertical3DSubtitleAbsoluteOffset(int pos)
  941. {
  942. this->m_3dSubtitleOffset.ry() = pos;
  943. }
  944. void MediaPresenter::setHorizontal3DSubtitleAbsoluteOffset(int pos)
  945. {
  946. this->m_3dSubtitleOffset.rx() = pos;
  947. }
  948. int MediaPresenter::getVertical3DSubtitleOffset() const
  949. {
  950. return this->m_3dSubtitleOffset.y();
  951. }
  952. int MediaPresenter::getHorizontal3DSubtitleOffset() const
  953. {
  954. return this->m_3dSubtitleOffset.x();
  955. }
  956. void MediaPresenter::resetVirtual3DDepth()
  957. {
  958. this->m_virtual3DDepth = DEFAULT_VIRTUAL_3D_DEPTH;
  959. }
  960. void MediaPresenter::setVirtual3DDepth(qreal depth)
  961. {
  962. this->m_virtual3DDepth = depth;
  963. }
  964. qreal MediaPresenter::getVirtual3DDepth() const
  965. {
  966. return this->m_virtual3DDepth;
  967. }
  968. void MediaPresenter::setRepeatStart(double start)
  969. {
  970. this->m_repeatRange.start = start;
  971. }
  972. void MediaPresenter::setRepeatEnd(double end)
  973. {
  974. this->m_repeatRange.end = end;
  975. }
  976. void MediaPresenter::setRepeatEnable(bool enable)
  977. {
  978. this->m_repeatRange.enable = enable;
  979. }
  980. bool MediaPresenter::getRepeatEnable() const
  981. {
  982. return this->m_repeatRange.enable;
  983. }
  984. double MediaPresenter::getRepeatStart() const
  985. {
  986. return this->m_repeatRange.start;
  987. }
  988. double MediaPresenter::getRepeatEnd() const
  989. {
  990. return this->m_repeatRange.end;
  991. }
  992. void MediaPresenter::setCaptureMode(bool capture)
  993. {
  994. this->m_captureMode = capture;
  995. }
  996. bool MediaPresenter::getCaptureMode() const
  997. {
  998. return this->m_captureMode;
  999. }
  1000. void MediaPresenter::setSeekKeyFrame(bool keyFrame)
  1001. {
  1002. this->m_seekKeyFrame = keyFrame;
  1003. }
  1004. bool MediaPresenter::isSeekKeyFrame() const
  1005. {
  1006. return this->m_seekKeyFrame;
  1007. }
  1008. void MediaPresenter::set3DMethod(AnyVODEnums::Video3DMethod method)
  1009. {
  1010. this->m_3dMethod = method;
  1011. this->computeFrameSize();
  1012. }
  1013. AnyVODEnums::Video3DMethod MediaPresenter::get3DMethod() const
  1014. {
  1015. return this->m_3dMethod;
  1016. }
  1017. void MediaPresenter::setSubtitle3DMethod(AnyVODEnums::Subtitle3DMethod method)
  1018. {
  1019. this->m_3dSubtitleMethod = method;
  1020. }
  1021. AnyVODEnums::Subtitle3DMethod MediaPresenter::getSubtitle3DMethod() const
  1022. {
  1023. return this->m_3dSubtitleMethod;
  1024. }
  1025. void MediaPresenter::setVRInputSource(AnyVODEnums::VRInputSource source)
  1026. {
  1027. this->m_vrInputSource = source;
  1028. this->computeFrameSize();
  1029. this->reset3DSubtitleOffset();
  1030. }
  1031. AnyVODEnums::VRInputSource MediaPresenter::getVRInputSource() const
  1032. {
  1033. return this->m_vrInputSource;
  1034. }
  1035. void MediaPresenter::setDistortionAdjustMode(AnyVODEnums::DistortionAdjustMode mode)
  1036. {
  1037. this->m_distortionAdjustMode = mode;
  1038. }
  1039. AnyVODEnums::DistortionAdjustMode MediaPresenter::getDistortionAdjustMode() const
  1040. {
  1041. return this->m_distortionAdjustMode;
  1042. }
  1043. void MediaPresenter::setSkipRanges(const QVector<Range> &ranges)
  1044. {
  1045. this->m_skipRanges = ranges;
  1046. }
  1047. void MediaPresenter::getSkipRanges(QVector<Range> *ret) const
  1048. {
  1049. *ret = this->m_skipRanges;
  1050. }
  1051. void MediaPresenter::setSkipOpening(bool skip)
  1052. {
  1053. this->m_skipOpening = skip;
  1054. }
  1055. bool MediaPresenter::getSkipOpening() const
  1056. {
  1057. return this->m_skipOpening;
  1058. }
  1059. void MediaPresenter::setSkipEnding(bool skip)
  1060. {
  1061. this->m_skipEnding = skip;
  1062. }
  1063. bool MediaPresenter::getSkipEnding() const
  1064. {
  1065. return this->m_skipEnding;
  1066. }
  1067. void MediaPresenter::setUseSkipRange(bool use)
  1068. {
  1069. this->m_useSkipRange = use;
  1070. }
  1071. bool MediaPresenter::getUseSkipRange() const
  1072. {
  1073. return this->m_useSkipRange;
  1074. }
  1075. double MediaPresenter::getOpeningSkipTime() const
  1076. {
  1077. for (int i = 0; i < this->m_skipRanges.count(); i++)
  1078. {
  1079. if (this->m_skipRanges[i].start < 0.0)
  1080. return this->m_skipRanges[i].end;
  1081. }
  1082. return 0.0;
  1083. }
  1084. double MediaPresenter::getEndingSkipTime() const
  1085. {
  1086. for (int i = 0; i < this->m_skipRanges.count(); i++)
  1087. {
  1088. if (this->m_skipRanges[i].end < 0.0)
  1089. return this->m_skipRanges[i].start;
  1090. }
  1091. return 0.0;
  1092. }
  1093. void MediaPresenter::useNormalizer(bool use)
  1094. {
  1095. if (this->m_spdif.isOpened())
  1096. return;
  1097. this->m_audioEffect.useNormalizer = use;
  1098. if (this->m_state && this->m_state->audio.handle)
  1099. {
  1100. if (use)
  1101. this->initNormalizer();
  1102. else
  1103. this->closeNormalizer();
  1104. }
  1105. }
  1106. bool MediaPresenter::isUsingNormalizer() const
  1107. {
  1108. return this->m_audioEffect.useNormalizer;
  1109. }
  1110. void MediaPresenter::useEqualizer(bool use)
  1111. {
  1112. if (this->m_spdif.isOpened())
  1113. return;
  1114. this->m_audioEffect.useEqualizer = use;
  1115. if (this->m_state && this->m_state->audio.handle)
  1116. {
  1117. if (use)
  1118. this->initEqualizer();
  1119. else
  1120. this->closeEqualizer();
  1121. }
  1122. }
  1123. bool MediaPresenter::isUsingEqualizer() const
  1124. {
  1125. return this->m_audioEffect.useEqualizer;
  1126. }
  1127. void MediaPresenter::useLowerVoice(bool use)
  1128. {
  1129. if (this->m_spdif.isOpened())
  1130. return;
  1131. this->m_audioEffect.useLowerVoice = use;
  1132. if (this->m_state && this->m_state->audio.handle)
  1133. {
  1134. if (use)
  1135. this->initLowerVoice();
  1136. else
  1137. this->closeLowerVoice();
  1138. }
  1139. }
  1140. bool MediaPresenter::isUsingLowerVoice() const
  1141. {
  1142. return this->m_audioEffect.useLowerVoice;
  1143. }
  1144. void MediaPresenter::useHigherVoice(bool use)
  1145. {
  1146. if (this->m_spdif.isOpened())
  1147. return;
  1148. this->m_audioEffect.useHigherVoice = use;
  1149. if (this->m_state && this->m_state->audio.handle)
  1150. {
  1151. if (use)
  1152. this->initHigherVoice();
  1153. else
  1154. this->closeHigherVoice();
  1155. }
  1156. }
  1157. bool MediaPresenter::isUsingHigherVoice() const
  1158. {
  1159. return this->m_audioEffect.useHigherVoice;
  1160. }
  1161. void MediaPresenter::useLowerMusic(bool use)
  1162. {
  1163. if (this->m_spdif.isOpened())
  1164. return;
  1165. this->m_audioEffect.useLowerMusic = use;
  1166. if (this->m_state && this->m_state->audio.handle)
  1167. {
  1168. if (use)
  1169. this->initLowerMusic();
  1170. else
  1171. this->closeLowerMusic();
  1172. }
  1173. }
  1174. bool MediaPresenter::isUsingLowerMusic() const
  1175. {
  1176. return this->m_audioEffect.useLowerMusic;
  1177. }
  1178. void MediaPresenter::setSubtitleOpaque(float opaque)
  1179. {
  1180. this->m_subtitleOpaque = opaque;
  1181. }
  1182. float MediaPresenter::getSubtitleOpaque() const
  1183. {
  1184. return this->m_subtitleOpaque;
  1185. }
  1186. void MediaPresenter::setSubtitleSize(float size)
  1187. {
  1188. this->m_subtitleSize = size;
  1189. if (!this->m_scheduleRecomputeSubtitleSize)
  1190. this->computeSubtitleSize();
  1191. }
  1192. float MediaPresenter::getSubtitleSize() const
  1193. {
  1194. return this->m_subtitleSize;
  1195. }
  1196. void MediaPresenter::setScheduleRecomputeSubtitleSize()
  1197. {
  1198. this->m_scheduleRecomputeSubtitleSize = true;
  1199. }
  1200. bool MediaPresenter::setPreAmp(float dB)
  1201. {
  1202. this->m_audioEffect.preampValue = dB;
  1203. if (this->m_audioEffect.preamp && this->m_state && this->m_state->audio.handle)
  1204. {
  1205. BASS_BFX_VOLUME vol;
  1206. vol.lChannel = 0;
  1207. vol.fVolume = BASS_BFX_dB2Linear(dB);
  1208. if (BASS_FXSetParameters(this->m_audioEffect.preamp, &vol) == TRUE)
  1209. return true;
  1210. }
  1211. else
  1212. {
  1213. return true;
  1214. }
  1215. return false;
  1216. }
  1217. float MediaPresenter::getPreAmp() const
  1218. {
  1219. return this->m_audioEffect.preampValue;
  1220. }
  1221. bool MediaPresenter::setEqualizerGain(int band, float gain)
  1222. {
  1223. QVector<Equalizer> &values = this->m_audioEffect.equalizerValues;
  1224. if (band >= 0 && band < values.count())
  1225. {
  1226. Equalizer &eq = values[band];
  1227. eq.gain = gain;
  1228. if (this->m_audioEffect.eqaulizer && this->m_state && this->m_state->audio.handle)
  1229. {
  1230. BASS_BFX_PEAKEQ eqValue;
  1231. eqValue.fBandwidth = eq.octave;
  1232. eqValue.fCenter = eq.center;
  1233. eqValue.fGain = eq.gain;
  1234. eqValue.lBand = band;
  1235. eqValue.lChannel = BASS_BFX_CHANALL;
  1236. if (BASS_FXSetParameters(this->m_audioEffect.eqaulizer, &eqValue) == TRUE)
  1237. return true;
  1238. }
  1239. else
  1240. {
  1241. return true;
  1242. }
  1243. }
  1244. return false;
  1245. }
  1246. float MediaPresenter::getEqualizerGain(int band) const
  1247. {
  1248. const QVector<Equalizer> &values = this->m_audioEffect.equalizerValues;
  1249. if (band >= 0 && band < values.count())
  1250. return values[band].gain;
  1251. return 0.0f;
  1252. }
  1253. int MediaPresenter::getBandCount() const
  1254. {
  1255. return this->m_audioEffect.equalizerValues.count();
  1256. }
  1257. bool MediaPresenter::isEnableSearchSubtitle() const
  1258. {
  1259. return this->m_enableSearchSubtitle;
  1260. }
  1261. bool MediaPresenter::isEnableSearchLyrics() const
  1262. {
  1263. return this->m_enableSearchLyrics;
  1264. }
  1265. void MediaPresenter::enableSearchSubtitle(bool enable)
  1266. {
  1267. this->m_enableSearchSubtitle = enable;
  1268. }
  1269. void MediaPresenter::enableSearchLyrics(bool enable)
  1270. {
  1271. this->m_enableSearchLyrics = enable;
  1272. }
  1273. void MediaPresenter::enableAutoSaveSearchLyrics(bool enable)
  1274. {
  1275. this->m_autoSaveSearchLyrics = enable;
  1276. }
  1277. bool MediaPresenter::isAutoSaveSearchLyrics() const
  1278. {
  1279. return this->m_autoSaveSearchLyrics;
  1280. }
  1281. void MediaPresenter::showAlbumJacket(bool show)
  1282. {
  1283. this->m_showAlbumJacket = show;
  1284. }
  1285. bool MediaPresenter::isShowAlbumJacket() const
  1286. {
  1287. return this->m_showAlbumJacket;
  1288. }
  1289. void MediaPresenter::useFrameDrop(bool enable)
  1290. {
  1291. this->m_useFrameDrop = enable;
  1292. }
  1293. bool MediaPresenter::isUseFrameDrop() const
  1294. {
  1295. return this->m_useFrameDrop;
  1296. }
  1297. void MediaPresenter::useBufferingMode(bool enable)
  1298. {
  1299. this->m_useBufferingMode = enable;
  1300. }
  1301. bool MediaPresenter::isUseBufferingMode() const
  1302. {
  1303. return this->m_useBufferingMode;
  1304. }
  1305. void MediaPresenter::useGPUConvert(bool use)
  1306. {
  1307. bool prev = this->m_useGPUConvert;
  1308. this->m_useGPUConvert = use;
  1309. if (prev != use)
  1310. {
  1311. if (this->isEnabledVideo())
  1312. this->recover(this->getMasterClock());
  1313. }
  1314. }
  1315. bool MediaPresenter::isUseGPUConvert() const
  1316. {
  1317. return this->m_useGPUConvert;
  1318. }
  1319. void MediaPresenter::seek(double time, bool any)
  1320. {
  1321. QMutexLocker locker(&this->m_controlLocker);
  1322. if (this->m_state)
  1323. {
  1324. double incr = time - this->getCurrentPosition();
  1325. int flag = (this->m_seekKeyFrame && !any) ? 0 : AVSEEK_FLAG_BACKWARD | AVSEEK_FLAG_ANY;
  1326. this->seekStream(time, incr, flag);
  1327. }
  1328. }
  1329. uint8_t MediaPresenter::getMaxVolume() const
  1330. {
  1331. return 255;
  1332. }
  1333. void MediaPresenter::mute(bool mute)
  1334. {
  1335. if (mute)
  1336. this->volumeInternal(0);
  1337. else
  1338. this->volume(this->m_volume);
  1339. this->m_isMute = mute;
  1340. }
  1341. void MediaPresenter::volumeInternal(uint8_t volume)
  1342. {
  1343. if (this->m_state && !this->m_spdif.isOpened())
  1344. BASS_ChannelSetAttribute(this->m_state->audio.handle, BASS_ATTRIB_VOL, (float)volume / (float)this->getMaxVolume());
  1345. }
  1346. void MediaPresenter::volume(uint8_t volume)
  1347. {
  1348. if (volume > this->getMaxVolume())
  1349. this->m_volume = this->getMaxVolume();
  1350. else
  1351. this->m_volume = volume;
  1352. this->volumeInternal(this->m_volume);
  1353. }
  1354. uint8_t MediaPresenter::getVolume() const
  1355. {
  1356. return this->m_volume;
  1357. }
  1358. double MediaPresenter::getDuration() const
  1359. {
  1360. if (this->m_state)
  1361. return this->m_playData.duration;
  1362. else
  1363. return 0.0;
  1364. }
  1365. double MediaPresenter::getCurrentPosition()
  1366. {
  1367. if (this->m_state)
  1368. {
  1369. double duration = this->getDuration();
  1370. double clock;
  1371. clock = this->getMasterClock() + this->m_state->seek.inc;
  1372. if (clock > duration)
  1373. return duration;
  1374. else
  1375. return clock;
  1376. }
  1377. else
  1378. {
  1379. return 0.0;
  1380. }
  1381. }
  1382. bool MediaPresenter::hasDuration() const
  1383. {
  1384. return Utils::zeroDouble(this->getDuration()) > 0.0;
  1385. }
  1386. double MediaPresenter::getAspectRatio(bool widthPrio) const
  1387. {
  1388. MediaState *ms = this->m_state;
  1389. double aspectRatio = 0.0;
  1390. if (!ms)
  1391. return 0.0;
  1392. if (!ms->video.stream.stream)
  1393. return 0.0;
  1394. AVCodecContext *codec = ms->video.stream.ctx;
  1395. if (!codec)
  1396. return 0.0;
  1397. if (codec->sample_aspect_ratio.num == 0)
  1398. {
  1399. aspectRatio = 0.0;
  1400. }
  1401. else
  1402. {
  1403. aspectRatio = av_q2d(codec->sample_aspect_ratio);
  1404. if (widthPrio)
  1405. aspectRatio *= (double)codec->height / (double)codec->width;
  1406. else
  1407. aspectRatio *= (double)codec->width / (double)codec->height;
  1408. }
  1409. if (aspectRatio <= 0.0)
  1410. {
  1411. if (widthPrio)
  1412. aspectRatio = (double)codec->height / (double)codec->width;
  1413. else
  1414. aspectRatio = (double)codec->width / (double)codec->height;
  1415. }
  1416. return aspectRatio;
  1417. }
  1418. bool MediaPresenter::isEnabledVideo() const
  1419. {
  1420. if (this->m_state && this->m_state->video.stream.stream)
  1421. return true;
  1422. else
  1423. return false;
  1424. }
  1425. bool MediaPresenter::isAudio() const
  1426. {
  1427. return this->m_playData.totalFrame <= 100 && this->m_isAudioExt;
  1428. }
  1429. bool MediaPresenter::isVideo() const
  1430. {
  1431. return this->isEnabledVideo() && !this->isAudio();
  1432. }
  1433. bool MediaPresenter::isTempoUsable() const
  1434. {
  1435. if (this->m_state)
  1436. {
  1437. if (this->getCurrentAudioStreamIndex() >= 0)
  1438. return this->m_state->audio.tempo != 0;
  1439. else
  1440. return true;
  1441. }
  1442. return false;
  1443. }
  1444. float MediaPresenter::getTempo() const
  1445. {
  1446. float tempo = 0.0f;
  1447. if (this->isTempoUsable())
  1448. {
  1449. if (this->getCurrentAudioStreamIndex() >= 0)
  1450. BASS_ChannelGetAttribute(this->m_state->audio.tempo, BASS_ATTRIB_TEMPO, &tempo);
  1451. else
  1452. tempo = this->m_state->video.tempo;
  1453. }
  1454. return tempo;
  1455. }
  1456. void MediaPresenter::setTempo(float percent)
  1457. {
  1458. if (this->isTempoUsable())
  1459. {
  1460. if (this->getCurrentAudioStreamIndex() >= 0)
  1461. BASS_ChannelSetAttribute(this->m_state->audio.tempo, BASS_ATTRIB_TEMPO, percent);
  1462. else
  1463. this->m_state->video.tempo = percent;
  1464. }
  1465. }
  1466. VirtualFile& MediaPresenter::getVirtualFile()
  1467. {
  1468. return VIRTUAL_FILE;
  1469. }
  1470. DTVReader& MediaPresenter::getDTVReader()
  1471. {
  1472. return DTV_READER;
  1473. }
  1474. bool MediaPresenter::isRemoteFile() const
  1475. {
  1476. return this->m_isRemoteFile;
  1477. }
  1478. bool MediaPresenter::isRemoteProtocol() const
  1479. {
  1480. return this->m_isRemoteProtocol;
  1481. }
  1482. bool MediaPresenter::changeStream(int newIndex, int oldIndex, bool isAudio, int *lastStreamIndex, bool *quitFlag)
  1483. {
  1484. QMutexLocker locker(&this->m_controlLocker);
  1485. bool success = false;
  1486. if (this->m_state == nullptr)
  1487. return false;
  1488. double clock = this->getMasterClock();
  1489. this->m_state->streamChangeStartTime = this->getAbsoluteClock();
  1490. this->m_state->readThreadQuit = true;
  1491. if (this->m_readThread.isRunning())
  1492. this->m_readThread.wait();
  1493. if (quitFlag)
  1494. *quitFlag = true;
  1495. this->closeStreamComponent(oldIndex, isAudio);
  1496. if (this->openStreamComponent(newIndex, isAudio))
  1497. {
  1498. if (newIndex == this->getCurrentAudioStreamIndex())
  1499. {
  1500. if (this->m_spdif.isOpened())
  1501. this->m_spdif.play();
  1502. else
  1503. BASS_ChannelPlay(this->m_state->audio.handle, true);
  1504. }
  1505. this->seekStream(clock, 0.0, AVSEEK_FLAG_ANY | AVSEEK_FLAG_BACKWARD);
  1506. if (lastStreamIndex)
  1507. *lastStreamIndex = newIndex;
  1508. success = true;
  1509. }
  1510. this->startReadThread();
  1511. this->m_state->streamChangeDriftTime += this->getAbsoluteClock() - this->m_state->streamChangeStartTime;
  1512. return success;
  1513. }
  1514. int MediaPresenter::getCurrentAudioStreamIndex() const
  1515. {
  1516. if (this->m_state)
  1517. return this->m_state->audio.stream.index;
  1518. else
  1519. return -1;
  1520. }
  1521. void MediaPresenter::getAudioStreamInfo(QVector<AudioStreamInfo> *ret) const
  1522. {
  1523. *ret = this->m_audioStreamInfo;
  1524. }
  1525. bool MediaPresenter::resetAudioStream()
  1526. {
  1527. return this->changeAudioStream(this->getCurrentAudioStreamIndex());
  1528. }
  1529. bool MediaPresenter::changeAudioStream(int index)
  1530. {
  1531. return this->changeStream(index, this->getCurrentAudioStreamIndex(),
  1532. this->isUseAudioPath(), &this->m_lastAudioStream, nullptr);
  1533. }
  1534. HSTREAM MediaPresenter::getAudioHandle() const
  1535. {
  1536. if (this->m_state)
  1537. return this->m_state->audio.handle;
  1538. return 0;
  1539. }
  1540. Deinterlacer& MediaPresenter::getDeinterlacer()
  1541. {
  1542. return this->m_deinterlacer;
  1543. }
  1544. void MediaPresenter::setDeinterlacerAlgorithm(AnyVODEnums::DeinterlaceAlgorithm algorithm)
  1545. {
  1546. this->m_deinterlacer.setAlgorithm(algorithm);
  1547. if (this->m_state)
  1548. {
  1549. Video &video = this->m_state->video;
  1550. this->m_deinterlacer.setCodec(video.stream.ctx, video.pixFormat, video.stream.stream->time_base);
  1551. }
  1552. }
  1553. FilterGraph& MediaPresenter::getFilterGraph()
  1554. {
  1555. return this->m_filterGraph;
  1556. }
  1557. bool MediaPresenter::configFilterGraph()
  1558. {
  1559. if (this->m_state)
  1560. {
  1561. Video &video = this->m_state->video;
  1562. return this->m_filterGraph.setCodec(video.stream.ctx, video.pixFormat, this->m_format, video.stream.stream->time_base);
  1563. }
  1564. return false;
  1565. }
  1566. int MediaPresenter::getOptionDescY() const
  1567. {
  1568. return this->m_optionDescY;
  1569. }
  1570. void MediaPresenter::setOptionDescY(int y)
  1571. {
  1572. this->m_optionDescY = y;
  1573. }
  1574. void MediaPresenter::setVerticalScreenOffset(int offset)
  1575. {
  1576. QMutexLocker locker(&this->m_cameraLock);
  1577. this->m_screenOffset.setY(offset);
  1578. }
  1579. void MediaPresenter::setHorizontalScreenOffset(int offset)
  1580. {
  1581. QMutexLocker locker(&this->m_cameraLock);
  1582. this->m_screenOffset.setX(offset);
  1583. }
  1584. void MediaPresenter::useDistortion(bool use)
  1585. {
  1586. this->m_useDistortion = use;
  1587. }
  1588. bool MediaPresenter::isUseDistortion() const
  1589. {
  1590. return this->m_useDistortion;
  1591. }
  1592. void MediaPresenter::setBarrelDistortionCoefficients(const QVector2D &coefficients)
  1593. {
  1594. this->m_barrelDistortionCoefficients = coefficients;
  1595. }
  1596. QVector2D MediaPresenter::getBarrelDistortionCoefficients() const
  1597. {
  1598. return this->m_barrelDistortionCoefficients;
  1599. }
  1600. void MediaPresenter::setPincushionDistortionCoefficients(const QVector2D &coefficients)
  1601. {
  1602. this->m_pincushionDistortionCoefficients = coefficients;
  1603. }
  1604. QVector2D MediaPresenter::getPincushionDistortionCoefficients() const
  1605. {
  1606. return this->m_pincushionDistortionCoefficients;
  1607. }
  1608. void MediaPresenter::setDistortionLensCenter(const QVector2D &lensCenter)
  1609. {
  1610. this->m_distortionLensCenter = lensCenter;
  1611. }
  1612. QVector2D MediaPresenter::getDistortionLensCenter() const
  1613. {
  1614. return this->m_distortionLensCenter;
  1615. }
  1616. QString MediaPresenter::getRealFilePath() const
  1617. {
  1618. return this->m_realFilePath;
  1619. }
  1620. AVPixelFormat MediaPresenter::getFormat() const
  1621. {
  1622. return this->m_format;
  1623. }
  1624. void MediaPresenter::setBluetoothHeadsetConnected(bool connected)
  1625. {
  1626. this->m_bluetoothHeadsetConnected = connected;
  1627. }
  1628. bool MediaPresenter::getBluetoothHeadsetConnected() const
  1629. {
  1630. return this->m_bluetoothHeadsetConnected;
  1631. }
  1632. void MediaPresenter::setBluetoothHeadsetSync(double sync)
  1633. {
  1634. this->m_bluetoothHeadsetSync = sync;
  1635. }
  1636. double MediaPresenter::getBluetoothHeadsetSync() const
  1637. {
  1638. return this->m_bluetoothHeadsetSync;
  1639. }
  1640. #ifdef Q_OS_IOS
  1641. void MediaPresenter::setIOSNotifyCallback(IOSNOTIFYPROC *proc)
  1642. {
  1643. this->m_iosNotify = proc;
  1644. }
  1645. #endif
  1646. void MediaPresenter::setUserAspectRatio(UserAspectRatio &ratio)
  1647. {
  1648. this->m_userRatio = ratio;
  1649. this->computeFrameSize();
  1650. }
  1651. void MediaPresenter::getUserAspectRatio(UserAspectRatio *ret) const
  1652. {
  1653. *ret = this->m_userRatio;
  1654. }
  1655. void MediaPresenter::setMaxTextureSize(int size)
  1656. {
  1657. this->m_maxTextureSize = size;
  1658. this->initFrameBufferObject(&this->m_anaglyphFrameBuffer, size, size);
  1659. }
  1660. int MediaPresenter::getMaxTextureSize() const
  1661. {
  1662. return this->m_maxTextureSize;
  1663. }
  1664. void MediaPresenter::useSubtitleCacheMode(bool use)
  1665. {
  1666. this->m_useSubtitleCacheMode = use;
  1667. }
  1668. bool MediaPresenter::isUseSubtitleCacheMode() const
  1669. {
  1670. return this->m_useSubtitleCacheMode;
  1671. }
  1672. void MediaPresenter::showOptionDesc(const QString &desc)
  1673. {
  1674. if (this->isRunning())
  1675. {
  1676. QMutexLocker locker(&this->m_optionDescMutex);
  1677. this->m_optionDesc = desc;
  1678. this->m_showOptionDesc = true;
  1679. if (this->m_showAudioOptionDescCallback.callback && this->isAudio())
  1680. this->m_showAudioOptionDescCallback.callback(this->m_showAudioOptionDescCallback.userData, desc, true);
  1681. }
  1682. else
  1683. {
  1684. if (this->m_nonePlayingDescCallback.callback)
  1685. this->m_nonePlayingDescCallback.callback(this->m_nonePlayingDescCallback.userData, desc);
  1686. }
  1687. }
  1688. void MediaPresenter::clearFonts()
  1689. {
  1690. this->m_font.clear();
  1691. this->m_subtitleFont.clear();
  1692. }
  1693. void MediaPresenter::clearFrameBuffers()
  1694. {
  1695. this->destroyFrameBufferObject(&this->m_anaglyphFrameBuffer);
  1696. this->destroyFrameBufferObject(&this->m_distortionFrameBuffer);
  1697. this->destroyFrameBufferObject(&this->m_leftDistortionFrameBuffer);
  1698. this->destroyFrameBufferObject(&this->m_rightDistortionFrameBuffer);
  1699. }
  1700. float MediaPresenter::getCPUUsage()
  1701. {
  1702. qint64 pid = QCoreApplication::applicationPid();
  1703. float usage = 0.0f;
  1704. uint64_t processKernelNow = 0;
  1705. uint64_t processUserNow = 0;
  1706. uint64_t systemKernelNow = 0;
  1707. uint64_t systemUserNow = 0;
  1708. uint64_t processKernelElapsed = 0;
  1709. uint64_t processUserElapsed = 0;
  1710. uint64_t systemKernelElapsed = 0;
  1711. uint64_t systemUserElapsed = 0;
  1712. uint64_t totalProcessElapsed = 0;
  1713. uint64_t totalSystemElapsed = 0;
  1714. #ifdef Q_OS_WIN
  1715. ULARGE_INTEGER int64;
  1716. FILETIME dummy;
  1717. FILETIME processFileTimeKernelNow;
  1718. FILETIME processFileTimeUserNow;
  1719. FILETIME systemFileTimeKernelNow;
  1720. FILETIME systemFileTimeUserNow;
  1721. HANDLE pHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
  1722. if (GetProcessTimes(pHandle, &dummy, &dummy, &processFileTimeKernelNow, &processFileTimeUserNow) &&
  1723. GetSystemTimes(&dummy, &systemFileTimeKernelNow, &systemFileTimeUserNow))
  1724. {
  1725. int64.LowPart = processFileTimeKernelNow.dwLowDateTime;
  1726. int64.HighPart = processFileTimeKernelNow.dwHighDateTime;
  1727. processKernelNow = int64.QuadPart;
  1728. int64.LowPart = processFileTimeUserNow.dwLowDateTime;
  1729. int64.HighPart = processFileTimeUserNow.dwHighDateTime;
  1730. processUserNow = int64.QuadPart;
  1731. int64.LowPart = systemFileTimeKernelNow.dwLowDateTime;
  1732. int64.HighPart = systemFileTimeKernelNow.dwHighDateTime;
  1733. systemKernelNow = int64.QuadPart;
  1734. int64.LowPart = systemFileTimeUserNow.dwLowDateTime;
  1735. int64.HighPart = systemFileTimeUserNow.dwHighDateTime;
  1736. systemUserNow = int64.QuadPart;
  1737. }
  1738. if (pHandle)
  1739. CloseHandle(pHandle);
  1740. #elif defined Q_OS_LINUX
  1741. QFile processStat(QString("/proc/%1/stat").arg(pid));
  1742. QFile systemStat("/proc/stat");
  1743. if (!processStat.open(QIODevice::ReadOnly))
  1744. return 0.0f;
  1745. if (!systemStat.open(QIODevice::ReadOnly))
  1746. return 0.0f;
  1747. QTextStream data;
  1748. QString line;
  1749. int idum;
  1750. QString sdum;
  1751. data.setDevice(&processStat);

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