Question

Je continue de travailler sur mon application DirectShow et je mets simplement la touche finale. Ce que le programme fait est de passer par un fichier vidéo à 1 seconde intervalles et de capturer à partir de l'échantillon de tampon actuel et de le traiter avant de passer à autre chose. Cependant, je remarquais que je recevais des images en double dans mes tests auxquels j'ai découvert que Directshow n'avait pas incrémenté à travers la vidéo dans cet intervalle de seconde assez rapidement. Ma question est de savoir s'il existe un moyen de vérifier lorsque DirectShow est prêt pour moi d'appeler le SampleGrabber pour obtenir le cadre actuel et le traiter. Pour le moment, j'appelle le sommeil pendant 1 seconde, mais il doit y avoir une meilleure méthode. Merci d'avance pour votre aide.

ÉDITER

J'ai juste essayé d'exécuter un chèque pour voir si la position de la vidéo est égale à la position suivante que je voudrais saisir et traiter. Cela a diminué le nombre de trames en double mais je les vois toujours apparaître en morceaux.

Était-ce utile?

La solution

Je laisse toujours le framework DS gérer le taux de traitement: dans le thread principal de l'application, configurez le rappel d'échantillon Grabber, puis lorsque le rappel est déclenché, vous obtenez l'échantillon multimédia ainsi que le temps d'échantillon: à ce stade, vous pouvez traiter l'échantillon si L'intervalle approprié, c'est-à-dire 1 seconde, s'est écoulé.

Comment voulez-vous dire que vous appelez le sommeil pendant une seconde et d'où (quel fil) l'appelez-vous? Si vous faites cela à l'intérieur du rappel, vous bloquez efficacement le pipeline DirectShow? Peut-être que si vous pouviez expliquer votre configuration plus en détail, je pourrais être plus utile.

/// Callback that is triggered per media sample
/// Note this all happens in the DirectShow streaming thread!
STDMETHODIMP SampleCB( double dSampleTime, IMediaSample * pSample )
{
  // check timestamp and if one second has elapsed process sample accordingly
  // else do nothing

  ...

  // Get byte pointer
  BYTE* pbData(NULL);
  HRESULT hr = pSample->GetPointer(&pbData);
  if (FAILED(hr)) 
  {
    return hr;
  }

  ...
}

PS Si vous souhaitez traiter les échantillons le plus rapidement possible, vous pouvez définir l'échantillon d'horodatage sur NULL dans votre rappel.

  // set time to NULL to allow for fast rendering since the 
  // the video renderer controls the rendering rate according
  // to the timestamps
  pSample->SetTime(NULL, NULL);

Autres conseils

Essayez de définir votre minuterie de graphique sur NULL. Il permettra à:

  • traiter le fichier le plus rapidement possible
  • vous soulagera des problèmes que vous avez.

Bien sûr, cela ne fonctionnera pas si vous rendez le fichier à dépister en même temps.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top