Anonymous avatar Anonymous committed 6611069

fast per-pixel copy, loop video

Comments (0)

Files changed (6)

 
 [Direct3D9 Rendering Subsystem]
 Allow NVPerfHUD=No
-Anti aliasing=Level 4
+Anti aliasing=None
 Floating-point mode=Fastest
 Full Screen=No
 Rendering Device=NVIDIA GeForce 8600 GT

ogre-movingcube/OgreVideoCanvas.cpp

+#include "OgreVideoCanvas.h"
+
+OgreVideoCanvas::OgreVideoCanvas(void)
+{
+}
+
+OgreVideoCanvas::~OgreVideoCanvas(void)
+{
+}

ogre-movingcube/OgreVideoCanvas.h

+#pragma once
+
+class OgreVideoCanvas
+{
+public:
+    OgreVideoCanvas(void);
+    ~OgreVideoCanvas(void);
+};

ogre-movingcube/OgreVideoTexture.cpp

 #include "OgreVideoTexture.h"
 
 #include <boost/format.hpp>
+#include <cstring>
 
 //------------------------------------------------------------------------------
 OgreVideoTexture::OgreVideoTexture(const Ogre::String _filename)
     :mVideoFileName(_filename)
-    ,mVideoStream(NULL)
+    ,mCvCapture(NULL)
     ,mCurrentVideoFrame(NULL)
+    ,mCurrentFrameIndex(0)
 {
     mLog = Ogre::LogManager::getSingletonPtr()->createLog("OgreVideoTexture.log");
     _init();
 //------------------------------------------------------------------------------
 OgreVideoTexture::~OgreVideoTexture(void)
 {
+    _endCapture();
+    _destroyTexture();
 }
 //------------------------------------------------------------------------------
 void OgreVideoTexture::_init()
 {
     mLog->logMessage("init");
     
-    // OpenCv crap
-    Ogre::String fullName = Ogre::String("../media/videos/") + mVideoFileName;
-    mVideoStream = cvCreateFileCapture(fullName.c_str());
 
-    mLog->logMessage("openned " + fullName);
-
-    _createTextureFromCapture(mVideoStream);
+    _initCapture();
+    _createTextureFromCapture(mCvCapture);
 
     // set first frame
-    cvGrabFrame(mVideoStream);
-    cvGrabFrame(mVideoStream);
-    mCurrentVideoFrame = cvRetrieveFrame(mVideoStream);
+    mCurrentVideoFrame = cvQueryFrame(mCvCapture);
+    mCurrentFrameIndex++;
 
     _updateTextureFromImage(mCurrentVideoFrame);
 
     mMaterialName = "Video Texture "+ mVideoFileName;
     mTimeSinceLastUpdate.reset();
 
-    mFrameCount = cvGetCaptureProperty(mVideoStream, CV_CAP_PROP_FRAME_COUNT);
-    mCurrentFrameIndex = 2;
+     
+    mLog->logMessage("init done");
+}
+//------------------------------------------------------------------------------
+void OgreVideoTexture::_initCapture()
+{
+    Ogre::String fullName = Ogre::String("../media/videos/") + mVideoFileName;
+    mCvCapture = cvCreateFileCapture(fullName.c_str());
+    mFrameCount = cvGetCaptureProperty(mCvCapture, CV_CAP_PROP_FRAME_COUNT);
 
-    mLog->logMessage("init done");
+    // skip first frame
+    cvGrabFrame(mCvCapture);
+    mCurrentFrameIndex++;
+
+    mLog->logMessage("openned " + fullName);
+}
+//------------------------------------------------------------------------------
+void OgreVideoTexture::_endCapture()
+{
+    cvReleaseCapture(&mCvCapture);
+    mCurrentFrameIndex = 0;
+    mCurrentVideoFrame = NULL;
+    mCvCapture = NULL;
+    mLog->logMessage("video file" + mVideoFileName + "ended");
+}
+//------------------------------------------------------------------------------
+void OgreVideoTexture::_reinitCapture()
+{
+    cvSetCaptureProperty(mCvCapture, CV_CAP_PROP_POS_MSEC, 0.0);
+    
+    cvGrabFrame(mCvCapture);
+    mCurrentFrameIndex = 1;
 }
 //------------------------------------------------------------------------------
 void OgreVideoTexture::nextFrame()
 {
-    if (mTimeSinceLastUpdate.getMilliseconds() > 37 &&
-        mCurrentFrameIndex < mFrameCount) 
+    if (mCurrentFrameIndex < mFrameCount)
     {
-        cvGrabFrame(mVideoStream);
-        mCurrentVideoFrame = cvRetrieveFrame(mVideoStream);
-        _updateTextureFromImage(mCurrentVideoFrame);
-        mTimeSinceLastUpdate.reset();
-        mCurrentFrameIndex++;
+        if (mTimeSinceLastUpdate.getMilliseconds() > 30)
+            
+        {
+            mCurrentVideoFrame = cvQueryFrame(mCvCapture);
+            _updateTextureFromImage(mCurrentVideoFrame);
+            mTimeSinceLastUpdate.reset();
+            mCurrentFrameIndex++;
+        }
+    }
+    else
+    {
+        // reinit
+        _reinitCapture();
+        //_endCapture();
+        //_initCapture();
     }
 }
 //------------------------------------------------------------------------------
         Ogre::TEX_TYPE_2D,      // type
         1024, 1024,         // width & height
         0,                // number of mipmaps
-        Ogre::PF_BYTE_RGBA,
-        Ogre::TU_DYNAMIC_WRITE_ONLY_DISCARDABLE);     
+        Ogre::PF_BYTE_BGR,
+        Ogre::TU_DYNAMIC_WRITE_ONLY_DISCARDABLE);
 
     _initTexture(mVideoTexture);
 
         Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
 
     mVideoMaterial->getTechnique(0)->getPass(0)->createTextureUnitState("DynamicTexture");
-    mVideoMaterial->getTechnique(0)->getPass(0)->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA);
+    //mVideoMaterial->getTechnique(0)->getPass(0)->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA);
 
 }
 //------------------------------------------------------------------------------
+void OgreVideoTexture::_destroyTexture()
+{
+    //TODO
+}
+//------------------------------------------------------------------------------
 void OgreVideoTexture::_initTexture(Ogre::TexturePtr _texture)
 {
     // Get the pixel buffer
 
     Ogre::uint8* pDest = static_cast<Ogre::uint8*>(pixelBox.data);
 
-    // Fill in some pixel data. This will give a semi-transparent blue,
-    // but this is of course dependent on the chosen pixel format.
     for (size_t j = 0; j < _texture->getHeight(); j++)
         for(size_t i = 0; i < _texture->getWidth() ; i++)
         {
             }
 
         }
-
-        // Unlock the pixel buffer
+ 
         pixelBuffer->unlock();
 }
 //------------------------------------------------------------------------------
     // Get the pixel buffer
     Ogre::HardwarePixelBufferSharedPtr pixelBuffer = mVideoTexture->getBuffer();
 
+    //_copyImagePerChannel(_image, pixelBuffer);
+    //_copyImagePerLine(_image, pixelBuffer);
+    _copyImagePerPixel(_image, pixelBuffer);
+
+
+    boost::format fmt("%1% (%2%) : %3% �s");
+    
+    fmt % "write to texture" 
+        % mCurrentFrameIndex
+        % mTimer.getMicroseconds();
+    
+    mLog->logMessage(fmt.str());
+}
+//------------------------------------------------------------------------------
+void OgreVideoTexture::_copyImagePerLine(const IplImage *_image
+                                        ,Ogre::HardwarePixelBufferSharedPtr _pixelBuffer)
+{
+
     // Lock the pixel buffer and get a pixel box
-    pixelBuffer->lock(Ogre::HardwareBuffer::HBL_NORMAL); // for best performance use HBL_DISCARD!
-    const Ogre::PixelBox& pixelBox = pixelBuffer->getCurrentLock();
+    _pixelBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD); // for best performance use HBL_DISCARD!
+    const Ogre::PixelBox& pixelBox = _pixelBuffer->getCurrentLock();
+
+    //Ogre::uint32* pDest = static_cast<Ogre::uint32*>(pixelBox.data);
+    Ogre::uint8* pDest = static_cast<Ogre::uint8*>(pixelBox.data);
+
+    for (size_t i = 0 ; i < _image->height ; i++)
+    {
+    memcpy(pDest + i*1024*4
+          , (_image->imageData) +   i*_image->width * 3
+          , _image->width * 3);
+    }
+
+    _pixelBuffer->unlock();
+}
+//------------------------------------------------------------------------------
+void OgreVideoTexture::_copyImagePerPixel(const IplImage *_image
+                                         ,Ogre::HardwarePixelBufferSharedPtr _pixelBuffer)
+{
+    // Lock the pixel buffer and get a pixel box
+    _pixelBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD); // for best performance use HBL_DISCARD!
+    const Ogre::PixelBox& pixelBox = _pixelBuffer->getCurrentLock();
+
+    Ogre::uint32* pDest = static_cast<Ogre::uint32*>(pixelBox.data);
+    
+    size_t w, h, widthStep;
+    w = _image->width;
+    h = _image->height;
+    widthStep = _image->widthStep;
+
+    Ogre::uint32 pixelBGRA;
+    for(size_t i=0 ; i < h ; i++)
+    {
+        size_t offset = i*widthStep;
+        for (size_t j=0 ; j < w ; j++)
+        {
+            memcpy(&pixelBGRA, _image->imageData + offset +j*3, sizeof(Ogre::uint32));            
+            pDest[i *1024 + j] = pixelBGRA;            
+        }
+    }
+   
+    _pixelBuffer->unlock();
+}
+//------------------------------------------------------------------------------
+void OgreVideoTexture::_copyImagePerChannel(const IplImage *_image
+                                         ,Ogre::HardwarePixelBufferSharedPtr _pixelBuffer)
+{
+
+    // Lock the pixel buffer and get a pixel box
+    _pixelBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD); // for best performance use HBL_DISCARD!
+    const Ogre::PixelBox& pixelBox = _pixelBuffer->getCurrentLock();
+
     
     Ogre::uint8* pDest = static_cast<Ogre::uint8*>(pixelBox.data);
 
-    // Fill in some pixel data. This will give a semi-transparent blue,
-    // but this is of course dependent on the chosen pixel format.
+
     for (size_t j = 0; j < _image->height; j++)
         for(size_t i = 0; i < _image->width ; i++)
         {
 
             int w = mVideoTexture->getWidth();
 
-            pDest[j*w*4 + i*4]   = pixelB;
-            pDest[j*w*4 + i*4+1] = pixelG;
-            pDest[j*w*4 + i*4+2] = pixelR;
-            pDest[j*w*4 + i*4+3] = 255;
+            pDest[j*1024*4 + i*4]   = pixelB;
+            pDest[j*1024*4 + i*4+1] = pixelG;
+            pDest[j*1024*4 + i*4+2] = pixelR;
+            //pDest[j*w*4 + i*4+3] = 255;
         }
 
-    // Unlock the pixel buffer
-    pixelBuffer->unlock();
-
-    boost::format fmt("%1% : %2% �s");
-    
-    fmt % "write to texture" % mTimer.getMicroseconds();
-    
-    mLog->logMessage(fmt.str());
-}
+    _pixelBuffer->unlock();
+}

ogre-movingcube/OgreVideoTexture.h

 
 protected:
     void _init();
+    void _initCapture();
+    void _reinitCapture();
+    void _endCapture();
     void _createTextureFromCapture(CvCapture*);
     void _initTexture(Ogre::TexturePtr);
     void _updateTextureFromImage(const IplImage*);
+    void _destroyTexture();
+
+   
+    inline void _copyImagePerLine(const IplImage*, Ogre::HardwarePixelBufferSharedPtr);
+    inline void _copyImagePerPixel(const IplImage*, Ogre::HardwarePixelBufferSharedPtr);
+    inline void _copyImagePerChannel(const IplImage*, Ogre::HardwarePixelBufferSharedPtr);
 
 protected:
     Ogre::String mVideoFileName;
-    CvCapture *mVideoStream;
+    CvCapture *mCvCapture;
     IplImage *mCurrentVideoFrame;
     Ogre::TexturePtr mVideoTexture;
     Ogre::MaterialPtr mVideoMaterial;

ogre-movingcube/ogre-movingcube.cpp

 
 		// set the rotation and move speed
 		mRotate = 0.13;
-		mMove = 250;
+		mMoveSpeed = 500;
 
 		mCanvasNode = canvasNode;
         mVideoTexture = _videoTexture;
-	
 	}
 
 	//// Overriding the default processUnbufferedKeyInput so the key updates we define
 
 	bool frameStarted(const FrameEvent &evt)
 	{
-		//mCamNode->getParentSceneNode()->yaw(Degree(1.0) * evt.timeSinceLastFrame * 200, SceneNode::TS_PARENT);
-        //mCanvasNode->roll(Degree(1.0) * evt.timeSinceLastFrame * 100);
+        mCanvasNode->roll(Degree(1.0) * evt.timeSinceLastFrame * 100);
 
         mVideoTexture->nextFrame();
 
-		mMouse->capture();
-		mKeyboard->capture();
-
 
 		if(mKeyboard->isKeyDown(OIS::KC_ESCAPE))
 			return false;
         
 		mSceneMgr->setAmbientLight(ColourValue(0.25, 0.25, 0.25));
 
+        float uMin = 0, vMin = 0;
+        float uMax = 640.0/1024, vMax = 480.0/1024;
 
         mCanvas = mSceneMgr->createManualObject("video canvas");
         mCanvas->begin("BaseWhiteNoLighting", RenderOperation::OT_TRIANGLE_STRIP);
-        //mCanvas->position(-0.65,  0.5, 0);   mCanvas->textureCoord(    0, 0.9375);
-        //mCanvas->position( 0.65,  0.5, 0);   mCanvas->textureCoord(0.625, 0.9375);
-        //mCanvas->position(-0.65, -0.5, 0);   mCanvas->textureCoord(    0,      0);
-        //mCanvas->position( 0.65, -0.5, 0);   mCanvas->textureCoord(0.625,      0);
+   
+        /*mCanvas->position(-0.65,  0.5, 0);   mCanvas->textureCoord(uMin, vMax);     mCanvas->normal(Ogre::Vector3::UNIT_Y);
+        mCanvas->position( 0.65,  0.5, 0);   mCanvas->textureCoord(uMax, vMax);     mCanvas->normal(Ogre::Vector3::UNIT_Y);
+        mCanvas->position(-0.65, -0.5, 0);   mCanvas->textureCoord(uMin, vMin);     mCanvas->normal(Ogre::Vector3::UNIT_Y);
+        mCanvas->position( 0.65, -0.5, 0);   mCanvas->textureCoord(uMax, vMin);     mCanvas->normal(Ogre::Vector3::UNIT_Y);*/
+   
+        mCanvas->position(-320,  240, 0);   mCanvas->textureCoord(uMin, vMax);     mCanvas->normal(Ogre::Vector3::NEGATIVE_UNIT_Z);
+        mCanvas->position( 320,  240, 0);   mCanvas->textureCoord(uMax, vMax);     mCanvas->normal(Ogre::Vector3::NEGATIVE_UNIT_Z);
+        mCanvas->position(-320, -240, 0);   mCanvas->textureCoord(uMin, vMin);     mCanvas->normal(Ogre::Vector3::NEGATIVE_UNIT_Z);
+        mCanvas->position( 320, -240, 0);   mCanvas->textureCoord(uMax, vMin);     mCanvas->normal(Ogre::Vector3::NEGATIVE_UNIT_Z);
 
-    
-        float uMin = 0, vMin = 0;
-        float uMax = 640.0/1024, vMax = 480.0/1024;
+        mCanvas->end();
 
-        mCanvas->position(-0.65,  0.5, 0);   mCanvas->textureCoord(uMin, vMax);
-        mCanvas->position( 0.65,  0.5, 0);   mCanvas->textureCoord(uMax, vMax);
-        mCanvas->position(-0.65, -0.5, 0);   mCanvas->textureCoord(uMin, vMin);
-        mCanvas->position( 0.65, -0.5, 0);   mCanvas->textureCoord(uMax, vMin);
-        mCanvas->end();
 
 
         SceneNode *node = mSceneMgr->getRootSceneNode()->createChildSceneNode("Canvas Node", Vector3(0, 100, 0));
         node->attachObject(mCanvas);
-        node->scale(100, 100, 100);
+        //node->scale(100, 100, 100);
         node->yaw(Degree(180.0));
         node->roll(Degree(180.0));
         mCanvasNode = node;
 
 		Light *light = mSceneMgr->createLight("Light1");
 		light->setType(Light::LT_POINT);
-		light->setPosition(Vector3(250, 150, 250));
+		light->setPosition(Vector3(0, 300, 600));
 		light->setDiffuseColour(ColourValue::White);
 		light->setSpecularColour(ColourValue::White);
 
 		// Create the scene node
 		SceneNode *yawnode = mSceneMgr->getRootSceneNode()->createChildSceneNode("YawCamNode1");
-		node = yawnode->createChildSceneNode("CamNode1", Vector3(0, 100, 400));
+		node = yawnode->createChildSceneNode("CamNode1", Vector3(0, 100, 1000));
 		node->attachObject(mCamera);
 
 
-        mVideoTexture = new OgreVideoTexture("indochine.avi");
+        mVideoTexture = new OgreVideoTexture("liege.avi");
         mCanvas->setMaterialName(0, mVideoTexture->getMaterialName());
         
 	}
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.