summaryrefslogtreecommitdiffstats
path: root/audio/out/ao_lavc.c
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-03-08 23:38:53 +0100
committerwm4 <wm4@nowhere>2014-03-09 00:19:35 +0100
commit5ffd6a9e9b7a0d894d7513ad20c24c2727426ecd (patch)
treef87a9c927774d8829ab2a920dcd857d2ee54a4e2 /audio/out/ao_lavc.c
parentb48d09a89dd14616e5ae4e9d017b921486d5f541 (diff)
downloadmpv-5ffd6a9e9b7a0d894d7513ad20c24c2727426ecd.tar.bz2
mpv-5ffd6a9e9b7a0d894d7513ad20c24c2727426ecd.tar.xz
encode: add locking
Since the AO will run in a thread, and there's lots of shared state with encoding, we have to add locking. One case this doesn't handle correctly are the encode_lavc_available() calls in ao_lavc.c and vo_lavc.c. They don't do much (and usually only to protect against doing --ao=lavc with normal playback), and changing it would be a bit messy. So just leave them.
Diffstat (limited to 'audio/out/ao_lavc.c')
-rw-r--r--audio/out/ao_lavc.c23
1 files changed, 19 insertions, 4 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;
}