Hi,
I've been trying to capture video from webcam using openCV functions and openGL for rendering.
The code is working fine and I can acquire and display both the cameras.
Now I'm trying to record the captured video's and saving them to a file using openCV createvideowriter object. I can easily save the video into .avi format. However when I try to save/write both the videos from both camera's then the video is saved from first cam properly but not from second. I then started looking for using threads. I haven't used threads before and even after going thru articles I'm unsuccessful running the code.
Getting following error :Error 1 error C2664: 'pthread_create' : cannot convert parameter 3 from 'void *' to 'void *(__cdecl *)(void *)'
The code is like this...
#include <highgui.h>
#include <cv.h>
#include <cstdio>
#include <pthread.h>
#include "Shader.h"
typedef unsigned int uint32;
typedef unsigned char uint8;
uint8 * img0 = 0, * img1 = 0;
uint32 texID[2];
Shader * shader = 0;
uint32 program = 0, locImg0, locImg1;
CvCapture* capture0;
CvCapture* capture1;
IplImage* frame0;
IplImage* frame1;
static CvVideoWriter* writer0;
static CvVideoWriter* writer1;
typedef struct {
IplImage *image;
} thread_param;
uint32 imageWidth, imageHeight, sizeImg;
int w = 800, h = 600;//Bredde og høyde på vindu
void initOpenGL(); //Setter parametre
int initCameras();
void initWindow();
void setBuffers();
void display(); //Kalles av systemet
void reshape(int bredde, int hoyde); //Kalles av systemet
void keyboard(uint8 key, int x, int y);
void idle(); //Kalles av systemet
void close();
int main(int argc, char* argv[])
{
int s = sizeof(void*);
atexit(close);
//Disse 5 funksjonene må være tilstede
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
initCameras();
//Initialize Writers
writer0 = cvCreateVideoWriter("video/camera0.avi", CV_FOURCC('X','V','I','D'), 15, cvSize(320,240));
writer1 = cvCreateVideoWriter("video/camera1.avi", CV_FOURCC('X','V','I','D'), 15, cvSize(320,240));
//create and initialize thread
// pthread_t thread1, thread2;
// thread_param *p1 = (thread_param*) malloc(sizeof(thread_param));
initWindow();
initOpenGL();
glewInit();
setBuffers();
shader = new Shader();
program = shader->setShader("../Shader/ProcessImages");
locImg0 = glGetUniformLocation(program, "Image0");
locImg1 = glGetUniformLocation(program, "Image1");
glutMainLoop();
return 0;
}
void initWindow()
{
glutInitWindowSize(w, h);
glutInitWindowPosition(100, 150);
glutCreateWindow("Multi Video");
//Callback-funksjoner
glutKeyboardFunc(keyboard);
glutIdleFunc(idle);
glutDisplayFunc(display);
glutReshapeFunc(reshape);
}
int initCameras()
{
capture0 = cvCaptureFromCAM(0);
capture1 = cvCaptureFromCAM(0);
if( !capture0 || !capture1) {
fprintf( stderr, "ERROR: capture is NULL \n" );
getchar();
close();
return -1;
}
frame0 = cvQueryFrame(capture0);
frame1 = cvQueryFrame(capture1);
imageWidth = frame0->width;
imageHeight = frame0->height;
w = imageWidth;
h = imageHeight;
sizeImg = w * h * 3;
img0 = new unsigned char[sizeImg];
img1 = new unsigned char[sizeImg];
memcpy(img0, (uint8 *) frame0->imageData, sizeImg);
memcpy(img1, (uint8 *) frame1->imageData, sizeImg);
}
void close()
{
if (capture0)
{ cvReleaseCapture(&capture0);
cvReleaseVideoWriter(&writer0);
}
if (capture1)
cvReleaseCapture(&capture1);
cvReleaseVideoWriter(&writer1);
exit(0);
}
void* record1(void *p)
{
thread_param *param = (thread_param*) p;
IplImage *image = param->image;
// On écrit la frame dans le fichier vidéo
cvWriteFrame(writer1, image);
return NULL;
}
//callback
void display()
{
if (cvGrabFrame(capture0)) {
frame0 = cvRetrieveFrame(capture0);
//cvWriteFrame(writer0, frame0);
memcpy(img0, (uint8 *) frame0->imageData, sizeImg);
// Parameters for thread 1
pthread_t thread1;
thread_param *p1 = (thread_param*) malloc(sizeof(thread_param));
(*p1).image = frame0;
// Start the threads for recording each frame from each camera separately
//pthread_create(&thread1, NULL, NULL, (void*) p1);
pthread_create(&thread1, NULL, (void*) cvWriteFrame(writer0, frame0) , NULL);
// Wait the end of the threads
pthread_join(thread1, NULL);
}
if (cvGrabFrame(capture1)) {
frame1 = cvRetrieveFrame(capture1);
cvWriteFrame(writer1, frame1);
memcpy(img1, (uint8 *) frame1->imageData, sizeImg);
}
glBindTexture(GL_TEXTURE_2D, texID[0]);
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB, imageWidth, imageHeight, 0, GL_BGR, GL_UNSIGNED_BYTE, img0);
glUniform1i(locImg0, 0);
glBindTexture(GL_TEXTURE_2D, texID[1]);
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB, imageWidth, imageHeight, 0, GL_BGR, GL_UNSIGNED_BYTE, img1);
glUniform1i(locImg1, 1);
glBegin(GL_QUADS);
{
glTexCoord2f(0, 1); glVertex2f(0, 0);
glTexCoord2f(1, 1); glVertex2f(1, 0);
glTexCoord2f(1, 0); glVertex2f(1, 1);
glTexCoord2f(0, 0); glVertex2f(0, 1);
}
glEnd();
glBindTexture(GL_TEXTURE_2D, 0);
glutSwapBuffers();
}
void idle()
{
glutPostRedisplay();
}
void reshape(int bredde, int hoyde)
{
glViewport(0, 0, bredde, hoyde);
}
void keyboard(uint8 key, int x, int y)
{
switch(key) {
case 27 : close();
}
}
void initOpenGL()
{
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);//Hvit bakgrunn
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, 1, 0, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void setBuffers()
{
// create texture for display
glGenTextures(2, texID);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texID[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, imageWidth, imageHeight, 0, GL_BGR, GL_UNSIGNED_BYTE, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glActiveTexture(GL_TEXTURE0 + 1);
glBindTexture(GL_TEXTURE_2D, texID[1]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, imageWidth, imageHeight, 0, GL_BGR, GL_UNSIGNED_BYTE, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glBindTexture(GL_TEXTURE_2D, 0);
}
Anyone of you out there can help me out ?
Thanks