瀏覽代碼

encode with qsv

Luke Pulverenti 9 年之前
父節點
當前提交
ce34c35b94
共有 43 個文件被更改,包括 324 次插入233 次删除
  1. 5 0
      MediaBrowser.Api/Playback/BaseStreamingService.cs
  2. 1 1
      MediaBrowser.Api/Playback/TranscodingThrottler.cs
  3. 7 0
      MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs
  4. 1 0
      MediaBrowser.Api/UserLibrary/ItemsService.cs
  5. 2 2
      MediaBrowser.Controller/Channels/ChannelAudioItem.cs
  6. 6 0
      MediaBrowser.Controller/Channels/ChannelFolderItem.cs
  7. 2 2
      MediaBrowser.Controller/Channels/ChannelVideoItem.cs
  8. 2 2
      MediaBrowser.Controller/Entities/Audio/Audio.cs
  9. 5 0
      MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs
  10. 5 0
      MediaBrowser.Controller/Entities/Audio/MusicArtist.cs
  11. 26 6
      MediaBrowser.Controller/Entities/BaseItem.cs
  12. 2 2
      MediaBrowser.Controller/Entities/Book.cs
  13. 2 16
      MediaBrowser.Controller/Entities/Folder.cs
  14. 2 2
      MediaBrowser.Controller/Entities/Game.cs
  15. 5 0
      MediaBrowser.Controller/Entities/GameSystem.cs
  16. 5 0
      MediaBrowser.Controller/Entities/InternalItemsQuery.cs
  17. 5 0
      MediaBrowser.Controller/Entities/Movies/BoxSet.cs
  18. 2 2
      MediaBrowser.Controller/Entities/Movies/Movie.cs
  19. 2 2
      MediaBrowser.Controller/Entities/MusicVideo.cs
  20. 0 5
      MediaBrowser.Controller/Entities/Photo.cs
  21. 2 15
      MediaBrowser.Controller/Entities/TV/Episode.cs
  22. 6 13
      MediaBrowser.Controller/Entities/TV/Season.cs
  23. 5 0
      MediaBrowser.Controller/Entities/TV/Series.cs
  24. 2 2
      MediaBrowser.Controller/Entities/Trailer.cs
  25. 15 0
      MediaBrowser.Controller/Entities/UserViewBuilder.cs
  26. 2 2
      MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs
  27. 2 2
      MediaBrowser.Controller/LiveTv/LiveTvChannel.cs
  28. 2 2
      MediaBrowser.Controller/LiveTv/LiveTvProgram.cs
  29. 2 2
      MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs
  30. 6 0
      MediaBrowser.Controller/LiveTv/RecordingGroup.cs
  31. 2 2
      MediaBrowser.Model/Configuration/EncodingOptions.cs
  32. 1 1
      MediaBrowser.Providers/TV/TvdbSeriesProvider.cs
  33. 25 25
      MediaBrowser.Server.Implementations/Channels/ChannelManager.cs
  34. 4 4
      MediaBrowser.Server.Implementations/Channels/ChannelPostScanTask.cs
  35. 24 18
      MediaBrowser.Server.Implementations/Library/LibraryManager.cs
  36. 1 8
      MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs
  37. 14 4
      MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
  38. 34 26
      MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
  39. 7 0
      MediaBrowser.Server.Implementations/Localization/LocalizationManager.cs
  40. 2 1
      MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs
  41. 74 59
      MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs
  42. 1 1
      MediaBrowser.Server.Implementations/Sync/MediaSync.cs
  43. 4 4
      MediaBrowser.Server.Implementations/Sync/SyncManager.cs

+ 5 - 0
MediaBrowser.Api/Playback/BaseStreamingService.cs

@@ -291,6 +291,11 @@ namespace MediaBrowser.Api.Playback
         {
             get
             {
+                if (string.Equals(ApiEntryPoint.Instance.GetEncodingOptions().HardwareVideoDecoder, "qsv", StringComparison.OrdinalIgnoreCase))
+                {
+                    return "h264_qsv";
+                }
+                
                 return "libx264";
             }
         }

+ 1 - 1
MediaBrowser.Api/Playback/TranscodingThrottler.cs

@@ -42,7 +42,7 @@ namespace MediaBrowser.Api.Playback
 
             var options = GetOptions();
 
-            if (options.EnableThrottling && IsThrottleAllowed(_job, options.ThrottleThresholdInSeconds))
+            if (options.EnableThrottling && IsThrottleAllowed(_job, options.ThrottleThresholdSeconds))
             {
                 PauseTranscoding();
             }

+ 7 - 0
MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs

@@ -199,6 +199,8 @@ namespace MediaBrowser.Api.UserLibrary
         [ApiMember(Name = "Genres", Description = "Optional. If specified, results will be filtered based on genre. This allows multiple, pipe delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
         public string Genres { get; set; }
 
+        public string GenreIds { get; set; }
+        
         [ApiMember(Name = "OfficialRatings", Description = "Optional. If specified, results will be filtered based on OfficialRating. This allows multiple, pipe delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
         public string OfficialRatings { get; set; }
 
@@ -378,6 +380,11 @@ namespace MediaBrowser.Api.UserLibrary
             return (StudioIds ?? string.Empty).Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
         }
 
+        public string[] GetGenreIds()
+        {
+            return (GenreIds ?? string.Empty).Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
+        }
+
         public string[] GetPersonTypes()
         {
             return (PersonTypes ?? string.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

+ 1 - 0
MediaBrowser.Api/UserLibrary/ItemsService.cs

@@ -210,6 +210,7 @@ namespace MediaBrowser.Api.UserLibrary
                 Tags = request.GetTags(),
                 OfficialRatings = request.GetOfficialRatings(),
                 Genres = request.GetGenres(),
+                GenreIds = request.GetGenreIds(),
                 Studios = request.GetStudios(),
                 StudioIds = request.GetStudioIds(),
                 Person = request.Person,

+ 2 - 2
MediaBrowser.Controller/Channels/ChannelAudioItem.cs

@@ -18,9 +18,9 @@ namespace MediaBrowser.Controller.Channels
 
         public List<ChannelMediaInfo> ChannelMediaSources { get; set; }
 
-        protected override bool GetBlockUnratedValue(UserPolicy config)
+        public override UnratedItem GetBlockUnratedType()
         {
-            return config.BlockUnratedItems.Contains(UnratedItem.ChannelContent);
+            return UnratedItem.ChannelContent;
         }
 
         protected override string CreateUserDataKey()

+ 6 - 0
MediaBrowser.Controller/Channels/ChannelFolderItem.cs

@@ -6,6 +6,7 @@ using System;
 using System.Runtime.Serialization;
 using System.Threading;
 using System.Threading.Tasks;
+using MediaBrowser.Model.Configuration;
 using MediaBrowser.Model.Entities;
 
 namespace MediaBrowser.Controller.Channels
@@ -20,6 +21,11 @@ namespace MediaBrowser.Controller.Channels
             return false;
         }
 
+        public override UnratedItem GetBlockUnratedType()
+        {
+            return UnratedItem.ChannelContent;
+        }
+
         [IgnoreDataMember]
         public override bool SupportsLocalMetadata
         {

+ 2 - 2
MediaBrowser.Controller/Channels/ChannelVideoItem.cs

@@ -42,9 +42,9 @@ namespace MediaBrowser.Controller.Channels
             return ExternalId;
         }
 
-        protected override bool GetBlockUnratedValue(UserPolicy config)
+        public override UnratedItem GetBlockUnratedType()
         {
-            return config.BlockUnratedItems.Contains(UnratedItem.ChannelContent);
+            return UnratedItem.ChannelContent;
         }
 
         [IgnoreDataMember]

+ 2 - 2
MediaBrowser.Controller/Entities/Audio/Audio.cs

@@ -171,9 +171,9 @@ namespace MediaBrowser.Controller.Entities.Audio
             return base.CreateUserDataKey();
         }
 
-        protected override bool GetBlockUnratedValue(UserPolicy config)
+        public override UnratedItem GetBlockUnratedType()
         {
-            return config.BlockUnratedItems.Contains(UnratedItem.Music);
+            return UnratedItem.Music;
         }
 
         public SongInfo GetLookupInfo()

+ 5 - 0
MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs

@@ -110,6 +110,11 @@ namespace MediaBrowser.Controller.Entities.Audio
             return config.BlockUnratedItems.Contains(UnratedItem.Music);
         }
 
+        public override UnratedItem GetBlockUnratedType()
+        {
+            return UnratedItem.Music;
+        }
+
         public AlbumInfo GetLookupInfo()
         {
             var id = GetItemLookupInfo<AlbumInfo>();

+ 5 - 0
MediaBrowser.Controller/Entities/Audio/MusicArtist.cs

@@ -138,6 +138,11 @@ namespace MediaBrowser.Controller.Entities.Audio
             return config.BlockUnratedItems.Contains(UnratedItem.Music);
         }
 
+        public override UnratedItem GetBlockUnratedType()
+        {
+            return UnratedItem.Music;
+        }
+
         public async Task RefreshAllMetadata(MetadataRefreshOptions refreshOptions, IProgress<double> progress, CancellationToken cancellationToken)
         {
             var items = GetRecursiveChildren().ToList();

+ 26 - 6
MediaBrowser.Controller/Entities/BaseItem.cs

@@ -690,10 +690,25 @@ namespace MediaBrowser.Controller.Entities
         [IgnoreDataMember]
         public int? ParentIndexNumber { get; set; }
 
-        [IgnoreDataMember]
-        public virtual string OfficialRatingForComparison
+        public virtual string GetOfficialRatingForComparison(bool inherit)
         {
-            get { return OfficialRating; }
+            if (inherit)
+            {
+                if (!string.IsNullOrWhiteSpace(OfficialRating))
+                {
+                    return OfficialRating;
+                }
+
+                var parent = DisplayParent;
+                if (parent != null)
+                {
+                    return parent.GetOfficialRatingForComparison(inherit);
+                }
+
+                return null;
+            }
+
+            return OfficialRating;
         }
 
         [IgnoreDataMember]
@@ -1126,7 +1141,7 @@ namespace MediaBrowser.Controller.Entities
 
             if (string.IsNullOrWhiteSpace(rating))
             {
-                rating = OfficialRatingForComparison;
+                rating = GetOfficialRatingForComparison(true);
             }
 
             if (string.IsNullOrWhiteSpace(rating))
@@ -1175,7 +1190,7 @@ namespace MediaBrowser.Controller.Entities
 
             if (string.IsNullOrWhiteSpace(rating))
             {
-                rating = OfficialRatingForComparison;
+                rating = GetOfficialRatingForComparison(true);
             }
 
             if (string.IsNullOrWhiteSpace(rating))
@@ -1207,6 +1222,11 @@ namespace MediaBrowser.Controller.Entities
             return true;
         }
 
+        public virtual UnratedItem GetBlockUnratedType()
+        {
+            return UnratedItem.Other;
+        }
+
         /// <summary>
         /// Gets the block unrated value.
         /// </summary>
@@ -1225,7 +1245,7 @@ namespace MediaBrowser.Controller.Entities
                 return false;
             }
 
-            return config.BlockUnratedItems.Contains(UnratedItem.Other);
+            return config.BlockUnratedItems.Contains(GetBlockUnratedType());
         }
 
         /// <summary>

+ 2 - 2
MediaBrowser.Controller/Entities/Book.cs

@@ -26,9 +26,9 @@ namespace MediaBrowser.Controller.Entities
                    locationType != LocationType.Virtual;
         }
 
-        protected override bool GetBlockUnratedValue(UserPolicy config)
+        public override UnratedItem GetBlockUnratedType()
         {
-            return config.BlockUnratedItems.Contains(UnratedItem.Book);
+            return UnratedItem.Book;
         }
 
         public BookInfo GetLookupInfo()

+ 2 - 16
MediaBrowser.Controller/Entities/Folder.cs

@@ -202,21 +202,6 @@ namespace MediaBrowser.Controller.Entities
             }
         }
 
-        [IgnoreDataMember]
-        public override string OfficialRatingForComparison
-        {
-            get
-            {
-                // Never want folders to be blocked by "BlockNotRated"
-                if (this is Series)
-                {
-                    return base.OfficialRatingForComparison;
-                }
-
-                return !string.IsNullOrWhiteSpace(base.OfficialRatingForComparison) ? base.OfficialRatingForComparison : "None";
-            }
-        }
-
         /// <summary>
         /// Removes the child.
         /// </summary>
@@ -1190,7 +1175,8 @@ namespace MediaBrowser.Controller.Entities
             {
                 User = user,
                 Recursive = true,
-                IsFolder = false
+                IsFolder = false,
+                IsMissing = false
 
             }).ConfigureAwait(false);
 

+ 2 - 2
MediaBrowser.Controller/Entities/Game.cs

@@ -98,9 +98,9 @@ namespace MediaBrowser.Controller.Entities
             return base.GetDeletePaths();
         }
 
-        protected override bool GetBlockUnratedValue(UserPolicy config)
+        public override UnratedItem GetBlockUnratedType()
         {
-            return config.BlockUnratedItems.Contains(UnratedItem.Game);
+            return UnratedItem.Game;
         }
 
         public GameInfo GetLookupInfo()

+ 5 - 0
MediaBrowser.Controller/Entities/GameSystem.cs

@@ -50,6 +50,11 @@ namespace MediaBrowser.Controller.Entities
             return false;
         }
 
+        public override UnratedItem GetBlockUnratedType()
+        {
+            return UnratedItem.Game;
+        }
+
         public GameSystemInfo GetLookupInfo()
         {
             var id = GetItemLookupInfo<GameSystemInfo>();

+ 5 - 0
MediaBrowser.Controller/Entities/InternalItemsQuery.cs

@@ -1,6 +1,7 @@
 using MediaBrowser.Model.Entities;
 using System;
 using System.Collections.Generic;
+using MediaBrowser.Model.Configuration;
 
 namespace MediaBrowser.Controller.Entities
 {
@@ -69,8 +70,10 @@ namespace MediaBrowser.Controller.Entities
 
         public string[] Studios { get; set; }
         public string[] StudioIds { get; set; }
+        public string[] GenreIds { get; set; }
         public ImageType[] ImageTypes { get; set; }
         public VideoType[] VideoTypes { get; set; }
+        public UnratedItem[] BlockUnratedItems { get; set; }
         public int[] Years { get; set; }
         public string[] Tags { get; set; }
         public string[] OfficialRatings { get; set; }
@@ -108,6 +111,7 @@ namespace MediaBrowser.Controller.Entities
         
         public InternalItemsQuery()
         {
+            BlockUnratedItems = new UnratedItem[] { };
             Tags = new string[] { };
             OfficialRatings = new string[] { };
             SortBy = new string[] { };
@@ -117,6 +121,7 @@ namespace MediaBrowser.Controller.Entities
             Genres = new string[] { };
             Studios = new string[] { };
             StudioIds = new string[] { };
+            GenreIds = new string[] { };
             ImageTypes = new ImageType[] { };
             VideoTypes = new VideoType[] { };
             Years = new int[] { };

+ 5 - 0
MediaBrowser.Controller/Entities/Movies/BoxSet.cs

@@ -65,6 +65,11 @@ namespace MediaBrowser.Controller.Entities.Movies
             return config.BlockUnratedItems.Contains(UnratedItem.Movie);
         }
 
+        public override UnratedItem GetBlockUnratedType()
+        {
+            return UnratedItem.Movie;
+        }
+
         [IgnoreDataMember]
         public override bool IsPreSorted
         {

+ 2 - 2
MediaBrowser.Controller/Entities/Movies/Movie.cs

@@ -159,9 +159,9 @@ namespace MediaBrowser.Controller.Entities.Movies
             return itemsChanged;
         }
 
-        protected override bool GetBlockUnratedValue(UserPolicy config)
+        public override UnratedItem GetBlockUnratedType()
         {
-            return config.BlockUnratedItems.Contains(UnratedItem.Movie);
+            return UnratedItem.Movie;
         }
 
         public MovieInfo GetLookupInfo()

+ 2 - 2
MediaBrowser.Controller/Entities/MusicVideo.cs

@@ -56,9 +56,9 @@ namespace MediaBrowser.Controller.Entities
             return this.GetProviderId(MetadataProviders.Tmdb) ?? this.GetProviderId(MetadataProviders.Imdb) ?? base.CreateUserDataKey();
         }
 
-        protected override bool GetBlockUnratedValue(UserPolicy config)
+        public override UnratedItem GetBlockUnratedType()
         {
-            return config.BlockUnratedItems.Contains(UnratedItem.Music);
+            return UnratedItem.Music;
         }
 
         public MusicVideoInfo GetLookupInfo()

+ 0 - 5
MediaBrowser.Controller/Entities/Photo.cs

@@ -68,10 +68,5 @@ namespace MediaBrowser.Controller.Entities
         public double? Longitude { get; set; }
         public double? Altitude { get; set; }
         public int? IsoSpeedRating { get; set; }
-
-        protected override bool GetBlockUnratedValue(UserPolicy config)
-        {
-            return config.BlockUnratedItems.Contains(UnratedItem.Other);
-        }
     }
 }

+ 2 - 15
MediaBrowser.Controller/Entities/TV/Episode.cs

@@ -115,19 +115,6 @@ namespace MediaBrowser.Controller.Entities.TV
             return base.CreateUserDataKey();
         }
 
-        /// <summary>
-        /// Our rating comes from our series
-        /// </summary>
-        [IgnoreDataMember]
-        public override string OfficialRatingForComparison
-        {
-            get
-            {
-                var series = Series;
-                return series != null ? series.OfficialRatingForComparison : base.OfficialRatingForComparison;
-            }
-        }
-
         /// <summary>
         /// This Episode's Series Instance
         /// </summary>
@@ -284,9 +271,9 @@ namespace MediaBrowser.Controller.Entities.TV
             return new[] { Path };
         }
 
-        protected override bool GetBlockUnratedValue(UserPolicy config)
+        public override UnratedItem GetBlockUnratedType()
         {
-            return config.BlockUnratedItems.Contains(UnratedItem.Series);
+            return UnratedItem.Series;
         }
 
         public EpisodeInfo GetLookupInfo()

+ 6 - 13
MediaBrowser.Controller/Entities/TV/Season.cs

@@ -6,6 +6,7 @@ using MoreLinq;
 using System.Collections.Generic;
 using System.Linq;
 using System.Runtime.Serialization;
+using MediaBrowser.Model.Configuration;
 
 namespace MediaBrowser.Controller.Entities.TV
 {
@@ -87,19 +88,6 @@ namespace MediaBrowser.Controller.Entities.TV
             }
         }
 
-        /// <summary>
-        /// Our rating comes from our series
-        /// </summary>
-        [IgnoreDataMember]
-        public override string OfficialRatingForComparison
-        {
-            get
-            {
-                var series = Series;
-                return series != null ? series.OfficialRatingForComparison : base.OfficialRatingForComparison;
-            }
-        }
-
         /// <summary>
         /// Creates the name of the sort.
         /// </summary>
@@ -234,6 +222,11 @@ namespace MediaBrowser.Controller.Entities.TV
             return false;
         }
 
+        public override UnratedItem GetBlockUnratedType()
+        {
+            return UnratedItem.Series;
+        }
+
         [IgnoreDataMember]
         public string SeriesName
         {

+ 5 - 0
MediaBrowser.Controller/Entities/TV/Series.cs

@@ -333,6 +333,11 @@ namespace MediaBrowser.Controller.Entities.TV
             return config.BlockUnratedItems.Contains(UnratedItem.Series);
         }
 
+        public override UnratedItem GetBlockUnratedType()
+        {
+            return UnratedItem.Series;
+        }
+
         public SeriesInfo GetLookupInfo()
         {
             var info = GetItemLookupInfo<SeriesInfo>();

+ 2 - 2
MediaBrowser.Controller/Entities/Trailer.cs

@@ -97,9 +97,9 @@ namespace MediaBrowser.Controller.Entities
             return base.CreateUserDataKey();
         }
 
-        protected override bool GetBlockUnratedValue(UserPolicy config)
+        public override UnratedItem GetBlockUnratedType()
         {
-            return config.BlockUnratedItems.Contains(UnratedItem.Trailer);
+            return UnratedItem.Trailer;
         }
 
         public TrailerInfo GetLookupInfo()

+ 15 - 0
MediaBrowser.Controller/Entities/UserViewBuilder.cs

@@ -1057,6 +1057,11 @@ namespace MediaBrowser.Controller.Entities
                 return false;
             }
 
+            if (request.GenreIds.Length > 0)
+            {
+                return false;
+            }
+
             if (request.VideoTypes.Length > 0)
             {
                 return false;
@@ -1653,6 +1658,16 @@ namespace MediaBrowser.Controller.Entities
                 return false;
             }
 
+            // Apply genre filter
+            if (query.GenreIds.Length > 0 && !query.GenreIds.Any(id =>
+            {
+                var genreItem = libraryManager.GetItemById(id);
+                return genreItem != null && item.Genres.Contains(genreItem.Name, StringComparer.OrdinalIgnoreCase);
+            }))
+            {
+                return false;
+            }
+
             // Apply year filter
             if (query.Years.Length > 0)
             {

+ 2 - 2
MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs

@@ -105,9 +105,9 @@ namespace MediaBrowser.Controller.LiveTv
             }
         }
 
-        protected override bool GetBlockUnratedValue(UserPolicy config)
+        public override UnratedItem GetBlockUnratedType()
         {
-            return config.BlockUnratedItems.Contains(UnratedItem.LiveTvProgram);
+            return UnratedItem.LiveTvProgram;
         }
 
         protected override string GetInternalMetadataPath(string basePath)

+ 2 - 2
MediaBrowser.Controller/LiveTv/LiveTvChannel.cs

@@ -22,9 +22,9 @@ namespace MediaBrowser.Controller.LiveTv
             return GetClientTypeName() + "-" + Name;
         }
 
-        protected override bool GetBlockUnratedValue(UserPolicy config)
+        public override UnratedItem GetBlockUnratedType()
         {
-            return config.BlockUnratedItems.Contains(UnratedItem.LiveTvChannel);
+            return UnratedItem.LiveTvChannel;
         }
 
         /// <summary>

+ 2 - 2
MediaBrowser.Controller/LiveTv/LiveTvProgram.cs

@@ -170,9 +170,9 @@ namespace MediaBrowser.Controller.LiveTv
             return "Program";
         }
 
-        protected override bool GetBlockUnratedValue(UserPolicy config)
+        public override UnratedItem GetBlockUnratedType()
         {
-            return config.BlockUnratedItems.Contains(UnratedItem.LiveTvProgram);
+            return UnratedItem.LiveTvProgram;
         }
 
         protected override string GetInternalMetadataPath(string basePath)

+ 2 - 2
MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs

@@ -115,9 +115,9 @@ namespace MediaBrowser.Controller.LiveTv
             }
         }
 
-        protected override bool GetBlockUnratedValue(UserPolicy config)
+        public override UnratedItem GetBlockUnratedType()
         {
-            return config.BlockUnratedItems.Contains(UnratedItem.LiveTvProgram);
+            return UnratedItem.LiveTvProgram;
         }
 
         protected override string GetInternalMetadataPath(string basePath)

+ 6 - 0
MediaBrowser.Controller/LiveTv/RecordingGroup.cs

@@ -1,4 +1,5 @@
 using MediaBrowser.Controller.Entities;
+using MediaBrowser.Model.Configuration;
 using MediaBrowser.Model.Users;
 
 namespace MediaBrowser.Controller.LiveTv
@@ -11,6 +12,11 @@ namespace MediaBrowser.Controller.LiveTv
             return false;
         }
 
+        public override UnratedItem GetBlockUnratedType()
+        {
+            return UnratedItem.LiveTvProgram;
+        }
+
         public override bool SupportsLocalMetadata
         {
             get

+ 2 - 2
MediaBrowser.Model/Configuration/EncodingOptions.cs

@@ -8,14 +8,14 @@ namespace MediaBrowser.Model.Configuration
         public double DownMixAudioBoost { get; set; }
         public bool EnableDebugLogging { get; set; }
         public bool EnableThrottling { get; set; }
-        public int ThrottleThresholdInSeconds { get; set; }
+        public int ThrottleThresholdSeconds { get; set; }
         public string HardwareVideoDecoder { get; set; }
 
         public EncodingOptions()
         {
             DownMixAudioBoost = 2;
             EnableThrottling = true;
-            ThrottleThresholdInSeconds = 100;
+            ThrottleThresholdSeconds = 100;
             EncodingThreadCount = -1;
         }
     }

+ 1 - 1
MediaBrowser.Providers/TV/TvdbSeriesProvider.cs

@@ -287,7 +287,7 @@ namespace MediaBrowser.Providers.TV
 
                 var automaticUpdatesEnabled = GetTvDbOptions().EnableAutomaticUpdates;
 
-                const int cacheDays = 2;
+                const int cacheDays = 1;
 
                 var seriesFile = files.FirstOrDefault(i => string.Equals(seriesXmlFilename, i.Name, StringComparison.OrdinalIgnoreCase));
                 // No need to check age if automatic updates are enabled

+ 25 - 25
MediaBrowser.Server.Implementations/Channels/ChannelManager.cs

@@ -104,6 +104,11 @@ namespace MediaBrowser.Server.Implementations.Channels
                 .OrderBy(i => i.Name);
         }
 
+        public IEnumerable<Guid> GetInstalledChannelIds()
+        {
+            return GetAllChannels().Select(i => GetInternalChannelId(i.Name));
+        }
+
         public Task<QueryResult<Channel>> GetChannelsInternal(ChannelQuery query, CancellationToken cancellationToken)
         {
             var user = string.IsNullOrWhiteSpace(query.UserId)
@@ -416,20 +421,7 @@ namespace MediaBrowser.Server.Implementations.Channels
             var path = Channel.GetInternalMetadataPath(_config.ApplicationPaths.InternalMetadataPath, id);
 
             var isNew = false;
-
-            if (!_fileSystem.DirectoryExists(path))
-            {
-                _logger.Debug("Creating directory {0}", path);
-
-                _fileSystem.CreateDirectory(path);
-
-                if (!_fileSystem.DirectoryExists(path))
-                {
-                    throw new IOException("Path not created: " + path);
-                }
-
-                isNew = true;
-            }
+            var forceUpdate = false;
 
             var item = _libraryManager.GetItemById(id) as Channel;
             var channelId = channelInfo.Name.GetMD5().ToString("N");
@@ -441,23 +433,27 @@ namespace MediaBrowser.Server.Implementations.Channels
                     Name = channelInfo.Name,
                     Id = id,
                     DateCreated = _fileSystem.GetCreationTimeUtc(path),
-                    DateModified = _fileSystem.GetLastWriteTimeUtc(path),
-                    Path = path,
-                    ChannelId = channelId
+                    DateModified = _fileSystem.GetLastWriteTimeUtc(path)
                 };
 
                 isNew = true;
             }
 
-            if (!string.Equals(item.ChannelId, channelId, StringComparison.OrdinalIgnoreCase))
+            if (!string.Equals(item.Path, path, StringComparison.OrdinalIgnoreCase))
             {
                 isNew = true;
             }
+            item.Path = path;
+            
+            if (!string.Equals(item.ChannelId, channelId, StringComparison.OrdinalIgnoreCase))
+            {
+                forceUpdate = true;
+            }
             item.ChannelId = channelId;
 
             if (item.ParentId != parentFolderId)
             {
-                isNew = true;
+                forceUpdate = true;
             }
             item.ParentId = parentFolderId;
 
@@ -469,13 +465,17 @@ namespace MediaBrowser.Server.Implementations.Channels
             {
                 item.Name = channelInfo.Name;
             }
-            
-            await item.RefreshMetadata(new MetadataRefreshOptions(_fileSystem)
-            {
-                ForceSave = isNew
 
-            }, cancellationToken);
+            if (isNew)
+            {
+                await _libraryManager.CreateItem(item, cancellationToken).ConfigureAwait(false);
+            }
+            else if (forceUpdate)
+            {
+                await item.UpdateToRepository(ItemUpdateType.None, cancellationToken).ConfigureAwait(false);
+            }
 
+            await item.RefreshMetadata(new MetadataRefreshOptions(_fileSystem), cancellationToken);
             return item;
         }
 
@@ -1281,7 +1281,7 @@ namespace MediaBrowser.Server.Implementations.Channels
 
             if (!string.Equals(channelItem.ExternalId, info.Id, StringComparison.OrdinalIgnoreCase))
             {
-                isNew = true;
+                forceUpdate = true;
             }
             channelItem.ExternalId = info.Id;
 

+ 4 - 4
MediaBrowser.Server.Implementations/Channels/ChannelPostScanTask.cs

@@ -123,15 +123,15 @@ namespace MediaBrowser.Server.Implementations.Channels
 
         private async Task CleanDatabase(CancellationToken cancellationToken)
         {
-            var allChannels = await _channelManager.GetChannelsInternal(new ChannelQuery { }, cancellationToken);
+            var installedChannelIds = ((ChannelManager)_channelManager).GetInstalledChannelIds();
 
-            var allIds = _libraryManager.GetItemIds(new InternalItemsQuery
+            var databaseIds = _libraryManager.GetItemIds(new InternalItemsQuery
             {
                 IncludeItemTypes = new[] { typeof(Channel).Name }
             });
 
-            var invalidIds = allIds
-                .Except(allChannels.Items.Select(i => i.Id).ToList())
+            var invalidIds = databaseIds
+                .Except(installedChannelIds)
                 .ToList();
 
             foreach (var id in invalidIds)

+ 24 - 18
MediaBrowser.Server.Implementations/Library/LibraryManager.cs

@@ -1272,6 +1272,11 @@ namespace MediaBrowser.Server.Implementations.Library
 
         public QueryResult<BaseItem> GetItems(InternalItemsQuery query)
         {
+            if (query.User != null)
+            {
+                AddUserToQuery(query, query.User);
+            }
+
             var result = ItemRepository.GetItemIdsList(query);
 
             var items = result.Select(GetItemById).Where(i => i != null).ToArray();
@@ -1284,11 +1289,21 @@ namespace MediaBrowser.Server.Implementations.Library
 
         public QueryResult<BaseItem> QueryItems(InternalItemsQuery query)
         {
+            if (query.User != null)
+            {
+                AddUserToQuery(query, query.User);
+            }
+
             return ItemRepository.GetItems(query);
         }
 
         public List<Guid> GetItemIds(InternalItemsQuery query)
         {
+            if (query.User != null)
+            {
+                AddUserToQuery(query, query.User);
+            }
+
             return ItemRepository.GetItemIdsList(query);
         }
 
@@ -1298,14 +1313,7 @@ namespace MediaBrowser.Server.Implementations.Library
 
             query.AncestorIds = parents.SelectMany(i => i.GetIdsForAncestorQuery()).Select(i => i.ToString("N")).ToArray();
 
-            if (user != null)
-            {
-                AddUserToQuery(query, user);
-            }
-
-            var items = GetItemIds(query).Select(GetItemById);
-
-            return items;
+            return GetItemIds(query).Select(GetItemById);
         }
 
         public QueryResult<BaseItem> GetItemsResult(InternalItemsQuery query, IEnumerable<string> parentIds)
@@ -1314,26 +1322,24 @@ namespace MediaBrowser.Server.Implementations.Library
 
             query.AncestorIds = parents.SelectMany(i => i.GetIdsForAncestorQuery()).Select(i => i.ToString("N")).ToArray();
 
-            if (query.User != null)
-            {
-                AddUserToQuery(query, query.User);
-            }
-
             return GetItems(query);
         }
 
         private void AddUserToQuery(InternalItemsQuery query, User user)
         {
-            if (query.AncestorIds.Length == 0)
+            if (query.AncestorIds.Length == 0 && !query.ParentId.HasValue && query.ChannelIds.Length == 0)
             {
-                // Need to filter on user folders
+                // TODO: Need to filter on user folders
             }
 
-            query.MaxParentalRating = user.Policy.MaxParentalRating;
+            // TODO: handle blocking by tags
 
-            // handle blocking by tags
+            query.MaxParentalRating = user.Policy.MaxParentalRating;
 
-            // handle unrated filter
+            if (user.Policy.MaxParentalRating.HasValue)
+            {
+                query.BlockUnratedItems = user.Policy.BlockUnratedItems;
+            }
         }
 
         /// <summary>

+ 1 - 8
MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs

@@ -107,14 +107,7 @@ namespace MediaBrowser.Server.Implementations.Library
 
         private int GetMaxAllowedBitrateForExternalSubtitleStream()
         {
-            // This is abitrary but at some point it becomes too slow to extract subtitles on the fly
-            // We need to learn more about when this is the case vs. when it isn't
-            if (Environment.ProcessorCount >= 8)
-            {
-                return 10000000;
-            }
-
-            return 4000000;
+            return 20000000;
         }
 
         private IEnumerable<MediaStream> GetMediaStreamsForItem(IEnumerable<MediaStream> streams)

+ 14 - 4
MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs

@@ -134,11 +134,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
 
         public async Task RefreshSeriesTimers(CancellationToken cancellationToken, IProgress<double> progress)
         {
-            var timers = await GetSeriesTimersAsync(cancellationToken).ConfigureAwait(false);
+            var seriesTimers = await GetSeriesTimersAsync(cancellationToken).ConfigureAwait(false);
 
             List<ChannelInfo> channels = null;
 
-            foreach (var timer in timers)
+            foreach (var timer in seriesTimers)
             {
                 List<ProgramInfo> epgData;
 
@@ -157,6 +157,16 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
                 }
                 await UpdateTimersForSeriesTimer(epgData, timer).ConfigureAwait(false);
             }
+
+            var timers = await GetTimersAsync(cancellationToken).ConfigureAwait(false);
+
+            foreach (var timer in timers.ToList())
+            {
+                if (DateTime.UtcNow > timer.EndDate && !_activeRecordings.ContainsKey(timer.Id))
+                {
+                    _timerProvider.Delete(timer);
+                }
+            }
         }
 
         private List<ChannelInfo> _channelCache = null;
@@ -828,12 +838,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
 
         private async Task UpdateTimersForSeriesTimer(List<ProgramInfo> epgData, SeriesTimerInfo seriesTimer)
         {
+            var newTimers = GetTimersForSeries(seriesTimer, epgData, _recordingProvider.GetAll()).ToList();
+
             var registration = await GetRegistrationInfo("seriesrecordings").ConfigureAwait(false);
 
             if (registration.IsValid)
             {
-                var newTimers = GetTimersForSeries(seriesTimer, epgData, _recordingProvider.GetAll()).ToList();
-
                 foreach (var timer in newTimers)
                 {
                     _timerProvider.AddOrUpdate(timer);

+ 34 - 26
MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs

@@ -534,7 +534,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
             }
         }
 
-        private async Task<LiveTvChannel> GetChannel(ChannelInfo channelInfo, string serviceName, CancellationToken cancellationToken)
+        private async Task<LiveTvChannel> GetChannel(ChannelInfo channelInfo, string serviceName, Guid parentFolderId, CancellationToken cancellationToken)
         {
             var isNew = false;
 
@@ -560,6 +560,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv
             }
             item.ExternalId = channelInfo.Id;
 
+            if (!item.ParentId.Equals(parentFolderId))
+            {
+                isNew = true;
+            }
+            item.ParentId = parentFolderId;
+            
             item.ChannelType = channelInfo.ChannelType;
             item.ServiceName = serviceName;
             item.Number = channelInfo.Number;
@@ -601,7 +607,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
             return item;
         }
 
-        private async Task<LiveTvProgram> GetProgram(ProgramInfo info, string channelId, ChannelType channelType, string serviceName, CancellationToken cancellationToken)
+        private async Task<LiveTvProgram> GetProgram(ProgramInfo info, LiveTvChannel channel, ChannelType channelType, string serviceName, CancellationToken cancellationToken)
         {
             var id = _tvDtoService.GetInternalProgramId(serviceName, info.Id);
 
@@ -622,6 +628,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv
                 };
             }
 
+            if (!item.ParentId.Equals(channel.Id))
+            {
+                forceUpdate = true;
+            }
+            item.ParentId = channel.Id;
+            
             //item.ChannelType = channelType;
             if (!string.Equals(item.ServiceName, serviceName, StringComparison.Ordinal))
             {
@@ -630,7 +642,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
             item.ServiceName = serviceName;
 
             item.Audio = info.Audio;
-            item.ChannelId = channelId;
+            item.ChannelId = channel.Id.ToString("N");
             item.CommunityRating = item.CommunityRating ?? info.CommunityRating;
             item.EndDate = info.EndDate;
             item.EpisodeTitle = info.EpisodeTitle;
@@ -695,7 +707,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
             return item;
         }
 
-        private async Task<Guid> CreateRecordingRecord(RecordingInfo info, string serviceName, CancellationToken cancellationToken)
+        private async Task<Guid> CreateRecordingRecord(RecordingInfo info, string serviceName, Guid parentFolderId, CancellationToken cancellationToken)
         {
             var isNew = false;
 
@@ -764,6 +776,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv
             }
             recording.IsSeries = info.IsSeries;
 
+            if (!item.ParentId.Equals(parentFolderId))
+            {
+                dataChanged = true;
+            }
+            item.ParentId = parentFolderId;
+            
             if (!item.HasImage(ImageType.Primary))
             {
                 if (!string.IsNullOrWhiteSpace(info.ImagePath))
@@ -856,14 +874,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv
                 SortOrder = query.SortOrder ?? SortOrder.Ascending
             };
 
-            if (user != null)
-            {
-                if (user.Policy.BlockUnratedItems.Contains(UnratedItem.LiveTvProgram))
-                {
-                    internalQuery.HasParentalRating = true;
-                }
-            }
-
             if (query.HasAired.HasValue)
             {
                 if (query.HasAired.Value)
@@ -918,14 +928,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv
                 }
             }
 
-            if (user != null)
-            {
-                if (user.Policy.BlockUnratedItems.Contains(UnratedItem.LiveTvProgram))
-                {
-                    internalQuery.HasParentalRating = true;
-                }
-            }
-
             IEnumerable<LiveTvProgram> programs = _libraryManager.QueryItems(internalQuery).Items.Cast<LiveTvProgram>();
 
             var programList = programs.ToList();
@@ -1168,6 +1170,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
             var list = new List<LiveTvChannel>();
 
             var numComplete = 0;
+            var folder = await GetInternalLiveTvFolder(cancellationToken).ConfigureAwait(false);
 
             foreach (var channelInfo in allChannelsList)
             {
@@ -1175,7 +1178,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
 
                 try
                 {
-                    var item = await GetChannel(channelInfo.Item2, channelInfo.Item1, cancellationToken).ConfigureAwait(false);
+                    var item = await GetChannel(channelInfo.Item2, channelInfo.Item1, folder.Id, cancellationToken).ConfigureAwait(false);
 
                     list.Add(item);
 
@@ -1219,11 +1222,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv
 
                     var channelPrograms = await service.GetProgramsAsync(currentChannel.ExternalId, start, end, cancellationToken).ConfigureAwait(false);
 
-                    var channelId = currentChannel.Id.ToString("N");
-
                     foreach (var program in channelPrograms)
                     {
-                        var programItem = await GetProgram(program, channelId, currentChannel.ChannelType, service.Name, cancellationToken).ConfigureAwait(false);
+                        var programItem = await GetProgram(program, currentChannel, currentChannel.ChannelType, service.Name, cancellationToken).ConfigureAwait(false);
 
                         programs.Add(programItem.Id);
                     }
@@ -1349,8 +1350,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv
                 });
 
                 var results = await Task.WhenAll(tasks).ConfigureAwait(false);
+                var folder = await GetInternalLiveTvFolder(cancellationToken).ConfigureAwait(false);
+                var parentFolderId = folder.Id;
 
-                var recordingTasks = results.SelectMany(i => i.ToList()).Select(i => CreateRecordingRecord(i.Item1, i.Item2.Name, cancellationToken));
+                var recordingTasks = results.SelectMany(i => i.ToList()).Select(i => CreateRecordingRecord(i.Item1, i.Item2.Name, parentFolderId, cancellationToken));
 
                 var idList = await Task.WhenAll(recordingTasks).ConfigureAwait(false);
 
@@ -1660,7 +1663,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv
 
             }
 
-            await _libraryManager.DeleteItem((BaseItem)recording).ConfigureAwait(false);
+            // This is the responsibility of the live tv service
+            await _libraryManager.DeleteItem((BaseItem)recording, new DeleteOptions
+            {
+                DeleteFileLocation = false
+
+            }).ConfigureAwait(false);
 
             _lastRecordingRefreshTime = DateTime.MinValue;
         }

+ 7 - 0
MediaBrowser.Server.Implementations/Localization/LocalizationManager.cs

@@ -243,6 +243,8 @@ namespace MediaBrowser.Server.Implementations.Localization
             _allParentalRatings.TryAdd(countryCode, dict);
         }
 
+        private readonly string[] _unratedValues = {"n/a", "unrated", "not rated"};
+
         /// <summary>
         /// Gets the rating level.
         /// </summary>
@@ -253,6 +255,11 @@ namespace MediaBrowser.Server.Implementations.Localization
                 throw new ArgumentNullException("rating");
             }
 
+            if (_unratedValues.Contains(rating, StringComparer.OrdinalIgnoreCase))
+            {
+                return null;
+            }
+
             // Fairly common for some users to have "Rated R" in their rating field
             rating = rating.Replace("Rated ", string.Empty, StringComparison.OrdinalIgnoreCase);
 

+ 2 - 1
MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs

@@ -12,6 +12,7 @@ using System.Collections.Generic;
 using System.Threading;
 using System.Threading.Tasks;
 using CommonIO;
+using MediaBrowser.Controller.Channels;
 using MediaBrowser.Controller.Entities.Audio;
 
 namespace MediaBrowser.Server.Implementations.Persistence
@@ -180,7 +181,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
                 //Limit = limit,
 
                 // These have their own cleanup routines
-                ExcludeItemTypes = new[] { typeof(Person).Name, typeof(Genre).Name, typeof(MusicGenre).Name, typeof(GameGenre).Name, typeof(Studio).Name, typeof(Year).Name }
+                ExcludeItemTypes = new[] { typeof(Person).Name, typeof(Genre).Name, typeof(MusicGenre).Name, typeof(GameGenre).Name, typeof(Studio).Name, typeof(Year).Name, typeof(Channel).Name }
             });
 
             var numComplete = 0;

+ 74 - 59
MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs

@@ -80,7 +80,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
         private IDbCommand _deleteAncestorsCommand;
         private IDbCommand _saveAncestorCommand;
 
-        private const int LatestSchemaVersion = 25;
+        private const int LatestSchemaVersion = 29;
 
         /// <summary>
         /// Initializes a new instance of the <see cref="SqliteItemRepository"/> class.
@@ -219,6 +219,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
             _connection.AddColumn(_logger, "TypedBaseItems", "Tags", "Text");
             _connection.AddColumn(_logger, "TypedBaseItems", "IsFolder", "BIT");
             _connection.AddColumn(_logger, "TypedBaseItems", "InheritedParentalRatingValue", "INT");
+            _connection.AddColumn(_logger, "TypedBaseItems", "UnratedType", "Text");
 
             PrepareStatements();
 
@@ -446,7 +447,8 @@ namespace MediaBrowser.Server.Implementations.Persistence
                 "Audio",
                 "ExternalServiceId",
                 "Tags",
-                "IsFolder"
+                "IsFolder",
+                "UnratedType"
             };
             _saveItemCommand = _connection.CreateCommand();
             _saveItemCommand.CommandText = "replace into TypedBaseItems (" + string.Join(",", saveColumns.ToArray()) + ") values (";
@@ -714,6 +716,8 @@ namespace MediaBrowser.Server.Implementations.Persistence
                     _saveItemCommand.GetParameter(index++).Value = string.Join("|", item.Tags.ToArray());
                     _saveItemCommand.GetParameter(index++).Value = item.IsFolder;
 
+                    _saveItemCommand.GetParameter(index++).Value = item.GetBlockUnratedType().ToString();
+                    
                     _saveItemCommand.Transaction = transaction;
 
                     _saveItemCommand.ExecuteNonQuery();
@@ -1916,6 +1920,17 @@ namespace MediaBrowser.Server.Implementations.Persistence
                     whereClauses.Add("ParentId NOT NULL AND ParentId NOT IN (select guid from TypedBaseItems)");
                 }
             }
+            if (query.ExcludeLocationTypes.Length == 1)
+            {
+                whereClauses.Add("LocationType<>@LocationType");
+                cmd.Parameters.Add(cmd, "@LocationType", DbType.String).Value = query.ExcludeLocationTypes[0].ToString();
+            }
+            if (query.ExcludeLocationTypes.Length > 1)
+            {
+                var val = string.Join(",", query.ExcludeLocationTypes.Select(i => "'" + i + "'").ToArray());
+
+                whereClauses.Add("LocationType not in (" + val + ")");
+            }
 
             if (query.AncestorIds.Length == 1)
             {
@@ -1927,18 +1942,18 @@ namespace MediaBrowser.Server.Implementations.Persistence
                 var inClause = string.Join(",", query.AncestorIds.Select(i => "'" + new Guid(i).ToString("N") + "'").ToArray());
                 whereClauses.Add(string.Format("Guid in (select itemId from AncestorIds where AncestorIdText in ({0}))", inClause));
             }
-            if (query.ExcludeLocationTypes.Length == 1)
+
+            if (query.BlockUnratedItems.Length == 1)
             {
-                whereClauses.Add("LocationType<>@LocationType");
-                cmd.Parameters.Add(cmd, "@LocationType", DbType.String).Value = query.ExcludeLocationTypes[0].ToString();
+                whereClauses.Add("(InheritedParentalRatingValue > 0 or UnratedType <> @UnratedType)");
+                cmd.Parameters.Add(cmd, "@UnratedType", DbType.String).Value = query.BlockUnratedItems[0].ToString();
             }
-            if (query.ExcludeLocationTypes.Length > 1)
+            if (query.BlockUnratedItems.Length > 1)
             {
-                var val = string.Join(",", query.ExcludeLocationTypes.Select(i => "'" + i + "'").ToArray());
-
-                whereClauses.Add("LocationType not in (" + val + ")");
+                var inClause = string.Join(",", query.BlockUnratedItems.Select(i => "'" + i.ToString() + "'").ToArray());
+                whereClauses.Add(string.Format("(InheritedParentalRatingValue > 0 or UnratedType not in ({0}))", inClause));
             }
-
+            
             if (addPaging)
             {
                 if (query.StartIndex.HasValue && query.StartIndex.Value > 0)
@@ -1996,55 +2011,55 @@ namespace MediaBrowser.Server.Implementations.Persistence
 
         public async Task UpdateInheritedValues(CancellationToken cancellationToken)
         {
-            await _writeLock.WaitAsync(cancellationToken).ConfigureAwait(false);
-
-            IDbTransaction transaction = null;
-
-            try
-            {
-                transaction = _connection.BeginTransaction();
-
-                using (var cmd = _connection.CreateCommand())
-                {
-                    cmd.CommandText = "update TypedBaseItems set InheritedParentalRatingValue = (select Max(ParentalRatingValue, (select COALESCE(MAX(ParentalRatingValue),0) from TypedBaseItems as T where guid in (Select AncestorId from AncestorIds where ItemId=T.guid))))";
-
-                    cmd.Transaction = transaction;
-                    cmd.ExecuteNonQuery();
-
-                    cmd.ExecuteNonQuery();
-                }
-
-                transaction.Commit();
-            }
-            catch (OperationCanceledException)
-            {
-                if (transaction != null)
-                {
-                    transaction.Rollback();
-                }
-
-                throw;
-            }
-            catch (Exception e)
-            {
-                _logger.ErrorException("Error running query:", e);
-
-                if (transaction != null)
-                {
-                    transaction.Rollback();
-                }
-
-                throw;
-            }
-            finally
-            {
-                if (transaction != null)
-                {
-                    transaction.Dispose();
-                }
-
-                _writeLock.Release();
-            }
+            //await _writeLock.WaitAsync(cancellationToken).ConfigureAwait(false);
+
+            //IDbTransaction transaction = null;
+
+            //try
+            //{
+            //    transaction = _connection.BeginTransaction();
+
+            //    using (var cmd = _connection.CreateCommand())
+            //    {
+            //        cmd.CommandText = "update TypedBaseItems set InheritedParentalRatingValue = (select Max(ParentalRatingValue, (select COALESCE(MAX(ParentalRatingValue),0) from TypedBaseItems as T where guid in (Select AncestorId from AncestorIds where ItemId=T.guid))))";
+
+            //        cmd.Transaction = transaction;
+            //        cmd.ExecuteNonQuery();
+
+            //        cmd.ExecuteNonQuery();
+            //    }
+
+            //    transaction.Commit();
+            //}
+            //catch (OperationCanceledException)
+            //{
+            //    if (transaction != null)
+            //    {
+            //        transaction.Rollback();
+            //    }
+
+            //    throw;
+            //}
+            //catch (Exception e)
+            //{
+            //    _logger.ErrorException("Error running query:", e);
+
+            //    if (transaction != null)
+            //    {
+            //        transaction.Rollback();
+            //    }
+
+            //    throw;
+            //}
+            //finally
+            //{
+            //    if (transaction != null)
+            //    {
+            //        transaction.Dispose();
+            //    }
+
+            //    _writeLock.Release();
+            //}
         }
 
         private static Dictionary<string, string[]> GetTypeMapDictionary()

+ 1 - 1
MediaBrowser.Server.Implementations/Sync/MediaSync.cs

@@ -66,7 +66,7 @@ namespace MediaBrowser.Server.Implementations.Sync
 
             // Do the data sync twice so the server knows what was removed from the device
             await SyncData(provider, dataProvider, serverId, target, cancellationToken).ConfigureAwait(false);
-
+            
             progress.Report(100);
         }
 

+ 4 - 4
MediaBrowser.Server.Implementations/Sync/SyncManager.cs

@@ -739,10 +739,10 @@ namespace MediaBrowser.Server.Implementations.Sync
                 var requiresSaving = false;
                 var removeFromDevice = false;
 
-                var libraryItem = _libraryManager.GetItemById(jobItem.ItemId);
-
                 if (request.LocalItemIds.Contains(jobItem.ItemId, StringComparer.OrdinalIgnoreCase))
                 {
+                    var libraryItem = _libraryManager.GetItemById(jobItem.ItemId);
+
                     var job = _repo.GetJob(jobItem.JobId);
                     var user = _userManager.GetUserById(job.UserId);
 
@@ -845,10 +845,10 @@ namespace MediaBrowser.Server.Implementations.Sync
                 var requiresSaving = false;
                 var removeFromDevice = false;
 
-                var libraryItem = _libraryManager.GetItemById(jobItem.ItemId);
-
                 if (request.SyncJobItemIds.Contains(jobItem.Id, StringComparer.OrdinalIgnoreCase))
                 {
+                    var libraryItem = _libraryManager.GetItemById(jobItem.ItemId);
+
                     var job = _repo.GetJob(jobItem.JobId);
                     var user = _userManager.GetUserById(job.UserId);