OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "media/capture/video/win/sink_input_pin_win.h" | 5 #include "media/capture/video/win/sink_input_pin_win.h" |
6 | 6 |
7 #include <cstring> | 7 #include <cstring> |
8 | 8 |
9 // Avoid including strsafe.h via dshow as it will cause build warnings. | 9 // Avoid including strsafe.h via dshow as it will cause build warnings. |
10 #define NO_DSHOW_STRSAFE | 10 #define NO_DSHOW_STRSAFE |
(...skipping 18 matching lines...) Expand all Loading... |
29 float frame_rate, | 29 float frame_rate, |
30 const BITMAPINFOHEADER& info_header) { | 30 const BITMAPINFOHEADER& info_header) { |
31 requested_pixel_format_ = pixel_format; | 31 requested_pixel_format_ = pixel_format; |
32 requested_frame_rate_ = frame_rate; | 32 requested_frame_rate_ = frame_rate; |
33 requested_info_header_ = info_header; | 33 requested_info_header_ = info_header; |
34 resulting_format_.frame_size.SetSize(0, 0); | 34 resulting_format_.frame_size.SetSize(0, 0); |
35 resulting_format_.frame_rate = 0; | 35 resulting_format_.frame_rate = 0; |
36 resulting_format_.pixel_format = PIXEL_FORMAT_UNKNOWN; | 36 resulting_format_.pixel_format = PIXEL_FORMAT_UNKNOWN; |
37 } | 37 } |
38 | 38 |
39 const VideoCaptureFormat& SinkInputPin::ResultingFormat() { | |
40 return resulting_format_; | |
41 } | |
42 | |
43 bool SinkInputPin::IsMediaTypeValid(const AM_MEDIA_TYPE* media_type) { | 39 bool SinkInputPin::IsMediaTypeValid(const AM_MEDIA_TYPE* media_type) { |
44 GUID type = media_type->majortype; | 40 const GUID type = media_type->majortype; |
45 if (type != MEDIATYPE_Video) | 41 if (type != MEDIATYPE_Video) |
46 return false; | 42 return false; |
47 | 43 |
48 GUID format_type = media_type->formattype; | 44 const GUID format_type = media_type->formattype; |
49 if (format_type != FORMAT_VideoInfo) | 45 if (format_type != FORMAT_VideoInfo) |
50 return false; | 46 return false; |
51 | 47 |
52 // Check for the sub types we support. | 48 // Check for the sub types we support. |
53 GUID sub_type = media_type->subtype; | 49 const GUID sub_type = media_type->subtype; |
54 VIDEOINFOHEADER* pvi = | 50 VIDEOINFOHEADER* pvi = |
55 reinterpret_cast<VIDEOINFOHEADER*>(media_type->pbFormat); | 51 reinterpret_cast<VIDEOINFOHEADER*>(media_type->pbFormat); |
56 if (pvi == NULL) | 52 if (pvi == NULL) |
57 return false; | 53 return false; |
58 | 54 |
59 // Store the incoming width and height. | 55 // Store the incoming width and height. |
60 resulting_format_.frame_size.SetSize(pvi->bmiHeader.biWidth, | 56 resulting_format_.frame_size.SetSize(pvi->bmiHeader.biWidth, |
61 abs(pvi->bmiHeader.biHeight)); | 57 abs(pvi->bmiHeader.biHeight)); |
62 if (pvi->AvgTimePerFrame > 0) { | 58 if (pvi->AvgTimePerFrame > 0) { |
63 resulting_format_.frame_rate = | 59 resulting_format_.frame_rate = |
64 static_cast<int>(kSecondsToReferenceTime / pvi->AvgTimePerFrame); | 60 static_cast<int>(kSecondsToReferenceTime / pvi->AvgTimePerFrame); |
65 } else { | 61 } else { |
66 resulting_format_.frame_rate = requested_frame_rate_; | 62 resulting_format_.frame_rate = requested_frame_rate_; |
67 } | 63 } |
68 if (sub_type == kMediaSubTypeI420 && | 64 if (sub_type == kMediaSubTypeI420 && |
69 pvi->bmiHeader.biCompression == MAKEFOURCC('I', '4', '2', '0')) { | 65 pvi->bmiHeader.biCompression == MAKEFOURCC('I', '4', '2', '0')) { |
70 resulting_format_.pixel_format = PIXEL_FORMAT_I420; | 66 resulting_format_.pixel_format = PIXEL_FORMAT_I420; |
71 return true; | 67 return true; |
72 } | 68 } |
73 if (sub_type == MEDIASUBTYPE_YUY2 && | 69 if (sub_type == MEDIASUBTYPE_YUY2 && |
74 pvi->bmiHeader.biCompression == MAKEFOURCC('Y', 'U', 'Y', '2')) { | 70 pvi->bmiHeader.biCompression == MAKEFOURCC('Y', 'U', 'Y', '2')) { |
75 resulting_format_.pixel_format = PIXEL_FORMAT_YUY2; | 71 resulting_format_.pixel_format = PIXEL_FORMAT_YUY2; |
76 return true; | 72 return true; |
77 } | 73 } |
| 74 // This format is added after http:/crbug.com/508413. |
| 75 if (sub_type == MEDIASUBTYPE_UYVY && |
| 76 pvi->bmiHeader.biCompression == MAKEFOURCC('U', 'Y', 'V', 'Y')) { |
| 77 resulting_format_.pixel_format = PIXEL_FORMAT_UYVY; |
| 78 return true; |
| 79 } |
78 if (sub_type == MEDIASUBTYPE_MJPG && | 80 if (sub_type == MEDIASUBTYPE_MJPG && |
79 pvi->bmiHeader.biCompression == MAKEFOURCC('M', 'J', 'P', 'G')) { | 81 pvi->bmiHeader.biCompression == MAKEFOURCC('M', 'J', 'P', 'G')) { |
80 resulting_format_.pixel_format = PIXEL_FORMAT_MJPEG; | 82 resulting_format_.pixel_format = PIXEL_FORMAT_MJPEG; |
81 return true; | 83 return true; |
82 } | 84 } |
83 if (sub_type == MEDIASUBTYPE_RGB24 && | 85 if (sub_type == MEDIASUBTYPE_RGB24 && |
84 pvi->bmiHeader.biCompression == BI_RGB) { | 86 pvi->bmiHeader.biCompression == BI_RGB) { |
85 resulting_format_.pixel_format = PIXEL_FORMAT_RGB24; | 87 resulting_format_.pixel_format = PIXEL_FORMAT_RGB24; |
86 return true; | 88 return true; |
87 } | 89 } |
88 if (sub_type == MEDIASUBTYPE_RGB32 && | 90 if (sub_type == MEDIASUBTYPE_RGB32 && |
89 pvi->bmiHeader.biCompression == BI_RGB) { | 91 pvi->bmiHeader.biCompression == BI_RGB) { |
90 resulting_format_.pixel_format = PIXEL_FORMAT_RGB32; | 92 resulting_format_.pixel_format = PIXEL_FORMAT_RGB32; |
91 return true; | 93 return true; |
92 } | 94 } |
| 95 |
| 96 #ifndef NDEBUG |
| 97 WCHAR guid_str[128]; |
| 98 StringFromGUID2(sub_type, guid_str, arraysize(guid_str)); |
| 99 DVLOG(2) << __FUNCTION__ << " unsupported media type: " << guid_str; |
| 100 #endif |
93 return false; | 101 return false; |
94 } | 102 } |
95 | 103 |
96 bool SinkInputPin::GetValidMediaType(int index, AM_MEDIA_TYPE* media_type) { | 104 bool SinkInputPin::GetValidMediaType(int index, AM_MEDIA_TYPE* media_type) { |
97 if (media_type->cbFormat < sizeof(VIDEOINFOHEADER)) | 105 if (media_type->cbFormat < sizeof(VIDEOINFOHEADER)) |
98 return false; | 106 return false; |
99 | 107 |
100 VIDEOINFOHEADER* pvi = | 108 VIDEOINFOHEADER* const pvi = |
101 reinterpret_cast<VIDEOINFOHEADER*>(media_type->pbFormat); | 109 reinterpret_cast<VIDEOINFOHEADER*>(media_type->pbFormat); |
102 | 110 |
103 ZeroMemory(pvi, sizeof(VIDEOINFOHEADER)); | 111 ZeroMemory(pvi, sizeof(VIDEOINFOHEADER)); |
104 pvi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); | 112 pvi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); |
105 pvi->bmiHeader.biPlanes = 1; | 113 pvi->bmiHeader.biPlanes = 1; |
106 pvi->bmiHeader.biClrImportant = 0; | 114 pvi->bmiHeader.biClrImportant = 0; |
107 pvi->bmiHeader.biClrUsed = 0; | 115 pvi->bmiHeader.biClrUsed = 0; |
108 if (requested_frame_rate_ > 0) { | 116 if (requested_frame_rate_ > 0) |
109 pvi->AvgTimePerFrame = kSecondsToReferenceTime / requested_frame_rate_; | 117 pvi->AvgTimePerFrame = kSecondsToReferenceTime / requested_frame_rate_; |
110 } | |
111 | 118 |
112 media_type->majortype = MEDIATYPE_Video; | 119 media_type->majortype = MEDIATYPE_Video; |
113 media_type->formattype = FORMAT_VideoInfo; | 120 media_type->formattype = FORMAT_VideoInfo; |
114 media_type->bTemporalCompression = FALSE; | 121 media_type->bTemporalCompression = FALSE; |
115 | 122 |
116 if (requested_pixel_format_ == PIXEL_FORMAT_MJPEG) { | 123 if (requested_pixel_format_ == PIXEL_FORMAT_MJPEG) { |
117 // If the requested pixel format is MJPEG, accept only MJPEG. | 124 // If the requested pixel format is MJPEG, accept only MJPEG. |
118 // This is ok since the capabilities of the capturer have been | 125 // This is ok since the capabilities of the capturer have been |
119 // enumerated and we know that it is supported. | 126 // enumerated and we know that it is supported. |
120 if (index != 0) | 127 if (index != 0) |
(...skipping 16 matching lines...) Expand all Loading... |
137 case 1: { | 144 case 1: { |
138 pvi->bmiHeader.biCompression = MAKEFOURCC('Y', 'U', 'Y', '2'); | 145 pvi->bmiHeader.biCompression = MAKEFOURCC('Y', 'U', 'Y', '2'); |
139 pvi->bmiHeader.biBitCount = 16; | 146 pvi->bmiHeader.biBitCount = 16; |
140 pvi->bmiHeader.biWidth = requested_info_header_.biWidth; | 147 pvi->bmiHeader.biWidth = requested_info_header_.biWidth; |
141 pvi->bmiHeader.biHeight = requested_info_header_.biHeight; | 148 pvi->bmiHeader.biHeight = requested_info_header_.biHeight; |
142 pvi->bmiHeader.biSizeImage = GetArea(requested_info_header_) * 2; | 149 pvi->bmiHeader.biSizeImage = GetArea(requested_info_header_) * 2; |
143 media_type->subtype = MEDIASUBTYPE_YUY2; | 150 media_type->subtype = MEDIASUBTYPE_YUY2; |
144 break; | 151 break; |
145 } | 152 } |
146 case 2: { | 153 case 2: { |
| 154 pvi->bmiHeader.biCompression = MAKEFOURCC('U', 'Y', 'V', 'Y'); |
| 155 pvi->bmiHeader.biBitCount = 16; |
| 156 pvi->bmiHeader.biWidth = requested_info_header_.biWidth; |
| 157 pvi->bmiHeader.biHeight = requested_info_header_.biHeight; |
| 158 pvi->bmiHeader.biSizeImage = GetArea(requested_info_header_) * 2; |
| 159 media_type->subtype = MEDIASUBTYPE_UYVY; |
| 160 break; |
| 161 } |
| 162 case 3: { |
147 pvi->bmiHeader.biCompression = BI_RGB; | 163 pvi->bmiHeader.biCompression = BI_RGB; |
148 pvi->bmiHeader.biBitCount = 24; | 164 pvi->bmiHeader.biBitCount = 24; |
149 pvi->bmiHeader.biWidth = requested_info_header_.biWidth; | 165 pvi->bmiHeader.biWidth = requested_info_header_.biWidth; |
150 pvi->bmiHeader.biHeight = requested_info_header_.biHeight; | 166 pvi->bmiHeader.biHeight = requested_info_header_.biHeight; |
151 pvi->bmiHeader.biSizeImage = GetArea(requested_info_header_) * 3; | 167 pvi->bmiHeader.biSizeImage = GetArea(requested_info_header_) * 3; |
152 media_type->subtype = MEDIASUBTYPE_RGB24; | 168 media_type->subtype = MEDIASUBTYPE_RGB24; |
153 break; | 169 break; |
154 } | 170 } |
155 case 3: { | 171 case 4: { |
156 pvi->bmiHeader.biCompression = BI_RGB; | 172 pvi->bmiHeader.biCompression = BI_RGB; |
157 pvi->bmiHeader.biBitCount = 32; | 173 pvi->bmiHeader.biBitCount = 32; |
158 pvi->bmiHeader.biWidth = requested_info_header_.biWidth; | 174 pvi->bmiHeader.biWidth = requested_info_header_.biWidth; |
159 pvi->bmiHeader.biHeight = requested_info_header_.biHeight; | 175 pvi->bmiHeader.biHeight = requested_info_header_.biHeight; |
160 pvi->bmiHeader.biSizeImage = GetArea(requested_info_header_) * 4; | 176 pvi->bmiHeader.biSizeImage = GetArea(requested_info_header_) * 4; |
161 media_type->subtype = MEDIASUBTYPE_RGB32; | 177 media_type->subtype = MEDIASUBTYPE_RGB32; |
162 break; | 178 break; |
163 } | 179 } |
164 default: | 180 default: |
165 return false; | 181 return false; |
(...skipping 17 matching lines...) Expand all Loading... |
183 return S_FALSE; | 199 return S_FALSE; |
184 | 200 |
185 observer_->FrameReceived(buffer, length); | 201 observer_->FrameReceived(buffer, length); |
186 return S_OK; | 202 return S_OK; |
187 } | 203 } |
188 | 204 |
189 SinkInputPin::~SinkInputPin() { | 205 SinkInputPin::~SinkInputPin() { |
190 } | 206 } |
191 | 207 |
192 } // namespace media | 208 } // namespace media |
OLD | NEW |