Created local XineImageStream class to ensure xine streams are cleaned up correctly.
This commit is contained in:
@@ -17,16 +17,85 @@
|
|||||||
|
|
||||||
#include "video_out_rgb.h"
|
#include "video_out_rgb.h"
|
||||||
|
|
||||||
static int ready = 0;
|
namespace osgXine
|
||||||
|
{
|
||||||
|
|
||||||
|
class XineImageStream : public osg::ImageStream
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
XineImageStream() {}
|
||||||
|
|
||||||
|
/** Copy constructor using CopyOp to manage deep vs shallow copy. */
|
||||||
|
XineImageStream(const XineImageStream& image,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY):
|
||||||
|
ImageStream(image,copyop) {}
|
||||||
|
|
||||||
|
META_Object(osgXine,XineImageStream);
|
||||||
|
|
||||||
|
bool open(xine_t* xine, const std::string& filename)
|
||||||
|
{
|
||||||
|
if (filename==getFileName()) return true;
|
||||||
|
|
||||||
|
_xine = xine;
|
||||||
|
|
||||||
|
// create visual
|
||||||
|
rgbout_visual_info_t* visual = new rgbout_visual_info_t;
|
||||||
|
visual->levels = PXLEVEL_ALL;
|
||||||
|
visual->format = PX_RGB32;
|
||||||
|
visual->user_data = this;
|
||||||
|
visual->callback = my_render_frame;
|
||||||
|
|
||||||
|
// set up video driver
|
||||||
|
_vo = xine_open_video_driver(_xine, "rgb", XINE_VISUAL_TYPE_RGBOUT, (void*)visual);
|
||||||
|
|
||||||
|
// set up audio driver
|
||||||
|
char* audio_driver = getenv("OSG_XINE_AUDIO_DRIVER");
|
||||||
|
_ao = audio_driver ? xine_open_audio_driver(_xine, audio_driver, NULL) : xine_open_audio_driver(_xine, "none", NULL);
|
||||||
|
|
||||||
|
if (!_vo)
|
||||||
|
{
|
||||||
|
osg::notify(osg::NOTICE)<<"Failed to create video driver"<<std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// set up stream
|
||||||
|
_stream = xine_stream_new(_xine, _ao, _vo);
|
||||||
|
|
||||||
|
// set up queue
|
||||||
|
// xine_event_queue_t* queue = xine_event_new_queue(stream);
|
||||||
|
|
||||||
|
int result = xine_open(_stream, filename.c_str());
|
||||||
|
osg::notify(osg::NOTICE)<<"XineImageStream::open - xine_open"<<result<<std::endl;
|
||||||
|
|
||||||
|
_ready = false;
|
||||||
|
|
||||||
|
xine_play(_stream, 0, 0);
|
||||||
|
|
||||||
|
// imageStream->play();
|
||||||
|
|
||||||
|
while (!_ready)
|
||||||
|
{
|
||||||
|
osg::notify(osg::NOTICE)<<"waiting..."<<std::endl;
|
||||||
|
usleep(10000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void play() { _status=PLAYING; }
|
||||||
|
|
||||||
|
virtual void pause() { _status=PAUSED; }
|
||||||
|
|
||||||
|
virtual void rewind() { _status=REWINDING; }
|
||||||
|
|
||||||
|
virtual void quit(bool /*waitForThreadToExit*/ = true) {}
|
||||||
|
|
||||||
static void my_render_frame(uint32_t width, uint32_t height, void* data, void* userData)
|
static void my_render_frame(uint32_t width, uint32_t height, void* data, void* userData)
|
||||||
{
|
{
|
||||||
osg::Image* imageStream = (osg::Image*) userData;
|
XineImageStream* imageStream = (XineImageStream*) userData;
|
||||||
|
|
||||||
GLenum pixelFormat = GL_BGRA;
|
GLenum pixelFormat = GL_BGRA;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
if (!ready)
|
if (!imageStream->_ready)
|
||||||
{
|
{
|
||||||
imageStream->allocateImage(width,height,1,pixelFormat,GL_UNSIGNED_BYTE,1);
|
imageStream->allocateImage(width,height,1,pixelFormat,GL_UNSIGNED_BYTE,1);
|
||||||
imageStream->setInternalTextureFormat(GL_RGBA);
|
imageStream->setInternalTextureFormat(GL_RGBA);
|
||||||
@@ -48,7 +117,52 @@ static void my_render_frame(uint32_t width, uint32_t height, void* data, void* u
|
|||||||
osg::Image::NO_DELETE,
|
osg::Image::NO_DELETE,
|
||||||
1);
|
1);
|
||||||
#endif
|
#endif
|
||||||
ready = 1;
|
imageStream->_ready = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
xine_t* _xine;
|
||||||
|
|
||||||
|
xine_video_port_t* _vo;
|
||||||
|
xine_audio_port_t* _ao;
|
||||||
|
|
||||||
|
rgbout_visual_info_t* _visual;
|
||||||
|
xine_stream_t* _stream;
|
||||||
|
|
||||||
|
bool _ready;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
|
||||||
|
virtual ~XineImageStream()
|
||||||
|
{
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
void close()
|
||||||
|
{
|
||||||
|
if (_stream)
|
||||||
|
{
|
||||||
|
xine_close(_stream);
|
||||||
|
xine_dispose(_stream);
|
||||||
|
_stream = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (_ao)
|
||||||
|
{
|
||||||
|
xine_close_audio_driver(_xine, _ao);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_vo)
|
||||||
|
{
|
||||||
|
xine_close_video_driver(_xine, _vo);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class ReaderWriterXine : public osgDB::ReaderWriter
|
class ReaderWriterXine : public osgDB::ReaderWriter
|
||||||
@@ -97,57 +211,9 @@ class ReaderWriterXine : public osgDB::ReaderWriter
|
|||||||
|
|
||||||
osg::notify(osg::NOTICE)<<"ReaderWriterXine::readImage "<< file<< std::endl;
|
osg::notify(osg::NOTICE)<<"ReaderWriterXine::readImage "<< file<< std::endl;
|
||||||
|
|
||||||
//XineImageStream* imageStream = new XineImageStream(file.c_str());
|
osg::ref_ptr<osgXine::XineImageStream> imageStream = new osgXine::XineImageStream();
|
||||||
osg::ref_ptr<osg::ImageStream> imageStream = new osg::ImageStream;
|
|
||||||
|
|
||||||
|
if (!imageStream->open(_xine, file)) return ReadResult::FILE_NOT_HANDLED;
|
||||||
|
|
||||||
// create visual
|
|
||||||
rgbout_visual_info_t* visual = new rgbout_visual_info_t;
|
|
||||||
visual->levels = PXLEVEL_ALL;
|
|
||||||
visual->format = PX_RGB32;
|
|
||||||
visual->user_data = imageStream.get();
|
|
||||||
visual->callback = my_render_frame;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// set up video driver
|
|
||||||
xine_video_port_t* vo = xine_open_video_driver(_xine, "rgb", XINE_VISUAL_TYPE_RGBOUT, (void*)visual);
|
|
||||||
|
|
||||||
// set up audio driver
|
|
||||||
char* audio_driver = getenv("OSG_XINE_AUDIO_DRIVER");
|
|
||||||
xine_audio_port_t* ao = audio_driver ? xine_open_audio_driver(_xine, audio_driver, NULL) : xine_open_audio_driver(_xine, "none", NULL);
|
|
||||||
|
|
||||||
if (!vo)
|
|
||||||
{
|
|
||||||
osg::notify(osg::NOTICE)<<"Failed to create video driver"<<std::endl;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// set up stream
|
|
||||||
xine_stream_t* stream = xine_stream_new(_xine, ao, vo);
|
|
||||||
|
|
||||||
// set up queue
|
|
||||||
// xine_event_queue_t* queue = xine_event_new_queue(stream);
|
|
||||||
|
|
||||||
int result = xine_open(stream, file.c_str());
|
|
||||||
osg::notify(osg::NOTICE)<<"ReaderWriterXine::readImage - xine_open "<<result<<std::endl;
|
|
||||||
|
|
||||||
if (!result) return 0;
|
|
||||||
|
|
||||||
imageStream->setFileName(file);
|
|
||||||
|
|
||||||
xine_play(stream, 0, 0);
|
|
||||||
|
|
||||||
// imageStream->play();
|
|
||||||
|
|
||||||
while (!ready)
|
|
||||||
{
|
|
||||||
osg::notify(osg::NOTICE)<<"waiting..."<<std::endl;
|
|
||||||
usleep(10000);
|
|
||||||
}
|
|
||||||
|
|
||||||
return imageStream.release();
|
return imageStream.release();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user