Hi guys,
I have developed an application which captures the screen shots of the desktop and creates a movie out of it. But the movie created is is not playing for some reason.
The filtergraph i used is
Capture filer -> MSScreen 9 encoder DMO ->AVI MUX ->filewriter.
But if i use WMVideo9 encoder DMO then the movie is playing. I want to use MSScreen 9 encoder. Can you guys tell me why i cannot play a movie when i used MSScreen dmo. Do i need to connect ot other MUX instead of AVI Mux..
Here is the code which i am trying..
===========
namespace MovieMaker
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.TextBox widthTextBox;
private System.Windows.Forms.TextBox heightTextBox;
private System.Windows.Forms.TextBox bitrateTextBox;
private System.Windows.Forms.TextBox fpsTextBox;
private System.Windows.Forms.Button button1;
private System.Windows.Forms.Button stopBtn;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
public Form1()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
//
// TODO: Add any constructor code after InitializeComponent call
//
this.Load +=new EventHandler(Form1_Load);
}
FilgraphManagerClass fgm = null;
IGraphBuilder iGB = null;
ICaptureGraphBuilder2 iCGB2 = null;
int rotID = 0;
IScreenScraper iSS = null;
private _AMMediaType cMT;
private VIDEOINFOHEADER cVI;
private IPin cOutputPin;
private IBaseFilter compressor;
private void BuildFilterGraph()
{
InitializeFgm();
// iCGB2.RenderStream fails if you try to connect source, compressor and renderer all at
// once because the compressor needs to have settled on the media type before then so...
// Start with source filter - ScreenScraper
// Compressor takes source filter and renders with it
// Renderer takes compressor and renders with it
AddAVIToFileWriter(AddCompressor(AddScreenScraper()));
}
private void InitializeFgm()
{
fgm = new FilgraphManagerClass();
iGB = (IGraphBuilder)fgm;
rotID = MDShowUtility.AddToRot(iGB);
iCGB2 = CaptureGraphBuilder2Class.CreateInstance();
iCGB2.SetFiltergraph(iGB);
}
private IBaseFilter AddScreenScraper()
{
IBaseFilter screenScraper = MSR.LST.MDShow.ScreenScraperClass.CreateInstance();
iGB.AddFilter(screenScraper, "Screen Scraper");
iSS = (IScreenScraper)screenScraper;
iSS.FrameRate(Int32.Parse(fpsTextBox.Text));
return screenScraper;
}
private IBaseFilter AddCompressor(IBaseFilter source)
{
compressor = MDShowUtility.CreateFilterByName("MSScreen 9 encoder DMO");
iGB.AddFilter(compressor, "MSScreen 9 encoder DMO");
iCGB2.RenderStream(IntPtr.Zero, IntPtr.Zero, source, null, compressor);
// Get the output pin, Configure the Video Compressor
cOutputPin = MDShowUtility.GetPin(compressor, MDShowUtility.PinType.Output);
InitializeCompressorMediaType();
ConfigureCompressor();
return compressor;
}
private void InitializeCompressorMediaType()
{
ArrayList mts = new ArrayList();
ArrayList ihs = new ArrayList();
ArrayList sccs = new ArrayList();
MDShowUtility.GetStreamCapabilities(cOutputPin, ref mts, ref ihs, ref sccs);
for(int i = 0; i < mts.Count; i++)
{
Console.WriteLine(MediaType.DebugMediaType((_AMMediaType)mts, "InitializeCompressorMediaType"));
Console.WriteLine(MDShowUtility.DebugStreamConfigCaps(sccs));
}
// There's only one
cMT = (_AMMediaType)mts[0];
cMT.formattype = MediaType.FORMAT_VideoInfo;
// MediaTypes are local to method, so free them all
// then reallocate just the one we want
MDShowUtility.FreeMediaTypes(mts);
cMT.cbFormat = (uint)Marshal.SizeOf(typeof(VIDEOINFOHEADER));
cMT.pbFormat = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(VIDEOINFOHEADER)));
}
private void ConfigureCompressor()
{
// Have the compressor use the same height and width settings as the device
cVI.AvgTimePerFrame = (ulong) (10000000 / Int32.Parse( fpsTextBox.Text ));
cVI.BitmapInfo.Width = Int32.Parse(widthTextBox.Text);
cVI.BitmapInfo.Height = Int32.Parse(heightTextBox.Text);
cVI.BitmapInfo.Size = (uint)Marshal.SizeOf(typeof(BITMAPINFOHEADER));
cVI.BitmapInfo.Planes = 1;
cVI.BitmapInfo.Compression = 844321613;//0x33D9A760;
//MessageBox.Show(cVI.BitmapInfo.Compression +"");
//cVI.BitmapInfo.BitCount = 24;
//cVI.BitmapInfo.ClrUsed = 0;
//cVI.BitmapInfo.ClrImportant = 0;
//cVI.BitErrorRate = 0;
cVI.Source.left = cVI.Source.top = cVI.Target.left = cVI.Target.top = 0;
cVI.Source.right = Int32.Parse(widthTextBox.Text);
cVI.Source.bottom = Int32.Parse(heightTextBox.Text);
cVI.Target.right = Int32.Parse(widthTextBox.Text);
cVI.Target.bottom = Int32.Parse(heightTextBox.Text);
// Configure the bit rate
cVI.BitRate = UInt32.Parse(bitrateTextBox.Text);
// Update the structure in memory
Marshal.StructureToPtr(cVI, cMT.pbFormat, false);
// Allow compressor specific configuration
// e.g. WM9+ requires extra configuration, others may as well
ConfigureWMScreenEncoder();
// Use the structure in the compressor
((IAMStreamConfig)cOutputPin).SetFormat(ref cMT);
}
private void ConfigureWMScreenEncoder()
{
//
// Note: Configure compressor before setting private data
//
// IPropertyBag iPB = (IPropertyBag)compressor;
// object o = 1; // 1 == Live, can be obtained from IWMCodecProps.GetCodecProp(WM9PropList.g_wszWMVCComplexityExLive)
// iPB.Write(WM9PropList.g_wszWMVCComplexityEx, ref o);
//
// // More configuration possibilities
// o = 0;
// iPB.Write(WM9PropList.g_wszWMVCComplexityMode, ref o);
//
// o = 0;
// iPB.Write(WM9PropList.g_wszWMVCCrisp, ref o);
//
// o = "MP";
// iPB.Write(WM9PropList.g_wszWMVCDecoderComplexityRequested, ref o);
//
// o = 10000;
// iPB.Write(WM9PropList.g_wszWMVCVideoWindow, ref o);
//
// o = true;
// iPB.Write(WM9PropList.g_wszWMVCVBREnabled, ref o);
//
// Set Private Data
//
IWMCodecPrivateData iPD = (IWMCodecPrivateData)compressor;
iPD.SetPartialOutputType(ref cMT);
uint cbData = 0;
iPD.GetPrivateData(IntPtr.Zero, ref cbData);
if(cbData != 0)
{
int vihSize = Marshal.SizeOf(cVI);
// Allocate space for video info header + private data
IntPtr vipd = Marshal.AllocCoTaskMem(vihSize + (int)cbData);
// Copy vih into place
Marshal.StructureToPtr(cVI, vipd, false);
// Fill in private data
iPD.GetPrivateData(new IntPtr(vipd.ToInt32() + vihSize), ref cbData);
// Clean up current media type
MDShowUtility.FreeMediaType(cMT);
// Reset it
cMT.pbFormat = vipd;
cMT.cbFormat = (uint)vihSize + cbData;
}
}
string FilePath = "C:\\SnapShotCapture\\screen.avi";
private void AddAVIToFileWriter(IBaseFilter compressor)
{
// Avi mux filter
IBaseFilter aviMuxFilter;
// File writer
IFileSinkFilter fileSinkFilter;
// adding AVI Mux & File sink filters and connecting the pins
iCGB2.SetOutputFileName(ref MediaType.MEDIASUBTYPE_Avi, this.FilePath,
out aviMuxFilter, out fileSinkFilter);
iCGB2.RenderStream(IntPtr.Zero, IntPtr.Zero, compressor, null, aviMuxFilter);
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
MDShowUtility.RemoveAllFilters(fgm);
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.widthTextBox = new System.Windows.Forms.TextBox();
this.heightTextBox = new System.Windows.Forms.TextBox();
this.bitrateTextBox = new System.Windows.Forms.TextBox();
this.fpsTextBox = new System.Windows.Forms.TextBox();
this.button1 = new System.Windows.Forms.Button();
this.stopBtn = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// widthTextBox
//
this.widthTextBox.Location = new System.Drawing.Point(32, 24);
this.widthTextBox.Name = "widthTextBox";
this.widthTextBox.TabIndex = 0;
this.widthTextBox.Text = "1024";
//
// heightTextBox
//
this.heightTextBox.Location = new System.Drawing.Point(32, 72);
this.heightTextBox.Name = "heightTextBox";
this.heightTextBox.TabIndex = 1;
this.heightTextBox.Text = "768";
//
// bitrateTextBox
//
this.bitrateTextBox.Location = new System.Drawing.Point(40, 136);
this.bitrateTextBox.Name = "bitrateTextBox";
this.bitrateTextBox.TabIndex = 2;
this.bitrateTextBox.Text = "540000";
//
// fpsTextBox
//
this.fpsTextBox.Location = new System.Drawing.Point(184, 136);
this.fpsTextBox.Name = "fpsTextBox";
this.fpsTextBox.Size = new System.Drawing.Size(64, 20);
this.fpsTextBox.TabIndex = 3;
this.fpsTextBox.Text = "1";
//
// button1
//
this.button1.Location = new System.Drawing.Point(56, 208);
this.button1.Name = "button1";
this.button1.TabIndex = 4;
this.button1.Text = "start";
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// stopBtn
//
this.stopBtn.Location = new System.Drawing.Point(176, 208);
this.stopBtn.Name = "stopBtn";
this.stopBtn.TabIndex = 5;
this.stopBtn.Text = "stop";
this.stopBtn.Click += new System.EventHandler(this.stopBtn_Click);
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 266);
this.Controls.Add(this.stopBtn);
this.Controls.Add(this.button1);
this.Controls.Add(this.fpsTextBox);
this.Controls.Add(this.bitrateTextBox);
this.Controls.Add(this.heightTextBox);
this.Controls.Add(this.widthTextBox);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
}
#endregion
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
private void button1_Click(object sender, System.EventArgs e)
{
BuildFilterGraph();
fgm.Run();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void stopBtn_Click(object sender, System.EventArgs e)
{
fgm.Stop();
}
}
}
===========
I have developed an application which captures the screen shots of the desktop and creates a movie out of it. But the movie created is is not playing for some reason.
The filtergraph i used is
Capture filer -> MSScreen 9 encoder DMO ->AVI MUX ->filewriter.
But if i use WMVideo9 encoder DMO then the movie is playing. I want to use MSScreen 9 encoder. Can you guys tell me why i cannot play a movie when i used MSScreen dmo. Do i need to connect ot other MUX instead of AVI Mux..
Here is the code which i am trying..
===========
namespace MovieMaker
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.TextBox widthTextBox;
private System.Windows.Forms.TextBox heightTextBox;
private System.Windows.Forms.TextBox bitrateTextBox;
private System.Windows.Forms.TextBox fpsTextBox;
private System.Windows.Forms.Button button1;
private System.Windows.Forms.Button stopBtn;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
public Form1()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
//
// TODO: Add any constructor code after InitializeComponent call
//
this.Load +=new EventHandler(Form1_Load);
}
FilgraphManagerClass fgm = null;
IGraphBuilder iGB = null;
ICaptureGraphBuilder2 iCGB2 = null;
int rotID = 0;
IScreenScraper iSS = null;
private _AMMediaType cMT;
private VIDEOINFOHEADER cVI;
private IPin cOutputPin;
private IBaseFilter compressor;
private void BuildFilterGraph()
{
InitializeFgm();
// iCGB2.RenderStream fails if you try to connect source, compressor and renderer all at
// once because the compressor needs to have settled on the media type before then so...
// Start with source filter - ScreenScraper
// Compressor takes source filter and renders with it
// Renderer takes compressor and renders with it
AddAVIToFileWriter(AddCompressor(AddScreenScraper()));
}
private void InitializeFgm()
{
fgm = new FilgraphManagerClass();
iGB = (IGraphBuilder)fgm;
rotID = MDShowUtility.AddToRot(iGB);
iCGB2 = CaptureGraphBuilder2Class.CreateInstance();
iCGB2.SetFiltergraph(iGB);
}
private IBaseFilter AddScreenScraper()
{
IBaseFilter screenScraper = MSR.LST.MDShow.ScreenScraperClass.CreateInstance();
iGB.AddFilter(screenScraper, "Screen Scraper");
iSS = (IScreenScraper)screenScraper;
iSS.FrameRate(Int32.Parse(fpsTextBox.Text));
return screenScraper;
}
private IBaseFilter AddCompressor(IBaseFilter source)
{
compressor = MDShowUtility.CreateFilterByName("MSScreen 9 encoder DMO");
iGB.AddFilter(compressor, "MSScreen 9 encoder DMO");
iCGB2.RenderStream(IntPtr.Zero, IntPtr.Zero, source, null, compressor);
// Get the output pin, Configure the Video Compressor
cOutputPin = MDShowUtility.GetPin(compressor, MDShowUtility.PinType.Output);
InitializeCompressorMediaType();
ConfigureCompressor();
return compressor;
}
private void InitializeCompressorMediaType()
{
ArrayList mts = new ArrayList();
ArrayList ihs = new ArrayList();
ArrayList sccs = new ArrayList();
MDShowUtility.GetStreamCapabilities(cOutputPin, ref mts, ref ihs, ref sccs);
for(int i = 0; i < mts.Count; i++)
{
Console.WriteLine(MediaType.DebugMediaType((_AMMediaType)mts, "InitializeCompressorMediaType"));
Console.WriteLine(MDShowUtility.DebugStreamConfigCaps(sccs));
}
// There's only one
cMT = (_AMMediaType)mts[0];
cMT.formattype = MediaType.FORMAT_VideoInfo;
// MediaTypes are local to method, so free them all
// then reallocate just the one we want
MDShowUtility.FreeMediaTypes(mts);
cMT.cbFormat = (uint)Marshal.SizeOf(typeof(VIDEOINFOHEADER));
cMT.pbFormat = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(VIDEOINFOHEADER)));
}
private void ConfigureCompressor()
{
// Have the compressor use the same height and width settings as the device
cVI.AvgTimePerFrame = (ulong) (10000000 / Int32.Parse( fpsTextBox.Text ));
cVI.BitmapInfo.Width = Int32.Parse(widthTextBox.Text);
cVI.BitmapInfo.Height = Int32.Parse(heightTextBox.Text);
cVI.BitmapInfo.Size = (uint)Marshal.SizeOf(typeof(BITMAPINFOHEADER));
cVI.BitmapInfo.Planes = 1;
cVI.BitmapInfo.Compression = 844321613;//0x33D9A760;
//MessageBox.Show(cVI.BitmapInfo.Compression +"");
//cVI.BitmapInfo.BitCount = 24;
//cVI.BitmapInfo.ClrUsed = 0;
//cVI.BitmapInfo.ClrImportant = 0;
//cVI.BitErrorRate = 0;
cVI.Source.left = cVI.Source.top = cVI.Target.left = cVI.Target.top = 0;
cVI.Source.right = Int32.Parse(widthTextBox.Text);
cVI.Source.bottom = Int32.Parse(heightTextBox.Text);
cVI.Target.right = Int32.Parse(widthTextBox.Text);
cVI.Target.bottom = Int32.Parse(heightTextBox.Text);
// Configure the bit rate
cVI.BitRate = UInt32.Parse(bitrateTextBox.Text);
// Update the structure in memory
Marshal.StructureToPtr(cVI, cMT.pbFormat, false);
// Allow compressor specific configuration
// e.g. WM9+ requires extra configuration, others may as well
ConfigureWMScreenEncoder();
// Use the structure in the compressor
((IAMStreamConfig)cOutputPin).SetFormat(ref cMT);
}
private void ConfigureWMScreenEncoder()
{
//
// Note: Configure compressor before setting private data
//
// IPropertyBag iPB = (IPropertyBag)compressor;
// object o = 1; // 1 == Live, can be obtained from IWMCodecProps.GetCodecProp(WM9PropList.g_wszWMVCComplexityExLive)
// iPB.Write(WM9PropList.g_wszWMVCComplexityEx, ref o);
//
// // More configuration possibilities
// o = 0;
// iPB.Write(WM9PropList.g_wszWMVCComplexityMode, ref o);
//
// o = 0;
// iPB.Write(WM9PropList.g_wszWMVCCrisp, ref o);
//
// o = "MP";
// iPB.Write(WM9PropList.g_wszWMVCDecoderComplexityRequested, ref o);
//
// o = 10000;
// iPB.Write(WM9PropList.g_wszWMVCVideoWindow, ref o);
//
// o = true;
// iPB.Write(WM9PropList.g_wszWMVCVBREnabled, ref o);
//
// Set Private Data
//
IWMCodecPrivateData iPD = (IWMCodecPrivateData)compressor;
iPD.SetPartialOutputType(ref cMT);
uint cbData = 0;
iPD.GetPrivateData(IntPtr.Zero, ref cbData);
if(cbData != 0)
{
int vihSize = Marshal.SizeOf(cVI);
// Allocate space for video info header + private data
IntPtr vipd = Marshal.AllocCoTaskMem(vihSize + (int)cbData);
// Copy vih into place
Marshal.StructureToPtr(cVI, vipd, false);
// Fill in private data
iPD.GetPrivateData(new IntPtr(vipd.ToInt32() + vihSize), ref cbData);
// Clean up current media type
MDShowUtility.FreeMediaType(cMT);
// Reset it
cMT.pbFormat = vipd;
cMT.cbFormat = (uint)vihSize + cbData;
}
}
string FilePath = "C:\\SnapShotCapture\\screen.avi";
private void AddAVIToFileWriter(IBaseFilter compressor)
{
// Avi mux filter
IBaseFilter aviMuxFilter;
// File writer
IFileSinkFilter fileSinkFilter;
// adding AVI Mux & File sink filters and connecting the pins
iCGB2.SetOutputFileName(ref MediaType.MEDIASUBTYPE_Avi, this.FilePath,
out aviMuxFilter, out fileSinkFilter);
iCGB2.RenderStream(IntPtr.Zero, IntPtr.Zero, compressor, null, aviMuxFilter);
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
MDShowUtility.RemoveAllFilters(fgm);
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.widthTextBox = new System.Windows.Forms.TextBox();
this.heightTextBox = new System.Windows.Forms.TextBox();
this.bitrateTextBox = new System.Windows.Forms.TextBox();
this.fpsTextBox = new System.Windows.Forms.TextBox();
this.button1 = new System.Windows.Forms.Button();
this.stopBtn = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// widthTextBox
//
this.widthTextBox.Location = new System.Drawing.Point(32, 24);
this.widthTextBox.Name = "widthTextBox";
this.widthTextBox.TabIndex = 0;
this.widthTextBox.Text = "1024";
//
// heightTextBox
//
this.heightTextBox.Location = new System.Drawing.Point(32, 72);
this.heightTextBox.Name = "heightTextBox";
this.heightTextBox.TabIndex = 1;
this.heightTextBox.Text = "768";
//
// bitrateTextBox
//
this.bitrateTextBox.Location = new System.Drawing.Point(40, 136);
this.bitrateTextBox.Name = "bitrateTextBox";
this.bitrateTextBox.TabIndex = 2;
this.bitrateTextBox.Text = "540000";
//
// fpsTextBox
//
this.fpsTextBox.Location = new System.Drawing.Point(184, 136);
this.fpsTextBox.Name = "fpsTextBox";
this.fpsTextBox.Size = new System.Drawing.Size(64, 20);
this.fpsTextBox.TabIndex = 3;
this.fpsTextBox.Text = "1";
//
// button1
//
this.button1.Location = new System.Drawing.Point(56, 208);
this.button1.Name = "button1";
this.button1.TabIndex = 4;
this.button1.Text = "start";
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// stopBtn
//
this.stopBtn.Location = new System.Drawing.Point(176, 208);
this.stopBtn.Name = "stopBtn";
this.stopBtn.TabIndex = 5;
this.stopBtn.Text = "stop";
this.stopBtn.Click += new System.EventHandler(this.stopBtn_Click);
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 266);
this.Controls.Add(this.stopBtn);
this.Controls.Add(this.button1);
this.Controls.Add(this.fpsTextBox);
this.Controls.Add(this.bitrateTextBox);
this.Controls.Add(this.heightTextBox);
this.Controls.Add(this.widthTextBox);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
}
#endregion
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
private void button1_Click(object sender, System.EventArgs e)
{
BuildFilterGraph();
fgm.Run();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void stopBtn_Click(object sender, System.EventArgs e)
{
fgm.Stop();
}
}
}
===========