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

« back to all changes in this revision

Viewing changes to src/mplayerprocess.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 "mplayerprocess.h"
 
20
#include <QRegExp>
 
21
#include <QStringList>
 
22
#include <QApplication>
 
23
 
 
24
#include "global.h"
 
25
#include "preferences.h"
 
26
#include "mplayerversion.h"
 
27
#include "helper.h"
 
28
 
 
29
using namespace Global;
 
30
 
 
31
MplayerProcess::MplayerProcess(QObject * parent) : MyProcess(parent) 
 
32
{
 
33
#if NOTIFY_SUB_CHANGES
 
34
        qRegisterMetaType<SubTracks>("SubTracks");
 
35
#endif
 
36
 
 
37
#if NOTIFY_AUDIO_CHANGES
 
38
        qRegisterMetaType<Tracks>("Tracks");
 
39
#endif
 
40
 
 
41
        connect( this, SIGNAL(lineAvailable(QByteArray)),
 
42
                         this, SLOT(parseLine(QByteArray)) );
 
43
 
 
44
        connect( this, SIGNAL(finished(int,QProcess::ExitStatus)), 
 
45
             this, SLOT(processFinished(int,QProcess::ExitStatus)) );
 
46
 
 
47
        connect( this, SIGNAL(error(QProcess::ProcessError)),
 
48
             this, SLOT(gotError(QProcess::ProcessError)) );
 
49
 
 
50
        notified_mplayer_is_running = false;
 
51
        last_sub_id = -1;
 
52
        mplayer_svn = -1; // Not found yet
 
53
}
 
54
 
 
55
MplayerProcess::~MplayerProcess() {
 
56
}
 
57
 
 
58
bool MplayerProcess::start() {
 
59
        md.reset();
 
60
        notified_mplayer_is_running = false;
 
61
        last_sub_id = -1;
 
62
        mplayer_svn = -1; // Not found yet
 
63
        received_end_of_file = false;
 
64
 
 
65
#if NOTIFY_SUB_CHANGES
 
66
        subs.clear();
 
67
        subtitle_info_received = false;
 
68
        subtitle_info_changed = false;
 
69
#endif
 
70
 
 
71
#if NOTIFY_AUDIO_CHANGES
 
72
        audios.clear();
 
73
        audio_info_changed = false;
 
74
#endif
 
75
 
 
76
#if GENERIC_CHAPTER_SUPPORT
 
77
        dvd_current_title = -1;
 
78
#endif
 
79
 
 
80
        MyProcess::start();
 
81
        return waitForStarted();
 
82
}
 
83
 
 
84
void MplayerProcess::writeToStdin(QString text) {
 
85
        if (isRunning()) {
 
86
                //qDebug("MplayerProcess::writeToStdin");
 
87
                write( text.toLocal8Bit() + "\n");
 
88
        } else {
 
89
                qWarning("MplayerProcess::writeToStdin: process not running");
 
90
        }
 
91
}
 
92
 
 
93
static QRegExp rx_av("^[AV]: *([0-9,:.-]+)");
 
94
static QRegExp rx_frame("^[AV]:.* (\\d+)\\/.\\d+");// [0-9,.]+");
 
95
static QRegExp rx("^(.*)=(.*)");
 
96
#if !NOTIFY_AUDIO_CHANGES
 
97
static QRegExp rx_audio_mat("^ID_AID_(\\d+)_(LANG|NAME)=(.*)");
 
98
#endif
 
99
static QRegExp rx_video("^ID_VID_(\\d+)_(LANG|NAME)=(.*)");
 
100
static QRegExp rx_title("^ID_DVD_TITLE_(\\d+)_(LENGTH|CHAPTERS|ANGLES)=(.*)");
 
101
static QRegExp rx_winresolution("^VO: \\[(.*)\\] (\\d+)x(\\d+) => (\\d+)x(\\d+)");
 
102
static QRegExp rx_ao("^AO: \\[(.*)\\]");
 
103
static QRegExp rx_paused("^ID_PAUSED");
 
104
#if !CHECK_VIDEO_CODEC_FOR_NO_VIDEO
 
105
static QRegExp rx_novideo("^Video: no video");
 
106
#endif
 
107
static QRegExp rx_cache("^Cache fill:.*");
 
108
static QRegExp rx_create_index("^Generating Index:.*");
 
109
static QRegExp rx_play("^Starting playback...");
 
110
static QRegExp rx_connecting("^Connecting to .*");
 
111
static QRegExp rx_resolving("^Resolving .*");
 
112
static QRegExp rx_screenshot("^\\*\\*\\* screenshot '(.*)'");
 
113
static QRegExp rx_endoffile("^Exiting... \\(End of file\\)|^ID_EXIT=EOF");
 
114
static QRegExp rx_mkvchapters("\\[mkv\\] Chapter (\\d+) from");
 
115
static QRegExp rx_aspect2("^Movie-Aspect is ([0-9,.]+):1");
 
116
static QRegExp rx_fontcache("^\\[ass\\] Updating font cache|^\\[ass\\] Init");
 
117
#if DVDNAV_SUPPORT
 
118
static QRegExp rx_dvdnav_switch_title("^DVDNAV, switched to title: (\\d+)");
 
119
static QRegExp rx_dvdnav_length("^ANS_length=(.*)");
 
120
#endif
 
121
 
 
122
// VCD
 
123
static QRegExp rx_vcd("^ID_VCD_TRACK_(\\d+)_MSF=(.*)");
 
124
 
 
125
// Audio CD
 
126
static QRegExp rx_cdda("^ID_CDDA_TRACK_(\\d+)_MSF=(.*)");
 
127
 
 
128
//Subtitles
 
129
static QRegExp rx_subtitle("^ID_(SUBTITLE|FILE_SUB|VOBSUB)_ID=(\\d+)");
 
130
static QRegExp rx_sid("^ID_(SID|VSID)_(\\d+)_(LANG|NAME)=(.*)");
 
131
static QRegExp rx_subtitle_file("^ID_FILE_SUB_FILENAME=(.*)");
 
132
 
 
133
// Audio
 
134
#if NOTIFY_AUDIO_CHANGES
 
135
static QRegExp rx_audio("^ID_AUDIO_ID=(\\d+)");
 
136
static QRegExp rx_audio_info("^ID_AID_(\\d+)_(LANG|NAME)=(.*)");
 
137
#endif
 
138
 
 
139
//Clip info
 
140
static QRegExp rx_clip_name("^ (name|title): (.*)", Qt::CaseInsensitive);
 
141
static QRegExp rx_clip_artist("^ artist: (.*)", Qt::CaseInsensitive);
 
142
static QRegExp rx_clip_author("^ author: (.*)", Qt::CaseInsensitive);
 
143
static QRegExp rx_clip_album("^ album: (.*)", Qt::CaseInsensitive);
 
144
static QRegExp rx_clip_genre("^ genre: (.*)", Qt::CaseInsensitive);
 
145
static QRegExp rx_clip_date("^ (creation date|year): (.*)", Qt::CaseInsensitive);
 
146
static QRegExp rx_clip_track("^ track: (.*)", Qt::CaseInsensitive);
 
147
static QRegExp rx_clip_copyright("^ copyright: (.*)", Qt::CaseInsensitive);
 
148
static QRegExp rx_clip_comment("^ comment: (.*)", Qt::CaseInsensitive);
 
149
static QRegExp rx_clip_software("^ software: (.*)", Qt::CaseInsensitive);
 
150
 
 
151
static QRegExp rx_stream_title("^.* StreamTitle='(.*)';StreamUrl='(.*)';");
 
152
 
 
153
 
 
154
void MplayerProcess::parseLine(QByteArray ba) {
 
155
        //qDebug("MplayerProcess::parseLine: '%s'", ba.data() );
 
156
 
 
157
        QString tag;
 
158
        QString value;
 
159
 
 
160
#if COLOR_OUTPUT_SUPPORT
 
161
    QString line = Helper::stripColorsTags(QString::fromLocal8Bit(ba));
 
162
#else
 
163
        QString line = QString::fromLocal8Bit(ba);
 
164
#endif
 
165
 
 
166
        // Parse A: V: line
 
167
        //qDebug("%s", line.toUtf8().data());
 
168
    if (rx_av.indexIn(line) > -1) {
 
169
                double sec = rx_av.cap(1).toDouble();
 
170
                //qDebug("cap(1): '%s'", rx_av.cap(1).toUtf8().data() );
 
171
                //qDebug("sec: %f", sec);
 
172
 
 
173
#if NOTIFY_SUB_CHANGES
 
174
                if (notified_mplayer_is_running) {
 
175
                        if (subtitle_info_changed) {
 
176
                                qDebug("MplayerProcess::parseLine: subtitle_info_changed");
 
177
                                subtitle_info_changed = false;
 
178
                                subtitle_info_received = false;
 
179
                                emit subtitleInfoChanged(subs);
 
180
                        }
 
181
                        if (subtitle_info_received) {
 
182
                                qDebug("MplayerProcess::parseLine: subtitle_info_received");
 
183
                                subtitle_info_received = false;
 
184
                                emit subtitleInfoReceivedAgain(subs);
 
185
                        }
 
186
                }
 
187
#endif
 
188
 
 
189
#if NOTIFY_AUDIO_CHANGES
 
190
                if (notified_mplayer_is_running) {
 
191
                        if (audio_info_changed) {
 
192
                                qDebug("MplayerProcess::parseLine: audio_info_changed");
 
193
                                audio_info_changed = false;
 
194
                                emit audioInfoChanged(audios);
 
195
                        }
 
196
                }
 
197
#endif
 
198
 
 
199
                if (!notified_mplayer_is_running) {
 
200
                        qDebug("MplayerProcess::parseLine: starting sec: %f", sec);
 
201
#if GENERIC_CHAPTER_SUPPORT
 
202
                        if ( (md.chapters <= 0) && (dvd_current_title > 0) && 
 
203
                 (md.titles.find(dvd_current_title) != -1) )
 
204
                        {
 
205
                                int idx = md.titles.find(dvd_current_title);
 
206
                                md.chapters = md.titles.itemAt(idx).chapters();
 
207
                                qDebug("MplayerProcess::parseLine: setting chapters to %d", md.chapters);
 
208
                        }
 
209
#endif
 
210
 
 
211
#if CHECK_VIDEO_CODEC_FOR_NO_VIDEO
 
212
                        // Another way to find out if there's no video
 
213
                        if (md.video_codec.isEmpty()) {
 
214
                                md.novideo = true;
 
215
                                emit receivedNoVideo();
 
216
                        }
 
217
#endif
 
218
 
 
219
                        emit receivedStartingTime(sec);
 
220
                        emit mplayerFullyLoaded();
 
221
 
 
222
                        emit receivedCurrentFrame(0); // Ugly hack: set the frame counter to 0
 
223
 
 
224
                        notified_mplayer_is_running = true;
 
225
                }
 
226
                
 
227
            emit receivedCurrentSec( sec );
 
228
 
 
229
                // Check for frame
 
230
        if (rx_frame.indexIn(line) > -1) {
 
231
                        int frame = rx_frame.cap(1).toInt();
 
232
                        //qDebug(" frame: %d", frame);
 
233
                        emit receivedCurrentFrame(frame);
 
234
                }
 
235
        }
 
236
        else {
 
237
                // Emulates mplayer version in Ubuntu:
 
238
                //if (line.startsWith("MPlayer 1.0rc1")) line = "MPlayer 2:1.0~rc1-0ubuntu13.1 (C) 2000-2006 MPlayer Team";
 
239
 
 
240
                // Emulates unknown version
 
241
                //if (line.startsWith("MPlayer SVN")) line = "MPlayer lalksklsjjakksja";
 
242
 
 
243
                emit lineAvailable(line);
 
244
 
 
245
                // Parse other things
 
246
                qDebug("MplayerProcess::parseLine: '%s'", line.toUtf8().data() );
 
247
 
 
248
                // Screenshot
 
249
                if (rx_screenshot.indexIn(line) > -1) {
 
250
                        QString shot = rx_screenshot.cap(1);
 
251
                        qDebug("MplayerProcess::parseLine: screenshot: '%s'", shot.toUtf8().data());
 
252
                        emit receivedScreenshot( shot );
 
253
                }
 
254
                else
 
255
 
 
256
                // End of file
 
257
                if (rx_endoffile.indexIn(line) > -1)  {
 
258
                        qDebug("MplayerProcess::parseLine: detected end of file");
 
259
                        if (!received_end_of_file) {
 
260
                                // In case of playing VCDs or DVDs, maybe the first title
 
261
                // is not playable, so the GUI doesn't get the info about
 
262
                    // available titles. So if we received the end of file
 
263
                // first let's pretend the file has started so the GUI can have
 
264
                    // the data.
 
265
                                if ( !notified_mplayer_is_running) {
 
266
                                        emit mplayerFullyLoaded();
 
267
                                }
 
268
 
 
269
                                //emit receivedEndOfFile();
 
270
                                // Send signal once the process is finished, not now!
 
271
                                received_end_of_file = true;
 
272
                        }
 
273
                }
 
274
                else
 
275
 
 
276
                // Window resolution
 
277
                if (rx_winresolution.indexIn(line) > -1) {
 
278
                        /*
 
279
                        md.win_width = rx_winresolution.cap(4).toInt();
 
280
                        md.win_height = rx_winresolution.cap(5).toInt();
 
281
                    md.video_aspect = (double) md.win_width / md.win_height;
 
282
                        */
 
283
 
 
284
                        int w = rx_winresolution.cap(4).toInt();
 
285
                        int h = rx_winresolution.cap(5).toInt();
 
286
 
 
287
                        emit receivedVO( rx_winresolution.cap(1) );
 
288
                        emit receivedWindowResolution( w, h );
 
289
                        //emit mplayerFullyLoaded();
 
290
                }
 
291
                else
 
292
 
 
293
#if !CHECK_VIDEO_CODEC_FOR_NO_VIDEO
 
294
                // No video
 
295
                if (rx_novideo.indexIn(line) > -1) {
 
296
                        md.novideo = TRUE;
 
297
                        emit receivedNoVideo();
 
298
                        //emit mplayerFullyLoaded();
 
299
                }
 
300
                else
 
301
#endif
 
302
 
 
303
                // Pause
 
304
                if (rx_paused.indexIn(line) > -1) {
 
305
                        emit receivedPause();
 
306
                }
 
307
 
 
308
                // Stream title
 
309
                if (rx_stream_title.indexIn(line) > -1) {
 
310
                        QString s = rx_stream_title.cap(1);
 
311
                        QString url = rx_stream_title.cap(2);
 
312
                        qDebug("MplayerProcess::parseLine: stream_title: '%s'", s.toUtf8().data());
 
313
                        qDebug("MplayerProcess::parseLine: stream_url: '%s'", url.toUtf8().data());
 
314
                        md.stream_title = s;
 
315
                        md.stream_url = url;
 
316
                        emit receivedStreamTitleAndUrl( s, url );
 
317
                }
 
318
 
 
319
#if NOTIFY_SUB_CHANGES
 
320
                // Subtitles
 
321
                if ((rx_subtitle.indexIn(line) > -1) || (rx_sid.indexIn(line) > -1) || (rx_subtitle_file.indexIn(line) > -1)) {
 
322
                        int r = subs.parse(line);
 
323
                        subtitle_info_received = true;
 
324
                        subtitle_info_changed = ((r == SubTracks::SubtitleAdded) || (r == SubTracks::SubtitleChanged));
 
325
                }
 
326
#endif
 
327
 
 
328
#if NOTIFY_AUDIO_CHANGES
 
329
                // Audio
 
330
                if (rx_audio.indexIn(line) > -1) {
 
331
                        int ID = rx_audio.cap(1).toInt();
 
332
                        qDebug("MplayerProcess::parseLine: ID_AUDIO_ID: %d", ID);
 
333
                        if (audios.find(ID) == -1) audio_info_changed = true;
 
334
                        audios.addID( ID );
 
335
                }
 
336
 
 
337
                if (rx_audio_info.indexIn(line) > -1) {
 
338
                        int ID = rx_audio_info.cap(1).toInt();
 
339
                        QString lang = rx_audio_info.cap(3);
 
340
                        QString t = rx_audio_info.cap(2);
 
341
                        qDebug("MplayerProcess::parseLine: Audio: ID: %d, Lang: '%s' Type: '%s'", 
 
342
                    ID, lang.toUtf8().data(), t.toUtf8().data());
 
343
 
 
344
                        int idx = audios.find(ID);
 
345
                        if (idx == -1) {
 
346
                                qDebug("MplayerProcess::parseLine: audio %d doesn't exist, adding it", ID);
 
347
 
 
348
                                audio_info_changed = true;
 
349
                                if ( t == "NAME" ) 
 
350
                                        audios.addName(ID, lang);
 
351
                                else
 
352
                                        audios.addLang(ID, lang);
 
353
                        } else {
 
354
                                qDebug("MplayerProcess::parseLine: audio %d exists, modifing it", ID);
 
355
 
 
356
                                if (t == "NAME") {
 
357
                                        //qDebug("MplayerProcess::parseLine: name of audio %d: %s", ID, audios.itemAt(idx).name().toUtf8().constData());
 
358
                                        if (audios.itemAt(idx).name() != lang) {
 
359
                                                audio_info_changed = true;
 
360
                                                audios.addName(ID, lang);
 
361
                                        }
 
362
                                } else {
 
363
                                        //qDebug("MplayerProcess::parseLine: language of audio %d: %s", ID, audios.itemAt(idx).lang().toUtf8().constData());
 
364
                                        if (audios.itemAt(idx).lang() != lang) {
 
365
                                                audio_info_changed = true;
 
366
                                                audios.addLang(ID, lang);
 
367
                                        }
 
368
                                }
 
369
                        }
 
370
                }
 
371
#endif
 
372
 
 
373
#if DVDNAV_SUPPORT
 
374
                if (rx_dvdnav_switch_title.indexIn(line) > -1) {
 
375
                        int title = rx_dvdnav_switch_title.cap(1).toInt();
 
376
                        qDebug("MplayerProcess::parseLine: dvd title: %d", title);
 
377
                        emit receivedDVDTitle(title);
 
378
                }
 
379
                if (rx_dvdnav_length.indexIn(line) > -1) {
 
380
                        double length = rx_dvdnav_length.cap(1).toDouble();
 
381
                        qDebug("MplayerProcess::parseLine: length: %f", length);
 
382
                        if (length != md.duration) {
 
383
                                md.duration = length;
 
384
                                emit receivedDuration(length);
 
385
                        }
 
386
                }
 
387
#endif
 
388
 
 
389
                // The following things are not sent when the file has started to play
 
390
                // (or if sent, smplayer will ignore anyway...)
 
391
                // So not process anymore, if video is playing to save some time
 
392
                if (notified_mplayer_is_running) {
 
393
                        return;
 
394
                }
 
395
 
 
396
                if ( (mplayer_svn == -1) && (line.startsWith("MPlayer ")) ) {
 
397
                        mplayer_svn = MplayerVersion::mplayerVersion(line);
 
398
                        qDebug("MplayerProcess::parseLine: MPlayer SVN: %d", mplayer_svn);
 
399
                        if (mplayer_svn <= 0) {
 
400
                                qWarning("MplayerProcess::parseLine: couldn't parse mplayer version!");
 
401
                                emit failedToParseMplayerVersion(line);
 
402
                        }
 
403
                }
 
404
 
 
405
#if !NOTIFY_SUB_CHANGES
 
406
                // Subtitles
 
407
                if (rx_subtitle.indexIn(line) > -1) {
 
408
                        md.subs.parse(line);
 
409
                }
 
410
                else
 
411
                if (rx_sid.indexIn(line) > -1) {
 
412
                        md.subs.parse(line);
 
413
                }
 
414
                else
 
415
                if (rx_subtitle_file.indexIn(line) > -1) {
 
416
                        md.subs.parse(line);
 
417
                }
 
418
#endif
 
419
                // AO
 
420
                if (rx_ao.indexIn(line) > -1) {
 
421
                        emit receivedAO( rx_ao.cap(1) );
 
422
                }
 
423
                else
 
424
 
 
425
#if !NOTIFY_AUDIO_CHANGES
 
426
                // Matroska audio
 
427
                if (rx_audio_mat.indexIn(line) > -1) {
 
428
                        int ID = rx_audio_mat.cap(1).toInt();
 
429
                        QString lang = rx_audio_mat.cap(3);
 
430
                        QString t = rx_audio_mat.cap(2);
 
431
                        qDebug("MplayerProcess::parseLine: Audio: ID: %d, Lang: '%s' Type: '%s'", 
 
432
                    ID, lang.toUtf8().data(), t.toUtf8().data());
 
433
 
 
434
                        if ( t == "NAME" ) 
 
435
                                md.audios.addName(ID, lang);
 
436
                        else
 
437
                                md.audios.addLang(ID, lang);
 
438
                }
 
439
                else
 
440
#endif
 
441
 
 
442
                // Video tracks
 
443
                if (rx_video.indexIn(line) > -1) {
 
444
                        int ID = rx_video.cap(1).toInt();
 
445
                        QString lang = rx_video.cap(3);
 
446
                        QString t = rx_video.cap(2);
 
447
                        qDebug("MplayerProcess::parseLine: Video: ID: %d, Lang: '%s' Type: '%s'", 
 
448
                    ID, lang.toUtf8().data(), t.toUtf8().data());
 
449
 
 
450
                        if ( t == "NAME" ) 
 
451
                                md.videos.addName(ID, lang);
 
452
                        else
 
453
                                md.videos.addLang(ID, lang);
 
454
                }
 
455
                else
 
456
 
 
457
                // Matroshka chapters
 
458
                if (rx_mkvchapters.indexIn(line)!=-1) {
 
459
                        int c = rx_mkvchapters.cap(1).toInt();
 
460
                        qDebug("MplayerProcess::parseLine: mkv chapters: %d", c);
 
461
#if GENERIC_CHAPTER_SUPPORT
 
462
                        if ((c+1) > md.chapters) {
 
463
                                md.chapters = c+1;
 
464
                                qDebug("MplayerProcess::parseLine: chapters set to: %d", md.chapters);
 
465
                        }
 
466
#else
 
467
                        if ((c+1) > md.mkv_chapters) {
 
468
                                md.mkv_chapters = c+1;
 
469
                                qDebug("MplayerProcess::parseLine: mkv_chapters set to: %d", md.mkv_chapters);
 
470
                        }
 
471
#endif
 
472
                }
 
473
                else
 
474
 
 
475
                // VCD titles
 
476
                if (rx_vcd.indexIn(line) > -1 ) {
 
477
                        int ID = rx_vcd.cap(1).toInt();
 
478
                        QString length = rx_vcd.cap(2);
 
479
                        //md.titles.addID( ID );
 
480
                        md.titles.addName( ID, length );
 
481
                }
 
482
                else
 
483
 
 
484
                // Audio CD titles
 
485
                if (rx_cdda.indexIn(line) > -1 ) {
 
486
                        int ID = rx_cdda.cap(1).toInt();
 
487
                        QString length = rx_cdda.cap(2);
 
488
                        double duration = 0;
 
489
                        QRegExp r("(\\d+):(\\d+):(\\d+)");
 
490
                        if ( r.indexIn(length) > -1 ) {
 
491
                                duration = r.cap(1).toInt() * 60;
 
492
                                duration += r.cap(2).toInt();
 
493
                        }
 
494
                        md.titles.addID( ID );
 
495
                        /*
 
496
                        QString name = QString::number(ID) + " (" + length + ")";
 
497
                        md.titles.addName( ID, name );
 
498
                        */
 
499
                        md.titles.addDuration( ID, duration );
 
500
                }
 
501
                else
 
502
 
 
503
                // DVD titles
 
504
                if (rx_title.indexIn(line) > -1) {
 
505
                        int ID = rx_title.cap(1).toInt();
 
506
                        QString t = rx_title.cap(2);
 
507
 
 
508
                        if (t=="LENGTH") {
 
509
                                double length = rx_title.cap(3).toDouble();
 
510
                                qDebug("MplayerProcess::parseLine: Title: ID: %d, Length: '%f'", ID, length);
 
511
                                md.titles.addDuration(ID, length);
 
512
                        } 
 
513
                        else
 
514
                        if (t=="CHAPTERS") {
 
515
                                int chapters = rx_title.cap(3).toInt();
 
516
                                qDebug("MplayerProcess::parseLine: Title: ID: %d, Chapters: '%d'", ID, chapters);
 
517
                                md.titles.addChapters(ID, chapters);
 
518
                        }
 
519
                        else
 
520
                        if (t=="ANGLES") {
 
521
                                int angles = rx_title.cap(3).toInt();
 
522
                                qDebug("MplayerProcess::parseLine: Title: ID: %d, Angles: '%d'", ID, angles);
 
523
                                md.titles.addAngles(ID, angles);
 
524
                        }
 
525
                }
 
526
                else
 
527
 
 
528
                // Catch cache messages
 
529
                if (rx_cache.indexIn(line) > -1) {
 
530
                        emit receivedCacheMessage(line);
 
531
                }
 
532
                else
 
533
 
 
534
                // Creating index
 
535
                if (rx_create_index.indexIn(line) > -1) {
 
536
                        emit receivedCreatingIndex(line);
 
537
                }
 
538
                else
 
539
 
 
540
                // Catch connecting message
 
541
                if (rx_connecting.indexIn(line) > -1) {
 
542
                        emit receivedConnectingToMessage(line);
 
543
                }
 
544
                else
 
545
 
 
546
                // Catch resolving message
 
547
                if (rx_resolving.indexIn(line) > -1) {
 
548
                        emit receivedResolvingMessage(line);
 
549
                }
 
550
                else
 
551
 
 
552
                // Aspect ratio for old versions of mplayer
 
553
                if (rx_aspect2.indexIn(line) > -1) {
 
554
                        md.video_aspect = rx_aspect2.cap(1).toDouble();
 
555
                        qDebug("MplayerProcess::parseLine: md.video_aspect set to %f", md.video_aspect);
 
556
                }
 
557
                else
 
558
 
 
559
                // Clip info
 
560
 
 
561
                //QString::trimmed() is used for removing leading and trailing whitespaces
 
562
                //Some .mp3 files contain tags with starting and ending whitespaces
 
563
                //Unfortunately MPlayer gives us leading and trailing whitespaces, Winamp for example doesn't show them
 
564
 
 
565
                // Name
 
566
                if (rx_clip_name.indexIn(line) > -1) {
 
567
                        QString s = rx_clip_name.cap(2).trimmed();
 
568
                        qDebug("MplayerProcess::parseLine: clip_name: '%s'", s.toUtf8().data());
 
569
                        md.clip_name = s;
 
570
                }
 
571
                else
 
572
 
 
573
                // Artist
 
574
                if (rx_clip_artist.indexIn(line) > -1) {
 
575
                        QString s = rx_clip_artist.cap(1).trimmed();
 
576
                        qDebug("MplayerProcess::parseLine: clip_artist: '%s'", s.toUtf8().data());
 
577
                        md.clip_artist = s;
 
578
                }
 
579
                else
 
580
 
 
581
                // Author
 
582
                if (rx_clip_author.indexIn(line) > -1) {
 
583
                        QString s = rx_clip_author.cap(1).trimmed();
 
584
                        qDebug("MplayerProcess::parseLine: clip_author: '%s'", s.toUtf8().data());
 
585
                        md.clip_author = s;
 
586
                }
 
587
                else
 
588
 
 
589
                // Album
 
590
                if (rx_clip_album.indexIn(line) > -1) {
 
591
                        QString s = rx_clip_album.cap(1).trimmed();
 
592
                        qDebug("MplayerProcess::parseLine: clip_album: '%s'", s.toUtf8().data());
 
593
                        md.clip_album = s;
 
594
                }
 
595
                else
 
596
 
 
597
                // Genre
 
598
                if (rx_clip_genre.indexIn(line) > -1) {
 
599
                        QString s = rx_clip_genre.cap(1).trimmed();
 
600
                        qDebug("MplayerProcess::parseLine: clip_genre: '%s'", s.toUtf8().data());
 
601
                        md.clip_genre = s;
 
602
                }
 
603
                else
 
604
 
 
605
                // Date
 
606
                if (rx_clip_date.indexIn(line) > -1) {
 
607
                        QString s = rx_clip_date.cap(2).trimmed();
 
608
                        qDebug("MplayerProcess::parseLine: clip_date: '%s'", s.toUtf8().data());
 
609
                        md.clip_date = s;
 
610
                }
 
611
                else
 
612
 
 
613
                // Track
 
614
                if (rx_clip_track.indexIn(line) > -1) {
 
615
                        QString s = rx_clip_track.cap(1).trimmed();
 
616
                        qDebug("MplayerProcess::parseLine: clip_track: '%s'", s.toUtf8().data());
 
617
                        md.clip_track = s;
 
618
                }
 
619
                else
 
620
 
 
621
                // Copyright
 
622
                if (rx_clip_copyright.indexIn(line) > -1) {
 
623
                        QString s = rx_clip_copyright.cap(1).trimmed();
 
624
                        qDebug("MplayerProcess::parseLine: clip_copyright: '%s'", s.toUtf8().data());
 
625
                        md.clip_copyright = s;
 
626
                }
 
627
                else
 
628
 
 
629
                // Comment
 
630
                if (rx_clip_comment.indexIn(line) > -1) {
 
631
                        QString s = rx_clip_comment.cap(1).trimmed();
 
632
                        qDebug("MplayerProcess::parseLine: clip_comment: '%s'", s.toUtf8().data());
 
633
                        md.clip_comment = s;
 
634
                }
 
635
                else
 
636
 
 
637
                // Software
 
638
                if (rx_clip_software.indexIn(line) > -1) {
 
639
                        QString s = rx_clip_software.cap(1).trimmed();
 
640
                        qDebug("MplayerProcess::parseLine: clip_software: '%s'", s.toUtf8().data());
 
641
                        md.clip_software = s;
 
642
                }
 
643
                else
 
644
 
 
645
                if (rx_fontcache.indexIn(line) > -1) {
 
646
                        //qDebug("MplayerProcess::parseLine: updating font cache");
 
647
                        emit receivedUpdatingFontCache();
 
648
                }
 
649
                else
 
650
 
 
651
                // Catch starting message
 
652
                /*
 
653
                pos = rx_play.indexIn(line);
 
654
                if (pos > -1) {
 
655
                        emit mplayerFullyLoaded();
 
656
                }
 
657
                */
 
658
 
 
659
                //Generic things
 
660
                if (rx.indexIn(line) > -1) {
 
661
                        tag = rx.cap(1);
 
662
                        value = rx.cap(2);
 
663
                        //qDebug("MplayerProcess::parseLine: tag: %s, value: %s", tag.toUtf8().data(), value.toUtf8().data());
 
664
 
 
665
#if !NOTIFY_AUDIO_CHANGES
 
666
                        // Generic audio
 
667
                        if (tag == "ID_AUDIO_ID") {
 
668
                                int ID = value.toInt();
 
669
                                qDebug("MplayerProcess::parseLine: ID_AUDIO_ID: %d", ID);
 
670
                                md.audios.addID( ID );
 
671
                        }
 
672
                        else
 
673
#endif
 
674
 
 
675
                        // Video
 
676
                        if (tag == "ID_VIDEO_ID") {
 
677
                                int ID = value.toInt();
 
678
                                qDebug("MplayerProcess::parseLine: ID_VIDEO_ID: %d", ID);
 
679
                                md.videos.addID( ID );
 
680
                        }
 
681
                        else
 
682
                        if (tag == "ID_LENGTH") {
 
683
                                md.duration = value.toDouble();
 
684
                                qDebug("MplayerProcess::parseLine: md.duration set to %f", md.duration);
 
685
                        }
 
686
                        else
 
687
                        if (tag == "ID_VIDEO_WIDTH") {
 
688
                                md.video_width = value.toInt();
 
689
                                qDebug("MplayerProcess::parseLine: md.video_width set to %d", md.video_width);
 
690
                        }
 
691
                        else
 
692
                        if (tag == "ID_VIDEO_HEIGHT") {
 
693
                                md.video_height = value.toInt();
 
694
                                qDebug("MplayerProcess::parseLine: md.video_height set to %d", md.video_height);
 
695
                        }
 
696
                        else
 
697
                        if (tag == "ID_VIDEO_ASPECT") {
 
698
                                md.video_aspect = value.toDouble();
 
699
                                if ( md.video_aspect == 0.0 ) {
 
700
                                        // I hope width & height are already set.
 
701
                                        md.video_aspect = (double) md.video_width / md.video_height;
 
702
                                }
 
703
                                qDebug("MplayerProcess::parseLine: md.video_aspect set to %f", md.video_aspect);
 
704
                        }
 
705
                        else
 
706
                        if (tag == "ID_DVD_DISC_ID") {
 
707
                                md.dvd_id = value;
 
708
                                qDebug("MplayerProcess::parseLine: md.dvd_id set to '%s'", md.dvd_id.toUtf8().data());
 
709
                        }
 
710
                        else
 
711
                        if (tag == "ID_DEMUXER") {
 
712
                                md.demuxer = value;
 
713
                        }
 
714
                        else
 
715
                        if (tag == "ID_VIDEO_FORMAT") {
 
716
                                md.video_format = value;
 
717
                        }
 
718
                        else
 
719
                        if (tag == "ID_AUDIO_FORMAT") {
 
720
                                md.audio_format = value;
 
721
                        }
 
722
                        else
 
723
                        if (tag == "ID_VIDEO_BITRATE") {
 
724
                                md.video_bitrate = value.toInt();
 
725
                        }
 
726
                        else
 
727
                        if (tag == "ID_VIDEO_FPS") {
 
728
                                md.video_fps = value;
 
729
                        }
 
730
                        else
 
731
                        if (tag == "ID_AUDIO_BITRATE") {
 
732
                                md.audio_bitrate = value.toInt();
 
733
                        }
 
734
                        else
 
735
                        if (tag == "ID_AUDIO_RATE") {
 
736
                                md.audio_rate = value.toInt();
 
737
                        }
 
738
                        else
 
739
                        if (tag == "ID_AUDIO_NCH") {
 
740
                                md.audio_nch = value.toInt();
 
741
                        }
 
742
                        else
 
743
                        if (tag == "ID_VIDEO_CODEC") {
 
744
                                md.video_codec = value;
 
745
                        }
 
746
                        else
 
747
                        if (tag == "ID_AUDIO_CODEC") {
 
748
                                md.audio_codec = value;
 
749
                        }
 
750
#if GENERIC_CHAPTER_SUPPORT
 
751
                        else
 
752
                        if (tag == "ID_CHAPTERS") {
 
753
                                md.chapters = value.toInt();
 
754
                        }
 
755
                        else
 
756
                        if (tag == "ID_DVD_CURRENT_TITLE") {
 
757
                                dvd_current_title = value.toInt();
 
758
                        }
 
759
#endif
 
760
                }
 
761
        }
 
762
}
 
763
 
 
764
// Called when the process is finished
 
765
void MplayerProcess::processFinished(int exitCode, QProcess::ExitStatus exitStatus) {
 
766
        qDebug("MplayerProcess::processFinished: exitCode: %d, status: %d", exitCode, (int) exitStatus);
 
767
        // Send this signal before the endoffile one, otherwise
 
768
        // the playlist will start to play next file before all
 
769
        // objects are notified that the process has exited.
 
770
        emit processExited();
 
771
        if (received_end_of_file) emit receivedEndOfFile();
 
772
}
 
773
 
 
774
void MplayerProcess::gotError(QProcess::ProcessError error) {
 
775
        qDebug("MplayerProcess::gotError: %d", (int) error);
 
776
}
 
777
 
 
778
#include "moc_mplayerprocess.cpp"