Linguagem
Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Video Super Resolution (VSR) é uma tecnologia de upsampling de vídeo baseada em IA que escalona de forma inteligente fluxos de vídeo de baixa resolução de pessoas, restaurando nitidez e detalhes que, de outra forma, seriam perdidos devido a limitações de largura de banda, más condições de rede, compressão ou conteúdo de origem de baixa qualidade.
Adicionar recursos VSR ao seu aplicativo permite cenários que incluem o seguinte:
- Melhorar a qualidade de vídeo através de ligações de rede deficientes
- Otimização da largura de banda para reduzir os custos de CDN
- Cenários de alta largura de banda, como chamadas de vídeo em grupo com vários participantes
- Melhorar a qualidade do vídeo das redes sociais na edição, upload ou visualização
A funcionalidade VSR está disponível em Copilot+ PCs com NPU e em dispositivos que cumpram as especificações recomendadas CPU. Para mais informações, consulte Desenvolver aplicações de IA para PCs Copilot+ e a tabela de hardware suportado.
Hardware suportado
| Hardware | Situação | Detalhes |
|---|---|---|
| NPU (Copilot+ PC) | ✅ Disponível | Melhor desempenho. Consulte Copilot+ PCs guia para desenvolvedores. |
| CPU | ✅ Disponível | Melhor para dispositivos que cumpram as especificações recomendadas do CPU. O VSR continuará a tentar correr em dispositivos de especificações inferiores, mas a qualidade em tempo real e a taxa de fotogramas podem sofrer. |
| GPU | ❌ Não suportado | O VSR não está disponível na GPU. |
Note
A seleção de hardware é automática. Num PC Copilot+ com NPU, o VSR é sempre executado na NPU. Em dispositivos que não sejam Copilot+, o VSR corre automaticamente no CPU — não existe a opção do programador ou do utilizador final para selecionar a CPU num dispositivo Copilot+. Isto corresponde ao padrão usado por outras APIs Windows IA; veja Hardware suportado para a visão cross-API.
Essas APIs VSR usam modelos de Machine Learning (ML), foram projetadas especificamente para cenários como aplicativos de videochamada e conferência e vídeos sociais e curtos que apresentam rostos humanos falando
Atualmente, o VSR suporta os seguintes intervalos de resolução, formato e FPS:
| Attribute | Conteúdo suportado |
|---|---|
| Resolução de entrada | 240p – 1440p |
| Resolução de saída | 480p – 1440p (4K para processamento de vídeo offline) |
| Intervalo de quadros por segundo (FPS) | 15 fps – 60 fps |
| Formato de píxel de entrada | BGR (API ImageBuffer), NV12 (API Direct3D) |
| Formato de píxel de saída | BGR (ImageBuffer API), BGRA e NV12 (Direct3D API) |
Especificações recomendadas do CPU
O modelo VSR é fornecido como parte do SDK de Aplicações Windows, pelo que não existe uma etapa separada de consentimento para download ou primeira execução nos dispositivos CPU. O VSR será executado em qualquer CPU em que as restantes APIs de IA do Windows sejam executadas, mas a qualidade do redimensionamento em tempo real e a taxa de fotogramas dependem do CPU anfitrião.
Para uma boa experiência de CPU, opte por dispositivos que cumpram todas as seguintes especificações recomendadas:
- 4 ou mais núcleos físicos
- Relógio base de 3 GHz ou superior
- 32 MB ou mais de cache L3
Estas são recomendações, não mínimos rígidos — a API continuará a tentar escalar em dispositivos de especificações mais baixas. Aplicações que visam uma ampla gama de CPU devem consultar a CPU em tempo de execução e, se o dispositivo ficar abaixo da barra recomendada, recorrer a um pipeline que não seja VSR ou apresentar uma dica de compensação de qualidade ao utilizador.
Note
GetReadyState e a verificação das especificações da CPU respondem a perguntas diferentes e devem ser usados em conjunto.
GetReadyState indica se o VSR é de todo suportado no dispositivo (modelo carregado, controladores presentes, a política de hardware o permite). A verificação das especificações do CPU diz-te se o VSR corre suficientemente bem para a tua experiência de utilizador. Utilize GetReadyState para decidir se deve chamar o VSR; utilize a verificação do CPU para decidir entre o VSR e uma alternativa leve (como ampliação bilinear) em hardware no limite.
Verifique o nível de suporte ao CPU
O exemplo seguinte de C# utiliza Windows Management Instrumentation (WMI) para consultar a classe Win32_Processor e devolve true quando o dispositivo cumpre as especificações recomendadas. O exemplo utiliza o pacote NuGet System.Management publicado pela Microsoft — a biblioteca de encapsulamento padrão do .NET para WMI — para aceder ao WMI a partir de C#.
using System;
using System.Management;
private static bool MeetsRecommendedCpuSpecs()
{
const int RecommendedCores = 4;
const int RecommendedClockMhz = 3000;
const int RecommendedL3CacheKb = 32 * 1024; // 32 MB
int totalCores = 0;
int maxClockMhz = 0;
int maxL3CacheKb = 0;
using var searcher = new ManagementObjectSearcher(
"SELECT NumberOfCores, MaxClockSpeed, L3CacheSize FROM Win32_Processor");
foreach (ManagementObject processor in searcher.Get())
{
totalCores += Convert.ToInt32(processor["NumberOfCores"]);
maxClockMhz = Math.Max(maxClockMhz, Convert.ToInt32(processor["MaxClockSpeed"]));
maxL3CacheKb = Math.Max(maxL3CacheKb, Convert.ToInt32(processor["L3CacheSize"]));
}
return totalCores >= RecommendedCores
&& maxClockMhz >= RecommendedClockMhz
&& maxL3CacheKb >= RecommendedL3CacheKb;
}
Utilize o resultado para condicionar as opções de UX — por exemplo, mostrar um aviso sobre o compromisso entre qualidade e desempenho, predefinir uma resolução de saída mais baixa ou dispensar totalmente o VSR em dispositivos que não cumpram as recomendações.
Notas sobre a verificação WMI
- Armazene o resultado em cache. A primeira consulta WMI demora ~50–200 ms devido à inicialização do COM. As consultas subsequentes são rápidas, mas o padrão mais limpo é executar
MeetsRecommendedCpuSpecsuma vez no arranque e guardar o booleano em cache durante toda a vida útil do processo. O hardware da CPU não muda em tempo de execução. -
MaxClockSpeedé a frequência base nominal, não a frequência turbo. Um processador de 2,5 GHz que atinge os 4,5 GHz em modo turbo indicará2500e falhará na verificação dos 3 GHz. Isto é intencional — a taxa de transferência sustentada importa mais do que a frequência turbo de pico para cargas de trabalho de IA de streaming, como o VSR, pelo que a frequência base é o indicador certo. - Alternativa para verificações inferiores a um milissegundo. Se precisar de evitar a dependência de
System.Managementou se a sobrecarga do WMI for inaceitável (por exemplo, num percurso crítico de arranque), os mesmos dados estão disponíveis através de APIs nativas do Windows:GetLogicalProcessorInformationExdevolve o número de núcleos e os tamanhos da cache, e a velocidade nominal do relógio é disponibilizada emHKLM\HARDWARE\DESCRIPTION\System\CentralProcessor\0(valor~MHz). Estes retornam em tempo sub-milissegundo, mas requerem mais código.
Criar uma sessão VideoScaler
O exemplo a seguir mostra como criar uma sessão VSR. Primeiro, obtenha uma instância de ExecutionProviderCatalog e chame EnsureAndRegisterCertifiedAsync para carregar os modelos disponíveis. Ligue para o GetReadyState na classe VideoScaler para determinar se o escalador de vídeo está pronto para processar frames. Caso contrário, chame EnsureReadyAsync para inicializar o escalador de vídeo.
using Microsoft.Windows.AI;
using Microsoft.Windows.AI.MachineLearning;
using Microsoft.Windows.AI.Video;
private VideoScaler? _videoScaler;
protected override async Task LoadModelAsync(SampleNavigationParameters sampleParams)
{
try
{
var catalog = ExecutionProviderCatalog.GetDefault();
await catalog.EnsureAndRegisterCertifiedAsync();
var readyState = VideoScaler.GetReadyState();
if (readyState == AIFeatureReadyState.NotSupportedOnCurrentSystem)
{
// VSR cannot run on this device. Fall back to a non-VSR pipeline
// (for example, a bilinear or bicubic upscaler) or hide the feature.
ShowException(null, "Video Super Resolution is not supported on this device.");
return;
}
if (readyState == AIFeatureReadyState.NotReady)
{
var operation = await VideoScaler.EnsureReadyAsync();
if (operation.Status != AIFeatureReadyResultState.Success)
{
ShowException(null, "Video Scaler is not available.");
return;
}
}
_videoScaler = await VideoScaler.CreateAsync();
}
catch (Exception ex)
{
ShowException(ex, "Failed to load model.");
}
sampleParams.NotifyCompletion();
}
Dimensionar um Quadro de Vídeo
O exemplo de código seguinte utiliza o método VideoScaler.Scale para ampliar dados de imagem contidos num objeto VideoFrame . Você pode obter VideoFrame de uma câmera usando a classe MediaFrameReader . Para obter mais informações, consulte Processar quadros de mídia com MediaFrameReader. Você também pode usar o controle WinUI Community Toolkit CameraPreview para obter objetos VideoFrame da câmera.
Em seguida, um Direct3DSurface é obtido a partir do quadro de vídeo de entrada e outro Direct3DSurface é criado para a saída do upscaling. O VideoScaler.Scale é chamado para aumentar o frame. Neste exemplo, um controlo Image na interface de utilizador do aplicativo é atualizado com o quadro aumentado.
private async Task ProcessFrame(VideoFrame videoFrame)
{
// Process the frame with super resolution model
var processedBitmap = await Task.Run(async () =>
{
int width = 0;
int height = 0;
var inputD3dSurface = videoFrame.Direct3DSurface;
if (inputD3dSurface != null)
{
Debug.Assert(inputD3dSurface.Description.Format == Windows.Graphics.DirectX.DirectXPixelFormat.NV12, "input in NV12 format");
width = inputD3dSurface.Description.Width;
height = inputD3dSurface.Description.Height;
}
else
{
var softwareBitmap = videoFrame.SoftwareBitmap;
if (softwareBitmap == null)
{
return null;
}
Debug.Assert(softwareBitmap.BitmapPixelFormat == BitmapPixelFormat.Nv12, "input in NV12 format");
width = softwareBitmap.PixelWidth;
height = softwareBitmap.PixelHeight;
}
try
{
if (inputD3dSurface == null)
{
// Create Direct3D11-backed VideoFrame for input
using var inputVideoFrame = VideoFrame.CreateAsDirect3D11SurfaceBacked(
Windows.Graphics.DirectX.DirectXPixelFormat.NV12,
width,
height);
if (inputVideoFrame.Direct3DSurface == null)
{
return null;
}
// Copy the software bitmap to the Direct3D-backed frame
await videoFrame.CopyToAsync(inputVideoFrame);
inputD3dSurface = inputVideoFrame.Direct3DSurface;
}
// Create or resize output surface (BGRA8 format for display)
if (_outputD3dSurface == null || _outputWidth != width || _outputHeight != height)
{
_outputD3dSurface?.Dispose();
// DXGI_FORMAT_B8G8R8A8_UNORM = 87
_outputD3dSurface = Direct3DExtensions.CreateDirect3DSurface(87, width, height);
_outputWidth = width;
_outputHeight = height;
}
// Scale the frame using VideoScaler
var result = _videoScaler!.Scale(inputD3dSurface, _outputD3dSurface, new VideoScalerOptions());
if (result.Status == VideoScalerStatus.Success)
{
var outputBitmap = await SoftwareBitmap.CreateCopyFromSurfaceAsync(
_outputD3dSurface,
BitmapAlphaMode.Premultiplied);
return outputBitmap;
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"ProcessFrame error: {ex.Message}");
}
return null;
});
if (processedBitmap == null)
{
return;
}
DispatcherQueue.TryEnqueue(async () =>
{
using (processedBitmap)
{
var source = new SoftwareBitmapSource();
await source.SetBitmapAsync(processedBitmap);
ProcessedVideoImage.Source = source;
}
});
}
Dimensionar um SoftwareBitmap usando ImageBuffer
O exemplo de código seguinte demonstra o uso da classe VideoScaler para fazer upscale de um SoftwareBitmap. Este exemplo não representa um uso típico das APIs VSR. Tem menos desempenho do que usar o Direct3D. Mas você pode usar este exemplo para experimentar as APIs VSR sem configurar uma câmera ou pipeline de streaming de vídeo. Como o dimensionador de vídeo requer um BGR8 ao usar um ImageBuffer, alguns métodos auxiliares são necessários para converter o formato de pixel do SoftwareBitmap fornecido.
O código de exemplo neste artigo baseia-se no componente VSR das amostras da API de IA do Windows
public SoftwareBitmap ScaleVideoFrame(SoftwareBitmap inputFrame)
{
ImageBuffer inputImageBuffer = SoftwareBitmapExtensions.ConvertToBgr8ImageBuffer(inputFrame);
var size = (uint)(inputFrame.PixelWidth * inputFrame.PixelHeight * 3);
IBuffer outputBuffer = new global::Windows.Storage.Streams.Buffer(size);
outputBuffer.Length = size;
ImageBuffer outputImageBuffer = ImageBuffer.CreateForBuffer(
outputBuffer,
ImageBufferPixelFormat.Bgr8,
inputFrame.PixelWidth,
inputFrame.PixelHeight,
inputFrame.PixelWidth * 3);
var result = _videoScaler!.ScaleImageBuffer(inputImageBuffer, outputImageBuffer, new VideoScalerOptions());
if (result.Status != VideoScalerStatus.Success)
{
throw new Exception($"Failed to scale video frame: {result.Status}");
}
return SoftwareBitmapExtensions.ConvertBgr8ImageBufferToBgra8SoftwareBitmap(outputImageBuffer);
}
Métodos de extensão para bitmaps em software
Os seguintes métodos auxiliares convertem um SoftwareBitmap entre os formatos BGRA8 e BGR8 para corresponder aos requisitos de entrada e saída do escalar de vídeo.
public static ImageBuffer ConvertToBgr8ImageBuffer(SoftwareBitmap input)
{
var bgraBitmap = input;
if (input.BitmapPixelFormat != BitmapPixelFormat.Bgra8)
{
bgraBitmap = SoftwareBitmap.Convert(input, BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied);
}
int width = bgraBitmap.PixelWidth;
int height = bgraBitmap.PixelHeight;
byte[] bgraBuffer = new byte[width * height * 4];
bgraBitmap.CopyToBuffer(bgraBuffer.AsBuffer());
byte[] bgrBuffer = new byte[width * height * 3];
for (int i = 0, j = 0; i < bgraBuffer.Length; i += 4, j += 3)
{
bgrBuffer[j] = bgraBuffer[i];
bgrBuffer[j + 1] = bgraBuffer[i + 1];
bgrBuffer[j + 2] = bgraBuffer[i + 2];
}
return ImageBuffer.CreateForBuffer(
bgrBuffer.AsBuffer(),
ImageBufferPixelFormat.Bgr8,
width,
height,
width * 3);
}
public static SoftwareBitmap ConvertBgr8ImageBufferToBgra8SoftwareBitmap(ImageBuffer bgrImageBuffer)
{
if (bgrImageBuffer.PixelFormat != ImageBufferPixelFormat.Bgr8)
{
throw new ArgumentException("Input ImageBuffer must be in Bgr8 format");
}
int width = bgrImageBuffer.PixelWidth;
int height = bgrImageBuffer.PixelHeight;
// Get BGR data from ImageBuffer
byte[] bgrBuffer = new byte[width * height * 3];
bgrImageBuffer.CopyToByteArray(bgrBuffer);
// Create BGRA buffer (4 bytes per pixel)
byte[] bgraBuffer = new byte[width * height * 4];
for (int i = 0, j = 0; i < bgrBuffer.Length; i += 3, j += 4)
{
bgraBuffer[j] = bgrBuffer[i]; // B
bgraBuffer[j + 1] = bgrBuffer[i + 1]; // G
bgraBuffer[j + 2] = bgrBuffer[i + 2]; // R
bgraBuffer[j + 3] = 255; // A (full opacity)
}
// Create SoftwareBitmap and copy data
var softwareBitmap = new SoftwareBitmap(
BitmapPixelFormat.Bgra8,
width,
height,
BitmapAlphaMode.Premultiplied);
softwareBitmap.CopyFromBuffer(bgraBuffer.AsBuffer());
return softwareBitmap;
}
Inteligência Artificial responsável
Seguimos os princípios e práticas fundamentais descritos nos Microsoft Responsible AI Standards para garantir que estas APIs são fiáveis, seguras e construídas de forma responsável. Para mais detalhes sobre a implementação de funcionalidades de IA na sua aplicação, consulte Desenvolvimento Responsável de IA Generativa no Windows.
Essas APIs VSR usam modelos de Machine Learning (ML), foram projetadas especificamente para cenários como aplicativos de videochamada e conferência e vídeos sociais e curtos que apresentam rostos humanos falando. Por isso, não recomendamos a utilização destas APIs para vídeos nos seguintes cenários:
- Quando o vídeo contém conteúdo potencialmente sensível, o upscaling pode introduzir detalhes enganadores ou alterar identidade ou traços faciais, como imagens de indivíduos, símbolos culturais ou símbolos religiosos.
- Quando fiel, o vídeo não alterado é fundamental, como para imagens médicas, provas legais ou forenses, ou verificação de identidade.