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

Revision 8792, 5.4 kB (checked in by robert, 6 years ago)

From Michael Guerrero, Fixed crash that occurred when openning an new movie file after all previous movie ImageStream? had been closed. Also add a missing close of the movie file.

  • 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>
[5799]11#include <osgDB/FileNameUtils>
[5656]12
[2815]13#include "MovieData.h"
14#include "QTUtils.h"
15
[5656]16
17
[2815]18   
[6701]19MovieData::MovieData() : _pointer(NULL), _movie(NULL), _gw(NULL), _fError(false), _isLooping(false)
[3100]20{
21
22}
23
24
25MovieData::~MovieData()
[8792]26
[5799]27    if (_pointer) free(_pointer);
[3100]28    if (_gw) DisposeGWorld(_gw);
[8792]29
30    if (_movie) {
31        CloseMovieFile(_resref);
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{
[2815]41    Rect bounds;
[5799]42    std::string filename = afilename;
43    if (!osgDB::isFileNameNativeStyle(filename))
44        filename = osgDB::convertFileNameToNativeStyle(filename);
45
[2815]46    osg::notify(osg::INFO) << "MovieData :: opening movie '" << filename << "'" << std::endl;
47   
[8792]48    OSStatus err = MakeMovieFromPath(filename.c_str(), &_movie, _resref);
[2815]49    if (err !=0) {
50        _fError = true;
51        osg::notify(osg::FATAL) << " MovieData :: MakeMovieFromPath failed with err " << err << std::endl;
52        return;
53    }
54
55    GetMovieBox(_movie, &bounds);
56    _checkMovieError("Can't get movie box\n");
57   
58    OffsetRect(&bounds, -bounds.left, -bounds.top);
59    SetMovieBox(_movie, &bounds);
60    _checkMovieError("Can't set movie box\n");
61
62    _movieWidth = bounds.right;
63    _movieHeight = bounds.bottom;
64   
65    _timescale = (float)GetMovieTimeScale(_movie);
66
67    _initImage(image);
68    if (!_fError) _initGWorldStuff(image);
69
70       
71    if (!_fError) {
72   
73        if ( startTime == 0.0f)
74            GoToBeginningOfMovie(_movie);
75        else {
76            TimeValue t = (TimeValue) (startTime*_timescale);
77            SetMovieTimeValue(_movie,t);
78        }
79           
80        UpdateMovie(_movie);
81        SetMovieRate(_movie,0);
[5799]82        SetMovieActive(_movie, true);
83        UpdateMovie(_movie);
84        MoviesTask(_movie,0);
[2815]85    }
86}
87
88
89// ---------------------------------------------------------------------------
90// _intImage
91// create image for storing
92// ---------------------------------------------------------------------------
93
[3100]94void MovieData::_initImage(osg::Image* image)
95{
[2815]96
[3100]97    void* buffer;
[5799]98   
[2815]99
100    _textureWidth = ((_movieWidth + 7) >> 3) << 3;
101    _textureHeight = _movieHeight;
102   
103    // some magic alignment...
[5799]104    _pointer = (char*)malloc(4 * _textureWidth * _textureHeight + 32);
[2815]105
[5799]106    if (_pointer == NULL) {
[2815]107        osg::notify(osg::FATAL) << "MovieData: " << "Can't allocate texture buffer" << std::endl;
108        _fError= true;
109    }
110
[5799]111    buffer = (void*)(((unsigned long)(_pointer + 31) >> 5) << 5);
[5656]112
[5803]113    GLenum internalFormat = (osg::getCpuByteOrder()==osg::BigEndian)?
[5656]114                            GL_UNSIGNED_INT_8_8_8_8_REV :
115                            GL_UNSIGNED_INT_8_8_8_8;
116
[5799]117    image->setImage(_textureWidth,_textureHeight,1,
[4801]118                   (GLint) GL_RGBA8,
119                   (GLenum)GL_BGRA_EXT,
[5803]120                   internalFormat,
[5799]121                   (unsigned char*) buffer,osg::Image::NO_DELETE,4);
[2815]122
123}
124
125// ---------------------------------------------------------------------------
126// _initGWorldStuff
127// init gworld-stuff, so quicktime can play the movie into the gWorld.
128// ---------------------------------------------------------------------------
129
130void MovieData::_initGWorldStuff(osg::Image * image)  {
131
132    Rect textureBounds;
133    OSStatus err;
[4801]134    GDHandle        origDevice;
135    CGrafPtr        origPort;
[2815]136    PixMapHandle pixmap = NULL;
137
138    textureBounds.left = 0;
139    textureBounds.top = 0;
140    textureBounds.right = image->s();
141    textureBounds.bottom = image->t();
142    err = QTNewGWorldFromPtr(&_gw, k32ARGBPixelFormat, &textureBounds, NULL, NULL, 0, image->data(), 4 * image->s());
143   
144    if (err !=0 )
145        osg::notify(osg::FATAL) << "MovieData : Could not create gWorld" << std::endl;
146       
147    GetGWorld (&origPort, &origDevice);
[4801]148    SetGWorld(_gw, NULL);                                         // set current graphics port to offscreen
[2815]149    SetMovieGWorld(_movie, (CGrafPtr)_gw, NULL);
150   
151    _checkMovieError("SetMovieGWorld failed");
152
153    pixmap = GetGWorldPixMap (_gw);
154    if (pixmap)
155    {
[4801]156        if (!LockPixels (pixmap))                                        // lock offscreen pixel map
[2815]157        {
158            osg::notify(osg::FATAL) << "Could not lock PixMap" << std::endl;
159            ExitToShell ();
160        }
161    }
162    else
163    {
164        osg::notify(osg::FATAL) << "Could not GetGWorldPixMap" << std::endl;
165        ExitToShell ();
166    }
167
168    SetGWorld(origPort, origDevice);
169
170}
171
[5799]172void MovieData::setMovieTime(float atime) {
173    float time = (atime > getMovieDuration()) ? getMovieDuration() : atime;
174   
175    TimeValue t = (TimeValue) (time * _timescale);
176    SetMovieTimeValue(_movie,t);
177    _checkMovieError("setMovieTime failed");
178    UpdateMovie(_movie);
179    MoviesTask(_movie,0);
180   
181       
182}
[2815]183
[5799]184void MovieData::setMovieRate(float rate) {
185    // osg::notify(osg::ALWAYS) << "new movierate: " << rate << " current: " << getMovieRate() << std::endl;
186    _movieRate = rate;
[5803]187    if ((rate != 0) && (_preRolled == false)) {
[5799]188        PrerollMovie(_movie, GetMovieTime(_movie,NULL), X2Fix(rate));
189        _checkMovieError("PrerollMovie failed");
[5803]190        _preRolled = true;
[5799]191    }
192   
193    SetMovieRate(_movie, X2Fix(rate));
194    _checkMovieError("setMovieRate failed");
195    MoviesTask(_movie, 0);
196    _checkMovieError("MoviesTask failed");
197   
198    UpdateMovie(_movie);
199    _checkMovieError("UpdateMovie failed");
[2815]200
[5799]201}
202
203
204
Note: See TracBrowser for help on using the browser.