~ubuntu-branches/ubuntu/wily/smplayer/wily

« back to all changes in this revision

Viewing changes to src/core.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Maia Kozheva
  • Date: 2009-03-31 23:05:43 UTC
  • mfrom: (1.2.2 upstream)
  • mto: This revision was merged to the branch mainline in revision 14.
  • Revision ID: james.westby@ubuntu.com-20090331230543-0h2hfwpwlu9opbv2
* New upstream release. (Closes: #523791)
  - Reworked subtitle font preferences. (Closes: #503295)
  - No longer installs qt_fr.qm. (Closes: #486314)
* debian/control:
  - Bumped Standards-Version to 3.8.1.
  - Changed maintainer name (still the same person and GPG key).
  - Changed section to video.
  - Build-depend on zlib1g-dev for findsubtitles.
  - Require Qt >= 4.3 per readme.
  - Added ${misc:Depends}.
  - Make smplayer-translations depend on smplayer and smplayer recommend
    smplayer-translations, not the other way round. (Closes: #489375)
* debian/copyright:
  - Significantly expanded per-file with new upstream authors.
* debian/rules:
  - Make make use correct uic in install.
  - Clean svn_revision.
  - Removed get-orig-source - not needed with uscan --repack.
* debian/patches/01_gl_translation.patch:
  - Added patch to fix lrelease error on smplayer_gl.ts.
* Added debian/README.source for simple-patchsys.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*  smplayer, GUI front-end for mplayer.
 
2
    Copyright (C) 2006-2009 Ricardo Villalba <rvm@escomposlinux.org>
 
3
 
 
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.
 
8
 
 
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.
 
13
 
 
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
 
17
*/
 
18
 
 
19
#include "core.h"
 
20
#include <QDir>
 
21
#include <QFileInfo>
 
22
#include <QRegExp>
 
23
#include <QTextStream>
 
24
 
 
25
#include <cmath>
 
26
 
 
27
#include "mplayerwindow.h"
 
28
#include "desktopinfo.h"
 
29
#include "helper.h"
 
30
#include "paths.h"
 
31
#include "preferences.h"
 
32
#include "global.h"
 
33
#include "config.h"
 
34
#include "mplayerversion.h"
 
35
#include "constants.h"
 
36
#include "colorutils.h"
 
37
#include "discname.h"
 
38
 
 
39
#ifdef Q_OS_WIN
 
40
#include <windows.h> // To change app priority
 
41
#include <QSysInfo> // To get Windows version
 
42
#ifdef SCREENSAVER_OFF
 
43
#include "screensaver.h"
 
44
#endif
 
45
#endif
 
46
 
 
47
#ifndef NO_USE_INI_FILES
 
48
#include "filesettings.h"
 
49
#include "filesettingshash.h"
 
50
#endif
 
51
 
 
52
using namespace Global;
 
53
 
 
54
Core::Core( MplayerWindow *mpw, QWidget* parent ) 
 
55
        : QObject( parent ) 
 
56
{
 
57
        qRegisterMetaType<Core::State>("Core::State");
 
58
 
 
59
        mplayerwindow = mpw;
 
60
 
 
61
        _state = Stopped;
 
62
 
 
63
        we_are_restarting = false;
 
64
        just_loaded_external_subs = false;
 
65
        just_unloaded_external_subs = false;
 
66
        change_volume_after_unpause = false;
 
67
 
 
68
#ifndef NO_USE_INI_FILES
 
69
        // Create file_settings
 
70
        #if NEW_SETTINGS_MANAGEMENT
 
71
        file_settings = 0;
 
72
        changeFileSettingsMethod(pref->file_settings_method);
 
73
        #else
 
74
        if (Paths::iniPath().isEmpty()) {       
 
75
                file_settings = new QSettings(QSettings::IniFormat, QSettings::UserScope,
 
76
                                      QString(COMPANY), QString("smplayer_files") );
 
77
        } else {
 
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());
 
81
        }
 
82
        #endif
 
83
#endif
 
84
 
 
85
    proc = new MplayerProcess(this);
 
86
 
 
87
        // Do this the first
 
88
        connect( proc, SIGNAL(processExited()),
 
89
             mplayerwindow->videoLayer(), SLOT(playingStopped()) );
 
90
 
 
91
        connect( proc, SIGNAL(error(QProcess::ProcessError)),
 
92
             mplayerwindow->videoLayer(), SLOT(playingStopped()) );
 
93
 
 
94
        connect( proc, SIGNAL(receivedCurrentSec(double)),
 
95
             this, SLOT(changeCurrentSec(double)) );
 
96
 
 
97
        connect( proc, SIGNAL(receivedCurrentFrame(int)),
 
98
             this, SIGNAL(showFrame(int)) );
 
99
 
 
100
        connect( proc, SIGNAL(receivedPause()),
 
101
                         this, SLOT(changePause()) );
 
102
 
 
103
    connect( proc, SIGNAL(processExited()),
 
104
                 this, SLOT(processFinished()), Qt::QueuedConnection );
 
105
 
 
106
        connect( proc, SIGNAL(mplayerFullyLoaded()),
 
107
                         this, SLOT(finishRestart()), Qt::QueuedConnection );
 
108
 
 
109
        connect( proc, SIGNAL(lineAvailable(QString)),
 
110
             this, SIGNAL(logLineAvailable(QString)) );
 
111
 
 
112
        connect( proc, SIGNAL(receivedCacheMessage(QString)),
 
113
                         this, SLOT(displayMessage(QString)) );
 
114
 
 
115
        connect( proc, SIGNAL(receivedCreatingIndex(QString)),
 
116
                         this, SLOT(displayMessage(QString)) );
 
117
 
 
118
        connect( proc, SIGNAL(receivedConnectingToMessage(QString)),
 
119
                         this, SLOT(displayMessage(QString)) );
 
120
 
 
121
        connect( proc, SIGNAL(receivedResolvingMessage(QString)),
 
122
                         this, SLOT(displayMessage(QString)) );
 
123
 
 
124
        connect( proc, SIGNAL(receivedScreenshot(QString)),
 
125
             this, SLOT(displayScreenshotName(QString)) );
 
126
 
 
127
        connect( proc, SIGNAL(receivedUpdatingFontCache()),
 
128
             this, SLOT(displayUpdatingFontCache()) );
 
129
        
 
130
        connect( proc, SIGNAL(receivedWindowResolution(int,int)),
 
131
             this, SLOT(gotWindowResolution(int,int)) );
 
132
 
 
133
        connect( proc, SIGNAL(receivedNoVideo()),
 
134
             this, SLOT(gotNoVideo()) );
 
135
 
 
136
        connect( proc, SIGNAL(receivedVO(QString)),
 
137
             this, SLOT(gotVO(QString)) );
 
138
 
 
139
        connect( proc, SIGNAL(receivedAO(QString)),
 
140
             this, SLOT(gotAO(QString)) );
 
141
 
 
142
        connect( proc, SIGNAL(receivedEndOfFile()),
 
143
             this, SLOT(fileReachedEnd()), Qt::QueuedConnection );
 
144
 
 
145
        connect( proc, SIGNAL(receivedStartingTime(double)),
 
146
             this, SLOT(gotStartingTime(double)) );
 
147
 
 
148
        connect( proc, SIGNAL(receivedStreamTitleAndUrl(QString,QString)),
 
149
             this, SLOT(streamTitleAndUrlChanged(QString,QString)) );
 
150
 
 
151
        connect( proc, SIGNAL(failedToParseMplayerVersion(QString)),
 
152
             this, SIGNAL(failedToParseMplayerVersion(QString)) );
 
153
 
 
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 );
 
157
#endif
 
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 );
 
163
#endif
 
164
#if NOTIFY_AUDIO_CHANGES
 
165
        connect( proc, SIGNAL(audioInfoChanged(const Tracks &)), 
 
166
             this, SLOT(initAudioTrack(const Tracks &)), Qt::QueuedConnection );
 
167
#endif
 
168
#if DVDNAV_SUPPORT
 
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 );
 
173
 
 
174
        QTimer * ask_timer = new QTimer(this);
 
175
        connect( ask_timer, SIGNAL(timeout()), this, SLOT(askForInfo()) );
 
176
        ask_timer->start(5000);
 
177
#endif
 
178
        
 
179
        connect( this, SIGNAL(stateChanged(Core::State)), 
 
180
                 this, SLOT(watchState(Core::State)) );
 
181
 
 
182
        connect( proc, SIGNAL(error(QProcess::ProcessError)), 
 
183
             this, SIGNAL(mplayerFailed(QProcess::ProcessError)) );
 
184
 
 
185
        //pref->load();
 
186
        mset.reset();
 
187
 
 
188
        // Mplayerwindow
 
189
        connect( this, SIGNAL(aboutToStartPlaying()),
 
190
             mplayerwindow->videoLayer(), SLOT(playingStarted()) );
 
191
#if DVDNAV_SUPPORT
 
192
        connect( mplayerwindow, SIGNAL(mouseMoved(QPoint)), 
 
193
             this, SLOT(dvdnavUpdateMousePos(QPoint)) );
 
194
#endif
 
195
 
 
196
#if REPAINT_BACKGROUND_OPTION
 
197
        mplayerwindow->videoLayer()->setRepaintBackground(pref->repaint_video_background);
 
198
#endif
 
199
        mplayerwindow->setMonitorAspect( pref->monitor_aspect_double() );
 
200
 
 
201
#ifdef Q_OS_WIN
 
202
#ifdef SCREENSAVER_OFF
 
203
        // Windows screensaver
 
204
        win_screensaver = new WinScreenSaver();
 
205
#endif
 
206
#endif
 
207
 
 
208
#if DISCNAME_TEST
 
209
        DiscName::test();
 
210
#endif
 
211
}
 
212
 
 
213
 
 
214
Core::~Core() {
 
215
#ifndef NO_USE_INI_FILES
 
216
        saveMediaInfo();
 
217
#endif
 
218
 
 
219
    if (proc->isRunning()) stopMplayer();
 
220
    proc->terminate();
 
221
    delete proc;
 
222
 
 
223
#ifndef NO_USE_INI_FILES
 
224
        delete file_settings;
 
225
#endif
 
226
 
 
227
#ifdef Q_OS_WIN
 
228
#ifdef SCREENSAVER_OFF
 
229
        delete win_screensaver;
 
230
#endif
 
231
#endif
 
232
}
 
233
 
 
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;
 
239
 
 
240
        if (method.toLower() == "hash")
 
241
                file_settings = new FileSettingsHash(Paths::iniPath());
 
242
        else
 
243
                file_settings = new FileSettings(Paths::iniPath());
 
244
#endif
 
245
}
 
246
#endif
 
247
 
 
248
void Core::setState(State s) {
 
249
        if (s != _state) {
 
250
                _state = s;
 
251
                emit stateChanged(_state);
 
252
        }
 
253
}
 
254
 
 
255
QString Core::stateToString() {
 
256
        if (state()==Playing) return "Playing";
 
257
        else
 
258
        if (state()==Stopped) return "Stopped";
 
259
        else
 
260
        if (state()==Paused) return "Paused";
 
261
        else
 
262
        return "Unknown";
 
263
}
 
264
 
 
265
// Public restart
 
266
void Core::restart() {
 
267
        qDebug("Core::restart");
 
268
        if (proc->isRunning()) {
 
269
                restartPlay();
 
270
        } else {
 
271
                qDebug("Core::restart: mplayer is not running");
 
272
        }
 
273
}
 
274
 
 
275
void Core::reload() {
 
276
        qDebug("Core::reload");
 
277
 
 
278
        stopMplayer();
 
279
        we_are_restarting = false;
 
280
 
 
281
        initPlaying();
 
282
}
 
283
 
 
284
#ifndef NO_USE_INI_FILES
 
285
#if !NEW_SETTINGS_MANAGEMENT
 
286
 
 
287
bool Core::checkHaveSettingsSaved(QString group_name) {
 
288
        qDebug("Core::checkHaveSettingsSaved: group_name: '%s'", group_name.toUtf8().data());
 
289
 
 
290
        file_settings->beginGroup( group_name );
 
291
        bool saved = file_settings->value( "saved", false ).toBool();
 
292
        file_settings->endGroup();
 
293
 
 
294
        return saved;
 
295
}
 
296
 
 
297
void Core::loadMediaInfo(QString group_name) {
 
298
        qDebug("Core::loadMediaInfo: '%s'", group_name.toUtf8().data() );
 
299
 
 
300
        file_settings->beginGroup( group_name );
 
301
 
 
302
        /*mdat.load(*settings);*/
 
303
        mset.load(file_settings);
 
304
 
 
305
        file_settings->endGroup();
 
306
}
 
307
 
 
308
#endif // NEW_SETTINGS_MANAGEMENT
 
309
 
 
310
void Core::saveMediaInfo() {
 
311
        qDebug("Core::saveMediaInfo");
 
312
 
 
313
        if (pref->dont_remember_media_settings) {
 
314
                qDebug("Core::saveMediaInfo: not saving settings, disabled by user");
 
315
                return;
 
316
        }
 
317
 
 
318
#if NEW_SETTINGS_MANAGEMENT
 
319
        if ( (mdat.type == TYPE_FILE) && (!mdat.filename.isEmpty()) ) {
 
320
                file_settings->saveSettingsFor(mdat.filename, mset);
 
321
        }
 
322
#else
 
323
        QString group_name;
 
324
 
 
325
        /*
 
326
        if ( (mdat.type == TYPE_DVD) && (!mdat.dvd_id.isEmpty()) ) {
 
327
                group_name = dvdForPref( mdat.dvd_id, mset.current_title_id );
 
328
        }
 
329
        else
 
330
        */
 
331
        if ( (mdat.type == TYPE_FILE) && (!mdat.filename.isEmpty()) ) {
 
332
                group_name = FileSettings::filenameToGroupname( mdat.filename );
 
333
        }
 
334
 
 
335
        if (!group_name.isEmpty()) {
 
336
                file_settings->beginGroup( group_name );
 
337
                file_settings->setValue( "saved", true);
 
338
 
 
339
                /*mdat.save(*settings);*/
 
340
                mset.save(file_settings);
 
341
 
 
342
                file_settings->endGroup();
 
343
        }
 
344
#endif // NEW_SETTINGS_MANAGEMENT
 
345
}
 
346
 
 
347
#endif // NO_USE_INI_FILES
 
348
 
 
349
void Core::initializeMenus() {
 
350
        qDebug("Core::initializeMenus");
 
351
 
 
352
        emit menusNeedInitialize();
 
353
}
 
354
 
 
355
 
 
356
void Core::updateWidgets() {
 
357
        qDebug("Core::updateWidgets");
 
358
 
 
359
        emit widgetsNeedUpdate();
 
360
}
 
361
 
 
362
 
 
363
void Core::tellmp(const QString & command) {
 
364
        qDebug("Core::tellmp: '%s'", command.toUtf8().data());
 
365
 
 
366
    //qDebug("Command: '%s'", command.toUtf8().data());
 
367
    if (proc->isRunning()) {
 
368
                proc->writeToStdin( command );
 
369
    } else {
 
370
                qWarning(" tellmp: no process running: %s", command.toUtf8().data());
 
371
    }
 
372
}
 
373
 
 
374
// Generic open, autodetect type
 
375
void Core::open(QString file, int seek) {
 
376
        qDebug("Core::open: '%s'", file.toUtf8().data());
 
377
 
 
378
        QFileInfo fi(file);
 
379
 
 
380
        if ( (fi.exists()) && (fi.suffix().toLower()=="iso") ) {
 
381
                qDebug("Core::open: * identified as a dvd iso");
 
382
#if DVDNAV_SUPPORT
 
383
                openDVD( DiscName::joinDVD(0, file, pref->use_dvdnav) );
 
384
#else
 
385
                openDVD( DiscName::joinDVD(1, file, false) );
 
386
#endif
 
387
        }
 
388
        else
 
389
        if ( (fi.exists()) && (!fi.isDir()) ) {
 
390
                qDebug("Core::open: * identified as local file");
 
391
                // Local file
 
392
                file = QFileInfo(file).absoluteFilePath();
 
393
                openFile(file, seek);
 
394
        } 
 
395
        else
 
396
        if ( (fi.exists()) && (fi.isDir()) ) {
 
397
                // Directory
 
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");
 
403
#if DVDNAV_SUPPORT
 
404
                        openDVD( DiscName::joinDVD(1, file, pref->use_dvdnav) );
 
405
#else
 
406
                        openDVD( DiscName::joinDVD(1, file, false) );
 
407
#endif
 
408
                } else {
 
409
                        qDebug("Core::open: * directory doesn't contain a dvd");
 
410
                        qDebug("Core::open:   opening nothing");
 
411
                }
 
412
        }
 
413
        else 
 
414
        if ((file.toLower().startsWith("dvd:")) || (file.toLower().startsWith("dvdnav:"))) {
 
415
                qDebug("Core::open: * identified as dvd");
 
416
                openDVD(file);
 
417
                /*
 
418
                QString f = file.lower();
 
419
                QRegExp s("^dvd://(\\d+)");
 
420
                if (s.indexIn(f) != -1) {
 
421
                        int title = s.cap(1).toInt();
 
422
                        openDVD(title);
 
423
                } else {
 
424
                        qWarning("Core::open: couldn't parse dvd title, playing first one");
 
425
                        openDVD();
 
426
                }
 
427
                */
 
428
        }
 
429
        else
 
430
        if (file.toLower().startsWith("vcd:")) {
 
431
                qDebug("Core::open: * identified as vcd");
 
432
 
 
433
                QString f = file.toLower();
 
434
                QRegExp s("^vcd://(\\d+)");
 
435
                if (s.indexIn(f) != -1) {
 
436
                        int title = s.cap(1).toInt();
 
437
                        openVCD(title);
 
438
                } else {
 
439
                        qWarning("Core::open: couldn't parse vcd title, playing first one");
 
440
                        openVCD();
 
441
                }
 
442
        }
 
443
        else
 
444
        if (file.toLower().startsWith("cdda:")) {
 
445
                qDebug("Core::open: * identified as cdda");
 
446
 
 
447
                QString f = file.toLower();
 
448
                QRegExp s("^cdda://(\\d+)");
 
449
                if (s.indexIn(f) != -1) {
 
450
                        int title = s.cap(1).toInt();
 
451
                        openAudioCD(title);
 
452
                } else {
 
453
                        qWarning("Core::open: couldn't parse cdda title, playing first one");
 
454
                        openAudioCD();
 
455
                }
 
456
        }
 
457
        else {
 
458
                qDebug("Core::open: * not identified, playing as stream");
 
459
                openStream(file);
 
460
        }
 
461
}
 
462
 
 
463
void Core::openFile(QString filename, int seek) {
 
464
        qDebug("Core::openFile: '%s'", filename.toUtf8().data());
 
465
 
 
466
        QFileInfo fi(filename);
 
467
        if (fi.exists()) {
 
468
                playNewFile(fi.absoluteFilePath(), seek);
 
469
        } else {
 
470
                //File doesn't exists
 
471
                //TODO: error message
 
472
        }
 
473
}
 
474
 
 
475
 
 
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;
 
481
 
 
482
                QFileInfo fi(sub);
 
483
                if (fi.suffix().toLower() != "idx") {
 
484
                        QString sub_file = sub;
 
485
                        #ifdef Q_OS_WIN
 
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("\\","/");
 
491
                        }
 
492
                        #endif
 
493
                        tellmp( "sub_load \""+ sub_file +"\"" );
 
494
                } else {
 
495
                        restartPlay();
 
496
                }
 
497
#else
 
498
                mset.external_subtitles = sub;
 
499
                just_loaded_external_subs = true;
 
500
                restartPlay();
 
501
#endif
 
502
        } else {
 
503
                qWarning("Core::loadSub: file '%s' is not valid", sub.toUtf8().constData());
 
504
        }
 
505
}
 
506
 
 
507
void Core::unloadSub() {
 
508
        if ( !mset.external_subtitles.isEmpty() ) {
 
509
                mset.external_subtitles = "";
 
510
                just_unloaded_external_subs = true;
 
511
                restartPlay();
 
512
        }
 
513
}
 
514
 
 
515
void Core::loadAudioFile(const QString & audiofile) {
 
516
        if (!audiofile.isEmpty()) {
 
517
                mset.external_audio = audiofile;
 
518
                restartPlay();
 
519
        }
 
520
}
 
521
 
 
522
void Core::unloadAudioFile() {
 
523
        if (!mset.external_audio.isEmpty()) {
 
524
                mset.external_audio = "";
 
525
                restartPlay();
 
526
        }
 
527
}
 
528
 
 
529
/*
 
530
void Core::openDVD( bool from_folder, QString directory) {
 
531
        qDebug("Core::openDVD");
 
532
 
 
533
        if (from_folder) {
 
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;
 
539
                                openDVD();
 
540
                        } else {
 
541
                                qDebug("Core::openDVD: directory '%s' is not valid", directory.toUtf8().data());
 
542
                        }
 
543
                } else {
 
544
                        qDebug("Core::openDVD: directory is empty");
 
545
                }
 
546
        } else {
 
547
                pref->play_dvd_from_hd = FALSE;
 
548
                openDVD();
 
549
        }
 
550
}
 
551
 
 
552
void Core::openDVD() {
 
553
        openDVD(1);
 
554
}
 
555
 
 
556
void Core::openDVD(int title) {
 
557
        qDebug("Core::openDVD: %d", title);
 
558
 
 
559
        if (proc->isRunning()) {
 
560
                stopMplayer();
 
561
        }
 
562
 
 
563
        // Save data of previous file:
 
564
        saveMediaInfo();
 
565
 
 
566
        mdat.reset();
 
567
        mdat.filename = "dvd://" + QString::number(title);
 
568
        mdat.type = TYPE_DVD;
 
569
 
 
570
        mset.reset();
 
571
 
 
572
        mset.current_title_id = title;
 
573
        mset.current_chapter_id = 1;
 
574
        mset.current_angle_id = 1;
 
575
 
 
576
        initializeMenus();
 
577
 
 
578
        initPlaying();
 
579
}
 
580
*/
 
581
 
 
582
void Core::openVCD(int title) {
 
583
        qDebug("Core::openVCD: %d", title);
 
584
 
 
585
        if (title == -1) title = pref->vcd_initial_title;
 
586
 
 
587
        if (proc->isRunning()) {
 
588
                stopMplayer();
 
589
        }
 
590
 
 
591
        // Save data of previous file:
 
592
#ifndef NO_USE_INI_FILES
 
593
        saveMediaInfo();
 
594
#endif
 
595
 
 
596
        mdat.reset();
 
597
        mdat.filename = "vcd://" + QString::number(title);
 
598
        mdat.type = TYPE_VCD;
 
599
 
 
600
        mset.reset();
 
601
 
 
602
        mset.current_title_id = title;
 
603
        mset.current_chapter_id = -1;
 
604
        mset.current_angle_id = -1;
 
605
 
 
606
        /* initializeMenus(); */
 
607
 
 
608
        initPlaying();
 
609
}
 
610
 
 
611
void Core::openAudioCD(int title) {
 
612
        qDebug("Core::openAudioCD: %d", title);
 
613
 
 
614
        if (title == -1) title = 1;
 
615
 
 
616
        if (proc->isRunning()) {
 
617
                stopMplayer();
 
618
        }
 
619
 
 
620
        // Save data of previous file:
 
621
#ifndef NO_USE_INI_FILES
 
622
        saveMediaInfo();
 
623
#endif
 
624
 
 
625
        mdat.reset();
 
626
        mdat.filename = "cdda://" + QString::number(title);
 
627
        mdat.type = TYPE_AUDIO_CD;
 
628
 
 
629
        mset.reset();
 
630
 
 
631
        mset.current_title_id = title;
 
632
        mset.current_chapter_id = -1;
 
633
        mset.current_angle_id = -1;
 
634
 
 
635
        /* initializeMenus(); */
 
636
 
 
637
        initPlaying();
 
638
}
 
639
 
 
640
void Core::openDVD(QString dvd_url) {
 
641
        qDebug("Core::openDVD: '%s'", dvd_url.toUtf8().data());
 
642
 
 
643
        //Checks
 
644
        DiscData disc_data = DiscName::split(dvd_url);
 
645
        QString folder = disc_data.device;
 
646
        int title = disc_data.title;
 
647
 
 
648
        if (title == -1) {
 
649
                qWarning("Core::openDVD: title invalid, not playing dvd");
 
650
                return;
 
651
        }
 
652
 
 
653
        if (folder.isEmpty()) {
 
654
                qDebug("Core::openDVD: not folder");
 
655
        } else {
 
656
                QFileInfo fi(folder);
 
657
                if ( (!fi.exists()) /*|| (!fi.isDir())*/ ) {
 
658
                        qWarning("Core::openDVD: folder invalid, not playing dvd");
 
659
                        return;
 
660
                }
 
661
        }
 
662
 
 
663
        if (proc->isRunning()) {
 
664
                stopMplayer();
 
665
                we_are_restarting = false;
 
666
        }
 
667
 
 
668
        // Save data of previous file:
 
669
#ifndef NO_USE_INI_FILES
 
670
        saveMediaInfo();
 
671
#endif
 
672
 
 
673
        mdat.reset();
 
674
        mdat.filename = dvd_url;
 
675
        mdat.type = TYPE_DVD;
 
676
 
 
677
        mset.reset();
 
678
 
 
679
        mset.current_title_id = title;
 
680
#if GENERIC_CHAPTER_SUPPORT
 
681
        mset.current_chapter_id = firstChapter();
 
682
#else
 
683
        mset.current_chapter_id = dvdFirstChapter();
 
684
#endif
 
685
        mset.current_angle_id = 1;
 
686
 
 
687
        /* initializeMenus(); */
 
688
 
 
689
        initPlaying();
 
690
}
 
691
 
 
692
void Core::openStream(QString name) {
 
693
        qDebug("Core::openStream: '%s'", name.toUtf8().data());
 
694
 
 
695
        if (proc->isRunning()) {
 
696
                stopMplayer();
 
697
                we_are_restarting = false;
 
698
        }
 
699
 
 
700
        // Save data of previous file:
 
701
#ifndef NO_USE_INI_FILES
 
702
        saveMediaInfo();
 
703
#endif
 
704
 
 
705
        mdat.reset();
 
706
        mdat.filename = name;
 
707
        mdat.type = TYPE_STREAM;
 
708
 
 
709
        mset.reset();
 
710
 
 
711
        /* initializeMenus(); */
 
712
 
 
713
        initPlaying();
 
714
}
 
715
 
 
716
 
 
717
void Core::playNewFile(QString file, int seek) {
 
718
        qDebug("Core::playNewFile: '%s'", file.toUtf8().data());
 
719
 
 
720
        if (proc->isRunning()) {
 
721
                stopMplayer();
 
722
                we_are_restarting = false;
 
723
        }
 
724
 
 
725
        // Save data of previous file:
 
726
#ifndef NO_USE_INI_FILES
 
727
        saveMediaInfo();
 
728
#endif
 
729
 
 
730
        mdat.reset();
 
731
        mdat.filename = file;
 
732
        mdat.type = TYPE_FILE;
 
733
 
 
734
        int old_volume = mset.volume;
 
735
        mset.reset();
 
736
 
 
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)) {
 
741
        #else
 
742
        if (checkHaveSettingsSaved( FileSettings::filenameToGroupname(file) )) {
 
743
        #endif
 
744
                qDebug("Core::playNewFile: We have settings for this file!!!");
 
745
 
 
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);
 
750
                        #else
 
751
                        loadMediaInfo( FileSettings::filenameToGroupname(file) );
 
752
                        #endif
 
753
                        qDebug("Core::playNewFile: Media settings read");
 
754
 
 
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
 
760
                        // audio files
 
761
                        if ((saved_width == 400) && (saved_height == 300)) {
 
762
                                saved_width = 0;
 
763
                                saved_height = 0;
 
764
                        }
 
765
                        if ((saved_width > 0) && (saved_height > 0)) {
 
766
                                emit needResize(mset.win_width, mset.win_height);
 
767
                                changeAspectRatio(mset.aspect_ratio_id);
 
768
                        }
 
769
 
 
770
                        if (pref->dont_remember_time_pos) {
 
771
                                mset.current_sec = 0;
 
772
                                qDebug("Core::playNewFile: Time pos reset to 0");
 
773
                        }
 
774
                } else {
 
775
                        qDebug("Core::playNewFile: Media settings have not read because of preferences setting");
 
776
                }
 
777
        } else {
 
778
                // Recover volume
 
779
                mset.volume = old_volume;
 
780
        }
 
781
#else
 
782
        // Recover volume
 
783
        mset.volume = old_volume;
 
784
#endif // NO_USE_INI_FILES
 
785
 
 
786
        /* initializeMenus(); */
 
787
 
 
788
        qDebug("Core::playNewFile: volume: %d, old_volume: %d", mset.volume, old_volume);
 
789
        initPlaying(seek);
 
790
}
 
791
 
 
792
 
 
793
void Core::restartPlay() {
 
794
        we_are_restarting = true;
 
795
        initPlaying();
 
796
}
 
797
 
 
798
void Core::initPlaying(int seek) {
 
799
        qDebug("Core::initPlaying");
 
800
 
 
801
        /*
 
802
        mdat.list();
 
803
        mset.list();
 
804
        */
 
805
 
 
806
        /* updateWidgets(); */
 
807
 
 
808
        mplayerwindow->showLogo(FALSE);
 
809
 
 
810
        if (proc->isRunning()) {
 
811
                stopMplayer();
 
812
        }
 
813
 
 
814
        int start_sec = (int) mset.current_sec;
 
815
        if (seek > -1) start_sec = seek;
 
816
 
 
817
        startMplayer( mdat.filename, start_sec );
 
818
}
 
819
 
 
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 ---");
 
824
 
 
825
        QString file = mdat.filename;
 
826
        int type = mdat.type;
 
827
        mdat = proc->mediaData();
 
828
        mdat.filename = file;
 
829
        mdat.type = type;
 
830
 
 
831
        initializeMenus(); // Old
 
832
 
 
833
        // Video
 
834
        if ( (mset.current_video_id == MediaSettings::NoneSelected) && 
 
835
         (mdat.videos.numItems() > 0) ) 
 
836
        {
 
837
                changeVideo( mdat.videos.itemAt(0).ID(), false ); // Don't allow to restart
 
838
        }
 
839
 
 
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) ) 
 
844
        {
 
845
                // Don't set mset.current_audio_id here! changeAudio will do. 
 
846
                // Otherwise changeAudio will do nothing.
 
847
 
 
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();
 
851
                }
 
852
 
 
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;
 
857
                }
 
858
 
 
859
                // Change the audio without restarting mplayer, it's not
 
860
                // safe to do it here.
 
861
                changeAudio( audio, false );
 
862
 
 
863
        }
 
864
#endif
 
865
 
 
866
#if !NOTIFY_SUB_CHANGES
 
867
        // Subtitles
 
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 );
 
874
                        }
 
875
                } else {
 
876
                        changeSubtitle( MediaSettings::SubNone );
 
877
                }
 
878
        }
 
879
#endif
 
880
 
 
881
#if GENERIC_CHAPTER_SUPPORT
 
882
        if (mdat.chapters > 0) {
 
883
#else
 
884
        // mkv chapters
 
885
        if (mdat.mkv_chapters > 0) {
 
886
#endif
 
887
                // Just to show the first chapter checked in the menu
 
888
                mset.current_chapter_id = firstChapter();
 
889
        }
 
890
 
 
891
        mdat.initialized = TRUE;
 
892
 
 
893
        // MPlayer doesn't display the length in ID_LENGTH for audio CDs...
 
894
        if ((mdat.duration == 0) && (mdat.type == TYPE_AUDIO_CD)) {
 
895
                /*
 
896
                qDebug(" *** get duration here from title info *** ");
 
897
                qDebug(" *** current title: %d", mset.current_title_id );
 
898
                */
 
899
                if (mset.current_title_id > 0) {
 
900
                        mdat.duration = mdat.titles.item(mset.current_title_id).duration();
 
901
                }
 
902
        }
 
903
 
 
904
        /* updateWidgets(); */
 
905
 
 
906
        mdat.list();
 
907
        mset.list();
 
908
 
 
909
        qDebug("Core::newMediaPlaying: --- end ---");
 
910
}
 
911
 
 
912
void Core::finishRestart() {
 
913
        qDebug("Core::finishRestart: --- start ---");
 
914
 
 
915
        if (!we_are_restarting) {
 
916
                newMediaPlaying();
 
917
                //QTimer::singleShot(1000, this, SIGNAL(mediaStartPlay())); 
 
918
                emit mediaStartPlay();
 
919
        } 
 
920
 
 
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;
 
926
        }
 
927
 
 
928
#if !NOTIFY_SUB_CHANGES
 
929
        // Subtitles
 
930
        //if (we_are_restarting) {
 
931
        if ( (just_loaded_external_subs) || (just_unloaded_external_subs) ) {
 
932
                qDebug("Core::finishRestart: processing new subtitles");
 
933
 
 
934
                // Just to simplify things
 
935
                if (mset.current_sub_id == MediaSettings::NoneSelected) {
 
936
                        mset.current_sub_id = MediaSettings::SubNone;
 
937
                }
 
938
 
 
939
                // Save current sub
 
940
                SubData::Type type;
 
941
                int ID;
 
942
                int old_item = -1;
 
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();
 
947
                }
 
948
 
 
949
                // Use the subtitle info from mplayerprocess
 
950
                qDebug( "Core::finishRestart: copying sub data from proc to mdat");
 
951
            mdat.subs = proc->mediaData().subs;
 
952
                initializeMenus();
 
953
                int item = MediaSettings::SubNone;
 
954
 
 
955
                // Try to recover old subtitle
 
956
                if (just_unloaded_external_subs) {
 
957
                        if (old_item > -1) {
 
958
                                int new_item = mdat.subs.find(type, ID);
 
959
                                if (new_item > -1) item = new_item;
 
960
                        }
 
961
                }
 
962
 
 
963
                // If we've just loaded a subtitle file
 
964
                // select one if the user wants to autoload
 
965
                // one subtitle
 
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 );
 
971
                        }
 
972
                }
 
973
                changeSubtitle( item );
 
974
                just_loaded_external_subs = false;
 
975
                just_unloaded_external_subs = false;
 
976
        } else {
 
977
                // Normal restart, subtitles haven't changed
 
978
                // Recover current subtitle
 
979
                changeSubtitle( mset.current_sub_id );
 
980
        }
 
981
#endif
 
982
 
 
983
        we_are_restarting = false;
 
984
 
 
985
#if NEW_ASPECT_CODE
 
986
        changeAspectRatio(mset.aspect_ratio_id);
 
987
#else
 
988
        if (mset.aspect_ratio_id < MediaSettings::Aspect43Letterbox) {
 
989
                changeAspectRatio(mset.aspect_ratio_id);
 
990
        }
 
991
#endif
 
992
 
 
993
        bool isMuted = mset.mute;
 
994
        if (!pref->dont_change_volume) {
 
995
                 setVolume( mset.volume, TRUE );
 
996
        }
 
997
        if (isMuted) mute(TRUE);
 
998
 
 
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!
 
1002
                setGamma( gamma );
 
1003
        }
 
1004
        // Hack to be sure that the equalizers are up to date
 
1005
        emit videoEqualizerNeedsUpdate();
 
1006
        emit audioEqualizerNeedsUpdate();
 
1007
 
 
1008
        changePanscan(mset.panscan_factor);
 
1009
 
 
1010
        emit mediaLoaded();
 
1011
        emit mediaInfoChanged();
 
1012
 
 
1013
        updateWidgets(); // New
 
1014
 
 
1015
        qDebug("Core::finishRestart: --- end ---");
 
1016
}
 
1017
 
 
1018
 
 
1019
void Core::stop()
 
1020
{
 
1021
        qDebug("Core::stop");
 
1022
        qDebug("Core::stop: state: %s", stateToString().toUtf8().data());
 
1023
        
 
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 );
 
1031
#else
 
1032
                emit posChanged( 0 );
 
1033
#endif
 
1034
                //updateWidgets();
 
1035
        }
 
1036
 
 
1037
        stopMplayer();
 
1038
        emit mediaStoppedByUser();
 
1039
}
 
1040
 
 
1041
 
 
1042
void Core::play()
 
1043
{
 
1044
        qDebug("Core::play");
 
1045
    
 
1046
        if ((proc->isRunning()) && (state()==Paused)) {
 
1047
                tellmp("pause"); // Unpauses
 
1048
    } 
 
1049
        else
 
1050
        if ((proc->isRunning()) && (state()==Playing)) {
 
1051
                // nothing to do, continue playing
 
1052
        }
 
1053
        else {
 
1054
                // if we're stopped, play it again
 
1055
                if ( !mdat.filename.isEmpty() ) {
 
1056
                        /*
 
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;
 
1060
                        }
 
1061
                        */
 
1062
                        restartPlay();
 
1063
                }
 
1064
    }
 
1065
}
 
1066
 
 
1067
void Core::pause_and_frame_step() {
 
1068
        qDebug("Core::pause_and_frame_step");
 
1069
        
 
1070
        if (proc->isRunning()) {
 
1071
                if (state() == Paused) {
 
1072
                        tellmp("frame_step");
 
1073
                }
 
1074
                else {
 
1075
                        tellmp("pause");
 
1076
                }
 
1077
        }
 
1078
}
 
1079
 
 
1080
void Core::pause() {
 
1081
        qDebug("Core::pause");
 
1082
        qDebug("Core::pause: current state: %s", stateToString().toUtf8().data());
 
1083
 
 
1084
        if (proc->isRunning()) {
 
1085
                // Pauses and unpauses
 
1086
                tellmp("pause");
 
1087
        }
 
1088
}
 
1089
 
 
1090
void Core::play_or_pause() {
 
1091
        if (proc->isRunning()) {
 
1092
                pause();
 
1093
        } else {
 
1094
                play();
 
1095
        }
 
1096
}
 
1097
 
 
1098
void Core::frameStep() {
 
1099
        qDebug("Core::frameStep");
 
1100
 
 
1101
        if (proc->isRunning()) {
 
1102
                tellmp("frame_step");
 
1103
        }
 
1104
}
 
1105
 
 
1106
void Core::screenshot() {
 
1107
        qDebug("Core::screenshot");
 
1108
 
 
1109
        if ( (!pref->screenshot_directory.isEmpty()) && 
 
1110
         (QFileInfo(pref->screenshot_directory).isDir()) ) 
 
1111
        {
 
1112
                tellmp( pausing_prefix() + " screenshot 0");
 
1113
                qDebug("Core::screenshot: taken screenshot");
 
1114
        } else {
 
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);
 
1119
        }
 
1120
}
 
1121
 
 
1122
void Core::processFinished()
 
1123
{
 
1124
    qDebug("Core::processFinished");
 
1125
 
 
1126
#ifdef Q_OS_WIN
 
1127
#ifdef SCREENSAVER_OFF
 
1128
        // Restores the Windows screensaver
 
1129
        if (pref->disable_screensaver) {
 
1130
                win_screensaver->restore();
 
1131
        }
 
1132
#endif
 
1133
#endif
 
1134
 
 
1135
        qDebug("Core::processFinished: we_are_restarting: %d", we_are_restarting);
 
1136
 
 
1137
        //mset.current_sec = 0;
 
1138
 
 
1139
        if (!we_are_restarting) {
 
1140
                qDebug("Core::processFinished: play has finished!");
 
1141
                setState(Stopped);
 
1142
                //emit stateChanged(state());
 
1143
        }
 
1144
 
 
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);
 
1149
        }
 
1150
}
 
1151
 
 
1152
void Core::fileReachedEnd() {
 
1153
        /*
 
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.
 
1157
                initializeMenus();
 
1158
        }
 
1159
        */
 
1160
 
 
1161
        // If we're at the end of the movie, reset to 0
 
1162
        mset.current_sec = 0;
 
1163
        updateWidgets();
 
1164
 
 
1165
        emit mediaFinished();
 
1166
}
 
1167
 
 
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;
 
1173
                goToSec(jump_time);
 
1174
        }
 
1175
}
 
1176
#else
 
1177
void Core::goToPos(int perc) {
 
1178
        qDebug("Core::goToPos: per: %d", perc);
 
1179
        tellmp( "seek " + QString::number(perc) + " 1");
 
1180
}
 
1181
#endif
 
1182
 
 
1183
 
 
1184
void Core::startMplayer( QString file, double seek ) {
 
1185
        qDebug("Core::startMplayer");
 
1186
 
 
1187
        if (file.isEmpty()) {
 
1188
                qWarning("Core:startMplayer: file is empty!");
 
1189
                return;
 
1190
        }
 
1191
 
 
1192
        if (proc->isRunning()) {
 
1193
                qWarning("Core::startMplayer: MPlayer still running!");
 
1194
                return;
 
1195
    } 
 
1196
 
 
1197
#ifdef Q_OS_WIN
 
1198
#ifdef SCREENSAVER_OFF
 
1199
        // Disable the Windows screensaver
 
1200
        if (pref->disable_screensaver) {
 
1201
                win_screensaver->disable();
 
1202
        }
 
1203
#endif
 
1204
#endif
 
1205
 
 
1206
        bool is_mkv = (QFileInfo(file).suffix().toLower() == "mkv");
 
1207
 
 
1208
        // DVD
 
1209
        QString dvd_folder;
 
1210
        int dvd_title = -1;
 
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);
 
1218
        }
 
1219
 
 
1220
        // URL
 
1221
        bool url_is_playlist = file.endsWith(IS_PLAYLIST_TAG);
 
1222
        if (url_is_playlist) file = file.remove( QRegExp(IS_PLAYLIST_TAG_RX) );
 
1223
 
 
1224
        bool screenshot_enabled = ( (!pref->screenshot_directory.isEmpty()) && 
 
1225
                                 (QFileInfo(pref->screenshot_directory).isDir()) );
 
1226
 
 
1227
        proc->clearArguments();
 
1228
 
 
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 );
 
1233
        }
 
1234
 
 
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();
 
1242
        }
 
1243
 
 
1244
        proc->addArgument( mplayer_bin );
 
1245
 
 
1246
        proc->addArgument("-noquiet");
 
1247
 
 
1248
        if (pref->fullscreen && pref->use_mplayer_window) {
 
1249
                proc->addArgument("-fs");
 
1250
        } else {
 
1251
                // No mplayer fullscreen mode
 
1252
                proc->addArgument("-nofs");
 
1253
        }
 
1254
 
 
1255
        proc->addArgument("-nomouseinput");
 
1256
 
 
1257
        // Demuxer and audio and video codecs:
 
1258
        if (!mset.forced_demuxer.isEmpty()) {
 
1259
                proc->addArgument("-demuxer");
 
1260
                proc->addArgument(mset.forced_demuxer);
 
1261
        }
 
1262
        if (!mset.forced_audio_codec.isEmpty()) {
 
1263
                proc->addArgument("-ac");
 
1264
                proc->addArgument(mset.forced_audio_codec);
 
1265
        }
 
1266
        if (!mset.forced_video_codec.isEmpty()) {
 
1267
                proc->addArgument("-vc");
 
1268
                proc->addArgument(mset.forced_video_codec);
 
1269
        }
 
1270
 
 
1271
        if (pref->use_hwac3) {
 
1272
                proc->addArgument("-afm");
 
1273
                proc->addArgument("hwac3");
 
1274
        }
 
1275
 
 
1276
 
 
1277
        QString lavdopts;
 
1278
 
 
1279
        if ( (pref->h264_skip_loop_filter == Preferences::LoopDisabled) || 
 
1280
         ((pref->h264_skip_loop_filter == Preferences::LoopDisabledOnHD) && 
 
1281
          (mset.is264andHD)) )
 
1282
        {
 
1283
                if (!lavdopts.isEmpty()) lavdopts += ":";
 
1284
                lavdopts += "skiploopfilter=all";
 
1285
        }
 
1286
 
 
1287
        if (pref->show_motion_vectors) {
 
1288
                if (!lavdopts.isEmpty()) lavdopts += ":";
 
1289
                lavdopts += "vismv=7";
 
1290
        }
 
1291
 
 
1292
        if (pref->threads > 1) {
 
1293
                if (!lavdopts.isEmpty()) lavdopts += ":";
 
1294
                lavdopts += "threads=" + QString::number(pref->threads);
 
1295
        }
 
1296
 
 
1297
        if (!lavdopts.isEmpty()) {
 
1298
                proc->addArgument("-lavdopts");
 
1299
                proc->addArgument(lavdopts);
 
1300
        }
 
1301
 
 
1302
        proc->addArgument("-sub-fuzziness");
 
1303
        proc->addArgument( QString::number(pref->subfuzziness) );
 
1304
 
 
1305
        proc->addArgument("-identify");
 
1306
 
 
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
 
1311
        } else {
 
1312
#endif
 
1313
                // We need this to get info about mkv chapters
 
1314
                if (is_mkv) {
 
1315
                        proc->addArgument("-msglevel");
 
1316
                        proc->addArgument("demux=6");
 
1317
 
 
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;
 
1323
                }
 
1324
#if GENERIC_CHAPTER_SUPPORT
 
1325
        }
 
1326
#endif
 
1327
        
 
1328
        proc->addArgument("-slave");
 
1329
 
 
1330
        if (!pref->vo.isEmpty()) {
 
1331
                proc->addArgument( "-vo");
 
1332
                proc->addArgument( pref->vo );
 
1333
        } else {
 
1334
                proc->addArgument("-vo");
 
1335
#ifdef Q_OS_WIN
 
1336
                if (QSysInfo::WindowsVersion == QSysInfo::WV_VISTA) {
 
1337
                        proc->addArgument("direct3d,");
 
1338
                } else {
 
1339
                        proc->addArgument("directx,");
 
1340
                }
 
1341
#else
 
1342
                proc->addArgument("xv,");
 
1343
#endif
 
1344
        }
 
1345
 
 
1346
#if USE_ADAPTER
 
1347
        if (pref->adapter > -1) {
 
1348
                proc->addArgument("-adapter");
 
1349
                proc->addArgument(QString::number(pref->adapter));
 
1350
        }
 
1351
#endif
 
1352
 
 
1353
        if (!pref->ao.isEmpty()) {
 
1354
                proc->addArgument( "-ao");
 
1355
                proc->addArgument( pref->ao );
 
1356
        }
 
1357
#ifndef Q_OS_WIN
 
1358
        else {
 
1359
                proc->addArgument( "-ao");
 
1360
                proc->addArgument( "alsa," );
 
1361
        }
 
1362
#endif
 
1363
 
 
1364
#ifndef Q_OS_WIN
 
1365
        if (pref->vo.startsWith("x11")) {
 
1366
                proc->addArgument( "-zoom");
 
1367
        }
 
1368
#endif
 
1369
        proc->addArgument("-nokeepaspect");
 
1370
 
 
1371
        // Performance options
 
1372
        #ifdef Q_OS_WIN
 
1373
        QString p;
 
1374
        int app_p = NORMAL_PRIORITY_CLASS;
 
1375
        switch (pref->priority) {
 
1376
                case Preferences::Realtime:     p = "realtime"; 
 
1377
                                                                                app_p = REALTIME_PRIORITY_CLASS;
 
1378
                                                                                break;
 
1379
                case Preferences::High:                 p = "high"; 
 
1380
                                                                                app_p = REALTIME_PRIORITY_CLASS;
 
1381
                                                                                break;
 
1382
                case Preferences::AboveNormal:  p = "abovenormal"; 
 
1383
                                                                                app_p = HIGH_PRIORITY_CLASS;
 
1384
                                                                                break;
 
1385
                case Preferences::Normal:               p = "normal"; 
 
1386
                                                                                app_p = ABOVE_NORMAL_PRIORITY_CLASS; 
 
1387
                                                                                break;
 
1388
                case Preferences::BelowNormal:  p = "belownormal"; break;
 
1389
                case Preferences::Idle:                 p = "idle"; break;
 
1390
                default:                                                p = "normal";
 
1391
        }
 
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);
 
1396
        #endif
 
1397
 
 
1398
        if (pref->frame_drop) {
 
1399
                proc->addArgument("-framedrop");
 
1400
        }
 
1401
 
 
1402
        if (pref->hard_frame_drop) {
 
1403
                proc->addArgument("-hardframedrop");
 
1404
        }
 
1405
 
 
1406
        if (pref->autosync) {
 
1407
                proc->addArgument("-autosync");
 
1408
                proc->addArgument( QString::number( pref->autosync_factor ) );
 
1409
        }
 
1410
 
 
1411
        if (pref->use_direct_rendering) {
 
1412
                proc->addArgument("-dr");
 
1413
        } else {
 
1414
                proc->addArgument("-nodr");
 
1415
        }
 
1416
 
 
1417
        if (pref->use_double_buffer) {
 
1418
                proc->addArgument("-double");
 
1419
        } else {
 
1420
                proc->addArgument("-nodouble");
 
1421
        }
 
1422
 
 
1423
#ifndef Q_OS_WIN
 
1424
        if (!pref->use_mplayer_window) {
 
1425
                proc->addArgument( "-input" );
 
1426
                proc->addArgument( "conf=" + Paths::dataPath() +"/input.conf" );
 
1427
        }
 
1428
#endif
 
1429
 
 
1430
#ifdef Q_WS_X11
 
1431
        if (pref->disable_screensaver) {
 
1432
                proc->addArgument("-stop-xscreensaver");
 
1433
        } else {
 
1434
                proc->addArgument("-nostop-xscreensaver");
 
1435
        }
 
1436
#endif
 
1437
 
 
1438
        if (!pref->use_mplayer_window) {
 
1439
                proc->addArgument("-wid");
 
1440
                proc->addArgument( QString::number( (int) mplayerwindow->videoLayer()->winId() ) );
 
1441
 
 
1442
#if USE_COLORKEY
 
1443
                #ifdef Q_OS_WIN
 
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) );
 
1448
                } else {
 
1449
                #endif
 
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"); 
 
1452
                #ifdef Q_OS_WIN
 
1453
                }
 
1454
                #endif
 
1455
#endif
 
1456
 
 
1457
                // Square pixels
 
1458
                proc->addArgument("-monitorpixelaspect");
 
1459
                proc->addArgument("1");
 
1460
        } else {
 
1461
                // no -wid
 
1462
                if (!pref->monitor_aspect.isEmpty()) {
 
1463
                        proc->addArgument("-monitoraspect");
 
1464
                        proc->addArgument( pref->monitor_aspect );
 
1465
                }
 
1466
        }
 
1467
 
 
1468
        // Subtitles fonts
 
1469
        if ((pref->use_ass_subtitles) && (pref->freetype_support)) {
 
1470
                // ASS:
 
1471
                proc->addArgument("-ass");
 
1472
                proc->addArgument("-embeddedfonts");
 
1473
 
 
1474
                proc->addArgument("-ass-line-spacing");
 
1475
                proc->addArgument(QString::number(pref->ass_line_spacing));
 
1476
 
 
1477
                proc->addArgument( "-ass-font-scale");
 
1478
                proc->addArgument( QString::number(mset.sub_scale_ass) );
 
1479
 
 
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());
 
1485
                        }
 
1486
                        if (QFile::exists(Paths::subtitleStyleFile())) {
 
1487
                                proc->addArgument("-ass-styles");
 
1488
                                proc->addArgument( Paths::subtitleStyleFile() );
 
1489
                        } else {
 
1490
                                qWarning("Core::startMplayer: '%s' doesn't exist", Paths::subtitleStyleFile().toUtf8().constData());
 
1491
                        }
 
1492
                } else {
 
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);
 
1497
                        } else {
 
1498
                                proc->addArgument(pref->ass_styles.toString());
 
1499
                        }
 
1500
                }
 
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 );
 
1506
                }
 
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));
 
1515
                }
 
1516
        } else {
 
1517
                // NO ASS:
 
1518
                if (pref->freetype_support) proc->addArgument("-noass");
 
1519
 
 
1520
                if ( (pref->use_fontconfig) && (!pref->font_name.isEmpty()) ) {
 
1521
                        proc->addArgument("-fontconfig");
 
1522
                        proc->addArgument("-font");
 
1523
                        proc->addArgument( pref->font_name );
 
1524
                }
 
1525
 
 
1526
                if ( (!pref->use_fontconfig) && (!pref->font_file.isEmpty()) ) {
 
1527
                        proc->addArgument("-font");
 
1528
                        proc->addArgument( pref->font_file );
 
1529
                }
 
1530
 
 
1531
                if (pref->freetype_support) {
 
1532
                        proc->addArgument( "-subfont-autoscale");
 
1533
                        proc->addArgument( QString::number( pref->font_autoscale ) );
 
1534
 
 
1535
                        proc->addArgument( "-subfont-text-scale");
 
1536
                        proc->addArgument( QString::number(mset.sub_scale) );
 
1537
                }
 
1538
        }
 
1539
 
 
1540
        // Subtitle encoding
 
1541
        {
 
1542
                QString 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;
 
1547
                        }
 
1548
                }
 
1549
                else
 
1550
                if (!pref->subcp.isEmpty()) {
 
1551
                        encoding = pref->subcp;
 
1552
                }
 
1553
 
 
1554
                if (!encoding.isEmpty()) {
 
1555
                        proc->addArgument("-subcp");
 
1556
                        proc->addArgument( encoding );
 
1557
                }
 
1558
        }
 
1559
 
 
1560
        if (pref->use_closed_caption_subs) {
 
1561
                proc->addArgument("-subcc");
 
1562
        }
 
1563
 
 
1564
        if (pref->use_forced_subs_only) {
 
1565
                proc->addArgument("-forcedsubsonly");
 
1566
        }
 
1567
 
 
1568
        if (mset.current_video_id != MediaSettings::NoneSelected) {
 
1569
                proc->addArgument("-vid");
 
1570
                proc->addArgument( QString::number( mset.current_video_id ) );
 
1571
        }
 
1572
 
 
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 ) );
 
1578
                }
 
1579
        }
 
1580
 
 
1581
        if (!initial_subtitle.isEmpty()) {
 
1582
                mset.external_subtitles = initial_subtitle;
 
1583
                initial_subtitle = "";
 
1584
                just_loaded_external_subs = true; // Big ugly hack :(
 
1585
        }
 
1586
        if (!mset.external_subtitles.isEmpty()) {
 
1587
                if (QFileInfo(mset.external_subtitles).suffix().toLower()=="idx") {
 
1588
                        // sub/idx subtitles
 
1589
                        QFileInfo fi;
 
1590
 
 
1591
                        #ifdef Q_OS_WIN
 
1592
                        if (pref->use_short_pathnames)
 
1593
                                fi.setFile(Helper::shortPathName(mset.external_subtitles));
 
1594
                        else
 
1595
                        #endif
 
1596
                        fi.setFile(mset.external_subtitles);
 
1597
 
 
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 );
 
1602
                } else {
 
1603
                        proc->addArgument("-sub");
 
1604
                        #ifdef Q_OS_WIN
 
1605
                        if (pref->use_short_pathnames)
 
1606
                                proc->addArgument(Helper::shortPathName(mset.external_subtitles));
 
1607
                        else
 
1608
                        #endif
 
1609
                        proc->addArgument( mset.external_subtitles );
 
1610
                }
 
1611
        }
 
1612
 
 
1613
        if (!mset.external_audio.isEmpty()) {
 
1614
                proc->addArgument("-audiofile");
 
1615
                #ifdef Q_OS_WIN
 
1616
                if (pref->use_short_pathnames)
 
1617
                        proc->addArgument(Helper::shortPathName(mset.external_audio));
 
1618
                else
 
1619
                #endif
 
1620
                proc->addArgument( mset.external_audio );
 
1621
        }
 
1622
 
 
1623
        proc->addArgument("-subpos");
 
1624
        proc->addArgument( QString::number(mset.sub_pos) );
 
1625
 
 
1626
        if (mset.audio_delay!=0) {
 
1627
                proc->addArgument("-delay");
 
1628
                proc->addArgument( QString::number( (double) mset.audio_delay/1000 ) );
 
1629
        }
 
1630
 
 
1631
        if (mset.sub_delay!=0) {
 
1632
                proc->addArgument("-subdelay");
 
1633
                proc->addArgument( QString::number( (double) mset.sub_delay/1000 ) );
 
1634
        }
 
1635
 
 
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 ) );
 
1641
                }
 
1642
        
 
1643
                if (mset.brightness != 0) {
 
1644
                        proc->addArgument("-brightness");
 
1645
                        proc->addArgument( QString::number( mset.brightness ) );
 
1646
                }
 
1647
 
 
1648
                if (mset.hue != 0) {
 
1649
                        proc->addArgument("-hue");
 
1650
                        proc->addArgument( QString::number( mset.hue ) );
 
1651
                }
 
1652
 
 
1653
                if (mset.saturation != 0) {
 
1654
                        proc->addArgument("-saturation");
 
1655
                        proc->addArgument( QString::number( mset.saturation ) );
 
1656
                }
 
1657
        }
 
1658
 
 
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));
 
1663
        }
 
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 ) );
 
1671
        }
 
1672
 
 
1673
 
 
1674
        if (mdat.type==TYPE_DVD) {
 
1675
                if (!dvd_folder.isEmpty()) {
 
1676
                        proc->addArgument("-dvd-device");
 
1677
                        proc->addArgument( dvd_folder );
 
1678
                } else {
 
1679
                        qWarning("Core::startMplayer: dvd device is empty!");
 
1680
                }
 
1681
        }
 
1682
 
 
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 );
 
1687
                }
 
1688
        }
 
1689
 
 
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++;
 
1696
#else
 
1697
                if ((mdat.type == TYPE_DVD) && (dvdFirstChapter() == 0)) chapter++;
 
1698
#endif
 
1699
                proc->addArgument( QString::number( chapter ) );
 
1700
        }
 
1701
 
 
1702
        if (mset.current_angle_id > 0) {
 
1703
                proc->addArgument("-dvdangle");
 
1704
                proc->addArgument( QString::number( mset.current_angle_id ) );
 
1705
        }
 
1706
 
 
1707
 
 
1708
        int cache = 0;
 
1709
        switch (mdat.type) {
 
1710
                case TYPE_FILE          : cache = pref->cache_for_files; break;
 
1711
                case TYPE_DVD           : cache = pref->cache_for_dvds; 
 
1712
#if DVDNAV_SUPPORT
 
1713
                                                          if (file.startsWith("dvdnav:")) cache = 0;
 
1714
#endif
 
1715
                                      break;
 
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;
 
1719
                default: cache = 0;
 
1720
        }
 
1721
 
 
1722
        if (cache > 31) { // Minimum value for cache = 32
 
1723
                proc->addArgument("-cache");
 
1724
                proc->addArgument( QString::number( cache ) );
 
1725
        } else {
 
1726
                proc->addArgument("-nocache");
 
1727
        }
 
1728
 
 
1729
        if (mset.speed != 1.0) {
 
1730
                proc->addArgument("-speed");
 
1731
                proc->addArgument( QString::number( mset.speed ) );
 
1732
        }
 
1733
 
 
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 ) );
 
1738
        }
 
1739
 
 
1740
        proc->addArgument("-osdlevel");
 
1741
        proc->addArgument( QString::number( pref->osd ) );
 
1742
 
 
1743
        if (pref->use_idx) {
 
1744
                proc->addArgument("-idx");
 
1745
        }
 
1746
 
 
1747
        if (mdat.type == TYPE_STREAM) {
 
1748
                if (pref->prefer_ipv4) {
 
1749
                        proc->addArgument("-prefer-ipv4");
 
1750
                } else {
 
1751
                        proc->addArgument("-prefer-ipv6");
 
1752
                }
 
1753
        }
 
1754
 
 
1755
        if (pref->use_correct_pts != Preferences::Detect) {
 
1756
                if (pref->use_correct_pts == Preferences::Enabled) {
 
1757
                        proc->addArgument("-correct-pts");
 
1758
                } else {
 
1759
                        if (pref->mplayer_detected_version > 0) {
 
1760
                                if (MplayerVersion::isMplayerAtLeast(26842)) {
 
1761
                                        proc->addArgument("-nocorrect-pts");
 
1762
                                } else {
 
1763
                                        proc->addArgument("-no-correct-pts");
 
1764
                                }
 
1765
                        } else {
 
1766
                                qDebug("Core::startMplayer: unknown version of mplayer, not passing -no(-)correct-pts");
 
1767
                        }
 
1768
                }
 
1769
        }
 
1770
 
 
1771
        // Video filters:
 
1772
        // Phase
 
1773
        if (mset.phase_filter) {
 
1774
                proc->addArgument("-vf-add");
 
1775
                proc->addArgument( "phase=A" );
 
1776
        }
 
1777
 
 
1778
        // Deinterlace
 
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;
 
1787
                }
 
1788
        }
 
1789
 
 
1790
#if !NEW_ASPECT_CODE
 
1791
        // Panscan (crop)
 
1792
        if (!mset.panscan_filter.isEmpty()) {
 
1793
                proc->addArgument( "-vf-add" );
 
1794
                proc->addArgument( mset.panscan_filter );
 
1795
        }
 
1796
 
 
1797
        // Crop 4:3 to 16:9
 
1798
        if (!mset.crop_43to169_filter.isEmpty()) {
 
1799
                proc->addArgument( "-vf-add" );
 
1800
                proc->addArgument( mset.crop_43to169_filter );
 
1801
        }
 
1802
#endif
 
1803
 
 
1804
        // Denoise
 
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" );
 
1809
                } else {
 
1810
                        proc->addArgument( "hqdn3d" );
 
1811
                }
 
1812
        }
 
1813
 
 
1814
        // Deblock
 
1815
        if (mset.deblock_filter) {
 
1816
                proc->addArgument("-vf-add");
 
1817
                proc->addArgument( "pp=vb/hb" );
 
1818
        }
 
1819
 
 
1820
        // Dering
 
1821
        if (mset.dering_filter) {
 
1822
                proc->addArgument("-vf-add");
 
1823
                proc->addArgument( "pp=dr" );
 
1824
        }
 
1825
 
 
1826
        // Upscale
 
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");
 
1833
        }
 
1834
 
 
1835
        // Addnoise
 
1836
        if (mset.noise_filter) {
 
1837
                proc->addArgument("-vf-add");
 
1838
                proc->addArgument( "noise=9ah:5ah" );
 
1839
        }
 
1840
 
 
1841
        // Postprocessing
 
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) );
 
1847
        }
 
1848
 
 
1849
 
 
1850
        // Letterbox (expand)
 
1851
#if NEW_ASPECT_CODE
 
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.
 
1860
        }
 
1861
#else
 
1862
        if (mset.letterbox == MediaSettings::Letterbox_43) {            
 
1863
                proc->addArgument("-vf-add");
 
1864
                proc->addArgument("expand=:::::4/3");
 
1865
        }
 
1866
        else
 
1867
        if (mset.letterbox == MediaSettings::Letterbox_169) {
 
1868
                proc->addArgument("-vf-add");
 
1869
                proc->addArgument("expand=:::::16/9");
 
1870
        }
 
1871
#endif
 
1872
 
 
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")
 
1878
#ifdef Q_OS_WIN
 
1879
             || (pref->vo == "directx:noaccel")
 
1880
#endif
 
1881
                    ) eq_filter += ",scale";
 
1882
                proc->addArgument(eq_filter);
 
1883
        }
 
1884
 
 
1885
        // Additional video filters, supplied by user
 
1886
        // File
 
1887
        if ( !mset.mplayer_additional_video_filters.isEmpty() ) {
 
1888
                proc->addArgument("-vf-add");
 
1889
                proc->addArgument( mset.mplayer_additional_video_filters );
 
1890
        }
 
1891
        // Global
 
1892
        if ( !pref->mplayer_additional_video_filters.isEmpty() ) {
 
1893
                proc->addArgument("-vf-add");
 
1894
                proc->addArgument( pref->mplayer_additional_video_filters );
 
1895
        }
 
1896
 
 
1897
        bool force_noslices = false;
 
1898
 
 
1899
        // Filters for subtitles on screenshots
 
1900
        if ((screenshot_enabled) && (pref->subtitles_on_screenshots)) 
 
1901
        {
 
1902
                if (pref->use_ass_subtitles) {
 
1903
                        proc->addArgument("-vf-add");
 
1904
                        proc->addArgument("ass");
 
1905
                } else {
 
1906
                        proc->addArgument("-vf-add");
 
1907
                        proc->addArgument("expand=osd=1");
 
1908
                        //proc->addArgument("-noslices");
 
1909
                        force_noslices = true;
 
1910
                }
 
1911
        }
 
1912
 
 
1913
        // Rotate
 
1914
        if (mset.rotate != MediaSettings::NoRotate) {
 
1915
                proc->addArgument( "-vf-add" );
 
1916
                proc->addArgument( QString("rotate=%1").arg(mset.rotate) );
 
1917
        }
 
1918
 
 
1919
        // Flip
 
1920
        if (mset.flip) {
 
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");
 
1925
        }
 
1926
 
 
1927
        // Mirror
 
1928
        if (mset.mirror) {
 
1929
                proc->addArgument( "-vf-add" );
 
1930
                proc->addArgument("mirror");
 
1931
        }
 
1932
 
 
1933
        // Screenshots
 
1934
        if (screenshot_enabled) {
 
1935
                proc->addArgument("-vf-add");
 
1936
                proc->addArgument("screenshot");
 
1937
        }
 
1938
 
 
1939
        // slices
 
1940
        if ((pref->use_slices) && (!force_noslices)) {
 
1941
                proc->addArgument("-slices");
 
1942
        } else {
 
1943
                proc->addArgument("-noslices");
 
1944
        }
 
1945
 
 
1946
 
 
1947
        // Audio channels
 
1948
        if (mset.audio_use_channels != 0) {
 
1949
                proc->addArgument("-channels");
 
1950
                proc->addArgument( QString::number( mset.audio_use_channels ) );
 
1951
        }
 
1952
 
 
1953
        // Stereo mode
 
1954
        if (mset.stereo_mode != 0) {
 
1955
                proc->addArgument("-stereo");
 
1956
                proc->addArgument( QString::number( mset.stereo_mode ) );
 
1957
        }
 
1958
 
 
1959
        // Audio filters
 
1960
        QString af="";
 
1961
        if (mset.karaoke_filter) {
 
1962
                af="karaoke";
 
1963
        }
 
1964
 
 
1965
        if (mset.extrastereo_filter) {
 
1966
                if (!af.isEmpty()) af += ",";
 
1967
                af += "extrastereo";
 
1968
        }
 
1969
 
 
1970
        if (mset.volnorm_filter) {
 
1971
                if (!af.isEmpty()) af += ",";
 
1972
                af += "volnorm=2";
 
1973
        }
 
1974
 
 
1975
        bool use_scaletempo = (pref->use_scaletempo == Preferences::Enabled);
 
1976
        if (pref->use_scaletempo == Preferences::Detect) {
 
1977
                use_scaletempo = (MplayerVersion::isMplayerAtLeast(24924));
 
1978
        }
 
1979
        if (use_scaletempo) {
 
1980
                if (!af.isEmpty()) af += ",";
 
1981
                af += "scaletempo";
 
1982
        }
 
1983
 
 
1984
        // Audio equalizer
 
1985
        if (pref->use_audio_equalizer) {
 
1986
                if (!af.isEmpty()) af += ",";
 
1987
                af += "equalizer=" + Helper::equalizerListToString(mset.audio_equalizer);
 
1988
        }
 
1989
 
 
1990
 
 
1991
        // Additional audio filters, supplied by user
 
1992
        // File
 
1993
        if ( !pref->mplayer_additional_audio_filters.isEmpty() ) {
 
1994
                if (!af.isEmpty()) af += ",";
 
1995
                af += pref->mplayer_additional_audio_filters;
 
1996
        }
 
1997
        // Global
 
1998
        if ( !mset.mplayer_additional_audio_filters.isEmpty() ) {
 
1999
                if (!af.isEmpty()) af += ",";
 
2000
                af += mset.mplayer_additional_audio_filters;
 
2001
        }
 
2002
 
 
2003
        if (!af.isEmpty()) {
 
2004
                proc->addArgument("-af");
 
2005
                proc->addArgument( af );
 
2006
        }
 
2007
 
 
2008
        if (pref->use_soft_vol) {
 
2009
                proc->addArgument("-softvol");
 
2010
                proc->addArgument("-softvol-max");
 
2011
                proc->addArgument( QString::number(pref->softvol_max) );
 
2012
        }
 
2013
 
 
2014
        // Load edl file
 
2015
        if (pref->use_edl_files) {
 
2016
                QString edl_f;
 
2017
                QFileInfo f(file);
 
2018
                QString basename = f.path() + "/" + f.completeBaseName();
 
2019
 
 
2020
                qDebug("Core::startMplayer: file basename: '%s'", basename.toUtf8().data());
 
2021
 
 
2022
                if (QFile::exists(basename+".edl")) 
 
2023
                        edl_f = basename+".edl";
 
2024
                else
 
2025
                if (QFile::exists(basename+".EDL")) 
 
2026
                        edl_f = basename+".EDL";
 
2027
 
 
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);
 
2032
                }
 
2033
        }
 
2034
 
 
2035
        // Additional options supplied by the user
 
2036
        // File
 
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) );
 
2042
                        ++it;
 
2043
                }
 
2044
        }
 
2045
        // Global
 
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) );
 
2051
                        ++it;
 
2052
                }
 
2053
        }
 
2054
 
 
2055
        // File to play
 
2056
        if (url_is_playlist) {
 
2057
                proc->addArgument("-playlist");
 
2058
        }
 
2059
 
 
2060
#ifdef Q_OS_WIN
 
2061
        if (pref->use_short_pathnames)
 
2062
                proc->addArgument(Helper::shortPathName(file));
 
2063
        else
 
2064
#endif
 
2065
        proc->addArgument( file );
 
2066
 
 
2067
        // It seems the loop option must be after the filename
 
2068
        if (pref->loop) {
 
2069
                proc->addArgument("-loop");
 
2070
                proc->addArgument("0");
 
2071
        }
 
2072
 
 
2073
        emit aboutToStartPlaying();
 
2074
 
 
2075
        QString commandline = proc->arguments().join(" ");
 
2076
        qDebug("Core::startMplayer: command: '%s'", commandline.toUtf8().data());
 
2077
 
 
2078
        //Log command
 
2079
        QString line_for_log = commandline + "\n";
 
2080
        emit logLineAvailable(line_for_log);
 
2081
        
 
2082
        if ( !proc->start() ) {
 
2083
            // error handling
 
2084
                qWarning("Core::startMplayer: mplayer process didn't start");
 
2085
        }
 
2086
 
 
2087
}
 
2088
 
 
2089
void Core::stopMplayer() {
 
2090
        qDebug("Core::stopMplayer");
 
2091
 
 
2092
        if (!proc->isRunning()) {
 
2093
                qWarning("Core::stopMplayer: mplayer in not running!");
 
2094
                return;
 
2095
        }
 
2096
 
 
2097
    tellmp("quit");
 
2098
    
 
2099
        qDebug("Core::stopMplayer: Waiting mplayer to finish...");
 
2100
        if (!proc->waitForFinished(5000)) {
 
2101
                qWarning("Core::stopMplayer: process didn't finish. Killing it...");
 
2102
                proc->kill();
 
2103
        }
 
2104
 
 
2105
        qDebug("Core::stopMplayer: Finished. (I hope)");
 
2106
}
 
2107
 
 
2108
 
 
2109
void Core::goToSec( double sec ) {
 
2110
        qDebug("Core::goToSec: %f", sec);
 
2111
 
 
2112
    if (sec < 0) sec = 0;
 
2113
    if (sec > mdat.duration ) sec = mdat.duration - 20;
 
2114
    tellmp("seek " + QString::number(sec) + " 2");
 
2115
}
 
2116
 
 
2117
 
 
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");
 
2122
        }
 
2123
}
 
2124
 
 
2125
void Core::sforward() {
 
2126
        qDebug("Core::sforward");
 
2127
        seek( pref->seeking1 ); // +10s
 
2128
}
 
2129
 
 
2130
void Core::srewind() {
 
2131
        qDebug("Core::srewind");
 
2132
        seek( -pref->seeking1 ); // -10s
 
2133
}
 
2134
 
 
2135
 
 
2136
void Core::forward() {
 
2137
        qDebug("Core::forward");
 
2138
        seek( pref->seeking2 ); // +1m
 
2139
}
 
2140
 
 
2141
 
 
2142
void Core::rewind() {
 
2143
        qDebug("Core::rewind");
 
2144
        seek( -pref->seeking2 ); // -1m
 
2145
}
 
2146
 
 
2147
 
 
2148
void Core::fastforward() {
 
2149
        qDebug("Core::fastforward");
 
2150
        seek( pref->seeking3 ); // +10m
 
2151
}
 
2152
 
 
2153
 
 
2154
void Core::fastrewind() {
 
2155
        qDebug("Core::fastrewind");
 
2156
        seek( -pref->seeking3 ); // -10m
 
2157
}
 
2158
 
 
2159
void Core::forward(int secs) {
 
2160
        qDebug("Core::forward: %d", secs);
 
2161
        seek(secs);
 
2162
}
 
2163
 
 
2164
void Core::rewind(int secs) {
 
2165
        qDebug("Core::rewind: %d", secs);
 
2166
        seek(-secs);
 
2167
}
 
2168
 
 
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
 
2177
        }
 
2178
}
 
2179
 
 
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
 
2188
        }
 
2189
}
 
2190
 
 
2191
 
 
2192
void Core::toggleRepeat() {
 
2193
        qDebug("Core::toggleRepeat");
 
2194
        toggleRepeat( !pref->loop );
 
2195
}
 
2196
 
 
2197
void Core::toggleRepeat(bool b) {
 
2198
        qDebug("Core::toggleRepeat: %d", b);
 
2199
        if ( pref->loop != b ) {
 
2200
                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) );
 
2206
                } else {
 
2207
                        // Restart mplayer
 
2208
                        if (proc->isRunning()) restartPlay();
 
2209
                }
 
2210
        }
 
2211
}
 
2212
 
 
2213
 
 
2214
void Core::toggleFlip() {
 
2215
        qDebug("Core::toggleFlip");
 
2216
        toggleFlip( !mset.flip );
 
2217
}
 
2218
 
 
2219
void Core::toggleFlip(bool b) {
 
2220
        qDebug("Core::toggleFlip: %d", b);
 
2221
 
 
2222
        if (mset.flip != b) {
 
2223
                mset.flip = b;
 
2224
                if (proc->isRunning()) restartPlay();
 
2225
        }
 
2226
}
 
2227
 
 
2228
void Core::toggleMirror() {
 
2229
        qDebug("Core::toggleMirror");
 
2230
        toggleMirror( !mset.mirror );
 
2231
}
 
2232
 
 
2233
void Core::toggleMirror(bool b) {
 
2234
        qDebug("Core::toggleMirror: %d", b);
 
2235
 
 
2236
        if (mset.mirror != b) {
 
2237
                mset.mirror = b;
 
2238
                if (proc->isRunning()) restartPlay();
 
2239
        }
 
2240
}
 
2241
 
 
2242
// Audio filters
 
2243
void Core::toggleKaraoke() {
 
2244
        toggleKaraoke( !mset.karaoke_filter );
 
2245
}
 
2246
 
 
2247
void Core::toggleKaraoke(bool b) {
 
2248
        qDebug("Core::toggleKaraoke: %d", b);
 
2249
        if (b != mset.karaoke_filter) {
 
2250
                mset.karaoke_filter = b;
 
2251
                restartPlay();
 
2252
        }
 
2253
}
 
2254
 
 
2255
void Core::toggleExtrastereo() {
 
2256
        toggleExtrastereo( !mset.extrastereo_filter );
 
2257
}
 
2258
 
 
2259
void Core::toggleExtrastereo(bool b) {
 
2260
        qDebug("Core::toggleExtrastereo: %d", b);
 
2261
        if (b != mset.extrastereo_filter) {
 
2262
                mset.extrastereo_filter = b;
 
2263
                restartPlay();
 
2264
        }
 
2265
}
 
2266
 
 
2267
void Core::toggleVolnorm() {
 
2268
        toggleVolnorm( !mset.volnorm_filter );
 
2269
}
 
2270
 
 
2271
void Core::toggleVolnorm(bool b) {
 
2272
        qDebug("Core::toggleVolnorm: %d", b);
 
2273
        if (b != mset.volnorm_filter) {
 
2274
                mset.volnorm_filter = b;
 
2275
                restartPlay();
 
2276
        }
 
2277
}
 
2278
 
 
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;
 
2283
                restartPlay();
 
2284
        }
 
2285
}
 
2286
 
 
2287
void Core::setStereoMode(int mode) {
 
2288
        qDebug("Core::setStereoMode:%d", mode);
 
2289
        if (mode != mset.stereo_mode ) {
 
2290
                mset.stereo_mode = mode;
 
2291
                restartPlay();
 
2292
        }
 
2293
}
 
2294
 
 
2295
 
 
2296
// Video filters
 
2297
void Core::toggleAutophase() {
 
2298
        toggleAutophase( !mset.phase_filter );
 
2299
}
 
2300
 
 
2301
void Core::toggleAutophase( bool b ) {
 
2302
        qDebug("Core::toggleAutophase: %d", b);
 
2303
        if ( b != mset.phase_filter) {
 
2304
                mset.phase_filter = b;
 
2305
                restartPlay();
 
2306
        }
 
2307
}
 
2308
 
 
2309
void Core::toggleDeblock() {
 
2310
        toggleDeblock( !mset.deblock_filter );
 
2311
}
 
2312
 
 
2313
void Core::toggleDeblock(bool b) {
 
2314
        qDebug("Core::toggleDeblock: %d", b);
 
2315
        if ( b != mset.deblock_filter ) {
 
2316
                mset.deblock_filter = b;
 
2317
                restartPlay();
 
2318
        }
 
2319
}
 
2320
 
 
2321
void Core::toggleDering() {
 
2322
        toggleDering( !mset.dering_filter );
 
2323
}
 
2324
 
 
2325
void Core::toggleDering(bool b) {
 
2326
        qDebug("Core::toggleDering: %d", b);
 
2327
        if ( b != mset.dering_filter) {
 
2328
                mset.dering_filter = b;
 
2329
                restartPlay();
 
2330
        }
 
2331
}
 
2332
 
 
2333
void Core::toggleNoise() {
 
2334
        toggleNoise( !mset.noise_filter );
 
2335
}
 
2336
 
 
2337
void Core::toggleNoise(bool b) {
 
2338
        qDebug("Core::toggleNoise: %d", b);
 
2339
        if ( b!= mset.noise_filter ) {
 
2340
                mset.noise_filter = b;
 
2341
                restartPlay();
 
2342
        }
 
2343
}
 
2344
 
 
2345
void Core::togglePostprocessing() {
 
2346
        togglePostprocessing( !mset.postprocessing_filter );
 
2347
}
 
2348
 
 
2349
void Core::togglePostprocessing(bool b) {
 
2350
        qDebug("Core::togglePostprocessing: %d", b);
 
2351
        if ( b != mset.postprocessing_filter ) {
 
2352
                mset.postprocessing_filter = b;
 
2353
                restartPlay();
 
2354
        }
 
2355
}
 
2356
 
 
2357
void Core::changeDenoise(int id) {
 
2358
        qDebug( "Core::changeDenoise: %d", id );
 
2359
        if (id != mset.current_denoiser) {
 
2360
                mset.current_denoiser = id;
 
2361
                restartPlay();
 
2362
        }
 
2363
}
 
2364
 
 
2365
void Core::changeUpscale(bool b) {
 
2366
        qDebug( "Core::changeUpscale: %d", b );
 
2367
        if (mset.upscaling_filter != b) {
 
2368
                mset.upscaling_filter = b;
 
2369
                restartPlay();
 
2370
        }
 
2371
}
 
2372
 
 
2373
void Core::setBrightness(int value) {
 
2374
        qDebug("Core::setBrightness: %d", value);
 
2375
 
 
2376
        if (value > 100) value = 100;
 
2377
        if (value < -100) value = -100;
 
2378
 
 
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();
 
2384
        }
 
2385
}
 
2386
 
 
2387
 
 
2388
void Core::setContrast(int value) {
 
2389
        qDebug("Core::setContrast: %d", value);
 
2390
 
 
2391
        if (value > 100) value = 100;
 
2392
        if (value < -100) value = -100;
 
2393
 
 
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();
 
2399
        }
 
2400
}
 
2401
 
 
2402
void Core::setGamma(int value) {
 
2403
        qDebug("Core::setGamma: %d", value);
 
2404
 
 
2405
        if (value > 100) value = 100;
 
2406
        if (value < -100) value = -100;
 
2407
 
 
2408
        if (value != mset.gamma) {
 
2409
                tellmp(pausing_prefix() + " gamma " + QString::number(value) + " 1");
 
2410
                mset.gamma= value;
 
2411
                displayMessage( tr("Gamma: %1").arg(value) );
 
2412
                emit videoEqualizerNeedsUpdate();
 
2413
        }
 
2414
}
 
2415
 
 
2416
void Core::setHue(int value) {
 
2417
        qDebug("Core::setHue: %d", value);
 
2418
 
 
2419
        if (value > 100) value = 100;
 
2420
        if (value < -100) value = -100;
 
2421
 
 
2422
        if (value != mset.hue) {
 
2423
                tellmp(pausing_prefix() + " hue " + QString::number(value) + " 1");
 
2424
                mset.hue = value;
 
2425
                displayMessage( tr("Hue: %1").arg(value) );
 
2426
                emit videoEqualizerNeedsUpdate();
 
2427
        }
 
2428
}
 
2429
 
 
2430
void Core::setSaturation(int value) {
 
2431
        qDebug("Core::setSaturation: %d", value);
 
2432
 
 
2433
        if (value > 100) value = 100;
 
2434
        if (value < -100) value = -100;
 
2435
 
 
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();
 
2441
        }
 
2442
}
 
2443
 
 
2444
void Core::incBrightness() {
 
2445
        setBrightness(mset.brightness + 4);
 
2446
}
 
2447
 
 
2448
void Core::decBrightness() {
 
2449
        setBrightness(mset.brightness - 4);
 
2450
}
 
2451
 
 
2452
void Core::incContrast() {
 
2453
        setContrast(mset.contrast + 4);
 
2454
}
 
2455
 
 
2456
void Core::decContrast() {
 
2457
        setContrast(mset.contrast - 4);
 
2458
}
 
2459
 
 
2460
void Core::incGamma() {
 
2461
        setGamma(mset.gamma + 4);
 
2462
}
 
2463
 
 
2464
void Core::decGamma() {
 
2465
        setGamma(mset.gamma - 4);
 
2466
}
 
2467
 
 
2468
void Core::incHue() {
 
2469
        setHue(mset.hue + 4);
 
2470
}
 
2471
 
 
2472
void Core::decHue() {
 
2473
        setHue(mset.hue - 4);
 
2474
}
 
2475
 
 
2476
void Core::incSaturation() {
 
2477
        setSaturation(mset.saturation + 4);
 
2478
}
 
2479
 
 
2480
void Core::decSaturation() {
 
2481
        setSaturation(mset.saturation - 4);
 
2482
}
 
2483
 
 
2484
void Core::setSpeed( double value ) {
 
2485
        qDebug("Core::setSpeed: %f", value);
 
2486
 
 
2487
        if (value < 0.10) value = 0.10;
 
2488
        if (value > 100) value = 100;
 
2489
 
 
2490
        mset.speed = value;
 
2491
        tellmp( "speed_set " + QString::number( value ) );
 
2492
}
 
2493
 
 
2494
void Core::incSpeed10() {
 
2495
        qDebug("Core::incSpeed10");
 
2496
        setSpeed( (double) mset.speed + 0.1 );
 
2497
}
 
2498
 
 
2499
void Core::decSpeed10() {
 
2500
        qDebug("Core::decSpeed10");
 
2501
        setSpeed( (double) mset.speed - 0.1 );
 
2502
}
 
2503
 
 
2504
void Core::incSpeed4() {
 
2505
        qDebug("Core::incSpeed4");
 
2506
        setSpeed( (double) mset.speed + 0.04 );
 
2507
}
 
2508
 
 
2509
void Core::decSpeed4() {
 
2510
        qDebug("Core::decSpeed4");
 
2511
        setSpeed( (double) mset.speed - 0.04 );
 
2512
}
 
2513
 
 
2514
void Core::incSpeed1() {
 
2515
        qDebug("Core::incSpeed1");
 
2516
        setSpeed( (double) mset.speed + 0.01 );
 
2517
}
 
2518
 
 
2519
void Core::decSpeed1() {
 
2520
        qDebug("Core::decSpeed1");
 
2521
        setSpeed( (double) mset.speed - 0.01 );
 
2522
}
 
2523
 
 
2524
void Core::doubleSpeed() {
 
2525
        qDebug("Core::doubleSpeed");
 
2526
        setSpeed( (double) mset.speed * 2 );
 
2527
}
 
2528
 
 
2529
void Core::halveSpeed() {
 
2530
        qDebug("Core::halveSpeed");
 
2531
        setSpeed( (double) mset.speed / 2 );
 
2532
}
 
2533
 
 
2534
void Core::normalSpeed() {
 
2535
        setSpeed(1);
 
2536
}
 
2537
 
 
2538
void Core::setVolume(int volume, bool force) {
 
2539
        qDebug("Core::setVolume: %d", volume);
 
2540
 
 
2541
        if ((volume==mset.volume) && (!force)) return;
 
2542
 
 
2543
        mset.volume = volume;
 
2544
        if (mset.volume > 100 ) mset.volume = 100;
 
2545
        if (mset.volume < 0 ) mset.volume = 0;
 
2546
 
 
2547
        if (state() == Paused) {
 
2548
                // Change volume later, after quiting pause
 
2549
                change_volume_after_unpause = true;
 
2550
        } else {
 
2551
                tellmp("volume " + QString::number(volume) + " 1");
 
2552
        }
 
2553
 
 
2554
        //if (mset.mute) mute(TRUE);
 
2555
        mset.mute=false;
 
2556
 
 
2557
        updateWidgets();
 
2558
 
 
2559
        displayMessage( tr("Volume: %1").arg(mset.volume) );
 
2560
        emit volumeChanged( mset.volume );
 
2561
}
 
2562
 
 
2563
void Core::switchMute() {
 
2564
        qDebug("Core::switchMute");
 
2565
 
 
2566
        mset.mute = !mset.mute;
 
2567
        mute(mset.mute);
 
2568
}
 
2569
 
 
2570
void Core::mute(bool b) {
 
2571
        qDebug("Core::mute");
 
2572
 
 
2573
        mset.mute = b;
 
2574
 
 
2575
        int v = 0;
 
2576
        if (mset.mute) v = 1;
 
2577
        tellmp( pausing_prefix() + " mute " + QString::number(v) );
 
2578
 
 
2579
        updateWidgets();
 
2580
}
 
2581
 
 
2582
void Core::incVolume() {
 
2583
        qDebug("Core::incVolume");
 
2584
        setVolume(mset.volume + 4);
 
2585
}
 
2586
 
 
2587
void Core::decVolume() {
 
2588
        qDebug("Core::incVolume");
 
2589
        setVolume(mset.volume-4);
 
2590
}
 
2591
 
 
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");
 
2596
}
 
2597
 
 
2598
void Core::incSubDelay() {
 
2599
        qDebug("Core::incSubDelay");
 
2600
        setSubDelay(mset.sub_delay + 100);
 
2601
}
 
2602
 
 
2603
void Core::decSubDelay() {
 
2604
        qDebug("Core::decSubDelay");
 
2605
        setSubDelay(mset.sub_delay - 100);
 
2606
}
 
2607
 
 
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");
 
2612
}
 
2613
 
 
2614
void Core::incAudioDelay() {
 
2615
        qDebug("Core::incAudioDelay");
 
2616
        setAudioDelay(mset.audio_delay + 100);
 
2617
}
 
2618
 
 
2619
void Core::decAudioDelay() {
 
2620
        qDebug("Core::decAudioDelay");
 
2621
        setAudioDelay(mset.audio_delay - 100);
 
2622
}
 
2623
 
 
2624
void Core::incSubPos() {
 
2625
        qDebug("Core::incSubPos");
 
2626
 
 
2627
        mset.sub_pos++;
 
2628
        if (mset.sub_pos > 100) mset.sub_pos = 100;
 
2629
        tellmp("sub_pos " + QString::number( mset.sub_pos ) + " 1");
 
2630
}
 
2631
 
 
2632
void Core::decSubPos() {
 
2633
        qDebug("Core::decSubPos");
 
2634
 
 
2635
        mset.sub_pos--;
 
2636
        if (mset.sub_pos < 0) mset.sub_pos = 0;
 
2637
        tellmp("sub_pos " + QString::number( mset.sub_pos ) + " 1");
 
2638
}
 
2639
 
 
2640
bool Core::subscale_need_restart() {
 
2641
        bool need_restart = false;
 
2642
 
 
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));
 
2647
                else
 
2648
                        need_restart = (!MplayerVersion::isMplayerAtLeast(23745));
 
2649
        }
 
2650
        return need_restart;
 
2651
}
 
2652
 
 
2653
void Core::changeSubScale(double value) {
 
2654
        qDebug("Core::changeSubScale: %f", value);
 
2655
 
 
2656
        bool need_restart = subscale_need_restart();
 
2657
 
 
2658
        if (value < 0) value = 0;
 
2659
 
 
2660
        if (pref->use_ass_subtitles) {
 
2661
                if (value != mset.sub_scale_ass) {
 
2662
                        mset.sub_scale_ass = value;
 
2663
                        if (need_restart) {
 
2664
                                restartPlay();
 
2665
                        } else {
 
2666
                                tellmp("sub_scale " + QString::number( mset.sub_scale_ass ) + " 1");
 
2667
                        }
 
2668
                        displayMessage( tr("Font scale: %1").arg(mset.sub_scale_ass) );
 
2669
                }
 
2670
        } else {
 
2671
                // No ass
 
2672
                if (value != mset.sub_scale) {
 
2673
                        mset.sub_scale = value;
 
2674
                        if (need_restart) {
 
2675
                                restartPlay();
 
2676
                        } else {
 
2677
                                tellmp("sub_scale " + QString::number( mset.sub_scale ) + " 1");
 
2678
                                
 
2679
                        }
 
2680
                        displayMessage( tr("Font scale: %1").arg(mset.sub_scale) );
 
2681
                }
 
2682
        }
 
2683
}
 
2684
 
 
2685
void Core::incSubScale() {
 
2686
        double step = 0.20;
 
2687
 
 
2688
        if (pref->use_ass_subtitles) {
 
2689
                changeSubScale( mset.sub_scale_ass + step );
 
2690
        } else {
 
2691
                if (subscale_need_restart()) step = 1;
 
2692
                changeSubScale( mset.sub_scale + step );
 
2693
        }
 
2694
}
 
2695
 
 
2696
void Core::decSubScale() {
 
2697
        double step = 0.20;
 
2698
 
 
2699
        if (pref->use_ass_subtitles) {
 
2700
                changeSubScale( mset.sub_scale_ass - step );
 
2701
        } else {
 
2702
                if (subscale_need_restart()) step = 1;
 
2703
                changeSubScale( mset.sub_scale - step );
 
2704
        }
 
2705
}
 
2706
 
 
2707
void Core::incSubStep() {
 
2708
        qDebug("Core::incSubStep");
 
2709
        tellmp("sub_step +1");
 
2710
}
 
2711
 
 
2712
void Core::decSubStep() {
 
2713
        qDebug("Core::decSubStep");
 
2714
        tellmp("sub_step -1");
 
2715
}
 
2716
 
 
2717
// Audio equalizer functions
 
2718
void Core::setAudioEqualizer(AudioEqualizerList values, bool restart) {
 
2719
        mset.audio_equalizer = values;
 
2720
 
 
2721
        if (!restart) {
 
2722
                tellmp( "af_eq_set_bands " + Helper::equalizerListToString(values) );
 
2723
        } else {
 
2724
                restartPlay();
 
2725
        }
 
2726
 
 
2727
        emit audioEqualizerNeedsUpdate();
 
2728
}
 
2729
 
 
2730
void Core::updateAudioEqualizer() {
 
2731
        setAudioEqualizer(mset.audio_equalizer);
 
2732
}
 
2733
 
 
2734
void Core::setAudioEq0(int value) {
 
2735
        mset.audio_equalizer[0] = value;
 
2736
        updateAudioEqualizer();
 
2737
}
 
2738
 
 
2739
void Core::setAudioEq1(int value) {
 
2740
        mset.audio_equalizer[1] = value;
 
2741
        updateAudioEqualizer();
 
2742
}
 
2743
 
 
2744
void Core::setAudioEq2(int value) {
 
2745
        mset.audio_equalizer[2] = value;
 
2746
        updateAudioEqualizer();
 
2747
}
 
2748
 
 
2749
void Core::setAudioEq3(int value) {
 
2750
        mset.audio_equalizer[3] = value;
 
2751
        updateAudioEqualizer();
 
2752
}
 
2753
 
 
2754
void Core::setAudioEq4(int value) {
 
2755
        mset.audio_equalizer[4] = value;
 
2756
        updateAudioEqualizer();
 
2757
}
 
2758
 
 
2759
void Core::setAudioEq5(int value) {
 
2760
        mset.audio_equalizer[5] = value;
 
2761
        updateAudioEqualizer();
 
2762
}
 
2763
 
 
2764
void Core::setAudioEq6(int value) {
 
2765
        mset.audio_equalizer[6] = value;
 
2766
        updateAudioEqualizer();
 
2767
}
 
2768
 
 
2769
void Core::setAudioEq7(int value) {
 
2770
        mset.audio_equalizer[7] = value;
 
2771
        updateAudioEqualizer();
 
2772
}
 
2773
 
 
2774
void Core::setAudioEq8(int value) {
 
2775
        mset.audio_equalizer[8] = value;
 
2776
        updateAudioEqualizer();
 
2777
}
 
2778
 
 
2779
void Core::setAudioEq9(int value) {
 
2780
        mset.audio_equalizer[9] = value;
 
2781
        updateAudioEqualizer();
 
2782
}
 
2783
 
 
2784
 
 
2785
 
 
2786
void Core::changeCurrentSec(double sec) {
 
2787
    mset.current_sec = sec;
 
2788
 
 
2789
        if (mset.starting_time != -1) {
 
2790
                mset.current_sec -= mset.starting_time;
 
2791
        }
 
2792
        
 
2793
        if (state() != Playing) {
 
2794
                setState(Playing);
 
2795
                qDebug("Core::changeCurrentSec: mplayer reports that now it's playing");
 
2796
                //emit mediaStartPlay();
 
2797
                //emit stateChanged(state());
 
2798
        }
 
2799
 
 
2800
        emit showTime(mset.current_sec);
 
2801
 
 
2802
        // Emit posChanged:
 
2803
        static int last_second = 0;
 
2804
 
 
2805
        if (floor(sec)==last_second) return; // Update only once per second
 
2806
        last_second = (int) floor(sec);
 
2807
 
 
2808
#ifdef SEEKBAR_RESOLUTION
 
2809
        int value = 0;
 
2810
        if ( (mdat.duration > 1) && (mset.current_sec > 1) &&
 
2811
         (mdat.duration > mset.current_sec) )
 
2812
        {
 
2813
                value = ( (int) mset.current_sec * SEEKBAR_RESOLUTION) / (int) mdat.duration;
 
2814
        }
 
2815
        emit positionChanged(value);
 
2816
#else
 
2817
        int perc = 0;
 
2818
        if ( (mdat.duration > 1) && (mset.current_sec > 1) &&
 
2819
         (mdat.duration > mset.current_sec) )
 
2820
        {
 
2821
                perc = ( (int) mset.current_sec * 100) / (int) mdat.duration;
 
2822
        }
 
2823
        emit posChanged( perc );
 
2824
#endif
 
2825
}
 
2826
 
 
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);
 
2833
        }
 
2834
}
 
2835
 
 
2836
 
 
2837
void Core::changePause() {
 
2838
        qDebug("Core::changePause");
 
2839
        qDebug("Core::changePause: mplayer reports that it's paused");
 
2840
        setState(Paused);
 
2841
        //emit stateChanged(state());
 
2842
}
 
2843
 
 
2844
void Core::changeDeinterlace(int ID) {
 
2845
        qDebug("Core::changeDeinterlace: %d", ID);
 
2846
 
 
2847
        if (ID!=mset.current_deinterlacer) {
 
2848
                mset.current_deinterlacer = ID;
 
2849
                restartPlay();
 
2850
        }
 
2851
}
 
2852
 
 
2853
 
 
2854
 
 
2855
void Core::changeSubtitle(int ID) {
 
2856
        qDebug("Core::changeSubtitle: %d", ID);
 
2857
 
 
2858
        mset.current_sub_id = ID;
 
2859
        if (ID==MediaSettings::SubNone) {
 
2860
                ID=-1;
 
2861
        }
 
2862
 
 
2863
        if (ID==MediaSettings::NoneSelected) {
 
2864
                ID=-1;
 
2865
                qDebug("Core::changeSubtitle: subtitle is NoneSelected, this shouldn't happen. ID set to -1.");
 
2866
        }
 
2867
        
 
2868
        qDebug("Core::changeSubtitle: ID: %d", ID);
 
2869
 
 
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));
 
2873
        }
 
2874
 
 
2875
        if (!use_new_commands) {
 
2876
                // Old command sub_select
 
2877
                tellmp( "sub_select " + QString::number(ID) );
 
2878
        } else {
 
2879
                // New commands
 
2880
                int real_id = -1;
 
2881
                if (ID == -1) {
 
2882
                        tellmp( "sub_source -1" );
 
2883
                } else {
 
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()) {
 
2889
                                        case SubData::Vob:
 
2890
                                                tellmp( "sub_vob " + QString::number(real_id) );
 
2891
                                                break;
 
2892
                                        case SubData::Sub:
 
2893
                                                tellmp( "sub_demux " + QString::number(real_id) );
 
2894
                                                break;
 
2895
                                        case SubData::File:
 
2896
                                                tellmp( "sub_file " + QString::number(real_id) );
 
2897
                                                break;
 
2898
                                        default: {
 
2899
                                                qWarning("Core::changeSubtitle: unknown type!");
 
2900
                                        }
 
2901
                                }
 
2902
                        } else {
 
2903
                                qWarning("Core::changeSubtitle: subtitle list is empty!");
 
2904
                        }
 
2905
                }
 
2906
        }
 
2907
 
 
2908
        updateWidgets();
 
2909
}
 
2910
 
 
2911
void Core::nextSubtitle() {
 
2912
        qDebug("Core::nextSubtitle");
 
2913
 
 
2914
        if ( (mset.current_sub_id == MediaSettings::SubNone) && 
 
2915
         (mdat.subs.numItems() > 0) ) 
 
2916
        {
 
2917
                changeSubtitle(0);
 
2918
        } 
 
2919
        else {
 
2920
                int item = mset.current_sub_id + 1;
 
2921
                if (item >= mdat.subs.numItems()) {
 
2922
                        item = MediaSettings::SubNone;
 
2923
                }
 
2924
                changeSubtitle( item );
 
2925
        }
 
2926
}
 
2927
 
 
2928
void Core::changeAudio(int ID, bool allow_restart) {
 
2929
        qDebug("Core::changeAudio: ID: %d, allow_restart: %d", ID, allow_restart);
 
2930
 
 
2931
        if (ID!=mset.current_audio_id) {
 
2932
                mset.current_audio_id = ID;
 
2933
                qDebug("changeAudio: ID: %d", ID);
 
2934
 
 
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));
 
2940
                        }
 
2941
                }
 
2942
 
 
2943
                if (need_restart) {
 
2944
                        restartPlay(); 
 
2945
                } else {
 
2946
                        tellmp("switch_audio " + QString::number(ID) );
 
2947
                        //#ifdef Q_OS_WIN
 
2948
                        // Workaround for a mplayer problem in windows,
 
2949
                        // volume is too loud after changing audio.
 
2950
 
 
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 );
 
2955
                        }
 
2956
                        //#endif
 
2957
                        if (mset.mute) mute(true); // if muted, mute again
 
2958
                        updateWidgets();
 
2959
                }
 
2960
        }
 
2961
}
 
2962
 
 
2963
void Core::nextAudio() {
 
2964
        qDebug("Core::nextAudio");
 
2965
 
 
2966
        int item = mdat.audios.find( mset.current_audio_id );
 
2967
        if (item == -1) {
 
2968
                qWarning("Core::nextAudio: audio ID %d not found!", mset.current_audio_id);
 
2969
        } else {
 
2970
                qDebug( "Core::nextAudio: numItems: %d, item: %d", mdat.audios.numItems(), item);
 
2971
                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);
 
2975
                changeAudio( ID );
 
2976
        }
 
2977
}
 
2978
 
 
2979
void Core::changeVideo(int ID, bool allow_restart) {
 
2980
        qDebug("Core::changeVideo: ID: %d, allow_restart: %d", ID, allow_restart);
 
2981
 
 
2982
        if (ID != mset.current_video_id) {
 
2983
                mset.current_video_id = ID;
 
2984
                qDebug("Core::changeVideo: ID set to: %d", ID);
 
2985
 
 
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");
 
2990
                }
 
2991
 
 
2992
                if (need_restart) {
 
2993
                        restartPlay(); 
 
2994
                } else {
 
2995
                        tellmp("set_property switch_video " + QString::number(ID) );
 
2996
                }
 
2997
        }
 
2998
}
 
2999
 
 
3000
void Core::nextVideo() {
 
3001
        qDebug("Core::nextVideo");
 
3002
 
 
3003
        int item = mdat.videos.find( mset.current_video_id );
 
3004
        if (item == -1) {
 
3005
                qWarning("Core::nextVideo: video ID %d not found!", mset.current_video_id);
 
3006
        } else {
 
3007
                qDebug( "Core::nextVideo: numItems: %d, item: %d", mdat.videos.numItems(), item);
 
3008
                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);
 
3012
                changeVideo( ID );
 
3013
        }
 
3014
}
 
3015
 
 
3016
 
 
3017
void Core::changeTitle(int ID) {
 
3018
        if (mdat.type == TYPE_VCD) {
 
3019
                // VCD
 
3020
                openVCD( ID );
 
3021
        }
 
3022
        else 
 
3023
        if (mdat.type == TYPE_AUDIO_CD) {
 
3024
                // AUDIO CD
 
3025
                openAudioCD( ID );
 
3026
        }
 
3027
        else
 
3028
        if (mdat.type == TYPE_DVD) {
 
3029
#if DVDNAV_SUPPORT
 
3030
                if (mdat.filename.startsWith("dvdnav:")) {
 
3031
                        tellmp("switch_title " + QString::number(ID));
 
3032
                } else {
 
3033
#endif
 
3034
                        DiscData disc_data = DiscName::split(mdat.filename);
 
3035
                        disc_data.title = ID;
 
3036
                        QString dvd_url = DiscName::join(disc_data);
 
3037
 
 
3038
                        openDVD( DiscName::join(disc_data) );
 
3039
#if DVDNAV_SUPPORT
 
3040
                }
 
3041
#endif
 
3042
        }
 
3043
}
 
3044
 
 
3045
void Core::changeChapter(int ID) {
 
3046
        qDebug("Core::changeChapter: ID: %d", ID);
 
3047
 
 
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) {
 
3052
#else
 
3053
                if (mdat.mkv_chapters > 0) {
 
3054
                        // mkv doesn't require to restart
 
3055
#endif
 
3056
                        tellmp("seek_chapter " + QString::number(ID) +" 1");
 
3057
                        mset.current_chapter_id = ID;
 
3058
                        updateWidgets();
 
3059
                } else {
 
3060
#if SMART_DVD_CHAPTERS
 
3061
                        if (pref->cache_for_dvds == 0) {
 
3062
#else
 
3063
                        if (pref->fast_chapter_change) {
 
3064
#endif
 
3065
                                tellmp("seek_chapter " + QString::number(ID) +" 1");
 
3066
                                mset.current_chapter_id = ID;
 
3067
                                updateWidgets();
 
3068
                        } else {
 
3069
                                stopMplayer();
 
3070
                                mset.current_chapter_id = ID;
 
3071
                                //goToPos(0);
 
3072
                                mset.current_sec = 0;
 
3073
                                restartPlay();
 
3074
                        }
 
3075
                }
 
3076
        }
 
3077
}
 
3078
 
 
3079
int Core::firstChapter() {
 
3080
        if (MplayerVersion::isMplayerAtLeast(25391)) 
 
3081
                return 1;
 
3082
        else
 
3083
                return 0;
 
3084
}
 
3085
 
 
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();
 
3090
}
 
3091
#endif
 
3092
 
 
3093
void Core::prevChapter() {
 
3094
        qDebug("Core::prevChapter");
 
3095
 
 
3096
#if GENERIC_CHAPTER_SUPPORT
 
3097
        int last_chapter = 0;
 
3098
        int first_chapter = firstChapter();
 
3099
 
 
3100
        last_chapter = mdat.chapters + firstChapter() - 1;
 
3101
 
 
3102
        int ID = mset.current_chapter_id - 1;
 
3103
        if (ID < first_chapter) {
 
3104
                ID = last_chapter;
 
3105
        }
 
3106
        changeChapter(ID);
 
3107
#else
 
3108
        int last_chapter = 0;
 
3109
        bool matroshka = (mdat.mkv_chapters > 0);
 
3110
 
 
3111
        int first_chapter = dvdFirstChapter();
 
3112
        if (matroshka) first_chapter = firstChapter();
 
3113
 
 
3114
        // Matroshka chapters
 
3115
        if (matroshka) last_chapter = mdat.mkv_chapters + firstChapter() - 1;
 
3116
        else
 
3117
        // DVD chapters
 
3118
        if (mset.current_title_id > 0) {
 
3119
                last_chapter = mdat.titles.item(mset.current_title_id).chapters() + dvdFirstChapter() -1;
 
3120
        }
 
3121
 
 
3122
        int ID = mset.current_chapter_id - 1;
 
3123
        if (ID < first_chapter) {
 
3124
                ID = last_chapter;
 
3125
        }
 
3126
        changeChapter(ID);
 
3127
#endif
 
3128
}
 
3129
 
 
3130
void Core::nextChapter() {
 
3131
        qDebug("Core::nextChapter");
 
3132
 
 
3133
#if GENERIC_CHAPTER_SUPPORT
 
3134
        int last_chapter = 0;
 
3135
        last_chapter = mdat.chapters + firstChapter() - 1;
 
3136
 
 
3137
        int ID = mset.current_chapter_id + 1;
 
3138
        if (ID > last_chapter) {
 
3139
                ID = firstChapter();
 
3140
        }
 
3141
        changeChapter(ID);
 
3142
#else
 
3143
        int last_chapter = 0;
 
3144
        bool matroshka = (mdat.mkv_chapters > 0);
 
3145
 
 
3146
        // Matroshka chapters
 
3147
        if (matroshka) last_chapter = mdat.mkv_chapters + firstChapter() - 1;
 
3148
        else
 
3149
        // DVD chapters
 
3150
        if (mset.current_title_id > 0) {
 
3151
                last_chapter = mdat.titles.item(mset.current_title_id).chapters() + dvdFirstChapter() - 1;
 
3152
        }
 
3153
 
 
3154
        int ID = mset.current_chapter_id + 1;
 
3155
        if (ID > last_chapter) {
 
3156
                if (matroshka) ID = firstChapter(); else ID = dvdFirstChapter();
 
3157
        }
 
3158
        changeChapter(ID);
 
3159
#endif
 
3160
}
 
3161
 
 
3162
void Core::changeAngle(int ID) {
 
3163
        qDebug("Core::changeAngle: ID: %d", ID);
 
3164
 
 
3165
        if (ID != mset.current_angle_id) {
 
3166
                mset.current_angle_id = ID;
 
3167
                restartPlay();
 
3168
        }
 
3169
}
 
3170
 
 
3171
#if NEW_ASPECT_CODE
 
3172
void Core::changeAspectRatio( int ID ) {
 
3173
        qDebug("Core::changeAspectRatio: %d", ID);
 
3174
 
 
3175
        mset.aspect_ratio_id = ID;
 
3176
 
 
3177
        double asp = mset.aspectToNum( (MediaSettings::Aspect) ID);
 
3178
 
 
3179
        if (!pref->use_mplayer_window) {
 
3180
                mplayerwindow->setAspect( asp );
 
3181
        } else {
 
3182
                // Using mplayer own window
 
3183
                if (!mdat.novideo) {
 
3184
                        tellmp("switch_ratio " + QString::number(asp));
 
3185
                }
 
3186
        }
 
3187
 
 
3188
        QString asp_name = MediaSettings::aspectToString( (MediaSettings::Aspect) mset.aspect_ratio_id);
 
3189
        displayMessage( tr("Aspect ratio: %1").arg(asp_name) );
 
3190
}
 
3191
 
 
3192
void Core::nextAspectRatio() {
 
3193
        int ID = mset.aspect_ratio_id + 1;
 
3194
        if (ID > MediaSettings:: Aspect11) ID = MediaSettings::AspectNone;
 
3195
        changeAspectRatio(ID);
 
3196
 
 
3197
        updateWidgets();
 
3198
}
 
3199
 
 
3200
void Core::changeLetterbox(bool b) {
 
3201
        qDebug("Core::changeLetterbox: %d", b);
 
3202
 
 
3203
        if (mset.add_letterbox != b) {
 
3204
                mset.add_letterbox = b;
 
3205
                restartPlay();
 
3206
        }
 
3207
}
 
3208
 
 
3209
#else
 
3210
void Core::changeAspectRatio( int ID ) {
 
3211
        qDebug("Core::changeAspectRatio: %d", ID);
 
3212
 
 
3213
        int old_id = mset.aspect_ratio_id;
 
3214
        mset.aspect_ratio_id = ID;
 
3215
        bool need_restart = FALSE;
 
3216
 
 
3217
    double asp = mdat.video_aspect; // Set a default
 
3218
 
 
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 = "";
 
3225
        }
 
3226
        else
 
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 = "";
 
3233
        }
 
3234
        else
 
3235
        if (ID==MediaSettings::Aspect43Panscan) {
 
3236
                need_restart = (old_id != MediaSettings::Aspect43Panscan);
 
3237
                mset.crop_43to169_filter = "";
 
3238
                mset.letterbox = MediaSettings::NoLetterbox;
 
3239
 
 
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() );
 
3246
 
 
3247
        }
 
3248
    else
 
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;
 
3254
 
 
3255
                int real_width = (int) round(mdat.video_height * mdat.video_aspect);
 
3256
                int height = (int) round(real_width * 9 / 16);
 
3257
 
 
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 );
 
3260
 
 
3261
                if (height > mdat.video_height) {
 
3262
                        // Invalid size, source video is not 4:3
 
3263
                        need_restart = FALSE;
 
3264
                } else {
 
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() );
 
3269
                }
 
3270
        }
 
3271
        else
 
3272
    {
 
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 = "";
 
3281
        switch (ID) {
 
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;
 
3286
                        }
 
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;
 
3293
                }
 
3294
        }
 
3295
 
 
3296
        if (!pref->use_mplayer_window) {
 
3297
                mplayerwindow->setAspect( asp );
 
3298
        } else {
 
3299
                // Using mplayer own window
 
3300
                tellmp("switch_ratio " + QString::number(asp));
 
3301
        }
 
3302
 
 
3303
        updateWidgets();
 
3304
 
 
3305
    if (need_restart) {
 
3306
                /*mdat.calculateWinResolution(mset.force_letterbox);*/
 
3307
        restartPlay();
 
3308
        }
 
3309
}
 
3310
#endif
 
3311
 
 
3312
void Core::changeOSD(int v) {
 
3313
        qDebug("Core::changeOSD: %d", v);
 
3314
 
 
3315
        pref->osd = v;
 
3316
        tellmp("osd " + QString::number( pref->osd ) );
 
3317
        updateWidgets();
 
3318
}
 
3319
 
 
3320
void Core::nextOSD() {
 
3321
        int osd = pref->osd + 1;
 
3322
        if (osd > Preferences::SeekTimerTotal) {
 
3323
                osd = Preferences::None;        
 
3324
        }
 
3325
        changeOSD( osd );
 
3326
}
 
3327
 
 
3328
void Core::changeRotate(int r) {
 
3329
        qDebug("Core::changeRotate: %d", r);
 
3330
 
 
3331
        if (mset.rotate != r) {
 
3332
                mset.rotate = r;
 
3333
                restartPlay();
 
3334
        }
 
3335
}
 
3336
 
 
3337
#if USE_ADAPTER
 
3338
void Core::changeAdapter(int n) {
 
3339
        qDebug("Core::changeScreen: %d", n);
 
3340
 
 
3341
        if (pref->adapter != n) {
 
3342
                pref->adapter = n;
 
3343
                restartPlay();
 
3344
        }
 
3345
}
 
3346
#endif
 
3347
 
 
3348
void Core::changeSize(int n) {
 
3349
        if ( /*(n != pref->size_factor) &&*/ (!pref->use_mplayer_window) ) {
 
3350
                pref->size_factor = n;
 
3351
 
 
3352
                emit needResize(mset.win_width, mset.win_height);
 
3353
                updateWidgets();
 
3354
        }
 
3355
}
 
3356
 
 
3357
void Core::toggleDoubleSize() {
 
3358
        if (pref->size_factor != 100) 
 
3359
                changeSize(100);
 
3360
        else
 
3361
                changeSize(200);
 
3362
}
 
3363
 
 
3364
void Core::changePanscan(double p) {
 
3365
        qDebug("Core::changePanscan: %f", p);
 
3366
        if (p < ZOOM_MIN) p = ZOOM_MIN;
 
3367
 
 
3368
        mset.panscan_factor = p;
 
3369
        mplayerwindow->setZoom(p);
 
3370
        displayMessage( tr("Zoom: %1").arg(mset.panscan_factor) );
 
3371
}
 
3372
 
 
3373
void Core::resetPanscan() {
 
3374
        changePanscan(1.0);
 
3375
}
 
3376
 
 
3377
void Core::autoPanscan() {
 
3378
        double video_aspect = mset.aspectToNum( (MediaSettings::Aspect) mset.aspect_ratio_id);
 
3379
 
 
3380
        if (video_aspect <= 0) {
 
3381
                QSize w = mplayerwindow->videoLayer()->size();
 
3382
                video_aspect = (double) w.width() / w.height();
 
3383
        }
 
3384
 
 
3385
        double screen_aspect = DesktopInfo::desktop_aspectRatio(mplayerwindow);
 
3386
        double zoom_factor;
 
3387
 
 
3388
        if (video_aspect > screen_aspect)
 
3389
                zoom_factor = video_aspect / screen_aspect;
 
3390
        else
 
3391
                zoom_factor = screen_aspect / video_aspect;
 
3392
 
 
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);
 
3396
 
 
3397
        changePanscan(zoom_factor);
 
3398
}
 
3399
 
 
3400
void Core::autoPanscanFromLetterbox(double aspect) {
 
3401
        qDebug("Core::autoPanscanFromLetterbox: %f", aspect);
 
3402
 
 
3403
        // Probably there's a much easy way to do this, but I'm not good with maths...
 
3404
 
 
3405
        QSize desktop =  DesktopInfo::desktop_size(mplayerwindow);
 
3406
 
 
3407
        double video_aspect = mset.aspectToNum( (MediaSettings::Aspect) mset.aspect_ratio_id);
 
3408
 
 
3409
        if (video_aspect <= 0) {
 
3410
                QSize w = mplayerwindow->videoLayer()->size();
 
3411
                video_aspect = (double) w.width() / w.height();
 
3412
        }
 
3413
 
 
3414
        // Calculate size of the video in fullscreen
 
3415
        QSize video;
 
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) );
 
3421
        }
 
3422
 
 
3423
        qDebug("Core::autoPanscanFromLetterbox: max. size of video: %d %d", video.width(), video.height());
 
3424
 
 
3425
        // Calculate the size of the actual video inside the letterbox
 
3426
        QSize actual_video;
 
3427
        actual_video.setWidth( video.width() );
 
3428
        actual_video.setHeight( (int) (actual_video.width() / aspect) );
 
3429
 
 
3430
        qDebug("Core::autoPanscanFromLetterbox: calculated size of actual video for aspect %f: %d %d", aspect, actual_video.width(), actual_video.height());
 
3431
 
 
3432
        double zoom_factor = (double) desktop.height() / actual_video.height();
 
3433
 
 
3434
        qDebug("Core::autoPanscanFromLetterbox: calculated zoom factor: %f", zoom_factor);
 
3435
        changePanscan(zoom_factor);     
 
3436
}
 
3437
 
 
3438
void Core::autoPanscanFor169() {
 
3439
        autoPanscanFromLetterbox((double) 16 / 9);
 
3440
}
 
3441
 
 
3442
void Core::autoPanscanFor235() {
 
3443
        autoPanscanFromLetterbox(2.35);
 
3444
}
 
3445
 
 
3446
void Core::incPanscan() {
 
3447
        qDebug("Core::incPanscan");
 
3448
        changePanscan( mset.panscan_factor + ZOOM_STEP );
 
3449
}
 
3450
 
 
3451
void Core::decPanscan() {
 
3452
        qDebug("Core::decPanscan");
 
3453
        changePanscan( mset.panscan_factor - ZOOM_STEP );
 
3454
}
 
3455
 
 
3456
void Core::changeUseAss(bool b) {
 
3457
        qDebug("Core::changeUseAss: %d", b);
 
3458
 
 
3459
        if (pref->use_ass_subtitles != b) {
 
3460
                pref->use_ass_subtitles = b;
 
3461
                if (proc->isRunning()) restartPlay();
 
3462
        }
 
3463
}
 
3464
 
 
3465
void Core::toggleClosedCaption(bool b) {
 
3466
        qDebug("Core::toggleClosedCaption: %d", b);
 
3467
 
 
3468
        if (pref->use_closed_caption_subs != b) {
 
3469
                pref->use_closed_caption_subs = b;
 
3470
                if (proc->isRunning()) restartPlay();
 
3471
        }
 
3472
}
 
3473
 
 
3474
void Core::toggleForcedSubsOnly(bool b) {
 
3475
        qDebug("Core::toggleForcedSubsOnly: %d", b);
 
3476
 
 
3477
        if (pref->use_forced_subs_only != b) {
 
3478
                pref->use_forced_subs_only = b;
 
3479
                //if (proc->isRunning()) restartPlay();
 
3480
                int v = 0;
 
3481
                if (b) v = 1;
 
3482
                tellmp( QString("forced_subs_only %1").arg(v) );
 
3483
        }
 
3484
}
 
3485
 
 
3486
void Core::visualizeMotionVectors(bool b) {
 
3487
        qDebug("Core::visualizeMotionVectors: %d", b);
 
3488
 
 
3489
        if (pref->show_motion_vectors != b) {
 
3490
                pref->show_motion_vectors = b;
 
3491
                if (proc->isRunning()) restartPlay();
 
3492
        }
 
3493
}
 
3494
 
 
3495
#if DVDNAV_SUPPORT
 
3496
// dvdnav buttons
 
3497
void Core::dvdnavUp() {
 
3498
        qDebug("Core::dvdnavUp");
 
3499
        tellmp("dvdnav up");
 
3500
}
 
3501
 
 
3502
void Core::dvdnavDown() {
 
3503
        qDebug("Core::dvdnavDown");
 
3504
        tellmp("dvdnav down");
 
3505
}
 
3506
 
 
3507
void Core::dvdnavLeft() {
 
3508
        qDebug("Core::dvdnavLeft");
 
3509
        tellmp("dvdnav left");
 
3510
}
 
3511
 
 
3512
void Core::dvdnavRight() {
 
3513
        qDebug("Core::dvdnavRight");
 
3514
        tellmp("dvdnav right");
 
3515
}
 
3516
 
 
3517
void Core::dvdnavMenu() {
 
3518
        qDebug("Core::dvdnavMenu");
 
3519
        tellmp("dvdnav menu");
 
3520
}
 
3521
 
 
3522
void Core::dvdnavSelect() {
 
3523
        qDebug("Core::dvdnavSelect");
 
3524
        tellmp("dvdnav select");
 
3525
}
 
3526
 
 
3527
void Core::dvdnavPrev() {
 
3528
        qDebug("Core::dvdnavPrev");
 
3529
        tellmp("dvdnav prev");
 
3530
}
 
3531
 
 
3532
void Core::dvdnavMouse() {
 
3533
        qDebug("Core::dvdnavMouse");
 
3534
 
 
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");
 
3539
        }
 
3540
}
 
3541
#endif
 
3542
 
 
3543
void Core::displayMessage(QString text) {
 
3544
        qDebug("Core::displayMessage");
 
3545
        emit showMessage(text);
 
3546
 
 
3547
        if ((pref->fullscreen) && (state() != Paused)) {
 
3548
                tellmp("osd_show_text \"" + text + "\" 3000 1");
 
3549
        }
 
3550
}
 
3551
 
 
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);
 
3556
 
 
3557
        if (MplayerVersion::isMplayerAtLeast(27665)) {
 
3558
                tellmp( "pausing_keep_force osd_show_text \"" + text + "\" 3000 1");
 
3559
        }
 
3560
        else
 
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");
 
3565
        }
 
3566
 
 
3567
        emit showMessage(text);
 
3568
}
 
3569
 
 
3570
void Core::displayUpdatingFontCache() {
 
3571
        qDebug("Core::displayUpdatingFontCache");
 
3572
        emit showMessage( tr("Updating the font cache. This may take some seconds...") );
 
3573
}
 
3574
 
 
3575
void Core::gotWindowResolution(int w, int h) {
 
3576
        qDebug("Core::gotWindowResolution: %d, %d", w, h);
 
3577
        //double aspect = (double) w/h;
 
3578
 
 
3579
        if (pref->use_mplayer_window) {
 
3580
                emit noVideo();
 
3581
        } else {
 
3582
                if ((pref->resize_method==Preferences::Afterload) && (we_are_restarting)) {
 
3583
                        // Do nothing
 
3584
                } else {
 
3585
                        emit needResize(w,h);
 
3586
                }
 
3587
        }
 
3588
 
 
3589
        mset.win_width = w;
 
3590
        mset.win_height = h;
 
3591
 
 
3592
        //Override aspect ratio, is this ok?
 
3593
        //mdat.video_aspect = mset.win_aspect();
 
3594
 
 
3595
        mplayerwindow->setResolution( w, h );
 
3596
        mplayerwindow->setAspect( mset.win_aspect() );
 
3597
}
 
3598
 
 
3599
void Core::gotNoVideo() {
 
3600
        // File has no video (a sound file)
 
3601
 
 
3602
        // Reduce size of window
 
3603
        /*
 
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 );
 
3608
        */
 
3609
        //mplayerwindow->showLogo(TRUE);
 
3610
        emit noVideo();
 
3611
}
 
3612
 
 
3613
void Core::gotVO(QString vo) {
 
3614
        qDebug("Core::gotVO: '%s'", vo.toUtf8().data() );
 
3615
 
 
3616
        if ( pref->vo.isEmpty()) {
 
3617
                qDebug("Core::gotVO: saving vo");
 
3618
                pref->vo = vo;
 
3619
        }
 
3620
}
 
3621
 
 
3622
void Core::gotAO(QString ao) {
 
3623
        qDebug("Core::gotAO: '%s'", ao.toUtf8().data() );
 
3624
 
 
3625
        if ( pref->ao.isEmpty()) {
 
3626
                qDebug("Core::gotAO: saving ao");
 
3627
                pref->ao = ao;
 
3628
        }
 
3629
}
 
3630
 
 
3631
void Core::streamTitleAndUrlChanged(QString title, QString url) {
 
3632
        mdat.stream_title = title;
 
3633
        mdat.stream_url = url;
 
3634
        emit mediaInfoChanged();
 
3635
}
 
3636
 
 
3637
//!  Called when the state changes
 
3638
void Core::watchState(Core::State state) {
 
3639
        if ((state == Playing) && (change_volume_after_unpause)) 
 
3640
        {
 
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;
 
3645
        }
 
3646
}
 
3647
 
 
3648
void Core::checkIfVideoIsHD() {
 
3649
        qDebug("Core::checkIfVideoIsHD");
 
3650
 
 
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");
 
3658
                                restartPlay();
 
3659
                        }
 
3660
                }
 
3661
        } else {
 
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.
 
3665
        }
 
3666
}
 
3667
 
 
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"
 
3670
#endif
 
3671
 
 
3672
#if DELAYED_AUDIO_SETUP_ON_STARTUP
 
3673
void Core::initAudioTrack() {
 
3674
        qDebug("Core::initAudioTrack");
 
3675
 
 
3676
        // First audio if none selected
 
3677
        if ( (mset.current_audio_id == MediaSettings::NoneSelected) && 
 
3678
         (mdat.audios.numItems() > 0) ) 
 
3679
        {
 
3680
                // Don't set mset.current_audio_id here! changeAudio will do. 
 
3681
                // Otherwise changeAudio will do nothing.
 
3682
 
 
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();
 
3686
                }
 
3687
 
 
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;
 
3692
                }
 
3693
 
 
3694
                changeAudio( audio );
 
3695
        }
 
3696
}
 
3697
#endif
 
3698
 
 
3699
#if NOTIFY_AUDIO_CHANGES
 
3700
void Core::initAudioTrack(const Tracks & audios) {
 
3701
        qDebug("Core::initAudioTrack");
 
3702
 
 
3703
        qDebug("Core::initAudioTrack: num_items: %d", mdat.audios.numItems());
 
3704
 
 
3705
        bool restore_audio = ((mdat.audios.numItems() > 0) || 
 
3706
                          (mset.current_audio_id != MediaSettings::NoneSelected));
 
3707
 
 
3708
        mdat.audios = audios;
 
3709
 
 
3710
        qDebug("Core::initAudioTrack: list of audios:");
 
3711
        mdat.audios.list();
 
3712
 
 
3713
        initializeMenus();
 
3714
 
 
3715
        if (!restore_audio) {
 
3716
                // Select initial track
 
3717
                qDebug("Core::initAudioTrack: selecting initial track");
 
3718
 
 
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();
 
3722
                }
 
3723
 
 
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;
 
3728
                }
 
3729
 
 
3730
                changeAudio( audio );
 
3731
        } else {
 
3732
                // Try to restore previous audio track
 
3733
                qDebug("Core::initAudioTrack: restoring audio");
 
3734
                // Nothing to do, the audio is already set with -aid
 
3735
        }
 
3736
 
 
3737
        updateWidgets();
 
3738
 
 
3739
        emit audioTracksChanged();
 
3740
}
 
3741
#endif
 
3742
 
 
3743
#if NOTIFY_SUB_CHANGES
 
3744
void Core::initSubtitleTrack(const SubTracks & subs) {
 
3745
        qDebug("Core::initSubtitleTrack");
 
3746
 
 
3747
        qDebug("Core::initSubtitleTrack: num_items: %d", mdat.subs.numItems());
 
3748
 
 
3749
        bool restore_subs = ((mdat.subs.numItems() > 0) || 
 
3750
                         (mset.current_sub_id != MediaSettings::NoneSelected));
 
3751
 
 
3752
        // Save current sub
 
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)) 
 
3758
                {
 
3759
                        previous_sub_type = mdat.subs.itemAt(mset.current_sub_id).type();
 
3760
                        previous_sub_id = mdat.subs.itemAt(mset.current_sub_id).ID();
 
3761
                }
 
3762
        }
 
3763
        qDebug("Core::initSubtitleTrack: previous subtitle: type: %d id: %d", previous_sub_type, previous_sub_id);
 
3764
 
 
3765
        mdat.subs = subs;
 
3766
 
 
3767
        qDebug("Core::initSubtitleTrack: list of subtitles:");
 
3768
        mdat.subs.list();
 
3769
 
 
3770
        initializeMenus();
 
3771
 
 
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;
 
3776
        }
 
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;
 
3781
                
 
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 );
 
3788
                                goto end;
 
3789
                        }
 
3790
                }
 
3791
        }
 
3792
 
 
3793
        if (!restore_subs) {
 
3794
                // Select initial track
 
3795
                qDebug("Core::initSubtitleTrack: selecting initial track");
 
3796
 
 
3797
                if (!pref->autoload_sub) {
 
3798
                        changeSubtitle( MediaSettings::SubNone );
 
3799
                } else {
 
3800
                        //Select first subtitle
 
3801
                        int sub = mdat.subs.selectOne( pref->subtitle_lang, pref->initial_subtitle_track-1 );
 
3802
                        changeSubtitle( sub );
 
3803
                }
 
3804
        } else {
 
3805
                // Try to restore previous subtitle track
 
3806
                qDebug("Core::initSubtitleTrack: restoring subtitle");
 
3807
 
 
3808
                if (mset.current_sub_id == MediaSettings::SubNone) {
 
3809
                        changeSubtitle( MediaSettings::SubNone );
 
3810
                }
 
3811
                else
 
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) {
 
3818
                                        item = sub_item;
 
3819
                                        qDebug("Core::initSubtitleTrack: previous subtitle found: %d", sub_item);
 
3820
                                }
 
3821
                        }
 
3822
                        if (item > -1) {
 
3823
                                changeSubtitle(item );
 
3824
                        } else {
 
3825
                                qDebug("Core::initSubtitleTrack: previous subtitle not found!");
 
3826
                        }
 
3827
                }
 
3828
        }
 
3829
end:
 
3830
        updateWidgets();
 
3831
}
 
3832
 
 
3833
void Core::setSubtitleTrackAgain(const SubTracks &) {
 
3834
        qDebug("Core::setSubtitleTrackAgain");
 
3835
        changeSubtitle( mset.current_sub_id );
 
3836
}
 
3837
#endif
 
3838
 
 
3839
#if DVDNAV_SUPPORT
 
3840
void Core::dvdTitleChanged(int title) {
 
3841
        qDebug("Core::dvdTitleChanged: %d", title);
 
3842
}
 
3843
 
 
3844
void Core::durationChanged(double length) {
 
3845
        qDebug("Core::durationChanged: %f", length);
 
3846
        mdat.duration = length;
 
3847
}
 
3848
 
 
3849
void Core::askForInfo() {
 
3850
        if ((state() == Playing) && (mdat.filename.startsWith("dvdnav:"))) {
 
3851
                tellmp( pausing_prefix() + " get_property length");
 
3852
        }
 
3853
}
 
3854
 
 
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()));
 
3860
                }
 
3861
        }
 
3862
}
 
3863
#endif
 
3864
 
 
3865
QString Core::pausing_prefix() {
 
3866
        qDebug("Core::pausing_prefix");
 
3867
 
 
3868
        if ( (pref->use_pausing_keep_force) && 
 
3869
         (MplayerVersion::isMplayerAtLeast(27665)) ) 
 
3870
        {
 
3871
                return "pausing_keep_force";
 
3872
        } else {
 
3873
                return "pausing_keep";
 
3874
        }
 
3875
}
 
3876
 
 
3877
#include "moc_core.cpp"