const core::video_format_desc format_desc_;\r
\r
const bool key_only_;\r
- std::vector<uint8_t, tbb::cache_aligned_allocator<uint8_t>> key_data_;\r
+ std::vector<uint8_t, tbb::cache_aligned_allocator<uint8_t>> data_;\r
public:\r
decklink_frame(const safe_ptr<core::read_frame>& frame, const core::video_format_desc& format_desc, bool key_only)\r
: frame_(frame)\r
{\r
ref_count_ = 0;\r
}\r
+ \r
+ // IUnknown\r
\r
- const boost::iterator_range<const int32_t*> audio_data()\r
+ STDMETHOD (QueryInterface(REFIID, LPVOID*)) \r
{\r
- return frame_->audio_data();\r
+ return E_NOINTERFACE;\r
}\r
\r
- STDMETHOD (QueryInterface(REFIID, LPVOID*)) {return E_NOINTERFACE;}\r
STDMETHOD_(ULONG, AddRef()) \r
{\r
return ++ref_count_;\r
}\r
+\r
STDMETHOD_(ULONG, Release()) \r
{\r
- --ref_count_;\r
- if(ref_count_ == 0)\r
+ if(--ref_count_ == 0)\r
delete this;\r
return ref_count_;\r
}\r
\r
+ // IDecklinkVideoFrame\r
+\r
STDMETHOD_(long, GetWidth()) {return format_desc_.width;} \r
STDMETHOD_(long, GetHeight()) {return format_desc_.height;} \r
STDMETHOD_(long, GetRowBytes()) {return format_desc_.width*4;} \r
\r
STDMETHOD(GetBytes(void** buffer))\r
{\r
- static std::vector<uint8_t, tbb::cache_aligned_allocator<uint8_t>> zeros(1920*1080*4, 0);\r
- if(static_cast<size_t>(frame_->image_data().size()) != format_desc_.size)\r
- {\r
- *buffer = zeros.data();\r
- return S_OK;\r
- }\r
-\r
- if(!key_only_)\r
- *buffer = const_cast<uint8_t*>(frame_->image_data().begin());\r
- else\r
+ try\r
{\r
- if(key_data_.empty())\r
+ if(static_cast<size_t>(frame_->image_data().size()) != format_desc_.size)\r
{\r
- key_data_.resize(frame_->image_data().size());\r
- fast_memshfl(key_data_.data(), frame_->image_data().begin(), frame_->image_data().size(), 0x0F0F0F0F, 0x0B0B0B0B, 0x07070707, 0x03030303);\r
- frame_.reset();\r
+ data_.resize(format_desc_.size, 0);\r
+ *buffer = data_.data();\r
}\r
- *buffer = key_data_.data();\r
+ else if(key_only_)\r
+ {\r
+ if(data_.empty())\r
+ {\r
+ data_.resize(frame_->image_data().size());\r
+ fast_memshfl(data_.data(), frame_->image_data().begin(), frame_->image_data().size(), 0x0F0F0F0F, 0x0B0B0B0B, 0x07070707, 0x03030303);\r
+ frame_.reset();\r
+ }\r
+ *buffer = data_.data();\r
+ }\r
+ else\r
+ *buffer = const_cast<uint8_t*>(frame_->image_data().begin());\r
+ }\r
+ catch(...)\r
+ {\r
+ CASPAR_LOG_CURRENT_EXCEPTION();\r
+ return E_FAIL;\r
}\r
\r
return S_OK;\r
\r
STDMETHOD(GetTimecode(BMDTimecodeFormat format, IDeckLinkTimecode** timecode)){return S_FALSE;} \r
STDMETHOD(GetAncillaryData(IDeckLinkVideoFrameAncillary** ancillary)) {return S_FALSE;}\r
+\r
+ // decklink_frame \r
+\r
+ const boost::iterator_range<const int32_t*> audio_data()\r
+ {\r
+ return frame_->audio_data();\r
+ }\r
};\r
\r
struct decklink_consumer : public IDeckLinkVideoOutputCallback, public IDeckLinkAudioOutputCallback, boost::noncopyable\r