summaryrefslogtreecommitdiff
path: root/libavdevice/decklink_dec.cpp
diff options
context:
space:
mode:
authorMarton Balint <cus@passwd.hu>2018-06-04 10:02:46 +0200
committerMarton Balint <cus@passwd.hu>2018-06-13 00:09:48 +0200
commit643123b29d4072f27be9b348d03069b648dbddf9 (patch)
tree818682e7ecbe871f56f8f04bd872719e5ba62a5d /libavdevice/decklink_dec.cpp
parent8a0c2901f1fa1cd4b2cf8f347840e4465d65cbae (diff)
downloadffmpeg-643123b29d4072f27be9b348d03069b648dbddf9.tar.gz
avdevice/decklink_dec: use a custom memory allocator
The default memory allocator is limited in the max number of frames available, and therefore caused frame drops if the frames were not freed fast enough. Signed-off-by: Marton Balint <cus@passwd.hu>
Diffstat (limited to 'libavdevice/decklink_dec.cpp')
-rw-r--r--libavdevice/decklink_dec.cpp50
1 files changed, 50 insertions, 0 deletions
diff --git a/libavdevice/decklink_dec.cpp b/libavdevice/decklink_dec.cpp
index 510637676c..897fca1003 100644
--- a/libavdevice/decklink_dec.cpp
+++ b/libavdevice/decklink_dec.cpp
@@ -21,6 +21,9 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <atomic>
+using std::atomic;
+
/* Include internal.h first to avoid conflict between winsock.h (used by
* DeckLink headers) and winsock2.h (used by libavformat) in MSVC++ builds */
extern "C" {
@@ -98,6 +101,44 @@ static VANCLineNumber vanc_line_numbers[] = {
{bmdModeUnknown, 0, -1, -1, -1}
};
+class decklink_allocator : public IDeckLinkMemoryAllocator
+{
+public:
+ decklink_allocator(): _refs(1) { }
+ virtual ~decklink_allocator() { }
+
+ // IDeckLinkMemoryAllocator methods
+ virtual HRESULT STDMETHODCALLTYPE AllocateBuffer(unsigned int bufferSize, void* *allocatedBuffer)
+ {
+ void *buf = av_malloc(bufferSize + AV_INPUT_BUFFER_PADDING_SIZE);
+ if (!buf)
+ return E_OUTOFMEMORY;
+ *allocatedBuffer = buf;
+ return S_OK;
+ }
+ virtual HRESULT STDMETHODCALLTYPE ReleaseBuffer(void* buffer)
+ {
+ av_free(buffer);
+ return S_OK;
+ }
+ virtual HRESULT STDMETHODCALLTYPE Commit() { return S_OK; }
+ virtual HRESULT STDMETHODCALLTYPE Decommit() { return S_OK; }
+
+ // IUnknown methods
+ virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, LPVOID *ppv) { return E_NOINTERFACE; }
+ virtual ULONG STDMETHODCALLTYPE AddRef(void) { return ++_refs; }
+ virtual ULONG STDMETHODCALLTYPE Release(void)
+ {
+ int ret = --_refs;
+ if (!ret)
+ delete this;
+ return ret;
+ }
+
+private:
+ std::atomic<int> _refs;
+};
+
extern "C" {
static void decklink_object_free(void *opaque, uint8_t *data)
{
@@ -924,6 +965,7 @@ av_cold int ff_decklink_read_header(AVFormatContext *avctx)
{
struct decklink_cctx *cctx = (struct decklink_cctx *)avctx->priv_data;
struct decklink_ctx *ctx;
+ class decklink_allocator *allocator;
AVStream *st;
HRESULT result;
char fname[1024];
@@ -1017,6 +1059,14 @@ av_cold int ff_decklink_read_header(AVFormatContext *avctx)
ctx->input_callback = new decklink_input_callback(avctx);
ctx->dli->SetCallback(ctx->input_callback);
+ allocator = new decklink_allocator();
+ ret = (ctx->dli->SetVideoInputFrameMemoryAllocator(allocator) == S_OK ? 0 : AVERROR_EXTERNAL);
+ allocator->Release();
+ if (ret < 0) {
+ av_log(avctx, AV_LOG_ERROR, "Cannot set custom memory allocator\n");
+ goto error;
+ }
+
if (mode_num == 0 && !cctx->format_code) {
if (decklink_autodetect(cctx) < 0) {
av_log(avctx, AV_LOG_ERROR, "Cannot Autodetect input stream or No signal\n");