On Thu, Apr 13, 2017 at 5:32 AM, Aaron Levinson <alevi...@aracnet.com> wrote: > From d175e7fc94a2efc4f0bad021c118e4f907832c9c Mon Sep 17 00:00:00 2001 > From: Aaron Levinson <alevi...@aracnet.com> > Date: Wed, 12 Apr 2017 20:12:11 -0700 > Subject: [PATCH] avdevice/decklink: Removed pthread dependency > > Purpose: avdevice/decklink: Removed pthread dependency by > replacing semaphore used in code appropriately. Doing so makes it easier to > build ffmpeg using Visual C++ on Windows. This is a contination of Kyle > Schwarz's "avdevice/decklink: Remove pthread dependency" patch that is > available at https://patchwork.ffmpeg.org/patch/2654/ . This patch wasn't > accepted, and as far as I can tell, there was no follow-up after it was > rejected. > > Notes: Used Visual Studio 2015 (with update 3) for this. > > Comments: > > -- configure: Eliminated pthreads dependency for decklink_indev_deps > and decklink_outdev_deps > > -- libavdevice/decklink_common.cpp / .h: > a) Eliminated semaphore and replaced with a combination of a mutex, > condition variable, and a counter (frames_buffer_available_spots). > b) Removed include of pthread.h and semaphore.h and now using > libavutil/thread.h instead. > > -- libavdevice/decklink_dec.cpp: Eliminated include of pthread.h and > semaphore.h. > > -- libavdevice/decklink_enc.cpp: > a) Eliminated include of pthread.h and semaphore.h. > b) Replaced use of semaphore with the equivalent using a combination > of a mutex, condition variable, and a counter > (frames_buffer_available_spots). In theory, libavutil/thread.h and > the associated code could have been modified instead to add > cross-platform implementations of the sem_ functions, but an > inspection of the ffmpeg source base indicates that there are only > two cases in which semaphores are used (including this one that was > replaced), so it was deemed to not be worth the effort. > --- > configure | 4 ++-- > libavdevice/decklink_common.cpp | 3 --- > libavdevice/decklink_common.h | 5 ++++- > libavdevice/decklink_dec.cpp | 3 --- > libavdevice/decklink_enc.cpp | 23 +++++++++++++++-------- > 5 files changed, 21 insertions(+), 17 deletions(-) > > diff --git a/configure b/configure > index b0f7b1a..adb0060 100755 > --- a/configure > +++ b/configure > @@ -2992,9 +2992,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" > decklink_indev_extralibs="-lstdc++" > -decklink_outdev_deps="decklink pthreads" > +decklink_outdev_deps="decklink"
You should probably still have a dependency on "threads" (a combined dep for any threading support), or does the device work without any threading support now? > 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 c9107c0..f01fba9 100644 > --- a/libavdevice/decklink_common.cpp > +++ b/libavdevice/decklink_common.cpp > @@ -26,9 +26,6 @@ > #include <DeckLinkAPIDispatch.cpp> > #endif > > -#include <pthread.h> > -#include <semaphore.h> > - > extern "C" { > #include "libavformat/avformat.h" > #include "libavformat/internal.h" > diff --git a/libavdevice/decklink_common.h b/libavdevice/decklink_common.h > index 4753287..c12cf18 100644 > --- a/libavdevice/decklink_common.h > +++ b/libavdevice/decklink_common.h > @@ -24,6 +24,7 @@ > > #include <DeckLinkAPIVersion.h> > > +#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 8cc1bdf..67eaf97 100644 > --- a/libavdevice/decklink_dec.cpp > +++ b/libavdevice/decklink_dec.cpp > @@ -21,9 +21,6 @@ > > #include <DeckLinkAPI.h> > > -#include <pthread.h> > -#include <semaphore.h> > - > extern "C" { > #include "config.h" > #include "libavformat/avformat.h" > diff --git a/libavdevice/decklink_enc.cpp b/libavdevice/decklink_enc.cpp > index 18ef905..5105967 100644 > --- a/libavdevice/decklink_enc.cpp > +++ b/libavdevice/decklink_enc.cpp > @@ -24,9 +24,6 @@ using std::atomic; > > #include <DeckLinkAPI.h> > > -#include <pthread.h> > -#include <semaphore.h> > - > 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, > -- > 2.10.1.windows.1 > > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel