<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>16.7ms in the life</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/peterrosser/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/peterrosser/feed.xml</link>
    <description>A sample in the life of a Media Center developer</description>
    <lastBuildDate>Tue, 16 Apr 2019 05:23:08 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>&lt;Invoke Target="[Blog.Entries.Add]" item="[NewPosting]" InvokePolicy="Synchronous" ExclusiveApply="true" /&gt;</title>
      <link>https://docs.microsoft.com/archive/blogs/peterrosser/invoke-targetblog-entries-add-itemnewposting-invokepolicysynchronous-exclusiveapplytrue</link>
      <pubDate>Wed, 21 Mar 2007 00:35:00 GMT</pubDate>
      <dc:creator><![CDATA[PeterRosser]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/peterrosser/2007/03/21/invoke-targetblog-entries-add-itemnewposting-invokepolicysynchronous-exclusiveapplytrue/</guid>
      <description><![CDATA[So, the last several months have been fairly busy, what with Vista shipping (woohoo!), vacations,...]]></description>
      <content:encoded><![CDATA[<P>So, the last several months have been fairly busy, what with Vista shipping (woohoo!), vacations, and plannng the next rev. I worked long hours alongside my fellow eHomers, we shipped, and I took off a couple of months to find myself in Mexico and decompress. I've been back for a while now, and been bugged enough about my blog neglect--so here I am posting again.</P>
<P>The timbre of my postings will probably shift quite a bit now that I am in a new position on a new team. As of February, I have left the Windows TV team and joined the Media Center Core, a move that shifts me from the south side of building 50 to the north side, across the Great Divide of the central hallway. That is, when my office move happens to place me somewhat closer to my new team. It's always a little melancholy moving teams, but I am excited at the new opportunities I have to make a&nbsp;positive&nbsp;impact on the product.</P>
<P>The Media Center Core Team owns the Media Center application, non-TV experiences: Movies Guide, music, photos &amp;&nbsp;video library, extensibility, online spotlight, and a bunch of other stuff on the side. It's always difficult to talk about what we do without talking about what we're <STRONG>doing</STRONG>, if you get my meaning.</P>
<P>One thing I <STRONG>can</STRONG> talk about is that we are growing, and with growing comes new jobs! We have several positions open for experienced developers posted on the Microsoft job site (here's one: <A href="http://members.microsoft.com/careers/search/details.aspx?JobID=9D2139A0-0D36-414E-8C66-B3C8CFD35086" mce_href="http://members.microsoft.com/careers/search/details.aspx?JobID=9D2139A0-0D36-414E-8C66-B3C8CFD35086">http://members.microsoft.com/careers/search/details.aspx?JobID=9D2139A0-0D36-414E-8C66-B3C8CFD35086</A>&nbsp;). If you think you have what it takes to help us ship the coolest feature in Windows to millions of users, send me your resume! Whether your passion is TV, music, photos, or you're just a scary-smart engineer, we are hiring across the board, for Test, Development, and Program Management.</P>
<P>Oh, if anyone has anything in particular they'd like me to talk about, shoot me an email (<A href="mailto:peter.rosser@microsoft.com" mce_href="mailto:peter.rosser@microsoft.com">peter.rosser@microsoft.com</A>) or add a comment.</P>]]></content:encoded>
    </item>
    <item>
      <title>Thoughts on software complexity</title>
      <link>https://docs.microsoft.com/archive/blogs/peterrosser/thoughts-on-software-complexity</link>
      <pubDate>Sat, 03 Jun 2006 00:06:00 GMT</pubDate>
      <dc:creator><![CDATA[PeterRosser]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/peterrosser/2006/06/03/thoughts-on-software-complexity/</guid>
      <description><![CDATA[If you've ever tried to create a software application of any decent size, you have probably realized...]]></description>
      <content:encoded><![CDATA[<P>If you've ever tried to create a software application of any decent size, you have probably realized that what works with small tools more often than not does not scale well to larger sizes.&nbsp; There are whole books written about how to scale up and out, new languages and technologies invented to help manage it, and millions of dollars in educational budgets spent every year to achieve that elusive goal.</P>
<P>And yet, the landscape is still rife with examples of poorly designed software.</P>
<P>A significant part of the&nbsp;problem is not that engineers are not smart enough--it's that we outsmart ourselves.&nbsp; The conventional wisdom is that humans can store 7 ± 2 primitives (e.g. numbers) on the top stack of short-term memory.&nbsp; The number skews higher for strongly associative items, and vice versa.&nbsp; We can store fewer abstract items, often only 2 or 3 at a time.&nbsp; The issue is not one of comprehension, it's one of focused retension.&nbsp; When the number of data items in a class exceeds our capacity to retain them at once, the brain tends to move the perceived "less important" fields/properties into peripheral storage.&nbsp; This, I think, leads to not fully comprehending the interactions in the class.&nbsp; We engineers like to think of ourselves as intelligent, and that we can understand very complex ideas.&nbsp; This may be true, but it misses the point; the point of software engineering is to create&nbsp;reliable, performant, maintainable software.&nbsp; It is <EM>not</EM> to create complex applications.</P>
<P>Well, there's the problem, isn't it?&nbsp; In order to create the really cool applications, you must have complexity.&nbsp; It's simply unavoidable, especially given the advanced competition for consumer dollars.&nbsp; You can't very well create a next generation RPG that has realistic physics, with a "real" economy, kickass graphics and brutally smart AI without complexity.</P>
<P>Or can you?</P>
<P>Actually, I believe the answer is that you can, at least the bad kind of complexity that causes the pain.&nbsp;The key is differentiating between behavioral complexity and system complexity.&nbsp; Behavioral complexity is the aforementioned features like smart AI, or realistic physics.&nbsp; Those sorts of things are monstrously difficult to get right, but that's not what holds back the very large application development projects.&nbsp; The major cause for schedule slips, regressions, out-and-out bugs, and general angst is system complexity.</P>
<P>Before I go on, I'd like to define what I mean (yes, I do get to hijack words like this) by&nbsp;system complexity: </P>
<BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px">
<P><FONT style="BACKGROUND-COLOR: #f5f5dc">System complexity a property of a system that&nbsp;is directly proportional to the difficulty one has&nbsp;in&nbsp;comprehending&nbsp;the system&nbsp;at the level and detail necessary to make changes to the system without introducing instability or functional regressions. </FONT></P></BLOCKQUOTE>
<P>In other words, the higher the system complexity, the harder it is to upgrade, maintain, and&nbsp;develop the system.&nbsp;Whether the system is a single class, an object library, an inheritance heirarchy, or an entire application, someone "schooled in the art" of software engineering should be able to understand it, given a reasonable time to examine the system.&nbsp; This ability should <EM>scale through the system.</EM>&nbsp; When one examines a particular object, it should be apparent without examining the private implementation details how to use it.&nbsp; From top to bottom, from bottom to top; the entire system should be accessible to the non-super-geniuses out there.&nbsp; What goes for good UI design also goes for good C++, C# and COM design: your target audience should be able to use it without extensive systems training.</P>
<P>System Complexity is what makes the Mythical Man Month true.&nbsp; It's what keeps that guy who wrote the accounting system from scratch in 1986 employed.&nbsp; It's what causes games, productivity applications, and even (some might say especially) large operating system projects to slip their schedules.</P>
<P>So what can you do about it?&nbsp; The first step to recovery is admitting you have a problem.&nbsp; Pedantic, but true.&nbsp; Getting back to the point I tried to make earlier about engineers--we like to think we are smart.&nbsp; Egos loom large in the software industry, and often with good reason.&nbsp; One of the smartest developers I have come across worked on a critical piece of the code for several years, and guarded his territory jealously.&nbsp; Make no mistake, this guy was brilliant--and he knew it.&nbsp; To make a long story short, when he left, the code he left behind was an engineering marvel [he says wryly] that no one else understood.&nbsp; Oh, we know what it does, but there's a crucial difference in understanding what something does, and grokking fully how it does it.&nbsp; Tracing execution paths through this code is difficult, and 1200-line methods named "Run" are common.&nbsp; </P>
<P>The author understood it all, or said he did, but my opinion is that he was fooling himself, too.&nbsp;Once you get a piece of the system working, after all, you don't need to touch that piece again unless the design changes, a bug is found, or something like that.&nbsp;Over time, though, people started to notice that even small fixes in this particular area would touch a dozen or more files, and churn lots of code.&nbsp; That's a symptom of high system complexity; he would go in to make the fix, then discover that 100 variables influenced the behavior, or the implementation in one area was strongly dependent on the implementation in another, or most often, both.&nbsp; But since the author had traveled this area so much, he was able to turn around the fixes in an acceptable timeframe, so he "got away" with it.</P>
<P>It's no surprise that when the author decided to move on to other things, as employees often do, that we had a tough decision to make.&nbsp; Do we maintain this code that's <EM>working</EM>?&nbsp; Do we refactor?&nbsp; In the end it came down to pragmatism and schedule: the problem was recognized, and we chose to refactor the system in measured stages, minimizing the risk to the product and getting back to a good, maintainable state.</P>
<P>That's all I have time for today... my build is done, so back to work I go.&nbsp;Windows Vista waits for no man!</P>]]></content:encoded>
    </item>
    <item>
      <title>Where's Peter?</title>
      <link>https://docs.microsoft.com/archive/blogs/peterrosser/wheres-peter</link>
      <pubDate>Thu, 01 Jun 2006 19:01:00 GMT</pubDate>
      <dc:creator><![CDATA[PeterRosser]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/peterrosser/2006/06/01/wheres-peter/</guid>
      <description><![CDATA[... working, working, working.
That, in short, is why there have been no updates in so long.&nbsp;...]]></description>
      <content:encoded><![CDATA[<P>... working, working, working.</P>
<P>That, in short, is why there have been no updates in so long.&nbsp; Between my work schedule, family and renovation project I have not had much time to myself.&nbsp; I have neglected my blog in favor of meatspace; sorry!</P>
<P>When things settle down a bit, I'll blog the drama a bit (what I can). ^_^</P>
<P>&nbsp;</P>]]></content:encoded>
    </item>
    <item>
      <title>Media Center Technical Discussion 1: Tuners and TuningSpaces</title>
      <link>https://docs.microsoft.com/archive/blogs/peterrosser/media-center-technical-discussion-1-tuners-and-tuningspaces</link>
      <pubDate>Mon, 03 Apr 2006 23:08:00 GMT</pubDate>
      <dc:creator><![CDATA[PeterRosser]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/peterrosser/2006/04/03/media-center-technical-discussion-1-tuners-and-tuningspaces/</guid>
      <description><![CDATA[The Media Center TV experience driven by a flexible, multi-standard engine that works with any...]]></description>
      <content:encoded><![CDATA[<P>The Media Center TV experience driven by a flexible, multi-standard engine that works with any compatible tuner (including a good number of analog tuner cards and all <A href="http://msdn.microsoft.com/archive/default.asp?url=/archive/en-us/directx9_c/directx/htm/bdanetworkprovider.asp">BDA</A> digital tuner cards) to create portable recordings viewable on any Windows XP machine.&nbsp; To support “trick play” on Live TV (Pause, FFWD, etc.), the video engine is separated into two main segments: capture and playback.&nbsp; The capture engine, controlled through the Media Center Receiver Service (ehrecvr.exe), is responsible for creating the actual recordings, including controlling tuners, creating a media stream, and optionally encrypting the stream before writing it to disk.&nbsp; The playback engine, controlled through the Media Center Shell (ehshell.exe), processes media streams created by the capture engine and renders them for the user.&nbsp; Everything else, as far as TV goes, is built on top of or leverages these two components.</P>
<P>The capture engine uses the <A href="http://msdn.microsoft.com/archive/default.asp?url=/archive/en-us/directx9_c/directx/htm/themicrosoftunifiedtuningmodel.asp">Microsoft Unified Tuning Model</A>, with <A href="http://msdn.microsoft.com/archive/default.asp?url=/archive/en-us/directx9_c/directx/htm/ituningspaceinterface.asp">TuningSpaces</A> and <A href="http://msdn.microsoft.com/archive/default.asp?url=/archive/en-us/directx9_c/directx/htm/itunerequestinterface.asp">TuneRequests</A>, as a layer on top of the physical tuner, allowing Media Center to treat tuners agnostically.&nbsp; To actually tune to a channel, Media Center first creates (or looks up) a tune request that corresponds to that channel, then submits it to the capture engine, which uses it to tell the tuner what to do. </P>
<P>A TuningSpace corresponds to code written specifically to handle a type of video broadcast, such as ATSC, NTSC, or DVB-T.&nbsp; Some properties are present in all TuningSpaces, like its ID (e.g. {8A674B4D-1F63-11D3-B64C-00C04F79498E} for NTSC Analog Cable), and some are specific to an implementation.&nbsp; The implementation-specific properties--like NetworkType or DefaultLocator for digital standards--let the capture engine configure the underlying BDA driver, and provide a way to tweak default values.&nbsp; A TuningSpace can be considered a "template" for how Media Center will try to talk to the tuner card, depending on how you have it configured--mapping roughly to the old TV setting of "Antenna" or "Cable".</P>
<P>All by itself, a TuningSpace is not enough to actually tune to a broadcast stream.&nbsp; For that, Media Center creates a TuneRequest (by using the ITuningSpace object).&nbsp; A TuneRequest can be thought of as "everything you need to know about tuning to a channel"; what it contains varies from TuningSpace to TuningSpace. For an NTSC tune request, you could expect it to contain a channel number and a reference to the TuningSpace; an ATSC tune request would contain a physical channel (the "major" channel) and a minor channel; a DVB-T tune request would contain the broadcast frequency, ONID, TSID, and SID.&nbsp; All tune requests contain a reference back to the proper TuningSpace.</P>
<P>Media Center stores information about which TuningSpace(s) are configured on the system on a per-tuner basis in the Windows registry under the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Media Center\Service\Video\Tuners key.&nbsp; If you open this key, you'll see something like this:</P>
<P><IMG src="http://pegasi.com/MCE_TT_1_1.gif" border=0></P>
<P>The GUIDs correspond to "tuning categories", which are digital ({71985F48-1CA1-11D3-9CC8-00C04F7971E0}) and analog ({A799A800-A46D-11D0-A18C-00A02401DCD4}), each containing subkeys that correspond to individual tuner devices.&nbsp; Note that there can be more than one tuner device per physical tuner card or USB device--Media Center treats multi-tuner cards as separate devices.&nbsp; I will use my Hauppauge WinTV PVR PCI II device's entry as an example:</P>
<TABLE border=0>
<TBODY>
<TR vAlign=top>
<TD><IMG src="http://pegasi.com/MCE_TT_1_2.gif" border=0></TD>
<TD><IMG src="http://pegasi.com/MCE_TT_1_3.gif" border=0></TD></TR></TBODY></TABLE>
<P>As you can see above, the tuner's auto-generated GUID is {99F4E181-4B58-4258-8547-2CE73F3C0386}.&nbsp; This key is created by the ehrecvr service automatically when it detects the tuner: for a PCI card, this happens at service startup; for a USB device, this happens either at service startup or when you plug in the device.&nbsp; If you delete the key and restart the ehrecvr service--and the card is still installed--a key will be created with a new GUID.&nbsp; If a USB device is detached and reattached to a different port it will also get a new key.</P>
<P>Examining the properties, there are a couple of interesting values:</P>
<UL>
<LI><I>ConfiguredTuningspace </I>is a REG_MULTI_SZ that contains a list of the TuningSpace IDs for which this card has been configured in Media Center. 
<LI><I>SupportedTuningspace </I>contains a list of the TuningSpace IDs with which the tuner's driver reports compatibility.&nbsp; These lists<I> can</I> differ if the tuner supports more than one type of tuning, like some of the newer "hybrid" tuners--a card that supports both NTSC and PAL is an example of such a card.&nbsp; 
<LI><I>DevInstance</I>, <I>DevName</I>, and <I>DevPath </I>are obtained from the tuner driver, and give Media Center "pointers" to the physical device.&nbsp; If you open up Device Manager and look at the advanced properties for the matching device, you will find that the values map 1:1 to entries here. 
<LI><I>PrefEncoder</I> either points to another hardware ID (in the case of a tuner with hardware MPEG2 encoding) or a software encoder (e.g. ATI AIW cards).&nbsp; This is populated after we successfully build a capture graph for the device, and points to the MPEG2 encoder that is included in the graph at that time.</LI></UL>
<P>It's important to note that ehrecvr will create a key for every tuner device detected, whether or not it is configured in Media Center or not.&nbsp; Whether it is available for tuning in Media Center is just a matter of whether the registry keys <I>says</I> it is.&nbsp; For example, you can easily get more than 2 tuners working for scheduling, recording and Live TV viewing by editing the registry entries for the tuners to enable them.&nbsp; The reason that you cannot do this through the UI is simply because there is not a good graphical way to resolve recording/viewing conflicts amongst more than 2 tuners for a given TuningSpace.&nbsp; Instead of being able to choose which of the 4 tuners to "steal", you can only choose from 2 of them.&nbsp; However, with 4 tuners you're much less likely to actually<I> </I>need conflict resolution, so IMHO it's acceptable.</P>
<P>To actually get the n-tuner scenario working properly, every tuner must be in the same TuningSpace, and change channels the same way.&nbsp; So you cannot mix STB with non-STB, Satellite with Cable, etc. This is due to limitations in the Guide and PVR engine, not in the capture or playback engines.&nbsp; STB tuners are somewhat of a pain, so I recommend using Method 2 (below) if you are going to go with n-tuners on STBs.&nbsp; Also, you must have an STB for each and every tuner... not a fun scenario if you have to pay for each one.&nbsp; </P>
<P>This week's Media Center tweak is getting N tuners working in Media Center.&nbsp; There are various versions floating around out there on the internet, most of which include extra, unnecessary steps, likely because the authors figured out this stuff without the benefit of internal knowledge of the codebase, so they included everything they did to get it all working.&nbsp; <A href="http://www.thegreenbutton.com/community/shwmessage.aspx?ForumID=27&amp;MessageID=106105">The version of this tweak posted on The Green Button</A> works just like Method 2 below, but requires a reboot between each configuration run.</P>
<P>If you have NTSC + ATSC, you can use this method for the ATSC tuners, the NTSC tuners, or both!&nbsp; The only limitations are your hard drive's bandwidth, your system bus bandwidth, CPU time, and the number of tuners you can attach to the machine.&nbsp; For NTSC that means a practical limit of about 10 tuners, if they are all recording non-DRM content.&nbsp; For High Definition ATSC and DVB it's a little more intensive, but since there's no encoding going on (digital broadcasts are already encoded!), it actually balances out a little, with a top limit of around 7-8 tuners.&nbsp; I have personally run 3 ATSC + 6 NTSC on my home system (through dual-tuner USB devices like the Adaptec AVC-3610), and it hummed right along (1 GB DDR Dual-Channel DDR 3200 RAM, Pentium 4 2.8 GHz (HT), 2x 7200 RPM 500GB Hitachi SATA drives in RAID-0 with the system/boot drive on a 40 GB PATA drive).&nbsp; That's a bit more than I need, so I backed off to only 3 NTSC (2 USB + 1 PCI) and 2 ATSC (both PCI).</P>
<P>Step-by-step, here's how to get n-tuner going.&nbsp; Both methods assume you've already installed the tuners and have the drivers installed.&nbsp; </P>
<P><B>N Tuners in MCE, Method 1 (only registry editing):</B></P>
<OL>
<LI>Stop the Media Center Receiver Service (<TT>net stop ehrecvr</TT>) 
<LI>Open Registry Editor (<TT>regedit.exe</TT>) and open this key:<BR>HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Media Center\Service\Video\Tuners\<I>{GUID}</I><BR>where <I>{GUID}</I> is either {71985F48-1CA1-11D3-9CC8-00C04F7971E0} for Digital (ATSC or DVB-T) or {A799A800-A46D-11D0-A18C-00A02401DCD4} for Analog (NTSC or PAL). 
<LI>Under the <I>{GUID}</I> key, there will be one key per tuner device. 
<LI>Select the first tuner's key. 
<LI>Select the UserSettings key. 
<LI>Set these DWORD values as follows (case sensitive, all values in hexadecimal), creating them if they do not exist:<BR>EnabledForMCE = 0xffffffff<BR>UseSTB = 0 
<LI>Create a REG_SZ value named UserDefName and set its value to "Tuner X", where X is the tuner number (1 for the first tuner, 2 for the 2nd, etc.) 
<LI><B>If this is the FIRST tuner:</B><BR>RecordOrder = 0<BR>RecordPrefered = 0xffffffff<BR>WatchOrder = number of tuners - 1, e.g. for 4 tuners set this to 3<BR>WatchPrefered = 0<BR><BR><B>If this is the LAST tuner:</B><BR>RecordOrder = number of tuners - 1, e.g. for 4 tuners set this to 3<BR>RecordPrefered = 0<BR>WatchOrder = 0<BR>WatchPrefered = 0xffffffff<BR><BR><B>If this is a tuner somewhere in the middle:</B><BR>RecordOrder = whatever you put for the last tuner + 1<BR>RecordPrefered = 0<BR>WatchOrder = whatever you put for the last tuner - 1<BR>WatchPrefered = 0<BR><BR>The idea here is that you increment the RecordOrder by 1 for each tuner, and decrement the WatchOrder by 1.&nbsp; RecordOrder starts at 0 on the first tuner and goes up to #Tuners - 1; WatchOrder starts at #Tuners - 1 and ends at 0 on the last tuner.&nbsp; RecordPrefered is true (0xffffffff) on the first tuner, false (0x00000000) everywhere else; WatchPrefered is true on the last tuner, false everywhere else. 
<LI>Repeat steps 7 - 10 for each tuner, adjusting the values of RecordOrder, RecordPrefered, WatchOrder and WatchPrefered as appropriate. 
<LI>Close Registry Editor. 
<LI>Start Media Center. Voila!</LI></OL>
<P>Yes, "Prefered" is misspelled.&nbsp; We caught that after we shipped, and it's a little late to change now...</P>
<P><B>N Tuners in MCE Method 2 (a little registry stuff, no manual editing though):</B></P>
<OL>
<LI>Start the Media Center shell (Green Button) 
<LI>Go to Settings--&gt;TV--&gt;Set Up TV Signal 
<LI>Choose the 2 tuners from the list of tuners that you will configure this time (first time through, just the first 2) 
<LI>Close the Media Center shell. 
<LI>Stop the Media Center Receiver service (<TT>net stop ehrecvr</TT> or stop the service from Control Panel--&gt;Administrative Tools--&gt;Services) 
<LI>Open Registry Editor (<TT>regedit.exe</TT>) and open this key:<BR>HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Media Center\Service\Video\Tuners\<I>{GUID}</I><BR>where <I>{GUID}</I> is either {71985F48-1CA1-11D3-9CC8-00C04F7971E0} for Digital (ATSC or DVB-T) or {A799A800-A46D-11D0-A18C-00A02401DCD4} for Analog (NTSC or PAL). 
<LI>Under the <I>{GUID}</I> key, there will be one key per tuner device. 
<LI>Find the 2 keys that were just configured by Media Center.&nbsp; You can tell which ones they are by looking for the "EnabledForMCE" value under the UserSettings key.&nbsp; If it is set to 0xffffffff, it was configured--otherwise it will be 0x00000000 (0). 
<LI>Export the 2 keys to .reg files on your hard disk. (right-click on the {GUID} key and choose Export [selected branch only]).&nbsp; Make a note of where you save those files... you're going to need them!&nbsp; Name each one differently (e.g. Tuner1.reg, Tuner2.reg). 
<LI>Repeat steps 1 - 8 for each set of 2 tuners (if you have 3, then just then 3rd, etc.), selecting different tuners each time. 
<LI>Repeat steps 4 and 5. 
<LI>Double-click on each of the .reg files you created in step 9 to import them into the registry. 
<LI>Close Registry Editor. 
<LI>Start Media Center. Voila!</LI></OL>
<P>Next week we'll talk about the PVR engine and recording management.</P>
<P>This posting is provided AS-IS with no warranties.&nbsp; The views expressed above do not represent those of Microsoft Corporation.</P>]]></content:encoded>
    </item>
    <item>
      <title>Media Center Technical Discussion Series</title>
      <link>https://docs.microsoft.com/archive/blogs/peterrosser/media-center-technical-discussion-series</link>
      <pubDate>Mon, 03 Apr 2006 14:52:00 GMT</pubDate>
      <dc:creator><![CDATA[PeterRosser]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/peterrosser/2006/04/03/media-center-technical-discussion-series/</guid>
      <description><![CDATA[One of the more popular subjects for users who email me is how to get Media Center to do something...]]></description>
      <content:encoded><![CDATA[<P>One of the more popular subjects for users who email me is how to get Media Center to do something that cannot be done (or is hard to do) from the UI.&nbsp; Since I have not been able to talk about my current work much (Windows Vista and unannounced other stuff)&nbsp;I am kicking off a roughly weekly technical discussion on tweaking Media Center.</P>
<P>Planned discussions:</P>
<UL>
<LI><A HREF="/peterrosser/archive/2006/04/03/MCE_TechTalk_1.aspx">Tuners and Tuning Spaces </A>
<LI>PVR and Recording 
<LI>Unattended/Scripted Configuration 
<LI>Video Playback 
<LI>Writing Your Own Media Center Application</LI></UL>
<P>Want to know how to tweak something in Media Center that's not listed above?&nbsp; Let me know and I'll see if I can work it in.</P>]]></content:encoded>
    </item>
    <item>
      <title>VoodooPC's 8TB Media Center PC</title>
      <link>https://docs.microsoft.com/archive/blogs/peterrosser/voodoopcs-8tb-media-center-pc</link>
      <pubDate>Thu, 02 Mar 2006 17:51:00 GMT</pubDate>
      <dc:creator><![CDATA[PeterRosser]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/peterrosser/2006/03/02/voodoopcs-8tb-media-center-pc/</guid>
      <description><![CDATA[From Engadget:
 

When we heard that VoodooPC was planning a media PC with 16 drive bays and a...]]></description>
      <content:encoded><![CDATA[<P>From Engadget:</P>
<DIV align=center><A href="http://news.com.com/2100-1003_3-6044142.html?part=rss"><IMG alt="" hspace=4 src="http://img.engadget.com/common/images/5178632431807386.jpg?0.19406108734385585" align=absBottom vspace=4 border=0></A> </DIV>
<BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px">
<P><BR>When we heard that VoodooPC was planning a media PC with 16 drive bays and a maximum capacity of 8 terabytes... [<A href="http://www.engadget.com/2006/02/28/voodoopc-plans-8tb-media-pc/">Read full posting on Engadget</A>]</P></BLOCKQUOTE>
<P dir=ltr>Sounds pretty cool--maybe I'll get one here to "test" with ^_^.</P>]]></content:encoded>
    </item>
    <item>
      <title>Tripod sings about romantic love</title>
      <link>https://docs.microsoft.com/archive/blogs/peterrosser/tripod-sings-about-romantic-love</link>
      <pubDate>Fri, 24 Feb 2006 19:01:00 GMT</pubDate>
      <dc:creator><![CDATA[PeterRosser]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/peterrosser/2006/02/24/tripod-sings-about-romantic-love/</guid>
      <description><![CDATA[I saw this the other day... definitely worth a viewing.
WARNING: If you have a girlfriend/wife/S.O....]]></description>
      <content:encoded><![CDATA[<P>I saw this the other day... definitely worth a viewing.</P>
<P>WARNING: If you have a girlfriend/wife/S.O. and you game a lot, you might want to put on headphones or suffer facial contortions and rolling eyes.</P>
<P><A href="http://video.google.com/videoplay?docid=1329362959167995041&amp;q=tripod">http://video.google.com/videoplay?docid=1329362959167995041&amp;q=tripod</A></P>
<P>HAHAHA</P>]]></content:encoded>
    </item>
    <item>
      <title>Using exported DLL functions</title>
      <link>https://docs.microsoft.com/archive/blogs/peterrosser/using-exported-dll-functions</link>
      <pubDate>Wed, 22 Feb 2006 17:11:00 GMT</pubDate>
      <dc:creator><![CDATA[PeterRosser]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/peterrosser/2006/02/22/using-exported-dll-functions/</guid>
      <description><![CDATA[Now and then it's necessary to use "private" or "internal-only" functions in DLLs that you did not...]]></description>
      <content:encoded><![CDATA[<P>Now and then it's necessary to use "private" or "internal-only" functions in DLLs that you did not write, don't have the source for, and/or cannot get public interfaces for.&nbsp; I recently had to do this again for a utility application, so I thought it would be nice to document the process a little more clearly for others.</P>
<P>A starting assumption is that the reader is familiar with GetProcAddress() in its "main" form, which is when you know the full signature of the function you need to call.&nbsp; For example, if you have a copy of foo.dll that exports Bar(LPWSTR, DWORD*):</P><FONT color=#008000 size=2>
<P><FONT face="Courier New">// library function is: Bar(LPWSTR lpParam, DWORD *pdwParam)<BR></FONT></FONT><FONT face="Courier New"><FONT color=#0000ff size=2>typedef</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>void</FONT><FONT size=2> (</FONT><FONT color=#0000ff size=2>__stdcall</FONT></FONT><FONT face="Courier New"><FONT size=2> *BAR_PROC)(LPWSTR, DWORD*);<BR><BR>HANDLE hFoo = LoadLibrary(</FONT><FONT color=#800000 size=2>"foo.dll"</FONT></FONT><FONT face="Courier New"><FONT size=2>);<BR>BAR_PROC proc = (BAR_PROC)GetProcAddress(hFoo, </FONT><FONT color=#800000 size=2>"Bar"</FONT></FONT><FONT face="Courier New" size=2>);<BR><BR></FONT><FONT face="Courier New" color=#008000 size=2>// call the library function<BR></FONT><FONT face="Courier New"><FONT size=2>DWORD dwParam = 0x4;<BR>(proc)(L</FONT><FONT color=#800000 size=2>"string"</FONT><FONT size=2>, &amp;dwParam);</P></FONT></FONT>
<P>But what if you need to access a function that is not included in the named exports of the library?&nbsp; 90% of the time the functions will be exported with a name, but sometimes not, and for various reasons.&nbsp; The most common reason is for "security through obscurity", because using the function is supposed to be something that you, the user, "should never have to do".&nbsp; Unfortunately, there are scenarios when you need to do just that, for reasons the original publisher never considered, such as if you need to tweak the way something behaves in your mission-critical server process, and the company that made the original custom component has gone out of business.</P>
<P>Enter the "ordinal" function access method.&nbsp; If you look at the MSDN docs, they even allude to using a function's ordinal with GetProcAddress, but it's a bit of a mystery how to a) get the ordinal, and b) how to use it even if you get it.&nbsp; Once you know the ordinal and prototype of a function, it's simple to use it--getting the function prototypes is the fun part.</P>
<P>Say you got your hands on a .DEF file that lists the function ordinals, or have used link.exe and&nbsp;through sufficiently wizardly use of a hex editor have examined the [NONAME] functions and determined what their prototypes are.&nbsp; Let's pretend that the Bar function above was actually a [NONAME] function, and you got a listing like this from link.exe /dump /exports foo.dll:</P><PRE>Microsoft (R) COFF/PE Dumper Version 7.10.4035 
Copyright (C) Microsoft Corporation. All rights reserved. 


Dump of file c:\myprojects\foo.dll 

File Type: DLL

  Section contains the following exports for foo.dll

    00000000 characteristics 
    41107692 time date stamp Tue Aug 03 22:39:30 2005 
        0.00 version 
           1 ordinal base 
           6 number of functions 
           4 number of names 

    ordinal hint RVA      name 
          3    0 00006948 Connect 
          4    1 00007798 Close 
          5    2 00012000 GetFoo 
          6    3 00014D12 SetFoo 
          1      0000F3A0 [NONAME] 
          2      0000D20A [NONAME]

  Summary

        6000 .data
        2000 .reloc
        9000 .rsrc
       18000 .text
</PRE>
<P>The depends.exe tool provides similar data in a GUI fashion.&nbsp;You can examine the binary at offsets F3A0 and D20A to determine what the function signature is (well, what the base pointer sig is), and match them up to the expected signature of Bar(LPWSTR, DWORD*) manually to get the proper ordinal.&nbsp; Or more easily, if you know that one of the methods is the droid you are looking for, you can just code up a quick test app and poke at the method as if it were the one you wanted.&nbsp; If it works without throwing an exception... ;-)</P>
<P>Getting back to the main point, to load the exported-by-ordinal function, there's a handy macro pre-defined in the Visual Studio (v6 or later, IIRC) build environment&nbsp;that can package up that ordinal into the "expected" LPSTR for GetProcAddress.&nbsp; In my example, assuming Bar was actually at ordinal 1, you would do this:</P><FONT color=#008000 size=2>
<P><FONT face="Courier New">// library function is: Bar(LPWSTR lpParam, DWORD *pdwParam)<BR></FONT></FONT><FONT face="Courier New"><FONT color=#0000ff size=2>typedef</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>void</FONT><FONT size=2> (</FONT><FONT color=#0000ff size=2>__stdcall</FONT></FONT><FONT face="Courier New"><FONT size=2> *BAR_PROC)(LPWSTR, DWORD*);<BR><BR>HANDLE hFoo = LoadLibrary(</FONT><FONT color=#800000 size=2>"foo.dll"</FONT></FONT><FONT face="Courier New" size=2>);<BR>BAR_PROC proc = (BAR_PROC)GetProcAddress(hFoo, MAKEINTRESOURCEA(1));<BR><BR></FONT><FONT face="Courier New" color=#008000 size=2>// call the library function<BR></FONT><FONT face="Courier New"><FONT size=2>DWORD dwParam = 0x4;<BR>(proc)(L</FONT><FONT color=#800000 size=2>"string"</FONT><FONT size=2>, &amp;dwParam);</P></FONT></FONT>
<P>The only difference is that you use the MAKEINTRESOURCEA macro to convert that ordinal into something that GetProcAddress can understand, rather than the string name of the function.</P>
<P>If you really want to get tricky, you don't actually need GetProcAddress at all to do this magic.&nbsp; If you can guarantee that the DLL won't change underneath you, or you don't mind breaking if it does, or you have smart scanning code that can "find" the offsets again, you can plug the RVA directly into the FARPROC variable.&nbsp; It's all just numbers under the hood, after all.&nbsp; Using the example output of link.exe from above, you can do this:</P><FONT color=#008000 size=2>
<P><FONT face="Courier New">// library function is: Bar(LPWSTR lpParam, DWORD *pdwParam)<BR></FONT></FONT><FONT face="Courier New"><FONT color=#0000ff size=2>typedef</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>void</FONT><FONT size=2> (</FONT><FONT color=#0000ff size=2>__stdcall</FONT></FONT><FONT face="Courier New"><FONT size=2> *BAR_PROC)(LPWSTR, DWORD*);<BR><FONT color=#0000ff>#define</FONT><FONT color=#000000> PROC_OFFSET 0x0000F3A0<BR><BR></FONT>HANDLE hFoo = LoadLibrary(</FONT><FONT color=#800000 size=2>"foo.dll"</FONT></FONT><FONT face="Courier New"><FONT size=2>);<BR>BAR_PROC proc = (BAR_PROC)(hFoo + PROC_OFFSET)</FONT></FONT><FONT face="Courier New" size=2>;<BR><BR></FONT><FONT face="Courier New" color=#008000 size=2>// call the library function<BR></FONT><FONT face="Courier New"><FONT size=2>DWORD dwParam = 0x4;<BR>(proc)(L</FONT><FONT color=#800000 size=2>"string"</FONT><FONT size=2>, &amp;dwParam);</P></FONT></FONT>
<P>Why does this work?&nbsp; LoadLibrary(dll) loads the specified library into the process' address space, and returns a HANDLE value.&nbsp; This HANDLE is the starting address of the library, and since the RVA values for a DLL are offsets from the starting address, you can perform simple addition to the base to get a function's entry point.&nbsp; Pretty cool, huh?&nbsp; All GetProcAddress does is read the DLL's export table into a struct and performs the math for you, returning the result.&nbsp; I'm a big fan of not reinventing the wheel, so I use GetProcAddress when there's an exports entry for what I need.</P>
<P>What do you do if the function you need is not exported at all?&nbsp; Nine times out of ten it's much easier to just get it exported, but if that's not possible, well, that's a topic for another day.</P>]]></content:encoded>
    </item>
    <item>
      <title>Captioning Support Sucks</title>
      <link>https://docs.microsoft.com/archive/blogs/peterrosser/captioning-support-sucks</link>
      <pubDate>Sun, 19 Feb 2006 04:42:00 GMT</pubDate>
      <dc:creator><![CDATA[PeterRosser]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/peterrosser/2006/02/19/captioning-support-sucks/</guid>
      <description><![CDATA[Looking back at the&nbsp;bugs&nbsp;we've fixed over the last several months,&nbsp;we certainly...]]></description>
      <content:encoded><![CDATA[<P>Looking back at the&nbsp;bugs&nbsp;we've fixed over the last several months,&nbsp;we certainly have&nbsp;had a good share of captioning issues, especially with regards to the&nbsp;size of the codebase&nbsp;compared to &nbsp;the "video" code.&nbsp; Surprisingly, we don't hear from users a ton when captions don't work properly, but maybe that's because a minority of the users actually use them in the first place.</P>
<P>I'm not usually so negative, but I'm just annoyed at captioning today.&nbsp; The following is&nbsp;a poorly thought-out rant on the subject.</P>
<P><EM>[donning my asbestos underwear]</EM></P>
<P>I happen to be one of those users, so it drives me up the wall seeing poor-quality captions, time-delay issues, and glitchy behavior.&nbsp; In the U.S. it isn't so bad, but that is mainly because the only thing available here is dumb-as-a-rock Closed Captioning over VBI.&nbsp; In PAL countries they have Teletext, which tried to learn from the limitations of CC, and DVB goes even farther with MHEG support and all sorts of other interactive goodies.&nbsp; Not that we support those (yet), but they're there.&nbsp; Even with our CC support, though, the results are not what I would consider stellar.&nbsp; Whether the fault lies in poor VBI support at the tuner card, our VBI capture filter, or the CC decode itself, the end result is often missing or incorrect characters, bad timing, and the decades-old CC text look-and-feel.</P>
<P>I suffer from a mild hearing impairment that makes it a little more difficult for me to pick out conversations against background noise than the average Joe, so I turn captions on pretty often.&nbsp; The experience is not good on any&nbsp;American TV, ATSC or NTSC, only marginally better on European sets, and worse in Media Center.&nbsp; I admit I have not tested out TiVO or other PC-based systems to see if their support is any better (if you have, let me know how it goes for you).&nbsp; Mainly it's a low-level nuisance to parse words around the junk that crops up on the screen, and the "white text on a black/gray bar" color scheme with fixed font sizes is so 1970s.&nbsp; Come on!&nbsp; It's the 21st century... can't we do better than <SPAN style="FONT-FAMILY: Lucida Sans,fixed">Lucida Sans</SPAN> fixed-width fonts?&nbsp; The DVD implementation, in contrast, is fantastic in most cases, with bigger, clearer captions and no noise/dropped words (yes, it's because it's a low-loss streaming medium, not like TV, but still).</P>
<P>Lest I put too much blame on the software or hardware on the user side of things, I also want to point out that broadcasters and content producers are&nbsp;often shoddy&nbsp;in their support of captioning features on their shows and networks.&nbsp; You'd think they want to get the captions in as close to perfect shape as possible, but between dialog inconsistencies (perhaps they used a pre-release script to make the captions?) and transmission problems, it's too often that captions come out unusable or barely usable.&nbsp; I count my blessings that most times I do not have to depend on the captions alone to track the storyline or news story.&nbsp; Maybe the hearing-impaired market isn't big enough to justify spending more resources on the problem to the boards of directors.</P>
<P>I wonder if I am a member of a small group of people that use these features and find them annoying.&nbsp; Almost deal breakers, in my case, if I didn't love the rest of it.&nbsp; Well, not almost, but damn it, I'm annoyed.&nbsp; Nobody seems to get this stuff right, and it <EM>almost</EM> seems like the folks implementing decoders and renderers nowadays put in captioning support as a legally-required afterthought.&nbsp; TVs do it poorly, we do it poorly, everybody does it poorly.&nbsp; If it's just me, I'll shut up.</P>]]></content:encoded>
    </item>
    <item>
      <title>DVB Guide issues - "cannot schedule recoding because guide data cannot be accessed"</title>
      <link>https://docs.microsoft.com/archive/blogs/peterrosser/dvb-guide-issues-cannot-schedule-recoding-because-guide-data-cannot-be-accessed</link>
      <pubDate>Thu, 16 Feb 2006 02:27:00 GMT</pubDate>
      <dc:creator><![CDATA[PeterRosser]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/peterrosser/2006/02/16/dvb-guide-issues-cannot-schedule-recoding-because-guide-data-cannot-be-accessed/</guid>
      <description><![CDATA[We have been getting reports about Guide problems&nbsp;from DVB users across&nbsp;Europe and the...]]></description>
      <content:encoded><![CDATA[<P>We have been getting reports about Guide problems&nbsp;from DVB users across&nbsp;Europe and the world, hopefully in time for the next Rollup release (external date not yet announced, but should be late Q1 to early Q2).&nbsp; The problem typically manifests itself when scheduling many shows to record, but can occur anytime.&nbsp; Without a code fix, you cannot work around the issue cleanly/easily, but closing the shell (Media Center UI) and restarting the "Media Center Scheduler Service" (ehsched) will reset the state of the machine.</P>
<P><EM>Edit: This is the "cannot schedule recording because guide data can't be accessed" issue.</EM></P>
<P>We root-caused the problem to an unusual memory management problem in how we deal with the Guide data.&nbsp; For performance reasons, we temporarily increase certain buffer sizes during a Guide download, and decrease them again later.&nbsp; There is a timing issue with garbage collection events in some situations, though, that can cause the decrease to not take effect "in time", thus keeping the buffer sizes large.&nbsp; This does not actually reduce the amount of real memory used, but it does exhaust the virtual address space eventually.&nbsp; You can observe the behavior using <A href="http://www.sysinternals.com/Utilities/ProcessExplorer.html">SysInternals' Process Explorer</A> by adding the "Virtual Size" column (under the Process Performance tab) and observing its value for ehrec.exe.</P>
<P>With better knowledge of the cause, though, comes a better workaround than "gun ehshell.exe and restart ehsched when it happens".&nbsp; Until the fix comes out, the best thing to do to <EM>prevent</EM> this problem from occurring is probably to set up a Scheduled Task to do those things for you at a predictable time.&nbsp;To wit:</P>
<OL>
<LI>Download recycle_mce.cmd from&nbsp;<A href="http://pegasi.com/recycle_mce.zip">here</A>.&nbsp;(script to recycle ehshell.exe and TV services).&nbsp; Unpack the script somewhere on your drive. 
<LI>Change your Guide download time to a time that you are not likely to have a need to either watch TV on your MCE or record a show.&nbsp; 4am is pretty safe for me, but to each his own.&nbsp; I wrote a tool that lets you edit this time easily, you can <A href="http://www.pegasi.com/MceDlTimeEditor_0.1.zip">download it from my site</A>. 
<LI>Create a Scheduled Task to run the script daily about 30 minutes after the time you configured the Guide to download.&nbsp; If you have a modem, you may need to give it more time.&nbsp; If you have a pretty fast computer and broadband, 30 minutes is very generous. <A href="http://www.uwec.edu/help/WinXP/scheduledtasks.htm">Guide to creating scheduled tasks</A>.</LI></OL>
<P>It's not a perfect solution, since a) it presumes you have a time during the day you will not make recordings or watch TV, and b) it cannot prevent the problem 100%, especially if you are a "heavy" user.&nbsp; If you run into the problem, though, running recycle_mce.cmd will at least reset your state.</P>
<P>The real fix is coming with the next rollup, but since there are users out there feeling pain <EM>now</EM>, I thought I'd try to help a little.</P>
<P><STRONG>The programs, scripts, and instructions in this posting are provided AS-IS, with no warranties, and are not sanctioned nor released by Microsoft.</STRONG></P>]]></content:encoded>
    </item>
  </channel>
</rss>