Directshow的媒體類(lèi)型結(jié)構(gòu)
在directshow中,對(duì)于push模式的source filter來(lái)說(shuō)争群,有兩個(gè)重要的基礎(chǔ)類(lèi)锨推,CSource
和CSourceStream寝并。CSource是filter的基礎(chǔ)類(lèi)蜕猫,CSourceStream是outputpin的基礎(chǔ)類(lèi)寂曹。這里我們就看看后者里有關(guān)媒體類(lèi)型的內(nèi)容。
在directshow中兩個(gè)Pin(gstreamer叫做pad)相連接時(shí)回右,需要進(jìn)行類(lèi)型與格式的協(xié)商,其中就依賴(lài)CSourceStream的一個(gè)重要方法:
//Gets a media type from the output pin.
virtual HRESULT GetMediaType(
int iPosition,
CMediaType *pMediaType
);
GetMediaType返回一個(gè)或多個(gè)媒體類(lèi)型(media type)漱挚,用于和下游的filter進(jìn)行協(xié)商翔烁。下游如果是decoder/encoder,需要這些信息進(jìn)行編碼和解碼工作旨涝;如果是render蹬屹,需要更詳細(xì)的信息,包括格式信息等進(jìn)行渲染。詳細(xì)可參考How to Write a Source Filter for DirectShow
AM_MEDIA_TYPE
在這里慨默,可以看到媒體類(lèi)型使用CMediaType類(lèi)來(lái)表示贩耐, CMediaType類(lèi)繼承自AM_MEDIA_TYPE結(jié)構(gòu)體,提供了AM_MEDIA_TYPE結(jié)構(gòu)體操作方法厦取。如下正式AM_MEDIA_TYPE的定義:
typedef struct _AMMediaType {
GUID majortype;
GUID subtype;
BOOL bFixedSizeSamples;
BOOL bTemporalCompression;
ULONG lSampleSize;
GUID formattype;
IUnknown *pUnk;
ULONG cbFormat;
BYTE *pbFormat;
} AM_MEDIA_TYPE
majortype
majortype 的值是一個(gè)GUID, 用它來(lái)確定媒體數(shù)據(jù)的主要類(lèi)型潮太,directshow為每個(gè)GUID都定義了常量標(biāo)識(shí)符,下面是它的list:
GUID | Description |
---|---|
MEDIATYPE_AnalogAudio | Analog audio.模擬音頻虾攻,一般是聲卡采集輸入的數(shù)據(jù)類(lèi)型铡买,TV Audio Filter就接收這種類(lèi)型的音頻 |
MEDIATYPE_AnalogVideo | Analog video. 模擬視頻,一般是視頻采集卡輸入的數(shù)據(jù)類(lèi)型 |
MEDIATYPE_Audio | Audio. See Audio Subtypes. 數(shù)字音頻信號(hào) |
MEDIATYPE_AUXLine21Data | Line 21 data. Used by closed captions. See Line 21 Media Types. 閉路電視信號(hào)(參考EIA-608) |
MEDIATYPE_File | File. (Obsolete) 已經(jīng)廢棄文件類(lèi)型 |
MEDIATYPE_Interleaved | Interleaved audio and video. Used for Digital Video (DV). DV的數(shù)據(jù)流(包括音視頻數(shù)據(jù)) |
MEDIATYPE_LMRT | Obsolete. Do not use. |
MEDIATYPE_Midi | MIDI format. 樂(lè)器數(shù)字接口信號(hào)霎箍,MIDI是編曲界最廣泛的音樂(lè)標(biāo)準(zhǔn)格式 |
MEDIATYPE_MPEG2_PES | MPEG-2 PES packets. See MPEG-2 Media Types. 用于DVD或數(shù)字視頻廣播(DVB) |
MEDIATYPE_MPEG2_SECTIONS | MPEG-2 section data. See MPEG-2 Media Types. MPEG-2 Demultiplexer的output媒體類(lèi)型之一 |
MEDIATYPE_ScriptCommand | Data is a script command, used by closed captions. 閉路電視 |
MEDIATYPE_Stream | Byte stream with no time stamps. See Stream Subtypes. 字節(jié)流奇钞,如(Pull模式)文件源的輸出數(shù)據(jù)類(lèi)型 |
MEDIATYPE_Text | Text. |
MEDIATYPE_Timecode | Timecode data. Note: DirectShow does not provide any filters that support this media type. |
MEDIATYPE_URL_STREAM | Obsolete. Do not use. |
MEDIATYPE_VBI | Vertical blanking interval (VBI) data (for television). Same as KSDATAFORMAT_TYPE_VBI. 電視廣播VBI信號(hào) |
MEDIATYPE_Video | Video. See Video Subtypes. 數(shù)字視頻信號(hào) |
參考圖:PES 在 MPEG-2 系統(tǒng)中的位置,可以看到它是一視頻編碼后更外邊的包漂坏。
subtype
很多著類(lèi)型都有子類(lèi)型景埃,在上面的列表種我們主要關(guān)心的是MEDIATYPE_Video類(lèi)型,在MEDIATYPE_Video下的subtype可以被分為幾類(lèi):
- Analog Video Subtypes // 模擬視頻子類(lèi)型
- DirectX Video Acceleration Video Subtypes
- DV Video Subtypes // 攝像機(jī)DV的具體子類(lèi)型
- H.264 Video Types // H.264類(lèi)型的video
- Uncompressed RGB Video Subtypes
- Video Mixing Renderer Video Subtypes //用于特定的fitler
- YUV Video Subtypes
- Miscellaneous Video Subtypes
- MPEG-1,-2 media type // MPEG-1 Video數(shù)據(jù)
我們最常見(jiàn)的圖像表示方法是RGB和YUV; 在YUV視頻分類(lèi)下顶别,我們可以看到如下常用的類(lèi)型:
GUID | Format | Sampling | Packed or planar | Bits per channel |
---|---|---|---|---|
MEDIASUBTYPE_AYUV | AYUV | 4:4:4 | Packed | 8 |
MEDIASUBTYPE_YUY2 | YUY2 | 4:2:2 | Packed | 8 |
MEDIASUBTYPE_UYVY | UYVY | 4:2:2 | Packed | 8 |
MEDIASUBTYPE_IMC1 | IMC1 | 4:2:0 | Planar | 8 |
MEDIASUBTYPE_IMC3 | IMC2 | 4:2:0 | Planar | 8 |
MEDIASUBTYPE_IMC2 | IMC3 | 4:2:0 | Planar | 8 |
MEDIASUBTYPE_IMC4 | IMC4 | 4:2:0 | Planar | 8 |
MEDIASUBTYPE_YV12 | YUY2 | 4:2:0 | Planar | 8 |
MEDIASUBTYPE_NV12 | NV12 | 4:2:0 | Planar | 8 |
YUV類(lèi)別下的子類(lèi)型 像素都是YUV格式纠亚, 主要按照 采樣比、存儲(chǔ)方式筋夏,和字節(jié)深度來(lái)區(qū)分蒂胞。
formattype
majortype和subtype主要描述媒體的主要類(lèi)型和次要類(lèi)型:majortype主要定義大概的分類(lèi),例如視頻条篷、音頻骗随、字節(jié)流等;子類(lèi)型定義大分類(lèi)下的更小的分類(lèi)赴叹,例如YUY2鸿染, YUY2等。
但是這些信息還不足夠保證兩個(gè)pin(gstremer稱(chēng)為pad)之間的成功連接乞巧,它們還需要一些詳細(xì)的格式信息涨椒,例如支持的圖像寬度、高度绽媒,播放頻率等蚕冬。
這些信息會(huì)被保存在一個(gè)格式數(shù)據(jù)塊,并且僅跟在AM_MEDIA_TYPE 結(jié)構(gòu)體的后面存儲(chǔ),私用AM_MEDIA_TYPE結(jié)構(gòu)體的pbFormat指針來(lái)指向是辕。這個(gè)format塊是不定長(zhǎng)的囤热,所以需要使用formattype來(lái)描述它的類(lèi)別,看它是那種媒體類(lèi)型的格式信息获三。
formattype也是使用GUID表示旁蔼,directshow同樣提供了一個(gè)常量列表來(lái)描述它所支持的Format類(lèi)型:
在上面的媒體對(duì)于視頻來(lái)說(shuō)锨苏,在常用的就是FORMAT_VideoInfo 和 FORMAT_VideoInfo2。
- VIDEOINFOHEADER 結(jié)構(gòu)體
typedef struct tagVIDEOINFOHEADER {
RECT rcSource; //確定source視頻窗口的長(zhǎng)方形
RECT rcTarget; //確定目標(biāo)視頻窗口的長(zhǎng)方形
DWORD dwBitRate; //視頻流按bit計(jì)算的數(shù)據(jù)速率
DWORD dwBitErrorRate; //出錯(cuò)率
REFERENCE_TIME AvgTimePerFrame; //期望的每幀平均顯示時(shí)間棺聊,以100納秒為單位
BITMAPINFOHEADER bmiHeader;
} VIDEOINFOHEADER;
- VIDEOINFOHEADER2結(jié)構(gòu)體
VIDEOINFOHEADER2結(jié)構(gòu)體描述了用于視頻圖像的位圖信息和顏色信息伞租,包括 interlace, copy protection和 picture aspect ratio等。
typedef struct tagVIDEOINFOHEADER2 {
RECT rcSource;
RECT rcTarget;
DWORD dwBitRate;
DWORD dwBitErrorRate;
REFERENCE_TIME AvgTimePerFrame;
DWORD dwInterlaceFlags; //flags that specify how the video is interlaced
DWORD dwCopyProtectFlags; //用于copy保護(hù)
DWORD dwPictAspectRatioX; //The X dimension of picture aspect ratio
DWORD dwPictAspectRatioY; //he Y dimension of picture aspect ratio
union {
DWORD dwControlFlags;
DWORD dwReserved1;
};
DWORD dwReserved2;
BITMAPINFOHEADER bmiHeader;
} VIDEOINFOHEADER2;
- BITMAPINFOHEADER結(jié)構(gòu)體
如上,在VIDEOINFOHEADER和VIDEOINFOHEADER2結(jié)構(gòu)體中又包含了一個(gè)BITMAPINFOHEADER的信息結(jié)構(gòu)體限佩,它 包含了視頻圖像的顏色和維度信息:
typedef struct tagBITMAPINFOHEADER {
DWORD biSize; //本結(jié)構(gòu)體大小
LONG biWidth; // bitmap寬度葵诈, 單位為pixel
LONG biHeight; //bitmap高度, 單位為pixel
WORD biPlanes; //number of planes for the target device. This value must be set to 1
WORD biBitCount; //Specifies the number of bits per pixel (bpp)
DWORD biCompression; //對(duì)于壓縮視頻和YUV格式犀暑,這個(gè)字段是 FOURCC code驯击,對(duì)于未壓縮的RGB格式,它又固定的值
DWORD biSizeImage; //image的大小耐亏,以byte為單位徊都。
LONG biXPelsPerMeter; //Specifies the horizontal resolution
LONG biYPelsPerMeter; // Specifies the vertical resolution
DWORD biClrUsed; // Specifies the number of color indices in the color table that are actually used by the bitmap
DWORD biClrImportant; //Specifies the number of color indices that are considered important for displaying the bitmap.
} BITMAPINFOHEADER, *LPBITMAPINFOHEADER, *PBITMAPINFOHEADER;
需要注意的是BITMAPINFOHEADER結(jié)構(gòu)體后面可能會(huì)跟隨palette 和 color mask信息。需要參考BITMAPINFOHEADER Color Tables的描述广辰。
rcSource暇矫,rcTarget 和biWidth/biHeight的關(guān)系
在幾個(gè)結(jié)構(gòu)體中,都有關(guān)于圖像寬度和高度的描述择吊,例如VIDEOINFOHEADER 和VIDEOINFOHEADER2 中的rcSource李根、rcTarget ;還有BITMAPINFOHEADER中的biwidth几睛、biHeight. 它們之間的關(guān)系可以用兩個(gè)filter連接后的動(dòng)作來(lái)描述:
當(dāng)filter A與Filter B 相連接后房轿,數(shù)據(jù)通過(guò)A與B之間的buffer傳遞。Buffer有自己的大小所森,它由bmiHeader.biWidth, bmiHeader.biHeight決定囱持。FilteA在填充buffer的時(shí)候,將會(huì)使用rcSource矩形來(lái)確定哪一部分的input video應(yīng)該放在buffer里焕济;并且通過(guò)拉伸操作纷妆,將由rcTarget矩形確定的buffer位置填充滿(mǎn)。
所以在填充時(shí)需要比較rcsource,bitWidth等信息晴弃,如果rcsource值為0掩幢,表示使用整個(gè)輸入視頻圖像填充;如果rctarget為0,表示填滿(mǎn)整個(gè)buffer.
gst videotestsrc 的媒體類(lèi)型信息
在gststreamer種上鞠, videotestsrc被用來(lái)生成各種格式的測(cè)試視頻數(shù)據(jù)际邻,默認(rèn)情況下,它可以無(wú)限的生成數(shù)據(jù)旗国。
**gst-launch-1.0 -v videotestsrc pattern=snow ! video/x-raw,width=1280,height=720 ! autovideosink **
例如使用如上命令產(chǎn)生的效果:
在Gststreamer中枯怖,一般用pad模板用來(lái)描述input/output pad的能力,每個(gè)filter都有一個(gè)或多個(gè)pad(directshow中稱(chēng)為PIN), 用來(lái)描述這個(gè)filter能夠接收的媒體類(lèi)型與格式或者可以輸出的媒體類(lèi)型和格式能曾。 videotestsrc作為數(shù)據(jù)生成filter度硝,它只有一個(gè)output pad, 如下是它的pad模板:
video/x-raw:
format: { ABGR64_LE, BGRA64_LE, AYUV64, ARGB64_LE, ARGB64, RGBA64_LE, ABGR64_BE, BGRA64_BE, ARGB64_BE, RGBA64_BE, GBRA_12LE, GBRA_12BE, Y412_LE, Y412_BE, A444_10LE, GBRA_10LE, A444_10BE, GBRA_10BE, A422_10LE, A422_10BE, A420_10LE, A420_10BE, RGB10A2_LE, BGR10A2_LE, Y410, GBRA, ABGR, VUYA, BGRA, AYUV, ARGB, RGBA, A420, AV12, Y444_16LE, Y444_16BE, v216, P016_LE, P016_BE, Y444_12LE, GBR_12LE, Y444_12BE, GBR_12BE, I422_12LE, I422_12BE, Y212_LE, Y212_BE, I420_12LE, I420_12BE, P012_LE, P012_BE, Y444_10LE, GBR_10LE, Y444_10BE, GBR_10BE, r210, I422_10LE, I422_10BE, NV16_10LE32, Y210, v210, UYVP, I420_10LE, I420_10BE, P010_10LE, NV12_10LE32, NV12_10LE40, P010_10BE, Y444, RGBP, GBR, BGRP, NV24, xBGR, BGRx, xRGB, RGBx, BGR, IYU2, v308, RGB, Y42B, NV61, NV16, VYUY, UYVY, YVYU, YUY2, I420, YV12, NV21, NV12, NV12_64Z32, NV12_4L4, NV12_32L32, Y41B, IYU1, YVU9, YUV9, RGB16, BGR16, RGB15, BGR15, RGB8P, GRAY16_LE, GRAY16_BE, GRAY10_LE32, GRAY8 }
width: [ 1, 2147483647 ]
height: [ 1, 2147483647 ]
framerate: [ 0/1, 2147483647/1 ]
multiview-mode: { (string)mono, (string)left, (string)right }
video/x-bayer:
format: { bggr, rggb, grbg, gbrg }
width: [ 1, 2147483647 ]
: [ 1, 2147483647 ]
: [ 0/1, 2147483647/1 ]
multiview-mode: { (string)mono, (string)left, (string)right }
- video/x-raw,video/x-bayer
它們是兩種視頻媒體類(lèi)型寿冕。
video/x-raw 是只未經(jīng)encode的原始視頻蕊程,video/x-bayer bayer格式的視頻
notes: gststreamer的媒體類(lèi)型寫(xiě)法和mine一樣,但是并不能和mine對(duì)應(yīng)上驼唱,需要注意fitler的caps 模板的描述 - format
表示視頻支持的編碼格式藻茂。
raw video支持的格式包含很多,可以看到對(duì)于YUV玫恳,它可以支持的格式有VYUY, UYVY, YVYU, YUY2, I420, YV12, NV21, NV12, NV12_64Z32, NV12_4L4, NV12_32L32, Y41B, IYU1, YVU9, YUV9辨赐。YUV作為標(biāo)準(zhǔn)格式,在Gststreamer和direcshow里是通用的京办。 - width掀序,height,framerate
寬度惭婿,高度不恭,幀速率的取值是區(qū)間值,表示可以產(chǎn)生這個(gè)范圍內(nèi)的視頻數(shù)據(jù)财饥。 - multiview-mode
表示在3d /VR場(chǎng)景中换吧,多畫(huà)面的顯示方式,這個(gè)不常用钥星。
CSourceStream中的GetMediaType方法
了解了directshow的媒體類(lèi)型信息沾瓦,以及gstreamer中videotestsrc的pad 模板,我們更深一步的看看如何實(shí)現(xiàn)CSourceStream的GetMediaType方法谦炒,并且他的媒體信息與videotestsrc的模板能力保持一致贯莺。
GetMediaType有兩個(gè)重載方法:
- GetMediaType (1) 只有一個(gè)參數(shù),指向 CMediaType 類(lèi)型對(duì)象.
-
GetMediaType (2) 有兩個(gè)參數(shù)编饺,一個(gè)是index變量乖篷,一個(gè)是指向 CMediaType 類(lèi)型對(duì)象的指針.
第一個(gè)用于只提供一個(gè)媒體類(lèi)型的場(chǎng)景,第二個(gè)用于能支持多個(gè)媒體類(lèi)型的場(chǎng)景透且,并且第二個(gè)需要和 CheckMediaType方法一起使用撕蔼。
在CSourceStream中,已經(jīng)對(duì)這三個(gè)方法做了基本的實(shí)現(xiàn)秽誊,只需要按照自己的需要overwite相關(guān)的方法就可以鲸沮。
我們實(shí)現(xiàn)比較簡(jiǎn)單的方法1,只包含一個(gè)參數(shù):
HRESULT CVCamStream::GetMediaType(CMediaType *pmt)
{
//為pmt創(chuàng)建一個(gè)VIDEOINFOHEADER結(jié)構(gòu)體指針锅论,并為它分配內(nèi)存
DECLARE_PTR(VIDEOINFOHEADER, pvi,
pmt->AllocFormatBuffer(sizeof(VIDEOINFOHEADER)));
ZeroMemory(pvi, sizeof(VIDEOINFOHEADER));
pvi->bmiHeader.biWidth = 1280; //圖像寬度
pvi->bmiHeader.biHeight = 720; //圖像高度
pvi->AvgTimePerFrame = 333333;//每幀平均顯示時(shí)常,單位100-nanosecond
pvi->bmiHeader.biCompression = MAKEFOURCC('Y', 'U', 'Y', '2');//對(duì)于YUV格式需要在這個(gè)字段設(shè)置它的4CC代碼
pvi->bmiHeader.biBitCount = 16; //設(shè)置YUY2格式下一個(gè)像素的bits數(shù)
pvi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);//bmiHeader的size
pvi->bmiHeader.biPlanes = 1; //總是設(shè)置1
pvi->bmiHeader.biSizeImage = pvi->bmiHeader.biWidth *
pvi->bmiHeader.biHeight * 2;//YUY2一個(gè)像素相當(dāng)于兩個(gè)字節(jié)讼溺,設(shè)置圖像的大小,單位是字節(jié)byte.
pvi->bmiHeader.biClrImportant = 0; //0表示所有顏色都是重要的
SetRectEmpty(&(pvi->rcSource)); //填充所有source image數(shù)據(jù)
SetRectEmpty(&(pvi->rcTarget)); //填充滿(mǎn)buffer
pmt->SetType(&MEDIATYPE_Video); //設(shè)置著類(lèi)型未video 對(duì)應(yīng)video/x-raw
pmt->SetFormatType(&FORMAT_VideoInfo); //設(shè)置格式類(lèi)型為FORMAT_VideoInfo
pmt->SetTemporalCompression(FALSE); // 每一幀無(wú)壓縮
pmt->SetSubtype(&MEDIASUBTYPE_YUY2); //設(shè)置子類(lèi)型格式
pmt->SetSampleSize(pvi->bmiHeader.biSizeImage);//設(shè)置sample的大小為固定1幀的大小
return NOERROR;
}
如上directshow的代碼最易,在gstreamer中怒坯,它對(duì)應(yīng)的videotestsrc的caps信息為:
video/x-raw,width=1280,height=720炫狱,format=YUY2,framerate=(fraction)30/1
這里需要注意剔猿,framerate的格式用的是我們通常理解的幀/每秒视译, pvi->AvgTimePerFrame用的是時(shí)間,單位是100-nanosecond归敬。
可以使用gst-launch-1.0測(cè)試以下:
gst-launch-1.0 -v videotestsrc \
! video/x-raw,foramt=YUV2,width=1280,height=720,framerate=30/1 \
! autovideosink
顯示效果:
CSourceStream中的DecideBufferSize方法
當(dāng)確定了媒體類(lèi)型和格式信息后酷含,作為通常output pin還需要overwiter DecideBufferSize方法,這個(gè)方法用來(lái)設(shè)置sample buffers的大小
HRESULT CVCamStream::DecideBufferSize(IMemAllocator *pAlloc, //pAlloc為指向allocator的指針汪茧,allocator管理這buffer
ALLOCATOR_PROPERTIES *pProperties)//ALLOCATOR_PROPERTIES 包含有input pin對(duì)buffer的需求
{
CAutoLock cAutoLock(m_pFilter->pStateLock());
HRESULT hr = NOERROR;
VIDEOINFOHEADER *pvi = (VIDEOINFOHEADER *)m_mt.Format();
pProperties->cBuffers = 1; //設(shè)置被allocator創(chuàng)建的buffer的多少
pProperties->cbBuffer = pvi->bmiHeader.biSizeImage; //設(shè)置buffer的大小椅亚,以字節(jié)為單位
ALLOCATOR_PROPERTIES Actual;
hr = pAlloc->SetProperties(pProperties, &Actual);//這是新屬性
if (FAILED(hr)) return hr;
if (Actual.cbBuffer < pProperties->cbBuffer) return E_FAIL;
return NOERROR;
}
如上面的方法,allocator被要求只創(chuàng)建一個(gè)buffer舱污,且大小等于1幀(bitmap的大醒教颉)。
IAMStreamConfig接口和video Capabilities
始于視頻輸入設(shè)備來(lái)說(shuō)慌闭,它們通常支持一些列的格式别威。例如一個(gè)設(shè)備可能會(huì)支持 16-bit RGB, 32-bit RGB, 和YUYV. 在每個(gè)格式里,這個(gè)設(shè)備又可能會(huì)支持一系列的幀大小.
這時(shí)候 IAMStreamConfig接口通常被用來(lái)報(bào)告這個(gè)設(shè)備支持的所有格式信息驴剔,并且允許設(shè)置格式信息, 對(duì)于capture filter來(lái)說(shuō)省古,它的output pin需要實(shí)現(xiàn)這個(gè)接口。
HRESULT GetNumberOfCapabilities(
[out] int *piCount,
[out] int *piSize
);
這個(gè)接口返回兩個(gè)數(shù)據(jù): 通過(guò)piCount獲得這個(gè)filter支持的媒體類(lèi)型個(gè)數(shù)丧失。通過(guò)piSize可以獲得保存caps信息的結(jié)構(gòu)體的大小豺妓,對(duì)于視頻來(lái)說(shuō),這個(gè)接口體時(shí)VIDEO_STREAM_CONFIG_CAPS布讹。
HRESULT GetStreamCaps(
[in] int iIndex,
[out] AM_MEDIA_TYPE **ppmt,
[out] BYTE *pSCC
);
這個(gè)方法通過(guò)索引index獲得具體的某個(gè)format信息(ppmt指向)和能力信息(pSCC指向)琳拭,對(duì)于視頻pSCC指向一個(gè) VIDEO_STREAM_CONFIG_CAPS結(jié)構(gòu)體。
-
SetFormat 和GetFormat
GetFormat用于返回一個(gè)pin的format信息:當(dāng)pin已經(jīng)連接成功描验,它返回的是當(dāng)前正在使用的format白嘁;如果還沒(méi)有連接成功,它返回下次連接最合適的format. 特別是如果用戶(hù)使用了setFormat 設(shè)置了一個(gè)format, 則GetFormat會(huì)返回這個(gè)設(shè)置的值膘流。
setformat可以用來(lái)設(shè)置output pin的格式絮缅,如果還沒(méi)有連接了,這個(gè)format將被用來(lái)做下一次連接呼股,如果已經(jīng)連接了. 這個(gè)方法會(huì)嘗試重連接耕魄。 -
VIDEO_STREAM_CONFIG_CAPS
這個(gè)結(jié)構(gòu)體用來(lái)描述設(shè)備的視頻能力,包括format和resolution信息:
typedef struct _VIDEO_STREAM_CONFIG_CAPS {
GUID guid; //確定Format類(lèi)型的GUID
ULONG VideoStandard;//支持的模擬視頻標(biāo)準(zhǔn)彭谁,數(shù)字視頻設(shè)為0(AnalogVideo_None)
SIZE InputSize; ////輸入視頻的大小 ---已經(jīng)廢棄
SIZE MinCroppingSize; //允許的最小resSource ---已經(jīng)廢棄
SIZE MaxCroppingSize; //允許的最小resSource ---已經(jīng)廢棄
int CropGranularityX; //resSource的水平increment的度 ---已經(jīng)廢棄
int CropGranularityY; //resSource的垂直increment的度 ---已經(jīng)廢棄
int CropAlignX; //resSource水平對(duì)齊 ---已經(jīng)廢棄
int CropAlignY; //resSource垂直對(duì)齊 ---已經(jīng)廢棄
SIZE MinOutputSize; //最小輸出大小 ---已經(jīng)廢棄
SIZE MaxOutputSize; //最大輸出大小 ---已經(jīng)廢棄
int OutputGranularityX; //Granularity of the output width ---已經(jīng)廢棄
int OutputGranularityY; //Granularity of output height. ---已經(jīng)廢棄
int StretchTapsX; //水平stretch的程度 取值[0,1,2,3...] ---已經(jīng)廢棄
int StretchTapsY; //垂直stretch的程度 ---已經(jīng)廢棄
int ShrinkTapsX; //水平Shrink的程度 ---已經(jīng)廢棄
int ShrinkTapsY; //水平Shrink的程度 ---已經(jīng)廢棄
LONGLONG MinFrameInterval; //最小幀間隔 單位100納秒
LONGLONG MaxFrameInterval; //最大幀間隔 單位100納秒
LONG MinBitsPerSecond; //Minimum data rate this pin can produce. ---已經(jīng)廢棄
LONG MaxBitsPerSecond; //Maximum data rate this pin can produce. ---已經(jīng)廢棄
} VIDEO_STREAM_CONFIG_CAPS;
IAMStreamConfig::GetStreamCaps將返回這個(gè)結(jié)構(gòu)體吸奴,應(yīng)用程序可以使用這個(gè)信息output pin的格式。關(guān)于它詳細(xì)的介紹可以參考Video Capabilities和VIDEO_STREAM_CONFIG_CAPS structure。例如對(duì)于如下的設(shè)置:
MinOutputSize: 160 x 120
MaxOutputSize: 320 x 240
OutputGranularityX: 8 pixels (horizontal step size)
OutputGranularityY: 8 pixels (vertical step size)
下圖是這些屬性值的解釋?zhuān)?br>
最后我們來(lái)看一下则奥,根據(jù)我們的媒體和格式類(lèi)型考润,實(shí)現(xiàn)GetStreamCaps方法:
HRESULT STDMETHODCALLTYPE CVCamStream::GetStreamCaps(int iIndex,
AM_MEDIA_TYPE **pmt, BYTE *pSCC)
{
if (iIndex < 0 )
return E_INVALIDARG;
*pmt = CreateMediaType(&m_mt); //創(chuàng)建媒體類(lèi)型
DECLARE_PTR(VIDEOINFOHEADER, pvi, (*pmt)->pbFormat); //創(chuàng)建format類(lèi)型
//設(shè)置format
pvi->bmiHeader.biWidth = 1280;
pvi->bmiHeader.biHeight = 720;
pvi->AvgTimePerFrame = 333333;
pvi->bmiHeader.biCompression = MAKEFOURCC('Y', 'U', 'Y', '2');
pvi->bmiHeader.biBitCount = 16;
pvi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
pvi->bmiHeader.biPlanes = 1;
pvi->bmiHeader.biSizeImage = pvi->bmiHeader.biWidth *
pvi->bmiHeader.biHeight * 2;
pvi->bmiHeader.biClrImportant = 0;
SetRectEmpty(&(pvi->rcSource));
SetRectEmpty(&(pvi->rcTarget));
//設(shè)置meida Type
(*pmt)->majortype = MEDIATYPE_Video;
(*pmt)->subtype = MEDIASUBTYPE_YUY2;
(*pmt)->formattype = FORMAT_VideoInfo;
(*pmt)->bTemporalCompression = FALSE;
(*pmt)->bFixedSizeSamples = FALSE;
(*pmt)->lSampleSize = pvi->bmiHeader.biSizeImage;
(*pmt)->cbFormat = sizeof(VIDEOINFOHEADER);
//創(chuàng)建VIDEO_STREAM_CONFIG_CAPS結(jié)構(gòu)體
DECLARE_PTR(VIDEO_STREAM_CONFIG_CAPS, pvscc, pSCC);
//設(shè)置VIDEO_STREAM_CONFIG_CAPS
pvscc->guid = FORMAT_VideoInfo; //媒體類(lèi)型為FORMAT_VideoInfo
pvscc->VideoStandard = AnalogVideo_None; //不是模擬視頻
pvscc->InputSize.cx = pvi->bmiHeader.biWidth; //輸入寬度
pvscc->InputSize.cy = pvi->bmiHeader.biHeight; //輸入高度
pvscc->MinCroppingSize.cx = pvi->bmiHeader.biWidth; //最小可裁剪寬度 相當(dāng)于不允許水平裁剪
pvscc->MinCroppingSize.cy = pvi->bmiHeader.biHeight;//最小可裁剪高度
pvscc->MaxCroppingSize.cx = pvi->bmiHeader.biWidth;//最大可裁剪寬度
pvscc->MaxCroppingSize.cy = pvi->bmiHeader.biHeight;//最大可裁剪高度
pvscc->CropGranularityX = pvi->bmiHeader.biWidth; //水平裁剪增量
pvscc->CropGranularityY = pvi->bmiHeader.biHeight; //水平裁剪增量
pvscc->CropAlignX = 0; //水平對(duì)其
pvscc->CropAlignY = 0; //垂直對(duì)齊
pvscc->MinOutputSize.cx = pvi->bmiHeader.biWidth; //最小輸出寬度
pvscc->MinOutputSize.cy = pvi->bmiHeader.biHeight; //最小輸出高度度
pvscc->MaxOutputSize.cx = pvi->bmiHeader.biWidth; /最大輸出寬度
pvscc->MaxOutputSize.cy = pvi->bmiHeader.biHeight; //最大輸出高度度
pvscc->OutputGranularityX = 0; //水平輸出變化增量
pvscc->OutputGranularityY = 0; //垂直輸出變化增量
pvscc->StretchTapsX = 0; //不允許tretching
pvscc->StretchTapsY = 0; //不允許tretching
pvscc->ShrinkTapsX = 0; //不允許Shrink
pvscc->ShrinkTapsY = 0; //不允許Shrink
pvscc->MinFrameInterval = pvi->AvgTimePerFrame; //最小幀間隔=平均幀播放時(shí)間
pvscc->MaxFrameInterval = pvi->AvgTimePerFrame; //最大幀間隔=平均幀播放時(shí)間
pvscc->MinBitsPerSecond = pvi->bmiHeader.biWidth * pvi->bmiHeader.biHeight
* 2 * 8 * (10000000 / pvi->AvgTimePerFrame); //最小輸出數(shù)據(jù)bit單位
pvscc->MaxBitsPerSecond = pvi->bmiHeader.biWidth * pvi->bmiHeader.biHeight
* 2 * 8 * (10000000 / pvi->AvgTimePerFrame); /最大輸出數(shù)據(jù)bit單位
return S_OK;
}
上面有一個(gè)關(guān)于pin產(chǎn)生數(shù)據(jù)大小的計(jì)算:
pvscc->MinBitsPerSecond = pvi->bmiHeader.biWidth * pvi->bmiHeader.biHeight
* 2 * 8 * (10000000 / pvi->AvgTimePerFrame);
biWidth 是位圖寬度(單位像素),biHeight是位圖高度(單位像素)逞度,YUV2一個(gè)像素需要2個(gè)字節(jié)额划,每個(gè)字節(jié)8bit位妙啃。所以biWidth biHeight28就是bitmap的大小档泽。10000000 / pvi->AvgTimePerFrame表示一秒中,可以播放多少幀揖赴。我們知道這個(gè)值在我們的例子里就是30.
所以最終我們獲得了馆匿,每秒鐘output pin可以傳輸?shù)腷it的大小。他就等于size(bitmap)幀頻率燥滑。