PageRenderTime 38ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/trunk/src/core.cpp

https://github.com/rdp/smplayer-svn
C++ | 4281 lines | 3200 code | 745 blank | 336 comment | 786 complexity | 56b02342a29a9fd8e318170113e67e6c MD5 | raw file
Possible License(s): BSD-3-Clause, GPL-2.0, LGPL-2.1
  1. /* smplayer, GUI front-end for mplayer.
  2. Copyright (C) 2006-2012 Ricardo Villalba <rvm@users.sourceforge.net>
  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 2 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, write to the Free Software
  13. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  14. */
  15. #include "core.h"
  16. #include <QDir>
  17. #include <QFileInfo>
  18. #include <QRegExp>
  19. #include <QTextStream>
  20. #include <QUrl>
  21. #ifdef Q_OS_OS2
  22. #include <QEventLoop>
  23. #endif
  24. #include <cmath>
  25. #include "mplayerwindow.h"
  26. #include "desktopinfo.h"
  27. #include "helper.h"
  28. #include "paths.h"
  29. #include "preferences.h"
  30. #include "global.h"
  31. #include "config.h"
  32. #include "mplayerversion.h"
  33. #include "constants.h"
  34. #include "colorutils.h"
  35. #include "discname.h"
  36. #include "filters.h"
  37. #if defined(Q_OS_WIN) || defined(Q_OS_OS2)
  38. #ifdef Q_OS_WIN
  39. #include <windows.h> // To change app priority
  40. #include <QSysInfo> // To get Windows version
  41. #endif
  42. #ifdef SCREENSAVER_OFF
  43. #include "screensaver.h"
  44. #endif
  45. #endif
  46. #ifndef NO_USE_INI_FILES
  47. #include "filesettings.h"
  48. #include "filesettingshash.h"
  49. #include "tvsettings.h"
  50. #endif
  51. #ifdef YOUTUBE_SUPPORT
  52. #include "retrieveyoutubeurl.h"
  53. #endif
  54. using namespace Global;
  55. Core::Core( MplayerWindow *mpw, QWidget* parent )
  56. : QObject( parent )
  57. {
  58. qRegisterMetaType<Core::State>("Core::State");
  59. mplayerwindow = mpw;
  60. _state = Stopped;
  61. we_are_restarting = false;
  62. just_loaded_external_subs = false;
  63. just_unloaded_external_subs = false;
  64. change_volume_after_unpause = false;
  65. #if DVDNAV_SUPPORT
  66. dvdnav_title_is_menu = true; // Enabled by default for compatibility with previous versions of mplayer
  67. #endif
  68. #ifndef NO_USE_INI_FILES
  69. // Create file_settings
  70. file_settings = 0;
  71. changeFileSettingsMethod(pref->file_settings_method);
  72. // TV settings
  73. tv_settings = new TVSettings(Paths::iniPath());
  74. #endif
  75. proc = new MplayerProcess(this);
  76. // Do this the first
  77. connect( proc, SIGNAL(processExited()),
  78. mplayerwindow->videoLayer(), SLOT(playingStopped()) );
  79. connect( proc, SIGNAL(error(QProcess::ProcessError)),
  80. mplayerwindow->videoLayer(), SLOT(playingStopped()) );
  81. // Necessary to hide/unhide mouse cursor on black borders
  82. connect( proc, SIGNAL(processExited()),
  83. mplayerwindow, SLOT(playingStopped()) );
  84. connect( proc, SIGNAL(error(QProcess::ProcessError)),
  85. mplayerwindow, SLOT(playingStopped()) );
  86. connect( proc, SIGNAL(receivedCurrentSec(double)),
  87. this, SLOT(changeCurrentSec(double)) );
  88. connect( proc, SIGNAL(receivedCurrentFrame(int)),
  89. this, SIGNAL(showFrame(int)) );
  90. connect( proc, SIGNAL(receivedPause()),
  91. this, SLOT(changePause()) );
  92. connect( proc, SIGNAL(processExited()),
  93. this, SLOT(processFinished()), Qt::QueuedConnection );
  94. connect( proc, SIGNAL(mplayerFullyLoaded()),
  95. this, SLOT(finishRestart()), Qt::QueuedConnection );
  96. connect( proc, SIGNAL(lineAvailable(QString)),
  97. this, SIGNAL(logLineAvailable(QString)) );
  98. connect( proc, SIGNAL(receivedCacheMessage(QString)),
  99. this, SLOT(displayMessage(QString)) );
  100. connect( proc, SIGNAL(receivedCreatingIndex(QString)),
  101. this, SLOT(displayMessage(QString)) );
  102. connect( proc, SIGNAL(receivedConnectingToMessage(QString)),
  103. this, SLOT(displayMessage(QString)) );
  104. connect( proc, SIGNAL(receivedResolvingMessage(QString)),
  105. this, SLOT(displayMessage(QString)) );
  106. connect( proc, SIGNAL(receivedScreenshot(QString)),
  107. this, SLOT(displayScreenshotName(QString)) );
  108. connect( proc, SIGNAL(receivedUpdatingFontCache()),
  109. this, SLOT(displayUpdatingFontCache()) );
  110. connect( proc, SIGNAL(receivedScanningFont(QString)),
  111. this, SLOT(displayMessage(QString)) );
  112. connect( proc, SIGNAL(receivedWindowResolution(int,int)),
  113. this, SLOT(gotWindowResolution(int,int)) );
  114. connect( proc, SIGNAL(receivedNoVideo()),
  115. this, SLOT(gotNoVideo()) );
  116. connect( proc, SIGNAL(receivedVO(QString)),
  117. this, SLOT(gotVO(QString)) );
  118. connect( proc, SIGNAL(receivedAO(QString)),
  119. this, SLOT(gotAO(QString)) );
  120. connect( proc, SIGNAL(receivedEndOfFile()),
  121. this, SLOT(fileReachedEnd()), Qt::QueuedConnection );
  122. connect( proc, SIGNAL(receivedStartingTime(double)),
  123. this, SLOT(gotStartingTime(double)) );
  124. connect( proc, SIGNAL(receivedStreamTitle(QString)),
  125. this, SLOT(streamTitleChanged(QString)) );
  126. connect( proc, SIGNAL(receivedStreamTitleAndUrl(QString,QString)),
  127. this, SLOT(streamTitleAndUrlChanged(QString,QString)) );
  128. connect( proc, SIGNAL(failedToParseMplayerVersion(QString)),
  129. this, SIGNAL(failedToParseMplayerVersion(QString)) );
  130. connect( this, SIGNAL(mediaLoaded()), this, SLOT(checkIfVideoIsHD()), Qt::QueuedConnection );
  131. #if DELAYED_AUDIO_SETUP_ON_STARTUP
  132. connect( this, SIGNAL(mediaLoaded()), this, SLOT(initAudioTrack()), Qt::QueuedConnection );
  133. #endif
  134. #if NOTIFY_SUB_CHANGES
  135. connect( proc, SIGNAL(subtitleInfoChanged(const SubTracks &)),
  136. this, SLOT(initSubtitleTrack(const SubTracks &)), Qt::QueuedConnection );
  137. connect( proc, SIGNAL(subtitleInfoReceivedAgain(const SubTracks &)),
  138. this, SLOT(setSubtitleTrackAgain(const SubTracks &)), Qt::QueuedConnection );
  139. #endif
  140. #if NOTIFY_AUDIO_CHANGES
  141. connect( proc, SIGNAL(audioInfoChanged(const Tracks &)),
  142. this, SLOT(initAudioTrack(const Tracks &)), Qt::QueuedConnection );
  143. #endif
  144. #if DVDNAV_SUPPORT
  145. connect( proc, SIGNAL(receivedDVDTitle(int)),
  146. this, SLOT(dvdTitleChanged(int)), Qt::QueuedConnection );
  147. connect( proc, SIGNAL(receivedDuration(double)),
  148. this, SLOT(durationChanged(double)), Qt::QueuedConnection );
  149. QTimer * ask_timer = new QTimer(this);
  150. connect( ask_timer, SIGNAL(timeout()), this, SLOT(askForInfo()) );
  151. ask_timer->start(5000);
  152. connect( proc, SIGNAL(receivedTitleIsMenu()),
  153. this, SLOT(dvdTitleIsMenu()) );
  154. connect( proc, SIGNAL(receivedTitleIsMovie()),
  155. this, SLOT(dvdTitleIsMovie()) );
  156. #endif
  157. connect( this, SIGNAL(stateChanged(Core::State)),
  158. this, SLOT(watchState(Core::State)) );
  159. connect( this, SIGNAL(mediaInfoChanged()), this, SLOT(sendMediaInfo()) );
  160. connect( proc, SIGNAL(error(QProcess::ProcessError)),
  161. this, SIGNAL(mplayerFailed(QProcess::ProcessError)) );
  162. //pref->load();
  163. mset.reset();
  164. // Mplayerwindow
  165. connect( this, SIGNAL(aboutToStartPlaying()),
  166. mplayerwindow->videoLayer(), SLOT(playingStarted()) );
  167. // Necessary to hide/unhide mouse cursor on black borders
  168. connect( this, SIGNAL(aboutToStartPlaying()),
  169. mplayerwindow, SLOT(playingStarted()) );
  170. #if DVDNAV_SUPPORT
  171. connect( mplayerwindow, SIGNAL(mouseMoved(QPoint)),
  172. this, SLOT(dvdnavUpdateMousePos(QPoint)) );
  173. #endif
  174. #if REPAINT_BACKGROUND_OPTION
  175. mplayerwindow->videoLayer()->setRepaintBackground(pref->repaint_video_background);
  176. #endif
  177. mplayerwindow->setMonitorAspect( pref->monitor_aspect_double() );
  178. #if defined(Q_OS_WIN) || defined(Q_OS_OS2)
  179. #ifdef SCREENSAVER_OFF
  180. // Windows or OS2 screensaver
  181. win_screensaver = new WinScreenSaver();
  182. #endif
  183. #endif
  184. #if DISCNAME_TEST
  185. DiscName::test();
  186. #endif
  187. #ifdef YOUTUBE_SUPPORT
  188. yt = new RetrieveYoutubeUrl(this);
  189. connect(yt, SIGNAL(gotPreferredUrl(const QString &)), this, SLOT(openYT(const QString &)));
  190. connect(yt, SIGNAL(connecting(QString)), this, SLOT(connectingToYT(QString)));
  191. connect(yt, SIGNAL(downloadFailed(QString)), this, SLOT(YTFailed(QString)));
  192. connect(yt, SIGNAL(gotEmptyList()), this, SLOT(YTNoVideoUrl()));
  193. #endif
  194. }
  195. Core::~Core() {
  196. #ifndef NO_USE_INI_FILES
  197. saveMediaInfo();
  198. #endif
  199. if (proc->isRunning()) stopMplayer();
  200. proc->terminate();
  201. delete proc;
  202. #ifndef NO_USE_INI_FILES
  203. delete file_settings;
  204. delete tv_settings;
  205. #endif
  206. #if defined(Q_OS_WIN) || defined(Q_OS_OS2)
  207. #ifdef SCREENSAVER_OFF
  208. delete win_screensaver;
  209. #endif
  210. #endif
  211. #ifdef YOUTUBE_SUPPORT
  212. delete yt;
  213. #endif
  214. }
  215. #ifndef NO_USE_INI_FILES
  216. void Core::changeFileSettingsMethod(QString method) {
  217. qDebug("Core::changeFileSettingsMethod: %s", method.toUtf8().constData());
  218. if (file_settings) delete file_settings;
  219. if (method.toLower() == "hash")
  220. file_settings = new FileSettingsHash(Paths::iniPath());
  221. else
  222. file_settings = new FileSettings(Paths::iniPath());
  223. }
  224. #endif
  225. void Core::setState(State s) {
  226. if (s != _state) {
  227. _state = s;
  228. emit stateChanged(_state);
  229. }
  230. }
  231. QString Core::stateToString() {
  232. if (state()==Playing) return "Playing";
  233. else
  234. if (state()==Stopped) return "Stopped";
  235. else
  236. if (state()==Paused) return "Paused";
  237. else
  238. return "Unknown";
  239. }
  240. // Public restart
  241. void Core::restart() {
  242. qDebug("Core::restart");
  243. if (proc->isRunning()) {
  244. restartPlay();
  245. } else {
  246. qDebug("Core::restart: mplayer is not running");
  247. }
  248. }
  249. void Core::reload() {
  250. qDebug("Core::reload");
  251. stopMplayer();
  252. we_are_restarting = false;
  253. initPlaying();
  254. }
  255. #ifndef NO_USE_INI_FILES
  256. void Core::saveMediaInfo() {
  257. qDebug("Core::saveMediaInfo");
  258. if (pref->dont_remember_media_settings) {
  259. qDebug("Core::saveMediaInfo: not saving settings, disabled by user");
  260. return;
  261. }
  262. if ( (mdat.type == TYPE_FILE) && (!mdat.filename.isEmpty()) ) {
  263. file_settings->saveSettingsFor(mdat.filename, mset);
  264. }
  265. else
  266. if ( (mdat.type == TYPE_TV) && (!mdat.filename.isEmpty()) ) {
  267. tv_settings->saveSettingsFor(mdat.filename, mset);
  268. }
  269. }
  270. #endif // NO_USE_INI_FILES
  271. void Core::initializeMenus() {
  272. qDebug("Core::initializeMenus");
  273. emit menusNeedInitialize();
  274. }
  275. void Core::updateWidgets() {
  276. qDebug("Core::updateWidgets");
  277. emit widgetsNeedUpdate();
  278. }
  279. void Core::tellmp(const QString & command) {
  280. qDebug("Core::tellmp: '%s'", command.toUtf8().data());
  281. //qDebug("Command: '%s'", command.toUtf8().data());
  282. if (proc->isRunning()) {
  283. proc->writeToStdin( command );
  284. } else {
  285. qWarning(" tellmp: no process running: %s", command.toUtf8().data());
  286. }
  287. }
  288. void Core::displayTextOnOSD(QString text, int duration, int level, QString prefix) {
  289. qDebug("Core::displayTextOnOSD: '%s'", text.toUtf8().constData());
  290. if (proc->isRunning()) {
  291. QString str = QString("osd_show_text \"%1\" %2 %3\n").arg(text.toUtf8().constData()).arg(duration).arg(level);
  292. if (!prefix.isEmpty()) str = prefix + " " + str;
  293. qDebug("Core::displayTextOnOSD: command: '%s'", str.toUtf8().constData());
  294. proc->write(str.toAscii());
  295. }
  296. }
  297. // Generic open, autodetect type
  298. void Core::open(QString file, int seek) {
  299. qDebug("Core::open: '%s'", file.toUtf8().data());
  300. if (file.startsWith("file:")) {
  301. file = QUrl(file).toLocalFile();
  302. qDebug("Core::open: converting url to local file: %s", file.toUtf8().constData());
  303. }
  304. QFileInfo fi(file);
  305. if ( (fi.exists()) && (fi.suffix().toLower()=="iso") ) {
  306. qDebug("Core::open: * identified as a dvd iso");
  307. #if DVDNAV_SUPPORT
  308. openDVD( DiscName::joinDVD(0, file, pref->use_dvdnav) );
  309. #else
  310. openDVD( DiscName::joinDVD(1, file, false) );
  311. #endif
  312. }
  313. else
  314. if ( (fi.exists()) && (!fi.isDir()) ) {
  315. qDebug("Core::open: * identified as local file");
  316. // Local file
  317. file = QFileInfo(file).absoluteFilePath();
  318. openFile(file, seek);
  319. }
  320. else
  321. if ( (fi.exists()) && (fi.isDir()) ) {
  322. // Directory
  323. qDebug("Core::open: * identified as a directory");
  324. qDebug("Core::open: checking if contains a dvd");
  325. file = QFileInfo(file).absoluteFilePath();
  326. if (Helper::directoryContainsDVD(file)) {
  327. qDebug("Core::open: * directory contains a dvd");
  328. #if DVDNAV_SUPPORT
  329. openDVD( DiscName::joinDVD(1, file, pref->use_dvdnav) );
  330. #else
  331. openDVD( DiscName::joinDVD(1, file, false) );
  332. #endif
  333. } else {
  334. qDebug("Core::open: * directory doesn't contain a dvd");
  335. qDebug("Core::open: opening nothing");
  336. }
  337. }
  338. else
  339. if ((file.toLower().startsWith("dvd:")) || (file.toLower().startsWith("dvdnav:"))) {
  340. qDebug("Core::open: * identified as dvd");
  341. openDVD(file);
  342. /*
  343. QString f = file.lower();
  344. QRegExp s("^dvd://(\\d+)");
  345. if (s.indexIn(f) != -1) {
  346. int title = s.cap(1).toInt();
  347. openDVD(title);
  348. } else {
  349. qWarning("Core::open: couldn't parse dvd title, playing first one");
  350. openDVD();
  351. }
  352. */
  353. }
  354. else
  355. if (file.toLower().startsWith("vcd:")) {
  356. qDebug("Core::open: * identified as vcd");
  357. QString f = file.toLower();
  358. QRegExp s("^vcd://(\\d+)");
  359. if (s.indexIn(f) != -1) {
  360. int title = s.cap(1).toInt();
  361. openVCD(title);
  362. } else {
  363. qWarning("Core::open: couldn't parse vcd title, playing first one");
  364. openVCD();
  365. }
  366. }
  367. else
  368. if (file.toLower().startsWith("cdda:")) {
  369. qDebug("Core::open: * identified as cdda");
  370. QString f = file.toLower();
  371. QRegExp s("^cdda://(\\d+)");
  372. if (s.indexIn(f) != -1) {
  373. int title = s.cap(1).toInt();
  374. openAudioCD(title);
  375. } else {
  376. qWarning("Core::open: couldn't parse cdda title, playing first one");
  377. openAudioCD();
  378. }
  379. }
  380. else
  381. if ((file.toLower().startsWith("dvb:")) || (file.toLower().startsWith("tv:"))) {
  382. qDebug("Core::open: * identified as TV");
  383. openTV(file);
  384. }
  385. else {
  386. qDebug("Core::open: * not identified, playing as stream");
  387. openStream(file);
  388. }
  389. }
  390. void Core::openFile(QString filename, int seek) {
  391. qDebug("Core::openFile: '%s'", filename.toUtf8().data());
  392. QFileInfo fi(filename);
  393. if (fi.exists()) {
  394. playNewFile(fi.absoluteFilePath(), seek);
  395. } else {
  396. //File doesn't exists
  397. //TODO: error message
  398. }
  399. }
  400. #ifdef YOUTUBE_SUPPORT
  401. void Core::openYT(const QString & url) {
  402. qDebug("Core::openYT: %s", url.toUtf8().constData());
  403. openStream(url);
  404. yt->close();
  405. }
  406. void Core::connectingToYT(QString host) {
  407. emit showMessage( tr("Connecting to %1").arg(host) );
  408. }
  409. void Core::YTFailed(QString /*error*/) {
  410. emit showMessage( tr("Unable to retrieve youtube page") );
  411. }
  412. void Core::YTNoVideoUrl() {
  413. emit showMessage( tr("Unable to locate the url of the video") );
  414. }
  415. #endif
  416. void Core::loadSub(const QString & sub ) {
  417. if ( (!sub.isEmpty()) && (QFile::exists(sub)) ) {
  418. #if NOTIFY_SUB_CHANGES
  419. mset.external_subtitles = sub;
  420. just_loaded_external_subs = true;
  421. QFileInfo fi(sub);
  422. if ((pref->fast_load_sub) && (fi.suffix().toLower() != "idx")) {
  423. QString sub_file = sub;
  424. #ifdef Q_OS_WIN
  425. if (pref->use_short_pathnames) {
  426. sub_file = Helper::shortPathName(sub);
  427. // For some reason it seems it's necessary to change the path separator to unix style
  428. // otherwise mplayer fails to load it
  429. sub_file = sub_file.replace("\\","/");
  430. }
  431. #endif
  432. tellmp( "sub_load \""+ sub_file +"\"" );
  433. } else {
  434. restartPlay();
  435. }
  436. #else
  437. mset.external_subtitles = sub;
  438. just_loaded_external_subs = true;
  439. restartPlay();
  440. #endif
  441. } else {
  442. qWarning("Core::loadSub: file '%s' is not valid", sub.toUtf8().constData());
  443. }
  444. }
  445. void Core::unloadSub() {
  446. if ( !mset.external_subtitles.isEmpty() ) {
  447. mset.external_subtitles = "";
  448. just_unloaded_external_subs = true;
  449. restartPlay();
  450. }
  451. }
  452. void Core::loadAudioFile(const QString & audiofile) {
  453. if (!audiofile.isEmpty()) {
  454. mset.external_audio = audiofile;
  455. restartPlay();
  456. }
  457. }
  458. void Core::unloadAudioFile() {
  459. if (!mset.external_audio.isEmpty()) {
  460. mset.external_audio = "";
  461. restartPlay();
  462. }
  463. }
  464. /*
  465. void Core::openDVD( bool from_folder, QString directory) {
  466. qDebug("Core::openDVD");
  467. if (from_folder) {
  468. if (!directory.isEmpty()) {
  469. QFileInfo fi(directory);
  470. if ( (fi.exists()) && (fi.isDir()) ) {
  471. pref->dvd_directory = directory;
  472. pref->play_dvd_from_hd = TRUE;
  473. openDVD();
  474. } else {
  475. qDebug("Core::openDVD: directory '%s' is not valid", directory.toUtf8().data());
  476. }
  477. } else {
  478. qDebug("Core::openDVD: directory is empty");
  479. }
  480. } else {
  481. pref->play_dvd_from_hd = FALSE;
  482. openDVD();
  483. }
  484. }
  485. void Core::openDVD() {
  486. openDVD(1);
  487. }
  488. void Core::openDVD(int title) {
  489. qDebug("Core::openDVD: %d", title);
  490. if (proc->isRunning()) {
  491. stopMplayer();
  492. }
  493. // Save data of previous file:
  494. saveMediaInfo();
  495. mdat.reset();
  496. mdat.filename = "dvd://" + QString::number(title);
  497. mdat.type = TYPE_DVD;
  498. mset.reset();
  499. mset.current_title_id = title;
  500. mset.current_chapter_id = 1;
  501. mset.current_angle_id = 1;
  502. initializeMenus();
  503. initPlaying();
  504. }
  505. */
  506. void Core::openVCD(int title) {
  507. qDebug("Core::openVCD: %d", title);
  508. if (title == -1) title = pref->vcd_initial_title;
  509. if (proc->isRunning()) {
  510. stopMplayer();
  511. }
  512. // Save data of previous file:
  513. #ifndef NO_USE_INI_FILES
  514. saveMediaInfo();
  515. #endif
  516. mdat.reset();
  517. mdat.filename = "vcd://" + QString::number(title);
  518. mdat.type = TYPE_VCD;
  519. mset.reset();
  520. mset.current_title_id = title;
  521. mset.current_chapter_id = -1;
  522. mset.current_angle_id = -1;
  523. /* initializeMenus(); */
  524. initPlaying();
  525. }
  526. void Core::openAudioCD(int title) {
  527. qDebug("Core::openAudioCD: %d", title);
  528. if (title == -1) title = 1;
  529. if (proc->isRunning()) {
  530. stopMplayer();
  531. }
  532. // Save data of previous file:
  533. #ifndef NO_USE_INI_FILES
  534. saveMediaInfo();
  535. #endif
  536. mdat.reset();
  537. mdat.filename = "cdda://" + QString::number(title);
  538. mdat.type = TYPE_AUDIO_CD;
  539. mset.reset();
  540. mset.current_title_id = title;
  541. mset.current_chapter_id = -1;
  542. mset.current_angle_id = -1;
  543. /* initializeMenus(); */
  544. initPlaying();
  545. }
  546. void Core::openDVD(QString dvd_url) {
  547. qDebug("Core::openDVD: '%s'", dvd_url.toUtf8().data());
  548. //Checks
  549. DiscData disc_data = DiscName::split(dvd_url);
  550. QString folder = disc_data.device;
  551. int title = disc_data.title;
  552. if (title == -1) {
  553. qWarning("Core::openDVD: title invalid, not playing dvd");
  554. return;
  555. }
  556. if (folder.isEmpty()) {
  557. qDebug("Core::openDVD: not folder");
  558. } else {
  559. QFileInfo fi(folder);
  560. if ( (!fi.exists()) /*|| (!fi.isDir())*/ ) {
  561. qWarning("Core::openDVD: folder invalid, not playing dvd");
  562. return;
  563. }
  564. }
  565. if (proc->isRunning()) {
  566. stopMplayer();
  567. we_are_restarting = false;
  568. }
  569. // Save data of previous file:
  570. #ifndef NO_USE_INI_FILES
  571. saveMediaInfo();
  572. #endif
  573. mdat.reset();
  574. mdat.filename = dvd_url;
  575. mdat.type = TYPE_DVD;
  576. mset.reset();
  577. mset.current_title_id = title;
  578. mset.current_chapter_id = firstChapter();
  579. mset.current_angle_id = 1;
  580. /* initializeMenus(); */
  581. initPlaying();
  582. }
  583. void Core::openTV(QString channel_id) {
  584. qDebug("Core::openTV: '%s'", channel_id.toUtf8().constData());
  585. if (proc->isRunning()) {
  586. stopMplayer();
  587. we_are_restarting = false;
  588. }
  589. // Save data of previous file:
  590. #ifndef NO_USE_INI_FILES
  591. saveMediaInfo();
  592. #endif
  593. // Use last channel if the name is just "dvb://" or "tv://"
  594. if ((channel_id == "dvb://") && (!pref->last_dvb_channel.isEmpty())) {
  595. channel_id = pref->last_dvb_channel;
  596. }
  597. else
  598. if ((channel_id == "tv://") && (!pref->last_tv_channel.isEmpty())) {
  599. channel_id = pref->last_tv_channel;
  600. }
  601. // Save last channel
  602. if (channel_id.startsWith("dvb://")) pref->last_dvb_channel = channel_id;
  603. else
  604. if (channel_id.startsWith("tv://")) pref->last_tv_channel = channel_id;
  605. mdat.reset();
  606. mdat.filename = channel_id;
  607. mdat.type = TYPE_TV;
  608. mset.reset();
  609. // Set the default deinterlacer for TV
  610. mset.current_deinterlacer = pref->initial_tv_deinterlace;
  611. #ifndef NO_USE_INI_FILES
  612. if (!pref->dont_remember_media_settings) {
  613. // Check if we already have info about this file
  614. if (tv_settings->existSettingsFor(channel_id)) {
  615. qDebug("Core::openTV: we have settings for this file!!!");
  616. // In this case we read info from config
  617. tv_settings->loadSettingsFor(channel_id, mset);
  618. qDebug("Core::openTV: media settings read");
  619. }
  620. }
  621. #endif
  622. /* initializeMenus(); */
  623. initPlaying();
  624. }
  625. void Core::openStream(QString name) {
  626. qDebug("Core::openStream: '%s'", name.toUtf8().data());
  627. #ifdef YOUTUBE_SUPPORT
  628. if (name.contains("youtube.com/watch", Qt::CaseInsensitive) ||
  629. name.contains("youtu.be/", Qt::CaseInsensitive) ||
  630. name.contains("y2u.be/", Qt::CaseInsensitive) )
  631. {
  632. qDebug("Core::openStream: youtube url detected");
  633. if (name.startsWith("www.youtube.com")) name = "http://" + name;
  634. if (name.startsWith("youtube.com")) name = "http://www." + name;
  635. if (name.startsWith("youtu.be")) name = "http://" + name;
  636. if (name.startsWith("y2u.be")) name = "http://" + name;
  637. yt->setPreferredQuality( (RetrieveYoutubeUrl::Quality) pref->yt_quality );
  638. yt->fetchPage(name);
  639. return;
  640. }
  641. #endif
  642. if (proc->isRunning()) {
  643. stopMplayer();
  644. we_are_restarting = false;
  645. }
  646. // Save data of previous file:
  647. #ifndef NO_USE_INI_FILES
  648. saveMediaInfo();
  649. #endif
  650. mdat.reset();
  651. mdat.filename = name;
  652. mdat.type = TYPE_STREAM;
  653. mset.reset();
  654. /* initializeMenus(); */
  655. initPlaying();
  656. }
  657. void Core::playNewFile(QString file, int seek) {
  658. qDebug("Core::playNewFile: '%s'", file.toUtf8().data());
  659. if (proc->isRunning()) {
  660. stopMplayer();
  661. we_are_restarting = false;
  662. }
  663. // Save data of previous file:
  664. #ifndef NO_USE_INI_FILES
  665. saveMediaInfo();
  666. #endif
  667. mdat.reset();
  668. mdat.filename = file;
  669. mdat.type = TYPE_FILE;
  670. int old_volume = mset.volume;
  671. mset.reset();
  672. #ifndef NO_USE_INI_FILES
  673. // Check if we already have info about this file
  674. if (file_settings->existSettingsFor(file)) {
  675. qDebug("Core::playNewFile: We have settings for this file!!!");
  676. // In this case we read info from config
  677. if (!pref->dont_remember_media_settings) {
  678. file_settings->loadSettingsFor(file, mset);
  679. qDebug("Core::playNewFile: Media settings read");
  680. // Resize the window and set the aspect as soon as possible
  681. int saved_width = mset.win_width;
  682. int saved_height = mset.win_height;
  683. // 400x300 is the default size for win_width and win_height
  684. // so we set them to 0 to avoid to resize the window on
  685. // audio files
  686. if ((saved_width == 400) && (saved_height == 300)) {
  687. saved_width = 0;
  688. saved_height = 0;
  689. }
  690. if ((saved_width > 0) && (saved_height > 0)) {
  691. emit needResize(mset.win_width, mset.win_height);
  692. changeAspectRatio(mset.aspect_ratio_id);
  693. }
  694. if (pref->dont_remember_time_pos) {
  695. mset.current_sec = 0;
  696. qDebug("Core::playNewFile: Time pos reset to 0");
  697. }
  698. } else {
  699. qDebug("Core::playNewFile: Media settings have not read because of preferences setting");
  700. }
  701. } else {
  702. // Recover volume
  703. mset.volume = old_volume;
  704. }
  705. #else
  706. // Recover volume
  707. mset.volume = old_volume;
  708. #endif // NO_USE_INI_FILES
  709. /* initializeMenus(); */
  710. qDebug("Core::playNewFile: volume: %d, old_volume: %d", mset.volume, old_volume);
  711. initPlaying(seek);
  712. }
  713. void Core::restartPlay() {
  714. we_are_restarting = true;
  715. initPlaying();
  716. }
  717. void Core::initPlaying(int seek) {
  718. qDebug("Core::initPlaying");
  719. /*
  720. mdat.list();
  721. mset.list();
  722. */
  723. /* updateWidgets(); */
  724. mplayerwindow->hideLogo();
  725. if (proc->isRunning()) {
  726. stopMplayer();
  727. }
  728. int start_sec = (int) mset.current_sec;
  729. if (seek > -1) start_sec = seek;
  730. #ifdef YOUTUBE_SUPPORT
  731. // Avoid to pass to mplayer the youtube page url
  732. if (mdat.type == TYPE_STREAM) {
  733. if (mdat.filename == yt->origUrl()) {
  734. mdat.filename = yt->latestPreferredUrl();
  735. }
  736. }
  737. #endif
  738. startMplayer( mdat.filename, start_sec );
  739. }
  740. // This is reached when a new video has just started playing
  741. // and maybe we need to give some defaults
  742. void Core::newMediaPlaying() {
  743. qDebug("Core::newMediaPlaying: --- start ---");
  744. QString file = mdat.filename;
  745. int type = mdat.type;
  746. mdat = proc->mediaData();
  747. mdat.filename = file;
  748. mdat.type = type;
  749. initializeMenus(); // Old
  750. // Video
  751. if ( (mset.current_video_id == MediaSettings::NoneSelected) &&
  752. (mdat.videos.numItems() > 0) )
  753. {
  754. changeVideo( mdat.videos.itemAt(0).ID(), false ); // Don't allow to restart
  755. }
  756. #if !DELAYED_AUDIO_SETUP_ON_STARTUP && !NOTIFY_AUDIO_CHANGES
  757. // First audio if none selected
  758. if ( (mset.current_audio_id == MediaSettings::NoneSelected) &&
  759. (mdat.audios.numItems() > 0) )
  760. {
  761. // Don't set mset.current_audio_id here! changeAudio will do.
  762. // Otherwise changeAudio will do nothing.
  763. int audio = mdat.audios.itemAt(0).ID(); // First one
  764. if (mdat.audios.existsItemAt(pref->initial_audio_track-1)) {
  765. audio = mdat.audios.itemAt(pref->initial_audio_track-1).ID();
  766. }
  767. // Check if one of the audio tracks is the user preferred.
  768. if (!pref->audio_lang.isEmpty()) {
  769. int res = mdat.audios.findLang( pref->audio_lang );
  770. if (res != -1) audio = res;
  771. }
  772. // Change the audio without restarting mplayer, it's not
  773. // safe to do it here.
  774. changeAudio( audio, false );
  775. }
  776. #endif
  777. #if !NOTIFY_SUB_CHANGES
  778. // Subtitles
  779. if (mset.external_subtitles.isEmpty()) {
  780. if (pref->autoload_sub) {
  781. //Select first subtitle if none selected
  782. if (mset.current_sub_id == MediaSettings::NoneSelected) {
  783. int sub = mdat.subs.selectOne( pref->subtitle_lang, pref->initial_subtitle_track-1 );
  784. changeSubtitle( sub );
  785. }
  786. } else {
  787. changeSubtitle( MediaSettings::SubNone );
  788. }
  789. }
  790. #endif
  791. if (mdat.n_chapters > 0) {
  792. // Just to show the first chapter checked in the menu
  793. mset.current_chapter_id = firstChapter();
  794. }
  795. mdat.initialized = TRUE;
  796. // MPlayer doesn't display the length in ID_LENGTH for audio CDs...
  797. if ((mdat.duration == 0) && (mdat.type == TYPE_AUDIO_CD)) {
  798. /*
  799. qDebug(" *** get duration here from title info *** ");
  800. qDebug(" *** current title: %d", mset.current_title_id );
  801. */
  802. if (mset.current_title_id > 0) {
  803. mdat.duration = mdat.titles.item(mset.current_title_id).duration();
  804. }
  805. }
  806. /* updateWidgets(); */
  807. mdat.list();
  808. mset.list();
  809. qDebug("Core::newMediaPlaying: --- end ---");
  810. }
  811. void Core::finishRestart() {
  812. qDebug("Core::finishRestart: --- start ---");
  813. if (!we_are_restarting) {
  814. newMediaPlaying();
  815. //QTimer::singleShot(1000, this, SIGNAL(mediaStartPlay()));
  816. emit mediaStartPlay();
  817. }
  818. if (we_are_restarting) {
  819. // Update info about codecs and demuxer
  820. mdat.video_codec = proc->mediaData().video_codec;
  821. mdat.audio_codec = proc->mediaData().audio_codec;
  822. mdat.demuxer = proc->mediaData().demuxer;
  823. }
  824. #ifdef YOUTUBE_SUPPORT
  825. // Change the real url with the youtube page url and set the title
  826. if (mdat.type == TYPE_STREAM) {
  827. if (mdat.filename == yt->latestPreferredUrl()) {
  828. mdat.filename = yt->origUrl();
  829. mdat.stream_title = yt->urlTitle();
  830. }
  831. }
  832. #endif
  833. #if !NOTIFY_SUB_CHANGES
  834. // Subtitles
  835. //if (we_are_restarting) {
  836. if ( (just_loaded_external_subs) || (just_unloaded_external_subs) ) {
  837. qDebug("Core::finishRestart: processing new subtitles");
  838. // Just to simplify things
  839. if (mset.current_sub_id == MediaSettings::NoneSelected) {
  840. mset.current_sub_id = MediaSettings::SubNone;
  841. }
  842. // Save current sub
  843. SubData::Type type;
  844. int ID;
  845. int old_item = -1;
  846. if ( mset.current_sub_id != MediaSettings::SubNone ) {
  847. old_item = mset.current_sub_id;
  848. type = mdat.subs.itemAt(old_item).type();
  849. ID = mdat.subs.itemAt(old_item).ID();
  850. }
  851. // Use the subtitle info from mplayerprocess
  852. qDebug( "Core::finishRestart: copying sub data from proc to mdat");
  853. mdat.subs = proc->mediaData().subs;
  854. initializeMenus();
  855. int item = MediaSettings::SubNone;
  856. // Try to recover old subtitle
  857. if (just_unloaded_external_subs) {
  858. if (old_item > -1) {
  859. int new_item = mdat.subs.find(type, ID);
  860. if (new_item > -1) item = new_item;
  861. }
  862. }
  863. // If we've just loaded a subtitle file
  864. // select one if the user wants to autoload
  865. // one subtitle
  866. if (just_loaded_external_subs) {
  867. if ( (pref->autoload_sub) && (item == MediaSettings::SubNone) ) {
  868. qDebug("Core::finishRestart: cannot find previous subtitle");
  869. qDebug("Core::finishRestart: selecting a new one");
  870. item = mdat.subs.selectOne( pref->subtitle_lang );
  871. }
  872. }
  873. changeSubtitle( item );
  874. just_loaded_external_subs = false;
  875. just_unloaded_external_subs = false;
  876. } else {
  877. // Normal restart, subtitles haven't changed
  878. // Recover current subtitle
  879. changeSubtitle( mset.current_sub_id );
  880. }
  881. #endif
  882. we_are_restarting = false;
  883. changeAspectRatio(mset.aspect_ratio_id);
  884. if (pref->global_volume) {
  885. bool was_muted = pref->mute;
  886. setVolume( pref->volume, true);
  887. if (was_muted) mute(true);
  888. } else {
  889. bool was_muted = mset.mute;
  890. setVolume( mset.volume, true );
  891. if (was_muted) mute(true);
  892. }
  893. if (pref->change_video_equalizer_on_startup && (mset.gamma != 0)) {
  894. int gamma = mset.gamma;
  895. mset.gamma = -1000; // if mset.gamma == new value, mset.gamma is not changed!
  896. setGamma( gamma );
  897. }
  898. // Hack to be sure that the equalizers are up to date
  899. emit videoEqualizerNeedsUpdate();
  900. emit audioEqualizerNeedsUpdate();
  901. changeZoom(mset.zoom_factor);
  902. // Toggle subtitle visibility
  903. changeSubVisibility(pref->sub_visibility);
  904. // A-B marker
  905. emit ABMarkersChanged(mset.A_marker, mset.B_marker);
  906. // Initialize the OSD level
  907. QTimer::singleShot(pref->osd_delay, this, SLOT(initializeOSD()));
  908. emit mediaLoaded();
  909. emit mediaInfoChanged();
  910. updateWidgets(); // New
  911. qDebug("Core::finishRestart: --- end ---");
  912. }
  913. void Core::initializeOSD() {
  914. changeOSD(pref->osd);
  915. }
  916. void Core::stop()
  917. {
  918. qDebug("Core::stop");
  919. qDebug("Core::stop: state: %s", stateToString().toUtf8().data());
  920. if (state()==Stopped) {
  921. // if pressed stop twice, reset video to the beginning
  922. qDebug("Core::stop: mset.current_sec: %f", mset.current_sec);
  923. mset.current_sec = 0;
  924. qDebug("Core::stop: mset.current_sec set to 0");
  925. emit showTime( mset.current_sec );
  926. #ifdef SEEKBAR_RESOLUTION
  927. emit positionChanged( 0 );
  928. #else
  929. emit posChanged( 0 );
  930. #endif
  931. //updateWidgets();
  932. }
  933. stopMplayer();
  934. emit mediaStoppedByUser();
  935. }
  936. void Core::play()
  937. {
  938. qDebug("Core::play");
  939. if ((proc->isRunning()) && (state()==Paused)) {
  940. tellmp("pause"); // Unpauses
  941. }
  942. else
  943. if ((proc->isRunning()) && (state()==Playing)) {
  944. // nothing to do, continue playing
  945. }
  946. else {
  947. // if we're stopped, play it again
  948. if ( !mdat.filename.isEmpty() ) {
  949. /*
  950. qDebug( "current_sec: %f, duration: %f", mset.current_sec, mdat.duration);
  951. if ( (floor(mset.current_sec)) >= (floor(mdat.duration)) ) {
  952. mset.current_sec = 0;
  953. }
  954. */
  955. restartPlay();
  956. }
  957. }
  958. }
  959. void Core::pause_and_frame_step() {
  960. qDebug("Core::pause_and_frame_step");
  961. if (proc->isRunning()) {
  962. if (state() == Paused) {
  963. tellmp("frame_step");
  964. }
  965. else {
  966. tellmp("pause");
  967. }
  968. }
  969. }
  970. void Core::pause() {
  971. qDebug("Core::pause");
  972. qDebug("Core::pause: current state: %s", stateToString().toUtf8().data());
  973. if (proc->isRunning()) {
  974. // Pauses and unpauses
  975. tellmp("pause");
  976. }
  977. }
  978. void Core::play_or_pause() {
  979. if (proc->isRunning()) {
  980. pause();
  981. } else {
  982. play();
  983. }
  984. }
  985. void Core::frameStep() {
  986. qDebug("Core::frameStep");
  987. if (proc->isRunning()) {
  988. tellmp("frame_step");
  989. }
  990. }
  991. void Core::screenshot() {
  992. qDebug("Core::screenshot");
  993. if ( (!pref->screenshot_directory.isEmpty()) &&
  994. (QFileInfo(pref->screenshot_directory).isDir()) )
  995. {
  996. tellmp( pausing_prefix() + " screenshot 0");
  997. qDebug("Core::screenshot: taken screenshot");
  998. } else {
  999. qDebug("Core::screenshot: error: directory for screenshots not valid");
  1000. emit showMessage( tr("Screenshot NOT taken, folder not configured") );
  1001. }
  1002. }
  1003. void Core::screenshots() {
  1004. qDebug("Core::screenshots");
  1005. if ( (!pref->screenshot_directory.isEmpty()) &&
  1006. (QFileInfo(pref->screenshot_directory).isDir()) )
  1007. {
  1008. tellmp( "screenshot 1");
  1009. } else {
  1010. qDebug("Core::screenshots: error: directory for screenshots not valid");
  1011. emit showMessage( tr("Screenshots NOT taken, folder not configured") );
  1012. }
  1013. }
  1014. void Core::processFinished()
  1015. {
  1016. qDebug("Core::processFinished");
  1017. #if defined(Q_OS_WIN) || defined(Q_OS_OS2)
  1018. #ifdef SCREENSAVER_OFF
  1019. // Restores the Windows or OS2 screensaver
  1020. if (pref->turn_screensaver_off) {
  1021. win_screensaver->enable();
  1022. }
  1023. #endif
  1024. #endif
  1025. qDebug("Core::processFinished: we_are_restarting: %d", we_are_restarting);
  1026. //mset.current_sec = 0;
  1027. if (!we_are_restarting) {
  1028. qDebug("Core::processFinished: play has finished!");
  1029. setState(Stopped);
  1030. //emit stateChanged(state());
  1031. }
  1032. int exit_code = proc->exitCode();
  1033. qDebug("Core::processFinished: exit_code: %d", exit_code);
  1034. if (exit_code != 0) {
  1035. emit mplayerFinishedWithError(exit_code);
  1036. }
  1037. }
  1038. void Core::fileReachedEnd() {
  1039. /*
  1040. if (mdat.type == TYPE_VCD) {
  1041. // If the first vcd title has nothing, it doesn't start to play
  1042. // and menus are not initialized.
  1043. initializeMenus();
  1044. }
  1045. */
  1046. // If we're at the end of the movie, reset to 0
  1047. mset.current_sec = 0;
  1048. updateWidgets();
  1049. emit mediaFinished();
  1050. }
  1051. #if SEEKBAR_RESOLUTION
  1052. void Core::goToPosition(int value) {
  1053. qDebug("Core::goToPosition: value: %d", value);
  1054. if (pref->relative_seeking) {
  1055. goToPos( (double) value / (SEEKBAR_RESOLUTION / 100) );
  1056. }
  1057. else {
  1058. if (mdat.duration > 0) {
  1059. int jump_time = (int) mdat.duration * value / SEEKBAR_RESOLUTION;
  1060. goToSec(jump_time);
  1061. }
  1062. }
  1063. }
  1064. void Core::goToPos(double perc) {
  1065. qDebug("Core::goToPos: per: %f", perc);
  1066. tellmp( seek_cmd(perc, 1) );
  1067. }
  1068. #else
  1069. void Core::goToPos(int perc) {
  1070. qDebug("Core::goToPos: per: %d", perc);
  1071. tellmp( seek_cmd(perc, 1) );
  1072. }
  1073. #endif
  1074. void Core::startMplayer( QString file, double seek ) {
  1075. qDebug("Core::startMplayer");
  1076. if (file.isEmpty()) {
  1077. qWarning("Core:startMplayer: file is empty!");
  1078. return;
  1079. }
  1080. if (proc->isRunning()) {
  1081. qWarning("Core::startMplayer: MPlayer still running!");
  1082. return;
  1083. }
  1084. #ifdef YOUTUBE_SUPPORT
  1085. // Stop any pending request
  1086. qDebug("Core::startMplayer: yt state: %d", yt->state());
  1087. if (yt->state() != QHttp::Unconnected) {
  1088. //yt->abort(); /* Make the app to crash, don't know why */
  1089. }
  1090. #endif
  1091. #if defined(Q_OS_WIN) || defined(Q_OS_OS2)
  1092. #ifdef SCREENSAVER_OFF
  1093. // Disable the Windows or OS2 screensaver
  1094. if (pref->turn_screensaver_off) {
  1095. win_screensaver->disable();
  1096. }
  1097. #endif
  1098. #endif
  1099. bool is_mkv = (QFileInfo(file).suffix().toLower() == "mkv");
  1100. // DVD
  1101. QString dvd_folder;
  1102. int dvd_title = -1;
  1103. if (mdat.type==TYPE_DVD) {
  1104. DiscData disc_data = DiscName::split(file);
  1105. dvd_folder = disc_data.device;
  1106. if (dvd_folder.isEmpty()) dvd_folder = pref->dvd_device;
  1107. dvd_title = disc_data.title;
  1108. file = disc_data.protocol + "://";
  1109. if (dvd_title > 0) file += QString::number(dvd_title);
  1110. }
  1111. // Check URL playlist
  1112. bool url_is_playlist = false;
  1113. if (file.endsWith("|playlist")) {
  1114. url_is_playlist = true;
  1115. file = file.remove("|playlist");
  1116. } else {
  1117. QUrl url(file);
  1118. qDebug("Core::startMplayer: checking if stream is a playlist");
  1119. qDebug("Core::startMplayer: url path: '%s'", url.path().toUtf8().constData());
  1120. QRegExp rx("\\.ram$|\\.asx$|\\.m3u$|\\.pls$", Qt::CaseInsensitive);
  1121. url_is_playlist = (rx.indexIn(url.path()) != -1);
  1122. }
  1123. qDebug("Core::startMplayer: url_is_playlist: %d", url_is_playlist);
  1124. bool screenshot_enabled = ( (pref->use_screenshot) &&
  1125. (!pref->screenshot_directory.isEmpty()) &&
  1126. (QFileInfo(pref->screenshot_directory).isDir()) );
  1127. proc->clearArguments();
  1128. // Set working directory to screenshot directory
  1129. if (screenshot_enabled) {
  1130. qDebug("Core::startMplayer: setting working directory to '%s'", pref->screenshot_directory.toUtf8().data());
  1131. proc->setWorkingDirectory( pref->screenshot_directory );
  1132. }
  1133. // Use absolute path, otherwise after changing to the screenshot directory
  1134. // the mplayer path might not be found if it's a relative path
  1135. // (seems to be necessary only for linux)
  1136. QString mplayer_bin = pref->mplayer_bin;
  1137. QFileInfo fi(mplayer_bin);
  1138. if (fi.exists() && fi.isExecutable() && !fi.isDir()) {
  1139. mplayer_bin = fi.absoluteFilePath();
  1140. }
  1141. proc->addArgument( mplayer_bin );
  1142. proc->addArgument("-noquiet");
  1143. #ifdef LOG_MPLAYER
  1144. if (pref->verbose_log) {
  1145. proc->addArgument("-v");
  1146. }
  1147. #endif
  1148. if (pref->fullscreen && pref->use_mplayer_window) {
  1149. proc->addArgument("-fs");
  1150. } else {
  1151. // No mplayer fullscreen mode
  1152. #if !USE_MPLAYER_PANSCAN
  1153. proc->addArgument("-nofs");
  1154. #else
  1155. // The command 'panscan' requires -fs
  1156. proc->addArgument("-fs");
  1157. #endif
  1158. }
  1159. proc->addArgument("-nomouseinput");
  1160. // Demuxer and audio and video codecs:
  1161. if (!mset.forced_demuxer.isEmpty()) {
  1162. proc->addArgument("-demuxer");
  1163. proc->addArgument(mset.forced_demuxer);
  1164. }
  1165. if (!mset.forced_audio_codec.isEmpty()) {
  1166. proc->addArgument("-ac");
  1167. proc->addArgument(mset.forced_audio_codec);
  1168. }
  1169. if (!mset.forced_video_codec.isEmpty()) {
  1170. proc->addArgument("-vc");
  1171. proc->addArgument(mset.forced_video_codec);
  1172. }
  1173. #ifndef Q_OS_WIN
  1174. else {
  1175. /* if (pref->vo.startsWith("x11")) { */ // My card doesn't support vdpau, I use x11 to test
  1176. if (pref->vo.startsWith("vdpau")) {
  1177. QString c;
  1178. if (pref->vdpau.ffh264vdpau) c += "ffh264vdpau,";
  1179. if (pref->vdpau.ffmpeg12vdpau) c += "ffmpeg12vdpau,";
  1180. if (pref->vdpau.ffwmv3vdpau) c += "ffwmv3vdpau,";
  1181. if (pref->vdpau.ffvc1vdpau) c += "ffvc1vdpau,";
  1182. if (pref->vdpau.ffodivxvdpau) c += "ffodivxvdpau,";
  1183. if (!c.isEmpty()) {
  1184. proc->addArgument("-vc");
  1185. proc->addArgument(c);
  1186. }
  1187. }
  1188. #endif
  1189. else {
  1190. if (pref->coreavc) {
  1191. proc->addArgument("-vc");
  1192. proc->addArgument("coreserve,");
  1193. }
  1194. }
  1195. #ifndef Q_OS_WIN
  1196. }
  1197. #endif
  1198. if (pref->use_hwac3) {
  1199. proc->addArgument("-afm");
  1200. proc->addArgument("hwac3");
  1201. }
  1202. QString lavdopts;
  1203. if ( (pref->h264_skip_loop_filter == Preferences::LoopDisabled) ||
  1204. ((pref->h264_skip_loop_filter == Preferences::LoopDisabledOnHD) &&
  1205. (mset.is264andHD)) )
  1206. {
  1207. if (!lavdopts.isEmpty()) lavdopts += ":";
  1208. lavdopts += "skiploopfilter=all";
  1209. }
  1210. if (pref->threads > 1) {
  1211. if (!lavdopts.isEmpty()) lavdopts += ":";
  1212. lavdopts += "threads=" + QString::number(pref->threads);
  1213. }
  1214. if (!lavdopts.isEmpty()) {
  1215. proc->addArgument("-lavdopts");
  1216. proc->addArgument(lavdopts);
  1217. }
  1218. proc->addArgument("-sub-fuzziness");
  1219. proc->addArgument( QString::number(pref->subfuzziness) );
  1220. proc->addArgument("-identify");
  1221. if (MplayerVersion::isMplayerAtLeast(27667)) {
  1222. // From r27667 the number of chapters can be obtained from ID_CHAPTERS
  1223. mset.current_chapter_id = 0; // Reset chapters
  1224. } else {
  1225. // We need this to get info about mkv chapters
  1226. if (is_mkv) {
  1227. proc->addArgument("-msglevel");
  1228. proc->addArgument("demux=6");
  1229. // **** Reset chapter ***
  1230. // Select first chapter, otherwise we cannot
  1231. // resume playback at the same point
  1232. // (time would be relative to chapter)
  1233. mset.current_chapter_id = 0;
  1234. }
  1235. }
  1236. proc->addArgument("-slave");
  1237. if (!pref->vo.isEmpty()) {
  1238. proc->addArgument( "-vo");
  1239. proc->addArgument( pref->vo );
  1240. } else {
  1241. proc->addArgument("-vo");
  1242. #ifdef Q_OS_WIN
  1243. if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA) {
  1244. proc->addArgument("direct3d,");
  1245. } else {
  1246. proc->addArgument("directx,");
  1247. }
  1248. #else
  1249. proc->addArgument("xv,");
  1250. #endif
  1251. }
  1252. #if USE_ADAPTER
  1253. if (pref->adapter > -1) {
  1254. proc->addArgument("-adapter");
  1255. proc->addArgument(QString::number(pref->adapter));
  1256. }
  1257. #endif
  1258. if (!pref->ao.isEmpty()) {
  1259. proc->addArgument( "-ao");
  1260. proc->addArgument( pref->ao );
  1261. }
  1262. #if !defined(Q_OS_WIN) && !defined(Q_OS_OS2)
  1263. if (pref->vo.startsWith("x11")) {
  1264. proc->addArgument( "-zoom");
  1265. }
  1266. #endif
  1267. proc->addArgument("-nokeepaspect");
  1268. // Performance options
  1269. #ifdef Q_OS_WIN
  1270. QString p;
  1271. int app_p = NORMAL_PRIORITY_CLASS;
  1272. switch (pref->priority) {
  1273. case Preferences::Realtime: p = "realtime";
  1274. app_p = REALTIME_PRIORITY_CLASS;
  1275. break;
  1276. case Preferences::High: p = "high";
  1277. app_p = REALTIME_PRIORITY_CLASS;
  1278. break;
  1279. case Preferences::AboveNormal: p = "abovenormal";
  1280. app_p = HIGH_PRIORITY_CLASS;
  1281. break;
  1282. case Preferences::Normal: p = "normal";
  1283. app_p = ABOVE_NORMAL_PRIORITY_CLASS;
  1284. break;
  1285. case Preferences::BelowNormal: p = "belownormal"; break;
  1286. case Preferences::Idle: p = "idle"; break;
  1287. default: p = "normal";
  1288. }
  1289. proc->addArgument("-priority");
  1290. proc->addArgument( p );
  1291. SetPriorityClass(GetCurrentProcess(), app_p);
  1292. qDebug("Core::startMplayer: priority of smplayer process set to %d", app_p);
  1293. #endif
  1294. if (pref->frame_drop) {
  1295. proc->addArgument("-framedrop");
  1296. }
  1297. if (pref->hard_frame_drop) {
  1298. proc->addArgument("-hardframedrop");
  1299. }
  1300. if (pref->autosync) {
  1301. proc->addArgument("-autosync");
  1302. proc->addArgument( QString::number( pref->autosync_factor ) );
  1303. }
  1304. if (pref->use_mc) {
  1305. proc->addArgument("-mc");
  1306. proc->addArgument( QString::number( pref->mc_value ) );
  1307. }
  1308. if (pref->use_direct_rendering) {
  1309. proc->addArgument("-dr");
  1310. } else {
  1311. proc->addArgument("-nodr");
  1312. }
  1313. if (pref->use_double_buffer) {
  1314. proc->addArgument("-double");
  1315. } else {
  1316. proc->addArgument("-nodouble");
  1317. }
  1318. #if !defined(Q_OS_WIN) && !defined(Q_OS_OS2)
  1319. if (!pref->use_mplayer_window) {
  1320. proc->addArgument( "-input" );
  1321. if (MplayerVersion::isMplayerAtLeast(29058)) {
  1322. proc->addArgument( "nodefault-bindings:conf=/dev/null" );
  1323. } else {
  1324. proc->addArgument( "conf=" + Paths::dataPath() +"/input.conf" );
  1325. }
  1326. }
  1327. #endif
  1328. #ifdef Q_WS_X11
  1329. if (pref->disable_screensaver) {
  1330. proc->addArgument("-stop-xscreensaver");
  1331. } else {
  1332. proc->addArgument("-nostop-xscreensaver");
  1333. }
  1334. #endif
  1335. if (!pref->use_mplayer_window) {
  1336. proc->addArgument("-wid");
  1337. #if defined(Q_OS_OS2)
  1338. #define WINIDFROMHWND(hwnd) ( ( hwnd ) - 0x80000000UL )
  1339. proc->addArgument( QString::number( WINIDFROMHWND( (int) mplayerwindow->videoLayer()->winId() ) ));
  1340. #else
  1341. proc->addArgument( QString::number( (qint64) mplayerwindow->videoLayer()->winId() ) );
  1342. #endif
  1343. #if USE_COLORKEY
  1344. #if defined(Q_OS_WIN) || defined(Q_OS_OS2)
  1345. if ((pref->vo.startsWith("directx")) || (pref->vo.startsWith("kva")) || (pref->vo.isEmpty())) {
  1346. proc->addArgument("-colorkey");
  1347. //proc->addArgument( "0x"+QString::number(pref->color_key, 16) );
  1348. proc->addArgument( ColorUtils::colorToRGB(pref->color_key) );
  1349. } else {
  1350. #endif
  1351. qDebug("Core::startMplayer: * not using -colorkey for %s", pref->vo.toUtf8().data());
  1352. qDebug("Core::startMplayer: * report if you can't see the video");
  1353. #if defined(Q_OS_WIN) || defined(Q_OS_OS2)
  1354. }
  1355. #endif
  1356. #endif
  1357. // Square pixels
  1358. proc->addArgument("-monitorpixelaspect");
  1359. proc->addArgument("1");
  1360. } else {
  1361. // no -wid
  1362. if (!pref->monitor_aspect.isEmpty()) {
  1363. proc->addArgument("-monitoraspect");
  1364. proc->addArgument( pref->monitor_aspect );
  1365. }
  1366. }
  1367. // Subtitles fonts
  1368. if ((pref->use_ass_subtitles) && (pref->freetype_support)) {
  1369. // ASS:
  1370. proc->addArgument("-ass");
  1371. proc->addArgument("-embeddedfonts");
  1372. proc->addArgument("-ass-line-spacing");
  1373. proc->addArgument(QString::number(pref->ass_line_spacing));
  1374. proc->addArgument( "-ass-font-scale");
  1375. proc->addArgument( QString::number(mset.sub_scale_ass) );
  1376. if (!pref->force_ass_styles) {
  1377. // Load the styles.ass file
  1378. if (!QFile::exists(Paths::subtitleStyleFile())) {
  1379. // If file doesn't exist, create it
  1380. pref->ass_styles.exportStyles(Paths::subtitleStyleFile());
  1381. }
  1382. if (QFile::exists(Paths::subtitleStyleFile())) {
  1383. proc->addArgument("-ass-styles");
  1384. proc->addArgument( Paths::subtitleStyleFile() );
  1385. } else {
  1386. qWarning("Core::startMplayer: '%s' doesn't exist", Paths::subtitleStyleFile().toUtf8().constData());
  1387. }
  1388. } else {
  1389. // Force styles for ass subtitles too
  1390. proc->addArgument("-ass-force-style");
  1391. if (!pref->user_forced_ass_style.isEmpty()) {
  1392. proc->addArgument(pref->user_forced_ass_style);
  1393. } else {
  1394. proc->addArgument(pref->ass_styles.toString());
  1395. }
  1396. }
  1397. // Use the same font for OSD
  1398. #if !defined(Q_OS_OS2)
  1399. if (!pref->ass_styles.fontname.isEmpty()) {
  1400. proc->addArgument("-fontconfig");
  1401. proc->addArgument("-font");
  1402. proc->addArgument( pref->ass_styles.fontname );
  1403. }
  1404. #endif
  1405. // Set the size of OSD
  1406. if (pref->freetype_support) {
  1407. proc->addArgument("-subfont-autoscale");
  1408. proc->addArgument("0");
  1409. proc->addArgument("-subfont-osd-scale");
  1410. proc->addArgument(QString::number(pref->ass_styles.fontsize));
  1411. proc->addArgument("-subfont-text-scale"); // Old versions (like 1.0rc2) need this
  1412. proc->addArgument(QString::number(pref->ass_styles.fontsize));
  1413. }
  1414. } else {
  1415. // NO ASS:
  1416. if (pref->freetype_support) proc->addArgument("-noass");
  1417. #if !defined(Q_OS_OS2)
  1418. if ( (pref->use_fontconfig) && (!pref->font_name.isEmpty()) ) {
  1419. proc->addArgument("-fontconfig");
  1420. proc->addArgument("-font");
  1421. proc->addArgument( pref->font_name );
  1422. }
  1423. #endif
  1424. if ( (!pref->use_fontconfig) && (!pref->font_file.isEmpty()) ) {
  1425. proc->addArgument("-font");
  1426. proc->addArgument( pref->font_file );
  1427. }
  1428. if (pref->freetype_support) {
  1429. proc->addArgument( "-subfont-autoscale");
  1430. proc->addArgument( QString::number( pref->font_autoscale ) );
  1431. proc->addArgument( "-subfont-text-scale");
  1432. proc->addArgument( QString::number(mset.sub_scale) );
  1433. }
  1434. }
  1435. // Subtitle encoding
  1436. {
  1437. QString encoding;
  1438. if ( (pref->use_enca) && (!pref->enca_lang.isEmpty()) ) {
  1439. encoding = "enca:"+ pref->enca_lang;
  1440. if (!pref->subcp.isEmpty()) {
  1441. encoding += ":"+ pref->subcp;
  1442. }
  1443. }
  1444. else
  1445. if (!pref->subcp.isEmpty()) {
  1446. encoding = pref->subcp;
  1447. }
  1448. if (!encoding.isEmpty()) {
  1449. proc->addArgument("-subcp");
  1450. proc->addArgument( encoding );
  1451. }
  1452. }
  1453. if (mset.closed_caption_channel > 0) {
  1454. proc->addArgument("-subcc");
  1455. if (MplayerVersion::isMplayerAtLeast(32607)) {
  1456. proc->addArgument( QString::number( mset.closed_caption_channel ) );
  1457. }
  1458. }
  1459. if (pref->use_forced_subs_only) {
  1460. proc->addArgument("-forcedsubsonly");
  1461. }
  1462. #if PROGRAM_SWITCH
  1463. if ( (mset.current_program_id != MediaSettings::NoneSelected) /*&&
  1464. (mset.current_video_id == MediaSettings::NoneSelected) &&
  1465. (mset.current_audio_id == MediaSettings::NoneSelected)*/ )
  1466. {
  1467. proc->addArgument("-tsprog");
  1468. proc->addArgument( QString::number( mset.current_program_id ) );
  1469. }
  1470. // Don't set video and audio track if using -tsprog
  1471. else {
  1472. #endif
  1473. if (mset.current_video_id != MediaSettings::NoneSelected) {
  1474. proc->addArgument("-vid");
  1475. proc->addArgument( QString::number( mset.current_video_id ) );
  1476. }
  1477. if (mset.current_audio_id != MediaSettings::NoneSelected) {
  1478. // Workaround for MPlayer bug #1321 (http://bugzilla.mplayerhq.hu/show_bug.cgi?id=1321)
  1479. if (mdat.audios.numItems() != 1) {
  1480. proc->addArgument("-aid");
  1481. proc->addArgument( QString::number( mset.current_audio_id ) );
  1482. }
  1483. }
  1484. #if PROGRAM_SWITCH
  1485. }
  1486. #endif
  1487. if (!initial_subtitle.isEmpty()) {
  1488. mset.external_subtitles = initial_subtitle;
  1489. initial_subtitle = "";
  1490. just_loaded_external_subs = true; // Big ugly hack :(
  1491. }
  1492. if (!mset.external_subtitles.isEmpty()) {
  1493. if (QFileInfo(mset.external_subtitles).suffix().toLower()=="idx") {
  1494. // sub/idx subtitles
  1495. QFileInfo fi;
  1496. #ifdef Q_OS_WIN
  1497. if (pref->use_short_pathnames)
  1498. fi.setFile(Helper::shortPathName(mset.external_subtitles));
  1499. else
  1500. #endif
  1501. fi.setFile(mset.external_subtitles);
  1502. QString s = fi.path() +"/"+ fi.completeBaseName();
  1503. qDebug("Core::startMplayer: subtitle file without extension: '%s'", s.toUtf8().data());
  1504. proc->addArgument("-vobsub");
  1505. proc->addArgument( s );
  1506. } else {
  1507. proc->addArgument("-sub");
  1508. #ifdef Q_OS_WIN
  1509. if (pref->use_short_pathnames)
  1510. proc->addArgument(Helper::shortPathName(mset.external_subtitles));
  1511. else
  1512. #endif
  1513. proc->addArgument( mset.external_subtitles );
  1514. }
  1515. }
  1516. if (!mset.external_audio.isEmpty()) {
  1517. proc->addArgument("-audiofile");
  1518. #ifdef Q_OS_WIN
  1519. if (pref->use_short_pathnames)
  1520. proc->addArgument(Helper::shortPathName(mset.external_audio));
  1521. else
  1522. #endif
  1523. proc->addArgument( mset.external_audio );
  1524. }
  1525. proc->addArgument("-subpos");
  1526. proc->addArgument( QString::number(mset.sub_pos) );
  1527. if (mset.audio_delay!=0) {
  1528. proc->addArgument("-delay");
  1529. proc->addArgument( QString::number( (double) mset.audio_delay/1000 ) );
  1530. }
  1531. if (mset.sub_delay!=0) {
  1532. proc->addArgument("-subdelay");
  1533. proc->addArgument( QString::number( (double) mset.sub_delay/1000 ) );
  1534. }
  1535. // Contrast, brightness...
  1536. if (pref->change_video_equalizer_on_startup) {
  1537. if (mset.contrast != 0) {
  1538. proc->addArgument("-contrast");
  1539. proc->addArgument( QString::number( mset.contrast ) );
  1540. }
  1541. if (mset.brightness != 0) {
  1542. proc->addArgument("-brightness");
  1543. proc->addArgument( QString::number( mset.brightness ) );
  1544. }
  1545. if (mset.hue != 0) {
  1546. proc->addArgument("-hue");
  1547. proc->addArgument( QString::number( mset.hue ) );
  1548. }
  1549. if (mset.saturation != 0) {
  1550. proc->addArgument("-saturation");
  1551. proc->addArgument( QString::number( mset.saturation ) );
  1552. }
  1553. }
  1554. // Set volume, requires mplayer svn r27872
  1555. bool use_volume_option = (MplayerVersion::isMplayerAtLeast(27872));
  1556. if (pref->global_volume) {
  1557. if (use_volume_option) {
  1558. proc->addArgument("-volume");
  1559. proc->addArgument( QString::number( pref->volume ) );
  1560. }
  1561. } else {
  1562. if (use_volume_option) {
  1563. proc->addArgument("-volume");
  1564. // Note: mset.volume may not be right, it can be the volume of the previous video if
  1565. // playing a new one, but I think it's better to use anyway the current volume on
  1566. // startup than set it to 0 or something.
  1567. // The right volume will be set later, when the video starts to play.
  1568. proc->addArgument( QString::number( mset.volume ) );
  1569. }
  1570. }
  1571. if (mdat.type==TYPE_DVD) {
  1572. if (!dvd_folder.isEmpty()) {
  1573. proc->addArgument("-dvd-device");
  1574. proc->addArgument( dvd_folder );
  1575. } else {
  1576. qWarning("Core::startMplayer: dvd device is empty!");
  1577. }
  1578. }
  1579. if ((mdat.type==TYPE_VCD) || (mdat.type==TYPE_AUDIO_CD)) {
  1580. if (!pref->cdrom_device.isEmpty()) {
  1581. proc->addArgument("-cdrom-device");
  1582. proc->addArgument( pref->cdrom_device );
  1583. }
  1584. }
  1585. if (mset.current_chapter_id > 0) {
  1586. proc->addArgument("-chapter");
  1587. int chapter = mset.current_chapter_id;
  1588. // Fix for older versions of mplayer:
  1589. if ((mdat.type == TYPE_DVD) && (firstChapter() == 0)) chapter++;
  1590. proc->addArgument( QString::number( chapter ) );
  1591. }
  1592. if (mset.current_angle_id > 0) {
  1593. proc->addArgument("-dvdangle");
  1594. proc->addArgument( QString::number( mset.current_angle_id ) );
  1595. }
  1596. int cache = 0;
  1597. switch (mdat.type) {
  1598. case TYPE_FILE : cache = pref->cache_for_files; break;
  1599. case TYPE_DVD : cache = pref->cache_for_dvds;
  1600. #if DVDNAV_SUPPORT
  1601. if (file.startsWith("dvdnav:")) cache = 0;
  1602. #endif
  1603. break;
  1604. case TYPE_STREAM : cache = pref->cache_for_streams; break;
  1605. case TYPE_VCD : cache = pref->cache_for_vcds; break;
  1606. case TYPE_AUDIO_CD : cache = pref->cache_for_audiocds; break;
  1607. case TYPE_TV : cache = pref->cache_for_tv; break;
  1608. default: cache = 0;
  1609. }
  1610. if (cache > 31) { // Minimum value for cache = 32
  1611. proc->addArgument("-cache");
  1612. proc->addArgument( QString::number( cache ) );
  1613. } else {
  1614. proc->addArgument("-nocache");
  1615. }
  1616. if (mset.speed != 1.0) {
  1617. proc->addArgument("-speed");
  1618. proc->addArgument( QString::number( mset.speed ) );
  1619. }
  1620. if (mdat.type != TYPE_TV) {
  1621. // Play A - B
  1622. if ((mset.A_marker > -1) && (mset.B_marker > mset.A_marker)) {
  1623. proc->addArgument("-ss");
  1624. proc->addArgument( QString::number( mset.A_marker ) );
  1625. proc->addArgument("-endpos");
  1626. proc->addArgument( QString::number( mset.B_marker - mset.A_marker ) );
  1627. }
  1628. else
  1629. // If seek < 5 it's better to allow the video to start from the beginning
  1630. if ((seek >= 5) && (!mset.loop)) {
  1631. proc->addArgument("-ss");
  1632. proc->addArgument( QString::number( seek ) );
  1633. }
  1634. }
  1635. // Enable the OSD later, to avoid a lot of messages to be
  1636. // printed on startup
  1637. proc->addArgument("-osdlevel");
  1638. proc->addArgument( "0" );
  1639. if (pref->use_idx) {
  1640. proc->addArgument("-idx");
  1641. }
  1642. if (mdat.type == TYPE_STREAM) {
  1643. if (pref->prefer_ipv4) {
  1644. proc->addArgument("-prefer-ipv4");
  1645. } else {
  1646. proc->addArgument("-prefer-ipv6");
  1647. }
  1648. }
  1649. if (pref->use_correct_pts != Preferences::Detect) {
  1650. if (pref->use_correct_pts == Preferences::Enabled) {
  1651. proc->addArgument("-correct-pts");
  1652. } else {
  1653. if (pref->mplayer_detected_version > 0) {
  1654. if (MplayerVersion::isMplayerAtLeast(26842)) {
  1655. proc->addArgument("-nocorrect-pts");
  1656. } else {
  1657. proc->addArgument("-no-correct-pts");
  1658. }
  1659. } else {
  1660. qDebug("Core::startMplayer: unknown version of mplayer, not passing -no(-)correct-pts");
  1661. }
  1662. }
  1663. }
  1664. bool force_noslices = false;
  1665. #ifndef Q_OS_WIN
  1666. if ((pref->vdpau.disable_video_filters) && (pref->vo.startsWith("vdpau"))) {
  1667. qDebug("Core::startMplayer: using vdpau, video filters are ignored");
  1668. goto end_video_filters;
  1669. }
  1670. #endif
  1671. // Video filters:
  1672. // Phase
  1673. if (mset.phase_filter) {
  1674. proc->addArgument("-vf-add");
  1675. proc->addArgument( "phase=A" );
  1676. }
  1677. // Deinterlace
  1678. if (mset.current_deinterlacer != MediaSettings::NoDeinterlace) {
  1679. proc->addArgument("-vf-add");
  1680. switch (mset.current_deinterlacer) {
  1681. case MediaSettings::L5: proc->addArgument("pp=l5"); break;
  1682. case MediaSettings::Yadif: proc->addArgument("yadif"); break;
  1683. case MediaSettings::LB: proc->addArgument("pp=lb"); break;
  1684. case MediaSettings::Yadif_1: proc->addArgument("yadif=1"); break;
  1685. case MediaSettings::Kerndeint: proc->addArgument("kerndeint=5"); break;
  1686. }
  1687. }
  1688. // Denoise
  1689. if (mset.current_denoiser != MediaSettings::NoDenoise) {
  1690. proc->addArgument("-vf-add");
  1691. if (mset.current_denoiser==MediaSettings::DenoiseSoft) {
  1692. proc->addArgument( pref->filters->item("denoise_soft").filter() );
  1693. } else {
  1694. proc->addArgument( pref->filters->item("denoise_normal").filter() );
  1695. }
  1696. }
  1697. // Unsharp
  1698. if (mset.current_unsharp != 0) {
  1699. proc->addArgument("-vf-add");
  1700. if (mset.current_unsharp == 1) {
  1701. proc->addArgument( pref->filters->item("blur").filter() );
  1702. } else {
  1703. proc->addArgument( pref->filters->item("sharpen").filter() );
  1704. }
  1705. }
  1706. // Deblock
  1707. if (mset.deblock_filter) {
  1708. proc->addArgument("-vf-add");
  1709. proc->addArgument( pref->filters->item("deblock").filter() );
  1710. }
  1711. // Dering
  1712. if (mset.dering_filter) {
  1713. proc->addArgument("-vf-add");
  1714. proc->addArgument( "pp=dr" );
  1715. }
  1716. // Gradfun
  1717. if (mset.gradfun_filter) {
  1718. proc->addArgument("-vf-add");
  1719. proc->addArgument( pref->filters->item("gradfun").filter() );
  1720. }
  1721. // Upscale
  1722. if (mset.upscaling_filter) {
  1723. int width = DesktopInfo::desktop_size(mplayerwindow).width();
  1724. proc->addArgument("-sws");
  1725. proc->addArgument("9");
  1726. proc->addArgument("-vf-add");
  1727. proc->addArgument("scale="+QString::number(width)+":-2");
  1728. }
  1729. // Addnoise
  1730. if (mset.noise_filter) {
  1731. proc->addArgument("-vf-add");
  1732. proc->addArgument( pref->filters->item("noise").filter() );
  1733. }
  1734. // Postprocessing
  1735. if (mset.postprocessing_filter) {
  1736. proc->addArgument("-vf-add");
  1737. proc->addArgument("pp");
  1738. proc->addArgument("-autoq");
  1739. proc->addArgument( QString::number(pref->autoq) );
  1740. }
  1741. // Letterbox (expand)
  1742. if ((mset.add_letterbox) || (pref->fullscreen && pref->add_blackborders_on_fullscreen)) {
  1743. proc->addArgument("-vf-add");
  1744. proc->addArgument( QString("expand=:::::%1,harddup").arg( DesktopInfo::desktop_aspectRatio(mplayerwindow)) );
  1745. // Note: on some videos (h264 for instance) the subtitles doesn't disappear,
  1746. // appearing the new ones on top of the old ones. It seems adding another
  1747. // filter after expand fixes the problem. I chose harddup 'cos I think
  1748. // it will be harmless in mplayer.
  1749. // Anyway, if you know a proper way to fix the problem, please tell me.
  1750. }
  1751. // Software equalizer
  1752. if ( (pref->use_soft_video_eq) ) {
  1753. proc->addArgument("-vf-add");
  1754. QString eq_filter = "eq2,hue";
  1755. if ( (pref->vo == "gl") || (pref->vo == "gl2")
  1756. #ifdef Q_OS_WIN
  1757. || (pref->vo == "directx:noaccel")
  1758. #endif
  1759. ) eq_filter += ",scale";
  1760. proc->addArgument(eq_filter);
  1761. }
  1762. // Additional video filters, supplied by user
  1763. // File
  1764. if ( !mset.mplayer_additional_video_filters.isEmpty() ) {
  1765. proc->addArgument("-vf-add");
  1766. proc->addArgument( mset.mplayer_additional_video_filters );
  1767. }
  1768. // Global
  1769. if ( !pref->mplayer_additional_video_filters.isEmpty() ) {
  1770. proc->addArgument("-vf-add");
  1771. proc->addArgument( pref->mplayer_additional_video_filters );
  1772. }
  1773. // Filters for subtitles on screenshots
  1774. if ((screenshot_enabled) && (pref->subtitles_on_screenshots))
  1775. {
  1776. if (pref->use_ass_subtitles) {
  1777. proc->addArgument("-vf-add");
  1778. proc->addArgument("ass");
  1779. } else {
  1780. proc->addArgument("-vf-add");
  1781. proc->addArgument("expand=osd=1");
  1782. //proc->addArgument("-noslices");
  1783. force_noslices = true;
  1784. }
  1785. }
  1786. // Rotate
  1787. if (mset.rotate != MediaSettings::NoRotate) {
  1788. proc->addArgument( "-vf-add" );
  1789. proc->addArgument( QString("rotate=%1").arg(mset.rotate) );
  1790. }
  1791. // Flip
  1792. if (mset.flip) {
  1793. proc->addArgument( "-vf-add" );
  1794. // expand + flip doesn't work well, a workaround is to add another
  1795. // filter between them, so that's why harddup is here
  1796. proc->addArgument("harddup,flip");
  1797. }
  1798. // Mirror
  1799. if (mset.mirror) {
  1800. proc->addArgument( "-vf-add" );
  1801. proc->addArgument("mirror");
  1802. }
  1803. // Screenshots
  1804. if (screenshot_enabled) {
  1805. proc->addArgument("-vf-add");
  1806. proc->addArgument("screenshot");
  1807. }
  1808. #ifndef Q_OS_WIN
  1809. end_video_filters:
  1810. #endif
  1811. // slices
  1812. if ((pref->use_slices) && (!force_noslices)) {
  1813. proc->addArgument("-slices");
  1814. } else {
  1815. proc->addArgument("-noslices");
  1816. }
  1817. // Audio channels
  1818. if (mset.audio_use_channels != 0) {
  1819. proc->addArgument("-channels");
  1820. proc->addArgument( QString::number( mset.audio_use_channels ) );
  1821. }
  1822. // Audio filters
  1823. QString af="";
  1824. if (mset.karaoke_filter) {
  1825. af="karaoke";
  1826. }
  1827. // Stereo mode
  1828. if (mset.stereo_mode != 0) {
  1829. if (mset.stereo_mode == MediaSettings::Left)
  1830. af += "channels=2:2:0:1:0:0";
  1831. else
  1832. af += "channels=2:2:1:0:1:1";
  1833. }
  1834. if (mset.extrastereo_filter) {
  1835. if (!af.isEmpty()) af += ",";
  1836. af += "extrastereo";
  1837. }
  1838. if (mset.volnorm_filter) {
  1839. if (!af.isEmpty()) af += ",";
  1840. af += pref->filters->item("volnorm").filter();
  1841. }
  1842. bool use_scaletempo = (pref->use_scaletempo == Preferences::Enabled);
  1843. if (pref->use_scaletempo == Preferences::Detect) {
  1844. use_scaletempo = (MplayerVersion::isMplayerAtLeast(24924));
  1845. }
  1846. if (use_scaletempo) {
  1847. if (!af.isEmpty()) af += ",";
  1848. af += "scaletempo";
  1849. }
  1850. // Audio equalizer
  1851. if (pref->use_audio_equalizer) {
  1852. if (!af.isEmpty()) af += ",";
  1853. af += "equalizer=" + Helper::equalizerListToString(mset.audio_equalizer);
  1854. }
  1855. // Additional audio filters, supplied by user
  1856. // File
  1857. if ( !pref->mplayer_additional_audio_filters.isEmpty() ) {
  1858. if (!af.isEmpty()) af += ",";
  1859. af += pref->mplayer_additional_audio_filters;
  1860. }
  1861. // Global
  1862. if ( !mset.mplayer_additional_audio_filters.isEmpty() ) {
  1863. if (!af.isEmpty()) af += ",";
  1864. af += mset.mplayer_additional_audio_filters;
  1865. }
  1866. if (!af.isEmpty()) {
  1867. // Don't use audio filters if using the S/PDIF output
  1868. if (pref->use_hwac3) {
  1869. qDebug("Core::startMplayer: audio filters are disabled when using the S/PDIF output!");
  1870. } else {
  1871. proc->addArgument("-af");
  1872. proc->addArgument( af );
  1873. }
  1874. }
  1875. if (pref->use_soft_vol) {
  1876. proc->addArgument("-softvol");
  1877. proc->addArgument("-softvol-max");
  1878. proc->addArgument( QString::number(pref->softvol_max) );
  1879. }
  1880. // Load edl file
  1881. if (pref->use_edl_files) {
  1882. QString edl_f;
  1883. QFileInfo f(file);
  1884. QString basename = f.path() + "/" + f.completeBaseName();
  1885. qDebug("Core::startMplayer: file basename: '%s'", basename.toUtf8().data());
  1886. if (QFile::exists(basename+".edl"))
  1887. edl_f = basename+".edl";
  1888. else
  1889. if (QFile::exists(basename+".EDL"))
  1890. edl_f = basename+".EDL";
  1891. qDebug("Core::startMplayer: edl file: '%s'", edl_f.toUtf8().data());
  1892. if (!edl_f.isEmpty()) {
  1893. proc->addArgument("-edl");
  1894. proc->addArgument(edl_f);
  1895. }
  1896. }
  1897. // Additional options supplied by the user
  1898. // File
  1899. if (!mset.mplayer_additional_options.isEmpty()) {
  1900. QStringList args = MyProcess::splitArguments(mset.mplayer_additional_options);
  1901. QStringList::Iterator it = args.begin();
  1902. while( it != args.end() ) {
  1903. proc->addArgument( (*it) );
  1904. ++it;
  1905. }
  1906. }
  1907. // Global
  1908. if (!pref->mplayer_additional_options.isEmpty()) {
  1909. QStringList args = MyProcess::splitArguments(pref->mplayer_additional_options);
  1910. QStringList::Iterator it = args.begin();
  1911. while( it != args.end() ) {
  1912. proc->addArgument( (*it) );
  1913. ++it;
  1914. }
  1915. }
  1916. // File to play
  1917. if (url_is_playlist) {
  1918. proc->addArgument("-playlist");
  1919. }
  1920. #ifdef Q_OS_WIN
  1921. if (pref->use_short_pathnames)
  1922. proc->addArgument(Helper::shortPathName(file));
  1923. else
  1924. #endif
  1925. proc->addArgument( file );
  1926. // It seems the loop option must be after the filename
  1927. if (mset.loop) {
  1928. proc->addArgument("-loop");
  1929. proc->addArgument("0");
  1930. }
  1931. emit aboutToStartPlaying();
  1932. QString commandline = proc->arguments().join(" ");
  1933. qDebug("Core::startMplayer: command: '%s'", commandline.toUtf8().data());
  1934. //Log command
  1935. QString line_for_log = commandline + "\n";
  1936. emit logLineAvailable(line_for_log);
  1937. if ( !proc->start() ) {
  1938. // error handling
  1939. qWarning("Core::startMplayer: mplayer process didn't start");
  1940. }
  1941. }
  1942. void Core::stopMplayer() {
  1943. qDebug("Core::stopMplayer");
  1944. if (!proc->isRunning()) {
  1945. qWarning("Core::stopMplayer: mplayer in not running!");
  1946. return;
  1947. }
  1948. #ifdef Q_OS_OS2
  1949. QEventLoop eventLoop;
  1950. connect(proc, SIGNAL(processExited()), &eventLoop, SLOT(quit()));
  1951. tellmp("quit");
  1952. QTimer::singleShot(5000, &eventLoop, SLOT(quit()));
  1953. eventLoop.exec(QEventLoop::ExcludeUserInputEvents);
  1954. if (proc->isRunning()) {
  1955. qWarning("Core::stopMplayer: process didn't finish. Killing it...");
  1956. proc->kill();
  1957. }
  1958. #else
  1959. tellmp("quit");
  1960. qDebug("Core::stopMplayer: Waiting mplayer to finish...");
  1961. if (!proc->waitForFinished(5000)) {
  1962. qWarning("Core::stopMplayer: process didn't finish. Killing it...");
  1963. proc->kill();
  1964. }
  1965. #endif
  1966. qDebug("Core::stopMplayer: Finished. (I hope)");
  1967. }
  1968. void Core::goToSec( double sec ) {
  1969. qDebug("Core::goToSec: %f", sec);
  1970. if (sec < 0) sec = 0;
  1971. if (sec > mdat.duration ) sec = mdat.duration - 20;
  1972. tellmp( seek_cmd(sec, 2) );
  1973. }
  1974. void Core::seek(int secs) {
  1975. qDebug("Core::seek: %d", secs);
  1976. if ( (proc->isRunning()) && (secs!=0) ) {
  1977. tellmp( seek_cmd(secs, 0) );
  1978. }
  1979. }
  1980. QString Core::seek_cmd(double secs, int mode) {
  1981. QString s = QString("seek %1 %2").arg(secs).arg(mode);
  1982. if (MplayerVersion::isMplayer2()) {
  1983. //hr-seek
  1984. if (pref->precise_seeking) s += " 1"; else s += " -1";
  1985. }
  1986. return s;
  1987. }
  1988. void Core::sforward() {
  1989. qDebug("Core::sforward");
  1990. seek( pref->seeking1 ); // +10s
  1991. }
  1992. void Core::srewind() {
  1993. qDebug("Core::srewind");
  1994. seek( -pref->seeking1 ); // -10s
  1995. }
  1996. void Core::forward() {
  1997. qDebug("Core::forward");
  1998. seek( pref->seeking2 ); // +1m
  1999. }
  2000. void Core::rewind() {
  2001. qDebug("Core::rewind");
  2002. seek( -pref->seeking2 ); // -1m
  2003. }
  2004. void Core::fastforward() {
  2005. qDebug("Core::fastforward");
  2006. seek( pref->seeking3 ); // +10m
  2007. }
  2008. void Core::fastrewind() {
  2009. qDebug("Core::fastrewind");
  2010. seek( -pref->seeking3 ); // -10m
  2011. }
  2012. void Core::forward(int secs) {
  2013. qDebug("Core::forward: %d", secs);
  2014. seek(secs);
  2015. }
  2016. void Core::rewind(int secs) {
  2017. qDebug("Core::rewind: %d", secs);
  2018. seek(-secs);
  2019. }
  2020. void Core::wheelUp() {
  2021. qDebug("Core::wheelUp");
  2022. switch (pref->wheel_function) {
  2023. case Preferences::Volume : incVolume(); break;
  2024. case Preferences::Zoom : incZoom(); break;
  2025. case Preferences::Seeking : pref->wheel_function_seeking_reverse ? rewind( pref->seeking4 ) : forward( pref->seeking4 ); break;
  2026. case Preferences::ChangeSpeed : incSpeed10(); break;
  2027. default : {} // do nothing
  2028. }
  2029. }
  2030. void Core::wheelDown() {
  2031. qDebug("Core::wheelDown");
  2032. switch (pref->wheel_function) {
  2033. case Preferences::Volume : decVolume(); break;
  2034. case Preferences::Zoom : decZoom(); break;
  2035. case Preferences::Seeking : pref->wheel_function_seeking_reverse ? forward( pref->seeking4 ) : rewind( pref->seeking4 ); break;
  2036. case Preferences::ChangeSpeed : decSpeed10(); break;
  2037. default : {} // do nothing
  2038. }
  2039. }
  2040. void Core::setAMarker() {
  2041. setAMarker((int)mset.current_sec);
  2042. }
  2043. void Core::setAMarker(int sec) {
  2044. qDebug("Core::setAMarker: %d", sec);
  2045. mset.A_marker = sec;
  2046. displayMessage( tr("\"A\" marker set to %1").arg(Helper::formatTime(sec)) );
  2047. if (mset.B_marker > mset.A_marker) {
  2048. if (proc->isRunning()) restartPlay();
  2049. }
  2050. emit ABMarkersChanged(mset.A_marker, mset.B_marker);
  2051. }
  2052. void Core::setBMarker() {
  2053. setBMarker((int)mset.current_sec);
  2054. }
  2055. void Core::setBMarker(int sec) {
  2056. qDebug("Core::setBMarker: %d", sec);
  2057. mset.B_marker = sec;
  2058. displayMessage( tr("\"B\" marker set to %1").arg(Helper::formatTime(sec)) );
  2059. if ((mset.A_marker > -1) && (mset.A_marker < mset.B_marker)) {
  2060. if (proc->isRunning()) restartPlay();
  2061. }
  2062. emit ABMarkersChanged(mset.A_marker, mset.B_marker);
  2063. }
  2064. void Core::clearABMarkers() {
  2065. qDebug("Core::clearABMarkers");
  2066. if ((mset.A_marker != -1) || (mset.B_marker != -1)) {
  2067. mset.A_marker = -1;
  2068. mset.B_marker = -1;
  2069. displayMessage( tr("A-B markers cleared") );
  2070. if (proc->isRunning()) restartPlay();
  2071. }
  2072. emit ABMarkersChanged(mset.A_marker, mset.B_marker);
  2073. }
  2074. void Core::toggleRepeat() {
  2075. qDebug("Core::toggleRepeat");
  2076. toggleRepeat( !mset.loop );
  2077. }
  2078. void Core::toggleRepeat(bool b) {
  2079. qDebug("Core::toggleRepeat: %d", b);
  2080. if ( mset.loop != b ) {
  2081. mset.loop = b;
  2082. if (MplayerVersion::isMplayerAtLeast(23747)) {
  2083. // Use slave command
  2084. int v = -1; // no loop
  2085. if (mset.loop) v = 0; // infinite loop
  2086. tellmp( QString("loop %1 1").arg(v) );
  2087. } else {
  2088. // Restart mplayer
  2089. if (proc->isRunning()) restartPlay();
  2090. }
  2091. }
  2092. }
  2093. void Core::toggleFlip() {
  2094. qDebug("Core::toggleFlip");
  2095. toggleFlip( !mset.flip );
  2096. }
  2097. void Core::toggleFlip(bool b) {
  2098. qDebug("Core::toggleFlip: %d", b);
  2099. if (mset.flip != b) {
  2100. mset.flip = b;
  2101. if (proc->isRunning()) restartPlay();
  2102. }
  2103. }
  2104. void Core::toggleMirror() {
  2105. qDebug("Core::toggleMirror");
  2106. toggleMirror( !mset.mirror );
  2107. }
  2108. void Core::toggleMirror(bool b) {
  2109. qDebug("Core::toggleMirror: %d", b);
  2110. if (mset.mirror != b) {
  2111. mset.mirror = b;
  2112. if (proc->isRunning()) restartPlay();
  2113. }
  2114. }
  2115. // Audio filters
  2116. void Core::toggleKaraoke() {
  2117. toggleKaraoke( !mset.karaoke_filter );
  2118. }
  2119. void Core::toggleKaraoke(bool b) {
  2120. qDebug("Core::toggleKaraoke: %d", b);
  2121. if (b != mset.karaoke_filter) {
  2122. mset.karaoke_filter = b;
  2123. if (MplayerVersion::isMplayerAtLeast(31030)) {
  2124. // Change filter without restarting
  2125. if (b) tellmp("af_add karaoke"); else tellmp("af_del karaoke");
  2126. } else {
  2127. restartPlay();
  2128. }
  2129. }
  2130. }
  2131. void Core::toggleExtrastereo() {
  2132. toggleExtrastereo( !mset.extrastereo_filter );
  2133. }
  2134. void Core::toggleExtrastereo(bool b) {
  2135. qDebug("Core::toggleExtrastereo: %d", b);
  2136. if (b != mset.extrastereo_filter) {
  2137. mset.extrastereo_filter = b;
  2138. if (MplayerVersion::isMplayerAtLeast(31030)) {
  2139. // Change filter without restarting
  2140. if (b) tellmp("af_add extrastereo"); else tellmp("af_del extrastereo");
  2141. } else {
  2142. restartPlay();
  2143. }
  2144. }
  2145. }
  2146. void Core::toggleVolnorm() {
  2147. toggleVolnorm( !mset.volnorm_filter );
  2148. }
  2149. void Core::toggleVolnorm(bool b) {
  2150. qDebug("Core::toggleVolnorm: %d", b);
  2151. if (b != mset.volnorm_filter) {
  2152. mset.volnorm_filter = b;
  2153. if (MplayerVersion::isMplayerAtLeast(31030)) {
  2154. // Change filter without restarting
  2155. QString f = pref->filters->item("volnorm").filter();
  2156. if (b) tellmp("af_add " + f); else tellmp("af_del volnorm");
  2157. } else {
  2158. restartPlay();
  2159. }
  2160. }
  2161. }
  2162. void Core::setAudioChannels(int channels) {
  2163. qDebug("Core::setAudioChannels:%d", channels);
  2164. if (channels != mset.audio_use_channels ) {
  2165. mset.audio_use_channels = channels;
  2166. restartPlay();
  2167. }
  2168. }
  2169. void Core::setStereoMode(int mode) {
  2170. qDebug("Core::setStereoMode:%d", mode);
  2171. if (mode != mset.stereo_mode ) {
  2172. mset.stereo_mode = mode;
  2173. restartPlay();
  2174. }
  2175. }
  2176. // Video filters
  2177. void Core::toggleAutophase() {
  2178. toggleAutophase( !mset.phase_filter );
  2179. }
  2180. void Core::toggleAutophase( bool b ) {
  2181. qDebug("Core::toggleAutophase: %d", b);
  2182. if ( b != mset.phase_filter) {
  2183. mset.phase_filter = b;
  2184. restartPlay();
  2185. }
  2186. }
  2187. void Core::toggleDeblock() {
  2188. toggleDeblock( !mset.deblock_filter );
  2189. }
  2190. void Core::toggleDeblock(bool b) {
  2191. qDebug("Core::toggleDeblock: %d", b);
  2192. if ( b != mset.deblock_filter ) {
  2193. mset.deblock_filter = b;
  2194. restartPlay();
  2195. }
  2196. }
  2197. void Core::toggleDering() {
  2198. toggleDering( !mset.dering_filter );
  2199. }
  2200. void Core::toggleDering(bool b) {
  2201. qDebug("Core::toggleDering: %d", b);
  2202. if ( b != mset.dering_filter) {
  2203. mset.dering_filter = b;
  2204. restartPlay();
  2205. }
  2206. }
  2207. void Core::toggleGradfun() {
  2208. toggleGradfun( !mset.gradfun_filter );
  2209. }
  2210. void Core::toggleGradfun(bool b) {
  2211. qDebug("Core::toggleGradfun: %d", b);
  2212. if ( b != mset.gradfun_filter) {
  2213. mset.gradfun_filter = b;
  2214. restartPlay();
  2215. }
  2216. }
  2217. void Core::toggleNoise() {
  2218. toggleNoise( !mset.noise_filter );
  2219. }
  2220. void Core::toggleNoise(bool b) {
  2221. qDebug("Core::toggleNoise: %d", b);
  2222. if ( b!= mset.noise_filter ) {
  2223. mset.noise_filter = b;
  2224. restartPlay();
  2225. }
  2226. }
  2227. void Core::togglePostprocessing() {
  2228. togglePostprocessing( !mset.postprocessing_filter );
  2229. }
  2230. void Core::togglePostprocessing(bool b) {
  2231. qDebug("Core::togglePostprocessing: %d", b);
  2232. if ( b != mset.postprocessing_filter ) {
  2233. mset.postprocessing_filter = b;
  2234. restartPlay();
  2235. }
  2236. }
  2237. void Core::changeDenoise(int id) {
  2238. qDebug( "Core::changeDenoise: %d", id );
  2239. if (id != mset.current_denoiser) {
  2240. mset.current_denoiser = id;
  2241. restartPlay();
  2242. }
  2243. }
  2244. void Core::changeUnsharp(int id) {
  2245. qDebug( "Core::changeUnsharp: %d", id );
  2246. if (id != mset.current_unsharp) {
  2247. mset.current_unsharp = id;
  2248. restartPlay();
  2249. }
  2250. }
  2251. void Core::changeUpscale(bool b) {
  2252. qDebug( "Core::changeUpscale: %d", b );
  2253. if (mset.upscaling_filter != b) {
  2254. mset.upscaling_filter = b;
  2255. restartPlay();
  2256. }
  2257. }
  2258. void Core::setBrightness(int value) {
  2259. qDebug("Core::setBrightness: %d", value);
  2260. if (value > 100) value = 100;
  2261. if (value < -100) value = -100;
  2262. if (value != mset.brightness) {
  2263. tellmp(pausing_prefix() + " brightness " + QString::number(value) + " 1");
  2264. mset.brightness = value;
  2265. displayMessage( tr("Brightness: %1").arg(value) );
  2266. emit videoEqualizerNeedsUpdate();
  2267. }
  2268. }
  2269. void Core::setContrast(int value) {
  2270. qDebug("Core::setContrast: %d", value);
  2271. if (value > 100) value = 100;
  2272. if (value < -100) value = -100;
  2273. if (value != mset.contrast) {
  2274. tellmp(pausing_prefix() + " contrast " + QString::number(value) + " 1");
  2275. mset.contrast = value;
  2276. displayMessage( tr("Contrast: %1").arg(value) );
  2277. emit videoEqualizerNeedsUpdate();
  2278. }
  2279. }
  2280. void Core::setGamma(int value) {
  2281. qDebug("Core::setGamma: %d", value);
  2282. if (value > 100) value = 100;
  2283. if (value < -100) value = -100;
  2284. if (value != mset.gamma) {
  2285. tellmp(pausing_prefix() + " gamma " + QString::number(value) + " 1");
  2286. mset.gamma= value;
  2287. displayMessage( tr("Gamma: %1").arg(value) );
  2288. emit videoEqualizerNeedsUpdate();
  2289. }
  2290. }
  2291. void Core::setHue(int value) {
  2292. qDebug("Core::setHue: %d", value);
  2293. if (value > 100) value = 100;
  2294. if (value < -100) value = -100;
  2295. if (value != mset.hue) {
  2296. tellmp(pausing_prefix() + " hue " + QString::number(value) + " 1");
  2297. mset.hue = value;
  2298. displayMessage( tr("Hue: %1").arg(value) );
  2299. emit videoEqualizerNeedsUpdate();
  2300. }
  2301. }
  2302. void Core::setSaturation(int value) {
  2303. qDebug("Core::setSaturation: %d", value);
  2304. if (value > 100) value = 100;
  2305. if (value < -100) value = -100;
  2306. if (value != mset.saturation) {
  2307. tellmp(pausing_prefix() + " saturation " + QString::number(value) + " 1");
  2308. mset.saturation = value;
  2309. displayMessage( tr("Saturation: %1").arg(value) );
  2310. emit videoEqualizerNeedsUpdate();
  2311. }
  2312. }
  2313. void Core::incBrightness() {
  2314. setBrightness(mset.brightness + 4);
  2315. }
  2316. void Core::decBrightness() {
  2317. setBrightness(mset.brightness - 4);
  2318. }
  2319. void Core::incContrast() {
  2320. setContrast(mset.contrast + 4);
  2321. }
  2322. void Core::decContrast() {
  2323. setContrast(mset.contrast - 4);
  2324. }
  2325. void Core::incGamma() {
  2326. setGamma(mset.gamma + 4);
  2327. }
  2328. void Core::decGamma() {
  2329. setGamma(mset.gamma - 4);
  2330. }
  2331. void Core::incHue() {
  2332. setHue(mset.hue + 4);
  2333. }
  2334. void Core::decHue() {
  2335. setHue(mset.hue - 4);
  2336. }
  2337. void Core::incSaturation() {
  2338. setSaturation(mset.saturation + 4);
  2339. }
  2340. void Core::decSaturation() {
  2341. setSaturation(mset.saturation - 4);
  2342. }
  2343. void Core::setSpeed( double value ) {
  2344. qDebug("Core::setSpeed: %f", value);
  2345. if (value < 0.10) value = 0.10;
  2346. if (value > 100) value = 100;
  2347. mset.speed = value;
  2348. tellmp( "speed_set " + QString::number( value ) );
  2349. displayMessage( tr("Speed: %1").arg(value) );
  2350. }
  2351. void Core::incSpeed10() {
  2352. qDebug("Core::incSpeed10");
  2353. setSpeed( (double) mset.speed + 0.1 );
  2354. }
  2355. void Core::decSpeed10() {
  2356. qDebug("Core::decSpeed10");
  2357. setSpeed( (double) mset.speed - 0.1 );
  2358. }
  2359. void Core::incSpeed4() {
  2360. qDebug("Core::incSpeed4");
  2361. setSpeed( (double) mset.speed + 0.04 );
  2362. }
  2363. void Core::decSpeed4() {
  2364. qDebug("Core::decSpeed4");
  2365. setSpeed( (double) mset.speed - 0.04 );
  2366. }
  2367. void Core::incSpeed1() {
  2368. qDebug("Core::incSpeed1");
  2369. setSpeed( (double) mset.speed + 0.01 );
  2370. }
  2371. void Core::decSpeed1() {
  2372. qDebug("Core::decSpeed1");
  2373. setSpeed( (double) mset.speed - 0.01 );
  2374. }
  2375. void Core::doubleSpeed() {
  2376. qDebug("Core::doubleSpeed");
  2377. setSpeed( (double) mset.speed * 2 );
  2378. }
  2379. void Core::halveSpeed() {
  2380. qDebug("Core::halveSpeed");
  2381. setSpeed( (double) mset.speed / 2 );
  2382. }
  2383. void Core::normalSpeed() {
  2384. setSpeed(1);
  2385. }
  2386. void Core::setVolume(int volume, bool force) {
  2387. qDebug("Core::setVolume: %d", volume);
  2388. int current_volume = (pref->global_volume ? pref->volume : mset.volume);
  2389. if ((volume == current_volume) && (!force)) return;
  2390. current_volume = volume;
  2391. if (current_volume > 100) current_volume = 100;
  2392. if (current_volume < 0) current_volume = 0;
  2393. if (state() == Paused) {
  2394. // Change volume later, after quiting pause
  2395. change_volume_after_unpause = true;
  2396. } else {
  2397. tellmp("volume " + QString::number(current_volume) + " 1");
  2398. }
  2399. if (pref->global_volume) {
  2400. pref->volume = current_volume;
  2401. pref->mute = false;
  2402. } else {
  2403. mset.volume = current_volume;
  2404. mset.mute = false;
  2405. }
  2406. updateWidgets();
  2407. displayMessage( tr("Volume: %1").arg(current_volume) );
  2408. emit volumeChanged( current_volume );
  2409. }
  2410. void Core::switchMute() {
  2411. qDebug("Core::switchMute");
  2412. mset.mute = !mset.mute;
  2413. mute(mset.mute);
  2414. }
  2415. void Core::mute(bool b) {
  2416. qDebug("Core::mute");
  2417. int v = (b ? 1 : 0);
  2418. tellmp( pausing_prefix() + " mute " + QString::number(v) );
  2419. if (pref->global_volume) {
  2420. pref->mute = b;
  2421. } else {
  2422. mset.mute = b;
  2423. }
  2424. updateWidgets();
  2425. }
  2426. void Core::incVolume() {
  2427. qDebug("Core::incVolume");
  2428. int new_vol = (pref->global_volume ? pref->volume + 4 : mset.volume + 4);
  2429. setVolume(new_vol);
  2430. }
  2431. void Core::decVolume() {
  2432. qDebug("Core::incVolume");
  2433. int new_vol = (pref->global_volume ? pref->volume - 4 : mset.volume - 4);
  2434. setVolume(new_vol);
  2435. }
  2436. void Core::setSubDelay(int delay) {
  2437. qDebug("Core::setSubDelay: %d", delay);
  2438. mset.sub_delay = delay;
  2439. tellmp( pausing_prefix() + " sub_delay " + QString::number( (double) mset.sub_delay/1000 ) +" 1");
  2440. displayMessage( tr("Subtitle delay: %1 ms").arg(delay) );
  2441. }
  2442. void Core::incSubDelay() {
  2443. qDebug("Core::incSubDelay");
  2444. setSubDelay(mset.sub_delay + 100);
  2445. }
  2446. void Core::decSubDelay() {
  2447. qDebug("Core::decSubDelay");
  2448. setSubDelay(mset.sub_delay - 100);
  2449. }
  2450. void Core::setAudioDelay(int delay) {
  2451. qDebug("Core::setAudioDelay: %d", delay);
  2452. mset.audio_delay = delay;
  2453. tellmp( pausing_prefix() + " audio_delay " + QString::number( (double) mset.audio_delay/1000 ) +" 1");
  2454. displayMessage( tr("Audio delay: %1 ms").arg(delay) );
  2455. }
  2456. void Core::incAudioDelay() {
  2457. qDebug("Core::incAudioDelay");
  2458. setAudioDelay(mset.audio_delay + 100);
  2459. }
  2460. void Core::decAudioDelay() {
  2461. qDebug("Core::decAudioDelay");
  2462. setAudioDelay(mset.audio_delay - 100);
  2463. }
  2464. void Core::incSubPos() {
  2465. qDebug("Core::incSubPos");
  2466. mset.sub_pos++;
  2467. if (mset.sub_pos > 100) mset.sub_pos = 100;
  2468. tellmp("sub_pos " + QString::number( mset.sub_pos ) + " 1");
  2469. }
  2470. void Core::decSubPos() {
  2471. qDebug("Core::decSubPos");
  2472. mset.sub_pos--;
  2473. if (mset.sub_pos < 0) mset.sub_pos = 0;
  2474. tellmp("sub_pos " + QString::number( mset.sub_pos ) + " 1");
  2475. }
  2476. bool Core::subscale_need_restart() {
  2477. bool need_restart = false;
  2478. need_restart = (pref->change_sub_scale_should_restart == Preferences::Enabled);
  2479. if (pref->change_sub_scale_should_restart == Preferences::Detect) {
  2480. if (pref->use_ass_subtitles)
  2481. need_restart = (!MplayerVersion::isMplayerAtLeast(25843));
  2482. else
  2483. need_restart = (!MplayerVersion::isMplayerAtLeast(23745));
  2484. }
  2485. return need_restart;
  2486. }
  2487. void Core::changeSubScale(double value) {
  2488. qDebug("Core::changeSubScale: %f", value);
  2489. bool need_restart = subscale_need_restart();
  2490. if (value < 0) value = 0;
  2491. if (pref->use_ass_subtitles) {
  2492. if (value != mset.sub_scale_ass) {
  2493. mset.sub_scale_ass = value;
  2494. if (need_restart) {
  2495. restartPlay();
  2496. } else {
  2497. tellmp("sub_scale " + QString::number( mset.sub_scale_ass ) + " 1");
  2498. }
  2499. displayMessage( tr("Font scale: %1").arg(mset.sub_scale_ass) );
  2500. }
  2501. } else {
  2502. // No ass
  2503. if (value != mset.sub_scale) {
  2504. mset.sub_scale = value;
  2505. if (need_restart) {
  2506. restartPlay();
  2507. } else {
  2508. tellmp("sub_scale " + QString::number( mset.sub_scale ) + " 1");
  2509. }
  2510. displayMessage( tr("Font scale: %1").arg(mset.sub_scale) );
  2511. }
  2512. }
  2513. }
  2514. void Core::incSubScale() {
  2515. double step = 0.20;
  2516. if (pref->use_ass_subtitles) {
  2517. changeSubScale( mset.sub_scale_ass + step );
  2518. } else {
  2519. if (subscale_need_restart()) step = 1;
  2520. changeSubScale( mset.sub_scale + step );
  2521. }
  2522. }
  2523. void Core::decSubScale() {
  2524. double step = 0.20;
  2525. if (pref->use_ass_subtitles) {
  2526. changeSubScale( mset.sub_scale_ass - step );
  2527. } else {
  2528. if (subscale_need_restart()) step = 1;
  2529. changeSubScale( mset.sub_scale - step );
  2530. }
  2531. }
  2532. void Core::incSubStep() {
  2533. qDebug("Core::incSubStep");
  2534. tellmp("sub_step +1");
  2535. }
  2536. void Core::decSubStep() {
  2537. qDebug("Core::decSubStep");
  2538. tellmp("sub_step -1");
  2539. }
  2540. void Core::changeSubVisibility(bool visible) {
  2541. qDebug("Core::changeSubVisilibity: %d", visible);
  2542. pref->sub_visibility = visible;
  2543. tellmp(QString("sub_visibility %1").arg(pref->sub_visibility ? 1 : 0));
  2544. if (pref->sub_visibility)
  2545. displayMessage( tr("Subtitles on") );
  2546. else
  2547. displayMessage( tr("Subtitles off") );
  2548. }
  2549. // Audio equalizer functions
  2550. void Core::setAudioEqualizer(AudioEqualizerList values, bool restart) {
  2551. mset.audio_equalizer = values;
  2552. if (!restart) {
  2553. const char *command = "af_cmdline equalizer ";
  2554. if (!MplayerVersion::isMplayerAtLeast(32505))
  2555. command = "af_eq_set_bands ";
  2556. tellmp( command + Helper::equalizerListToString(values) );
  2557. } else {
  2558. restartPlay();
  2559. }
  2560. emit audioEqualizerNeedsUpdate();
  2561. }
  2562. void Core::updateAudioEqualizer() {
  2563. setAudioEqualizer(mset.audio_equalizer);
  2564. }
  2565. void Core::setAudioEq0(int value) {
  2566. mset.audio_equalizer[0] = value;
  2567. updateAudioEqualizer();
  2568. }
  2569. void Core::setAudioEq1(int value) {
  2570. mset.audio_equalizer[1] = value;
  2571. updateAudioEqualizer();
  2572. }
  2573. void Core::setAudioEq2(int value) {
  2574. mset.audio_equalizer[2] = value;
  2575. updateAudioEqualizer();
  2576. }
  2577. void Core::setAudioEq3(int value) {
  2578. mset.audio_equalizer[3] = value;
  2579. updateAudioEqualizer();
  2580. }
  2581. void Core::setAudioEq4(int value) {
  2582. mset.audio_equalizer[4] = value;
  2583. updateAudioEqualizer();
  2584. }
  2585. void Core::setAudioEq5(int value) {
  2586. mset.audio_equalizer[5] = value;
  2587. updateAudioEqualizer();
  2588. }
  2589. void Core::setAudioEq6(int value) {
  2590. mset.audio_equalizer[6] = value;
  2591. updateAudioEqualizer();
  2592. }
  2593. void Core::setAudioEq7(int value) {
  2594. mset.audio_equalizer[7] = value;
  2595. updateAudioEqualizer();
  2596. }
  2597. void Core::setAudioEq8(int value) {
  2598. mset.audio_equalizer[8] = value;
  2599. updateAudioEqualizer();
  2600. }
  2601. void Core::setAudioEq9(int value) {
  2602. mset.audio_equalizer[9] = value;
  2603. updateAudioEqualizer();
  2604. }
  2605. void Core::changeCurrentSec(double sec) {
  2606. mset.current_sec = sec;
  2607. if (mset.starting_time != -1) {
  2608. mset.current_sec -= mset.starting_time;
  2609. }
  2610. if (state() != Playing) {
  2611. setState(Playing);
  2612. qDebug("Core::changeCurrentSec: mplayer reports that now it's playing");
  2613. //emit mediaStartPlay();
  2614. //emit stateChanged(state());
  2615. }
  2616. emit showTime(mset.current_sec);
  2617. // Emit posChanged:
  2618. static int last_second = 0;
  2619. if (floor(sec)==last_second) return; // Update only once per second
  2620. last_second = (int) floor(sec);
  2621. #ifdef SEEKBAR_RESOLUTION
  2622. int value = 0;
  2623. if ( (mdat.duration > 1) && (mset.current_sec > 1) &&
  2624. (mdat.duration > mset.current_sec) )
  2625. {
  2626. value = ( (int) mset.current_sec * SEEKBAR_RESOLUTION) / (int) mdat.duration;
  2627. }
  2628. emit positionChanged(value);
  2629. #else
  2630. int perc = 0;
  2631. if ( (mdat.duration > 1) && (mset.current_sec > 1) &&
  2632. (mdat.duration > mset.current_sec) )
  2633. {
  2634. perc = ( (int) mset.current_sec * 100) / (int) mdat.duration;
  2635. }
  2636. emit posChanged( perc );
  2637. #endif
  2638. }
  2639. void Core::gotStartingTime(double time) {
  2640. qDebug("Core::gotStartingTime: %f", time);
  2641. qDebug("Core::gotStartingTime: current_sec: %f", mset.current_sec);
  2642. if ((mset.starting_time == -1.0) && (mset.current_sec == 0)) {
  2643. mset.starting_time = time;
  2644. qDebug("Core::gotStartingTime: starting time set to %f", time);
  2645. }
  2646. }
  2647. void Core::changePause() {
  2648. qDebug("Core::changePause");
  2649. qDebug("Core::changePause: mplayer reports that it's paused");
  2650. setState(Paused);
  2651. //emit stateChanged(state());
  2652. }
  2653. void Core::changeDeinterlace(int ID) {
  2654. qDebug("Core::changeDeinterlace: %d", ID);
  2655. if (ID!=mset.current_deinterlacer) {
  2656. mset.current_deinterlacer = ID;
  2657. restartPlay();
  2658. }
  2659. }
  2660. void Core::changeSubtitle(int ID) {
  2661. qDebug("Core::changeSubtitle: %d", ID);
  2662. mset.current_sub_id = ID;
  2663. if (ID==MediaSettings::SubNone) {
  2664. ID=-1;
  2665. }
  2666. if (ID==MediaSettings::NoneSelected) {
  2667. ID=-1;
  2668. qDebug("Core::changeSubtitle: subtitle is NoneSelected, this shouldn't happen. ID set to -1.");
  2669. }
  2670. qDebug("Core::changeSubtitle: ID: %d", ID);
  2671. bool use_new_commands = (pref->use_new_sub_commands == Preferences::Enabled);
  2672. if (pref->use_new_sub_commands == Preferences::Detect) {
  2673. use_new_commands = (MplayerVersion::isMplayerAtLeast(25158));
  2674. }
  2675. if (!use_new_commands) {
  2676. // Old command sub_select
  2677. tellmp( "sub_select " + QString::number(ID) );
  2678. } else {
  2679. // New commands
  2680. int real_id = -1;
  2681. if (ID == -1) {
  2682. tellmp( "sub_source -1" );
  2683. } else {
  2684. bool valid_item = ( (ID >= 0) && (ID < mdat.subs.numItems()) );
  2685. if (!valid_item) qWarning("Core::changeSubtitle: ID: %d is not valid!", ID);
  2686. if ( (mdat.subs.numItems() > 0) && (valid_item) ) {
  2687. real_id = mdat.subs.itemAt(ID).ID();
  2688. switch (mdat.subs.itemAt(ID).type()) {
  2689. case SubData::Vob:
  2690. tellmp( "sub_vob " + QString::number(real_id) );
  2691. break;
  2692. case SubData::Sub:
  2693. tellmp( "sub_demux " + QString::number(real_id) );
  2694. break;
  2695. case SubData::File:
  2696. tellmp( "sub_file " + QString::number(real_id) );
  2697. break;
  2698. default: {
  2699. qWarning("Core::changeSubtitle: unknown type!");
  2700. }
  2701. }
  2702. } else {
  2703. qWarning("Core::changeSubtitle: subtitle list is empty!");
  2704. }
  2705. }
  2706. }
  2707. updateWidgets();
  2708. }
  2709. void Core::nextSubtitle() {
  2710. qDebug("Core::nextSubtitle");
  2711. if ( (mset.current_sub_id == MediaSettings::SubNone) &&
  2712. (mdat.subs.numItems() > 0) )
  2713. {
  2714. changeSubtitle(0);
  2715. }
  2716. else {
  2717. int item = mset.current_sub_id + 1;
  2718. if (item >= mdat.subs.numItems()) {
  2719. item = MediaSettings::SubNone;
  2720. }
  2721. changeSubtitle( item );
  2722. }
  2723. }
  2724. void Core::changeAudio(int ID, bool allow_restart) {
  2725. qDebug("Core::changeAudio: ID: %d, allow_restart: %d", ID, allow_restart);
  2726. if (ID!=mset.current_audio_id) {
  2727. mset.current_audio_id = ID;
  2728. qDebug("changeAudio: ID: %d", ID);
  2729. bool need_restart = false;
  2730. if (allow_restart) {
  2731. need_restart = (pref->fast_audio_change == Preferences::Disabled);
  2732. if (pref->fast_audio_change == Preferences::Detect) {
  2733. need_restart = (!MplayerVersion::isMplayerAtLeast(21441));
  2734. }
  2735. }
  2736. if (need_restart) {
  2737. restartPlay();
  2738. } else {
  2739. tellmp("switch_audio " + QString::number(ID) );
  2740. // Workaround for a mplayer problem in windows,
  2741. // volume is too loud after changing audio.
  2742. // Workaround too for a mplayer problem in linux,
  2743. // the volume is reduced if using -softvol-max.
  2744. if (pref->global_volume) {
  2745. setVolume( pref->volume, true);
  2746. if (pref->mute) mute(true);
  2747. } else {
  2748. setVolume( mset.volume, true );
  2749. if (mset.mute) mute(true); // if muted, mute again
  2750. }
  2751. updateWidgets();
  2752. }
  2753. }
  2754. }
  2755. void Core::nextAudio() {
  2756. qDebug("Core::nextAudio");
  2757. int item = mdat.audios.find( mset.current_audio_id );
  2758. if (item == -1) {
  2759. qWarning("Core::nextAudio: audio ID %d not found!", mset.current_audio_id);
  2760. } else {
  2761. qDebug( "Core::nextAudio: numItems: %d, item: %d", mdat.audios.numItems(), item);
  2762. item++;
  2763. if (item >= mdat.audios.numItems()) item=0;
  2764. int ID = mdat.audios.itemAt(item).ID();
  2765. qDebug( "Core::nextAudio: item: %d, ID: %d", item, ID);
  2766. changeAudio( ID );
  2767. }
  2768. }
  2769. void Core::changeVideo(int ID, bool allow_restart) {
  2770. qDebug("Core::changeVideo: ID: %d, allow_restart: %d", ID, allow_restart);
  2771. if (ID != mset.current_video_id) {
  2772. mset.current_video_id = ID;
  2773. qDebug("Core::changeVideo: ID set to: %d", ID);
  2774. bool need_restart = false;
  2775. if (allow_restart) {
  2776. // afaik lavf doesn't require to restart, any other?
  2777. need_restart = ((mdat.demuxer != "lavf") && (mdat.demuxer != "mpegts"));
  2778. }
  2779. if (need_restart) {
  2780. restartPlay();
  2781. } else {
  2782. if (mdat.demuxer == "nsv") {
  2783. // Workaround a problem with the nsv demuxer
  2784. qWarning("Core::changeVideo: not calling set_property switch_video with nsv to prevent mplayer go crazy");
  2785. } else {
  2786. tellmp("set_property switch_video " + QString::number(ID) );
  2787. }
  2788. }
  2789. }
  2790. }
  2791. void Core::nextVideo() {
  2792. qDebug("Core::nextVideo");
  2793. int item = mdat.videos.find( mset.current_video_id );
  2794. if (item == -1) {
  2795. qWarning("Core::nextVideo: video ID %d not found!", mset.current_video_id);
  2796. } else {
  2797. qDebug( "Core::nextVideo: numItems: %d, item: %d", mdat.videos.numItems(), item);
  2798. item++;
  2799. if (item >= mdat.videos.numItems()) item=0;
  2800. int ID = mdat.videos.itemAt(item).ID();
  2801. qDebug( "Core::nextVideo: item: %d, ID: %d", item, ID);
  2802. changeVideo( ID );
  2803. }
  2804. }
  2805. #if PROGRAM_SWITCH
  2806. void Core::changeProgram(int ID) {
  2807. qDebug("Core::changeProgram: %d", ID);
  2808. if (ID != mset.current_program_id) {
  2809. mset.current_program_id = ID;
  2810. tellmp("set_property switch_program " + QString::number(ID) );
  2811. tellmp("get_property switch_audio");
  2812. tellmp("get_property switch_video");
  2813. /*
  2814. mset.current_video_id = MediaSettings::NoneSelected;
  2815. mset.current_audio_id = MediaSettings::NoneSelected;
  2816. updateWidgets();
  2817. */
  2818. }
  2819. }
  2820. void Core::nextProgram() {
  2821. qDebug("Core::nextProgram");
  2822. // Not implemented yet
  2823. }
  2824. #endif
  2825. void Core::changeTitle(int ID) {
  2826. if (mdat.type == TYPE_VCD) {
  2827. // VCD
  2828. openVCD( ID );
  2829. }
  2830. else
  2831. if (mdat.type == TYPE_AUDIO_CD) {
  2832. // AUDIO CD
  2833. openAudioCD( ID );
  2834. }
  2835. else
  2836. if (mdat.type == TYPE_DVD) {
  2837. #if DVDNAV_SUPPORT
  2838. if (mdat.filename.startsWith("dvdnav:")) {
  2839. tellmp("switch_title " + QString::number(ID));
  2840. } else {
  2841. #endif
  2842. DiscData disc_data = DiscName::split(mdat.filename);
  2843. disc_data.title = ID;
  2844. QString dvd_url = DiscName::join(disc_data);
  2845. openDVD( DiscName::join(disc_data) );
  2846. #if DVDNAV_SUPPORT
  2847. }
  2848. #endif
  2849. }
  2850. }
  2851. void Core::changeChapter(int ID) {
  2852. qDebug("Core::changeChapter: ID: %d", ID);
  2853. if (mdat.type != TYPE_DVD) {
  2854. /*
  2855. if (mdat.chapters.find(ID) > -1) {
  2856. double start = mdat.chapters.item(ID).start();
  2857. qDebug("Core::changeChapter: start: %f", start);
  2858. goToSec(start);
  2859. mset.current_chapter_id = ID;
  2860. } else {
  2861. */
  2862. tellmp("seek_chapter " + QString::number(ID) +" 1");
  2863. mset.current_chapter_id = ID;
  2864. //updateWidgets();
  2865. /*
  2866. }
  2867. */
  2868. } else {
  2869. #if SMART_DVD_CHAPTERS
  2870. if (pref->cache_for_dvds == 0) {
  2871. #else
  2872. if (pref->fast_chapter_change) {
  2873. #endif
  2874. tellmp("seek_chapter " + QString::number(ID) +" 1");
  2875. mset.current_chapter_id = ID;
  2876. updateWidgets();
  2877. } else {
  2878. stopMplayer();
  2879. mset.current_chapter_id = ID;
  2880. //goToPos(0);
  2881. mset.current_sec = 0;
  2882. restartPlay();
  2883. }
  2884. }
  2885. }
  2886. int Core::firstChapter() {
  2887. if ( (MplayerVersion::isMplayerAtLeast(25391)) &&
  2888. (!MplayerVersion::isMplayerAtLeast(29407)) )
  2889. return 1;
  2890. else
  2891. return 0;
  2892. }
  2893. void Core::prevChapter() {
  2894. qDebug("Core::prevChapter");
  2895. int last_chapter = 0;
  2896. int first_chapter = firstChapter();
  2897. int ID = mdat.chapters.itemBeforeTime(mset.current_sec).ID();
  2898. if (ID == -1) {
  2899. last_chapter = mdat.n_chapters + firstChapter() - 1;
  2900. ID = mset.current_chapter_id - 1;
  2901. if (ID < first_chapter) {
  2902. ID = last_chapter;
  2903. }
  2904. }
  2905. changeChapter(ID);
  2906. }
  2907. void Core::nextChapter() {
  2908. qDebug("Core::nextChapter");
  2909. int last_chapter = mdat.n_chapters + firstChapter() - 1;
  2910. int ID = mdat.chapters.itemAfterTime(mset.current_sec).ID();
  2911. if (ID == -1) {
  2912. ID = mset.current_chapter_id + 1;
  2913. if (ID > last_chapter) {
  2914. ID = firstChapter();
  2915. }
  2916. }
  2917. changeChapter(ID);
  2918. }
  2919. void Core::changeAngle(int ID) {
  2920. qDebug("Core::changeAngle: ID: %d", ID);
  2921. if (ID != mset.current_angle_id) {
  2922. mset.current_angle_id = ID;
  2923. restartPlay();
  2924. }
  2925. }
  2926. void Core::changeAspectRatio( int ID ) {
  2927. qDebug("Core::changeAspectRatio: %d", ID);
  2928. mset.aspect_ratio_id = ID;
  2929. double asp = mset.aspectToNum( (MediaSettings::Aspect) ID);
  2930. if (!pref->use_mplayer_window) {
  2931. mplayerwindow->setAspect( asp );
  2932. } else {
  2933. // Using mplayer own window
  2934. if (!mdat.novideo) {
  2935. tellmp("switch_ratio " + QString::number(asp));
  2936. }
  2937. }
  2938. QString asp_name = MediaSettings::aspectToString( (MediaSettings::Aspect) mset.aspect_ratio_id);
  2939. displayMessage( tr("Aspect ratio: %1").arg(asp_name) );
  2940. }
  2941. void Core::nextAspectRatio() {
  2942. // Ordered list
  2943. QList<int> s;
  2944. s << MediaSettings::AspectNone
  2945. << MediaSettings::AspectAuto
  2946. << MediaSettings::Aspect11 // 1
  2947. << MediaSettings::Aspect54 // 1.25
  2948. << MediaSettings::Aspect43 // 1.33
  2949. << MediaSettings::Aspect1410 // 1.4
  2950. << MediaSettings::Aspect32 // 1.5
  2951. << MediaSettings::Aspect149 // 1.55
  2952. << MediaSettings::Aspect1610 // 1.6
  2953. << MediaSettings::Aspect169 // 1.77
  2954. << MediaSettings::Aspect235; // 2.35
  2955. int i = s.indexOf( mset.aspect_ratio_id ) + 1;
  2956. if (i >= s.count()) i = 0;
  2957. int new_aspect_id = s[i];
  2958. changeAspectRatio( new_aspect_id );
  2959. updateWidgets();
  2960. }
  2961. void Core::nextWheelFunction() {
  2962. int a = pref->wheel_function;
  2963. bool done = false;
  2964. if(((int ) pref->wheel_function_cycle)==0)
  2965. return;
  2966. while(!done){
  2967. // get next a
  2968. a = a*2;
  2969. if(a==32)
  2970. a = 2;
  2971. // See if we are done
  2972. if(pref->wheel_function_cycle.testFlag(QFlag(a)))
  2973. done = true;
  2974. }
  2975. pref->wheel_function = a;
  2976. QString m = "";
  2977. switch(a){
  2978. case Preferences::Seeking:
  2979. m = tr("Mouse wheel seeks now");
  2980. break;
  2981. case Preferences::Volume:
  2982. m = tr("Mouse wheel changes volume now");
  2983. break;
  2984. case Preferences::Zoom:
  2985. m = tr("Mouse wheel changes zoom level now");
  2986. break;
  2987. case Preferences::ChangeSpeed:
  2988. m = tr("Mouse wheel changes speed now");
  2989. break;
  2990. }
  2991. displayMessage(m);
  2992. }
  2993. void Core::changeLetterbox(bool b) {
  2994. qDebug("Core::changeLetterbox: %d", b);
  2995. if (mset.add_letterbox != b) {
  2996. mset.add_letterbox = b;
  2997. restartPlay();
  2998. }
  2999. }
  3000. void Core::changeOSD(int v) {
  3001. qDebug("Core::changeOSD: %d", v);
  3002. pref->osd = v;
  3003. tellmp( pausing_prefix() + " osd " + QString::number( pref->osd ) );
  3004. updateWidgets();
  3005. }
  3006. void Core::nextOSD() {
  3007. int osd = pref->osd + 1;
  3008. if (osd > Preferences::SeekTimerTotal) {
  3009. osd = Preferences::None;
  3010. }
  3011. changeOSD( osd );
  3012. }
  3013. void Core::changeRotate(int r) {
  3014. qDebug("Core::changeRotate: %d", r);
  3015. if (mset.rotate != r) {
  3016. mset.rotate = r;
  3017. restartPlay();
  3018. }
  3019. }
  3020. #if USE_ADAPTER
  3021. void Core::changeAdapter(int n) {
  3022. qDebug("Core::changeScreen: %d", n);
  3023. if (pref->adapter != n) {
  3024. pref->adapter = n;
  3025. restartPlay();
  3026. }
  3027. }
  3028. #endif
  3029. void Core::changeSize(int n) {
  3030. if ( /*(n != pref->size_factor) &&*/ (!pref->use_mplayer_window) ) {
  3031. pref->size_factor = n;
  3032. emit needResize(mset.win_width, mset.win_height);
  3033. updateWidgets();
  3034. }
  3035. }
  3036. void Core::toggleDoubleSize() {
  3037. if (pref->size_factor != 100)
  3038. changeSize(100);
  3039. else
  3040. changeSize(200);
  3041. }
  3042. void Core::changeZoom(double p) {
  3043. qDebug("Core::changeZoom: %f", p);
  3044. if (p < ZOOM_MIN) p = ZOOM_MIN;
  3045. mset.zoom_factor = p;
  3046. mplayerwindow->setZoom(p);
  3047. displayMessage( tr("Zoom: %1").arg(mset.zoom_factor) );
  3048. }
  3049. void Core::resetZoom() {
  3050. changeZoom(1.0);
  3051. }
  3052. void Core::autoZoom() {
  3053. double video_aspect = mset.aspectToNum( (MediaSettings::Aspect) mset.aspect_ratio_id);
  3054. if (video_aspect <= 0) {
  3055. QSize w = mplayerwindow->videoLayer()->size();
  3056. video_aspect = (double) w.width() / w.height();
  3057. }
  3058. double screen_aspect = DesktopInfo::desktop_aspectRatio(mplayerwindow);
  3059. double zoom_factor;
  3060. if (video_aspect > screen_aspect)
  3061. zoom_factor = video_aspect / screen_aspect;
  3062. else
  3063. zoom_factor = screen_aspect / video_aspect;
  3064. qDebug("Core::autoZoom: video_aspect: %f", video_aspect);
  3065. qDebug("Core::autoZoom: screen_aspect: %f", screen_aspect);
  3066. qDebug("Core::autoZoom: zoom_factor: %f", zoom_factor);
  3067. changeZoom(zoom_factor);
  3068. }
  3069. void Core::autoZoomFromLetterbox(double aspect) {
  3070. qDebug("Core::autoZoomFromLetterbox: %f", aspect);
  3071. // Probably there's a much easy way to do this, but I'm not good with maths...
  3072. QSize desktop = DesktopInfo::desktop_size(mplayerwindow);
  3073. double video_aspect = mset.aspectToNum( (MediaSettings::Aspect) mset.aspect_ratio_id);
  3074. if (video_aspect <= 0) {
  3075. QSize w = mplayerwindow->videoLayer()->size();
  3076. video_aspect = (double) w.width() / w.height();
  3077. }
  3078. // Calculate size of the video in fullscreen
  3079. QSize video;
  3080. video.setHeight( desktop.height() );;
  3081. video.setWidth( (int) (video.height() * video_aspect) );
  3082. if (video.width() > desktop.width()) {
  3083. video.setWidth( desktop.width() );;
  3084. video.setHeight( (int) (video.width() / video_aspect) );
  3085. }
  3086. qDebug("Core::autoZoomFromLetterbox: max. size of video: %d %d", video.width(), video.height());
  3087. // Calculate the size of the actual video inside the letterbox
  3088. QSize actual_video;
  3089. actual_video.setWidth( video.width() );
  3090. actual_video.setHeight( (int) (actual_video.width() / aspect) );
  3091. qDebug("Core::autoZoomFromLetterbox: calculated size of actual video for aspect %f: %d %d", aspect, actual_video.width(), actual_video.height());
  3092. double zoom_factor = (double) desktop.height() / actual_video.height();
  3093. qDebug("Core::autoZoomFromLetterbox: calculated zoom factor: %f", zoom_factor);
  3094. changeZoom(zoom_factor);
  3095. }
  3096. void Core::autoZoomFor169() {
  3097. autoZoomFromLetterbox((double) 16 / 9);
  3098. }
  3099. void Core::autoZoomFor235() {
  3100. autoZoomFromLetterbox(2.35);
  3101. }
  3102. void Core::incZoom() {
  3103. qDebug("Core::incZoom");
  3104. changeZoom( mset.zoom_factor + ZOOM_STEP );
  3105. }
  3106. void Core::decZoom() {
  3107. qDebug("Core::decZoom");
  3108. changeZoom( mset.zoom_factor - ZOOM_STEP );
  3109. }
  3110. #if USE_MPLAYER_PANSCAN
  3111. void Core::changePanscan(double p) {
  3112. qDebug("Core::changePanscan: %f", p);
  3113. if (p < 0.1) p = 0;
  3114. if (p > 1) p = 1;
  3115. mset.panscan_factor = p;
  3116. tellmp(QString("panscan %1 1").arg(mset.panscan_factor));
  3117. displayMessage( QString("Panscan: %1").arg(mset.panscan_factor) );
  3118. }
  3119. void Core::incPanscan() {
  3120. changePanscan(mset.panscan_factor + .1);
  3121. }
  3122. void Core::decPanscan() {
  3123. changePanscan(mset.panscan_factor - .1);
  3124. }
  3125. #endif
  3126. void Core::showFilenameOnOSD() {
  3127. tellmp("osd_show_property_text \"${filename}\" 5000 0");
  3128. }
  3129. void Core::toggleDeinterlace() {
  3130. qDebug("Core::toggleDeinterlace");
  3131. tellmp("step_property deinterlace");
  3132. }
  3133. void Core::changeUseAss(bool b) {
  3134. qDebug("Core::changeUseAss: %d", b);
  3135. if (pref->use_ass_subtitles != b) {
  3136. pref->use_ass_subtitles = b;
  3137. if (proc->isRunning()) restartPlay();
  3138. }
  3139. }
  3140. void Core::toggleForcedSubsOnly(bool b) {
  3141. qDebug("Core::toggleForcedSubsOnly: %d", b);
  3142. if (pref->use_forced_subs_only != b) {
  3143. pref->use_forced_subs_only = b;
  3144. //if (proc->isRunning()) restartPlay();
  3145. int v = 0;
  3146. if (b) v = 1;
  3147. tellmp( QString("forced_subs_only %1").arg(v) );
  3148. }
  3149. }
  3150. void Core::changeClosedCaptionChannel(int c) {
  3151. qDebug("Core::changeClosedCaptionChannel: %d", c);
  3152. if (c != mset.closed_caption_channel) {
  3153. mset.closed_caption_channel = c;
  3154. if (proc->isRunning()) restartPlay();
  3155. }
  3156. }
  3157. /*
  3158. void Core::nextClosedCaptionChannel() {
  3159. int c = mset.closed_caption_channel;
  3160. c++;
  3161. if (c > 4) c = 0;
  3162. changeClosedCaptionChannel(c);
  3163. }
  3164. void Core::prevClosedCaptionChannel() {
  3165. int c = mset.closed_caption_channel;
  3166. c--;
  3167. if (c < 0) c = 4;
  3168. changeClosedCaptionChannel(c);
  3169. }
  3170. */
  3171. #if DVDNAV_SUPPORT
  3172. // dvdnav buttons
  3173. void Core::dvdnavUp() {
  3174. qDebug("Core::dvdnavUp");
  3175. tellmp("dvdnav up");
  3176. }
  3177. void Core::dvdnavDown() {
  3178. qDebug("Core::dvdnavDown");
  3179. tellmp("dvdnav down");
  3180. }
  3181. void Core::dvdnavLeft() {
  3182. qDebug("Core::dvdnavLeft");
  3183. tellmp("dvdnav left");
  3184. }
  3185. void Core::dvdnavRight() {
  3186. qDebug("Core::dvdnavRight");
  3187. tellmp("dvdnav right");
  3188. }
  3189. void Core::dvdnavMenu() {
  3190. qDebug("Core::dvdnavMenu");
  3191. tellmp("dvdnav menu");
  3192. }
  3193. void Core::dvdnavSelect() {
  3194. qDebug("Core::dvdnavSelect");
  3195. tellmp("dvdnav select");
  3196. }
  3197. void Core::dvdnavPrev() {
  3198. qDebug("Core::dvdnavPrev");
  3199. tellmp("dvdnav prev");
  3200. }
  3201. void Core::dvdnavMouse() {
  3202. qDebug("Core::dvdnavMouse");
  3203. if ((state() == Playing) && (mdat.filename.startsWith("dvdnav:"))) {
  3204. //QPoint p = mplayerwindow->videoLayer()->mapFromGlobal(QCursor::pos());
  3205. //tellmp(QString("set_mouse_pos %1 %2").arg(p.x()).arg(p.y()));
  3206. tellmp("dvdnav mouse");
  3207. }
  3208. }
  3209. #endif
  3210. void Core::displayMessage(QString text) {
  3211. qDebug("Core::displayMessage");
  3212. emit showMessage(text);
  3213. if ((pref->fullscreen) && (state() != Paused)) {
  3214. displayTextOnOSD( text );
  3215. }
  3216. }
  3217. void Core::displayScreenshotName(QString filename) {
  3218. qDebug("Core::displayScreenshotName");
  3219. //QString text = tr("Screenshot saved as %1").arg(filename);
  3220. QString text = QString("Screenshot saved as %1").arg(filename);
  3221. if (MplayerVersion::isMplayer2()) {
  3222. displayTextOnOSD(text, 3000, 1, "");
  3223. }
  3224. else
  3225. if (MplayerVersion::isMplayerAtLeast(27665)) {
  3226. displayTextOnOSD(text, 3000, 1, "pausing_keep_force");
  3227. }
  3228. else
  3229. if (state() != Paused) {
  3230. // Dont' show the message on OSD while in pause, otherwise
  3231. // the video goes forward a frame.
  3232. displayTextOnOSD(text, 3000, 1, "pausing_keep");
  3233. }
  3234. emit showMessage(text);
  3235. }
  3236. void Core::displayUpdatingFontCache() {
  3237. qDebug("Core::displayUpdatingFontCache");
  3238. emit showMessage( tr("Updating the font cache. This may take some seconds...") );
  3239. }
  3240. void Core::gotWindowResolution(int w, int h) {
  3241. qDebug("Core::gotWindowResolution: %d, %d", w, h);
  3242. //double aspect = (double) w/h;
  3243. if (pref->use_mplayer_window) {
  3244. emit noVideo();
  3245. } else {
  3246. if ((pref->resize_method==Preferences::Afterload) && (we_are_restarting)) {
  3247. // Do nothing
  3248. } else {
  3249. emit needResize(w,h);
  3250. }
  3251. }
  3252. mset.win_width = w;
  3253. mset.win_height = h;
  3254. //Override aspect ratio, is this ok?
  3255. //mdat.video_aspect = mset.win_aspect();
  3256. mplayerwindow->setResolution( w, h );
  3257. mplayerwindow->setAspect( mset.win_aspect() );
  3258. }
  3259. void Core::gotNoVideo() {
  3260. // File has no video (a sound file)
  3261. // Reduce size of window
  3262. /*
  3263. mset.win_width = mplayerwindow->size().width();
  3264. mset.win_height = 0;
  3265. mplayerwindow->setResolution( mset.win_width, mset.win_height );
  3266. emit needResize( mset.win_width, mset.win_height );
  3267. */
  3268. //mplayerwindow->showLogo(TRUE);
  3269. emit noVideo();
  3270. }
  3271. void Core::gotVO(QString vo) {
  3272. qDebug("Core::gotVO: '%s'", vo.toUtf8().data() );
  3273. if ( pref->vo.isEmpty()) {
  3274. qDebug("Core::gotVO: saving vo");
  3275. pref->vo = vo;
  3276. }
  3277. }
  3278. void Core::gotAO(QString ao) {
  3279. qDebug("Core::gotAO: '%s'", ao.toUtf8().data() );
  3280. if ( pref->ao.isEmpty()) {
  3281. qDebug("Core::gotAO: saving ao");
  3282. pref->ao = ao;
  3283. }
  3284. }
  3285. void Core::streamTitleChanged(QString title) {
  3286. mdat.stream_title = title;
  3287. emit mediaInfoChanged();
  3288. }
  3289. void Core::streamTitleAndUrlChanged(QString title, QString url) {
  3290. mdat.stream_title = title;
  3291. mdat.stream_url = url;
  3292. emit mediaInfoChanged();
  3293. }
  3294. void Core::sendMediaInfo() {
  3295. qDebug("Core::sendMediaInfo");
  3296. emit mediaPlaying(mdat.filename, mdat.displayName(pref->show_tag_in_window_title));
  3297. }
  3298. //! Called when the state changes
  3299. void Core::watchState(Core::State state) {
  3300. if ((state == Playing) && (change_volume_after_unpause))
  3301. {
  3302. // Delayed volume change
  3303. qDebug("Core::watchState: delayed volume change");
  3304. int volume = (pref->global_volume ? pref->volume : mset.volume);
  3305. tellmp("volume " + QString::number(volume) + " 1");
  3306. change_volume_after_unpause = false;
  3307. }
  3308. }
  3309. void Core::checkIfVideoIsHD() {
  3310. qDebug("Core::checkIfVideoIsHD");
  3311. // Check if the video is in HD and uses ffh264 codec.
  3312. if ((mdat.video_codec=="ffh264") && (mset.win_height >= pref->HD_height)) {
  3313. qDebug("Core::checkIfVideoIsHD: video == ffh264 and height >= %d", pref->HD_height);
  3314. if (!mset.is264andHD) {
  3315. mset.is264andHD = true;
  3316. if (pref->h264_skip_loop_filter == Preferences::LoopDisabledOnHD) {
  3317. qDebug("Core::checkIfVideoIsHD: we're about to restart the video");
  3318. restartPlay();
  3319. }
  3320. }
  3321. } else {
  3322. mset.is264andHD = false;
  3323. // FIXME: if the video was previously marked as HD, and now it's not
  3324. // then the video should restart too.
  3325. }
  3326. }
  3327. #if DELAYED_AUDIO_SETUP_ON_STARTUP && NOTIFY_AUDIO_CHANGES
  3328. #error "DELAYED_AUDIO_SETUP_ON_STARTUP and NOTIFY_AUDIO_CHANGES can't be both defined"
  3329. #endif
  3330. #if DELAYED_AUDIO_SETUP_ON_STARTUP
  3331. void Core::initAudioTrack() {
  3332. qDebug("Core::initAudioTrack");
  3333. // First audio if none selected
  3334. if ( (mset.current_audio_id == MediaSettings::NoneSelected) &&
  3335. (mdat.audios.numItems() > 0) )
  3336. {
  3337. // Don't set mset.current_audio_id here! changeAudio will do.
  3338. // Otherwise changeAudio will do nothing.
  3339. int audio = mdat.audios.itemAt(0).ID(); // First one
  3340. if (mdat.audios.existsItemAt(pref->initial_audio_track-1)) {
  3341. audio = mdat.audios.itemAt(pref->initial_audio_track-1).ID();
  3342. }
  3343. // Check if one of the audio tracks is the user preferred.
  3344. if (!pref->audio_lang.isEmpty()) {
  3345. int res = mdat.audios.findLang( pref->audio_lang );
  3346. if (res != -1) audio = res;
  3347. }
  3348. changeAudio( audio );
  3349. }
  3350. }
  3351. #endif
  3352. #if NOTIFY_AUDIO_CHANGES
  3353. void Core::initAudioTrack(const Tracks & audios) {
  3354. qDebug("Core::initAudioTrack");
  3355. qDebug("Core::initAudioTrack: num_items: %d", mdat.audios.numItems());
  3356. bool restore_audio = ((mdat.audios.numItems() > 0) ||
  3357. (mset.current_audio_id != MediaSettings::NoneSelected));
  3358. mdat.audios = audios;
  3359. qDebug("Core::initAudioTrack: list of audios:");
  3360. mdat.audios.list();
  3361. initializeMenus();
  3362. if (!restore_audio) {
  3363. // Select initial track
  3364. qDebug("Core::initAudioTrack: selecting initial track");
  3365. int audio = mdat.audios.itemAt(0).ID(); // First one
  3366. if (mdat.audios.existsItemAt(pref->initial_audio_track-1)) {
  3367. audio = mdat.audios.itemAt(pref->initial_audio_track-1).ID();
  3368. }
  3369. // Check if one of the audio tracks is the user preferred.
  3370. if (!pref->audio_lang.isEmpty()) {
  3371. int res = mdat.audios.findLang( pref->audio_lang );
  3372. if (res != -1) audio = res;
  3373. }
  3374. changeAudio( audio );
  3375. } else {
  3376. // Try to restore previous audio track
  3377. qDebug("Core::initAudioTrack: restoring audio");
  3378. // Nothing to do, the audio is already set with -aid
  3379. }
  3380. updateWidgets();
  3381. emit audioTracksChanged();
  3382. }
  3383. #endif
  3384. #if NOTIFY_SUB_CHANGES
  3385. void Core::initSubtitleTrack(const SubTracks & subs) {
  3386. qDebug("Core::initSubtitleTrack");
  3387. qDebug("Core::initSubtitleTrack: num_items: %d", mdat.subs.numItems());
  3388. bool restore_subs = ((mdat.subs.numItems() > 0) ||
  3389. (mset.current_sub_id != MediaSettings::NoneSelected));
  3390. // Save current sub
  3391. SubData::Type previous_sub_type = SubData::Sub;
  3392. int previous_sub_id = -1;
  3393. if (mdat.subs.numItems() > 0) {
  3394. if ((mset.current_sub_id != MediaSettings::SubNone) &&
  3395. (mset.current_sub_id != MediaSettings::NoneSelected))
  3396. {
  3397. previous_sub_type = mdat.subs.itemAt(mset.current_sub_id).type();
  3398. previous_sub_id = mdat.subs.itemAt(mset.current_sub_id).ID();
  3399. }
  3400. }
  3401. qDebug("Core::initSubtitleTrack: previous subtitle: type: %d id: %d", previous_sub_type, previous_sub_id);
  3402. mdat.subs = subs;
  3403. qDebug("Core::initSubtitleTrack: list of subtitles:");
  3404. mdat.subs.list();
  3405. initializeMenus();
  3406. if (just_unloaded_external_subs) {
  3407. qDebug("Core::initSubtitleTrack: just_unloaded_external_subs: true");
  3408. restore_subs = false;
  3409. just_unloaded_external_subs = false;
  3410. }
  3411. if (just_loaded_external_subs) {
  3412. qDebug("Core::initSubtitleTrack: just_loaded_external_subs: true");
  3413. restore_subs = false;
  3414. just_loaded_external_subs = false;
  3415. QFileInfo fi(mset.external_subtitles);
  3416. if (fi.suffix().toLower() != "idx") {
  3417. // The loaded subtitle file is the last one, so
  3418. // try to select that one.
  3419. if (mdat.subs.numItems() > 0) {
  3420. int selected_subtitle = mdat.subs.numItems()-1; // If everything fails, use the last one
  3421. // Try to find the subtitle file in the list
  3422. for (int n = 0; n < mdat.subs.numItems(); n++) {
  3423. SubData sub = mdat.subs.itemAt(n);
  3424. if ((sub.type() == SubData::File) && (sub.filename() == mset.external_subtitles)) {
  3425. selected_subtitle = n;
  3426. qDebug("Core::initSubtitleTrack: external subtitle found: #%d", n);
  3427. break;
  3428. }
  3429. }
  3430. changeSubtitle( selected_subtitle );
  3431. goto end;
  3432. }
  3433. }
  3434. }
  3435. if (!restore_subs) {
  3436. // Select initial track
  3437. qDebug("Core::initSubtitleTrack: selecting initial track");
  3438. if (!pref->autoload_sub) {
  3439. changeSubtitle( MediaSettings::SubNone );
  3440. } else {
  3441. //Select first subtitle
  3442. int sub = mdat.subs.selectOne( pref->subtitle_lang, pref->initial_subtitle_track-1 );
  3443. changeSubtitle( sub );
  3444. }
  3445. } else {
  3446. // Try to restore previous subtitle track
  3447. qDebug("Core::initSubtitleTrack: restoring subtitle");
  3448. if (mset.current_sub_id == MediaSettings::SubNone) {
  3449. changeSubtitle( MediaSettings::SubNone );
  3450. }
  3451. else
  3452. if (mset.current_sub_id != MediaSettings::NoneSelected) {
  3453. // Try to find old subtitle
  3454. int item = mset.current_sub_id;
  3455. if (previous_sub_id != -1) {
  3456. int sub_item = mdat.subs.find(previous_sub_type, previous_sub_id);
  3457. if (sub_item > -1) {
  3458. item = sub_item;
  3459. qDebug("Core::initSubtitleTrack: previous subtitle found: %d", sub_item);
  3460. }
  3461. }
  3462. if (item > -1) {
  3463. changeSubtitle(item );
  3464. } else {
  3465. qDebug("Core::initSubtitleTrack: previous subtitle not found!");
  3466. }
  3467. }
  3468. }
  3469. end:
  3470. updateWidgets();
  3471. }
  3472. void Core::setSubtitleTrackAgain(const SubTracks &) {
  3473. qDebug("Core::setSubtitleTrackAgain");
  3474. changeSubtitle( mset.current_sub_id );
  3475. }
  3476. #endif
  3477. #if DVDNAV_SUPPORT
  3478. void Core::dvdTitleChanged(int title) {
  3479. qDebug("Core::dvdTitleChanged: %d", title);
  3480. }
  3481. void Core::durationChanged(double length) {
  3482. qDebug("Core::durationChanged: %f", length);
  3483. mdat.duration = length;
  3484. }
  3485. void Core::askForInfo() {
  3486. if ((state() == Playing) && (mdat.filename.startsWith("dvdnav:"))) {
  3487. tellmp( pausing_prefix() + " get_property length");
  3488. }
  3489. }
  3490. void Core::dvdnavUpdateMousePos(QPoint pos) {
  3491. if ((state() == Playing) && (mdat.filename.startsWith("dvdnav:")) && (dvdnav_title_is_menu)) {
  3492. if (mplayerwindow->videoLayer()->underMouse()) {
  3493. QPoint p = mplayerwindow->videoLayer()->mapFromParent(pos);
  3494. tellmp(QString("set_mouse_pos %1 %2").arg(p.x()).arg(p.y()));
  3495. }
  3496. }
  3497. }
  3498. void Core::dvdTitleIsMenu() {
  3499. qDebug("Core::dvdTitleIsMenu");
  3500. dvdnav_title_is_menu = true;
  3501. }
  3502. void Core::dvdTitleIsMovie() {
  3503. qDebug("Core::dvdTitleIsMovie");
  3504. dvdnav_title_is_menu = false;
  3505. }
  3506. #endif
  3507. QString Core::pausing_prefix() {
  3508. qDebug("Core::pausing_prefix");
  3509. if (MplayerVersion::isMplayer2()) {
  3510. return QString::null;
  3511. }
  3512. else
  3513. if ( (pref->use_pausing_keep_force) &&
  3514. (MplayerVersion::isMplayerAtLeast(27665)) )
  3515. {
  3516. return "pausing_keep_force";
  3517. } else {
  3518. return "pausing_keep";
  3519. }
  3520. }
  3521. #include "moc_core.cpp"