diff options
Diffstat (limited to 'linden/indra/llmedia/llmediaimplquicktime.cpp')
-rw-r--r-- | linden/indra/llmedia/llmediaimplquicktime.cpp | 657 |
1 files changed, 0 insertions, 657 deletions
diff --git a/linden/indra/llmedia/llmediaimplquicktime.cpp b/linden/indra/llmedia/llmediaimplquicktime.cpp deleted file mode 100644 index 76cacee..0000000 --- a/linden/indra/llmedia/llmediaimplquicktime.cpp +++ /dev/null | |||
@@ -1,657 +0,0 @@ | |||
1 | /** | ||
2 | * @file llmediaimplquicktime.cpp | ||
3 | * @brief QuickTime media impl concrete class | ||
4 | * | ||
5 | * $LicenseInfo:firstyear=2007&license=viewergpl$ | ||
6 | * | ||
7 | * Copyright (c) 2007-2009, Linden Research, Inc. | ||
8 | * | ||
9 | * Second Life Viewer Source Code | ||
10 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
11 | * to you under the terms of the GNU General Public License, version 2.0 | ||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 | ||
16 | * | ||
17 | * There are special exceptions to the terms and conditions of the GPL as | ||
18 | * it is applied to this Source Code. View the full text of the exception | ||
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
20 | * online at | ||
21 | * http://secondlifegrid.net/programs/open_source/licensing/flossexception | ||
22 | * | ||
23 | * By copying, modifying or distributing this software, you acknowledge | ||
24 | * that you have read and understood your obligations described above, | ||
25 | * and agree to abide by those obligations. | ||
26 | * | ||
27 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
28 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
29 | * COMPLETENESS OR PERFORMANCE. | ||
30 | * $/LicenseInfo$ | ||
31 | */ | ||
32 | |||
33 | #include "llmediaimplquicktime.h" | ||
34 | |||
35 | #if LL_QUICKTIME_ENABLED | ||
36 | |||
37 | #include "llmediamanager.h" | ||
38 | #include "llmediaimplregister.h" | ||
39 | |||
40 | #if LL_WINDOWS | ||
41 | #include <windows.h> | ||
42 | #endif | ||
43 | |||
44 | #include <iostream> | ||
45 | #include <sstream> | ||
46 | |||
47 | // register this impl with media manager factory | ||
48 | static LLMediaImplRegister sLLMediaImplQuickTimeReg( "LLMediaImplQuickTime", new LLMediaImplQuickTimeMaker() ); | ||
49 | |||
50 | /////////////////////////////////////////////////////////////////////////////// | ||
51 | // | ||
52 | LLMediaImplQuickTimeMaker::LLMediaImplQuickTimeMaker() | ||
53 | { | ||
54 | // Register to handle the scheme | ||
55 | mSchema.push_back( "rtsp" ); | ||
56 | |||
57 | // Register to handle the category | ||
58 | mMimeTypeCategories.push_back( "video" ); | ||
59 | mMimeTypeCategories.push_back( "audio" ); | ||
60 | mMimeTypeCategories.push_back( "image" ); | ||
61 | } | ||
62 | |||
63 | /////////////////////////////////////////////////////////////////////////////// | ||
64 | // | ||
65 | LLMediaImplQuickTime::LLMediaImplQuickTime() : | ||
66 | mMovieHandle( 0 ), | ||
67 | mGWorldHandle( 0 ), | ||
68 | mMovieController( 0 ), | ||
69 | mMinWidth( 32 ), | ||
70 | mMaxWidth( 2048 ), | ||
71 | mMinHeight( 32 ), | ||
72 | mMaxHeight( 2048 ), | ||
73 | mCurVolume( 0 ) | ||
74 | { | ||
75 | } | ||
76 | |||
77 | /////////////////////////////////////////////////////////////////////////////// | ||
78 | // | ||
79 | LLMediaImplQuickTime::~LLMediaImplQuickTime() | ||
80 | { | ||
81 | unload(); | ||
82 | } | ||
83 | |||
84 | //////////////////////////////////////////////////////////////////////////////// | ||
85 | // (static) super-initialization - called once at application startup | ||
86 | bool LLMediaImplQuickTime::startup( LLMediaManagerData* init_data ) | ||
87 | { | ||
88 | #ifdef WIN32 | ||
89 | if ( InitializeQTML( 0L ) != noErr ) | ||
90 | { | ||
91 | return false; | ||
92 | }; | ||
93 | #endif | ||
94 | |||
95 | EnterMovies(); | ||
96 | |||
97 | return true; | ||
98 | } | ||
99 | |||
100 | //////////////////////////////////////////////////////////////////////////////// | ||
101 | // (static) super-uninitialization - called once at application closedown | ||
102 | bool LLMediaImplQuickTime::closedown() | ||
103 | { | ||
104 | ExitMovies(); | ||
105 | |||
106 | #ifdef WIN32 | ||
107 | TerminateQTML(); | ||
108 | #endif | ||
109 | |||
110 | return true; | ||
111 | } | ||
112 | |||
113 | //////////////////////////////////////////////////////////////////////////////// | ||
114 | // private | ||
115 | bool LLMediaImplQuickTime::load( const std::string url ) | ||
116 | { | ||
117 | if ( url.empty() ) | ||
118 | return false; | ||
119 | |||
120 | //In case std::string::c_str() makes a copy of the url data, | ||
121 | //make sure there is memory to hold it before allocating memory for handle. | ||
122 | //if fails, NewHandleClear(...) should return NULL. | ||
123 | const char* url_string = url.c_str() ; | ||
124 | Handle handle = NewHandleClear( ( Size )( url.length() + 1 ) ); | ||
125 | if ( NULL == handle ) | ||
126 | return false; | ||
127 | if(noErr != MemError() || NULL == *handle) | ||
128 | { | ||
129 | return false ; | ||
130 | } | ||
131 | |||
132 | BlockMove( url_string, *handle, ( Size )( url.length() + 1 ) ); | ||
133 | |||
134 | //std::cout << "LLMediaImplQuickTime::load( " << url << " )" << std::endl; | ||
135 | |||
136 | // TODO: supposed to use NewMovieFromDataParams now | ||
137 | OSErr err = NewMovieFromDataRef( &mMovieHandle, newMovieActive | newMovieDontInteractWithUser | newMovieAsyncOK | newMovieIdleImportOK, nil, handle, URLDataHandlerSubType ); | ||
138 | DisposeHandle( handle ); | ||
139 | if ( noErr != err ) | ||
140 | return false; | ||
141 | |||
142 | // do pre-roll actions (typically fired for streaming movies but not always) | ||
143 | PrePrerollMovie( mMovieHandle, 0, GetMoviePreferredRate( mMovieHandle ), moviePrePrerollCompleteCallback, ( void * )this ); | ||
144 | |||
145 | // get movie rect (and check for min/max) | ||
146 | Rect movie_rect; | ||
147 | setMovieBoxEnhanced( &movie_rect ); | ||
148 | |||
149 | // make a new movie controller | ||
150 | mMovieController = NewMovieController( mMovieHandle, &movie_rect, mcNotVisible | mcTopLeftMovie ); | ||
151 | |||
152 | #if defined(__APPLE__) || defined(MACOSX) | ||
153 | setMediaDepth( 4 ); | ||
154 | #else | ||
155 | setMediaDepth( 3 ); | ||
156 | #endif | ||
157 | |||
158 | // tell manager about the media size | ||
159 | setMediaSize( movie_rect.right - movie_rect.left, movie_rect.bottom - movie_rect.top); | ||
160 | |||
161 | // movie controller | ||
162 | MCSetActionFilterWithRefCon( mMovieController, mcActionFilterCallBack, ( long )this ); | ||
163 | |||
164 | SetMoviePlayHints( mMovieHandle, hintsAllowDynamicResize, hintsAllowDynamicResize ); | ||
165 | |||
166 | // function that gets called when a frame is drawn | ||
167 | SetMovieDrawingCompleteProc( mMovieHandle, movieDrawingCallWhenChanged, movieDrawingCompleteCallback, ( long )this ); | ||
168 | |||
169 | // emit an event to say that a media source was loaded | ||
170 | LLMediaEvent event( this ); | ||
171 | mEventEmitter.update( &LLMediaObserver::onMediaLoaded, event ); | ||
172 | |||
173 | // set up inital state | ||
174 | sizeChanged(); | ||
175 | |||
176 | return true; | ||
177 | } | ||
178 | |||
179 | //////////////////////////////////////////////////////////////////////////////// | ||
180 | // virtual | ||
181 | std::string LLMediaImplQuickTime::getVersion() | ||
182 | { | ||
183 | long version; | ||
184 | Gestalt( gestaltQuickTimeVersion, &version ); | ||
185 | |||
186 | std::ostringstream codec( "" ); | ||
187 | codec << "["; | ||
188 | codec << sLLMediaImplQuickTimeReg.getImplName(); | ||
189 | codec << "] - "; | ||
190 | codec << "QuickTime: " << std::hex << version; | ||
191 | |||
192 | return codec.str(); | ||
193 | } | ||
194 | |||
195 | //////////////////////////////////////////////////////////////////////////////// | ||
196 | // virtual | ||
197 | bool LLMediaImplQuickTime::navigateTo( const std::string url ) | ||
198 | { | ||
199 | // tell engine what we're doing | ||
200 | setStatus( LLMediaBase::STATUS_NAVIGATING ); | ||
201 | |||
202 | // remove the movie we were looking at | ||
203 | unload(); | ||
204 | |||
205 | // load the new one (no real 'go to this url' function in QT) | ||
206 | load( url ); | ||
207 | |||
208 | return true; | ||
209 | } | ||
210 | |||
211 | //////////////////////////////////////////////////////////////////////////////// | ||
212 | // virtual | ||
213 | bool LLMediaImplQuickTime::sizeChanged() | ||
214 | { | ||
215 | if ( ! mMovieHandle ) | ||
216 | return false; | ||
217 | |||
218 | // sanitize size of movie | ||
219 | Rect movie_rect; | ||
220 | setMovieBoxEnhanced( &movie_rect ); | ||
221 | |||
222 | // we need this later | ||
223 | int width = ( movie_rect.right - movie_rect.left ); | ||
224 | int height = ( movie_rect.bottom - movie_rect.top ); | ||
225 | |||
226 | std::cout << "LLMEDIA> size changed to " << width << " x " << height << std::endl; | ||
227 | |||
228 | setMediaSize( width, height ); | ||
229 | |||
230 | // media depth won't change | ||
231 | int depth_bits = getMediaDepth() * 8; | ||
232 | |||
233 | GWorldPtr old_gworld_handle = mGWorldHandle; | ||
234 | |||
235 | if (old_gworld_handle) | ||
236 | { | ||
237 | GWorldFlags result = UpdateGWorld( &mGWorldHandle, depth_bits, &movie_rect, NULL, NULL, 0 ); | ||
238 | if ( gwFlagErr == result ) | ||
239 | { | ||
240 | // TODO: unrecoverable?? throw exception? return something? | ||
241 | return false; | ||
242 | } | ||
243 | } | ||
244 | else | ||
245 | { | ||
246 | OSErr result = NewGWorld( &mGWorldHandle, depth_bits, &movie_rect, NULL, NULL, keepLocal | pixelsLocked ); | ||
247 | if ( noErr != result ) | ||
248 | { | ||
249 | // ATODO: unrecoverable?? throw exception? return something? | ||
250 | return false; | ||
251 | } | ||
252 | |||
253 | // clear memory in GWorld to avoid random screen visual fuzz from uninitialized texture data | ||
254 | if ( mGWorldHandle ) | ||
255 | { | ||
256 | PixMapHandle pix_map_handle = GetGWorldPixMap( mGWorldHandle ); | ||
257 | unsigned char* ptr = ( unsigned char* )GetPixBaseAddr( pix_map_handle ); | ||
258 | memset( ptr, 0x00, height * QTGetPixMapHandleRowBytes( pix_map_handle ) ); | ||
259 | } | ||
260 | } | ||
261 | |||
262 | // point movie at GWorld if it's new | ||
263 | if ( mMovieHandle && ! old_gworld_handle ) | ||
264 | { | ||
265 | SetMovieGWorld( mMovieHandle, mGWorldHandle, GetGWorldDevice ( mGWorldHandle ) ); | ||
266 | } | ||
267 | |||
268 | // update movie controller | ||
269 | if ( mMovieController ) | ||
270 | { | ||
271 | MCSetControllerPort( mMovieController, mGWorldHandle ); | ||
272 | MCPositionController( mMovieController, &movie_rect, &movie_rect, | ||
273 | mcTopLeftMovie | mcPositionDontInvalidate ); | ||
274 | MCMovieChanged( mMovieController, mMovieHandle ); | ||
275 | } | ||
276 | |||
277 | // Emit event with size change so the calling app knows about it too | ||
278 | LLMediaEvent event( this ); | ||
279 | mEventEmitter.update( &LLMediaObserver::onMediaSizeChange, event ); | ||
280 | |||
281 | return true; | ||
282 | } | ||
283 | |||
284 | //////////////////////////////////////////////////////////////////////////////// | ||
285 | // static | ||
286 | Boolean LLMediaImplQuickTime::mcActionFilterCallBack( MovieController mc, short action, void *params, long ref ) | ||
287 | { | ||
288 | Boolean result = false; | ||
289 | |||
290 | LLMediaImplQuickTime* self = ( LLMediaImplQuickTime* )ref; | ||
291 | |||
292 | switch( action ) | ||
293 | { | ||
294 | // handle window resizing | ||
295 | case mcActionControllerSizeChanged: | ||
296 | self->sizeChanged(); | ||
297 | break; | ||
298 | |||
299 | // Block any movie controller actions that open URLs. | ||
300 | case mcActionLinkToURL: | ||
301 | case mcActionGetNextURL: | ||
302 | case mcActionLinkToURLExtended: | ||
303 | // Prevent the movie controller from handling the message | ||
304 | result = true; | ||
305 | break; | ||
306 | |||
307 | default: | ||
308 | break; | ||
309 | }; | ||
310 | |||
311 | return result; | ||
312 | } | ||
313 | |||
314 | //////////////////////////////////////////////////////////////////////////////// | ||
315 | // private | ||
316 | bool LLMediaImplQuickTime::unload() | ||
317 | { | ||
318 | if ( mMovieHandle ) | ||
319 | { | ||
320 | StopMovie( mMovieHandle ); | ||
321 | if ( mMovieController ) | ||
322 | { | ||
323 | MCMovieChanged( mMovieController, mMovieHandle ); | ||
324 | }; | ||
325 | }; | ||
326 | |||
327 | if ( mMovieController ) | ||
328 | { | ||
329 | MCSetActionFilterWithRefCon( mMovieController, NULL, (long)this ); | ||
330 | DisposeMovieController( mMovieController ); | ||
331 | mMovieController = NULL; | ||
332 | }; | ||
333 | |||
334 | if ( mMovieHandle ) | ||
335 | { | ||
336 | SetMovieDrawingCompleteProc( mMovieHandle, movieDrawingCallWhenChanged, nil, ( long )this ); | ||
337 | DisposeMovie ( mMovieHandle ); | ||
338 | mMovieHandle = NULL; | ||
339 | }; | ||
340 | |||
341 | if ( mGWorldHandle ) | ||
342 | { | ||
343 | DisposeGWorld( mGWorldHandle ); | ||
344 | mGWorldHandle = NULL; | ||
345 | }; | ||
346 | |||
347 | return true; | ||
348 | } | ||
349 | |||
350 | //////////////////////////////////////////////////////////////////////////////// | ||
351 | // static | ||
352 | OSErr LLMediaImplQuickTime::movieDrawingCompleteCallback( Movie call_back_movie, long ref ) | ||
353 | { | ||
354 | LLMediaImplQuickTime* self = ( LLMediaImplQuickTime* )ref; | ||
355 | |||
356 | // IMPORTANT: typically, a consumer who is observing this event will set a flag | ||
357 | // when this event is fired then render later. Be aware that the media stream | ||
358 | // can change during this period - dimensions, depth, format etc. | ||
359 | LLMediaEvent event( self ); | ||
360 | self->mEventEmitter.update( &LLMediaObserver::onMediaContentsChange, event ); | ||
361 | |||
362 | return noErr; | ||
363 | } | ||
364 | |||
365 | //////////////////////////////////////////////////////////////////////////////// | ||
366 | // static | ||
367 | void LLMediaImplQuickTime::moviePrePrerollCompleteCallback( Movie movie, OSErr preroll_err, void *ref ) | ||
368 | { | ||
369 | LLMediaImplQuickTime* self = ( LLMediaImplQuickTime* )ref; | ||
370 | |||
371 | LLMediaEvent event( self ); | ||
372 | self->mEventEmitter.update( &LLMediaObserver::onMediaPreroll, event ); | ||
373 | } | ||
374 | |||
375 | /////////////////////////////////////////////////////////////////////////////// | ||
376 | // used for stop / loop | ||
377 | void LLMediaImplQuickTime::rewind() | ||
378 | { | ||
379 | GoToBeginningOfMovie ( mMovieHandle ); | ||
380 | |||
381 | MCMovieChanged( mMovieController, mMovieHandle ); | ||
382 | } | ||
383 | |||
384 | //////////////////////////////////////////////////////////////////////////////// | ||
385 | // | ||
386 | bool LLMediaImplQuickTime::processState() | ||
387 | { | ||
388 | // start stream | ||
389 | if ( nextCommand() == LLMediaBase::COMMAND_START ) | ||
390 | { | ||
391 | // valid when we are in these states | ||
392 | if ( getStatus() == LLMediaBase::STATUS_NAVIGATING|| getStatus() == LLMediaBase::STATUS_STOPPED || getStatus() == LLMediaBase::STATUS_PAUSED ) | ||
393 | { | ||
394 | // it appears that the movie must be in a loaded state before we do this command | ||
395 | if ( GetMovieLoadState( mMovieHandle ) >= kMovieLoadStatePlaythroughOK ) | ||
396 | { | ||
397 | MCDoAction( mMovieController, mcActionPrerollAndPlay, (void*)GetMoviePreferredRate( mMovieHandle ) ); | ||
398 | |||
399 | MCDoAction( mMovieController, mcActionSetVolume, (void*)mCurVolume ); | ||
400 | |||
401 | setStatus( LLMediaBase::STATUS_STARTED ); | ||
402 | |||
403 | clearCommand(); | ||
404 | } | ||
405 | } | ||
406 | } | ||
407 | else | ||
408 | if ( nextCommand() == LLMediaBase::COMMAND_STOP ) | ||
409 | { | ||
410 | // valid when we are in these states | ||
411 | if ( getStatus() == LLMediaBase::STATUS_NAVIGATING || getStatus() == LLMediaBase::STATUS_STARTED || getStatus() == LLMediaBase::STATUS_PAUSED ) | ||
412 | { | ||
413 | // it appears that the movie must be in a loaded state before we do this command | ||
414 | if ( GetMovieLoadState( mMovieHandle ) >= kMovieLoadStatePlaythroughOK ) | ||
415 | { | ||
416 | // stop playing | ||
417 | Fixed rate = X2Fix( 0.0 ); | ||
418 | MCDoAction( mMovieController, mcActionPlay, (void*)rate ); | ||
419 | |||
420 | // go back to start | ||
421 | rewind(); | ||
422 | |||
423 | setStatus( LLMediaBase::STATUS_STOPPED ); | ||
424 | clearCommand(); | ||
425 | }; | ||
426 | }; | ||
427 | } | ||
428 | else | ||
429 | if ( nextCommand() == LLMediaBase::COMMAND_PAUSE ) | ||
430 | { | ||
431 | // valid when we are in these states | ||
432 | if ( getStatus() == LLMediaBase::STATUS_NAVIGATING || getStatus() == LLMediaBase::STATUS_STARTED || getStatus() == LLMediaBase::STATUS_STOPPED ) | ||
433 | { | ||
434 | // it appears that the movie must be in a loaded state before we do this command | ||
435 | if ( GetMovieLoadState( mMovieHandle ) >= kMovieLoadStatePlaythroughOK ) | ||
436 | { | ||
437 | // stop playing | ||
438 | Fixed rate = X2Fix( 0.0 ); | ||
439 | MCDoAction( mMovieController, mcActionPlay, (void*)rate ); | ||
440 | |||
441 | setStatus( LLMediaBase::STATUS_PAUSED ); | ||
442 | clearCommand(); | ||
443 | }; | ||
444 | }; | ||
445 | }; | ||
446 | |||
447 | return true; | ||
448 | } | ||
449 | |||
450 | //////////////////////////////////////////////////////////////////////////////// | ||
451 | // virtual | ||
452 | bool LLMediaImplQuickTime::setMovieBoxEnhanced( Rect* rect ) | ||
453 | { | ||
454 | // get movie rect | ||
455 | GetMovieNaturalBoundsRect( mMovieHandle, rect ); | ||
456 | |||
457 | int natural_width = ( rect->right - rect->left ); | ||
458 | int natural_height = ( rect->bottom - rect->top ); | ||
459 | |||
460 | int width = natural_width; | ||
461 | int height = natural_height; | ||
462 | |||
463 | // if the user has requested a specific size, use it: | ||
464 | if ((mMediaRequestedWidth != 0) && (mMediaRequestedHeight != 0)) | ||
465 | { | ||
466 | width = mMediaRequestedWidth; | ||
467 | height = mMediaRequestedHeight; | ||
468 | } | ||
469 | |||
470 | // if the user has requested, resize media to exactly fit texture | ||
471 | if (mAutoScaled) | ||
472 | { | ||
473 | width = LLMediaManager::textureWidthFromMediaWidth( width ); | ||
474 | height = LLMediaManager::textureHeightFromMediaHeight( height ); | ||
475 | } | ||
476 | |||
477 | // make sure it falls in valid range | ||
478 | if ( width < mMinWidth ) | ||
479 | width = mMinWidth; | ||
480 | |||
481 | if ( width > mMaxWidth ) | ||
482 | width = mMaxWidth; | ||
483 | |||
484 | if ( height < mMinHeight ) | ||
485 | height = mMinHeight; | ||
486 | |||
487 | if ( height > mMaxHeight ) | ||
488 | height = mMaxHeight; | ||
489 | |||
490 | |||
491 | // scale movie to fit rect and invert vertically to match opengl image format | ||
492 | MatrixRecord transform; | ||
493 | SetIdentityMatrix( &transform ); // transforms are additive so start from identify matrix | ||
494 | double scaleX = (double) width / natural_width; | ||
495 | double scaleY = -1.0 * (double) height / natural_height; | ||
496 | double centerX = width / 2.0; | ||
497 | double centerY = height / 2.0; | ||
498 | ScaleMatrix( &transform, X2Fix ( scaleX ), X2Fix ( scaleY ), X2Fix ( centerX ), X2Fix ( centerY ) ); | ||
499 | SetMovieMatrix( mMovieHandle, &transform ); | ||
500 | |||
501 | // return the new rect | ||
502 | rect->right = width; | ||
503 | rect->bottom = height; | ||
504 | rect->left = 0; | ||
505 | rect->top = 0; | ||
506 | |||
507 | return true; | ||
508 | } | ||
509 | |||
510 | //////////////////////////////////////////////////////////////////////////////// | ||
511 | // virtual | ||
512 | bool LLMediaImplQuickTime::updateMedia() | ||
513 | { | ||
514 | if ( ! mMovieHandle ) | ||
515 | return false; | ||
516 | |||
517 | if ( ! mMovieController ) | ||
518 | return false; | ||
519 | |||
520 | if ( ! mGWorldHandle ) | ||
521 | return false; | ||
522 | |||
523 | // service QuickTime | ||
524 | MoviesTask( mMovieHandle, 0 ); | ||
525 | MCIdle( mMovieController ); | ||
526 | |||
527 | // update state machine (deals with transport controls for example) | ||
528 | processState(); | ||
529 | |||
530 | // special code for looping - need to rewind at the end of the movie | ||
531 | |||
532 | if ( isLooping() ) | ||
533 | { | ||
534 | // QT call to see if we are at the end - can't do with controller | ||
535 | if ( IsMovieDone( mMovieHandle ) ) | ||
536 | { | ||
537 | // go back to start | ||
538 | rewind(); | ||
539 | |||
540 | // kick off new play | ||
541 | MCDoAction( mMovieController, mcActionPrerollAndPlay, (void*)GetMoviePreferredRate( mMovieHandle ) ); | ||
542 | |||
543 | // set the volume | ||
544 | MCDoAction( mMovieController, mcActionSetVolume, (void*)mCurVolume ); | ||
545 | } | ||
546 | } | ||
547 | |||
548 | return true; | ||
549 | } | ||
550 | |||
551 | //////////////////////////////////////////////////////////////////////////////// | ||
552 | // virtual | ||
553 | unsigned char* LLMediaImplQuickTime::getMediaData() | ||
554 | { | ||
555 | unsigned char* ptr = NULL; | ||
556 | |||
557 | if ( mGWorldHandle ) | ||
558 | { | ||
559 | PixMapHandle pix_map_handle = GetGWorldPixMap( mGWorldHandle ); | ||
560 | |||
561 | ptr = ( unsigned char* )GetPixBaseAddr( pix_map_handle ); | ||
562 | }; | ||
563 | |||
564 | return ptr; | ||
565 | } | ||
566 | |||
567 | //////////////////////////////////////////////////////////////////////////////// | ||
568 | // virtual | ||
569 | int LLMediaImplQuickTime::getMediaDataWidth() const | ||
570 | { | ||
571 | if ( mGWorldHandle ) | ||
572 | { | ||
573 | int depth = getMediaDepth(); | ||
574 | |||
575 | if (depth < 1) | ||
576 | depth = 1; | ||
577 | |||
578 | // ALWAYS use the row bytes from the PixMap if we have a GWorld because | ||
579 | // sometimes it's not the same as mMediaDepth * mMediaWidth ! | ||
580 | PixMapHandle pix_map_handle = GetGWorldPixMap( mGWorldHandle ); | ||
581 | return QTGetPixMapHandleRowBytes( pix_map_handle ) / depth; | ||
582 | } | ||
583 | else | ||
584 | { | ||
585 | return LLMediaImplCommon::getMediaDataWidth(); | ||
586 | } | ||
587 | } | ||
588 | |||
589 | //////////////////////////////////////////////////////////////////////////////// | ||
590 | // virtual | ||
591 | int LLMediaImplQuickTime::getTextureFormatPrimary() const | ||
592 | { | ||
593 | #if defined(__APPLE__) || defined(MACOSX) | ||
594 | return LL_MEDIA_BGRA; | ||
595 | #else | ||
596 | return LL_MEDIA_RGB; | ||
597 | #endif | ||
598 | } | ||
599 | |||
600 | //////////////////////////////////////////////////////////////////////////////// | ||
601 | // virtual | ||
602 | int LLMediaImplQuickTime::getTextureFormatType() const | ||
603 | { | ||
604 | #if defined(__APPLE__) || defined(MACOSX) | ||
605 | #ifdef __BIG_ENDIAN__ | ||
606 | return LL_MEDIA_UNSIGNED_INT_8_8_8_8_REV; | ||
607 | #else | ||
608 | return LL_MEDIA_UNSIGNED_INT_8_8_8_8; | ||
609 | #endif | ||
610 | #else | ||
611 | return LL_MEDIA_UNSIGNED_BYTE; | ||
612 | #endif | ||
613 | } | ||
614 | |||
615 | //////////////////////////////////////////////////////////////////////////////// | ||
616 | // virtual | ||
617 | bool LLMediaImplQuickTime::seek( double time ) | ||
618 | { | ||
619 | if ( mMovieController ) | ||
620 | { | ||
621 | TimeRecord when; | ||
622 | when.scale = GetMovieTimeScale( mMovieHandle ); | ||
623 | when.base = 0; | ||
624 | |||
625 | // 'time' is in (floating point) seconds. The timebase time will be in 'units', where | ||
626 | // there are 'scale' units per second. | ||
627 | SInt64 raw_time = ( SInt64 )( time * (double)( when.scale ) ); | ||
628 | |||
629 | when.value.hi = ( SInt32 )( raw_time >> 32 ); | ||
630 | when.value.lo = ( SInt32 )( ( raw_time & 0x00000000FFFFFFFF ) ); | ||
631 | |||
632 | MCDoAction( mMovieController, mcActionGoToTime, &when ); | ||
633 | |||
634 | return true; | ||
635 | } | ||
636 | |||
637 | return false; | ||
638 | } | ||
639 | |||
640 | //////////////////////////////////////////////////////////////////////////////// | ||
641 | // virtual | ||
642 | bool LLMediaImplQuickTime::setVolume( float volume ) | ||
643 | { | ||
644 | mCurVolume = (short)(volume * ( double ) 0x100 ); | ||
645 | |||
646 | if ( mMovieController ) | ||
647 | { | ||
648 | MCDoAction( mMovieController, mcActionSetVolume, (void*)mCurVolume ); | ||
649 | |||
650 | return true; | ||
651 | } | ||
652 | |||
653 | return false; | ||
654 | } | ||
655 | |||
656 | #endif // _3DNOW_InstructionExtensions/ LL_QUICKTIME_ENABLED | ||
657 | |||