/// <summary>
        /// Encodes a <see cref="Expression"/> into an object that can be
        /// serialized.
        /// </summary>
        /// <param name="expression">The expression to be encoded.</param>
        /// <param name="state">The state tracker for the encode operation.</param>
        /// <param name="options">The options that will be used during encoding.</param>
        /// <returns>An object that can be serialized.</returns>
        internal static EncodedExpression EncodeExpression(Expression expression, EncodeState state, EncodeOptions options)
        {
            if (!ExpressionTypeMapping.ContainsKey(expression.NodeType))
            {
                throw new ArgumentException($"Encountered unknown node type {expression.NodeType} when encoding expression.", nameof(expression));
            }

            return(ExpressionTypeMapping[expression.NodeType].Encode(expression, state, options));
        }
Example #2
0
        // Returns true if we sent a stop signal to the encode.
        public bool StopEncodeIfPossible()
        {
            lock (this.encodeLock)
            {
                if (this.state == EncodeState.Encoding)
                {
                    this.instance.StopEncode();
                    this.state = EncodeState.Stopping;
                    return(true);
                }
            }

            return(false);
        }
Example #3
0
        /// <summary>
        /// Starts an encode.
        /// </summary>
        /// <param name="scanPath">The path to scan.</param>
        /// <param name="titleNumber">The title number to scan.</param>
        /// <param name="jsonFunc">A function to pick the encode JSON given the scan.</param>
        private void StartEncodeInternal(string scanPath, int titleNumber, Func <JsonScanObject, string> jsonFunc)
        {
            try
            {
                this.instance = new HandBrakeInstance();
                this.instance.Initialize(this.passedVerbosity);

                this.instance.ScanCompleted += (o, e) =>
                {
                    try
                    {
                        string encodeJson = jsonFunc(this.instance.Titles);
                        if (encodeJson != null)
                        {
                            lock (this.encodeLock)
                            {
                                this.instance.StartEncode(encodeJson);
                                this.callback.OnEncodeStarted();
                                this.state = EncodeState.Encoding;
                            }
                        }
                        else
                        {
                            this.callback.OnEncodeComplete(error: true);
                            this.CleanUpAndSignalCompletion();
                        }
                    }
                    catch (Exception exception)
                    {
                        this.callback.OnException(exception.ToString());
                        this.CleanUpAndSignalCompletion();
                    }
                };

                this.instance.EncodeProgress += (o, e) =>
                {
                    this.StopOnException(() =>
                    {
                        this.callback.OnEncodeProgress((float)e.AverageFrameRate, (float)e.CurrentFrameRate, e.EstimatedTimeLeft, (float)e.FractionComplete, e.PassId, e.Pass, e.PassCount);
                    });
                };

                this.instance.EncodeCompleted += (o, e) =>
                {
                    this.state = EncodeState.Finished;

                    try
                    {
                        this.callback.OnEncodeComplete(e.Error);
                    }
                    catch (CommunicationException exception)
                    {
                        WorkerErrorLogger.LogError("Got exception when reporting completion: " + exception, isError: true);
                    }
                    finally
                    {
                        this.CleanUpAndSignalCompletion();
                    }
                };


                this.instance.StartScan(scanPath, this.passedPreviewCount, TimeSpan.FromSeconds(this.passedMinTitleDurationSeconds), titleNumber);
                this.state = EncodeState.Scanning;
            }
            catch (Exception exception)
            {
                this.callback.OnException(exception.ToString());
                throw;
            }
        }
        /// <summary>
        /// Starts an encode.
        /// </summary>
        /// <param name="scanPath">The path to scan.</param>
        /// <param name="titleNumber">The title number to scan.</param>
        /// <param name="jsonFunc">A function to pick the encode JSON given the scan.</param>
        private void StartEncodeInternal(string scanPath, int titleNumber, Func <JsonScanObject, string> jsonFunc)
        {
            try
            {
                this.Instance = new HandBrakeInstance();
                this.Instance.Initialize(this.PassedVerbosity, noHardware: false);

                this.Instance.ScanCompleted += (o, e) =>
                {
                    try
                    {
                        string encodeJson = jsonFunc(this.Instance.Titles);
                        if (encodeJson != null)
                        {
                            lock (this.encodeLock)
                            {
                                this.Instance.StartEncode(encodeJson);
                                this.MakeOneWayCallback(c => c.OnEncodeStarted());
                                this.state = EncodeState.Encoding;
                            }
                        }
                        else
                        {
                            this.MakeOneWayCallback(c => c.OnEncodeComplete(true));
                            this.CleanUpAndSignalCompletion();
                        }
                    }
                    catch (Exception exception)
                    {
                        this.MakeOneWayCallback(c => c.OnException(exception.ToString()));
                        this.CleanUpAndSignalCompletion();
                    }
                };

                this.Instance.EncodeProgress += (o, e) =>
                {
                    this.StopOnException(() =>
                    {
                        if (e.PassId > this.lastSetAffinityPassId && e.FractionComplete > 0)
                        {
                            this.ApplyCpuThrottling();
                            this.lastSetAffinityPassId = e.PassId;
                        }

                        this.MakeOneWayCallback(c => c.OnEncodeProgress(
                                                    (float)e.AverageFrameRate,
                                                    (float)e.CurrentFrameRate,
                                                    e.EstimatedTimeLeft,
                                                    (float)e.FractionComplete,
                                                    e.PassId,
                                                    e.Pass,
                                                    e.PassCount,
                                                    e.StateCode));

                        return(Task.CompletedTask);
                    });
                };

                this.Instance.EncodeCompleted += async(o, e) =>
                {
                    this.state = EncodeState.Finished;

                    try
                    {
                        await this.SendPendingLogMessagesAsync().ConfigureAwait(false);

                        await this.CallbackInvoker.InvokeAsync(c => c.OnEncodeComplete(e.Error)).ConfigureAwait(false);
                    }
                    catch (Exception exception)
                    {
                        WorkerErrorLogger.LogError("Got exception when reporting completion: " + exception, isError: true);
                    }
                    finally
                    {
                        this.CleanUpAndSignalCompletion();
                    }
                };


                this.Instance.StartScan(scanPath, this.PassedPreviewCount, TimeSpan.FromSeconds(this.PassedMinTitleDurationSeconds), titleNumber);
                this.state = EncodeState.Scanning;
            }
            catch (Exception exception)
            {
                this.MakeOneWayCallback(c => c.OnException(exception.ToString()));
                throw;
            }
        }
Example #5
0
		public void StartEncode(EncodeJob job, bool preview, int previewNumber, int previewSeconds, double overallSelectedLengthSeconds, int verbosity, int previewCount, bool useDvdNav)
		{
			CurrentEncoder = this;
			this.callback = OperationContext.Current.GetCallbackChannel<IHandBrakeEncoderCallback>();

			try
			{
				if (this.callback == null)
				{
					throw new ArgumentException("Could not get callback channel.");
				}

				HandBrakeUtils.MessageLogged += (o, e) =>
					{
						this.StopOnException(() =>
							{
								this.callback.OnMessageLogged(e.Message);
							});
					};

				HandBrakeUtils.ErrorLogged += (o, e) =>
					{
						this.StopOnException(() =>
							{
								this.callback.OnErrorLogged(e.Message);
							});
					};

				HandBrakeUtils.SetDvdNav(useDvdNav);

				this.instance = new HandBrakeInstance();
				this.instance.Initialize(verbosity);

				this.instance.ScanCompleted += (o, e) =>
					{
						try
						{
							Title encodeTitle = this.instance.Titles.FirstOrDefault(title => title.TitleNumber == job.Title);

							if (encodeTitle != null)
							{
								lock (this.encodeLock)
								{
									this.instance.StartEncode(job, preview, previewNumber, previewSeconds, overallSelectedLengthSeconds, previewCount);
									this.callback.OnEncodeStarted();
									this.state = EncodeState.Encoding;
								}
							}
							else
							{
								this.callback.OnEncodeComplete(true);
								this.CleanUpAndSignalCompletion();
							}
						}
						catch (Exception exception)
						{
							this.callback.OnException(exception.ToString());
							this.CleanUpAndSignalCompletion();
						}
					};

				this.instance.EncodeProgress += (o, e) =>
					{
						this.StopOnException(() =>
							{
								this.callback.OnEncodeProgress(e.AverageFrameRate, e.CurrentFrameRate, e.EstimatedTimeLeft, e.FractionComplete, e.Pass);
							});
					};

				this.instance.EncodeCompleted += (o, e) =>
					{
						this.state = EncodeState.Finished;

						try
						{
							this.callback.OnEncodeComplete(e.Error);
						}
						catch (CommunicationException exception)
						{
							WorkerLogger.Log("Got exception when reporting completion: " + exception, isError: true);
						}
						finally
						{
							this.CleanUpAndSignalCompletion();
						}
					};

				this.instance.StartScan(job.SourcePath, previewCount, job.Title);
				this.state = EncodeState.Scanning;
			}
			catch (Exception exception)
			{
				this.callback.OnException(exception.ToString());
				throw;
			}
		}
Example #6
0
		// Returns true if we sent a stop signal to the encode.
		public bool StopEncodeIfPossible()
		{
			lock (this.encodeLock)
			{
				if (this.state == EncodeState.Encoding)
				{
					this.instance.StopEncode();
					this.state = EncodeState.Stopping;
					return true;
				}
			}

			return false;
		}
Example #7
0
        public void StartEncode(EncodeJob job, bool preview, int previewNumber, int previewSeconds, double overallSelectedLengthSeconds, int verbosity, int previewCount, bool useDvdNav)
        {
            CurrentEncoder = this;
            this.callback  = OperationContext.Current.GetCallbackChannel <IHandBrakeEncoderCallback>();

            try
            {
                if (this.callback == null)
                {
                    throw new ArgumentException("Could not get callback channel.");
                }

                HandBrakeUtils.MessageLogged += (o, e) =>
                {
                    this.StopOnException(() =>
                    {
                        this.callback.OnMessageLogged(e.Message);
                    });
                };

                HandBrakeUtils.ErrorLogged += (o, e) =>
                {
                    this.StopOnException(() =>
                    {
                        this.callback.OnErrorLogged(e.Message);
                    });
                };

                HandBrakeUtils.SetDvdNav(useDvdNav);

                this.instance = new HandBrakeInstance();
                this.instance.Initialize(verbosity);

                this.instance.ScanCompleted += (o, e) =>
                {
                    try
                    {
                        Title encodeTitle = this.instance.Titles.FirstOrDefault(title => title.TitleNumber == job.Title);

                        if (encodeTitle != null)
                        {
                            lock (this.encodeLock)
                            {
                                this.instance.StartEncode(job, preview, previewNumber, previewSeconds, overallSelectedLengthSeconds, previewCount);
                                this.callback.OnEncodeStarted();
                                this.state = EncodeState.Encoding;
                            }
                        }
                        else
                        {
                            this.callback.OnEncodeComplete(true);
                            this.CleanUpAndSignalCompletion();
                        }
                    }
                    catch (Exception exception)
                    {
                        this.callback.OnException(exception.ToString());
                        this.CleanUpAndSignalCompletion();
                    }
                };

                this.instance.EncodeProgress += (o, e) =>
                {
                    this.StopOnException(() =>
                    {
                        this.callback.OnEncodeProgress(e.AverageFrameRate, e.CurrentFrameRate, e.EstimatedTimeLeft, e.FractionComplete, e.Pass);
                    });
                };

                this.instance.EncodeCompleted += (o, e) =>
                {
                    this.state = EncodeState.Finished;

                    try
                    {
                        this.callback.OnEncodeComplete(e.Error);
                    }
                    catch (CommunicationException exception)
                    {
                        WorkerLogger.Log("Got exception when reporting completion: " + exception, isError: true);
                    }
                    finally
                    {
                        this.CleanUpAndSignalCompletion();
                    }
                };

                this.instance.StartScan(job.SourcePath, previewCount, job.Title);
                this.state = EncodeState.Scanning;
            }
            catch (Exception exception)
            {
                this.callback.OnException(exception.ToString());
                throw;
            }
        }
        /// <summary>
        /// Encodes the method call expression.
        /// </summary>
        /// <param name="expression">The expression to be encoded.</param>
        /// <param name="state">The current state of the encode operation.</param>
        /// <param name="options">The options for the encode operation.</param>
        /// <returns>An <see cref="EncodedExpression"/> object.</returns>
        internal static EncodedExpression EncodeMethodCallExpression(Expression expression, EncodeState state, EncodeOptions options)
        {
            var methodCallExpression = ( MethodCallExpression )expression;

            var expressions     = new Dictionary <string, EncodedExpression>();
            var methodSignature = state.SignatureHelper.GetSignatureFromMethodInfo(methodCallExpression.Method);

            for (int i = 0; i < methodCallExpression.Arguments.Count; i++)
            {
                expressions.Add($"a{i}", EncodeExpression(methodCallExpression.Arguments[i], state, options));
            }

            if (methodCallExpression.Object != null)
            {
                expressions.Add("Object", EncodeExpression(methodCallExpression.Object, state, options));
            }
            else
            {
                expressions.Add("Object", null);
            }

            return(new EncodedExpression
            {
                NodeType = methodCallExpression.NodeType,
                Expressions = expressions,
                Values = new Dictionary <string, string>
                {
                    { "Method", methodSignature },
                    { "ArgumentCount", methodCallExpression.Arguments.Count.ToString() }
                }
            });
        }
 /// <summary>
 /// Encodes the parameter expression.
 /// </summary>
 /// <param name="expression">The expression to be encoded.</param>
 /// <param name="state">The current state of the encode operation.</param>
 /// <param name="options">The options for the encode operation.</param>
 /// <returns>An <see cref="EncodedExpression"/> object.</returns>
 internal static EncodedExpression EncodeParameterExpression(Expression expression, EncodeState state, EncodeOptions options)
 {
     return(state.GetOrAddParameter(( ParameterExpression )expression));
 }
        /// <summary>
        /// Encodes the member expression.
        /// </summary>
        /// <param name="expression">The expression to be encoded.</param>
        /// <param name="state">The current state of the encode operation.</param>
        /// <param name="options">The options for the encode operation.</param>
        /// <returns>An <see cref="EncodedExpression"/> object.</returns>
        internal static EncodedExpression EncodeMemberExpression(Expression expression, EncodeState state, EncodeOptions options)
        {
            var memberExpression = ( MemberExpression )expression;

            if (IsAnonymousType(memberExpression.Member.ReflectedType))
            {
                throw new Exception("Encoding member access of anonymous types is not supported.");
            }

            return(new EncodedExpression
            {
                NodeType = memberExpression.NodeType,
                Expressions = new Dictionary <string, EncodedExpression>
                {
                    { "Expression", EncodeExpression(memberExpression.Expression, state, options) }
                },
                Values = new Dictionary <string, string>
                {
                    { "Type", state.SignatureHelper.GetSignatureFromType(memberExpression.Member.ReflectedType) },
                    { "Member", memberExpression.Member.Name },
                    { "IsProperty", (memberExpression.Member.MemberType == MemberTypes.Property).ToString() }
                }
            });
        }
        /// <summary>
        /// Encodes the lambda expression.
        /// </summary>
        /// <param name="expression">The expression to be encoded.</param>
        /// <param name="state">The current state of the encode operation.</param>
        /// <param name="options">The options for the encode operation.</param>
        /// <returns>An <see cref="EncodedExpression"/> object.</returns>
        internal static EncodedExpression EncodeLambdaExpression(Expression expression, EncodeState state, EncodeOptions options)
        {
            var lambdaExpression = ( LambdaExpression )expression;

            var expressions = new Dictionary <string, EncodedExpression>
            {
                { "Body", EncodeExpression(lambdaExpression.Body, state, options) }
            };

            for (int i = 0; i < lambdaExpression.Parameters.Count; i++)
            {
                expressions.Add($"p{i}", EncodeExpression(lambdaExpression.Parameters[i], state, options));
            }

            return(new EncodedExpression
            {
                NodeType = lambdaExpression.NodeType,
                Expressions = expressions,
                Values = new Dictionary <string, string>
                {
                    { "ParameterCount", lambdaExpression.Parameters.Count.ToString() }
                }
            });
        }
        /// <summary>
        /// Decodes the binary expression.
        /// </summary>
        /// <param name="expression">The expression to be decoded.</param>
        /// <param name="state">The current state of the decode operation.</param>
        /// <param name="options">The options for the decode operation.</param>
        /// <returns>An <see cref="Expression"/> object.</returns>
        internal static EncodedExpression EncodeConstantExpression(Expression expression, EncodeState state, EncodeOptions options)
        {
            var constantExpression = ( ConstantExpression )expression;

            return(new EncodedExpression
            {
                NodeType = constantExpression.NodeType,
                Values = new Dictionary <string, string>
                {
                    { "Type", state.SignatureHelper.GetSignatureFromType(constantExpression.Type) },
                    { "Value", constantExpression.Value?.ToString() }
                }
            });
        }
        /// <summary>
        /// Encodes the unary expression.
        /// </summary>
        /// <param name="expression">The expression to be encoded.</param>
        /// <param name="state">The current state of the encode operation.</param>
        /// <param name="options">The options for the encode operation.</param>
        /// <returns>An <see cref="EncodedExpression"/> object.</returns>
        internal static EncodedExpression EncodeUnaryExpression(Expression expression, EncodeState state, EncodeOptions options)
        {
            var unaryExpression = ( UnaryExpression )expression;

            return(new EncodedExpression
            {
                NodeType = unaryExpression.NodeType,
                Expressions = new Dictionary <string, EncodedExpression>
                {
                    { "Operand", EncodeExpression(unaryExpression.Operand, state, options) }
                },
                Values = new Dictionary <string, string>
                {
                    { "Type", state.SignatureHelper.GetSignatureFromType(unaryExpression.Type) }
                }
            });
        }
        /// <summary>
        /// Encodes the binary expression.
        /// </summary>
        /// <param name="expression">The expression to be encoded.</param>
        /// <param name="state">The current state of the encode operation.</param>
        /// <param name="options">The options for the encode operation.</param>
        /// <returns>An <see cref="EncodedExpression"/> object.</returns>
        internal static EncodedExpression EncodeBinaryExpression(Expression expression, EncodeState state, EncodeOptions options)
        {
            var binaryExpression = ( BinaryExpression )expression;

            return(new EncodedExpression
            {
                NodeType = binaryExpression.NodeType,
                Expressions = new Dictionary <string, EncodedExpression>
                {
                    { "Left", EncodeExpression(binaryExpression.Left, state, options) },
                    { "Right", EncodeExpression(binaryExpression.Right, state, options) },
                    { "Conversion", binaryExpression.Conversion != null?EncodeExpression(binaryExpression.Conversion, state, options) : null }
                }
            });
        }