currently I have a disfigured avi file that a program of mine creates. I found out that by going into graphedit, i can refigure it correctly.
I found that if i do:
SourceFile(test1.avi) -> AVI Splitter -> ffdshow video encoder -> AVI Mux -> File Writer
i can get a video stream back that is correct.
Now I am trying to convert this into C# Directshow.Net program that i can just call.
I create a graph and i add in a SourceFilter from the video file i want converted, i add in a grabber, find and then add the ffdshow encoder, AVI Mux and then 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)samplegrabb开发者_开发百科er;
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();
}
this code creates the same graph to my knowledge. It creates my file, but doesnt convert anything. The file it creates is 0bytes. Am i doing renderstream wrong or some other error in my code?
i put in a piece of code:
DsRotEntry m_rot = new DsRotEntry(filter);
this allowed me to view my filter i made, in graphedit.
what happened was i add the filters but none of them got connected to each other.
So then what i did was got each of the filters i added, found the input and output pins associated with them
Filter2.FindPin( "name of the input pin here", out pinName);
Filter1.FindPin( "name of the output pin here", out PinName2);
MainFilter.connect( PinName2, pinName);
this created a connection between the filters. I wasnt doing this and i did this and now im getting closer to what i want.
so basically for Directshow.net and DirectShowNet-Lib it programs like
find a filter -> add a filter -> find a filter -> add a filter -> find the pins -> connect the pins -> run
精彩评论