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);
} |
Partager