Merge pull request #2887 from MediaBrowser/dev

Dev
pull/1154/head
Luke 7 years ago committed by GitHub
commit 3cc6c739c9

@ -194,7 +194,10 @@ namespace Emby.Dlna.PlayTo
GeneralCommandType.SetSubtitleStreamIndex.ToString() GeneralCommandType.SetSubtitleStreamIndex.ToString()
}, },
SupportsMediaControl = true SupportsMediaControl = true,
// xbox one creates a new uuid everytime it restarts
SupportsPersistentIdentifier = (device.Properties.ModelName ?? string.Empty).IndexOf("xbox", StringComparison.OrdinalIgnoreCase) == -1
}); });
_logger.Info("DLNA Session created for {0} - {1}", device.Properties.Name, device.Properties.ModelName); _logger.Info("DLNA Session created for {0} - {1}", device.Properties.Name, device.Properties.ModelName);

@ -180,11 +180,6 @@ namespace Emby.Server.Implementations.Library
} }
} }
public Task<User> AuthenticateUser(string username, string passwordSha1, string remoteEndPoint)
{
return AuthenticateUser(username, passwordSha1, null, remoteEndPoint);
}
public bool IsValidUsername(string username) public bool IsValidUsername(string username)
{ {
// Usernames can contain letters (a-z), numbers (0-9), dashes (-), underscores (_), apostrophes ('), and periods (.) // Usernames can contain letters (a-z), numbers (0-9), dashes (-), underscores (_), apostrophes ('), and periods (.)
@ -223,7 +218,7 @@ namespace Emby.Server.Implementations.Library
return builder.ToString(); return builder.ToString();
} }
public async Task<User> AuthenticateUser(string username, string passwordSha1, string passwordMd5, string remoteEndPoint) public async Task<User> AuthenticateUser(string username, string password, string hashedPassword, string passwordMd5, string remoteEndPoint)
{ {
if (string.IsNullOrWhiteSpace(username)) if (string.IsNullOrWhiteSpace(username))
{ {
@ -237,23 +232,23 @@ namespace Emby.Server.Implementations.Library
if (user != null) if (user != null)
{ {
// Authenticate using local credentials if not a guest if (password != null)
if (!user.ConnectLinkType.HasValue || user.ConnectLinkType.Value != UserLinkType.Guest)
{ {
success = string.Equals(GetPasswordHash(user), passwordSha1.Replace("-", string.Empty), StringComparison.OrdinalIgnoreCase); hashedPassword = GetHashedString(user, password);
}
if (!success && _networkManager.IsInLocalNetwork(remoteEndPoint) && user.Configuration.EnableLocalPassword) // Authenticate using local credentials if not a guest
if (!user.ConnectLinkType.HasValue || user.ConnectLinkType.Value != UserLinkType.Guest)
{ {
success = string.Equals(GetLocalPasswordHash(user), passwordSha1.Replace("-", string.Empty), StringComparison.OrdinalIgnoreCase); success = AuthenticateLocalUser(user, password, hashedPassword, remoteEndPoint);
}
} }
// Maybe user accidently entered connect credentials. let's be flexible // Maybe user accidently entered connect credentials. let's be flexible
if (!success && user.ConnectLinkType.HasValue && !string.IsNullOrWhiteSpace(passwordMd5) && !string.IsNullOrWhiteSpace(user.ConnectUserName)) if (!success && user.ConnectLinkType.HasValue && !string.IsNullOrWhiteSpace(user.ConnectUserName))
{ {
try try
{ {
await _connectFactory().Authenticate(user.ConnectUserName, passwordMd5).ConfigureAwait(false); await _connectFactory().Authenticate(user.ConnectUserName, password, passwordMd5).ConfigureAwait(false);
success = true; success = true;
} }
catch catch
@ -268,7 +263,7 @@ namespace Emby.Server.Implementations.Library
{ {
try try
{ {
var connectAuthResult = await _connectFactory().Authenticate(username, passwordMd5).ConfigureAwait(false); var connectAuthResult = await _connectFactory().Authenticate(username, password, passwordMd5).ConfigureAwait(false);
user = Users.FirstOrDefault(i => string.Equals(i.ConnectUserId, connectAuthResult.User.Id, StringComparison.OrdinalIgnoreCase)); user = Users.FirstOrDefault(i => string.Equals(i.ConnectUserId, connectAuthResult.User.Id, StringComparison.OrdinalIgnoreCase));
@ -307,6 +302,36 @@ namespace Emby.Server.Implementations.Library
return success ? user : null; return success ? user : null;
} }
private bool AuthenticateLocalUser(User user, string password, string hashedPassword, string remoteEndPoint)
{
bool success;
if (password == null)
{
// legacy
success = string.Equals(GetPasswordHash(user), hashedPassword.Replace("-", string.Empty), StringComparison.OrdinalIgnoreCase);
}
else
{
success = string.Equals(GetPasswordHash(user), GetHashedString(user, password), StringComparison.OrdinalIgnoreCase);
}
if (!success && _networkManager.IsInLocalNetwork(remoteEndPoint) && user.Configuration.EnableLocalPassword)
{
if (password == null)
{
// legacy
success = string.Equals(GetLocalPasswordHash(user), hashedPassword.Replace("-", string.Empty), StringComparison.OrdinalIgnoreCase);
}
else
{
success = string.Equals(GetLocalPasswordHash(user), GetHashedString(user, password), StringComparison.OrdinalIgnoreCase);
}
}
return success;
}
private void UpdateInvalidLoginAttemptCount(User user, int newValue) private void UpdateInvalidLoginAttemptCount(User user, int newValue)
{ {
if (user.Policy.InvalidLoginAttemptCount != newValue || newValue > 0) if (user.Policy.InvalidLoginAttemptCount != newValue || newValue > 0)
@ -342,29 +367,39 @@ namespace Emby.Server.Implementations.Library
private string GetPasswordHash(User user) private string GetPasswordHash(User user)
{ {
return string.IsNullOrEmpty(user.Password) return string.IsNullOrEmpty(user.Password)
? GetSha1String(string.Empty) ? GetEmptyHashedString(user)
: user.Password; : user.Password;
} }
private string GetLocalPasswordHash(User user) private string GetLocalPasswordHash(User user)
{ {
return string.IsNullOrEmpty(user.EasyPassword) return string.IsNullOrEmpty(user.EasyPassword)
? GetSha1String(string.Empty) ? GetEmptyHashedString(user)
: user.EasyPassword; : user.EasyPassword;
} }
private bool IsPasswordEmpty(string passwordHash) private bool IsPasswordEmpty(User user, string passwordHash)
{ {
return string.Equals(passwordHash, GetSha1String(string.Empty), StringComparison.OrdinalIgnoreCase); return string.Equals(passwordHash, GetEmptyHashedString(user), StringComparison.OrdinalIgnoreCase);
}
private string GetEmptyHashedString(User user)
{
return GetHashedString(user, string.Empty);
} }
/// <summary> /// <summary>
/// Gets the sha1 string. /// Gets the hashed string.
/// </summary> /// </summary>
/// <param name="str">The STR.</param> private string GetHashedString(User user, string str)
/// <returns>System.String.</returns>
private string GetSha1String(string str)
{ {
var salt = user.Salt;
if (salt != null)
{
// return BCrypt.HashPassword(str, salt);
}
// legacy
return BitConverter.ToString(_cryptographyProvider.ComputeSHA1(Encoding.UTF8.GetBytes(str))).Replace("-", string.Empty); return BitConverter.ToString(_cryptographyProvider.ComputeSHA1(Encoding.UTF8.GetBytes(str))).Replace("-", string.Empty);
} }
@ -407,8 +442,8 @@ namespace Emby.Server.Implementations.Library
var passwordHash = GetPasswordHash(user); var passwordHash = GetPasswordHash(user);
var hasConfiguredPassword = !IsPasswordEmpty(passwordHash); var hasConfiguredPassword = !IsPasswordEmpty(user, passwordHash);
var hasConfiguredEasyPassword = !IsPasswordEmpty(GetLocalPasswordHash(user)); var hasConfiguredEasyPassword = !IsPasswordEmpty(user, GetLocalPasswordHash(user));
var hasPassword = user.Configuration.EnableLocalPassword && !string.IsNullOrEmpty(remoteEndPoint) && _networkManager.IsInLocalNetwork(remoteEndPoint) ? var hasPassword = user.Configuration.EnableLocalPassword && !string.IsNullOrEmpty(remoteEndPoint) && _networkManager.IsInLocalNetwork(remoteEndPoint) ?
hasConfiguredEasyPassword : hasConfiguredEasyPassword :
@ -460,14 +495,6 @@ namespace Emby.Server.Implementations.Library
{ {
var dto = GetUserDto(user); var dto = GetUserDto(user);
var offlinePasswordHash = GetLocalPasswordHash(user);
dto.HasPassword = !IsPasswordEmpty(offlinePasswordHash);
dto.OfflinePasswordSalt = Guid.NewGuid().ToString("N");
// Hash the pin with the device Id to create a unique result for this device
dto.OfflinePassword = GetSha1String((offlinePasswordHash + dto.OfflinePasswordSalt).ToLower());
dto.ServerName = _appHost.FriendlyName; dto.ServerName = _appHost.FriendlyName;
return dto; return dto;
@ -682,23 +709,29 @@ namespace Emby.Server.Implementations.Library
/// <returns>Task.</returns> /// <returns>Task.</returns>
public void ResetPassword(User user) public void ResetPassword(User user)
{ {
ChangePassword(user, GetSha1String(string.Empty)); ChangePassword(user, string.Empty, null);
} }
public void ResetEasyPassword(User user) public void ResetEasyPassword(User user)
{ {
ChangeEasyPassword(user, GetSha1String(string.Empty)); ChangeEasyPassword(user, string.Empty, null);
} }
public void ChangePassword(User user, string newPasswordSha1) public void ChangePassword(User user, string newPassword, string newPasswordHash)
{ {
if (user == null) if (user == null)
{ {
throw new ArgumentNullException("user"); throw new ArgumentNullException("user");
} }
if (string.IsNullOrWhiteSpace(newPasswordSha1))
if (newPassword != null)
{ {
throw new ArgumentNullException("newPasswordSha1"); newPasswordHash = GetHashedString(user, newPassword);
}
if (string.IsNullOrWhiteSpace(newPasswordHash))
{
throw new ArgumentNullException("newPasswordHash");
} }
if (user.ConnectLinkType.HasValue && user.ConnectLinkType.Value == UserLinkType.Guest) if (user.ConnectLinkType.HasValue && user.ConnectLinkType.Value == UserLinkType.Guest)
@ -706,25 +739,31 @@ namespace Emby.Server.Implementations.Library
throw new ArgumentException("Passwords for guests cannot be changed."); throw new ArgumentException("Passwords for guests cannot be changed.");
} }
user.Password = newPasswordSha1; user.Password = newPasswordHash;
UpdateUser(user); UpdateUser(user);
EventHelper.FireEventIfNotNull(UserPasswordChanged, this, new GenericEventArgs<User>(user), _logger); EventHelper.FireEventIfNotNull(UserPasswordChanged, this, new GenericEventArgs<User>(user), _logger);
} }
public void ChangeEasyPassword(User user, string newPasswordSha1) public void ChangeEasyPassword(User user, string newPassword, string newPasswordHash)
{ {
if (user == null) if (user == null)
{ {
throw new ArgumentNullException("user"); throw new ArgumentNullException("user");
} }
if (string.IsNullOrWhiteSpace(newPasswordSha1))
if (newPassword != null)
{
newPasswordHash = GetHashedString(user, newPassword);
}
if (string.IsNullOrWhiteSpace(newPasswordHash))
{ {
throw new ArgumentNullException("newPasswordSha1"); throw new ArgumentNullException("newPasswordHash");
} }
user.EasyPassword = newPasswordSha1; user.EasyPassword = newPasswordHash;
UpdateUser(user); UpdateUser(user);
@ -744,7 +783,8 @@ namespace Emby.Server.Implementations.Library
Id = Guid.NewGuid(), Id = Guid.NewGuid(),
DateCreated = DateTime.UtcNow, DateCreated = DateTime.UtcNow,
DateModified = DateTime.UtcNow, DateModified = DateTime.UtcNow,
UsesIdForConfigurationPath = true UsesIdForConfigurationPath = true,
//Salt = BCrypt.GenerateSalt()
}; };
} }

@ -285,7 +285,14 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
{ {
var filters = new List<string>(); var filters = new List<string>();
if (string.Equals(GetEncodingOptions().DeinterlaceMethod, "bobandweave", StringComparison.OrdinalIgnoreCase))
{
filters.Add("yadif=1:-1:0");
}
else
{
filters.Add("yadif=0:-1:0"); filters.Add("yadif=0:-1:0");
}
var output = string.Empty; var output = string.Empty;

@ -97,6 +97,9 @@ namespace MediaBrowser.Api
[ApiMember(Name = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")] [ApiMember(Name = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
public string Id { get; set; } public string Id { get; set; }
[ApiMember(Name = "Pw", IsRequired = true, DataType = "string", ParameterType = "body", Verb = "POST")]
public string Pw { get; set; }
/// <summary> /// <summary>
/// Gets or sets the password. /// Gets or sets the password.
/// </summary> /// </summary>
@ -125,6 +128,9 @@ namespace MediaBrowser.Api
[ApiMember(Name = "Password", IsRequired = true, DataType = "string", ParameterType = "body", Verb = "POST")] [ApiMember(Name = "Password", IsRequired = true, DataType = "string", ParameterType = "body", Verb = "POST")]
public string Password { get; set; } public string Password { get; set; }
[ApiMember(Name = "Pw", IsRequired = true, DataType = "string", ParameterType = "body", Verb = "POST")]
public string Pw { get; set; }
[ApiMember(Name = "PasswordMd5", IsRequired = true, DataType = "string", ParameterType = "body", Verb = "POST")] [ApiMember(Name = "PasswordMd5", IsRequired = true, DataType = "string", ParameterType = "body", Verb = "POST")]
public string PasswordMd5 { get; set; } public string PasswordMd5 { get; set; }
} }
@ -148,12 +154,16 @@ namespace MediaBrowser.Api
/// <value>The password.</value> /// <value>The password.</value>
public string CurrentPassword { get; set; } public string CurrentPassword { get; set; }
public string CurrentPw { get; set; }
/// <summary> /// <summary>
/// Gets or sets the new password. /// Gets or sets the new password.
/// </summary> /// </summary>
/// <value>The new password.</value> /// <value>The new password.</value>
public string NewPassword { get; set; } public string NewPassword { get; set; }
public string NewPw { get; set; }
/// <summary> /// <summary>
/// Gets or sets a value indicating whether [reset password]. /// Gets or sets a value indicating whether [reset password].
/// </summary> /// </summary>
@ -180,6 +190,8 @@ namespace MediaBrowser.Api
/// <value>The new password.</value> /// <value>The new password.</value>
public string NewPassword { get; set; } public string NewPassword { get; set; }
public string NewPw { get; set; }
/// <summary> /// <summary>
/// Gets or sets a value indicating whether [reset password]. /// Gets or sets a value indicating whether [reset password].
/// </summary> /// </summary>
@ -408,7 +420,8 @@ namespace MediaBrowser.Api
return Post(new AuthenticateUserByName return Post(new AuthenticateUserByName
{ {
Username = user.Name, Username = user.Name,
Password = request.Password Password = request.Password,
Pw = request.Pw
}); });
} }
@ -422,6 +435,7 @@ namespace MediaBrowser.Api
AppVersion = auth.Version, AppVersion = auth.Version,
DeviceId = auth.DeviceId, DeviceId = auth.DeviceId,
DeviceName = auth.Device, DeviceName = auth.Device,
Password = request.Pw,
PasswordSha1 = request.Password, PasswordSha1 = request.Password,
PasswordMd5 = request.PasswordMd5, PasswordMd5 = request.PasswordMd5,
RemoteEndPoint = Request.RemoteIp, RemoteEndPoint = Request.RemoteIp,
@ -459,14 +473,14 @@ namespace MediaBrowser.Api
} }
else else
{ {
var success = await _userManager.AuthenticateUser(user.Name, request.CurrentPassword, Request.RemoteIp).ConfigureAwait(false); var success = await _userManager.AuthenticateUser(user.Name, request.CurrentPw, request.CurrentPassword, null, Request.RemoteIp).ConfigureAwait(false);
if (success == null) if (success == null)
{ {
throw new ArgumentException("Invalid user or password entered."); throw new ArgumentException("Invalid user or password entered.");
} }
_userManager.ChangePassword(user, request.NewPassword); _userManager.ChangePassword(user, request.NewPw, request.NewPassword);
var currentToken = _authContext.GetAuthorizationInfo(Request).Token; var currentToken = _authContext.GetAuthorizationInfo(Request).Token;
@ -491,7 +505,7 @@ namespace MediaBrowser.Api
} }
else else
{ {
_userManager.ChangeEasyPassword(user, request.NewPassword); _userManager.ChangeEasyPassword(user, request.NewPw, request.NewPassword);
} }
} }
@ -501,8 +515,6 @@ namespace MediaBrowser.Api
/// <param name="request">The request.</param> /// <param name="request">The request.</param>
public void Post(UpdateUser request) public void Post(UpdateUser request)
{ {
// We need to parse this manually because we told service stack not to with IRequiresRequestStream
// https://code.google.com/p/servicestack/source/browse/trunk/Common/ServiceStack.Text/ServiceStack.Text/Controller/PathInfo.cs
var id = GetPathValue(1); var id = GetPathValue(1);
AssertCanUpdateUser(_authContext, _userManager, id, false); AssertCanUpdateUser(_authContext, _userManager, id, false);

@ -58,10 +58,7 @@ namespace MediaBrowser.Controller.Connect
/// <summary> /// <summary>
/// Authenticates the specified username. /// Authenticates the specified username.
/// </summary> /// </summary>
/// <param name="username">The username.</param> Task<ConnectAuthenticationResult> Authenticate(string username, string password, string passwordMd5);
/// <param name="passwordMd5">The password MD5.</param>
/// <returns>Task.</returns>
Task<ConnectAuthenticationResult> Authenticate(string username, string passwordMd5);
/// <summary> /// <summary>
/// Gets the local user. /// Gets the local user.

@ -30,6 +30,7 @@ namespace MediaBrowser.Controller.Entities
/// <value>The password.</value> /// <value>The password.</value>
public string Password { get; set; } public string Password { get; set; }
public string EasyPassword { get; set; } public string EasyPassword { get; set; }
public string Salt { get; set; }
public string ConnectUserName { get; set; } public string ConnectUserName { get; set; }
public string ConnectUserId { get; set; } public string ConnectUserId { get; set; }

@ -58,16 +58,6 @@ namespace MediaBrowser.Controller.Library
/// <returns>User.</returns> /// <returns>User.</returns>
User GetUserByName(string name); User GetUserByName(string name);
/// <summary>
/// Authenticates a User and returns a result indicating whether or not it succeeded
/// </summary>
/// <param name="username">The username.</param>
/// <param name="passwordSha1">The password sha1.</param>
/// <param name="remoteEndPoint">The remote end point.</param>
/// <returns>Task{System.Boolean}.</returns>
/// <exception cref="System.ArgumentNullException">user</exception>
Task<User> AuthenticateUser(string username, string passwordSha1, string remoteEndPoint);
/// <summary> /// <summary>
/// Refreshes metadata for each user /// Refreshes metadata for each user
/// </summary> /// </summary>
@ -135,18 +125,12 @@ namespace MediaBrowser.Controller.Library
/// <summary> /// <summary>
/// Changes the password. /// Changes the password.
/// </summary> /// </summary>
/// <param name="user">The user.</param> void ChangePassword(User user, string newPassword, string newPasswordSha1);
/// <param name="newPasswordSha1">The new password sha1.</param>
/// <returns>Task.</returns>
void ChangePassword(User user, string newPasswordSha1);
/// <summary> /// <summary>
/// Changes the easy password. /// Changes the easy password.
/// </summary> /// </summary>
/// <param name="user">The user.</param> void ChangeEasyPassword(User user, string newPassword, string newPasswordSha1);
/// <param name="newPasswordSha1">The new password sha1.</param>
/// <returns>Task.</returns>
void ChangeEasyPassword(User user, string newPasswordSha1);
/// <summary> /// <summary>
/// Gets the user dto. /// Gets the user dto.
@ -159,12 +143,7 @@ namespace MediaBrowser.Controller.Library
/// <summary> /// <summary>
/// Authenticates the user. /// Authenticates the user.
/// </summary> /// </summary>
/// <param name="username">The username.</param> Task<User> AuthenticateUser(string username, string password, string passwordSha1, string passwordMd5, string remoteEndPoint);
/// <param name="passwordSha1">The password sha1.</param>
/// <param name="passwordMd5">The password MD5.</param>
/// <param name="remoteEndPoint">The remote end point.</param>
/// <returns>Task&lt;System.Boolean&gt;.</returns>
Task<User> AuthenticateUser(string username, string passwordSha1, string passwordMd5, string remoteEndPoint);
/// <summary> /// <summary>
/// Starts the forgot password process. /// Starts the forgot password process.

@ -1288,10 +1288,7 @@ namespace MediaBrowser.Controller.MediaEncoding
/// <summary> /// <summary>
/// Gets the internal graphical subtitle param. /// Gets the internal graphical subtitle param.
/// </summary> /// </summary>
/// <param name="state">The state.</param> public string GetGraphicalSubtitleParam(EncodingJobInfo state, EncodingOptions options, string outputVideoCodec)
/// <param name="outputVideoCodec">The output video codec.</param>
/// <returns>System.String.</returns>
public string GetGraphicalSubtitleParam(EncodingJobInfo state, string outputVideoCodec)
{ {
var outputSizeParam = string.Empty; var outputSizeParam = string.Empty;
@ -1300,7 +1297,7 @@ namespace MediaBrowser.Controller.MediaEncoding
// Add resolution params, if specified // Add resolution params, if specified
if (request.Width.HasValue || request.Height.HasValue || request.MaxHeight.HasValue || request.MaxWidth.HasValue) if (request.Width.HasValue || request.Height.HasValue || request.MaxHeight.HasValue || request.MaxWidth.HasValue)
{ {
outputSizeParam = GetOutputSizeParam(state, outputVideoCodec).TrimEnd('"'); outputSizeParam = GetOutputSizeParam(state, options, outputVideoCodec).TrimEnd('"');
if (string.Equals(outputVideoCodec, "h264_vaapi", StringComparison.OrdinalIgnoreCase)) if (string.Equals(outputVideoCodec, "h264_vaapi", StringComparison.OrdinalIgnoreCase))
{ {
@ -1343,11 +1340,8 @@ namespace MediaBrowser.Controller.MediaEncoding
/// <summary> /// <summary>
/// If we're going to put a fixed size on the command line, this will calculate it /// If we're going to put a fixed size on the command line, this will calculate it
/// </summary> /// </summary>
/// <param name="state">The state.</param>
/// <param name="outputVideoCodec">The output video codec.</param>
/// <param name="allowTimeStampCopy">if set to <c>true</c> [allow time stamp copy].</param>
/// <returns>System.String.</returns>
public string GetOutputSizeParam(EncodingJobInfo state, public string GetOutputSizeParam(EncodingJobInfo state,
EncodingOptions options,
string outputVideoCodec, string outputVideoCodec,
bool allowTimeStampCopy = true) bool allowTimeStampCopy = true)
{ {
@ -1364,9 +1358,16 @@ namespace MediaBrowser.Controller.MediaEncoding
} }
if (state.DeInterlace && !string.Equals(outputVideoCodec, "h264_vaapi", StringComparison.OrdinalIgnoreCase)) if (state.DeInterlace && !string.Equals(outputVideoCodec, "h264_vaapi", StringComparison.OrdinalIgnoreCase))
{
if (string.Equals(options.DeinterlaceMethod, "bobandweave", StringComparison.OrdinalIgnoreCase))
{
filters.Add("yadif=1:-1:0");
}
else
{ {
filters.Add("yadif=0:-1:0"); filters.Add("yadif=0:-1:0");
} }
}
if (string.Equals(outputVideoCodec, "h264_vaapi", StringComparison.OrdinalIgnoreCase)) if (string.Equals(outputVideoCodec, "h264_vaapi", StringComparison.OrdinalIgnoreCase))
{ {
@ -1400,14 +1401,23 @@ namespace MediaBrowser.Controller.MediaEncoding
} }
else else
{ {
var isExynosV4L2 = string.Equals(outputVideoCodec, "h264_v4l2m2m", StringComparison.OrdinalIgnoreCase);
// If fixed dimensions were supplied // If fixed dimensions were supplied
if (request.Width.HasValue && request.Height.HasValue) if (request.Width.HasValue && request.Height.HasValue)
{ {
var widthParam = request.Width.Value.ToString(_usCulture); var widthParam = request.Width.Value.ToString(_usCulture);
var heightParam = request.Height.Value.ToString(_usCulture); var heightParam = request.Height.Value.ToString(_usCulture);
if (isExynosV4L2)
{
filters.Add(string.Format("scale=trunc({0}/64)*64:trunc({1}/2)*2", widthParam, heightParam));
}
else
{
filters.Add(string.Format("scale=trunc({0}/2)*2:trunc({1}/2)*2", widthParam, heightParam)); filters.Add(string.Format("scale=trunc({0}/2)*2:trunc({1}/2)*2", widthParam, heightParam));
} }
}
// If Max dimensions were supplied, for width selects lowest even number between input width and width req size and selects lowest even number from in width*display aspect and requested size // If Max dimensions were supplied, for width selects lowest even number between input width and width req size and selects lowest even number from in width*display aspect and requested size
else if (request.MaxWidth.HasValue && request.MaxHeight.HasValue) else if (request.MaxWidth.HasValue && request.MaxHeight.HasValue)
@ -1415,8 +1425,15 @@ namespace MediaBrowser.Controller.MediaEncoding
var maxWidthParam = request.MaxWidth.Value.ToString(_usCulture); var maxWidthParam = request.MaxWidth.Value.ToString(_usCulture);
var maxHeightParam = request.MaxHeight.Value.ToString(_usCulture); var maxHeightParam = request.MaxHeight.Value.ToString(_usCulture);
if (isExynosV4L2)
{
filters.Add(string.Format("scale=trunc(min(max(iw\\,ih*dar)\\,min({0}\\,{1}*dar))/64)*64:trunc(min(max(iw/dar\\,ih)\\,min({0}/dar\\,{1}))/2)*2", maxWidthParam, maxHeightParam));
}
else
{
filters.Add(string.Format("scale=trunc(min(max(iw\\,ih*dar)\\,min({0}\\,{1}*dar))/2)*2:trunc(min(max(iw/dar\\,ih)\\,min({0}/dar\\,{1}))/2)*2", maxWidthParam, maxHeightParam)); filters.Add(string.Format("scale=trunc(min(max(iw\\,ih*dar)\\,min({0}\\,{1}*dar))/2)*2:trunc(min(max(iw/dar\\,ih)\\,min({0}/dar\\,{1}))/2)*2", maxWidthParam, maxHeightParam));
} }
}
// If a fixed width was requested // If a fixed width was requested
else if (request.Width.HasValue) else if (request.Width.HasValue)
@ -1431,25 +1448,46 @@ namespace MediaBrowser.Controller.MediaEncoding
{ {
var heightParam = request.Height.Value.ToString(_usCulture); var heightParam = request.Height.Value.ToString(_usCulture);
if (isExynosV4L2)
{
filters.Add(string.Format("scale=trunc(oh*a/64)*64:{0}", heightParam));
}
else
{
filters.Add(string.Format("scale=trunc(oh*a/2)*2:{0}", heightParam)); filters.Add(string.Format("scale=trunc(oh*a/2)*2:{0}", heightParam));
} }
}
// If a max width was requested // If a max width was requested
else if (request.MaxWidth.HasValue) else if (request.MaxWidth.HasValue)
{ {
var maxWidthParam = request.MaxWidth.Value.ToString(_usCulture); var maxWidthParam = request.MaxWidth.Value.ToString(_usCulture);
if (isExynosV4L2)
{
filters.Add(string.Format("scale=trunc(min(max(iw\\,ih*dar)\\,{0})/64)*64:trunc(ow/dar/2)*2", maxWidthParam));
}
else
{
filters.Add(string.Format("scale=trunc(min(max(iw\\,ih*dar)\\,{0})/2)*2:trunc(ow/dar/2)*2", maxWidthParam)); filters.Add(string.Format("scale=trunc(min(max(iw\\,ih*dar)\\,{0})/2)*2:trunc(ow/dar/2)*2", maxWidthParam));
} }
}
// If a max height was requested // If a max height was requested
else if (request.MaxHeight.HasValue) else if (request.MaxHeight.HasValue)
{ {
var maxHeightParam = request.MaxHeight.Value.ToString(_usCulture); var maxHeightParam = request.MaxHeight.Value.ToString(_usCulture);
if (isExynosV4L2)
{
filters.Add(string.Format("scale=trunc(oh*a/64)*64:min(max(iw/dar\\,ih)\\,{0})", maxHeightParam));
}
else
{
filters.Add(string.Format("scale=trunc(oh*a/2)*2:min(max(iw/dar\\,ih)\\,{0})", maxHeightParam)); filters.Add(string.Format("scale=trunc(oh*a/2)*2:min(max(iw/dar\\,ih)\\,{0})", maxHeightParam));
} }
} }
}
var output = string.Empty; var output = string.Empty;
@ -1903,9 +1941,9 @@ namespace MediaBrowser.Controller.MediaEncoding
{ {
case "avc": case "avc":
case "h264": case "h264":
if (_mediaEncoder.SupportsDecoder("h264_omx") && encodingOptions.HardwareDecodingCodecs.Contains("h264", StringComparer.OrdinalIgnoreCase)) if (_mediaEncoder.SupportsDecoder("h264_mmal") && encodingOptions.HardwareDecodingCodecs.Contains("h264", StringComparer.OrdinalIgnoreCase))
{ {
return "-c:v h264_omx "; return "-c:v h264_mmal";
} }
break; break;
} }
@ -2055,7 +2093,7 @@ namespace MediaBrowser.Controller.MediaEncoding
// Add resolution params, if specified // Add resolution params, if specified
if (!hasGraphicalSubs) if (!hasGraphicalSubs)
{ {
var outputSizeParam = GetOutputSizeParam(state, videoCodec); var outputSizeParam = GetOutputSizeParam(state, encodingOptions, videoCodec);
args += outputSizeParam; args += outputSizeParam;
hasCopyTs = outputSizeParam.IndexOf("copyts", StringComparison.OrdinalIgnoreCase) != -1; hasCopyTs = outputSizeParam.IndexOf("copyts", StringComparison.OrdinalIgnoreCase) != -1;
} }
@ -2079,7 +2117,7 @@ namespace MediaBrowser.Controller.MediaEncoding
// This is for internal graphical subs // This is for internal graphical subs
if (hasGraphicalSubs) if (hasGraphicalSubs)
{ {
args += GetGraphicalSubtitleParam(state, videoCodec); args += GetGraphicalSubtitleParam(state, encodingOptions, videoCodec);
} }
if (!state.RunTimeTicks.HasValue) if (!state.RunTimeTicks.HasValue)

@ -5,6 +5,7 @@ namespace MediaBrowser.Controller.Session
{ {
public string Username { get; set; } public string Username { get; set; }
public string UserId { get; set; } public string UserId { get; set; }
public string Password { get; set; }
public string PasswordSha1 { get; set; } public string PasswordSha1 { get; set; }
public string PasswordMd5 { get; set; } public string PasswordMd5 { get; set; }
public string App { get; set; } public string App { get; set; }

@ -13,6 +13,7 @@ namespace MediaBrowser.Model.Configuration
public string VaapiDevice { get; set; } public string VaapiDevice { get; set; }
public int H264Crf { get; set; } public int H264Crf { get; set; }
public string H264Preset { get; set; } public string H264Preset { get; set; }
public string DeinterlaceMethod { get; set; }
public bool EnableHardwareEncoding { get; set; } public bool EnableHardwareEncoding { get; set; }
public bool EnableSubtitleExtraction { get; set; } public bool EnableSubtitleExtraction { get; set; }

@ -54,18 +54,6 @@ namespace MediaBrowser.Model.Dto
/// <value>The id.</value> /// <value>The id.</value>
public string Id { get; set; } public string Id { get; set; }
/// <summary>
/// Gets or sets the offline password.
/// </summary>
/// <value>The offline password.</value>
public string OfflinePassword { get; set; }
/// <summary>
/// Gets or sets the offline password salt.
/// </summary>
/// <value>The offline password salt.</value>
public string OfflinePasswordSalt { get; set; }
/// <summary> /// <summary>
/// Gets or sets the primary image tag. /// Gets or sets the primary image tag.
/// </summary> /// </summary>

@ -1,3 +1,3 @@
using System.Reflection; using System.Reflection;
[assembly: AssemblyVersion("3.2.30.23")] [assembly: AssemblyVersion("3.2.30.24")]

@ -285,16 +285,11 @@ namespace SocketHttpListener.Net
} }
} }
private bool EnableSendFileWithSocket = false;
public Task TransmitFile(string path, long offset, long count, FileShareMode fileShareMode, CancellationToken cancellationToken) public Task TransmitFile(string path, long offset, long count, FileShareMode fileShareMode, CancellationToken cancellationToken)
{ {
//if (_supportsDirectSocketAccess && offset == 0 && count == 0 && !_response.SendChunked && _response.ContentLength64 > 8192) //if (_supportsDirectSocketAccess && offset == 0 && count == 0 && !_response.SendChunked)
//{ //{
// if (EnableSendFileWithSocket)
// {
// return TransmitFileOverSocket(path, offset, count, fileShareMode, cancellationToken); // return TransmitFileOverSocket(path, offset, count, fileShareMode, cancellationToken);
// }
//} //}
return TransmitFileManaged(path, offset, count, fileShareMode, cancellationToken); return TransmitFileManaged(path, offset, count, fileShareMode, cancellationToken);
@ -319,7 +314,9 @@ namespace SocketHttpListener.Net
return TransmitFileManaged(path, offset, count, fileShareMode, cancellationToken); return TransmitFileManaged(path, offset, count, fileShareMode, cancellationToken);
} }
//_logger.Info("Socket sending file {0} {1}", path, response.ContentLength64); _stream.Flush();
_logger.Info("Socket sending file {0}", path);
var taskCompletion = new TaskCompletionSource<bool>(); var taskCompletion = new TaskCompletionSource<bool>();

Loading…
Cancel
Save