2013-02-07 5 views
0

Je voudrais être en mesure de chercher une image arbitraire dans un fichier MPEG-2 (à partir de DVD, je suppose que cela s'appelle MPEG-2 Program Stream). Jusqu'à présent, j'utilisais OpenCV 2.1 pour accéder à ces images, mais cela ne fonctionnait que trame par image (seulement en recherche directe). Plus tard, lorsque j'ai installé OpenCV 2.3.1, cette possibilité a été perdue, c'est-à-dire limitée à AVI. De toute façon, j'aimerais le faire sans OpenCV. J'ai réussi à chercher des images-clés (je suppose) ou à tous les trames (par exemple toutes les 12 images). Maintenant, en regardant VirtualDub cadre recherche précise est possible. Il dit: '' analyser le fichier MPEG-2 entrelacé ''. Qu'est-ce que cela signifie exactement et où devrais-je commencer à faire de même? Est-ce légal même, je me souviens avoir lu quelque chose à ce sujet quelque part, je ne m'en souviens pas vraiment. Je programme en C++ en utilisant DirectShow. Autant que je sache, DirectShow ne le fera pas. Ensuite, je regardais CBaseFilter, la méthode streamtime, etc. Mais avant de plonger dans ce sujet complexe, j'aimerais savoir si c'est la bonne façon de procéder. Dans l'attente de vos réponses, merci!MPEG-2 cherchant par où commencer?

@ Geraint: extrait de code de filtre graphique:

CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC,IID_IGraphBuilder,(LPVOID *)&pGraphBuilder); 
CoCreateInstance(CLSID_MPEG2Demultiplexer,NULL,CLSCTX_INPROC,IID_IBaseFilter,(LPVOID *)&pib); 
CoCreateInstance(CLSID_CMPEG2VidDecoderDS,NULL,CLSCTX_INPROC,IID_IBaseFilter,(LPVOID *)&pib2); 

pGraphBuilder->AddFilter(pib,L"Sample Splitter"); 
pGraphBuilder->AddFilter(pib2,L"Sample Decoder"); 

ZeroMemory(&am_media_type, sizeof(am_media_type)); 
am_media_type.majortype = MEDIATYPE_Video; 
am_media_type.subtype = MEDIASUBTYPE_MPEG2_VIDEO; 
am_media_type.formattype = FORMAT_MPEG2Video; 

pGraphBuilder->QueryInterface(IID_IMediaControl,(LPVOID *)&pMediaControl); 
pGraphBuilder->QueryInterface(IID_IMediaSeeking, (void**)(&pMediaSeeking)); 
pGraphBuilder->QueryInterface(__uuidof(IVideoFrameStep), (PVOID *)&fst); 
pGraphBuilder->QueryInterface(IID_IMediaEvent, (void **)&imev); 
pGraphBuilder->QueryInterface(IID_IBasicVideo,(LPVOID *)&ibv); 

pGraphBuilder->RenderFile(FILENAME,0); 

puis-je utiliser IMediaSeeking de rechercher la vid. J'ai aussi essayé le pas de cadre (d'où les références ci-dessus).

+0

Vous dites que vous voulez rechercher une image arbitraire. Mais que veux-tu faire après avoir cherché? Est-ce que ce cadre devrait par exemple être affiché sur votre écran? Fondamentalement, j'aime savoir que vous voulez chercher dans le train de bits mpeg compressé, ou voulez-vous chercher à l'intérieur des images vidéo décodées? – wimh

+0

bien, j'ai mentionné OpenCV (Computer '' Vision ''), donc vous pouvez imaginer que je veux chercher les cadres décodés :-) – user1331044

Répondre

3

DirectShow est capable de fournir une recherche précise. Toutefois, sans un index, il est basé sur un décalage temporel par rapport au début du fichier, et non sur un nombre d'images.

Utilisez IMediaSeeking pour définir l'heure de début. Le demux débutera la livraison des trames compressées avant cela. Le décodeur commencera le décodage à l'image clé précédente mais rejettera toutes les images qui sont avant le point de départ choisi.

G

+0

Hi Geraint, J'ai mis en place une barre de recherche qui affiche le cadre choisi. Pour ce faire, j'utilise IMediaSeeking :: SetPositions jusqu'à présent avec TIME_FORMAT_MEDIA_TIME (par défaut), je pense que c'est ce que vous suggérez, n'est-ce pas? Avec AVI c'est bien, mais quand je cherche dans une vidéo MPEG-2, cela ne m'amène qu'aux images-clés, même si j'indique une autre fois (= frame). Cependant, je veux arriver à n'importe quelle image arbitraire, pas seulement les images clés. Voici comment je définis les positions: pMediaSeeking-> SetPositions (& llPlay, AM_SEEKING_AbsolutePositioning, NULL, AM_SEEKING_NoPositioning);} llPlay dans le temps média. – user1331044

+0

À quoi ressemble votre graphique? Si vous cherchez une image arbitraire dans un graphe de lecture (demux => decoder => renderer), le décodeur décode l'image clé en frame et affiche la trame choisie dans le rendu, en supprimant les images qu'il doit décoder pour y arriver . –

+0

Je pense qu'il me manque le demux et la partie décodeur (au moins le décodeur). J'ai modifié le message original pour montrer le code. Comment puis-je implémenter le démultiplexeur et le décodeur alors? – user1331044