mirror of https://github.com/mpv-player/mpv
audio: deal with AVFrame-style buffer assignments
In the AVFrame-style system (which we inreasingly map our internal data stuctures on), buffers and plane pointers don't necessarily have a 1:1 correspondence. For example, a single buffer could cover 2 or more planes, all while other planes are covered by a second buffer, and so on. They don't need to be ordered in the same way. Change mp_audio_get_allocated_size() to retrieve the maximum size all planes provide. This also considers the case of planes not pointing to buffer start. Change mp_audio_realloc() to reset all planes, even if corresponding buffers are not reallocated. (The caller has to be careful anyway if it wants to be sure the contents are preserved on realloc calls.)
This commit is contained in:
parent
0d2456ae5f
commit
627b87b0d8
|
@ -160,8 +160,8 @@ void mp_audio_realloc(struct mp_audio *mpa, int samples)
|
||||||
if (!mpa->allocated[n] || size != mpa->allocated[n]->size) {
|
if (!mpa->allocated[n] || size != mpa->allocated[n]->size) {
|
||||||
if (av_buffer_realloc(&mpa->allocated[n], size) < 0)
|
if (av_buffer_realloc(&mpa->allocated[n], size) < 0)
|
||||||
abort(); // OOM
|
abort(); // OOM
|
||||||
mpa->planes[n] = mpa->allocated[n]->data;
|
|
||||||
}
|
}
|
||||||
|
mpa->planes[n] = mpa->allocated[n]->data;
|
||||||
}
|
}
|
||||||
for (int n = mpa->num_planes; n < MP_NUM_CHANNELS; n++) {
|
for (int n = mpa->num_planes; n < MP_NUM_CHANNELS; n++) {
|
||||||
av_buffer_unref(&mpa->allocated[n]);
|
av_buffer_unref(&mpa->allocated[n]);
|
||||||
|
@ -192,8 +192,18 @@ int mp_audio_get_allocated_size(struct mp_audio *mpa)
|
||||||
{
|
{
|
||||||
int size = 0;
|
int size = 0;
|
||||||
for (int n = 0; n < mpa->num_planes; n++) {
|
for (int n = 0; n < mpa->num_planes; n++) {
|
||||||
int s = mpa->allocated[n] ? mpa->allocated[n]->size / mpa->sstride : 0;
|
for (int i = 0; i < MP_NUM_CHANNELS && mpa->allocated[i]; i++) {
|
||||||
size = n == 0 ? s : MPMIN(size, s);
|
uint8_t *start = mpa->allocated[i]->data;
|
||||||
|
uint8_t *end = start + mpa->allocated[i]->size;
|
||||||
|
uint8_t *plane = mpa->planes[n];
|
||||||
|
if (plane >= start && plane < end) {
|
||||||
|
int s = MPMIN((end - plane) / mpa->sstride, INT_MAX);
|
||||||
|
size = n == 0 ? s : MPMIN(size, s);
|
||||||
|
goto next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0; // plane is not covered by any buffer
|
||||||
|
next: ;
|
||||||
}
|
}
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,8 +37,11 @@ struct mp_audio {
|
||||||
int num_planes; // number of planes
|
int num_planes; // number of planes
|
||||||
int bps; // size of sub-samples (af_fmt2bps(format))
|
int bps; // size of sub-samples (af_fmt2bps(format))
|
||||||
|
|
||||||
// private
|
// --- private
|
||||||
bool readonly;
|
bool readonly;
|
||||||
|
// These do not necessarily map directly to planes[]. They can have
|
||||||
|
// different order or count. There shouldn't be more buffers than planes.
|
||||||
|
// If allocated[n] is NULL, allocated[n+1] must also be NULL.
|
||||||
struct AVBufferRef *allocated[MP_NUM_CHANNELS];
|
struct AVBufferRef *allocated[MP_NUM_CHANNELS];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue