From ba8a1d161820f9e5f1485118a0f508e312f69a8b Mon Sep 17 00:00:00 2001 From: Marton Balint Date: Mon, 4 Jun 2018 10:27:42 +0200 Subject: [PATCH] avdevice/decklink_dec: use std::atomic for decklink_input_callback refcounting Also remove the callback from the context, and add proper error handling. Signed-off-by: Marton Balint --- libavdevice/decklink_common.h | 1 - libavdevice/decklink_dec.cpp | 35 ++++++++++++++--------------------- 2 files changed, 14 insertions(+), 22 deletions(-) diff --git a/libavdevice/decklink_common.h b/libavdevice/decklink_common.h index 57ee7d1d68..f416134b8a 100644 --- a/libavdevice/decklink_common.h +++ b/libavdevice/decklink_common.h @@ -56,7 +56,6 @@ struct decklink_ctx { IDeckLinkConfiguration *cfg; IDeckLinkAttributes *attr; decklink_output_callback *output_callback; - decklink_input_callback *input_callback; /* DeckLink mode information */ BMDTimeValue bmd_tb_den; diff --git a/libavdevice/decklink_dec.cpp b/libavdevice/decklink_dec.cpp index 897fca1003..974ee1d94c 100644 --- a/libavdevice/decklink_dec.cpp +++ b/libavdevice/decklink_dec.cpp @@ -596,8 +596,7 @@ public: virtual HRESULT STDMETHODCALLTYPE VideoInputFrameArrived(IDeckLinkVideoInputFrame*, IDeckLinkAudioInputPacket*); private: - ULONG m_refCount; - pthread_mutex_t m_mutex; + std::atomic _refs; AVFormatContext *avctx; decklink_ctx *ctx; int no_video; @@ -605,42 +604,30 @@ private: int64_t initial_audio_pts; }; -decklink_input_callback::decklink_input_callback(AVFormatContext *_avctx) : m_refCount(0) +decklink_input_callback::decklink_input_callback(AVFormatContext *_avctx) : _refs(1) { avctx = _avctx; decklink_cctx *cctx = (struct decklink_cctx *)avctx->priv_data; ctx = (struct decklink_ctx *)cctx->ctx; no_video = 0; initial_audio_pts = initial_video_pts = AV_NOPTS_VALUE; - pthread_mutex_init(&m_mutex, NULL); } decklink_input_callback::~decklink_input_callback() { - pthread_mutex_destroy(&m_mutex); } ULONG decklink_input_callback::AddRef(void) { - pthread_mutex_lock(&m_mutex); - m_refCount++; - pthread_mutex_unlock(&m_mutex); - - return (ULONG)m_refCount; + return ++_refs; } ULONG decklink_input_callback::Release(void) { - pthread_mutex_lock(&m_mutex); - m_refCount--; - pthread_mutex_unlock(&m_mutex); - - if (m_refCount == 0) { + int ret = --_refs; + if (!ret) delete this; - return 0; - } - - return (ULONG)m_refCount; + return ret; } static int64_t get_pkt_pts(IDeckLinkVideoInputFrame *videoFrame, @@ -966,6 +953,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; + class decklink_input_callback *input_callback; AVStream *st; HRESULT result; char fname[1024]; @@ -1056,8 +1044,13 @@ av_cold int ff_decklink_read_header(AVFormatContext *avctx) goto error; } - ctx->input_callback = new decklink_input_callback(avctx); - ctx->dli->SetCallback(ctx->input_callback); + input_callback = new decklink_input_callback(avctx); + ret = (ctx->dli->SetCallback(input_callback) == S_OK ? 0 : AVERROR_EXTERNAL); + input_callback->Release(); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "Cannot set input callback\n"); + goto error; + } allocator = new decklink_allocator(); ret = (ctx->dli->SetVideoInputFrameMemoryAllocator(allocator) == S_OK ? 0 : AVERROR_EXTERNAL);