diff options
Diffstat (limited to 'src/plugins')
| -rw-r--r-- | src/plugins/multimedia/ffmpeg/qffmpeghwaccel.cpp | 25 | ||||
| -rw-r--r-- | src/plugins/multimedia/ffmpeg/qffmpeghwaccel_p.h | 6 |
2 files changed, 24 insertions, 7 deletions
diff --git a/src/plugins/multimedia/ffmpeg/qffmpeghwaccel.cpp b/src/plugins/multimedia/ffmpeg/qffmpeghwaccel.cpp index cb6c1696b..6e78f8eb6 100644 --- a/src/plugins/multimedia/ffmpeg/qffmpeghwaccel.cpp +++ b/src/plugins/multimedia/ffmpeg/qffmpeghwaccel.cpp @@ -405,7 +405,16 @@ AVHWFramesContext *HWAccel::hwFramesContext() const static void deleteHwFrameContextData(AVHWFramesContext *context) { - delete reinterpret_cast<HwFrameContextData *>(context->user_opaque); + std::unique_ptr<HwFrameContextData> contextData( + static_cast<HwFrameContextData *>(context->user_opaque)); + Q_ASSERT(contextData); + + if (contextData->avDeleter) { + context->user_opaque = contextData->avUserOpaque; + context->free = contextData->avDeleter; + + context->free(context); + } } HwFrameContextData &HwFrameContextData::ensure(AVFrame &hwFrame) @@ -413,15 +422,19 @@ HwFrameContextData &HwFrameContextData::ensure(AVFrame &hwFrame) Q_ASSERT(hwFrame.hw_frames_ctx && hwFrame.hw_frames_ctx->data); auto context = reinterpret_cast<AVHWFramesContext *>(hwFrame.hw_frames_ctx->data); - if (!context->user_opaque) { - context->user_opaque = new HwFrameContextData; - Q_ASSERT(!context->free); + + if (context->free != deleteHwFrameContextData) { + // In most cases, we expect null context->free and context->user_opaque. + // However, FFmpeg decoding implementations for specific graphic card backends + // may set a custom deleter. Let's save the deleter and its data (user_opaque) + // to invoke it in deleteHwFrameContextData. + context->user_opaque = new HwFrameContextData{ context->free, context->user_opaque }; context->free = deleteHwFrameContextData; } else { - Q_ASSERT(context->free == deleteHwFrameContextData); + Q_ASSERT(context->user_opaque); } - return *reinterpret_cast<HwFrameContextData *>(context->user_opaque); + return *static_cast<HwFrameContextData *>(context->user_opaque); } AVFrameUPtr copyFromHwPool(AVFrameUPtr frame) diff --git a/src/plugins/multimedia/ffmpeg/qffmpeghwaccel_p.h b/src/plugins/multimedia/ffmpeg/qffmpeghwaccel_p.h index 64aeb098c..d2f9ed0b3 100644 --- a/src/plugins/multimedia/ffmpeg/qffmpeghwaccel_p.h +++ b/src/plugins/multimedia/ffmpeg/qffmpeghwaccel_p.h @@ -47,7 +47,11 @@ using HWAccelUPtr = std::unique_ptr<HWAccel>; */ struct HwFrameContextData { - QRhiValueMapper<TextureConverter> textureConverterMapper; + using AVHWFramesContextDeleter = void (*)(struct AVHWFramesContext *ctx); + AVHWFramesContextDeleter avDeleter = nullptr; + void *avUserOpaque = nullptr; + + QRhiValueMapper<TextureConverter> textureConverterMapper = {}; /** * @brief gets or creates an instance of the class, associated with |
