【发布时间】:2011-06-09 16:53:37
【问题描述】:
目前我有一个我的程序创建的毁容的 avi 文件。我发现通过进入graphedit,我可以正确地重构它。
我发现如果我这样做:
SourceFile(test1.avi) -> AVI Splitter -> ffdshow video encoder -> AVI Mux -> File Writer
我可以得到正确的视频流。
现在我正在尝试将其转换为我可以调用的 C# Directshow.Net 程序。
我创建了一个图表,并从我要转换的视频文件中添加了一个 SourceFilter,我添加了一个抓取器,找到并添加了 ffdshow 编码器、AVI Mux,然后添加了 setOutputFileName()。
{
filename = textBox1.Text;
IFilterGraph2 filter = new FilterGraph() as IFilterGraph2;
ICaptureGraphBuilder2 MainGraph = new CaptureGraphBuilder2() as ICaptureGraphBuilder2;
int result;
result = MainGraph.SetFiltergraph(filter);
IBaseFilter source;
result = filter.AddSourceFilter(filename, filename, out source);
ISampleGrabber samplegrabber = (ISampleGrabber)new SampleGrabber();
IBaseFilter basegrab = (IBaseFilter)samplegrabber;
AMMediaType media;
media = new AMMediaType();
media.majorType = MediaType.Video;
media.subType = MediaSubType.RGB32;
media.formatType = FormatType.VideoInfo;
result = samplegrabber.SetMediaType(media);
DsUtils.FreeAMMediaType(media);
result = samplegrabber.SetBufferSamples(true);
result = filter.AddFilter(basegrab, "filter");
//MainGraph.RenderStream(null, null, source, basegrab, null);
IMediaEvent mediaEvent;
IMediaControl mediacontrol;
mediaEvent = filter as IMediaEvent;
mediacontrol = filter as IMediaControl;
IntPtr hEvent;
result = mediaEvent.GetEventHandle(out hEvent);
ManualResetEvent mre;
mre = new ManualResetEvent(false);
mre.SafeWaitHandle = new Microsoft.Win32.SafeHandles.SafeWaitHandle(hEvent, true);
//Thread t = new Thread(new ThreadStart(this.EventWait));
//mediacontrol.Run();
object newsource = null;
IBaseFilter encoder;
Guid iid = typeof(IBaseFilter).GUID;
foreach (DsDevice device in DsDevice.GetDevicesOfCat(FilterCategory.VideoCompressorCategory))
{
if (device.Name.CompareTo("ffdshow video encoder") == 0)
{
device.Mon.BindToObject(null, null, ref iid, out newsource);
break;
}
}
encoder = (IBaseFilter)newsource;
object newsource2 = null;
IBaseFilter encoder2;
Guid iid2 = typeof(IBaseFilter).GUID;
foreach (DsDevice device in DsDevice.GetDevicesOfCat(FilterCategory.LegacyAmFilterCategory))
{
if (device.Name.CompareTo("AVI Mux") == 0)
{
device.Mon.BindToObject(null, null, ref iid2, out newsource2);
break;
}
}
encoder2 = (IBaseFilter)newsource2;
result = filter.AddFilter(encoder, "encoder");
result = filter.AddFilter(encoder2, "Avi Mux");
FileWriter file = new FileWriter();
IFileSinkFilter fs = (IFileSinkFilter)file;
IBaseFilter mux;
IFileSinkFilter sink;
Guid cat;
Guid med;
cat = PinCategory.Capture;
med = MediaType.Video;
//result = filter.AddFilter(encoder, "encoder");
result = MainGraph.SetOutputFileName(MediaSubType.Avi, "C:\\Users\\Caleb\\Desktop\\conversion.avi", out mux, out sink);
result = MainGraph.RenderStream( cat, med, source, null, mux);
mediacontrol.Run();
}
据我所知,此代码创建了相同的图表。它会创建我的文件,但不会转换任何内容。它创建的文件是 0bytes。我的代码中是渲染流错误还是其他错误?
【问题讨论】:
-
您确定要创建解压后的 avi 文件吗?您可能需要一个巨大的硬盘驱动器...
-
我需要从某个地方开始。我最初创建的文件是解压缩的 avi,但颜色被搞砸了,因为视频从未正确编码,所以我在这里这样做。当它工作时,我可以解压缩它
-
这听起来是个不错的计划。请记住,当您使用“SetOutputFileName”时,您不需要在图形上显式添加 avi muxer,因为它将由该函数为您添加,并将在“mux”参数中返回。
-
问题是,这段代码只生成一个文件。它没有对该文件做任何事情,我试图找出原因
-
旁注。 MSDN:“不要关闭
IMediaEvent.GetEventHandle方法返回的事件句柄,因为过滤器图在内部使用事件句柄。”换句话说,不要使用SafeWaitHandle(hEvent, true),而是使用SafeWaitHandle(hEvent, false)。这将有助于避免将来出现问题。
标签: c# directshow directshow.net