summaryrefslogtreecommitdiffstats
path: root/src/plugins/directshow/camera/dscamerasession.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/directshow/camera/dscamerasession.cpp')
-rw-r--r--src/plugins/directshow/camera/dscamerasession.cpp1160
1 files changed, 0 insertions, 1160 deletions
diff --git a/src/plugins/directshow/camera/dscamerasession.cpp b/src/plugins/directshow/camera/dscamerasession.cpp
deleted file mode 100644
index 073bc60..0000000
--- a/src/plugins/directshow/camera/dscamerasession.cpp
+++ /dev/null
@@ -1,1160 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtCore/qdebug.h>
-#include <QWidget>
-#include <QFile>
-#include <QtMultimedia/qabstractvideobuffer.h>
-#include <QtMultimedia/qvideosurfaceformat.h>
-
-#include "dscamerasession.h"
-#include "dsvideorenderer.h"
-#include "directshowglobal.h"
-
-QT_BEGIN_NAMESPACE
-
-// If frames come in quicker than we display them, we allow the queue to build
-// up to this number before we start dropping them.
-const int LIMIT_FRAME = 5;
-
-namespace {
-// DirectShow helper implementation
-void _FreeMediaType(AM_MEDIA_TYPE& mt)
-{
- if (mt.cbFormat != 0) {
- CoTaskMemFree((PVOID)mt.pbFormat);
- mt.cbFormat = 0;
- mt.pbFormat = NULL;
- }
- if (mt.pUnk != NULL) {
- // pUnk should not be used.
- mt.pUnk->Release();
- mt.pUnk = NULL;
- }
-}
-
-} // end namespace
-
-class SampleGrabberCallbackPrivate : public ISampleGrabberCB
-{
-public:
- STDMETHODIMP_(ULONG) AddRef() { return 1; }
- STDMETHODIMP_(ULONG) Release() { return 2; }
-
- STDMETHODIMP QueryInterface(REFIID riid, void **ppvObject)
- {
- if (NULL == ppvObject)
- return E_POINTER;
- if (riid == IID_IUnknown /*__uuidof(IUnknown) */ ) {
- *ppvObject = static_cast<IUnknown*>(this);
- return S_OK;
- }
- if (riid == IID_ISampleGrabberCB /*__uuidof(ISampleGrabberCB)*/ ) {
- *ppvObject = static_cast<ISampleGrabberCB*>(this);
- return S_OK;
- }
- return E_NOTIMPL;
- }
-
- STDMETHODIMP SampleCB(double Time, IMediaSample *pSample)
- {
- return E_NOTIMPL;
- }
-
- STDMETHODIMP BufferCB(double Time, BYTE *pBuffer, long BufferLen)
- {
- if (!cs || active) {
- return S_OK;
- }
-
- if ((cs->StillMediaType.majortype != MEDIATYPE_Video) ||
- (cs->StillMediaType.formattype != FORMAT_VideoInfo) ||
- (cs->StillMediaType.cbFormat < sizeof(VIDEOINFOHEADER))) {
- return VFW_E_INVALIDMEDIATYPE;
- }
-
- active = true;
-
- if(toggle == true) {
- toggle = false;
- }
- else {
- toggle = true;
- }
-
- if(toggle) {
- active = false;
- return S_OK;
- }
-
- bool check = false;
- cs->mutex.lock();
-
- if (cs->frames.size() > LIMIT_FRAME) {
- check = true;
- }
-
- if (check) {
- cs->mutex.unlock();
- // Frames building up. We're going to drop some here
- Sleep(100);
- active = false;
- return S_OK;
- }
- cs->mutex.unlock();
-
- unsigned char* vidData = new unsigned char[BufferLen];
- memcpy(vidData, pBuffer, BufferLen);
-
- cs->mutex.lock();
-
- video_buffer* buf = new video_buffer;
- buf->buffer = vidData;
- buf->length = BufferLen;
- buf->time = (qint64)Time;
-
- cs->frames.append(buf);
-
- cs->mutex.unlock();
-
- QMetaObject::invokeMethod(cs, "captureFrame", Qt::QueuedConnection);
-
- active = false;
-
- return S_OK;
- }
-
- DSCameraSession* cs;
- bool active;
- bool toggle;
-};
-
-
-DSCameraSession::DSCameraSession(QObject *parent)
- : QObject(parent)
- ,m_currentImageId(0)
-{
- pBuild = NULL;
- pGraph = NULL;
- pCap = NULL;
- pSG_Filter = NULL;
- pSG = NULL;
-
- opened = false;
- available = false;
- resolutions.clear();
- m_state = QCamera::UnloadedState;
- m_device = "default";
-
- StillCapCB = new SampleGrabberCallbackPrivate;
- StillCapCB->cs = this;
- StillCapCB->active = false;
- StillCapCB->toggle = false;
-
- m_output = 0;
- m_surface = 0;
- m_windowSize = QSize(320,240);
- pixelF = QVideoFrame::Format_RGB24;
- actualFormat = QVideoSurfaceFormat(m_windowSize,pixelF);
-
- graph = false;
- active = false;
-
- ::CoInitialize(NULL);
-}
-
-DSCameraSession::~DSCameraSession()
-{
- if (opened) {
- closeStream();
- }
-
- CoUninitialize();
-
- SAFE_RELEASE(pCap);
- SAFE_RELEASE(pSG_Filter);
- SAFE_RELEASE(pGraph);
- SAFE_RELEASE(pBuild);
-
- if (StillCapCB) {
- delete StillCapCB;
- }
-}
-
-int DSCameraSession::captureImage(const QString &fileName)
-{
- emit readyForCaptureChanged(false);
-
- // We're going to do this in one big synchronous call
- m_currentImageId++;
- if (fileName.isEmpty()) {
- m_snapshot = "img.jpg";
- } else {
- m_snapshot = fileName;
- }
-
- if (!active) {
- startStream();
- }
-
- return m_currentImageId;
-}
-
-void DSCameraSession::setSurface(QAbstractVideoSurface* surface)
-{
- m_surface = surface;
-}
-
-bool DSCameraSession::deviceReady()
-{
- return available;
-}
-
-bool DSCameraSession::pictureInProgress()
-{
- return m_snapshot.isEmpty();
-}
-
-int DSCameraSession::framerate() const
-{
- return -1;
-}
-
-void DSCameraSession::setFrameRate(int rate)
-{
- Q_UNUSED(rate)
-}
-
-int DSCameraSession::brightness() const
-{
- return -1;
-}
-
-void DSCameraSession::setBrightness(int b)
-{
- Q_UNUSED(b)
-}
-
-int DSCameraSession::contrast() const
-{
- return -1;
-}
-
-void DSCameraSession::setContrast(int c)
-{
- Q_UNUSED(c)
-}
-
-int DSCameraSession::saturation() const
-{
- return -1;
-}
-
-void DSCameraSession::setSaturation(int s)
-{
- Q_UNUSED(s)
-}
-
-int DSCameraSession::hue() const
-{
- return -1;
-}
-
-void DSCameraSession::setHue(int h)
-{
- Q_UNUSED(h)
-}
-
-int DSCameraSession::sharpness() const
-{
- return -1;
-}
-
-void DSCameraSession::setSharpness(int s)
-{
- Q_UNUSED(s)
-}
-
-int DSCameraSession::zoom() const
-{
- return -1;
-}
-
-void DSCameraSession::setZoom(int z)
-{
- Q_UNUSED(z)
-}
-
-bool DSCameraSession::backlightCompensation() const
-{
- return false;
-}
-
-void DSCameraSession::setBacklightCompensation(bool b)
-{
- Q_UNUSED(b)
-}
-
-int DSCameraSession::whitelevel() const
-{
- return -1;
-}
-
-void DSCameraSession::setWhitelevel(int w)
-{
- Q_UNUSED(w)
-}
-
-int DSCameraSession::rotation() const
-{
- return 0;
-}
-
-void DSCameraSession::setRotation(int r)
-{
- Q_UNUSED(r)
-}
-
-bool DSCameraSession::flash() const
-{
- return false;
-}
-
-void DSCameraSession::setFlash(bool f)
-{
- Q_UNUSED(f)
-}
-
-bool DSCameraSession::autofocus() const
-{
- return false;
-}
-
-void DSCameraSession::setAutofocus(bool f)
-{
- Q_UNUSED(f)
-}
-
-QSize DSCameraSession::frameSize() const
-{
- return m_windowSize;
-}
-
-void DSCameraSession::setFrameSize(const QSize& s)
-{
- if (supportedResolutions(pixelF).contains(s))
- m_windowSize = s;
- else
- qWarning() << "frame size if not supported for current pixel format, no change";
-}
-
-void DSCameraSession::setDevice(const QString &device)
-{
- if(opened)
- stopStream();
-
- if(graph) {
- SAFE_RELEASE(pCap);
- SAFE_RELEASE(pSG_Filter);
- SAFE_RELEASE(pGraph);
- SAFE_RELEASE(pBuild);
- }
-
- available = false;
- m_state = QCamera::LoadedState;
-
- CoInitialize(NULL);
-
- ICreateDevEnum* pDevEnum = NULL;
- IEnumMoniker* pEnum = NULL;
-
- // Create the System device enumerator
- HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,
- CLSCTX_INPROC_SERVER, IID_ICreateDevEnum,
- reinterpret_cast<void**>(&pDevEnum));
- if(SUCCEEDED(hr)) {
- // Create the enumerator for the video capture category
- hr = pDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnum, 0);
- if (S_OK == hr) {
- pEnum->Reset();
- // go through and find all video capture devices
- IMoniker* pMoniker = NULL;
- while(pEnum->Next(1, &pMoniker, NULL) == S_OK) {
- IPropertyBag *pPropBag;
- hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag,
- (void**)(&pPropBag));
- if(FAILED(hr)) {
- pMoniker->Release();
- continue; // skip this one
- }
- // Find the description
- WCHAR str[120];
- VARIANT varName;
- varName.vt = VT_BSTR;
- hr = pPropBag->Read(L"Description", &varName, 0);
- if(FAILED(hr))
- hr = pPropBag->Read(L"FriendlyName", &varName, 0);
- if(SUCCEEDED(hr)) {
- wcsncpy(str, varName.bstrVal, sizeof(str)/sizeof(str[0]));
- QString temp(QString::fromUtf16((unsigned short*)str));
- if(temp.contains(device)) {
- available = true;
- }
- }
- pPropBag->Release();
- pMoniker->Release();
- }
- pEnum->Release();
- }
- pDevEnum->Release();
- }
- CoUninitialize();
-
- if(available) {
- m_device = QByteArray(device.toLocal8Bit().constData());
- graph = createFilterGraph();
- if(!graph)
- available = false;
- }
-}
-
-QList<QVideoFrame::PixelFormat> DSCameraSession::supportedPixelFormats()
-{
- return types;
-}
-
-QVideoFrame::PixelFormat DSCameraSession::pixelFormat() const
-{
- return pixelF;
-}
-
-void DSCameraSession::setPixelFormat(QVideoFrame::PixelFormat fmt)
-{
- pixelF = fmt;
-}
-
-QList<QSize> DSCameraSession::supportedResolutions(QVideoFrame::PixelFormat format)
-{
- if (!resolutions.contains(format))
- return QList<QSize>();
- return resolutions.value(format);
-}
-
-bool DSCameraSession::setOutputLocation(const QUrl &sink)
-{
- m_sink = sink;
-
- return true;
-}
-
-QUrl DSCameraSession::outputLocation() const
-{
- return m_sink;
-}
-
-qint64 DSCameraSession::position() const
-{
- return timeStamp.elapsed();
-}
-
-int DSCameraSession::state() const
-{
- return int(m_state);
-}
-
-void DSCameraSession::record()
-{
- if(opened) {
- return;
- }
-
- if(m_surface) {
- bool match = false;
-
- if (!m_surface->isFormatSupported(actualFormat)) {
- QList<QVideoFrame::PixelFormat> fmts;
- foreach(QVideoFrame::PixelFormat f, types) {
- if (fmts.contains(f)) {
- match = true;
- pixelF = f;
- actualFormat = QVideoSurfaceFormat(m_windowSize,pixelF);
- break;
- }
- }
- }
- if (!m_surface->isFormatSupported(actualFormat) && !match) {
- // fallback
- if (types.contains(QVideoFrame::Format_RGB24)) {
- // get RGB24 from camera and convert to RGB32 for surface!
- pixelF = QVideoFrame::Format_RGB32;
- actualFormat = QVideoSurfaceFormat(m_windowSize,pixelF);
- }
- }
-
- if (m_surface->isFormatSupported(actualFormat)) {
- m_surface->start(actualFormat);
- m_state = QCamera::ActiveState;
- emit stateChanged(QCamera::ActiveState);
- } else {
- qWarning() << "surface doesn't support camera format, cant start";
- m_state = QCamera::LoadedState;
- emit stateChanged(QCamera::LoadedState);
- return;
- }
- } else {
- qWarning() << "no video surface, cant start";
- m_state = QCamera::LoadedState;
- emit stateChanged(QCamera::LoadedState);
- return;
- }
-
- opened = startStream();
-
- if (!opened) {
- qWarning() << "Stream did not open";
- m_state = QCamera::LoadedState;
- emit stateChanged(QCamera::LoadedState);
- }
-}
-
-void DSCameraSession::pause()
-{
- suspendStream();
-}
-
-void DSCameraSession::stop()
-{
- if(!opened) {
- return;
- }
-
- stopStream();
- opened = false;
- m_state = QCamera::LoadedState;
- emit stateChanged(QCamera::LoadedState);
-}
-
-void DSCameraSession::captureFrame()
-{
- if(m_surface && frames.count() > 0) {
-
- QImage image;
-
- if(pixelF == QVideoFrame::Format_RGB24) {
-
- mutex.lock();
-
- image = QImage(frames.at(0)->buffer,m_windowSize.width(),m_windowSize.height(),
- QImage::Format_RGB888).rgbSwapped().mirrored(true);
-
- QVideoFrame frame(image);
- frame.setStartTime(frames.at(0)->time);
-
- mutex.unlock();
-
- m_surface->present(frame);
-
- } else if (pixelF == QVideoFrame::Format_RGB32) {
-
- mutex.lock();
-
- image = QImage(frames.at(0)->buffer,m_windowSize.width(),m_windowSize.height(),
- QImage::Format_RGB888).rgbSwapped().mirrored(true);
-
- QVideoFrame frame(image.convertToFormat(QImage::Format_RGB32));
- frame.setStartTime(frames.at(0)->time);
-
- mutex.unlock();
-
- m_surface->present(frame);
-
- } else {
- qWarning() << "TODO:captureFrame() format =" << pixelF;
- }
-
- if (m_snapshot.length() > 0) {
- emit imageCaptured(m_currentImageId, image);
- image.save(m_snapshot,"JPG");
- emit imageSaved(m_currentImageId, m_snapshot);
- m_snapshot.clear();
- emit readyForCaptureChanged(true);
- }
-
- mutex.lock();
- if (frames.isEmpty()) {
- qWarning() << "Frames over-run";
- }
-
- video_buffer* buf = frames.takeFirst();
- delete buf->buffer;
- delete buf;
- mutex.unlock();
- }
-}
-
-HRESULT DSCameraSession::getPin(IBaseFilter *pFilter, PIN_DIRECTION PinDir, IPin **ppPin)
-{
- *ppPin = 0;
- IEnumPins *pEnum = 0;
- IPin *pPin = 0;
-
- HRESULT hr = pFilter->EnumPins(&pEnum);
- if(FAILED(hr)) {
- return hr;
- }
-
- pEnum->Reset();
- while(pEnum->Next(1, &pPin, NULL) == S_OK) {
- PIN_DIRECTION ThisPinDir;
- pPin->QueryDirection(&ThisPinDir);
- if(ThisPinDir == PinDir) {
- pEnum->Release();
- *ppPin = pPin;
- return S_OK;
- }
- pEnum->Release();
- }
- pEnum->Release();
- return E_FAIL;
-}
-
-bool DSCameraSession::createFilterGraph()
-{
- HRESULT hr;
- IMoniker* pMoniker = NULL;
- ICreateDevEnum* pDevEnum = NULL;
- IEnumMoniker* pEnum = NULL;
-
- CoInitialize(NULL);
-
- // Create the filter graph
- hr = CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC,
- IID_IGraphBuilder, (void**)&pGraph);
- if (FAILED(hr)) {
- qWarning()<<"failed to create filter graph";
- return false;
- }
-
- // Create the capture graph builder
- hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC,
- IID_ICaptureGraphBuilder2, (void**)&pBuild);
- if (FAILED(hr)) {
- qWarning()<<"failed to create graph builder";
- return false;
- }
-
- // Attach the filter graph to the capture graph
- hr = pBuild->SetFiltergraph(pGraph);
- if (FAILED(hr)) {
- qWarning()<<"failed to connect capture graph and filter graph";
- return false;
- }
-
- // Find the Capture device
- hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,
- CLSCTX_INPROC_SERVER, IID_ICreateDevEnum,
- reinterpret_cast<void**>(&pDevEnum));
- if (SUCCEEDED(hr)) {
- // Create an enumerator for the video capture category
- hr = pDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnum, 0);
- pDevEnum->Release();
- if (S_OK == hr) {
- pEnum->Reset();
- //go through and find all video capture devices
- while (pEnum->Next(1, &pMoniker, NULL) == S_OK) {
- IPropertyBag *pPropBag;
- hr = pMoniker->BindToStorage(0, 0,
- IID_IPropertyBag, (void**)(&pPropBag));
- if(FAILED(hr)) {
- pMoniker->Release();
- continue; // skip this one
- }
- // Find the description
- WCHAR str[120];
- VARIANT varName;
- varName.vt = VT_BSTR;
- hr = pPropBag->Read(L"FriendlyName", &varName, 0);
- if (SUCCEEDED(hr)) {
- // check if it is the selected device
- wcsncpy(str, varName.bstrVal, sizeof(str)/sizeof(str[0]));
- QString output = QString::fromUtf16((unsigned short*)str);
- if (m_device.contains(output.toLocal8Bit().constData())) {
- hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&pCap);
- if (SUCCEEDED(hr)) {
- pPropBag->Release();
- pMoniker->Release();
- break;
- }
- }
- }
- pPropBag->Release();
- pMoniker->Release();
- }
- if (NULL == pCap)
- {
- if (m_device.contains("default"))
- {
- pEnum->Reset();
- // still have to loop to discard bind to storage failure case
- while (pEnum->Next(1, &pMoniker, NULL) == S_OK) {
- IPropertyBag *pPropBag = 0;
-
- hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void**)(&pPropBag));
- if (FAILED(hr)) {
- pMoniker->Release();
- continue; // Don't panic yet
- }
-
- // No need to get the description, just grab it
-
- hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&pCap);
- pPropBag->Release();
- pMoniker->Release();
- if (SUCCEEDED(hr)) {
- break; // done, stop looping through
- }
- else
- {
- qWarning() << "Object bind failed";
- }
- }
- }
- }
- pEnum->Release();
- }
- }
-
- // Sample grabber filter
- hr = CoCreateInstance(CLSID_SampleGrabber, NULL,CLSCTX_INPROC,
- IID_IBaseFilter, (void**)&pSG_Filter);
- if (FAILED(hr)) {
- qWarning() << "failed to create sample grabber";
- return false;
- }
-
- pSG_Filter->QueryInterface(IID_ISampleGrabber, (void**)&pSG);
- if (FAILED(hr)) {
- qWarning() << "failed to get sample grabber";
- return false;
- }
- pSG->SetOneShot(FALSE);
- pSG->SetBufferSamples(TRUE);
- pSG->SetCallback(StillCapCB, 1);
-
- CoUninitialize();
-
- return true;
-}
-
-void DSCameraSession::updateProperties()
-{
- HRESULT hr;
- AM_MEDIA_TYPE *pmt = NULL;
- VIDEOINFOHEADER *pvi = NULL;
- VIDEO_STREAM_CONFIG_CAPS scc;
- IAMStreamConfig* pConfig = 0;
-
- hr = pBuild->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,pCap,
- IID_IAMStreamConfig, (void**)&pConfig);
- if (FAILED(hr)) {
- qWarning()<<"failed to get config on capture device";
- return;
- }
-
- int iCount;
- int iSize;
- hr = pConfig->GetNumberOfCapabilities(&iCount, &iSize);
- if (FAILED(hr)) {
- qWarning()<<"failed to get capabilities";
- return;
- }
-
- QList<QSize> sizes;
- QVideoFrame::PixelFormat f = QVideoFrame::Format_Invalid;
-
- types.clear();
- resolutions.clear();
-
- for (int iIndex = 0; iIndex < iCount; iIndex++) {
- hr = pConfig->GetStreamCaps(iIndex, &pmt, reinterpret_cast<BYTE*>(&scc));
- if (hr == S_OK) {
- pvi = (VIDEOINFOHEADER*)pmt->pbFormat;
- if ((pmt->majortype == MEDIATYPE_Video) &&
- (pmt->formattype == FORMAT_VideoInfo)) {
- // Add types
- if (pmt->subtype == MEDIASUBTYPE_RGB24) {
- if (!types.contains(QVideoFrame::Format_RGB24)) {
- types.append(QVideoFrame::Format_RGB24);
- f = QVideoFrame::Format_RGB24;
- }
- } else if (pmt->subtype == MEDIASUBTYPE_RGB32) {
- if (!types.contains(QVideoFrame::Format_RGB32)) {
- types.append(QVideoFrame::Format_RGB32);
- f = QVideoFrame::Format_RGB32;
- }
- } else if (pmt->subtype == MEDIASUBTYPE_YUY2) {
- if (!types.contains(QVideoFrame::Format_YUYV)) {
- types.append(QVideoFrame::Format_YUYV);
- f = QVideoFrame::Format_YUYV;
- }
- } else if (pmt->subtype == MEDIASUBTYPE_MJPG) {
- } else if (pmt->subtype == MEDIASUBTYPE_I420) {
- if (!types.contains(QVideoFrame::Format_YUV420P)) {
- types.append(QVideoFrame::Format_YUV420P);
- f = QVideoFrame::Format_YUV420P;
- }
- } else if (pmt->subtype == MEDIASUBTYPE_RGB555) {
- if (!types.contains(QVideoFrame::Format_RGB555)) {
- types.append(QVideoFrame::Format_RGB555);
- f = QVideoFrame::Format_RGB555;
- }
- } else if (pmt->subtype == MEDIASUBTYPE_YVU9) {
- } else if (pmt->subtype == MEDIASUBTYPE_UYVY) {
- if (!types.contains(QVideoFrame::Format_UYVY)) {
- types.append(QVideoFrame::Format_UYVY);
- f = QVideoFrame::Format_UYVY;
- }
- } else {
- qWarning() << "UNKNOWN FORMAT: " << pmt->subtype.Data1;
- }
- // Add resolutions
- QSize res(pvi->bmiHeader.biWidth, pvi->bmiHeader.biHeight);
- if (!resolutions.contains(f)) {
- sizes.clear();
- resolutions.insert(f,sizes);
- }
- resolutions[f].append(res);
- }
- }
- }
- pConfig->Release();
-}
-
-bool DSCameraSession::setProperties()
-{
- CoInitialize(NULL);
-
- HRESULT hr;
- AM_MEDIA_TYPE am_media_type;
- AM_MEDIA_TYPE *pmt = NULL;
- VIDEOINFOHEADER *pvi = NULL;
- VIDEO_STREAM_CONFIG_CAPS scc;
-
- IAMStreamConfig* pConfig = 0;
- hr = pBuild->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, pCap,
- IID_IAMStreamConfig, (void**)&pConfig);
- if(FAILED(hr)) {
- qWarning()<<"failed to get config on capture device";
- return false;
- }
-
- int iCount;
- int iSize;
- hr = pConfig->GetNumberOfCapabilities(&iCount, &iSize);
- if(FAILED(hr)) {
- qWarning()<<"failed to get capabilities";
- return false;
- }
-
- bool setFormatOK = false;
- for (int iIndex = 0; iIndex < iCount; iIndex++) {
- hr = pConfig->GetStreamCaps(iIndex, &pmt, reinterpret_cast<BYTE*>(&scc));
- if (hr == S_OK) {
- pvi = (VIDEOINFOHEADER*)pmt->pbFormat;
-
- if ((pmt->majortype == MEDIATYPE_Video) &&
- (pmt->formattype == FORMAT_VideoInfo)) {
- if ((actualFormat.frameWidth() == pvi->bmiHeader.biWidth) &&
- (actualFormat.frameHeight() == pvi->bmiHeader.biHeight)) {
- hr = pConfig->SetFormat(pmt);
- _FreeMediaType(*pmt);
- if(FAILED(hr)) {
- qWarning()<<"failed to set format:" << hr;
- qWarning()<<"but going to continue";
- continue; // We going to continue
- } else {
- setFormatOK = true;
- break;
- }
- }
- }
- }
- }
- pConfig->Release();
-
- if (!setFormatOK) {
- qWarning() << "unable to set any format for camera";
- return false;
- }
-
- // Set Sample Grabber config to match capture
- ZeroMemory(&am_media_type, sizeof(am_media_type));
- am_media_type.majortype = MEDIATYPE_Video;
-
- if (actualFormat.pixelFormat() == QVideoFrame::Format_RGB32)
- am_media_type.subtype = MEDIASUBTYPE_RGB24;
- else if (actualFormat.pixelFormat() == QVideoFrame::Format_RGB24)
- am_media_type.subtype = MEDIASUBTYPE_RGB24;
- else if (actualFormat.pixelFormat() == QVideoFrame::Format_YUYV)
- am_media_type.subtype = MEDIASUBTYPE_YUY2;
- else if (actualFormat.pixelFormat() == QVideoFrame::Format_YUV420P)
- am_media_type.subtype = MEDIASUBTYPE_I420;
- else if (actualFormat.pixelFormat() == QVideoFrame::Format_RGB555)
- am_media_type.subtype = MEDIASUBTYPE_RGB555;
- else if (actualFormat.pixelFormat() == QVideoFrame::Format_UYVY)
- am_media_type.subtype = MEDIASUBTYPE_UYVY;
- else {
- qWarning()<<"unknown format? for SG";
- return false;
- }
-
- am_media_type.formattype = FORMAT_VideoInfo;
- hr = pSG->SetMediaType(&am_media_type);
- if (FAILED(hr)) {
- qWarning()<<"failed to set video format on grabber";
- return false;
- }
-
- pSG->GetConnectedMediaType(&StillMediaType);
-
- CoUninitialize();
-
- return true;
-}
-
-bool DSCameraSession::openStream()
-{
- //Opens the stream for reading and allocates any necessary resources needed
- //Return true if success, false otherwise
-
- if (opened) {
- return true;
- }
-
- if (!graph) {
- graph = createFilterGraph();
- if(!graph) {
- qWarning()<<"failed to create filter graph in openStream";
- return false;
- }
- }
-
- CoInitialize(NULL);
-
- HRESULT hr;
-
- hr = pGraph->AddFilter(pCap, L"Capture Filter");
- if (FAILED(hr)) {
- qWarning()<<"failed to create capture filter";
- return false;
- }
-
- hr = pGraph->AddFilter(pSG_Filter, L"Sample Grabber");
- if (FAILED(hr)) {
- qWarning()<<"failed to add sample grabber";
- return false;
- }
-
- hr = pBuild->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,
- pCap, NULL, pSG_Filter);
- if (FAILED(hr)) {
- qWarning() << "failed to renderstream" << hr;
- return false;
- }
- pSG->GetConnectedMediaType(&StillMediaType);
- pSG_Filter->Release();
-
- CoUninitialize();
-
- return true;
-}
-
-void DSCameraSession::closeStream()
-{
- // Closes the stream and internally frees any resources used
- HRESULT hr;
- IMediaControl* pControl = 0;
-
- hr = pGraph->QueryInterface(IID_IMediaControl,(void**)&pControl);
- if (FAILED(hr)) {
- qWarning()<<"failed to get stream control";
- return;
- }
-
- hr = pControl->StopWhenReady();
- if (FAILED(hr)) {
- qWarning()<<"failed to stop";
- pControl->Release();
- return;
- }
-
- pControl->Release();
-
- opened = false;
- IPin *pPin = 0;
-
- if (pCap)
- {
- hr = getPin(pCap, PINDIR_OUTPUT, &pPin);
- if(FAILED(hr)) {
- qWarning()<<"failed to disconnect capture filter";
- return;
- }
- }
-
- pGraph->Disconnect(pPin);
- if (FAILED(hr)) {
- qWarning()<<"failed to disconnect grabber filter";
- return;
- }
-
- hr = getPin(pSG_Filter,PINDIR_INPUT,&pPin);
- pGraph->Disconnect(pPin);
- pGraph->RemoveFilter(pSG_Filter);
- pGraph->RemoveFilter(pCap);
-
- SAFE_RELEASE(pCap);
- SAFE_RELEASE(pSG_Filter);
- SAFE_RELEASE(pGraph);
- SAFE_RELEASE(pBuild);
-
- graph = false;
-}
-
-bool DSCameraSession::startStream()
-{
- // Starts the stream, by emitting either QVideoPackets
- // or QvideoFrames, depending on Format chosen
- if (!graph)
- graph = createFilterGraph();
-
- if (!setProperties()) {
- qWarning() << "Couldn't set properties (retrying)";
- closeStream();
- if (!openStream()) {
- qWarning() << "Retry to open strean failed";
- return false;
- }
- }
-
- if (!opened) {
- opened = openStream();
- if (!opened) {
- qWarning() << "failed to openStream()";
- return false;
- }
- }
-
- HRESULT hr;
- IMediaControl* pControl = 0;
-
- hr = pGraph->QueryInterface(IID_IMediaControl, (void**)&pControl);
- if (FAILED(hr)) {
- qWarning() << "failed to get stream control";
- return false;
- }
-
- hr = pControl->Run();
- pControl->Release();
-
- if (FAILED(hr)) {
- qWarning() << "failed to start";
- return false;
- }
- active = true;
- return true;
-}
-
-void DSCameraSession::stopStream()
-{
- // Stops the stream from emitting packets
- HRESULT hr;
-
- IMediaControl* pControl = 0;
- hr = pGraph->QueryInterface(IID_IMediaControl, (void**)&pControl);
- if (FAILED(hr)) {
- qWarning() << "failed to get stream control";
- return;
- }
-
- hr = pControl->Stop();
- pControl->Release();
- if (FAILED(hr)) {
- qWarning() << "failed to stop";
- return;
- }
- active = false;
-
- if (opened) {
- closeStream();
- }
-}
-
-void DSCameraSession::suspendStream()
-{
- // Pauses the stream
- HRESULT hr;
-
- IMediaControl* pControl = 0;
- hr = pGraph->QueryInterface(IID_IMediaControl, (void**)&pControl);
- if (FAILED(hr)) {
- qWarning() << "failed to get stream control";
- return;
- }
-
- hr = pControl->Pause();
- pControl->Release();
- if (FAILED(hr)) {
- qWarning() << "failed to pause";
- return;
- }
-
- active = false;
-}
-
-void DSCameraSession::resumeStream()
-{
- // Resumes a paused stream
- startStream();
-}
-
-QT_END_NAMESPACE
-