diff --git a/ClientServerLib/ClientServerLib/CConnection.cs b/ClientServerLib/ClientServerLib/CConnection.cs index c217bd4b..08f02e26 100644 --- a/ClientServerLib/ClientServerLib/CConnection.cs +++ b/ClientServerLib/ClientServerLib/CConnection.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Net.Sockets; using System.IO; +using System.IO.Compression; using System.Security.Cryptography; using System.Text; @@ -91,6 +92,16 @@ namespace ClientServerLib } public byte[] Encrypt(byte[] Data) + { + return _Encrypt(_Compress(Data)); + } + + public byte[] Decrypt(byte[] Data) + { + return _Decompress(_Decrypt(Data)); + } + + private byte[] _Encrypt(byte[] Data) { if (Data == null || (!keySet && encryption)) return Data; @@ -142,7 +153,7 @@ namespace ClientServerLib } } - public byte[] Decrypt(byte[] Data) + private byte[] _Decrypt(byte[] Data) { if (Data == null || (!keySet && encryption)) return Data; @@ -202,5 +213,64 @@ namespace ClientServerLib } } } + + private byte[] _Compress(byte[] Data) + { + if (Data == null) + return Data; + + using (var compressed = new MemoryStream()) + { + using (var gz = new GZipStream(compressed, CompressionMode.Compress, true)) + { + gz.Write(Data, 0, Data.Length); + } + + byte[] result = null; + + if (compressed.Length < Data.Length) + { + result = new byte[compressed.Length + 1]; + result[0] = 1; //data stream is compressed + compressed.Position = 0; + compressed.Read(result, 1, (int)compressed.Length); + } + else + { + result = new byte[Data.Length + 1]; + result[0] = 0; //data stream is not compressed + Array.Copy(Data, 0, result, 1, Data.Length); + } + + return result; + } + } + + private byte[] _Decompress(byte[] Data) + { + if (Data == null) + return Data; + + if (Data[0] == 0) //not compressed + { + byte[] result = new byte[Data.Length - 1]; + Array.Copy(Data, 1, result, 0, result.Length); + return result; + } + + using (var inStream = new MemoryStream()) + { + inStream.Write(Data, 1, Data.Length - 1); + inStream.Position = 0; + + using (var outStream = new MemoryStream()) + { + using (var gz = new GZipStream(inStream, CompressionMode.Decompress, true)) + gz.CopyTo(outStream); + + return outStream.ToArray(); + } + } + } } } diff --git a/GstreamerHelper/GstreamerHelper.vcxproj b/GstreamerHelper/GstreamerHelper.vcxproj index d6ef40c8..3f43af5b 100644 --- a/GstreamerHelper/GstreamerHelper.vcxproj +++ b/GstreamerHelper/GstreamerHelper.vcxproj @@ -116,6 +116,7 @@ Windows true gstreamer-1.0.lib;gstcontroller-1.0.lib;gobject-2.0.lib;glib-2.0.lib;gstapp-1.0.lib;%(AdditionalDependencies) + true xcopy "$(OutDir)*.dll" "$(SolutionDir)Output\x86\gstreamer\" /I /Y @@ -136,6 +137,7 @@ Windows true gstreamer-1.0.lib;gstcontroller-1.0.lib;gobject-2.0.lib;glib-2.0.lib;gstapp-1.0.lib;%(AdditionalDependencies) + true xcopy "$(OutDir)*.dll" "$(SolutionDir)Output\x64\gstreamer\" /I /Y diff --git a/Vocaluxe.sln.DotSettings b/Vocaluxe.sln.DotSettings index 473f1044..33cad2d0 100644 --- a/Vocaluxe.sln.DotSettings +++ b/Vocaluxe.sln.DotSettings @@ -9,8 +9,8 @@ DO_NOT_SHOW DO_NOT_SHOW DO_NOT_SHOW - <?xml version="1.0" encoding="utf-16"?><Profile name="Cleanup"><CSArrangeThisQualifier>True</CSArrangeThisQualifier><CSRemoveCodeRedundancies>True</CSRemoveCodeRedundancies><CSMakeFieldReadonly>True</CSMakeFieldReadonly><CSUseVar><BehavourStyle>CAN_CHANGE_TO_EXPLICIT</BehavourStyle><LocalVariableStyle>ALWAYS_EXPLICIT</LocalVariableStyle><ForeachVariableStyle>ALWAYS_EXPLICIT</ForeachVariableStyle></CSUseVar><CSOptimizeUsings><OptimizeUsings>False</OptimizeUsings><EmbraceInRegion>False</EmbraceInRegion><RegionName></RegionName></CSOptimizeUsings><CSReformatCode>True</CSReformatCode><CSharpFormatDocComments>True</CSharpFormatDocComments><CSShortenReferences>True</CSShortenReferences><StyleCop.Documentation><SA1600ElementsMustBeDocumented>False</SA1600ElementsMustBeDocumented><SA1604ElementDocumentationMustHaveSummary>False</SA1604ElementDocumentationMustHaveSummary><SA1609PropertyDocumentationMustHaveValueDocumented>False</SA1609PropertyDocumentationMustHaveValueDocumented><SA1611ElementParametersMustBeDocumented>False</SA1611ElementParametersMustBeDocumented><SA1615ElementReturnValueMustBeDocumented>False</SA1615ElementReturnValueMustBeDocumented><SA1617VoidReturnValueMustNotBeDocumented>False</SA1617VoidReturnValueMustNotBeDocumented><SA1618GenericTypeParametersMustBeDocumented>False</SA1618GenericTypeParametersMustBeDocumented><SA1626SingleLineCommentsMustNotUseDocumentationStyleSlashes>False</SA1626SingleLineCommentsMustNotUseDocumentationStyleSlashes><SA1628DocumentationTextMustBeginWithACapitalLetter>False</SA1628DocumentationTextMustBeginWithACapitalLetter><SA1629DocumentationTextMustEndWithAPeriod>False</SA1629DocumentationTextMustEndWithAPeriod><SA1633SA1641UpdateFileHeader>Ignore</SA1633SA1641UpdateFileHeader><SA1639FileHeaderMustHaveSummary>False</SA1639FileHeaderMustHaveSummary><SA1642ConstructorSummaryDocumentationMustBeginWithStandardText>False</SA1642ConstructorSummaryDocumentationMustBeginWithStandardText><SA1643DestructorSummaryDocumentationMustBeginWithStandardText>False</SA1643DestructorSummaryDocumentationMustBeginWithStandardText><SA1644DocumentationHeadersMustNotContainBlankLines>False</SA1644DocumentationHeadersMustNotContainBlankLines></StyleCop.Documentation><StyleCop.Layout><SA1500CurlyBracketsForMultiLineStatementsMustNotShareLine>False</SA1500CurlyBracketsForMultiLineStatementsMustNotShareLine><SA1509OpeningCurlyBracketsMustNotBePrecededByBlankLine>True</SA1509OpeningCurlyBracketsMustNotBePrecededByBlankLine><SA1510ChainedStatementBlocksMustNotBePrecededByBlankLine>True</SA1510ChainedStatementBlocksMustNotBePrecededByBlankLine><SA1511WhileDoFooterMustNotBePrecededByBlankLine>True</SA1511WhileDoFooterMustNotBePrecededByBlankLine><SA1512SingleLineCommentsMustNotBeFollowedByBlankLine>True</SA1512SingleLineCommentsMustNotBeFollowedByBlankLine><SA1513ClosingCurlyBracketMustBeFollowedByBlankLine>False</SA1513ClosingCurlyBracketMustBeFollowedByBlankLine><SA1514ElementDocumentationHeaderMustBePrecededByBlankLine>False</SA1514ElementDocumentationHeaderMustBePrecededByBlankLine><SA1515SingleLineCommentMustBeProceededByBlankLine>False</SA1515SingleLineCommentMustBeProceededByBlankLine></StyleCop.Layout><StyleCop.Readability><SA1100DoNotPrefixCallsWithBaseUnlessLocalImplementationExists>True</SA1100DoNotPrefixCallsWithBaseUnlessLocalImplementationExists><SA1106CodeMustNotContainEmptyStatements>True</SA1106CodeMustNotContainEmptyStatements><SA1108BlockStatementsMustNotContainEmbeddedComments>True</SA1108BlockStatementsMustNotContainEmbeddedComments><SA1109BlockStatementsMustNotContainEmbeddedRegions>True</SA1109BlockStatementsMustNotContainEmbeddedRegions><SA1120CommentsMustContainText>False</SA1120CommentsMustContainText><SA1121UseBuiltInTypeAlias>False</SA1121UseBuiltInTypeAlias><SA1122UseStringEmptyForEmptyStrings>False</SA1122UseStringEmptyForEmptyStrings><SA1123DoNotPlaceRegionsWithinElements>False</SA1123DoNotPlaceRegionsWithinElements><SA1124CodeMustNotContainEmptyRegions>True</SA1124CodeMustNotContainEmptyRegions></StyleCop.Readability><StyleCop.Spacing><SA1001CommasMustBeSpacedCorrectly>False</SA1001CommasMustBeSpacedCorrectly><SA1005SingleLineCommentsMustBeginWithSingleSpace>False</SA1005SingleLineCommentsMustBeginWithSingleSpace><SA1006PreprocessorKeywordsMustNotBePrecededBySpace>True</SA1006PreprocessorKeywordsMustNotBePrecededBySpace><SA1021NegativeSignsMustBeSpacedCorrectly>True</SA1021NegativeSignsMustBeSpacedCorrectly><SA1022PositiveSignsMustBeSpacedCorrectly>True</SA1022PositiveSignsMustBeSpacedCorrectly><SA1025CodeMustNotContainMultipleWhitespaceInARow>True</SA1025CodeMustNotContainMultipleWhitespaceInARow></StyleCop.Spacing><StyleCop.Ordering><AlphabeticalUsingDirectives>Ignore</AlphabeticalUsingDirectives><ExpandUsingDirectives>Ignore</ExpandUsingDirectives><SA1212PropertyAccessorsMustFollowOrder>True</SA1212PropertyAccessorsMustFollowOrder><SA1213EventAccessorsMustFollowOrder>True</SA1213EventAccessorsMustFollowOrder></StyleCop.Ordering><CSUpdateFileHeader>True</CSUpdateFileHeader><CSUseAutoProperty>True</CSUseAutoProperty></Profile> - <?xml version="1.0" encoding="utf-16"?><Profile name="Simple Reformat"><CSOptimizeUsings><OptimizeUsings>False</OptimizeUsings><EmbraceInRegion>False</EmbraceInRegion><RegionName></RegionName></CSOptimizeUsings><CSReformatCode>True</CSReformatCode><StyleCop.Documentation><SA1600ElementsMustBeDocumented>False</SA1600ElementsMustBeDocumented><SA1604ElementDocumentationMustHaveSummary>False</SA1604ElementDocumentationMustHaveSummary><SA1609PropertyDocumentationMustHaveValueDocumented>False</SA1609PropertyDocumentationMustHaveValueDocumented><SA1611ElementParametersMustBeDocumented>False</SA1611ElementParametersMustBeDocumented><SA1615ElementReturnValueMustBeDocumented>False</SA1615ElementReturnValueMustBeDocumented><SA1617VoidReturnValueMustNotBeDocumented>False</SA1617VoidReturnValueMustNotBeDocumented><SA1618GenericTypeParametersMustBeDocumented>False</SA1618GenericTypeParametersMustBeDocumented><SA1626SingleLineCommentsMustNotUseDocumentationStyleSlashes>False</SA1626SingleLineCommentsMustNotUseDocumentationStyleSlashes><SA1628DocumentationTextMustBeginWithACapitalLetter>False</SA1628DocumentationTextMustBeginWithACapitalLetter><SA1629DocumentationTextMustEndWithAPeriod>False</SA1629DocumentationTextMustEndWithAPeriod><SA1633SA1641UpdateFileHeader>Ignore</SA1633SA1641UpdateFileHeader><SA1639FileHeaderMustHaveSummary>False</SA1639FileHeaderMustHaveSummary><SA1642ConstructorSummaryDocumentationMustBeginWithStandardText>False</SA1642ConstructorSummaryDocumentationMustBeginWithStandardText><SA1643DestructorSummaryDocumentationMustBeginWithStandardText>False</SA1643DestructorSummaryDocumentationMustBeginWithStandardText><SA1644DocumentationHeadersMustNotContainBlankLines>False</SA1644DocumentationHeadersMustNotContainBlankLines></StyleCop.Documentation><StyleCop.Spacing><SA1001CommasMustBeSpacedCorrectly>False</SA1001CommasMustBeSpacedCorrectly><SA1005SingleLineCommentsMustBeginWithSingleSpace>False</SA1005SingleLineCommentsMustBeginWithSingleSpace><SA1006PreprocessorKeywordsMustNotBePrecededBySpace>True</SA1006PreprocessorKeywordsMustNotBePrecededBySpace><SA1021NegativeSignsMustBeSpacedCorrectly>True</SA1021NegativeSignsMustBeSpacedCorrectly><SA1022PositiveSignsMustBeSpacedCorrectly>True</SA1022PositiveSignsMustBeSpacedCorrectly><SA1025CodeMustNotContainMultipleWhitespaceInARow>True</SA1025CodeMustNotContainMultipleWhitespaceInARow></StyleCop.Spacing><StyleCop.Readability><SA1100DoNotPrefixCallsWithBaseUnlessLocalImplementationExists>True</SA1100DoNotPrefixCallsWithBaseUnlessLocalImplementationExists><SA1106CodeMustNotContainEmptyStatements>True</SA1106CodeMustNotContainEmptyStatements><SA1108BlockStatementsMustNotContainEmbeddedComments>True</SA1108BlockStatementsMustNotContainEmbeddedComments><SA1109BlockStatementsMustNotContainEmbeddedRegions>True</SA1109BlockStatementsMustNotContainEmbeddedRegions><SA1120CommentsMustContainText>False</SA1120CommentsMustContainText><SA1121UseBuiltInTypeAlias>False</SA1121UseBuiltInTypeAlias><SA1122UseStringEmptyForEmptyStrings>False</SA1122UseStringEmptyForEmptyStrings><SA1123DoNotPlaceRegionsWithinElements>False</SA1123DoNotPlaceRegionsWithinElements><SA1124CodeMustNotContainEmptyRegions>True</SA1124CodeMustNotContainEmptyRegions></StyleCop.Readability><StyleCop.Layout><SA1500CurlyBracketsForMultiLineStatementsMustNotShareLine>False</SA1500CurlyBracketsForMultiLineStatementsMustNotShareLine><SA1509OpeningCurlyBracketsMustNotBePrecededByBlankLine>True</SA1509OpeningCurlyBracketsMustNotBePrecededByBlankLine><SA1510ChainedStatementBlocksMustNotBePrecededByBlankLine>True</SA1510ChainedStatementBlocksMustNotBePrecededByBlankLine><SA1511WhileDoFooterMustNotBePrecededByBlankLine>True</SA1511WhileDoFooterMustNotBePrecededByBlankLine><SA1512SingleLineCommentsMustNotBeFollowedByBlankLine>True</SA1512SingleLineCommentsMustNotBeFollowedByBlankLine><SA1513ClosingCurlyBracketMustBeFollowedByBlankLine>False</SA1513ClosingCurlyBracketMustBeFollowedByBlankLine><SA1514ElementDocumentationHeaderMustBePrecededByBlankLine>False</SA1514ElementDocumentationHeaderMustBePrecededByBlankLine><SA1515SingleLineCommentMustBeProceededByBlankLine>False</SA1515SingleLineCommentMustBeProceededByBlankLine></StyleCop.Layout><StyleCop.Ordering><AlphabeticalUsingDirectives>Ignore</AlphabeticalUsingDirectives><ExpandUsingDirectives>Ignore</ExpandUsingDirectives><SA1212PropertyAccessorsMustFollowOrder>True</SA1212PropertyAccessorsMustFollowOrder><SA1213EventAccessorsMustFollowOrder>True</SA1213EventAccessorsMustFollowOrder></StyleCop.Ordering><CSShortenReferences>True</CSShortenReferences></Profile> + <?xml version="1.0" encoding="utf-16"?><Profile name="Cleanup"><CSArrangeThisQualifier>True</CSArrangeThisQualifier><CSRemoveCodeRedundancies>True</CSRemoveCodeRedundancies><CSMakeFieldReadonly>True</CSMakeFieldReadonly><CSUseVar><BehavourStyle>CAN_CHANGE_TO_IMPLICIT</BehavourStyle><LocalVariableStyle>IMPLICIT_WHEN_INITIALIZER_HAS_TYPE</LocalVariableStyle><ForeachVariableStyle>ALWAYS_EXPLICIT</ForeachVariableStyle></CSUseVar><CSOptimizeUsings><OptimizeUsings>False</OptimizeUsings><EmbraceInRegion>False</EmbraceInRegion><RegionName></RegionName></CSOptimizeUsings><CSReformatCode>True</CSReformatCode><CSharpFormatDocComments>True</CSharpFormatDocComments><CSShortenReferences>True</CSShortenReferences><StyleCop.Documentation><SA1600ElementsMustBeDocumented>False</SA1600ElementsMustBeDocumented><SA1604ElementDocumentationMustHaveSummary>False</SA1604ElementDocumentationMustHaveSummary><SA1609PropertyDocumentationMustHaveValueDocumented>False</SA1609PropertyDocumentationMustHaveValueDocumented><SA1611ElementParametersMustBeDocumented>False</SA1611ElementParametersMustBeDocumented><SA1615ElementReturnValueMustBeDocumented>False</SA1615ElementReturnValueMustBeDocumented><SA1617VoidReturnValueMustNotBeDocumented>False</SA1617VoidReturnValueMustNotBeDocumented><SA1618GenericTypeParametersMustBeDocumented>False</SA1618GenericTypeParametersMustBeDocumented><SA1626SingleLineCommentsMustNotUseDocumentationStyleSlashes>False</SA1626SingleLineCommentsMustNotUseDocumentationStyleSlashes><SA1628DocumentationTextMustBeginWithACapitalLetter>False</SA1628DocumentationTextMustBeginWithACapitalLetter><SA1629DocumentationTextMustEndWithAPeriod>False</SA1629DocumentationTextMustEndWithAPeriod><SA1633SA1641UpdateFileHeader>Ignore</SA1633SA1641UpdateFileHeader><SA1639FileHeaderMustHaveSummary>False</SA1639FileHeaderMustHaveSummary><SA1642ConstructorSummaryDocumentationMustBeginWithStandardText>False</SA1642ConstructorSummaryDocumentationMustBeginWithStandardText><SA1643DestructorSummaryDocumentationMustBeginWithStandardText>False</SA1643DestructorSummaryDocumentationMustBeginWithStandardText><SA1644DocumentationHeadersMustNotContainBlankLines>False</SA1644DocumentationHeadersMustNotContainBlankLines></StyleCop.Documentation><StyleCop.Layout><SA1500CurlyBracketsForMultiLineStatementsMustNotShareLine>False</SA1500CurlyBracketsForMultiLineStatementsMustNotShareLine><SA1509OpeningCurlyBracketsMustNotBePrecededByBlankLine>True</SA1509OpeningCurlyBracketsMustNotBePrecededByBlankLine><SA1510ChainedStatementBlocksMustNotBePrecededByBlankLine>True</SA1510ChainedStatementBlocksMustNotBePrecededByBlankLine><SA1511WhileDoFooterMustNotBePrecededByBlankLine>True</SA1511WhileDoFooterMustNotBePrecededByBlankLine><SA1512SingleLineCommentsMustNotBeFollowedByBlankLine>True</SA1512SingleLineCommentsMustNotBeFollowedByBlankLine><SA1513ClosingCurlyBracketMustBeFollowedByBlankLine>False</SA1513ClosingCurlyBracketMustBeFollowedByBlankLine><SA1514ElementDocumentationHeaderMustBePrecededByBlankLine>False</SA1514ElementDocumentationHeaderMustBePrecededByBlankLine><SA1515SingleLineCommentMustBeProceededByBlankLine>False</SA1515SingleLineCommentMustBeProceededByBlankLine></StyleCop.Layout><StyleCop.Readability><SA1100DoNotPrefixCallsWithBaseUnlessLocalImplementationExists>True</SA1100DoNotPrefixCallsWithBaseUnlessLocalImplementationExists><SA1106CodeMustNotContainEmptyStatements>True</SA1106CodeMustNotContainEmptyStatements><SA1108BlockStatementsMustNotContainEmbeddedComments>True</SA1108BlockStatementsMustNotContainEmbeddedComments><SA1109BlockStatementsMustNotContainEmbeddedRegions>True</SA1109BlockStatementsMustNotContainEmbeddedRegions><SA1120CommentsMustContainText>False</SA1120CommentsMustContainText><SA1121UseBuiltInTypeAlias>False</SA1121UseBuiltInTypeAlias><SA1122UseStringEmptyForEmptyStrings>False</SA1122UseStringEmptyForEmptyStrings><SA1123DoNotPlaceRegionsWithinElements>False</SA1123DoNotPlaceRegionsWithinElements><SA1124CodeMustNotContainEmptyRegions>True</SA1124CodeMustNotContainEmptyRegions></StyleCop.Readability><StyleCop.Spacing><SA1001CommasMustBeSpacedCorrectly>False</SA1001CommasMustBeSpacedCorrectly><SA1005SingleLineCommentsMustBeginWithSingleSpace>False</SA1005SingleLineCommentsMustBeginWithSingleSpace><SA1006PreprocessorKeywordsMustNotBePrecededBySpace>True</SA1006PreprocessorKeywordsMustNotBePrecededBySpace><SA1021NegativeSignsMustBeSpacedCorrectly>True</SA1021NegativeSignsMustBeSpacedCorrectly><SA1022PositiveSignsMustBeSpacedCorrectly>True</SA1022PositiveSignsMustBeSpacedCorrectly><SA1025CodeMustNotContainMultipleWhitespaceInARow>True</SA1025CodeMustNotContainMultipleWhitespaceInARow></StyleCop.Spacing><StyleCop.Ordering><AlphabeticalUsingDirectives>Ignore</AlphabeticalUsingDirectives><ExpandUsingDirectives>Ignore</ExpandUsingDirectives><SA1212PropertyAccessorsMustFollowOrder>True</SA1212PropertyAccessorsMustFollowOrder><SA1213EventAccessorsMustFollowOrder>True</SA1213EventAccessorsMustFollowOrder></StyleCop.Ordering><CSUpdateFileHeader>True</CSUpdateFileHeader><CSUseAutoProperty>True</CSUseAutoProperty></Profile> + <?xml version="1.0" encoding="utf-16"?><Profile name="Simple Reformat"><CSOptimizeUsings><OptimizeUsings>False</OptimizeUsings><EmbraceInRegion>False</EmbraceInRegion><RegionName></RegionName></CSOptimizeUsings><CSReformatCode>True</CSReformatCode><StyleCop.Documentation><SA1600ElementsMustBeDocumented>False</SA1600ElementsMustBeDocumented><SA1604ElementDocumentationMustHaveSummary>False</SA1604ElementDocumentationMustHaveSummary><SA1609PropertyDocumentationMustHaveValueDocumented>False</SA1609PropertyDocumentationMustHaveValueDocumented><SA1611ElementParametersMustBeDocumented>False</SA1611ElementParametersMustBeDocumented><SA1615ElementReturnValueMustBeDocumented>False</SA1615ElementReturnValueMustBeDocumented><SA1617VoidReturnValueMustNotBeDocumented>False</SA1617VoidReturnValueMustNotBeDocumented><SA1618GenericTypeParametersMustBeDocumented>False</SA1618GenericTypeParametersMustBeDocumented><SA1626SingleLineCommentsMustNotUseDocumentationStyleSlashes>False</SA1626SingleLineCommentsMustNotUseDocumentationStyleSlashes><SA1628DocumentationTextMustBeginWithACapitalLetter>False</SA1628DocumentationTextMustBeginWithACapitalLetter><SA1629DocumentationTextMustEndWithAPeriod>False</SA1629DocumentationTextMustEndWithAPeriod><SA1633SA1641UpdateFileHeader>Ignore</SA1633SA1641UpdateFileHeader><SA1639FileHeaderMustHaveSummary>False</SA1639FileHeaderMustHaveSummary><SA1642ConstructorSummaryDocumentationMustBeginWithStandardText>False</SA1642ConstructorSummaryDocumentationMustBeginWithStandardText><SA1643DestructorSummaryDocumentationMustBeginWithStandardText>False</SA1643DestructorSummaryDocumentationMustBeginWithStandardText><SA1644DocumentationHeadersMustNotContainBlankLines>False</SA1644DocumentationHeadersMustNotContainBlankLines></StyleCop.Documentation><StyleCop.Spacing><SA1001CommasMustBeSpacedCorrectly>False</SA1001CommasMustBeSpacedCorrectly><SA1005SingleLineCommentsMustBeginWithSingleSpace>False</SA1005SingleLineCommentsMustBeginWithSingleSpace><SA1006PreprocessorKeywordsMustNotBePrecededBySpace>True</SA1006PreprocessorKeywordsMustNotBePrecededBySpace><SA1021NegativeSignsMustBeSpacedCorrectly>True</SA1021NegativeSignsMustBeSpacedCorrectly><SA1022PositiveSignsMustBeSpacedCorrectly>True</SA1022PositiveSignsMustBeSpacedCorrectly><SA1025CodeMustNotContainMultipleWhitespaceInARow>True</SA1025CodeMustNotContainMultipleWhitespaceInARow></StyleCop.Spacing><StyleCop.Readability><SA1100DoNotPrefixCallsWithBaseUnlessLocalImplementationExists>True</SA1100DoNotPrefixCallsWithBaseUnlessLocalImplementationExists><SA1106CodeMustNotContainEmptyStatements>True</SA1106CodeMustNotContainEmptyStatements><SA1108BlockStatementsMustNotContainEmbeddedComments>True</SA1108BlockStatementsMustNotContainEmbeddedComments><SA1109BlockStatementsMustNotContainEmbeddedRegions>True</SA1109BlockStatementsMustNotContainEmbeddedRegions><SA1120CommentsMustContainText>False</SA1120CommentsMustContainText><SA1121UseBuiltInTypeAlias>False</SA1121UseBuiltInTypeAlias><SA1122UseStringEmptyForEmptyStrings>False</SA1122UseStringEmptyForEmptyStrings><SA1123DoNotPlaceRegionsWithinElements>False</SA1123DoNotPlaceRegionsWithinElements><SA1124CodeMustNotContainEmptyRegions>True</SA1124CodeMustNotContainEmptyRegions></StyleCop.Readability><StyleCop.Layout><SA1500CurlyBracketsForMultiLineStatementsMustNotShareLine>False</SA1500CurlyBracketsForMultiLineStatementsMustNotShareLine><SA1509OpeningCurlyBracketsMustNotBePrecededByBlankLine>True</SA1509OpeningCurlyBracketsMustNotBePrecededByBlankLine><SA1510ChainedStatementBlocksMustNotBePrecededByBlankLine>True</SA1510ChainedStatementBlocksMustNotBePrecededByBlankLine><SA1511WhileDoFooterMustNotBePrecededByBlankLine>True</SA1511WhileDoFooterMustNotBePrecededByBlankLine><SA1512SingleLineCommentsMustNotBeFollowedByBlankLine>True</SA1512SingleLineCommentsMustNotBeFollowedByBlankLine><SA1513ClosingCurlyBracketMustBeFollowedByBlankLine>False</SA1513ClosingCurlyBracketMustBeFollowedByBlankLine><SA1514ElementDocumentationHeaderMustBePrecededByBlankLine>False</SA1514ElementDocumentationHeaderMustBePrecededByBlankLine><SA1515SingleLineCommentMustBeProceededByBlankLine>False</SA1515SingleLineCommentMustBeProceededByBlankLine></StyleCop.Layout><StyleCop.Ordering><AlphabeticalUsingDirectives>Ignore</AlphabeticalUsingDirectives><ExpandUsingDirectives>Ignore</ExpandUsingDirectives><SA1212PropertyAccessorsMustFollowOrder>True</SA1212PropertyAccessorsMustFollowOrder><SA1213EventAccessorsMustFollowOrder>True</SA1213EventAccessorsMustFollowOrder></StyleCop.Ordering><CSShortenReferences>True</CSShortenReferences><CSUseVar><BehavourStyle>CAN_CHANGE_TO_IMPLICIT</BehavourStyle><LocalVariableStyle>IMPLICIT_WHEN_INITIALIZER_HAS_TYPE</LocalVariableStyle><ForeachVariableStyle>ALWAYS_EXPLICIT</ForeachVariableStyle></CSUseVar></Profile> Cleanup Simple Reformat 0 diff --git a/Vocaluxe/Base/CBackgroundMusic.cs b/Vocaluxe/Base/CBackgroundMusic.cs index 26377f1d..a47de520 100644 --- a/Vocaluxe/Base/CBackgroundMusic.cs +++ b/Vocaluxe/Base/CBackgroundMusic.cs @@ -55,14 +55,9 @@ namespace Vocaluxe.Base get { return _VideoEnabled; } set { - if (_VideoEnabled && value) + if (_VideoEnabled == value) return; - if (!_VideoEnabled && !value) - return; - if (_VideoEnabled && !value) - ToggleVideo(); - if (!_VideoEnabled && value) - ToggleVideo(); + ToggleVideo(); _VideoEnabled = value; } } @@ -126,7 +121,7 @@ namespace Vocaluxe.Base public static void Init() { - List templist = new List(); + var templist = new List(); foreach (string ending in CSettings.MusicFileTypes) templist.AddRange(CHelper.ListFiles(CSettings.FolderBackgroundMusic, ending, true, true)); @@ -136,8 +131,8 @@ namespace Vocaluxe.Base if (CConfig.BackgroundMusicSource != EBackgroundMusicSource.TR_CONFIG_ONLY_OWN_MUSIC) AddBackgroundMusic(); - if (CConfig.VideoBackgrounds == EOffOn.TR_CONFIG_ON && CConfig.VideosToBackground == EOffOn.TR_CONFIG_ON) - _VideoEnabled = true; + + _VideoEnabled = (CConfig.VideoBackgrounds == EOffOn.TR_CONFIG_ON && CConfig.VideosToBackground == EOffOn.TR_CONFIG_ON); IsPlaying = false; } @@ -439,20 +434,9 @@ namespace Vocaluxe.Base { if (_Video != -1) { - if (_VideoEnabled) - { - _VideoEnabled = false; - CVideo.Close(_Video); - _Video = -1; - CDraw.RemoveTexture(ref _CurrentVideoTexture); - return; - } - if (CVideo.Finished(_Video)) - { - CVideo.Close(_Video); - CDraw.RemoveTexture(ref _CurrentVideoTexture); - _Video = -1; - } + CVideo.Close(_Video); + CDraw.RemoveTexture(ref _CurrentVideoTexture); + _Video = -1; } else _LoadVideo(); @@ -485,17 +469,15 @@ namespace Vocaluxe.Base private static void _LoadVideo() { - if (_Video == -1) - { - _Video = CVideo.Load(_CurrentPlaylistElement.VideoFilePath); - if (_CurrentPlaylistElement.Start > 0.001 && CConfig.BackgroundMusicUseStart == EOffOn.TR_CONFIG_ON) - CVideo.Skip(_Video, _CurrentPlaylistElement.Start, _CurrentPlaylistElement.VideoGap); - else - CVideo.Skip(_Video, 0f, _CurrentPlaylistElement.VideoGap); - _VideoEnabled = true; - _FadeTimer.Reset(); - _FadeTimer.Start(); - } + if (_Video != -1 || String.IsNullOrEmpty(_CurrentPlaylistElement.VideoFilePath)) + return; + _Video = CVideo.Load(_CurrentPlaylistElement.VideoFilePath); + if (_CurrentPlaylistElement.Start > 0.001 && CConfig.BackgroundMusicUseStart == EOffOn.TR_CONFIG_ON) + CVideo.Skip(_Video, _CurrentPlaylistElement.Start, _CurrentPlaylistElement.VideoGap); + else + CVideo.Skip(_Video, 0f, _CurrentPlaylistElement.VideoGap); + _FadeTimer.Reset(); + _FadeTimer.Start(); } } diff --git a/Vocaluxe/Base/CParty.cs b/Vocaluxe/Base/CParty.cs index 461f2269..32b283c8 100644 --- a/Vocaluxe/Base/CParty.cs +++ b/Vocaluxe/Base/CParty.cs @@ -68,7 +68,7 @@ namespace Vocaluxe.Base _IDs.Enqueue(i); //add dummy normal game mode and set it as default - SPartyMode pm = new SPartyMode {PartyMode = new CPartyModeNone(), ScreenFiles = new List()}; + var pm = new SPartyMode {PartyMode = new CPartyModeNone(), ScreenFiles = new List()}; pm.PartyMode.Initialize(); pm.PartyModeID = _IDs.Dequeue(); _NormalGameModeID = pm.PartyModeID; @@ -97,9 +97,9 @@ namespace Vocaluxe.Base public static List GetPartyModeInfos() { - List infos = new List(); + var infos = new List(); - int[] pmIDs = new int[_PartyModes.Count]; + var pmIDs = new int[_PartyModes.Count]; _PartyModes.Keys.CopyTo(pmIDs, 0); foreach (int pmID in pmIDs) @@ -111,7 +111,7 @@ namespace Vocaluxe.Base if (mode.PartyMode != null) { - SPartyModeInfos info = new SPartyModeInfos + var info = new SPartyModeInfos { Author = mode.Author, Description = mode.Description, @@ -219,7 +219,7 @@ namespace Vocaluxe.Base #region private stuff private static void _LoadPartyModes() { - List files = new List(); + var files = new List(); files.AddRange(CHelper.ListFiles(CSettings.FolderPartyModes, "*.xml", false, true)); foreach (string file in files) @@ -231,7 +231,7 @@ namespace Vocaluxe.Base private static SPartyMode _LoadPartyMode(string file) { - SPartyMode pm = new SPartyMode {PartyModeID = _IDs.Dequeue(), ScreenFiles = new List(), NoErrors = false}; + var pm = new SPartyMode {PartyModeID = _IDs.Dequeue(), ScreenFiles = new List(), NoErrors = false}; CXMLReader xmlReader = CXMLReader.OpenFile(file); @@ -272,7 +272,7 @@ namespace Vocaluxe.Base string pathToCode = Path.Combine(Path.Combine(CSettings.FolderPartyModes, pm.Folder), CSettings.FolderPartyModeCode); - List filesToCompile = new List(); + var filesToCompile = new List(); filesToCompile.AddRange(CHelper.ListFiles(pathToCode, "*.cs", false, true)); Assembly output = _CompileFiles(filesToCompile.ToArray()); @@ -304,7 +304,7 @@ namespace Vocaluxe.Base pm.PartyMode.Initialize(); pm.PartyMode.SetFolder(Path.Combine(Directory.GetCurrentDirectory(), Path.Combine(CSettings.FolderPartyModes, pm.Folder))); - if (!CTheme.AddTheme(Path.Combine(Directory.GetCurrentDirectory(), Path.Combine(Path.Combine(CSettings.FolderPartyModes, pm.Folder), "Theme.xml")), pm.PartyModeID)) + if (!CTheme.AddTheme(Path.Combine(pm.PartyMode.GetFolder(), "Theme.xml"),pm.PartyModeID)) return pm; int themeIndex = CTheme.GetThemeIndex(pm.PartyModeID); @@ -325,7 +325,7 @@ namespace Vocaluxe.Base if (screen != null) { screen.Init(); - screen.AssingPartyMode(pm.PartyMode); + screen.AssignPartyMode(pm.PartyMode); screen.SetPartyModeID(pm.PartyModeID); screen.LoadTheme(xmlPath); pm.PartyMode.AddScreen(screen, screenfile); @@ -343,7 +343,7 @@ namespace Vocaluxe.Base if (files == null || files.Length == 0) return null; - CompilerParameters compilerParams = new CompilerParameters(); + var compilerParams = new CompilerParameters(); compilerParams.ReferencedAssemblies.Add("System.Windows.Forms.dll"); compilerParams.ReferencedAssemblies.Add("System.Core.dll"); compilerParams.ReferencedAssemblies.Add("VocaluxeLib.dll"); diff --git a/Vocaluxe/Base/CTheme.cs b/Vocaluxe/Base/CTheme.cs index 9461dbda..7f08c8e9 100644 --- a/Vocaluxe/Base/CTheme.cs +++ b/Vocaluxe/Base/CTheme.cs @@ -44,13 +44,15 @@ namespace Vocaluxe.Base public int PartyModeID; } - struct SSkinElement + class CSkinElement { - public string Name; public string Value; - public CTexture Texture; - public int VideoIndex; + } + + class CVideoSkinElement : CSkinElement + { + public int VideoIndex = -1; } struct SSkin @@ -64,8 +66,8 @@ namespace Vocaluxe.Base public string FileName; public int PartyModeID; - public Dictionary SkinList; - public List VideoList; + public Dictionary SkinList; + public Dictionary VideoList; public SColors ThemeColors; } @@ -111,9 +113,9 @@ namespace Vocaluxe.Base { get { - List names = new List(); + var names = new List(); // ReSharper disable LoopCanBeConvertedToQuery - foreach (STheme th in _Themes) + foreach (var th in _Themes) // ReSharper restore LoopCanBeConvertedToQuery { if (th.PartyModeID == -1) @@ -128,9 +130,9 @@ namespace Vocaluxe.Base { get { - List names = new List(); + var names = new List(); // ReSharper disable LoopCanBeConvertedToQuery - foreach (SSkin sk in _Skins) + foreach (var sk in _Skins) // ReSharper restore LoopCanBeConvertedToQuery { if (sk.PartyModeID == -1) @@ -172,48 +174,34 @@ namespace Vocaluxe.Base if (xmlReader == null) return false; - string value; - - // load skins/textures - List keys = new List(_Skins[skinIndex].SkinList.Keys); - - foreach (string name in keys) + foreach (var valuePair in _Skins[skinIndex].SkinList) { + CSkinElement sk = valuePair.Value; try { - xmlReader.GetValue("//root/Skins/" + name, out value, String.Empty); - SSkinElement sk = _Skins[skinIndex].SkinList[name]; - sk.Value = value; - sk.VideoIndex = -1; + xmlReader.GetValue("//root/Skins/" + valuePair.Key, out sk.Value, String.Empty); sk.Texture = CDraw.AddTexture(Path.Combine(_Skins[skinIndex].Path, sk.Value)); - _Skins[skinIndex].SkinList[name] = sk; } catch (Exception e) { - MessageBox.Show("Error on loading texture \"" + name + "\": " + e.Message + e.StackTrace); - CLog.LogError("Error on loading texture \"" + name + "\": " + e.Message + e.StackTrace); + MessageBox.Show("Error on loading texture \"" + valuePair.Key + "\": " + e.Message + e.StackTrace); + CLog.LogError("Error on loading texture \"" + valuePair.Key + "\": " + e.Message + e.StackTrace); } } // load videos - for (int i = 0; i < _Skins[skinIndex].VideoList.Count; i++) + foreach (var valuePair in _Skins[skinIndex].VideoList) { try { - xmlReader.GetValue("//root/Videos/" + _Skins[skinIndex].VideoList[i].Name, out value, String.Empty); - SSkinElement sk = new SSkinElement {Name = _Skins[skinIndex].VideoList[i].Name, Value = value}; - sk.VideoIndex = CVideo.Load(Path.Combine(_Skins[skinIndex].Path, sk.Value)); - CVideo.SetLoop(sk.VideoIndex, true); - CVideo.Pause(sk.VideoIndex); - sk.Texture = null; - _Skins[skinIndex].VideoList[i] = sk; + xmlReader.GetValue("//root/Videos/" + valuePair.Key, out valuePair.Value.Value, String.Empty); } catch (Exception e) { - MessageBox.Show("Error on loading video \"" + _Skins[skinIndex].VideoList[i].Name + "\": " + e.Message + e.StackTrace); - CLog.LogError("Error on loading video \"" + _Skins[skinIndex].VideoList[i].Name + "\": " + e.Message + e.StackTrace); + MessageBox.Show("Error on loading video \"" + valuePair.Key + "\": " + e.Message + e.StackTrace); + CLog.LogError("Error on loading video \"" + valuePair.Key + "\": " + e.Message + e.StackTrace); } } @@ -224,37 +212,24 @@ namespace Vocaluxe.Base public static void UnloadSkins() { - int numPartyModeSkins = 0; for (int i = 0; i < _Skins.Count; i++) { - foreach (SSkinElement sk in _Skins[i].SkinList.Values) - { - CTexture texture = sk.Texture; - CDraw.RemoveTexture(ref texture); - } + foreach (var sk in _Skins[i].SkinList.Values) + CDraw.RemoveTexture(ref sk.Texture); - for (int j = 0; j < _Skins[i].VideoList.Count; j++) + foreach (var vsk in _Skins[i].VideoList.Values) { - CVideo.Close(_Skins[i].VideoList[j].VideoIndex); - CTexture videoTexture = _Skins[i].VideoList[j].Texture; - CDraw.RemoveTexture(ref videoTexture); + CVideo.Close(vsk.VideoIndex); + CDraw.RemoveTexture(ref vsk.Texture); } - - if (_Skins[i].PartyModeID != -1) - numPartyModeSkins++; } - while (_Skins.Count > numPartyModeSkins) + for (int i = 0; i < _Skins.Count; i++) { - int num = _Skins.Count; - for (int i = 0; i < num; i++) - { - if (_Skins[i].PartyModeID == -1) - { - _Skins.RemoveAt(i); - break; - } - } + if (_Skins[i].PartyModeID != -1) + continue; + _Skins.RemoveAt(i); + i--; } } @@ -383,16 +358,16 @@ namespace Vocaluxe.Base #region Skins writer.WriteStartElement("Skins"); - foreach (SSkinElement element in _Skins[skinIndex].SkinList.Values) - writer.WriteElementString(element.Name, element.Value); + foreach (var element in _Skins[skinIndex].SkinList) + writer.WriteElementString(element.Key, element.Value.Value); writer.WriteEndElement(); #endregion Skins #region Videos writer.WriteStartElement("Videos"); - foreach (SSkinElement element in _Skins[skinIndex].VideoList) - writer.WriteElementString(element.Name, element.Value); + foreach (var element in _Skins[skinIndex].VideoList) + writer.WriteElementString(element.Key, element.Value.Value); writer.WriteEndElement(); #endregion Videos @@ -422,7 +397,7 @@ namespace Vocaluxe.Base if (xmlReader == null) return false; - STheme theme = new STheme(); + var theme = new STheme(); int version = 0; xmlReader.TryGetIntValue("//root/ThemeSystemVersion", ref version); @@ -489,7 +464,7 @@ namespace Vocaluxe.Base if (xmlReader == null) continue; - SSkin skin = new SSkin(); + var skin = new SSkin(); int version = 0; xmlReader.TryGetIntValue("//root/SkinSystemVersion", ref version); @@ -508,21 +483,15 @@ namespace Vocaluxe.Base skin.FileName = file; skin.PartyModeID = theme.PartyModeID; - skin.SkinList = new Dictionary(); + skin.SkinList = new Dictionary(); List names = xmlReader.GetValues("Skins"); foreach (string str in names) - { - SSkinElement sk = new SSkinElement {Name = str, Value = String.Empty}; - skin.SkinList[str] = sk; - } + skin.SkinList[str] = new CSkinElement(); - skin.VideoList = new List(); + skin.VideoList = new Dictionary(); names = xmlReader.GetValues("Videos"); foreach (string str in names) - { - SSkinElement sk = new SSkinElement {Name = str, Value = String.Empty}; - skin.VideoList.Add(sk); - } + skin.VideoList[str] = new CVideoSkinElement(); _Skins.Add(skin); } } @@ -587,8 +556,9 @@ namespace Vocaluxe.Base public static CTexture GetSkinTexture(string textureName, int partyModeID) { int skinIndex = GetSkinIndex(partyModeID); - if (skinIndex != -1 && textureName != null && _Skins[skinIndex].SkinList.ContainsKey(textureName)) - return _Skins[skinIndex].SkinList[textureName].Texture; + CSkinElement sk; + if (skinIndex != -1 && textureName != null && _Skins[skinIndex].SkinList.TryGetValue(textureName, out sk)) + return sk.Texture; return null; } @@ -599,85 +569,57 @@ namespace Vocaluxe.Base private static string _GetSkinFileName(string skinName, int skinIndex, bool returnPath = false) { - foreach (SSkinElement sk in _Skins[skinIndex].SkinList.Values) - { - if (sk.Name == skinName) - return !returnPath ? sk.Value : Path.Combine(_Skins[skinIndex].Path, sk.Value); - } + CSkinElement sk; + if (_Skins[skinIndex].SkinList.TryGetValue(skinName, out sk)) + return !returnPath ? sk.Value : Path.Combine(_Skins[skinIndex].Path, sk.Value); CLog.LogError("Can't find Skin Element \"" + skinName); return skinName; } - public static CTexture GetSkinVideoTexture(string videoName, int partyModeID) + public static CVideoSkinElement GetSkinVideo(string videoName, int partyModeID, bool load = true) { int skinIndex = GetSkinIndex(partyModeID); if (skinIndex != -1) { - for (int i = 0; i < _Skins[skinIndex].VideoList.Count; i++) + CVideoSkinElement sk; + if (_Skins[skinIndex].VideoList.TryGetValue(videoName, out sk)) { - SSkinElement sk = _Skins[skinIndex].VideoList[i]; - if (sk.Name == videoName) + if (sk.VideoIndex == -1 && load) { - float time = 0f; - if (sk.VideoIndex == -1) - { - sk.VideoIndex = CVideo.Load(GetVideoFilePath(sk.Name, partyModeID)); - CVideo.SetLoop(sk.VideoIndex, true); - } - CVideo.GetFrame(sk.VideoIndex, ref sk.Texture, time, out time); - _Skins[skinIndex].VideoList[i] = sk; - return sk.Texture; + sk.VideoIndex = CVideo.Load(GetVideoFilePath(videoName, partyModeID)); + CVideo.SetLoop(sk.VideoIndex, true); } + return sk; } } return null; } + public static CTexture GetSkinVideoTexture(string videoName, int partyModeID) + { + CVideoSkinElement sk = GetSkinVideo(videoName, partyModeID); + if (sk == null) + return null; + float time = 0f; + CVideo.GetFrame(sk.VideoIndex, ref sk.Texture, time, out time); + return sk.Texture; + } + public static void SkinVideoPause(string videoName, int partyModeID) { - int skinIndex = GetSkinIndex(partyModeID); - if (skinIndex != -1) - { - for (int i = 0; i < _Skins[skinIndex].VideoList.Count; i++) - { - SSkinElement sk = _Skins[skinIndex].VideoList[i]; - if (sk.Name == videoName) - { - if (sk.VideoIndex == -1) - { - sk.VideoIndex = CVideo.Load(GetVideoFilePath(sk.Name, partyModeID)); - CVideo.SetLoop(sk.VideoIndex, true); - } - CVideo.Pause(sk.VideoIndex); - _Skins[skinIndex].VideoList[i] = sk; - return; - } - } - } + CVideoSkinElement sk = GetSkinVideo(videoName, partyModeID, false); + if (sk == null) + return; + CVideo.Pause(sk.VideoIndex); } public static void SkinVideoResume(string videoName, int partyModeID) { - int skinIndex = GetSkinIndex(partyModeID); - if (skinIndex != -1) - { - for (int i = 0; i < _Skins[skinIndex].VideoList.Count; i++) - { - SSkinElement sk = _Skins[skinIndex].VideoList[i]; - if (sk.Name == videoName) - { - if (sk.VideoIndex == -1) - { - sk.VideoIndex = CVideo.Load(GetVideoFilePath(sk.Name, partyModeID)); - CVideo.SetLoop(sk.VideoIndex, true); - } - CVideo.Resume(sk.VideoIndex); - _Skins[skinIndex].VideoList[i] = sk; - return; - } - } - } + CVideoSkinElement sk = GetSkinVideo(videoName, partyModeID); + if (sk == null) + return; + CVideo.Resume(sk.VideoIndex); } public static string GetVideoFilePath(string videoName, int partyModeID) @@ -687,11 +629,9 @@ namespace Vocaluxe.Base private static string _GetVideoFileName(string videoName, int skinIndex, bool returnPath = false) { - foreach (SSkinElement sk in _Skins[skinIndex].VideoList) - { - if (sk.Name == videoName) - return !returnPath ? sk.Value : Path.Combine(_Skins[skinIndex].Path, sk.Value); - } + CVideoSkinElement sk; + if (_Skins[skinIndex].VideoList.TryGetValue(videoName, out sk)) + return !returnPath ? sk.Value : Path.Combine(_Skins[skinIndex].Path, sk.Value); CLog.LogError("Can't find Video Element \"" + videoName); return videoName; @@ -705,13 +645,13 @@ namespace Vocaluxe.Base if (_Skins[skinIndex].PartyModeID == -1) { - List playerColors = new List(); + var playerColors = new List(); float value = 0f; int i = 1; while (xmlReader.TryGetFloatValue("//root/Colors/Player" + i + "/R", ref value)) { - SColorF color = new SColorF {R = value}; + var color = new SColorF {R = value}; xmlReader.TryGetFloatValue("//root/Colors/Player" + i + "/G", ref color.G); xmlReader.TryGetFloatValue("//root/Colors/Player" + i + "/B", ref color.B); @@ -723,11 +663,11 @@ namespace Vocaluxe.Base skin.ThemeColors.Player = playerColors.ToArray(); } - List colorScheme = new List(); + var colorScheme = new List(); List names = xmlReader.GetValues("ColorSchemes"); foreach (string str in names) { - SColorScheme scheme = new SColorScheme {Name = str}; + var scheme = new SColorScheme {Name = str}; xmlReader.TryGetFloatValue("//root/ColorSchemes/" + str + "/R", ref scheme.Color.R); xmlReader.TryGetFloatValue("//root/ColorSchemes/" + str + "/G", ref scheme.Color.G); @@ -790,7 +730,7 @@ namespace Vocaluxe.Base } writer.WriteStartElement("ColorSchemes"); - foreach (SColorScheme scheme in _Skins[skinIndex].ThemeColors.ColorSchemes) + foreach (var scheme in _Skins[skinIndex].ThemeColors.ColorSchemes) { writer.WriteStartElement(scheme.Name); @@ -840,7 +780,7 @@ namespace Vocaluxe.Base public static bool GetColor(string colorName, int skinIndex, out SColorF color) { - foreach (SColorScheme scheme in _Skins[skinIndex].ThemeColors.ColorSchemes) + foreach (var scheme in _Skins[skinIndex].ThemeColors.ColorSchemes) { if (scheme.Name == colorName) { @@ -856,7 +796,7 @@ namespace Vocaluxe.Base public static SColorF GetPlayerColor(int playerNr) { - SColorF color = new SColorF(1f, 1f, 1f, 1f); + var color = new SColorF(1f, 1f, 1f, 1f); int skinIndex = GetSkinIndex(-1); diff --git a/Vocaluxe/Lib/Sound/Decoder/CAudioDecoderFFmpeg.cs b/Vocaluxe/Lib/Sound/Decoder/CAudioDecoderFFmpeg.cs index 22787416..15e06b56 100644 --- a/Vocaluxe/Lib/Sound/Decoder/CAudioDecoderFFmpeg.cs +++ b/Vocaluxe/Lib/Sound/Decoder/CAudioDecoderFFmpeg.cs @@ -57,7 +57,7 @@ namespace Vocaluxe.Lib.Sound.Decoder if (!_Instance.Opened) { - //Free(); + Close(); return; } @@ -72,12 +72,13 @@ namespace Vocaluxe.Lib.Sound.Decoder catch (Exception) { CLog.LogError("Error opening audio file (can't find decoder): " + _FileName); + Close(); return; } if (audioStreamIndex < 0) { - //Free(); + Close(); return; } @@ -93,6 +94,7 @@ namespace Vocaluxe.Lib.Sound.Decoder if (_FormatInfo.BitDepth != 16) { CLog.LogError("Unsupported BitDepth in file " + fileName); + Close(); return; } _FileOpened = true; @@ -100,35 +102,29 @@ namespace Vocaluxe.Lib.Sound.Decoder public void Close() { - if (!_FileOpened) - return; - if (_Audiodecoder != IntPtr.Zero) + { CAcinerella.AcFreeDecoder(_Audiodecoder); - + _Audiodecoder = IntPtr.Zero; + } if (_InstancePtr != IntPtr.Zero) + { CAcinerella.AcClose(_InstancePtr); - - if (_InstancePtr != IntPtr.Zero) CAcinerella.AcFree(_InstancePtr); + _InstancePtr = IntPtr.Zero; + } _FileOpened = false; } public SFormatInfo GetFormatInfo() { - if (!_FileOpened) - return new SFormatInfo(); - - return _FormatInfo; + return _FileOpened ? _FormatInfo : new SFormatInfo(); } public float GetLength() { - if (!_FileOpened) - return 0f; - - return _Instance.Info.Duration / 1000f; + return _FileOpened ? _Instance.Info.Duration / 1000f:0; } public void SetPosition(float time) @@ -138,7 +134,7 @@ namespace Vocaluxe.Lib.Sound.Decoder try { - CAcinerella.AcSeek(_Audiodecoder, 0, (Int64)(time * 1000f)); + CAcinerella.AcSeek(_Audiodecoder, (time>_CurrentTime)?0:-1, (Int64)(time * 1000f)); } catch (Exception) { @@ -149,7 +145,7 @@ namespace Vocaluxe.Lib.Sound.Decoder public float GetPosition() { - return !_FileOpened ? 0f : _CurrentTime; + return _FileOpened ? _CurrentTime : 0f; } public void Decode(out byte[] buffer, out float timeStamp) @@ -161,17 +157,9 @@ namespace Vocaluxe.Lib.Sound.Decoder return; } - int frameFinished; - try - { - frameFinished = CAcinerella.AcGetAudioFrame(_InstancePtr, _Audiodecoder); - } - catch (Exception) - { - frameFinished = 0; - } + bool frameFinished = CAcinerella.AcGetAudioFrame(_InstancePtr, _Audiodecoder); - if (frameFinished == 1) + if (frameFinished) { SACDecoder decoder = (SACDecoder)Marshal.PtrToStructure(_Audiodecoder, typeof(SACDecoder)); diff --git a/Vocaluxe/Lib/Video/Acinerella/CAcinerella.cs b/Vocaluxe/Lib/Video/Acinerella/CAcinerella.cs index 3851b485..bfc814c9 100644 --- a/Vocaluxe/Lib/Video/Acinerella/CAcinerella.cs +++ b/Vocaluxe/Lib/Video/Acinerella/CAcinerella.cs @@ -156,11 +156,7 @@ namespace Vocaluxe.Lib.Video.Acinerella // the number of bytes read or an value smaller than zero if an error occured. //TAc_read_callback = function(sender: Pointer; byte[] buf, int size): integer; cdecl; [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate Int32 ACReadCallback( - IntPtr sender, - IntPtr buf, - Int32 size - ); + public delegate Int32 ACReadCallback(IntPtr sender, IntPtr buf, Int32 size); // Callback function used to ask the application to seek. return 0 if succeed , -1 on failure. //TAc_seek_callback = function(sender: Pointer; pos: int64; whence: integer): int64; cdecl; @@ -274,17 +270,11 @@ namespace Vocaluxe.Lib.Video.Acinerella }*/ [DllImport(_AcDll, EntryPoint = "ac_open", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] - private static extern Int32 _ac_open2( - IntPtr pAcInstance, - string filename - ); + private static extern Int32 _ac_open2(IntPtr pAcInstance, string filename); // ReSharper disable UnusedMethodReturnValue.Global - public static Int32 AcOpen2( + public static Int32 AcOpen2(IntPtr pAcInstance, string filename) // ReSharper restore UnusedMethodReturnValue.Global - IntPtr pAcInstance, - string filename - ) { lock (_Lock) { @@ -306,28 +296,15 @@ namespace Vocaluxe.Lib.Video.Acinerella } // Stores information in "pInfo" about stream number "nb". - //procedure ac_get_stream_info( - //inst: PAc_instance; nb: integer; pinfo: PAc_stream_info); cdecl; external ac_dll; + //procedure ac_get_stream_info(inst: PAc_instance; nb: integer; pinfo: PAc_stream_info); cdecl; external ac_dll; [DllImport(_AcDll, EntryPoint = "ac_get_stream_info", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)] - private static extern void _ac_get_stream_info( - IntPtr pAcInstance, - Int32 nb, - out SACStreamInfo info - ); + private static extern void _ac_get_stream_info(IntPtr pAcInstance, Int32 nb, out SACStreamInfo info); - public static void AcGetStreamInfo( - IntPtr pAcInstance, - Int32 nb, - out SACStreamInfo info - ) + public static void AcGetStreamInfo(IntPtr pAcInstance, Int32 nb, out SACStreamInfo info) { lock (_Lock) { - _ac_get_stream_info( - pAcInstance, - nb, - out info - ); + _ac_get_stream_info(pAcInstance, nb, out info); } } @@ -382,44 +359,44 @@ namespace Vocaluxe.Lib.Video.Acinerella [DllImport(_AcDll, EntryPoint = "ac_decode_package", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)] private static extern Int32 _ac_decode_package(IntPtr pAcPackage, IntPtr pAcDecoder); - public static Int32 AcDecodePackage(IntPtr pAcPackage, IntPtr pAcDecoder) + public static bool AcDecodePackage(IntPtr pAcPackage, IntPtr pAcDecoder) { lock (_Lock) { - return _ac_decode_package(pAcPackage, pAcDecoder); + return _ac_decode_package(pAcPackage, pAcDecoder)!=0; } } [DllImport(_AcDll, EntryPoint = "ac_get_audio_frame", ExactSpelling = true, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)] private static extern Int32 _ac_get_audio_frame(IntPtr pAcInstance, IntPtr pAcDecoder); - public static Int32 AcGetAudioFrame(IntPtr pAcInstance, IntPtr pAcDecoder) + public static bool AcGetAudioFrame(IntPtr pAcInstance, IntPtr pAcDecoder) { lock (_Lock) { - return _ac_get_audio_frame(pAcInstance, pAcDecoder); + return _ac_get_audio_frame(pAcInstance, pAcDecoder)!=0; } } [DllImport(_AcDll, EntryPoint = "ac_get_frame", ExactSpelling = true, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)] private static extern Int32 _ac_get_frame(IntPtr pAcInstance, IntPtr pAcDecoder); - public static Int32 AcGetFrame(IntPtr pAcInstance, IntPtr pAcDecoder) + public static bool AcGetFrame(IntPtr pAcInstance, IntPtr pAcDecoder) { lock (_Lock) { - return _ac_get_frame(pAcInstance, pAcDecoder); + return _ac_get_frame(pAcInstance, pAcDecoder)!=0; } } [DllImport(_AcDll, EntryPoint = "ac_skip_frames", ExactSpelling = true, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)] private static extern Int32 _ac_skip_frames(IntPtr pAcInstance, IntPtr pAcDecoder, Int32 num); - public static Int32 AcSkipFrames(IntPtr pAcInstance, IntPtr pAcDecoder, Int32 num) + public static bool AcSkipFrames(IntPtr pAcInstance, IntPtr pAcDecoder, Int32 num) { lock (_Lock) { - return _ac_skip_frames(pAcInstance, pAcDecoder, num); + return _ac_skip_frames(pAcInstance, pAcDecoder, num)!=0; } } @@ -431,25 +408,18 @@ namespace Vocaluxe.Lib.Video.Acinerella [DllImport(_AcDll, EntryPoint = "ac_seek", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)] private static extern Int32 _ac_seek(IntPtr pAcDecoder, Int32 dir, Int64 targetPos); - // ReSharper disable UnusedMethodReturnValue.Global - public static Int32 AcSeek(IntPtr pAcDecoder, Int32 dir, Int64 targetPos) - // ReSharper restore UnusedMethodReturnValue.Global + public static bool AcSeek(IntPtr pAcDecoder, Int32 dir, Int64 targetPos) { lock (_Lock) { - return _ac_seek(pAcDecoder, dir, targetPos); + return _ac_seek(pAcDecoder, dir, targetPos)!=0; } } //function ac_probe_input_buffer(buf: PChar; bufsize: Integer; filename: PChar; //var score_max: Integer): PAc_proberesult; cdecl; external ac_dll; [DllImport(_AcDll, EntryPoint = "ac_probe_input_buffer", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)] - public static extern IntPtr ac_probe_input_buffer( - IntPtr buf, - Int32 bufsize, - IntPtr filename, - out Int32 scoreMax - ); + public static extern IntPtr ac_probe_input_buffer(IntPtr buf, Int32 bufsize, IntPtr filename, out Int32 scoreMax); } // ReSharper restore UnusedMember.Global diff --git a/Vocaluxe/Lib/Video/Acinerella/CDecoder.cs b/Vocaluxe/Lib/Video/Acinerella/CDecoder.cs new file mode 100644 index 00000000..028c4b2f --- /dev/null +++ b/Vocaluxe/Lib/Video/Acinerella/CDecoder.cs @@ -0,0 +1,441 @@ +using System; +using System.Diagnostics; +using System.IO; +using System.Runtime.InteropServices; +using System.Threading; +using Vocaluxe.Base; +using VocaluxeLib.Draw; + +namespace Vocaluxe.Lib.Video.Acinerella +{ + class CDecoder + { + private IntPtr _Instance = IntPtr.Zero; // acinerella instance + private IntPtr _Videodecoder = IntPtr.Zero; // acinerella video decoder instance + + private readonly Stopwatch _LoopTimer = new Stopwatch(); + private readonly Thread _Thread; + private readonly Object _MutexFramebuffer = new Object(); + private readonly CFramebuffer _Framebuffer; + private readonly Object _MutexSyncSignals = new Object(); + + private bool _FileOpened; + + private float _FrameDuration; // frame time in s + private float _LastDecodedTime; // time of last decoded frame + private float _LastShownTime; // current video position + + private float _Time; + private float _Gap; + private float _Start; + private bool _Loop; + + private float _SetTime; + private float _SetGap; + private float _SetStart; + private bool _SetSkip; + + private bool _Terminated; + private bool _FrameAvailable; + private bool _NoMoreFrames; + private readonly AutoResetEvent _EvWakeUp = new AutoResetEvent(false); + private bool _IsSleeping; + private int _WaitCount; + + private float _SkipTime; // = Start + VideoGap + + private string _FileName; // current video file name + private int _Width; + private int _Height; + private bool _Paused; + + public CDecoder() + { + _Thread = new Thread(_Execute); + _Framebuffer = new CFramebuffer(10); + } + + public float Length { get; private set; } + + public bool Paused + { + set + { + lock (_MutexSyncSignals) + { + _Paused = value; + if (_Paused) + _LoopTimer.Stop(); + else + _LoopTimer.Start(); + } + } + } + + public bool Loop { private get; set; } + + public bool Finished { get; private set; } + + public bool Open(string fileName) + { + if (_FileOpened) + return false; + + if (!File.Exists(fileName)) + return false; + + _FileName = fileName; + + //Do this here as one may want to get the length afterwards! + if (!_DoOpen()) + return false; + + _FileOpened = true; + + _Thread.Priority = ThreadPriority.Normal; + _Thread.Name = Path.GetFileName(fileName); + _Thread.Start(); + return true; + } + + public void Close() + { + _Terminated = true; + Length = 0; + } + + public bool GetFrame(ref CTexture frame, float time, out float videoTime) + { + if (_Paused) + { + videoTime = 0; + return false; + } + + if (Loop) + { + lock (_MutexSyncSignals) + { + _SetTime += _LoopTimer.ElapsedMilliseconds / 1000f; + _LoopTimer.Restart(); + } + } + else if (Math.Abs(_SetTime - time) > float.Epsilon) + { + lock (_MutexSyncSignals) + { + _SetTime = time; + } + } + else + { + videoTime = 0; + return false; + } + _UploadNewFrame(ref frame); + videoTime = _LastShownTime; + return frame != null; + } + + public bool Skip(float start, float gap) + { + lock (_MutexSyncSignals) + { + _SetStart = start; + _SetGap = gap; + _SetSkip = true; + _NoMoreFrames = false; + Finished = false; + } + return true; + } + + #region Threading + private void _Skip() + { + _SkipTime = _Start + _Gap; + + if (_SkipTime < 0) + _SkipTime = 0; + + try + { + CAcinerella.AcSeek(_Videodecoder, (_LastDecodedTime > _SkipTime) ? -1 : 0, (Int64)(_SkipTime * 1000f)); + } + catch (Exception e) + { + CLog.LogError("Error seeking video file \"" + _FileName + "\": " + e.Message); + } + _LastDecodedTime = _SkipTime; + + lock (_MutexSyncSignals) + { + _LastShownTime = _LastDecodedTime; + } + + lock (_MutexFramebuffer) + { + _Framebuffer.Clear(); + } + + _FrameAvailable = false; + } + + private void _Execute() + { + while (!_Terminated) + { + bool skip; + lock (_MutexSyncSignals) + { + _Time = _SetTime; + skip = _SetSkip; + _SetSkip = false; + _Gap = _SetGap; + _Start = _SetStart; + _Loop = Loop; + } + + if (skip) + _Skip(); + + if (!_FrameAvailable) + _Decode(); + + if (_FrameAvailable) + { + if (!_Framebuffer.IsFull()) + { + _Copy(); + _WaitCount = 0; + Thread.Sleep(1); + } + else if (_WaitCount > 3) + { + _IsSleeping = true; + _EvWakeUp.WaitOne(); + } + else + { + Thread.Sleep((int)((_Framebuffer.Size - 2) * _FrameDuration * 1000)); + _WaitCount++; + } + } + } + + _Free(); + } + + private bool _DoOpen() + { + bool ok; + try + { + _Instance = CAcinerella.AcInit(); + CAcinerella.AcOpen2(_Instance, _FileName); + + var instance = (SACInstance)Marshal.PtrToStructure(_Instance, typeof(SACInstance)); + Length = instance.Info.Duration / 1000f; + ok = instance.Opened; + } + catch (Exception) + { + ok = false; + } + + if (!ok) + { + CLog.LogError("Error opening video file: " + _FileName); + return false; + } + + int videoStreamIndex; + SACDecoder videodecoder; + try + { + _Videodecoder = CAcinerella.AcCreateVideoDecoder(_Instance); + videodecoder = (SACDecoder)Marshal.PtrToStructure(_Videodecoder, typeof(SACDecoder)); + videoStreamIndex = videodecoder.StreamIndex; + } + catch (Exception) + { + CLog.LogError("Error opening video file (can't find decoder): " + _FileName); + _Free(); + return false; + } + + if (videoStreamIndex < 0) + { + _Free(); + return false; + } + + _Width = videodecoder.StreamInfo.VideoInfo.FrameWidth; + _Height = videodecoder.StreamInfo.VideoInfo.FrameHeight; + + if (videodecoder.StreamInfo.VideoInfo.FramesPerSecond > 0) + _FrameDuration = 1f / (float)videodecoder.StreamInfo.VideoInfo.FramesPerSecond; + + _LastDecodedTime = 0f; + _SetTime = 0f; + + _Framebuffer.Init(_Width * _Height * 4); + _FrameAvailable = false; + return true; + } + + private void _Decode() + { + const int minFrameDropCount = 4; + + if (_Paused || _NoMoreFrames) + return; + + float videoTime = _Time + _Gap; + float timeDifference = videoTime - _LastDecodedTime; + + bool dropFrame = timeDifference >= (minFrameDropCount - 1) * _FrameDuration; + + if (_Terminated) + return; + + bool frameFinished = false; + if (dropFrame) + { + try + { + if (videoTime >= Length) + { + if (_Loop) + { + lock (_MutexSyncSignals) + { + _Start = 0; + _Gap = 0f; + _SetTime = 0; + } + _Skip(); + } + else + { + _NoMoreFrames = true; + return; + } + } + else + { + var frameDropCount = (int)(timeDifference / _FrameDuration); + frameFinished = CAcinerella.AcSkipFrames(_Instance, _Videodecoder, frameDropCount); + } + } + catch (Exception) + { + CLog.LogError("Error AcSkipFrame " + _FileName); + } + } + + if (!frameFinished) + { + try + { + frameFinished = CAcinerella.AcGetFrame(_Instance, _Videodecoder); + } + catch (Exception) + { + CLog.LogError("Error AcGetFrame " + _FileName); + } + } + if (frameFinished) + _FrameAvailable = true; + else + { + if (_Loop) + { + lock (_MutexSyncSignals) + { + _Start = 0f; + _Gap = 0f; + _SetTime = 0f; + } + _Skip(); + } + else + _NoMoreFrames = true; + } + } + + private void _Copy() + { + var videodecoder = (SACDecoder)Marshal.PtrToStructure(_Videodecoder, typeof(SACDecoder)); + if (videodecoder.Buffer == IntPtr.Zero) + return; + _LastDecodedTime = (float)videodecoder.Timecode; + _Framebuffer.Put(videodecoder.Buffer, _LastDecodedTime); + _FrameAvailable = false; + } + + private void _UploadNewFrame(ref CTexture frame) + { + lock (_MutexFramebuffer) + { + CFrame curFrame = _FindFrame(); + + if (curFrame != null) + { + CDraw.UpdateOrAddTexture(ref frame, _Width, _Height, curFrame.Data); + + lock (_MutexSyncSignals) + { + _LastShownTime = curFrame.Time; + } + } + else + { + if (_NoMoreFrames && _Framebuffer.IsEmpty()) + Finished = true; + } + } + if (!Finished && _IsSleeping) + { + _IsSleeping = false; + _EvWakeUp.Set(); + } + } + + private CFrame _FindFrame() + { + CFrame result = null; + float now = _SetTime + _Gap; + float maxEnd = now - _FrameDuration * 2; //Get only frames younger than 2 + CFrame frame; + while ((frame = _Framebuffer.Get()) != null) + { + float frameEnd = frame.Time + _FrameDuration; + //Don't show frames that are shown during or after now + if (frameEnd >= now) + break; //All following frames are after that one + + _Framebuffer.SetRead(); + //Get the last(newest) possible frame and skip the rest to force in-order showing + if (frameEnd <= maxEnd) + continue; + maxEnd = frameEnd; + result = frame; + } + return result; + } + + private void _Free() + { + if (_Videodecoder != IntPtr.Zero) + CAcinerella.AcFreeDecoder(_Videodecoder); + + if (_Instance != IntPtr.Zero) + { + CAcinerella.AcClose(_Instance); + CAcinerella.AcFree(_Instance); + } + } + #endregion Threading + } +} \ No newline at end of file diff --git a/Vocaluxe/Lib/Video/Acinerella/CFramebuffer.cs b/Vocaluxe/Lib/Video/Acinerella/CFramebuffer.cs new file mode 100644 index 00000000..8aaa6287 --- /dev/null +++ b/Vocaluxe/Lib/Video/Acinerella/CFramebuffer.cs @@ -0,0 +1,91 @@ +using System; +using System.Runtime.InteropServices; + +namespace Vocaluxe.Lib.Video.Acinerella +{ + class CFrame + { + public readonly byte[] Data; + public float Time = -1; + + public CFrame(int dataSize) + { + Data = new byte[dataSize]; + } + } + + class CFramebuffer + { + private readonly CFrame[] _Frames; + private readonly int _Size; + private int _DataSize; + private int _Last; + private int _First; + private bool _Initialized; + + public int Size + { + get { return _Size; } + } + + public CFramebuffer(int size) + { + _Size = size; + _Frames = new CFrame[size]; + } + + public void Init(int dataSize) + { + _DataSize = dataSize; + for (int i = 0; i < _Size; i++) + _Frames[i] = new CFrame(dataSize); + _Initialized = true; + } + + private int _Next(int current) + { + current++; + return (current < _Size) ? current : 0; + } + + public bool IsFull() + { + return _Next(_Last) == _First; + } + + public bool IsEmpty() + { + return _First == _Last; + } + + public bool Put(IntPtr data, float time) + { + if (!_Initialized || IsFull()) + return false; + CFrame frame = _Frames[_Last]; + Marshal.Copy(data, frame.Data, 0, _DataSize); + frame.Time = time; + _Last = _Next(_Last); + return true; + } + + public CFrame Get() + { + return IsEmpty() ? null : _Frames[_First]; + } + + public bool SetRead() + { + if (IsEmpty()) + return false; + _First = _Next(_First); + return true; + } + + public void Clear() + { + _First = 0; + _Last = 0; + } + } +} \ No newline at end of file diff --git a/Vocaluxe/Lib/Video/CVideoDecoder.cs b/Vocaluxe/Lib/Video/CVideoDecoder.cs deleted file mode 100644 index 79ea8b52..00000000 --- a/Vocaluxe/Lib/Video/CVideoDecoder.cs +++ /dev/null @@ -1,96 +0,0 @@ -#region license -// /* -// This file is part of Vocaluxe. -// -// Vocaluxe is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Vocaluxe is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Vocaluxe. If not, see . -// */ -#endregion - -using System.Collections.Generic; -using System.Linq; -using VocaluxeLib.Draw; - -namespace Vocaluxe.Lib.Video -{ - abstract class CVideoDecoder : IVideoDecoder - { - protected List _Streams = new List(); - protected bool _Initialized; - - public virtual bool Init() - { - _Streams = new List(); - _Initialized = true; - - return true; - } - - public abstract void CloseAll(); - - public virtual int GetNumStreams() - { - return _Streams.Count; - } - - public virtual int Load(string videoFileName) - { - return 0; - } - - public virtual bool Close(int streamID) - { - return true; - } - - public virtual float GetLength(int streamID) - { - return 0f; - } - - public abstract bool GetFrame(int streamID, ref CTexture frame, float time, out float videoTime); - - public virtual bool Skip(int streamID, float start, float gap) - { - return true; - } - - public virtual void SetLoop(int streamID, bool loop) {} - - public virtual void Pause(int streamID) {} - - public virtual void Resume(int streamID) {} - - public virtual bool Finished(int streamID) - { - return false; - } - - public virtual void Update() {} - - protected bool _AlreadyAdded(int streamID) - { - return _Streams.Any(st => st.Handle == streamID); - } - - protected int _GetStreamIndex(int streamID) - { - for (int i = 0; i < _Streams.Count; i++) - { - if (_Streams[i].Handle == streamID) - return i; - } - return -1; - } - } -} \ No newline at end of file diff --git a/Vocaluxe/Lib/Video/CVideoDecoderFFmpeg.cs b/Vocaluxe/Lib/Video/CVideoDecoderFFmpeg.cs index 003f1a09..85d9b25c 100644 --- a/Vocaluxe/Lib/Video/CVideoDecoderFFmpeg.cs +++ b/Vocaluxe/Lib/Video/CVideoDecoderFFmpeg.cs @@ -17,709 +17,114 @@ // */ #endregion -using System; using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Runtime.InteropServices; -using System.Threading; -using Vocaluxe.Base; using Vocaluxe.Lib.Video.Acinerella; using VocaluxeLib.Draw; namespace Vocaluxe.Lib.Video { - delegate void Closeproc(int streamID); - - class CVideoDecoderFFmpeg : CVideoDecoder + class CVideoDecoderFFmpeg : IVideoDecoder { - private readonly List _Decoder = new List(); - private Closeproc _Closeproc; - private int _Count = 1; + private readonly Dictionary _Decoder = new Dictionary(); + private int _LastID; - private readonly Object _MutexDecoder = new Object(); - - public override bool Init() + public bool Init() { - _Closeproc = _CloseProc; CloseAll(); - - return base.Init(); + return true; } - public override void CloseAll() + public void CloseAll() { - lock (_MutexDecoder) - { - for (int i = 0; i < _Decoder.Count; i++) - _Decoder[i].Free(_Closeproc, i + 1); - } + foreach (var decoder in _Decoder.Values) + decoder.Close(); + _Decoder.Clear(); } - public override int Load(string videoFileName) + public int Load(string videoFileName) { - SVideoStreams stream = new SVideoStreams(0); - CDecoder decoder = new CDecoder(); + var decoder = new CDecoder(); if (decoder.Open(videoFileName)) { - lock (_MutexDecoder) - { - _Decoder.Add(decoder); - stream.Handle = _Count++; - _Streams.Add(stream); - return stream.Handle; - } + int id = _LastID++; + _Decoder.Add(id, decoder); + return id; } return -1; } - public override bool Close(int streamID) + public bool Close(int streamID) { - if (_Initialized) + CDecoder decoder; + if (_Decoder.TryGetValue(streamID, out decoder)) { - lock (_MutexDecoder) - { - if (_AlreadyAdded(streamID)) - { - _Decoder[_GetStreamIndex(streamID)].Free(_Closeproc, streamID); - return true; - } - } + decoder.Close(); + _Decoder.Remove(streamID); + return true; } return false; } - public override bool GetFrame(int streamID, ref CTexture frame, float time, out float videoTime) + public int GetNumStreams() { + return _Decoder.Count; + } + + public bool GetFrame(int streamID, ref CTexture frame, float time, out float videoTime) + { + CDecoder decoder; + if (_Decoder.TryGetValue(streamID, out decoder)) + return decoder.GetFrame(ref frame, time, out videoTime); videoTime = 0; - if (_Initialized) - { - lock (_MutexDecoder) - { - if (_AlreadyAdded(streamID)) - return _Decoder[_GetStreamIndex(streamID)].GetFrame(ref frame, time, out videoTime); - } - } return false; } - public override float GetLength(int streamID) + public float GetLength(int streamID) { - if (_Initialized) - { - lock (_MutexDecoder) - { - if (_AlreadyAdded(streamID)) - return _Decoder[_GetStreamIndex(streamID)].Length; - } - } + CDecoder decoder; + if (_Decoder.TryGetValue(streamID, out decoder)) + return decoder.Length; return 0f; } - public override bool Skip(int streamID, float start, float gap) + public bool Skip(int streamID, float start, float gap) { - if (_Initialized) - { - lock (_MutexDecoder) - { - if (_AlreadyAdded(streamID)) - return _Decoder[_GetStreamIndex(streamID)].Skip(start, gap); - } - } + CDecoder decoder; + if (_Decoder.TryGetValue(streamID, out decoder)) + return decoder.Skip(start, gap); return false; } - public override void SetLoop(int streamID, bool loop) + public void SetLoop(int streamID, bool loop) { - if (_Initialized) - { - lock (_MutexDecoder) - { - if (_AlreadyAdded(streamID)) - _Decoder[_GetStreamIndex(streamID)].Loop = loop; - } - } + CDecoder decoder; + if (_Decoder.TryGetValue(streamID, out decoder)) + decoder.Loop = loop; } - public override void Pause(int streamID) + public void Pause(int streamID) { - if (_Initialized) - { - lock (_MutexDecoder) - { - if (_AlreadyAdded(streamID)) - _Decoder[_GetStreamIndex(streamID)].Paused = true; - } - } + CDecoder decoder; + if (_Decoder.TryGetValue(streamID, out decoder)) + decoder.Paused = true; } - public override void Resume(int streamID) + public void Resume(int streamID) { - if (_Initialized) - { - lock (_MutexDecoder) - { - if (_AlreadyAdded(streamID)) - _Decoder[_GetStreamIndex(streamID)].Paused = false; - } - } + CDecoder decoder; + if (_Decoder.TryGetValue(streamID, out decoder)) + decoder.Paused = false; } - public override bool Finished(int streamID) + public bool Finished(int streamID) { - if (_Initialized) - { - lock (_MutexDecoder) - { - if (_AlreadyAdded(streamID)) - return _Decoder[_GetStreamIndex(streamID)].Finished; - } - } + CDecoder decoder; + if (_Decoder.TryGetValue(streamID, out decoder)) + return decoder.Finished; return true; } - private void _CloseProc(int streamID) - { - if (_Initialized) - { - lock (_MutexDecoder) - { - if (_AlreadyAdded(streamID)) - { - int index = _GetStreamIndex(streamID); - _Decoder.RemoveAt(index); - _Streams.RemoveAt(index); - } - } - } - } - } - - struct SFrameBuffer - { - public byte[] Data; - public float Time; - public bool Displayed; - } - - class CDecoder : IDisposable - { - private IntPtr _Instance = IntPtr.Zero; // acinerella instance - private IntPtr _Videodecoder = IntPtr.Zero; // acinerella video decoder instance - - private readonly Stopwatch _LoopTimer = new Stopwatch(); - private Closeproc _Closeproc; // delegate for stream closing - private int _StreamID; // stream ID for stream closing - private string _FileName; // current video file name - - private bool _FileOpened; - - private float _VideoTimeBase; // frame time - private float _VideoDecoderTime; // time of last decoded frame - private float _CurrentVideoTime; // current video position - private bool _BufferFull; // buffer is full, waiting for free frame slot - - private bool _Skip; // do skip - private float _Time; - private float _Gap; - private float _Start; - private bool _Loop; - private float _Duration; - private float _VideoSkipTime; // = VideoGap - private float _SkipTime; // = Start + VideoGap - - private bool _Paused; - private bool _NoMoreFrames; - private bool _BeforeLoop; - - private int _Width; - private int _Height; - private float _SetTime; - private float _SetGap; - private float _SetStart; - private bool _SetSkip; - private bool _Terminated; - - private readonly Thread _Thread; - //AutoResetEvent EventDecode = new AutoResetEvent(false); - private readonly SFrameBuffer[] _FrameBuffer = new SFrameBuffer[5]; - private bool _NewFrame; - private readonly Object _MutexFramebuffer = new Object(); - private readonly Object _MutexSyncSignals = new Object(); - - public CDecoder() - { - _Thread = new Thread(_Execute); - } - - public void Free(Closeproc closeProc, int streamID) - { - _Closeproc = closeProc; - _StreamID = streamID; - _Terminated = true; - } - - public float Length - { - get { return _FileOpened ? _Duration : 0f; } - } - - public bool Paused - { - set - { - lock (_MutexSyncSignals) - { - _Paused = value; - if (_Paused) - _LoopTimer.Stop(); - else - _LoopTimer.Start(); - } - } - } - - public bool Loop { private get; set; } - - public bool Finished { get; private set; } - - public bool Open(string fileName) - { - if (_FileOpened) - return false; - - if (!File.Exists(fileName)) - return false; - - _FileName = fileName; - _Thread.Priority = ThreadPriority.Normal; - _Thread.Name = Path.GetFileName(fileName); - _Thread.Start(); - return true; - } - - public bool GetFrame(ref CTexture frame, float time, out float videoTime) - { - videoTime = 0; - if (!_FileOpened) - return false; - - if (_Paused) - return false; - - if (Loop) - { - lock (_MutexSyncSignals) - { - _SetTime += _LoopTimer.ElapsedMilliseconds / 1000f; - videoTime = _SetTime; - - _LoopTimer.Stop(); - _LoopTimer.Reset(); - _LoopTimer.Start(); - } - - - _UploadNewFrame(ref frame); - //EventDecode.Set(); - return frame != null; - } - - if (Math.Abs(_SetTime - time) > float.Epsilon) - { - lock (_MutexSyncSignals) - { - _SetTime = time; - } - _UploadNewFrame(ref frame); - videoTime = _CurrentVideoTime; - //EventDecode.Set(); - return frame != null; - } - return false; - } - - public bool Skip(float start, float gap) - { - lock (_MutexSyncSignals) - { - _SetStart = start; - _SetGap = gap; - _SetSkip = true; - _NoMoreFrames = false; - Finished = false; - } - //EventDecode.Set(); - return true; - } - - #region Threading - private void _DoSkip() - { - if (!_FileOpened) - return; - - _VideoSkipTime = _Gap; - _SkipTime = _Start + _Gap; - _BeforeLoop = false; - - if (_SkipTime > 0) - { - _VideoDecoderTime = _SkipTime; - try - { - CAcinerella.AcSeek(_Videodecoder, -1, (Int64)(_SkipTime * 1000f)); - } - catch (Exception e) - { - CLog.LogError("Error seeking video file \"" + _FileName + "\": " + e.Message); - } - } - else - { - _VideoDecoderTime = 0f; - try - { - CAcinerella.AcSeek(_Videodecoder, -1, 0); - } - catch (Exception e) - { - CLog.LogError("Error seeking video file \"" + _FileName + "\": " + e.Message); - } - } - - lock (_MutexSyncSignals) - { - _CurrentVideoTime = _VideoDecoderTime; - } - - lock (_MutexFramebuffer) - { - for (int i = 0; i < _FrameBuffer.Length; i++) - { - _FrameBuffer[i].Displayed = true; - _FrameBuffer[i].Time = -1f; - } - } - - _BufferFull = false; - _Skip = false; - _NewFrame = false; - //EventDecode.Set(); - } - - private void _Execute() - { - _DoOpen(); - //EventDecode.Set(); - while (!_Terminated) - { - { - //if (EventDecode.WaitOne(10)) - lock (_MutexSyncSignals) - { - _Time = _SetTime; - if (_SetSkip) - _Skip = true; - - _SetSkip = false; - _Gap = _SetGap; - _Start = _SetStart; - _Loop = Loop; - } - - if (_Skip) - _DoSkip(); - - if (!_NewFrame) - _DoDecode(); - - if (_NewFrame) - _Copy(); - Thread.Sleep(1); - } - } - - _DoFree(); - } - - private void _DoOpen() - { - bool ok; - SACInstance instance = new SACInstance(); - try - { - _Instance = CAcinerella.AcInit(); - CAcinerella.AcOpen2(_Instance, _FileName); - - instance = (SACInstance)Marshal.PtrToStructure(_Instance, typeof(SACInstance)); - ok = instance.Opened; - } - catch (Exception) - { - CLog.LogError("Error opening video file: " + _FileName); - ok = false; - } - - - if (!instance.Opened || !ok) - { - //Free(); - return; - } - - _Duration = instance.Info.Duration / 1000f; - - int videoStreamIndex; - SACDecoder videodecoder; - try - { - _Videodecoder = CAcinerella.AcCreateVideoDecoder(_Instance); - videodecoder = (SACDecoder)Marshal.PtrToStructure(_Videodecoder, typeof(SACDecoder)); - videoStreamIndex = videodecoder.StreamIndex; - } - catch (Exception) - { - CLog.LogError("Error opening video file (can't find decoder): " + _FileName); - return; - } - - - if (videoStreamIndex < 0) - { - //Free(); - return; - } - - _Width = videodecoder.StreamInfo.VideoInfo.FrameWidth; - _Height = videodecoder.StreamInfo.VideoInfo.FrameHeight; - - if (videodecoder.StreamInfo.VideoInfo.FramesPerSecond > 0) - _VideoTimeBase = 1f / (float)videodecoder.StreamInfo.VideoInfo.FramesPerSecond; - - _VideoDecoderTime = 0f; - _Time = 0f; - - for (int i = 0; i < _FrameBuffer.Length; i++) - { - _FrameBuffer[i].Time = -1f; - _FrameBuffer[i].Displayed = true; - _FrameBuffer[i].Data = new byte[_Width * _Height * 4]; - } - _FileOpened = true; - } - - private void _DoDecode() - { - const int framedropcount = 4; - - if (!_FileOpened || _NewFrame) - return; - - if (_Paused || _NoMoreFrames || _BufferFull) - return; - - if ((_SkipTime < 0f) && (_Time + _SkipTime >= 0f)) - _SkipTime = 0f; - - float myTime = _Time + _VideoSkipTime; - float timeDifference = myTime - _VideoDecoderTime; - - bool dropFrame = timeDifference >= (framedropcount - 1) * _VideoTimeBase; - - if (_Terminated) - return; - - int frameFinished = 0; - if (dropFrame && !_BeforeLoop) - { - try - { - frameFinished = CAcinerella.AcSkipFrames(_Instance, _Videodecoder, framedropcount - 1); - } - catch (Exception) - { - CLog.LogError("Error AcSkipFrame " + _FileName); - } - } - - if (!_BeforeLoop && (!dropFrame || frameFinished != 0)) - { - try - { - frameFinished = CAcinerella.AcGetFrame(_Instance, _Videodecoder); - } - catch (Exception) - { - CLog.LogError("Error AcGetFrame " + _FileName); - } - } - - if (frameFinished == 0) - { - if (_Loop) - { - _BeforeLoop = true; - bool doskip = true; - float tm = 0f; - int num = -1; - lock (_MutexFramebuffer) - { - for (int i = 0; i < _FrameBuffer.Length; i++) - { - if (_FrameBuffer[i].Time > tm && !_FrameBuffer[i].Displayed) - { - tm = _FrameBuffer[i].Time; - num = i; - } - } - - if (num >= 0) - doskip = _FrameBuffer[num].Displayed; - } - - if (!doskip) - return; - - lock (_MutexSyncSignals) - { - _Start = 0f; - _Gap = 0f; - _SetTime = 0f; - } - - _DoSkip(); - } - else - _NoMoreFrames = true; - } - else - { - _NewFrame = true; - _Copy(); - } - } - - private void _Copy() - { - if (!_NewFrame) - return; - - int num = -1; - - lock (_MutexFramebuffer) - { - for (int i = 0; i < _FrameBuffer.Length; i++) - { - if (_FrameBuffer[i].Displayed) - { - num = i; - break; - } - } - - if (num == -1) - _BufferFull = true; - else - { - SACDecoder videodecoder = (SACDecoder)Marshal.PtrToStructure(_Videodecoder, typeof(SACDecoder)); - - _VideoDecoderTime = (float)videodecoder.Timecode; - _FrameBuffer[num].Time = _VideoDecoderTime; - - if (videodecoder.Buffer != IntPtr.Zero) - { - Marshal.Copy(videodecoder.Buffer, _FrameBuffer[num].Data, 0, _Width * _Height * 4); - - _FrameBuffer[num].Displayed = false; - } - - int numfull = 0; - for (int i = 0; i < _FrameBuffer.Length; i++) - { - if (!_FrameBuffer[i].Displayed) - numfull++; - } - - if (numfull < _FrameBuffer.Length) - _BufferFull = false; - - _NewFrame = false; - } - } - } - - private void _UploadNewFrame(ref CTexture frame) - { - if (!_FileOpened) - return; - - lock (_MutexFramebuffer) - { - int num = _FindFrame(); - - if (num >= 0) - { - CDraw.UpdateOrAddTexture(ref frame, _Width, _Height, _FrameBuffer[num].Data); - - lock (_MutexSyncSignals) - { - _CurrentVideoTime = _FrameBuffer[num].Time; - } - Finished = false; - } - else - { - if (_NoMoreFrames) - Finished = true; - } - } - } - - private int _FindFrame() - { - int result = -1; - float diff = 10000000f; - - for (int i = 0; i < _FrameBuffer.Length; i++) - { - float td = _SetTime + _VideoSkipTime - _FrameBuffer[i].Time; - - if (td > _VideoTimeBase * 2f) - _FrameBuffer[i].Displayed = true; - - if (!_FrameBuffer[i].Displayed && (td < diff) && (td > _VideoTimeBase)) - { - diff = Math.Abs(_FrameBuffer[i].Time - _SetTime - _VideoSkipTime); - result = i; - } - } - - if (result != -1) - { - _FrameBuffer[result].Displayed = true; - _BufferFull = false; - } - - return result; - } - - private void _DoFree() - { - if (_Videodecoder != IntPtr.Zero) - CAcinerella.AcFreeDecoder(_Videodecoder); - - if (_Instance != IntPtr.Zero) - CAcinerella.AcClose(_Instance); - - if (_Instance != IntPtr.Zero) - CAcinerella.AcFree(_Instance); - - _Closeproc(_StreamID); - } - #endregion Threading - - public void Dispose() {} + public void Update() {} } } \ No newline at end of file diff --git a/Vocaluxe/Lib/Video/IVideoDecoder.cs b/Vocaluxe/Lib/Video/IVideoDecoder.cs index 39b54587..6c48a24e 100644 --- a/Vocaluxe/Lib/Video/IVideoDecoder.cs +++ b/Vocaluxe/Lib/Video/IVideoDecoder.cs @@ -21,16 +21,6 @@ using VocaluxeLib.Draw; namespace Vocaluxe.Lib.Video { - struct SVideoStreams - { - public int Handle; - - public SVideoStreams(int stream) - { - Handle = stream; - } - } - interface IVideoDecoder { bool Init(); diff --git a/Vocaluxe/Screens/CPopupScreenPlayerControl.cs b/Vocaluxe/Screens/CPopupScreenPlayerControl.cs index 6184d583..1856b90d 100644 --- a/Vocaluxe/Screens/CPopupScreenPlayerControl.cs +++ b/Vocaluxe/Screens/CPopupScreenPlayerControl.cs @@ -54,10 +54,7 @@ namespace Vocaluxe.Screens set { _VideoPreviewInt = value; - if (!_VideoPreviewInt && !_VideoBackground) - CBackgroundMusic.VideoEnabled = false; - else - CBackgroundMusic.VideoEnabled = true; + CBackgroundMusic.VideoEnabled = _VideoPreviewInt || _VideoBackground; } } diff --git a/Vocaluxe/Screens/CScreenOptionsVideo.cs b/Vocaluxe/Screens/CScreenOptionsVideo.cs index 04b1ef16..71c11d97 100644 --- a/Vocaluxe/Screens/CScreenOptionsVideo.cs +++ b/Vocaluxe/Screens/CScreenOptionsVideo.cs @@ -221,7 +221,7 @@ namespace Vocaluxe.Screens CConfig.VideosToBackground = (EOffOn)_SelectSlides[_SelectSlideVideosToBackground].Selection; CConfig.WebcamConfig = _Config; - CBackgroundMusic.VideoEnabled = true; + CBackgroundMusic.VideoEnabled = CConfig.VideoBackgrounds == EOffOn.TR_CONFIG_ON && CConfig.VideosToBackground == EOffOn.TR_CONFIG_ON; CConfig.SaveConfig(); } diff --git a/Vocaluxe/Vocaluxe.csproj b/Vocaluxe/Vocaluxe.csproj index f8b34199..2360607d 100644 --- a/Vocaluxe/Vocaluxe.csproj +++ b/Vocaluxe/Vocaluxe.csproj @@ -216,6 +216,8 @@ + + @@ -247,7 +249,6 @@ - diff --git a/VocaluxeLib/Menu/CMenu.cs b/VocaluxeLib/Menu/CMenu.cs index 3de37a98..4a3021b9 100644 --- a/VocaluxeLib/Menu/CMenu.cs +++ b/VocaluxeLib/Menu/CMenu.cs @@ -137,7 +137,7 @@ namespace VocaluxeLib.Menu _ThemeScreenSettings = null; } - protected void _FadeTo(EScreens nextScreen) + protected static void _FadeTo(EScreens nextScreen) { CBase.Graphics.FadeTo(nextScreen); } diff --git a/VocaluxeLib/Menu/CMenuParty.cs b/VocaluxeLib/Menu/CMenuParty.cs index 965f6175..d57a9304 100644 --- a/VocaluxeLib/Menu/CMenuParty.cs +++ b/VocaluxeLib/Menu/CMenuParty.cs @@ -36,7 +36,7 @@ namespace VocaluxeLib.Menu _PartyModeID = partyModeID; } - public void AssingPartyMode(IPartyMode partyMode) + public void AssignPartyMode(IPartyMode partyMode) { _PartyMode = partyMode; }