summaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/multimedia/ffmpeg/qffmpeghwaccel.cpp25
-rw-r--r--src/plugins/multimedia/ffmpeg/qffmpeghwaccel_p.h6
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