DirectShow是有点难度啊。。。


今天下班前半个小时,运气来了。让我发现了程序的逻辑错误,不至于今天白忙活了.

最近有以下几个错误:
错误1: IWMProfile::GetStream中的ID 与 IWMProfile::RemoveStreamByNumber 中的ID不一样。
   通常GetStream的ID从0到最后一个,而RemoveStreamByNumber中的ID则是在profile配置文件中指定的!
 
错误2:我使用的默认的profile 中,第一个PIN是 AUDIO STREAM,第二个才是VIDEO STREAM.
   再加上错误一。所以我一直操作的 IWMStreamConfig 是AUDIO STREAM而不是VIDEO STREAM。
           因此其数据一但更改,很可能 IWMMediaProps::SetMediaType 就会失败。

错误3:只要数据一但不合法 IWMProfile::ReconfigStream 方法调用就会失败。我竟然对此有一丝怀疑,认为是不是这个函数有问题。
            例如,VIDEOINFOHEADER 结构中的 rcSource 与 rcTarget 参数是错误是 0 的话,IWMProfile::ReconfigStream也是
   会调用失败的。由于我的 WM_MEDIA_TYPE 是从 Source Filter(我写的源Filter) 中导出的正常AM_MEDIA_TYPE强制转换过来的。
           但由于Source Filter似乎对于 rcSource ,rcTarget这两个参数不在意。另别还有比特率呀什么的,所以还是用GetMediaType得到出数据
   再修改比较好一些。

 

 

在网上找了两天都没找到NND,下面给出设置ASF WRITER关于调整输出画面大小的代码:

//AM_MEDIA_TYPE 与WM_MEDIA_TYPE两个结构是完全一样的,可以通用

//思路是把原来的一个端口给删除,最后只有VIDEO INPUT PIN。否则会出错,因为ASF是以音频的时钟做为参考时钟。

//下面的代码与运行环境有一定关系,实际使用还要自已动手。

///由于成生CMediaType 也是一件麻烦事,所以我在2006_9_6已把下面的代码修改了//

 


//这个CLSID就是我机器用的默认profile
DEFINE_GUID(CLSID_PROFIEL1,
0x6E2A6955, 0x81DF, 0x4943, 0xBA, 0x50, 0x68, 0xA9, 0x86, 0xA7, 0x08, 0xF6);
HRESULT   CTestMy::ConfigAsfWriter (CComQIPtr<IConfigAsfWriter> pConfig)
{
    //pConfig->ConfigureFilterUsingProfileGuid(CLSID_PROFIEL1); 如果不行可以把这行加上
    int nWidth = 1024,nHeight = 768; //设置它的高与宽

    HRESULT hr;
    CComQIPtr<IWMProfile> pProfile;
    hr = pConfig->GetCurrentProfile( &pProfile );
    ERRORBOX(hr);

    //删除多余的其它流数据,否则会出错
    DWORD nStreamCount;
    hr = pProfile->GetStreamCount(&nStreamCount);
    ASSERT (nStreamCount <= 2); //最多只能有两个接口,否则不是期望的profile
    ERRORBOX(hr);
    if (nStreamCount > 1)
    {
        hr = pProfile->RemoveStreamByNumber(1);
        ERRORBOX(hr);
    }
    
    CComQIPtr<IWMStreamConfig> pStreamConfig;
    hr = pProfile->GetStream(0, &pStreamConfig); //因为应该只有一个流,所以获取视频流的
    ERRORBOX(hr);


    /设置视频流的属性
    CComQIPtr<IWMMediaProps> pMediaProps;
    pMediaProps = pStreamConfig;
    ASSERT (!!pMediaProps);
    //WM_MEDIA_TYPE *pType = reinterpret_cast<WM_MEDIA_TYPE *>( &mt );
    
    WM_MEDIA_TYPE *mediaType;
    DWORD bufsize;
    pMediaProps->GetMediaType(NULL,&bufsize);
    BYTE *pBuf = new BYTE[bufsize];
    mediaType = (WM_MEDIA_TYPE*) pBuf;
    pMediaProps->GetMediaType(mediaType,&bufsize);

    VIDEOINFOHEADER *pVih =  reinterpret_cast<VIDEOINFOHEADER*>(mediaType->pbFormat);

    pVih->bmiHeader.biWidth =  nWidth;
    pVih->bmiHeader.biHeight =  nHeight;
    pVih->bmiHeader.biSizeImage  = GetBitmapSize(&pVih->bmiHeader);
    
    mediaType->lSampleSize = pVih->bmiHeader.biSizeImage;
    RECT src = {0,0,pVih->bmiHeader.biWidth,pVih->bmiHeader.biHeight};
    pVih->rcSource = src;
    pVih->rcTarget = src;

    hr = pMediaProps->SetMediaType (mediaType);
    ERRORBOX(hr);

    hr = pProfile->ReconfigStream (pStreamConfig);
    ERRORBOX(hr);
    
    hr = pConfig->ConfigureFilterUsingProfile(pProfile);
    ERRORBOX(hr);
    delete []pBuf;
    return hr;
    return NOERROR;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值