Chromium Code Reviews| Index: media/video/capture/win/sink_input_pin_win.cc |
| =================================================================== |
| --- media/video/capture/win/sink_input_pin_win.cc (revision 0) |
| +++ media/video/capture/win/sink_input_pin_win.cc (revision 0) |
| @@ -0,0 +1,153 @@ |
| +// Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "media/video/capture/win/sink_input_pin_win.h" |
| + |
| +// Avoid including strsafe.h via dshow as it will cause build warnings. |
| +#define NO_DSHOW_STRSAFE |
| +#include <dshow.h> |
| + |
| +#include "base/logging.h" |
| + |
| +namespace media { |
| + |
| +SinkInputPin::SinkInputPin(IBaseFilter* filter, |
| + SinkFilter::SinkFilterObserver* observer) |
| + : observer_(observer), |
| + PinBase(filter) { |
| +} |
| + |
| +SinkInputPin::~SinkInputPin() { |
| +} |
| + |
| +bool SinkInputPin::GetValidMediaType(int index, AM_MEDIA_TYPE* media_type) { |
| + if (media_type->cbFormat < sizeof(VIDEOINFOHEADER)) { |
|
tommi (sloooow) - chröme
2011/06/23 14:05:56
nit: no need for braces
Per K
2011/06/27 11:47:50
Done.
|
| + return false; |
| + } |
| + VIDEOINFOHEADER* pvi = |
| + reinterpret_cast<VIDEOINFOHEADER*>(media_type->pbFormat); |
| + |
| + ZeroMemory(pvi, sizeof(VIDEOINFOHEADER)); |
| + pvi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); |
| + pvi->bmiHeader.biPlanes = 1; |
| + pvi->bmiHeader.biClrImportant = 0; |
| + pvi->bmiHeader.biClrUsed = 0; |
| + if (requested_capability_.frame_rate > 0) { |
| + pvi->AvgTimePerFrame = kSecondsToReferenceTime / |
| + requested_capability_.frame_rate; |
| + } |
| + |
| + media_type->majortype = MEDIATYPE_Video; |
| + media_type->formattype = FORMAT_VideoInfo; |
| + media_type->bTemporalCompression = FALSE; |
| + |
| + switch (index) { |
| + case 0: { |
|
tommi (sloooow) - chröme
2011/06/23 14:05:56
enum values for the index? Instead of 0,1,2 maybe
Per K
2011/06/27 11:47:50
It called from TypeEnumerator::Next where index is
|
| + pvi->bmiHeader.biCompression = MAKEFOURCC('I', '4', '2', '0'); |
| + pvi->bmiHeader.biBitCount = 12; // bit per pixel |
| + pvi->bmiHeader.biWidth = requested_capability_.width; |
| + pvi->bmiHeader.biHeight = requested_capability_.height; |
| + pvi->bmiHeader.biSizeImage = 3 * requested_capability_.height * |
| + requested_capability_.width / 2; |
| + media_type->subtype = kMediaSubTypeI420; |
| + break; |
| + } |
| + case 1: { |
| + pvi->bmiHeader.biCompression = MAKEFOURCC('Y', 'U', 'Y', '2'); |
| + pvi->bmiHeader.biBitCount = 16; |
| + pvi->bmiHeader.biWidth = requested_capability_.width; |
| + pvi->bmiHeader.biHeight = requested_capability_.height; |
| + pvi->bmiHeader.biSizeImage = 2 * requested_capability_.width * |
| + requested_capability_.height; |
| + media_type->subtype = MEDIASUBTYPE_YUY2; |
| + break; |
| + } |
| + case 2: { |
| + pvi->bmiHeader.biCompression = BI_RGB; |
| + pvi->bmiHeader.biBitCount = 24; |
| + pvi->bmiHeader.biWidth = requested_capability_.width; |
| + pvi->bmiHeader.biHeight = requested_capability_.height; |
| + pvi->bmiHeader.biSizeImage = 3 * requested_capability_.height * |
| + requested_capability_.width; |
| + media_type->subtype = MEDIASUBTYPE_RGB24; |
| + break; |
| + } |
| + default: |
| + return false; |
| + } |
| + |
| + media_type->bFixedSizeSamples = TRUE; |
| + media_type->lSampleSize = pvi->bmiHeader.biSizeImage; |
| + return true; |
| +} |
| + |
| +bool SinkInputPin::IsMediaTypeValid(const AM_MEDIA_TYPE* media_type) { |
| + GUID type = media_type->majortype; |
| + if (type != MEDIATYPE_Video) { |
| + return false; |
| + } |
| + GUID format_type = media_type->formattype; |
| + |
| + // Check for the sub types we support. |
| + GUID sub_type = media_type->subtype; |
| + |
| + if (format_type == FORMAT_VideoInfo) { |
| + VIDEOINFOHEADER* pvi = |
| + reinterpret_cast<VIDEOINFOHEADER*>(media_type->pbFormat); |
|
tommi (sloooow) - chröme
2011/06/23 14:05:56
indent
Per K
2011/06/27 11:47:50
Done.
|
| + if (pvi == NULL) { |
| + return false; |
| + } |
| + |
| + // Store the incoming width and height. |
| + resulting_capability_.width = pvi->bmiHeader.biWidth; |
| + resulting_capability_.height = abs(pvi->bmiHeader.biHeight); |
| + if (pvi->AvgTimePerFrame > 0) { |
| + resulting_capability_.frame_rate = |
| + static_cast<int>(kSecondsToReferenceTime / pvi->AvgTimePerFrame); |
| + } else { |
| + resulting_capability_.frame_rate = requested_capability_.frame_rate; |
| + } |
| + if (sub_type == kMediaSubTypeI420 && |
| + pvi->bmiHeader.biCompression == MAKEFOURCC('I', '4', '2', '0')) { |
| + resulting_capability_.color = VideoCaptureDevice::kI420; |
| + return true; // This format is acceptable. |
| + } |
| + if (sub_type == MEDIASUBTYPE_YUY2 && |
| + pvi->bmiHeader.biCompression == MAKEFOURCC('Y', 'U', 'Y', '2')) { |
| + resulting_capability_.color = VideoCaptureDevice::kYUY2; |
| + ::Sleep(60); // Workaround for bad driver. |
|
tommi (sloooow) - chröme
2011/06/23 14:05:56
is this a driver that's always installed or a 3rd
Per K
2011/06/27 11:47:50
This is an old fix that we unfortunately are not s
|
| + return true; // This format is acceptable. |
| + } |
| + if (sub_type == MEDIASUBTYPE_RGB24 && |
| + pvi->bmiHeader.biCompression == BI_RGB) { |
| + resulting_capability_.color = VideoCaptureDevice::kRGB24; |
| + return true; // This format is acceptable. |
| + } |
| + } |
| + return false; |
| +} |
| + |
| +HRESULT SinkInputPin::Receive(IMediaSample* media_sample) { |
| + DCHECK(media_sample); |
| + const int length = media_sample->GetActualDataLength(); |
| + uint8* buffer = NULL; |
| + if (FAILED(media_sample->GetPointer(&buffer))) { |
| + return S_FALSE; |
| + } |
| + observer_->FrameReceived(buffer, length); |
| + |
| + return S_OK; |
| +} |
| + |
| +void SinkInputPin::SetRequestedMediaCapability( |
| + const VideoCaptureDevice::Capability& capability) { |
| + requested_capability_ = capability; |
| + resulting_capability_ = VideoCaptureDevice::Capability(); |
| +} |
| + |
| +const VideoCaptureDevice::Capability& SinkInputPin::ResultingCapability() { |
| + return resulting_capability_; |
| +} |
| + |
| +} // namespace media |