mirror of https://github.com/mpv-player/mpv
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:
parent
31c271f4ad
commit
202b9e8069
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue