mirror of
https://github.com/mpv-player/mpv
synced 2025-02-27 02:40:53 +00:00
encode: get rid of the recursion that led to a deadlock.
Instead, the recursive call has been flattened away by instead overwriting a parameter and continuing.
This commit is contained in:
parent
309eb6398c
commit
ee2e91dce1
@ -331,6 +331,7 @@ static int play(struct ao *ao, void **data, int samples, int flags)
|
|||||||
int bufpos = 0;
|
int bufpos = 0;
|
||||||
double nextpts;
|
double nextpts;
|
||||||
double outpts;
|
double outpts;
|
||||||
|
int orig_samples = samples;
|
||||||
|
|
||||||
pthread_mutex_lock(&ectx->lock);
|
pthread_mutex_lock(&ectx->lock);
|
||||||
|
|
||||||
@ -346,28 +347,20 @@ static int play(struct ao *ao, void **data, int samples, int flags)
|
|||||||
|
|
||||||
size_t num_planes = af_fmt_is_planar(ao->format) ? ao->channels.num : 1;
|
size_t num_planes = af_fmt_is_planar(ao->format) ? ao->channels.num : 1;
|
||||||
|
|
||||||
if (flags & AOPLAY_FINAL_CHUNK) {
|
void *tempdata = NULL;
|
||||||
int written = 0;
|
|
||||||
if (samples > 0) {
|
|
||||||
void *tmp = talloc_new(NULL);
|
|
||||||
size_t bytelen = samples * ao->sstride;
|
|
||||||
size_t extralen = (ac->aframesize - 1) * ao->sstride;
|
|
||||||
void *padded[MP_NUM_CHANNELS];
|
|
||||||
for (int n = 0; n < num_planes; n++) {
|
|
||||||
padded[n] = talloc_size(tmp, bytelen + extralen);
|
|
||||||
memcpy(padded[n], data[n], bytelen);
|
|
||||||
af_fill_silence((char *)padded[n] + bytelen, extralen, ao->format);
|
|
||||||
}
|
|
||||||
// No danger of recursion, because AOPLAY_FINAL_CHUNK not set
|
|
||||||
written = play(ao, padded, (bytelen + extralen) / ao->sstride, 0);
|
|
||||||
if (written < samples) {
|
|
||||||
MP_ERR(ao, "did not write enough data at the end\n");
|
|
||||||
}
|
|
||||||
talloc_free(tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_mutex_unlock(&ectx->lock);
|
if ((flags & AOPLAY_FINAL_CHUNK) && (samples % ac->aframesize)) {
|
||||||
return FFMIN(written, samples);
|
tempdata = talloc_new(NULL);
|
||||||
|
size_t bytelen = samples * ao->sstride;
|
||||||
|
size_t extralen = (ac->aframesize - 1) * ao->sstride;
|
||||||
|
void *padded[MP_NUM_CHANNELS];
|
||||||
|
for (int n = 0; n < num_planes; n++) {
|
||||||
|
padded[n] = talloc_size(tempdata, bytelen + extralen);
|
||||||
|
memcpy(padded[n], data[n], bytelen);
|
||||||
|
af_fill_silence((char *)padded[n] + bytelen, extralen, ao->format);
|
||||||
|
}
|
||||||
|
data = padded;
|
||||||
|
samples = (bytelen + extralen) / ao->sstride;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pts == MP_NOPTS_VALUE) {
|
if (pts == MP_NOPTS_VALUE) {
|
||||||
@ -457,8 +450,20 @@ static int play(struct ao *ao, void **data, int samples, int flags)
|
|||||||
ectx->next_in_pts = nextpts;
|
ectx->next_in_pts = nextpts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
talloc_free(tempdata);
|
||||||
pthread_mutex_unlock(&ectx->lock);
|
pthread_mutex_unlock(&ectx->lock);
|
||||||
return bufpos;
|
|
||||||
|
if (flags & AOPLAY_FINAL_CHUNK) {
|
||||||
|
if (bufpos < orig_samples) {
|
||||||
|
MP_ERR(ao, "did not write enough data at the end\n");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (bufpos > orig_samples) {
|
||||||
|
MP_ERR(ao, "audio buffer overflow (should never happen)\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FFMIN(bufpos, orig_samples);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void drain(struct ao *ao)
|
static void drain(struct ao *ao)
|
||||||
|
Loading…
Reference in New Issue
Block a user