Some screen record changes

This commit is contained in:
Jaex 2014-04-27 10:07:43 +03:00
parent 96974186d2
commit 10e7260f7b
7 changed files with 73 additions and 120 deletions

View file

@ -342,15 +342,7 @@ public void Open(string fileName, int width, int height, bool showOptions = fals
throw new Exception("Failed creating compressed stream.");
// describe frame format
BITMAPINFOHEADER bitmapInfoHeader = new BITMAPINFOHEADER();
bitmapInfoHeader.size = Marshal.SizeOf(bitmapInfoHeader.GetType());
bitmapInfoHeader.width = width;
bitmapInfoHeader.height = height;
bitmapInfoHeader.planes = 1;
bitmapInfoHeader.bitCount = 24;
bitmapInfoHeader.sizeImage = 0;
bitmapInfoHeader.compression = 0; // BI_RGB
BITMAPINFOHEADER bitmapInfoHeader = new BITMAPINFOHEADER(width, height, 24);
// set frame format
if (NativeMethods.AVIStreamSetFormat(streamCompressed, 0, ref bitmapInfoHeader, Marshal.SizeOf(bitmapInfoHeader.GetType())) != 0)

View file

@ -51,7 +51,7 @@ private void Write(string text, string timeText)
timeText = text + ": " + timeText;
}
Debug.WriteLine(timeText);
DebugHelper.WriteLine(timeText);
}
public void WriteElapsedSeconds(string text = "")

View file

@ -2015,4 +2015,14 @@ public enum SetWindowPosFlags : uint
/// </summary>
SWP_SHOWWINDOW = 0x0040
}
public enum BitmapCompressionMode : uint
{
BI_RGB = 0,
BI_RLE8 = 1,
BI_RLE4 = 2,
BI_BITFIELDS = 3,
BI_JPEG = 4,
BI_PNG = 5
}
}

View file

@ -307,6 +307,9 @@ public static partial class NativeMethods
[DllImport("gdi32.dll")]
public static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj);
[DllImport("gdi32.dll")]
public static extern IntPtr CreateDIBSection(IntPtr hdc, [In] ref BITMAPINFOHEADER pbmi, uint pila, out IntPtr ppvBits, IntPtr hSection, uint dwOffset);
#endregion gdi32.dll
#region gdiplus.dll

View file

@ -429,94 +429,6 @@ public struct AVISTREAMINFO
public string name;
}
/// <summary>
/// Structure, which contains information about the dimensions and color format of a DIB.
/// </summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct BITMAPINFOHEADER
{
/// <summary>
/// Specifies the number of bytes required by the structure.
/// </summary>
///
[MarshalAs(UnmanagedType.I4)]
public int size;
/// <summary>
/// Specifies the width of the bitmap, in pixels.
/// </summary>
///
[MarshalAs(UnmanagedType.I4)]
public int width;
/// <summary>
/// Specifies the height of the bitmap, in pixels.
/// </summary>
///
/// <remarks>If <b>heigh</b>t is positive, the bitmap is a bottom-up DIB and its origin is
/// the lower-left corner. If <b>height</b> is negative, the bitmap is a top-down DIB and its
/// origin is the upper-left corner.</remarks>
///
[MarshalAs(UnmanagedType.I4)]
public int height;
/// <summary>
/// Specifies the number of planes for the target device. This value must be set to 1.
/// </summary>
///
[MarshalAs(UnmanagedType.I2)]
public short planes;
/// <summary>
/// Specifies the number of bits-per-pixel.
/// </summary>
///
[MarshalAs(UnmanagedType.I2)]
public short bitCount;
/// <summary>
/// Specifies the type of compression for a compressed bottom-up bitmap (top-down DIBs cannot be compressed).
/// </summary>
///
[MarshalAs(UnmanagedType.I4)]
public int compression;
/// <summary>
/// Specifies the size, in bytes, of the image.
/// </summary>
///
[MarshalAs(UnmanagedType.I4)]
public int sizeImage;
/// <summary>
/// Specifies the horizontal resolution, in pixels-per-meter, of the target device for the bitmap.
/// </summary>
///
[MarshalAs(UnmanagedType.I4)]
public int xPelsPerMeter;
/// <summary>
/// Specifies the vertical resolution, in pixels-per-meter, of the target device for the bitmap.
/// </summary>
///
[MarshalAs(UnmanagedType.I4)]
public int yPelsPerMeter;
/// <summary>
/// Specifies the number of color indexes in the color table that are actually used by the bitmap.
/// </summary>
///
[MarshalAs(UnmanagedType.I4)]
public int colorsUsed;
/// <summary>
/// Specifies the number of color indexes that are required for displaying the bitmap.
/// </summary>
///
[MarshalAs(UnmanagedType.I4)]
public int colorsImportant;
}
/// <summary>
/// Structure, which contains information about a stream and how it is compressed and saved.
/// </summary>
@ -599,4 +511,35 @@ public struct AVICOMPRESSOPTIONS
[MarshalAs(UnmanagedType.I4)]
public int interleaveEvery;
}
[StructLayout(LayoutKind.Sequential)]
public struct BITMAPINFOHEADER
{
public uint biSize;
public int biWidth;
public int biHeight;
public ushort biPlanes;
public ushort biBitCount;
public BitmapCompressionMode biCompression;
public uint biSizeImage;
public int biXPelsPerMeter;
public int biYPelsPerMeter;
public uint biClrUsed;
public uint biClrImportant;
public BITMAPINFOHEADER(int width, int height, ushort bitCount)
{
biSize = (uint)Marshal.SizeOf(typeof(BITMAPINFOHEADER));
biWidth = width;
biHeight = height;
biPlanes = 1;
biBitCount = bitCount;
biCompression = BitmapCompressionMode.BI_RGB;
biSizeImage = 0;
biXPelsPerMeter = 0;
biYPelsPerMeter = 0;
biClrUsed = 0;
biClrImportant = 0;
}
}
}

View file

@ -39,6 +39,7 @@ public class AVICache : IDisposable
public Size Size { get; private set; }
public bool ShowOptions { get; private set; }
private AVIWriter aviWriter;
private Task task;
private BlockingCollection<Image> imageQueue;
private int position;
@ -49,8 +50,10 @@ public AVICache(string outputPath, int fps, Size size, bool showOptions = false)
FPS = fps;
Size = size;
ShowOptions = showOptions;
Helpers.CreateDirectoryIfNotExist(OutputPath);
aviWriter = new AVIWriter(OutputPath, FPS, Size.Width, Size.Height, ShowOptions);
imageQueue = new BlockingCollection<Image>();
StartConsumerThread();
}
private void StartConsumerThread()
@ -59,10 +62,6 @@ private void StartConsumerThread()
{
IsWorking = true;
Helpers.CreateDirectoryIfNotExist(OutputPath);
AVIWriter aviWriter = new AVIWriter(OutputPath, FPS, Size.Width, Size.Height, ShowOptions);
task = TaskEx.Run(() =>
{
try
@ -79,7 +78,7 @@ private void StartConsumerThread()
if (img != null)
{
//img.Save("Test\\" + position + ".bmp", ImageFormat.Bmp);
//using (new DebugTimer("Frame saved"))
aviWriter.AddFrame((Bitmap)img);
position++;
}
@ -96,11 +95,6 @@ private void StartConsumerThread()
finally
{
IsWorking = false;
if (aviWriter != null)
{
aviWriter.Dispose();
}
}
});
}
@ -108,15 +102,17 @@ private void StartConsumerThread()
public void AddImageAsync(Image img)
{
if (IsWorking)
if (!IsWorking)
{
/*if (imageQueue.Count > 0)
{
Debug.WriteLine("ImageQueue count: " + imageQueue.Count);
}*/
imageQueue.Add(img);
StartConsumerThread();
}
/*if (imageQueue.Count > 0)
{
Debug.WriteLine("ImageQueue count: " + imageQueue.Count);
}*/
imageQueue.Add(img);
}
public void Finish()
@ -126,10 +122,17 @@ public void Finish()
imageQueue.CompleteAdding();
task.Wait();
}
Dispose();
}
public void Dispose()
{
if (aviWriter != null)
{
aviWriter.Dispose();
}
if (imageQueue != null)
{
imageQueue.Dispose();

View file

@ -136,10 +136,12 @@ public void StartRecording()
IsRecording = true;
stopRequest = false;
for (int i = 0; (frameCount == 0 && !stopRequest) || i < frameCount; i++)
for (int i = 0; !stopRequest && (frameCount == 0 || i < frameCount); i++)
{
Stopwatch timer = Stopwatch.StartNew();
Image img = Screenshot.CaptureRectangle(CaptureRectangle);
//DebugHelper.WriteLine("Screen capture: " + (int)timer.ElapsedMilliseconds);
if (OutputType == ScreenRecordOutput.AVI || OutputType == ScreenRecordOutput.AVICommandLine)
{
@ -150,7 +152,7 @@ public void StartRecording()
hdCache.AddImageAsync(img);
}
if ((frameCount == 0 && !stopRequest) || (i + 1 < frameCount))
if (!stopRequest && (frameCount == 0 || i + 1 < frameCount))
{
int sleepTime = delay - (int)timer.ElapsedMilliseconds;
@ -158,9 +160,9 @@ public void StartRecording()
{
Thread.Sleep(sleepTime);
}
else
else if (sleepTime < 0)
{
//Debug.WriteLine("FPS drop: " + sleepTime);
//DebugHelper.WriteLine("FPS drop: " + -sleepTime);
}
}
}