Oppure

Loading
19/06/11 18:17
pixul
Ciao a tutti,

sto modificando il codice di Taksi (software free open source, per il download del codice sourceforge.net/projects/taksi/files/stable/taksi-0.7.6/taksi-0.7.6-src.zip/…) per fare streaming via UDP di immagini jpeg.

Taksi permette di catturare il contenuto di finestre openGL e directX; quello che devo fare è inviare il contenuto della finestra openGL ed inviarlo su una LAN tramite protocollo UDP; in ricezione, su un altro pc, mostrare lo stesso contenuto.

Il programma funziona in questo modo: in base al fps (frame per second) impostato in Taksi quest'ultimo legge il frame buffer tramite funzione readpixels (utilizza librerie openGL); io ho aggiunto del codice che crea il jpeg del frame buffer letto; questo jpeg lo salvo in un buffer; il jpeg viene salvato in real time in base al fps (frame per second) impostato in Taksi. Quindi ad ogni lettura del frame buffer salvo il jpeg relativo che a sua volta lo salvo in un buffer; la mia idea è poi inviare, utilizzando le librerie Qt, il buffer contenente il jpeg in rete LAN utilizzando la funzione socketudp->writedatagram; in ricezione utilizzare funzione socketudp->readdatagram per leggere il buffer contenente il jpeg.

Potrei inviare più jpeg insieme invece che uno alla volta, ma non vi è un limite sulla dimensione del jpeg da inviare (limite dei datagrams del protocollo UDP)?
Se sì dovrei suddividere il file jpeg ed inviare i vari frammenti uno dopo l'altro?

Di seguito la funzione che sto modificando:

[void CTaksiOGL::GetFrameFullSize(CVideoFrame& frame)
{
    // Gets current frame to be stored in video file.
    // select back buffer
    s_glReadBuffer(GL_BACK);

    // read the pixels data
    s_glReadPixels(0, 0, frame.m_Size.cx, frame.m_Size.cy, GL_RGB, GL_UNSIGNED_BYTE, frame.m_pPixels);



    // Adjust pixel encodings: RGB -> BGR
    SwapColorComponents(frame.m_pPixels, frame.m_Size.cx, frame.m_Size.cy);


    CODICE CHE HO AGGIUNTO IO:


FILE* outfile = fopen("C:\testgrab\test.jpeg", "wb";);

struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;

cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo);
jpeg_stdio_dest(&cinfo, outfile);



GLubyte* flip = new GLubyte[sizeof(GLubyte)*frame.m_Size.cx*frame.m_Size.cy*3];



cinfo.image_width = frame.m_Size.cx;
cinfo.image_height = frame.m_Size.cy;
cinfo.input_components = 3;
cinfo.in_color_space = JCS_RGB;

int width=frame.m_Size.cx;
int height=frame.m_Size.cy;

jpeg_set_defaults(&cinfo);
/*set the quality [0..100] */
jpeg_set_quality (&cinfo, 75, true);
jpeg_start_compress(&cinfo, true);

JSAMPROW row_pointer; /* pointer to a single row */


// OpenGL writes from bottom to top.
// libjpeg goes from top to bottom.
// flip lines.



for (int x = 0; x < width; x++) {
        for (int y = 0; y < height; y++) {
flip[(y*height+x)*3] = frame.m_pPixels[((width-1-y)*height+x)*3];
flip[(y*height+x)*3+1] = frame.m_pPixels[((width-1-y)*height+x)*3+1];
flip[(y*height+x)*3+2] = frame.m_pPixels[((width-1-y)*height+x)*3+2];
}
}


while (cinfo.next_scanline < cinfo.image_height) {
row_pointer = (JSAMPROW) &frame.m_pPixels[cinfo.next_scanline*width*3];
jpeg_write_scanlines(&cinfo, &row_pointer, 1);
}

jpeg_finish_compress(&cinfo);
jpeg_destroy_compress(&cinfo);



fseek(outfile, 0, SEEK_END);
long size = ftell(outfile);
rewind(outfile);
char *str = new char[size];
fgets(str, size, outfile);
fclose(outfile);
udpSocket->writeDatagram(str, 100, QHostAddress::Broadcast, 3000);

}]


Quello che accde è che la funzione senddatagram fa interrompere il programma e la finestra openGL aperta; non sono sicuro sulle ultime 7 righe di codice che salvano il contenuto del jpeg nel buffer e lo inviano in rete.

Inoltre i jpeg che salvo mostrano l'immagine al contrario; in allegato un esempio; il problema penso sia nel codice sopra nel ciclo for; sapreste indicarmi l'errore?

Potreste indicarmi la procedura migliore secondo voi?


Grazie mille.

Marco



aaa