Я не пойму логику цикла. Если кодеки мы создаём на нижнем уровне, а на верхнем ловим экскепшен, то как переходить?
foreach (Guid codec in codecs)
{
try
{
//тут что?
}
}
Соединять фильтры я умею. Я не пойму, что должно быть на верхнем уровне, а что на нижнем?
Cейчас у меня такой код (еще не допиленный):
private int BuildGraph()
{
switch (GraphMode)
{
case GRAPH_MODE.GM_INTELLECTUAL:
CreateGraphBuilder(out graphBuilder);
CreateCaptureGraphBuilder2(out captureGraphBuilder2);
captureGraphBuilder2.SetFiltergraph(graphBuilder);
graphBuilder.AddSourceFilter(FileName, "source", out sourceFilter);
//тут надо будет запустить цикл перебора кодеков, но этого пока не сделано.
//если все будут с ошибками, то просто возвращаем код последней ошибки.
int errorCode = CreateFilter(CLSID_LAV_VideoDecoder, out videoDecoder);
if (errorCode != 0)
{
//log
Clear();
return errorCode;
}
graphBuilder.AddFilter(videoDecoder, "video decoder");
errorCode = CreateFilter(CLSID_VideoMixingRenderer9, out videoRenderer);
if (errorCode != 0)
{
//log
Clear();
return errorCode;
}
graphBuilder.AddFilter(videoRenderer, "video renderer");
captureGraphBuilder2.RenderStream(null, MediaType.Video, sourceFilter, videoDecoder, videoRenderer);
if (errorCode != 0)
{
//log
Clear();
return errorCode;
}
CreateFilter(CLSID_LAV_AudioDecoder, out audioDecoder);
graphBuilder.AddFilter(audioDecoder, "audio decoder");
errorCode = CreateFilter(CLSID_DirectSoundAudioRenderer, out audioRenderer);
if (errorCode != 0)
{
//log
Clear();
return errorCode;
}
graphBuilder.AddFilter(audioRenderer, "audio renderer");
errorCode = captureGraphBuilder2.RenderStream(null, MediaType.Audio, sourceFilter, audioDecoder, audioRenderer);
if (errorCode != 0)
{
Clear();
return errorCode;
}
errorCode = CreateBasicVideo(graphBuilder, out basicVideo);
if (errorCode != 0)
{
Clear();
return errorCode;
}
CreateMediaPosition(graphBuilder, out mediaPosition);
CreateVideoWindow(graphBuilder, out videoWindow);
videoWindow.put_Owner(OutputWindow.Handle);
videoWindow.put_WindowStyle(WindowStyle.Child | WindowStyle.ClipChildren | WindowStyle.ClipSiblings);
basicVideo.GetVideoSize(out _videoWidth, out _videoHeight);
OutputScreenRect = CenterRect(ResizeRect(new Rectangle(0, 0, _videoWidth, _videoHeight), OutputWindow.Size), OutputWindow.ClientRectangle);
videoWindow.SetWindowPosition(OutputScreenRect.X, OutputScreenRect.Y, OutputScreenRect.Width, OutputScreenRect.Height);
videoWindow.put_MessageDrain(OutputWindow.Handle);
videoWindow.put_Visible(OABool.True);
errorCode = CreateBasicAudio(graphBuilder, out basicAudio);
if (errorCode == 0)
basicAudio.put_Volume(GetDecibellsVolume(Volume));
errorCode = CreateMediaControl(graphBuilder, out mediaControl);
if (errorCode != 0)
{
//log
Clear();
return errorCode;
}
_state = PLAYER_STATE.PS_STOPPED;
return errorCode;
}
return -1;
}
Возможно, не профессионально. Зато всё предельно понятно и работает. Я не знаю, что и зачем тут можно вынести в try
Просто можно создать отдельные методы для перебора кодеков видео и аудио.
Мне кажется, что перебор и соединение фильтров должны быть на одном и том же уровне