[Qt4] QBuffer offen -> Daten holen und Live Video stream

Alles rund um die Programmierung mit Qt
Antworten
goofy
Beiträge: 38
Registriert: 4. April 2006 15:40

[Qt4] QBuffer offen -> Daten holen und Live Video stream

Beitrag von goofy »

Hallo

haben 1 bzw. 2 Probleme

Zunächst mal, habe eine Netzwerk-Kamera, die natürlich Bilder macht.
Dazu habe eine HTTP API, d.h. ich kann über Requests Daten von der Kamera abholen.

Will einen LiveStream von der Kamera aufbauen.
Also hab das schon geschafft, aber es flimmert.
Hab zwei möglichkeiten die Bilder von der Kamera zuholen,

- Einzelbilder nacheinander (momentan so)
Probleme:
ein Bild - ein Reqeust/Response
Anzeige flimmert

- MJPG Stream, also eigentlich auch Einzelbilder
besser: ein Stream - ein Request/Response
Problem:
für einen Request mit QHttp benötige ich ein IODevice,
in meinen Fall nehm ich QBuffer. Brauch die Bilder um
diese eventl. noch verarbeiten.
Kann aber erst auf meine QBuffer zugreifen, wenn ich
diesen schließe, oder? Is aber blöd bei einem LiveStream! :D

Die Anzeige der Einzelbilder mach momentan per paintEvent()

Code: Alles auswählen

void CameraControl::paintEvent(QPaintEvent *event)
{
   QPainter stream(this);
   QPixmap pic;
   pic.loadFromData(buf->buffer());
   stream.drawPixmap(0, 0, 640, 480, pic);
}
Is das die beste Möglichkeit ein Video anzuzeigen? Die Einzelbilder hol ich mir mit timerEvent(), dann kann ich mein Framrate einstellen.

Bei 2 fps flimmert nix, aber es ruckelt.
Bei 25 fps flimmert es und machmal setzt die Anzeige für 1-3 Bilder aus.

Kennt jeman ne bessere Möglichkeit Video aus Einzelbildern darzustellen?

Glaub aber, dass es einen meine vielen Request zur Kamera liegt (25 fps -> 25 Request pro Sekunde) .
Dadurch wird alles ausgebremst!

Dies könnte ich vermeiden, wenn ich das Ganze von der Kamera streame!
Aber der QBuffer ist offen, wie komme ich an die Daten?
Dann noch das nächste Problem, der LiveStream soll ja immer laufen. Dadurch wird mein Buffer rein theoretisch unendlich groß! :shock:

Will eigentlich nur 1-3 Sekunden in Vergangenheit blicken können, d.h. 25-75 Bilder sollten im Buffer bleiben.
Aber zunächst mal wie kommt man an die Daten eines offen QBuffer, hab leider nix hier im Forum gefunden und auch nix bei den Trolls.

Danke.

gruß
Goofy
goofy
Beiträge: 38
Registriert: 4. April 2006 15:40

Beitrag von goofy »

morgen,

schade, dass bis jetzt noch keiner helfen konnte.

Das mit dem Bilder anzeigen, hat sich mittlerweile erledigt. Hab ein Stückchen Software, dass es für mich macht!

Aber der QBuffer macht mir noch Sorgen.

Bin für jede Anregung dankbar ....

goofy
lepsai
Beiträge: 573
Registriert: 14. September 2004 21:33
Wohnort: Berlin
Kontaktdaten:

Beitrag von lepsai »

hol doch das Bild von der Kamera und zeig es direkt an, wozu willste puffern? Flimmern tut's, weil deine Anzeigeimplementierung schlecht ist. Wir haben hier solche Probleme schon mal diskutiert gehabt, also such einfach im Forum danach...
goofy
Beiträge: 38
Registriert: 4. April 2006 15:40

Beitrag von goofy »

Wenn ich die bilder nur anzeigen wollte dann hätte einfach im Forum gesucht.

Aber dieses Problem hat sich ja schon erledigt.

Das Problem ist, dass ich 2 Möglichkeiten hab die Bilder zu holen

- Einzelbilder, d.h. ein Bilder - ein Request zur Camera

- als MJPG-Stream (viele Bilder hinter einander :D ), d.h. ein Stream - ein Request zur Camera.

also mit QHttp geht ja sowas ...

Code: Alles auswählen

QHttp http;
http.setHost("serverIP");
QHttpRequestHeader getImage("GET", "/cgi/jpg/image.cgi");
http.request(getImage, 0, buffer);
dann gibts noch Signal die man connecten muss und dann die Daten im
buffer zu verarbeiten.
das wäre requestFinisihed() ...

--> Request fertig --> Buffer schließen --> Daten anzeigen usw.

Problem bei MJPG-Stream
--> Request starten --> Buffer öffnen --> Buffer wird gefüllt --> ?

wie komm ich an die Daten eines offenen Buffers.

Und ich müsste die Bilder puffern, weil ich mit denen noch was anstellen muss.

danke
goofy
goofy
Beiträge: 38
Registriert: 4. April 2006 15:40

Beitrag von goofy »

Hallo

habs geschafft, den Buffer anzuzapfen, wenn er noch nicht geschlossen ist!
Man sollte einfach öfters den Kopf einschalten! :D

hier mal das Ganze vereinfacht:

Code: Alles auswählen

 QBuffer *buf = new QBuffer();
buf->open(QIODevice::ReadWrite);
buf->seek(offset);
imageBuffer = buf->readAll();
buf->reset();
also man braucht ja eigentlich nur ReadWrite .... 8)
dann geht das was ich machen will auch.

mit seek überspring ich einfach ein paar sachen, die nicht zu meinem Bild gehören, dann werden mit readAll() die restlichen Daten (bild) in ein QByteArray geschrieben. Und dieses Wird dann angezeigt oder was auch immer.

mit reset() wird der Buffer zurück gesetzt, damit gleich wieder das nächste Bild von meiner kamera eingeschrieben werden kann.

Da hab ich noch ein Problem! :(

ca. 70-90% der geholten Bilder werden korrekt angezeigt bzw. steh richtig im buffer, aber der Rest leider nicht. Bei hören Frameraten sinkt die Zahl der korrekten Bilder.

Hab die Vermutung, dass es daran liegt wie ich mit meinem Buffer umgehe.
Entweder, will ich zu früh Daten lesen, d.h. die Daten sind noch nicht alle da.
Oder beim resteten des Buffers geht etwas schief.

Weiß jemand eine Möglichkeit einen Buffer mit 100%iger Sicherheit zurück zu setzten ohne diesen dabei schließen zu müssen. Dass der Buffer offen ist, ist die Herausforderung! :D

thx

Goofy

edit:
Da fällt mir noch was ein ..
bekomm wenn das mit den Bilder nicht funktioniert eine Aussage auf
Konsole "Corrupt JPEG data: premature end of data segment"
wahrscheinlich eine Exception, kann aber nicht nachvollziehen woher die kommt. Zeige Bilder im paintEvent() mit QPainter an.
Kommt das von dort? thx
goofy
Beiträge: 38
Registriert: 4. April 2006 15:40

Beitrag von goofy »

wieder mal,

schade, dass bis jetzt noch keiner helfen konnte.

Was ich bis jetzt noch so heraus gefunden haben.

Zunächst am Reseten des Buffers liegst wohl nicht, laut der Qt Docu
wird nur an den Anfang geseekt .

Nun aber QByteArray gehört zu den sogenannten Shared Classes, diese Klassen können ein implicit shared memory haben! :shock:

Also es geht hauptsächlich um das Kopieren von Daten von einem Objekt zum anderen ...
Wird nur kopiert, z.B. von QByteArray zu QByteArray, wird eine flache Kopie gemacht. -> schnell, weniger Speicher

Sobald die Daten eines QByteArray verändert werden gibts ne tiefe Kopie!
http://doc.trolltech.com/4.1/shclass.ht ... tly-shared

Da QBuffer eigentlich ja nur ein QByteArray verkapselt, sellt sich die Frage, ob nun unser QBuffer ein QByteArray, das mit QBuffer::readAll() erzeugt wird, den gleichen Speicher teilen?

man kann händisch mit QByteArray::detach() eine tiefe Kopie machen!
hat aber nix an meinem Problem geändert.

Daher müsste es wohl an den zeitlichen Abläufen liegen, dass mein Buffer Inhalt inkorrekt ist. Mach es momentan mit einem Timer, um z.B. 10 fps zu holen.
QBuffer hat auch das Signal readyRead(), allerdings sind damit die Ergebnisse noch schlechter!

Hat jemand ne Idee wie ich meinem Buffer erst wieder auslesen, wenn er richtig gefüllt wurde? Natürlich ohne diesen zu schließen, immer an die kleinen Herausforderungen denken!

am obigen Bespielcode hat sich nix geändert ...

thx

Goofy
Antworten