]> git.sesse.net Git - casparcg/blob - core/consumer/bluefish/BluefishPlaybackStrategy.cpp
2.0.0.2:
[casparcg] / core / consumer / bluefish / BluefishPlaybackStrategy.cpp
1 /*\r
2 * copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
3 *\r
4 *  This file is part of CasparCG.\r
5 *\r
6 *    CasparCG is free software: you can redistribute it and/or modify\r
7 *    it under the terms of the GNU General Public License as published by\r
8 *    the Free Software Foundation, either version 3 of the License, or\r
9 *    (at your option) any later version.\r
10 *\r
11 *    CasparCG is distributed in the hope that it will be useful,\r
12 *    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
14 *    GNU General Public License for more details.\r
15 \r
16 *    You should have received a copy of the GNU General Public License\r
17 *    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
18 *\r
19 */\r
20  \r
21 #include "../../StdAfx.h"\r
22 \r
23 #include "../../../common/image/image.h"\r
24 #include <BlueVelvet4.h>\r
25 #include <BlueHancUtils.h>\r
26 \r
27 #include <vector>\r
28 \r
29 #include "BluefishPlaybackStrategy.h"\r
30 #include "BluefishVideoConsumer.h"\r
31 \r
32 namespace caspar { namespace bluefish {\r
33 \r
34 using namespace caspar::common;\r
35 \r
36 struct BluefishPlaybackStrategy::Implementation\r
37 {\r
38         Implementation(BlueFishVideoConsumer* pConsumer) : pConsumer_(pConsumer), currentReservedFrameIndex_(0)\r
39         {\r
40                 auto frame = pConsumer->pFrameManager_->CreateFrame();\r
41                 if(frame != 0)\r
42                         reservedFrames_.push_back(frame);\r
43                 else {\r
44                         throw std::exception("Failed to reserve temporary bluefishframe");\r
45                 }\r
46                 frame.reset();\r
47 \r
48                 frame = pConsumer->pFrameManager_->CreateFrame();\r
49                 if(frame != 0)\r
50                         reservedFrames_.push_back(frame);\r
51                 else {\r
52                         throw std::exception("Failed to reserve temporary bluefishframe");\r
53                 }\r
54 \r
55                 memset(&hancStreamInfo_, 0, sizeof(hancStreamInfo_));\r
56         }\r
57         std::shared_ptr<BluefishVideoFrame> GetReservedFrame() {\r
58                 std::shared_ptr<BluefishVideoFrame> frame = reservedFrames_[currentReservedFrameIndex_];\r
59                 currentReservedFrameIndex_ ^= 1;\r
60                 return frame;\r
61         }\r
62 \r
63         void DisplayFrame(const gpu_frame_ptr& frame)\r
64         {\r
65                 if(frame != nullptr) {\r
66                         if(pConsumer_->pFrameManager_.get() == reinterpret_cast<BluefishFrameManager*>(frame->tag())) {\r
67                                 DoRender(std::static_pointer_cast<BluefishVideoFrame>(frame));\r
68                         }\r
69                         else {\r
70                                 std::shared_ptr<BluefishVideoFrame> pTempFrame = reservedFrames_[currentReservedFrameIndex_];\r
71                                 if(frame->size() == pTempFrame->size()) {\r
72                                         common::image::copy(pTempFrame->data(), frame->data(), pTempFrame->size());\r
73                                         DoRender(pTempFrame);\r
74                                 }\r
75 \r
76                                 currentReservedFrameIndex_ ^= 1;\r
77                         }\r
78                 }\r
79                 else {\r
80                         CASPAR_LOG(error) << "BLUEFISH: Tried to render frame with no data";\r
81                 }\r
82         }\r
83 \r
84         void DoRender(const std::shared_ptr<BluefishVideoFrame>& frame) {\r
85                 static bool doLog = true;\r
86                 static int frameID = 0;\r
87                 // video synch\r
88                 unsigned long fieldCount = 0;\r
89                 pConsumer_->pSDK_->wait_output_video_synch(UPD_FMT_FRAME, fieldCount);\r
90 \r
91                 // Host->PCI in_Frame buffer to the card buffer\r
92                 pConsumer_->pSDK_->system_buffer_write_async(frame->data(), frame->size(), 0, frame->meta_data(), 0);\r
93                 if(BLUE_FAIL(pConsumer_->pSDK_->render_buffer_update(frame->meta_data()))) {\r
94                 /*pConsumer_->pSDK_->system_buffer_write_async(frame->data(), frame->size(), 0, frameID, 0);\r
95                 if(BLUE_FAIL(pConsumer_->pSDK_->render_buffer_update(frameID))) {*/\r
96                         if(doLog) {\r
97                                 CASPAR_LOG(error) << "BLUEFISH: render_buffer_update failed";\r
98                                 doLog = false;\r
99                         }\r
100                 }\r
101                 else\r
102                         doLog = true;\r
103 \r
104                 frameID = (frameID+1) & 3;\r
105         }\r
106 \r
107         BlueFishVideoConsumer* pConsumer_;\r
108         std::vector<std::shared_ptr<BluefishVideoFrame>> reservedFrames_;\r
109         int currentReservedFrameIndex_;\r
110 \r
111         hanc_stream_info_struct hancStreamInfo_;\r
112 };\r
113 \r
114 BluefishPlaybackStrategy::BluefishPlaybackStrategy(BlueFishVideoConsumer* pConsumer) : pImpl_(new Implementation(pConsumer)) \r
115 { }\r
116 \r
117 BluefishPlaybackStrategy::~BluefishPlaybackStrategy()\r
118 { }\r
119 //\r
120 //FrameConsumer* BluefishPlaybackStrategy::GetConsumer()\r
121 //{\r
122 //      return pImpl_->pConsumer_;\r
123 //}\r
124 //\r
125 //gpu_frame_ptr BluefishPlaybackStrategy::GetReservedFrame() {\r
126 //      return pImpl_->GetReservedFrame();\r
127 //}\r
128 \r
129 void BluefishPlaybackStrategy::display(const gpu_frame_ptr& frame) \r
130 {\r
131         return pImpl_->DisplayFrame(frame);\r
132 }\r
133 \r
134 }       //namespace bluefish\r
135 }       //namespace caspar