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.
This commit is contained in:
wm4 2013-07-24 19:47:05 +02:00
parent 31c271f4ad
commit 202b9e8069
1 changed files with 9 additions and 1 deletions

View File

@ -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;
}