src/3rdparty/phonon/ds9/qasyncreader.cpp
changeset 0 1918ee327afb
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /*  This file is part of the KDE project.
       
     2 
       
     3 Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 
       
     5 This library is free software: you can redistribute it and/or modify
       
     6 it under the terms of the GNU Lesser General Public License as published by
       
     7 the Free Software Foundation, either version 2.1 or 3 of the License.
       
     8 
       
     9 This library is distributed in the hope that it will be useful,
       
    10 but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       
    12 GNU Lesser General Public License for more details.
       
    13 
       
    14 You should have received a copy of the GNU Lesser General Public License
       
    15 along with this library.  If not, see <http://www.gnu.org/licenses/>.
       
    16 */
       
    17 
       
    18 #include "qasyncreader.h"
       
    19 #include "qbasefilter.h"
       
    20 
       
    21 QT_BEGIN_NAMESPACE
       
    22 
       
    23 namespace Phonon
       
    24 {
       
    25     namespace DS9
       
    26     {
       
    27         QAsyncReader::QAsyncReader(QBaseFilter *parent, const QVector<AM_MEDIA_TYPE> &mediaTypes) : QPin(parent, PINDIR_OUTPUT, mediaTypes)
       
    28         {
       
    29         }
       
    30 
       
    31         QAsyncReader::~QAsyncReader()
       
    32         {
       
    33         }
       
    34 
       
    35         STDMETHODIMP QAsyncReader::QueryInterface(REFIID iid, void **out)
       
    36         {
       
    37             if (!out) {
       
    38                 return E_POINTER;
       
    39             }
       
    40 
       
    41             if (iid == IID_IAsyncReader) {
       
    42                 AddRef();
       
    43                 *out = static_cast<IAsyncReader*>(this);
       
    44                 return S_OK;
       
    45             }
       
    46 
       
    47             return QPin::QueryInterface(iid, out);
       
    48         }
       
    49 
       
    50         STDMETHODIMP_(ULONG) QAsyncReader::AddRef()
       
    51         {
       
    52             return QPin::AddRef();
       
    53         }
       
    54 
       
    55         STDMETHODIMP_(ULONG) QAsyncReader::Release()
       
    56         {
       
    57             return QPin::Release();
       
    58         }
       
    59 
       
    60 
       
    61         STDMETHODIMP QAsyncReader::RequestAllocator(IMemAllocator *preferred, ALLOCATOR_PROPERTIES *prop,IMemAllocator **actual)
       
    62         {
       
    63             ALLOCATOR_PROPERTIES prop2;
       
    64 
       
    65             if (prop->cbAlign == 0) {
       
    66                 prop->cbAlign = 1; //align on 1 char
       
    67             }
       
    68 
       
    69             if (preferred && preferred->SetProperties(prop, &prop2) == S_OK) {
       
    70                 preferred->AddRef();
       
    71                 *actual = preferred;
       
    72                 return S_OK;
       
    73             }
       
    74 
       
    75             //we should try to create one memory allocator ourselves here
       
    76             return E_FAIL;
       
    77         }
       
    78 
       
    79         STDMETHODIMP QAsyncReader::Request(IMediaSample *sample,DWORD_PTR user)
       
    80         {
       
    81             QMutexLocker locker(&m_mutex);
       
    82             if (m_flushing) {
       
    83                 return VFW_E_WRONG_STATE;
       
    84             }
       
    85 
       
    86             m_requestQueue.enqueue(AsyncRequest(sample, user));
       
    87             m_requestWait.wakeOne();
       
    88             return S_OK;
       
    89         }
       
    90 
       
    91         STDMETHODIMP QAsyncReader::WaitForNext(DWORD timeout, IMediaSample **sample, DWORD_PTR *user)
       
    92         {
       
    93             QMutexLocker locker(&m_mutex);
       
    94             if (!sample ||!user) {
       
    95                 return E_POINTER;
       
    96             }
       
    97 
       
    98             //msdn says to return immediately if we're flushing but that doesn't seem to be true
       
    99             //since it triggers a dead-lock somewhere inside directshow (see task 258830)
       
   100 
       
   101             *sample = 0;
       
   102             *user = 0;
       
   103 
       
   104             if (m_requestQueue.isEmpty()) {
       
   105                 if (m_requestWait.wait(&m_mutex, timeout) == false) {
       
   106                     return VFW_E_TIMEOUT;
       
   107                 }
       
   108                 if (m_requestQueue.isEmpty()) {
       
   109                     return VFW_E_WRONG_STATE;
       
   110                 }
       
   111             }
       
   112 
       
   113             AsyncRequest r = m_requestQueue.dequeue();
       
   114 
       
   115             //at this point we're sure to have a request to proceed
       
   116             if (r.sample == 0) {
       
   117                 return E_FAIL;
       
   118             }
       
   119 
       
   120             *sample = r.sample;
       
   121             *user = r.user;
       
   122             return syncReadAlignedUnlocked(r.sample);
       
   123         }
       
   124 
       
   125         STDMETHODIMP QAsyncReader::BeginFlush()
       
   126         {
       
   127             QMutexLocker locker(&m_mutex);
       
   128             m_flushing = true;
       
   129             m_requestWait.wakeOne();
       
   130             return S_OK;
       
   131         }
       
   132 
       
   133         STDMETHODIMP QAsyncReader::EndFlush()
       
   134         {
       
   135             QMutexLocker locker(&m_mutex);
       
   136             m_flushing = false;
       
   137             return S_OK;
       
   138         }
       
   139 
       
   140         STDMETHODIMP QAsyncReader::SyncReadAligned(IMediaSample *sample)
       
   141         {
       
   142             QMutexLocker locker(&m_mutex);
       
   143             return syncReadAlignedUnlocked(sample);
       
   144         }
       
   145 
       
   146         STDMETHODIMP QAsyncReader::SyncRead(LONGLONG pos, LONG length, BYTE *buffer)
       
   147         {
       
   148             QMutexLocker locker(&m_mutex);
       
   149             return read(pos, length, buffer, 0);
       
   150         }
       
   151 
       
   152 
       
   153         STDMETHODIMP QAsyncReader::syncReadAlignedUnlocked(IMediaSample *sample)
       
   154         {
       
   155             Q_ASSERT(!m_mutex.tryLock());
       
   156 
       
   157             if (!sample) {
       
   158                 return E_POINTER;
       
   159             }
       
   160 
       
   161             REFERENCE_TIME start = 0,
       
   162                 stop = 0;
       
   163             HRESULT hr = sample->GetTime(&start, &stop);
       
   164             if(FAILED(hr)) {
       
   165                 return hr;
       
   166             }
       
   167 
       
   168             LONGLONG startPos = start / 10000000;
       
   169             LONG length = static_cast<LONG>((stop - start) / 10000000);
       
   170 
       
   171             BYTE *buffer;
       
   172             hr = sample->GetPointer(&buffer);
       
   173             if(FAILED(hr)) {
       
   174                 return hr;
       
   175             }
       
   176 
       
   177             LONG actual = 0;
       
   178             read(startPos, length, buffer, &actual);
       
   179 
       
   180             return sample->SetActualDataLength(actual);
       
   181         }
       
   182 
       
   183     }
       
   184 }
       
   185 
       
   186 QT_END_NAMESPACE