Raúl
Moderador
 Moderador
| Mensajes: 432 |  | Karma: 6
|
Simulated WebCam exception in QueryFrame - 2007/09/18 12:31
I found a bug in the Robotics Studio SimulatedWebcam service.
The problem is that after a few seconds (some times it takes longer) I get an InvalidOperationException in the QueryFrameHandler method in file SimulatedWebcam.cs (The lines causing the exception are these:
| Code: | // size not specified
if(size.Width == 0)
size = _state.Image.Size;
|
see the rest of the code below)
The runtime is complaining because Object (_state.Image) is currently in use elsewhere.
I think the size assignment should be moved within the next try-catch. Also the method QueryFrameHandler should declared as Exclusive, because the image is being locked in the method.
Microsoft are making these changes for the next release.
| Code: | [ServiceHandler(ServiceHandlerBehavior.Concurrent)]
public IEnumerator<ITask> QueryFrameHandler(webcam.QueryFrame query)
{
if (_state.Image == null)
{
query.ResponsePort.Post(new webcam.QueryFrameResponse());
yield break;
}
Size size = new Size((int)query.Body.Size.X, (int)query.Body.Size.Y);
if (query.Body.Format == Guid.Empty)
{
// raw image requested;
BitmapData raw = null;
// size not specified
if(size.Width == 0)
size = _state.Image.Size;
try
{
raw = _state.Image.LockBits(new Rectangle(Point.Empty, size),
ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
int byteSize = raw.Height * raw.Stride;
webcam.QueryFrameResponse response = new webcam.QueryFrameResponse();
response.TimeStamp = _state.LastFrameUpdate;
response.Frame = new byte[byteSize];
response.Size = new Size(raw.Width, raw.Height);
response.Format = Guid.Empty;
System.Runtime.InteropServices.Marshal.Copy(raw.Scan0, response.Frame, 0, byteSize);
query.ResponsePort.Post(response);
}
catch (Exception ex)
{
query.ResponsePort.Post(Fault.FromException(ex));
}
finally
{
if (raw != null)
{
_state.Image.UnlockBits(raw);
}
}
}
else
{
ImageFormat format = new ImageFormat(query.Body.Format);
using (MemoryStream stream = new MemoryStream())
{
if (size == _state.Image.Size ||
size.Width == 0 ||
size.Height == 0 ||
size.Width >= _state.Image.Width ||
size.Height >= _state.Image.Height)
{
size = _state.Image.Size;
_state.Image.Save(stream, format);
}
else
{
using (Bitmap temp = new Bitmap(
_state.Image, size))
{
temp.Save(stream, format);
}
}
webcam.QueryFrameResponse response = new webcam.QueryFrameResponse();
response.TimeStamp = _state.LastFrameUpdate;
response.Frame = new byte[(int)stream.Length];
response.Size = size;
response.Format = format.Guid;
stream.Position = 0;
stream.Read(response.Frame, 0, response.Frame.Length);
query.ResponsePort.Post(response);
}
}
yield break;
}
|
Post edited by: Raúl, at: 2007/09/18 12:45
Raúl Arrabales Moreno. conscious-robots.com/raul |