Ziehen von Daten aus einem CMSampleBuffer, um eine tiefe Kopie zu erstellen

Ich versuche, eine Kopie eines CMSampleBuffers zu erstellen, der von captureOutput in einem AVCaptureVideoDataOutputSampleBufferDelegate zurückgegeben wird.

Da die CMSampleBuffer aus einem vorab zugewiesenen Pool von (15) Puffern stammen, können sie nicht erneut erfasst werden, wenn ich einen Verweis auf sie anhänge. Dadurch werden alle verbleibenden Frames gelöscht.

Um eine optimale Leistung aufrechtzuerhalten, verweisen einige Beispielpuffer direkt auf Speicherpools, die möglicherweise vom Gerätesystem und anderen Erfassungseingaben wiederverwendet werden müssen. Dies ist häufig bei unkomprimierter geräteeigener Erfassung der Fall, bei der Speicherblöcke so wenig wie möglich kopiert werden. Wenn mehrere Sample-Puffer zu lange auf solche Speicherpools verweisen, können die Eingänge keine neuen Samples mehr in den Speicher kopieren und diese Samples werden gelöscht.

Wenn Ihre Anwendung bewirkt, dass Samples gelöscht werden, indem die bereitgestellten CMSampleBufferRef-Objekte zu lange aufbewahrt werden, Sie jedoch über einen längeren Zeitraum auf die Sample-Daten zugreifen müssen, sollten Sie die Daten in einen neuen Puffer kopieren und dann den Sample-Puffer freigeben ( wenn es zuvor beibehalten wurde), damit der Speicher, auf den es verweist, wiederverwendet werden kann.

Natürlich muss ich den CMSampleBuffer kopieren, aber CMSampleBufferCreateCopy () erstellt nur eine flache Kopie. Daraus schließe ich, dass ich CMSampleBufferCreate () verwenden muss. Ich habe die 12 ausgefüllt! Parameter, die der Konstruktor benötigt, die aber das Problem haben, dass meine CMSampleBuffers keinen blockBuffer enthalten (nicht ganz sicher, was das ist, aber es scheint wichtig).

Diese Frage wurde mehrmals gestellt, aber nicht beantwortet.

Deep Copy von CMImageBuffer oder CVImageBuffer undErstellen Sie eine Kopie von CMSampleBuffer in Swift 2.0

Eine mögliche Antwort lautet: "Ich habe endlich herausgefunden, wie ich damit einen tiefen Klon erstellen kann. Alle Kopiermethoden haben die Daten im Heap wiederverwendet, der die AVCaptureSession sperrt. Also musste ich die Daten in ein NSMutableData-Objekt ziehen und erstellt dann einen neuen Beispielpuffer. "credit to Rob auf SO. Ich weiß jedoch nicht, wie ich das richtig machen soll.

Wenn Sie interessiert sind,Die ist die Ausgabe vonprint(sampleBuffer). BlockBuffer wird nicht erwähnt, auch bekannt als CMSampleBufferGetDataBuffer gibt nil zurück. Es gibt einen imageBuffer, aber das Erstellen einer "Kopie" mit CMSampleBufferCreateForImageBuffer scheint auch den CMSampleBuffer nicht freizugeben.

EDIT: Seitdem diese Frage gestellt wurde, habe ich noch mehr Möglichkeiten ausprobiert, den Speicher zu kopieren.

Ich habe das gleiche getan, dass Benutzer Kametrixom versucht.Die ist mein Versuch, den CVPixelBuffer zu kopieren und dann mit CMSampleBufferCreateForImageBuffer den endgültigen Sample-Buffer zu erstellen. Dies führt jedoch zu einem von zwei Fehlern:

A EXC_BAD_ACCESS in der memcpy-Anweisung. AKA, ein Segfault beim Versuch, auf Daten außerhalb des Anwendungsspeichers zuzugreifen. Oder der Speicher wird erfolgreich kopiert, aber dasCMSampleBufferCreateReadyWithImageBuffer() schlägt mit dem Ergebniscode -12743 fehl, der angibt, dass das Format des angegebenen Mediums nicht mit der angegebenen Formatbeschreibung übereinstimmt. Beispiel: Eine mit CVImageBuffer gepaarte Formatbeschreibung, bei der CMVideoFormatDescriptionMatchesImageBuffer fehlschläg

Sie können sehen, dass sowohl Kametrixom als auch ich @ verwendet habCMSampleBufferGetFormatDescription(sampleBuffer), um zu versuchen, die Formatbeschreibung des Quellpuffers zu kopieren. Daher bin ich mir nicht sicher, warum das Format des angegebenen Mediums nicht mit der angegebenen Formatbeschreibung übereinstimmt.

Antworten auf die Frage(8)

Ihre Antwort auf die Frage