summaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/encode_lavc.c40
-rw-r--r--common/encode_lavc.h7
2 files changed, 43 insertions, 4 deletions
diff --git a/common/encode_lavc.c b/common/encode_lavc.c
index 5f9e2a0390..5d9853673b 100644
--- a/common/encode_lavc.c
+++ b/common/encode_lavc.c
@@ -103,6 +103,15 @@ static bool value_has_flag(const char *value, const char *flag)
return val; \
}
+#define CHECK_FAIL_UNLOCK(ctx, val) \
+ if (ctx && (ctx->failed || ctx->finished)) { \
+ MP_ERR(ctx, \
+ "Called a function on a %s encoding context. Bailing out.\n", \
+ ctx->failed ? "failed" : "finished"); \
+ pthread_mutex_unlock(&ctx->lock); \
+ return val; \
+ }
+
int encode_lavc_available(struct encode_lavc_context *ctx)
{
CHECK_FAIL(ctx, 0);
@@ -134,6 +143,7 @@ struct encode_lavc_context *encode_lavc_init(struct encode_output_conf *options,
mp_msg_force_stderr(global, true);
ctx = talloc_zero(NULL, struct encode_lavc_context);
+ pthread_mutex_init(&ctx->lock, NULL);
ctx->log = mp_log_new(ctx, global->log, "encode-lavc");
ctx->global = global;
encode_lavc_discontinuity(ctx);
@@ -309,6 +319,7 @@ void encode_lavc_free(struct encode_lavc_context *ctx)
encode_lavc_fail(ctx,
"called encode_lavc_free without encode_lavc_finish\n");
+ pthread_mutex_destroy(&ctx->lock);
talloc_free(ctx);
}
@@ -383,14 +394,18 @@ void encode_lavc_finish(struct encode_lavc_context *ctx)
void encode_lavc_set_video_fps(struct encode_lavc_context *ctx, float fps)
{
+ pthread_mutex_lock(&ctx->lock);
ctx->vo_fps = fps;
+ pthread_mutex_unlock(&ctx->lock);
}
void encode_lavc_set_audio_pts(struct encode_lavc_context *ctx, double pts)
{
if (ctx) {
+ pthread_mutex_lock(&ctx->lock);
ctx->last_audio_in_pts = pts;
ctx->samples_since_last_pts = 0;
+ pthread_mutex_unlock(&ctx->lock);
}
}
@@ -780,11 +795,15 @@ void encode_lavc_discontinuity(struct encode_lavc_context *ctx)
if (!ctx)
return;
- CHECK_FAIL(ctx, );
+ pthread_mutex_lock(&ctx->lock);
+
+ CHECK_FAIL_UNLOCK(ctx, );
ctx->audio_pts_offset = MP_NOPTS_VALUE;
ctx->last_video_in_pts = MP_NOPTS_VALUE;
ctx->discontinuity_pts_offset = MP_NOPTS_VALUE;
+
+ pthread_mutex_unlock(&ctx->lock);
}
static void encode_lavc_printoptions(struct mp_log *log, void *obj,
@@ -1013,7 +1032,9 @@ int encode_lavc_getstatus(struct encode_lavc_context *ctx,
if (!ctx)
return -1;
- CHECK_FAIL(ctx, -1);
+ pthread_mutex_lock(&ctx->lock);
+
+ CHECK_FAIL_UNLOCK(ctx, -1);
minutes = (now - ctx->t0) / 60.0 * (1 - f) / f;
megabytes = ctx->avc->pb ? (avio_size(ctx->avc->pb) / 1048576.0 / f) : 0;
@@ -1029,12 +1050,16 @@ int encode_lavc_getstatus(struct encode_lavc_context *ctx,
snprintf(buf, bufsize, "{%.1fmin %.1fMB}",
minutes, megabytes);
buf[bufsize - 1] = 0;
+
+ pthread_mutex_unlock(&ctx->lock);
return 0;
}
void encode_lavc_expect_stream(struct encode_lavc_context *ctx, int mt)
{
- CHECK_FAIL(ctx, );
+ pthread_mutex_lock(&ctx->lock);
+
+ CHECK_FAIL_UNLOCK(ctx, );
switch (mt) {
case AVMEDIA_TYPE_VIDEO:
@@ -1044,11 +1069,18 @@ void encode_lavc_expect_stream(struct encode_lavc_context *ctx, int mt)
ctx->expect_audio = true;
break;
}
+
+ pthread_mutex_unlock(&ctx->lock);
}
bool encode_lavc_didfail(struct encode_lavc_context *ctx)
{
- return ctx && ctx->failed;
+ if (!ctx)
+ return false;
+ pthread_mutex_lock(&ctx->lock);
+ bool fail = ctx && ctx->failed;
+ pthread_mutex_unlock(&ctx->lock);
+ return fail;
}
void encode_lavc_fail(struct encode_lavc_context *ctx, const char *format, ...)
diff --git a/common/encode_lavc.h b/common/encode_lavc.h
index deaf42b684..af7f4fba3d 100644
--- a/common/encode_lavc.h
+++ b/common/encode_lavc.h
@@ -22,6 +22,8 @@
#ifndef MPLAYER_ENCODE_LAVC_H
#define MPLAYER_ENCODE_LAVC_H
+#include <pthread.h>
+
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavutil/avstring.h>
@@ -37,6 +39,11 @@ struct encode_lavc_context {
struct encode_output_conf *options;
struct mp_log *log;
+ // All entry points must be guarded with the lock. Functions called by
+ // the playback core lock this automatically, but ao_lavc.c and vo_lavc.c
+ // must lock manually before accessing state.
+ pthread_mutex_t lock;
+
float vo_fps;
// these are processed from the options