You've already forked FFmpeg
mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-08-15 14:13:16 +02:00
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>
This commit is contained in:
@@ -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);
|
||||||
|
Reference in New Issue
Block a user