0

任务:组织佳能 500D 相机的实时取景流...只需流而不录制。

环境:Windows 7,佳能500D通过USB2.0

一切正常,但我的 FPS 非常低,画面闪烁。

我有一个计时器。我绑定到 OnTimer 下一个函数:

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;

然后我从相机下载图像以流式加载 jpg: TJPEGImage 从流中:

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;

然后我将 jpg 渲染到 TImage 上:

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

结果,我在 TImage 上得到了闪烁的图像。我尝试将任何值设置为计时器的时间间隔,但没有取得重大成功。

我应该怎么做才能加快流式传输速度?

谢谢。

更新:我怀疑重点是我在单线程应用程序中执行所有步骤......你怎么看?我应该执行单独的线程以从相机获取实时取景图像吗?

4

1 回答 1

2

关闭关于它的未来问题。解决方案是 @TLama 建议的快速 jpeg 解码和一些简单的附加步骤:

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

之后,实时视频流就像真实视频一样。

谢谢您的帮助。

于 2014-03-06T13:17:37.487 回答