1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "media/video/capture/win/sink_input_pin_win.h"
7 // Avoid including strsafe.h via dshow as it will cause build warnings.
8 #define NO_DSHOW_STRSAFE
11 #include "base/logging.h"
15 const REFERENCE_TIME kSecondsToReferenceTime
= 10000000;
17 SinkInputPin::SinkInputPin(IBaseFilter
* filter
,
18 SinkFilterObserver
* observer
)
19 : observer_(observer
),
23 SinkInputPin::~SinkInputPin() {}
25 bool SinkInputPin::GetValidMediaType(int index
, AM_MEDIA_TYPE
* media_type
) {
26 if (media_type
->cbFormat
< sizeof(VIDEOINFOHEADER
))
29 VIDEOINFOHEADER
* pvi
=
30 reinterpret_cast<VIDEOINFOHEADER
*>(media_type
->pbFormat
);
32 ZeroMemory(pvi
, sizeof(VIDEOINFOHEADER
));
33 pvi
->bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
34 pvi
->bmiHeader
.biPlanes
= 1;
35 pvi
->bmiHeader
.biClrImportant
= 0;
36 pvi
->bmiHeader
.biClrUsed
= 0;
37 if (requested_capability_
.frame_rate
> 0) {
38 pvi
->AvgTimePerFrame
= kSecondsToReferenceTime
/
39 requested_capability_
.frame_rate
;
42 media_type
->majortype
= MEDIATYPE_Video
;
43 media_type
->formattype
= FORMAT_VideoInfo
;
44 media_type
->bTemporalCompression
= FALSE
;
48 pvi
->bmiHeader
.biCompression
= MAKEFOURCC('I', '4', '2', '0');
49 pvi
->bmiHeader
.biBitCount
= 12; // bit per pixel
50 pvi
->bmiHeader
.biWidth
= requested_capability_
.width
;
51 pvi
->bmiHeader
.biHeight
= requested_capability_
.height
;
52 pvi
->bmiHeader
.biSizeImage
= 3 * requested_capability_
.height
*
53 requested_capability_
.width
/ 2;
54 media_type
->subtype
= kMediaSubTypeI420
;
58 pvi
->bmiHeader
.biCompression
= MAKEFOURCC('Y', 'U', 'Y', '2');
59 pvi
->bmiHeader
.biBitCount
= 16;
60 pvi
->bmiHeader
.biWidth
= requested_capability_
.width
;
61 pvi
->bmiHeader
.biHeight
= requested_capability_
.height
;
62 pvi
->bmiHeader
.biSizeImage
= 2 * requested_capability_
.width
*
63 requested_capability_
.height
;
64 media_type
->subtype
= MEDIASUBTYPE_YUY2
;
68 pvi
->bmiHeader
.biCompression
= BI_RGB
;
69 pvi
->bmiHeader
.biBitCount
= 24;
70 pvi
->bmiHeader
.biWidth
= requested_capability_
.width
;
71 pvi
->bmiHeader
.biHeight
= requested_capability_
.height
;
72 pvi
->bmiHeader
.biSizeImage
= 3 * requested_capability_
.height
*
73 requested_capability_
.width
;
74 media_type
->subtype
= MEDIASUBTYPE_RGB24
;
81 media_type
->bFixedSizeSamples
= TRUE
;
82 media_type
->lSampleSize
= pvi
->bmiHeader
.biSizeImage
;
86 bool SinkInputPin::IsMediaTypeValid(const AM_MEDIA_TYPE
* media_type
) {
87 GUID type
= media_type
->majortype
;
88 if (type
!= MEDIATYPE_Video
)
91 GUID format_type
= media_type
->formattype
;
92 if (format_type
!= FORMAT_VideoInfo
)
95 // Check for the sub types we support.
96 GUID sub_type
= media_type
->subtype
;
97 VIDEOINFOHEADER
* pvi
=
98 reinterpret_cast<VIDEOINFOHEADER
*>(media_type
->pbFormat
);
102 // Store the incoming width and height.
103 resulting_capability_
.width
= pvi
->bmiHeader
.biWidth
;
104 resulting_capability_
.height
= abs(pvi
->bmiHeader
.biHeight
);
105 if (pvi
->AvgTimePerFrame
> 0) {
106 resulting_capability_
.frame_rate
=
107 static_cast<int>(kSecondsToReferenceTime
/ pvi
->AvgTimePerFrame
);
109 resulting_capability_
.frame_rate
= requested_capability_
.frame_rate
;
111 if (sub_type
== kMediaSubTypeI420
&&
112 pvi
->bmiHeader
.biCompression
== MAKEFOURCC('I', '4', '2', '0')) {
113 resulting_capability_
.color
= VideoCaptureDevice::kI420
;
114 return true; // This format is acceptable.
116 if (sub_type
== MEDIASUBTYPE_YUY2
&&
117 pvi
->bmiHeader
.biCompression
== MAKEFOURCC('Y', 'U', 'Y', '2')) {
118 resulting_capability_
.color
= VideoCaptureDevice::kYUY2
;
119 return true; // This format is acceptable.
121 if (sub_type
== MEDIASUBTYPE_RGB24
&&
122 pvi
->bmiHeader
.biCompression
== BI_RGB
) {
123 resulting_capability_
.color
= VideoCaptureDevice::kRGB24
;
124 return true; // This format is acceptable.
129 HRESULT
SinkInputPin::Receive(IMediaSample
* sample
) {
130 const int length
= sample
->GetActualDataLength();
131 uint8
* buffer
= NULL
;
132 if (FAILED(sample
->GetPointer(&buffer
)))
135 observer_
->FrameReceived(buffer
, length
);
139 void SinkInputPin::SetRequestedMediaCapability(
140 const VideoCaptureDevice::Capability
& capability
) {
141 requested_capability_
= capability
;
142 resulting_capability_
= VideoCaptureDevice::Capability();
145 const VideoCaptureDevice::Capability
& SinkInputPin::ResultingCapability() {
146 return resulting_capability_
;