Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/video/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 我的DirectShow筛选器在通话中崩溃Skype 5.x。在4.x、图形编辑和其他程序中运行良好_Delphi_Video_Directshow_Skype_Dspack - Fatal编程技术网

Delphi 我的DirectShow筛选器在通话中崩溃Skype 5.x。在4.x、图形编辑和其他程序中运行良好

Delphi 我的DirectShow筛选器在通话中崩溃Skype 5.x。在4.x、图形编辑和其他程序中运行良好,delphi,video,directshow,skype,dspack,Delphi,Video,Directshow,Skype,Dspack,我有一个DirectShow推送源视频过滤器,它是用Delphi6和DSPACK组件库编写的。只要使用该筛选器的Skype客户端不是5.x或更新版本,则该筛选器在Skype呼叫期间可以正常运行。使用5.x时,Skype客户端会变得非常迟钝,直到挂起,然后会出现各种严重的崩溃,包括数据执行预防警告和典型的Microsoft“此程序已崩溃”对话框。有时它会立即崩溃,有时它会在通话30秒或更长时间后崩溃 我还可以在以下上下文中无错误地运行视频过滤器: 在视频过滤器预览窗口中使用Skype 5.x,您

我有一个DirectShow推送源视频过滤器,它是用Delphi6和DSPACK组件库编写的。只要使用该筛选器的Skype客户端不是5.x或更新版本,则该筛选器在Skype呼叫期间可以正常运行。使用5.x时,Skype客户端会变得非常迟钝,直到挂起,然后会出现各种严重的崩溃,包括数据执行预防警告和典型的Microsoft“此程序已崩溃”对话框。有时它会立即崩溃,有时它会在通话30秒或更长时间后崩溃

我还可以在以下上下文中无错误地运行视频过滤器

  • 在视频过滤器预览窗口中使用Skype 5.x,您可以在选择要与Skype一起使用的视频设备时看到该窗口(不是在通话中,而是在“视频选项选择”对话框页面)
  • Skype 4.x客户端(在通话和通话中都能完美运行)
  • 图形编辑
  • DSPACK TVideoWindow实例
  • 其他利用网络摄像头提要的程序
我在网上做了一些调查,确实发现了不少关于Skype 5.x和崩溃的投诉。我读到的帖子建议下载5.7测试版。我试过了,但没用。它运行得稍微好一点,但还是崩溃了

作为一个简单的测试,我改变了FillBuffer()方法,只发送一个静态位图,在启动时加载,而不是通常中继到Skype的外部视频流。它仍然崩溃。此外,我甚至尝试在设置了FastMM4的情况下运行push source filter DLL,以便对每个FillBuffer()调用和将媒体样本发送到下游pin的调用进行完全内存扫描。没有任何错误

既然Skype显然与其他网络摄像头驱动程序一起工作,或者网络上会有大量的抗议,那么我的过滤器可能会做什么它不喜欢的事情呢

更新:经过进一步测试,我遇到了一些奇怪的事情。最初,过滤器中的GetMediaType()调用有4种格式。我将其简化为1种格式:24位,压缩设置为BI_RGB,因为这是我从外部接收的内容,然后传递给Skype。当Skype在登录后进行DirectShow筛选器扫描时,我立即从Skype收到一个快速故障,故障发生在我的GetStreamCaps()调用期间。由于Skype有反调试代码,我在每一行之后都煞费苦心地向GetStreamCaps()调用中添加了跟踪消息,并发现这是在我第一次尝试访问它的媒体格式变量时发生的(请参见下文)。似乎我在访问Skype传递给DirectShow筛选器的内存区域时遇到问题。与之前的4种媒体格式相比,为什么只有1种媒体格式可以使故障更快发生,这是一个未知数

这完全是我的猜测,但是否有可能Skype和我的过滤器之间发生了某种奇怪的内存区域访问权限错误?Skype在我开始通话之前偶尔会报告一个数据执行预防错误,以及其他常见的崩溃,这让我怀疑是否发生了什么奇怪的事情。尝试写入标记为代码块的区域时,会发生DEP错误。就好像Skype传递给我的指针指向某个陌生或受保护的地方,而我却无法写信

概括地说,现在每次Skype在调用GetStreamCaps()时访问我的DirectShow筛选器时,在我开始调用之前,甚至在我能够访问视频设备选择屏幕之前,都会100%发生错误。以下是相关的代码片段:

function TBCPushPinDesktop.GetStreamCaps(iIndex: Integer; out ppmt: PAMMediaType; out pSCC): HResult;
var
    pvi:PVIDEOINFOHEADER;
begin
  ppmt := CreateMediaType(@Fmt);

  pvi:=PVIDEOINFOHEADER(ppmt.pbFormat);

  // Error occurs at THIS statement, the first attempt to write to the memory area
  //  provided by Skype.
  pvi.bmiHeader.biCompression  := BI_RGB;

 .... SNIP ....
end;
更新2:我的代码有问题,但我不知道是什么。Graph Edit不像Skype那样调用GetStreamCaps()。我添加了更多的跟踪语句,结果发现在上面的代码中,DSPACK CreateMediaType()调用返回的媒体类型对象有一个NIL pbFormat字段,因此可以解释fast失败的原因。如果有人知道我需要做什么才能得到一个正确配置的pbFormat字段,请告诉我。下面是执行CreateMediaType()操作的DSPACK中的代码:

  // this also comes in useful when using the IEnumMediaTypes interface so
  // that you can copy a media type, you can do nearly the same by creating
  // a CMediaType object but as soon as it goes out of scope the destructor
  // will delete the memory it allocated (this takes a copy of the memory)
  function  CreateMediaType(pSrc: PAMMediaType): PAMMediaType;
  var pMediaType: PAMMediaType;
  begin
    ASSERT(pSrc<>nil);

    // Allocate a block of memory for the media type
    pMediaType := CoTaskMemAlloc(sizeof(TAMMediaType));
    if (pMediaType = nil) then
    begin
      result := nil;
      exit;
    end;

    // Copy the variable length format block
    CopyMediaType(pMediaType,pSrc);
    result := pMediaType;
  end;

  //----------------------------------------------------------------------------
  // Copies a task-allocated AM_MEDIA_TYPE structure.
  //----------------------------------------------------------------------------
  procedure CopyMediaType(pmtTarget: PAMMediaType; pmtSource: PAMMediaType);
  begin
    //  We'll leak if we copy onto one that already exists - there's one
    //  case we can check like that - copying to itself.
    ASSERT(pmtSource <> pmtTarget);
    //pmtTarget^ := pmtSource^;
    move(pmtSource^, pmtTarget^, SizeOf(TAMMediaType));
    if (pmtSource.cbFormat <> 0) then
    begin
      ASSERT(pmtSource.pbFormat <> nil);
      pmtTarget.pbFormat := CoTaskMemAlloc(pmtSource.cbFormat);
      if (pmtTarget.pbFormat = nil) then
        pmtTarget.cbFormat := 0
      else
        CopyMemory(pmtTarget.pbFormat, pmtSource.pbFormat, pmtTarget.cbFormat);
    end;
    if (pmtTarget.pUnk <> nil) then  pmtTarget.pUnk._AddRef;
  end;
//这在使用IEnumMediaTypes接口时也很有用
//您可以复制媒体类型,也可以通过创建
//一个CMediaType对象,但一旦它超出范围,析构函数
//将删除分配的内存(这将获取内存的副本)
函数CreateMediaType(pSrc:PAMMediaType):PAMMediaType;
var pMediaType:PAMMediaType;
开始
断言(pSrcnil);
//为媒体类型分配一块内存
pMediaType:=CoTaskMemAlloc(sizeof(TAMMediaType));
如果(pMediaType=nil),则
开始
结果:=无;
出口
结束;
//复制可变长度格式块
CopyMediaType(pMediaType,pSrc);
结果:=pMediaType;
结束;
//----------------------------------------------------------------------------
//复制任务分配的AM_介质类型结构。
//----------------------------------------------------------------------------
过程CopyMediaType(pmtTarget:PAMMediaType;pmtSource:PAMMediaType);
开始
//如果我们复制到一个已经存在的系统上,我们会泄露信息——有一个
//我们可以这样检查案例-复制到自身。
断言(pmtSource-pmtTarget);
//pmtTarget^:=pmtSource^;
move(pmtSource^,pmtTarget^,SizeOf(TAMMediaType));
如果(pmtSource.cb0格式),则
开始
断言(pmtSource.pbFormat nil);
pmtTarget.pbFormat:=CoTaskMemAlloc(pmtSource.cbFormat);
如果(pmtTarget.pbFormat=nil),则
pmtTarget.cbFormat:=0
其他的
CopyMemory(pmtTarget.pbFormat、pmtSource.pbFormat、pmtTarget.cbFormat);
结束;
如果(pmtTarget.pUnk nil),则pmtTarget.pUnk.\u AddRef;
结束;

有很多信息,但我能掌握以下几点:

ppmt := CreateMediaType(@Fmt);
pvi:=PVIDEOINFOHEADER(ppmt.pbFormat);
// Error occurs at THIS statement, the first attempt to write to the memory area
//  provided by Skype.
pvi.bmiHeader.biCompression  := BI_RGB;
你能打ac的唯一原因