OLD | NEW |
---|---|
(Empty) | |
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. | |
4 | |
5 #include "media/video/capture/win/sink_input_pin_win.h" | |
6 | |
7 // Avoid including strsafe.h via dshow as it will cause build warnings. | |
8 #define NO_DSHOW_STRSAFE | |
9 #include <dshow.h> | |
10 | |
11 #include "base/logging.h" | |
12 | |
13 namespace media { | |
14 | |
15 SinkInputPin::SinkInputPin(IBaseFilter* filter, | |
16 SinkFilterObserver* observer) | |
17 : observer_(observer), | |
18 PinBase(filter) { | |
19 } | |
20 | |
21 SinkInputPin::~SinkInputPin() {} | |
22 | |
23 bool SinkInputPin::GetValidMediaType(int index, AM_MEDIA_TYPE* media_type) { | |
24 if (media_type->cbFormat < sizeof(VIDEOINFOHEADER)) | |
25 return false; | |
26 | |
27 VIDEOINFOHEADER* pvi = | |
28 reinterpret_cast<VIDEOINFOHEADER*>(media_type->pbFormat); | |
29 | |
30 ZeroMemory(pvi, sizeof(VIDEOINFOHEADER)); | |
31 pvi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); | |
32 pvi->bmiHeader.biPlanes = 1; | |
33 pvi->bmiHeader.biClrImportant = 0; | |
34 pvi->bmiHeader.biClrUsed = 0; | |
35 if (requested_capability_.frame_rate > 0) { | |
36 pvi->AvgTimePerFrame = kSecondsToReferenceTime / | |
37 requested_capability_.frame_rate; | |
38 } | |
39 | |
40 media_type->majortype = MEDIATYPE_Video; | |
41 media_type->formattype = FORMAT_VideoInfo; | |
42 media_type->bTemporalCompression = FALSE; | |
43 | |
44 switch (index) { | |
45 case 0: { | |
46 pvi->bmiHeader.biCompression = MAKEFOURCC('I', '4', '2', '0'); | |
47 pvi->bmiHeader.biBitCount = 12; // bit per pixel | |
48 pvi->bmiHeader.biWidth = requested_capability_.width; | |
49 pvi->bmiHeader.biHeight = requested_capability_.height; | |
50 pvi->bmiHeader.biSizeImage = 3 * requested_capability_.height * | |
51 requested_capability_.width / 2; | |
52 media_type->subtype = kMediaSubTypeI420; | |
53 break; | |
54 } | |
55 case 1: { | |
56 pvi->bmiHeader.biCompression = MAKEFOURCC('Y', 'U', 'Y', '2'); | |
57 pvi->bmiHeader.biBitCount = 16; | |
58 pvi->bmiHeader.biWidth = requested_capability_.width; | |
59 pvi->bmiHeader.biHeight = requested_capability_.height; | |
60 pvi->bmiHeader.biSizeImage = 2 * requested_capability_.width * | |
61 requested_capability_.height; | |
62 media_type->subtype = MEDIASUBTYPE_YUY2; | |
63 break; | |
64 } | |
65 case 2: { | |
66 pvi->bmiHeader.biCompression = BI_RGB; | |
67 pvi->bmiHeader.biBitCount = 24; | |
68 pvi->bmiHeader.biWidth = requested_capability_.width; | |
69 pvi->bmiHeader.biHeight = requested_capability_.height; | |
70 pvi->bmiHeader.biSizeImage = 3 * requested_capability_.height * | |
71 requested_capability_.width; | |
72 media_type->subtype = MEDIASUBTYPE_RGB24; | |
73 break; | |
74 } | |
75 default: | |
76 return false; | |
77 } | |
78 | |
79 media_type->bFixedSizeSamples = TRUE; | |
80 media_type->lSampleSize = pvi->bmiHeader.biSizeImage; | |
81 return true; | |
82 } | |
83 | |
84 bool SinkInputPin::IsMediaTypeValid(const AM_MEDIA_TYPE* media_type) { | |
85 GUID type = media_type->majortype; | |
86 if (type != MEDIATYPE_Video) { | |
87 return false; | |
88 } | |
89 GUID format_type = media_type->formattype; | |
90 | |
91 // Check for the sub types we support. | |
92 GUID sub_type = media_type->subtype; | |
93 | |
94 if (format_type == FORMAT_VideoInfo) { | |
cpu_(ooo_6.6-7.5)
2011/06/27 18:10:27
same nit about negative logic.
if (format_type !=
Per K
2011/06/28 10:14:07
Done.
| |
95 VIDEOINFOHEADER* pvi = | |
96 reinterpret_cast<VIDEOINFOHEADER*>(media_type->pbFormat); | |
97 if (pvi == NULL) { | |
98 return false; | |
99 } | |
100 | |
101 // Store the incoming width and height. | |
102 resulting_capability_.width = pvi->bmiHeader.biWidth; | |
103 resulting_capability_.height = abs(pvi->bmiHeader.biHeight); | |
104 if (pvi->AvgTimePerFrame > 0) { | |
105 resulting_capability_.frame_rate = | |
106 static_cast<int>(kSecondsToReferenceTime / pvi->AvgTimePerFrame); | |
107 } else { | |
108 resulting_capability_.frame_rate = requested_capability_.frame_rate; | |
109 } | |
110 if (sub_type == kMediaSubTypeI420 && | |
111 pvi->bmiHeader.biCompression == MAKEFOURCC('I', '4', '2', '0')) { | |
112 resulting_capability_.color = VideoCaptureDevice::kI420; | |
113 return true; // This format is acceptable. | |
114 } | |
115 if (sub_type == MEDIASUBTYPE_YUY2 && | |
116 pvi->bmiHeader.biCompression == MAKEFOURCC('Y', 'U', 'Y', '2')) { | |
117 resulting_capability_.color = VideoCaptureDevice::kYUY2; | |
118 return true; // This format is acceptable. | |
119 } | |
120 if (sub_type == MEDIASUBTYPE_RGB24 && | |
121 pvi->bmiHeader.biCompression == BI_RGB) { | |
122 resulting_capability_.color = VideoCaptureDevice::kRGB24; | |
123 return true; // This format is acceptable. | |
124 } | |
125 } | |
126 return false; | |
127 } | |
128 | |
129 HRESULT SinkInputPin::Receive(IMediaSample* media_sample) { | |
130 DCHECK(media_sample); | |
131 const int length = media_sample->GetActualDataLength(); | |
132 uint8* buffer = NULL; | |
133 if (FAILED(media_sample->GetPointer(&buffer))) { | |
134 return S_FALSE; | |
135 } | |
136 observer_->FrameReceived(buffer, length); | |
137 | |
138 return S_OK; | |
139 } | |
140 | |
141 void SinkInputPin::SetRequestedMediaCapability( | |
142 const VideoCaptureDevice::Capability& capability) { | |
143 requested_capability_ = capability; | |
144 resulting_capability_ = VideoCaptureDevice::Capability(); | |
145 } | |
146 | |
147 const VideoCaptureDevice::Capability& SinkInputPin::ResultingCapability() { | |
148 return resulting_capability_; | |
149 } | |
150 | |
151 } // namespace media | |
OLD | NEW |