This repository has been archived by the owner on Mar 30, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 640
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[MediaFoundation] Fix issue #38. Implemented AsyncCallback for MediaE…
…ventGenerator.
- Loading branch information
Alexandre Mutel
committed
Jun 25, 2013
1 parent
9d121f8
commit c5e6484
Showing
7 changed files
with
306 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
// Copyright (c) 2010-2012 SharpDX - Alexandre Mutel | ||
// | ||
// Permission is hereby granted, free of charge, to any person obtaining a copy | ||
// of this software and associated documentation files (the "Software"), to deal | ||
// in the Software without restriction, including without limitation the rights | ||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
// copies of the Software, and to permit persons to whom the Software is | ||
// furnished to do so, subject to the following conditions: | ||
// | ||
// The above copyright notice and this permission notice shall be included in | ||
// all copies or substantial portions of the Software. | ||
// | ||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
// THE SOFTWARE. | ||
|
||
namespace SharpDX.MediaFoundation | ||
{ | ||
/// <summary> | ||
/// A default implementation of AsyncCallbackBase. | ||
/// </summary> | ||
public abstract class AsyncCallbackBase : CallbackBase, IAsyncCallback | ||
{ | ||
public virtual AsyncCallbackFlags Flags | ||
{ | ||
get { return AsyncCallbackFlags.None; } | ||
} | ||
|
||
public virtual WorkQueueId WorkQueueId | ||
{ | ||
get { return WorkQueueId.Standard; } | ||
} | ||
|
||
public abstract void Invoke(AsyncResult asyncResult); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
// Copyright (c) 2010-2013 SharpDX - Alexandre Mutel | ||
// | ||
// Permission is hereby granted, free of charge, to any person obtaining a copy | ||
// of this software and associated documentation files (the "Software"), to deal | ||
// in the Software without restriction, including without limitation the rights | ||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
// copies of the Software, and to permit persons to whom the Software is | ||
// furnished to do so, subject to the following conditions: | ||
// | ||
// The above copyright notice and this permission notice shall be included in | ||
// all copies or substantial portions of the Software. | ||
// | ||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
// THE SOFTWARE. | ||
using System; | ||
using System.Runtime.InteropServices; | ||
|
||
namespace SharpDX.MediaFoundation | ||
{ | ||
/// <summary> | ||
/// Internal AsyncCallback Callback | ||
/// </summary> | ||
internal class AsyncCallbackShadow : SharpDX.ComObjectShadow | ||
{ | ||
private static readonly AsyncCallbackVtbl Vtbl = new AsyncCallbackVtbl(); | ||
|
||
/// <summary> | ||
/// Return a pointer to the unmanaged version of this callback. | ||
/// </summary> | ||
/// <param name="callback">The callback.</param> | ||
/// <returns>A pointer to a shadow c++ callback</returns> | ||
public static IntPtr ToIntPtr(IAsyncCallback callback) | ||
{ | ||
return ToCallbackPtr<IAsyncCallback>(callback); | ||
} | ||
|
||
public class AsyncCallbackVtbl : ComObjectVtbl | ||
{ | ||
public AsyncCallbackVtbl() : base(2) | ||
{ | ||
AddMethod(new GetParametersDelegate(GetParametersImpl)); | ||
AddMethod(new InvokeDelegate(InvokeImpl)); | ||
} | ||
|
||
/// <unmanaged>HRESULT IMFAsyncCallback::GetParameters([Out] MFASYNC_CALLBACK_FLAGS* pdwFlags,[Out] unsigned int* pdwQueue)</unmanaged> | ||
[UnmanagedFunctionPointer(CallingConvention.StdCall)] | ||
private delegate int GetParametersDelegate(IntPtr thisPtr, out AsyncCallbackFlags flags, out WorkQueueId workQueueId); | ||
private static int GetParametersImpl(IntPtr thisPtr, out AsyncCallbackFlags flags, out WorkQueueId workQueueId) | ||
{ | ||
flags = AsyncCallbackFlags.None; | ||
workQueueId = WorkQueueId.Standard; | ||
try | ||
{ | ||
var shadow = ToShadow<AsyncCallbackShadow>(thisPtr); | ||
var callback = (IAsyncCallback)shadow.Callback; | ||
workQueueId = callback.WorkQueueId; | ||
flags = callback.Flags; | ||
} | ||
catch (Exception exception) | ||
{ | ||
return (int)SharpDX.Result.GetResultFromException(exception); | ||
} | ||
return Result.Ok.Code; | ||
} | ||
|
||
/// <unmanaged>HRESULT IMFAsyncCallback::Invoke([In, Optional] IMFAsyncResult* pAsyncResult)</unmanaged> | ||
[UnmanagedFunctionPointer(CallingConvention.StdCall)] | ||
private delegate int InvokeDelegate(IntPtr thisPtr, IntPtr asyncResult); | ||
private static int InvokeImpl(IntPtr thisPtr, IntPtr asyncResult) | ||
{ | ||
try | ||
{ | ||
var shadow = ToShadow<AsyncCallbackShadow>(thisPtr); | ||
var callback = (IAsyncCallback)shadow.Callback; | ||
callback.Invoke(new AsyncResult(asyncResult)); | ||
} | ||
catch (Exception exception) | ||
{ | ||
return (int)SharpDX.Result.GetResultFromException(exception); | ||
} | ||
return Result.Ok.Code; | ||
} | ||
} | ||
|
||
protected override CppObjectVtbl GetVtbl | ||
{ | ||
get { return Vtbl; } | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
// Copyright (c) 2010-2013 SharpDX - Alexandre Mutel | ||
// | ||
// Permission is hereby granted, free of charge, to any person obtaining a copy | ||
// of this software and associated documentation files (the "Software"), to deal | ||
// in the Software without restriction, including without limitation the rights | ||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
// copies of the Software, and to permit persons to whom the Software is | ||
// furnished to do so, subject to the following conditions: | ||
// | ||
// The above copyright notice and this permission notice shall be included in | ||
// all copies or substantial portions of the Software. | ||
// | ||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
// THE SOFTWARE. | ||
|
||
using System; | ||
using System.Runtime.InteropServices; | ||
|
||
namespace SharpDX.MediaFoundation | ||
{ | ||
public partial class AsyncResult | ||
{ | ||
private object state; | ||
private bool isStateVerified; | ||
|
||
/// <summary> | ||
/// Gets the state object specified by the caller in the asynchronous <strong>Begin</strong> method. If the value is not <strong><c>null</c></strong>, the caller must dispose. | ||
/// </summary> | ||
/// <value>The state.</value> | ||
/// <remarks> | ||
/// <p>The caller of the asynchronous method specifies the state object, and can use it for any caller-defined purpose. The state object can be <strong><c>null</c></strong>. If the state object is <strong><c>null</c></strong>, <strong>GetState</strong> returns <strong>E_POINTER</strong>.</p><p>If you are implementing an asynchronous method, set the state object on the through the <em>punkState</em> parameter of the <strong><see cref="SharpDX.MediaFoundation.MediaFactory.CreateAsyncResult"/></strong> function.</p><p>This interface is available on the following platforms if the Windows Media Format 11 SDK redistributable components are installed:</p><ul> <li>Windows?XP with Service Pack?2 (SP2) and later.</li> <li>Windows?XP Media Center Edition?2005 with KB900325 (Windows?XP Media Center Edition?2005) and KB925766 (October 2006 Update Rollup for Windows?XP Media Center Edition) installed.</li> </ul> | ||
/// </remarks> | ||
/// <msdn-id>bb970576</msdn-id> | ||
/// <unmanaged>HRESULT IMFAsyncResult::GetState([Out] IUnknown** ppunkState)</unmanaged> | ||
/// <unmanaged-short>IMFAsyncResult::GetState</unmanaged-short> | ||
public object State | ||
{ | ||
get | ||
{ | ||
if (!isStateVerified) | ||
{ | ||
IntPtr statePtr; | ||
GetState(out statePtr); | ||
if (statePtr != IntPtr.Zero) | ||
{ | ||
state = Marshal.GetObjectForIUnknown(statePtr); | ||
Marshal.Release(statePtr); | ||
} | ||
isStateVerified = true; | ||
} | ||
return state; | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// <p>Get or sets the status of the asynchronous operation.</p> | ||
/// </summary> | ||
/// <value><p>The method returns an <strong><see cref="SharpDX.Result"/></strong>. Possible values include, but are not limited to, those in the following table.</p><table> <tr><th>Return code</th><th>Description</th></tr> <tr><td> <dl> <dt><strong><see cref="SharpDX.Result.Ok"/></strong></dt> </dl> </td><td> <p>The operation completed successfully.</p> </td></tr> </table><p>?</p></value> | ||
/// <remarks> | ||
/// <p>This interface is available on the following platforms if the Windows Media Format 11 SDK redistributable components are installed:</p><ul> <li>Windows?XP with Service Pack?2 (SP2) and later.</li> <li>Windows?XP Media Center Edition?2005 with KB900325 (Windows?XP Media Center Edition?2005) and KB925766 (October 2006 Update Rollup for Windows?XP Media Center Edition) installed.</li> </ul> | ||
/// </remarks> | ||
/// <msdn-id>ms702095</msdn-id> | ||
/// <unmanaged>HRESULT IMFAsyncResult::GetStatus()</unmanaged> | ||
/// <unmanaged-short>IMFAsyncResult::GetStatus</unmanaged-short> | ||
public SharpDX.Result Status | ||
{ | ||
get { return GetStatus(); } | ||
set { SetStatus(value); } | ||
} | ||
|
||
/// <summary> | ||
/// <p><strong>Applies to: </strong>desktop apps | Metro style apps</p><p> </p><p>Returns an object associated with the asynchronous operation. The type of object, if any, depends on the asynchronous method that was called.</p> | ||
/// </summary> | ||
/// <value><dd> <p>Receives a reference to the object's <strong><see cref="SharpDX.ComObject"/></strong> interface. If no object is associated with the operation, this parameter receives the value <strong><c>null</c></strong>. If the value is not <strong><c>null</c></strong>, the caller must release the interface.</p> </dd></value> | ||
/// <remarks> | ||
/// <p>Typically, this object is used by the component that implements the asynchronous method. It provides a way for the function that invokes the callback to pass information to the asynchronous <strong>End...</strong> method that completes the operation.</p><p>If you are implementing an asynchronous method, you can set the object through the <em>punkObject</em> parameter of the <strong><see cref="SharpDX.MediaFoundation.MediaFactory.CreateAsyncResult"/></strong> function.</p><p>If the asynchronous result object's internal <strong><see cref="SharpDX.ComObject"/></strong> reference is <strong><c>null</c></strong>, the method returns <strong>E_POINTER</strong>.</p><p>This interface is available on the following platforms if the Windows Media Format 11 SDK redistributable components are installed:</p><ul> <li>Windows?XP with Service Pack?2 (SP2) and later.</li> <li>Windows?XP Media Center Edition?2005 with KB900325 (Windows?XP Media Center Edition?2005) and KB925766 (October 2006 Update Rollup for Windows?XP Media Center Edition) installed.</li> </ul> | ||
/// </remarks> | ||
/// <msdn-id>bb970500</msdn-id> | ||
/// <unmanaged>HRESULT IMFAsyncResult::GetObjectW([Out] IUnknown** ppObject)</unmanaged> | ||
/// <unmanaged-short>IMFAsyncResult::GetObjectW</unmanaged-short> | ||
public ComObject PrivateObject | ||
{ | ||
get | ||
{ | ||
ComObject privateObject; | ||
GetObjectW(out privateObject); | ||
return privateObject; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
// Copyright (c) 2010-2012 SharpDX - Alexandre Mutel | ||
// | ||
// Permission is hereby granted, free of charge, to any person obtaining a copy | ||
// of this software and associated documentation files (the "Software"), to deal | ||
// in the Software without restriction, including without limitation the rights | ||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
// copies of the Software, and to permit persons to whom the Software is | ||
// furnished to do so, subject to the following conditions: | ||
// | ||
// The above copyright notice and this permission notice shall be included in | ||
// all copies or substantial portions of the Software. | ||
// | ||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
// THE SOFTWARE. | ||
|
||
using System; | ||
using System.Runtime.InteropServices; | ||
|
||
namespace SharpDX.MediaFoundation | ||
{ | ||
public partial class MediaEventGenerator | ||
{ | ||
/// <summary> | ||
/// <p><strong>Applies to: </strong>desktop apps | Metro style apps</p><p> </p><p>Retrieves the next event in the queue. This method is synchronous.</p> | ||
/// </summary> | ||
/// <param name="isBlocking"><c>true</c> if the method blocks until the event generator queues an event, <c>false</c> otherwise.</param> | ||
/// <returns>a reference to the <strong><see cref="SharpDX.MediaFoundation.MediaEvent"/></strong> interface. The caller must release the interface.</returns> | ||
/// <remarks> | ||
/// <p>This method executes synchronously.</p><p>If the queue already contains an event, the method returns <see cref="SharpDX.Result.Ok"/> immediately. If the queue does not contain an event, the behavior depends on the value of <em>dwFlags</em>:</p><ul> <li> <p>If <em>dwFlags</em> is 0, the method blocks indefinitely until a new event is queued, or until the event generator is shut down.</p> </li> <li> <p>If <em>dwFlags</em> is MF_EVENT_FLAG_NO_WAIT, the method fails immediately with the return code <see cref="SharpDX.MediaFoundation.ResultCode.NoEventsAvailable"/>.</p> </li> </ul><p>This method returns <see cref="SharpDX.MediaFoundation.ResultCode.MultipleSubScribers"/> if you previously called <strong><see cref="SharpDX.MediaFoundation.MediaEventGenerator.BeginGetEvent_"/></strong> and have not yet called <strong><see cref="SharpDX.MediaFoundation.MediaEventGenerator.EndGetEvent"/></strong>.</p> | ||
/// </remarks> | ||
/// <msdn-id>ms704754</msdn-id> | ||
/// <unmanaged>HRESULT IMFMediaEventGenerator::GetEvent([In] unsigned int dwFlags,[Out] IMFMediaEvent** ppEvent)</unmanaged> | ||
/// <unmanaged-short>IMFMediaEventGenerator::GetEvent</unmanaged-short> | ||
public MediaEvent GetEvent(bool isBlocking) | ||
{ | ||
MediaEvent mediaEvent; | ||
GetEvent(isBlocking ? 1 : 0, out mediaEvent); | ||
return mediaEvent; | ||
} | ||
|
||
/// <summary> | ||
/// <p><strong>Applies to: </strong>desktop apps | Metro style apps</p><p> </p><p>Begins an asynchronous request for the next event in the queue.</p> | ||
/// </summary> | ||
/// <param name="callback"><dd> <p>Pointer to the <strong><see cref="SharpDX.MediaFoundation.IAsyncCallback"/></strong> interface of a callback object. The client must implement this interface.</p> </dd></param> | ||
/// <param name="stateObject">A reference to a state object, defined by the caller. This parameter can be <strong><c>null</c></strong>. You can use this object to hold state information. The object is returned to the caller when the callback is invoked.</param> | ||
/// <remarks> | ||
/// <p>When a new event is available, the event generator calls the <strong><see cref="SharpDX.MediaFoundation.IAsyncCallback.Invoke"/></strong> method. The <strong>Invoke</strong> method should call <strong><see cref="SharpDX.MediaFoundation.MediaEventGenerator.EndGetEvent"/></strong> to get a reference to the <strong><see cref="SharpDX.MediaFoundation.MediaEvent"/></strong> interface, and use that interface to examine the event.</p><p>Do not call <strong>BeginGetEvent</strong> a second time before calling <strong>EndGetEvent</strong>. While the first call is still pending, additional calls to the same object will fail. Also, the <strong><see cref="SharpDX.MediaFoundation.MediaEventGenerator.GetEvent"/></strong> method fails if an asynchronous request is still pending.</p> | ||
/// </remarks> | ||
/// <msdn-id>ms701637</msdn-id> | ||
/// <unmanaged>HRESULT IMFMediaEventGenerator::BeginGetEvent([In] IMFAsyncCallback* pCallback,[In] void* punkState)</unmanaged> | ||
/// <unmanaged-short>IMFMediaEventGenerator::BeginGetEvent</unmanaged-short> | ||
public void BeginGetEvent(IAsyncCallback callback, object stateObject) | ||
{ | ||
BeginGetEvent_(AsyncCallbackShadow.ToIntPtr(callback), stateObject == null ? IntPtr.Zero : Marshal.GetIUnknownForObject(stateObject)); | ||
} | ||
} | ||
} |
Oops, something went wrong.