| 
							- /*
 -   ==============================================================================
 - 
 -    This file is part of the JUCE library.
 -    Copyright (c) 2013 - Raw Material Software Ltd.
 - 
 -    Permission is granted to use this software under the terms of either:
 -    a) the GPL v2 (or any later version)
 -    b) the Affero GPL v3
 - 
 -    Details of these licenses can be found at: www.gnu.org/licenses
 - 
 -    JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
 -    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 -    A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
 - 
 -    ------------------------------------------------------------------------------
 - 
 -    To release a closed-source product which uses JUCE, commercial licenses are
 -    available: visit www.juce.com for more information.
 - 
 -   ==============================================================================
 - */
 - 
 - namespace DirectShowHelpers
 - {
 -     bool checkDShowAvailability()
 -     {
 -         ComSmartPtr <IGraphBuilder> graph;
 -         return SUCCEEDED (graph.CoCreateInstance (CLSID_FilterGraph));
 -     }
 - 
 -     //======================================================================
 -     class VideoRenderer
 -     {
 -     public:
 -         VideoRenderer() {}
 -         virtual ~VideoRenderer() {}
 - 
 -         virtual HRESULT create (ComSmartPtr <IGraphBuilder>& graphBuilder,
 -                                 ComSmartPtr <IBaseFilter>& baseFilter, HWND hwnd) = 0;
 - 
 -         virtual void setVideoWindow (HWND hwnd) = 0;
 -         virtual void setVideoPosition (HWND hwnd, long videoWidth, long videoHeight) = 0;
 -         virtual void repaintVideo (HWND hwnd, HDC hdc) = 0;
 -         virtual void displayModeChanged() = 0;
 -         virtual HRESULT getVideoSize (long& videoWidth, long& videoHeight) = 0;
 -     };
 - 
 -     //======================================================================
 -     class VMR7  : public VideoRenderer
 -     {
 -     public:
 -         VMR7() {}
 - 
 -         HRESULT create (ComSmartPtr <IGraphBuilder>& graphBuilder,
 -                         ComSmartPtr <IBaseFilter>& baseFilter, HWND hwnd)
 -         {
 -             ComSmartPtr <IVMRFilterConfig> filterConfig;
 - 
 -             HRESULT hr = baseFilter.CoCreateInstance (CLSID_VideoMixingRenderer);
 - 
 -             if (SUCCEEDED (hr))   hr = graphBuilder->AddFilter (baseFilter, L"VMR-7");
 -             if (SUCCEEDED (hr))   hr = baseFilter.QueryInterface (filterConfig);
 -             if (SUCCEEDED (hr))   hr = filterConfig->SetRenderingMode (VMRMode_Windowless);
 -             if (SUCCEEDED (hr))   hr = baseFilter.QueryInterface (windowlessControl);
 -             if (SUCCEEDED (hr))   hr = windowlessControl->SetVideoClippingWindow (hwnd);
 -             if (SUCCEEDED (hr))   hr = windowlessControl->SetAspectRatioMode (VMR_ARMODE_LETTER_BOX);
 - 
 -             return hr;
 -         }
 - 
 -         void setVideoWindow (HWND hwnd)
 -         {
 -             windowlessControl->SetVideoClippingWindow (hwnd);
 -         }
 - 
 -         void setVideoPosition (HWND hwnd, long videoWidth, long videoHeight)
 -         {
 -             RECT src, dest;
 - 
 -             SetRect (&src, 0, 0, videoWidth, videoHeight);
 -             GetClientRect (hwnd, &dest);
 - 
 -             windowlessControl->SetVideoPosition (&src, &dest);
 -         }
 - 
 -         void repaintVideo (HWND hwnd, HDC hdc)
 -         {
 -             windowlessControl->RepaintVideo (hwnd, hdc);
 -         }
 - 
 -         void displayModeChanged()
 -         {
 -             windowlessControl->DisplayModeChanged();
 -         }
 - 
 -         HRESULT getVideoSize (long& videoWidth, long& videoHeight)
 -         {
 -             return windowlessControl->GetNativeVideoSize (&videoWidth, &videoHeight, nullptr, nullptr);
 -         }
 - 
 -     private:
 -         ComSmartPtr <IVMRWindowlessControl> windowlessControl;
 - 
 -         JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (VMR7)
 -     };
 - 
 - 
 -     //======================================================================
 - #if JUCE_MEDIAFOUNDATION
 -     class EVR : public VideoRenderer
 -     {
 -     public:
 -         EVR() {}
 - 
 -         HRESULT create (ComSmartPtr <IGraphBuilder>& graphBuilder,
 -                         ComSmartPtr <IBaseFilter>& baseFilter, HWND hwnd)
 -         {
 -             ComSmartPtr <IMFGetService> getService;
 - 
 -             HRESULT hr = baseFilter.CoCreateInstance (CLSID_EnhancedVideoRenderer);
 - 
 -             if (SUCCEEDED (hr))   hr = graphBuilder->AddFilter (baseFilter, L"EVR");
 -             if (SUCCEEDED (hr))   hr = baseFilter.QueryInterface (getService);
 -             if (SUCCEEDED (hr))   hr = getService->GetService (MR_VIDEO_RENDER_SERVICE, IID_IMFVideoDisplayControl,
 -                                                                (LPVOID*) videoDisplayControl.resetAndGetPointerAddress());
 -             if (SUCCEEDED (hr))   hr = videoDisplayControl->SetVideoWindow (hwnd);
 -             if (SUCCEEDED (hr))   hr = videoDisplayControl->SetAspectRatioMode (MFVideoARMode_PreservePicture);
 - 
 -             return hr;
 -         }
 - 
 -         void setVideoWindow (HWND hwnd)
 -         {
 -             videoDisplayControl->SetVideoWindow (hwnd);
 -         }
 - 
 -         void setVideoPosition (HWND hwnd, long /*videoWidth*/, long /*videoHeight*/)
 -         {
 -             const MFVideoNormalizedRect src = { 0.0f, 0.0f, 1.0f, 1.0f };
 - 
 -             RECT dest;
 -             GetClientRect (hwnd, &dest);
 - 
 -             videoDisplayControl->SetVideoPosition (&src, &dest);
 -         }
 - 
 -         void repaintVideo (HWND /*hwnd*/, HDC /*hdc*/)
 -         {
 -             videoDisplayControl->RepaintVideo();
 -         }
 - 
 -         void displayModeChanged() {}
 - 
 -         HRESULT getVideoSize (long& videoWidth, long& videoHeight)
 -         {
 -             SIZE sz;
 -             HRESULT hr = videoDisplayControl->GetNativeVideoSize (&sz, nullptr);
 -             videoWidth  = sz.cx;
 -             videoHeight = sz.cy;
 -             return hr;
 -         }
 - 
 -     private:
 -         ComSmartPtr <IMFVideoDisplayControl> videoDisplayControl;
 - 
 -         JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (EVR)
 -     };
 - #endif
 - }
 - 
 - 
 - //======================================================================
 - class DirectShowComponent::DirectShowContext    : public AsyncUpdater
 - {
 - public:
 -     DirectShowContext (DirectShowComponent& c, VideoRendererType renderType)
 -         : component (c),
 -           hwnd (0),
 -           hdc (0),
 -           state (uninitializedState),
 -           hasVideo (false),
 -           videoWidth (0),
 -           videoHeight (0),
 -           type (renderType),
 -           needToUpdateViewport (true),
 -           needToRecreateNativeWindow (false)
 -     {
 -         CoInitialize (0);
 - 
 -         if (type == dshowDefault)
 -         {
 -             type = dshowVMR7;
 - 
 -            #if JUCE_MEDIAFOUNDATION
 -             if (SystemStats::getOperatingSystemType() >= SystemStats::WinVista)
 -                 type = dshowEVR;
 -            #endif
 -         }
 -     }
 - 
 -     ~DirectShowContext()
 -     {
 -         release();
 -         CoUninitialize();
 -     }
 - 
 -     //======================================================================
 -     void updateWindowPosition (const Rectangle<int>& newBounds)
 -     {
 -         nativeWindow->setWindowPosition (newBounds);
 -     }
 - 
 -     void showWindow (bool shouldBeVisible)
 -     {
 -         nativeWindow->showWindow (shouldBeVisible);
 -     }
 - 
 -     //======================================================================
 -     void repaint()
 -     {
 -         if (hasVideo)
 -             videoRenderer->repaintVideo (nativeWindow->getHandle(), nativeWindow->getContext());
 -     }
 - 
 -     void updateVideoPosition()
 -     {
 -         if (hasVideo)
 -             videoRenderer->setVideoPosition (nativeWindow->getHandle(), videoWidth, videoHeight);
 -     }
 - 
 -     void displayResolutionChanged()
 -     {
 -         if (hasVideo)
 -             videoRenderer->displayModeChanged();
 -     }
 - 
 -     //======================================================================
 -     void peerChanged()
 -     {
 -         deleteNativeWindow();
 - 
 -         mediaEvent->SetNotifyWindow (0, 0, 0);
 -         if (videoRenderer != nullptr)
 -             videoRenderer->setVideoWindow (nullptr);
 - 
 -         createNativeWindow();
 - 
 -         mediaEvent->SetNotifyWindow ((OAHWND) hwnd, graphEventID, 0);
 -         if (videoRenderer != nullptr)
 -             videoRenderer->setVideoWindow (hwnd);
 -     }
 - 
 -     void handleAsyncUpdate() override
 -     {
 -         if (hwnd != 0)
 -         {
 -             if (needToRecreateNativeWindow)
 -             {
 -                 peerChanged();
 -                 needToRecreateNativeWindow = false;
 -             }
 - 
 -             if (needToUpdateViewport)
 -             {
 -                 updateVideoPosition();
 -                 needToUpdateViewport = false;
 -             }
 - 
 -             repaint();
 -         }
 -         else
 -         {
 -             triggerAsyncUpdate();
 -         }
 -     }
 - 
 -     void recreateNativeWindowAsync()
 -     {
 -         needToRecreateNativeWindow = true;
 -         triggerAsyncUpdate();
 -     }
 - 
 -     void updateContextPosition()
 -     {
 -         needToUpdateViewport = true;
 -         triggerAsyncUpdate();
 -     }
 - 
 -     //======================================================================
 -     bool loadFile (const String& fileOrURLPath)
 -     {
 -         jassert (state == uninitializedState);
 - 
 -         if (! createNativeWindow())
 -             return false;
 - 
 -         HRESULT hr = graphBuilder.CoCreateInstance (CLSID_FilterGraph);
 - 
 -         // basic playback interfaces
 -         if (SUCCEEDED (hr))   hr = graphBuilder.QueryInterface (mediaControl);
 -         if (SUCCEEDED (hr))   hr = graphBuilder.QueryInterface (mediaPosition);
 -         if (SUCCEEDED (hr))   hr = graphBuilder.QueryInterface (mediaEvent);
 -         if (SUCCEEDED (hr))   hr = graphBuilder.QueryInterface (basicAudio);
 - 
 -         // video renderer interface
 -         if (SUCCEEDED (hr))
 -         {
 -            #if JUCE_MEDIAFOUNDATION
 -             if (type == dshowEVR)
 -                 videoRenderer = new DirectShowHelpers::EVR();
 -             else
 -            #endif
 -                 videoRenderer = new DirectShowHelpers::VMR7();
 - 
 -             hr = videoRenderer->create (graphBuilder, baseFilter, hwnd);
 -         }
 - 
 -         // build filter graph
 -         if (SUCCEEDED (hr))
 -         {
 -             hr = graphBuilder->RenderFile (fileOrURLPath.toWideCharPointer(), nullptr);
 - 
 -             if (FAILED (hr))
 -             {
 -                 // Annoyingly, if we don't run the msg loop between failing and deleting the window, the
 -                 // whole OS message-dispatch system gets itself into a state, and refuses to deliver any
 -                 // more messages for the whole app. (That's what happens in Win7, anyway)
 -                 MessageManager::getInstance()->runDispatchLoopUntil (200);
 -             }
 -         }
 - 
 -         // remove video renderer if not connected (no video)
 -         if (SUCCEEDED (hr))
 -         {
 -             if (isRendererConnected())
 -             {
 -                 hasVideo = true;
 -                 hr = videoRenderer->getVideoSize (videoWidth, videoHeight);
 -             }
 -             else
 -             {
 -                 hasVideo = false;
 -                 graphBuilder->RemoveFilter (baseFilter);
 -                 videoRenderer = nullptr;
 -                 baseFilter = nullptr;
 -             }
 -         }
 - 
 -         // set window to receive events
 -         if (SUCCEEDED (hr))
 -             hr = mediaEvent->SetNotifyWindow ((OAHWND) hwnd, graphEventID, 0);
 - 
 -         if (SUCCEEDED (hr))
 -         {
 -             state = stoppedState;
 -             pause();
 -             return true;
 -         }
 - 
 -         release();
 -         return false;
 -     }
 - 
 -     void release()
 -     {
 -         if (mediaControl != nullptr)
 -             mediaControl->Stop();
 - 
 -         if (mediaEvent != nullptr)
 -             mediaEvent->SetNotifyWindow (0, 0, 0);
 - 
 -         if (videoRenderer != nullptr)
 -             videoRenderer->setVideoWindow (0);
 - 
 -         hasVideo = false;
 -         videoRenderer = nullptr;
 - 
 -         baseFilter = nullptr;
 -         basicAudio = nullptr;
 -         mediaEvent = nullptr;
 -         mediaPosition = nullptr;
 -         mediaControl = nullptr;
 -         graphBuilder = nullptr;
 - 
 -         state = uninitializedState;
 - 
 -         videoWidth = 0;
 -         videoHeight = 0;
 - 
 -         if (nativeWindow != nullptr)
 -             deleteNativeWindow();
 -     }
 - 
 -     void graphEventProc()
 -     {
 -         LONG ec;
 -         LONG_PTR p1, p2;
 - 
 -         jassert (mediaEvent != nullptr);
 - 
 -         while (SUCCEEDED (mediaEvent->GetEvent (&ec, &p1, &p2, 0)))
 -         {
 -             switch (ec)
 -             {
 -             case EC_REPAINT:
 -                 component.repaint();
 -                 break;
 - 
 -             case EC_COMPLETE:
 -                 if (component.isLooping())
 -                     component.goToStart();
 -                 else
 -                     component.stop();
 -                 break;
 - 
 -             case EC_USERABORT:
 -             case EC_ERRORABORT:
 -             case EC_ERRORABORTEX:
 -                 component.closeMovie();
 -                 break;
 - 
 -             default:
 -                 break;
 -             }
 - 
 -             mediaEvent->FreeEventParams (ec, p1, p2);
 -         }
 -     }
 - 
 -     //======================================================================
 -     void run()
 -     {
 -         mediaControl->Run();
 -         state = runningState;
 -     }
 - 
 -     void stop()
 -     {
 -         mediaControl->Stop();
 -         state = stoppedState;
 -     }
 - 
 -     void pause()
 -     {
 -         mediaControl->Pause();
 -         state = pausedState;
 -     }
 - 
 -     //======================================================================
 -     bool isInitialised() const noexcept  { return state != uninitializedState; }
 -     bool isRunning() const noexcept      { return state == runningState; }
 -     bool isPaused() const noexcept       { return state == pausedState; }
 -     bool isStopped() const noexcept      { return state == stoppedState; }
 -     bool containsVideo() const noexcept  { return hasVideo; }
 -     int getVideoWidth() const noexcept   { return (int) videoWidth; }
 -     int getVideoHeight() const noexcept  { return (int) videoHeight; }
 - 
 -     //======================================================================
 -     double getDuration() const
 -     {
 -         REFTIME duration;
 -         mediaPosition->get_Duration (&duration);
 -         return duration;
 -     }
 - 
 -     double getPosition() const
 -     {
 -         REFTIME seconds;
 -         mediaPosition->get_CurrentPosition (&seconds);
 -         return seconds;
 -     }
 - 
 -     //======================================================================
 -     void setSpeed (const float newSpeed)        { mediaPosition->put_Rate (newSpeed); }
 -     void setPosition (const double seconds)     { mediaPosition->put_CurrentPosition (seconds); }
 -     void setVolume (const float newVolume)      { basicAudio->put_Volume (convertToDShowVolume (newVolume)); }
 - 
 -     // in DirectShow, full volume is 0, silence is -10000
 -     static long convertToDShowVolume (const float vol) noexcept
 -     {
 -         if (vol >= 1.0f) return 0;
 -         if (vol <= 0.0f) return -10000;
 - 
 -         return roundToInt ((vol * 10000.0f) - 10000.0f);
 -     }
 - 
 -     float getVolume() const
 -     {
 -         long volume;
 -         basicAudio->get_Volume (&volume);
 -         return (volume + 10000) / 10000.0f;
 -     }
 - 
 - private:
 -     //======================================================================
 -     enum { graphEventID = WM_APP + 0x43f0 };
 - 
 -     DirectShowComponent& component;
 -     HWND hwnd;
 -     HDC hdc;
 - 
 -     enum State { uninitializedState, runningState, pausedState, stoppedState };
 -     State state;
 - 
 -     bool hasVideo;
 -     long videoWidth, videoHeight;
 - 
 -     VideoRendererType type;
 - 
 -     ComSmartPtr <IGraphBuilder> graphBuilder;
 -     ComSmartPtr <IMediaControl> mediaControl;
 -     ComSmartPtr <IMediaPosition> mediaPosition;
 -     ComSmartPtr <IMediaEventEx> mediaEvent;
 -     ComSmartPtr <IBasicAudio> basicAudio;
 -     ComSmartPtr <IBaseFilter> baseFilter;
 - 
 -     ScopedPointer <DirectShowHelpers::VideoRenderer> videoRenderer;
 - 
 -     bool needToUpdateViewport, needToRecreateNativeWindow;
 - 
 -     //======================================================================
 -     class NativeWindowClass   : private DeletedAtShutdown
 -     {
 -     public:
 -         bool isRegistered() const noexcept              { return atom != 0; }
 -         LPCTSTR getWindowClassName() const noexcept     { return (LPCTSTR) MAKELONG (atom, 0); }
 - 
 -         juce_DeclareSingleton_SingleThreaded_Minimal (NativeWindowClass);
 - 
 -     private:
 -         NativeWindowClass()
 -             : atom (0)
 -         {
 -             String windowClassName ("JUCE_DIRECTSHOW_");
 -             windowClassName << (int) (Time::currentTimeMillis() & 0x7fffffff);
 - 
 -             HINSTANCE moduleHandle = (HINSTANCE) Process::getCurrentModuleInstanceHandle();
 - 
 -             TCHAR moduleFile [1024] = { 0 };
 -             GetModuleFileName (moduleHandle, moduleFile, 1024);
 - 
 -             WNDCLASSEX wcex = { 0 };
 -             wcex.cbSize         = sizeof (wcex);
 -             wcex.style          = CS_OWNDC;
 -             wcex.lpfnWndProc    = (WNDPROC) wndProc;
 -             wcex.lpszClassName  = windowClassName.toWideCharPointer();
 -             wcex.hInstance      = moduleHandle;
 - 
 -             atom = RegisterClassEx (&wcex);
 -             jassert (atom != 0);
 -         }
 - 
 -         ~NativeWindowClass()
 -         {
 -             if (atom != 0)
 -                 UnregisterClass (getWindowClassName(), (HINSTANCE) Process::getCurrentModuleInstanceHandle());
 - 
 -             clearSingletonInstance();
 -         }
 - 
 -         static LRESULT CALLBACK wndProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
 -         {
 -             if (DirectShowContext* const c = (DirectShowContext*) GetWindowLongPtr (hwnd, GWLP_USERDATA))
 -             {
 -                 switch (msg)
 -                 {
 -                     case WM_NCHITTEST:          return HTTRANSPARENT;
 -                     case WM_ERASEBKGND:         return 1;
 -                     case WM_DISPLAYCHANGE:      c->displayResolutionChanged(); break;
 -                     case graphEventID:          c->graphEventProc(); return 0;
 -                     default:                    break;
 -                 }
 -             }
 - 
 -             return DefWindowProc (hwnd, msg, wParam, lParam);
 -         }
 - 
 -         ATOM atom;
 - 
 -         JUCE_DECLARE_NON_COPYABLE (NativeWindowClass)
 -     };
 - 
 -     //======================================================================
 -     class NativeWindow
 -     {
 -     public:
 -         NativeWindow (HWND parentToAddTo, void* const userData)
 -             : hwnd (0), hdc (0)
 -         {
 -             NativeWindowClass* const wc = NativeWindowClass::getInstance();
 - 
 -             if (wc->isRegistered())
 -             {
 -                 DWORD exstyle = 0;
 -                 DWORD type = WS_CHILD;
 - 
 -                 hwnd = CreateWindowEx (exstyle, wc->getWindowClassName(),
 -                                        L"", type, 0, 0, 0, 0, parentToAddTo, 0,
 -                                        (HINSTANCE) Process::getCurrentModuleInstanceHandle(), 0);
 - 
 -                 if (hwnd != 0)
 -                 {
 -                     hdc = GetDC (hwnd);
 -                     SetWindowLongPtr (hwnd, GWLP_USERDATA, (LONG_PTR) userData);
 -                 }
 -             }
 - 
 -             jassert (hwnd != 0);
 -         }
 - 
 -         ~NativeWindow()
 -         {
 -             if (hwnd != 0)
 -             {
 -                 SetWindowLongPtr (hwnd, GWLP_USERDATA, (LONG_PTR) 0);
 -                 DestroyWindow (hwnd);
 -             }
 -         }
 - 
 -         HWND getHandle() const noexcept   { return hwnd; }
 -         HDC getContext() const noexcept   { return hdc; }
 - 
 -         void setWindowPosition (const Rectangle<int>& newBounds)
 -         {
 -             SetWindowPos (hwnd, 0, newBounds.getX(), newBounds.getY(),
 -                           newBounds.getWidth(), newBounds.getHeight(),
 -                           SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOOWNERZORDER);
 -         }
 - 
 -         void showWindow (const bool shouldBeVisible)
 -         {
 -             ShowWindow (hwnd, shouldBeVisible ? SW_SHOWNA : SW_HIDE);
 -         }
 - 
 -     private:
 -         HWND hwnd;
 -         HDC hdc;
 - 
 -         JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (NativeWindow)
 -     };
 - 
 -     ScopedPointer<NativeWindow> nativeWindow;
 - 
 -     //======================================================================
 -     bool createNativeWindow()
 -     {
 -         jassert (nativeWindow == nullptr);
 - 
 -         if (ComponentPeer* const topLevelPeer = component.getTopLevelComponent()->getPeer())
 -         {
 -             nativeWindow = new NativeWindow ((HWND) topLevelPeer->getNativeHandle(), this);
 - 
 -             hwnd = nativeWindow->getHandle();
 - 
 -             if (hwnd != 0)
 -             {
 -                 hdc = GetDC (hwnd);
 -                 component.updateContextPosition();
 -                 component.showContext (component.isShowing());
 -                 return true;
 -             }
 -             else
 -             {
 -                 nativeWindow = nullptr;
 -             }
 -         }
 -         else
 -         {
 -             jassertfalse;
 -         }
 - 
 -         return false;
 -     }
 - 
 -     void deleteNativeWindow()
 -     {
 -         jassert (nativeWindow != nullptr);
 -         ReleaseDC (hwnd, hdc);
 -         hwnd = 0;
 -         hdc = 0;
 -         nativeWindow = nullptr;
 -     }
 - 
 -     bool isRendererConnected()
 -     {
 -         ComSmartPtr <IEnumPins> enumPins;
 - 
 -         HRESULT hr = baseFilter->EnumPins (enumPins.resetAndGetPointerAddress());
 - 
 -         if (SUCCEEDED (hr))
 -             hr = enumPins->Reset();
 - 
 -         ComSmartPtr<IPin> pin;
 - 
 -         while (SUCCEEDED (hr)
 -                 && enumPins->Next (1, pin.resetAndGetPointerAddress(), nullptr) == S_OK)
 -         {
 -             ComSmartPtr<IPin> otherPin;
 - 
 -             hr = pin->ConnectedTo (otherPin.resetAndGetPointerAddress());
 - 
 -             if (SUCCEEDED (hr))
 -             {
 -                 PIN_DIRECTION direction;
 -                 hr = pin->QueryDirection (&direction);
 - 
 -                 if (SUCCEEDED (hr) && direction == PINDIR_INPUT)
 -                     return true;
 -             }
 -             else if (hr == VFW_E_NOT_CONNECTED)
 -             {
 -                 hr = S_OK;
 -             }
 -         }
 - 
 -         return false;
 -     }
 - 
 -     JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DirectShowContext)
 - };
 - 
 - juce_ImplementSingleton_SingleThreaded (DirectShowComponent::DirectShowContext::NativeWindowClass);
 - 
 - 
 - //======================================================================
 - class DirectShowComponent::DirectShowComponentWatcher   : public ComponentMovementWatcher
 - {
 - public:
 -     DirectShowComponentWatcher (DirectShowComponent* const c)
 -         : ComponentMovementWatcher (c),
 -           owner (c)
 -     {
 -     }
 - 
 -     void componentMovedOrResized (bool /*wasMoved*/, bool /*wasResized*/) override
 -     {
 -         if (owner->videoLoaded)
 -             owner->updateContextPosition();
 -     }
 - 
 -     void componentPeerChanged() override
 -     {
 -         if (owner->videoLoaded)
 -             owner->recreateNativeWindowAsync();
 -     }
 - 
 -     void componentVisibilityChanged() override
 -     {
 -         if (owner->videoLoaded)
 -             owner->showContext (owner->isShowing());
 -     }
 - 
 - private:
 -     DirectShowComponent* const owner;
 - 
 -     JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DirectShowComponentWatcher)
 - };
 - 
 - 
 - //======================================================================
 - DirectShowComponent::DirectShowComponent (VideoRendererType type)
 -     : videoLoaded (false),
 -       looping (false)
 - {
 -     setOpaque (true);
 -     context = new DirectShowContext (*this, type);
 -     componentWatcher = new DirectShowComponentWatcher (this);
 - }
 - 
 - DirectShowComponent::~DirectShowComponent()
 - {
 -     componentWatcher = nullptr;
 - }
 - 
 - bool DirectShowComponent::isDirectShowAvailable()
 - {
 -     static bool isDSAvailable = DirectShowHelpers::checkDShowAvailability();
 -     return isDSAvailable;
 - }
 - 
 - void DirectShowComponent::recreateNativeWindowAsync()
 - {
 -     context->recreateNativeWindowAsync();
 -     repaint();
 - }
 - 
 - void DirectShowComponent::updateContextPosition()
 - {
 -     context->updateContextPosition();
 - 
 -     if (getWidth() > 0 && getHeight() > 0)
 -         if (ComponentPeer* peer = getTopLevelComponent()->getPeer())
 -             context->updateWindowPosition (peer->getAreaCoveredBy (*this));
 - }
 - 
 - void DirectShowComponent::showContext (const bool shouldBeVisible)
 - {
 -     context->showWindow (shouldBeVisible);
 - }
 - 
 - void DirectShowComponent::paint (Graphics& g)
 - {
 -     if (videoLoaded)
 -         context->handleUpdateNowIfNeeded();
 -     else
 -         g.fillAll (Colours::grey);
 - }
 - 
 - //======================================================================
 - bool DirectShowComponent::loadMovie (const String& fileOrURLPath)
 - {
 -     closeMovie();
 - 
 -     videoLoaded = context->loadFile (fileOrURLPath);
 - 
 -     if (videoLoaded)
 -     {
 -         videoPath = fileOrURLPath;
 -         context->updateVideoPosition();
 -     }
 - 
 -     return videoLoaded;
 - }
 - 
 - bool DirectShowComponent::loadMovie (const File& videoFile)
 - {
 -     return loadMovie (videoFile.getFullPathName());
 - }
 - 
 - bool DirectShowComponent::loadMovie (const URL& videoURL)
 - {
 -     return loadMovie (videoURL.toString (false));
 - }
 - 
 - void DirectShowComponent::closeMovie()
 - {
 -     if (videoLoaded)
 -         context->release();
 - 
 -     videoLoaded = false;
 -     videoPath = String::empty;
 - }
 - 
 - //======================================================================
 - File DirectShowComponent::getCurrentMoviePath() const           { return videoPath; }
 - bool DirectShowComponent::isMovieOpen() const                   { return videoLoaded; }
 - double DirectShowComponent::getMovieDuration() const            { return videoLoaded ? context->getDuration() : 0.0; }
 - void DirectShowComponent::setLooping (const bool shouldLoop)    { looping = shouldLoop; }
 - bool DirectShowComponent::isLooping() const                     { return looping; }
 - 
 - void DirectShowComponent::getMovieNormalSize (int &width, int &height) const
 - {
 -     width = context->getVideoWidth();
 -     height = context->getVideoHeight();
 - }
 - 
 - //======================================================================
 - void DirectShowComponent::setBoundsWithCorrectAspectRatio (const Rectangle<int>& spaceToFitWithin,
 -                                                            RectanglePlacement placement)
 - {
 -     int normalWidth, normalHeight;
 -     getMovieNormalSize (normalWidth, normalHeight);
 - 
 -     const Rectangle<int> normalSize (0, 0, normalWidth, normalHeight);
 - 
 -     if (! (spaceToFitWithin.isEmpty() || normalSize.isEmpty()))
 -         setBounds (placement.appliedTo (normalSize, spaceToFitWithin));
 -     else
 -         setBounds (spaceToFitWithin);
 - }
 - 
 - //======================================================================
 - void DirectShowComponent::play()
 - {
 -     if (videoLoaded)
 -         context->run();
 - }
 - 
 - void DirectShowComponent::stop()
 - {
 -     if (videoLoaded)
 -         context->pause();
 - }
 - 
 - bool DirectShowComponent::isPlaying() const
 - {
 -     return context->isRunning();
 - }
 - 
 - void DirectShowComponent::goToStart()
 - {
 -     setPosition (0.0);
 - }
 - 
 - void DirectShowComponent::setPosition (const double seconds)
 - {
 -     if (videoLoaded)
 -         context->setPosition (seconds);
 - }
 - 
 - double DirectShowComponent::getPosition() const
 - {
 -     return videoLoaded ? context->getPosition() : 0.0;
 - }
 - 
 - void DirectShowComponent::setSpeed (const float newSpeed)
 - {
 -     if (videoLoaded)
 -         context->setSpeed (newSpeed);
 - }
 - 
 - void DirectShowComponent::setMovieVolume (const float newVolume)
 - {
 -     if (videoLoaded)
 -         context->setVolume (newVolume);
 - }
 - 
 - float DirectShowComponent::getMovieVolume() const
 - {
 -     return videoLoaded ? context->getVolume() : 0.0f;
 - }
 
 
  |