2013-09-11 4 views
2

В настоящее время я пишу небольшое приложение, которое показывает предварительный просмотр с камеры телефона с помощью справки 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.

ответ

1

Мой Guess

Как вы уже догадались, я также уверен, что это может быть связано с потоками. Я подозреваю, что, например, относительно длинный вызов SetData может быть перехвачен вызовом Draw, что приведет к неожиданному выводу.

Решение

Следующее решение не использует синхронизацию, но вместо этого перемещает «критические» части (доступ к текстурам) в том же контекст.

Кроме того, давайте выделим два int[] вместо одного, который мы будем использовать чередующимся образом.

Код Фрагменты

void photoDevice_PreviewFrameAvailable(ICameraCaptureDevice sender, object args) 
{ 
    sender.GetPreviewBufferArgb(previewData2); 
    // swap buffers 
    var previewDataTemp = previewData1; 
    previewData1 = previewData2; 
    previewData2 = previewDataTemp; 
} 

Затем добавьте в ваш Draw вызова (или равного контекста):

cameraTexture.SetData(previewData1); 

Заключение

Это должно практически предотвратить проблему, так как только «полностью обновлены» текстуры, и там я s нет согласованного доступа к ним. Использование двух int[] снижает риск возникновения SetData и GetPreviewBufferArgb доступа тот же массив одновременно - тем не менее, он не исключает риска (но понятия не имею, если одновременный доступ к int[] может привести к странным поведением в первую очередь).