ich schreibe im moment einen Videoplayer, welcher im Raw-Format vorliegende Videofiles mit bis zu 60 Hz bei bis zu Full-HD-Auflösung abspielen können soll. Raw-Format heißt: in den Videofiles liegen die Farbinformationen der Bildpunkte unkodiert ein Frame nach dem anderen in einem header-losen File. Ein File enthält also nacheinander die Rot-Werte aller Pixel eines Frames, dann die Grün Werte aller Pixel eines Frames und dann die Blau-Werte aller Pixel eines Frames. Dann folgt das nächste Frame usw...
Um das ganze abzuspielen muss mein Programm also das File byte-weise auslesen, aus einer durch die Auflösung der Frames festgelegten Anzahl an Bytes ein Bild erstellen, an den Farbwerten dieser Bilder noch ein paar Transformationen vornehmen und die Bilder mit einer festgelegten Framerate anzeigen. Leider habe ich dabei bereits bei niedrigen Auflösungen große Performance-Probleme und kann das Video nichtmehr ruckelfrei darstellen, weshalb ich mich nun hilfesuchend an euch wende.
Ich versuche kurz zu erklären was ich bisher mache:
Zuerst wird ein Handle auf das abzuspielende File erzeugt
Code: Alles auswählen
videoFile = new QFile(fileParameters->Name);
if (!videoFile->open(QIODevice::ReadOnly)) {
deviceReady = 0;
return;
}Ich hoffe das war soweit verständlich.
Das füllen der Buffer dürfte nun der performance-lastige Teil sein:
Ich poste hier mal den Code wie ich das mache exemplarisch nur für eine Komponente. Erst springe ich im File per QFile::seek() zur richtigen Position. Dann lese ich Pixel für Pixel aus und hänge die Werte an meine BufferListe für diese Komponente an. Nachdem das für alle Komponenten aller Pixel eines Frames geschehen ist wird die Transformation vorgenommen und anschließend ein QImage erstellt, welches ein meinen Haupt-Buffer gehängt wird.
Hier der Code dazu:
Code: Alles auswählen
videoFile->seek(frameNumber * fileParameters->ResolutionX * fileParameters->ResolutionY * 3);
for (j = 0; j < fileParameters->ResolutionY; j++) {
for (k = 0; k < fileParameters->ResolutionX; k++) {
videoFile->read(oneByte, 1); //oneByte ist vom Typ char*
RedBufferList->last()[j][k] = oneByte;
}
// selbe Prozedur für G- und B-Komponenten
this->Color-Conversion();
this->buildImageFromComponents();
this->addImageToImagebuffer();
}Viele Grüße,
HdW