سؤال

Task: to organize liveview streaming from Canon 500D camera... just stream without recording.

Environment: Windows 7, Canon 500D via USB2.0

Everything works but I have terrible low FPS with picture flickering.

I have a timer. I bind to OnTimer next function:

function TCanonCamera.CMD_StartLiveView: EdsError;
var
  prop: EdsUInt32;
  err : EdsError;
begin
  prop := 1;
  err := SetProperty(kEdsPropID_Evf_Mode, prop);
  prop := EdsUInt32(kEdsEvfOutputDevice_PC);
  err := SetProperty(kEdsPropID_Evf_OutputDevice, prop);
  Result := err;
end;

Then I download an image from the camera to stream load jpg: TJPEGImage from the stream:

function TCanonCamera.DownloadLiveViewData: EdsError;
var
  err : EdsError;
  stream : EdsStreamRef;
  EvfImageRef: EdsEvfImageRef;
  prop: EdsUInt32;
  ImageData : Pointer;
  ImageSize : EdsUInt32;
  ImageStream: TmemoryStream;
  jpg: TJPEGImage;
begin
  err := EDS_ERR_OK;

  err := EdsCreateMemoryStream(0, stream);

  if err = EDS_ERR_OK then
    err := EdsCreateEvfImageRef(stream, EvfImageRef);

  if err = EDS_ERR_OK then
    err := EdsDownloadEvfImage(FCameraRef, EvfImageRef);

  if err = EDS_ERR_OK then
  begin
    EdsGetPointer(Stream, ImageData);
    EdsGetLength(Stream, ImageSize);

    ImageStream := TMemoryStream.Create;
    ImageStream.WriteBuffer(ImageData^, ImageSize);

    ImageStream.Position := 0;

    if Assigned(FEvfImageUpdatedEvent) then
    begin
      jpg := TJPEGImage.Create;
      jpg.LoadFromStream(ImageStream);
      FEvfImageUpdatedEvent(jpg);
    end;
    ImageStream.Free;
  end;

  EdsRelease(EvfImageRef);
  EdsRelease(stream);

  Result := err;
end;

Then I render the jpg onto TImage:

procedure TfrmMain.OnLiveViewImageUpdate(jpg: TJPEGImage);
begin
  imLiveview.Picture.Assign(jpg);
  jpg.Free;
end;

As a result I get flickering image on the TImage. I tryed to set any values to timer's interval but without significant success.

What should I do to speed up streaming?

Thanks.

UPDATE: I suspect main point is I do all steps in single thread app... What do you think about it? Should I execute separated thread to get liveview images from the camera?

هل كانت مفيدة؟

المحلول

to close future questions about it. Solution is fast jpeg decode as suggested by @TLama and some simple additional steps:

procedure TfrmMain.OnLiveViewImageUpdate(bmp: TBitmap);
begin
  bmp.IgnorePalette := true;
  imLiveview.Canvas.Draw(0,0,bmp);
  Application.ProcessMessages;
  bmp.Free;
end;

after that liveview streams like real video.

Thanks for the help.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top