Major rework to bump up the framerate.
Changed the interface between the Native and Managed, simplified the usage of the buffers.
This commit is contained in:
Родитель
f93eaf0804
Коммит
10b339be27
|
@ -1,16 +1,114 @@
|
|||
ipch/*
|
||||
Debug/*
|
||||
ARM/*
|
||||
*/Debug/*
|
||||
*/ARM/*
|
||||
*/ipch/*
|
||||
*/Generated Files/*
|
||||
*/Bin/*
|
||||
*/PerfLogs/*
|
||||
*/obj/*
|
||||
*.sdf
|
||||
*.bak
|
||||
# Build Folders (you can keep bin if you'd like, to store dlls and pdbs)
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
|
||||
# mstest test results
|
||||
TestResults
|
||||
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.opensdf
|
||||
*.user
|
||||
*.pfx
|
||||
*.sln.docstates
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Rr]elease/
|
||||
x64/
|
||||
*_i.c
|
||||
*_p.c
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*
|
||||
|
||||
# Mindbench SASS cache
|
||||
.sass-cache/
|
||||
|
||||
# NCrunch
|
||||
*.ncrunch*
|
||||
.*crunch*.local.xml
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish
|
||||
|
||||
# Publish Web Output
|
||||
*.Publish.xml
|
||||
|
||||
# NuGet Packages Directory
|
||||
packages
|
||||
|
||||
# Windows Azure Build Output
|
||||
csx
|
||||
*.build.csdef
|
||||
|
||||
# Windows Store app package directory
|
||||
AppPackages/
|
||||
|
||||
# Others
|
||||
sql
|
||||
TestResults
|
||||
[Tt]est[Rr]esult*
|
||||
*.Cache
|
||||
ClientBin
|
||||
[Ss]tyle[Cc]op.*
|
||||
~$*
|
||||
*.dbmdl
|
||||
Generated_Code #added for RIA/Silverlight projects
|
||||
|
||||
# Backup & report files from converting an old project file to a newer
|
||||
# Visual Studio version. Backup files are not needed, because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
|
||||
# SQL Server files
|
||||
App_Data/*.mdf
|
||||
App_Data/*.ldf
|
||||
|
||||
|
|
|
@ -0,0 +1,136 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|ARM">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>ARM</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|ARM">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>ARM</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{b54d292c-6154-413f-9c4c-d4a08cdb7edf}</ProjectGuid>
|
||||
<RootNamespace>CameraEffectInterface</RootNamespace>
|
||||
<DefaultLanguage>en-US</DefaultLanguage>
|
||||
<MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
|
||||
<WinMDAssembly>true</WinMDAssembly>
|
||||
<ProjectName>CameraEffectInterface</ProjectName>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v110_wp80</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v110_wp80</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PlatformToolset>v110_wp80</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PlatformToolset>v110_wp80</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<GenerateManifest>false</GenerateManifest>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>_WINRT_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<AdditionalUsingDirectories>$(WindowsSDK_MetadataPath);$(AdditionalUsingDirectories)</AdditionalUsingDirectories>
|
||||
<CompileAsWinRT>true</CompileAsWinRT>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
|
||||
<IgnoreSpecificDefaultLibraries>ole32.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
|
||||
<GenerateWindowsMetadata>true</GenerateWindowsMetadata>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>_WINRT_DLL;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<AdditionalUsingDirectories>$(WindowsSDK_MetadataPath);$(AdditionalUsingDirectories)</AdditionalUsingDirectories>
|
||||
<CompileAsWinRT>true</CompileAsWinRT>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
|
||||
<IgnoreSpecificDefaultLibraries>ole32.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
|
||||
<GenerateWindowsMetadata>true</GenerateWindowsMetadata>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>_WINRT_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<AdditionalUsingDirectories>$(WindowsSDK_MetadataPath);$(AdditionalUsingDirectories)</AdditionalUsingDirectories>
|
||||
<CompileAsWinRT>true</CompileAsWinRT>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
|
||||
<IgnoreSpecificDefaultLibraries>ole32.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
|
||||
<GenerateWindowsMetadata>true</GenerateWindowsMetadata>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>_WINRT_DLL;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<AdditionalUsingDirectories>$(WindowsSDK_MetadataPath);$(AdditionalUsingDirectories)</AdditionalUsingDirectories>
|
||||
<CompileAsWinRT>true</CompileAsWinRT>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
|
||||
<IgnoreSpecificDefaultLibraries>ole32.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
|
||||
<GenerateWindowsMetadata>true</GenerateWindowsMetadata>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="platform.winmd">
|
||||
<IsWinMDFile>true</IsWinMDFile>
|
||||
<Private>false</Private>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="ICameraEffect.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="ICameraEffect.cpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<Import Project="$(MSBuildExtensionsPath)\Microsoft\WindowsPhone\v$(TargetPlatformVersion)\Microsoft.Cpp.WindowsPhone.$(TargetPlatformVersion).targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
|
@ -0,0 +1,6 @@
|
|||
// ICameraEffect.cpp
|
||||
#include "ICameraEffect.h"
|
||||
|
||||
using namespace CameraEffectInterface;
|
||||
using namespace Platform;
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
#pragma once
|
||||
|
||||
namespace CameraEffectInterface
|
||||
{
|
||||
/// <summary>
|
||||
/// The ICameraEffect interface definition
|
||||
/// This interface can be implemented either from managed or from native code.
|
||||
/// </summary>
|
||||
|
||||
public interface class ICameraEffect {
|
||||
|
||||
/// <summary>
|
||||
/// The camera device, the effect will poll the preview frames from it
|
||||
/// </summary>
|
||||
property Windows::Phone::Media::Capture::PhotoCaptureDevice^ CaptureDevice
|
||||
{
|
||||
void set( Windows::Phone::Media::Capture::PhotoCaptureDevice^ captureDevice);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The buffer where image data is written once the effect has been applied.
|
||||
/// </summary>
|
||||
property Windows::Storage::Streams::IBuffer^ OutputBuffer
|
||||
{
|
||||
void set( Windows::Storage::Streams::IBuffer^ OutputBuffer );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The dimensions of the output buffer
|
||||
/// </summary>
|
||||
property Windows::Foundation::Size OutputBufferSize
|
||||
{
|
||||
void set( Windows::Foundation::Size outputBufferSize);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a frame from the camera and apply an effect on it
|
||||
/// </summary>
|
||||
/// <param name="processedBuffer">A buffer with the camera data with the effect applied</param>
|
||||
/// <returns>A task that completes when effect has been applied</returns>
|
||||
Windows::Foundation::IAsyncAction^ GetNewFrameAndApplyEffect();
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Change the type of effect
|
||||
/// </summary>
|
||||
void ChangeEffectType();
|
||||
|
||||
};
|
||||
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Resources">
|
||||
<UniqueIdentifier>5fd0e509-b6ae-4f29-bd2a-4d2cc10f3aa0</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="ICameraEffect.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="ICameraEffect.h" />
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -5,6 +5,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NativeFilterDemo", "NativeF
|
|||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NativeComponent", "NativeComponent\NativeComponent.vcxproj", "{ECCD1443-9EAA-4666-BC16-6AA5B5C11BA2}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CameraEffectInterface", "CameraEffectInterface\CameraEffectInterface.vcxproj", "{B54D292C-6154-413F-9C4C-D4A08CDB7EDF}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
@ -67,6 +69,24 @@ Global
|
|||
{ECCD1443-9EAA-4666-BC16-6AA5B5C11BA2}.Release|Win32.Build.0 = Release|Win32
|
||||
{ECCD1443-9EAA-4666-BC16-6AA5B5C11BA2}.Release|x86.ActiveCfg = Release|Win32
|
||||
{ECCD1443-9EAA-4666-BC16-6AA5B5C11BA2}.Release|x86.Build.0 = Release|Win32
|
||||
{B54D292C-6154-413F-9C4C-D4A08CDB7EDF}.Debug|Any CPU.ActiveCfg = Debug|Win32
|
||||
{B54D292C-6154-413F-9C4C-D4A08CDB7EDF}.Debug|ARM.ActiveCfg = Debug|ARM
|
||||
{B54D292C-6154-413F-9C4C-D4A08CDB7EDF}.Debug|ARM.Build.0 = Debug|ARM
|
||||
{B54D292C-6154-413F-9C4C-D4A08CDB7EDF}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
|
||||
{B54D292C-6154-413F-9C4C-D4A08CDB7EDF}.Debug|Mixed Platforms.Build.0 = Debug|Win32
|
||||
{B54D292C-6154-413F-9C4C-D4A08CDB7EDF}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{B54D292C-6154-413F-9C4C-D4A08CDB7EDF}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{B54D292C-6154-413F-9C4C-D4A08CDB7EDF}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{B54D292C-6154-413F-9C4C-D4A08CDB7EDF}.Debug|x86.Build.0 = Debug|Win32
|
||||
{B54D292C-6154-413F-9C4C-D4A08CDB7EDF}.Release|Any CPU.ActiveCfg = Release|Win32
|
||||
{B54D292C-6154-413F-9C4C-D4A08CDB7EDF}.Release|ARM.ActiveCfg = Release|ARM
|
||||
{B54D292C-6154-413F-9C4C-D4A08CDB7EDF}.Release|ARM.Build.0 = Release|ARM
|
||||
{B54D292C-6154-413F-9C4C-D4A08CDB7EDF}.Release|Mixed Platforms.ActiveCfg = Release|Win32
|
||||
{B54D292C-6154-413F-9C4C-D4A08CDB7EDF}.Release|Mixed Platforms.Build.0 = Release|Win32
|
||||
{B54D292C-6154-413F-9C4C-D4A08CDB7EDF}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{B54D292C-6154-413F-9C4C-D4A08CDB7EDF}.Release|Win32.Build.0 = Release|Win32
|
||||
{B54D292C-6154-413F-9C4C-D4A08CDB7EDF}.Release|x86.ActiveCfg = Release|Win32
|
||||
{B54D292C-6154-413F-9C4C-D4A08CDB7EDF}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
// NativeComponent.cpp
|
||||
|
||||
#include "pch.h"
|
||||
#include <client.h>
|
||||
#include <windows.h>
|
||||
#include "NativeComponent.h"
|
||||
#include <robuffer.h>
|
||||
#if defined(_M_ARM)
|
||||
#include <arm_neon.h>
|
||||
#endif
|
||||
|
@ -10,46 +11,77 @@
|
|||
using namespace NativeComponent;
|
||||
using namespace Platform;
|
||||
using namespace Windows::Phone::Media::Capture;
|
||||
using namespace Windows::Foundation;
|
||||
using namespace Windows::Storage::Streams;
|
||||
using namespace Microsoft::WRL;
|
||||
|
||||
WindowsPhoneRuntimeComponent::WindowsPhoneRuntimeComponent()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
void WindowsPhoneRuntimeComponent::Initialize(Windows::Phone::Media::Capture::PhotoCaptureDevice^ captureDevice)
|
||||
void WindowsPhoneRuntimeComponent::CaptureDevice::set (PhotoCaptureDevice^ device)
|
||||
{
|
||||
m_camera = captureDevice;
|
||||
Windows::Foundation::Size viewfinderResolution = m_camera->PreviewResolution;
|
||||
|
||||
m_processingFrame = false;
|
||||
|
||||
m_camera = device;
|
||||
Windows::Foundation::Size cameraFrameResolution = device->PreviewResolution;
|
||||
int numberOfPixels = int(cameraFrameResolution.Width) * int (cameraFrameResolution.Height);
|
||||
m_cameraPreviewBuffer = ref new Array<int>(numberOfPixels);
|
||||
}
|
||||
|
||||
|
||||
void WindowsPhoneRuntimeComponent::NewViewfinderFrame( Platform::WriteOnlyArray<int,1U>^ inputBuffer,
|
||||
Platform::WriteOnlyArray<uint8,1U>^ outputBuffer)
|
||||
void WindowsPhoneRuntimeComponent::OutputBuffer::set (Windows::Storage::Streams::IBuffer^ outputBuffer)
|
||||
{
|
||||
m_camera->GetPreviewBufferArgb(inputBuffer);
|
||||
#if defined(_M_ARM)
|
||||
ConvertToGrayNeon(inputBuffer,outputBuffer );
|
||||
#else
|
||||
ConvertToGrayOriginal(inputBuffer, outputBuffer);
|
||||
#endif
|
||||
|
||||
|
||||
// Com magic to retrieve the pointer to the pixel buffer.
|
||||
Object^ obj = outputBuffer;
|
||||
ComPtr<IInspectable> insp(reinterpret_cast<IInspectable*>(obj));
|
||||
ComPtr<IBufferByteAccess> bufferByteAccess;
|
||||
ThrowIfFailed(insp.As(&bufferByteAccess));
|
||||
m_pixelsBuffer = nullptr;
|
||||
ThrowIfFailed(bufferByteAccess->Buffer(&m_pixelsBuffer));
|
||||
}
|
||||
|
||||
void WindowsPhoneRuntimeComponent::OutputBufferSize::set (Windows::Foundation::Size bufferSize)
|
||||
{
|
||||
m_outputBufferSize = bufferSize;
|
||||
}
|
||||
|
||||
IAsyncAction^ WindowsPhoneRuntimeComponent::GetNewFrameAndApplyEffect()
|
||||
{
|
||||
return concurrency::create_async([this](){
|
||||
|
||||
m_camera->GetPreviewBufferArgb(m_cameraPreviewBuffer);
|
||||
|
||||
#if defined(_M_ARM)
|
||||
ConvertToGrayNeon(m_cameraPreviewBuffer,m_pixelsBuffer);
|
||||
#else
|
||||
ConvertToGrayOriginal(m_cameraPreviewBuffer,m_pixelsBuffer);
|
||||
#endif
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
void WindowsPhoneRuntimeComponent::ChangeEffectType()
|
||||
{
|
||||
}
|
||||
|
||||
// The gray convertion and its NEON optimization is copied from http://hilbert-space.de/?p=22
|
||||
|
||||
void WindowsPhoneRuntimeComponent::ConvertToGrayOriginal( Platform::WriteOnlyArray<int,1U>^ inputBuffer,
|
||||
Platform::WriteOnlyArray<uint8,1U>^ outputBuffer)
|
||||
{ uint8 * src = (uint8 *) inputBuffer->Data;
|
||||
uint8 * dest = (uint8 *) outputBuffer->Data;
|
||||
byte * outputBuffer)
|
||||
{
|
||||
uint8 * src = (uint8 *) inputBuffer->Data;
|
||||
uint8 * dest = (uint8 *) outputBuffer;
|
||||
ConvertToGrayOriginal(src, dest, inputBuffer->Length);
|
||||
}
|
||||
|
||||
|
||||
inline void WindowsPhoneRuntimeComponent::ThrowIfFailed(HRESULT hr)
|
||||
{
|
||||
if (FAILED(hr))
|
||||
{
|
||||
// Set a breakpoint on this line to catch Win32 API errors.
|
||||
throw Platform::Exception::CreateException(hr);
|
||||
}
|
||||
}
|
||||
|
||||
void WindowsPhoneRuntimeComponent::ConvertToGrayOriginal( uint8 * src, uint8* dest, int length)
|
||||
{
|
||||
int i;
|
||||
|
@ -77,10 +109,10 @@ void WindowsPhoneRuntimeComponent::ConvertToGrayOriginal( uint8 * src, uint8* de
|
|||
// For a good introduction to NEON: http://www.stanford.edu/class/ee282/10_handouts/lect.10.arm_soc.pdf
|
||||
#if defined(_M_ARM)
|
||||
void WindowsPhoneRuntimeComponent::ConvertToGrayNeon( Platform::WriteOnlyArray<int,1U>^ inputBuffer,
|
||||
Platform::WriteOnlyArray<uint8,1U>^ outputBuffer)
|
||||
byte * outputBuffer)
|
||||
{
|
||||
uint8 * src = (uint8 *) inputBuffer->Data;
|
||||
uint8 * dest = (uint8 *) outputBuffer->Data;
|
||||
uint8 * dest = (uint8 *) outputBuffer;
|
||||
|
||||
int n = inputBuffer->Length;
|
||||
|
||||
|
@ -88,7 +120,7 @@ void WindowsPhoneRuntimeComponent::ConvertToGrayNeon( Platform::WriteOnlyArray<i
|
|||
uint8x8_t gfac = vdup_n_u8 (151);
|
||||
uint8x8_t bfac = vdup_n_u8 (28);
|
||||
n/=8;
|
||||
|
||||
|
||||
uint8x8x4_t interleaved;
|
||||
interleaved.val[3] = vdup_n_u8 (0xFF); //Alpha value
|
||||
|
||||
|
|
|
@ -2,27 +2,45 @@
|
|||
|
||||
namespace NativeComponent
|
||||
{
|
||||
public ref class WindowsPhoneRuntimeComponent sealed
|
||||
public ref class WindowsPhoneRuntimeComponent sealed : CameraEffectInterface::ICameraEffect
|
||||
{
|
||||
public:
|
||||
WindowsPhoneRuntimeComponent();
|
||||
void Initialize(Windows::Phone::Media::Capture::PhotoCaptureDevice^ captureDevice);
|
||||
|
||||
void NewViewfinderFrame( Platform::WriteOnlyArray<int,1U>^ inputBuffer,
|
||||
Platform::WriteOnlyArray<uint8,1U>^ outputBuffer);
|
||||
virtual property Windows::Phone::Media::Capture::PhotoCaptureDevice^ CaptureDevice
|
||||
{
|
||||
void set( Windows::Phone::Media::Capture::PhotoCaptureDevice^ );
|
||||
}
|
||||
|
||||
virtual property Windows::Storage::Streams::IBuffer^ OutputBuffer
|
||||
{
|
||||
void set( Windows::Storage::Streams::IBuffer^ );
|
||||
}
|
||||
|
||||
virtual property Windows::Foundation::Size OutputBufferSize
|
||||
{
|
||||
void set( Windows::Foundation::Size );
|
||||
}
|
||||
|
||||
virtual Windows::Foundation::IAsyncAction^ GetNewFrameAndApplyEffect();
|
||||
|
||||
virtual void ChangeEffectType();
|
||||
|
||||
private:
|
||||
|
||||
void ConvertToGrayOriginal( Platform::WriteOnlyArray<int,1U>^ inputBuffer,
|
||||
Platform::WriteOnlyArray<uint8,1U>^ outputBuffer);
|
||||
byte * outputBuffer);
|
||||
void ConvertToGrayOriginal( uint8 * src, uint8* dest, int length);
|
||||
|
||||
#if defined(_M_ARM)
|
||||
void ConvertToGrayNeon ( Platform::WriteOnlyArray<int,1U>^ inputBuffer,
|
||||
Platform::WriteOnlyArray<uint8,1U>^ outputBuffer);
|
||||
byte * outputBuffer);
|
||||
#endif
|
||||
|
||||
void ThrowIfFailed(HRESULT hr);
|
||||
Windows::Phone::Media::Capture::PhotoCaptureDevice^ m_camera;
|
||||
Platform::Array<int>^ m_cameraPreviewBuffer;
|
||||
Windows::Foundation::Size m_outputBufferSize;
|
||||
byte* m_pixelsBuffer;
|
||||
bool m_processingFrame;
|
||||
};
|
||||
}
|
|
@ -18,7 +18,6 @@
|
|||
<Platform>ARM</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{eccd1443-9eaa-4666-bc16-6aa5b5c11ba2}</ProjectGuid>
|
||||
<RootNamespace>NativeComponent</RootNamespace>
|
||||
|
@ -26,9 +25,7 @@
|
|||
<MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
|
||||
<WinMDAssembly>true</WinMDAssembly>
|
||||
</PropertyGroup>
|
||||
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
|
@ -51,19 +48,14 @@
|
|||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PlatformToolset>v110_wp80</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
|
||||
<ImportGroup Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
|
||||
<PropertyGroup>
|
||||
<GenerateManifest>false</GenerateManifest>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>_WINRT_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
|
@ -79,7 +71,6 @@
|
|||
<GenerateWindowsMetadata>true</GenerateWindowsMetadata>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>_WINRT_DLL;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
|
@ -95,7 +86,6 @@
|
|||
<GenerateWindowsMetadata>true</GenerateWindowsMetadata>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>_WINRT_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
|
@ -111,7 +101,6 @@
|
|||
<GenerateWindowsMetadata>true</GenerateWindowsMetadata>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>_WINRT_DLL;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
|
@ -127,14 +116,12 @@
|
|||
<GenerateWindowsMetadata>true</GenerateWindowsMetadata>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="platform.winmd">
|
||||
<IsWinMDFile>true</IsWinMDFile>
|
||||
<Private>false</Private>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ClInclude Include="NativeComponent.h" />
|
||||
<ClInclude Include="pch.h" />
|
||||
|
@ -145,11 +132,13 @@
|
|||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\CameraEffectInterface\CameraEffectInterface.vcxproj">
|
||||
<Project>{b54d292c-6154-413f-9c4c-d4a08cdb7edf}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<Import Project="$(MSBuildExtensionsPath)\Microsoft\WindowsPhone\v$(TargetPlatformVersion)\Microsoft.Cpp.WindowsPhone.$(TargetPlatformVersion).targets" />
|
||||
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
|
||||
</Project>
|
||||
</Project>
|
|
@ -6,4 +6,12 @@
|
|||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="NativeComponent.cpp" />
|
||||
<ClCompile Include="pch.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="NativeComponent.h" />
|
||||
<ClInclude Include="pch.h" />
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -4,3 +4,7 @@
|
|||
//
|
||||
|
||||
#pragma once
|
||||
#include <ppl.h>
|
||||
#include <ppltasks.h>
|
||||
#include <windows.h>
|
||||
#include "NativeComponent.h"
|
|
@ -2,7 +2,6 @@
|
|||
x:Class="NativeFilterDemo.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
|
||||
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone">
|
||||
|
||||
<!--Application Resources-->
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Resources;
|
||||
using System.Windows;
|
||||
using System.Windows.Markup;
|
||||
using System.Windows.Navigation;
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace NativeFilterDemo
|
||||
|
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 527 B |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 533 B |
|
@ -1,45 +1,38 @@
|
|||
using NativeComponent;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace NativeFilterDemo
|
||||
namespace NativeFilterDemo
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices.WindowsRuntime;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Threading;
|
||||
using Windows.Foundation;
|
||||
using CameraEffectInterface;
|
||||
|
||||
/// <summary>
|
||||
/// A source for the media element. Feeds the Media Element with frames coming from the
|
||||
/// ICameraEffect implementation.
|
||||
/// </summary>
|
||||
public class CameraStreamSource : MediaStreamSource
|
||||
{
|
||||
|
||||
private MediaStreamDescription _videoStreamDescription;
|
||||
|
||||
private int _frameTime = 0;
|
||||
private long _currentTime = 0;
|
||||
private int _frameWidth;
|
||||
private int _frameHeight;
|
||||
private const int _framePixelSize = 4; // RGBA
|
||||
private int _frameBufferSize;
|
||||
private int _frameStreamSize;
|
||||
|
||||
private MemoryStream _frameStream;
|
||||
private int _frameStreamOffset = 0;
|
||||
private Dictionary<MediaSampleAttributeKeys, string> _emptySampleDict =
|
||||
private readonly Dictionary<MediaSampleAttributeKeys, string> emptySampleDict =
|
||||
new Dictionary<MediaSampleAttributeKeys, string>();
|
||||
WindowsPhoneRuntimeComponent _cameraBuffer;
|
||||
|
||||
int[] _cameraData;
|
||||
byte[] _cameraFilteredData;
|
||||
private long currentTime;
|
||||
private int frameStreamOffset;
|
||||
private int frameTime;
|
||||
private MediaStreamDescription videoStreamDescription;
|
||||
|
||||
public CameraStreamSource(WindowsPhoneRuntimeComponent cameraBuffer, Windows.Foundation.Size size)
|
||||
public CameraStreamSource(ICameraEffect cameraEffect, Size targetMediaElementSize)
|
||||
{
|
||||
_cameraBuffer = cameraBuffer;
|
||||
_frameWidth = (int)size.Width;
|
||||
_frameHeight = (int)size.Height;
|
||||
|
||||
_cameraData = new int[_frameWidth * _frameHeight];
|
||||
_frameBufferSize = _frameWidth * _frameHeight * _framePixelSize;
|
||||
_cameraFilteredData = new byte[_frameBufferSize];
|
||||
_frameStreamSize = _frameBufferSize * 4; //Number of frames for buffering : 4 works well.
|
||||
_frameStream = new MemoryStream(_frameStreamSize);
|
||||
CameraStreamSourceDataSingleton dataSource = CameraStreamSourceDataSingleton.Instance;
|
||||
dataSource.Initialize(targetMediaElementSize);
|
||||
dataSource.CameraEffect = cameraEffect;
|
||||
cameraEffect.OutputBufferSize = targetMediaElementSize;
|
||||
cameraEffect.OutputBuffer = dataSource.ImageBuffer.AsBuffer();
|
||||
}
|
||||
|
||||
protected override void OpenMediaAsync()
|
||||
|
@ -49,12 +42,14 @@ namespace NativeFilterDemo
|
|||
Dictionary<MediaStreamAttributeKeys, string> mediaStreamAttributes = new Dictionary<MediaStreamAttributeKeys, string>();
|
||||
List<MediaStreamDescription> mediaStreamDescriptions = new List<MediaStreamDescription>();
|
||||
|
||||
mediaStreamAttributes[MediaStreamAttributeKeys.VideoFourCC] = "RGBA";
|
||||
mediaStreamAttributes[MediaStreamAttributeKeys.Width] = _frameWidth.ToString();
|
||||
mediaStreamAttributes[MediaStreamAttributeKeys.Height] = _frameHeight.ToString();
|
||||
CameraStreamSourceDataSingleton dataSource = CameraStreamSourceDataSingleton.Instance;
|
||||
|
||||
_videoStreamDescription = new MediaStreamDescription(MediaStreamType.Video, mediaStreamAttributes);
|
||||
mediaStreamDescriptions.Add(_videoStreamDescription);
|
||||
mediaStreamAttributes[MediaStreamAttributeKeys.VideoFourCC] = "RGBA";
|
||||
mediaStreamAttributes[MediaStreamAttributeKeys.Width] = dataSource.FrameWidth.ToString();
|
||||
mediaStreamAttributes[MediaStreamAttributeKeys.Height] = dataSource.FrameHeight.ToString();
|
||||
|
||||
videoStreamDescription = new MediaStreamDescription(MediaStreamType.Video, mediaStreamAttributes);
|
||||
mediaStreamDescriptions.Add(videoStreamDescription);
|
||||
|
||||
// a zero timespan is an infinite video
|
||||
mediaSourceAttributes[MediaSourceAttributesKeys.Duration] =
|
||||
|
@ -62,37 +57,44 @@ namespace NativeFilterDemo
|
|||
|
||||
mediaSourceAttributes[MediaSourceAttributesKeys.CanSeek] = false.ToString();
|
||||
|
||||
_frameTime = (int)TimeSpan.FromSeconds((double)1 / 30).Ticks;
|
||||
frameTime = (int)TimeSpan.FromSeconds((double)0).Ticks;
|
||||
|
||||
// Report that we finished initializing its internal state and can now
|
||||
// pass in frame samples.
|
||||
|
||||
ReportOpenMediaCompleted(mediaSourceAttributes, mediaStreamDescriptions);
|
||||
|
||||
}
|
||||
|
||||
|
||||
protected override void GetSampleAsync(MediaStreamType mediaStreamType)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine("GetSampleAsync in");
|
||||
if (_frameStreamOffset + _frameBufferSize > _frameStreamSize)
|
||||
CameraStreamSourceDataSingleton dataSource = CameraStreamSourceDataSingleton.Instance;
|
||||
|
||||
if (frameStreamOffset + dataSource.FrameBufferSize > dataSource.FrameStreamSize)
|
||||
{
|
||||
_frameStream.Seek(0, SeekOrigin.Begin);
|
||||
_frameStreamOffset = 0;
|
||||
dataSource.FrameStream.Seek(0, SeekOrigin.Begin);
|
||||
frameStreamOffset = 0;
|
||||
}
|
||||
|
||||
_cameraBuffer.NewViewfinderFrame(_cameraData, _cameraFilteredData);
|
||||
_frameStream.Write(_cameraFilteredData, 0, _frameBufferSize);
|
||||
Task tsk = dataSource.CameraEffect.GetNewFrameAndApplyEffect().AsTask();
|
||||
|
||||
// Wait that the asynchroneous call completes, and proceed by reporting
|
||||
// the MediaElement that new samples are ready.
|
||||
tsk.ContinueWith((task) =>
|
||||
{
|
||||
dataSource.FrameStream.Position = 0;
|
||||
|
||||
MediaStreamSample msSamp = new MediaStreamSample(
|
||||
_videoStreamDescription, _frameStream, _frameStreamOffset,
|
||||
_frameBufferSize, _currentTime, _emptySampleDict);
|
||||
MediaStreamSample msSamp = new MediaStreamSample(
|
||||
videoStreamDescription,
|
||||
dataSource.FrameStream,
|
||||
frameStreamOffset,
|
||||
dataSource.FrameBufferSize,
|
||||
currentTime,
|
||||
emptySampleDict);
|
||||
|
||||
ReportGetSampleCompleted(msSamp);
|
||||
|
||||
_currentTime += _frameTime;
|
||||
_frameStreamOffset += _frameBufferSize;
|
||||
|
||||
System.Diagnostics.Debug.WriteLine("GetSampleAsync out");
|
||||
ReportGetSampleCompleted(msSamp);
|
||||
currentTime += frameTime;
|
||||
frameStreamOffset += dataSource.FrameBufferSize;
|
||||
});
|
||||
}
|
||||
|
||||
protected override void CloseMedia()
|
||||
|
@ -106,8 +108,8 @@ namespace NativeFilterDemo
|
|||
|
||||
protected override void SeekAsync(long seekToTime)
|
||||
{
|
||||
_currentTime = seekToTime;
|
||||
this.ReportSeekCompleted(seekToTime);
|
||||
currentTime = seekToTime;
|
||||
ReportSeekCompleted(seekToTime);
|
||||
}
|
||||
|
||||
protected override void SwitchMediaStreamAsync(MediaStreamDescription mediaStreamDescription)
|
||||
|
@ -115,6 +117,5 @@ namespace NativeFilterDemo
|
|||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
namespace NativeFilterDemo
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using CameraEffectInterface;
|
||||
|
||||
/// <summary>
|
||||
/// A class to work around a problem with MediaElement.
|
||||
/// MediaElement doesn't destruct the current MediaStreamSource when the source is changed.
|
||||
/// To avoid memory leaks when source is changed (for example when navigating away from a page)
|
||||
/// reserve the memory once and use it for all the MediaStreamSource instances we create.
|
||||
/// </summary>
|
||||
public sealed class CameraStreamSourceDataSingleton
|
||||
{
|
||||
private const int FramePixelSize = 4; // RGBA
|
||||
private const int NumberOfBufferedFrames = 1;
|
||||
|
||||
private static CameraStreamSourceDataSingleton classInstance = null;
|
||||
public static CameraStreamSourceDataSingleton Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (classInstance == null)
|
||||
{
|
||||
classInstance = new CameraStreamSourceDataSingleton();
|
||||
}
|
||||
|
||||
return classInstance;
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] ImageBuffer { get; private set; }
|
||||
public MemoryStream FrameStream { get; private set; }
|
||||
public int FrameHeight { get; private set; }
|
||||
public int FrameWidth { get; private set; }
|
||||
public int FrameBufferSize { get; private set; }
|
||||
public int FrameStreamSize { get; private set; }
|
||||
public ICameraEffect CameraEffect { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Create the buffers of the data source
|
||||
/// </summary>
|
||||
/// <param name="cameraFrameSize">The dimensions of a camera frame</param>
|
||||
public void Initialize(Windows.Foundation.Size cameraFrameSize)
|
||||
{
|
||||
if (this.FrameWidth != 0)
|
||||
{
|
||||
if (((int)cameraFrameSize.Width != this.FrameWidth)
|
||||
|| ((int)cameraFrameSize.Height != this.FrameHeight))
|
||||
{
|
||||
// Currently, we don't allow changing the frame size
|
||||
// after first initialization
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
return; // singleton is already initialized.
|
||||
}
|
||||
|
||||
this.FrameWidth = (int)cameraFrameSize.Width;
|
||||
this.FrameHeight = (int)cameraFrameSize.Height;
|
||||
this.FrameBufferSize = FrameWidth * FrameHeight * FramePixelSize;
|
||||
this.ImageBuffer = new byte[FrameBufferSize];
|
||||
this.FrameStreamSize = FrameBufferSize * NumberOfBufferedFrames;
|
||||
this.FrameStream = new MemoryStream(ImageBuffer);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,76 +6,31 @@
|
|||
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:NativeFilterDemo"
|
||||
mc:Ignorable="d"
|
||||
FontFamily="{StaticResource PhoneFontFamilyNormal}"
|
||||
FontSize="{StaticResource PhoneFontSizeNormal}"
|
||||
Foreground="{StaticResource PhoneForegroundBrush}"
|
||||
SupportedOrientations="Landscape" Orientation="Landscape"
|
||||
SupportedOrientations="Landscape" Orientation="LandscapeLeft"
|
||||
shell:SystemTray.IsVisible="False">
|
||||
|
||||
<phone:PhoneApplicationPage.Resources>
|
||||
<local:AspectRatioValueConverter x:Key="AspectRatioValueConverter"/>
|
||||
</phone:PhoneApplicationPage.Resources>
|
||||
|
||||
<!--LayoutRoot is the root grid where all page content is placed-->
|
||||
<Grid x:Name="LayoutRoot" Background="Transparent" Height="{Binding Width, ElementName=rectangle}">
|
||||
<Grid x:Name="LayoutRoot" Background="Transparent">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- LOCALIZATION NOTE:
|
||||
To localize the displayed strings copy their values to appropriately named
|
||||
keys in the app's neutral language resource file (AppResources.resx) then
|
||||
replace the hard-coded text value between the attributes' quotation marks
|
||||
with the binding clause whose path points to that string name.
|
||||
|
||||
For example:
|
||||
|
||||
Text="{Binding Path=LocalizedResources.ApplicationTitle, Source={StaticResource LocalizedStrings}}"
|
||||
|
||||
This binding points to the template's string resource named "ApplicationTitle".
|
||||
|
||||
Adding supported languages in the Project Properties tab will create a
|
||||
new resx file per language that can carry the translated values of your
|
||||
UI strings. The binding in these examples will cause the value of the
|
||||
attributes to be drawn from the .resx file that matches the
|
||||
CurrentUICulture of the app at run time.
|
||||
-->
|
||||
|
||||
<!--TitlePanel contains the name of the application and page title-->
|
||||
<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
|
||||
<TextBlock Text="NATIVE FILTER DEMO" Style="{StaticResource PhoneTextNormalStyle}" Margin="12,0"/>
|
||||
</StackPanel>
|
||||
|
||||
<!--ContentPanel - place additional content here-->
|
||||
<Grid Grid.Row="1" Background="Transparent">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="109*"/>
|
||||
<ColumnDefinition Width="291*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Rectangle x:Name="Viewfinder" Grid.Column="0" Grid.ColumnSpan="1" Canvas.ZIndex="2"
|
||||
HorizontalAlignment="Stretch" VerticalAlignment="Center" Margin="5,0,0,0"
|
||||
Height="{Binding ActualWidth, Converter={StaticResource AspectRatioValueConverter}, ElementName=Viewfinder, Mode=OneWay}" >
|
||||
<Rectangle.Fill>
|
||||
<VideoBrush x:Name="ViewfinderBrush" />
|
||||
</Rectangle.Fill>
|
||||
</Rectangle>
|
||||
<Grid Grid.Row="1" Margin="8">
|
||||
<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
|
||||
<TextBlock Text="NATIVE FILTER DEMO" Style="{StaticResource PhoneTextNormalStyle}" Margin="12,0"/>
|
||||
</StackPanel>
|
||||
<MediaElement x:Name="MyCameraMediaElement"
|
||||
Grid.Row="0" Grid.Column="0"
|
||||
IsHitTestVisible="False"
|
||||
Margin="4" Width="640" Height="480" Grid.ColumnSpan="2" />
|
||||
Stretch="UniformToFill"
|
||||
BufferingTime="0"
|
||||
Tap="MyCameraMediaElement_Tap"/>
|
||||
|
||||
</Grid>
|
||||
|
||||
|
||||
<!--Uncomment to see an alignment grid to help ensure your controls are
|
||||
aligned on common boundaries. The image has a top margin of -32px to
|
||||
account for the System Tray. Set this to 0 (or remove the margin altogether)
|
||||
if the System Tray is hidden.
|
||||
|
||||
Before shipping remove this XAML and the image itself.-->
|
||||
<!--<Image Source="/Assets/AlignmentGrid.png" VerticalAlignment="Top" Height="800" Width="480" Margin="0,-32,0,0" Grid.Row="0" Grid.RowSpan="2" IsHitTestVisible="False" />-->
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
</phone:PhoneApplicationPage>
|
|
@ -1,88 +1,98 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Threading;
|
||||
using Microsoft.Phone.Controls;
|
||||
using Microsoft.Phone.Shell;
|
||||
using NativeFilterDemo.Resources;
|
||||
using NativeComponent;
|
||||
using Microsoft.Devices;
|
||||
using Windows.Phone.Media.Capture;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Threading;
|
||||
using System.Threading;
|
||||
using Microsoft.Phone;
|
||||
|
||||
using Size = Windows.Foundation.Size;
|
||||
using System.Diagnostics;
|
||||
using CameraEffectInterface;
|
||||
using NativeComponent;
|
||||
|
||||
namespace NativeFilterDemo
|
||||
{
|
||||
public partial class MainPage : PhoneApplicationPage
|
||||
{
|
||||
PhotoCaptureDevice m_camera;
|
||||
WindowsPhoneRuntimeComponent m_nativeFilter;
|
||||
|
||||
DateTime m_startTime;
|
||||
DispatcherTimer m_timer;
|
||||
private PhotoCaptureDevice m_camera;
|
||||
private readonly ICameraEffect cameraEffect;
|
||||
private CameraStreamSource source;
|
||||
private DispatcherTimer m_timer;
|
||||
|
||||
// Constructor
|
||||
public MainPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
cameraEffect = new WindowsPhoneRuntimeComponent();
|
||||
BuildApplicationBar();
|
||||
}
|
||||
|
||||
private void BuildApplicationBar()
|
||||
{
|
||||
ApplicationBar = new ApplicationBar();
|
||||
|
||||
ApplicationBarIconButton button = new ApplicationBarIconButton(new Uri("/Assets/Icons/next.png", UriKind.Relative));
|
||||
button.Text = "Second page";
|
||||
button.Click += SecondPageButtonClick;
|
||||
ApplicationBar.Buttons.Add(button);
|
||||
Loaded += MainPage_Loaded;
|
||||
}
|
||||
|
||||
async void MainPage_Loaded(object sender, RoutedEventArgs e)
|
||||
async void MainPage_Loaded(object sender, System.Windows.RoutedEventArgs e)
|
||||
{
|
||||
Microsoft.Phone.Shell.PhoneApplicationService.Current.ApplicationIdleDetectionMode = IdleDetectionMode.Disabled;
|
||||
Windows.Foundation.Size resolution = new Windows.Foundation.Size(640, 480);
|
||||
m_camera = await PhotoCaptureDevice.OpenAsync(CameraSensorLocation.Back, resolution);
|
||||
Size targetMediaElementSize = new Size(640, 480);
|
||||
double aspectRatio = 4.0/3.0;
|
||||
|
||||
Windows.Foundation.Size actualResolution = m_camera.PreviewResolution;
|
||||
|
||||
// The viewfinderbrush (preview of the original data from camera)
|
||||
// is currently very unstable on the device, when used together
|
||||
// with a MediaEngine playback component.
|
||||
|
||||
//ViewfinderBrush.SetSource(m_camera);
|
||||
// 1. Open camera
|
||||
if (m_camera == null)
|
||||
{
|
||||
var captureRes = PhotoCaptureDevice.GetAvailableCaptureResolutions(CameraSensorLocation.Back);
|
||||
Size selectedCaptureRes = captureRes.Where(res => Math.Abs(aspectRatio - res.Width/res.Height ) <= 0.1)
|
||||
.OrderBy(res => res.Width)
|
||||
.Last();
|
||||
m_camera = await PhotoCaptureDevice.OpenAsync(CameraSensorLocation.Back, selectedCaptureRes);
|
||||
m_camera.SetProperty(KnownCameraGeneralProperties.EncodeWithOrientation, m_camera.SensorLocation == CameraSensorLocation.Back ? m_camera.SensorRotationInDegrees : -m_camera.SensorRotationInDegrees);
|
||||
|
||||
var previewRes = PhotoCaptureDevice.GetAvailablePreviewResolutions(CameraSensorLocation.Back);
|
||||
Size selectedPreviewRes = previewRes.Where(res => Math.Abs(aspectRatio - res.Width/res.Height ) <= 0.1)
|
||||
.Where(res => (res.Height >= targetMediaElementSize.Height) && (res.Width >= targetMediaElementSize.Width))
|
||||
.OrderBy(res => res.Width)
|
||||
.First();
|
||||
await m_camera.SetPreviewResolutionAsync(selectedPreviewRes);
|
||||
cameraEffect.CaptureDevice = m_camera;
|
||||
}
|
||||
|
||||
m_nativeFilter = new WindowsPhoneRuntimeComponent();
|
||||
m_nativeFilter.Initialize(m_camera);
|
||||
// Always create a new source, otherwise the MediaElement will not start.
|
||||
source = new CameraStreamSource(cameraEffect, targetMediaElementSize);
|
||||
MyCameraMediaElement.SetSource(source);
|
||||
|
||||
CameraStreamSource source = new CameraStreamSource(m_nativeFilter, actualResolution);
|
||||
MyCameraMediaElement.SetSource (source);
|
||||
|
||||
m_startTime = DateTime.Now;
|
||||
m_timer = new DispatcherTimer();
|
||||
m_timer.Interval = new TimeSpan(0, 0, 0, 1, 0); // Tick every 1s.
|
||||
m_timer.Tick += m_timer_Tick;
|
||||
m_timer.Start();
|
||||
|
||||
}
|
||||
|
||||
|
||||
void m_timer_Tick(object sender, EventArgs e)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine("FPS:" + MyCameraMediaElement.RenderedFramesPerSecond );
|
||||
System.Diagnostics.Debug.WriteLine("FPS 2:" + MyCameraMediaElement.RenderedFramesPerSecond);
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected override void OnNavigatedTo(NavigationEventArgs e)
|
||||
private void SecondPageButtonClick(object sender, EventArgs e)
|
||||
{
|
||||
if (m_camera != null)
|
||||
if (m_camera == null) return;
|
||||
|
||||
MyCameraMediaElement.Source = null;
|
||||
NavigationService.Navigate(new Uri("/SecondPage.xaml", UriKind.Relative));
|
||||
|
||||
}
|
||||
|
||||
private void MyCameraMediaElement_Tap(object sender, System.Windows.Input.GestureEventArgs e)
|
||||
{
|
||||
if (cameraEffect != null)
|
||||
{
|
||||
ViewfinderBrush.SetSource(m_camera);
|
||||
cameraEffect.ChangeEffectType();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnNavigatedFrom(NavigationEventArgs e)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine("OnNavigatedFrom");
|
||||
base.OnNavigatedFrom(e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -90,6 +90,7 @@
|
|||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="CameraStreamSourceDataSingleton.cs" />
|
||||
<Compile Include="App.xaml.cs">
|
||||
<DependentUpon>App.xaml</DependentUpon>
|
||||
</Compile>
|
||||
|
@ -105,6 +106,9 @@
|
|||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>AppResources.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="SecondPage.xaml.cs">
|
||||
<DependentUpon>SecondPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ApplicationDefinition Include="App.xaml">
|
||||
|
@ -115,6 +119,10 @@
|
|||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="SecondPage.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Properties\AppManifest.xml">
|
||||
|
@ -129,6 +137,8 @@
|
|||
<Content Include="Assets\ApplicationIcon.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Assets\Icons\back.png" />
|
||||
<Content Include="Assets\Icons\next.png" />
|
||||
<Content Include="Assets\Tiles\FlipCycleTileLarge.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
|
@ -153,6 +163,10 @@
|
|||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\CameraEffectInterface\CameraEffectInterface.vcxproj">
|
||||
<Project>{B54D292C-6154-413F-9C4C-D4A08CDB7EDF}</Project>
|
||||
<Name>ICameraEffect</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\NativeComponent\NativeComponent.vcxproj">
|
||||
<Project>{ECCD1443-9EAA-4666-BC16-6AA5B5C11BA2}</Project>
|
||||
<Name>NativeComponent</Name>
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
<phone:PhoneApplicationPage
|
||||
x:Class="NativeFilterDemo.SecondPage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
|
||||
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
FontFamily="{StaticResource PhoneFontFamilyNormal}"
|
||||
FontSize="{StaticResource PhoneFontSizeNormal}"
|
||||
Foreground="{StaticResource PhoneForegroundBrush}"
|
||||
SupportedOrientations="Portrait" Orientation="Portrait"
|
||||
mc:Ignorable="d"
|
||||
shell:SystemTray.IsVisible="True">
|
||||
|
||||
<!--LayoutRoot is the root grid where all page content is placed-->
|
||||
<Grid x:Name="LayoutRoot" Background="Transparent">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!--TitlePanel contains the name of the application and page title-->
|
||||
<StackPanel Grid.Row="0" Margin="12,17,0,28">
|
||||
<TextBlock Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}"/>
|
||||
<TextBlock Text="Second Page" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
|
||||
</StackPanel>
|
||||
|
||||
<!--ContentPanel - place additional content here-->
|
||||
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
|
||||
<TextBlock FontSize="{StaticResource PhoneFontSizeMedium}" Text="Click the back button in the application bar to return to the camera page. This is to test that navigation works properly." TextWrapping="Wrap"/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
</phone:PhoneApplicationPage>
|
|
@ -0,0 +1,30 @@
|
|||
using System;
|
||||
using Microsoft.Phone.Controls;
|
||||
using Microsoft.Phone.Shell;
|
||||
|
||||
namespace NativeFilterDemo
|
||||
{
|
||||
public partial class SecondPage : PhoneApplicationPage
|
||||
{
|
||||
public SecondPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
BuildApplicationBar();
|
||||
}
|
||||
|
||||
private void BuildApplicationBar()
|
||||
{
|
||||
ApplicationBar = new ApplicationBar();
|
||||
|
||||
ApplicationBarIconButton button = new ApplicationBarIconButton(new Uri("/Assets/Icons/back.png", UriKind.Relative));
|
||||
button.Text = "Camera page";
|
||||
button.Click += BackButtonClick;
|
||||
ApplicationBar.Buttons.Add(button);
|
||||
}
|
||||
|
||||
private void BackButtonClick(object sender, EventArgs e)
|
||||
{
|
||||
NavigationService.GoBack();
|
||||
}
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче