Closed benstevens48 closed 2 months ago
Are you sure that this is a bug and not the fact that these features could have been backported to this version of Windows 11? Checking in the latest Windows 11 SDK shows that CreateAv1 is available. The metadata also has CreateAv1 available.
That metadata is what Windows itself has in System32. So the result isn't an error.
I just installed the new 26100 SDK, used MediaEncodingProfile.CreateAv1, and it still hangs in the same way. It really should never hang so there's a bug there anyway.
Maybe the bug is that it just doesn't work.
Alternatively, it's not supposed to work currently, in which case there ought to be a way to tell that. It's possible that in fact the encoding capability is going to be added to an update to the AV1 Video Extensions package, which may be released at the same time as the 24H2 update, and then it will work down-level, but in the meantime how can we tell whether it's supported?
One of the big issues here is:
I don't see anything that you mention happening. My GPU (Radeon 7800 XT) does support hardware AV1 encoding though.
Out of curiosity, if you query for your encoders using Windows.Media.Core.CodecQuery, does that show an available AV1 encoder? I have one:
Encoder name: AMDh264Encoder
Encoder name: AMDh265Encoder
Encoder name: AMDh264Encoder
Encoder name: AMDav1Encoder <-- Here
Encoder name: AMDh265Encoder
Encoder name: HEIFImageExtension
Encoder name: VP9VideoExtensionEncoder
Encoder name: HEVCVideoExtensionEncoder
Encoder name: HEVCVideoExtensionEncoder
Encoder name: H264 Encoder MFT
Encoder name: WMVideo8 Encoder MFT
Encoder name: H263 Encoder MFT
Encoder name: WMVideo9 Encoder MFT
Encoder name: Microsoft MPEG-2 Video Encoder MFT
As I stated, my system does have hardware AV1 encoding.
When I say it hangs, I mean encoding hangs i.e.
var encodingProfile = MediaEncodingProfile.CreateAv1(VideoEncodingQuality.HD720p);
var preparedTranscoder = await transcoder.PrepareStreamTranscodeAsync(inputStream, outputStream, encodingProfile);
if (!preparedTranscoder.CanTranscode) {
return;
}
await preparedTranscoder.TranscodeAsync(); //Hangs here
Yes, apparently I do have a hardware encoder - Intel® Hardware Accelerated AV1 Encoder MFT.
That means that, if there is a bug, the bug isn't in the AV1 functionality exposed by WinRT. The transcoding functionality should be built upon Windows Media Foundation, and it is the Media Foundation object that is responsible for all of the work here. Now, there are two major questions, first how large is the file that you are transcoding? Transcoding isn't a fast process, and on my system a file that I was using for testing does take around a minute.
Another thing to remember is that TranscodeAsync returns an IAsyncActionWithProgress. This means that you can hook a progress routine up to it and have it report progress. Have you done that?
An example of this is:
winrt::Windows::Foundation::IAsyncAction MainWindow::Click_Click(winrt::IInspectable const &, winrt::RoutedEventArgs const &)
{
auto profile = Windows::Media::MediaProperties::MediaEncodingProfile::CreateAv1(Windows::Media::MediaProperties::VideoEncodingQuality::HD720p);
auto in_file = co_await Windows::Storage::StorageFile::GetFileFromPathAsync(LR"(C:\Users\Darran\Documents\wpin.mkv)");
auto out_folder = co_await Windows::Storage::StorageFolder::GetFolderFromPathAsync(LR"(C:\Users\Darran\Documents)");
Windows::Storage::StorageFile out_file{ nullptr };
auto out_file_list = co_await out_folder.GetFilesAsync();
for (auto file : out_file_list)
{
if (file.Name() == L"wpout.mp4")
{
out_file = file;
}
}
if (out_file == nullptr)
{
out_file = co_await out_folder.CreateFileAsync(L"wpout.mp4");
}
Windows::Media::Transcoding::MediaTranscoder transcoder{};
auto prep_transcoder = co_await transcoder.PrepareFileTranscodeAsync(in_file, out_file, profile);
if (prep_transcoder.CanTranscode())
{
//Note that there is no co_await here.
auto transcode_async = prep_transcoder.TranscodeAsync();
//Add a callback to the Progress member, which is IAsyncActionWithProgress<double>.Progress.
transcode_async.Progress([this](const Windows::Foundation::IAsyncActionWithProgress<double> &async_info, const double &progress)
{
DispatcherQueue().TryEnqueue([this, progress]() {
auto fmt_string = std::format(L"{}", progress);
Content().Text(fmt_string);
}
);
});
//Now we co_await the async transcoder.
co_await transcode_async;
}
Content().Text(L"File encode complete");
co_return;
}
It is C++ due to that being more comfortable for me, but this basically hooks up a progress callback, and this sets the contents of a TextBox to the stringified version of that progress.
As you can see, it is progressing. Finally, after it does report the transcode as complete:
The out file has a pretty substantial file size. The video track is around 20 minutes and CBR, so that is what I would expect.
Secondly, are your video drivers up to date? Since this is hardware encoding and if you really are seeing a hang, then this would mean that the Intel video drivers are a good candidate for the bug.
The video is only small and takes a few seconds to encode to H.264 or H.265. I have been using the progress. Some interesting notes on this.
Also, on a related note, while testing supported container and encoding types, I found that trying to use NV12 with a MPEG-4 container (not designed to be supported I guess) will freeze the app.
In conclusion, it seems like AV1 video encoding is not really currently supported, at least on my machine. Probably a software encoder is needed (i.e. an updated AV1 Video Extension package that supports encoding).
I thought that maybe this was the reason that the API was not available in an earlier SDK, but I guess perhaps the IsMethodPresent etc check will never be enough for this sort of scenario so I am going to change the title to reflect how to reliably test for encoding support. Meanwile, in my app I will just mark AV1 encoding as experimental.
Logged an internal bug for the media team. Closing as External.
Describe the bug
I am trying to determine whether video encoding using AV1 is supported. To do this I check ApiInformation.IsMethodPresent("Windows.Media.MediaProperties.MediaEncodingProfile", "CreateAv1"). However, this returns true on my machine, even though it says in the docs "Windows 11 Insider Preview (introduced in 10.0.23504.0)" and the method is not available when compiling (I am using the 22621 Windows SDK, not any insider preview SDK) and my machine is running 23H2. It's annoying because if I do try to encode AV1 video (not using this method but by using the "Av1" subtype string), it hangs indefinitely. I am struggling to think of how to limit the functionality. Maybe I will have to do a manual Windows version check, but I don't really want to do that.
Steps to reproduce the bug
See description
Expected behavior
ApiInformation.IsMethodPresent (and other related functions) should return false if the method is not really available. If the method is experimental or in preview, then there should be some way to determine that (and I can't see it, but please correct me if I'm wrong).
Screenshots
No response
NuGet package version
None
Packaging type
Packaged (MSIX)
Windows version
Windows 11 version 22H2 (22621, 2022 Update)
IDE
Visual Studio 2022
Additional context
Does not require WindAppSDK, is a WinRT issue.