summaryrefslogtreecommitdiffstats
path: root/video
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-07-24 19:47:05 +0200
committerwm4 <wm4@nowhere>2013-07-24 19:47:05 +0200
commit202b9e8069c3eeb7fba6cc8ed27d0e7e14c4ab6d (patch)
treef13eb6339519e926aa8bdb050d2562a33abe666f /video
parent31c271f4ad1c0ee2af8d1223243f0606ef3aa735 (diff)
downloadmpv-202b9e8069c3eeb7fba6cc8ed27d0e7e14c4ab6d.tar.bz2
mpv-202b9e8069c3eeb7fba6cc8ed27d0e7e14c4ab6d.tar.xz
mp_image: create AVBuffers for all planes when converting to AVFrame
It appears the API requires you to cover all plane data with AVBuffers (that is, one AVBuffer per plane in the most general case), because certain code can make certain assumptions about this. (Insert rant about how this is barely useful and increases complexity and potential bugs.) I don't know any cases where the current code actually fails, but we want to follow the API, so do it anyway. Note that we don't really know whether or not planes are from a single memory allocation, so we have to assume the most general case and create an AVBuffer for each plane. We simply assume that the data is padded to the full stride in the last image line. All these extra dummy references are stupid, but the code might become much simpler once we only support libavcodec versions with refcounting and can use AVFrame directly.
Diffstat (limited to 'video')
-rw-r--r--video/mp_image.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/video/mp_image.c b/video/mp_image.c
index c22f3b4246..34bd143547 100644
--- a/video/mp_image.c
+++ b/video/mp_image.c
@@ -591,7 +591,15 @@ struct AVFrame *mp_image_to_av_frame_and_unref(struct mp_image *img)
int flags = 0;
if (!mp_image_is_writeable(new_ref))
flags |= AV_BUFFER_FLAG_READONLY;
- frame->buf[0] = av_buffer_create(NULL, 0, free_img, new_ref, flags);
+ for (int n = 0; n < new_ref->num_planes; n++) {
+ // Make it so that the actual image data is freed only if _all_ buffers
+ // are unreferenced.
+ struct mp_image *dummy_ref = mp_image_new_ref(new_ref);
+ void *ptr = new_ref->planes[n];
+ size_t size = new_ref->stride[n] * new_ref->h;
+ frame->buf[n] = av_buffer_create(ptr, size, free_img, dummy_ref, flags);
+ }
+ talloc_free(new_ref);
return frame;
}