Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Made the vertical flip of frames optional. #6

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions SharpAvi/Codecs/IVideoEncoder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ public interface IVideoEncoder
/// </summary>
int MaxEncodedSize { get; }

/// <summary>
/// Wether to vertically flip the frame before writing
/// </summary>
bool FlipVertical { get; set; }

/// <summary>
/// Encodes video frame.
/// </summary>
Expand Down Expand Up @@ -73,6 +78,8 @@ public int MaxEncodedSize
}
}

public abstract bool FlipVertical { get; set; }

public int EncodeFrame(byte[] source, int srcOffset, byte[] destination, int destOffset, out bool isKeyFrame)
{
Contract.Requires(source != null);
Expand Down
27 changes: 26 additions & 1 deletion SharpAvi/Codecs/MotionJpegVideoEncoderWpf.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ public class MotionJpegVideoEncoderWpf : IVideoEncoder
{
private readonly Int32Rect rect;
private readonly int quality;
private bool flipVertical = false;
private byte[] sourceBuffer;


#if FX45
private readonly ThreadLocal<WriteableBitmap> bitmapHolder;
#else
Expand Down Expand Up @@ -94,16 +98,37 @@ public int MaxEncodedSize
}
}

/// <summary>
/// Whether to vertically flip the frame before writing
/// </summary>
public bool FlipVertical
{
get { return flipVertical; }
set { flipVertical = value; }
}

/// <summary>
/// Encodes a frame.
/// </summary>
/// <seealso cref="IVideoEncoder.EncodeFrame"/>
public int EncodeFrame(byte[] source, int srcOffset, byte[] destination, int destOffset, out bool isKeyFrame)
{
if (flipVertical)
{
if (sourceBuffer == null)
{
sourceBuffer = new byte[rect.Width * rect.Height * 4];
}
BitmapUtils.FlipVertical(source, srcOffset, sourceBuffer, 0, rect.Height, rect.Width * 4);
} else
{
sourceBuffer = source;
}

#if FX45
var bitmap = bitmapHolder.Value;
#endif
bitmap.WritePixels(rect, source, rect.Width * 4, srcOffset);
bitmap.WritePixels(rect, sourceBuffer, rect.Width * 4, srcOffset);

var encoderImpl = new JpegBitmapEncoder
{
Expand Down
24 changes: 22 additions & 2 deletions SharpAvi/Codecs/Mpeg4VideoEncoderVcm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ private static VfwApi.BitmapInfoHeader CreateBitmapInfo(int width, int height, u

private readonly int width;
private readonly int height;
private readonly byte[] sourceBuffer;
private byte[] sourceBuffer;
private readonly VfwApi.BitmapInfoHeader inBitmapInfo;
private readonly VfwApi.BitmapInfoHeader outBitmapInfo;
private readonly IntPtr compressorHandle;
Expand All @@ -129,6 +129,7 @@ private static VfwApi.BitmapInfoHeader CreateBitmapInfo(int width, int height, u
private int framesFromLastKey;
private bool isDisposed;
private bool needEnd;
private bool flipVertical = true;

/// <summary>
/// Creates a new instance of <see cref="Mpeg4VideoEncoderVcm"/>.
Expand Down Expand Up @@ -287,14 +288,33 @@ public int MaxEncodedSize
get { return maxEncodedSize; }
}

/// <summary>
/// Whether to vertically flip the frame before writing
/// </summary>
public bool FlipVertical
{
get { return flipVertical;}
set { flipVertical = value; }
}

/// <summary>Encodes a frame.</summary>
/// <seealso cref="IVideoEncoder.EncodeFrame"/>
public int EncodeFrame(byte[] source, int srcOffset, byte[] destination, int destOffset, out bool isKeyFrame)
{
// TODO: Introduce Width and Height in IVideoRecorder and add Requires to EncodeFrame contract
Contract.Assert(srcOffset + 4 * width * height <= source.Length);

BitmapUtils.FlipVertical(source, srcOffset, sourceBuffer, 0, height, width * 4);
if (flipVertical)
{
if (sourceBuffer == null)
{
sourceBuffer = new byte[width * height * 4];
}
BitmapUtils.FlipVertical(source, srcOffset, sourceBuffer, 0, height, width * 4);
} else
{
sourceBuffer = source;
}

var sourceHandle = GCHandle.Alloc(sourceBuffer, GCHandleType.Pinned);
var encodedHandle = GCHandle.Alloc(destination, GCHandleType.Pinned);
Expand Down
11 changes: 10 additions & 1 deletion SharpAvi/Codecs/SingleThreadedVideoEncoderWrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public class SingleThreadedVideoEncoderWrapper : IVideoEncoder, IDisposable
private readonly IVideoEncoder encoder;
private readonly Thread thread;
private readonly Dispatcher dispatcher;

/// <summary>
/// Creates a new instance of <see cref="SingleThreadedVideoEncoderWrapper"/>.
/// </summary>
Expand Down Expand Up @@ -103,6 +103,15 @@ public int MaxEncodedSize
}
}

/// <summary>
/// Wether to vertically flip the frame before writing
/// </summary>
public bool FlipVertical
{
get { return encoder.FlipVertical; }
set { encoder.FlipVertical = value; }
}

/// <summary>
/// Encodes video frame.
/// </summary>
Expand Down
29 changes: 26 additions & 3 deletions SharpAvi/Codecs/UncompressedVideoEncoder.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Diagnostics.Contracts;
using System;
using System.Diagnostics.Contracts;

namespace SharpAvi.Codecs
{
Expand All @@ -13,7 +14,8 @@ public class UncompressedVideoEncoder : IVideoEncoder
{
private readonly int width;
private readonly int height;
private readonly byte[] sourceBuffer;
private byte[] sourceBuffer;
private bool flipVertical = true;

/// <summary>
/// Creates a new instance of <see cref="UncompressedVideoEncoder"/>.
Expand Down Expand Up @@ -54,13 +56,34 @@ public int MaxEncodedSize
get { return width * height * 3; }
}

/// <summary>
/// Whether to vertically flip the frame before writing
/// </summary>
public bool FlipVertical
{
get { return flipVertical; }
set { flipVertical = value; }
}

/// <summary>
/// Encodes a frame.
/// </summary>
/// <seealso cref="IVideoEncoder.EncodeFrame"/>
public int EncodeFrame(byte[] source, int srcOffset, byte[] destination, int destOffset, out bool isKeyFrame)
{
BitmapUtils.FlipVertical(source, srcOffset, sourceBuffer, 0, height, width * 4);
if (flipVertical)
{
if (sourceBuffer == null)
{
sourceBuffer = new byte[width * height * 4];
}
BitmapUtils.FlipVertical(source, srcOffset, sourceBuffer, 0, height, width * 4);
}
else
{
sourceBuffer = source;
}

BitmapUtils.Bgr32ToBgr24(sourceBuffer, 0, destination, destOffset, width * height);
isKeyFrame = true;
return MaxEncodedSize;
Expand Down