⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 readerwriterxine.cpp

📁 最新osg包
💻 CPP
字号:
// (C) Robert Osfield, Feb 2004.// GPL'd.#include <osg/ImageStream>#include <osg/Notify>#include <osg/Geode>#include <osg/GL>#include <osg/Timer>#include <osgDB/Registry>#include <osgDB/FileNameUtils>#include <osgDB/FileUtils>#include <xine.h>#include <xine/xineutils.h>#include <xine/video_out.h>#include "video_out_rgb.h"namespace osgXine{class XineImageStream : public osg::ImageStream{    public:        XineImageStream():            _xine(0),            _vo(0),            _ao(0),            _visual(0),            _stream(0),            _event_queue(0),            _ready(false),            _volume(-1.0)        {            setOrigin(osg::Image::TOP_LEFT);        }        /** 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);                void setVolume(float volume)        {            _volume = osg::minimum(osg::maximum(volume,0.0f),1.0f);            if (_stream)             {                xine_set_param(_stream, XINE_PARAM_AUDIO_VOLUME, static_cast<int>(_volume*100.0f));                osg::notify(osg::NOTICE)<<"Setting volume "<<_volume<<std::endl;            }        }                float getVolume() const        {            return _volume;        }        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, "auto", NULL);            if (!_vo)            {                osg::notify(osg::NOTICE)<<"XineImageStream::open() : Failed to create video driver"<<std::endl;                return false;            }                        // set up stream            _stream = xine_stream_new(_xine, _ao, _vo);                        if (_stream)            {                if (_volume < 0.0)                {                    _volume = static_cast<float>(xine_get_param(_stream, XINE_PARAM_AUDIO_VOLUME))/100.0f;                }                else                {                    setVolume(_volume);                }            }            _event_queue = xine_event_new_queue(_stream);            xine_event_create_listener_thread(_event_queue, event_listener, this);            int result = xine_open(_stream, filename.c_str());                        if (result==0)            {                osg::notify(osg::INFO)<<"XineImageStream::open() : Could not ready movie file."<<std::endl;                close();                return false;            }                                    _ready = false;                        int width = xine_get_stream_info(_stream,XINE_STREAM_INFO_VIDEO_WIDTH);            int height = xine_get_stream_info(_stream,XINE_STREAM_INFO_VIDEO_HEIGHT);            allocateImage(width,height,1,GL_RGB,GL_UNSIGNED_BYTE,1);            osg::notify(osg::INFO)<<"XineImageStream::open() size "<<width<<" "<<height<<std::endl;            // play();                        return true;        }        virtual void play()        {            if (_status!=PLAYING && _stream)            {                if (_status==PAUSED)                {                    xine_set_param (_stream, XINE_PARAM_SPEED, XINE_SPEED_NORMAL);                    _status=PLAYING;                }                else                {                    osg::notify(osg::INFO)<<"XineImageStream::play()"<<std::endl;                    if (xine_play(_stream, 0, 0))                    {                        while (!_ready)                        {                            osg::notify(osg::INFO)<<"   waiting..."<<std::endl;                            OpenThreads::Thread::microSleep(10000);                        }                        _status=PLAYING;                    }                    else                    {                        osg::notify(osg::NOTICE)<<"Error!!!"<<std::endl;                    }                }            }        }        virtual void pause()        {            if (_status==PAUSED || _status==INVALID) return;            _status=PAUSED;                        if (_stream)            {                xine_set_param (_stream, XINE_PARAM_SPEED, XINE_SPEED_PAUSE);            }        }        virtual void rewind()        {            if (_status==INVALID) return;            _status=REWINDING;            if (_stream)            {                osg::notify(osg::INFO)<<"Warning::XineImageStream::rewind() - rewind disabled at present."<<std::endl;                //xine_trick_mode(_stream,XINE_TRICK_MODE_FAST_REWIND,0);            }        }        virtual void quit(bool /*waitForThreadToExit*/ = true)        {            close();        }        static void my_render_frame(uint32_t width, uint32_t height, void* data, void* userData)        {            XineImageStream* imageStream = (XineImageStream*) userData;            GLenum pixelFormat = GL_BGRA;        #if 0               if (!imageStream->_ready)            {                imageStream->allocateImage(width,height,1,pixelFormat,GL_UNSIGNED_BYTE,1);                imageStream->setInternalTextureFormat(GL_RGBA);            }            osg::Timer_t start_tick = osg::Timer::instance()->tick();            memcpy(imageStream->data(),data,imageStream->getTotalSizeInBytes());            osg::notify(osg::INFO)<<"image memcpy size="<<imageStream->getTotalSizeInBytes()<<" time="<<osg::Timer::instance()->delta_m(start_tick,osg::Timer::instance()->tick())<<"ms"<<std::endl;            imageStream->dirty();        #else             imageStream->setImage(width,height,1,                              GL_RGB,                              pixelFormat,GL_UNSIGNED_BYTE,                              (unsigned char *)data,                              osg::Image::NO_DELETE,                              1);        #endif            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;        xine_event_queue_t*     _event_queue;        bool                    _ready;        float                   _volume;    protected:        virtual ~XineImageStream()        {            osg::notify(osg::INFO)<<"Killing XineImageStream"<<std::endl;            close();            osg::notify(osg::INFO)<<"Closed XineImageStream"<<std::endl;        }        void close()        {            osg::notify(osg::INFO)<<"XineImageStream::close()"<<std::endl;            if (_stream)            {                  osg::notify(osg::INFO)<<"  Closing stream"<<std::endl;                                  xine_close(_stream);                  osg::notify(osg::INFO)<<"  Disposing stream"<<std::endl;                  xine_dispose(_stream);                  _stream = 0;            }            if (_event_queue)            {                _event_queue = 0;            }            if (_ao)            {               osg::notify(osg::INFO)<<"  Closing audio driver"<<std::endl;                xine_close_audio_driver(_xine, _ao);                                  _ao = 0;            }                        if (_vo)            {               osg::notify(osg::INFO)<<"  Closing video driver"<<std::endl;                xine_close_video_driver(_xine, _vo);                                  _vo = 0;            }           osg::notify(osg::INFO)<<"closed XineImageStream "<<std::endl;        }        static void event_listener(void *user_data, const xine_event_t *event)        {            XineImageStream* xis = reinterpret_cast<XineImageStream*>(user_data);            switch(event->type)            {            case XINE_EVENT_UI_PLAYBACK_FINISHED:                if (xis->getLoopingMode()==LOOPING)                {                    //rewind();                    xine_play(xis->_stream, 0, 0);                }                break;            }        }};}class ReaderWriterXine : public osgDB::ReaderWriter{    public:        ReaderWriterXine()        {            supportsExtension("avi","");            supportsExtension("db","");            supportsExtension("ogv","");            supportsExtension("flv","");            supportsExtension("mov","");            supportsExtension("mpg","Mpeg movie format");            supportsExtension("mpv","Mpeg movie format");            supportsExtension("wmv","");            supportsExtension("xine","Xine plugin Pseduo plugin");                    _xine = xine_new();            const char* user_home = xine_get_homedir();            if(user_home)            {                char* cfgfile = NULL;                asprintf(&(cfgfile), "%s/.xine/config", user_home);                xine_config_load(_xine, cfgfile);            }            xine_init(_xine);                        register_rgbout_plugin(_xine);        }             virtual ~ReaderWriterXine()        {            osg::notify(osg::INFO)<<"~ReaderWriterXine()"<<std::endl;                    if (_xine) xine_exit(_xine);            _xine = NULL;        }                virtual const char* className() const { return "Xine ImageStream Reader"; }        virtual ReadResult readImage(const std::string& file, const osgDB::ReaderWriter::Options* options) const        {            std::string ext = osgDB::getLowerCaseFileExtension(file);            if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;                        std::string fileName;            if (ext=="xine")            {                fileName = osgDB::findDataFile( osgDB::getNameLessExtension(file), options);                osg::notify(osg::INFO)<<"Xine stipped filename = "<<fileName<<std::endl;            }            else            {                fileName = osgDB::findDataFile( file, options );                if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;            }            osg::notify(osg::INFO)<<"ReaderWriterXine::readImage "<< file<< std::endl;            osg::ref_ptr<osgXine::XineImageStream> imageStream = new osgXine::XineImageStream();            if (!imageStream->open(_xine, fileName)) return ReadResult::FILE_NOT_HANDLED;            return imageStream.release();        }    protected:        xine_t*             _xine;};// now register with Registry to instantiate the above// reader/writer.REGISTER_OSGPLUGIN(xine, ReaderWriterXine)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -