mirror of
https://github.com/ShareX/ShareX.git
synced 2024-10-01 09:47:22 +13:00
Some screen record changes
This commit is contained in:
parent
96974186d2
commit
10e7260f7b
7 changed files with 73 additions and 120 deletions
|
@ -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)
|
||||
|
|
|
@ -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 = "")
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue