problem with vmr9 image compositor - method Draw
- From: "Petr Albrecht" <palbrecht@xxxxxxxxxxxxx>
- Date: Wed, 5 Dec 2007 09:27:32 +0100
I play video with playlist (string array), if i play video about 5x it is
fine , but so 6round of video playing throw exception int
IVMRWindowlessControl::RepaintVideo - 0x8004020c with te text COM+ not
installed - code: No buffer space has been set.". I have win xp sp2, directx
9.0c + graphic card with full support dx 9.
If in image compositor draw only text with drawText method - player runs
fine, error is throwing only if i use method sprite.draw(texture...)
pls Help me. Thank You. P. Albrecht
private void BuildGraph(string filename)
{
int hr = 0;
try
{
//initRenderingPanelHandle();
//graphBuilder = (IFilterGraph)new FilterGraph();
graphBuilder = (IFilterGraph2)new FilterGraph();
mediaControl = (IMediaControl)graphBuilder;
rot = new DsROTEntry(graphBuilder);
//videoWindow = (IVideoWindow)graphBuilder;
mediaEventEx = (IMediaEventEx)graphBuilder;
vmr9 = (IBaseFilter)new VideoMixingRenderer9();
ConfigureVMR9InWindowlessMode();
//hr = windowlessCtrl.SetVideoClippingWindow(renderingPanel.Handle);
//DsError.ThrowExceptionForHR(hr);
hr = graphBuilder.AddFilter(vmr9, "Video Mixing Renderer 9");
DsError.ThrowExceptionForHR(hr);
hr = graphBuilder.RenderFile(filename, null);
//hr = mediaControl.RenderFile(filename);
DsError.ThrowExceptionForHR(hr);
hr = this.mediaEventEx.SetNotifyWindow(this.Handle, WM_GRAPHNOTIFY,
IntPtr.Zero);
DsError.ThrowExceptionForHR(hr);
//int width, Height, ratioWidth, ratioHeight;
//windowlessCtrl.GetNativeVideoSize(out width, out Height, out ratioWidth,
out ratioHeight);
//if (width > renderingPanel.Width) renderingPanel.Width = width;
//renderingPanel.Width = renderingPanel.Width;
//clear rendering panel
renderingPanel.Refresh();
RunGraph();
}
catch (Exception e)
{
CloseInterfaces();
MessageBox.Show("An error occured during the graph building : \r\n\r\n" +
e.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ConfigureVMR9InWindowlessMode()
{
int hr = 0;
IVMRFilterConfig9 filterConfig = (IVMRFilterConfig9)vmr9;
// Must be called before calling SetImageCompositor
hr = filterConfig.SetNumberOfStreams(1);
DsError.ThrowExceptionForHR(hr);
// Create an instance of the Compositor
compositor = new Compositor();
// Configure the filter with the Compositor
hr = filterConfig.SetImageCompositor(compositor);
DsError.ThrowExceptionForHR(hr);
// Change VMR9 mode to Windowless
hr = filterConfig.SetRenderingMode(VMR9Mode.Windowless);
DsError.ThrowExceptionForHR(hr);
windowlessCtrl = (IVMRWindowlessControl9)vmr9;
// Set rendering window
hr = windowlessCtrl.SetVideoClippingWindow(renderingPanel.Handle);
DsError.ThrowExceptionForHR(hr);
// Set Aspect-Ratio
hr = windowlessCtrl.SetAspectRatioMode(VMR9AspectRatioMode.LetterBox);
DsError.ThrowExceptionForHR(hr);
filterConfig.SetRenderingPrefs(VMR9RenderPrefs.DoNotRenderBorder);
windowlessCtrl.SetBorderColor(0);
//renderingPanel.BackColor = Color.Black;
// Add delegates for Windowless operations
AddHandlers();
// Call the resize handler to configure the output size
MainForm_ResizeMove(null, null);
}
-----------------------------------------------------------------------------------------------------------------------------------------------------
edited image compositor from directshow samples
/****************************************************************************
While the underlying libraries are covered by LGPL, this sample is released
as public domain. It is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE.
*****************************************************************************/
using System;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using Microsoft.DirectX.Direct3D;
using Direct3D = Microsoft.DirectX.Direct3D;
using DirectShowLib;
namespace Videon.Client
{
public class Compositor : IVMRImageCompositor9, IDisposable
{
private IntPtr unmanagedDevice;
private Device device;
private Sprite sprite;
private Direct3D.Font d3dFont;
private Texture adTex;
private Texture backTex;
private Size adSize;
private int adMove = 2;
private System.Drawing.Font gdiFont;
public Compositor()//(Videon.Client.Screen screen)
{
//_screen = screen;
Device.IsUsingEventHandlers = false;
}
private Sample.Client.Screen _screen = null;
#region IVMRImageCompositor9 Membres
public int CompositeImage(IntPtr pD3DDevice, IntPtr pddsRenderTarget,
AMMediaType pmtRenderTarget, long rtStart, long rtEnd, int dwClrBkGnd,
VMR9VideoStreamInfo[] pVideoStreamInfo, int cStreams)
{
try
{
// Just in case the filter call CompositeImage before InitCompositionDevice
(this sometime occure)
if (unmanagedDevice != pD3DDevice)
{
SetManagedDevice(pD3DDevice);
}
// Create a managed Direct3D surface (the Render Target) from the unmanaged
pointer.
// The constructor don't call IUnknown.AddRef but the "destructor" seem to
call IUnknown.Release
// Direct3D seem to be happier with that according to the DirectX log
Marshal.AddRef(pddsRenderTarget);
Surface renderTarget = new Surface(pddsRenderTarget);
SurfaceDescription renderTargetDesc = renderTarget.Description;
Rectangle renderTargetRect = new Rectangle(0, 0, renderTargetDesc.Width,
renderTargetDesc.Height);
// Same thing for the first video surface
// WARNING : This Compositor sample only use the video provided to the first
pin.
Marshal.AddRef(pVideoStreamInfo[0].pddsVideoSurface);
Surface surface = new Surface(pVideoStreamInfo[0].pddsVideoSurface);
SurfaceDescription surfaceDesc = surface.Description;
Rectangle surfaceRect = new Rectangle(0, 0, surfaceDesc.Width,
surfaceDesc.Height);
//if (!device.CheckCooperativeLevel()) throw new SystemException("oper");
// Get the current time (to write it over the video later)
Videon.Client.Player.TimeStart = TimeSpan.FromTicks(rtStart);
// device.Clear(ClearFlags.Target, System.Drawing.Color.Transparent, 1.0f,
0);
// Set the device's render target (this doesn't seem to be needed)
device.SetRenderTarget(0, renderTarget);
// Copy the whole video surface into the render target
// it's a de facto surface cleaning...
for (int i = 0; i < adMove; i++)
{
device.StretchRectangle(surface, surfaceRect, renderTarget,
renderTargetRect, TextureFilter.None);
// sprite's methods need to be called between device.BeginScene and
device.EndScene
device.BeginScene();
// Init the sprite engine for AlphaBlending operations
sprite.Begin(SpriteFlags.AlphaBlend);
// Write the current video time (using the sprite)...
// Compute the ad moves
if ((Videon.Client.Player.adPos.X < (-adTex.Device.DisplayMode.Width)) ||
Videon.Client.Player.firstRound) Videon.Client.Player.adPos.X =
renderTargetDesc.Width;
Videon.Client.Player.firstRound = false;
Videon.Client.Player.adPos.X -= 1;// adMove;
// Vector for 0,0,0 center point
Microsoft.DirectX.Vector3 v = new Microsoft.DirectX.Vector3(0, 0, 0);
int posX = Videon.Client.Player.adPos.X;
if (posX < 0)
{
posX = renderTargetDesc.Width - adSize.Width - 50;
Videon.Client.Player.adPos.X = renderTargetDesc.Width - adSize.Width - 50;
}
if ((posX + adSize.Width) > renderTargetDesc.Width) posX =
renderTargetDesc.Width-adSize.Width-50;
//redrawTexture(new Point(posX, 0));
// Vector for position of ad text
//Microsoft.DirectX.Vector3 v2 = new
Microsoft.DirectX.Vector3(Videon.Client.Player.adPos.X, 0, 0);
Microsoft.DirectX.Vector3 v2 = new Microsoft.DirectX.Vector3(posX, 0, 0);
// Draw white strip and ad text
if (drawString != "")
{
sprite.Draw(backTex, v,
- problematic method
//d3dFont.DrawText(sprite, drawString, new Point(posX, 3), Color.Black);
sprite.Draw(adTex, Rectangle.Empty,Rectangle.Empty,new
-1); - problematic method
// sprite.Flush();
}
// Draw ad position
d3dFont.DrawText(sprite, drawString, new Point(posX, 0), Color.White);
// End the spite engine (drawings take place here)
/*sprite.End();
sprite.Begin(SpriteFlags.AlphaBlend);
sprite.Flush();*/
sprite.End();
// End the sceen.
device.EndScene();
//device.Present();
}
// No Present requiered because the rendering is on a render target...
// Dispose the managed surface
surface.Dispose();
surface = null;
// and the managed render target
renderTarget.Dispose();
renderTarget = null;
}
catch (Exception e)
{
Debug.WriteLine(e.ToString());
}
// return a success to the filter
return 0;
}
public int InitCompositionDevice(IntPtr pD3DDevice)
{
try
{
// Init the compositor with this unamanaged device
if (unmanagedDevice != pD3DDevice)
{
SetManagedDevice(pD3DDevice);
}
}
catch (Exception e)
{
Debug.WriteLine(e.ToString());
}
// return a success to the filter
return 0;
}
public int SetStreamMediaType(int dwStrmID, AMMediaType pmt, bool fTexture)
{
// This method is called many times with pmt == null
if (pmt == null)
return 0;
// This sample don't use this method... but return a success
return 0;
}
public int TermCompositionDevice(IntPtr pD3DDevice)
{
try
{
// Free the resources each time this method is called
unmanagedDevice = IntPtr.Zero;
FreeResources();
}
catch (Exception e)
{
Debug.WriteLine(e.ToString());
}
// return a success to the filter
return 0;
}
#endregion
#region IDisposable Membres
public void Dispose()
{
// free resources
FreeResources();
}
#endregion
private void FreeResources()
{
if (d3dFont != null)
{
d3dFont.Dispose();
d3dFont = null;
}
if (sprite != null)
{
sprite.Dispose();
sprite = null;
}
if (device != null)
{
device.Dispose();
device = null;
}
if (gdiFont != null)
{
gdiFont.Dispose();
gdiFont = null;
}
if (adTex != null)
{
adTex.Dispose();
adTex = null;
}
if (backTex != null)
{
backTex.Dispose();
backTex = null;
}
}
private void SetManagedDevice(IntPtr unmanagedDevice)
{
// Start by freeing everything
FreeResources();
// Create a managed Device from the unmanaged pointer
// The constructor don't call IUnknown.AddRef but the "destructor" seem to
call IUnknown.Release
// Direct3D seem to be happier with that according to the DirectX log
Marshal.AddRef(unmanagedDevice);
this.unmanagedDevice = unmanagedDevice;
device = new Device(unmanagedDevice);
// Create helper objects to draw over the video
sprite = new Sprite(device);
gdiFont = new System.Drawing.Font("Tahoma", 15);
d3dFont = new Direct3D.Font(device, gdiFont);
// Load a bitmap (the spider) from embedded resources. This is a png file
with alpha transparency
//compute string size for Texture
drawString = Videon.Client.Screen.ScrolledText;
if(drawString == "") drawString = "..";
//drawString = "asdf asdf asd";
size = getStringSizeInGraphics(drawString, font);
redrawTexture(Point.Empty);
using (Stream stream = new MemoryStream())
{
Bitmap b = new Bitmap(device.DisplayMode.Width, (int)size.Height + 4);
Graphics g = Graphics.FromImage(b);
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
int alpha = (int)(255 * 0.45f); // 25% opacity
Brush bFill = new SolidBrush(Color.FromArgb(alpha, Color.White));
g.FillRectangle(bFill, 0, 0, b.Width, b.Height);
b.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
stream.Position = 0;
backTex = TextureLoader.FromStream(device, stream, D3DX.Default,
D3DX.Default, D3DX.Default, D3DX.Default, Usage.None, Format.A8R8G8B8,
Pool.Default, Filter.None, Filter.None, 0);
g.Dispose();
b.Dispose();
}
}
private string drawString = "";
private SizeF size;
private System.Drawing.Font font = new System.Drawing.Font("tahoma", 13);
private void redrawTexture(Point p)
{
// Load a bitmap (the spider) from embedded resources. This is a png file
with alpha transparency
using (Stream stream = new
MemoryStream())//Assembly.GetExecutingAssembly().GetManifestResourceStream("DirectShowLib.Sample.redspider.png"))
{
Bitmap b = new Bitmap((int)size.Width, (int)size.Height);
Graphics g = Graphics.FromImage(b);
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
g.DrawString(drawString, font, new SolidBrush(Color.Black), p);
b.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
stream.Position = 0;
adTex = TextureLoader.FromStream(device, stream, D3DX.Default, D3DX.Default,
D3DX.Default, D3DX.Default, Usage.None, Format.A8R8G8B8, Pool.Default,
Filter.None, Filter.None, 0);
SurfaceDescription adDesc = adTex.GetLevelDescription(0);
adSize = new Size(b.Width, b.Height);
g.Dispose();
b.Dispose();
// adPos.X = adSize.Width + device.DisplayMode.Width;
}
}
private SizeF getStringSizeInGraphics(string s, System.Drawing.Font font)
{
Bitmap b = new Bitmap(1, 1);
Graphics g = Graphics.FromImage(b);
SizeF size = g.MeasureString(s, font);
g.Dispose();
b.Dispose();
return size;
}
}
}
.
- Prev by Date: Re: Managed DirectX, C# and Visual Studio 2008
- Next by Date: Re: Managed DirectX, C# and Visual Studio 2008
- Previous by thread: Re: Managed DirectX, C# and Visual Studio 2008
- Next by thread: Destroying a Frame
- Index(es):
Loading