Commit baac0420 authored by Ghislain MARY's avatar Ghislain MARY
Browse files

Handle loading of static picture for Windows 10.

parent cc108edd
......@@ -42,6 +42,9 @@
<ProjectReference Include="..\..\..\..\..\..\msilbc\build\windows10\libmsilbc\libmsilbc.vcxproj">
<Project>{6a18bbb9-08d1-41a8-be57-17fc992cc36f}</Project>
</ProjectReference>
<ProjectReference Include="..\..\..\..\..\..\msopenh264\build\windows10\libmsopenh264\libmsopenh264.vcxproj">
<Project>{bb8ebb21-f22c-4a68-99cb-67fa36c495e3}</Project>
</ProjectReference>
<ProjectReference Include="..\..\..\..\..\..\mssilk\build\windows10\libmssilk\libmssilk.vcxproj">
<Project>{b84d5c3b-6de5-49c8-b3dd-5eb67b01a527}</Project>
</ProjectReference>
......@@ -54,6 +57,9 @@
<ProjectReference Include="..\..\..\..\..\..\mswinrtvid\windows10\libmswinrtvid\libmswinrtvid.vcxproj">
<Project>{2d0e44c4-e51d-4911-b876-345d1e5e5209}</Project>
</ProjectReference>
<ProjectReference Include="..\..\mswinrtjpeg2yuv\mswinrtjpeg2yuv.vcxproj">
<Project>{545f846d-7f19-4d6d-a50b-172a7c9b61e7}</Project>
</ProjectReference>
<ProjectReference Include="..\ms2-tester-static\ms2-tester-static.vcxproj">
<Project>{6f92d56c-620f-4d56-8dba-c02c0e06a0d1}</Project>
</ProjectReference>
......
......@@ -109,6 +109,7 @@
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Content Include="Assets\Images\nowebcamCIF.jpg" />
<Content Include="Assets\Logo.png" />
<Content Include="Assets\SmallLogo.png" />
<Content Include="Assets\Sounds\arpeggio_8000_mono.wav" />
......@@ -183,7 +184,8 @@
</Target>
<Import Project="packages\Microsoft.ApplicationInsights.0.14.3-build00177\build\portable-win81+wpa81\Microsoft.ApplicationInsights.targets" Condition="Exists('packages\Microsoft.ApplicationInsights.0.14.3-build00177\build\portable-win81+wpa81\Microsoft.ApplicationInsights.targets')" />
<PropertyGroup>
<PreBuildEvent>XCopy /I /Y $(ProjectDir)..\..\..\tester\sounds $(ProjectDir)Assets\Sounds</PreBuildEvent>
<PreBuildEvent>XCopy /I /Y $(ProjectDir)..\..\..\tester\sounds $(ProjectDir)Assets\Sounds
XCopy /I /Y $(ProjectDir)..\..\..\src\voip\nowebcamCIF.jpg $(ProjectDir)Assets\Images</PreBuildEvent>
</PropertyGroup>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
......
......@@ -55,6 +55,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmsbcg729", "..\..\..\..\
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmswinrtvid", "..\..\..\..\..\mswinrtvid\windows10\libmswinrtvid\libmswinrtvid.vcxproj", "{2D0E44C4-E51D-4911-B876-345D1E5E5209}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmsopenh264", "..\..\..\..\..\msopenh264\build\windows10\libmsopenh264\libmsopenh264.vcxproj", "{BB8EBB21-F22C-4A68-99CB-67FA36C495E3}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mswinrtjpeg2yuv", "..\mswinrtjpeg2yuv\mswinrtjpeg2yuv.vcxproj", "{545F846D-7F19-4D6D-A50B-172A7C9B61E7}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM = Debug|ARM
......@@ -383,6 +387,30 @@ Global
{2D0E44C4-E51D-4911-B876-345D1E5E5209}.Release|x64.Build.0 = Release|x64
{2D0E44C4-E51D-4911-B876-345D1E5E5209}.Release|x86.ActiveCfg = Release|Win32
{2D0E44C4-E51D-4911-B876-345D1E5E5209}.Release|x86.Build.0 = Release|Win32
{BB8EBB21-F22C-4A68-99CB-67FA36C495E3}.Debug|ARM.ActiveCfg = Debug|ARM
{BB8EBB21-F22C-4A68-99CB-67FA36C495E3}.Debug|ARM.Build.0 = Debug|ARM
{BB8EBB21-F22C-4A68-99CB-67FA36C495E3}.Debug|x64.ActiveCfg = Debug|x64
{BB8EBB21-F22C-4A68-99CB-67FA36C495E3}.Debug|x64.Build.0 = Debug|x64
{BB8EBB21-F22C-4A68-99CB-67FA36C495E3}.Debug|x86.ActiveCfg = Debug|Win32
{BB8EBB21-F22C-4A68-99CB-67FA36C495E3}.Debug|x86.Build.0 = Debug|Win32
{BB8EBB21-F22C-4A68-99CB-67FA36C495E3}.Release|ARM.ActiveCfg = Release|ARM
{BB8EBB21-F22C-4A68-99CB-67FA36C495E3}.Release|ARM.Build.0 = Release|ARM
{BB8EBB21-F22C-4A68-99CB-67FA36C495E3}.Release|x64.ActiveCfg = Release|x64
{BB8EBB21-F22C-4A68-99CB-67FA36C495E3}.Release|x64.Build.0 = Release|x64
{BB8EBB21-F22C-4A68-99CB-67FA36C495E3}.Release|x86.ActiveCfg = Release|Win32
{BB8EBB21-F22C-4A68-99CB-67FA36C495E3}.Release|x86.Build.0 = Release|Win32
{545F846D-7F19-4D6D-A50B-172A7C9B61E7}.Debug|ARM.ActiveCfg = Debug|ARM
{545F846D-7F19-4D6D-A50B-172A7C9B61E7}.Debug|ARM.Build.0 = Debug|ARM
{545F846D-7F19-4D6D-A50B-172A7C9B61E7}.Debug|x64.ActiveCfg = Debug|x64
{545F846D-7F19-4D6D-A50B-172A7C9B61E7}.Debug|x64.Build.0 = Debug|x64
{545F846D-7F19-4D6D-A50B-172A7C9B61E7}.Debug|x86.ActiveCfg = Debug|Win32
{545F846D-7F19-4D6D-A50B-172A7C9B61E7}.Debug|x86.Build.0 = Debug|Win32
{545F846D-7F19-4D6D-A50B-172A7C9B61E7}.Release|ARM.ActiveCfg = Release|ARM
{545F846D-7F19-4D6D-A50B-172A7C9B61E7}.Release|ARM.Build.0 = Release|ARM
{545F846D-7F19-4D6D-A50B-172A7C9B61E7}.Release|x64.ActiveCfg = Release|x64
{545F846D-7F19-4D6D-A50B-172A7C9B61E7}.Release|x64.Build.0 = Release|x64
{545F846D-7F19-4D6D-A50B-172A7C9B61E7}.Release|x86.ActiveCfg = Release|Win32
{545F846D-7F19-4D6D-A50B-172A7C9B61E7}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
......
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|ARM">
<Configuration>Debug</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM">
<Configuration>Release</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\..\src\videofilters\winrtjpeg2yuv.cpp" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\oRTP\build\windows10\ortp\ortp.vcxproj">
<Project>{2e56b851-9d8d-40e5-84bb-e4ee63b71d25}</Project>
</ProjectReference>
<ProjectReference Include="..\mediastreamer2\mediastreamer2.vcxproj">
<Project>{88e3c241-eb6f-4c84-80dc-89b8961daf80}</Project>
</ProjectReference>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{545f846d-7f19-4d6d-a50b-172a7c9b61e7}</ProjectGuid>
<Keyword>WindowsRuntimeComponent</Keyword>
<ProjectName>mswinrtjpeg2yuv</ProjectName>
<RootNamespace>mswinrtjpeg2yuv</RootNamespace>
<DefaultLanguage>en-US</DefaultLanguage>
<MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>
<AppContainerApplication>true</AppContainerApplication>
<ApplicationType>Windows Store</ApplicationType>
<ApplicationTypeRevision>8.2</ApplicationTypeRevision>
<TargetPlatformVersion>10.0.10069.0</TargetPlatformVersion>
<TargetPlatformMinVersion>10.0.10069.0</TargetPlatformMinVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<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)'=='Debug'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<PreprocessorDefinitions>_WINRT_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalUsingDirectories>$(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories)</AdditionalUsingDirectories>
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
<DisableSpecificWarnings>28204</DisableSpecificWarnings>
<AdditionalIncludeDirectories>$(ProjectDir)..\..\..\include;$(ProjectDir)..\..\..\..\oRTP\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)'=='Release'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<PreprocessorDefinitions>_WINRT_DLL;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalUsingDirectories>$(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories)</AdditionalUsingDirectories>
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
<DisableSpecificWarnings>28204</DisableSpecificWarnings>
<AdditionalIncludeDirectories>$(ProjectDir)..\..\..\include;$(ProjectDir)..\..\..\..\oRTP\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
\ No newline at end of file
......@@ -276,6 +276,28 @@ static mblk_t *_ms_load_jpeg_as_yuv(const char *jpgpath, MSVideoSize *reqsize){
#endif
}
#ifdef MS2_WINDOWS_UNIVERSAL
typedef mblk_t * (*jpeg2yuv_routine_t)(const char *, MSVideoSize *);
mblk_t * _ms_winrt_load_jpeg_as_yuv(const char *jpgpath, MSVideoSize *reqsize) {
mblk_t *result = NULL;
HMODULE h = LoadPackagedLibrary(L"mswinrtjpeg2yuv.dll", 0);
if (h == NULL) {
ms_error("Cannot load mswinrtjpeg2yuv.dll to convert jpeg file to YUV");
}
else {
jpeg2yuv_routine_t routine = (jpeg2yuv_routine_t)GetProcAddress(h, "winrtjpeg2yuv");
if (routine == NULL) {
ms_error("Cannot find winrtjpeg2yuv routine in mswinrtjpeg2yuv.dll");
}
else {
result = routine(jpgpath, reqsize);
}
}
return result;
}
#endif
static mblk_t * generate_black_yuv_frame(MSVideoSize *reqsize) {
MSPicture dest;
mblk_t *m = ms_yuv_buf_alloc(&dest, reqsize->width, reqsize->height);
......@@ -289,7 +311,13 @@ static mblk_t * generate_black_yuv_frame(MSVideoSize *reqsize) {
mblk_t *ms_load_jpeg_as_yuv(const char *jpgpath, MSVideoSize *reqsize) {
mblk_t *m = NULL;
if (jpgpath != NULL) m = _ms_load_jpeg_as_yuv(jpgpath, reqsize);
if (jpgpath != NULL) {
#ifdef MS2_WINDOWS_UNIVERSAL
m = _ms_winrt_load_jpeg_as_yuv(jpgpath, reqsize);
#else
m = _ms_load_jpeg_as_yuv(jpgpath, reqsize);
#endif
}
if (m == NULL) m = generate_black_yuv_frame(reqsize);
return m;
}
......
#include <windows.h>
#include <ppltasks.h>
#include <string>
#include <mediastreamer2/mscommon.h>
#include <mediastreamer2/msvideo.h>
using namespace Concurrency;
using namespace Windows::Foundation;
using namespace Windows::Graphics::Imaging;
using namespace Windows::Storage;
using namespace Windows::Storage::Streams;
class MSWinRTJpeg2Yuv
{
private:
static std::wstring UTF8ToUTF16(const char *utf8)
{
if ((utf8 == nullptr) || (*utf8 == '\0'))
return std::wstring();
int utf8len = static_cast<int>(strlen(utf8));
// Get the size to alloc for utf-16 string
int utf16len = MultiByteToWideChar(CP_UTF8, 0, utf8, utf8len, nullptr, 0);
if (utf16len == 0) {
DWORD error = GetLastError();
ms_error("Invalid UTF-8 character, can't convert to UTF-16: %d", error);
return std::wstring();
}
// Do the conversion
std::wstring utf16;
utf16.resize(utf16len);
if (MultiByteToWideChar(CP_UTF8, 0, utf8, utf8len, &utf16[0], (int)utf16.length()) == 0) {
DWORD error = GetLastError();
ms_error("Error during string conversion from UTF-8 to UTF-16: %d", error);
return std::wstring();
}
return utf16;
};
const char *mJpegPath;
MSVideoSize *mReqSize;
HANDLE mConversionEvent;
mblk_t *mResult;
public:
MSWinRTJpeg2Yuv(const char *jpgpath, MSVideoSize *reqsize)
: mJpegPath(jpgpath), mReqSize(reqsize), mResult(NULL)
{
mConversionEvent = CreateEventEx(NULL, NULL, 0, EVENT_ALL_ACCESS);
}
~MSWinRTJpeg2Yuv()
{
CloseHandle(mConversionEvent);
}
mblk_t * Convert()
{
if (mJpegPath == NULL) return NULL;
std::wstring wsjpgpath = UTF8ToUTF16(mJpegPath);
std::replace(wsjpgpath.begin(), wsjpgpath.end(), L'/', L'\\');
const wchar_t* wjpgpath = wsjpgpath.c_str();
Platform::String^ sjpgpath = ref new Platform::String(wjpgpath);
IAsyncOperation<StorageFile^>^ op = StorageFile::GetFileFromPathAsync(sjpgpath);
op->Completed = ref new AsyncOperationCompletedHandler<StorageFile^>([this](IAsyncOperation<StorageFile^>^ asyncOp, AsyncStatus asyncStatus) {
if (asyncStatus == AsyncStatus::Completed) {
StorageFile^ file = asyncOp->GetResults();
IAsyncOperation<IRandomAccessStream^>^ op = file->OpenAsync(FileAccessMode::Read);
op->Completed = ref new AsyncOperationCompletedHandler<IRandomAccessStream^>([this](IAsyncOperation<IRandomAccessStream^>^ asyncOp, AsyncStatus asyncStatus) {
if (asyncStatus == AsyncStatus::Completed) {
IRandomAccessStream^ stream = asyncOp->GetResults();
IAsyncOperation<BitmapDecoder^>^ op = BitmapDecoder::CreateAsync(stream);
op->Completed = ref new AsyncOperationCompletedHandler<BitmapDecoder^>([this](IAsyncOperation<BitmapDecoder^>^ asyncOp, AsyncStatus asyncStatus) {
if (asyncStatus == AsyncStatus::Completed) {
BitmapDecoder^ decoder = asyncOp->GetResults();
BitmapTransform^ transform = ref new BitmapTransform();
transform->ScaledWidth = this->mReqSize->width;
transform->ScaledHeight = this->mReqSize->height;
IAsyncOperation<PixelDataProvider^>^ op = decoder->GetPixelDataAsync(
decoder->BitmapPixelFormat, decoder->BitmapAlphaMode, transform, ExifOrientationMode::RespectExifOrientation, ColorManagementMode::ColorManageToSRgb);
op->Completed = ref new AsyncOperationCompletedHandler<PixelDataProvider^>([this](IAsyncOperation<PixelDataProvider^>^ asyncOp, AsyncStatus asyncStatus) {
if (asyncStatus == AsyncStatus::Completed) {
PixelDataProvider^ provider = asyncOp->GetResults();
MSPicture destPicture;
mResult = ms_yuv_buf_alloc(&destPicture, mReqSize->width, mReqSize->height);
Platform::Array<unsigned char>^ data = provider->DetachPixelData();
unsigned char *cdata = data->Data;
for (int y = 0; y < mReqSize->height; y++) {
for (int x = 0; x < mReqSize->width; x++) {
uint8_t b = data->Data[y * mReqSize->width * 4 + x * 4 + 0];
uint8_t g = data->Data[y * mReqSize->width * 4 + x * 4 + 1];
uint8_t r = data->Data[y * mReqSize->width * 4 + x * 4 + 2];
// Y
*destPicture.planes[0]++ = (uint8_t)((0.257 * r) + (0.504 * g) + (0.098 * b) + 16);
// U/V subsampling
if ((y % 2 == 0) && (x % 2 == 0)) {
uint32_t r32 = 0, g32 = 0, b32 = 0;
for (int i = 0; i<2; i++) {
for (int j = 0; j<2; j++) {
b32 += data->Data[(y + i) * mReqSize->width * 4 + (x + j) * 4 + 0];
g32 += data->Data[(y + i) * mReqSize->width * 4 + (x + j) * 4 + 1];
r32 += data->Data[(y + i) * mReqSize->width * 4 + (x + j) * 4 + 2];
}
}
r32 = (uint32_t)(r32 * 0.25f); g32 = (uint32_t)(g32 * 0.25f); b32 = (uint32_t)(b32 * 0.25f);
// U
*destPicture.planes[1]++ = (uint8_t)(-(0.148 * r32) - (0.291 * g32) + (0.439 * b32) + 128);
// V
*destPicture.planes[2]++ = (uint8_t)((0.439 * r32) - (0.368 * g32) - (0.071 * b32) + 128);
}
}
}
} else {
ms_error("Windows::Graphics::Imaging::BitmapDecoder::GetPixelDataAsync failed");
}
SetEvent(this->mConversionEvent);
});
} else {
ms_error("Windows::Graphics::Imaging::BitmapDecoder::CreateAsync failed");
SetEvent(this->mConversionEvent);
}
});
} else {
ms_error("Windows::Storage::StorageFile::OpenAsync failed");
SetEvent(this->mConversionEvent);
}
});
} else {
ms_error("Windows::Storage::StorageFile::GetFileFromPathAsync failed");
SetEvent(this->mConversionEvent);
}
});
WaitForSingleObjectEx(mConversionEvent, INFINITE, FALSE);
return mResult;
};
};
extern "C" __declspec(dllexport) mblk_t * winrtjpeg2yuv(const char *jpgpath, MSVideoSize *reqsize)
{
mblk_t *result = NULL;
MSWinRTJpeg2Yuv *converter = new MSWinRTJpeg2Yuv(jpgpath, reqsize);
result = converter->Convert();
delete converter;
return result;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment