При остановке IMFSourceReader, как я могу убедиться, что OnReadSample больше не будет вызываться?

вы можете попробовать использовать trigger () Ссылка Ссылка

$('#form_id').trigger("reset");

1
задан David Sackstein 16 January 2019 в 21:00
поделиться

2 ответа

Хотя ответы и комментарии, размещенные здесь, были полезны, они не были причиной проблемы в моем случае.

Фактическая проблема заключалась в том, что образец поступал после того, как я уничтожил объект обратного вызова. Я думал, что решил эту проблему, используя «флаг, мьютекс и переменную условия», как описано в моем комментарии, но эта реализация была неправильной.

Решение, которое решило проблему, было следующим:

  1. Определите два 64-битных счетчика receiveSamples и requiredSamples. Кроме того, флаг «остановлено», мьютекс и условная переменная.
  2. После запуска заблокируйте мьютекс и установите счетчики на 0, а флаг остановки - на false. Затем вызовите sourceReader-> ReadSample, чтобы инициировать получение первого образца.
  3. В «Стоп» заблокируйте мьютекс, установите остановленный флог в значение «истина» и используйте условную переменную, чтобы дождаться получения ReceiveSamples == требуемых образцов.
  4. В OnReadSample заблокируйте мьютекс, увеличьте счетчик receiveSamples, разблокируйте мьютекс и уведомите переменную условия.
  5. Непосредственно перед вызовом sourceReader-> ReadSample заблокировать мьютекс (если он еще не принадлежит) увеличивать счетчик requiredSamples.

Я добавлю фрагмент кода, который демонстрирует это в ближайшее время

0
ответ дан David Sackstein 16 January 2019 в 21:00
поделиться

Поздние OnReadSample обратные вызовы возможны из-за многопоточной природы приложения и таких вызовов, инициируемых из рабочих потоков. В отличие от других примеров, которые для краткости кода срезают углы в реализации объекта обратного вызова, MFCaptureD3D реализует обратный вызов для класса CPreview с обычным подсчетом ссылок. Может быть поздний вызов CPreview::OnReadSample, а затем за ним следует вызов IMFSourceReaderCallback::Release, который, как ожидается, удалит экземпляр CPreview (если вы не ссылаетесь на него для других нужд).

Сказав это,

  • убедитесь, что с вашим счетчиком ссылок и управлением интерфейсом все в порядке
  • остановите захват, как вы уже сделали
  • будьте готовы чтобы иметь редкие поздние обратные вызовы
  • в вашем классе, которые принимают обратные вызовы, вы можете добавить флаг, указывающий состояние завершения, и установить его для немедленного возврата и ничего не делать, например здесь, в строке 189 ; когда вы останавливаете захват, установите также этот флаг в своем классе обратного вызова, чтобы игнорировать поздние вызовы
  • , в случае позднего обратного вызова ваш класс обратного вызова все еще имеет ссылку на интерфейс COM из API; флаг помощника защитит вас от совершения каких-либо вредных действий
  • вы можете проверить освобождение COM-интерфейса и удаление объекта обратного вызова в случае, если вы хотите быть уверенным, что дальнейший обратный вызов не поступит, но я бы сказал, что с предложенный флаг, который вам не нужно делать, так как ресурсы будут освобождены точно, хотя, возможно, с небольшой задержкой, вызванной многопоточностью
0
ответ дан Roman R. 16 January 2019 в 21:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: