|
화면전송용 프로그램을 만들고 있는데, 속도상의 문제가 있네요.
그래서 질문을 올립니다.
현재 구현하는 방법은,
1. 최초 화면 전송
전체 화면을 zip 알고리즘을 이용하여 압축하여 tcp/ip프로토콜을 이용하여 전송
2. 최초 이외의 화면전송
1) 최초 전송화면을 기억해 두었다가, 현재 화면과 비교, 틀린 픽셀정보를 따로 저장
(이때의 해당 위치는 index 배열에 저장)
2). index, 픽셀 정보를 각각 압축
3). index, 픽셀을 각 클라이언트에 전송
3. 클라이언트에서는 전송받은 데이터를 압축해제 및 index 배열을 이용하여 원래의 그림을 복원
위와 같은 알고리즘으로 처리하고 있는데, 시간이 너무 걸리는 군요.
index, 다른 정보를 가지는 pixel 찾아내기에 최소 0.5초~2초
압축에 1~2초
전송에 0.5~1초
정도 걸립니다.
그래서 클라이언트측에서 전송한 화면을 볼려면 최소 2.5초 정도 걸립니다.
그래서 이보다 빠르게 처리할 수 있는 알고리즘을 생각하고 있는데, 한계네요.
어떤 다른 방법이 있을까요?
아래의 구현한 내용은 전송할 index 및 pixel 데이터를 생성하는 것입니다.
TMemoryStream *zip_stream = NULL;
Byte *bmp_line8_1, *bmp_line8_2;
short *bmp_line16_1, *bmp_line16_2;
Byte r;
bool changed = false; // 화면변경유무 확인용 변수
int count = 0; // 전송할 변경된 픽셀의 저장위치 (comp_pixel 스트림의 크기)
TRect rect = TRect (0, 0, Screen->Width, Screen->Height);
Graphics::TBitmap *c_bmp = new Graphics::TBitmap (); // 현재의 서버화면 그림
GetCRT (c_bmp, rect, Screen->Width, Screen->Height); // 화면 캡처
// 비교처리 -----------------------------
TMemoryStream *comp_index = new TMemoryStream ();
comp_index->SetSize (c_bmp->Width * c_bmp->Height * sizeof (Byte));
TMemoryStream *comp_pixel = new TMemoryStream ();
if ( c_bmp->PixelFormat == mPrevSCRT_BMP->PixelFormat // mPrevSCRT_BMP는 이전 그림
&& c_bmp->Width == mPrevSCRT_BMP->Width
&& c_bmp->Height == mPrevSCRT_BMP->Height )
{ // 이전화면과 현재화면의 정보가 변경되지 않은 경우
for ( int row = 0; row < c_bmp->Height; row++ )
{
if ( c_bmp->PixelFormat == pf16bit )
{ // 16bit color
bmp_line16_1 = (short *) c_bmp->ScanLine [row];
bmp_line16_2 = (short *) mPrevSCRT_BMP->ScanLine [row];
for ( int x = 0; x < c_bmp->Width; x++ )
{
if ( bmp_line16_1 [x] == bmp_line16_2 [x] )
{ comp_index->Write (&(r = 0), sizeof (Byte)); }
else
{ // 픽셀정보가 다른 경우
comp_index->Write (&(r = 1), sizeof (Byte));
comp_pixel->SetSize ((++count) * sizeof (short));
comp_pixel->Write (bmp_line16_1 + x, sizeof (short));
changed = true;
}
} // for
}
else if ( c_bmp->PixelFormat == pf8bit )
{ // 8bit color
bmp_line8_1 = (Byte *) c_bmp->ScanLine [row];
bmp_line8_2 = (Byte *) mPrevSCRT_BMP->ScanLine [row];
for ( int x = 0; x < c_bmp->Width; x++ )
{
if ( bmp_line8_1 [x] == bmp_line8_2 [x] )
{ comp_index->Write (&(r = 0), sizeof (Byte)); }
else
{
comp_index->Write (&(r = 1), sizeof (Byte));
comp_pixel->SetSize ((++count) * sizeof (Byte));
comp_pixel->Write (bmp_line8_1 + x, sizeof (Byte));
changed = true;
}
} // for
}
} // for
}
// 이후 changed가 true이면 압축
// 압축된 comp_index, comp_pixel을 전송하는 루틴입니다.
덧붙이기:
comp_index를 Byte 단위가 아닌 bit단위로 처리할까도 생각해 보았으나 속도 증가에 그리 큰 도움이 되지 않을 것 같습니다. ㅠ_ㅠ;
|