Watch, Follow, &
Connect with Us

Please visit our new home
community.embarcadero.com.

Public Report
Report From: Delphi-BCB/FireMonkey/Components    [ Add a report in this area ]  
Report #:  109802   Status: Open
SampleBufferToBitmap only seems to work for TImage
Project:  C++Builder Build #:  17.0.4625.53395
Version:    17.0 Submitted By:   Mike Versteeg
Report Type:  Feature Specification issue Date Reported:  10/23/2012 8:39:55 AM
Severity:    Infrequently encountered problem Last Updated: 1/10/2013 5:27:32 PM
Platform:    All platforms Internal Tracking #:   33109
Resolution: Retest (Resolution Comments) Resolved in Build: : Update 1
Duplicate of:  None
Voting and Rating
Overall Rating: No Ratings Yet
0.00 out of 5
Total Votes: 10
Description
TVideoCaptureDevice's SampleBufferToBitmap works fine if you use it according to the documentation, i.e. using a TImage, but not if you use a TBitmap.

I am not sure if this is intended, so not sure whether to report this as omission in documentation or bug in TVideoCaptureDevice.
Steps to Reproduce:
This works fine (see also doc):
---------
VideoCaptureDevice->SampleBufferToBitmap(Image1->Bitmap, true); //this works
---------

This does not:
---------
TBitmap *bm = new TBitmap(0, 0);
VideoCaptureDevice->SampleBufferToBitmap(bm, true);               //this doesn't
Image1->Bitmap->CopyFromBitmap(bm, TRect(0, 0, bm->Width, bm->Height), 0, 0);
delete bm;
---------

I am aware of thread issues, but this is just to demo. The second case, where samples are first written to a bitmap, never shows any bitmap displayed. I cannot use a TImage as I wanted the faster write directly to a TPanel (so I do not have to synch to main thread but can use a TCriticalSection).

Update: the real problem seems to be that Image1->Bitmap->CopyFromBitmap (or DrawBitmap) does not work. Actually any form of writing bitmaps does not work, i.e. when I write a bitmap to a panel it ends of on the form (parent problem?).

Example:
Create HD form and add TPanel, do
---------
  TBitmap *bmFrame = new TBitmap(320, 180);
  bmFrame->Canvas->Fill->Color = claRed;
  bmFrame->Canvas->Fill->Kind = TBrushKind::bkSolid;
  bmFrame->Canvas->BeginScene();
  bmFrame->Canvas->FillRect(TRectF(0, 0, bmFrame->Width, bmFrame->Height), 0, 0, AllCorners, 1);
  bmFrame->Canvas->EndScene();
  Panel1->Canvas->BeginScene();
  Panel1->Canvas->DrawBitmap(bmFrame, RectF(0, 0, bmFrame->Width, bmFrame->Height), RectF(0, 0, Panel1->Width, Panel1->Height), 1, false);
  Panel1->Canvas->EndScene();
  delete bmFrame;
---------

and notice how read rectangle actually ends up in top left corner of the form, NOT on the panel in Win32. On MAc OS X NOTHING is displayed.

I have TONS of bugs I found but it is too much work to report all of them, especially as it is so hard to report them and see them fixed (the previous one is just being ignored). Also I find this QCW clients not very user friendly.
Workarounds
None
Attachment
None
Comments

Tomohiro Takahashi at 10/24/2012 6:25:57 PM -
Could you please attach sample project to reproduce/verify your issue?

Mike Versteeg at 10/25/2012 2:56:07 AM -
I know this is your defualt response to discourage people, but if you read my post you know I already gave it, this is all you  need to reproduce:

Example:
Create HD form and add TPanel, do
---------
  TBitmap *bmFrame = new TBitmap(320, 180);
  bmFrame->Canvas->Fill->Color = claRed;
  bmFrame->Canvas->Fill->Kind = TBrushKind::bkSolid;
  bmFrame->Canvas->BeginScene();
  bmFrame->Canvas->FillRect(TRectF(0, 0, bmFrame->Width, bmFrame->Height), 0, 0, AllCorners, 1);
  bmFrame->Canvas->EndScene();
  Panel1->Canvas->BeginScene();
  Panel1->Canvas->DrawBitmap(bmFrame, RectF(0, 0, bmFrame->Width, bmFrame->Height), RectF(0, 0, Panel1->Width, Panel1->Height), 1, false);
  Panel1->Canvas->EndScene();
  delete bmFrame;
---------

and notice how read rectangle actually ends up in top left corner of the form, NOT on the panel in Win32. On MAc OS X NOTHING is displayed.

I have TONS of bugs I found but it is too much work to report all of them, especially as it is so hard to report them and see them fixed (the previous one is just being ignored). Also I find this QCW clients not very user friendly.

Alexey Beloborodov at 12/14/2012 3:14:03 AM -
If you use Canvas methods in secondary thread you must call Canvas.Lock()/Canvas.Unlock() (even if nobody touches this Canvas in other threads). In opposite case you'll have all kinds of multithreading problems because VCL GDI objects garbage collector works in main thread and frees non-locked GDI objects asynchronously to secondary threads.

You also should not ignore Synchronize if it is required. You can draw on DC of visual components with low level API but you are completely responsible for correctness in this case.

Tomohiro Takahashi at 10/25/2012 4:26:03 PM -
> This does not:
> ---------
> TBitmap *bm = new TBitmap(0, 0);
> VideoCaptureDevice->SampleBufferToBitmap(bm, true);               //this doesn't
> Image1->Bitmap->CopyFromBitmap(bm, TRect(0, 0, bm->Width, bm->Height), 0, 0);
> delete bm;
> ---------
Is this your issue similar to QC#108967 ?

How about using Synchronize to update GUI in main thread?
---------------
procedure TForm240.SampleBufferReady(Sender: TObject; const ATime: TMediaTime);
var
  bmp: TBitmap;
begin
  bmp := TBitmap.Create(0, 0);
  VideoCamera.SampleBufferToBitmap(bmp, True);
  TThread.Synchronize(nil,
    procedure
    begin
      Image1.Bitmap.Assign(bmp);
    end
  );
  bmp.Free;
end;
---------------

Mike Versteeg at 10/26/2012 8:24:58 AM -
Syncing to the main thread should not be necessary, a simple Lock() takes care of that (but is missing, unless BeginScene() is the same).

However, after a full (!) week of running tests I can now conclude TVideoCaptureDevice is unstable. Even if I only write the samplebuffer to a bitmap and never display it (excluding any thread issues), it still hangs after a few seconds to an hour.

Code:

  bmFrame->Canvas->BeginScene();
  VideoCaptureDevice->SampleBufferToBitmap(bmFrame, true);
  bmFrame->Canvas->EndScene();

As documentation is poor I also tried

  VideoCaptureDevice->SampleBufferToBitmap(bmFrame, true);

and tested with both local and globally created bitmaps.

The instability is in the samplegrabber, when I removed the code above it does not hang in an hour of testing.

Note TVideoCaptureDevice has lots more problems: it does not work for several devices (they work fine in DirectShow), it hangs for some other devices after calling StopCapture() and it is missing functions to select video resolution, frame rate and input.

All tests, where possible, run in both W7 and OS X.

Mike Versteeg at 10/26/2012 8:32:15 AM -
As it is weekend and I want this fixed asap I will anticipate your next question and answer in advance: the bug has been confirmed on multiple systems (W7 and OS X) using various video capture devices. To work around poor support all stability tests have been run using basic webcams, which all run fine for days using other software.

Tomohiro Takahashi at 10/26/2012 10:32:02 PM -
If you need more intensive support, please contact technical support service.
http://support.embarcadero.com/

but, anyway, I opened this report.

Mike Versteeg at 1/9/2013 3:41:59 AM -
Note this bug appears to be fixed in Update 1 so you can close this report. Thanks.

Tomohiro Takahashi at 1/9/2013 5:47:33 AM -
Thanks for the confirmation. I will check the internal status of this report.

Tomohiro Takahashi at 10/25/2012 4:28:44 PM -
Please see also this documentation about how to use Synchronize.
[Docwiki - This tutorial demonstrates how to capture and display video data and how to customize the display of video data with FireMonkey.]
http://docwiki.embarcadero.com/RADStudio/XE3/en/Video_Capturing

Mike Versteeg at 10/26/2012 8:27:08 AM -
The tutorial is irrelevant, the bug is not related to video display. Also note your tutorial is for Delphi, this bug report is  for C++ Builder. I do not use Delphi.

Server Response from: ETNACODE01