Skip to content

Commit

Permalink
Bugfixes (Memory Leak), fallback mechanism to auto generate graph if …
Browse files Browse the repository at this point in the history
…manually generated graph doesn't work, fix video playback if no audio device is available, LAV Splitter Source is not hardcorded anymore, EVR is default Video Renderer
  • Loading branch information
Sascha-L committed Sep 15, 2015
1 parent bda877a commit 430ef2c
Show file tree
Hide file tree
Showing 20 changed files with 825 additions and 126 deletions.
1 change: 1 addition & 0 deletions EVR Presenter/EVRPresenter.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@
<DataExecutionPrevention>
</DataExecutionPrevention>
<TargetMachine>MachineX86</TargetMachine>
<AssemblyDebug>true</AssemblyDebug>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
Expand Down
2 changes: 2 additions & 0 deletions EVR Presenter/Helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ class ThreadSafeQueue
ComPtrList<T> m_list;
};

//#define FILE_LOGGING

#if defined FILE_LOGGING

Expand Down Expand Up @@ -176,6 +177,7 @@ static void LogGUID(const char *msg, REFGUID guid )

#else


#define LOG_MSG(msg)
#define LOG_GUID(msg, guid)
#define LOG_IF_FAILED(msg, hr)
Expand Down
2 changes: 1 addition & 1 deletion Source/DirectShow/Controls/MediaUriElement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public MediaUriPlayer MediaUriPlayer

public static readonly DependencyProperty VideoRendererProperty =
DependencyProperty.Register("VideoRenderer", typeof(VideoRendererType), typeof(MediaUriElement),
new FrameworkPropertyMetadata(VideoRendererType.VideoMixingRenderer9,
new FrameworkPropertyMetadata(VideoRendererType.EnhancedVideoRenderer,
new PropertyChangedCallback(OnVideoRendererChanged)));

public VideoRendererType VideoRenderer
Expand Down
155 changes: 78 additions & 77 deletions Source/DirectShow/MediaPlayers/BaseClasses.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#region Includes
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Runtime.CompilerServices;
Expand All @@ -12,7 +11,7 @@
using WPFMediaKit.MediaFoundation;
using WPFMediaKit.MediaFoundation.Interop;
using WPFMediaKit.Threading;
using Size=System.Windows.Size;
using Size = System.Windows.Size;
#endregion

namespace WPFMediaKit.DirectShow.MediaPlayers
Expand Down Expand Up @@ -305,7 +304,7 @@ private void GetMainWindowHwndHelper()

if (m_window.Handle == IntPtr.Zero)
{
lock(m_window)
lock (m_window)
{
m_window.CreateHandle(new CreateParams());
}
Expand Down Expand Up @@ -495,7 +494,7 @@ protected virtual void Dispose(bool disposing)
//if (m_disposed)
// return;

if(!disposing)
if (!disposing)
return;

if (m_window != null)
Expand All @@ -509,8 +508,8 @@ protected virtual void Dispose(bool disposing)
m_timer.Dispose();

m_timer = null;
if(CheckAccess())

if (CheckAccess())
{
FreeResources();
Dispatcher.BeginInvokeShutdown();
Expand Down Expand Up @@ -637,7 +636,7 @@ private void RemoveWndProcHook()
/// </summary>
private void AddWndProcHook()
{
// HwndHelper.AddHook(WndProcHook);
// HwndHelper.AddHook(WndProcHook);
}

/// <summary>
Expand Down Expand Up @@ -771,14 +770,16 @@ protected void FreeCustomAllocator()
if (m_customAllocator == null)
return;

m_customAllocator.Dispose();

m_customAllocator.NewAllocatorFrame -= CustomAllocatorNewAllocatorFrame;
m_customAllocator.NewAllocatorSurface -= CustomAllocatorNewAllocatorSurface;

if(Marshal.IsComObject(m_customAllocator))
m_customAllocator.Dispose();



if (Marshal.IsComObject(m_customAllocator))
Marshal.ReleaseComObject(m_customAllocator);

m_customAllocator = null;
}

Expand All @@ -798,7 +799,7 @@ private void ResetLocalGraphResources()
Marshal.ReleaseComObject(m_mediaControl);
m_mediaControl = null;

if(m_mediaEvent != null)
if (m_mediaEvent != null)
Marshal.ReleaseComObject(m_mediaEvent);
m_mediaEvent = null;
}
Expand Down Expand Up @@ -859,7 +860,7 @@ private IBaseFilter CreateEnhancedVideoRenderer(IGraphBuilder graph, int streamC
EvrPresenter presenter;
IBaseFilter filter;

lock(m_videoRendererInitLock)
lock (m_videoRendererInitLock)
{
var evr = new EnhancedVideoRenderer();
filter = evr as IBaseFilter;
Expand All @@ -883,7 +884,7 @@ private IBaseFilter CreateEnhancedVideoRenderer(IGraphBuilder graph, int streamC
var presenterSettings = presenter.VideoPresenter as IEVRPresenterSettings;
if (presenterSettings == null)
throw new Exception("Could not QueryInterface for the IEVRPresenterSettings");

presenterSettings.SetBufferCount(3);

/* Use our interop hWnd */
Expand All @@ -900,12 +901,12 @@ private IBaseFilter CreateEnhancedVideoRenderer(IGraphBuilder graph, int streamC
DsError.ThrowExceptionForHR(hr);

var filterConfig = filter as IEVRFilterConfig;

if (filterConfig != null)
filterConfig.SetNumberOfStreams(streamCount);
}


RegisterCustomAllocator(presenter);

return filter;
Expand Down Expand Up @@ -939,7 +940,7 @@ private IBaseFilter CreateVideoMixingRenderer9(IGraphBuilder graph, int streamCo

if (vmrSurfAllocNotify == null)
throw new Exception("Could not query the VMR surface allocator.");

var allocator = new Vmr9Allocator();

/* We supply our custom allocator to the renderer */
Expand All @@ -951,7 +952,7 @@ private IBaseFilter CreateVideoMixingRenderer9(IGraphBuilder graph, int streamCo

RegisterCustomAllocator(allocator);

hr = graph.AddFilter(vmr9,
hr = graph.AddFilter(vmr9,
string.Format("Renderer: {0}", VideoRendererType.VideoMixingRenderer9));

DsError.ThrowExceptionForHR(hr);
Expand Down Expand Up @@ -1104,7 +1105,7 @@ protected void InvokeNewAllocatorSurface(IntPtr pSurface)
}

#endregion

#region Helper Methods
/// <summary>
/// Sets the natural pixel resolution the video in the graph
Expand Down Expand Up @@ -1136,14 +1137,14 @@ protected static Size GetVideoSize(IBaseFilter renderer, PinDirection direction,

if (pin == null)
goto done;

int hr = pin.ConnectionMediaType(mediaType);

if (hr != 0)
goto done;

/* Check to see if its a video media type */
if (mediaType.formatType != FormatType.VideoInfo2 &&
if (mediaType.formatType != FormatType.VideoInfo2 &&
mediaType.formatType != FormatType.VideoInfo)
{
goto done;
Expand All @@ -1159,8 +1160,8 @@ protected static Size GetVideoSize(IBaseFilter renderer, PinDirection direction,

done:
DsUtils.FreeAMMediaType(mediaType);
if(pin != null)

if (pin != null)
Marshal.ReleaseComObject(pin);
return size;
}
Expand Down Expand Up @@ -1210,69 +1211,69 @@ protected static void RemoveAllFilters(IGraphBuilder graphBuilder)
{
graphBuilder.RemoveFilter(filtersArray[i]);
while (Marshal.ReleaseComObject(filtersArray[i]) > 0)
{}
{ }
}
}

/// <summary>
/// Adds a filter to a DirectShow graph based on it's name and filter category
/// </summary>
/// <param name="graphBuilder">The graph builder to add the filter to</param>
/// <param name="deviceCategory">The category the filter belongs to</param>
/// <param name="friendlyName">The friendly name of the filter</param>
/// <returns>Reference to the IBaseFilter that was added to the graph or returns null if unsuccessful</returns>
protected static IBaseFilter AddFilterByName(IGraphBuilder graphBuilder, Guid deviceCategory, string friendlyName)
{
var devices = DsDevice.GetDevicesOfCat(deviceCategory);

var deviceList = (from d in devices
where d.Name == friendlyName
select d);
DsDevice device = null;
if (deviceList.Count() > 0)
device = deviceList.Take(1).Single();

foreach (var item in deviceList)
{
/// <summary>
/// Adds a filter to a DirectShow graph based on it's name and filter category
/// </summary>
/// <param name="graphBuilder">The graph builder to add the filter to</param>
/// <param name="deviceCategory">The category the filter belongs to</param>
/// <param name="friendlyName">The friendly name of the filter</param>
/// <returns>Reference to the IBaseFilter that was added to the graph or returns null if unsuccessful</returns>
protected static IBaseFilter AddFilterByName(IGraphBuilder graphBuilder, Guid deviceCategory, string friendlyName)
{
var devices = DsDevice.GetDevicesOfCat(deviceCategory);

var deviceList = (from d in devices
where d.Name == friendlyName
select d);
DsDevice device = null;
if (deviceList.Count() > 0)
device = deviceList.Take(1).Single();

foreach (var item in deviceList)
{
if (item != device)
item.Dispose();
}
}

return AddFilterByDevice(graphBuilder, device);
}
return AddFilterByDevice(graphBuilder, device);
}

protected static IBaseFilter AddFilterByDevicePath(IGraphBuilder graphBuilder, Guid deviceCategory, string devicePath)
{
var devices = DsDevice.GetDevicesOfCat(deviceCategory);
protected static IBaseFilter AddFilterByDevicePath(IGraphBuilder graphBuilder, Guid deviceCategory, string devicePath)
{
var devices = DsDevice.GetDevicesOfCat(deviceCategory);

var deviceList = (from d in devices
where d.DevicePath == devicePath
select d);
DsDevice device = null;
if (deviceList.Count() > 0)
device = deviceList.Take(1).Single();
var deviceList = (from d in devices
where d.DevicePath == devicePath
select d);
DsDevice device = null;
if (deviceList.Count() > 0)
device = deviceList.Take(1).Single();

return AddFilterByDevice(graphBuilder, device);
}
return AddFilterByDevice(graphBuilder, device);
}

private static IBaseFilter AddFilterByDevice(IGraphBuilder graphBuilder, DsDevice device)
{
if (graphBuilder == null)
throw new ArgumentNullException("graphBuilder");
private static IBaseFilter AddFilterByDevice(IGraphBuilder graphBuilder, DsDevice device)
{
if (graphBuilder == null)
throw new ArgumentNullException("graphBuilder");

var filterGraph = graphBuilder as IFilterGraph2;
var filterGraph = graphBuilder as IFilterGraph2;

if (filterGraph == null)
return null;
if (filterGraph == null)
return null;

IBaseFilter filter = null;
if (device != null)
{
int hr = filterGraph.AddSourceFilterForMoniker(device.Mon, null, device.Name, out filter);
DsError.ThrowExceptionForHR(hr);
}
return filter;
}
IBaseFilter filter = null;
if (device != null)
{
int hr = filterGraph.AddSourceFilterForMoniker(device.Mon, null, device.Name, out filter);
DsError.ThrowExceptionForHR(hr);
}
return filter;
}

/// <summary>
/// Finds a pin that exists in a graph.
Expand All @@ -1284,7 +1285,7 @@ private static IBaseFilter AddFilterByDevice(IGraphBuilder graphBuilder, DsDevic
protected static IPin FindPinInGraphByMediaType(Guid majorOrMinorMediaType, PinDirection pinDirection, IGraphBuilder graph)
{
IEnumFilters enumFilters;

/* Get the filter enum */
graph.EnumFilters(out enumFilters);

Expand All @@ -1308,7 +1309,7 @@ protected static IPin FindPinInGraphByMediaType(Guid majorOrMinorMediaType, PinD
pin.EnumMediaTypes(out mediaTypesEnum);
var mediaTypesFetched = IntPtr.Zero;
var mediaTypes = new AMMediaType[1];

/* Enumerate the media types on the pin */
while (mediaTypesEnum.Next(1, mediaTypes, mediaTypesFetched) == 0)
{
Expand Down
Loading

1 comment on commit 430ef2c

@MatriXiao88
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bugfixes (Memory Leak)...
Does the commit fix the memory leak, or is there a memory leak problem in the commit?

Please sign in to comment.