Hi,
Please give guidance to , How to improve video quality using WMEncoder. In our project i want to use customs profile that is to be file .prx extension , according .prx file the video out put will change. I am going to convert image to video file... lastly i have download project from this site, it is good but the video output is too pooooor quality please see below the code which i am using.
----------------Form.cs-------------------------
Cursor.Current = Cursors.WaitCursor;
Guid g = new Guid("0F10D9D3-3B04-4fb0-A3D3-88D4AC854ACC");
CwmvFile f = new CwmvFile(textBox1.Text, ref g, (int)numericUpDown1.Value);
Bitmap b;
int x = 1;
bool bDone = false;
do
{
string s = string.Format(@"C:\chetan\screen" + x +".jpg", textBox2.Text, x);
if (File.Exists(s) == true)
{
b = new Bitmap(s);
f.AppendNewFrame(b);
b.Dispose();
x++;
}
else
{
bDone = true;
}
} while (!bDone);
f.Close();
Cursor.Current = Cursors.Default;
MessageBox.Show(string.Format("Added {0} frames", x-1), "Done");
----------------------------------Cwmvfile.cs-----------------------------------
public class CwmvFile
{
#region Member variables
private IWMWriter m_pWMWriter;
private IWMInputMediaProps m_pInputProps;
private int m_iFrameRate;
private int m_dwVideoInput;
private int m_dwCurrentVideoSample;
private long m_msVideoTime;
private bool m_Init;
#endregion
#region APIs
[DllImport("Kernel32.dll", EntryPoint="RtlMoveMemory")]
private static extern void CopyMemory(IntPtr Destination, IntPtr Source, [MarshalAs(UnmanagedType.U4)] int Length);
#endregion
public CwmvFile(string lpszFileName, ref Guid guidProfileID, int iFrameRate)
{
Guid guidInputType;
int dwInputCount;
IWMProfileManager pWMProfileManager = null;
IWMProfile pWMProfile = null;
m_iFrameRate = iFrameRate;
m_dwVideoInput = -1;
m_dwCurrentVideoSample = 0;
m_msVideoTime = 0;
m_pWMWriter = null;
m_pInputProps = null;
m_Init = false;
try
{
WMUtils.WMCreateProfileManager(out pWMProfileManager);
IWMProfileManager2 pProfileManager2 = (IWMProfileManager2)pWMProfileManager;
pProfileManager2.SetSystemProfileVersion(WMVersion.V8_0);
pProfileManager2.LoadProfileByID(guidProfileID, out pWMProfile);
WMUtils.WMCreateWriter(IntPtr.Zero, out m_pWMWriter);
m_pWMWriter.SetProfile(pWMProfile);
m_pWMWriter.GetInputCount(out dwInputCount);
m_dwVideoInput = -1;
for (int i=0; i < dwInputCount; i++)
{
m_pWMWriter.GetInputProps(i, out m_pInputProps);
m_pInputProps.GetType(out guidInputType);
if (guidInputType == MediaType.Video)
{
m_dwVideoInput = i;
break;
}
}
if (m_dwVideoInput == -1)
{
throw new Exception("Profile does not accept video input");
}
m_pWMWriter.SetOutputFilename(lpszFileName);
}
catch
{
Close();
throw;
}
finally
{
if (pWMProfile != null)
{
Marshal.ReleaseComObject(pWMProfile);
pWMProfile = null;
}
if (pWMProfileManager != null)
{
Marshal.ReleaseComObject(pWMProfileManager);
pWMProfileManager = null;
}
}
}
~CwmvFile()
{
Close();
}
public void Close()
{
if (m_Init)
{
if (m_pWMWriter != null)
{
try
{
m_pWMWriter.EndWriting();
}
catch { }
}
m_Init = false;
}
if (m_pInputProps != null)
{
Marshal.ReleaseComObject(m_pInputProps);
m_pInputProps = null;
}
if (m_pWMWriter != null)
{
Marshal.ReleaseComObject(m_pWMWriter);
m_pWMWriter = null;
}
}
public void AppendNewFrame(Bitmap hBitmap)
{
int hr = 0;
INSSBuffer pSample = null;
Rectangle r = new Rectangle(0, 0, hBitmap.Width, hBitmap.Height);
BitmapData bmd;
if (!m_Init)
{
Initialize(hBitmap);
}
bmd = hBitmap.LockBits(r, ImageLockMode.ReadOnly, hBitmap.PixelFormat);
try
{
int iSize = Math.Abs(bmd.Stride * bmd.Height);
IntPtr ip;
m_pWMWriter.AllocateSample(iSize, out pSample);
pSample.GetBuffer(out ip);
LoadSample(bmd, ip, iSize);
int iRetry = 0;
do
{
try
{
m_pWMWriter.WriteSample(m_dwVideoInput, 10000 * m_msVideoTime, SampleFlag.CleanPoint, pSample);
break;
}
catch (COMException e)
{
if ((iRetry++ < 3) && (e.ErrorCode != NSResults.E_INVALID_DATA))
{
continue;
}
else
{
throw;
}
}
} while (true);
Marshal.ThrowExceptionForHR(hr);
m_msVideoTime = (++m_dwCurrentVideoSample*1000)/m_iFrameRate;
}
finally
{
if (pSample != null)
{
Marshal.ReleaseComObject(pSample);
pSample = null;
}
hBitmap.UnlockBits(bmd);
}
}
private void Initialize(Bitmap hBitmap)
{
AMMediaType mt = new AMMediaType();
VideoInfoHeader videoInfo = new VideoInfoHeader();
videoInfo.BmiHeader.Size = Marshal.SizeOf(typeof(BitmapInfoHeader));
videoInfo.BmiHeader.Width = hBitmap.Width;
videoInfo.BmiHeader.Height = hBitmap.Height;
videoInfo.BmiHeader.Planes = 1;
mt.subType = MediaSubType.RGB32;
videoInfo.BmiHeader.BitCount = 32;
videoInfo.SrcRect = new Rectangle(0, 0, hBitmap.Width, hBitmap.Height);
videoInfo.TargetRect = videoInfo.SrcRect;
videoInfo.BmiHeader.ImageSize = hBitmap.Width * hBitmap.Height * (videoInfo.BmiHeader.BitCount / 8);
videoInfo.BitRate = videoInfo.BmiHeader.ImageSize * m_iFrameRate;
videoInfo.BitErrorRate = 0;
videoInfo.AvgTimePerFrame = 10000 * 1000 / m_iFrameRate;
mt.majorType = MediaType.Video;
mt.fixedSizeSamples = true;
mt.temporalCompression = false;
mt.sampleSize = videoInfo.BmiHeader.ImageSize;
mt.formatType = FormatType.VideoInfo;
mt.unkPtr = IntPtr.Zero;
mt.formatSize = Marshal.SizeOf(typeof(VideoInfoHeader));
GCHandle gHan = GCHandle.Alloc(videoInfo, GCHandleType.Pinned);
try
{
mt.formatPtr = gHan.AddrOfPinnedObject();
m_pInputProps.SetMediaType(mt);
}
finally
{
gHan.Free();
mt.formatPtr = IntPtr.Zero;
}
m_pWMWriter.SetInputProps(m_dwVideoInput, m_pInputProps);
m_pWMWriter.BeginWriting();
m_Init = true;
}
private void LoadSample(BitmapData bmd, IntPtr ip, int iSize)
{
if (bmd.Stride < 0)
{
CopyMemory(ip, bmd.Scan0, iSize);
}
else
{
IntPtr ip2 = (IntPtr)(ip.ToInt32() + iSize - bmd.Stride);
for (int x=0; x < bmd.Height; x++)
{
CopyMemory(ip2, (IntPtr)(bmd.Scan0.ToInt32() + (bmd.Stride * x)), bmd.Stride);
ip2 = (IntPtr)(ip2.ToInt32() - bmd.Stride);
}
}
}
}
Q. 1)How to Improve video Quality using WMEncoder SDK