System.OutOfMemoryException



Hi

I'm using the WMEncoder with C#. And it appears to be causing this
exception. Can any body help?

The encoder runs as part of a service processing encodings required.
For every encoding a new instance of the encoder is used (WmaEncoder
class below). This is because any error caused within the encoder was
found to throw subsequent errors when processing new encodings through
the same instance of WMEncoder.

I have proved that all the .net managed objects are being garbage
collected correctly i.e. there is no memory loss from my code. So can
only assume the WMEncoder is not being tidied correctly. Is there a
better way of implementing the WMEncoder or is it just bad at loosing
memory?

My implementation is copied in below.

A single instance of the class is created for each encoding call.

Thanks in advance,
Dave



internal class WmaEncoder
{
private Hashtable _profiles;
private WMEncoder _encoder;
private int _errorCode = 0;
private ManualResetEvent _completionSignal;

public WmaEncoder(string profilePath)
{
if (profilePath == null) throw new
ArgumentNullException("profilePath");

_profiles = new Hashtable();

foreach (FileInfo file in new
DirectoryInfo(profilePath).GetFiles("*.prx"))
{
WMEncProfile2 profile = new WMEncProfile2();
profile.LoadFromFile(file.FullName);
_profiles.Add(Path.GetFileNameWithoutExtension(file.Name),
profile);
}

_encoder = new WMEncoder();
_encoder.OnStateChange += new
_IWMEncoderEvents_OnStateChangeEventHandler(OnStateChange);
_encoder.OnError += new
_IWMEncoderEvents_OnErrorEventHandler(OnError);

_completionSignal = new ManualResetEvent(false);

}

/// <summary>
///
/// </summary>
/// <param name="sourceFile">The source file to encode from</param>
/// <param name="outputFolder">The folder to drop the created file
into</param>
/// <param name="format">The required WMA codec/bit rate etc</param>
/// <param name="start">The offset to create the clip from (in
milliseconds)</param>
/// <param name="duration">The duration of the clip (in
milliseconds)</param>
/// <returns>The created file</returns>
/// <exception cref="WmaEncoderException">Thrown if there was an
error with the encoding request, but subsequent encodings should still
be attempted.</exception>
public FileInfo Encode(FileInfo sourceFile,
DirectoryInfo outputFolder,
WmaFormat format,
int start,
int duration,
string fileExt,
ref int actualDuration)
{
if (sourceFile == null) throw new
ArgumentNullException("sourceFile");
if (outputFolder == null) throw new
ArgumentNullException("outputFolder");
if (fileExt == null) throw new ArgumentNullException("fileExt");

if (outputFolder.Exists == false) outputFolder.Create();

_encoder.Reset();
_errorCode = 0;
_completionSignal.Reset();

IWMEncSourceGroup srcGrp =
_encoder.SourceGroupCollection.Add("SG1");

// Retrieve the profile matching the requested format
if (_profiles.ContainsKey(format.ToString()))
{
srcGrp.set_Profile(_profiles[format.ToString()]);
}
else
{
throw new WmaEncoderException("No profile could be loaded for the
format: " + format.ToString());
}

IWMEncAudioSource srcAud =
(IWMEncAudioSource)srcGrp.AddSource(WMENC_SOURCE_TYPE.WMENC_AUDIO);
srcAud.SetInput(sourceFile.FullName, "", "");
if (format.ToString().EndsWith("Vbr"))
{
srcAud.PreProcessPass = 1;
}
else
{
srcAud.PreProcessPass = 0;
}

// Output file
string outputFile = Path.Combine(outputFolder.FullName,
Guid.NewGuid().ToString() + "." + fileExt);
IWMEncFile2 file = (IWMEncFile2)_encoder.File;
file.LocalFileName = outputFile;
try
{
_encoder.PrepareToEncode(true);

// Get the length (in milliseconds) of the song
// NB. We can only read this property after the call to
PrepareToEncode
int songLength = srcAud.Duration;

// Do we want a clip instead of the full track?
if (start > 0 || duration > 0)
{
Utility.CalculateClip(ref start, ref duration,
songLength);

if (start > 0) srcAud.MarkIn = start;
if (duration > 0 && duration < songLength)
srcAud.MarkOut = start + duration;
}

// Calculate the actual duration of the file we are
about to create.
// We want this in seconds and we will pass it out
through the ref parameter
if (srcAud.MarkOut > 0)
{
actualDuration = (srcAud.MarkOut - srcAud.MarkIn) /
1000;
}
else
{
actualDuration = (songLength - srcAud.MarkIn) /
1000;
}

// The call to start is asynchronous
// Wait for the encoding to finish
_encoder.Start();
_completionSignal.WaitOne();

if (_errorCode != 0)
{
try
{
// Found this was necessary otherwise the
encoder keeps a lock on the source file
_encoder.Reset();
}
catch
{
// Sometimes the Reset call fails because of
the original error that has occured.
// We will swallow this exception otherwise it
will obscure the root cause.
}

throw new
WmaEncoderException(WmaEncoderException.BuildExceptionMessage(_errorCode));
}


}
finally
{
// Found this was necessary otherwise the encoder keeps
a lock on the source file
_encoder.Reset();
//required to ensure wmaencoder object is released
_encoder.OnStateChange -= new
_IWMEncoderEvents_OnStateChangeEventHandler(OnStateChange);
_encoder.OnError -= new
_IWMEncoderEvents_OnErrorEventHandler(OnError);
}
return new FileInfo(outputFile);
}

private void OnError(int errorCode)
{
_errorCode = errorCode;
_completionSignal.Set();
}

private void OnStateChange(WMENC_ENCODER_STATE enumState)
{
if (enumState == WMENC_ENCODER_STATE.WMENC_ENCODER_STOPPED)
{
// The encoding has completed
_completionSignal.Set();
}
}
}

.



Relevant Pages

  • Re: Media encoder remainig open with oe task (tasklist) on XP
    ... on some machines the encoder behaves strange ... after starting the encoder and loading a profile for encoding ... and later closing the encoder (wehter after encoding or yust after loading ...
    (microsoft.public.windowsmedia.encoder)
  • Re: Using EncoderSDK to control encoder, no interface is shown... how?
    ... interface to start/stop and setup the profile to use for encoding. ... I'm getting a request that when I start the encoder, ...
    (microsoft.public.windowsmedia.sdk)
  • Re: Canopus ProCoder 2 mpeg 2 to XVID (MPEG4) OR DIVX conversion help please?
    ... There is a reason all those settings are made available. ... do a single pass encoding or a multi-pass encoding. ... Once you have everything set right make a profile and/or write down ... especially true if you have to reinstall the encoder or your OS. ...
    (rec.video.desktop)
  • RE: compressing mp3 files
    ... > structure of encoding process is identical in all Layers. ... The continuation of the encoding process depends on used Layer. ... > encoded with its own bitrate, calculated by encoder. ... > We shall consider now existing encoding techniques of stereo data stipulated ...
    (microsoft.public.windowsxp.music)
  • RE: compressing mp3 files
    ... > structure of encoding process is identical in all Layers. ... The continuation of the encoding process depends on used Layer. ... > encoded with its own bitrate, calculated by encoder. ... > We shall consider now existing encoding techniques of stereo data stipulated ...
    (microsoft.public.windowsxp.music)