1
/* smplayer, GUI front-end for mplayer.
2
Copyright (C) 2006-2008 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 "mplayerprocess.h"
28
#include "mplayerwindow.h"
29
#include "desktopinfo.h"
31
#include "preferences.h"
34
#include "mplayerversion.h"
35
#include "constants.h"
38
#include <windows.h> // To change app priority
39
#include <QSysInfo> // To get Windows version
40
#include "screensaver.h"
43
using namespace Global;
45
Core::Core( MplayerWindow *mpw, QWidget* parent )
52
we_are_restarting = false;
53
just_loaded_external_subs = false;
54
just_unloaded_external_subs = false;
55
change_volume_after_unpause = false;
57
#ifndef NO_USE_INI_FILES
58
// Create file_settings
59
if (Helper::iniPath().isEmpty()) {
60
file_settings = new QSettings(QSettings::IniFormat, QSettings::UserScope,
61
QString(COMPANY), QString("smplayer_files") );
63
QString filename = Helper::iniPath() + "/smplayer_files.ini";
64
file_settings = new QSettings( filename, QSettings::IniFormat );
65
qDebug("Core::Core: file_settings: '%s'", filename.toUtf8().data());
69
proc = new MplayerProcess(this);
72
connect( proc, SIGNAL(processExited()),
73
mplayerwindow->videoLayer(), SLOT(playingStopped()) );
75
connect( proc, SIGNAL(error(QProcess::ProcessError)),
76
mplayerwindow->videoLayer(), SLOT(playingStopped()) );
78
connect( proc, SIGNAL(receivedCurrentSec(double)),
79
this, SLOT(changeCurrentSec(double)) );
81
connect( proc, SIGNAL(receivedCurrentFrame(int)),
82
this, SIGNAL(showFrame(int)) );
84
connect( proc, SIGNAL(receivedPause()),
85
this, SLOT(changePause()) );
87
connect( proc, SIGNAL(processExited()),
88
this, SLOT(processFinished()) );
90
connect( proc, SIGNAL(mplayerFullyLoaded()),
91
this, SLOT(finishRestart()) );
93
connect( proc, SIGNAL(lineAvailable(QString)),
94
this, SLOT(updateLog(QString)) );
96
connect( proc, SIGNAL(receivedCacheMessage(QString)),
97
this, SLOT(displayMessage(QString)) );
99
connect( proc, SIGNAL(receivedCreatingIndex(QString)),
100
this, SLOT(displayMessage(QString)) );
102
connect( proc, SIGNAL(receivedConnectingToMessage(QString)),
103
this, SLOT(displayMessage(QString)) );
105
connect( proc, SIGNAL(receivedResolvingMessage(QString)),
106
this, SLOT(displayMessage(QString)) );
108
connect( proc, SIGNAL(receivedScreenshot(QString)),
109
this, SLOT(displayScreenshotName(QString)) );
111
connect( proc, SIGNAL(receivedWindowResolution(int,int)),
112
this, SLOT(gotWindowResolution(int,int)) );
114
connect( proc, SIGNAL(receivedNoVideo()),
115
this, SLOT(gotNoVideo()) );
117
connect( proc, SIGNAL(receivedVO(QString)),
118
this, SLOT(gotVO(QString)) );
120
connect( proc, SIGNAL(receivedAO(QString)),
121
this, SLOT(gotAO(QString)) );
123
connect( proc, SIGNAL(receivedEndOfFile()),
124
this, SLOT(fileReachedEnd()) );
126
connect( proc, SIGNAL(receivedStartingTime(double)),
127
this, SLOT(gotStartingTime(double)) );
129
connect( proc, SIGNAL(receivedStreamTitleAndUrl(QString,QString)),
130
this, SLOT(streamTitleAndUrlChanged(QString,QString)) );
132
connect( proc, SIGNAL(failedToParseMplayerVersion(QString)),
133
this, SIGNAL(failedToParseMplayerVersion(QString)) );
135
connect( this, SIGNAL(mediaLoaded()), this, SLOT(autosaveMplayerLog()) );
136
connect( this, SIGNAL(mediaLoaded()), this, SLOT(checkIfVideoIsHD()) );
138
connect( this, SIGNAL(stateChanged(Core::State)),
139
this, SLOT(watchState(Core::State)) );
141
connect( proc, SIGNAL(error(QProcess::ProcessError)),
142
this, SIGNAL(mplayerFailed(QProcess::ProcessError)) );
148
connect( this, SIGNAL(aboutToStartPlaying()),
149
mplayerwindow->videoLayer(), SLOT(playingStarted()) );
151
mplayerwindow->videoLayer()->allowClearingBackground(pref->always_clear_video_background);
152
mplayerwindow->setMonitorAspect( pref->monitor_aspect_double() );
155
// Windows screensaver
156
win_screensaver = new WinScreenSaver();
162
#ifndef NO_USE_INI_FILES
166
if (proc->isRunning()) stopMplayer();
170
#ifndef NO_USE_INI_FILES
171
delete file_settings;
175
delete win_screensaver;
179
void Core::setState(State s) {
182
emit stateChanged(_state);
186
QString Core::stateToString() {
187
if (state()==Playing) return "Playing";
189
if (state()==Stopped) return "Stopped";
191
if (state()==Paused) return "Paused";
197
void Core::restart() {
198
qDebug("Core::restart");
199
if (proc->isRunning()) {
202
qDebug("Core::restart: mplayer is not running");
206
void Core::reload() {
207
qDebug("Core::reload");
210
we_are_restarting = false;
215
#ifndef NO_USE_INI_FILES
216
bool Core::checkHaveSettingsSaved(QString group_name) {
217
qDebug("Core::checkHaveSettingsSaved: group_name: '%s'", group_name.toUtf8().data());
219
file_settings->beginGroup( group_name );
220
bool saved = file_settings->value( "saved", false ).toBool();
221
file_settings->endGroup();
226
void Core::saveMediaInfo() {
227
qDebug("Core::saveMediaInfo");
229
if (pref->dont_remember_media_settings) {
230
qDebug("Core::saveMediaInfo: not saving settings, disabled by user");
237
if ( (mdat.type == TYPE_DVD) && (!mdat.dvd_id.isEmpty()) ) {
238
group_name = dvdForPref( mdat.dvd_id, mset.current_title_id );
242
if ( (mdat.type == TYPE_FILE) && (!mdat.filename.isEmpty()) ) {
243
group_name = Helper::filenameForPref( mdat.filename );
246
if (!group_name.isEmpty()) {
247
file_settings->beginGroup( group_name );
248
file_settings->setValue( "saved", true);
250
/*mdat.save(*settings);*/
251
mset.save(file_settings);
253
file_settings->endGroup();
257
void Core::loadMediaInfo(QString group_name) {
258
qDebug("Core::loadMediaInfo: '%s'", group_name.toUtf8().data() );
260
file_settings->beginGroup( group_name );
262
/*mdat.load(*settings);*/
263
mset.load(file_settings);
265
file_settings->endGroup();
268
#endif // NO_USE_INI_FILES
270
void Core::updateLog(QString line) {
271
if (pref->log_mplayer) {
272
if ( (line.indexOf("A:")==-1) && (line.indexOf("V:")==-1) ) {
273
mplayer_log += line + "\n";
278
void Core::initializeMenus() {
279
qDebug("Core::initializeMenus");
281
emit menusNeedInitialize();
285
void Core::updateWidgets() {
286
qDebug("Core::updateWidgets");
288
emit widgetsNeedUpdate();
292
void Core::tellmp(const QString & command) {
293
qDebug("Core::tellmp: '%s'", command.toUtf8().data());
295
//qDebug("Command: '%s'", command.toUtf8().data());
296
if (proc->isRunning()) {
297
proc->writeToStdin( command );
299
qWarning(" tellmp: no process running: %s", command.toUtf8().data());
303
// Generic open, autodetect type
304
void Core::open(QString file, int seek) {
305
qDebug("Core::open: '%s'", file.toUtf8().data());
309
if ( (fi.exists()) && (fi.suffix().toLower()=="iso") ) {
310
qDebug(" * identified as a dvd iso");
311
openDVD("dvd://1:" + file);
314
if ( (fi.exists()) && (!fi.isDir()) ) {
315
qDebug(" * identified as local file");
317
file = QFileInfo(file).absoluteFilePath();
318
openFile(file, seek);
321
if ( (fi.exists()) && (fi.isDir()) ) {
323
qDebug(" * identified as a directory");
324
qDebug(" checking if contains a dvd");
325
file = QFileInfo(file).absoluteFilePath();
326
if (Helper::directoryContainsDVD(file)) {
327
qDebug(" * directory contains a dvd");
328
openDVD("dvd://1:"+ file);
330
qDebug(" * directory doesn't contain a dvd");
331
qDebug(" opening nothing");
335
if (file.toLower().startsWith("dvd:")) {
336
qDebug(" * identified as dvd");
339
QString f = file.lower();
340
QRegExp s("^dvd://(\\d+)");
341
if (s.indexIn(f) != -1) {
342
int title = s.cap(1).toInt();
345
qWarning("Core::open: couldn't parse dvd title, playing first one");
351
if (file.toLower().startsWith("vcd:")) {
352
qDebug(" * identified as vcd");
354
QString f = file.toLower();
355
QRegExp s("^vcd://(\\d+)");
356
if (s.indexIn(f) != -1) {
357
int title = s.cap(1).toInt();
360
qWarning("Core::open: couldn't parse vcd title, playing first one");
365
if (file.toLower().startsWith("cdda:")) {
366
qDebug(" * identified as cdda");
368
QString f = file.toLower();
369
QRegExp s("^cdda://(\\d+)");
370
if (s.indexIn(f) != -1) {
371
int title = s.cap(1).toInt();
374
qWarning("Core::open: couldn't parse cdda title, playing first one");
379
qDebug(" * not identified, playing as stream");
384
void Core::openFile(QString filename, int seek) {
385
qDebug("Core::openFile: '%s'", filename.toUtf8().data());
387
QFileInfo fi(filename);
389
playNewFile(fi.absoluteFilePath(), seek);
391
//File doesn't exists
392
//TODO: error message
397
void Core::loadSub(const QString & sub ) {
398
if ( !sub.isEmpty() ) {
399
//tellmp( "sub_load " + sub );
400
mset.external_subtitles = sub;
401
just_loaded_external_subs = true;
406
void Core::unloadSub() {
407
if ( !mset.external_subtitles.isEmpty() ) {
408
mset.external_subtitles = "";
409
just_unloaded_external_subs = true;
414
void Core::loadAudioFile(const QString & audiofile) {
415
if (!audiofile.isEmpty()) {
416
mset.external_audio = audiofile;
421
void Core::unloadAudioFile() {
422
if (!mset.external_audio.isEmpty()) {
423
mset.external_audio = "";
429
void Core::openDVD( bool from_folder, QString directory) {
430
qDebug("Core::openDVD");
433
if (!directory.isEmpty()) {
434
QFileInfo fi(directory);
435
if ( (fi.exists()) && (fi.isDir()) ) {
436
pref->dvd_directory = directory;
437
pref->play_dvd_from_hd = TRUE;
440
qDebug("Core::openDVD: directory '%s' is not valid", directory.toUtf8().data());
443
qDebug("Core::openDVD: directory is empty");
446
pref->play_dvd_from_hd = FALSE;
451
void Core::openDVD() {
455
void Core::openDVD(int title) {
456
qDebug("Core::openDVD: %d", title);
458
if (proc->isRunning()) {
462
// Save data of previous file:
466
mdat.filename = "dvd://" + QString::number(title);
467
mdat.type = TYPE_DVD;
471
mset.current_title_id = title;
472
mset.current_chapter_id = 1;
473
mset.current_angle_id = 1;
481
void Core::openVCD(int title) {
482
qDebug("Core::openVCD: %d", title);
484
if (title == -1) title = pref->vcd_initial_title;
486
if (proc->isRunning()) {
490
// Save data of previous file:
491
#ifndef NO_USE_INI_FILES
496
mdat.filename = "vcd://" + QString::number(title);
497
mdat.type = TYPE_VCD;
501
mset.current_title_id = title;
502
mset.current_chapter_id = -1;
503
mset.current_angle_id = -1;
505
/* initializeMenus(); */
510
void Core::openAudioCD(int title) {
511
qDebug("Core::openAudioCD: %d", title);
513
if (title == -1) title = 1;
515
if (proc->isRunning()) {
519
// Save data of previous file:
520
#ifndef NO_USE_INI_FILES
525
mdat.filename = "cdda://" + QString::number(title);
526
mdat.type = TYPE_AUDIO_CD;
530
mset.current_title_id = title;
531
mset.current_chapter_id = -1;
532
mset.current_angle_id = -1;
534
/* initializeMenus(); */
539
void Core::openDVD(QString dvd_url) {
540
qDebug("Core::openDVD: '%s'", dvd_url.toUtf8().data());
543
QString folder = Helper::dvdSplitFolder(dvd_url);
544
int title = Helper::dvdSplitTitle(dvd_url);
547
qWarning("Core::openDVD: title invalid, not playing dvd");
551
if (folder.isEmpty()) {
552
qDebug("Core::openDVD: not folder");
554
QFileInfo fi(folder);
555
if ( (!fi.exists()) /*|| (!fi.isDir())*/ ) {
556
qWarning("Core::openDVD: folder invalid, not playing dvd");
561
if (proc->isRunning()) {
563
we_are_restarting = false;
566
// Save data of previous file:
567
#ifndef NO_USE_INI_FILES
572
mdat.filename = dvd_url;
573
mdat.type = TYPE_DVD;
577
mset.current_title_id = title;
578
mset.current_chapter_id = dvd_first_chapter();
579
mset.current_angle_id = 1;
581
/* initializeMenus(); */
586
void Core::openStream(QString name) {
587
qDebug("Core::openStream: '%s'", name.toUtf8().data());
589
if (proc->isRunning()) {
591
we_are_restarting = false;
594
// Save data of previous file:
595
#ifndef NO_USE_INI_FILES
600
mdat.filename = name;
601
mdat.type = TYPE_STREAM;
605
/* initializeMenus(); */
611
void Core::playNewFile(QString file, int seek) {
612
qDebug("Core::playNewFile: '%s'", file.toUtf8().data());
614
if (proc->isRunning()) {
616
we_are_restarting = false;
619
// Save data of previous file:
620
#ifndef NO_USE_INI_FILES
625
mdat.filename = file;
626
mdat.type = TYPE_FILE;
628
int old_volume = mset.volume;
631
#ifndef NO_USE_INI_FILES
632
// Check if we already have info about this file
633
if (checkHaveSettingsSaved( Helper::filenameForPref(file) )) {
634
qDebug("We have settings for this file!!!");
636
// In this case we read info from config
637
if (!pref->dont_remember_media_settings) {
638
loadMediaInfo( Helper::filenameForPref(file) );
639
qDebug("Media settings read");
640
if (pref->dont_remember_time_pos) {
641
mset.current_sec = 0;
642
qDebug("Time pos reset to 0");
645
qDebug("Media settings have not read because of preferences setting");
649
mset.volume = old_volume;
653
mset.volume = old_volume;
654
#endif // NO_USE_INI_FILES
656
/* initializeMenus(); */
658
qDebug("Core::playNewFile: volume: %d, old_volume: %d", mset.volume, old_volume);
663
void Core::restartPlay() {
664
we_are_restarting = true;
668
void Core::initPlaying(int seek) {
669
qDebug("Core::initPlaying");
676
/* updateWidgets(); */
678
mplayerwindow->showLogo(FALSE);
680
if (proc->isRunning()) {
684
int start_sec = (int) mset.current_sec;
685
if (seek > -1) start_sec = seek;
687
startMplayer( mdat.filename, start_sec );
690
// This is reached when a new video has just started playing
691
// and maybe we need to give some defaults
692
void Core::newMediaPlaying() {
693
qDebug("Core::newMediaPlaying");
695
QString file = mdat.filename;
696
int type = mdat.type;
697
mdat = proc->mediaData();
698
mdat.filename = file;
701
initializeMenus(); // Old
703
// First audio if none selected
704
if ( (mset.current_audio_id == MediaSettings::NoneSelected) &&
705
(mdat.audios.numItems() > 0) )
707
// Don't set mset.current_audio_id here! changeAudio will do.
708
// Otherwise changeAudio will do nothing.
710
int audio = mdat.audios.itemAt(0).ID(); // First one
711
if (mdat.audios.existsItemAt(pref->initial_audio_track-1)) {
712
audio = mdat.audios.itemAt(pref->initial_audio_track-1).ID();
715
// Check if one of the audio tracks is the user preferred.
716
if (!pref->audio_lang.isEmpty()) {
717
int res = mdat.audios.findLang( pref->audio_lang );
718
if (res != -1) audio = res;
721
changeAudio( audio );
725
if (mset.external_subtitles.isEmpty()) {
726
if (pref->autoload_sub) {
727
//Select first subtitle if none selected
728
if (mset.current_sub_id == MediaSettings::NoneSelected) {
729
int sub = mdat.subs.selectOne( pref->subtitle_lang, pref->initial_subtitle_track-1 );
730
changeSubtitle( sub );
733
changeSubtitle( MediaSettings::SubNone );
738
if (mdat.mkv_chapters > 0) {
739
// Just to show the first chapter checked in the menu
740
mset.current_chapter_id = mkv_first_chapter();
743
mdat.initialized = TRUE;
745
// MPlayer doesn't display the length in ID_LENGTH for audio CDs...
746
if ((mdat.duration == 0) && (mdat.type == TYPE_AUDIO_CD)) {
748
qDebug(" *** get duration here from title info *** ");
749
qDebug(" *** current title: %d", mset.current_title_id );
751
if (mset.current_title_id > 0) {
752
mdat.duration = mdat.titles.item(mset.current_title_id).duration();
756
/* updateWidgets(); */
762
void Core::finishRestart() {
763
qDebug("Core::finishRestart");
765
if (!we_are_restarting) {
767
emit mediaStartPlay();
770
if (we_are_restarting) {
771
// Update info about codecs and demuxer
772
mdat.video_codec = proc->mediaData().video_codec;
773
mdat.audio_codec = proc->mediaData().audio_codec;
774
mdat.demuxer = proc->mediaData().demuxer;
778
//if (we_are_restarting) {
779
if ( (just_loaded_external_subs) || (just_unloaded_external_subs) ) {
780
qDebug("Core::finishRestart: processing new subtitles");
782
// Just to simplify things
783
if (mset.current_sub_id == MediaSettings::NoneSelected) {
784
mset.current_sub_id = MediaSettings::SubNone;
791
if ( mset.current_sub_id != MediaSettings::SubNone ) {
792
old_item = mset.current_sub_id;
793
type = mdat.subs.itemAt(old_item).type();
794
ID = mdat.subs.itemAt(old_item).ID();
797
// Use the subtitle info from mplayerprocess
798
qDebug( "Core::finishRestart: copying sub data from proc to mdat");
799
mdat.subs = proc->mediaData().subs;
801
int item = MediaSettings::SubNone;
803
// Try to recover old subtitle
805
int new_item = mdat.subs.find(type, ID);
806
if (new_item > -1) item = new_item;
809
// If we've just loaded a subtitle file
810
// select one if the user wants to autoload
812
if (just_loaded_external_subs) {
813
if ( (pref->autoload_sub) && (item == MediaSettings::SubNone) ) {
814
qDebug("Core::finishRestart: cannot find previous subtitle");
815
qDebug("Core::finishRestart: selecting a new one");
816
item = mdat.subs.selectOne( pref->subtitle_lang );
819
changeSubtitle( item );
820
just_loaded_external_subs = false;
821
just_unloaded_external_subs = false;
823
// Normal restart, subtitles haven't changed
824
// Recover current subtitle
825
changeSubtitle( mset.current_sub_id );
828
we_are_restarting = false;
831
changeAspectRatio(mset.aspect_ratio_id);
833
if (mset.aspect_ratio_id < MediaSettings::Aspect43Letterbox) {
834
changeAspectRatio(mset.aspect_ratio_id);
838
bool isMuted = mset.mute;
839
if (!pref->dont_change_volume) {
840
setVolume( mset.volume, TRUE );
842
if (isMuted) mute(TRUE);
844
setGamma( mset.gamma );
846
changePanscan(mset.panscan_factor);
849
emit mediaInfoChanged();
851
updateWidgets(); // New
857
qDebug("Core::stop");
858
qDebug(" state: %s", stateToString().toUtf8().data());
860
if (state()==Stopped) {
861
// if pressed stop twice, reset video to the beginning
862
qDebug(" mset.current_sec: %f", mset.current_sec);
863
mset.current_sec = 0;
864
emit showTime( mset.current_sec );
865
emit posChanged( 0 );
870
emit mediaStoppedByUser();
876
qDebug("Core::play");
878
if ((proc->isRunning()) && (state()==Paused)) {
879
tellmp("pause"); // Unpauses
882
if ((proc->isRunning()) && (state()==Playing)) {
883
// nothing to do, continue playing
886
// if we're stopped, play it again
887
if ( !mdat.filename.isEmpty() ) {
889
qDebug( "current_sec: %f, duration: %f", mset.current_sec, mdat.duration);
890
if ( (floor(mset.current_sec)) >= (floor(mdat.duration)) ) {
891
mset.current_sec = 0;
899
void Core::pause_and_frame_step() {
900
qDebug("Core::pause_and_frame_step");
902
if (proc->isRunning()) {
903
if (state() == Paused) {
904
tellmp("frame_step");
913
qDebug("Core::pause");
914
qDebug("Current state: %s", stateToString().toUtf8().data());
916
if (proc->isRunning()) {
917
// Pauses and unpauses
922
void Core::play_or_pause() {
923
if (proc->isRunning()) {
930
void Core::frameStep() {
931
qDebug("Core::franeStep");
933
if (proc->isRunning()) {
934
tellmp("frame_step");
938
void Core::screenshot() {
939
qDebug("Core::screenshot");
941
if ( (!pref->screenshot_directory.isEmpty()) &&
942
(QFileInfo(pref->screenshot_directory).isDir()) )
944
tellmp("pausing_keep screenshot 0");
945
qDebug(" taken screenshot");
947
qDebug(" error: directory for screenshots not valid");
948
QString text = "Screenshot NOT taken, folder not configured";
949
tellmp("osd_show_text \"" + text + "\" 3000 1");
950
emit showMessage(text);
954
void Core::processFinished()
956
qDebug("Core::processFinished");
959
// Restores the Windows screensaver
960
if (pref->disable_screensaver) {
961
win_screensaver->restore();
965
qDebug("Core::processFinished: we_are_restarting: %d", we_are_restarting);
967
//mset.current_sec = 0;
969
if (!we_are_restarting) {
970
qDebug("Core::processFinished: play has finished!");
972
//emit stateChanged(state());
975
int exit_code = proc->exitCode();
976
qDebug("Core::processFinished: exit_code: %d", exit_code);
977
if (exit_code != 0) {
978
emit mplayerFinishedWithError(exit_code);
982
void Core::fileReachedEnd() {
984
if (mdat.type == TYPE_VCD) {
985
// If the first vcd title has nothing, it doesn't start to play
986
// and menus are not initialized.
991
// If we're at the end of the movie, reset to 0
992
mset.current_sec = 0;
995
emit mediaFinished();
998
void Core::goToPos(int perc) {
999
qDebug("Core::goToPos: per: %d", perc);
1000
tellmp( "seek " + QString::number(perc) + " 1");
1005
void Core::startMplayer( QString file, double seek ) {
1006
qDebug("Core::startMplayer");
1008
if (file.isEmpty()) {
1009
qWarning("Core:startMplayer: file is empty!");
1013
if (proc->isRunning()) {
1014
qWarning("Core::startMplayer: MPlayer still running!");
1019
// Disable the Windows screensaver
1020
if (pref->disable_screensaver) {
1021
win_screensaver->disable();
1026
bool is_mkv = (QFileInfo(file).suffix().toLower() == "mkv");
1031
if (mdat.type==TYPE_DVD) {
1032
dvd_folder = Helper::dvdSplitFolder(file);
1033
if (dvd_folder.isEmpty()) dvd_folder = pref->dvd_device;
1034
// Remove trailing "/"
1035
if (dvd_folder.endsWith("/")) {
1037
QRegExp r("^[A-Z]:/$");
1038
int pos = r.indexIn(dvd_folder);
1039
qDebug("Core::startMplayer: drive check: '%s': regexp: %d", dvd_folder.toUtf8().data(), pos);
1042
dvd_folder = dvd_folder.remove( dvd_folder.length()-1, 1);
1044
dvd_title = Helper::dvdSplitTitle(file);
1045
file = "dvd://" + QString::number(dvd_title);
1049
bool url_is_playlist = file.endsWith(IS_PLAYLIST_TAG);
1050
if (url_is_playlist) file = file.remove( QRegExp(IS_PLAYLIST_TAG_RX) );
1052
proc->clearArguments();
1054
// Set working directory to screenshot directory
1055
if ( (!pref->screenshot_directory.isEmpty()) &&
1056
(QFileInfo(pref->screenshot_directory).isDir()) )
1058
qDebug("Core::startMplayer: setting working directory to '%s'", pref->screenshot_directory.toUtf8().data());
1059
proc->setWorkingDirectory( pref->screenshot_directory );
1062
// Use absolute path, otherwise after changing to the screenshot directory
1063
// the mplayer path might not be found if it's a relative path
1064
// (seems to be necessary only for linux)
1065
QString mplayer_bin = pref->mplayer_bin;
1066
QFileInfo fi(mplayer_bin);
1067
if (fi.exists() && fi.isExecutable() && !fi.isDir()) {
1068
mplayer_bin = fi.absoluteFilePath();
1071
proc->addArgument( mplayer_bin );
1073
proc->addArgument("-noquiet");
1075
if (pref->fullscreen && pref->use_mplayer_window) {
1076
proc->addArgument("-fs");
1078
// No mplayer fullscreen mode
1079
proc->addArgument("-nofs");
1082
// Demuxer and audio and video codecs:
1083
if (!mset.forced_demuxer.isEmpty()) {
1084
proc->addArgument("-demuxer");
1085
proc->addArgument(mset.forced_demuxer);
1087
if (!mset.forced_audio_codec.isEmpty()) {
1088
proc->addArgument("-ac");
1089
proc->addArgument(mset.forced_audio_codec);
1091
if (!mset.forced_video_codec.isEmpty()) {
1092
proc->addArgument("-vc");
1093
proc->addArgument(mset.forced_video_codec);
1096
if (pref->use_hwac3) {
1097
proc->addArgument("-afm");
1098
proc->addArgument("hwac3");
1104
if ( (pref->h264_skip_loop_filter == Preferences::LoopDisabled) ||
1105
((pref->h264_skip_loop_filter == Preferences::LoopDisabledOnHD) &&
1106
(mset.is264andHD)) )
1108
if (!lavdopts.isEmpty()) lavdopts += ":";
1109
lavdopts += "skiploopfilter=all";
1112
if (pref->show_motion_vectors) {
1113
if (!lavdopts.isEmpty()) lavdopts += ":";
1114
lavdopts += "vismv=7";
1117
if (!lavdopts.isEmpty()) {
1118
proc->addArgument("-lavdopts");
1119
proc->addArgument(lavdopts);
1122
proc->addArgument("-sub-fuzziness");
1123
proc->addArgument( QString::number(pref->subfuzziness) );
1126
if (!pref->mplayer_verbose.isEmpty()) {
1127
proc->addArgument("-msglevel");
1128
proc->addArgument( pref->mplayer_verbose );
1132
proc->addArgument("-identify");
1134
// We need this to get info about mkv chapters
1136
proc->addArgument("-msglevel");
1137
proc->addArgument("demux=6");
1139
// **** Reset chapter ***
1140
// Select first chapter, otherwise we cannot
1141
// resume playback at the same point
1142
// (time would be relative to chapter)
1143
mset.current_chapter_id = 0;
1146
proc->addArgument("-slave");
1148
if (!pref->vo.isEmpty()) {
1149
proc->addArgument( "-vo");
1150
proc->addArgument( pref->vo );
1152
proc->addArgument("-vo");
1154
if (QSysInfo::WindowsVersion == QSysInfo::WV_VISTA) {
1155
proc->addArgument("gl,");
1157
proc->addArgument("directx,");
1160
proc->addArgument("xv,");
1164
if (!pref->ao.isEmpty()) {
1165
proc->addArgument( "-ao");
1166
proc->addArgument( pref->ao );
1169
proc->addArgument( "-zoom");
1170
proc->addArgument("-nokeepaspect");
1172
// Performance options
1175
int app_p = NORMAL_PRIORITY_CLASS;
1176
switch (pref->priority) {
1177
case Preferences::Realtime: p = "realtime";
1178
app_p = REALTIME_PRIORITY_CLASS;
1180
case Preferences::High: p = "high";
1181
app_p = REALTIME_PRIORITY_CLASS;
1183
case Preferences::AboveNormal: p = "abovenormal";
1184
app_p = HIGH_PRIORITY_CLASS;
1186
case Preferences::Normal: p = "normal";
1187
app_p = ABOVE_NORMAL_PRIORITY_CLASS;
1189
case Preferences::BelowNormal: p = "belownormal"; break;
1190
case Preferences::Idle: p = "idle"; break;
1191
default: p = "normal";
1193
proc->addArgument("-priority");
1194
proc->addArgument( p );
1195
SetPriorityClass(GetCurrentProcess(), app_p);
1196
qDebug("Priority of smplayer process set to %d", app_p);
1199
if (pref->frame_drop) {
1200
proc->addArgument("-framedrop");
1203
if (pref->hard_frame_drop) {
1204
proc->addArgument("-hardframedrop");
1207
if (pref->autosync) {
1208
proc->addArgument("-autosync");
1209
proc->addArgument( QString::number( pref->autosync_factor ) );
1212
if (pref->use_direct_rendering) {
1213
proc->addArgument("-dr");
1216
if (!pref->use_double_buffer) {
1217
proc->addArgument("-nodouble");
1221
if (!pref->use_mplayer_window) {
1222
proc->addArgument( "-input" );
1223
proc->addArgument( "conf=" + Helper::dataPath() +"/input.conf" );
1228
if (pref->disable_screensaver) {
1229
proc->addArgument("-stop-xscreensaver");
1231
proc->addArgument("-nostop-xscreensaver");
1235
if (!pref->use_mplayer_window) {
1236
proc->addArgument("-wid");
1237
proc->addArgument( QString::number( (int) mplayerwindow->videoLayer()->winId() ) );
1241
if ((pref->vo == "directx") || (pref->vo.isEmpty())) {
1242
proc->addArgument("-colorkey");
1243
//proc->addArgument( "0x"+QString::number(pref->color_key, 16) );
1244
proc->addArgument( Helper::colorToRGB(pref->color_key) );
1247
qDebug("Core::startMplayer: * not using -colorkey for %s", pref->vo.toUtf8().data());
1248
qDebug("Core::startMplayer: * report if you can't see the video");
1255
proc->addArgument("-monitorpixelaspect");
1256
proc->addArgument("1");
1259
if (!pref->monitor_aspect.isEmpty()) {
1260
proc->addArgument("-monitoraspect");
1261
proc->addArgument( pref->monitor_aspect );
1265
if (pref->use_ass_subtitles) {
1266
proc->addArgument("-ass");
1267
proc->addArgument("-embeddedfonts");
1268
proc->addArgument("-ass-color");
1269
proc->addArgument( Helper::colorToRRGGBBAA( pref->ass_color ) );
1270
proc->addArgument("-ass-border-color");
1271
proc->addArgument( Helper::colorToRRGGBBAA( pref->ass_border_color ) );
1272
if (!pref->ass_styles.isEmpty()) {
1273
proc->addArgument("-ass-force-style");
1274
proc->addArgument( pref->ass_styles );
1279
if ( (pref->use_fontconfig) && (!pref->font_name.isEmpty()) ) {
1280
proc->addArgument("-fontconfig");
1281
proc->addArgument("-font");
1282
proc->addArgument( pref->font_name );
1285
if ( (!pref->use_fontconfig) && (!pref->font_file.isEmpty()) ) {
1286
proc->addArgument("-font");
1287
proc->addArgument( pref->font_file );
1290
proc->addArgument( "-subfont-autoscale");
1291
proc->addArgument( QString::number( pref->font_autoscale ) );
1294
if(pref->use_ass_subtitles) {
1295
proc->addArgument( "-ass-font-scale");
1296
proc->addArgument( QString::number(mset.sub_scale_ass) );
1298
proc->addArgument( "-subfont-text-scale");
1299
proc->addArgument( QString::number(mset.sub_scale) );
1302
proc->addArgument( "-subfont-text-scale");
1303
proc->addArgument( QString::number(mset.sub_scale) );
1306
if (!pref->subcp.isEmpty()) {
1307
proc->addArgument("-subcp");
1308
proc->addArgument( pref->subcp );
1311
if (pref->use_closed_caption_subs) {
1312
proc->addArgument("-subcc");
1315
if (pref->use_forced_subs_only) {
1316
proc->addArgument("-forcedsubsonly");
1319
if (mset.current_audio_id != MediaSettings::NoneSelected) {
1320
proc->addArgument("-aid");
1321
proc->addArgument( QString::number( mset.current_audio_id ) );
1324
if (!mset.external_subtitles.isEmpty()) {
1325
if (QFileInfo(mset.external_subtitles).suffix().toLower()=="idx") {
1326
// sub/idx subtitles
1330
if (pref->use_short_pathnames)
1331
fi.setFile(Helper::shortPathName(mset.external_subtitles));
1334
fi.setFile(mset.external_subtitles);
1336
QString s = fi.path() +"/"+ fi.completeBaseName();
1337
qDebug("Core::startMplayer: subtitle file without extension: '%s'", s.toUtf8().data());
1338
proc->addArgument("-vobsub");
1339
proc->addArgument( s );
1341
proc->addArgument("-sub");
1343
if (pref->use_short_pathnames)
1344
proc->addArgument(Helper::shortPathName(mset.external_subtitles));
1347
proc->addArgument( mset.external_subtitles );
1351
if (!mset.external_audio.isEmpty()) {
1352
proc->addArgument("-audiofile");
1354
if (pref->use_short_pathnames)
1355
proc->addArgument(Helper::shortPathName(mset.external_audio));
1358
proc->addArgument( mset.external_audio );
1361
proc->addArgument("-subpos");
1362
proc->addArgument( QString::number(mset.sub_pos) );
1364
if (mset.audio_delay!=0) {
1365
proc->addArgument("-delay");
1366
proc->addArgument( QString::number( (double) mset.audio_delay/1000 ) );
1369
if (mset.sub_delay!=0) {
1370
proc->addArgument("-subdelay");
1371
proc->addArgument( QString::number( (double) mset.sub_delay/1000 ) );
1374
// Contrast, brightness...
1375
//if (mset.contrast !=0) {
1376
if (!pref->dont_use_eq_options) {
1377
proc->addArgument("-contrast");
1378
proc->addArgument( QString::number( mset.contrast ) );
1382
if (mset.brightness != 0) {
1384
if (!pref->dont_use_eq_options) {
1385
proc->addArgument("-brightness");
1386
proc->addArgument( QString::number( mset.brightness ) );
1392
//if (mset.hue !=0) {
1393
if (!pref->dont_use_eq_options) {
1394
proc->addArgument("-hue");
1395
proc->addArgument( QString::number( mset.hue ) );
1398
//if (mset.saturation !=0) {
1399
if (!pref->dont_use_eq_options) {
1400
proc->addArgument("-saturation");
1401
proc->addArgument( QString::number( mset.saturation ) );
1404
// Set volume, requires a patched mplayer
1405
bool use_volume_option = (pref->use_volume_option2 == Preferences::Enabled);
1406
if (pref->use_volume_option2 == Preferences::Detect) {
1407
use_volume_option = pref->mplayer_has_volume_option;
1409
if ((use_volume_option) && (!pref->dont_change_volume)) {
1410
proc->addArgument("-volume");
1411
// Note: mset.volume may not be right, it can be the volume of the previous video if
1412
// playing a new one, but I think it's better to use anyway the current volume on
1413
// startup than set it to 0 or something.
1414
// The right volume will be set later, when the video starts to play.
1415
proc->addArgument( QString::number( mset.volume ) );
1419
if (mdat.type==TYPE_DVD) {
1420
if (!dvd_folder.isEmpty()) {
1421
proc->addArgument("-dvd-device");
1422
proc->addArgument( dvd_folder );
1424
qWarning("Core::startMplayer: dvd device is empty!");
1428
if ((mdat.type==TYPE_VCD) || (mdat.type==TYPE_AUDIO_CD)) {
1429
if (!pref->cdrom_device.isEmpty()) {
1430
proc->addArgument("-cdrom-device");
1431
proc->addArgument( pref->cdrom_device );
1435
if (mset.current_chapter_id > 0) {
1436
proc->addArgument("-chapter");
1437
int chapter = mset.current_chapter_id;
1438
// Fix for older versions of mplayer:
1439
if ((mdat.type == TYPE_DVD) && (dvd_first_chapter() == 0)) chapter++;
1440
proc->addArgument( QString::number( chapter ) );
1443
if (mset.current_angle_id > 0) {
1444
proc->addArgument("-dvdangle");
1445
proc->addArgument( QString::number( mset.current_angle_id ) );
1450
switch (mdat.type) {
1451
case TYPE_FILE : cache = pref->cache_for_files; break;
1452
case TYPE_DVD : cache = pref->cache_for_dvds; break;
1453
case TYPE_STREAM : cache = pref->cache_for_streams; break;
1454
case TYPE_VCD : cache = pref->cache_for_vcds; break;
1455
case TYPE_AUDIO_CD : cache = pref->cache_for_audiocds; break;
1460
proc->addArgument("-cache");
1461
proc->addArgument( QString::number( cache ) );
1463
proc->addArgument("-nocache");
1466
if (mset.speed != 1.0) {
1467
proc->addArgument("-speed");
1468
proc->addArgument( QString::number( mset.speed ) );
1471
// If seek < 5 it's better to allow the video to start from the beginning
1472
if ((seek >= 5) && (!pref->loop)) {
1473
proc->addArgument("-ss");
1474
proc->addArgument( QString::number( seek ) );
1477
proc->addArgument("-osdlevel");
1478
proc->addArgument( QString::number( pref->osd ) );
1481
proc->addArgument("-flip");
1484
if (pref->use_idx) {
1485
proc->addArgument("-idx");
1490
if (mset.phase_filter) {
1491
proc->addArgument("-vf-add");
1492
proc->addArgument( "phase=A" );
1496
if (mset.current_deinterlacer != MediaSettings::NoDeinterlace) {
1497
proc->addArgument("-vf-add");
1498
switch (mset.current_deinterlacer) {
1499
case MediaSettings::L5: proc->addArgument("pp=l5"); break;
1500
case MediaSettings::Yadif: proc->addArgument("yadif"); break;
1501
case MediaSettings::LB: proc->addArgument("pp=lb"); break;
1502
case MediaSettings::Yadif_1: proc->addArgument("yadif=1"); break;
1503
case MediaSettings::Kerndeint: proc->addArgument("kerndeint=5"); break;
1507
#if !NEW_ASPECT_CODE
1509
if (!mset.panscan_filter.isEmpty()) {
1510
proc->addArgument( "-vf-add" );
1511
proc->addArgument( mset.panscan_filter );
1515
if (!mset.crop_43to169_filter.isEmpty()) {
1516
proc->addArgument( "-vf-add" );
1517
proc->addArgument( mset.crop_43to169_filter );
1522
if (mset.rotate != MediaSettings::NoRotate) {
1523
proc->addArgument( "-vf-add" );
1524
proc->addArgument( QString("rotate=%1").arg(mset.rotate) );
1528
if (mset.current_denoiser != MediaSettings::NoDenoise) {
1529
proc->addArgument("-vf-add");
1530
if (mset.current_denoiser==MediaSettings::DenoiseSoft) {
1531
proc->addArgument( "hqdn3d=2:1:2" );
1533
proc->addArgument( "hqdn3d" );
1538
if (mset.deblock_filter) {
1539
proc->addArgument("-vf-add");
1540
proc->addArgument( "pp=vb/hb" );
1544
if (mset.dering_filter) {
1545
proc->addArgument("-vf-add");
1546
proc->addArgument( "pp=dr" );
1550
if (mset.upscaling_filter) {
1551
int width = DesktopInfo::desktop_size(mplayerwindow).width();
1552
proc->addArgument("-sws");
1553
proc->addArgument("9");
1554
proc->addArgument("-vf-add");
1555
proc->addArgument("scale="+QString::number(width)+":-2");
1559
if (mset.noise_filter) {
1560
proc->addArgument("-vf-add");
1561
proc->addArgument( "noise=9ah:5ah" );
1565
if (mset.postprocessing_filter) {
1566
proc->addArgument("-vf-add");
1567
proc->addArgument("pp");
1568
proc->addArgument("-autoq");
1569
proc->addArgument( QString::number(pref->autoq) );
1573
// Letterbox (expand)
1575
if (mset.add_letterbox) {
1576
proc->addArgument("-vf-add");
1577
proc->addArgument( QString("expand=:::::%1,harddup").arg( DesktopInfo::desktop_aspectRatio(mplayerwindow)) );
1578
// Note: on some videos (h264 for instance) the subtitles doesn't disappear,
1579
// appearing the new ones on top of the old ones. It seems adding another
1580
// filter after expand fixes the problem. I chose harddup 'cos I think
1581
// it will be harmless in mplayer.
1582
// Anyway, if you know a proper way to fix the problem, please tell me.
1585
if (mset.letterbox == MediaSettings::Letterbox_43) {
1586
proc->addArgument("-vf-add");
1587
proc->addArgument("expand=:::::4/3");
1590
if (mset.letterbox == MediaSettings::Letterbox_169) {
1591
proc->addArgument("-vf-add");
1592
proc->addArgument("expand=:::::16/9");
1596
// Additional video filters, supplied by user
1598
if ( !mset.mplayer_additional_video_filters.isEmpty() ) {
1599
proc->addArgument("-vf-add");
1600
proc->addArgument( mset.mplayer_additional_video_filters );
1603
if ( !pref->mplayer_additional_video_filters.isEmpty() ) {
1604
proc->addArgument("-vf-add");
1605
proc->addArgument( pref->mplayer_additional_video_filters );
1609
if ( (!pref->screenshot_directory.isEmpty()) &&
1610
(QFileInfo(pref->screenshot_directory).isDir()) )
1612
// Subtitles on screenshots
1613
if (pref->subtitles_on_screenshots) {
1614
if (pref->use_ass_subtitles) {
1615
proc->addArgument("-vf-add");
1616
proc->addArgument("ass");
1618
proc->addArgument("-vf-add");
1619
proc->addArgument("expand=osd=1");
1620
proc->addArgument("-noslices");
1623
proc->addArgument("-vf-add");
1624
proc->addArgument("screenshot");
1627
if ( (pref->use_soft_video_eq) ) {
1628
proc->addArgument("-vf-add");
1629
QString eq_filter = "eq2,hue";
1630
if ( (pref->vo == "gl") || (pref->vo == "gl2")
1632
|| (pref->vo == "directx:noaccel")
1634
) eq_filter += ",scale";
1635
proc->addArgument(eq_filter);
1639
if (mset.audio_use_channels != 0) {
1640
proc->addArgument("-channels");
1641
proc->addArgument( QString::number( mset.audio_use_channels ) );
1645
if (mset.stereo_mode != 0) {
1646
proc->addArgument("-stereo");
1647
proc->addArgument( QString::number( mset.stereo_mode ) );
1652
if (mset.karaoke_filter) {
1656
if (mset.extrastereo_filter) {
1657
if (!af.isEmpty()) af += ",";
1658
af += "extrastereo";
1661
if (mset.volnorm_filter) {
1662
if (!af.isEmpty()) af += ",";
1666
bool use_scaletempo = (pref->use_scaletempo == Preferences::Enabled);
1667
if (pref->use_scaletempo == Preferences::Detect) {
1668
use_scaletempo = (MplayerVersion::isMplayerAtLeast(24924));
1670
if (use_scaletempo) {
1671
if (!af.isEmpty()) af += ",";
1675
// Additional audio filters, supplied by user
1677
if ( !pref->mplayer_additional_audio_filters.isEmpty() ) {
1678
if (!af.isEmpty()) af += ",";
1679
af += pref->mplayer_additional_audio_filters;
1682
if ( !mset.mplayer_additional_audio_filters.isEmpty() ) {
1683
if (!af.isEmpty()) af += ",";
1684
af += mset.mplayer_additional_audio_filters;
1687
if (!af.isEmpty()) {
1688
proc->addArgument("-af");
1689
proc->addArgument( af );
1692
if (pref->use_soft_vol) {
1693
proc->addArgument("-softvol");
1694
proc->addArgument("-softvol-max");
1695
proc->addArgument( QString::number(pref->softvol_max) );
1699
if (pref->use_edl_files) {
1702
QString basename = f.path() + "/" + f.completeBaseName();
1704
qDebug("Core::startMplayer: file basename: '%s'", basename.toUtf8().data());
1706
if (QFile::exists(basename+".edl"))
1707
edl_f = basename+".edl";
1709
if (QFile::exists(basename+".EDL"))
1710
edl_f = basename+".EDL";
1712
qDebug("Core::startMplayer: edl file: '%s'", edl_f.toUtf8().data());
1713
if (!edl_f.isEmpty()) {
1714
proc->addArgument("-edl");
1715
proc->addArgument(edl_f);
1719
// Additional options supplied by the user
1721
if (!mset.mplayer_additional_options.isEmpty()) {
1722
QStringList args = mset.mplayer_additional_options.split(" ");
1723
QStringList::Iterator it = args.begin();
1724
while( it != args.end() ) {
1725
proc->addArgument( (*it) );
1730
if (!pref->mplayer_additional_options.isEmpty()) {
1731
QStringList args = pref->mplayer_additional_options.split(" ");
1732
QStringList::Iterator it = args.begin();
1733
while( it != args.end() ) {
1734
proc->addArgument( (*it) );
1740
if (url_is_playlist) {
1741
proc->addArgument("-playlist");
1745
if (pref->use_short_pathnames)
1746
proc->addArgument(Helper::shortPathName(file));
1749
proc->addArgument( file );
1751
// It seems the loop option must be after the filename
1753
proc->addArgument("-loop");
1754
proc->addArgument("0");
1758
//mplayer_log = "Command: \n";
1759
QString commandline = proc->arguments().join(" ");
1760
mplayer_log += commandline + "\n\n";
1761
qDebug("Core::startMplayer: command: '%s'", commandline.toUtf8().data());
1763
emit aboutToStartPlaying();
1765
if ( !proc->start() ) {
1767
qWarning("Core::startMplayer: mplayer process didn't start");
1772
void Core::stopMplayer() {
1773
qDebug("Core::stopMplayer");
1775
if (!proc->isRunning()) {
1776
qWarning("Core::stopMplayer: mplayer in not running!");
1782
qDebug("Core::stopMplayer: Waiting mplayer to finish...");
1783
//Helper::finishProcess( proc );
1784
if (!proc->waitForFinished(5000)) {
1788
qDebug("Core::stopMplayer: Finished. (I hope)");
1792
void Core::goToSec( double sec ) {
1793
qDebug("Core::goToSec: %f", sec);
1795
if (sec < 0) sec = 0;
1796
if (sec > mdat.duration ) sec = mdat.duration - 20;
1797
tellmp("seek " + QString::number(sec) + " 2");
1801
void Core::seek(int secs) {
1802
qDebug("seek: %d", secs);
1803
if ( (proc->isRunning()) && (secs!=0) ) {
1804
tellmp("seek " + QString::number(secs) + " 0");
1808
void Core::sforward() {
1809
qDebug("Core::sforward");
1810
seek( pref->seeking1 ); // +10s
1813
void Core::srewind() {
1814
qDebug("Core::srewind");
1815
seek( -pref->seeking1 ); // -10s
1819
void Core::forward() {
1820
qDebug("Core::forward");
1821
seek( pref->seeking2 ); // +1m
1825
void Core::rewind() {
1826
qDebug("Core::rewind");
1827
seek( -pref->seeking2 ); // -1m
1831
void Core::fastforward() {
1832
qDebug("Core::fastforward");
1833
seek( pref->seeking3 ); // +10m
1837
void Core::fastrewind() {
1838
qDebug("Core::fastrewind");
1839
seek( -pref->seeking3 ); // -10m
1842
void Core::forward(int secs) {
1843
qDebug("forward: %d", secs);
1847
void Core::rewind(int secs) {
1848
qDebug("rewind: %d", secs);
1852
void Core::wheelUp() {
1854
switch (pref->wheel_function) {
1855
case Preferences::Volume : incVolume(); break;
1856
case Preferences::Zoom : incPanscan(); break;
1857
case Preferences::Seeking : forward( pref->seeking4 ); break;
1858
case Preferences::ChangeSpeed : incSpeed(); break;
1859
default : {} // do nothing
1863
void Core::wheelDown() {
1864
qDebug("wheelDown");
1865
switch (pref->wheel_function) {
1866
case Preferences::Volume : decVolume(); break;
1867
case Preferences::Zoom : decPanscan(); break;
1868
case Preferences::Seeking : rewind( pref->seeking4 ); break;
1869
case Preferences::ChangeSpeed : decSpeed(); break;
1870
default : {} // do nothing
1875
void Core::toggleRepeat() {
1876
qDebug("Core::toggleRepeat");
1877
toggleRepeat( !pref->loop );
1880
void Core::toggleRepeat(bool b) {
1881
qDebug("Core::toggleRepeat: %d", b);
1882
if ( pref->loop != b ) {
1884
if (MplayerVersion::isMplayerAtLeast(23747)) {
1885
// Use slave command
1886
int v = -1; // no loop
1887
if (pref->loop) v = 0; // infinite loop
1888
tellmp( QString("loop %1 1").arg(v) );
1891
if (proc->isRunning()) restartPlay();
1897
void Core::toggleFlip() {
1898
qDebug("Core::toggleFlip");
1899
toggleFlip( !mset.flip );
1902
void Core::toggleFlip(bool b) {
1903
qDebug("Core::toggleFlip: %d", b);
1905
if (mset.flip != b) {
1907
if (proc->isRunning()) restartPlay();
1913
void Core::toggleKaraoke() {
1914
toggleKaraoke( !mset.karaoke_filter );
1917
void Core::toggleKaraoke(bool b) {
1918
qDebug("Core::toggleKaraoke: %d", b);
1919
if (b != mset.karaoke_filter) {
1920
mset.karaoke_filter = b;
1925
void Core::toggleExtrastereo() {
1926
toggleExtrastereo( !mset.extrastereo_filter );
1929
void Core::toggleExtrastereo(bool b) {
1930
qDebug("Core::toggleExtrastereo: %d", b);
1931
if (b != mset.extrastereo_filter) {
1932
mset.extrastereo_filter = b;
1937
void Core::toggleVolnorm() {
1938
toggleVolnorm( !mset.volnorm_filter );
1941
void Core::toggleVolnorm(bool b) {
1942
qDebug("Core::toggleVolnorm: %d", b);
1943
if (b != mset.volnorm_filter) {
1944
mset.volnorm_filter = b;
1949
void Core::setAudioChannels(int channels) {
1950
qDebug("Core::setAudioChannels:%d", channels);
1951
if (channels != mset.audio_use_channels ) {
1952
mset.audio_use_channels = channels;
1957
void Core::setStereoMode(int mode) {
1958
qDebug("Core::setStereoMode:%d", mode);
1959
if (mode != mset.stereo_mode ) {
1960
mset.stereo_mode = mode;
1967
void Core::toggleAutophase() {
1968
toggleAutophase( !mset.phase_filter );
1971
void Core::toggleAutophase( bool b ) {
1972
qDebug("Core::toggleAutophase: %d", b);
1973
if ( b != mset.phase_filter) {
1974
mset.phase_filter = b;
1979
void Core::toggleDeblock() {
1980
toggleDeblock( !mset.deblock_filter );
1983
void Core::toggleDeblock(bool b) {
1984
qDebug("Core::toggleDeblock: %d", b);
1985
if ( b != mset.deblock_filter ) {
1986
mset.deblock_filter = b;
1991
void Core::toggleDering() {
1992
toggleDering( !mset.dering_filter );
1995
void Core::toggleDering(bool b) {
1996
qDebug("Core::toggleDering: %d", b);
1997
if ( b != mset.dering_filter) {
1998
mset.dering_filter = b;
2003
void Core::toggleNoise() {
2004
toggleNoise( !mset.noise_filter );
2007
void Core::toggleNoise(bool b) {
2008
qDebug("Core::toggleNoise: %d", b);
2009
if ( b!= mset.noise_filter ) {
2010
mset.noise_filter = b;
2015
void Core::togglePostprocessing() {
2016
togglePostprocessing( !mset.postprocessing_filter );
2019
void Core::togglePostprocessing(bool b) {
2020
qDebug("Core::togglePostprocessing: %d", b);
2021
if ( b != mset.postprocessing_filter ) {
2022
mset.postprocessing_filter = b;
2027
void Core::changeDenoise(int id) {
2028
qDebug( "Core::changeDenoise: %d", id );
2029
if (id != mset.current_denoiser) {
2030
mset.current_denoiser = id;
2035
void Core::changeUpscale(bool b) {
2036
qDebug( "Core::changeUpscale: %d", b );
2037
if (mset.upscaling_filter != b) {
2038
mset.upscaling_filter = b;
2043
void Core::setBrightness(int value) {
2044
qDebug("Core::setBrightness: %d", value);
2045
tellmp("brightness " + QString::number(value) + " 1");
2046
mset.brightness = value;
2047
displayMessage( tr("Brightness: %1").arg(value) );
2048
emit equalizerNeedsUpdate();
2052
void Core::setContrast(int value) {
2053
qDebug("Core::setContrast: %d", value);
2054
tellmp("contrast " + QString::number(value) + " 1");
2055
mset.contrast = value;
2056
displayMessage( tr("Contrast: %1").arg(value) );
2057
emit equalizerNeedsUpdate();
2060
void Core::setGamma(int value) {
2061
qDebug("Core::setGamma: %d", value);
2062
tellmp("gamma " + QString::number(value) + " 1");
2064
displayMessage( tr("Gamma: %1").arg(value) );
2065
emit equalizerNeedsUpdate();
2068
void Core::setHue(int value) {
2069
qDebug("Core::setHue: %d", value);
2070
tellmp("hue " + QString::number(value) + " 1");
2072
displayMessage( tr("Hue: %1").arg(value) );
2073
emit equalizerNeedsUpdate();
2076
void Core::setSaturation(int value) {
2077
qDebug("Core::setSaturation: %d", value);
2078
tellmp("saturation " + QString::number(value) + " 1");
2079
mset.saturation = value;
2080
displayMessage( tr("Saturation: %1").arg(value) );
2081
emit equalizerNeedsUpdate();
2084
void Core::incBrightness() {
2085
int v = mset.brightness + 4;
2086
if (v > 100) v = 100;
2090
void Core::decBrightness() {
2091
int v = mset.brightness - 4;
2092
if (v < -100) v = -100;
2096
void Core::incContrast() {
2097
int v = mset.contrast + 4;
2098
if (v > 100) v = 100;
2102
void Core::decContrast() {
2103
int v = mset.contrast - 4;
2104
if (v < -100) v = -100;
2108
void Core::incGamma() {
2109
int v = mset.gamma + 4;
2110
if (v > 100) v = 100;
2114
void Core::decGamma() {
2115
int v = mset.gamma - 4;
2116
if (v < -100) v = -100;
2120
void Core::incHue() {
2121
int v = mset.hue + 4;
2122
if (v > 100) v = 100;
2126
void Core::decHue() {
2127
int v = mset.hue - 4;
2128
if (v < -100) v = -100;
2132
void Core::incSaturation() {
2133
int v = mset.saturation + 4;
2134
if (v > 100) v = 100;
2138
void Core::decSaturation() {
2139
int v = mset.saturation - 4;
2140
if (v < -100) v = -100;
2144
void Core::setSpeed( double value ) {
2145
qDebug("Core::setSpeed: %f", value);
2147
if (value < 0.10) value = 0.10;
2148
if (value > 100) value = 100;
2151
tellmp( "speed_set " + QString::number( value ) );
2154
void Core::incSpeed() {
2155
qDebug("Core::incSpeed");
2156
setSpeed( (double) mset.speed + 0.1 );
2159
void Core::decSpeed() {
2160
qDebug("Core::decSpeed");
2161
setSpeed( (double) mset.speed - 0.1 );
2164
void Core::doubleSpeed() {
2165
qDebug("Core::doubleSpeed");
2166
setSpeed( (double) mset.speed * 2 );
2169
void Core::halveSpeed() {
2170
qDebug("Core::halveSpeed");
2171
setSpeed( (double) mset.speed / 2 );
2174
void Core::normalSpeed() {
2178
void Core::setVolume(int volume, bool force) {
2179
qDebug("Core::setVolume: %d", volume);
2181
if ((volume==mset.volume) && (!force)) return;
2183
mset.volume = volume;
2184
if (mset.volume > 100 ) mset.volume = 100;
2185
if (mset.volume < 0 ) mset.volume = 0;
2187
if (state() == Paused) {
2188
// Change volume later, after quiting pause
2189
change_volume_after_unpause = true;
2191
tellmp("volume " + QString::number(volume) + " 1");
2194
//if (mset.mute) mute(TRUE);
2199
displayMessage( tr("Volume: %1").arg(mset.volume) );
2200
emit volumeChanged( mset.volume );
2203
void Core::switchMute() {
2204
qDebug("Core::switchMute");
2206
mset.mute = !mset.mute;
2210
void Core::mute(bool b) {
2211
qDebug("Core::mute");
2216
if (mset.mute) v = 1;
2217
tellmp("pausing_keep mute " + QString::number(v) );
2222
void Core::incVolume() {
2223
qDebug("Core::incVolume");
2224
setVolume(mset.volume + 4);
2227
void Core::decVolume() {
2228
qDebug("Core::incVolume");
2229
setVolume(mset.volume-4);
2232
void Core::incSubDelay() {
2233
qDebug("Core::incSubDelay");
2235
mset.sub_delay += 100;
2236
tellmp("sub_delay " + QString::number( (double) mset.sub_delay/1000 ) +" 1");
2239
void Core::decSubDelay() {
2240
qDebug("Core::decSubDelay");
2242
mset.sub_delay -= 100;
2243
tellmp("sub_delay " + QString::number( (double) mset.sub_delay/1000 ) +" 1");
2246
void Core::incAudioDelay() {
2247
qDebug("Core::incAudioDelay");
2249
mset.audio_delay += 100;
2250
tellmp("audio_delay " + QString::number( (double) mset.audio_delay/1000 ) +" 1");
2253
void Core::decAudioDelay() {
2254
qDebug("Core::decAudioDelay");
2256
mset.audio_delay -= 100;
2257
tellmp("audio_delay " + QString::number( (double) mset.audio_delay/1000 ) +" 1");
2260
void Core::incSubPos() {
2261
qDebug("Core::incSubPos");
2264
if (mset.sub_pos > 100) mset.sub_pos = 100;
2265
tellmp("sub_pos " + QString::number( mset.sub_pos ) + " 1");
2268
void Core::decSubPos() {
2269
qDebug("Core::decSubPos");
2272
if (mset.sub_pos < 0) mset.sub_pos = 0;
2273
tellmp("sub_pos " + QString::number( mset.sub_pos ) + " 1");
2278
bool Core::subscale_need_restart() {
2279
bool need_restart = false;
2281
need_restart = (pref->change_sub_scale_should_restart == Preferences::Enabled);
2282
if (pref->change_sub_scale_should_restart == Preferences::Detect) {
2283
if (pref->use_ass_subtitles)
2284
need_restart = (!MplayerVersion::isMplayerAtLeast(25843));
2286
need_restart = (!MplayerVersion::isMplayerAtLeast(23745));
2288
return need_restart;
2291
void Core::changeSubScale(double value) {
2292
qDebug("Core::changeSubScale: %f", value);
2294
bool need_restart = subscale_need_restart();
2296
if (value < 0) value = 0;
2298
if (pref->use_ass_subtitles) {
2299
if (value != mset.sub_scale_ass) {
2300
mset.sub_scale_ass = value;
2304
tellmp("sub_scale " + QString::number( mset.sub_scale_ass ) + " 1");
2306
displayMessage( tr("Font scale: %1").arg(mset.sub_scale_ass) );
2310
if (value != mset.sub_scale) {
2311
mset.sub_scale = value;
2315
tellmp("sub_scale " + QString::number( mset.sub_scale ) + " 1");
2318
displayMessage( tr("Font scale: %1").arg(mset.sub_scale) );
2323
void Core::incSubScale() {
2326
if (pref->use_ass_subtitles) {
2327
changeSubScale( mset.sub_scale_ass + step );
2329
if (subscale_need_restart()) step = 1;
2330
changeSubScale( mset.sub_scale + step );
2334
void Core::decSubScale() {
2337
if (pref->use_ass_subtitles) {
2338
changeSubScale( mset.sub_scale_ass - step );
2340
if (subscale_need_restart()) step = 1;
2341
changeSubScale( mset.sub_scale - step );
2345
#else // SCALE_ASS_SUBS
2347
void Core::changeSubScale(double value) {
2348
qDebug("Core::changeSubScale: %f", value);
2350
bool need_restart = false;
2352
if (pref->use_ass_subtitles ||
2353
pref->change_sub_scale_should_restart == Preferences::Enabled)
2355
need_restart = true;
2358
if (pref->change_sub_scale_should_restart == Preferences::Detect) {
2359
need_restart = (!proc->isMplayerAtLeast(23745));
2362
if (value < 0) value = 0;
2363
if (value != mset.sub_scale) {
2364
mset.sub_scale = value;
2368
tellmp("sub_scale " + QString::number( mset.sub_scale ) + " 1");
2373
void Core::incSubScale() {
2375
if (pref->use_ass_subtitles) step = 1.0;
2376
changeSubScale( mset.sub_scale + step );
2379
void Core::decSubScale() {
2381
if (pref->use_ass_subtitles) step = 1.0;
2382
changeSubScale( mset.sub_scale - step );
2385
#endif // SCALE_ASS_SUBS
2387
void Core::incSubStep() {
2388
qDebug("Core::incSubStep");
2389
tellmp("sub_step +1");
2392
void Core::decSubStep() {
2393
qDebug("Core::decSubStep");
2394
tellmp("sub_step -1");
2398
void Core::changeCurrentSec(double sec) {
2399
mset.current_sec = sec;
2401
if (mset.starting_time != -1) {
2402
mset.current_sec -= mset.starting_time;
2405
if (state() != Playing) {
2407
qDebug("mplayer reports that now it's playing");
2408
//emit mediaStartPlay();
2409
//emit stateChanged(state());
2412
emit showTime(mset.current_sec);
2415
static int last_second = 0;
2417
if (floor(sec)==last_second) return; // Update only once per second
2418
last_second = (int) floor(sec);
2421
if ( (mdat.duration > 1) && (mset.current_sec > 1) &&
2422
(mdat.duration > mset.current_sec) )
2424
perc = ( (int) mset.current_sec * 100) / (int) mdat.duration;
2426
emit posChanged( perc );
2429
void Core::gotStartingTime(double time) {
2430
qDebug("Core::gotStartingTime: %f", time);
2431
qDebug("Core::gotStartingTime: current_sec: %f", mset.current_sec);
2432
if ((mset.starting_time == -1.0) && (mset.current_sec == 0)) {
2433
mset.starting_time = time;
2434
qDebug("Core::gotStartingTime: starting time set to %f", time);
2439
void Core::changePause() {
2440
qDebug("Core::changePause");
2441
qDebug("mplayer reports that it's paused");
2443
//emit stateChanged(state());
2446
void Core::changeDeinterlace(int ID) {
2447
qDebug("Core::changeDeinterlace: %d", ID);
2449
if (ID!=mset.current_deinterlacer) {
2450
mset.current_deinterlacer = ID;
2457
void Core::changeSubtitle(int ID) {
2458
qDebug("Core::changeSubtitle: %d", ID);
2460
mset.current_sub_id = ID;
2461
if (ID==MediaSettings::SubNone) {
2465
qDebug("Core::changeSubtitle: ID: %d", ID);
2467
bool use_new_commands = (pref->use_new_sub_commands == Preferences::Enabled);
2468
if (pref->use_new_sub_commands == Preferences::Detect) {
2469
use_new_commands = (MplayerVersion::isMplayerAtLeast(25158));
2472
if (!use_new_commands) {
2473
// Old command sub_select
2474
tellmp( "sub_select " + QString::number(ID) );
2479
tellmp( "sub_source -1" );
2481
if (mdat.subs.numItems() > 0) {
2482
real_id = mdat.subs.itemAt(ID).ID();
2483
switch (mdat.subs.itemAt(ID).type()) {
2485
tellmp( "sub_vob " + QString::number(real_id) );
2488
tellmp( "sub_demux " + QString::number(real_id) );
2491
tellmp( "sub_file " + QString::number(real_id) );
2494
qWarning("Core::changeSubtitle: unknown type!");
2498
qWarning("Core::changeSubtitle: subtitle list is empty!");
2506
void Core::nextSubtitle() {
2507
qDebug("Core::nextSubtitle");
2509
if ( (mset.current_sub_id == MediaSettings::SubNone) &&
2510
(mdat.subs.numItems() > 0) )
2515
int item = mset.current_sub_id + 1;
2516
if (item >= mdat.subs.numItems()) {
2517
item = MediaSettings::SubNone;
2519
changeSubtitle( item );
2523
void Core::changeAudio(int ID) {
2524
qDebug("Core::changeAudio: ID: %d", ID);
2526
if (ID!=mset.current_audio_id) {
2527
mset.current_audio_id = ID;
2528
qDebug("changeAudio: ID: %d", ID);
2530
bool need_restart = (pref->fast_audio_change == Preferences::Disabled);
2531
if (pref->fast_audio_change == Preferences::Detect) {
2532
need_restart = (!MplayerVersion::isMplayerAtLeast(21441));
2538
tellmp("switch_audio " + QString::number(ID) );
2540
// Workaround for a mplayer problem in windows,
2541
// volume is too loud after changing audio.
2543
// Workaround too for a mplayer problem in linux,
2544
// the volume is reduced if using -softvol-max.
2545
setVolume( mset.volume, true );
2547
if (mset.mute) mute(true); // if muted, mute again
2553
void Core::nextAudio() {
2554
qDebug("Core::nextAudio");
2556
int item = mdat.audios.find( mset.current_audio_id );
2558
qWarning(" audio ID %d not found!", mset.current_audio_id);
2560
qDebug( " numItems: %d, item: %d", mdat.audios.numItems(), item);
2562
if (item >= mdat.audios.numItems()) item=0;
2563
int ID = mdat.audios.itemAt(item).ID();
2564
qDebug( " item: %d, ID: %d", item, ID);
2569
void Core::changeTitle(int ID) {
2570
if (mdat.type == TYPE_VCD) {
2575
if (mdat.type == TYPE_AUDIO_CD) {
2580
if (mdat.type == TYPE_DVD) {
2581
QString dvd_url = "dvd://" + QString::number(ID);
2582
QString folder = Helper::dvdSplitFolder(mdat.filename);
2583
if (!folder.isEmpty()) dvd_url += ":" + folder;
2590
void Core::changeChapter(int ID) {
2591
qDebug("Core::changeChapter: ID: %d", ID);
2593
if (ID != mset.current_chapter_id) {
2594
//if (QFileInfo(mdat.filename).extension().lower()=="mkv") {
2595
if (mdat.mkv_chapters > 0) {
2596
// mkv doesn't require to restart
2597
tellmp("seek_chapter " + QString::number(ID) +" 1");
2598
mset.current_chapter_id = ID;
2601
#if SMART_DVD_CHAPTERS
2602
if (pref->cache_for_dvds == 0) {
2604
if (pref->fast_chapter_change) {
2606
tellmp("seek_chapter " + QString::number(ID) +" 1");
2607
mset.current_chapter_id = ID;
2611
mset.current_chapter_id = ID;
2613
mset.current_sec = 0;
2620
int Core::mkv_first_chapter() {
2621
if (MplayerVersion::isMplayerAtLeast(25391))
2627
int Core::dvd_first_chapter() {
2628
// TODO: check if the change really happens in the same version as mkv
2629
return mkv_first_chapter();
2632
void Core::prevChapter() {
2633
qDebug("Core::prevChapter");
2635
int last_chapter = 0;
2636
bool matroshka = (mdat.mkv_chapters > 0);
2638
int first_chapter = dvd_first_chapter();
2639
if (matroshka) first_chapter = mkv_first_chapter();
2641
// Matroshka chapters
2642
if (matroshka) last_chapter = mdat.mkv_chapters + mkv_first_chapter() - 1;
2645
if (mset.current_title_id > 0) {
2646
last_chapter = mdat.titles.item(mset.current_title_id).chapters() + dvd_first_chapter() -1;
2649
int ID = mset.current_chapter_id - 1;
2650
if (ID < first_chapter) {
2656
void Core::nextChapter() {
2657
qDebug("Core::nextChapter");
2659
int last_chapter = 0;
2660
bool matroshka = (mdat.mkv_chapters > 0);
2662
// Matroshka chapters
2663
if (matroshka) last_chapter = mdat.mkv_chapters + mkv_first_chapter() - 1;
2666
if (mset.current_title_id > 0) {
2667
last_chapter = mdat.titles.item(mset.current_title_id).chapters() + dvd_first_chapter() - 1;
2670
int ID = mset.current_chapter_id + 1;
2671
if (ID > last_chapter) {
2672
if (matroshka) ID = mkv_first_chapter(); else ID = dvd_first_chapter();
2677
void Core::changeAngle(int ID) {
2678
qDebug("Core::changeAngle: ID: %d", ID);
2680
if (ID != mset.current_angle_id) {
2681
mset.current_angle_id = ID;
2687
void Core::changeAspectRatio( int ID ) {
2688
qDebug("Core::changeAspectRatio: %d", ID);
2690
mset.aspect_ratio_id = ID;
2691
double asp = mdat.video_aspect; // Set a default
2694
case MediaSettings::Aspect43: asp = (double) 4 / 3; break;
2695
case MediaSettings::Aspect169: asp = (double) 16 / 9; break;
2696
case MediaSettings::Aspect149: asp = (double) 14 / 9; break;
2697
case MediaSettings::Aspect1610: asp = (double) 16 / 10; break;
2698
case MediaSettings::Aspect54: asp = (double) 5 / 4; break;
2699
case MediaSettings::Aspect235: asp = 2.35; break;
2702
//MediaSettings::AspectAuto:
2703
qDebug("Core::changeAspectRatio: mset.win_width %d, mset.win_height: %d", mset.win_width, mset.win_height);
2704
asp = mset.win_aspect(); break;
2708
if (!pref->use_mplayer_window) {
2709
mplayerwindow->setAspect( asp );
2711
// Using mplayer own window
2712
tellmp("switch_ratio " + QString::number(asp));
2716
void Core::changeLetterbox(bool b) {
2717
qDebug("Core::changeLetterbox: %d", b);
2719
if (mset.add_letterbox != b) {
2720
mset.add_letterbox = b;
2726
void Core::changeAspectRatio( int ID ) {
2727
qDebug("Core::changeAspectRatio: %d", ID);
2729
int old_id = mset.aspect_ratio_id;
2730
mset.aspect_ratio_id = ID;
2731
bool need_restart = FALSE;
2733
double asp = mdat.video_aspect; // Set a default
2735
if (ID==MediaSettings::Aspect43Letterbox) {
2736
need_restart = (old_id != MediaSettings::Aspect43Letterbox);
2737
asp = (double) 4 / 3;
2738
mset.letterbox = MediaSettings::Letterbox_43;
2739
mset.panscan_filter = "";
2740
mset.crop_43to169_filter = "";
2743
if (ID==MediaSettings::Aspect169Letterbox) {
2744
need_restart = (old_id != MediaSettings::Aspect169Letterbox);
2745
asp = (double) 16 / 9;
2746
mset.letterbox = MediaSettings::Letterbox_169;
2747
mset.panscan_filter = "";
2748
mset.crop_43to169_filter = "";
2751
if (ID==MediaSettings::Aspect43Panscan) {
2752
need_restart = (old_id != MediaSettings::Aspect43Panscan);
2753
mset.crop_43to169_filter = "";
2754
mset.letterbox = MediaSettings::NoLetterbox;
2756
asp = (double) 4 / 3;
2757
int real_width = (int) round(mdat.video_height * mdat.video_aspect);
2758
mset.panscan_filter = QString("scale=%1:%2,").arg(real_width).arg(mdat.video_height);
2759
mset.panscan_filter += QString("crop=%1:%2").arg(round(mdat.video_height * 4 /3)).arg(mdat.video_height);
2760
//mset.crop = QSize( mdat.video_height * 4 /3, mdat.video_height );
2761
qDebug(" panscan_filter = '%s'", mset.panscan_filter.toUtf8().data() );
2765
if (ID==MediaSettings::Aspect43To169) {
2766
need_restart = (old_id != MediaSettings::Aspect43To169);
2767
mset.panscan_filter = "";
2768
mset.crop_43to169_filter = "";
2769
mset.letterbox = MediaSettings::NoLetterbox;
2771
int real_width = (int) round(mdat.video_height * mdat.video_aspect);
2772
int height = (int) round(real_width * 9 / 16);
2774
qDebug("video_width: %d, video_height: %d", real_width, mdat.video_height);
2775
qDebug("crop: %d, %d", real_width, height );
2777
if (height > mdat.video_height) {
2778
// Invalid size, source video is not 4:3
2779
need_restart = FALSE;
2781
asp = (double) 16 / 9;
2782
mset.crop_43to169_filter = QString("scale=%1:%2,").arg(real_width).arg(mdat.video_height);
2783
mset.crop_43to169_filter += QString("crop=%1:%2").arg(real_width).arg(height);
2784
qDebug(" crop_43to169_filter = '%s'", mset.crop_43to169_filter.toUtf8().data() );
2789
//need_restart = (mset.force_letterbox == TRUE);
2790
need_restart = ( (old_id == MediaSettings::Aspect43Letterbox) ||
2791
(old_id == MediaSettings::Aspect169Letterbox) ||
2792
(old_id == MediaSettings::Aspect43Panscan) ||
2793
(old_id == MediaSettings::Aspect43To169) );
2794
mset.letterbox = MediaSettings::NoLetterbox;
2795
mset.panscan_filter = "";
2796
mset.crop_43to169_filter = "";
2798
//case MediaSettings::AspectAuto: asp = mdat.video_aspect; break;
2799
case MediaSettings::AspectAuto: {
2800
qDebug("Core::changeAspectRatio: mset.win_width %d, mset.win_height: %d", mset.win_width, mset.win_height);
2801
asp = mset.win_aspect(); break;
2803
case MediaSettings::Aspect43: asp = (double) 4 / 3; break;
2804
case MediaSettings::Aspect169: asp = (double) 16 / 9; break;
2805
case MediaSettings::Aspect149: asp = (double) 14 / 9; break;
2806
case MediaSettings::Aspect1610: asp = (double) 16 / 10; break;
2807
case MediaSettings::Aspect54: asp = (double) 5 / 4; break;
2808
case MediaSettings::Aspect235: asp = 2.35; break;
2812
if (!pref->use_mplayer_window) {
2813
mplayerwindow->setAspect( asp );
2815
// Using mplayer own window
2816
tellmp("switch_ratio " + QString::number(asp));
2822
/*mdat.calculateWinResolution(mset.force_letterbox);*/
2828
void Core::changeOSD(int v) {
2829
qDebug("Core::changeOSD: %d", v);
2832
tellmp("osd " + QString::number( pref->osd ) );
2836
void Core::nextOSD() {
2837
int osd = pref->osd + 1;
2838
if (osd > Preferences::SeekTimerTotal) {
2839
osd = Preferences::None;
2844
void Core::changeRotate(int r) {
2845
if (mset.rotate != r) {
2851
void Core::changeSize(int n) {
2852
if ( /*(n != pref->size_factor) &&*/ (!pref->use_mplayer_window) ) {
2853
pref->size_factor = n;
2855
emit needResize(mset.win_width, mset.win_height);
2860
void Core::toggleDoubleSize() {
2861
if (pref->size_factor != 100)
2867
void Core::changePanscan(double p) {
2868
qDebug("Core::changePanscan: %f", p);
2869
if (p < ZOOM_MIN) p = ZOOM_MIN;
2871
mset.panscan_factor = p;
2872
mplayerwindow->setZoom(p);
2873
displayMessage( tr("Zoom: %1").arg(mset.panscan_factor) );
2876
void Core::resetPanscan() {
2880
void Core::incPanscan() {
2881
qDebug("Core::incPanscan");
2882
changePanscan( mset.panscan_factor + ZOOM_STEP );
2885
void Core::decPanscan() {
2886
qDebug("Core::decPanscan");
2887
changePanscan( mset.panscan_factor - ZOOM_STEP );
2890
void Core::changeUseAss(bool b) {
2891
qDebug("Core::changeUseAss: %d", b);
2893
if (pref->use_ass_subtitles != b) {
2894
pref->use_ass_subtitles = b;
2895
if (proc->isRunning()) restartPlay();
2899
void Core::toggleClosedCaption(bool b) {
2900
qDebug("Core::toggleClosedCaption: %d", b);
2902
if (pref->use_closed_caption_subs != b) {
2903
pref->use_closed_caption_subs = b;
2904
if (proc->isRunning()) restartPlay();
2908
void Core::toggleForcedSubsOnly(bool b) {
2909
qDebug("Core::toggleForcedSubsOnly: %d", b);
2911
if (pref->use_forced_subs_only != b) {
2912
pref->use_forced_subs_only = b;
2913
//if (proc->isRunning()) restartPlay();
2916
tellmp( QString("forced_subs_only %1").arg(v) );
2920
void Core::visualizeMotionVectors(bool b) {
2921
qDebug("Core::visualizeMotionVectors: %d", b);
2923
if (pref->show_motion_vectors != b) {
2924
pref->show_motion_vectors = b;
2925
if (proc->isRunning()) restartPlay();
2929
void Core::displayMessage(QString text) {
2930
qDebug("Core::displayMessage");
2931
emit showMessage(text);
2934
void Core::displayScreenshotName(QString filename) {
2935
qDebug("Core::displayScreenshotName");
2936
//QString text = tr("Screenshot saved as %1").arg(filename);
2937
QString text = QString("Screenshot saved as %1").arg(filename);
2939
if (state() != Paused) {
2940
// Dont' show the message on OSD while in pause, otherwise
2941
// the video goes forward a frame.
2942
tellmp("pausing_keep osd_show_text \"" + text + "\" 3000 1");
2945
emit showMessage(text);
2949
void Core::gotWindowResolution(int w, int h) {
2950
qDebug("Core::gotWindowResolution: %d, %d", w, h);
2951
//double aspect = (double) w/h;
2953
if (pref->use_mplayer_window) {
2956
if ((pref->resize_method==Preferences::Afterload) && (we_are_restarting)) {
2959
emit needResize(w,h);
2964
mset.win_height = h;
2966
//Override aspect ratio, is this ok?
2967
//mdat.video_aspect = mset.win_aspect();
2969
mplayerwindow->setResolution( w, h );
2970
mplayerwindow->setAspect( mset.win_aspect() );
2973
void Core::gotNoVideo() {
2974
// File has no video (a sound file)
2976
// Reduce size of window
2978
mset.win_width = mplayerwindow->size().width();
2979
mset.win_height = 0;
2980
mplayerwindow->setResolution( mset.win_width, mset.win_height );
2981
emit needResize( mset.win_width, mset.win_height );
2983
//mplayerwindow->showLogo(TRUE);
2987
void Core::gotVO(QString vo) {
2988
qDebug("Core::gotVO: '%s'", vo.toUtf8().data() );
2990
if ( pref->vo.isEmpty()) {
2991
qDebug("saving vo");
2996
void Core::gotAO(QString ao) {
2997
qDebug("Core::gotAO: '%s'", ao.toUtf8().data() );
2999
if ( pref->ao.isEmpty()) {
3000
qDebug("saving ao");
3005
void Core::streamTitleAndUrlChanged(QString title, QString url) {
3006
mdat.stream_title = title;
3007
mdat.stream_url = url;
3008
emit mediaInfoChanged();
3012
Save the mplayer log to a file, so it can be used by external
3015
void Core::autosaveMplayerLog() {
3016
qDebug("Core::autosaveMplayerLog");
3018
//mplayer log autosaving
3019
if (pref->autosave_mplayer_log) {
3020
if (!pref->mplayer_log_saveto.isEmpty()) {
3021
QFile file( pref->mplayer_log_saveto );
3022
if ( file.open( QIODevice::WriteOnly ) ) {
3023
QTextStream strm( &file );
3024
strm << mplayer_log;
3029
//mplayer log autosaving end
3032
//! Called when the state changes
3033
void Core::watchState(Core::State state) {
3034
if ((state == Playing) && (change_volume_after_unpause))
3036
// Delayed volume change
3037
qDebug("Core::watchState: delayed volume change");
3038
tellmp("volume " + QString::number(mset.volume) + " 1");
3039
change_volume_after_unpause = false;
3043
void Core::checkIfVideoIsHD() {
3044
qDebug("Core::checkIfVideoIsHD");
3046
// Check if the video is in HD and uses ffh264 codec.
3047
if ((mdat.video_codec=="ffh264") && (mset.win_height >= pref->HD_height)) {
3048
qDebug("Core::checkIfVideoIsHD: video == ffh264 and height >= %d", pref->HD_height);
3049
if (!mset.is264andHD) {
3050
mset.is264andHD = true;
3051
if (pref->h264_skip_loop_filter == Preferences::LoopDisabledOnHD) {
3052
qDebug("Core::checkIfVideoIsHD: we're about to restart the video");
3057
mset.is264andHD = false;
3058
// FIXME: if the video was previously marked as HD, and now it's not
3059
// then the video should restart too.
3063
#include "moc_core.cpp"