Ich arbeite an einem DirectShow-Filter, der Eingangssamples nimmt und sie in modifizierte Ausgangssamples umwandelt, aber wo es keine Eins-zu-Eins-Entsprechung zwischen Eingangs- und Ausgangssamples gibt, so dass CTransformFilter nicht der richtige Weg zu sein scheint.
Der beste Weg, dies zu schreiben, scheint das Schreiben eines Filters mit CBaseFilter, CBaseInputPin und CBaseOutputPin zu sein, bei dem Samples auf einem Input-Pin empfangen und von einem Worker-Thread verarbeitet werden, der neue Samples vom Output-Pin erstellt und liefert. Der Worker-Thread kopiert die Eingangs-Sample-Daten, bevor er mit der Arbeit beginnt, so dass mein Filter keinen Verweis auf die Eingangs-Samples außerhalb des CBaseInputPin::Receive-Aufrufs pflegen muss.
Was ist die beste Praxis für die Aufrechterhaltung der Threadsicherheit und die Vermeidung von Deadlocks in diesem Fall? Sollten sich der Eingangs- und der Ausgangs-Pin dieselbe Streaming-Sperre teilen oder sollten sie jeweils eine Streaming-Sperre für ihre Streaming-Operationen haben? Müssen die Pufferzuweisung, die Abtastung und andere Operationen am Ausgangspin die Streaming-Sperre(n) und/oder die Filtersperre halten? Gibt es einen Beispielcode, der etwas Ähnliches tut? Gibt es andere Probleme, auf die man in dieser Situation achten sollte?
Die DirectShow-Basisklassen enthalten beängstigende Kommentare für CBaseOutputPin::Deliver und CBaseOutputPin::GetDeliveryBuffer, die ich nicht ganz verstehe (unten eingefügt).
/* Deliver a filled-in sample to the connected input pin. NOTE the object must
have locked itself before calling us otherwise we may get halfway through
executing this method only to find the filter graph has got in and
disconnected us from the input pin. If the filter has no worker threads
then the lock is best applied on Receive(), otherwise it should be done
when the worker thread is ready to deliver. There is a wee snag to worker
threads that this shows up. The worker thread must lock the object when
it is ready to deliver a sample, but it may have to wait until a state
change has completed, but that may never complete because the state change
is waiting for the worker thread to complete. The way to handle this is for
the state change code to grab the critical section, then set an abort event
for the worker thread, then release the critical section and wait for the
worker thread to see the event we set and then signal that it has finished
(with another event). At which point the state change code can complete */