root/OpenSceneGraph/trunk/src/osgPlugins/quicktime/MovieData.cpp @ 11019

Revision 11019, 6.9 kB (checked in by robert, 5 years ago)

From Serge Lages, "Here is a fix for the Quicktime plugin, with the previous version, the size for some videos was not correct, using GetMovieBoundsRgn? instead of GetMovieBox? returns the real movie size.
"

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
RevLine 
[2815]1/*
2 *  MovieData.cpp
3 *  lala
4 *
5 *  Created by Stephan Huber on Wed Mar 10 2004.
6 *  Copyright (c) 2004 __MyCompanyName__. All rights reserved.
7 *
8 */
[5799]9#include <osg/GL>
[5803]10#include <osg/Endian>
[10891]11#include <osg/Image>
[5799]12#include <osgDB/FileNameUtils>
[5656]13
[2815]14#include "MovieData.h"
15#include "QTUtils.h"
16
[5656]17
18
[2815]19   
[6701]20MovieData::MovieData() : _pointer(NULL), _movie(NULL), _gw(NULL), _fError(false), _isLooping(false)
[3100]21{
22
23}
24
25
26MovieData::~MovieData()
[8792]27
[5799]28    if (_pointer) free(_pointer);
[3100]29    if (_gw) DisposeGWorld(_gw);
[8792]30
31    if (_movie) {
32        DisposeMovie(_movie);
33    }
[3100]34}
[2815]35   
36   
37   
38   
[5799]39void MovieData::load(osg::Image* image, std::string afilename, float startTime)
[3100]40{
[9932]41    bool isUrl( osgDB::containsServerAddress(afilename) );
42   
[5799]43    std::string filename = afilename;
[9932]44    if (!isUrl) {
45        if (!osgDB::isFileNameNativeStyle(filename))
46            filename = osgDB::convertFileNameToNativeStyle(filename);
47    }
48   
49    image->setFileName(filename);
50   
[5799]51
[9932]52    QTNewMoviePropertyElement newMovieProperties[2];
53    CFStringRef movieLocation = CFStringCreateWithCString(NULL, filename.c_str(), kCFStringEncodingUTF8);
54    CFURLRef movieURL(NULL);
55    Boolean trueValue = true;
56
57    newMovieProperties[0].propClass = kQTPropertyClass_DataLocation;
58    if (!isUrl)
59    {
60        #ifdef __APPLE__
61            newMovieProperties[0].propID = kQTDataLocationPropertyID_CFStringPosixPath;
62        #else
63            newMovieProperties[0].propID = kQTDataLocationPropertyID_CFStringWindowsPath;
64        #endif
65       
66        newMovieProperties[0].propValueSize = sizeof(CFStringRef);
67        newMovieProperties[0].propValueAddress = &movieLocation;
68    }
69    else 
70    {
71        movieURL = CFURLCreateWithString(kCFAllocatorDefault, movieLocation, NULL);
72       
73        newMovieProperties[0].propID = kQTDataLocationPropertyID_CFURL;
74        newMovieProperties[0].propValueSize = sizeof(movieURL);
75        newMovieProperties[0].propValueAddress = (void*)&movieURL;
76    }
77
78    // make movie active
79    newMovieProperties[1].propClass = kQTPropertyClass_NewMovieProperty;
80    newMovieProperties[1].propID = kQTNewMoviePropertyID_Active;
81    newMovieProperties[1].propValueSize = sizeof(trueValue);
82    newMovieProperties[1].propValueAddress = &trueValue;
[2815]83   
[9932]84    // Instantiate the Movie
85    OSStatus status = NewMovieFromProperties(2, newMovieProperties, 0, NULL, &_movie);
86    CFRelease(movieLocation);
87    if (movieURL) CFRelease(movieURL);
88   
89    if (status !=0) {
[2815]90        _fError = true;
[9932]91        osg::notify(osg::FATAL) << " MovieData :: NewMovieFromProperties failed with err " << status<< std::endl;
[2815]92        return;
93    }
[9932]94   
95   
[11019]96    Rect bounds = (*GetMovieBoundsRgn(_movie))->rgnBBox;
[9932]97 
[11019]98    _checkMovieError("Can't get movie bounds\n");
99
[2815]100    OffsetRect(&bounds, -bounds.left, -bounds.top);
101    SetMovieBox(_movie, &bounds);
102    _checkMovieError("Can't set movie box\n");
103
104    _movieWidth = bounds.right;
105    _movieHeight = bounds.bottom;
106   
107    _timescale = (float)GetMovieTimeScale(_movie);
108
109    _initImage(image);
110    if (!_fError) _initGWorldStuff(image);
111
112       
113    if (!_fError) {
114   
115        if ( startTime == 0.0f)
116            GoToBeginningOfMovie(_movie);
117        else {
118            TimeValue t = (TimeValue) (startTime*_timescale);
119            SetMovieTimeValue(_movie,t);
120        }
121           
122        UpdateMovie(_movie);
123        SetMovieRate(_movie,0);
[5799]124        SetMovieActive(_movie, true);
125        UpdateMovie(_movie);
126        MoviesTask(_movie,0);
[2815]127    }
128}
129
130
131// ---------------------------------------------------------------------------
132// _intImage
133// create image for storing
134// ---------------------------------------------------------------------------
135
[3100]136void MovieData::_initImage(osg::Image* image)
137{
[2815]138
[3100]139    void* buffer;
[5799]140   
[2815]141
142    _textureWidth = ((_movieWidth + 7) >> 3) << 3;
143    _textureHeight = _movieHeight;
144   
145    // some magic alignment...
[5799]146    _pointer = (char*)malloc(4 * _textureWidth * _textureHeight + 32);
[2815]147
[5799]148    if (_pointer == NULL) {
[2815]149        osg::notify(osg::FATAL) << "MovieData: " << "Can't allocate texture buffer" << std::endl;
150        _fError= true;
151    }
152
[5799]153    buffer = (void*)(((unsigned long)(_pointer + 31) >> 5) << 5);
[5656]154
[5803]155    GLenum internalFormat = (osg::getCpuByteOrder()==osg::BigEndian)?
[5656]156                            GL_UNSIGNED_INT_8_8_8_8_REV :
157                            GL_UNSIGNED_INT_8_8_8_8;
158
[5799]159    image->setImage(_textureWidth,_textureHeight,1,
[4801]160                   (GLint) GL_RGBA8,
[10891]161                   (GLenum)GL_BGRA,
[5803]162                   internalFormat,
[5799]163                   (unsigned char*) buffer,osg::Image::NO_DELETE,4);
[2815]164
165}
166
167// ---------------------------------------------------------------------------
168// _initGWorldStuff
169// init gworld-stuff, so quicktime can play the movie into the gWorld.
170// ---------------------------------------------------------------------------
171
172void MovieData::_initGWorldStuff(osg::Image * image)  {
173
174    Rect textureBounds;
175    OSStatus err;
[4801]176    GDHandle        origDevice;
177    CGrafPtr        origPort;
[2815]178    PixMapHandle pixmap = NULL;
179
180    textureBounds.left = 0;
181    textureBounds.top = 0;
182    textureBounds.right = image->s();
183    textureBounds.bottom = image->t();
184    err = QTNewGWorldFromPtr(&_gw, k32ARGBPixelFormat, &textureBounds, NULL, NULL, 0, image->data(), 4 * image->s());
185   
186    if (err !=0 )
187        osg::notify(osg::FATAL) << "MovieData : Could not create gWorld" << std::endl;
188       
189    GetGWorld (&origPort, &origDevice);
[4801]190    SetGWorld(_gw, NULL);                                         // set current graphics port to offscreen
[2815]191    SetMovieGWorld(_movie, (CGrafPtr)_gw, NULL);
192   
193    _checkMovieError("SetMovieGWorld failed");
194
195    pixmap = GetGWorldPixMap (_gw);
196    if (pixmap)
197    {
[4801]198        if (!LockPixels (pixmap))                                        // lock offscreen pixel map
[2815]199        {
200            osg::notify(osg::FATAL) << "Could not lock PixMap" << std::endl;
201            ExitToShell ();
202        }
203    }
204    else
205    {
206        osg::notify(osg::FATAL) << "Could not GetGWorldPixMap" << std::endl;
207        ExitToShell ();
208    }
209
210    SetGWorld(origPort, origDevice);
211
212}
213
[5799]214void MovieData::setMovieTime(float atime) {
215    float time = (atime > getMovieDuration()) ? getMovieDuration() : atime;
216   
217    TimeValue t = (TimeValue) (time * _timescale);
218    SetMovieTimeValue(_movie,t);
219    _checkMovieError("setMovieTime failed");
220    UpdateMovie(_movie);
221    MoviesTask(_movie,0);
222   
223       
224}
[2815]225
[5799]226void MovieData::setMovieRate(float rate) {
227    // osg::notify(osg::ALWAYS) << "new movierate: " << rate << " current: " << getMovieRate() << std::endl;
228    _movieRate = rate;
[5803]229    if ((rate != 0) && (_preRolled == false)) {
[5799]230        PrerollMovie(_movie, GetMovieTime(_movie,NULL), X2Fix(rate));
231        _checkMovieError("PrerollMovie failed");
[5803]232        _preRolled = true;
[5799]233    }
234   
235    SetMovieRate(_movie, X2Fix(rate));
236    _checkMovieError("setMovieRate failed");
237    MoviesTask(_movie, 0);
238    _checkMovieError("MoviesTask failed");
239   
240    UpdateMovie(_movie);
241    _checkMovieError("UpdateMovie failed");
[2815]242
[5799]243}
244
245
246
Note: See TracBrowser for help on using the browser.