mirror of
https://github.com/mpv-player/mpv
synced 2024-12-27 09:32:40 +00:00
fc8c1fcfb2
This commit fixes a bug where handle for a framebuffer gets double freed. It seems to happen that the same prime fd gets two framebuffers. As the prime fd is the same the resulting prime handle is also the same. This means one handle but 2 framebuffers and can lead to the following chain: 1. The first framebuffer gets deleted the handle gets also freed via the ioctl. 2. In startup phase not all 4 dumb buffers for overlay drawing are set up. It can happen that the last dumb buffer gets the handle we freed above. 3. The second framebuffer gets freed and the handle will be freed again resulting that the 4's dumb buffer handle is not backed by a buffer. 4. Drm prime continues to assign handles to its prime fds an will lead to have this handle which was just freed to reassign again but to an prime buffer. 5.Now the overlay should be drawn into dumb buffer 4 which still has the same handle but is backed by the wrong buffer. This leads to two different behaviors: - MPV crashes as the drm prime buffers size als calculated by the decoder output format. The overlay output format differs and it takes more space. SO the size check in kernel fails. - MPV is continuing play. This happens when the decoders allocates a bigger buffer than needed for the overlay. For example overlay is Full HD and decoder output is 4k. This leads to the behavior das the overlay wil be drawn into the wrong buffer as its a drm prime buffer and results in a flicker every fourth step.
46 lines
1.8 KiB
C
46 lines
1.8 KiB
C
/*
|
|
* This file is part of mpv.
|
|
*
|
|
* mpv is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* mpv is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with mpv. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#ifndef DRM_PRIME_H
|
|
#define DRM_PRIME_H
|
|
|
|
#include <libavutil/hwcontext_drm.h>
|
|
|
|
#include "common/msg.h"
|
|
|
|
struct drm_prime_framebuffer {
|
|
uint32_t fb_id;
|
|
uint32_t gem_handles[AV_DRM_MAX_PLANES];
|
|
};
|
|
|
|
struct drm_prime_handle_refs {
|
|
uint32_t *handle_ref_count;
|
|
size_t size;
|
|
void *ctx;
|
|
};
|
|
|
|
int drm_prime_create_framebuffer(struct mp_log *log, int fd, AVDRMFrameDescriptor *descriptor, int width, int height,
|
|
struct drm_prime_framebuffer *framebuffers,
|
|
struct drm_prime_handle_refs *handle_refs);
|
|
void drm_prime_destroy_framebuffer(struct mp_log *log, int fd, struct drm_prime_framebuffer *framebuffers,
|
|
struct drm_prime_handle_refs *handle_refs);
|
|
void drm_prime_init_handle_ref_count(void *talloc_parent, struct drm_prime_handle_refs *handle_refs);
|
|
void drm_prime_add_handle_ref(struct drm_prime_handle_refs *handle_refs, uint32_t handle);
|
|
void drm_prime_remove_handle_ref(struct drm_prime_handle_refs *handle_refs, uint32_t handle);
|
|
uint32_t drm_prime_get_handle_ref_count(struct drm_prime_handle_refs *handle_refs, uint32_t handle);
|
|
#endif // DRM_PRIME_H
|