fedora6 | bjone a écrit :
bin en fait à voir le code, je m'attendais a cette réponse
Il te faut le Platform SDK (Windows 2003), dedans tu auras le graphedit, et par exemple dans le graphedit en ouvrant un média, tu verras le graphe directshow construit automatiquement.
tu pourras ajouter des filtres intermédiaires et jouer avec les connections des pins, ça te donnera une représentation mentale de comment ça marche, ce qui est obligatoire avant d'essayer de coder quoique ce soit.
ensuite commence a potasser la doc:
http://msdn2.microsoft.com/en-us/l [...] S.85).aspx
Comme essai à coder, l'idée est d'abord de commencer par instancier une source, instancier un renderer, puis de connecter les deux avec le gestionnaire de graphe. puis d'incruster des filtres (dont le ISampleGrabber)
|
Bonjour J'ai besoin d'aide car j'ai toujours des problémes avec le SampleGrabber.
voila une partie de mon code source:
Les déclarations:
Code :
- long pBufferSize;
- unsigned char* pBuffer;
- unsigned char* buffer=0;
- unsigned char size = 640*576*3;
- unsigned int gWidth=0;
- unsigned int gHeight=0;
- unsigned int gChannels=0;
|
La fonction CaptureVideo() qui se charge de caputrer la video et qui fait appel à la fonction GrabData() qui me permet de récupérer le buffer(vers la fin de la fontion):
Code :
- HRESULT CCaptureVideo::CaptureVideo()
- {
- HRESULT hr;
- IBaseFilter *pSrcFilter=NULL;
- // Get DirectShow interfaces
- hr = GetInterfaces();
- if (FAILED(hr))
- {
- DisplayMesg(TEXT("Failed to get video interfaces! hr=0x%x" ), hr);
- return hr;
- }
- // Attach the filter graph to the capture graph
- hr = m_pCapture->SetFiltergraph(m_pGraph);
- if (FAILED(hr))
- {
- DisplayMesg(TEXT("Failed to set capture filter graph! hr=0x%x" ), hr);
- return hr;
- }
- // Use the system device enumerator and class enumerator to find
- // a video capture/preview device, such as a desktop USB video camera.
- hr = FindCaptureDevice(&pSrcFilter);
- if (FAILED(hr))
- {
- // Don't display a message because FindCaptureDevice will handle it
- return hr;
- }
- if( bDevCheck == FALSE)
- {
- return E_FAIL;
- }
- // Add Capture filter to our graph.
- hr = m_pGraph->AddFilter(pSrcFilter, L"Video Capture" );
- if (FAILED(hr))
- {
- DisplayMesg(TEXT("Couldn't add the capture filter to the graph! hr=0x%x\r\n\r\n" )
- TEXT("If you have a working video capture device, please make sure\r\n" )
- TEXT("that it is connected and is not being used by another application.\r\n\r\n" ), hr);
- pSrcFilter->Release();
- return hr;
- }
- // Create the Sample Grabber.
- hr = CoCreateInstance(CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER,
- IID_IBaseFilter, (void**) & pGrabberF);
- if (FAILED(hr)) {
- return hr;
- }
- hr = m_pGraph->AddFilter(pGrabberF, L"Sample Grabber" );
- if (FAILED(hr)) {
- return hr;
- }
- pGrabberF->QueryInterface(IID_ISampleGrabber, (void**)&pGrabber);
-
- AM_MEDIA_TYPE mt;
- ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE));
- mt.majortype = MEDIATYPE_Video;
- mt.subtype = MEDIASUBTYPE_RGB24;
- hr = pGrabber->SetMediaType(&mt);
- if (FAILED(hr)) {
- return hr;
- }
- hr = pGrabber->SetOneShot(FALSE);
- hr = pGrabber->SetBufferSamples(TRUE);
- hr = pSrcFilter->QueryInterface(IID_IAMVideoProcAmp, (void**)&pProcAmp);
- ConfigRenderer();
- // Add Renderer filter to our graph.
- hr = m_pGraph->AddFilter(pVmr, L"VMR9" );
- // Render the preview pin on the video capture filter
- // Use this instead of m_pGraph->RenderFile
- hr = m_pCapture->RenderStream (&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video,
- pSrcFilter,pGrabberF, pVmr);
- if (FAILED(hr))
- {
- DisplayMesg(TEXT("Couldn't render the video capture stream. hr=0x%x\r\n" )
- TEXT("The capture device may already be in use by another application.\r\n\r\n" )
- TEXT("The sample will now close." ), hr);
- pSrcFilter->Release();
- return hr;
- }
- hr = pGrabber->GetConnectedMediaType(&mt);
- if (FAILED(hr)) {
- return hr;
- }
- VIDEOINFOHEADER *pVih = (VIDEOINFOHEADER *)mt.pbFormat;
- gChannels = pVih->bmiHeader.biBitCount / 8;
- gWidth = pVih->bmiHeader.biWidth;
- gHeight = pVih->bmiHeader.biHeight;
- // Now that the filter has been added to the graph and we have
- // rendered its stream, we can release this reference to the filter.
- pSrcFilter->Release();
- #ifdef REGISTER_FILTERGRAPH
- // Add our graph to the running object table, which will allow
- // the GraphEdit application to "spy" on our graph
- hr = AddGraphToRot(m_pGraph, &m_dwGraphRegister);
- if (FAILED(hr))
- {
- DisplayMesg(TEXT("Failed to register filter graph with ROT! hr=0x%x" ), hr);
- m_dwGraphRegister = 0;
- }
- #endif
- // Start previewing video data
- hr = m_pMC->Run();
- if (FAILED(hr))
- {
- DisplayMesg(TEXT("Couldn't run the graph! hr=0x%x" ), hr);
- return hr;
- }
- // Remember current state
- m_psCurrent = RUNNING;
- FILE *stream;
- buffer = new unsigned char[size];
- for(int i=0;i<5;i++)
- {
- Sleep(100);
- buffer = GrabData();
- if (buffer!=NULL)
- {
- stream=fopen("c:\somefile.txt","w+" );
- //fwrite(buffer,3,sizeof(buffer),stream);
- fprintf(stream,"%s",buffer);
- fclose(stream);
- }
- }
- unsigned char image=GetImage();
- return S_OK;
- }
|
La fonction GrabData() qui me permet de récupérer le buffer:
Code :
- unsigned char* CCaptureVideo::GrabData()
- {
- HRESULT hr;
- if (pGrabber == 0)
- return 0;
- long Size = 0;
- hr = pGrabber->GetCurrentBuffer(&Size, NULL);
- if (FAILED(hr))
- return 0;
- else if (Size != pBufferSize) {
- pBufferSize = Size;
- if (pBuffer != 0)
- delete[] pBuffer;
- pBuffer = new unsigned char[pBufferSize];
- }
- hr = pGrabber->GetCurrentBuffer(&pBufferSize, (long*)pBuffer);
- if (FAILED(hr))
- {
- return 0;
- }
- else {
- return pBuffer;
- }
- }
|
La fonction qui me permet de lire une bitmap:
Code :
- unsigned char * CCaptureVideo::LoadBitmapFile(char *filename, BITMAPINFOHEADER *bitmapInfoHeader)
- {
- FILE *filePtr; // Le pointeur du fichier
- BITMAPFILEHEADER bitmapFileHeader; // En-tête du fichier bitmap
- unsigned char *bitmapImage; // Données du fichier bitmap
- int imageIdx = 0; // image index counter
- unsigned char tempRGB; // Variable temporaire de permutation BGR -> RGB
- // Ouvre le fichier en lecture binaire
- filePtr = fopen(filename, "rb" );
- if (filePtr == NULL)
- { // Si l'ouverture du fichier ne s'est pas dérouler correctement, on quitte la fonction
- return NULL; // On quitte la fonction en renvoyant un NULL
- }
- // Lecture de l'en-tête de fichier
- fread(&bitmapFileHeader, sizeof(BITMAPFILEHEADER), 1, filePtr);
- // On vérifie que le fichier est bien de type Bitmap
- if (bitmapFileHeader.bfType != BITMAP_ID)
- {
- fclose(filePtr); // Fermeture du fichier
- return NULL; // On quitte la fonction en renvoyant NULL
- }
- // Lecture des l'en-tête d'informations du Bitmap
- fread(bitmapInfoHeader, sizeof(BITMAPINFOHEADER), 1, filePtr);
- // Vérification de la compression. Doit être égal à BI_RGB
- if (bitmapInfoHeader->biCompression != BI_RGB)
- {
- fclose(filePtr); // Fermeture du fichier
- return NULL; // On quitte la fonction en renvoyant NULL
- }
- // Allocation de la mémoire pour contenir les données de l'image
- bitmapImage = (unsigned char*)malloc(bitmapInfoHeader->biSizeImage);
- // On vérifie l'allocation de la mémoire
- if (!bitmapImage)
- {
- free(bitmapImage); // Libération de la mémoire
- fclose(filePtr); // Fermeture du fichier
- return NULL; // Renvoie de NULL
- }
- // On place le pointeur du fichier au début des données du bitmap
- fseek(filePtr, bitmapFileHeader.bfOffBits, SEEK_SET);
- // Lecture des données de l'image
- fread(bitmapImage, 1, bitmapInfoHeader->biSizeImage, filePtr);
- // On s'assure que les données de l'image aient bien été lues
- if (bitmapImage == NULL)
- {
- fclose(filePtr); // Fermeture du fichier
- return NULL; // Renvoie de NULL
- }
- // Inversion du rouge et du bleu BGR -> RGB
- for (imageIdx = 0; imageIdx < bitmapInfoHeader->biSizeImage; imageIdx+=3)
- {
- tempRGB = bitmapImage[imageIdx];
- bitmapImage[imageIdx] = bitmapImage[imageIdx + 2];
- bitmapImage[imageIdx + 2] = tempRGB;
- }
- fclose(filePtr); // Fermeture du fichier
- return bitmapImage; // Renvoie des données de l'image
- }
|
La fonction qui me permet d'écrire une bitmap:
Code :
- BOOL CCaptureVideo::WriteBitmapFile(char *filename, int width, int height, unsigned char *imageData)
- {
- FILE *filePtr; // Pointeur de fichier
- BITMAPFILEHEADER bitmapFileHeader; // En-tête de fichier
- BITMAPINFOHEADER bitmapInfoHeader; // En-tête d'informations
- unsigned char tempRGB; // Variable temporaire pour changer BGR -> RGB
- // Ouverture du fichier en mode écriture binaire
- filePtr = fopen(filename, "wb" );
- if (!filePtr)
- return FALSE;
- // Définition de tous les champs des en-tête
- // En-tête de fichier BITMAPFILEHEADER
- bitmapFileHeader.bfSize = sizeof(BITMAPFILEHEADER);
- bitmapFileHeader.bfType = 0x4D42;
- bitmapFileHeader.bfReserved1 = 0;
- bitmapFileHeader.bfReserved2 = 0;
- bitmapFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
- // En-tête d'informations
- bitmapInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
- bitmapInfoHeader.biPlanes = 1;
- bitmapInfoHeader.biBitCount = 24;
- bitmapInfoHeader.biCompression = BI_RGB;
- bitmapInfoHeader.biSizeImage = width * abs(height) * 3;
- bitmapInfoHeader.biXPelsPerMeter = 0;
- bitmapInfoHeader.biYPelsPerMeter = 0;
- bitmapInfoHeader.biClrUsed = 0;
- bitmapInfoHeader.biClrImportant = 0;
- bitmapInfoHeader.biWidth = width;
- bitmapInfoHeader.biHeight = height;
- // Inversion des composants RGB -> BGR
- for (unsigned int i = 0; i < bitmapInfoHeader.biSizeImage; i += 3)
- {
- tempRGB = imageData[i];
- imageData[i] = imageData [i + 2];
- imageData[i + 2] = tempRGB;
- }
- // Ecriture de l'en-tête de fichier
- fwrite(&bitmapFileHeader, 1, sizeof(BITMAPFILEHEADER), filePtr);
- // Ecriture de l'en-tête d'informations
- fwrite(&bitmapInfoHeader, 1, sizeof(BITMAPINFOHEADER), filePtr);
- // Ecriture des données de l'image
- fwrite(imageData, 1, bitmapInfoHeader.biSizeImage, filePtr);
-
- fclose(filePtr); // fermeture du fichier
- return TRUE;
- }
|
La fonction GetIamge():
Code :
- unsigned char CCaptureVideo::GetImage()
- {
- FILE* stream;
- BITMAPINFOHEADER bitmapInfoHeader;
- unsigned char* bitmapData;
- bitmapData = LoadBitmapFile("C:\search.bmp", &bitmapInfoHeader);
- if(bitmapData!=0)
- {
- bool write;
- write = WriteBitmapFile("c:\imagewrite",760,576,bitmapData);
- stream = fopen("wahiba.txt","w+" );
- fprintf(stream,"%s",bitmapData);
- fclose(stream);
- }
- return (unsigned char)bitmapData;
- }
|
Au début je veux bien m'excuser d'avoir envoyé tout à la fois.
Mes problémes sont les suivants:
1. le buffer récupérer par la fonction GrabData() n'est pas de taille fixe, j'essaye de l'écrire dans un fichier texte et le nombre des caractéres écrits est considérablement variable(entre 12000 et 180000), alors je pense qu'il n'est pas entrain de récupérer une image car la taille doit être fixe (largeur*hauteur*3(RGB)=640*576*3)
alors je voulais savoir où est le probléme et si mon raisonnement est correcte ou pas???????
2. Alors vu que la récupération du buffer est bloquée et que je dois avancé dans la projet j'ai essayé de lire une image sur le disque dûr pour pouvoir continuer par la suite(j'ai besoin d'une image pour le reste du projet) alors j'utilise la fonction LoadBitmap avec une image enregistrée dans le repertoire du projet et d'essayer de la écrire dans un fichier juste pour vérifier et de la réecrire une autre fois avec la fonction WriteBitmap, le probléme est que cette fonction fonctionne correctement une fois dans un fichier .cpp tout seule(contenant uniquement LoadbitmapFile, WritebitmapFile et GetImage) mais dans mon programme le fichier
contenant l'image ne s'ouvre même pas(j'ai vérifié le chemin).
Alors si vous pouvez m'aider je serai vraiment trés reconnaissante et merci d'avance. ---------------
fedora6
|