Reputation: 67
I wrote a Windows Service Code to convert AVI to WMV file. I'm using XviD, and Windows Media 9, in a Windows Vista. The service starts converting, and stops before completing the job, with a WMENC_ENCODER_STOPPED status, but the file was not fully converted. And the resulting file stays locked to this application forever, until I stop the service. And when I do so, that resulting file is automatically deleted. Can anyone, please, help? It is important !!
EDIT: This program works constantly, executing conversion tasks. If a file fails to convert as described above, and I use the function GC.WaitForPendingFinalizers(), I still have the locking problem. But the service goes on, and pick another task. Succeeding or failing this new task, when I use GC.WaitForPendingFinalizers(), the first one is unlocked, and automatically deleted.
public WMENC_ENCODER_STATE EncoderStatus
{
get { return _encoderStatus; }
set { _encoderStatus = value; }
}
IWMEncFile2 File;
IWMEncAudioSource[] SrcAud;
IWMEncVideoSource2[] SrcVid;
IWMEncSourceGroup2[] SrcGrp;
WMEncoder glbEncoder = new WMEncoder();
WMEncProfile2[] Pro = null;
IWMEncSourceGroupCollection SrcGrpColl = null;
public WMVEnconder(ConvertGroup[] sourceGroup, string targetFile, string profilefile)
{
glbEncoder.OnStateChange += new _IWMEncoderEvents_OnStateChangeEventHandler(Encoder_OnStateChange);
glbEncoder.OnError +=new _IWMEncoderEvents_OnErrorEventHandler(Encoder_OnError);
// Creates source group.
SrcGrpColl = glbEncoder.SourceGroupCollection;
int[] intProVBRModeAudio = new int[sourceGroup.Length];
int[] intProVBRModeVideo = new int[sourceGroup.Length];
Int32[] intProContentType = new int[sourceGroup.Length];
Pro = new WMEncProfile2[sourceGroup.Length];
for (int i = 0; i < Pro.Length; i++)
{
Pro[i] = new WMEncProfile2();
Pro[i].LoadFromMemory(profilefile);
intProContentType[i] = Pro[i].ContentType;
intProVBRModeAudio[i] = (int)Pro[i].get_VBRMode(WMENC_SOURCE_TYPE.WMENC_AUDIO, 0);
intProVBRModeVideo[i] = (int)Pro[i].get_VBRMode(WMENC_SOURCE_TYPE.WMENC_VIDEO, 0);
}
SrcGrp = new IWMEncSourceGroup2[sourceGroup.Length];
for (int i = 0; i < SrcGrp.Length; i++)
SrcGrp[i] = (IWMEncSourceGroup2)SrcGrpColl.Add(i.ToString());
SrcAud = new IWMEncAudioSource[sourceGroup.Length];
SrcVid = new IWMEncVideoSource2[sourceGroup.Length];
for (int i = 0; i < sourceGroup.Length; i++)
{
if (intProContentType[i] == 1)
{
SrcAud[i] = (WMEncoderLib.IWMEncAudioSource)SrcGrp[i].AddSource(WMENC_SOURCE_TYPE.WMENC_AUDIO);
SrcAud[i].SetInput(sourceGroup[i].AudioFile, "", "");
SrcAud[i].MarkIn = sourceGroup[i].AudioMarkin;
SrcAud[i].MarkOut = sourceGroup[i].AudioMarkout;
}
else if (intProContentType[i] == 16)
{
SrcVid[i] = (WMEncoderLib.IWMEncVideoSource2)SrcGrp[i].AddSource(WMENC_SOURCE_TYPE.WMENC_VIDEO);
SrcVid[i].SetInput(sourceGroup[i].VideoFile, "", "");
SrcVid[i].MarkIn = sourceGroup[i].VideoMarkin;
SrcVid[i].MarkOut = sourceGroup[i].VideoMarkout;
}
else if (intProContentType[i] == 17)
{
SrcAud[i] = (WMEncoderLib.IWMEncAudioSource)SrcGrp[i].AddSource(WMENC_SOURCE_TYPE.WMENC_AUDIO);
SrcAud[i].SetInput(sourceGroup[i].AudioFile, "", "");
SrcVid[i] = (WMEncoderLib.IWMEncVideoSource2)SrcGrp[i].AddSource(WMENC_SOURCE_TYPE.WMENC_VIDEO);
SrcVid[i].SetInput(sourceGroup[i].VideoFile, "", "");
SrcAud[i].MarkIn = sourceGroup[i].AudioMarkin;
SrcAud[i].MarkOut = sourceGroup[i].AudioMarkout;
SrcVid[i].MarkIn = sourceGroup[i].VideoMarkin;
SrcVid[i].MarkOut = sourceGroup[i].VideoMarkout;
}
else
throw new Exception("erro - não suporta este tipo de profile");
SrcGrp[i].set_Profile(Pro[i]);
if (i + 1 < sourceGroup.Length)
SrcGrp[i].SetAutoRollover(-1, (i + 1).ToString());
}
File = (IWMEncFile2)glbEncoder.File;
File.LocalFileName = targetFile;
glbEncoder.PrepareToEncode(true);
}
/// <summary>
/// Inicia os processos do codificador.
/// </summary>
public void Start()
{
glbEncoder.Start();
}
/// <summary>
/// Pára os processos do codificador.
/// </summary>
public void Stop()
{
glbEncoder.Stop();
}
/// <summary>
/// Elimina as configurações atuais.
/// </summary>
public void Reset()
{
glbEncoder.Reset();
}
/// <summary>
/// Evento deflagrado pela mudança no estado do codificador.
/// </summary>
/// <param name="enumState">Enumerador indicador do estado do codificador.</param>
private void Encoder_OnStateChange(WMEncoderLib.WMENC_ENCODER_STATE enumState)
{
_encoderStatus = enumState;
string strRunState = "";
switch (enumState)
{
case WMENC_ENCODER_STATE.WMENC_ENCODER_STARTING :
strRunState = "Encoder Starting";
break;
case WMENC_ENCODER_STATE.WMENC_ENCODER_RUNNING:
strRunState = "Encoder Running";
break;
case WMENC_ENCODER_STATE.WMENC_ENCODER_END_PREPROCESS:
strRunState = "Encoder End Preprocess";
break;
case WMENC_ENCODER_STATE.WMENC_ENCODER_PAUSING:
strRunState = "Encoder Pausing";
break;
case WMENC_ENCODER_STATE.WMENC_ENCODER_PAUSED:
strRunState = "Encoder Paused";
break;
case WMENC_ENCODER_STATE.WMENC_ENCODER_STOPPING:
strRunState = "Encoder Stopping";
break;
case WMENC_ENCODER_STATE.WMENC_ENCODER_STOPPED:
strRunState = "Encoder Stopped";
break;
}
_strEncoderStatus = strRunState;
}
/// <summary>
/// Evento deflagrado pela ocorrência de um erro durante o processo de codificação.
/// </summary>
/// <param name="hr">Valor numérico do erro que ocorreu.</param>
private void Encoder_OnError(int hr)
{
string errorReceived = "";
switch (hr)
{
case -1074600792:
errorReceived = "The starting time must be greater than zero and less than the ending time.";
break;
case -1074600793:
errorReceived = "The ending time must be greater than the starting time and less than the file duration.";
break;
case -1074600804:
errorReceived = "The video capture device is in use and cannot be opened.";
break;
case -1074600808:
errorReceived = "The video capture driver returned an unrecoverable error.";
break;
case -1074600809:
errorReceived = "The video capture device did not start.";
break;
case -1074600813:
errorReceived = "The video capture window was not created.";
break;
case -1074600820:
errorReceived = "The specified operation is not allowed when the file is being archived.";
break;
case -1074600825:
errorReceived = "The archive file name is not properly specified.";
break;
case -1074600831:
errorReceived = "The specified operation is not allowed when the encoder engine is not running.";
break;
case -1074600833:
errorReceived = "Inverse telecine cannot be specified when the frame rate does not equal 30 frames per second.";
break;
case -1074600834:
errorReceived = "Internal problems are preventing the preview or postview.";
break;
case -1074600835:
errorReceived = "One or more required codecs cannot be found.";
break;
case -1074600840:
errorReceived = "The display size or color setting has changed since the encoding session was defined.";
break;
}
try
{
if (Directory.Exists(@"C:\MediaDNA_V2\Data\Conversion\Exception"))
{
MediaDNAException mdnaException = new MediaDNAException(Modulo.CONVERSION, 0, "C_110018", TipoErro.INFORMACAO, new Exception(errorReceived),
ErrorMessageConstants.C_110018, new object[] { hr.ToString("X") });
ExceptionManager.RegisterException(mdnaException, @"C:\MediaDNA_V2\Data\Conversion\Exception");
}
}
catch { }
}
#region IDisposable Members
/// <summary> Release everything. </summary>
public void Dispose()
{
glbEncoder.Stop();
glbEncoder.Reset();
GC.SuppressFinalize(this);
CloseInterfaces();
}
#endregion
/// <summary>
/// Fecha as interfaces utilizadas pelo codificador.
/// Obs: O processador precisa estar "STOPPED" para executar este processo.
/// </summary>
private void CloseInterfaces()
{
if (glbEncoder != null)
{
if (File != null)
Marshal.FinalReleaseComObject(File);
if (Pro != null)
{
for (int i = 0; i < Pro.Length; i++)
Marshal.FinalReleaseComObject(Pro[i]);
Pro = null;
}
if (SrcVid != null)
{
for (int i = 0; i < SrcVid.Length; i++)
Marshal.FinalReleaseComObject(SrcVid[i]);
SrcVid = null;
}
if (SrcAud != null)
{
for (int i = 0; i < SrcAud.Length; i++)
Marshal.FinalReleaseComObject(SrcAud[i]);
SrcAud = null;
}
if (SrcGrpColl != null)
Marshal.FinalReleaseComObject(SrcGrpColl);
if (SrcGrpColl != null)
Marshal.FinalReleaseComObject(SrcGrpColl);
if (glbEncoder != null)
Marshal.FinalReleaseComObject(glbEncoder);
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
}
}
Upvotes: 1
Views: 1159
Reputation: 17080
I attached my function which I converted wav file to wma.
Make sure that you do encoder.Stop();
and encoder.Reset();
and off-course release all your com object.
I'm pretty sure that once you will released your COM object your issue will be fixed.
// Create a WMEncoder object.
WMEncoder encoder = new WMEncoder();
// Retrieve the source group collection.
IWMEncSourceGroupCollection srcGrpColl = encoder.SourceGroupCollection;
// Add a source group to the collection.
IWMEncSourceGroup srcGrp = srcGrpColl.Add("SG_1");
// Add a video and audio source to the source group.
IWMEncSource srcAud = srcGrp.AddSource(WMENC_SOURCE_TYPE.WMENC_AUDIO);
srcAud.SetInput(wavFileName, "", "");
// Specify a file object in which to save encoded content.
IWMEncFile file = encoder.File;
file.LocalFileName = wmaFileName;
// Create a profile collection object from the WMEncoder object.
encoder.ProfileCollection.ProfileDirectory =
string.Format("{0}Profiles", Request.PhysicalApplicationPath);
encoder.ProfileCollection.Refresh();
IWMEncProfileCollection proColl = encoder.ProfileCollection;
// Create a profile object
IEnumerator profEnum = proColl.GetEnumerator();
IWMEncProfile profile = null; ;
IWMEncProfile2 newProfile = null;
while (profEnum.MoveNext())
{
profile = (IWMEncProfile)profEnum.Current;
if (profile.Name == "WavToWma")
{
// Load profile
newProfile = new WMEncProfile2();
newProfile.LoadFromIWMProfile(profile);
// Specify this profile object as the profile to use in source group.
srcGrp.set_Profile(newProfile);
}
}
// Start the encoding process.
// Wait until the encoding process stops before exiting the application.
encoder.PrepareToEncode(true);
encoder.Start();
while (encoder.RunState != WMENC_ENCODER_STATE.WMENC_ENCODER_STOPPED)
{
Thread.Sleep(500);
}
encoder.Stop();
encoder.Reset();
try
{
#region Release com objects
if (file != null)
Marshal.FinalReleaseComObject(file);
if (profile != null)
Marshal.FinalReleaseComObject(profile);
if (newProfile != null)
Marshal.FinalReleaseComObject(newProfile);
if (srcAud != null)
Marshal.FinalReleaseComObject(srcAud);
if (srcGrp != null)
Marshal.FinalReleaseComObject(srcGrp);
if (srcGrpColl != null)
Marshal.FinalReleaseComObject(srcGrpColl);
if (proColl != null)
Marshal.FinalReleaseComObject(proColl);
if (encoder != null)
Marshal.FinalReleaseComObject(encoder);
// GC collect is explicitly called because of a memory leak issue of WMEncoder.
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
#endregion
}
catch { }
}
Upvotes: 1