В настоящее время я пишу небольшое приложение, которое показывает предварительный просмотр с камеры телефона с помощью справки SharpDX. Для тех, кто имеет учетную запись разработчика nokia, код в основном состоит из this article.Отображение предварительного просмотра камеры с использованием DirectX Texture2D вызывает колебания на Windows Phone 8
Проблема
Иногда, кажется, что предыдущие кадры рисуются на screeb (далее «видео» прыгает вперед и назад), для разрушения второго, который выглядит как колебания/мерцание.
Я думал о проблеме с потоками (поскольку обработчик события PreviewFrameAvailable вызывается другим потоком, чем метод, который отвечает за рендеринг), но вставка инструкции блокировки в оба метода делает код слишком медленным (частота кадров падает ниже 15 кадров/сек).
Есть ли у кого-нибудь идеи, как решить эту проблему или как синхронизировать синхронизацию потоков в этом случае, не теряя слишком высокой производительности?
Код
Во-первых, все ресурсы создаются, в то время как устройство является допустимым экземпляром GraphicsDevice:
spriteBatch = new SpriteBatch(device);
photoDevice = await PhotoCaptureDevice.OpenAsync(CameraSensorLocation.Back, captureSize);
photoDevice.FocusRegion = null;
width = (int)photoDevice.PreviewResolution.Width;
height = (int)photoDevice.PreviewResolution.Height;
previewData = new int[width * height];
cameraTexture = Texture2D.New(device, width, height, PixelFormat.B8G8R8A8.UNorm);
photoDevice.PreviewFrameAvailable += photoDevice_PreviewFrameAvailable;
Затем, когда изменения предварительного просмотра кадров, я установить данные текстуры:
void photoDevice_PreviewFrameAvailable(ICameraCaptureDevice sender, object args)
{
sender.GetPreviewBufferArgb(previewData);
cameraTexture.SetData(previewData);
}
Наконец, текстура рисуется с использованием SpriteBatch в то время как параметры backBufferCenter, textureC входить, textureScaling и Math.PI/2 используются для центрирования и настроить текстуру в альбомной ориентации:
spriteBatch.Begin();
spriteBatch.Draw(cameraTexture, backBufferCenter, null, Color.White, (float)Math.PI/2, textureCenter, textureScaling, SpriteEffects.None, 1.0f);
spriteBatch.End();
Способ визуализации называют игровым классом SharpDX, который в основном использует интерфейс IDrawingSurfaceBackgroundContentProvider, который является компонентом called by the DrawingSurfaceBackgroundGrid времени работы Windows Phone 8.
Решение
Дополнительно к раствору Olydis (смотри ниже), я также должен был установить Game.IsFixedTimeStep ложь, из-за ошибки SharpDX (см это issue on GitHub для деталей).
Кроме того, не безопасно вызывать sender.GetPreviewBufferArgb(previewData)
внутри обработчика PreviewFrameAvailable, из-за перекрестный доступ потоков. См. Соответствующую резьбу в windows phone developer community.