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 <cus@passwd.hu>
pull/288/head
Marton Balint 7 years ago
parent 643123b29d
commit ba8a1d1618
  1. 1
      libavdevice/decklink_common.h
  2. 35
      libavdevice/decklink_dec.cpp

@ -56,7 +56,6 @@ struct decklink_ctx {
IDeckLinkConfiguration *cfg; IDeckLinkConfiguration *cfg;
IDeckLinkAttributes *attr; IDeckLinkAttributes *attr;
decklink_output_callback *output_callback; decklink_output_callback *output_callback;
decklink_input_callback *input_callback;
/* DeckLink mode information */ /* DeckLink mode information */
BMDTimeValue bmd_tb_den; BMDTimeValue bmd_tb_den;

@ -596,8 +596,7 @@ public:
virtual HRESULT STDMETHODCALLTYPE VideoInputFrameArrived(IDeckLinkVideoInputFrame*, IDeckLinkAudioInputPacket*); virtual HRESULT STDMETHODCALLTYPE VideoInputFrameArrived(IDeckLinkVideoInputFrame*, IDeckLinkAudioInputPacket*);
private: private:
ULONG m_refCount; std::atomic<int> _refs;
pthread_mutex_t m_mutex;
AVFormatContext *avctx; AVFormatContext *avctx;
decklink_ctx *ctx; decklink_ctx *ctx;
int no_video; int no_video;
@ -605,42 +604,30 @@ private:
int64_t initial_audio_pts; 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; avctx = _avctx;
decklink_cctx *cctx = (struct decklink_cctx *)avctx->priv_data; decklink_cctx *cctx = (struct decklink_cctx *)avctx->priv_data;
ctx = (struct decklink_ctx *)cctx->ctx; ctx = (struct decklink_ctx *)cctx->ctx;
no_video = 0; no_video = 0;
initial_audio_pts = initial_video_pts = AV_NOPTS_VALUE; initial_audio_pts = initial_video_pts = AV_NOPTS_VALUE;
pthread_mutex_init(&m_mutex, NULL);
} }
decklink_input_callback::~decklink_input_callback() decklink_input_callback::~decklink_input_callback()
{ {
pthread_mutex_destroy(&m_mutex);
} }
ULONG decklink_input_callback::AddRef(void) ULONG decklink_input_callback::AddRef(void)
{ {
pthread_mutex_lock(&m_mutex); return ++_refs;
m_refCount++;
pthread_mutex_unlock(&m_mutex);
return (ULONG)m_refCount;
} }
ULONG decklink_input_callback::Release(void) ULONG decklink_input_callback::Release(void)
{ {
pthread_mutex_lock(&m_mutex); int ret = --_refs;
m_refCount--; if (!ret)
pthread_mutex_unlock(&m_mutex);
if (m_refCount == 0) {
delete this; delete this;
return 0; return ret;
}
return (ULONG)m_refCount;
} }
static int64_t get_pkt_pts(IDeckLinkVideoInputFrame *videoFrame, 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_cctx *cctx = (struct decklink_cctx *)avctx->priv_data;
struct decklink_ctx *ctx; struct decklink_ctx *ctx;
class decklink_allocator *allocator; class decklink_allocator *allocator;
class decklink_input_callback *input_callback;
AVStream *st; AVStream *st;
HRESULT result; HRESULT result;
char fname[1024]; char fname[1024];
@ -1056,8 +1044,13 @@ av_cold int ff_decklink_read_header(AVFormatContext *avctx)
goto error; goto error;
} }
ctx->input_callback = new decklink_input_callback(avctx); input_callback = new decklink_input_callback(avctx);
ctx->dli->SetCallback(ctx->input_callback); 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(); allocator = new decklink_allocator();
ret = (ctx->dli->SetVideoInputFrameMemoryAllocator(allocator) == S_OK ? 0 : AVERROR_EXTERNAL); ret = (ctx->dli->SetVideoInputFrameMemoryAllocator(allocator) == S_OK ? 0 : AVERROR_EXTERNAL);

Loading…
Cancel
Save