1 /**************************************************************************** |
|
2 ** |
|
3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). |
|
4 ** All rights reserved. |
|
5 ** Contact: Nokia Corporation (qt-info@nokia.com) |
|
6 ** |
|
7 ** This file is part of the Qt Mobility Components. |
|
8 ** |
|
9 ** $QT_BEGIN_LICENSE:LGPL$ |
|
10 ** No Commercial Usage |
|
11 ** This file contains pre-release code and may not be distributed. |
|
12 ** You may use this file in accordance with the terms and conditions |
|
13 ** contained in the Technology Preview License Agreement accompanying |
|
14 ** this package. |
|
15 ** |
|
16 ** GNU Lesser General Public License Usage |
|
17 ** Alternatively, this file may be used under the terms of the GNU Lesser |
|
18 ** General Public License version 2.1 as published by the Free Software |
|
19 ** Foundation and appearing in the file LICENSE.LGPL included in the |
|
20 ** packaging of this file. Please review the following information to |
|
21 ** ensure the GNU Lesser General Public License version 2.1 requirements |
|
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
|
23 ** |
|
24 ** In addition, as a special exception, Nokia gives you certain additional |
|
25 ** rights. These rights are described in the Nokia Qt LGPL Exception |
|
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
|
27 ** |
|
28 ** If you have questions regarding the use of this file, please contact |
|
29 ** Nokia at qt-info@nokia.com. |
|
30 ** |
|
31 ** |
|
32 ** |
|
33 ** |
|
34 ** |
|
35 ** |
|
36 ** |
|
37 ** |
|
38 ** $QT_END_LICENSE$ |
|
39 ** |
|
40 ****************************************************************************/ |
|
41 |
|
42 #import <QTKit/QTDataReference.h> |
|
43 #import <QTKit/QTMovie.h> |
|
44 |
|
45 #include "qt7backend.h" |
|
46 |
|
47 #include "qt7playersession.h" |
|
48 #include "qt7playercontrol.h" |
|
49 #include "qt7videooutput.h" |
|
50 |
|
51 #include <QtNetwork/qnetworkcookie.h> |
|
52 #include <qmediaplaylistnavigator.h> |
|
53 |
|
54 #include <CoreFoundation/CoreFoundation.h> |
|
55 #include <Foundation/Foundation.h> |
|
56 |
|
57 #include <QtCore/qdatetime.h> |
|
58 #include <QtCore/qurl.h> |
|
59 |
|
60 #include <QtCore/qdebug.h> |
|
61 |
|
62 QT_USE_NAMESPACE |
|
63 |
|
64 @interface QTMovieObserver : NSObject |
|
65 { |
|
66 @private |
|
67 QT7PlayerSession *m_session; |
|
68 QTMovie *m_movie; |
|
69 } |
|
70 |
|
71 - (QTMovieObserver *) initWithPlayerSession:(QT7PlayerSession*)session; |
|
72 - (void) setMovie:(QTMovie *)movie; |
|
73 - (void) processEOS:(NSNotification *)notification; |
|
74 - (void) processLoadStateChange:(NSNotification *)notification; |
|
75 - (void) processVolumeChange:(NSNotification *)notification; |
|
76 - (void) processNaturalSizeChange :(NSNotification *)notification; |
|
77 @end |
|
78 |
|
79 @implementation QTMovieObserver |
|
80 |
|
81 - (QTMovieObserver *) initWithPlayerSession:(QT7PlayerSession*)session |
|
82 { |
|
83 if (!(self = [super init])) |
|
84 return nil; |
|
85 |
|
86 self->m_session = session; |
|
87 return self; |
|
88 } |
|
89 |
|
90 - (void) setMovie:(QTMovie *)movie |
|
91 { |
|
92 if (m_movie == movie) |
|
93 return; |
|
94 |
|
95 if (m_movie) { |
|
96 [[NSNotificationCenter defaultCenter] removeObserver:self]; |
|
97 [m_movie release]; |
|
98 } |
|
99 |
|
100 m_movie = movie; |
|
101 |
|
102 if (movie) { |
|
103 [[NSNotificationCenter defaultCenter] addObserver:self |
|
104 selector:@selector(processEOS:) |
|
105 name:QTMovieDidEndNotification |
|
106 object:m_movie]; |
|
107 |
|
108 [[NSNotificationCenter defaultCenter] addObserver:self |
|
109 selector:@selector(processLoadStateChange:) |
|
110 name:QTMovieLoadStateDidChangeNotification |
|
111 object:m_movie]; |
|
112 |
|
113 [[NSNotificationCenter defaultCenter] addObserver:self |
|
114 selector:@selector(processVolumeChange:) |
|
115 name:QTMovieVolumeDidChangeNotification |
|
116 object:m_movie]; |
|
117 |
|
118 if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_6) { |
|
119 [[NSNotificationCenter defaultCenter] addObserver:self |
|
120 selector:@selector(processNaturalSizeChange:) |
|
121 name:@"QTMovieNaturalSizeDidChangeNotification" |
|
122 object:m_movie]; |
|
123 |
|
124 } |
|
125 else { |
|
126 [[NSNotificationCenter defaultCenter] addObserver:self |
|
127 selector:@selector(processNaturalSizeChange:) |
|
128 name:QTMovieEditedNotification |
|
129 object:m_movie]; |
|
130 } |
|
131 |
|
132 [movie retain]; |
|
133 } |
|
134 } |
|
135 |
|
136 - (void) processEOS:(NSNotification *)notification |
|
137 { |
|
138 Q_UNUSED(notification); |
|
139 QMetaObject::invokeMethod(m_session, "processEOS", Qt::AutoConnection); |
|
140 } |
|
141 |
|
142 - (void) processLoadStateChange:(NSNotification *)notification |
|
143 { |
|
144 Q_UNUSED(notification); |
|
145 QMetaObject::invokeMethod(m_session, "processLoadStateChange", Qt::AutoConnection); |
|
146 } |
|
147 |
|
148 - (void) processVolumeChange:(NSNotification *)notification |
|
149 { |
|
150 Q_UNUSED(notification); |
|
151 QMetaObject::invokeMethod(m_session, "processVolumeChange", Qt::AutoConnection); |
|
152 } |
|
153 |
|
154 - (void) processNaturalSizeChange :(NSNotification *)notification |
|
155 { |
|
156 Q_UNUSED(notification); |
|
157 QMetaObject::invokeMethod(m_session, "processNaturalSizeChange", Qt::AutoConnection); |
|
158 } |
|
159 |
|
160 @end |
|
161 |
|
162 static inline NSString *qString2CFStringRef(const QString &string) |
|
163 { |
|
164 return [NSString stringWithCharacters:reinterpret_cast<const UniChar *>(string.unicode()) length:string.length()]; |
|
165 } |
|
166 |
|
167 QT7PlayerSession::QT7PlayerSession(QObject *parent) |
|
168 : QObject(parent) |
|
169 , m_QTMovie(0) |
|
170 , m_state(QMediaPlayer::StoppedState) |
|
171 , m_mediaStatus(QMediaPlayer::NoMedia) |
|
172 , m_mediaStream(0) |
|
173 , m_videoOutput(0) |
|
174 , m_muted(false) |
|
175 , m_tryingAsync(false) |
|
176 , m_volume(100) |
|
177 , m_rate(1.0) |
|
178 , m_duration(0) |
|
179 , m_videoAvailable(false) |
|
180 , m_audioAvailable(false) |
|
181 { |
|
182 m_movieObserver = [[QTMovieObserver alloc] initWithPlayerSession:this]; |
|
183 } |
|
184 |
|
185 QT7PlayerSession::~QT7PlayerSession() |
|
186 { |
|
187 [(QTMovieObserver*)m_movieObserver setMovie:nil]; |
|
188 [(QTMovieObserver*)m_movieObserver release]; |
|
189 [(QTMovie*)m_QTMovie release]; |
|
190 } |
|
191 |
|
192 void *QT7PlayerSession::movie() const |
|
193 { |
|
194 return m_QTMovie; |
|
195 } |
|
196 |
|
197 void QT7PlayerSession::setVideoOutput(QT7VideoOutput *output) |
|
198 { |
|
199 if (m_videoOutput == output) |
|
200 return; |
|
201 |
|
202 if (m_videoOutput) |
|
203 m_videoOutput->setMovie(0); |
|
204 |
|
205 m_videoOutput = output; |
|
206 |
|
207 if (m_videoOutput && m_state != QMediaPlayer::StoppedState) |
|
208 m_videoOutput->setMovie(m_QTMovie); |
|
209 } |
|
210 |
|
211 qint64 QT7PlayerSession::position() const |
|
212 { |
|
213 if (!m_QTMovie || m_state == QMediaPlayer::PausedState) |
|
214 return m_currentTime; |
|
215 |
|
216 QTTime qtTime = [(QTMovie*)m_QTMovie currentTime]; |
|
217 quint64 t = static_cast<quint64>(float(qtTime.timeValue) / float(qtTime.timeScale) * 1000.0f); |
|
218 m_currentTime = t; |
|
219 |
|
220 return m_currentTime; |
|
221 } |
|
222 |
|
223 qint64 QT7PlayerSession::duration() const |
|
224 { |
|
225 if (!m_QTMovie) |
|
226 return 0; |
|
227 |
|
228 QTTime qtTime = [(QTMovie*)m_QTMovie duration]; |
|
229 |
|
230 return static_cast<quint64>(float(qtTime.timeValue) / float(qtTime.timeScale) * 1000.0f); |
|
231 } |
|
232 |
|
233 QMediaPlayer::State QT7PlayerSession::state() const |
|
234 { |
|
235 return m_state; |
|
236 } |
|
237 |
|
238 QMediaPlayer::MediaStatus QT7PlayerSession::mediaStatus() const |
|
239 { |
|
240 return m_mediaStatus; |
|
241 } |
|
242 |
|
243 int QT7PlayerSession::bufferStatus() const |
|
244 { |
|
245 return 100; |
|
246 } |
|
247 |
|
248 int QT7PlayerSession::volume() const |
|
249 { |
|
250 return m_volume; |
|
251 } |
|
252 |
|
253 bool QT7PlayerSession::isMuted() const |
|
254 { |
|
255 return m_muted; |
|
256 } |
|
257 |
|
258 bool QT7PlayerSession::isSeekable() const |
|
259 { |
|
260 return true; |
|
261 } |
|
262 |
|
263 qreal QT7PlayerSession::playbackRate() const |
|
264 { |
|
265 return m_rate; |
|
266 } |
|
267 |
|
268 void QT7PlayerSession::setPlaybackRate(qreal rate) |
|
269 { |
|
270 if (qFuzzyCompare(m_rate, rate)) |
|
271 return; |
|
272 |
|
273 m_rate = rate; |
|
274 |
|
275 if (m_QTMovie != 0 && m_state == QMediaPlayer::PlayingState) { |
|
276 AutoReleasePool pool; |
|
277 float preferredRate = [[(QTMovie*)m_QTMovie attributeForKey:@"QTMoviePreferredRateAttribute"] floatValue]; |
|
278 [(QTMovie*)m_QTMovie setRate:preferredRate * m_rate]; |
|
279 } |
|
280 } |
|
281 |
|
282 void QT7PlayerSession::setPosition(qint64 pos) |
|
283 { |
|
284 if ( !isSeekable() || pos == position()) |
|
285 return; |
|
286 |
|
287 pos = qMin(pos, duration()); |
|
288 |
|
289 QTTime newQTTime = [(QTMovie*)m_QTMovie currentTime]; |
|
290 newQTTime.timeValue = (pos / 1000.0f) * newQTTime.timeScale; |
|
291 [(QTMovie*)m_QTMovie setCurrentTime:newQTTime]; |
|
292 } |
|
293 |
|
294 void QT7PlayerSession::play() |
|
295 { |
|
296 if (m_state == QMediaPlayer::PlayingState) |
|
297 return; |
|
298 |
|
299 m_state = QMediaPlayer::PlayingState; |
|
300 |
|
301 if (m_videoOutput) |
|
302 m_videoOutput->setMovie(m_QTMovie); |
|
303 |
|
304 AutoReleasePool pool; |
|
305 float preferredRate = [[(QTMovie*)m_QTMovie attributeForKey:@"QTMoviePreferredRateAttribute"] floatValue]; |
|
306 [(QTMovie*)m_QTMovie setRate:preferredRate * m_rate]; |
|
307 |
|
308 emit stateChanged(m_state); |
|
309 } |
|
310 |
|
311 void QT7PlayerSession::pause() |
|
312 { |
|
313 if (m_state == QMediaPlayer::PausedState) |
|
314 return; |
|
315 |
|
316 m_state = QMediaPlayer::PausedState; |
|
317 |
|
318 if (m_videoOutput) |
|
319 m_videoOutput->setMovie(m_QTMovie); |
|
320 |
|
321 [(QTMovie*)m_QTMovie setRate:0]; |
|
322 |
|
323 emit stateChanged(m_state); |
|
324 } |
|
325 |
|
326 void QT7PlayerSession::stop() |
|
327 { |
|
328 if (m_state == QMediaPlayer::StoppedState) |
|
329 return; |
|
330 |
|
331 m_state = QMediaPlayer::StoppedState; |
|
332 |
|
333 [(QTMovie*)m_QTMovie setRate:0]; |
|
334 setPosition(0); |
|
335 |
|
336 if (m_videoOutput) |
|
337 m_videoOutput->setMovie(0); |
|
338 |
|
339 emit stateChanged(m_state); |
|
340 } |
|
341 |
|
342 void QT7PlayerSession::setVolume(int volume) |
|
343 { |
|
344 if (m_volume == volume) |
|
345 return; |
|
346 |
|
347 m_volume = volume; |
|
348 |
|
349 if (m_QTMovie != 0) |
|
350 [(QTMovie*)m_QTMovie setVolume:m_volume / 100.0f]; |
|
351 else |
|
352 emit volumeChanged(m_volume); |
|
353 } |
|
354 |
|
355 void QT7PlayerSession::setMuted(bool muted) |
|
356 { |
|
357 if (m_muted == muted) |
|
358 return; |
|
359 |
|
360 m_muted = muted; |
|
361 |
|
362 if (m_QTMovie != 0) |
|
363 [(QTMovie*)m_QTMovie setMuted:m_muted]; |
|
364 |
|
365 emit mutedChanged(muted); |
|
366 } |
|
367 |
|
368 QMediaContent QT7PlayerSession::media() const |
|
369 { |
|
370 return m_resources; |
|
371 } |
|
372 |
|
373 const QIODevice *QT7PlayerSession::mediaStream() const |
|
374 { |
|
375 return m_mediaStream; |
|
376 } |
|
377 |
|
378 void QT7PlayerSession::setMedia(const QMediaContent &content, QIODevice *stream) |
|
379 { |
|
380 AutoReleasePool pool; |
|
381 |
|
382 #ifdef QT_DEBUG_QT7 |
|
383 qDebug() << Q_FUNC_INFO << content.canonicalUrl(); |
|
384 #endif |
|
385 |
|
386 if (m_QTMovie) { |
|
387 [(QTMovieObserver*)m_movieObserver setMovie:nil]; |
|
388 |
|
389 if (m_videoOutput) |
|
390 m_videoOutput->setMovie(0); |
|
391 |
|
392 [(QTMovie*)m_QTMovie release]; |
|
393 m_QTMovie = 0; |
|
394 } |
|
395 |
|
396 m_resources = content; |
|
397 m_mediaStream = stream; |
|
398 m_mediaStatus = QMediaPlayer::NoMedia; |
|
399 |
|
400 if (content.isNull()) |
|
401 return; |
|
402 |
|
403 QNetworkRequest request = content.canonicalResource().request(); |
|
404 |
|
405 QVariant cookies = request.header(QNetworkRequest::CookieHeader); |
|
406 if (cookies.isValid()) { |
|
407 NSHTTPCookieStorage *store = [NSHTTPCookieStorage sharedHTTPCookieStorage]; |
|
408 QList<QNetworkCookie> cookieList = cookies.value<QList<QNetworkCookie> >(); |
|
409 |
|
410 foreach (const QNetworkCookie &requestCookie, cookieList) { |
|
411 NSMutableDictionary *p = [NSMutableDictionary dictionaryWithObjectsAndKeys: |
|
412 qString2CFStringRef(requestCookie.name()), NSHTTPCookieName, |
|
413 qString2CFStringRef(requestCookie.value()), NSHTTPCookieValue, |
|
414 qString2CFStringRef(requestCookie.domain()), NSHTTPCookieDomain, |
|
415 qString2CFStringRef(requestCookie.path()), NSHTTPCookiePath, |
|
416 nil |
|
417 ]; |
|
418 if (requestCookie.isSessionCookie()) |
|
419 [p setObject:[NSString stringWithUTF8String:"TRUE"] forKey:NSHTTPCookieDiscard]; |
|
420 else |
|
421 [p setObject:[NSDate dateWithTimeIntervalSince1970:requestCookie.expirationDate().toTime_t()] forKey:NSHTTPCookieExpires]; |
|
422 |
|
423 [store setCookie:[NSHTTPCookie cookieWithProperties:p]]; |
|
424 } |
|
425 } |
|
426 |
|
427 // Attempt multiple times to open the movie. |
|
428 // First try - attempt open in async mode |
|
429 openMovie(true); |
|
430 } |
|
431 |
|
432 void QT7PlayerSession::openMovie(bool tryAsync) |
|
433 { |
|
434 QUrl requestUrl = m_resources.canonicalResource().request().url(); |
|
435 if (requestUrl.scheme().isEmpty()) |
|
436 requestUrl.setScheme(QLatin1String("file")); |
|
437 |
|
438 #ifdef QT_DEBUG_QT7 |
|
439 qDebug() << Q_FUNC_INFO << requestUrl; |
|
440 #endif |
|
441 |
|
442 NSError *err = 0; |
|
443 NSString *urlString = [NSString stringWithUTF8String:requestUrl.toEncoded().constData()]; |
|
444 |
|
445 NSMutableDictionary *attr = [NSMutableDictionary dictionaryWithObjectsAndKeys: |
|
446 [NSURL URLWithString:urlString], QTMovieURLAttribute, |
|
447 [NSNumber numberWithBool:YES], QTMovieOpenAsyncOKAttribute, |
|
448 [NSNumber numberWithBool:YES], QTMovieIsActiveAttribute, |
|
449 [NSNumber numberWithBool:YES], QTMovieResolveDataRefsAttribute, |
|
450 [NSNumber numberWithBool:YES], QTMovieDontInteractWithUserAttribute, |
|
451 nil]; |
|
452 |
|
453 if (tryAsync && QSysInfo::MacintoshVersion >= QSysInfo::MV_10_6) { |
|
454 [attr setObject:[NSNumber numberWithBool:YES] forKey:@"QTMovieOpenAsyncRequiredAttribute"]; |
|
455 // XXX: This is disabled for now. causes some problems with video playback for some formats |
|
456 // [attr setObject:[NSNumber numberWithBool:YES] forKey:@"QTMovieOpenForPlaybackAttribute"]; |
|
457 m_tryingAsync = true; |
|
458 } |
|
459 else |
|
460 m_tryingAsync = false; |
|
461 |
|
462 m_QTMovie = [QTMovie movieWithAttributes:attr error:&err]; |
|
463 if (err != nil) { |
|
464 // First attempt to test for inability to perform async |
|
465 // if ([err code] == QTErrorMovieOpeningCannotBeAsynchronous) { XXX: error code unknown! |
|
466 if (m_tryingAsync) { |
|
467 m_tryingAsync = false; |
|
468 err = nil; |
|
469 [attr removeObjectForKey:@"QTMovieOpenAsyncRequiredAttribute"]; |
|
470 m_QTMovie = [QTMovie movieWithAttributes:attr error:&err]; |
|
471 } |
|
472 } |
|
473 |
|
474 if (err != nil) { |
|
475 m_QTMovie = 0; |
|
476 QString description = QString::fromUtf8([[err localizedDescription] UTF8String]); |
|
477 emit error(QMediaPlayer::FormatError, description); |
|
478 |
|
479 #ifdef QT_DEBUG_QT7 |
|
480 qDebug() << Q_FUNC_INFO << description; |
|
481 #endif |
|
482 } |
|
483 else { |
|
484 [(QTMovie*)m_QTMovie retain]; |
|
485 |
|
486 [(QTMovieObserver*)m_movieObserver setMovie:(QTMovie*)m_QTMovie]; |
|
487 |
|
488 if (m_state != QMediaPlayer::StoppedState && m_videoOutput) |
|
489 m_videoOutput->setMovie(m_QTMovie); |
|
490 |
|
491 processLoadStateChange(); |
|
492 |
|
493 [(QTMovie*)m_QTMovie setMuted:m_muted]; |
|
494 [(QTMovie*)m_QTMovie setVolume:m_volume / 100.0f]; |
|
495 } |
|
496 } |
|
497 |
|
498 bool QT7PlayerSession::isAudioAvailable() const |
|
499 { |
|
500 if (!m_QTMovie) |
|
501 return false; |
|
502 |
|
503 AutoReleasePool pool; |
|
504 return [[(QTMovie*)m_QTMovie attributeForKey:@"QTMovieHasAudioAttribute"] boolValue] == YES; |
|
505 } |
|
506 |
|
507 bool QT7PlayerSession::isVideoAvailable() const |
|
508 { |
|
509 if (!m_QTMovie) |
|
510 return false; |
|
511 |
|
512 AutoReleasePool pool; |
|
513 return [[(QTMovie*)m_QTMovie attributeForKey:@"QTMovieHasVideoAttribute"] boolValue] == YES; |
|
514 } |
|
515 |
|
516 void QT7PlayerSession::processEOS() |
|
517 { |
|
518 #ifdef QT_DEBUG_QT7 |
|
519 qDebug() << Q_FUNC_INFO; |
|
520 #endif |
|
521 m_mediaStatus = QMediaPlayer::EndOfMedia; |
|
522 if (m_videoOutput) |
|
523 m_videoOutput->setMovie(0); |
|
524 emit stateChanged(m_state = QMediaPlayer::StoppedState); |
|
525 emit mediaStatusChanged(m_mediaStatus); |
|
526 } |
|
527 |
|
528 void QT7PlayerSession::processLoadStateChange() |
|
529 { |
|
530 if (!m_QTMovie) |
|
531 return; |
|
532 |
|
533 AutoReleasePool pool; |
|
534 |
|
535 long state = [[(QTMovie*)m_QTMovie attributeForKey:QTMovieLoadStateAttribute] longValue]; |
|
536 |
|
537 #ifdef QT_DEBUG_QT7 |
|
538 qDebug() << Q_FUNC_INFO << state; |
|
539 #endif |
|
540 |
|
541 #ifndef QUICKTIME_C_API_AVAILABLE |
|
542 enum { |
|
543 kMovieLoadStateError = -1L, |
|
544 kMovieLoadStateLoading = 1000, |
|
545 kMovieLoadStateLoaded = 2000, |
|
546 kMovieLoadStatePlayable = 10000, |
|
547 kMovieLoadStatePlaythroughOK = 20000, |
|
548 kMovieLoadStateComplete = 100000 |
|
549 }; |
|
550 #endif |
|
551 |
|
552 if (state == kMovieLoadStateError) { |
|
553 if (m_tryingAsync) { |
|
554 NSError *error = [(QTMovie*)m_QTMovie attributeForKey:@"QTMovieLoadStateErrorAttribute"]; |
|
555 if ([error code] == componentNotThreadSafeErr) { |
|
556 // Last Async check, try again with no such flag |
|
557 openMovie(false); |
|
558 } |
|
559 } |
|
560 else { |
|
561 if (m_videoOutput) |
|
562 m_videoOutput->setMovie(0); |
|
563 |
|
564 emit error(QMediaPlayer::FormatError, tr("Failed to load media")); |
|
565 emit mediaStatusChanged(m_mediaStatus = QMediaPlayer::InvalidMedia); |
|
566 emit stateChanged(m_state = QMediaPlayer::StoppedState); |
|
567 } |
|
568 |
|
569 return; |
|
570 } |
|
571 |
|
572 QMediaPlayer::MediaStatus newStatus = QMediaPlayer::NoMedia; |
|
573 bool isPlaying = (m_state != QMediaPlayer::StoppedState); |
|
574 |
|
575 if (state >= kMovieLoadStatePlaythroughOK) { |
|
576 newStatus = isPlaying ? QMediaPlayer::BufferedMedia : QMediaPlayer::LoadedMedia; |
|
577 } else if (state >= kMovieLoadStatePlayable) |
|
578 newStatus = isPlaying ? QMediaPlayer::BufferingMedia : QMediaPlayer::LoadingMedia; |
|
579 else if (state >= kMovieLoadStateLoading) |
|
580 newStatus = isPlaying ? QMediaPlayer::StalledMedia : QMediaPlayer::LoadingMedia; |
|
581 |
|
582 if (state >= kMovieLoadStatePlayable && |
|
583 m_state == QMediaPlayer::PlayingState && |
|
584 [(QTMovie*)m_QTMovie rate] == 0) { |
|
585 |
|
586 float preferredRate = [[(QTMovie*)m_QTMovie attributeForKey:@"QTMoviePreferredRateAttribute"] floatValue]; |
|
587 |
|
588 [(QTMovie*)m_QTMovie setRate:preferredRate * m_rate]; |
|
589 } |
|
590 |
|
591 if (state >= kMovieLoadStateLoaded) { |
|
592 qint64 currentDuration = duration(); |
|
593 if (m_duration != currentDuration) |
|
594 emit durationChanged(m_duration = currentDuration); |
|
595 |
|
596 if (m_audioAvailable != isAudioAvailable()) |
|
597 emit audioAvailableChanged(m_audioAvailable = !m_audioAvailable); |
|
598 |
|
599 if (m_videoAvailable != isVideoAvailable()) |
|
600 emit videoAvailableChanged(m_videoAvailable = !m_videoAvailable); |
|
601 } |
|
602 |
|
603 if (newStatus != m_mediaStatus) |
|
604 emit mediaStatusChanged(m_mediaStatus = newStatus); |
|
605 } |
|
606 |
|
607 void QT7PlayerSession::processVolumeChange() |
|
608 { |
|
609 if (!m_QTMovie) |
|
610 return; |
|
611 |
|
612 int newVolume = qRound(100.0f * [((QTMovie*)m_QTMovie) volume]); |
|
613 |
|
614 if (newVolume != m_volume) { |
|
615 emit volumeChanged(m_volume = newVolume); |
|
616 } |
|
617 } |
|
618 |
|
619 void QT7PlayerSession::processNaturalSizeChange() |
|
620 { |
|
621 AutoReleasePool pool; |
|
622 NSSize size = [[(QTMovie*)m_QTMovie attributeForKey:@"QTMovieNaturalSizeAttribute"] sizeValue]; |
|
623 #ifdef QT_DEBUG_QT7 |
|
624 qDebug() << Q_FUNC_INFO << QSize(size.width, size.height); |
|
625 #endif |
|
626 |
|
627 if (m_videoOutput) |
|
628 m_videoOutput->updateNaturalSize(QSize(size.width, size.height)); |
|
629 } |
|
630 |
|
631 #include "moc_qt7playersession.cpp" |
|