Bonjour

depuis pas mal de temps j'essaie d'envoyer une séquence vidéo capturée par ma webcam a travers le réseau.

pour la capture de la vidéo j'utilise la bibliothèque Opencv 2.1, et pour les sockets j'utilise <winsock.h>

a mon avis au niveau du serveur tout ce passe bien, le problème est au niveau du client car je n'arrive pas a reconstruire les données reçues.

voila le code du server :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
 
// SOCKET.cpp : définit le point d'entrée pour l'application console.
//
 
#include "stdafx.h"
#include <winsock2.h>    // library des sockets sous windows
#include <stdio.h>       
#include <stdlib.h>
#include <pthread.h>
#include <cv.h>
#include <highgui.h>
#define PORT 2459
typedef int socklen_t;  // Ce type sert à stocker la taille d'une structures de type sockaddr_in
 
CvCapture*	capture;	// declaration d'un pointeur vers CvCapture 
IplImage*	img0;		// declaration d'un pointeur vers IplImage
IplImage*	img1;		// declaration d'un pointeur vers IplImage
char key='0';
 
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; // mutex :mutuelle exclusion
 
int	is_data_ready = 0;
 
void* streamServer(void* arg);		// fonction d'envoi des frames
void  quit(char* msg, int retval);  // fonction d'arret de tt les programmes
 
int main(int argc, char** argv)
{
	pthread_t 	thread_s;   // déclaration d'un thread
 
	//capture = cvCaptureFromFile("Ronaldo.avi");
	capture = cvCaptureFromCAM(0);			/* capture depuis la webcam */
 
	if (!capture) 
	{    quit("cvCapture failed", 1);	/* si la capture échoue */	}
 
	img0 = cvQueryFrame(capture);		// capture de la frame
	img1 = cvCreateImage(cvGetSize(img0), IPL_DEPTH_8U, 1);		// création de l'image
 
	cvZero(img1);
	cvNamedWindow("stream_server", CV_WINDOW_AUTOSIZE); // initilaisation de la fenetre
 
	/* Affichage de la largauer et la hauteur de la frame, pour le client */
	fprintf(stdout, "width:  %d\nheight: %d\n\n", img0->width, img0->height);
	fprintf(stdout, "Press 'q' to quit.\n\n");
 
	/* Exécution du streaming dans un thread a part*/
	if (pthread_create(&thread_s, NULL, streamServer, NULL)) 
	{
		quit("pthread_create failed.", 1);   // en cas d'échoue on quit
	}
 
	while(key != 'q') 
	{
		/* récupération de la frame depuis la la webcam*/
		img0 = cvQueryFrame(capture);
		if (!img0) break;
		img0->origin = 0; 
		cvFlip(img0, img0, 1);
 
		/**
                 * conversion en niveau de gris 
                 * c'est l'image en niveau de gris qui va etre envoyée au client 
                 * lors de la conversion en verouille avec un mutex pour ne pas violer les droit de lecture
                 */
		pthread_mutex_lock(&mutex);
		cvCvtColor(img0, img1, CV_BGR2GRAY);
		is_data_ready = 1;
		printf("gray\n");
		pthread_mutex_unlock(&mutex);
 
		/* Affichage de la video sur le serveur */
		cvShowImage("stream_server", img0);
		printf("show\n");
		key = cvWaitKey(30);
	}
 
	/* Si la touche 'q' est appuiyée on arrete le streaming */
	if (pthread_cancel(thread_s)) 
	{
		quit("pthread_cancel failed.", 1);
	}
 
	/* libération de la mémoire */
	cvDestroyWindow("stream_server");
	quit(NULL, 0);
}
 
 
void* streamServer(void* arg)
{
 
/* make this thread cancellable using pthread_cancel() */
	pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
	pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
 
	WSADATA WSAData;
    int erreur = WSAStartup(MAKEWORD(2,2), &WSAData);
 
	/* Socket et contexte d'adressage du serveur */
    SOCKADDR_IN Servin;  // struct server
    SOCKET Server;       // declaration de la socket serveur
    socklen_t Svsize = sizeof(Servin); // taille structure serveur
 
	/* Socket et contexte d'adressage du client */
    SOCKADDR_IN Clisin;   // struct client
    SOCKET Client;        // declaration de la socket client
    socklen_t Clsize = sizeof(Clisin);   // taille structure client
 
	int sock_err;
 
	if(!erreur)
    {
        /* Création d'une socket server*/
        Server = socket(AF_INET, SOCK_STREAM, 0);
		/* Si la socket est valide */
        if(Server != INVALID_SOCKET)
        {
            printf("La socket %d est maintenant ouverte en mode TCP/IP \n \n", Server);
			/* Configuration */
            Servin.sin_addr.s_addr = htonl(INADDR_ANY);  /* Adresse IP automatique */
            Servin.sin_family = AF_INET;                 /* Protocole familial (IP) */
            Servin.sin_port = htons(PORT);               /* Listage du port */
            sock_err = bind(Server, (SOCKADDR*)&Servin, Svsize);
 
				/* Si la socket fonctionne */
	            if(sock_err != SOCKET_ERROR)
		        {
				   /* Démarrage du listage (mode server) */
					sock_err = listen(Server, 5);
					printf("Listage du port %d...\n \n", PORT);
 
					/* Si la socket fonctionne */
					while(sock_err != SOCKET_ERROR)
						{
							 /* Attente pendant laquelle le client se connecte */
							 printf("Patientez pendant que le client se connecte sur le port %d...\n \n", PORT);
							 Client = accept(Server, (SOCKADDR*)&Clisin, &Clsize);
							 printf("Un client se connecte avec la socket %d de %s:%d\n \n", Client, inet_ntoa(Clisin.sin_addr), htons(Clisin.sin_port));
 
							/* the size of the data to be sent */
							int imgsize = img1->imageSize;
							int bytes, i;
 
							/* start sending images */
							while(1) 
							{
								/* send the grayscaled frame, thread safe */
								pthread_mutex_lock(&mutex);
								if (is_data_ready) 
								{
									sock_err = send(Client,img0->imageData, imgsize, 0);  
									is_data_ready = 0;
									printf("data sent\n");
								}
								pthread_mutex_unlock(&mutex);
 
								/* have we terminated yet? */
								pthread_testcancel();
 
								/* no, take a rest for a while */
								Sleep(1000);
							}
 
							if(sock_err = SOCKET_ERROR)
							{
								printf("Structure envoyee\n \n");
							}
							else
							printf("Erreur de transmission\n \n");
 
							/* Fermeture de la connexion (fermée dans les deux sens) */
							shutdown(Client, 2);
						}
 
					perror("listen");
				}
				else
				perror("bind");
 
            /* Fermeture de la socket client et de la socket serveur */            
            closesocket(Client);            
            closesocket(Server);        
		}
		else
        perror("socket");
	}
		WSACleanup();
 
		return 0;
}	
 
void quit(char* msg, int retval)
{
	if (retval == 0) 
	{
		fprintf(stdout, (msg == NULL ? "" : msg));
		fprintf(stdout, "\n");
	} 
 
	else 
	{
		fprintf(stderr, (msg == NULL ? "" : msg));
		fprintf(stderr, "\n");
	}
 
	if (capture) cvReleaseCapture(&capture);
	if (img1) cvReleaseImage(&img1);
	pthread_mutex_destroy(&mutex);
	exit(retval);
}
code client :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
 
#include "stdafx.h"
#include <winsock2.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <pthread.h>
#include <cv.h>
#include <highgui.h>
typedef int socklen_t;
#define PORT 2459
 
IplImage* img;
int  is_data_ready = 0;
char key='0';
 
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
 
void* streamClient(void* arg);
void  quit(char* msg, int retval);
 
int main(int argc, char** argv)
{
	pthread_t thread_c;
	int	width, height;
 
	width		= 640;
	height		= 480;
 
	/* create image */
	img = cvCreateImage(cvSize(width, height), IPL_DEPTH_16U, 1);
	cvZero(img);
 
	/* run the streaming client as a separate thread */
	if (pthread_create(&thread_c, NULL, streamClient, NULL)) 
	{
		quit("pthread_create failed.", 1);
	}
 
	fprintf(stdout, "Press 'q' to quit.\n\n");
 
	cvNamedWindow("stream_client", CV_WINDOW_AUTOSIZE);
	//	cvResizeWindow("stream_client",640,	480);
	printf("cvWindows");
 
	while(key != 'q') 
	{
		/**
                 * Display the received image, make it thread safe
                 * by enclosing it using pthread_mutex_lock
                 */
		pthread_mutex_lock(&mutex);
		if (is_data_ready)
		{
			cvShowImage("stream_client", img);
			printf("inside mutex show");
			is_data_ready = 0;
		}
		pthread_mutex_unlock(&mutex);
 
		key = cvWaitKey(10);
	}
 
	/* user has pressed 'q', terminate the streaming client */
	if (pthread_cancel(thread_c)) 
	{
		quit("pthread_cancel failed.", 1);
	}
 
	/* free memory */
	cvDestroyWindow("stream_client");
	quit(NULL, 0);
}
 
void* streamClient(void* arg)
{
	/* make this thread cancellable using pthread_cancel() */
	pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
	pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
 
	WSADATA WSAData;
    int erreur = WSAStartup(MAKEWORD(2,2), &WSAData);
 
    SOCKET ClientSock;
    SOCKADDR_IN Clientin;
 
    if(!erreur)
    {
        /* Création de la socket */
        ClientSock = socket(AF_INET, SOCK_STREAM, 0);
 
        /* Configuration de la connexion */
		Clientin.sin_addr.s_addr = inet_addr("192.168.1.1");
        Clientin.sin_family = AF_INET;
        Clientin.sin_port = htons(PORT);
 
        /* Si le client arrive à se connecter */
        if(connect(ClientSock, (SOCKADDR*)&Clientin, sizeof(Clientin)) != SOCKET_ERROR)
		{
			printf("Connexion à %s sur le port %d\n", inet_ntoa(Clientin.sin_addr), htons(Clientin.sin_port));
 
			int  imgsize = img->imageSize;
			char sockdata[921600];
			int  i, j, k, bytes;
 
			/* start receiving images */
			while(1) 
			{
				/* get raw data */
				//pthread_mutex_lock(&mutex);
				for (i = 0; i < imgsize; i += bytes)
				{
					if ((bytes = recv(ClientSock, sockdata + i, imgsize - i, 0)) == -1)
					{
					quit("recv failed", 1);
					} 
				}
				//is_data_ready = 1;
				//pthread_mutex_unlock(&mutex);
 
				/* convert the received data to OpenCV's IplImage format, thread safe */
				pthread_mutex_lock(&mutex);
				for (i = 0, k = 0; i < img->height; i++) 
				{
					for (j = 0; j < img->width; j++) 
					{
						((uchar*)(img->imageData + i * img->widthStep))[j] = sockdata[k++];
						printf("data converted");
					}
				}
				is_data_ready = 1;
				pthread_mutex_unlock(&mutex);
 
				/* have we terminated yet? */
				pthread_testcancel();
 
				/* no, take a rest for a while */
				Sleep(1000);
			}			
		}
 
		else
            printf("Impossible de se connecter\n");
 
        /* On ferme la socket précédemment ouverte */
        closesocket(ClientSock);
	}
        WSACleanup();
 
		return 0;
}
 
/**
 * This function provides a way to exit nicely from the system
 */
void quit(char* msg, int retval)
{
	if (retval == 0) {
		fprintf(stdout, (msg == NULL ? "" : msg));
		fprintf(stdout, "\n");
	} else {
		fprintf(stderr, (msg == NULL ? "" : msg));
		fprintf(stderr, "\n");
	}
 
	if (img) cvReleaseImage(&img);
 
	pthread_mutex_destroy(&mutex);
 
	exit(retval);
}
a la réception j'ai une fenêtre de la même taille que la fenêtre transmise, mais le fond reste gris.