}
MultimediaDebug.AssertNoError(ret);
+
+ RegisterInputProcessed();
+ RegisterErrorOccurred();
}
#region IDisposable-support
}
/// <summary>
- /// Add the packet to the internal queue of the codec.
+ /// Adds the packet to the internal queue of the codec.
/// </summary>
/// <param name="packet">The packet to be encoded or decoded.</param>
/// <exception cref="ArgumentNullException">packet is null.</exception>
throw new ArgumentNullException(nameof(packet));
}
- MediaPacket.Lock packetLock = new MediaPacket.Lock(packet);
+ MediaPacket.Lock packetLock = MediaPacket.Lock.Get(packet);
int ret = Interop.MediaCodec.Process(_handle, packetLock.GetHandle(), 0);
}
/// <summary>
- /// Flush both input and output buffers.
+ /// Flushes both input and output buffers.
/// </summary>
public void FlushBuffers()
{
#endregion
#region InputProcessed event
- private EventHandler<InputProcessedEventArgs> _inputProcessed;
private Interop.MediaCodec.InputBufferUsedCallback _inputBufferUsedCb;
/// <summary>
/// Occurs when an input packet is processed.
/// </summary>
/// <see cref="ProcessInput(MediaPacket)"/>
- public event EventHandler<InputProcessedEventArgs> InputProcessed
- {
- add
- {
- ValidateNotDisposed();
-
- if (_inputProcessed == null)
- {
- RegisterInputProcessed();
- }
- _inputProcessed += value;
-
- }
- remove
- {
- ValidateNotDisposed();
-
- _inputProcessed -= value;
- if (_inputProcessed == null)
- {
- UnregisterInputProcessed();
- }
- }
- }
+ public event EventHandler<InputProcessedEventArgs> InputProcessed;
private void RegisterInputProcessed()
{
using (MediaPacket.Lock packetLock =
MediaPacket.Lock.FromHandle(lockedPacketHandle))
{
+ Debug.Assert(packetLock != null);
+
packet = packetLock.MediaPacket;
}
Debug.Assert(packet != null);
- _inputProcessed?.Invoke(this, new InputProcessedEventArgs(packet));
+ InputProcessed?.Invoke(this, new InputProcessedEventArgs(packet));
};
int ret = Interop.MediaCodec.SetInputBufferUsedCb(_handle,
#endregion
#region ErrorOccurred event
- private EventHandler<MediaCodecErrorOccurredEventArgs> _errorOccurred;
private Interop.MediaCodec.ErrorCallback _errorCb;
- // TODO replace
/// <summary>
/// Occurs whenever an error is produced in the codec.
/// </summary>
- public event EventHandler<MediaCodecErrorOccurredEventArgs> ErrorOccurred
- {
- add
- {
- ValidateNotDisposed();
-
- if (_errorOccurred == null)
- {
- RegisterErrorOccurred();
- }
- _errorOccurred += value;
-
- }
- remove
- {
- ValidateNotDisposed();
-
- _errorOccurred -= value;
- if (_errorOccurred == null)
- {
- UnregisterErrorOccurred();
- }
- }
- }
+ public event EventHandler<MediaCodecErrorOccurredEventArgs> ErrorOccurred;
private void RegisterErrorOccurred()
{
MediaCodecError error = (Enum.IsDefined(typeof(MediaCodecError), errorCode)) ?
(MediaCodecError)errorCode : MediaCodecError.InternalError;
- _errorOccurred?.Invoke(this, new MediaCodecErrorOccurredEventArgs(error));
+ ErrorOccurred?.Invoke(this, new MediaCodecErrorOccurredEventArgs(error));
};
int ret = Interop.MediaCodec.SetErrorCb(_handle, _errorCb, IntPtr.Zero);
{
private readonly MediaPacket _packet;
private readonly GCHandle _gcHandle;
+ private int _lockCount;
- internal Lock(MediaPacket packet)
+ internal static Lock Get(MediaPacket packet)
+ {
+ Debug.Assert(packet != null);
+
+ lock (packet)
+ {
+ Lock lck = FromHandle(packet._handle);
+
+ if (lck == null)
+ {
+ lck = new Lock(packet);
+ }
+
+ lck._lockCount++;
+
+ return lck;
+ }
+ }
+
+ private Lock(MediaPacket packet)
{
Debug.Assert(packet != null, "The packet is null!");
IntPtr extra = GetExtra(handle);
- Debug.Assert(extra != IntPtr.Zero, "Extra of packet must not be null.");
+ if (extra == IntPtr.Zero)
+ {
+ return null;
+ }
return (Lock)GCHandle.FromIntPtr(extra).Target;
}
{
if (!_isDisposed)
{
- // TODO rollback after the corresponding native api is fixed.
- //SetExtra(IntPtr.Zero);
-
- if (_gcHandle.IsAllocated)
+ lock (_packet)
{
- _gcHandle.Free();
- }
+ _lockCount--;
+
+ if (_lockCount == 0)
+ {
+ // TODO rollback after the corresponding native api is fixed.
+ //SetExtra(IntPtr.Zero);
- //We can assure that at this point '_packet' is always locked by this lock.
- _packet._lock.SetUnlock();
+ if (_gcHandle.IsAllocated)
+ {
+ _gcHandle.Free();
+ }
+
+ //We can assure that at this point '_packet' is always locked by this lock.
+ _packet._lock.SetUnlock();
+ }
+ }
_isDisposed = true;
}