[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