diff options
author | wm4 <wm4@nowhere> | 2014-11-11 21:20:21 +0100 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2014-11-11 21:20:21 +0100 |
commit | d4cc41bbcd378d30a3c52c5342c395e7f64539ca (patch) | |
tree | 23d1883cb41ce40d9a33a12a94596e39e625738e /audio/audio.c | |
parent | 475226c783cd3ce17a90ee5312727e013b2436cf (diff) | |
download | mpv-d4cc41bbcd378d30a3c52c5342c395e7f64539ca.tar.bz2 mpv-d4cc41bbcd378d30a3c52c5342c395e7f64539ca.tar.xz |
audio: make sure AVFrame is actually refcounted
The mp_audio_from_avframe() function requires the AVFrame to be
refcounted, and merely increases its refcount while referencing the same
data. For non-refcounted frames, it simply did nothing and potentially
would make the caller pass around a frame with dangling pointers.
(libavcodec should always return refcounted frames, but it's not clear
what other code does; and also the function should simply work, instead
of having weird requirements on its arguments.)
Diffstat (limited to 'audio/audio.c')
-rw-r--r-- | audio/audio.c | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/audio/audio.c b/audio/audio.c index 24539e6db5..0458e813e7 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -272,6 +272,7 @@ int mp_audio_make_writeable(struct mp_audio *data) struct mp_audio *mp_audio_from_avframe(struct AVFrame *avframe) { + AVFrame *tmp = NULL; struct mp_audio *new = talloc_zero(NULL, struct mp_audio); talloc_set_destructor(new, mp_audio_destructor); @@ -290,6 +291,16 @@ struct mp_audio *mp_audio_from_avframe(struct AVFrame *avframe) mp_audio_set_channels(new, &lavc_chmap); + // Force refcounted frame. + if (!avframe->buf[0]) { + tmp = av_frame_alloc(); + if (!tmp) + goto fail; + if (av_frame_ref(tmp, avframe) < 0) + goto fail; + avframe = tmp; + } + // If we can't handle the format (e.g. too many channels), bail out. if (!mp_audio_config_valid(new) || avframe->nb_extended_buf) goto fail; @@ -312,6 +323,7 @@ struct mp_audio *mp_audio_from_avframe(struct AVFrame *avframe) fail: talloc_free(new); + av_frame_free(&tmp); return NULL; } |