DirectShow中显示的图像是颠倒的

这些天在写source filter,读入一系列的视频序列帧从磁盘,然后把它们在

CSourceStream::FillBuffer()

中把读入的位图数据部分填入sample buffer中。

通过GraphEdit加载此sourcefilter并运行的时候发现图像时倒过来的。

后来查看media type发现其中关于位图高度的值为负值,原来是这个原因。

知道原因就知道怎么解决了。

CSourceStream::CheckMediaType()

检查位图的高度信息,如果是负值,那么就返回E_INVALIDARG,代码如下:

HRESULT SimpleVideoStream::CheckMediaType(const CMediaType *pMediaType)
{
    CAutoLock cAutoLock(m_pFilter->pStateLock());

    if ((*(pMediaType->Type()) != MEDIATYPE_Video)    // we only output video!
        || !(pMediaType->IsFixedSize()) ) // ...in fixed size samples
    {        
        return E_INVALIDARG;
    }

    // Check for the subtypes we support
    const GUID *SubType = pMediaType->Subtype();
    if ((*SubType != MEDIASUBTYPE_RGB8)
            && (*SubType != MEDIASUBTYPE_RGB565)
            && (*SubType != MEDIASUBTYPE_RGB555)
             && (*SubType != MEDIASUBTYPE_RGB24)
            && (*SubType != MEDIASUBTYPE_RGB32))
    {
        return E_INVALIDARG;
    }

    // Get the format area of the media type
    VIDEOINFO *pvi = (VIDEOINFO *) pMediaType->Format();

    if (pvi == NULL)
    return E_INVALIDARG;

    if ( pvi->bmiHeader.biHeight < 0 )
    {
        return E_INVALIDARG;
    }


    return S_OK;
}

注意上面绿色的部分是关键。

注意这里因为位图是从windows的位图文件中读取,其位图数据就是颠倒的。也就是图像中的第一行的位图数据是在位图文件的最后一行,因此我们才需要这么做。

如果你要显示的位图数据本身就不是颠倒的,那么上面的没有必要或者变为

    if ( pvi->bmiHeader.biHeight > 0 )
    {
        return E_INVALIDARG;
    }

其实不光是在directshow的fiilter中会有这种问题,在任何显示位图的情况下都有这种问题。如果图像颠倒就查看位图数据的顺序和高度的正负。

完。

版权所有,禁止转载. 如需转载,请先征得博主的同意,并且表明文章出处,否则按侵权处理.

    分享到:

Leave a Reply

Your email address will not be published. Required fields are marked *