summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/video_core/command_classes/codecs/codec.cpp35
1 files changed, 21 insertions, 14 deletions
diff --git a/src/video_core/command_classes/codecs/codec.cpp b/src/video_core/command_classes/codecs/codec.cpp
index 81fac94bf..40f7755e8 100644
--- a/src/video_core/command_classes/codecs/codec.cpp
+++ b/src/video_core/command_classes/codecs/codec.cpp
@@ -56,6 +56,18 @@ AVPixelFormat GetGpuFormat(AVCodecContext* av_codec_ctx, const AVPixelFormat* pi
56 av_codec_ctx->pix_fmt = PREFERRED_CPU_FMT; 56 av_codec_ctx->pix_fmt = PREFERRED_CPU_FMT;
57 return PREFERRED_CPU_FMT; 57 return PREFERRED_CPU_FMT;
58} 58}
59
60// List all the currently available hwcontext in ffmpeg
61std::vector<AVHWDeviceType> ListSupportedContexts() {
62 std::vector<AVHWDeviceType> contexts{};
63 AVHWDeviceType current_device_type = AV_HWDEVICE_TYPE_NONE;
64 do {
65 current_device_type = av_hwdevice_iterate_types(current_device_type);
66 contexts.push_back(current_device_type);
67 } while (current_device_type != AV_HWDEVICE_TYPE_NONE);
68 return contexts;
69}
70
59} // namespace 71} // namespace
60 72
61void AVFrameDeleter(AVFrame* ptr) { 73void AVFrameDeleter(AVFrame* ptr) {
@@ -76,17 +88,6 @@ Codec::~Codec() {
76 av_buffer_unref(&av_gpu_decoder); 88 av_buffer_unref(&av_gpu_decoder);
77} 89}
78 90
79// List all the currently available hwcontext in ffmpeg
80static std::vector<AVHWDeviceType> ListSupportedContexts() {
81 std::vector<AVHWDeviceType> contexts{};
82 AVHWDeviceType current_device_type = AV_HWDEVICE_TYPE_NONE;
83 do {
84 current_device_type = av_hwdevice_iterate_types(current_device_type);
85 contexts.push_back(current_device_type);
86 } while (current_device_type != AV_HWDEVICE_TYPE_NONE);
87 return contexts;
88}
89
90bool Codec::CreateGpuAvDevice() { 91bool Codec::CreateGpuAvDevice() {
91 static constexpr auto HW_CONFIG_METHOD = AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX; 92 static constexpr auto HW_CONFIG_METHOD = AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX;
92 static const auto supported_contexts = ListSupportedContexts(); 93 static const auto supported_contexts = ListSupportedContexts();
@@ -96,6 +97,8 @@ bool Codec::CreateGpuAvDevice() {
96 LOG_DEBUG(Service_NVDRV, "{} explicitly unsupported", av_hwdevice_get_type_name(type)); 97 LOG_DEBUG(Service_NVDRV, "{} explicitly unsupported", av_hwdevice_get_type_name(type));
97 continue; 98 continue;
98 } 99 }
100 // Avoid memory leak from not cleaning up after av_hwdevice_ctx_create
101 av_buffer_unref(&av_gpu_decoder);
99 const int hwdevice_res = av_hwdevice_ctx_create(&av_gpu_decoder, type, nullptr, nullptr, 0); 102 const int hwdevice_res = av_hwdevice_ctx_create(&av_gpu_decoder, type, nullptr, nullptr, 0);
100 if (hwdevice_res < 0) { 103 if (hwdevice_res < 0) {
101 LOG_DEBUG(Service_NVDRV, "{} av_hwdevice_ctx_create failed {}", 104 LOG_DEBUG(Service_NVDRV, "{} av_hwdevice_ctx_create failed {}",
@@ -127,15 +130,19 @@ bool Codec::CreateGpuAvDevice() {
127 av_codec->name, av_hwdevice_get_type_name(type)); 130 av_codec->name, av_hwdevice_get_type_name(type));
128 break; 131 break;
129 } 132 }
130 if (config->methods & HW_CONFIG_METHOD && config->device_type == type) { 133 if ((config->methods & HW_CONFIG_METHOD) != 0 && config->device_type == type) {
131 av_codec_ctx->pix_fmt = config->pix_fmt; 134#if defined(__unix__)
132 if (config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX) { 135 // Some linux decoding backends are reported to crash with this config method
136 // TODO(ameerj): Properly support this method
137 if ((config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX) != 0) {
133 // skip zero-copy decoders, we don't currently support them 138 // skip zero-copy decoders, we don't currently support them
134 LOG_DEBUG(Service_NVDRV, "Skipping decoder {} with unsupported capability {}.", 139 LOG_DEBUG(Service_NVDRV, "Skipping decoder {} with unsupported capability {}.",
135 av_hwdevice_get_type_name(type), config->methods); 140 av_hwdevice_get_type_name(type), config->methods);
136 continue; 141 continue;
137 } 142 }
143#endif
138 LOG_INFO(Service_NVDRV, "Using {} GPU decoder", av_hwdevice_get_type_name(type)); 144 LOG_INFO(Service_NVDRV, "Using {} GPU decoder", av_hwdevice_get_type_name(type));
145 av_codec_ctx->pix_fmt = config->pix_fmt;
139 return true; 146 return true;
140 } 147 }
141 } 148 }