Calling the same function second time doesn't work as expected

I am using a self-created function(I took some of the code from internet) called takeframefromvideo.Inside it has some jni and c++ functions to capture a frame from a video and then return an ofImage object and then the return ofImage is assigned to another ofImage object using “=” operator.Then inside draw()function I draw the ofImage objects into different ofFbo objects and then draw the ofFbo objects.

The problem is, when I call the function takeframefromvideo for once, it works.Then if I call the same function again for another video, it doesn’t work for the second or at least it is not drawing the second ofFbo object onto screen…But if I copy and create the same function with a different function name(for example:takeframefromvideo2) and after calling the first function(takeframefromvideo) if I call takeframefromvideo2, it works.But if I use one of the functions second time, it doesn’t work for the second time or at least the ofFbo object is not drawing anything onto screen.

What may be the reason?The code looks a bit complex, so I wanted to see first if it can be solved by a general understanding.If not, I will post the code but I need to do modifications on the code before posting, to make the code look cleaner(especially variable names).

have you tried to debug at different points in the function so see if you can find where it is failing?
depending on what IDE or coding environment you are using you can pause the execution of your code and see what is actually inside the variables or buffers and try and track where it is changing - happy to have a quick look if you post the relevant code…

Thanks for your answer.

I am copying almost the full code because I am not sure what is causing this problem.Also please note that I modified the variable/object names heavily before posting, so there may be small syntax errors.

This code is able to display the first ofFbo object on the screen but not the other two fbos.

If I copy the same takeframefromvideo() function under different function names and call them like:

filedirectorylistv[0].imageofv = takeframefromvideo( filedirectorylistv[0] .filepath);

filedirectorylistv[1].imageofv = takeframefromvideo2(filedirectorylistv[1].filepath);

filedirectorylistv[2].imageofv = takeframefromvideo3(filedirectorylistv[2].filepath);

it draws all of the fbos without problem.

ofApp.h:

class ofApp : public ofxAndroidApp{
{
 ....
 struct filedirectorylist
 {
        ofFboSettings settings;
        string filepath;
        
        ofFbo fbo;
        ofImage imageofv;
        
 }filedirectorylists;

 vector <filedirectorylist> filedirectorylistv;
 ....

}
ofApp.cpp:

void ofApp::setup()
{

ofxAndroidRequestPermission(OFX_ANDROID_PERMISSION_READ_EXTERNAL_STORAGE);
ofxAndroidRequestPermission(OFX_ANDROID_PERMISSION_WRITE_EXTERNAL_STORAGE);

dosyadizinlistesiv.push_back(dosyadizinlistesis);
dosyadizinlistesiv.push_back(dosyadizinlistesis);
dosyadizinlistesiv.push_back(dosyadizinlistesis);


filedirectorylistv[0].filepath = "/storage/emulated/0/try1/MOV_0270.mp4";
filedirectorylistv[1].filepath = "/storage/emulated/0/try1/hands.mp4";
filedirectorylistv[2].filepath = "/storage/emulated/0/try1/MOV_1200.mp4";


filedirectorylistv[0].imageofv = takeframefromvideo(filedirectorylistv[0].filepath);
filedirectorylistv[0].settings.width= filedirectorylistv[0].imageofv.getWidth();
filedirectorylistv[0].settings.height = filedirectorylistv[0].imageofv.getHeight();

filedirectorylistv[0].settings.internalformat = GL_RGBA;
filedirectorylistv[0].settings.textureTarget = GL_TEXTURE_2D;
filedirectorylistv[0].fbo.allocate(filedirectorylistv[0].settings);
   

filedirectorylistv[1].imageofv = takeframefromvideo(filedirectorylistv[1].filepath);
filedirectorylistv[1].settings.width= filedirectorylistv[1].imageofv.getWidth();
filedirectorylistv[1].settings.height = filedirectorylistv[1].imageofv.getHeight();

filedirectorylistv[1].settings.internalformat = GL_RGBA;
filedirectorylistv[1].settings.textureTarget = GL_TEXTURE_2D;
filedirectorylistv[1].fbo.allocate(filedirectorylistv[1].settings);

filedirectorylistv[2].imageofv = takeframefromvideo(filedirectorylistv[2].filepath);
filedirectorylistv[2].settings.width= filedirectorylistv[2].imageofv.getWidth();
filedirectorylistv[2].settings.height = filedirectorylistv[2].imageofv.getHeight();

filedirectorylistv[2].settings.internalformat = GL_RGBA;
filedirectorylistv[2].settings.textureTarget = GL_TEXTURE_2D;
filedirectorylistv[2].fbo.allocate(filedirectorylistv[2].settings);


gui.setup();
ofSetBackgroundColor(255,255,255,255);

}
void ofApp::draw()
{

filedirectorylistv[0].fbo.begin();
ofSetColor(255, 255, 255,255);
filedirectorylistv[0].imageofv.draw(0, 0);
filedirectorylistv[0].fbo.end();


filedirectorylistv[1].fbo.begin();
ofSetColor(255, 255, 255,255);
filedirectorylistv[1].imageofv.draw(500, 500);
filedirectorylistv[1].fbo.end();


filedirectorylistv[2].fbo.begin();
ofSetColor(255, 255, 255,255);
filedirectorylistv[2].imageofv.draw(0, 600);
filedirectorylistv[2].fbo.end();

}
ofImage ofApp::takeframefromvideo(string file_directory_path)
{
 ofImage image1;

 jclass bitmapConfig = ofGetJNIEnv()->FindClass("android/graphics/Bitmap$Config");

 jfieldID rgba8888FieldID = ofGetJNIEnv()->GetStaticFieldID(bitmapConfig, "ARGB_8888", "Landroid/graphics/Bitmap$Config;");

 jobject rgba8888Obj = ofGetJNIEnv()->GetStaticObjectField(bitmapConfig, rgba8888FieldID);

 jclass mediadataretclass = ofGetJNIEnv()->FindClass("android/media/MediaMetadataRetriever");
 jmethodID medinitID = ofGetJNIEnv()->GetMethodID(mediadataret,"<init>","()V");

 jobject mediadataretobj = ofGetJNIEnv()->NewObject(mediadataretclass,medinitID);


 jmethodID medsetsourceID = ofGetJNIEnv()->GetMethodID(mediadataretclass,"setDataSource","(Ljava/lang/String;)V");


 jstring strfiledirectorypath = ofGetJNIEnv()->NewStringUTF(file_directory_path.c_str());

 jlong framenum=7*1000;

 jint _height=396;
 jint _width = 396;
 long width_=100;
 long height_ = 100;


 ofGetJNIEnv()->CallVoidMethod(mediadataretobj,medsetsourceID,strfiledirectorypath);

 jclass classbitmap = ofGetJNIEnv()->FindClass("android/graphics/Bitmap");

 jmethodID createBitmapMethodID = ofGetJNIEnv()->GetStaticMethodID(classbitmap,"createBitmap", 
 "(IILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;" );

 jobject bitmap1= ofGetJNIEnv()->CallStaticObjectMethod(classbitmap, createBitmapMethodID, _width,_height,  rgba8888Obj);


 jmethodID medgetframeID = ofGetJNIEnv()->GetMethodID(mediadataret,"getFrameAtTime","(J)Landroid/graphics/Bitmap;");

 bitmap1 = ofGetJNIEnv()->CallObjectMethod(mediadataretobj,medgetframeID,framenum);
	
 jmethodID medgetpixelsID = ofGetJNIEnv()->GetMethodID(classbitmap,"getPixels","([IIIIIII)V");
 jmethodID widthgetID = ofGetJNIEnv()->GetMethodID(classbitmap,"getWidth","()I");
 jmethodID heightgetID = ofGetJNIEnv()->GetMethodID(classbitmap,"getHeight","()I");

 jint offset=0;
 jint stride=1;
 jint width=96;
 jint height=96;

 width= ofGetJNIEnv()->CallIntMethod(bitmap1,widthgetID);
 height = ofGetJNIEnv()->CallIntMethod(bitmap1,heightgetID);

 jintArray* pixels = ofGetJNIEnv()->NewIntArray(width * height*4);

 ofGetJNIEnv()->CallVoidMethod(bitmap1,medgetpixelsID,pixels,offset,width,x,y,width,height);

 int* pixelsp = ofGetJNIEnv()->GetIntArrayElements(pixels,0);

 unsigned char* bitmap = new unsigned char[width*height*4];


 for (int y=0; y<height; y++) {
		for (int x=0; x<width; x++) {
			static int i=0;

			int index = 4 * ( x + width * y );


                        unsigned char red = pixelsp[i]>>16;
			unsigned char green = pixelsp[i]>>8;
			unsigned char blue = pixelsp[i];
			unsigned char alpha = pixelsp[i]>> 24;

			bitmap[index]=red;
			bitmap[index+1]=green;
			bitmap[index+2]=blue;
			bitmap[index+3]=alpha;

			i++;
		}

 }

 image1.setFromPixels(bitmap, width, height, ofImageType::OF_IMAGE_COLOR_ALPHA,true);
 ofBackground(255,255,255);

 jmethodID medreleaseID = ofGetJNIEnv()->GetMethodID(mediadataretclass,"release","()V");
 ofGetJNIEnv()->CallVoidMethod(mediadataretobj,medreleaseID);

 return image1;

}

i’m working mostly on osX or linux so will pick thru this and see if i can post back a simplified example…

ofapp.h

/*
 Project Title:
 Description:
 ©Daniel Buzzo 2020
 dan@buzzo.com
 http://buzzo.com
 https://github.com/danbz
 */

#pragma once

#include "ofMain.h"

class ofApp : public ofBaseApp{

	public:
		void setup();
		void update();
		void draw();

		void keyPressed(int key);
		
    
    ofVideoPlayer vidPlayer;
    ofImage myImage;

};

and ofapp.cpp


 #include "ofApp.h"

//--------------------------------------------------------------
void ofApp::setup(){
    vidPlayer.load("point-cloud-cat.mov");
    vidPlayer.play();
    myImage.allocate(vidPlayer.getWidth(), vidPlayer.getHeight(), OF_IMAGE_COLOR);
}

//--------------------------------------------------------------
void ofApp::update(){
    vidPlayer.update();
}

//--------------------------------------------------------------
void ofApp::draw(){
    vidPlayer.draw(0,0,ofGetWidth()/2, ofGetHeight()/2);
    myImage.draw(ofGetWidth()/2, 0, ofGetWidth()/2, ofGetHeight()/2);
}

//--------------------------------------------------------------
void ofApp::keyPressed(int key){

    ofPixels newPixels;
    switch (key) {
        case '1':
            cout << "image 1" << endl;
            newPixels = vidPlayer.getPixels();
            myImage.setFromPixels(newPixels);
            break;
            
        default:
            break;
    }
}

will load a video and grab a frame to an image and draw to screen on key press =1

you can modify this for multiple videos depending on the logic you want -

press a key to load a different video

vidplayer.load("newvid.mov");

of make multiple instances of ofvideoPlayer objects each with different movies loaded in and grab from each one…

Thanks for your answer, sorry for my late reply.I think getPixels() function which you use in your code, is not implemented on Android, for ofVideoPlayer.