我正在一个视频文件具有非标准标题,使用H264算法且该文件为.avi格式的项目中。问题是文件不包含.avi标准标题,标题是自定义的,我想执行以下操作
请指导如何在这种情况下在GraphEditPlus中创建图形,并附带示例图像
using DirectShowLib;
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
//[STAThread]
//static void Main(string[] args)
//{
// Application.EnableVisualStyles();
// Application.SetCompatibleTextRenderingDefault(false);
// Application.Run(new Form1());
//}
static void checkHR(int hr, string msg)
{
if (hr < 0)
{
Console.WriteLine(msg);
DsError.ThrowExceptionForHR(hr);
}
}
static void BuildGraph(IGraphBuilder pGraph, string srcFile1)
{
int hr = 0;
//graph builder
ICaptureGraphBuilder2 pBuilder = (ICaptureGraphBuilder2)new CaptureGraphBuilder2();
hr = pBuilder.SetFiltergraph(pGraph);
checkHR(hr, "Can't SetFiltergraph");
Guid CLSID_Mpeg4sDecoderDMO = new Guid("{2A11BAE2-FE6E-4249-864B-9E9ED6E8DBC2}"); //DMO
Guid CLSID_Mpeg4sDecoderDMO_cat = new Guid("{4A69B442-28BE-4991-969C-B500ADF5D8A8}"); //DMO category
Guid CLSID_MP3DecoderDMO = new Guid("{BBEEA841-0A63-4F52-A7AB-A9B3A84ED38A}"); //DMO
Guid CLSID_MP3DecoderDMO_cat = new Guid("{57F2DB8B-E6BB-4513-9D43-DCD2A6593125}"); //DMO category
Guid CLSID_VideoRenderer = new Guid("{B87BEB7B-8D29-423F-AE4D-6582C10175AC}"); //quartz.dll
Guid CLSID_SampleGrabber = new Guid("{C1F400A0-3F08-11D3-9F0B-006008039E37}"); //qedit.dll
Guid CLSID_Filestreamrenderer = new Guid("{D51BD5A5-7548-11CF-A520-0080C77EF58A}"); //quartz.dll
//add File stream renderer
IBaseFilter pFilestreamrenderer = (IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_Filestreamrenderer));
hr = pGraph.AddFilter(pFilestreamrenderer, "File stream renderer");
checkHR(hr, "Can't add File stream renderer to graph");
//add File Source (Async.)
IBaseFilter pFileSourceAsync = (IBaseFilter)new AsyncReader();
hr = pGraph.AddFilter(pFileSourceAsync, "File Source (Async.)");
checkHR(hr, "Can't add File Source (Async.) to graph");
//set source filename
IFileSourceFilter pFileSourceAsync_src = pFileSourceAsync as IFileSourceFilter;
if (pFileSourceAsync_src == null)
checkHR(unchecked((int)0x80004002), "Can't get IFileSourceFilter");
hr = pFileSourceAsync_src.Load(srcFile1, null);
checkHR(hr, "Can't load file");
//add AVI Splitter
IBaseFilter pAVISplitter = (IBaseFilter)new AviSplitter();
hr = pGraph.AddFilter(pAVISplitter, "AVI Splitter");
checkHR(hr, "Can't add AVI Splitter to graph");
//connect File Source (Async.) and AVI Splitter
hr = pGraph.ConnectDirect(GetPin(pFileSourceAsync, "Output"), GetPin(pAVISplitter, "input pin"), null);
checkHR(hr, "Can't connect File Source (Async.) and AVI Splitter");
//add Mpeg4s Decoder DMO
IBaseFilter pMpeg4sDecoderDMO = (IBaseFilter)new DMOWrapperFilter();
var pMpeg4sDecoderDMO_wrapper = pMpeg4sDecoderDMO as IDMOWrapperFilter;
if (pMpeg4sDecoderDMO_wrapper == null)
checkHR(unchecked((int)0x80004002), "Can't get IDMOWrapperFilter");
hr = pMpeg4sDecoderDMO_wrapper.Init(CLSID_Mpeg4sDecoderDMO, CLSID_Mpeg4sDecoderDMO_cat);
checkHR(hr, "DMO Wrapper Init failed");
hr = pGraph.AddFilter(pMpeg4sDecoderDMO, "Mpeg4s Decoder DMO");
checkHR(hr, "Can't add Mpeg4s Decoder DMO to graph");
//add MP3 Decoder DMO
IBaseFilter pMP3DecoderDMO = (IBaseFilter)new DMOWrapperFilter();
var pMP3DecoderDMO_wrapper = pMP3DecoderDMO as IDMOWrapperFilter;
if (pMP3DecoderDMO_wrapper == null)
checkHR(unchecked((int)0x80004002), "Can't get IDMOWrapperFilter");
hr = pMP3DecoderDMO_wrapper.Init(CLSID_MP3DecoderDMO, CLSID_MP3DecoderDMO_cat);
checkHR(hr, "DMO Wrapper Init failed");
hr = pGraph.AddFilter(pMP3DecoderDMO, "MP3 Decoder DMO");
checkHR(hr, "Can't add MP3 Decoder DMO to graph");
//connect AVI Splitter and MP3 Decoder DMO
hr = pGraph.ConnectDirect(GetPin(pAVISplitter, "Stream 01"), GetPin(pMP3DecoderDMO, "in0"), null);
checkHR(hr, "Can't connect AVI Splitter and MP3 Decoder DMO");
//add Video Renderer
IBaseFilter pVideoRenderer = (IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_VideoRenderer));
hr = pGraph.AddFilter(pVideoRenderer, "Video Renderer");
checkHR(hr, "Can't add Video Renderer to graph");
//add Default DirectSound Device
IBaseFilter pDefaultDirectSoundDevice = (IBaseFilter)new DSoundRender();
hr = pGraph.AddFilter(pDefaultDirectSoundDevice, "Default DirectSound Device");
checkHR(hr, "Can't add Default DirectSound Device to graph");
//connect MP3 Decoder DMO and Default DirectSound Device
hr = pGraph.ConnectDirect(GetPin(pMP3DecoderDMO, "out0"), GetPin(pDefaultDirectSoundDevice, "Audio Input pin (rendered)"), null);
checkHR(hr, "Can't connect MP3 Decoder DMO and Default DirectSound Device");
//add SampleGrabber
IBaseFilter pSampleGrabber = (IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_SampleGrabber));
hr = pGraph.AddFilter(pSampleGrabber, "SampleGrabber");
checkHR(hr, "Can't add SampleGrabber to graph");
ISampleGrabber _sampleGrabber = ((ISampleGrabber)pSampleGrabber);
_sampleGrabber.SetOneShot(false);
_sampleGrabber.SetBufferSamples(false);
SampleGrabberCallback _sampleGrabberCallback = new SampleGrabberCallback();
//hr = ((ISampleGrabber)pSampleGrabber).SetBufferSamples(false);
//if (hr == 0)
//{
// hr = ((ISampleGrabber)pSampleGrabber).SetOneShot(false);
//}
//if (hr == 0)
//{
// hr = ((ISampleGrabber)pSampleGrabber).SetCallback(_sampleGrabberCallback, 0);
//}
//if (hr < 0)
//{
// Marshal.ThrowExceptionForHR(hr);
//}
//set callback
hr = _sampleGrabber.SetCallback(new SampleGrabberCallback(), 0);
checkHR(hr, "Can't set callback.");
AMMediaType pSampleGrabber_pmt = new AMMediaType();
pSampleGrabber_pmt.majorType = MediaType.Video;
pSampleGrabber_pmt.subType = MediaSubType.YUY2;
pSampleGrabber_pmt.formatType = FormatType.VideoInfo;
pSampleGrabber_pmt.fixedSizeSamples = true;
pSampleGrabber_pmt.formatSize = 88;
pSampleGrabber_pmt.sampleSize = 4147200;
pSampleGrabber_pmt.temporalCompression = false;
VideoInfoHeader pSampleGrabber_format = new VideoInfoHeader();
pSampleGrabber_format.SrcRect = new DsRect();
pSampleGrabber_format.TargetRect = new DsRect();
pSampleGrabber_format.AvgTimePerFrame = 400000;
pSampleGrabber_format.BmiHeader = new BitmapInfoHeader();
pSampleGrabber_format.BmiHeader.Size = 40;
pSampleGrabber_format.BmiHeader.Width = 1920;
pSampleGrabber_format.BmiHeader.Height = 1080;
pSampleGrabber_format.BmiHeader.Planes = 1;
pSampleGrabber_format.BmiHeader.BitCount = 16;
pSampleGrabber_format.BmiHeader.Compression = 844715353;
pSampleGrabber_format.BmiHeader.ImageSize = 4147200;
pSampleGrabber_pmt.formatPtr = Marshal.AllocCoTaskMem(Marshal.SizeOf(pSampleGrabber_format));
Marshal.StructureToPtr(pSampleGrabber_format, pSampleGrabber_pmt.formatPtr, false);
hr = ((ISampleGrabber)pSampleGrabber).SetMediaType(pSampleGrabber_pmt);
DsUtils.FreeAMMediaType(pSampleGrabber_pmt);
checkHR(hr, "Can't set media type to sample grabber");
//connect AVI Splitter and Mpeg4s Decoder DMO
hr = pGraph.ConnectDirect(GetPin(pAVISplitter, "Stream 00"), GetPin(pMpeg4sDecoderDMO, "in0"), null);
checkHR(hr, "Can't connect AVI Splitter and Mpeg4s Decoder DMO");
//connect Mpeg4s Decoder DMO and SampleGrabber
hr = pGraph.ConnectDirect(GetPin(pMpeg4sDecoderDMO, "out0"), GetPin(pSampleGrabber, "Input"), null);
checkHR(hr, "Can't connect Mpeg4s Decoder DMO and SampleGrabber");
//add AVI Decompressor
IBaseFilter pAVIDecompressor = (IBaseFilter)new AVIDec();
hr = pGraph.AddFilter(pAVIDecompressor, "AVI Decompressor");
checkHR(hr, "Can't add AVI Decompressor to graph");
//connect SampleGrabber and AVI Decompressor
hr = pGraph.ConnectDirect(GetPin(pSampleGrabber, "Output"), GetPin(pAVIDecompressor, "XForm In"), null);
checkHR(hr, "Can't connect SampleGrabber and AVI Decompressor");
//connect AVI Decompressor and Video Renderer
hr = pGraph.ConnectDirect(GetPin(pAVIDecompressor, "XForm Out"), GetPin(pVideoRenderer, "VMR Input0"), null);
checkHR(hr, "Can't connect AVI Decompressor and Video Renderer");
}
static void Main(string[] args)
{
try
{
IGraphBuilder graph = (IGraphBuilder)new FilterGraph();
Console.WriteLine("Building graph...");
BuildGraph(graph, @"Panasonic_HDC_TM_700_P_50i.avi");
Console.WriteLine("Running...");
IMediaControl mediaControl = (IMediaControl)graph;
IMediaEvent mediaEvent = (IMediaEvent)graph;
int hr = mediaControl.Run();
checkHR(hr, "Can't run the graph");
bool stop = false;
while (!stop)
{
System.Threading.Thread.Sleep(500);
Console.Write(".");
EventCode ev;
IntPtr p1, p2;
System.Windows.Forms.Application.DoEvents();
while (mediaEvent.GetEvent(out ev, out p1, out p2, 0) == 0)
{
if (ev == EventCode.Complete || ev == EventCode.UserAbort)
{
Console.WriteLine("Done!");
stop = true;
}
else
if (ev == EventCode.ErrorAbort)
{
Console.WriteLine("An error occured: HRESULT={0:X}", p1);
mediaControl.Stop();
stop = true;
}
mediaEvent.FreeEventParams(ev, p1, p2);
}
}
}
catch (COMException ex)
{
Console.WriteLine("COM error: " + ex.ToString());
}
catch (Exception ex)
{
Console.WriteLine("Error: " + ex.ToString());
}
}
static IPin GetPin(IBaseFilter filter, string pinname)
{
IEnumPins epins;
int hr = filter.EnumPins(out epins);
checkHR(hr, "Can't enumerate pins");
IntPtr fetched = Marshal.AllocCoTaskMem(4);
IPin[] pins = new IPin[1];
while (epins.Next(1, pins, fetched) == 0)
{
PinInfo pinfo;
pins[0].QueryPinInfo(out pinfo);
bool found = (pinfo.name == pinname);
DsUtils.FreePinInfo(pinfo);
if (found)
return pins[0];
}
checkHR(-1, "Pin not found");
return null;
}
}
class SampleGrabberCallback : ISampleGrabberCB
{
public int BufferCB(double SampleTime, IntPtr pBuffer, int BufferLen)
{
//Console.WriteLine("Time : " + SampleTime + " " + BufferLen);
return 0;
}
public int SampleCB(double SampleTime, IMediaSample pSample)
{
Console.WriteLine("Time : " + SampleTime + " " + pSample.GetActualDataLength().ToString());
if (pSample == null) return -1;
int len = pSample.GetActualDataLength();
IntPtr pbuf;
if (pSample.GetPointer(out pbuf) == 0 && len > 0)
{
byte[] buf = new byte[len];
Marshal.Copy(pbuf, buf, 0, len);
for (int i = 0; i < len; i += 2)
buf[i] = (byte)(255 - buf[i]);
Marshal.Copy(buf, 0, pbuf, len);
}
Marshal.ReleaseComObject(pSample);
return 0;
}
}