我正在试图在我的directshow应用程序中使用samplegrabber保存jpg文件。图表运行正常,但是当我启动CaptureImage()函数时,它获取GetCurrentBuffer并返回“参数不正确”.. hr = -2147024809。
AMMediaType mediaType = new AMMediaType();
VideoInfoHeader videoInfo = new VideoInfoHeader();
(pSampleGrabber as ISampleGrabber).GetConnectedMediaType(mediaType);
videoInfo = (VideoInfoHeader)Marshal.PtrToStructure(mediaType.formatPtr, typeof(VideoInfoHeader));
int width = videoInfo.BmiHeader.Width;
int height = videoInfo.BmiHeader.Height;
int size = videoInfo.BmiHeader.ImageSize;
DsUtils.FreeAMMediaType(mediaType);
int hr = 0;
int bufferSize = 0;
hr = (pSampleGrabber as ISampleGrabber).GetCurrentBuffer(ref bufferSize, IntPtr.Zero);
CheckHR(hr, "Could not get buffer size for image capture.");
IntPtr frameBufferPointer = Marshal.AllocCoTaskMem(bufferSize);
hr = (pSampleGrabber as ISampleGrabber).GetCurrentBuffer(ref bufferSize, frameBufferPointer);
CheckHR(hr, "Could not get buffer size for image capture.");
byte[] frameBuffer = new byte[bufferSize];
Marshal.Copy(frameBufferPointer, frameBuffer, 0, bufferSize);
Marshal.FreeCoTaskMem(frameBufferPointer);
Bitmap frame = new Bitmap(width, height, PixelFormat.Format32bppArgb);
Rectangle rect = new Rectangle(0, 0, width, height);
BitmapData bmpData = frame.LockBits(rect, ImageLockMode.ReadWrite, frame.PixelFormat);
Marshal.Copy(frameBuffer, 0, bmpData.Scan0, bufferSize);
frame.UnlockBits(bmpData);
frame.RotateFlip(RotateFlipType.RotateNoneFlipY);
if (format == "PAL" || format == "NTSC" || format == "NTSC32")
{
Bitmap sdBitmap = new Bitmap(width, height);
Graphics g = Graphics.FromImage((System.Drawing.Image)sdBitmap);
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
g.DrawImage(frame, 0, 0, width, height);
g.Dispose();
frame = sdBitmap;
sdBitmap.Dispose();
}
EncoderParameter qualityParam = new EncoderParameter(Encoder.Quality, (long)100);
ImageCodecInfo jpegInfo = null;
foreach (ImageCodecInfo codec in ImageCodecInfo.GetImageEncoders())
{
if (codec.MimeType.ToLower() == "image/jpeg")
{
jpegInfo = codec;
break;
}
}
EncoderParameters encoderParam = new EncoderParameters(1);
encoderParam.Param[0] = qualityParam;
double timeStamp = (DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds;
frame.Save(@"C:\Records\" + timeStamp.ToString() + ".jpg", jpegInfo, encoderParam);
frame.Dispose();
文件确实保存到最后,如果我拿出CheckHR检查但是图像是黑色的,具有正确的宽度和高度,这就是为什么我去检查HR以查看它是否健康。显然不是。我搜索谷歌试图弄清楚错误和问题的任何常见问题,但再次,敲打我的脑袋。 :(
快速浏览我的图表:
int hr = 0;
// Graph builder.
ICaptureGraphBuilder2 pBuilder = (ICaptureGraphBuilder2)new CaptureGraphBuilder2();
hr = pBuilder.SetFiltergraph(pGraph);
CheckHR(hr, "Can't SetFiltergraph.");
// Add Decklink Video Capture.
IBaseFilter pDecklinkVideoCapture = (IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_DecklinkVideoCapture));
hr = pGraph.AddFilter(pDecklinkVideoCapture, "Decklink Video Capture");
CheckHR(hr, "Can't add Decklink Video Capture to graph.");
// Get Decklink display format.
Dictionary<string, AMMediaType> formats = GetDisplayFormat(pDecklinkVideoCapture);
hr = (DsFindPin.ByName(pDecklinkVideoCapture, "Capture") as IAMStreamConfig).SetFormat(formats[format]);
CheckHR(hr, "Can't set video format on Decklink Video Capture.");
// Add Intel® Media SDK H.264 Encoder.
IBaseFilter pIntelMediaSDKH264Encoder = (IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_IntelMediaSDKH264Encoder));
hr = pGraph.AddFilter(pIntelMediaSDKH264Encoder, "Intel® Media SDK H.264 Encoder");
CheckHR(hr, "Can't add Intel® Media SDK H.264 Encoder to graph.");
// Add Intel® Media SDK MP4 Muxer.
IBaseFilter pIntelMediaSDKMP4Muxer = (IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_IntelMediaSDKMP4Muxer));
hr = pGraph.AddFilter(pIntelMediaSDKMP4Muxer, "Intel® Media SDK MP4 Muxer");
CheckHR(hr, "Can't add Intel® Media SDK MP4 Muxer to graph.");
// Add File writer.
IBaseFilter pFilewriter = (IBaseFilter)new FileWriter();
hr = pGraph.AddFilter(pFilewriter, "File writer");
CheckHR(hr, "Can't add File writer to graph");
// Set destination filename.
IFileSinkFilter pFilewriter_sink = pFilewriter as IFileSinkFilter;
if (pFilewriter_sink == null)
{
CheckHR(unchecked((int)0x80004002), "Can't get IFileSinkFilter");
}
hr = pFilewriter_sink.SetFileName(destination, null);
CheckHR(hr, "Can't set filename.");
// Add Smart Tee.
IBaseFilter pSmartTee = (IBaseFilter)new SmartTee();
hr = pGraph.AddFilter(pSmartTee, "Smart Tee");
CheckHR(hr, "Can't add Smart Tee to graph.");
// Add AVI Decompressor.
IBaseFilter pAVIDecompressor2 = (IBaseFilter)new AVIDec();
hr = pGraph.AddFilter(pAVIDecompressor2, "AVI Decompressor");
CheckHR(hr, "Can't add AVI Decompressor to graph.");
// Add SampleGrabber.
pSampleGrabber = (IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_SampleGrabber));
hr = pGraph.AddFilter(pSampleGrabber, "SampleGrabber");
CheckHR(hr, "Can't add SampleGrabber to graph.");
// Set SampleGrabber Media Type.
AMMediaType pSampleGrabber_pmt = new AMMediaType();
pSampleGrabber_pmt.majorType = MediaType.Video;
pSampleGrabber_pmt.subType = new Guid("{43594448-0000-0010-8000-00AA00389B71}");
pSampleGrabber_pmt.formatType = FormatType.VideoInfo;
VideoInfoHeader pSampleGrabber_format = new VideoInfoHeader();
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.");
// Add Null Renderer.
IBaseFilter pNullRenderer = (IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_NullRenderer));
hr = pGraph.AddFilter(pNullRenderer, "Null Renderer");
CheckHR(hr, "Can't add Null Renderer to graph.");
// Connect Decklink Video Capture and Smart Tee.
hr = pGraph.ConnectDirect(GetPin(pDecklinkVideoCapture, "Capture"), GetPin(pSmartTee, "Input"), null);
CheckHR(hr, "Can't connect Decklink Video Capture and Smart Tee.");
// Connect Smart Tee and AVI Decompressor.
hr = pGraph.ConnectDirect(GetPin(pSmartTee, "Capture"), GetPin(pAVIDecompressor2, "XForm In"), null);
CheckHR(hr, "Can't connect Smart Tee and AVI Decompressor.");
// Connect AVI Decompressor and Intel® Media SDK H.264 Encoder.
hr = pGraph.ConnectDirect(GetPin(pAVIDecompressor2, "XForm Out"), GetPin(pIntelMediaSDKH264Encoder, "In"), null);
CheckHR(hr, "Can't connect AVI Decompressor and Intel® Media SDK H.264 Encoder.");
// Connect Intel® Media SDK H.264 Encoder and Intel® Media SDK MP4 Muxer.
hr = pGraph.ConnectDirect(GetPin(pIntelMediaSDKH264Encoder, "Out"), GetPin(pIntelMediaSDKMP4Muxer, "Input 0"), null);
CheckHR(hr, "Can't connect Intel® Media SDK H.264 Encoder and Intel® Media SDK MP4 Muxer.");
// Connect Intel® Media SDK MP4 Muxer and File writer.
hr = pGraph.ConnectDirect(GetPin(pIntelMediaSDKMP4Muxer, "Output"), GetPin(pFilewriter, "in"), null);
CheckHR(hr, "Can't connect Intel® Media SDK MP4 Muxer and File writer.");
// Connect Smart Tee and SampleGrabber.
hr = pGraph.ConnectDirect(GetPin(pSmartTee, "Preview"), GetPin(pSampleGrabber, "Input"), null);
CheckHR(hr, "Can't connect Smart Tee and SampleGrabber.");
// Connect SampleGrabber and Null Renderer.
hr = pGraph.ConnectDirect(GetPin(pSampleGrabber, "Output"), GetPin(pNullRenderer, "In"), null);
CheckHR(hr, "Can't connect SampleGrabber and Null Renderer.");
欢迎任何建议或想法。如果需要更多信息,请与我们联系。
干杯。
答案 0 :(得分:3)
-2147024809是0x80070057,即E_INVALIDARG。
GetCurrentBuffer的E_INVALIDARG表示:样本未被缓冲。调用ISampleGrabber :: SetBufferSamples。
要激活缓冲,请调用值为TRUE的ISampleGrabber :: SetBufferSamples。