SageTV Community  

Go Back   SageTV Community > SageTV Development and Customizations > SageTV Github Development
Forum Rules FAQs Community Downloads Today's Posts Search

Notices

SageTV Github Development Discussion related to SageTV Open Source Development. Use this forum for development topics about the Open Source versions of SageTV, hosted on Github.

Reply
 
Thread Tools Search this Thread Display Modes
  #21  
Old 09-08-2015, 06:14 PM
sacrament055 sacrament055 is offline
Sage Aficionado
 
Join Date: Jul 2007
Posts: 474
Quote:
Originally Posted by Narflex View Post
You can do gapless playback/recording with network encoders...it's done on Google Fiber. As Fuzzy mentioned, the SWITCH command can be used for that. You also need to set the "fast_network_encoder_switch" property for that capture to enable it since most network encoders won't support it by default.

Ideally we should probably extend the protocol to query the network encoder itself for this capability, as that would be easier to setup (of course if its setup using network encoder discovery, then it can control the config that way).
Out of curiosity is an ATSC HDHomerun capable of the fast network encoder switch?
Reply With Quote
  #22  
Old 09-09-2015, 01:35 AM
Fuzzy's Avatar
Fuzzy Fuzzy is offline
SageTVaholic
 
Join Date: Sep 2005
Location: Jurupa Valley, CA
Posts: 9,957
Quote:
Originally Posted by jvl711 View Post
Thanks Jeff,

I will write a test program and load it as a runable in Sage to make sure the library is loading in Windows. I was having a hard time tracing everything that was going on in the C/C++ code, so I was not sure if/when the calls were available.

Do you have any interest or opposition if I were to attempt to add functionallity to sage to allow for tuner locking? I was thinking of adding a get/set method to CaptureDevice that would default to return not locked. I know that the sage core would need to be modified to check to see if the tuner is locked prior to utilizing the tuner for live or recorded tv.
Not sure how well this will work in practice. So sage has intended to use a given tuner to record a given program. It then goes to start the recording, and finds out the tuner is locked by some other pesky program/user. It then essentially needs to mark that encoder as unavailable, and kick off the scheduler from scratch, which will then reprocess then entire schedule without the locked tuner, likely creating a bunch of conflicts in the process, then once the schedule is completed, it will not try to tune that program on another available tuner, if one is available.
__________________
Buy Fuzzy a beer! (Fuzzy likes beer)

unRAID Server: i7-6700, 32GB RAM, Dual 128GB SSD cache and 13TB pool, with SageTVv9, openDCT, Logitech Media Server and Plex Media Server each in Dockers.
Sources: HRHR Prime with Charter CableCard. HDHR-US for OTA.
Primary Client: HD-300 through XBoxOne in Living Room, Samsung HLT-6189S
Other Clients: Mi Box in Master Bedroom, HD-200 in kids room
Reply With Quote
  #23  
Old 09-09-2015, 06:05 AM
BobPhoenix BobPhoenix is offline
SageTVaholic
 
Join Date: Oct 2004
Posts: 3,152
Quote:
Originally Posted by Fuzzy View Post
Not sure how well this will work in practice. So sage has intended to use a given tuner to record a given program. It then goes to start the recording, and finds out the tuner is locked by some other pesky program/user. It then essentially needs to mark that encoder as unavailable, and kick off the scheduler from scratch, which will then reprocess then entire schedule without the locked tuner, likely creating a bunch of conflicts in the process, then once the schedule is completed, it will not try to tune that program on another available tuner, if one is available.
How about if it does the lock when SageTV first boots up and doesn't unlock it until it is shutting down? But that is probably not what he wanted either.
__________________
"Keep your goals away from the trolls"
Reply With Quote
  #24  
Old 09-09-2015, 07:17 AM
Fuzzy's Avatar
Fuzzy Fuzzy is offline
SageTVaholic
 
Join Date: Sep 2005
Location: Jurupa Valley, CA
Posts: 9,957
Having sage lock the tuner is simple, and really should be done by your network encoder on start and stop commands. The issue I described was having sage deal with a tuner that might be locked by something else.
__________________
Buy Fuzzy a beer! (Fuzzy likes beer)

unRAID Server: i7-6700, 32GB RAM, Dual 128GB SSD cache and 13TB pool, with SageTVv9, openDCT, Logitech Media Server and Plex Media Server each in Dockers.
Sources: HRHR Prime with Charter CableCard. HDHR-US for OTA.
Primary Client: HD-300 through XBoxOne in Living Room, Samsung HLT-6189S
Other Clients: Mi Box in Master Bedroom, HD-200 in kids room
Reply With Quote
  #25  
Old 09-09-2015, 07:28 AM
Taddeusz Taddeusz is offline
SageTVaholic
 
Join Date: Nov 2004
Location: Yukon, OK
Posts: 3,919
This is a future thing but maybe the scheduler should be modified to have tuner pools. The scheduler can be set to record something from the pool. It will then try each tuner in the pool until it finds one not locked. This to me would be more logical than having each tuner stand on its own but associated with a particular channel lineup. It makes more sense in my mind to have a pool associated with a lineup and have tuners assigned to the pool that are able to receive the lineup.
__________________
Server: i5 8400, ASUS Prime H370M-Plus/CSM, 16GB RAM, 15TB drive array + 500GB cache, 2 HDHR's, SageTV 9, unRAID 6.6.3
Client 1: HD300 (latest FW), HDMI to an Insignia 65" 1080p LCD and optical SPDIF to a Sony Receiver
Client 2: HD200 (latest FW), HDMI to an Insignia NS-LCD42HD-09 1080p LCD
Reply With Quote
  #26  
Old 09-09-2015, 08:02 AM
Fuzzy's Avatar
Fuzzy Fuzzy is offline
SageTVaholic
 
Join Date: Sep 2005
Location: Jurupa Valley, CA
Posts: 9,957
Quote:
Originally Posted by Taddeusz View Post
This is a future thing but maybe the scheduler should be modified to have tuner pools. The scheduler can be set to record something from the pool. It will then try each tuner in the pool until it finds one not locked. This to me would be more logical than having each tuner stand on its own but associated with a particular channel lineup. It makes more sense in my mind to have a pool associated with a lineup and have tuners assigned to the pool that are able to receive the lineup.
What makes the MOST sense is to simply not have more than one thing trying to use the tuners. In theory, Sage should be the only thing accessing your tuners, and any viewing and/or recording is done via sage. most tuners don't even HAVE a locking mechanism, so it's not really something that could be done universally anyway.
__________________
Buy Fuzzy a beer! (Fuzzy likes beer)

unRAID Server: i7-6700, 32GB RAM, Dual 128GB SSD cache and 13TB pool, with SageTVv9, openDCT, Logitech Media Server and Plex Media Server each in Dockers.
Sources: HRHR Prime with Charter CableCard. HDHR-US for OTA.
Primary Client: HD-300 through XBoxOne in Living Room, Samsung HLT-6189S
Other Clients: Mi Box in Master Bedroom, HD-200 in kids room
Reply With Quote
  #27  
Old 09-09-2015, 08:08 AM
Taddeusz Taddeusz is offline
SageTVaholic
 
Join Date: Nov 2004
Location: Yukon, OK
Posts: 3,919
Quote:
Originally Posted by Fuzzy View Post
What makes the MOST sense is to simply not have more than one thing trying to use the tuners. In theory, Sage should be the only thing accessing your tuners, and any viewing and/or recording is done via sage. most tuners don't even HAVE a locking mechanism, so it's not really something that could be done universally anyway.
The Silicon Dust tuners are unique not only in their network connectivity but their ability to be accessed by multiple "users".
__________________
Server: i5 8400, ASUS Prime H370M-Plus/CSM, 16GB RAM, 15TB drive array + 500GB cache, 2 HDHR's, SageTV 9, unRAID 6.6.3
Client 1: HD300 (latest FW), HDMI to an Insignia 65" 1080p LCD and optical SPDIF to a Sony Receiver
Client 2: HD200 (latest FW), HDMI to an Insignia NS-LCD42HD-09 1080p LCD
Reply With Quote
  #28  
Old 09-09-2015, 08:24 AM
nyplayer nyplayer is offline
SageTVaholic
 
Join Date: Sep 2005
Posts: 4,997
You should have a way of locking HDHomerun tuners ... simply because anyone on the Network can access them and mostly any device can access them through DLNA. So that could interrupt a Sage recording in progress. I like the ability to fire up my Tablet and watch livetv when ever I want if there is an available tuner.

Edit

Not only does SageTV need to lock the tuners but also be able to check for tuner usage and move on to the next free tuner. Right now I have to segregate my 2 Primes and use 1 for WMC ,NEXTPVR and HDHomerun DVR and have no problem with tuner allocation. I would like to make all tuners available to all DVRs.... but SageTV is preventing me from doing this.

Last edited by nyplayer; 09-09-2015 at 10:13 AM.
Reply With Quote
  #29  
Old 09-09-2015, 12:28 PM
Narflex's Avatar
Narflex Narflex is offline
Sage
 
Join Date: Feb 2003
Location: Redondo Beach, CA
Posts: 6,349
Quote:
Originally Posted by jvl711 View Post
Thanks Jeff,

I will write a test program and load it as a runable in Sage to make sure the library is loading in Windows. I was having a hard time tracing everything that was going on in the C/C++ code, so I was not sure if/when the calls were available.

Do you have any interest or opposition if I were to attempt to add functionallity to sage to allow for tuner locking? I was thinking of adding a get/set method to CaptureDevice that would default to return not locked. I know that the sage core would need to be modified to check to see if the tuner is locked prior to utilizing the tuner for live or recorded tv.
This is more or less already in there. The isFunctioning() method in CaptureDevice tells SageTV if a tuner is currently available or not (because network encoders can go up/down). However...if something else 'locks' it; then you'd need to kick the Scheduler in SageTV so it could notice that and then reprocess the schedule.

Quote:
Originally Posted by Fuzzy View Post
Not sure how well this will work in practice. So sage has intended to use a given tuner to record a given program. It then goes to start the recording, and finds out the tuner is locked by some other pesky program/user. It then essentially needs to mark that encoder as unavailable, and kick off the scheduler from scratch, which will then reprocess then entire schedule without the locked tuner, likely creating a bunch of conflicts in the process, then once the schedule is completed, it will not try to tune that program on another available tuner, if one is available.
Yes, exactly. The whole concept of sharing tuners with other applications creates planning problems for SageTV because it never knows when a tuner will just be stolen out from underneath it when it was planning on using it.

Quote:
Originally Posted by sacrament055 View Post
Out of curiosity is an ATSC HDHomerun capable of the fast network encoder switch?
Yes, this should work fine if you're using it under the control of SageTV (if SageTV can do fast switch with a local tuner; it can do it as well if SageTV is running as a network encoder using that tuner).
__________________
Jeffrey Kardatzke
Google
Founder of SageTV
Reply With Quote
  #30  
Old 09-09-2015, 02:26 PM
jvl711's Avatar
jvl711 jvl711 is offline
Sage Fanatic
 
Join Date: Jan 2004
Posts: 825
Quote:
Originally Posted by Narflex View Post
This is more or less already in there. The isFunctioning() method in CaptureDevice tells SageTV if a tuner is currently available or not (because network encoders can go up/down). However...if something else 'locks' it; then you'd need to kick the Scheduler in SageTV so it could notice that and then reprocess the schedule.
I actually have no vested interest at this time to add locking, but I know there are a few people that are interested in it. Below are some of the reasons that I think you might want to consider adding something a little more robust to handle locking.

Adding the locking mechanism into Sage would allow users to utilize their tuners for other software than just Sage. There are a number of apps that can live stream from the HDHomeRun and it would be nice to allow users to share the tuner with these other applications without having to take them out of there available tuner pool for Sage. If they do not take these tuners out of the available pool they either face the possibility of a failed recording because the tuner is locked, or Sage stealing a tuner from them while they are attempting to use it.

If these other apps start utilizing locking then Sage has no choice then to either have the recording fail because it was unable to tune to the channel (It is unaware of the locking function), or it would need to force break the lock every time it tunes to a channel. If it force breaks the lock it might steal a tuner when it did not even need too.

If we hijack the isFunctioning then we loose the visibility between the tuner being offline vs the tuner being locked, but still a potential resource we could use if there are no other tuners available.

I would have Sage check to see if a tuner is locked when it goes to use a tuner. If so it can kick off the scheduler and pick another tuner that is not locked. If there are no other tuners available I would suggest that it should break the lock and steal a tuner to perform the recording anyway. Whether Sage breaks the lock or fails the recording could be a configuration option. Whether Sage uses locking at all could be a configuration option.
Reply With Quote
  #31  
Old 09-09-2015, 02:34 PM
sacrament055 sacrament055 is offline
Sage Aficionado
 
Join Date: Jul 2007
Posts: 474
Thanks for the response Narflex,

So does that mean I just add the following to my sage.properties file?

"fast_network_encoder_switch=true"

Or is it more like:

"mmc/encoders/-XXXXXXXX/fast_network_encoder_switch=true"?

I had noticed my HD Homerun tuners did this but didn't know why. Glad I asked the question and thanks for the response.
Reply With Quote
  #32  
Old 09-09-2015, 03:30 PM
Narflex's Avatar
Narflex Narflex is offline
Sage
 
Join Date: Feb 2003
Location: Redondo Beach, CA
Posts: 6,349
Quote:
Originally Posted by sacrament055 View Post
"mmc/encoders/-XXXXXXXX/fast_network_encoder_switch=true"?
This way.
__________________
Jeffrey Kardatzke
Google
Founder of SageTV
Reply With Quote
  #33  
Old 09-09-2015, 04:33 PM
Fuzzy's Avatar
Fuzzy Fuzzy is offline
SageTVaholic
 
Join Date: Sep 2005
Location: Jurupa Valley, CA
Posts: 9,957
Quote:
Originally Posted by jvl711 View Post
I actually have no vested interest at this time to add locking, but I know there are a few people that are interested in it. Below are some of the reasons that I think you might want to consider adding something a little more robust to handle locking.

Adding the locking mechanism into Sage would allow users to utilize their tuners for other software than just Sage. There are a number of apps that can live stream from the HDHomeRun and it would be nice to allow users to share the tuner with these other applications without having to take them out of there available tuner pool for Sage. If they do not take these tuners out of the available pool they either face the possibility of a failed recording because the tuner is locked, or Sage stealing a tuner from them while they are attempting to use it.

If these other apps start utilizing locking then Sage has no choice then to either have the recording fail because it was unable to tune to the channel (It is unaware of the locking function), or it would need to force break the lock every time it tunes to a channel. If it force breaks the lock it might steal a tuner when it did not even need too.

If we hijack the isFunctioning then we loose the visibility between the tuner being offline vs the tuner being locked, but still a potential resource we could use if there are no other tuners available.

I would have Sage check to see if a tuner is locked when it goes to use a tuner. If so it can kick off the scheduler and pick another tuner that is not locked. If there are no other tuners available I would suggest that it should break the lock and steal a tuner to perform the recording anyway. Whether Sage breaks the lock or fails the recording could be a configuration option. Whether Sage uses locking at all could be a configuration option.
Sage really would't care whether a tuner is 'gone' or 'locked'. It affects sage in exactly the same way. In either case, it will have to kick the scheduler to find an available tuner to tune what it needs to tune.
__________________
Buy Fuzzy a beer! (Fuzzy likes beer)

unRAID Server: i7-6700, 32GB RAM, Dual 128GB SSD cache and 13TB pool, with SageTVv9, openDCT, Logitech Media Server and Plex Media Server each in Dockers.
Sources: HRHR Prime with Charter CableCard. HDHR-US for OTA.
Primary Client: HD-300 through XBoxOne in Living Room, Samsung HLT-6189S
Other Clients: Mi Box in Master Bedroom, HD-200 in kids room
Reply With Quote
  #34  
Old 09-09-2015, 06:20 PM
sacrament055 sacrament055 is offline
Sage Aficionado
 
Join Date: Jul 2007
Posts: 474
Quote:
Originally Posted by Narflex View Post
This way.
Thanks, I'll give it a shot.
Reply With Quote
  #35  
Old 09-09-2015, 07:17 PM
KryptoNyte's Avatar
KryptoNyte KryptoNyte is offline
SageTVaholic
 
Join Date: Dec 2006
Posts: 2,754
Quote:
Originally Posted by Fuzzy View Post
Sage really would't care whether a tuner is 'gone' or 'locked'. It affects sage in exactly the same way. In either case, it will have to kick the scheduler to find an available tuner to tune what it needs to tune.
There was some guy in here a few days ago that mentioned he has 13 years of TV history in Sage. Anyways, with that much history, when SageTV kicks the Carnival Employee so it takes another look at the schedule, it can take quite a bit of time (on a slower machine as mentioned).

Meow on my young SageTV server, it uses (2) Primes for 6 tuners total, and one of the primes occasionally hard locks and the computer doesn't recognize it until I cycle the power on the offending prime. When this happens, there will inevitably be some recording conflicts that appear as Sage lost half it's tuners.

I have to believe that dynamic tuner locking would create some timing havoc, not to mention the sudden warnings of impending recording doom (unless you have 13 years of recording history on vacuum tubes in which case the warnings may not occur at all).

So let's say Sage thinks it has (3) tuners on a Prime, someone cranks up the HDHR software on their phone and grabs one of the tuners to watch live TV - at which point Sage has some mechanism that watches for and recognizes that it just lost one tuner, or more perhaps. Sage then reschedules programs (unless you have a bajillion years of TV history on a primitive transistor) if possible, or just starts saying there are unresolved conflicts. Some poor bastard is going to start getting a stream of messages via SageAlert and start getting concerned that the football program won't get recorded.

As it turns out, the kid in the house just wanted to catch the end of Sponge Bob, and as soon as he releases the tuner, Sage's tuner monitoring mechanism realizes that it has 3 tuners once again, and all is well. Unless you have the big history thing on the slow thing ...

Does that sound about right?

Last edited by KryptoNyte; 09-09-2015 at 07:20 PM.
Reply With Quote
  #36  
Old 09-10-2015, 03:29 AM
Fuzzy's Avatar
Fuzzy Fuzzy is offline
SageTVaholic
 
Join Date: Sep 2005
Location: Jurupa Valley, CA
Posts: 9,957
Quote:
Originally Posted by KryptoNyte View Post
There was some guy in here a few days ago that mentioned he has 13 years of TV history in Sage. Anyways, with that much history, when SageTV kicks the Carnival Employee so it takes another look at the schedule, it can take quite a bit of time (on a slower machine as mentioned).

Meow on my young SageTV server, it uses (2) Primes for 6 tuners total, and one of the primes occasionally hard locks and the computer doesn't recognize it until I cycle the power on the offending prime. When this happens, there will inevitably be some recording conflicts that appear as Sage lost half it's tuners.

I have to believe that dynamic tuner locking would create some timing havoc, not to mention the sudden warnings of impending recording doom (unless you have 13 years of recording history on vacuum tubes in which case the warnings may not occur at all).

So let's say Sage thinks it has (3) tuners on a Prime, someone cranks up the HDHR software on their phone and grabs one of the tuners to watch live TV - at which point Sage has some mechanism that watches for and recognizes that it just lost one tuner, or more perhaps. Sage then reschedules programs (unless you have a bajillion years of TV history on a primitive transistor) if possible, or just starts saying there are unresolved conflicts. Some poor bastard is going to start getting a stream of messages via SageAlert and start getting concerned that the football program won't get recorded.

As it turns out, the kid in the house just wanted to catch the end of Sponge Bob, and as soon as he releases the tuner, Sage's tuner monitoring mechanism realizes that it has 3 tuners once again, and all is well. Unless you have the big history thing on the slow thing ...

Does that sound about right?
That's pretty much how everything works already, using the 'isFuntioning' call on a tuner.
__________________
Buy Fuzzy a beer! (Fuzzy likes beer)

unRAID Server: i7-6700, 32GB RAM, Dual 128GB SSD cache and 13TB pool, with SageTVv9, openDCT, Logitech Media Server and Plex Media Server each in Dockers.
Sources: HRHR Prime with Charter CableCard. HDHR-US for OTA.
Primary Client: HD-300 through XBoxOne in Living Room, Samsung HLT-6189S
Other Clients: Mi Box in Master Bedroom, HD-200 in kids room
Reply With Quote
  #37  
Old 09-10-2015, 11:07 AM
Narflex's Avatar
Narflex Narflex is offline
Sage
 
Join Date: Feb 2003
Location: Redondo Beach, CA
Posts: 6,349
Quote:
Originally Posted by KryptoNyte View Post
There was some guy in here a few days ago that mentioned he has 13 years of TV history in Sage. Anyways, with that much history, when SageTV kicks the Carnival Employee so it takes another look at the schedule, it can take quite a bit of time (on a slower machine as mentioned).
Lol...that guy was me. And Carny wasn't actually named after Carnival Employees...it was named after Carnivore. That was an FBI program that analyzed people's emails: https://en.wikipedia.org/wiki/Carnivore_(software)

Carny is the thing that does 'profiling' of user behavior in SageTV in order to determine what Intelligent Recording should do (it also does all the Favorites processing since they use the same model for matching content).
__________________
Jeffrey Kardatzke
Google
Founder of SageTV
Reply With Quote
  #38  
Old 09-10-2015, 05:33 PM
KryptoNyte's Avatar
KryptoNyte KryptoNyte is offline
SageTVaholic
 
Join Date: Dec 2006
Posts: 2,754
Quote:
Originally Posted by Fuzzy View Post
That's pretty much how everything works already, using the 'isFuntioning' call on a tuner.
I guess I was trying to emphasize the fact that Sage believes that it lost the tuner ... forever ... at the point it can't see it or use it. At least that's how the system acts at this time. Even if that period of lost tuner is going to be very short.
Reply With Quote
  #39  
Old 09-10-2015, 05:35 PM
KryptoNyte's Avatar
KryptoNyte KryptoNyte is offline
SageTVaholic
 
Join Date: Dec 2006
Posts: 2,754
Quote:
Originally Posted by Narflex View Post
Lol...that guy was me. And Carny wasn't actually named after Carnival Employees...it was named after Carnivore. That was an FBI program that analyzed people's emails: https://en.wikipedia.org/wiki/Carnivore_(software)

Carny is the thing that does 'profiling' of user behavior in SageTV in order to determine what Intelligent Recording should do (it also does all the Favorites processing since they use the same model for matching content).
Oh, I know - I was just pokin' fun at you and that old computer, Jeff.
Reply With Quote
  #40  
Old 09-10-2015, 05:49 PM
Fuzzy's Avatar
Fuzzy Fuzzy is offline
SageTVaholic
 
Join Date: Sep 2005
Location: Jurupa Valley, CA
Posts: 9,957
Quote:
Originally Posted by KryptoNyte View Post
I guess I was trying to emphasize the fact that Sage believes that it lost the tuner ... forever ... at the point it can't see it or use it. At least that's how the system acts at this time. Even if that period of lost tuner is going to be very short.
Understand, though, that sage will have no idea how long a given tuner is 'lost', so it is still going to rehash it's entire schedule. There is no way for Sage to reschedule a small portion of it's schedule, or even a single item on it's schedule, without running through all it's multiple iterations from the beginning. Doens't matter if the tuner is gone for a minute, or 3 days. Sage's behavior when said tuner is unavailable has to be the same.
__________________
Buy Fuzzy a beer! (Fuzzy likes beer)

unRAID Server: i7-6700, 32GB RAM, Dual 128GB SSD cache and 13TB pool, with SageTVv9, openDCT, Logitech Media Server and Plex Media Server each in Dockers.
Sources: HRHR Prime with Charter CableCard. HDHR-US for OTA.
Primary Client: HD-300 through XBoxOne in Living Room, Samsung HLT-6189S
Other Clients: Mi Box in Master Bedroom, HD-200 in kids room
Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Question about HDHomeRun (Not Prime) TechBill Hardware Support 27 06-13-2017 08:24 AM
Does SageTV 7 support HDHomerun Prime? LabyrinthMike Hardware Support 14 02-18-2015 04:32 PM
HDHomeRun Prime on Woot 5/24 ranger The SageTV Community 6 05-25-2012 07:10 PM
HDHomerun Prime? cenwesi Hardware Support 26 04-19-2011 05:40 PM
HDHomeRun 68 channel remap limit / Native QAM tuning? taylork Hardware Support 40 07-11-2008 04:50 AM


All times are GMT -6. The time now is 02:12 AM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2023, vBulletin Solutions Inc.
Copyright 2003-2005 SageTV, LLC. All rights reserved.