05-03-2022, 06:51 AM
(This post was last modified: 05-03-2022, 06:55 AM by Ahmed Sayed.)
I have an issue with images being sent from server. I am using Berlin Upd2 and FMX camera component.
The data received on client side is bigger than the one sent from the server. I don't know why?
Server Side:
Camera buffering
Server get:
Client Side:
You will find a lot of commented code because I was trying some other stuff in order to make it work.
When I save the image stream to a file on the server side before pushing it, it's ok and a valid image png file. But when I do save it the stream on the client side it shows that it is not a valid png file.
As you can see I am only testing with one frame and it is invalid file
The data received on client side is bigger than the one sent from the server. I don't know why?
Server Side:
Camera buffering
Code:
void __fastcall TMain::CameraComponentSampleBufferReady(TObject *Sender, const TMediaTime ATime)
{
bmp->Clear(0);
CameraComponent->SampleBufferToBitmap(bmp.get(), true);
}
//---------------------------------------------------------------------------Server get:
Code:
if (ARequestInfo->Document == "/stream")
{
if (ARequestInfo->Command == "GET")
{
IsStreaming = true;
AResponseInfo->ResponseNo = 200;
AResponseInfo->ContentType = "multipart/x-mixed-replace; boundary=imgboundary";
AResponseInfo->CloseConnection = false;
AResponseInfo->WriteHeader();
TIdIOHandler* IOHandler = AContext->Connection->IOHandler;
IOHandler->LargeStream = true;
IOHandler->WriteLn("--imgboundary");
do
{
if (!AContext->Connection->Connected())
return;
unique_ptr<TMemoryStream> str(new TMemoryStream);
bmp->SaveToStream(str.get());
str->Position = 0;
IOHandler->WriteLn("Content-type: image/png");
IOHandler->WriteLn();
IOHandler->Write(str.get());
IOHandler->WriteLn(); //When client disconnects this raises exception
IOHandler->WriteLn("--imgboundary");
Sleep(5000);
} while(IsStreaming);
return;
}Client Side:
Code:
void __fastcall TMain::ButtonClick(TObject *Sender)
{
IdHTTP1->Get("http://localhost:1985/stream");
if (IdHTTP1->ResponseCode != 200 || !IsHeaderMediaType(IdHTTP1->Response->ContentType, "multipart/x-mixed-replace"))
return;
String LBoundary = ExtractHeaderSubItem(IdHTTP1->Response->ContentType,"boundary", QuoteHTTP);
// String LBoundary = IdHTTP1->Response->RawHeaders->Params["Content-Type"][ "boundary"];
String LBoundaryStart = _D("--") + LBoundary;
String LBoundaryEnd = LBoundaryStart + _D("--");
unique_ptr<TIdTCPStream> Stream(new TIdTCPStream(IdHTTP1, 0));
do
{
String LLine = IdHTTP1->IOHandler->ReadLn();
if (LLine == LBoundaryStart) break;
if (LLine == LBoundaryEnd) return;
}
while (true);
ThreadWait(FuncBind( &TMain::ProcessStreaming, this, Stream.get(), LBoundary));
}
//---------------------------------------------------------------------------Code:
void TMain::ProcessImage(TMemoryStream *LMStream)
{
Image1->Bitmap->LoadFromStream(LMStream);
}
//---------------------------------------------------------------------------
void TMain::ProcessStreaming(TIdTCPStream* Stream, String LBoundary)
{
IdHTTP1->IOHandler->LargeStream = true;
TIdMessageDecoder* LDecoder = new TIdMessageDecoderMIME(nullptr);
try
{
bool LMsgEnd = false;
// do
// {
static_cast<TIdMessageDecoderMIME*>(LDecoder)->MIMEBoundary = LBoundary;
LDecoder->SourceStream = Stream;
LDecoder->FreeSourceStream = false;
LDecoder->ReadHeader();
switch (LDecoder->PartType)
{
case mcptText:
case mcptAttachment:
{
TMemoryStream *LMStream = new TMemoryStream;
try
{
TIdMessageDecoder* LNewDecoder = LDecoder->ReadBody(LMStream, LMsgEnd);
LMStream->Position = 0;
LMStream->SaveToFile("image.png");
try
{
// SynchronizeUI(FuncBind( &TMain::ProcessImage, this, LMStream));
}
// catch (const Exception &)
// {
// delete LNewDecoder;
// throw;
// }
__finally
{
delete LDecoder;
LDecoder = LNewDecoder;
}
}
__finally
{
delete LMStream;
}
}
break;
case mcptIgnore:
{
FreeAndNil(LDecoder);
LDecoder = new TIdMessageDecoderMIME(nullptr);
static_cast<TIdMessageDecoderMIME*>(LDecoder)->MIMEBoundary = LBoundary;
}
break;
case mcptEOF:
{
FreeAndNil(LDecoder);
LMsgEnd = true;
}
break;
}
// } while (LDecoder && !LMsgEnd);
}
__finally
{
delete LDecoder;
}You will find a lot of commented code because I was trying some other stuff in order to make it work.
When I save the image stream to a file on the server side before pushing it, it's ok and a valid image png file. But when I do save it the stream on the client side it shows that it is not a valid png file.
As you can see I am only testing with one frame and it is invalid file

