[FFmpeg-devel] [PATCH] avdevice/decklink: Removed pthread dependency
Aaron Levinson
alevinsn at aracnet.com
Thu Apr 13 06:32:07 EEST 2017
>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"
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
More information about the ffmpeg-devel
mailing list