1
/* smplayer, GUI front-end for mplayer.
2
Copyright (C) 2006-2009 Ricardo Villalba <rvm@escomposlinux.org>
4
This program is free software; you can redistribute it and/or modify
5
it under the terms of the GNU General Public License as published by
6
the Free Software Foundation; either version 2 of the License, or
7
(at your option) any later version.
9
This program is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
GNU General Public License for more details.
14
You should have received a copy of the GNU General Public License
15
along with this program; if not, write to the Free Software
16
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23
#include <QTextStream>
27
#include "mplayerwindow.h"
28
#include "desktopinfo.h"
31
#include "preferences.h"
34
#include "mplayerversion.h"
35
#include "constants.h"
36
#include "colorutils.h"
40
#include <windows.h> // To change app priority
41
#include <QSysInfo> // To get Windows version
42
#ifdef SCREENSAVER_OFF
43
#include "screensaver.h"
47
#ifndef NO_USE_INI_FILES
48
#include "filesettings.h"
49
#include "filesettingshash.h"
52
using namespace Global;
54
Core::Core( MplayerWindow *mpw, QWidget* parent )
57
qRegisterMetaType<Core::State>("Core::State");
63
we_are_restarting = false;
64
just_loaded_external_subs = false;
65
just_unloaded_external_subs = false;
66
change_volume_after_unpause = false;
68
#ifndef NO_USE_INI_FILES
69
// Create file_settings
70
#if NEW_SETTINGS_MANAGEMENT
72
changeFileSettingsMethod(pref->file_settings_method);
74
if (Paths::iniPath().isEmpty()) {
75
file_settings = new QSettings(QSettings::IniFormat, QSettings::UserScope,
76
QString(COMPANY), QString("smplayer_files") );
78
QString filename = Paths::iniPath() + "/smplayer_files.ini";
79
file_settings = new QSettings( filename, QSettings::IniFormat );
80
qDebug("Core::Core: file_settings: '%s'", filename.toUtf8().data());
85
proc = new MplayerProcess(this);
88
connect( proc, SIGNAL(processExited()),
89
mplayerwindow->videoLayer(), SLOT(playingStopped()) );
91
connect( proc, SIGNAL(error(QProcess::ProcessError)),
92
mplayerwindow->videoLayer(), SLOT(playingStopped()) );
94
connect( proc, SIGNAL(receivedCurrentSec(double)),
95
this, SLOT(changeCurrentSec(double)) );
97
connect( proc, SIGNAL(receivedCurrentFrame(int)),
98
this, SIGNAL(showFrame(int)) );
100
connect( proc, SIGNAL(receivedPause()),
101
this, SLOT(changePause()) );
103
connect( proc, SIGNAL(processExited()),
104
this, SLOT(processFinished()), Qt::QueuedConnection );
106
connect( proc, SIGNAL(mplayerFullyLoaded()),
107
this, SLOT(finishRestart()), Qt::QueuedConnection );
109
connect( proc, SIGNAL(lineAvailable(QString)),
110
this, SIGNAL(logLineAvailable(QString)) );
112
connect( proc, SIGNAL(receivedCacheMessage(QString)),
113
this, SLOT(displayMessage(QString)) );
115
connect( proc, SIGNAL(receivedCreatingIndex(QString)),
116
this, SLOT(displayMessage(QString)) );
118
connect( proc, SIGNAL(receivedConnectingToMessage(QString)),
119
this, SLOT(displayMessage(QString)) );
121
connect( proc, SIGNAL(receivedResolvingMessage(QString)),
122
this, SLOT(displayMessage(QString)) );
124
connect( proc, SIGNAL(receivedScreenshot(QString)),
125
this, SLOT(displayScreenshotName(QString)) );
127
connect( proc, SIGNAL(receivedUpdatingFontCache()),
128
this, SLOT(displayUpdatingFontCache()) );
130
connect( proc, SIGNAL(receivedWindowResolution(int,int)),
131
this, SLOT(gotWindowResolution(int,int)) );
133
connect( proc, SIGNAL(receivedNoVideo()),
134
this, SLOT(gotNoVideo()) );
136
connect( proc, SIGNAL(receivedVO(QString)),
137
this, SLOT(gotVO(QString)) );
139
connect( proc, SIGNAL(receivedAO(QString)),
140
this, SLOT(gotAO(QString)) );
142
connect( proc, SIGNAL(receivedEndOfFile()),
143
this, SLOT(fileReachedEnd()), Qt::QueuedConnection );
145
connect( proc, SIGNAL(receivedStartingTime(double)),
146
this, SLOT(gotStartingTime(double)) );
148
connect( proc, SIGNAL(receivedStreamTitleAndUrl(QString,QString)),
149
this, SLOT(streamTitleAndUrlChanged(QString,QString)) );
151
connect( proc, SIGNAL(failedToParseMplayerVersion(QString)),
152
this, SIGNAL(failedToParseMplayerVersion(QString)) );
154
connect( this, SIGNAL(mediaLoaded()), this, SLOT(checkIfVideoIsHD()), Qt::QueuedConnection );
155
#if DELAYED_AUDIO_SETUP_ON_STARTUP
156
connect( this, SIGNAL(mediaLoaded()), this, SLOT(initAudioTrack()), Qt::QueuedConnection );
158
#if NOTIFY_SUB_CHANGES
159
connect( proc, SIGNAL(subtitleInfoChanged(const SubTracks &)),
160
this, SLOT(initSubtitleTrack(const SubTracks &)), Qt::QueuedConnection );
161
connect( proc, SIGNAL(subtitleInfoReceivedAgain(const SubTracks &)),
162
this, SLOT(setSubtitleTrackAgain(const SubTracks &)), Qt::QueuedConnection );
164
#if NOTIFY_AUDIO_CHANGES
165
connect( proc, SIGNAL(audioInfoChanged(const Tracks &)),
166
this, SLOT(initAudioTrack(const Tracks &)), Qt::QueuedConnection );
169
connect( proc, SIGNAL(receivedDVDTitle(int)),
170
this, SLOT(dvdTitleChanged(int)), Qt::QueuedConnection );
171
connect( proc, SIGNAL(receivedDuration(double)),
172
this, SLOT(durationChanged(double)), Qt::QueuedConnection );
174
QTimer * ask_timer = new QTimer(this);
175
connect( ask_timer, SIGNAL(timeout()), this, SLOT(askForInfo()) );
176
ask_timer->start(5000);
179
connect( this, SIGNAL(stateChanged(Core::State)),
180
this, SLOT(watchState(Core::State)) );
182
connect( proc, SIGNAL(error(QProcess::ProcessError)),
183
this, SIGNAL(mplayerFailed(QProcess::ProcessError)) );
189
connect( this, SIGNAL(aboutToStartPlaying()),
190
mplayerwindow->videoLayer(), SLOT(playingStarted()) );
192
connect( mplayerwindow, SIGNAL(mouseMoved(QPoint)),
193
this, SLOT(dvdnavUpdateMousePos(QPoint)) );
196
#if REPAINT_BACKGROUND_OPTION
197
mplayerwindow->videoLayer()->setRepaintBackground(pref->repaint_video_background);
199
mplayerwindow->setMonitorAspect( pref->monitor_aspect_double() );
202
#ifdef SCREENSAVER_OFF
203
// Windows screensaver
204
win_screensaver = new WinScreenSaver();
215
#ifndef NO_USE_INI_FILES
219
if (proc->isRunning()) stopMplayer();
223
#ifndef NO_USE_INI_FILES
224
delete file_settings;
228
#ifdef SCREENSAVER_OFF
229
delete win_screensaver;
234
#ifndef NO_USE_INI_FILES
235
void Core::changeFileSettingsMethod(QString method) {
236
#if NEW_SETTINGS_MANAGEMENT
237
qDebug("Core::changeFileSettingsMethod: %s", method.toUtf8().constData());
238
if (file_settings) delete file_settings;
240
if (method.toLower() == "hash")
241
file_settings = new FileSettingsHash(Paths::iniPath());
243
file_settings = new FileSettings(Paths::iniPath());
248
void Core::setState(State s) {
251
emit stateChanged(_state);
255
QString Core::stateToString() {
256
if (state()==Playing) return "Playing";
258
if (state()==Stopped) return "Stopped";
260
if (state()==Paused) return "Paused";
266
void Core::restart() {
267
qDebug("Core::restart");
268
if (proc->isRunning()) {
271
qDebug("Core::restart: mplayer is not running");
275
void Core::reload() {
276
qDebug("Core::reload");
279
we_are_restarting = false;
284
#ifndef NO_USE_INI_FILES
285
#if !NEW_SETTINGS_MANAGEMENT
287
bool Core::checkHaveSettingsSaved(QString group_name) {
288
qDebug("Core::checkHaveSettingsSaved: group_name: '%s'", group_name.toUtf8().data());
290
file_settings->beginGroup( group_name );
291
bool saved = file_settings->value( "saved", false ).toBool();
292
file_settings->endGroup();
297
void Core::loadMediaInfo(QString group_name) {
298
qDebug("Core::loadMediaInfo: '%s'", group_name.toUtf8().data() );
300
file_settings->beginGroup( group_name );
302
/*mdat.load(*settings);*/
303
mset.load(file_settings);
305
file_settings->endGroup();
308
#endif // NEW_SETTINGS_MANAGEMENT
310
void Core::saveMediaInfo() {
311
qDebug("Core::saveMediaInfo");
313
if (pref->dont_remember_media_settings) {
314
qDebug("Core::saveMediaInfo: not saving settings, disabled by user");
318
#if NEW_SETTINGS_MANAGEMENT
319
if ( (mdat.type == TYPE_FILE) && (!mdat.filename.isEmpty()) ) {
320
file_settings->saveSettingsFor(mdat.filename, mset);
326
if ( (mdat.type == TYPE_DVD) && (!mdat.dvd_id.isEmpty()) ) {
327
group_name = dvdForPref( mdat.dvd_id, mset.current_title_id );
331
if ( (mdat.type == TYPE_FILE) && (!mdat.filename.isEmpty()) ) {
332
group_name = FileSettings::filenameToGroupname( mdat.filename );
335
if (!group_name.isEmpty()) {
336
file_settings->beginGroup( group_name );
337
file_settings->setValue( "saved", true);
339
/*mdat.save(*settings);*/
340
mset.save(file_settings);
342
file_settings->endGroup();
344
#endif // NEW_SETTINGS_MANAGEMENT
347
#endif // NO_USE_INI_FILES
349
void Core::initializeMenus() {
350
qDebug("Core::initializeMenus");
352
emit menusNeedInitialize();
356
void Core::updateWidgets() {
357
qDebug("Core::updateWidgets");
359
emit widgetsNeedUpdate();
363
void Core::tellmp(const QString & command) {
364
qDebug("Core::tellmp: '%s'", command.toUtf8().data());
366
//qDebug("Command: '%s'", command.toUtf8().data());
367
if (proc->isRunning()) {
368
proc->writeToStdin( command );
370
qWarning(" tellmp: no process running: %s", command.toUtf8().data());
374
// Generic open, autodetect type
375
void Core::open(QString file, int seek) {
376
qDebug("Core::open: '%s'", file.toUtf8().data());
380
if ( (fi.exists()) && (fi.suffix().toLower()=="iso") ) {
381
qDebug("Core::open: * identified as a dvd iso");
383
openDVD( DiscName::joinDVD(0, file, pref->use_dvdnav) );
385
openDVD( DiscName::joinDVD(1, file, false) );
389
if ( (fi.exists()) && (!fi.isDir()) ) {
390
qDebug("Core::open: * identified as local file");
392
file = QFileInfo(file).absoluteFilePath();
393
openFile(file, seek);
396
if ( (fi.exists()) && (fi.isDir()) ) {
398
qDebug("Core::open: * identified as a directory");
399
qDebug("Core::open: checking if contains a dvd");
400
file = QFileInfo(file).absoluteFilePath();
401
if (Helper::directoryContainsDVD(file)) {
402
qDebug("Core::open: * directory contains a dvd");
404
openDVD( DiscName::joinDVD(1, file, pref->use_dvdnav) );
406
openDVD( DiscName::joinDVD(1, file, false) );
409
qDebug("Core::open: * directory doesn't contain a dvd");
410
qDebug("Core::open: opening nothing");
414
if ((file.toLower().startsWith("dvd:")) || (file.toLower().startsWith("dvdnav:"))) {
415
qDebug("Core::open: * identified as dvd");
418
QString f = file.lower();
419
QRegExp s("^dvd://(\\d+)");
420
if (s.indexIn(f) != -1) {
421
int title = s.cap(1).toInt();
424
qWarning("Core::open: couldn't parse dvd title, playing first one");
430
if (file.toLower().startsWith("vcd:")) {
431
qDebug("Core::open: * identified as vcd");
433
QString f = file.toLower();
434
QRegExp s("^vcd://(\\d+)");
435
if (s.indexIn(f) != -1) {
436
int title = s.cap(1).toInt();
439
qWarning("Core::open: couldn't parse vcd title, playing first one");
444
if (file.toLower().startsWith("cdda:")) {
445
qDebug("Core::open: * identified as cdda");
447
QString f = file.toLower();
448
QRegExp s("^cdda://(\\d+)");
449
if (s.indexIn(f) != -1) {
450
int title = s.cap(1).toInt();
453
qWarning("Core::open: couldn't parse cdda title, playing first one");
458
qDebug("Core::open: * not identified, playing as stream");
463
void Core::openFile(QString filename, int seek) {
464
qDebug("Core::openFile: '%s'", filename.toUtf8().data());
466
QFileInfo fi(filename);
468
playNewFile(fi.absoluteFilePath(), seek);
470
//File doesn't exists
471
//TODO: error message
476
void Core::loadSub(const QString & sub ) {
477
if ( (!sub.isEmpty()) && (QFile::exists(sub)) ) {
478
#if NOTIFY_SUB_CHANGES
479
mset.external_subtitles = sub;
480
just_loaded_external_subs = true;
483
if (fi.suffix().toLower() != "idx") {
484
QString sub_file = sub;
486
if (pref->use_short_pathnames) {
487
sub_file = Helper::shortPathName(sub);
488
// For some reason it seems it's necessary to change the path separator to unix style
489
// otherwise mplayer fails to load it
490
sub_file = sub_file.replace("\\","/");
493
tellmp( "sub_load \""+ sub_file +"\"" );
498
mset.external_subtitles = sub;
499
just_loaded_external_subs = true;
503
qWarning("Core::loadSub: file '%s' is not valid", sub.toUtf8().constData());
507
void Core::unloadSub() {
508
if ( !mset.external_subtitles.isEmpty() ) {
509
mset.external_subtitles = "";
510
just_unloaded_external_subs = true;
515
void Core::loadAudioFile(const QString & audiofile) {
516
if (!audiofile.isEmpty()) {
517
mset.external_audio = audiofile;
522
void Core::unloadAudioFile() {
523
if (!mset.external_audio.isEmpty()) {
524
mset.external_audio = "";
530
void Core::openDVD( bool from_folder, QString directory) {
531
qDebug("Core::openDVD");
534
if (!directory.isEmpty()) {
535
QFileInfo fi(directory);
536
if ( (fi.exists()) && (fi.isDir()) ) {
537
pref->dvd_directory = directory;
538
pref->play_dvd_from_hd = TRUE;
541
qDebug("Core::openDVD: directory '%s' is not valid", directory.toUtf8().data());
544
qDebug("Core::openDVD: directory is empty");
547
pref->play_dvd_from_hd = FALSE;
552
void Core::openDVD() {
556
void Core::openDVD(int title) {
557
qDebug("Core::openDVD: %d", title);
559
if (proc->isRunning()) {
563
// Save data of previous file:
567
mdat.filename = "dvd://" + QString::number(title);
568
mdat.type = TYPE_DVD;
572
mset.current_title_id = title;
573
mset.current_chapter_id = 1;
574
mset.current_angle_id = 1;
582
void Core::openVCD(int title) {
583
qDebug("Core::openVCD: %d", title);
585
if (title == -1) title = pref->vcd_initial_title;
587
if (proc->isRunning()) {
591
// Save data of previous file:
592
#ifndef NO_USE_INI_FILES
597
mdat.filename = "vcd://" + QString::number(title);
598
mdat.type = TYPE_VCD;
602
mset.current_title_id = title;
603
mset.current_chapter_id = -1;
604
mset.current_angle_id = -1;
606
/* initializeMenus(); */
611
void Core::openAudioCD(int title) {
612
qDebug("Core::openAudioCD: %d", title);
614
if (title == -1) title = 1;
616
if (proc->isRunning()) {
620
// Save data of previous file:
621
#ifndef NO_USE_INI_FILES
626
mdat.filename = "cdda://" + QString::number(title);
627
mdat.type = TYPE_AUDIO_CD;
631
mset.current_title_id = title;
632
mset.current_chapter_id = -1;
633
mset.current_angle_id = -1;
635
/* initializeMenus(); */
640
void Core::openDVD(QString dvd_url) {
641
qDebug("Core::openDVD: '%s'", dvd_url.toUtf8().data());
644
DiscData disc_data = DiscName::split(dvd_url);
645
QString folder = disc_data.device;
646
int title = disc_data.title;
649
qWarning("Core::openDVD: title invalid, not playing dvd");
653
if (folder.isEmpty()) {
654
qDebug("Core::openDVD: not folder");
656
QFileInfo fi(folder);
657
if ( (!fi.exists()) /*|| (!fi.isDir())*/ ) {
658
qWarning("Core::openDVD: folder invalid, not playing dvd");
663
if (proc->isRunning()) {
665
we_are_restarting = false;
668
// Save data of previous file:
669
#ifndef NO_USE_INI_FILES
674
mdat.filename = dvd_url;
675
mdat.type = TYPE_DVD;
679
mset.current_title_id = title;
680
#if GENERIC_CHAPTER_SUPPORT
681
mset.current_chapter_id = firstChapter();
683
mset.current_chapter_id = dvdFirstChapter();
685
mset.current_angle_id = 1;
687
/* initializeMenus(); */
692
void Core::openStream(QString name) {
693
qDebug("Core::openStream: '%s'", name.toUtf8().data());
695
if (proc->isRunning()) {
697
we_are_restarting = false;
700
// Save data of previous file:
701
#ifndef NO_USE_INI_FILES
706
mdat.filename = name;
707
mdat.type = TYPE_STREAM;
711
/* initializeMenus(); */
717
void Core::playNewFile(QString file, int seek) {
718
qDebug("Core::playNewFile: '%s'", file.toUtf8().data());
720
if (proc->isRunning()) {
722
we_are_restarting = false;
725
// Save data of previous file:
726
#ifndef NO_USE_INI_FILES
731
mdat.filename = file;
732
mdat.type = TYPE_FILE;
734
int old_volume = mset.volume;
737
#ifndef NO_USE_INI_FILES
738
// Check if we already have info about this file
739
#if NEW_SETTINGS_MANAGEMENT
740
if (file_settings->existSettingsFor(file)) {
742
if (checkHaveSettingsSaved( FileSettings::filenameToGroupname(file) )) {
744
qDebug("Core::playNewFile: We have settings for this file!!!");
746
// In this case we read info from config
747
if (!pref->dont_remember_media_settings) {
748
#if NEW_SETTINGS_MANAGEMENT
749
file_settings->loadSettingsFor(file, mset);
751
loadMediaInfo( FileSettings::filenameToGroupname(file) );
753
qDebug("Core::playNewFile: Media settings read");
755
// Resize the window and set the aspect as soon as possible
756
int saved_width = mset.win_width;
757
int saved_height = mset.win_height;
758
// 400x300 is the default size for win_width and win_height
759
// so we set them to 0 to avoid to resize the window on
761
if ((saved_width == 400) && (saved_height == 300)) {
765
if ((saved_width > 0) && (saved_height > 0)) {
766
emit needResize(mset.win_width, mset.win_height);
767
changeAspectRatio(mset.aspect_ratio_id);
770
if (pref->dont_remember_time_pos) {
771
mset.current_sec = 0;
772
qDebug("Core::playNewFile: Time pos reset to 0");
775
qDebug("Core::playNewFile: Media settings have not read because of preferences setting");
779
mset.volume = old_volume;
783
mset.volume = old_volume;
784
#endif // NO_USE_INI_FILES
786
/* initializeMenus(); */
788
qDebug("Core::playNewFile: volume: %d, old_volume: %d", mset.volume, old_volume);
793
void Core::restartPlay() {
794
we_are_restarting = true;
798
void Core::initPlaying(int seek) {
799
qDebug("Core::initPlaying");
806
/* updateWidgets(); */
808
mplayerwindow->showLogo(FALSE);
810
if (proc->isRunning()) {
814
int start_sec = (int) mset.current_sec;
815
if (seek > -1) start_sec = seek;
817
startMplayer( mdat.filename, start_sec );
820
// This is reached when a new video has just started playing
821
// and maybe we need to give some defaults
822
void Core::newMediaPlaying() {
823
qDebug("Core::newMediaPlaying: --- start ---");
825
QString file = mdat.filename;
826
int type = mdat.type;
827
mdat = proc->mediaData();
828
mdat.filename = file;
831
initializeMenus(); // Old
834
if ( (mset.current_video_id == MediaSettings::NoneSelected) &&
835
(mdat.videos.numItems() > 0) )
837
changeVideo( mdat.videos.itemAt(0).ID(), false ); // Don't allow to restart
840
#if !DELAYED_AUDIO_SETUP_ON_STARTUP && !NOTIFY_AUDIO_CHANGES
841
// First audio if none selected
842
if ( (mset.current_audio_id == MediaSettings::NoneSelected) &&
843
(mdat.audios.numItems() > 0) )
845
// Don't set mset.current_audio_id here! changeAudio will do.
846
// Otherwise changeAudio will do nothing.
848
int audio = mdat.audios.itemAt(0).ID(); // First one
849
if (mdat.audios.existsItemAt(pref->initial_audio_track-1)) {
850
audio = mdat.audios.itemAt(pref->initial_audio_track-1).ID();
853
// Check if one of the audio tracks is the user preferred.
854
if (!pref->audio_lang.isEmpty()) {
855
int res = mdat.audios.findLang( pref->audio_lang );
856
if (res != -1) audio = res;
859
// Change the audio without restarting mplayer, it's not
860
// safe to do it here.
861
changeAudio( audio, false );
866
#if !NOTIFY_SUB_CHANGES
868
if (mset.external_subtitles.isEmpty()) {
869
if (pref->autoload_sub) {
870
//Select first subtitle if none selected
871
if (mset.current_sub_id == MediaSettings::NoneSelected) {
872
int sub = mdat.subs.selectOne( pref->subtitle_lang, pref->initial_subtitle_track-1 );
873
changeSubtitle( sub );
876
changeSubtitle( MediaSettings::SubNone );
881
#if GENERIC_CHAPTER_SUPPORT
882
if (mdat.chapters > 0) {
885
if (mdat.mkv_chapters > 0) {
887
// Just to show the first chapter checked in the menu
888
mset.current_chapter_id = firstChapter();
891
mdat.initialized = TRUE;
893
// MPlayer doesn't display the length in ID_LENGTH for audio CDs...
894
if ((mdat.duration == 0) && (mdat.type == TYPE_AUDIO_CD)) {
896
qDebug(" *** get duration here from title info *** ");
897
qDebug(" *** current title: %d", mset.current_title_id );
899
if (mset.current_title_id > 0) {
900
mdat.duration = mdat.titles.item(mset.current_title_id).duration();
904
/* updateWidgets(); */
909
qDebug("Core::newMediaPlaying: --- end ---");
912
void Core::finishRestart() {
913
qDebug("Core::finishRestart: --- start ---");
915
if (!we_are_restarting) {
917
//QTimer::singleShot(1000, this, SIGNAL(mediaStartPlay()));
918
emit mediaStartPlay();
921
if (we_are_restarting) {
922
// Update info about codecs and demuxer
923
mdat.video_codec = proc->mediaData().video_codec;
924
mdat.audio_codec = proc->mediaData().audio_codec;
925
mdat.demuxer = proc->mediaData().demuxer;
928
#if !NOTIFY_SUB_CHANGES
930
//if (we_are_restarting) {
931
if ( (just_loaded_external_subs) || (just_unloaded_external_subs) ) {
932
qDebug("Core::finishRestart: processing new subtitles");
934
// Just to simplify things
935
if (mset.current_sub_id == MediaSettings::NoneSelected) {
936
mset.current_sub_id = MediaSettings::SubNone;
943
if ( mset.current_sub_id != MediaSettings::SubNone ) {
944
old_item = mset.current_sub_id;
945
type = mdat.subs.itemAt(old_item).type();
946
ID = mdat.subs.itemAt(old_item).ID();
949
// Use the subtitle info from mplayerprocess
950
qDebug( "Core::finishRestart: copying sub data from proc to mdat");
951
mdat.subs = proc->mediaData().subs;
953
int item = MediaSettings::SubNone;
955
// Try to recover old subtitle
956
if (just_unloaded_external_subs) {
958
int new_item = mdat.subs.find(type, ID);
959
if (new_item > -1) item = new_item;
963
// If we've just loaded a subtitle file
964
// select one if the user wants to autoload
966
if (just_loaded_external_subs) {
967
if ( (pref->autoload_sub) && (item == MediaSettings::SubNone) ) {
968
qDebug("Core::finishRestart: cannot find previous subtitle");
969
qDebug("Core::finishRestart: selecting a new one");
970
item = mdat.subs.selectOne( pref->subtitle_lang );
973
changeSubtitle( item );
974
just_loaded_external_subs = false;
975
just_unloaded_external_subs = false;
977
// Normal restart, subtitles haven't changed
978
// Recover current subtitle
979
changeSubtitle( mset.current_sub_id );
983
we_are_restarting = false;
986
changeAspectRatio(mset.aspect_ratio_id);
988
if (mset.aspect_ratio_id < MediaSettings::Aspect43Letterbox) {
989
changeAspectRatio(mset.aspect_ratio_id);
993
bool isMuted = mset.mute;
994
if (!pref->dont_change_volume) {
995
setVolume( mset.volume, TRUE );
997
if (isMuted) mute(TRUE);
999
if (pref->change_video_equalizer_on_startup && (mset.gamma != 0)) {
1000
int gamma = mset.gamma;
1001
mset.gamma = -1000; // if mset.gamma == new value, mset.gamma is not changed!
1004
// Hack to be sure that the equalizers are up to date
1005
emit videoEqualizerNeedsUpdate();
1006
emit audioEqualizerNeedsUpdate();
1008
changePanscan(mset.panscan_factor);
1011
emit mediaInfoChanged();
1013
updateWidgets(); // New
1015
qDebug("Core::finishRestart: --- end ---");
1021
qDebug("Core::stop");
1022
qDebug("Core::stop: state: %s", stateToString().toUtf8().data());
1024
if (state()==Stopped) {
1025
// if pressed stop twice, reset video to the beginning
1026
qDebug("Core::stop: mset.current_sec: %f", mset.current_sec);
1027
mset.current_sec = 0;
1028
emit showTime( mset.current_sec );
1029
#ifdef SEEKBAR_RESOLUTION
1030
emit positionChanged( 0 );
1032
emit posChanged( 0 );
1038
emit mediaStoppedByUser();
1044
qDebug("Core::play");
1046
if ((proc->isRunning()) && (state()==Paused)) {
1047
tellmp("pause"); // Unpauses
1050
if ((proc->isRunning()) && (state()==Playing)) {
1051
// nothing to do, continue playing
1054
// if we're stopped, play it again
1055
if ( !mdat.filename.isEmpty() ) {
1057
qDebug( "current_sec: %f, duration: %f", mset.current_sec, mdat.duration);
1058
if ( (floor(mset.current_sec)) >= (floor(mdat.duration)) ) {
1059
mset.current_sec = 0;
1067
void Core::pause_and_frame_step() {
1068
qDebug("Core::pause_and_frame_step");
1070
if (proc->isRunning()) {
1071
if (state() == Paused) {
1072
tellmp("frame_step");
1080
void Core::pause() {
1081
qDebug("Core::pause");
1082
qDebug("Core::pause: current state: %s", stateToString().toUtf8().data());
1084
if (proc->isRunning()) {
1085
// Pauses and unpauses
1090
void Core::play_or_pause() {
1091
if (proc->isRunning()) {
1098
void Core::frameStep() {
1099
qDebug("Core::frameStep");
1101
if (proc->isRunning()) {
1102
tellmp("frame_step");
1106
void Core::screenshot() {
1107
qDebug("Core::screenshot");
1109
if ( (!pref->screenshot_directory.isEmpty()) &&
1110
(QFileInfo(pref->screenshot_directory).isDir()) )
1112
tellmp( pausing_prefix() + " screenshot 0");
1113
qDebug("Core::screenshot: taken screenshot");
1115
qDebug("Core::screenshot: error: directory for screenshots not valid");
1116
QString text = "Screenshot NOT taken, folder not configured";
1117
tellmp("osd_show_text \"" + text + "\" 3000 1");
1118
emit showMessage(text);
1122
void Core::processFinished()
1124
qDebug("Core::processFinished");
1127
#ifdef SCREENSAVER_OFF
1128
// Restores the Windows screensaver
1129
if (pref->disable_screensaver) {
1130
win_screensaver->restore();
1135
qDebug("Core::processFinished: we_are_restarting: %d", we_are_restarting);
1137
//mset.current_sec = 0;
1139
if (!we_are_restarting) {
1140
qDebug("Core::processFinished: play has finished!");
1142
//emit stateChanged(state());
1145
int exit_code = proc->exitCode();
1146
qDebug("Core::processFinished: exit_code: %d", exit_code);
1147
if (exit_code != 0) {
1148
emit mplayerFinishedWithError(exit_code);
1152
void Core::fileReachedEnd() {
1154
if (mdat.type == TYPE_VCD) {
1155
// If the first vcd title has nothing, it doesn't start to play
1156
// and menus are not initialized.
1161
// If we're at the end of the movie, reset to 0
1162
mset.current_sec = 0;
1165
emit mediaFinished();
1168
#if SEEKBAR_RESOLUTION
1169
void Core::goToPosition(int value) {
1170
qDebug("Core::goToPosition: value: %d", value);
1171
if (mdat.duration > 0) {
1172
int jump_time = (int) mdat.duration * value / SEEKBAR_RESOLUTION;
1177
void Core::goToPos(int perc) {
1178
qDebug("Core::goToPos: per: %d", perc);
1179
tellmp( "seek " + QString::number(perc) + " 1");
1184
void Core::startMplayer( QString file, double seek ) {
1185
qDebug("Core::startMplayer");
1187
if (file.isEmpty()) {
1188
qWarning("Core:startMplayer: file is empty!");
1192
if (proc->isRunning()) {
1193
qWarning("Core::startMplayer: MPlayer still running!");
1198
#ifdef SCREENSAVER_OFF
1199
// Disable the Windows screensaver
1200
if (pref->disable_screensaver) {
1201
win_screensaver->disable();
1206
bool is_mkv = (QFileInfo(file).suffix().toLower() == "mkv");
1211
if (mdat.type==TYPE_DVD) {
1212
DiscData disc_data = DiscName::split(file);
1213
dvd_folder = disc_data.device;
1214
if (dvd_folder.isEmpty()) dvd_folder = pref->dvd_device;
1215
dvd_title = disc_data.title;
1216
file = disc_data.protocol + "://";
1217
if (dvd_title > 0) file += QString::number(dvd_title);
1221
bool url_is_playlist = file.endsWith(IS_PLAYLIST_TAG);
1222
if (url_is_playlist) file = file.remove( QRegExp(IS_PLAYLIST_TAG_RX) );
1224
bool screenshot_enabled = ( (!pref->screenshot_directory.isEmpty()) &&
1225
(QFileInfo(pref->screenshot_directory).isDir()) );
1227
proc->clearArguments();
1229
// Set working directory to screenshot directory
1230
if (screenshot_enabled) {
1231
qDebug("Core::startMplayer: setting working directory to '%s'", pref->screenshot_directory.toUtf8().data());
1232
proc->setWorkingDirectory( pref->screenshot_directory );
1235
// Use absolute path, otherwise after changing to the screenshot directory
1236
// the mplayer path might not be found if it's a relative path
1237
// (seems to be necessary only for linux)
1238
QString mplayer_bin = pref->mplayer_bin;
1239
QFileInfo fi(mplayer_bin);
1240
if (fi.exists() && fi.isExecutable() && !fi.isDir()) {
1241
mplayer_bin = fi.absoluteFilePath();
1244
proc->addArgument( mplayer_bin );
1246
proc->addArgument("-noquiet");
1248
if (pref->fullscreen && pref->use_mplayer_window) {
1249
proc->addArgument("-fs");
1251
// No mplayer fullscreen mode
1252
proc->addArgument("-nofs");
1255
proc->addArgument("-nomouseinput");
1257
// Demuxer and audio and video codecs:
1258
if (!mset.forced_demuxer.isEmpty()) {
1259
proc->addArgument("-demuxer");
1260
proc->addArgument(mset.forced_demuxer);
1262
if (!mset.forced_audio_codec.isEmpty()) {
1263
proc->addArgument("-ac");
1264
proc->addArgument(mset.forced_audio_codec);
1266
if (!mset.forced_video_codec.isEmpty()) {
1267
proc->addArgument("-vc");
1268
proc->addArgument(mset.forced_video_codec);
1271
if (pref->use_hwac3) {
1272
proc->addArgument("-afm");
1273
proc->addArgument("hwac3");
1279
if ( (pref->h264_skip_loop_filter == Preferences::LoopDisabled) ||
1280
((pref->h264_skip_loop_filter == Preferences::LoopDisabledOnHD) &&
1281
(mset.is264andHD)) )
1283
if (!lavdopts.isEmpty()) lavdopts += ":";
1284
lavdopts += "skiploopfilter=all";
1287
if (pref->show_motion_vectors) {
1288
if (!lavdopts.isEmpty()) lavdopts += ":";
1289
lavdopts += "vismv=7";
1292
if (pref->threads > 1) {
1293
if (!lavdopts.isEmpty()) lavdopts += ":";
1294
lavdopts += "threads=" + QString::number(pref->threads);
1297
if (!lavdopts.isEmpty()) {
1298
proc->addArgument("-lavdopts");
1299
proc->addArgument(lavdopts);
1302
proc->addArgument("-sub-fuzziness");
1303
proc->addArgument( QString::number(pref->subfuzziness) );
1305
proc->addArgument("-identify");
1307
#if GENERIC_CHAPTER_SUPPORT
1308
if (MplayerVersion::isMplayerAtLeast(27667)) {
1309
// From r27667 the number of chapters can be obtained from ID_CHAPTERS
1310
mset.current_chapter_id = 0; // Reset chapters
1313
// We need this to get info about mkv chapters
1315
proc->addArgument("-msglevel");
1316
proc->addArgument("demux=6");
1318
// **** Reset chapter ***
1319
// Select first chapter, otherwise we cannot
1320
// resume playback at the same point
1321
// (time would be relative to chapter)
1322
mset.current_chapter_id = 0;
1324
#if GENERIC_CHAPTER_SUPPORT
1328
proc->addArgument("-slave");
1330
if (!pref->vo.isEmpty()) {
1331
proc->addArgument( "-vo");
1332
proc->addArgument( pref->vo );
1334
proc->addArgument("-vo");
1336
if (QSysInfo::WindowsVersion == QSysInfo::WV_VISTA) {
1337
proc->addArgument("direct3d,");
1339
proc->addArgument("directx,");
1342
proc->addArgument("xv,");
1347
if (pref->adapter > -1) {
1348
proc->addArgument("-adapter");
1349
proc->addArgument(QString::number(pref->adapter));
1353
if (!pref->ao.isEmpty()) {
1354
proc->addArgument( "-ao");
1355
proc->addArgument( pref->ao );
1359
proc->addArgument( "-ao");
1360
proc->addArgument( "alsa," );
1365
if (pref->vo.startsWith("x11")) {
1366
proc->addArgument( "-zoom");
1369
proc->addArgument("-nokeepaspect");
1371
// Performance options
1374
int app_p = NORMAL_PRIORITY_CLASS;
1375
switch (pref->priority) {
1376
case Preferences::Realtime: p = "realtime";
1377
app_p = REALTIME_PRIORITY_CLASS;
1379
case Preferences::High: p = "high";
1380
app_p = REALTIME_PRIORITY_CLASS;
1382
case Preferences::AboveNormal: p = "abovenormal";
1383
app_p = HIGH_PRIORITY_CLASS;
1385
case Preferences::Normal: p = "normal";
1386
app_p = ABOVE_NORMAL_PRIORITY_CLASS;
1388
case Preferences::BelowNormal: p = "belownormal"; break;
1389
case Preferences::Idle: p = "idle"; break;
1390
default: p = "normal";
1392
proc->addArgument("-priority");
1393
proc->addArgument( p );
1394
SetPriorityClass(GetCurrentProcess(), app_p);
1395
qDebug("Core::startMplayer: priority of smplayer process set to %d", app_p);
1398
if (pref->frame_drop) {
1399
proc->addArgument("-framedrop");
1402
if (pref->hard_frame_drop) {
1403
proc->addArgument("-hardframedrop");
1406
if (pref->autosync) {
1407
proc->addArgument("-autosync");
1408
proc->addArgument( QString::number( pref->autosync_factor ) );
1411
if (pref->use_direct_rendering) {
1412
proc->addArgument("-dr");
1414
proc->addArgument("-nodr");
1417
if (pref->use_double_buffer) {
1418
proc->addArgument("-double");
1420
proc->addArgument("-nodouble");
1424
if (!pref->use_mplayer_window) {
1425
proc->addArgument( "-input" );
1426
proc->addArgument( "conf=" + Paths::dataPath() +"/input.conf" );
1431
if (pref->disable_screensaver) {
1432
proc->addArgument("-stop-xscreensaver");
1434
proc->addArgument("-nostop-xscreensaver");
1438
if (!pref->use_mplayer_window) {
1439
proc->addArgument("-wid");
1440
proc->addArgument( QString::number( (int) mplayerwindow->videoLayer()->winId() ) );
1444
if ((pref->vo.startsWith("directx")) || (pref->vo.isEmpty())) {
1445
proc->addArgument("-colorkey");
1446
//proc->addArgument( "0x"+QString::number(pref->color_key, 16) );
1447
proc->addArgument( ColorUtils::colorToRGB(pref->color_key) );
1450
qDebug("Core::startMplayer: * not using -colorkey for %s", pref->vo.toUtf8().data());
1451
qDebug("Core::startMplayer: * report if you can't see the video");
1458
proc->addArgument("-monitorpixelaspect");
1459
proc->addArgument("1");
1462
if (!pref->monitor_aspect.isEmpty()) {
1463
proc->addArgument("-monitoraspect");
1464
proc->addArgument( pref->monitor_aspect );
1469
if ((pref->use_ass_subtitles) && (pref->freetype_support)) {
1471
proc->addArgument("-ass");
1472
proc->addArgument("-embeddedfonts");
1474
proc->addArgument("-ass-line-spacing");
1475
proc->addArgument(QString::number(pref->ass_line_spacing));
1477
proc->addArgument( "-ass-font-scale");
1478
proc->addArgument( QString::number(mset.sub_scale_ass) );
1480
if (!pref->force_ass_styles) {
1481
// Load the styles.ass file
1482
if (!QFile::exists(Paths::subtitleStyleFile())) {
1483
// If file doesn't exist, create it
1484
pref->ass_styles.exportStyles(Paths::subtitleStyleFile());
1486
if (QFile::exists(Paths::subtitleStyleFile())) {
1487
proc->addArgument("-ass-styles");
1488
proc->addArgument( Paths::subtitleStyleFile() );
1490
qWarning("Core::startMplayer: '%s' doesn't exist", Paths::subtitleStyleFile().toUtf8().constData());
1493
// Force styles for ass subtitles too
1494
proc->addArgument("-ass-force-style");
1495
if (!pref->user_forced_ass_style.isEmpty()) {
1496
proc->addArgument(pref->user_forced_ass_style);
1498
proc->addArgument(pref->ass_styles.toString());
1501
// Use the same font for OSD
1502
if (!pref->ass_styles.fontname.isEmpty()) {
1503
proc->addArgument("-fontconfig");
1504
proc->addArgument("-font");
1505
proc->addArgument( pref->ass_styles.fontname );
1507
// Set the size of OSD
1508
if (pref->freetype_support) {
1509
proc->addArgument("-subfont-autoscale");
1510
proc->addArgument("0");
1511
proc->addArgument("-subfont-osd-scale");
1512
proc->addArgument(QString::number(pref->ass_styles.fontsize));
1513
proc->addArgument("-subfont-text-scale"); // Old versions (like 1.0rc2) need this
1514
proc->addArgument(QString::number(pref->ass_styles.fontsize));
1518
if (pref->freetype_support) proc->addArgument("-noass");
1520
if ( (pref->use_fontconfig) && (!pref->font_name.isEmpty()) ) {
1521
proc->addArgument("-fontconfig");
1522
proc->addArgument("-font");
1523
proc->addArgument( pref->font_name );
1526
if ( (!pref->use_fontconfig) && (!pref->font_file.isEmpty()) ) {
1527
proc->addArgument("-font");
1528
proc->addArgument( pref->font_file );
1531
if (pref->freetype_support) {
1532
proc->addArgument( "-subfont-autoscale");
1533
proc->addArgument( QString::number( pref->font_autoscale ) );
1535
proc->addArgument( "-subfont-text-scale");
1536
proc->addArgument( QString::number(mset.sub_scale) );
1540
// Subtitle encoding
1543
if ( (pref->use_enca) && (!pref->enca_lang.isEmpty()) ) {
1544
encoding = "enca:"+ pref->enca_lang;
1545
if (!pref->subcp.isEmpty()) {
1546
encoding += ":"+ pref->subcp;
1550
if (!pref->subcp.isEmpty()) {
1551
encoding = pref->subcp;
1554
if (!encoding.isEmpty()) {
1555
proc->addArgument("-subcp");
1556
proc->addArgument( encoding );
1560
if (pref->use_closed_caption_subs) {
1561
proc->addArgument("-subcc");
1564
if (pref->use_forced_subs_only) {
1565
proc->addArgument("-forcedsubsonly");
1568
if (mset.current_video_id != MediaSettings::NoneSelected) {
1569
proc->addArgument("-vid");
1570
proc->addArgument( QString::number( mset.current_video_id ) );
1573
if (mset.current_audio_id != MediaSettings::NoneSelected) {
1574
// Workaround for MPlayer bug #1321 (http://bugzilla.mplayerhq.hu/show_bug.cgi?id=1321)
1575
if (mdat.audios.numItems() != 1) {
1576
proc->addArgument("-aid");
1577
proc->addArgument( QString::number( mset.current_audio_id ) );
1581
if (!initial_subtitle.isEmpty()) {
1582
mset.external_subtitles = initial_subtitle;
1583
initial_subtitle = "";
1584
just_loaded_external_subs = true; // Big ugly hack :(
1586
if (!mset.external_subtitles.isEmpty()) {
1587
if (QFileInfo(mset.external_subtitles).suffix().toLower()=="idx") {
1588
// sub/idx subtitles
1592
if (pref->use_short_pathnames)
1593
fi.setFile(Helper::shortPathName(mset.external_subtitles));
1596
fi.setFile(mset.external_subtitles);
1598
QString s = fi.path() +"/"+ fi.completeBaseName();
1599
qDebug("Core::startMplayer: subtitle file without extension: '%s'", s.toUtf8().data());
1600
proc->addArgument("-vobsub");
1601
proc->addArgument( s );
1603
proc->addArgument("-sub");
1605
if (pref->use_short_pathnames)
1606
proc->addArgument(Helper::shortPathName(mset.external_subtitles));
1609
proc->addArgument( mset.external_subtitles );
1613
if (!mset.external_audio.isEmpty()) {
1614
proc->addArgument("-audiofile");
1616
if (pref->use_short_pathnames)
1617
proc->addArgument(Helper::shortPathName(mset.external_audio));
1620
proc->addArgument( mset.external_audio );
1623
proc->addArgument("-subpos");
1624
proc->addArgument( QString::number(mset.sub_pos) );
1626
if (mset.audio_delay!=0) {
1627
proc->addArgument("-delay");
1628
proc->addArgument( QString::number( (double) mset.audio_delay/1000 ) );
1631
if (mset.sub_delay!=0) {
1632
proc->addArgument("-subdelay");
1633
proc->addArgument( QString::number( (double) mset.sub_delay/1000 ) );
1636
// Contrast, brightness...
1637
if (pref->change_video_equalizer_on_startup) {
1638
if (mset.contrast != 0) {
1639
proc->addArgument("-contrast");
1640
proc->addArgument( QString::number( mset.contrast ) );
1643
if (mset.brightness != 0) {
1644
proc->addArgument("-brightness");
1645
proc->addArgument( QString::number( mset.brightness ) );
1648
if (mset.hue != 0) {
1649
proc->addArgument("-hue");
1650
proc->addArgument( QString::number( mset.hue ) );
1653
if (mset.saturation != 0) {
1654
proc->addArgument("-saturation");
1655
proc->addArgument( QString::number( mset.saturation ) );
1659
// Set volume, requires mplayer svn r27872
1660
bool use_volume_option = (pref->use_volume_option == Preferences::Enabled);
1661
if (pref->use_volume_option == Preferences::Detect) {
1662
use_volume_option = (MplayerVersion::isMplayerAtLeast(27872));
1664
if ((use_volume_option) && (!pref->dont_change_volume)) {
1665
proc->addArgument("-volume");
1666
// Note: mset.volume may not be right, it can be the volume of the previous video if
1667
// playing a new one, but I think it's better to use anyway the current volume on
1668
// startup than set it to 0 or something.
1669
// The right volume will be set later, when the video starts to play.
1670
proc->addArgument( QString::number( mset.volume ) );
1674
if (mdat.type==TYPE_DVD) {
1675
if (!dvd_folder.isEmpty()) {
1676
proc->addArgument("-dvd-device");
1677
proc->addArgument( dvd_folder );
1679
qWarning("Core::startMplayer: dvd device is empty!");
1683
if ((mdat.type==TYPE_VCD) || (mdat.type==TYPE_AUDIO_CD)) {
1684
if (!pref->cdrom_device.isEmpty()) {
1685
proc->addArgument("-cdrom-device");
1686
proc->addArgument( pref->cdrom_device );
1690
if (mset.current_chapter_id > 0) {
1691
proc->addArgument("-chapter");
1692
int chapter = mset.current_chapter_id;
1693
// Fix for older versions of mplayer:
1694
#if GENERIC_CHAPTER_SUPPORT
1695
if ((mdat.type == TYPE_DVD) && (firstChapter() == 0)) chapter++;
1697
if ((mdat.type == TYPE_DVD) && (dvdFirstChapter() == 0)) chapter++;
1699
proc->addArgument( QString::number( chapter ) );
1702
if (mset.current_angle_id > 0) {
1703
proc->addArgument("-dvdangle");
1704
proc->addArgument( QString::number( mset.current_angle_id ) );
1709
switch (mdat.type) {
1710
case TYPE_FILE : cache = pref->cache_for_files; break;
1711
case TYPE_DVD : cache = pref->cache_for_dvds;
1713
if (file.startsWith("dvdnav:")) cache = 0;
1716
case TYPE_STREAM : cache = pref->cache_for_streams; break;
1717
case TYPE_VCD : cache = pref->cache_for_vcds; break;
1718
case TYPE_AUDIO_CD : cache = pref->cache_for_audiocds; break;
1722
if (cache > 31) { // Minimum value for cache = 32
1723
proc->addArgument("-cache");
1724
proc->addArgument( QString::number( cache ) );
1726
proc->addArgument("-nocache");
1729
if (mset.speed != 1.0) {
1730
proc->addArgument("-speed");
1731
proc->addArgument( QString::number( mset.speed ) );
1734
// If seek < 5 it's better to allow the video to start from the beginning
1735
if ((seek >= 5) && (!pref->loop)) {
1736
proc->addArgument("-ss");
1737
proc->addArgument( QString::number( seek ) );
1740
proc->addArgument("-osdlevel");
1741
proc->addArgument( QString::number( pref->osd ) );
1743
if (pref->use_idx) {
1744
proc->addArgument("-idx");
1747
if (mdat.type == TYPE_STREAM) {
1748
if (pref->prefer_ipv4) {
1749
proc->addArgument("-prefer-ipv4");
1751
proc->addArgument("-prefer-ipv6");
1755
if (pref->use_correct_pts != Preferences::Detect) {
1756
if (pref->use_correct_pts == Preferences::Enabled) {
1757
proc->addArgument("-correct-pts");
1759
if (pref->mplayer_detected_version > 0) {
1760
if (MplayerVersion::isMplayerAtLeast(26842)) {
1761
proc->addArgument("-nocorrect-pts");
1763
proc->addArgument("-no-correct-pts");
1766
qDebug("Core::startMplayer: unknown version of mplayer, not passing -no(-)correct-pts");
1773
if (mset.phase_filter) {
1774
proc->addArgument("-vf-add");
1775
proc->addArgument( "phase=A" );
1779
if (mset.current_deinterlacer != MediaSettings::NoDeinterlace) {
1780
proc->addArgument("-vf-add");
1781
switch (mset.current_deinterlacer) {
1782
case MediaSettings::L5: proc->addArgument("pp=l5"); break;
1783
case MediaSettings::Yadif: proc->addArgument("yadif"); break;
1784
case MediaSettings::LB: proc->addArgument("pp=lb"); break;
1785
case MediaSettings::Yadif_1: proc->addArgument("yadif=1"); break;
1786
case MediaSettings::Kerndeint: proc->addArgument("kerndeint=5"); break;
1790
#if !NEW_ASPECT_CODE
1792
if (!mset.panscan_filter.isEmpty()) {
1793
proc->addArgument( "-vf-add" );
1794
proc->addArgument( mset.panscan_filter );
1798
if (!mset.crop_43to169_filter.isEmpty()) {
1799
proc->addArgument( "-vf-add" );
1800
proc->addArgument( mset.crop_43to169_filter );
1805
if (mset.current_denoiser != MediaSettings::NoDenoise) {
1806
proc->addArgument("-vf-add");
1807
if (mset.current_denoiser==MediaSettings::DenoiseSoft) {
1808
proc->addArgument( "hqdn3d=2:1:2" );
1810
proc->addArgument( "hqdn3d" );
1815
if (mset.deblock_filter) {
1816
proc->addArgument("-vf-add");
1817
proc->addArgument( "pp=vb/hb" );
1821
if (mset.dering_filter) {
1822
proc->addArgument("-vf-add");
1823
proc->addArgument( "pp=dr" );
1827
if (mset.upscaling_filter) {
1828
int width = DesktopInfo::desktop_size(mplayerwindow).width();
1829
proc->addArgument("-sws");
1830
proc->addArgument("9");
1831
proc->addArgument("-vf-add");
1832
proc->addArgument("scale="+QString::number(width)+":-2");
1836
if (mset.noise_filter) {
1837
proc->addArgument("-vf-add");
1838
proc->addArgument( "noise=9ah:5ah" );
1842
if (mset.postprocessing_filter) {
1843
proc->addArgument("-vf-add");
1844
proc->addArgument("pp");
1845
proc->addArgument("-autoq");
1846
proc->addArgument( QString::number(pref->autoq) );
1850
// Letterbox (expand)
1852
if ((mset.add_letterbox) || (pref->fullscreen && pref->add_blackborders_on_fullscreen)) {
1853
proc->addArgument("-vf-add");
1854
proc->addArgument( QString("expand=:::::%1,harddup").arg( DesktopInfo::desktop_aspectRatio(mplayerwindow)) );
1855
// Note: on some videos (h264 for instance) the subtitles doesn't disappear,
1856
// appearing the new ones on top of the old ones. It seems adding another
1857
// filter after expand fixes the problem. I chose harddup 'cos I think
1858
// it will be harmless in mplayer.
1859
// Anyway, if you know a proper way to fix the problem, please tell me.
1862
if (mset.letterbox == MediaSettings::Letterbox_43) {
1863
proc->addArgument("-vf-add");
1864
proc->addArgument("expand=:::::4/3");
1867
if (mset.letterbox == MediaSettings::Letterbox_169) {
1868
proc->addArgument("-vf-add");
1869
proc->addArgument("expand=:::::16/9");
1873
// Software equalizer
1874
if ( (pref->use_soft_video_eq) ) {
1875
proc->addArgument("-vf-add");
1876
QString eq_filter = "eq2,hue";
1877
if ( (pref->vo == "gl") || (pref->vo == "gl2")
1879
|| (pref->vo == "directx:noaccel")
1881
) eq_filter += ",scale";
1882
proc->addArgument(eq_filter);
1885
// Additional video filters, supplied by user
1887
if ( !mset.mplayer_additional_video_filters.isEmpty() ) {
1888
proc->addArgument("-vf-add");
1889
proc->addArgument( mset.mplayer_additional_video_filters );
1892
if ( !pref->mplayer_additional_video_filters.isEmpty() ) {
1893
proc->addArgument("-vf-add");
1894
proc->addArgument( pref->mplayer_additional_video_filters );
1897
bool force_noslices = false;
1899
// Filters for subtitles on screenshots
1900
if ((screenshot_enabled) && (pref->subtitles_on_screenshots))
1902
if (pref->use_ass_subtitles) {
1903
proc->addArgument("-vf-add");
1904
proc->addArgument("ass");
1906
proc->addArgument("-vf-add");
1907
proc->addArgument("expand=osd=1");
1908
//proc->addArgument("-noslices");
1909
force_noslices = true;
1914
if (mset.rotate != MediaSettings::NoRotate) {
1915
proc->addArgument( "-vf-add" );
1916
proc->addArgument( QString("rotate=%1").arg(mset.rotate) );
1921
proc->addArgument( "-vf-add" );
1922
// expand + flip doesn't work well, a workaround is to add another
1923
// filter between them, so that's why harddup is here
1924
proc->addArgument("harddup,flip");
1929
proc->addArgument( "-vf-add" );
1930
proc->addArgument("mirror");
1934
if (screenshot_enabled) {
1935
proc->addArgument("-vf-add");
1936
proc->addArgument("screenshot");
1940
if ((pref->use_slices) && (!force_noslices)) {
1941
proc->addArgument("-slices");
1943
proc->addArgument("-noslices");
1948
if (mset.audio_use_channels != 0) {
1949
proc->addArgument("-channels");
1950
proc->addArgument( QString::number( mset.audio_use_channels ) );
1954
if (mset.stereo_mode != 0) {
1955
proc->addArgument("-stereo");
1956
proc->addArgument( QString::number( mset.stereo_mode ) );
1961
if (mset.karaoke_filter) {
1965
if (mset.extrastereo_filter) {
1966
if (!af.isEmpty()) af += ",";
1967
af += "extrastereo";
1970
if (mset.volnorm_filter) {
1971
if (!af.isEmpty()) af += ",";
1975
bool use_scaletempo = (pref->use_scaletempo == Preferences::Enabled);
1976
if (pref->use_scaletempo == Preferences::Detect) {
1977
use_scaletempo = (MplayerVersion::isMplayerAtLeast(24924));
1979
if (use_scaletempo) {
1980
if (!af.isEmpty()) af += ",";
1985
if (pref->use_audio_equalizer) {
1986
if (!af.isEmpty()) af += ",";
1987
af += "equalizer=" + Helper::equalizerListToString(mset.audio_equalizer);
1991
// Additional audio filters, supplied by user
1993
if ( !pref->mplayer_additional_audio_filters.isEmpty() ) {
1994
if (!af.isEmpty()) af += ",";
1995
af += pref->mplayer_additional_audio_filters;
1998
if ( !mset.mplayer_additional_audio_filters.isEmpty() ) {
1999
if (!af.isEmpty()) af += ",";
2000
af += mset.mplayer_additional_audio_filters;
2003
if (!af.isEmpty()) {
2004
proc->addArgument("-af");
2005
proc->addArgument( af );
2008
if (pref->use_soft_vol) {
2009
proc->addArgument("-softvol");
2010
proc->addArgument("-softvol-max");
2011
proc->addArgument( QString::number(pref->softvol_max) );
2015
if (pref->use_edl_files) {
2018
QString basename = f.path() + "/" + f.completeBaseName();
2020
qDebug("Core::startMplayer: file basename: '%s'", basename.toUtf8().data());
2022
if (QFile::exists(basename+".edl"))
2023
edl_f = basename+".edl";
2025
if (QFile::exists(basename+".EDL"))
2026
edl_f = basename+".EDL";
2028
qDebug("Core::startMplayer: edl file: '%s'", edl_f.toUtf8().data());
2029
if (!edl_f.isEmpty()) {
2030
proc->addArgument("-edl");
2031
proc->addArgument(edl_f);
2035
// Additional options supplied by the user
2037
if (!mset.mplayer_additional_options.isEmpty()) {
2038
QStringList args = MyProcess::splitArguments(mset.mplayer_additional_options);
2039
QStringList::Iterator it = args.begin();
2040
while( it != args.end() ) {
2041
proc->addArgument( (*it) );
2046
if (!pref->mplayer_additional_options.isEmpty()) {
2047
QStringList args = MyProcess::splitArguments(pref->mplayer_additional_options);
2048
QStringList::Iterator it = args.begin();
2049
while( it != args.end() ) {
2050
proc->addArgument( (*it) );
2056
if (url_is_playlist) {
2057
proc->addArgument("-playlist");
2061
if (pref->use_short_pathnames)
2062
proc->addArgument(Helper::shortPathName(file));
2065
proc->addArgument( file );
2067
// It seems the loop option must be after the filename
2069
proc->addArgument("-loop");
2070
proc->addArgument("0");
2073
emit aboutToStartPlaying();
2075
QString commandline = proc->arguments().join(" ");
2076
qDebug("Core::startMplayer: command: '%s'", commandline.toUtf8().data());
2079
QString line_for_log = commandline + "\n";
2080
emit logLineAvailable(line_for_log);
2082
if ( !proc->start() ) {
2084
qWarning("Core::startMplayer: mplayer process didn't start");
2089
void Core::stopMplayer() {
2090
qDebug("Core::stopMplayer");
2092
if (!proc->isRunning()) {
2093
qWarning("Core::stopMplayer: mplayer in not running!");
2099
qDebug("Core::stopMplayer: Waiting mplayer to finish...");
2100
if (!proc->waitForFinished(5000)) {
2101
qWarning("Core::stopMplayer: process didn't finish. Killing it...");
2105
qDebug("Core::stopMplayer: Finished. (I hope)");
2109
void Core::goToSec( double sec ) {
2110
qDebug("Core::goToSec: %f", sec);
2112
if (sec < 0) sec = 0;
2113
if (sec > mdat.duration ) sec = mdat.duration - 20;
2114
tellmp("seek " + QString::number(sec) + " 2");
2118
void Core::seek(int secs) {
2119
qDebug("Core::seek: %d", secs);
2120
if ( (proc->isRunning()) && (secs!=0) ) {
2121
tellmp("seek " + QString::number(secs) + " 0");
2125
void Core::sforward() {
2126
qDebug("Core::sforward");
2127
seek( pref->seeking1 ); // +10s
2130
void Core::srewind() {
2131
qDebug("Core::srewind");
2132
seek( -pref->seeking1 ); // -10s
2136
void Core::forward() {
2137
qDebug("Core::forward");
2138
seek( pref->seeking2 ); // +1m
2142
void Core::rewind() {
2143
qDebug("Core::rewind");
2144
seek( -pref->seeking2 ); // -1m
2148
void Core::fastforward() {
2149
qDebug("Core::fastforward");
2150
seek( pref->seeking3 ); // +10m
2154
void Core::fastrewind() {
2155
qDebug("Core::fastrewind");
2156
seek( -pref->seeking3 ); // -10m
2159
void Core::forward(int secs) {
2160
qDebug("Core::forward: %d", secs);
2164
void Core::rewind(int secs) {
2165
qDebug("Core::rewind: %d", secs);
2169
void Core::wheelUp() {
2170
qDebug("Core::wheelUp");
2171
switch (pref->wheel_function) {
2172
case Preferences::Volume : incVolume(); break;
2173
case Preferences::Zoom : incPanscan(); break;
2174
case Preferences::Seeking : forward( pref->seeking4 ); break;
2175
case Preferences::ChangeSpeed : incSpeed10(); break;
2176
default : {} // do nothing
2180
void Core::wheelDown() {
2181
qDebug("Core::wheelDown");
2182
switch (pref->wheel_function) {
2183
case Preferences::Volume : decVolume(); break;
2184
case Preferences::Zoom : decPanscan(); break;
2185
case Preferences::Seeking : rewind( pref->seeking4 ); break;
2186
case Preferences::ChangeSpeed : decSpeed10(); break;
2187
default : {} // do nothing
2192
void Core::toggleRepeat() {
2193
qDebug("Core::toggleRepeat");
2194
toggleRepeat( !pref->loop );
2197
void Core::toggleRepeat(bool b) {
2198
qDebug("Core::toggleRepeat: %d", b);
2199
if ( pref->loop != b ) {
2201
if (MplayerVersion::isMplayerAtLeast(23747)) {
2202
// Use slave command
2203
int v = -1; // no loop
2204
if (pref->loop) v = 0; // infinite loop
2205
tellmp( QString("loop %1 1").arg(v) );
2208
if (proc->isRunning()) restartPlay();
2214
void Core::toggleFlip() {
2215
qDebug("Core::toggleFlip");
2216
toggleFlip( !mset.flip );
2219
void Core::toggleFlip(bool b) {
2220
qDebug("Core::toggleFlip: %d", b);
2222
if (mset.flip != b) {
2224
if (proc->isRunning()) restartPlay();
2228
void Core::toggleMirror() {
2229
qDebug("Core::toggleMirror");
2230
toggleMirror( !mset.mirror );
2233
void Core::toggleMirror(bool b) {
2234
qDebug("Core::toggleMirror: %d", b);
2236
if (mset.mirror != b) {
2238
if (proc->isRunning()) restartPlay();
2243
void Core::toggleKaraoke() {
2244
toggleKaraoke( !mset.karaoke_filter );
2247
void Core::toggleKaraoke(bool b) {
2248
qDebug("Core::toggleKaraoke: %d", b);
2249
if (b != mset.karaoke_filter) {
2250
mset.karaoke_filter = b;
2255
void Core::toggleExtrastereo() {
2256
toggleExtrastereo( !mset.extrastereo_filter );
2259
void Core::toggleExtrastereo(bool b) {
2260
qDebug("Core::toggleExtrastereo: %d", b);
2261
if (b != mset.extrastereo_filter) {
2262
mset.extrastereo_filter = b;
2267
void Core::toggleVolnorm() {
2268
toggleVolnorm( !mset.volnorm_filter );
2271
void Core::toggleVolnorm(bool b) {
2272
qDebug("Core::toggleVolnorm: %d", b);
2273
if (b != mset.volnorm_filter) {
2274
mset.volnorm_filter = b;
2279
void Core::setAudioChannels(int channels) {
2280
qDebug("Core::setAudioChannels:%d", channels);
2281
if (channels != mset.audio_use_channels ) {
2282
mset.audio_use_channels = channels;
2287
void Core::setStereoMode(int mode) {
2288
qDebug("Core::setStereoMode:%d", mode);
2289
if (mode != mset.stereo_mode ) {
2290
mset.stereo_mode = mode;
2297
void Core::toggleAutophase() {
2298
toggleAutophase( !mset.phase_filter );
2301
void Core::toggleAutophase( bool b ) {
2302
qDebug("Core::toggleAutophase: %d", b);
2303
if ( b != mset.phase_filter) {
2304
mset.phase_filter = b;
2309
void Core::toggleDeblock() {
2310
toggleDeblock( !mset.deblock_filter );
2313
void Core::toggleDeblock(bool b) {
2314
qDebug("Core::toggleDeblock: %d", b);
2315
if ( b != mset.deblock_filter ) {
2316
mset.deblock_filter = b;
2321
void Core::toggleDering() {
2322
toggleDering( !mset.dering_filter );
2325
void Core::toggleDering(bool b) {
2326
qDebug("Core::toggleDering: %d", b);
2327
if ( b != mset.dering_filter) {
2328
mset.dering_filter = b;
2333
void Core::toggleNoise() {
2334
toggleNoise( !mset.noise_filter );
2337
void Core::toggleNoise(bool b) {
2338
qDebug("Core::toggleNoise: %d", b);
2339
if ( b!= mset.noise_filter ) {
2340
mset.noise_filter = b;
2345
void Core::togglePostprocessing() {
2346
togglePostprocessing( !mset.postprocessing_filter );
2349
void Core::togglePostprocessing(bool b) {
2350
qDebug("Core::togglePostprocessing: %d", b);
2351
if ( b != mset.postprocessing_filter ) {
2352
mset.postprocessing_filter = b;
2357
void Core::changeDenoise(int id) {
2358
qDebug( "Core::changeDenoise: %d", id );
2359
if (id != mset.current_denoiser) {
2360
mset.current_denoiser = id;
2365
void Core::changeUpscale(bool b) {
2366
qDebug( "Core::changeUpscale: %d", b );
2367
if (mset.upscaling_filter != b) {
2368
mset.upscaling_filter = b;
2373
void Core::setBrightness(int value) {
2374
qDebug("Core::setBrightness: %d", value);
2376
if (value > 100) value = 100;
2377
if (value < -100) value = -100;
2379
if (value != mset.brightness) {
2380
tellmp(pausing_prefix() + " brightness " + QString::number(value) + " 1");
2381
mset.brightness = value;
2382
displayMessage( tr("Brightness: %1").arg(value) );
2383
emit videoEqualizerNeedsUpdate();
2388
void Core::setContrast(int value) {
2389
qDebug("Core::setContrast: %d", value);
2391
if (value > 100) value = 100;
2392
if (value < -100) value = -100;
2394
if (value != mset.contrast) {
2395
tellmp(pausing_prefix() + " contrast " + QString::number(value) + " 1");
2396
mset.contrast = value;
2397
displayMessage( tr("Contrast: %1").arg(value) );
2398
emit videoEqualizerNeedsUpdate();
2402
void Core::setGamma(int value) {
2403
qDebug("Core::setGamma: %d", value);
2405
if (value > 100) value = 100;
2406
if (value < -100) value = -100;
2408
if (value != mset.gamma) {
2409
tellmp(pausing_prefix() + " gamma " + QString::number(value) + " 1");
2411
displayMessage( tr("Gamma: %1").arg(value) );
2412
emit videoEqualizerNeedsUpdate();
2416
void Core::setHue(int value) {
2417
qDebug("Core::setHue: %d", value);
2419
if (value > 100) value = 100;
2420
if (value < -100) value = -100;
2422
if (value != mset.hue) {
2423
tellmp(pausing_prefix() + " hue " + QString::number(value) + " 1");
2425
displayMessage( tr("Hue: %1").arg(value) );
2426
emit videoEqualizerNeedsUpdate();
2430
void Core::setSaturation(int value) {
2431
qDebug("Core::setSaturation: %d", value);
2433
if (value > 100) value = 100;
2434
if (value < -100) value = -100;
2436
if (value != mset.saturation) {
2437
tellmp(pausing_prefix() + " saturation " + QString::number(value) + " 1");
2438
mset.saturation = value;
2439
displayMessage( tr("Saturation: %1").arg(value) );
2440
emit videoEqualizerNeedsUpdate();
2444
void Core::incBrightness() {
2445
setBrightness(mset.brightness + 4);
2448
void Core::decBrightness() {
2449
setBrightness(mset.brightness - 4);
2452
void Core::incContrast() {
2453
setContrast(mset.contrast + 4);
2456
void Core::decContrast() {
2457
setContrast(mset.contrast - 4);
2460
void Core::incGamma() {
2461
setGamma(mset.gamma + 4);
2464
void Core::decGamma() {
2465
setGamma(mset.gamma - 4);
2468
void Core::incHue() {
2469
setHue(mset.hue + 4);
2472
void Core::decHue() {
2473
setHue(mset.hue - 4);
2476
void Core::incSaturation() {
2477
setSaturation(mset.saturation + 4);
2480
void Core::decSaturation() {
2481
setSaturation(mset.saturation - 4);
2484
void Core::setSpeed( double value ) {
2485
qDebug("Core::setSpeed: %f", value);
2487
if (value < 0.10) value = 0.10;
2488
if (value > 100) value = 100;
2491
tellmp( "speed_set " + QString::number( value ) );
2494
void Core::incSpeed10() {
2495
qDebug("Core::incSpeed10");
2496
setSpeed( (double) mset.speed + 0.1 );
2499
void Core::decSpeed10() {
2500
qDebug("Core::decSpeed10");
2501
setSpeed( (double) mset.speed - 0.1 );
2504
void Core::incSpeed4() {
2505
qDebug("Core::incSpeed4");
2506
setSpeed( (double) mset.speed + 0.04 );
2509
void Core::decSpeed4() {
2510
qDebug("Core::decSpeed4");
2511
setSpeed( (double) mset.speed - 0.04 );
2514
void Core::incSpeed1() {
2515
qDebug("Core::incSpeed1");
2516
setSpeed( (double) mset.speed + 0.01 );
2519
void Core::decSpeed1() {
2520
qDebug("Core::decSpeed1");
2521
setSpeed( (double) mset.speed - 0.01 );
2524
void Core::doubleSpeed() {
2525
qDebug("Core::doubleSpeed");
2526
setSpeed( (double) mset.speed * 2 );
2529
void Core::halveSpeed() {
2530
qDebug("Core::halveSpeed");
2531
setSpeed( (double) mset.speed / 2 );
2534
void Core::normalSpeed() {
2538
void Core::setVolume(int volume, bool force) {
2539
qDebug("Core::setVolume: %d", volume);
2541
if ((volume==mset.volume) && (!force)) return;
2543
mset.volume = volume;
2544
if (mset.volume > 100 ) mset.volume = 100;
2545
if (mset.volume < 0 ) mset.volume = 0;
2547
if (state() == Paused) {
2548
// Change volume later, after quiting pause
2549
change_volume_after_unpause = true;
2551
tellmp("volume " + QString::number(volume) + " 1");
2554
//if (mset.mute) mute(TRUE);
2559
displayMessage( tr("Volume: %1").arg(mset.volume) );
2560
emit volumeChanged( mset.volume );
2563
void Core::switchMute() {
2564
qDebug("Core::switchMute");
2566
mset.mute = !mset.mute;
2570
void Core::mute(bool b) {
2571
qDebug("Core::mute");
2576
if (mset.mute) v = 1;
2577
tellmp( pausing_prefix() + " mute " + QString::number(v) );
2582
void Core::incVolume() {
2583
qDebug("Core::incVolume");
2584
setVolume(mset.volume + 4);
2587
void Core::decVolume() {
2588
qDebug("Core::incVolume");
2589
setVolume(mset.volume-4);
2592
void Core::setSubDelay(int delay) {
2593
qDebug("Core::setSubDelay: %d", delay);
2594
mset.sub_delay = delay;
2595
tellmp("sub_delay " + QString::number( (double) mset.sub_delay/1000 ) +" 1");
2598
void Core::incSubDelay() {
2599
qDebug("Core::incSubDelay");
2600
setSubDelay(mset.sub_delay + 100);
2603
void Core::decSubDelay() {
2604
qDebug("Core::decSubDelay");
2605
setSubDelay(mset.sub_delay - 100);
2608
void Core::setAudioDelay(int delay) {
2609
qDebug("Core::setAudioDelay: %d", delay);
2610
mset.audio_delay = delay;
2611
tellmp("audio_delay " + QString::number( (double) mset.audio_delay/1000 ) +" 1");
2614
void Core::incAudioDelay() {
2615
qDebug("Core::incAudioDelay");
2616
setAudioDelay(mset.audio_delay + 100);
2619
void Core::decAudioDelay() {
2620
qDebug("Core::decAudioDelay");
2621
setAudioDelay(mset.audio_delay - 100);
2624
void Core::incSubPos() {
2625
qDebug("Core::incSubPos");
2628
if (mset.sub_pos > 100) mset.sub_pos = 100;
2629
tellmp("sub_pos " + QString::number( mset.sub_pos ) + " 1");
2632
void Core::decSubPos() {
2633
qDebug("Core::decSubPos");
2636
if (mset.sub_pos < 0) mset.sub_pos = 0;
2637
tellmp("sub_pos " + QString::number( mset.sub_pos ) + " 1");
2640
bool Core::subscale_need_restart() {
2641
bool need_restart = false;
2643
need_restart = (pref->change_sub_scale_should_restart == Preferences::Enabled);
2644
if (pref->change_sub_scale_should_restart == Preferences::Detect) {
2645
if (pref->use_ass_subtitles)
2646
need_restart = (!MplayerVersion::isMplayerAtLeast(25843));
2648
need_restart = (!MplayerVersion::isMplayerAtLeast(23745));
2650
return need_restart;
2653
void Core::changeSubScale(double value) {
2654
qDebug("Core::changeSubScale: %f", value);
2656
bool need_restart = subscale_need_restart();
2658
if (value < 0) value = 0;
2660
if (pref->use_ass_subtitles) {
2661
if (value != mset.sub_scale_ass) {
2662
mset.sub_scale_ass = value;
2666
tellmp("sub_scale " + QString::number( mset.sub_scale_ass ) + " 1");
2668
displayMessage( tr("Font scale: %1").arg(mset.sub_scale_ass) );
2672
if (value != mset.sub_scale) {
2673
mset.sub_scale = value;
2677
tellmp("sub_scale " + QString::number( mset.sub_scale ) + " 1");
2680
displayMessage( tr("Font scale: %1").arg(mset.sub_scale) );
2685
void Core::incSubScale() {
2688
if (pref->use_ass_subtitles) {
2689
changeSubScale( mset.sub_scale_ass + step );
2691
if (subscale_need_restart()) step = 1;
2692
changeSubScale( mset.sub_scale + step );
2696
void Core::decSubScale() {
2699
if (pref->use_ass_subtitles) {
2700
changeSubScale( mset.sub_scale_ass - step );
2702
if (subscale_need_restart()) step = 1;
2703
changeSubScale( mset.sub_scale - step );
2707
void Core::incSubStep() {
2708
qDebug("Core::incSubStep");
2709
tellmp("sub_step +1");
2712
void Core::decSubStep() {
2713
qDebug("Core::decSubStep");
2714
tellmp("sub_step -1");
2717
// Audio equalizer functions
2718
void Core::setAudioEqualizer(AudioEqualizerList values, bool restart) {
2719
mset.audio_equalizer = values;
2722
tellmp( "af_eq_set_bands " + Helper::equalizerListToString(values) );
2727
emit audioEqualizerNeedsUpdate();
2730
void Core::updateAudioEqualizer() {
2731
setAudioEqualizer(mset.audio_equalizer);
2734
void Core::setAudioEq0(int value) {
2735
mset.audio_equalizer[0] = value;
2736
updateAudioEqualizer();
2739
void Core::setAudioEq1(int value) {
2740
mset.audio_equalizer[1] = value;
2741
updateAudioEqualizer();
2744
void Core::setAudioEq2(int value) {
2745
mset.audio_equalizer[2] = value;
2746
updateAudioEqualizer();
2749
void Core::setAudioEq3(int value) {
2750
mset.audio_equalizer[3] = value;
2751
updateAudioEqualizer();
2754
void Core::setAudioEq4(int value) {
2755
mset.audio_equalizer[4] = value;
2756
updateAudioEqualizer();
2759
void Core::setAudioEq5(int value) {
2760
mset.audio_equalizer[5] = value;
2761
updateAudioEqualizer();
2764
void Core::setAudioEq6(int value) {
2765
mset.audio_equalizer[6] = value;
2766
updateAudioEqualizer();
2769
void Core::setAudioEq7(int value) {
2770
mset.audio_equalizer[7] = value;
2771
updateAudioEqualizer();
2774
void Core::setAudioEq8(int value) {
2775
mset.audio_equalizer[8] = value;
2776
updateAudioEqualizer();
2779
void Core::setAudioEq9(int value) {
2780
mset.audio_equalizer[9] = value;
2781
updateAudioEqualizer();
2786
void Core::changeCurrentSec(double sec) {
2787
mset.current_sec = sec;
2789
if (mset.starting_time != -1) {
2790
mset.current_sec -= mset.starting_time;
2793
if (state() != Playing) {
2795
qDebug("Core::changeCurrentSec: mplayer reports that now it's playing");
2796
//emit mediaStartPlay();
2797
//emit stateChanged(state());
2800
emit showTime(mset.current_sec);
2803
static int last_second = 0;
2805
if (floor(sec)==last_second) return; // Update only once per second
2806
last_second = (int) floor(sec);
2808
#ifdef SEEKBAR_RESOLUTION
2810
if ( (mdat.duration > 1) && (mset.current_sec > 1) &&
2811
(mdat.duration > mset.current_sec) )
2813
value = ( (int) mset.current_sec * SEEKBAR_RESOLUTION) / (int) mdat.duration;
2815
emit positionChanged(value);
2818
if ( (mdat.duration > 1) && (mset.current_sec > 1) &&
2819
(mdat.duration > mset.current_sec) )
2821
perc = ( (int) mset.current_sec * 100) / (int) mdat.duration;
2823
emit posChanged( perc );
2827
void Core::gotStartingTime(double time) {
2828
qDebug("Core::gotStartingTime: %f", time);
2829
qDebug("Core::gotStartingTime: current_sec: %f", mset.current_sec);
2830
if ((mset.starting_time == -1.0) && (mset.current_sec == 0)) {
2831
mset.starting_time = time;
2832
qDebug("Core::gotStartingTime: starting time set to %f", time);
2837
void Core::changePause() {
2838
qDebug("Core::changePause");
2839
qDebug("Core::changePause: mplayer reports that it's paused");
2841
//emit stateChanged(state());
2844
void Core::changeDeinterlace(int ID) {
2845
qDebug("Core::changeDeinterlace: %d", ID);
2847
if (ID!=mset.current_deinterlacer) {
2848
mset.current_deinterlacer = ID;
2855
void Core::changeSubtitle(int ID) {
2856
qDebug("Core::changeSubtitle: %d", ID);
2858
mset.current_sub_id = ID;
2859
if (ID==MediaSettings::SubNone) {
2863
if (ID==MediaSettings::NoneSelected) {
2865
qDebug("Core::changeSubtitle: subtitle is NoneSelected, this shouldn't happen. ID set to -1.");
2868
qDebug("Core::changeSubtitle: ID: %d", ID);
2870
bool use_new_commands = (pref->use_new_sub_commands == Preferences::Enabled);
2871
if (pref->use_new_sub_commands == Preferences::Detect) {
2872
use_new_commands = (MplayerVersion::isMplayerAtLeast(25158));
2875
if (!use_new_commands) {
2876
// Old command sub_select
2877
tellmp( "sub_select " + QString::number(ID) );
2882
tellmp( "sub_source -1" );
2884
bool valid_item = ( (ID >= 0) && (ID < mdat.subs.numItems()) );
2885
if (!valid_item) qWarning("Core::changeSubtitle: ID: %d is not valid!", ID);
2886
if ( (mdat.subs.numItems() > 0) && (valid_item) ) {
2887
real_id = mdat.subs.itemAt(ID).ID();
2888
switch (mdat.subs.itemAt(ID).type()) {
2890
tellmp( "sub_vob " + QString::number(real_id) );
2893
tellmp( "sub_demux " + QString::number(real_id) );
2896
tellmp( "sub_file " + QString::number(real_id) );
2899
qWarning("Core::changeSubtitle: unknown type!");
2903
qWarning("Core::changeSubtitle: subtitle list is empty!");
2911
void Core::nextSubtitle() {
2912
qDebug("Core::nextSubtitle");
2914
if ( (mset.current_sub_id == MediaSettings::SubNone) &&
2915
(mdat.subs.numItems() > 0) )
2920
int item = mset.current_sub_id + 1;
2921
if (item >= mdat.subs.numItems()) {
2922
item = MediaSettings::SubNone;
2924
changeSubtitle( item );
2928
void Core::changeAudio(int ID, bool allow_restart) {
2929
qDebug("Core::changeAudio: ID: %d, allow_restart: %d", ID, allow_restart);
2931
if (ID!=mset.current_audio_id) {
2932
mset.current_audio_id = ID;
2933
qDebug("changeAudio: ID: %d", ID);
2935
bool need_restart = false;
2936
if (allow_restart) {
2937
need_restart = (pref->fast_audio_change == Preferences::Disabled);
2938
if (pref->fast_audio_change == Preferences::Detect) {
2939
need_restart = (!MplayerVersion::isMplayerAtLeast(21441));
2946
tellmp("switch_audio " + QString::number(ID) );
2948
// Workaround for a mplayer problem in windows,
2949
// volume is too loud after changing audio.
2951
// Workaround too for a mplayer problem in linux,
2952
// the volume is reduced if using -softvol-max.
2953
if (!pref->dont_change_volume) {
2954
setVolume( mset.volume, true );
2957
if (mset.mute) mute(true); // if muted, mute again
2963
void Core::nextAudio() {
2964
qDebug("Core::nextAudio");
2966
int item = mdat.audios.find( mset.current_audio_id );
2968
qWarning("Core::nextAudio: audio ID %d not found!", mset.current_audio_id);
2970
qDebug( "Core::nextAudio: numItems: %d, item: %d", mdat.audios.numItems(), item);
2972
if (item >= mdat.audios.numItems()) item=0;
2973
int ID = mdat.audios.itemAt(item).ID();
2974
qDebug( "Core::nextAudio: item: %d, ID: %d", item, ID);
2979
void Core::changeVideo(int ID, bool allow_restart) {
2980
qDebug("Core::changeVideo: ID: %d, allow_restart: %d", ID, allow_restart);
2982
if (ID != mset.current_video_id) {
2983
mset.current_video_id = ID;
2984
qDebug("Core::changeVideo: ID set to: %d", ID);
2986
bool need_restart = false;
2987
if (allow_restart) {
2988
// afaik lavf doesn't require to restart, any other?
2989
need_restart = (mdat.demuxer != "lavf");
2995
tellmp("set_property switch_video " + QString::number(ID) );
3000
void Core::nextVideo() {
3001
qDebug("Core::nextVideo");
3003
int item = mdat.videos.find( mset.current_video_id );
3005
qWarning("Core::nextVideo: video ID %d not found!", mset.current_video_id);
3007
qDebug( "Core::nextVideo: numItems: %d, item: %d", mdat.videos.numItems(), item);
3009
if (item >= mdat.videos.numItems()) item=0;
3010
int ID = mdat.videos.itemAt(item).ID();
3011
qDebug( "Core::nextVideo: item: %d, ID: %d", item, ID);
3017
void Core::changeTitle(int ID) {
3018
if (mdat.type == TYPE_VCD) {
3023
if (mdat.type == TYPE_AUDIO_CD) {
3028
if (mdat.type == TYPE_DVD) {
3030
if (mdat.filename.startsWith("dvdnav:")) {
3031
tellmp("switch_title " + QString::number(ID));
3034
DiscData disc_data = DiscName::split(mdat.filename);
3035
disc_data.title = ID;
3036
QString dvd_url = DiscName::join(disc_data);
3038
openDVD( DiscName::join(disc_data) );
3045
void Core::changeChapter(int ID) {
3046
qDebug("Core::changeChapter: ID: %d", ID);
3048
if (ID != mset.current_chapter_id) {
3049
//if (QFileInfo(mdat.filename).extension().lower()=="mkv") {
3050
#if GENERIC_CHAPTER_SUPPORT
3051
if (mdat.type != TYPE_DVD) {
3053
if (mdat.mkv_chapters > 0) {
3054
// mkv doesn't require to restart
3056
tellmp("seek_chapter " + QString::number(ID) +" 1");
3057
mset.current_chapter_id = ID;
3060
#if SMART_DVD_CHAPTERS
3061
if (pref->cache_for_dvds == 0) {
3063
if (pref->fast_chapter_change) {
3065
tellmp("seek_chapter " + QString::number(ID) +" 1");
3066
mset.current_chapter_id = ID;
3070
mset.current_chapter_id = ID;
3072
mset.current_sec = 0;
3079
int Core::firstChapter() {
3080
if (MplayerVersion::isMplayerAtLeast(25391))
3086
#if !GENERIC_CHAPTER_SUPPORT
3087
int Core::dvdFirstChapter() {
3088
// TODO: check if the change really happens in the same version as mkv
3089
return firstChapter();
3093
void Core::prevChapter() {
3094
qDebug("Core::prevChapter");
3096
#if GENERIC_CHAPTER_SUPPORT
3097
int last_chapter = 0;
3098
int first_chapter = firstChapter();
3100
last_chapter = mdat.chapters + firstChapter() - 1;
3102
int ID = mset.current_chapter_id - 1;
3103
if (ID < first_chapter) {
3108
int last_chapter = 0;
3109
bool matroshka = (mdat.mkv_chapters > 0);
3111
int first_chapter = dvdFirstChapter();
3112
if (matroshka) first_chapter = firstChapter();
3114
// Matroshka chapters
3115
if (matroshka) last_chapter = mdat.mkv_chapters + firstChapter() - 1;
3118
if (mset.current_title_id > 0) {
3119
last_chapter = mdat.titles.item(mset.current_title_id).chapters() + dvdFirstChapter() -1;
3122
int ID = mset.current_chapter_id - 1;
3123
if (ID < first_chapter) {
3130
void Core::nextChapter() {
3131
qDebug("Core::nextChapter");
3133
#if GENERIC_CHAPTER_SUPPORT
3134
int last_chapter = 0;
3135
last_chapter = mdat.chapters + firstChapter() - 1;
3137
int ID = mset.current_chapter_id + 1;
3138
if (ID > last_chapter) {
3139
ID = firstChapter();
3143
int last_chapter = 0;
3144
bool matroshka = (mdat.mkv_chapters > 0);
3146
// Matroshka chapters
3147
if (matroshka) last_chapter = mdat.mkv_chapters + firstChapter() - 1;
3150
if (mset.current_title_id > 0) {
3151
last_chapter = mdat.titles.item(mset.current_title_id).chapters() + dvdFirstChapter() - 1;
3154
int ID = mset.current_chapter_id + 1;
3155
if (ID > last_chapter) {
3156
if (matroshka) ID = firstChapter(); else ID = dvdFirstChapter();
3162
void Core::changeAngle(int ID) {
3163
qDebug("Core::changeAngle: ID: %d", ID);
3165
if (ID != mset.current_angle_id) {
3166
mset.current_angle_id = ID;
3172
void Core::changeAspectRatio( int ID ) {
3173
qDebug("Core::changeAspectRatio: %d", ID);
3175
mset.aspect_ratio_id = ID;
3177
double asp = mset.aspectToNum( (MediaSettings::Aspect) ID);
3179
if (!pref->use_mplayer_window) {
3180
mplayerwindow->setAspect( asp );
3182
// Using mplayer own window
3183
if (!mdat.novideo) {
3184
tellmp("switch_ratio " + QString::number(asp));
3188
QString asp_name = MediaSettings::aspectToString( (MediaSettings::Aspect) mset.aspect_ratio_id);
3189
displayMessage( tr("Aspect ratio: %1").arg(asp_name) );
3192
void Core::nextAspectRatio() {
3193
int ID = mset.aspect_ratio_id + 1;
3194
if (ID > MediaSettings:: Aspect11) ID = MediaSettings::AspectNone;
3195
changeAspectRatio(ID);
3200
void Core::changeLetterbox(bool b) {
3201
qDebug("Core::changeLetterbox: %d", b);
3203
if (mset.add_letterbox != b) {
3204
mset.add_letterbox = b;
3210
void Core::changeAspectRatio( int ID ) {
3211
qDebug("Core::changeAspectRatio: %d", ID);
3213
int old_id = mset.aspect_ratio_id;
3214
mset.aspect_ratio_id = ID;
3215
bool need_restart = FALSE;
3217
double asp = mdat.video_aspect; // Set a default
3219
if (ID==MediaSettings::Aspect43Letterbox) {
3220
need_restart = (old_id != MediaSettings::Aspect43Letterbox);
3221
asp = (double) 4 / 3;
3222
mset.letterbox = MediaSettings::Letterbox_43;
3223
mset.panscan_filter = "";
3224
mset.crop_43to169_filter = "";
3227
if (ID==MediaSettings::Aspect169Letterbox) {
3228
need_restart = (old_id != MediaSettings::Aspect169Letterbox);
3229
asp = (double) 16 / 9;
3230
mset.letterbox = MediaSettings::Letterbox_169;
3231
mset.panscan_filter = "";
3232
mset.crop_43to169_filter = "";
3235
if (ID==MediaSettings::Aspect43Panscan) {
3236
need_restart = (old_id != MediaSettings::Aspect43Panscan);
3237
mset.crop_43to169_filter = "";
3238
mset.letterbox = MediaSettings::NoLetterbox;
3240
asp = (double) 4 / 3;
3241
int real_width = (int) round(mdat.video_height * mdat.video_aspect);
3242
mset.panscan_filter = QString("scale=%1:%2,").arg(real_width).arg(mdat.video_height);
3243
mset.panscan_filter += QString("crop=%1:%2").arg(round(mdat.video_height * 4 /3)).arg(mdat.video_height);
3244
//mset.crop = QSize( mdat.video_height * 4 /3, mdat.video_height );
3245
qDebug("Core::changeAspectRatio: panscan_filter = '%s'", mset.panscan_filter.toUtf8().data() );
3249
if (ID==MediaSettings::Aspect43To169) {
3250
need_restart = (old_id != MediaSettings::Aspect43To169);
3251
mset.panscan_filter = "";
3252
mset.crop_43to169_filter = "";
3253
mset.letterbox = MediaSettings::NoLetterbox;
3255
int real_width = (int) round(mdat.video_height * mdat.video_aspect);
3256
int height = (int) round(real_width * 9 / 16);
3258
qDebug("Core::changeAspectRatio: video_width: %d, video_height: %d", real_width, mdat.video_height);
3259
qDebug("Core::changeAspectRatio: crop: %d, %d", real_width, height );
3261
if (height > mdat.video_height) {
3262
// Invalid size, source video is not 4:3
3263
need_restart = FALSE;
3265
asp = (double) 16 / 9;
3266
mset.crop_43to169_filter = QString("scale=%1:%2,").arg(real_width).arg(mdat.video_height);
3267
mset.crop_43to169_filter += QString("crop=%1:%2").arg(real_width).arg(height);
3268
qDebug("Core::changeAspectRatio: crop_43to169_filter = '%s'", mset.crop_43to169_filter.toUtf8().data() );
3273
//need_restart = (mset.force_letterbox == TRUE);
3274
need_restart = ( (old_id == MediaSettings::Aspect43Letterbox) ||
3275
(old_id == MediaSettings::Aspect169Letterbox) ||
3276
(old_id == MediaSettings::Aspect43Panscan) ||
3277
(old_id == MediaSettings::Aspect43To169) );
3278
mset.letterbox = MediaSettings::NoLetterbox;
3279
mset.panscan_filter = "";
3280
mset.crop_43to169_filter = "";
3282
//case MediaSettings::AspectAuto: asp = mdat.video_aspect; break;
3283
case MediaSettings::AspectAuto: {
3284
qDebug("Core::changeAspectRatio: mset.win_width %d, mset.win_height: %d", mset.win_width, mset.win_height);
3285
asp = mset.win_aspect(); break;
3287
case MediaSettings::Aspect43: asp = (double) 4 / 3; break;
3288
case MediaSettings::Aspect169: asp = (double) 16 / 9; break;
3289
case MediaSettings::Aspect149: asp = (double) 14 / 9; break;
3290
case MediaSettings::Aspect1610: asp = (double) 16 / 10; break;
3291
case MediaSettings::Aspect54: asp = (double) 5 / 4; break;
3292
case MediaSettings::Aspect235: asp = 2.35; break;
3296
if (!pref->use_mplayer_window) {
3297
mplayerwindow->setAspect( asp );
3299
// Using mplayer own window
3300
tellmp("switch_ratio " + QString::number(asp));
3306
/*mdat.calculateWinResolution(mset.force_letterbox);*/
3312
void Core::changeOSD(int v) {
3313
qDebug("Core::changeOSD: %d", v);
3316
tellmp("osd " + QString::number( pref->osd ) );
3320
void Core::nextOSD() {
3321
int osd = pref->osd + 1;
3322
if (osd > Preferences::SeekTimerTotal) {
3323
osd = Preferences::None;
3328
void Core::changeRotate(int r) {
3329
qDebug("Core::changeRotate: %d", r);
3331
if (mset.rotate != r) {
3338
void Core::changeAdapter(int n) {
3339
qDebug("Core::changeScreen: %d", n);
3341
if (pref->adapter != n) {
3348
void Core::changeSize(int n) {
3349
if ( /*(n != pref->size_factor) &&*/ (!pref->use_mplayer_window) ) {
3350
pref->size_factor = n;
3352
emit needResize(mset.win_width, mset.win_height);
3357
void Core::toggleDoubleSize() {
3358
if (pref->size_factor != 100)
3364
void Core::changePanscan(double p) {
3365
qDebug("Core::changePanscan: %f", p);
3366
if (p < ZOOM_MIN) p = ZOOM_MIN;
3368
mset.panscan_factor = p;
3369
mplayerwindow->setZoom(p);
3370
displayMessage( tr("Zoom: %1").arg(mset.panscan_factor) );
3373
void Core::resetPanscan() {
3377
void Core::autoPanscan() {
3378
double video_aspect = mset.aspectToNum( (MediaSettings::Aspect) mset.aspect_ratio_id);
3380
if (video_aspect <= 0) {
3381
QSize w = mplayerwindow->videoLayer()->size();
3382
video_aspect = (double) w.width() / w.height();
3385
double screen_aspect = DesktopInfo::desktop_aspectRatio(mplayerwindow);
3388
if (video_aspect > screen_aspect)
3389
zoom_factor = video_aspect / screen_aspect;
3391
zoom_factor = screen_aspect / video_aspect;
3393
qDebug("Core::autoPanscan: video_aspect: %f", video_aspect);
3394
qDebug("Core::autoPanscan: screen_aspect: %f", screen_aspect);
3395
qDebug("Core::autoPanscan: zoom_factor: %f", zoom_factor);
3397
changePanscan(zoom_factor);
3400
void Core::autoPanscanFromLetterbox(double aspect) {
3401
qDebug("Core::autoPanscanFromLetterbox: %f", aspect);
3403
// Probably there's a much easy way to do this, but I'm not good with maths...
3405
QSize desktop = DesktopInfo::desktop_size(mplayerwindow);
3407
double video_aspect = mset.aspectToNum( (MediaSettings::Aspect) mset.aspect_ratio_id);
3409
if (video_aspect <= 0) {
3410
QSize w = mplayerwindow->videoLayer()->size();
3411
video_aspect = (double) w.width() / w.height();
3414
// Calculate size of the video in fullscreen
3416
video.setHeight( desktop.height() );;
3417
video.setWidth( (int) (video.height() * video_aspect) );
3418
if (video.width() > desktop.width()) {
3419
video.setWidth( desktop.width() );;
3420
video.setHeight( (int) (video.width() / video_aspect) );
3423
qDebug("Core::autoPanscanFromLetterbox: max. size of video: %d %d", video.width(), video.height());
3425
// Calculate the size of the actual video inside the letterbox
3427
actual_video.setWidth( video.width() );
3428
actual_video.setHeight( (int) (actual_video.width() / aspect) );
3430
qDebug("Core::autoPanscanFromLetterbox: calculated size of actual video for aspect %f: %d %d", aspect, actual_video.width(), actual_video.height());
3432
double zoom_factor = (double) desktop.height() / actual_video.height();
3434
qDebug("Core::autoPanscanFromLetterbox: calculated zoom factor: %f", zoom_factor);
3435
changePanscan(zoom_factor);
3438
void Core::autoPanscanFor169() {
3439
autoPanscanFromLetterbox((double) 16 / 9);
3442
void Core::autoPanscanFor235() {
3443
autoPanscanFromLetterbox(2.35);
3446
void Core::incPanscan() {
3447
qDebug("Core::incPanscan");
3448
changePanscan( mset.panscan_factor + ZOOM_STEP );
3451
void Core::decPanscan() {
3452
qDebug("Core::decPanscan");
3453
changePanscan( mset.panscan_factor - ZOOM_STEP );
3456
void Core::changeUseAss(bool b) {
3457
qDebug("Core::changeUseAss: %d", b);
3459
if (pref->use_ass_subtitles != b) {
3460
pref->use_ass_subtitles = b;
3461
if (proc->isRunning()) restartPlay();
3465
void Core::toggleClosedCaption(bool b) {
3466
qDebug("Core::toggleClosedCaption: %d", b);
3468
if (pref->use_closed_caption_subs != b) {
3469
pref->use_closed_caption_subs = b;
3470
if (proc->isRunning()) restartPlay();
3474
void Core::toggleForcedSubsOnly(bool b) {
3475
qDebug("Core::toggleForcedSubsOnly: %d", b);
3477
if (pref->use_forced_subs_only != b) {
3478
pref->use_forced_subs_only = b;
3479
//if (proc->isRunning()) restartPlay();
3482
tellmp( QString("forced_subs_only %1").arg(v) );
3486
void Core::visualizeMotionVectors(bool b) {
3487
qDebug("Core::visualizeMotionVectors: %d", b);
3489
if (pref->show_motion_vectors != b) {
3490
pref->show_motion_vectors = b;
3491
if (proc->isRunning()) restartPlay();
3497
void Core::dvdnavUp() {
3498
qDebug("Core::dvdnavUp");
3499
tellmp("dvdnav up");
3502
void Core::dvdnavDown() {
3503
qDebug("Core::dvdnavDown");
3504
tellmp("dvdnav down");
3507
void Core::dvdnavLeft() {
3508
qDebug("Core::dvdnavLeft");
3509
tellmp("dvdnav left");
3512
void Core::dvdnavRight() {
3513
qDebug("Core::dvdnavRight");
3514
tellmp("dvdnav right");
3517
void Core::dvdnavMenu() {
3518
qDebug("Core::dvdnavMenu");
3519
tellmp("dvdnav menu");
3522
void Core::dvdnavSelect() {
3523
qDebug("Core::dvdnavSelect");
3524
tellmp("dvdnav select");
3527
void Core::dvdnavPrev() {
3528
qDebug("Core::dvdnavPrev");
3529
tellmp("dvdnav prev");
3532
void Core::dvdnavMouse() {
3533
qDebug("Core::dvdnavMouse");
3535
if ((state() == Playing) && (mdat.filename.startsWith("dvdnav:"))) {
3536
//QPoint p = mplayerwindow->videoLayer()->mapFromGlobal(QCursor::pos());
3537
//tellmp(QString("set_mouse_pos %1 %2").arg(p.x()).arg(p.y()));
3538
tellmp("dvdnav mouse");
3543
void Core::displayMessage(QString text) {
3544
qDebug("Core::displayMessage");
3545
emit showMessage(text);
3547
if ((pref->fullscreen) && (state() != Paused)) {
3548
tellmp("osd_show_text \"" + text + "\" 3000 1");
3552
void Core::displayScreenshotName(QString filename) {
3553
qDebug("Core::displayScreenshotName");
3554
//QString text = tr("Screenshot saved as %1").arg(filename);
3555
QString text = QString("Screenshot saved as %1").arg(filename);
3557
if (MplayerVersion::isMplayerAtLeast(27665)) {
3558
tellmp( "pausing_keep_force osd_show_text \"" + text + "\" 3000 1");
3561
if (state() != Paused) {
3562
// Dont' show the message on OSD while in pause, otherwise
3563
// the video goes forward a frame.
3564
tellmp("pausing_keep osd_show_text \"" + text + "\" 3000 1");
3567
emit showMessage(text);
3570
void Core::displayUpdatingFontCache() {
3571
qDebug("Core::displayUpdatingFontCache");
3572
emit showMessage( tr("Updating the font cache. This may take some seconds...") );
3575
void Core::gotWindowResolution(int w, int h) {
3576
qDebug("Core::gotWindowResolution: %d, %d", w, h);
3577
//double aspect = (double) w/h;
3579
if (pref->use_mplayer_window) {
3582
if ((pref->resize_method==Preferences::Afterload) && (we_are_restarting)) {
3585
emit needResize(w,h);
3590
mset.win_height = h;
3592
//Override aspect ratio, is this ok?
3593
//mdat.video_aspect = mset.win_aspect();
3595
mplayerwindow->setResolution( w, h );
3596
mplayerwindow->setAspect( mset.win_aspect() );
3599
void Core::gotNoVideo() {
3600
// File has no video (a sound file)
3602
// Reduce size of window
3604
mset.win_width = mplayerwindow->size().width();
3605
mset.win_height = 0;
3606
mplayerwindow->setResolution( mset.win_width, mset.win_height );
3607
emit needResize( mset.win_width, mset.win_height );
3609
//mplayerwindow->showLogo(TRUE);
3613
void Core::gotVO(QString vo) {
3614
qDebug("Core::gotVO: '%s'", vo.toUtf8().data() );
3616
if ( pref->vo.isEmpty()) {
3617
qDebug("Core::gotVO: saving vo");
3622
void Core::gotAO(QString ao) {
3623
qDebug("Core::gotAO: '%s'", ao.toUtf8().data() );
3625
if ( pref->ao.isEmpty()) {
3626
qDebug("Core::gotAO: saving ao");
3631
void Core::streamTitleAndUrlChanged(QString title, QString url) {
3632
mdat.stream_title = title;
3633
mdat.stream_url = url;
3634
emit mediaInfoChanged();
3637
//! Called when the state changes
3638
void Core::watchState(Core::State state) {
3639
if ((state == Playing) && (change_volume_after_unpause))
3641
// Delayed volume change
3642
qDebug("Core::watchState: delayed volume change");
3643
tellmp("volume " + QString::number(mset.volume) + " 1");
3644
change_volume_after_unpause = false;
3648
void Core::checkIfVideoIsHD() {
3649
qDebug("Core::checkIfVideoIsHD");
3651
// Check if the video is in HD and uses ffh264 codec.
3652
if ((mdat.video_codec=="ffh264") && (mset.win_height >= pref->HD_height)) {
3653
qDebug("Core::checkIfVideoIsHD: video == ffh264 and height >= %d", pref->HD_height);
3654
if (!mset.is264andHD) {
3655
mset.is264andHD = true;
3656
if (pref->h264_skip_loop_filter == Preferences::LoopDisabledOnHD) {
3657
qDebug("Core::checkIfVideoIsHD: we're about to restart the video");
3662
mset.is264andHD = false;
3663
// FIXME: if the video was previously marked as HD, and now it's not
3664
// then the video should restart too.
3668
#if DELAYED_AUDIO_SETUP_ON_STARTUP && NOTIFY_AUDIO_CHANGES
3669
#error "DELAYED_AUDIO_SETUP_ON_STARTUP and NOTIFY_AUDIO_CHANGES can't be both defined"
3672
#if DELAYED_AUDIO_SETUP_ON_STARTUP
3673
void Core::initAudioTrack() {
3674
qDebug("Core::initAudioTrack");
3676
// First audio if none selected
3677
if ( (mset.current_audio_id == MediaSettings::NoneSelected) &&
3678
(mdat.audios.numItems() > 0) )
3680
// Don't set mset.current_audio_id here! changeAudio will do.
3681
// Otherwise changeAudio will do nothing.
3683
int audio = mdat.audios.itemAt(0).ID(); // First one
3684
if (mdat.audios.existsItemAt(pref->initial_audio_track-1)) {
3685
audio = mdat.audios.itemAt(pref->initial_audio_track-1).ID();
3688
// Check if one of the audio tracks is the user preferred.
3689
if (!pref->audio_lang.isEmpty()) {
3690
int res = mdat.audios.findLang( pref->audio_lang );
3691
if (res != -1) audio = res;
3694
changeAudio( audio );
3699
#if NOTIFY_AUDIO_CHANGES
3700
void Core::initAudioTrack(const Tracks & audios) {
3701
qDebug("Core::initAudioTrack");
3703
qDebug("Core::initAudioTrack: num_items: %d", mdat.audios.numItems());
3705
bool restore_audio = ((mdat.audios.numItems() > 0) ||
3706
(mset.current_audio_id != MediaSettings::NoneSelected));
3708
mdat.audios = audios;
3710
qDebug("Core::initAudioTrack: list of audios:");
3715
if (!restore_audio) {
3716
// Select initial track
3717
qDebug("Core::initAudioTrack: selecting initial track");
3719
int audio = mdat.audios.itemAt(0).ID(); // First one
3720
if (mdat.audios.existsItemAt(pref->initial_audio_track-1)) {
3721
audio = mdat.audios.itemAt(pref->initial_audio_track-1).ID();
3724
// Check if one of the audio tracks is the user preferred.
3725
if (!pref->audio_lang.isEmpty()) {
3726
int res = mdat.audios.findLang( pref->audio_lang );
3727
if (res != -1) audio = res;
3730
changeAudio( audio );
3732
// Try to restore previous audio track
3733
qDebug("Core::initAudioTrack: restoring audio");
3734
// Nothing to do, the audio is already set with -aid
3739
emit audioTracksChanged();
3743
#if NOTIFY_SUB_CHANGES
3744
void Core::initSubtitleTrack(const SubTracks & subs) {
3745
qDebug("Core::initSubtitleTrack");
3747
qDebug("Core::initSubtitleTrack: num_items: %d", mdat.subs.numItems());
3749
bool restore_subs = ((mdat.subs.numItems() > 0) ||
3750
(mset.current_sub_id != MediaSettings::NoneSelected));
3753
SubData::Type previous_sub_type = SubData::Sub;
3754
int previous_sub_id = -1;
3755
if (mdat.subs.numItems() > 0) {
3756
if ((mset.current_sub_id != MediaSettings::SubNone) &&
3757
(mset.current_sub_id != MediaSettings::NoneSelected))
3759
previous_sub_type = mdat.subs.itemAt(mset.current_sub_id).type();
3760
previous_sub_id = mdat.subs.itemAt(mset.current_sub_id).ID();
3763
qDebug("Core::initSubtitleTrack: previous subtitle: type: %d id: %d", previous_sub_type, previous_sub_id);
3767
qDebug("Core::initSubtitleTrack: list of subtitles:");
3772
if (just_unloaded_external_subs) {
3773
qDebug("Core::initSubtitleTrack: just_unloaded_external_subs: true");
3774
restore_subs = false;
3775
just_unloaded_external_subs = false;
3777
if (just_loaded_external_subs) {
3778
qDebug("Core::initSubtitleTrack: just_loaded_external_subs: true");
3779
restore_subs = false;
3780
just_loaded_external_subs = false;
3782
QFileInfo fi(mset.external_subtitles);
3783
if (fi.suffix().toLower() != "idx") {
3784
// The loaded subtitle file is the last one, so
3785
// try to select that one.
3786
if (mdat.subs.numItems() > 0) {
3787
changeSubtitle( mdat.subs.numItems()-1 );
3793
if (!restore_subs) {
3794
// Select initial track
3795
qDebug("Core::initSubtitleTrack: selecting initial track");
3797
if (!pref->autoload_sub) {
3798
changeSubtitle( MediaSettings::SubNone );
3800
//Select first subtitle
3801
int sub = mdat.subs.selectOne( pref->subtitle_lang, pref->initial_subtitle_track-1 );
3802
changeSubtitle( sub );
3805
// Try to restore previous subtitle track
3806
qDebug("Core::initSubtitleTrack: restoring subtitle");
3808
if (mset.current_sub_id == MediaSettings::SubNone) {
3809
changeSubtitle( MediaSettings::SubNone );
3812
if (mset.current_sub_id != MediaSettings::NoneSelected) {
3813
// Try to find old subtitle
3814
int item = mset.current_sub_id;
3815
if (previous_sub_id != -1) {
3816
int sub_item = mdat.subs.find(previous_sub_type, previous_sub_id);
3817
if (sub_item > -1) {
3819
qDebug("Core::initSubtitleTrack: previous subtitle found: %d", sub_item);
3823
changeSubtitle(item );
3825
qDebug("Core::initSubtitleTrack: previous subtitle not found!");
3833
void Core::setSubtitleTrackAgain(const SubTracks &) {
3834
qDebug("Core::setSubtitleTrackAgain");
3835
changeSubtitle( mset.current_sub_id );
3840
void Core::dvdTitleChanged(int title) {
3841
qDebug("Core::dvdTitleChanged: %d", title);
3844
void Core::durationChanged(double length) {
3845
qDebug("Core::durationChanged: %f", length);
3846
mdat.duration = length;
3849
void Core::askForInfo() {
3850
if ((state() == Playing) && (mdat.filename.startsWith("dvdnav:"))) {
3851
tellmp( pausing_prefix() + " get_property length");
3855
void Core::dvdnavUpdateMousePos(QPoint pos) {
3856
if ((state() == Playing) && (mdat.filename.startsWith("dvdnav:"))) {
3857
if (mplayerwindow->videoLayer()->underMouse()) {
3858
QPoint p = mplayerwindow->videoLayer()->mapFromParent(pos);
3859
tellmp(QString("set_mouse_pos %1 %2").arg(p.x()).arg(p.y()));
3865
QString Core::pausing_prefix() {
3866
qDebug("Core::pausing_prefix");
3868
if ( (pref->use_pausing_keep_force) &&
3869
(MplayerVersion::isMplayerAtLeast(27665)) )
3871
return "pausing_keep_force";
3873
return "pausing_keep";
3877
#include "moc_core.cpp"