Bonjour,
Il y a quelques temps je suis arrivé à utiliser une vidéo en tant que texture OpenGL à l'aide de LibVLC ( Pour rappel, c'était ici : http://www.developpez.net/forums/d91...exture-opengl/ ).
Depuis j'ai cherché à simplifier la chose et j'ai finalement obtenu ce code :
Il fonctionne très bien ( si vous voulez tester : g++ -otest main.o -lvlc -lSDL_image -lSDL -lGLEW ).
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 #include <GL/glew.h> #include <SDL/SDL.h> #include <vlc/vlc.h> #define VIDEOFILE "/home/test/resfiles/hd.mov" // The movie to read // WIDTH, HEIGHT #define W 800 #define H 800 GLuint textureId; // Texture ID // SDL Structure struct sdlStructure { SDL_Surface *sdlSurface; SDL_mutex *sdlMutex; }; struct sdlStructure sdlStruct; // Load a texture void loadTexture() { void * rawData = (void *) malloc(W * H * 4); Uint8 * pixelSource; Uint8 * pixelDestination = (Uint8 *) rawData; Uint32 pix; for (unsigned int i = H; i > 0; i--) { for (unsigned int j = 0; j < W; j++) { pixelSource = (Uint8 *) sdlStruct.sdlSurface->pixels + (i-1) * sdlStruct.sdlSurface->pitch + j * 2; pix = *(Uint16 *) pixelSource; SDL_GetRGBA(pix, sdlStruct.sdlSurface->format, &(pixelDestination[0]), &(pixelDestination[1]), &(pixelDestination[2]), &(pixelDestination[3])); pixelDestination += 4; } } // Building the texture glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glBindTexture(GL_TEXTURE_2D, textureId); glTexImage2D(GL_TEXTURE_2D, 0, 4, W, H, 0, GL_RGBA, GL_UNSIGNED_BYTE, (Uint8 *) rawData); free(rawData); } // Lock func static void * lockfct(void *data, void **p_pixels) { SDL_LockMutex(sdlStruct.sdlMutex); SDL_LockSurface(sdlStruct.sdlSurface); *p_pixels = sdlStruct.sdlSurface->pixels; return NULL; } // Unlock func static void unlockfct(void *data, void *id, void * const *p_pixels) { SDL_UnlockSurface(sdlStruct.sdlSurface); SDL_UnlockMutex(sdlStruct.sdlMutex); } /** * Entry point (main func) */ int main(int argc, char **argv) { // Init SDL + OpenGL if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTTHREAD) == -1) { return -1; } SDL_SetVideoMode(W, H, 16, SDL_OPENGL); glewInit(); glEnable(GL_TEXTURE_2D); glEnable(GL_DEPTH_TEST); // Init Texture glGenTextures(1, &textureId); glBindTexture(GL_TEXTURE_2D, textureId); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Init SDL_surface sdlStruct.sdlSurface = SDL_CreateRGBSurface(SDL_SWSURFACE, W, H, 16, 0xf800, 0x07e0, 0x001f, 0); sdlStruct.sdlMutex = SDL_CreateMutex(); // Init LibVLC + media player const char *vlc_argv[] = {}; int vlc_argc = sizeof(vlc_argv) / sizeof(*vlc_argv); libvlc_instance_t * libVlcInstance = libvlc_new(vlc_argc, vlc_argv); libvlc_media_t * media = libvlc_media_new_path(libVlcInstance, VIDEOFILE); libvlc_media_player_t * mediaPlayer = libvlc_media_player_new_from_media(media); libvlc_media_release(media); libvlc_release(libVlcInstance); libvlc_video_set_callbacks(mediaPlayer, lockfct, unlockfct, NULL, &sdlStruct); libvlc_video_set_format(mediaPlayer, "RV16", W, H, W*2); // Start reading the video libvlc_media_player_play(mediaPlayer); libvlc_state_t state = libvlc_media_player_get_state(mediaPlayer); while ((state != libvlc_Ended) && (state != libvlc_Error)) { loadTexture(); // Loading the texture // Square glBegin(GL_QUADS); glTexCoord2d(0, 1); glVertex2f(-0.75, 0.75); glTexCoord2d(1, 1); glVertex2f(0.75, 0.75); glTexCoord2d(1, 0); glVertex2f(0.75, -0.75); glTexCoord2d(0, 0); glVertex2f(-0.75, -0.75); glEnd(); SDL_GL_SwapBuffers(); state = libvlc_media_player_get_state(mediaPlayer); } // Frees libvlc_media_player_release(mediaPlayer); SDL_DestroyMutex(sdlStruct.sdlMutex); SDL_FreeSurface(sdlStruct.sdlSurface); SDL_Quit(); return 0; }
Maintenant, mon problème est que je désire optimiser tout cela. Aussi j'ai déplacé les appels aux fonctions OpenGL dans la fonction "unlockfct()" ce qui, à la fin, nous donne ceci :
Et là c'est le drame. Plus rien ne s'affiche. :/ Donc ma question est : Pourquoi ?
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 #include <GL/glew.h> #include <SDL/SDL.h> #include <vlc/vlc.h> #define VIDEOFILE "/home/test/resfiles/hd.mov" // The movie to read // WIDTH, HEIGHT #define W 800 #define H 800 GLuint textureId; // Texture ID // SDL Structure struct sdlStructure { SDL_Surface *sdlSurface; SDL_mutex *sdlMutex; }; struct sdlStructure sdlStruct; // Load a texture void loadTexture() { void * rawData = (void *) malloc(W * H * 4); Uint8 * pixelSource; Uint8 * pixelDestination = (Uint8 *) rawData; Uint32 pix; for (unsigned int i = H; i > 0; i--) { for (unsigned int j = 0; j < W; j++) { pixelSource = (Uint8 *) sdlStruct.sdlSurface->pixels + (i-1) * sdlStruct.sdlSurface->pitch + j * 2; pix = *(Uint16 *) pixelSource; SDL_GetRGBA(pix, sdlStruct.sdlSurface->format, &(pixelDestination[0]), &(pixelDestination[1]), &(pixelDestination[2]), &(pixelDestination[3])); pixelDestination += 4; } } // Building the texture glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glBindTexture(GL_TEXTURE_2D, textureId); glTexImage2D(GL_TEXTURE_2D, 0, 4, W, H, 0, GL_RGBA, GL_UNSIGNED_BYTE, (Uint8 *) rawData); free(rawData); } // Lock func static void * lockfct(void *data, void **p_pixels) { SDL_LockMutex(sdlStruct.sdlMutex); SDL_LockSurface(sdlStruct.sdlSurface); *p_pixels = sdlStruct.sdlSurface->pixels; return NULL; } // Unlock func static void unlockfct(void *data, void *id, void * const *p_pixels) { loadTexture(); // Loading the texture SDL_UnlockSurface(sdlStruct.sdlSurface); SDL_UnlockMutex(sdlStruct.sdlMutex); // Square glBegin(GL_QUADS); glTexCoord2d(0, 1); glVertex2f(-0.75, 0.75); glTexCoord2d(1, 1); glVertex2f(0.75, 0.75); glTexCoord2d(1, 0); glVertex2f(0.75, -0.75); glTexCoord2d(0, 0); glVertex2f(-0.75, -0.75); glEnd(); SDL_GL_SwapBuffers(); } /** * Entry point (main func) */ int main(int argc, char **argv) { // Init SDL + OpenGL if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTTHREAD) == -1) { return -1; } SDL_SetVideoMode(W, H, 16, SDL_OPENGL); glewInit(); glEnable(GL_TEXTURE_2D); glEnable(GL_DEPTH_TEST); // Init Texture glGenTextures(1, &textureId); glBindTexture(GL_TEXTURE_2D, textureId); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Init SDL_surface sdlStruct.sdlSurface = SDL_CreateRGBSurface(SDL_SWSURFACE, W, H, 16, 0xf800, 0x07e0, 0x001f, 0); sdlStruct.sdlMutex = SDL_CreateMutex(); // Init LibVLC + media player const char *vlc_argv[] = {}; int vlc_argc = sizeof(vlc_argv) / sizeof(*vlc_argv); libvlc_instance_t * libVlcInstance = libvlc_new(vlc_argc, vlc_argv); libvlc_media_t * media = libvlc_media_new_path(libVlcInstance, VIDEOFILE); libvlc_media_player_t * mediaPlayer = libvlc_media_player_new_from_media(media); libvlc_media_release(media); libvlc_release(libVlcInstance); libvlc_video_set_callbacks(mediaPlayer, lockfct, unlockfct, NULL, &sdlStruct); libvlc_video_set_format(mediaPlayer, "RV16", W, H, W*2); // Start reading the video libvlc_media_player_play(mediaPlayer); libvlc_state_t state = libvlc_media_player_get_state(mediaPlayer); while ((state != libvlc_Ended) && (state != libvlc_Error)) { state = libvlc_media_player_get_state(mediaPlayer); } // Frees libvlc_media_player_release(mediaPlayer); SDL_DestroyMutex(sdlStruct.sdlMutex); SDL_FreeSurface(sdlStruct.sdlSurface); SDL_Quit(); return 0; }
Merci et bonne journée. :]
Partager