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:
Berthier Lemieux 2013-04-13 21:49:36 +03:00
Родитель f93eaf0804
Коммит 10b339be27
23 изменённых файлов: 727 добавлений и 239 удалений

126
.gitignore поставляемый
Просмотреть файл

@ -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

Двоичные данные
NativeFilterDemo/Assets/Icons/back.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 527 B

Двоичные данные
NativeFilterDemo/Assets/Icons/next.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 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();
}
}
}