blob: 84220a5cec4d0f8061ac20f490f14462028eddfd [file] [log] [blame]
atraczyk14ba30c2016-09-22 18:31:59 -04001/**************************************************************************
2* Copyright (C) 2016 by Savoir-faire Linux *
3* Author: Jäger Nicolas <nicolas.jager@savoirfairelinux.com> *
4* Author: Traczyk Andreas <andreas.traczyk@savoirfairelinux.com> *
5* *
6* This program is free software; you can redistribute it and/or modify *
7* it under the terms of the GNU General Public License as published by *
8* the Free Software Foundation; either version 3 of the License, or *
9* (at your option) any later version. *
10* *
11* This program is distributed in the hope that it will be useful, *
12* but WITHOUT ANY WARRANTY; without even the implied warranty of *
13* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14* GNU General Public License for more details. *
15* *
16* You should have received a copy of the GNU General Public License *
17* along with this program. If not, see <http://www.gnu.org/licenses/>. *
18**************************************************************************/
19
20#include "pch.h"
21
22#include "VideoRendererManager.h"
23
24using namespace RingClientUWP;
25using namespace Video;
26
27using namespace Platform;
28
29using namespace Windows::UI::Core;
30using namespace Windows::ApplicationModel::Core;
31
32void
33VideoRenderer::bindSinkFunctions()
34{
35 using namespace std::placeholders;
36 target.pull = std::bind(&VideoRenderer::requestFrameBuffer,this, _1);
37 target.push = std::bind(&VideoRenderer::onNewFrame,this, _1);
38}
39
40DRing::SinkTarget::FrameBufferPtr
41VideoRenderer::requestFrameBuffer(std::size_t bytes)
42{
43 std::lock_guard<std::mutex> lk(video_mutex);
44 if (!daemonFramePtr_)
45 daemonFramePtr_.reset(new DRing::FrameBuffer);
46 daemonFramePtr_->storage.resize(bytes);
47 daemonFramePtr_->ptr = daemonFramePtr_->storage.data();
48 daemonFramePtr_->ptrSize = bytes;
49 return std::move(daemonFramePtr_);
50}
51
52void
53VideoRenderer::onNewFrame(DRing::SinkTarget::FrameBufferPtr buf)
54{
55 std::lock_guard<std::mutex> lk(video_mutex);
56 daemonFramePtr_ = std::move(buf);
57 auto id = Utils::toPlatformString(this->id);
58 VideoManager::instance->rendererManager()->raiseWriteVideoFrame(id);
59}
60
61VideoRendererManager::VideoRendererManager()
62{
63 renderers = ref new Map<String^, VideoRendererWrapper^>();
64}
65
66void
67VideoRendererManager::startedDecoding(String^ id, int width, int height)
68{
69 renderers->Insert(id, ref new VideoRendererWrapper());
70 auto renderer = renderers->Lookup(id)->renderer;
71 renderer->id = Utils::toString(id);
72 renderer->bindSinkFunctions();
73 renderer->width = width;
74 renderer->height = height;
75 MSG_(Utils::toString( "startedDecoding for sink id: " + id).c_str());
76 registerSinkTarget(id, renderer->target);
77}
78
79void
80VideoRendererManager::registerSinkTarget(String^ sinkID, const DRing::SinkTarget& target)
81{
82 MSG_(Utils::toString( "registerSinkTarget for sink id: " + sinkID).c_str());
83 DRing::registerSinkTarget(Utils::toString(sinkID), target);
84}
85
86void
87VideoRendererManager::raiseWriteVideoFrame(String^ id)
88{
89 auto renderer = renderers->Lookup(id)->renderer;
90 if (!renderer)
91 return;
92 writeVideoFrame(id,
93 renderer->daemonFramePtr_->ptr,
94 renderer->width,
95 renderer->height);
96}
97
98void
99VideoRendererManager::raiseClearRenderTarget()
100{
101 clearRenderTarget();
102}
103
104void
105VideoRendererManager::removeRenderer(String^ id)
106{
107 if(!renderers)
108 return;
109 std::unique_lock<std::mutex> lk(renderers->Lookup(id)->render_mutex);
110 renderers->Lookup(id)->frame_cv.wait(lk, [=] {
111 return !renderers->Lookup(id)->isRendering;
112 });
113 renderers->Remove(id);
114}
115
116VideoRendererWrapper^
117VideoRendererManager::renderer(String^ id)
118{
119 if(!renderers)
120 return nullptr;
121 return renderers->Lookup(id);
122}