How to get ofxWMFVideoPlayer textures? help, please!

Hi!
The specific question is: How can I get a texture from a video played with ofxWMFVideoPlayer? (it doesn’t work as ofVideoPlayer).

Some background and considerations:
0) I’m on a windows 10 pc, intel i7-5500u cpu, NVIDIA GeForce 940m graphics, 8gb RAM.

  1. I have low perfomance issues playing videos with ofVideoPlayer. So I started testing addons for that matter and researching in this forum if someone had the same problem as me.
  2. I found that the problem seems to be the way ofVideoPlayer (oF>9.0) works in windows, and that WMF could solve this problem, playing videos faster.
  3. Side note: if I play the same videos on GOM player, they run super fine, even if I load many of them at the same time. 4) So, with ofxWMFVideoPlayer I get good results, but now the problem is that I can’t get textures from the video (it’s a big issue!).
  4. I’m not considering Hap video player as a solution because it has to work with “standard” or “normal” videos (the ones you use with resolume or arkaos without problems).
  5. I tried g-streamer but could not geit it to work in the first attempt (I’ll try harder again later).
  6. I have k-lite codecs installed (tested with last version and the one that says in the oF instalation guide) and tried to tweek some options as someone recommended in another forum thread, but with insignificant FPS improvement.

Please, help me! any kind of advice would be great!
thank you!

ofxWMFVideoPlayer is a little funky in the sense that it shares a texture between openGL (from the oF world) and a directx context ( from the Window Media Foundation world). As a consequence extra care needs to be followed when touching the texture (as it can be used by two separate process). If you look in the .cpp file of the video player, the draw function does the following:

 void ofxWMFVideoPlayer::draw(int x, int y , int w, int h) {
 _player->m_pEVRPresenter->lockSharedTexture()
 _tex.draw(x,y,w,h);
  _player->m_pEVRPresenter->unlockSharedTexture();
  }

The lock/unlock are to be sure directX doesn’t change your texture while you’re using it. If you need to do a lot of processing with that texture, then it might be advisable to lock, copy the texture to an ofTexture, unlock. And then work on the copy. If you don’t spend to much time with the texture, then lock, use the texture for whatever you need, unlock.

Hope it makes sense!

ps. The _tex object is marked as private in the definition of the video player, so the dirty hack would be to mark it as public so you can access it from your sketch. A cleaner solution would be to implement to texture copy I was describing in the update function of the player, and then make that copied texture accessible to everyone (and therefore match the ofVideoPlayer regular behavior).

1 Like

Thanks a lot @silverbahamut! your answer was really helpfull! I made a lot of tests adding stuff in the draw() function, but couln’t get it to work. For some reason I don’t understand, the “unlockSharedTexture()” is retro-active. If I copy the texture, for example adding “tex2=_tex;” in the line just below of "_text.draw(x,y,w,h), it just doesn’t work. But if I comment the line “unlockSharedTexture()”, it works. I don’t know why.
Anyway, I managed to solve this problem creating a new class called “hackWMFVideoPlayer”, that has a “freeTextureAndGetIt()” method, that basically do almost the same as the draw() method of ofxWMFVideoPlayer, but instead of drawing the texture, it returns a ofTexture object. And, to keep things clean, I added another method called “closeTexture()” that only calls the “unlockSharedTexture()”. (In reality, they have others names, in spanish, that reminds me to use both of them together).
I’ll leave the code here for those who may have the same problem as me.
Thanks again silverbahamut!

The use is simple. First you have to ask for the texture and then “close” the texture.
example:
#include “hackWMFVideoPlayer.h”
hackWMFVideoPlayer video;
ofTexture myTex;

//in setup:
video.load(“video.mp4”);
video,play();

//in update:
video.update();

//in draw:
myTex=video.freeTextureAndGetIt();
myTex.draw(0,0);
video.closeTexture();

that’s all!
The files:

hackWMFVideoPlayer.h:

#pragma once
#include “ofxWMFVideoPlayer.h”
class hackWMFVideoPlayer: public ofxWMFVideoPlayer {
public:
hackWMFVideoPlayer();
//~hackWMFVideoPlayer();

ofTexture freeTextureAndGetIt();
void closeTexture();

};

hackWMFVideoPlayer.cpp:

#include “hackWMFVideoPlayer.h”
hackWMFVideoPlayer::hackWMFVideoPlayer() {
};
ofTexture hackWMFVideoPlayer::freeTextureAndGetIt() {
if (lockSharedTexture()) {
return getTexture();
}
}
void hackWMFVideoPlayer::closeTexture() {
unlockSharedTexture();
}

My guess would be the tex2 = tex is not a deep copy but would just copy the texture id (that is to say, tex2 and tex would point to the same memory on the graphic card). But good job figuring out something that work for you! If you keep the texture locked for a long time (like if you do some crazy shader magic on it) and you see some performance drop then maybe trying to use something like glCopyTexImage2D could help! But otherwise, yeah, whatever works for you :slight_smile:

1 Like