Bonjour,
je souhaiterais savoir comment obtenir le nombre d'image total d'une vidéo avec DirectShow et l'image courante affiché de celle-ci....
merci.
![]()
Bonjour,
je souhaiterais savoir comment obtenir le nombre d'image total d'une vidéo avec DirectShow et l'image courante affiché de celle-ci....
merci.
![]()
Salut.
Les deux questions sont vagues pour moi. Précises un peu plus ce que tu veux faire et comment.
Pour répondre à la première question, tu peux connaître le nombre de trame lue par le filtre de rendu:
graphedit->propriete "filter renderer"->nombre de trames.
Le nombre de trames se rafraîchit pendant la lecture de la vidéo, à la fin tu as le nombre total.
Open Source Microsoft MediaFoundation
https://github.com/mofo7777
http://jeux.developpez.com/faq/directx/?page=dshow
Je veux en fait savoir, AVANT de lancer (affichage écran) la vidéo chargée,
- combien d'images contient la vidéo : ok pour ta réponse! mais j'ai cherché la méthode qui s'en rapprocherais le plus dans ces objets ci sans résultat! (peut être que la réponse n'est pas là!)
IGraphBuilder *pGraph = NULL;
IMediaControl *pControl = NULL;
IMediaEvent *pEvent = NULL;
UNE FOIS la vidéo chargée ET LANCEE, je souhaiterais savoir à quel ("frame") image j'en suis, sur le nombre total d'images de la vidéo.
Ici encore je n'ai pas de réponse!
Voici mon code (simpliste pour l'instant) :
merci.
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 #include <windows.h> #include <stdio.h> #include "DShow.h" void main(void) { IGraphBuilder *pGraph = NULL; IMediaControl *pControl = NULL; IMediaEvent *pEvent = NULL; // Initialize the COM library. HRESULT hr = CoInitialize(NULL); if (FAILED(hr)) { printf("ERROR - Could not initialize COM library"); return; } // Create the filter graph manager and query for interfaces. hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&pGraph); if (FAILED(hr)) { printf("ERROR - Could not create the Filter Graph Manager."); return; } hr = pGraph->QueryInterface(IID_IMediaControl, (void **)&pControl); hr = pGraph->QueryInterface(IID_IMediaEvent, (void **)&pEvent); // Build the graph. IMPORTANT: Change this string to a file on your system. hr = pGraph->RenderFile(L"D:\\OpenGL\\DEMO 3D\\LadyOfDarkAutumn.avi", NULL); if (SUCCEEDED(hr)) { // Run the graph. hr = pControl->Run(); if (SUCCEEDED(hr)) { // Wait for completion. long evCode; pEvent->WaitForCompletion(INFINITE, &evCode); // Note: Do not use INFINITE in a real application, because it // can block indefinitely. } } pControl->Release(); pEvent->Release(); pGraph->Release(); CoUninitialize(); }
![]()
Re.
L'interface IMediaSeeking est ton amie. Tu peux l'utiliser en mode TIME_FORMAT_FRAME ou en mode TIME_FORMAT_MEDIA_TIME.
La méthode qui t'intéresse :
Il y en a d'autres, pour faire le reste, mais je te laisse découvrir.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 IMediaSeeking::GetDuration HRESULT GetDuration(LONGLONG *pDuration);
Aller, je suis sympa ce soir je te donne l'autre:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 IMediaSeeking::GetCurrentPosition HRESULT GetCurrentPosition(LONGLONG *pCurrent);
Open Source Microsoft MediaFoundation
https://github.com/mofo7777
http://jeux.developpez.com/faq/directx/?page=dshow
ARG!!
Quand je fait un GetDuration() de IMediaSeeking,
il m'affiche un nombre à 9 chiffres comme celui que j'ai récupéré:
"220560452"!!
pourquoi un tel nombre!!
![]()
![]()
Quel format de temps as-tu utilisé?
Par défaut, c'est le TIME_FORMAT_MEDIA_TIME qui est utilisé et dont les valeurs sont en "(100-nanosecond units)". Tu dois utiliser le format TIME_FORMAT_FRAME pour avoir les valeurs en nombre de frames.
Je te conseilles de lire les spécifications de l'interface IMediaSeeking, tout y est expliqué.
Si tu veux que je te donne la solution, alors postes le code concerné.
Open Source Microsoft MediaFoundation
https://github.com/mofo7777
http://jeux.developpez.com/faq/directx/?page=dshow
Bonjour tous le monde et toi moldavi.![]()
J'ai en fait 2 problèmes pour être clair![]()
1°) J'ai un problème pour la méthode :
( pSeek de type IMediaSeeking* initialisé à NULL )
- pSeek->SetTimeFormat( GUID* format );
je crée donc une variable de pointeur de type GUID et j'essaie de la remplir... mais arg! dans MSDN il ne décrit pas la structure GUID !!
il y a 4 "Data" (je sais ce qui faut y mettre dedans!)
-> J'ai fait d'autres recherches .... en vain !!![]()
moi qui m'attendais à une simple constante comme :
TIME_FORMAT_MEDIA_TIME ou TIME_FORMAT_FRAME, ....
ben non! je n'appelle peut être pas la bonne méthode!
GRRRR!
2°) Je n'arrive pas à positionner la vidéo sur une image clé avant de commencer à la lire ( méthode run() )
Pour positionner le curseur vidéo sur une image X, je fait: pSeek->SetPositions( &pos, AM_SEEKING_AbsolutePositioning,
NULL,AM_SEEKING_AbsolutePositioning )
avec pos = 2, 8, 50, ...; de type "LONGLONG".
Et ca marche po!!![]()
![]()
Voilà où j'en suis....
Je donne le code:
( NOTE: A tout ce qui veulent débuter et se mettre à directshow, télécharger le SDK de directx 9.0 xxx (230 et quelques Mo), directshow est inclut. Ce code seul marche et vous pouver le copier/coller dans un seul fichier; pour le reste aller sur CodeProject, MSDN, et Google, ....)
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 #include <windows.h> #include <stdio.h> #include "DShow.h" void main(void) { IGraphBuilder *pGraph = NULL; IMediaControl *pControl = NULL; IMediaEvent *pEvent = NULL; IMediaSeeking *pSeek = NULL; // Initialize the COM library. HRESULT hr = CoInitialize(NULL); if (FAILED(hr)) { printf("ERROR - Could not initialize COM library"); return; } // Create the filter graph manager and query for interfaces. hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&pGraph); if (FAILED(hr)) { printf("ERROR - Could not create the Filter Graph Manager."); return; } hr = pGraph->QueryInterface(IID_IMediaControl, (void **)&pControl); hr = pGraph->QueryInterface(IID_IMediaEvent, (void **)&pEvent); hr = pGraph->QueryInterface(IID_IMediaSeeking, (void **)&pSeek); // Build the graph. IMPORTANT: Change this string to a file on your system. hr = pGraph->RenderFile(L"D:\\OpenGL\\DEMO 3D\\DEMOS D'ARTISTE\\LadyOfDarkAutumn.avi", NULL); if (SUCCEEDED(hr)) { // nb images totales LONGLONG duration = 0; pSeek->GetDuration( &duration ); TCHAR s[64]; wsprintf( s, "%d", duration ); MessageBox( NULL, s, "DURATION", MB_OK ); // Run the graph. hr = pControl->Run(); if (SUCCEEDED(hr)) { LONGLONG pos = duration; [color=red][b]pSeek->SetPositions( &pos, AM_SEEKING_AbsolutePositioning, NULL,AM_SEEKING_AbsolutePositioning );[/b][/color] // Wait for completion. long evCode; pEvent->WaitForCompletion(INFINITE, &evCode); // Note: Do not use INFINITE in a real application, because it // can block indefinitely. } } pControl->Release(); pEvent->Release(); pGraph->Release(); CoUninitialize(); }
![]()
![]()
Je vais mieux regarder ton code.
Ce que je vois ici en premier lieu, c'est que tu lances la lecture puis tu te positionnes aussitôt à la fin du fichier.
Ben ça doit être normal qu'il ne se passe rien, non?![]()
Open Source Microsoft MediaFoundation
https://github.com/mofo7777
http://jeux.developpez.com/faq/directx/?page=dshow
Ah, ca!
non, j'ai testé plein de chose avant de tester le positionnement à la fin de la vidéo!
Voici du code qui fonctionne chez moi. J'ai utilisé un fichier .avi qui traînait sur mon PC (je pense qu'il est fournit avec XP).
Avant de lancer la lecture, je vérifie les capacités de l'interface IMediaSeeking afin d'être sur que je peux bricoler dans le fichier.
Le code ci-dessous peut paraître décalé, normal c'est parce que j'utilise un positionnement de code particulier, et que j'ai fait un copier-coller.
J'ai mis les variables en globale afin d'utiliser des fonctions externes. En C++ je fais différemment.
J'utilise VC++, donc si tu compiles en C, modifies les bricoles qui ne vont pas dans l'en-tête:
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
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267 #pragma once #define WIN32_LEAN_AND_MEAN #define STRICT #define _WIN32_WINNT 0x0501 #pragma warning(disable : 4995) #ifdef _DEBUG #pragma comment(lib, "strmbasd") #else #pragma comment(lib, "strmbase") #endif #include <windows.h> #include <stdio.h> #include "dshow.h" IGraphBuilder* g_pGraph = NULL; IMediaControl* g_pControl = NULL; IMediaEvent* g_pEvent = NULL; IMediaSeeking* g_pSeek = NULL; void ReleaseInterface(){ if(g_pSeek) g_pSeek->Release(); if(g_pControl) g_pControl->Release(); if(g_pEvent) g_pEvent->Release(); if(g_pGraph) g_pGraph->Release(); CoUninitialize(); } bool GetCapbilities(){ HRESULT hr = S_OK; DWORD dwCaps = 0; hr = g_pSeek->GetCapabilities(&dwCaps); if(FAILED(hr)) return false; if(dwCaps & AM_SEEKING_CanSeekAbsolute) printf("IMediaSeeking can seek Absolute\n"); else printf("ERROR. IMediaSeeking can't seek Absolute\n"); if(dwCaps & AM_SEEKING_CanSeekForwards) printf("IMediaSeeking can seek Forwards\n"); else printf("ERROR. IMediaSeeking can't seek Forwards\n"); if(dwCaps & AM_SEEKING_CanSeekBackwards) printf("IMediaSeeking can seek Backwards\n"); else printf("ERROR. IMediaSeeking can't seek Backwards\n"); if(dwCaps & AM_SEEKING_CanGetCurrentPos) printf("IMediaSeeking can Get Current position\n"); else printf("ERROR. IMediaSeeking can't Get Current position\n"); if(dwCaps & AM_SEEKING_CanGetStopPos) printf("IMediaSeeking can Get Stop position\n"); else printf("ERROR. IMediaSeeking can't Get Stop position\n"); if(dwCaps & AM_SEEKING_CanGetDuration) printf("IMediaSeeking can Get Duration\n"); else printf("ERROR. IMediaSeeking can't Get Duration\n"); if(dwCaps & AM_SEEKING_CanPlayBackwards) printf("IMediaSeeking can Play Backwards\n"); else printf("ERROR. IMediaSeeking can't Play Backwards\n"); if(dwCaps & AM_SEEKING_CanDoSegments) printf("IMediaSeeking can Do Segments\n"); else printf("ERROR. IMediaSeeking can't Do Segments\n"); //if(dwCaps & AM_SEEKING_Source) //printf("IMediaSeeking can Get Source"); return true; } void CheckFormatSupported(){ HRESULT hr = S_OK; hr = g_pSeek->IsFormatSupported(&TIME_FORMAT_NONE); if(SUCCEEDED(hr)) printf("TIME_FORMAT_NONE is supported\n"); else printf("ERROR. TIME_FORMAT_NONE is not supported\n"); hr = g_pSeek->IsFormatSupported(&TIME_FORMAT_FRAME); if(SUCCEEDED(hr)) printf("TIME_FORMAT_FRAME is supported\n"); else printf("ERROR. TIME_FORMAT_FRAME is not supported\n"); hr = g_pSeek->IsFormatSupported(&TIME_FORMAT_SAMPLE); if(SUCCEEDED(hr)) printf("TIME_FORMAT_SAMPLE is supported\n"); else printf("ERROR. TIME_FORMAT_SAMPLE is not supported\n"); hr = g_pSeek->IsFormatSupported(&TIME_FORMAT_FIELD); if(SUCCEEDED(hr)) printf("TIME_FORMAT_FIELD is supported\n"); else printf("ERROR. TIME_FORMAT_FIELD is not supported\n"); hr = g_pSeek->IsFormatSupported(&TIME_FORMAT_BYTE); if(SUCCEEDED(hr)) printf("TIME_FORMAT_BYTE is supported\n"); else printf("ERROR. TIME_FORMAT_BYTE is not supported\n"); hr = g_pSeek->IsFormatSupported(&TIME_FORMAT_MEDIA_TIME); if(SUCCEEDED(hr)) printf("TIME_FORMAT_MEDIA_TIME is supported\n"); else printf("ERROR. TIME_FORMAT_MEDIA_TIME is not supported\n"); } void CheckCurrentFormat(){ GUID gformat; HRESULT hr = S_OK; hr = g_pSeek->GetTimeFormat(&gformat); if(SUCCEEDED(hr)){ if(gformat == TIME_FORMAT_NONE) printf("format en cours : TIME_FORMAT_NONE\n"); else if(gformat == TIME_FORMAT_FRAME) printf("format en cours : TIME_FORMAT_FRAME\n"); else if(gformat == TIME_FORMAT_SAMPLE) printf("format en cours : TIME_FORMAT_SAMPLE\n"); else if(gformat == TIME_FORMAT_FIELD) printf("format en cours : TIME_FORMAT_FIELD\n"); else if(gformat == TIME_FORMAT_BYTE) printf("format en cours : TIME_FORMAT_BYTE\n"); else if(gformat == TIME_FORMAT_MEDIA_TIME) printf("format en cours : TIME_FORMAT_MEDIA_TIME\n"); else printf("format en cours : Bizarre\n"); } } void main(){ HRESULT hr = S_OK; // CoInitialize est obsolète, de plus dans ton code il n'était pas utilisé avec les bons paramètres hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); if(FAILED(hr)){ printf("ERROR - Could not initialize COM library\n"); return; } hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void**)&g_pGraph); if(FAILED(hr)){ printf("ERROR - Could not create the Filter Graph Manager.\n"); return; } hr = g_pGraph->QueryInterface(IID_IMediaControl, (void **)&g_pControl); if(FAILED(hr)){ printf("ERROR - Could not Get IMediaControl interface.\n"); ReleaseInterface(); return; } hr = g_pGraph->QueryInterface(IID_IMediaEvent, (void **)&g_pEvent); if(FAILED(hr)){ printf("ERROR - Could not Get IMediaEvent interface.\n"); ReleaseInterface(); return; } hr = g_pGraph->QueryInterface(IID_IMediaSeeking, (void **)&g_pSeek); if(FAILED(hr)){ printf("ERROR - Could not Get IMediaSeeking interface.\n"); ReleaseInterface(); return; } // Build the graph. IMPORTANT: Change this string to a file on your system. hr = g_pGraph->RenderFile(L"FishTank.avi", NULL); if(SUCCEEDED(hr)){ if(!GetCapbilities()){ printf("ERROR - Could not Get the capabilities of IMediaSeeking interface.\n"); ReleaseInterface(); return; } CheckFormatSupported(); hr = g_pSeek->SetTimeFormat(&TIME_FORMAT_FRAME); if(SUCCEEDED(hr)) printf("TIME_FORMAT_FRAME OK\n"); else printf("ERROR - TIME_FORMAT_FRAME\n"); CheckCurrentFormat(); // nb images totales LONGLONG duration = 0LL; hr = g_pSeek->GetDuration(&duration); if(SUCCEEDED(hr)){ TCHAR s[64]; sprintf(s, "%d", duration); MessageBox(NULL, s, "DURATION", MB_OK); } // On se positionne à la moitié du fichier LONGLONG pos = duration / 2LL; hr = g_pSeek->SetPositions(&pos, AM_SEEKING_AbsolutePositioning | AM_SEEKING_ReturnTime, NULL, AM_SEEKING_NoPositioning); if(SUCCEEDED(hr)) printf("Positionnement en milieu de fichier OK\n"); else printf("ERROR. Positionnement en milieu de fichier a échoué\n"); // Run the graph. hr = g_pControl->Run(); if(SUCCEEDED(hr)){ // Wait for completion. long evCode; g_pEvent->WaitForCompletion(INFINITE, &evCode); // Note: Do not use INFINITE in a real application, because it // can block indefinitely. } } ReleaseInterface(); }
Open Source Microsoft MediaFoundation
https://github.com/mofo7777
http://jeux.developpez.com/faq/directx/?page=dshow
Je ne sais pas si c'est spécifique au format .avi, en tout cas la méthode GetCurrentPosition n'est pas supportée.
Il va falloir bidouiller avec la méthode GetPositions qui fait à peu près la même chose.
Open Source Microsoft MediaFoundation
https://github.com/mofo7777
http://jeux.developpez.com/faq/directx/?page=dshow
Merci pour ce code!
par contre j'aurais une dernière question à te poser:
- après qu'une frame (image) aie été affiché à l'écran, je souhaiterais retoucher l'image ( je crois le dc principale "device context" associé au bitmap fera l'affaire )
Qu'en penses-tu (et qu'en pensez-vous) ?
![]()
Bonjour,
Il me manque gros problème que j'arriva pas à résoudre lancer ce code en utilisant un projet MFC boite de dialogue ou single document.
la fonction CoInitializeEx() n'est pas reconnu !!
-> il me met : indeclared identifier !!!!!!!!!!!!!!!
je comprend pas là !
![]()
![]()
C'est avec cette ligne de code que cette fonction est reconnue par le compilateur:Envoyé par cyber_N
Regarder aussi du côté d'une directive genre "WIN32_DCOM" ou un truc comme ça.
Code : Sélectionner tout - Visualiser dans une fenêtre à part #define _WIN32_WINNT 0x0501
Pour les projets MFC, c'est pas trop ma tasse de thé, alors la méthode est peut-être différente . Mais avec un peu de recherche, ce problème devrait être résolu assez rapidement.
Open Source Microsoft MediaFoundation
https://github.com/mofo7777
http://jeux.developpez.com/faq/directx/?page=dshow
Va falloir me précisez exactement ce que tu veux faire, car j'ai peur que tu ne t'engages dans des choses compliquées à réaliser de la sorte, ou avec des performances médiocres.Envoyé par cyber_N
Open Source Microsoft MediaFoundation
https://github.com/mofo7777
http://jeux.developpez.com/faq/directx/?page=dshow
Bonjour,
la fonction non reconnue se trouve dans:
#include "OBJBASE.H"
Même si je déclare cette en-tête il refuse encore!! (indeclared identifier)
J'arrive à lancer le programme en réécriavnt ce qui se trouve dans ce .h
ce code se trouve normallement dans OBJBASE.H, mais il se trouve maitenant dans mon projet:
Vraiment bizarre!!
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 WINOLEAPI CoInitializeEx(LPVOID pvReserved, DWORD dwCoInit); #define COINIT_MULTITHREADED 0x0 // OLE calls objects on any thread.
J'ai eu récemment un problème / si on peux parler de problème d'ailleurs.... (le dernier je pense)
La vidéo se lance dans une autre fenetre!! j'aimerais bien qu'elle se lance dans la fenetre que je crée (ou par défaut).
!!
![]()
Si tu zieutes un peu le fichier, voici ce qu'il y a:Envoyé par cyber_N
J'en conclu que _WIN32_DCOM n'est pas définit ou que _WIN32_WINNT < 0x0400.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 #if (_WIN32_WINNT >= 0x0400 ) || defined(_WIN32_DCOM) // DCOM /* #!perl PoundIf("CoInitializeEx", "(_WIN32_WINNT >= 0x0400 ) || defined(_WIN32_DCOM)"); */ WINOLEAPI CoInitializeEx(IN LPVOID pvReserved, IN DWORD dwCoInit); /* #!perl PoundIf("CoGetCallerTID", "(_WIN32_WINNT >= 0x0400 ) || defined(_WIN32_DCOM)"); */ WINOLEAPI CoGetCallerTID( LPDWORD lpdwTID ); #endif // DCOM
Projet -> propriété-> C/C++ -> préprocesseur -> définitions de préprocesseur -> _WIN32_DCOM.
Si ça ne marche pas, c'est que tu as un #undef qui traîne ou alors que tu n'as pas de chance...
Je ne vais pas faire tout ton projet. Mon tarif habituel, c'est une bouteille de ricard (ça tombe bien je n'en ai plusEnvoyé par cyber_N
).
Open Source Microsoft MediaFoundation
https://github.com/mofo7777
http://jeux.developpez.com/faq/directx/?page=dshow
Déjà .... je ne bois pas ou très très peu! (1 peu de vin, ca entretien le coeur)
ensuite, la notion de "tarif" n'existe pas sur ces forums!![]()
et finalement je trouve désobligeant de devoir en arriver à l'alcool![]()
surtout le ricard!(pire l'abseinte ou le rhum)
![]()
Moi .... enfin, personnellement .... je puise mon inspiration autrepart ....
![]()
Sniff! Allez, Un dernier tuyau, un petit petit ............![]()
![]()
Le mot tarif est à prendre au sens de récompense. Je respecte les gens qui ne boivent pas. Tout n'est qu'affaire de tolérance les uns vis-à-vis des autres.
Pour ton problème, je te renvoie à l'exemple du SDK "playwnd", qui comme son nom l'indique veut dire : "jouer dans une fenêtre (window)".
Les interfaces "IVideoWindow" et "IBasicVideo" sont tes nouveaux amies.
Open Source Microsoft MediaFoundation
https://github.com/mofo7777
http://jeux.developpez.com/faq/directx/?page=dshow
Partager