Hi,

I have an application where I have to show multiple 1080p AVI videos rendering 
at the same time. I have implemented this using FFMPEG plugin with the code 
shown below. Most of the code is from osgmovie sample.

Upto 3 videos, the framerate is constant and shows no drop. However, I notice a 
significant frame rate drop for every subsequent video source added. With 3 
video sources, the framerate peaks at around 480 fps (60 fps with Vsync on) 
while with 6 videos, the frame rate drops to less than 80 (less than 20 fps 
with VSync turned on).

Note that CPU utilization never goes over 30% throughout the entire process. 

I also find that when the view shows only 3 videos, then the frame rate is at 
maximum (since presumably, the other 3 videos are getting culled out). When all 
5 videos become visible however, the frame rate drops as described above.

This looks to me like a rendering issue. Am I doing something wrong? 
Essentially, osg is rendering 6 textured quads (its the plugins that update the 
textures) and hence musn't show frame rate drops. Could someone please give me 
some hints as to how I can improve rendering performance?

Thank you!

Cheers,
Balajee.R.C

TestBed:
Intel Core i7 (3.07 GHz)
4GB RAM
AMD Radeon HD 6800

Windows 7
Visual Studio 2008
OpenScenegraph 3.2.0 Release


Code:

osg::Geometry* CreateTexturedQuadGeometry(const osg::Vec3& pos,float 
width,float height, osg::Image* image, bool useTextureRectangle, bool xyPlane, 
bool option_flip)
{
    bool flip = image->getOrigin()==osg::Image::TOP_LEFT;
    if (option_flip) flip = !flip;

    if (useTextureRectangle)
    {
        osg::Geometry* pictureQuad = osg::createTexturedQuadGeometry(pos,
                                                                     
osg::Vec3(width,0.0f,0.0f),
                                                                     xyPlane ? 
osg::Vec3(0.0f,height,0.0f) : osg::Vec3(0.0f,0.0f,height),
                                                                     0.0f, flip 
? image->t() : 0.0, image->s(), flip ? 0.0 : image->t());

        osg::ref_ptr<osg::TextureRectangle> texture = new 
osg::TextureRectangle(image);
        texture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE);
        texture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE);


        pictureQuad->getOrCreateStateSet()->setTextureAttributeAndModes(0,
                                                                        texture,
                                                                        
osg::StateAttribute::ON);

        return pictureQuad;
    }
    else
    {
        osg::Geometry* pictureQuad = osg::createTexturedQuadGeometry(pos,
                                     osg::Vec3(width,0.0f,0.0f),
                                     xyPlane ? osg::Vec3(0.0f,height,0.0f) : 
osg::Vec3(0.0f,0.0f,height),
                                     0.0f, flip ? 1.0f : 0.0f , 1.0f, flip ? 
0.0f : 1.0f);

        osg::ref_ptr<osg::Texture2D> texture = new osg::Texture2D(image);
        texture->setResizeNonPowerOfTwoHint(false);
        texture->setFilter(osg::Texture::MIN_FILTER,osg::Texture::LINEAR);
        texture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE);
        texture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE);

        pictureQuad->getOrCreateStateSet()->setTextureAttributeAndModes(0,
                    texture,
                    osg::StateAttribute::ON);

        return pictureQuad;
    }
}

osg::ref_ptr<osg::Node>
addAviVideo(const std::string& filepath, const float& xPos, const float& yPos, 
float& width, float& height)
{
    bool useTextureRectangle = false;
    bool xyPlane = false;
    bool flip = false;    

    osg::ref_ptr<osg::Image> image = osgDB::readImageFile(filepath.c_str(), 
osgDB::Registry::instance()->getOptions());
    osg::ref_ptr<osg::ImageStream> imagestream = 
dynamic_cast<osg::ImageStream*>(image.get());
    osg::ref_ptr<osg::Geode> geode = new osg::Geode();
    if (imagestream) 
    {
        osg::ImageStream::AudioStreams& audioStreams = 
imagestream->getAudioStreams();
        imagestream->play();
    }

    if (image)
    {
        osg::notify(osg::NOTICE)<<"image->s()"<<image->s()<<" 
image-t()="<<image->t()<<" 
aspectRatio="<<image->getPixelAspectRatio()<<std::endl;

        float width = image->s() * image->getPixelAspectRatio();
        float height = image->t();

        osg::ref_ptr<osg::Drawable> drawable = 
CreateTexturedQuadGeometry(osg::Vec3f(0.f, 0.f, 0.f), width, height,image, 
useTextureRectangle, xyPlane, flip);
        
        if (image->isImageTranslucent())
        {
            osg::notify(osg::NOTICE)<<"Transparent movie, enabling 
blending."<<std::endl;

            drawable->getOrCreateStateSet()->setMode(GL_BLEND, 
osg::StateAttribute::ON);
            
drawable->getOrCreateStateSet()->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
        }

        geode->addDrawable(drawable.get());
    }
    else
    {
        std::cout<<"Unable to read file "<<filepath.c_str()<<std::endl;
    }
    
    osg::ref_ptr<osg::MatrixTransform> transform = new osg::MatrixTransform();
    transform->addChild(geode);

    osg::Matrix m;
    m.makeRotate(3.14f, osg::Vec3f(0.f, 1.f, 0.f));
    m.setTrans(osg::Vec3(xPos, yPos, 0.f));
    transform->asMatrixTransform()->setMatrix(m);


    width = geode->getBoundingBox().xMax() - geode->getBoundingBox().xMin();
    height = geode->getBoundingBox().zMax() - geode->getBoundingBox().zMin();

    return transform.get();
}

int main(int argc, char *argv[] )
{
        //osg::setNotifyLevel(osg::DEBUG_INFO);
    long int numVideos = 0;
    if(argc < 2)
    {
        printf("No of video files to be loaded are not given as argument! 
Terminating!\n");
        exit(1);
    }
    else
    {
        numVideos = strtol(argv[1], NULL, 10);
    }

    /// parent node for all video sources
    osg::ref_ptr<osg::MatrixTransform> trans = new osg::MatrixTransform();

    const char* aviFolderPath = "data/";
    
    float xPos = 0.f;
    float zPos = 0.f;
    for (int i = 0; i < numVideos; ++i)
    {
        float width, height;
        char filename[1024];
        sprintf(filename, "%s%d.avi", aviFolderPath, i+1);
        osg::ref_ptr<osg::Node> aviVideoNode = 
addAviVideo(std::string(filename), xPos, zPos, width, height);
        trans->addChild(aviVideoNode);        

        xPos = xPos + width;
    }

    /// run the osg::Viewer using our tree
    osg::ref_ptr<osg::Group> m_osg_root = new osg::Group;
    m_osg_root->addChild(trans);
    
    osg::ref_ptr<osg::Node> nodePtr = static_cast<osg::Node*>(m_osg_root);

    osg::ArgumentParser arguments(&argc,argv);

    osgViewer::Viewer viewer(arguments);
    viewer.setSceneData(nodePtr);

    /// create windows
    viewer.realize();

    osg::ref_ptr<osgGA::TrackballManipulator> trackBall = new 
osgGA::TrackballManipulator; 
    trackBall->setHomePosition(osg::Vec3f(xPos, -4000.f, -320.f),
                               osg::Vec3f(xPos, 0.f, -320.f),
                               osg::Vec3f(0.f, 0.f, 1.f));
    viewer.setCameraManipulator( trackBall ); 


    osg::ref_ptr<osgViewer::StatsHandler> stats = new 
osgViewer::StatsHandler(); 
    viewer.addEventHandler(stats);

    /// run until escape pressed
        long frameCounter = 0;
        long frameAtLastStatPrint = 0;
        osg::Timer_t timeAtLastStatPrint = 0.f;
        int numLogs = 0;
    while (!viewer.done())
    {
        viewer.frame() ;
        ++frameCounter;
                osg::Timer_t currentTime = osg::Timer::instance()->tick();
                osg::Timer_t timeElapsedSinceLastStatUpdate =  
osg::Timer::instance()->delta_s(timeAtLastStatPrint, currentTime);       
                if(timeElapsedSinceLastStatUpdate > 5.f)
                {
                        ++numLogs;
                        int numFramesSinceLastStatUpdate = frameCounter - 
frameAtLastStatPrint;
                        float fps = ((float)numFramesSinceLastStatUpdate) / 
(float)timeElapsedSinceLastStatUpdate;
                        printf("==============%d. Updated FPS: 
%f====================\n", numLogs, fps);
                        frameAtLastStatPrint = frameCounter;
                        timeAtLastStatPrint = currentTime;
                }
    }

    return 0;
}


[/code]

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=56357#56357





_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to