diff --git a/configure b/configure index 98f7828489..3f2811a5b3 100755 --- a/configure +++ b/configure @@ -2995,9 +2995,9 @@ avfoundation_indev_deps="pthreads" avfoundation_indev_extralibs="-framework Foundation -framework AVFoundation -framework CoreVideo -framework CoreMedia" bktr_indev_deps_any="dev_bktr_ioctl_bt848_h machine_ioctl_bt848_h dev_video_bktr_ioctl_bt848_h dev_ic_bt8xx_h" caca_outdev_deps="libcaca" -decklink_indev_deps="decklink pthreads" +decklink_indev_deps="decklink threads" decklink_indev_extralibs="-lstdc++" -decklink_outdev_deps="decklink pthreads" +decklink_outdev_deps="decklink threads" decklink_outdev_extralibs="-lstdc++" dshow_indev_deps="IBaseFilter" dshow_indev_extralibs="-lpsapi -lole32 -lstrmiids -luuid -loleaut32 -lshlwapi" diff --git a/libavdevice/decklink_common.cpp b/libavdevice/decklink_common.cpp index c9107c036a..f01fba953e 100644 --- a/libavdevice/decklink_common.cpp +++ b/libavdevice/decklink_common.cpp @@ -26,9 +26,6 @@ #include #endif -#include -#include - extern "C" { #include "libavformat/avformat.h" #include "libavformat/internal.h" diff --git a/libavdevice/decklink_common.h b/libavdevice/decklink_common.h index 4753287ecf..c12cf18d70 100644 --- a/libavdevice/decklink_common.h +++ b/libavdevice/decklink_common.h @@ -24,6 +24,7 @@ #include +#include "libavutil/thread.h" #include "decklink_common_c.h" class decklink_output_callback; @@ -89,7 +90,9 @@ struct decklink_ctx { int frames_preroll; int frames_buffer; - sem_t semaphore; + pthread_mutex_t mutex; + pthread_cond_t cond; + int frames_buffer_available_spots; int channels; }; diff --git a/libavdevice/decklink_dec.cpp b/libavdevice/decklink_dec.cpp index 8cc1bdf7c9..67eaf97e89 100644 --- a/libavdevice/decklink_dec.cpp +++ b/libavdevice/decklink_dec.cpp @@ -21,9 +21,6 @@ #include -#include -#include - extern "C" { #include "config.h" #include "libavformat/avformat.h" diff --git a/libavdevice/decklink_enc.cpp b/libavdevice/decklink_enc.cpp index 18ef9058e2..5105967101 100644 --- a/libavdevice/decklink_enc.cpp +++ b/libavdevice/decklink_enc.cpp @@ -24,9 +24,6 @@ using std::atomic; #include -#include -#include - extern "C" { #include "libavformat/avformat.h" #include "libavformat/internal.h" @@ -91,7 +88,10 @@ public: av_frame_unref(avframe); - sem_post(&ctx->semaphore); + pthread_mutex_lock(&ctx->mutex); + ctx->frames_buffer_available_spots++; + pthread_cond_broadcast(&ctx->cond); + pthread_mutex_unlock(&ctx->mutex); return S_OK; } @@ -133,7 +133,6 @@ static int decklink_setup_video(AVFormatContext *avctx, AVStream *st) ctx->output_callback = new decklink_output_callback(); ctx->dlo->SetScheduledFrameCompletionCallback(ctx->output_callback); - /* Start video semaphore. */ ctx->frames_preroll = st->time_base.den * ctx->preroll; if (st->time_base.den > 1000) ctx->frames_preroll /= 1000; @@ -141,7 +140,9 @@ static int decklink_setup_video(AVFormatContext *avctx, AVStream *st) /* Buffer twice as many frames as the preroll. */ ctx->frames_buffer = ctx->frames_preroll * 2; ctx->frames_buffer = FFMIN(ctx->frames_buffer, 60); - sem_init(&ctx->semaphore, 0, ctx->frames_buffer); + pthread_mutex_init(&ctx->mutex, NULL); + pthread_cond_init(&ctx->cond, NULL); + ctx->frames_buffer_available_spots = ctx->frames_buffer; /* The device expects the framerate to be fixed. */ avpriv_set_pts_info(st, 64, st->time_base.num, st->time_base.den); @@ -211,7 +212,8 @@ av_cold int ff_decklink_write_trailer(AVFormatContext *avctx) if (ctx->output_callback) delete ctx->output_callback; - sem_destroy(&ctx->semaphore); + pthread_mutex_destroy(&ctx->mutex); + pthread_cond_destroy(&ctx->cond); av_freep(&cctx->ctx); @@ -247,7 +249,12 @@ static int decklink_write_video_packet(AVFormatContext *avctx, AVPacket *pkt) } /* Always keep at most one second of frames buffered. */ - sem_wait(&ctx->semaphore); + pthread_mutex_lock(&ctx->mutex); + while (ctx->frames_buffer_available_spots == 0) { + pthread_cond_wait(&ctx->cond, &ctx->mutex); + } + ctx->frames_buffer_available_spots--; + pthread_mutex_unlock(&ctx->mutex); /* Schedule frame for playback. */ hr = ctx->dlo->ScheduleVideoFrame((struct IDeckLinkVideoFrame *) frame,