[FFmpeg-devel] [PATCH] avdevice/decklink: Removed pthread dependency
Hendrik Leppkes
h.leppkes at gmail.com
Thu Apr 13 11:21:27 EEST 2017
On Thu, Apr 13, 2017 at 5:32 AM, Aaron Levinson <alevinsn at aracnet.com> wrote:
> From d175e7fc94a2efc4f0bad021c118e4f907832c9c Mon Sep 17 00:00:00 2001
> From: Aaron Levinson <alevinsn at 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 at ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
More information about the ffmpeg-devel
mailing list