summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--audio/out/ao_lavc.c23
-rw-r--r--common/encode_lavc.c40
-rw-r--r--common/encode_lavc.h7
-rw-r--r--video/out/vo_lavc.c53
4 files changed, 99 insertions, 24 deletions
diff --git a/audio/out/ao_lavc.c b/audio/out/ao_lavc.c
index 7d31f63ec9..afb021f7a0 100644
--- a/audio/out/ao_lavc.c
+++ b/audio/out/ao_lavc.c
@@ -102,12 +102,14 @@ static int init(struct ao *ao)
return -1;
}
+ pthread_mutex_lock(&ao->encode_lavc_ctx->lock);
+
ac->stream = encode_lavc_alloc_stream(ao->encode_lavc_ctx,
AVMEDIA_TYPE_AUDIO);
if (!ac->stream) {
MP_ERR(ao, "could not get a new audio stream\n");
- return -1;
+ goto fail;
}
codec = encode_lavc_get_codec(ao->encode_lavc_ctx, ac->stream);
@@ -126,7 +128,7 @@ static int init(struct ao *ao)
struct mp_chmap_sel sel = {0};
mp_chmap_sel_add_any(&sel);
if (!ao_chmap_sel_adjust(ao, &sel, &ao->channels))
- return -1;
+ goto fail;
mp_chmap_reorder_to_lavc(&ao->channels);
ac->stream->codec->channels = ao->channels.num;
ac->stream->codec->channel_layout = mp_chmap_to_lavc(&ao->channels);
@@ -140,7 +142,7 @@ static int init(struct ao *ao)
ac->stream->codec->bits_per_raw_sample = ac->sample_size * 8;
if (encode_lavc_open_codec(ao->encode_lavc_ctx, ac->stream) < 0)
- return -1;
+ goto fail;
ac->pcmhack = 0;
if (ac->stream->codec->frame_size <= 1)
@@ -169,7 +171,12 @@ static int init(struct ao *ao)
ao->untimed = true;
+ pthread_mutex_unlock(&ao->encode_lavc_ctx->lock);
return 0;
+
+fail:
+ pthread_mutex_unlock(&ao->encode_lavc_ctx->lock);
+ return -1;
}
// close audio device
@@ -179,8 +186,11 @@ static void uninit(struct ao *ao, bool cut_audio)
struct priv *ac = ao->priv;
struct encode_lavc_context *ectx = ao->encode_lavc_ctx;
+ pthread_mutex_lock(&ectx->lock);
+
if (!encode_lavc_start(ectx)) {
MP_WARN(ao, "not even ready to encode audio at end -> dropped");
+ pthread_mutex_unlock(&ectx->lock);
return;
}
@@ -192,7 +202,7 @@ static void uninit(struct ao *ao, bool cut_audio)
while (encode(ao, outpts, NULL) > 0) ;
}
- ao->priv = NULL;
+ pthread_mutex_unlock(&ectx->lock);
}
// return: how many bytes can be played without blocking
@@ -323,8 +333,11 @@ static int play(struct ao *ao, void **data, int samples, int flags)
double nextpts;
double outpts;
+ pthread_mutex_lock(&ectx->lock);
+
if (!encode_lavc_start(ectx)) {
MP_WARN(ao, "not ready yet for encoding audio\n");
+ pthread_mutex_unlock(&ectx->lock);
return 0;
}
@@ -354,6 +367,7 @@ static int play(struct ao *ao, void **data, int samples, int flags)
talloc_free(tmp);
}
+ pthread_mutex_unlock(&ectx->lock);
return FFMIN(written, samples);
}
@@ -444,6 +458,7 @@ static int play(struct ao *ao, void **data, int samples, int flags)
ectx->next_in_pts = nextpts;
}
+ pthread_mutex_unlock(&ectx->lock);
return bufpos;
}
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
diff --git a/video/out/vo_lavc.c b/video/out/vo_lavc.c
index e96556b1e8..b5176ebcb4 100644
--- a/video/out/vo_lavc.c
+++ b/video/out/vo_lavc.c
@@ -74,19 +74,21 @@ static int preinit(struct vo *vo)
return 0;
}
-static void draw_image(struct vo *vo, mp_image_t *mpi);
+static void draw_image_unlocked(struct vo *vo, mp_image_t *mpi);
static void uninit(struct vo *vo)
{
struct priv *vc = vo->priv;
if (!vc)
return;
+ pthread_mutex_lock(&vo->encode_lavc_ctx->lock);
+
if (vc->lastipts >= 0 && vc->stream)
- draw_image(vo, NULL);
+ draw_image_unlocked(vo, NULL);
mp_image_unrefp(&vc->lastimg);
- vo->priv = NULL;
+ pthread_mutex_unlock(&vo->encode_lavc_ctx->lock);
}
static int reconfig(struct vo *vo, struct mp_image_params *params, int flags)
@@ -101,6 +103,8 @@ static int reconfig(struct vo *vo, struct mp_image_params *params, int flags)
if (!vc)
return -1;
+ pthread_mutex_lock(&vo->encode_lavc_ctx->lock);
+
display_aspect_ratio.num = params->d_w;
display_aspect_ratio.den = params->d_h;
image_aspect_ratio.num = width;
@@ -123,7 +127,7 @@ static int reconfig(struct vo *vo, struct mp_image_params *params, int flags)
vc->stream->codec->sample_aspect_ratio.den,
aspect.num, aspect.den);
}
- return 0;
+ goto done;
}
/* FIXME Is it possible with raw video? */
@@ -168,9 +172,12 @@ static int reconfig(struct vo *vo, struct mp_image_params *params, int flags)
mp_image_unrefp(&vc->lastimg);
+done:
+ pthread_mutex_unlock(&vo->encode_lavc_ctx->lock);
return 0;
error:
+ pthread_mutex_unlock(&vo->encode_lavc_ctx->lock);
uninit(vo);
return -1;
}
@@ -182,14 +189,12 @@ static int query_format(struct vo *vo, uint32_t format)
if (!vo->encode_lavc_ctx)
return 0;
- if (!encode_lavc_supports_pixfmt(vo->encode_lavc_ctx, pix_fmt))
- return 0;
-
- return
- VFCAP_CSP_SUPPORTED |
- // we can do it
- VFCAP_CSP_SUPPORTED_BY_HW;
- // we don't convert colorspaces here
+ pthread_mutex_lock(&vo->encode_lavc_ctx->lock);
+ int flags = 0;
+ if (encode_lavc_supports_pixfmt(vo->encode_lavc_ctx, pix_fmt))
+ flags = VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW;
+ pthread_mutex_unlock(&vo->encode_lavc_ctx->lock);
+ return flags;
}
static void write_packet(struct vo *vo, int size, AVPacket *packet)
@@ -272,7 +277,7 @@ static int encode_video(struct vo *vo, AVFrame *frame, AVPacket *packet)
}
}
-static void draw_image(struct vo *vo, mp_image_t *mpi)
+static void draw_image_unlocked(struct vo *vo, mp_image_t *mpi)
{
struct priv *vc = vo->priv;
struct encode_lavc_context *ectx = vo->encode_lavc_ctx;
@@ -479,6 +484,13 @@ static void draw_image(struct vo *vo, mp_image_t *mpi)
}
}
+static void draw_image(struct vo *vo, mp_image_t *mpi)
+{
+ pthread_mutex_lock(&vo->encode_lavc_ctx->lock);
+ draw_image_unlocked(vo, mpi);
+ pthread_mutex_unlock(&vo->encode_lavc_ctx->lock);
+}
+
static void flip_page_timed(struct vo *vo, int64_t pts_us, int duration)
{
}
@@ -487,6 +499,8 @@ static void draw_osd(struct vo *vo, struct osd_state *osd)
{
struct priv *vc = vo->priv;
+ pthread_mutex_lock(&vo->encode_lavc_ctx->lock);
+
if (vc->lastimg && vc->lastimg_wants_osd && vo->params) {
struct mp_osd_res dim = osd_res_from_image_params(vo->params);
@@ -495,11 +509,15 @@ static void draw_osd(struct vo *vo, struct osd_state *osd)
osd_draw_on_image(osd, dim, osd_get_vo_pts(osd), OSD_DRAW_SUB_ONLY,
vc->lastimg);
}
+
+ pthread_mutex_unlock(&vo->encode_lavc_ctx->lock);
}
static int control(struct vo *vo, uint32_t request, void *data)
{
struct priv *vc = vo->priv;
+ int r = VO_NOTIMPL;
+ pthread_mutex_lock(&vo->encode_lavc_ctx->lock);
switch (request) {
case VOCTRL_SET_YUV_COLORSPACE:
vc->colorspace = *(struct mp_csp_details *)data;
@@ -509,12 +527,15 @@ static int control(struct vo *vo, uint32_t request, void *data)
vc->colorspace.format = encode_lavc_get_csp(vo->encode_lavc_ctx, vc->stream);
vc->colorspace.levels_out = encode_lavc_get_csp_levels(vo->encode_lavc_ctx, vc->stream);
}
- return 1;
+ r = 1;
+ break;
case VOCTRL_GET_YUV_COLORSPACE:
*(struct mp_csp_details *)data = vc->colorspace;
- return 1;
+ r = 1;
+ break;
}
- return VO_NOTIMPL;
+ pthread_mutex_unlock(&vo->encode_lavc_ctx->lock);
+ return r;
}
const struct vo_driver video_out_lavc = {