<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
   <channel>
      <title>UrlBlogGrey</title>
      <link>http://urlgrey.net/</link>
      <description></description>
      <language>en</language>
      <copyright>Copyright 2010</copyright>
      <lastBuildDate>Wed, 16 Jun 2010 13:46:29 -0800</lastBuildDate>
      <generator>http://www.sixapart.com/movabletype/?v=3.31</generator>
      <docs>http://blogs.law.harvard.edu/tech/rss</docs> 

            <item>
         <title>Evaluating Apache HTTPD Environment Variables in an Internal Redirect</title>
         <description><![CDATA[I recently needed to modify an Apache HTTPD module I wrote so that the module set a request-scoped environment variable that would be evaluated by some mod_rewrite rules invoked during an internal redirect.  The C source of my module contained the following function calls:
<p>

<pre class="mtc_block"><span class="c_Symbol def_Symbol">.</span><span class="c_Symbol def_Symbol">.</span><span class="c_Symbol def_Symbol">.</span>
        LOG<span class="c_Symbol def_Symbol"><span class="def_PairStart def_Special">(</span></span>LOG_DEBUG<span class="c_Symbol def_Symbol">,</span> <span class="c_String def_String">&quot;Internal Redirect starting: uri (<span class="c_StringEscape def_StringContent def_String">%s</span>)&quot;</span><span class="c_Symbol def_Symbol">,</span> filepath<span class="c_Symbol def_Symbol"><span class="def_PairEnd def_Special">)</span></span><span class="c_StructureSymbol def_SymbolStrong def_Symbol">;</span>
        apr_table_set<span class="c_Symbol def_Symbol"><span class="def_PairStart def_Special">(</span></span>r<span class="c_Symbol def_Symbol">-</span><span class="c_Symbol def_Symbol">&gt;</span>subprocess_env<span class="c_Symbol def_Symbol">,</span> <span class="c_String def_String">&quot;IS_PROCESSED&quot;</span><span class="c_Symbol def_Symbol">,</span> <span class="c_String def_String">&quot;true&quot;</span><span class="c_Symbol def_Symbol"><span class="def_PairEnd def_Special">)</span></span><span class="c_StructureSymbol def_SymbolStrong def_Symbol">;</span>
        ap_internal_redirect<span class="c_Symbol def_Symbol"><span class="def_PairStart def_Special">(</span></span>filepath<span class="c_Symbol def_Symbol">,</span> r<span class="c_Symbol def_Symbol"><span class="def_PairEnd def_Special">)</span></span><span class="c_StructureSymbol def_SymbolStrong def_Symbol">;</span>
        LOG<span class="c_Symbol def_Symbol"><span class="def_PairStart def_Special">(</span></span>LOG_DEBUG<span class="c_Symbol def_Symbol">,</span> <span class="c_String def_String">&quot;Internal Redirect finished: uri (<span class="c_StringEscape def_StringContent def_String">%s</span>)&quot;</span><span class="c_Symbol def_Symbol">,</span> filepath<span class="c_Symbol def_Symbol"><span class="def_PairEnd def_Special">)</span></span><span class="c_StructureSymbol def_SymbolStrong def_Symbol">;</span>
<span class="c_Symbol def_Symbol">.</span><span class="c_Symbol def_Symbol">.</span><span class="c_Symbol def_Symbol">.</span></pre>
<p>

The apr_table_set function call sets an environment variable named 'IS _PROCESSED' to the value 'true'.  Seems simple, right?  I had some mod_rewrite rules that looked for an environment variable named 'IS_PROCESSED' to direct the handling of the request:
<p>

<pre class="mtc_block"><span class="def_Syntax">RewriteCond </span><span class="def_Symbol">%</span><span class="def_Symbol">{</span>ENV<span class="def_Symbol">:</span><span class="def_Syntax">IS</span><span class="def_Symbol">_</span><span class="def_Syntax">PROCESSED</span><span class="def_Symbol">}</span> true
<span class="def_Syntax">RewriteRule </span><span class="def_Symbol">.</span><span class="def_Symbol">.</span><span class="def_Symbol">.</span><span class="def_Symbol">.</span></pre>
<p>

The mod_rewrite <a href="http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html#rewritecond">documentation</a> states that environment variables can be accessed using an ENV prefix:
<p>

<ul>
"%{ENV:variable}, where variable can be any environment variable, is also available. This is looked-up via internal Apache structures and (if not found there) via getenv() from the Apache server process."
</ul>

<p>
Unfortunately, there are some details that are omitted from the documentation; the RewriteCond directive above will not work.  When calling the ap_internal_redirect function, all of the environment variables currently associated with the request are renamed (<a href="http://www.google.com/codesearch/p?hl=en#cM_OVOKybvs/httpd/httpd-2.2.4.tar.bz2|W6G7kfsfmHo/httpd-2.2.4/modules/http/http_request.c&q=rename_original_env&l=299">see http_request.c</a>) to use the prefix "REDIRECT_".  I imagine this is intended to distinguish the pre-redirect and post-redirect environment variables.  It would be nice if this were documented some place.
<p>

So, the mod_rewrite directives ended up looking like:
<p>

<pre class="mtc_block"><span class="def_Syntax">RewriteCond </span><span class="def_Symbol">%</span><span class="def_Symbol">{</span>ENV<span class="def_Symbol">:</span><span class="def_Syntax">REDIRECT</span><span class="def_Symbol">_</span><span class="def_Syntax">IS</span><span class="def_Symbol">_</span><span class="def_Syntax">PROCESSED</span><span class="def_Symbol">}</span> true
<span class="def_Syntax">RewriteRule </span><span class="def_Symbol">.</span><span class="def_Symbol">.</span><span class="def_Symbol">.</span></pre>
<p>

This is another example of how the Apache HTTPD Server is incredibly flexible, but surprisingly lacking in the way of documentation and consistency.]]></description>
         <link>http://urlgrey.net/archives/2010/06/evaulating_apac.php</link>
         <guid>http://urlgrey.net/archives/2010/06/evaulating_apac.php</guid>
         <category>Computing</category>
         <pubDate>Wed, 16 Jun 2010 13:46:29 -0800</pubDate>
      </item>
            <item>
         <title>Playing MythTV DVR Recordings on the iPad &amp; iPod Touch with MythPodcaster</title>
         <description><![CDATA[<p>I've made a demonstration video showing how easy it is to configure program subscriptions for <a href="http://code.google.com/p/mythpodcaster/">MythPodcaster</a>.  The Web-based configuration is very straightfoward, and the generated <a href="http://en.wikipedia.org/wiki/RSS">RSS</a> feeds containing links to the transcoded videos can be viewed in any RSS reader.  The feeds display very nicely in Apple's Mobile Safari RSS reader.  The RSS feeds from MythPodcaster can bridge <a href="http://www.mythtv.org/">MythTV</a> with any RSS compatible client, such as the <a href="http://www.boxee.tv/">Boxee media player</a>.  I might add a Boxee demo at a later date.</p>

<p>In the meantime, here's a demo showing iPad and iPod Touch playback of <a href="http://en.wikipedia.org/wiki/ATSC_(standards)">ATSC</a> over-the-air broadcasts that were recorded with MythTV and transcoded using MythPodcaster.</p>

<p><object width="640" height="385"><param name="movie" value="http://www.youtube.com/v/2vDTMtMy4Pc&hl=en_US&fs=1&rel=0&color1=0x2b405b&color2=0x6b8ab6"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/2vDTMtMy4Pc&hl=en_US&fs=1&rel=0&color1=0x2b405b&color2=0x6b8ab6" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="385"></embed></object></p>]]></description>
         <link>http://urlgrey.net/archives/2010/06/playing_mythtv.php</link>
         <guid>http://urlgrey.net/archives/2010/06/playing_mythtv.php</guid>
         <category>MythTV</category>
         <pubDate>Fri, 11 Jun 2010 07:40:19 -0800</pubDate>
      </item>
            <item>
         <title>Open-Source Segmenter for Apple HTTP Live Streaming</title>
         <description><![CDATA[<p>I've been working a lot with Apple's HTTP Live Streaming specification that defines how audio & video are streamed to Apple's mobile devices (e.g. iPhone, iPod Touch, iPad).  There's an <a href="http://svn.assembla.com/svn/legend/segmenter/">open-source segmenter</a> circulating on the Internet.  The segmenter uses <a href="http://www.ffmpeg.org/">FFMpeg</a> to process an MPEG transport-stream into segments of a fixed duration.  The most widely duration is 10 seconds.  The transport-stream segments are pulled together through an M3U8 playlist that is passed to the QuickTime player on the device.  QuickTime will retrieve and play the segments in the appropriate order.  I've provided support for the segmenter in my <a href="http://code.google.com/p/mythpodcaster/">MythPodcaster</a> project that transcodes MythTV recordings.</p>

<p>There are some quirks to the open-source segmenter.  First, it doesn't support the segmenting of audio-only input files (i.e. an AAC or MP3 input file).  Second, the durations of the transport-stream segments that are reported in the M3U8 playlist are often incorrect.  The small duration deviations accumulate when applied to a clip that is 30 minutes or more in total duration.</p>

<p>I've made some improvements to the open-source segmenter to address the issues stated earlier.  The complete patched source file can be accessed <a href="http://urlgrey.net/drop/segmenter-accurate_durations.c">here</a>.  Many thanks go to Chase Douglas (original author of the segmenter) and Carson McDonald (made the segmenter popular).</p>

<p>The unified diff of the segmenter source file is shown below:</p>

<p><code><br />
--- segmenter.c	2010-05-18 09:51:57.932132172 -0700<br />
+++ segmenter-accurate_durations.c	2010-05-18 09:50:19.765611032 -0700<br />
@@ -20,6 +20,8 @@<br />
 <br />
 #include "libavformat/avformat.h"<br />
 <br />
+#define MAX_TS_FILES_DEFAULT 1000<br />
+<br />
 static AVStream *add_output_stream(AVFormatContext *output_format_context, AVStream *input_stream) {<br />
     AVCodecContext *input_codec_context;<br />
     AVCodecContext *output_codec_context;<br />
@@ -79,7 +81,7 @@<br />
     return output_stream;<br />
 }<br />
 <br />
-int write_index_file(const char index[], const char tmp_index[], const unsigned int segment_duration, const char output_prefix[], const char http_prefix[], const unsigned int first_segment, const unsigned int last_segment, const int end, const int window) {<br />
+int write_index_file(const char index[], const char tmp_index[], const unsigned int segment_duration, const char output_prefix[], const char http_prefix[], const unsigned int first_segment, const unsigned int last_segment, const int end, const int window, const unsigned int actual_segment_durations[]) {<br />
     FILE *index_fp;<br />
     char *write_buf;<br />
     unsigned int i;<br />
@@ -111,7 +113,7 @@<br />
     }<br />
 <br />
     for (i = first_segment; i <= last_segment; i++) {<br />
-        snprintf(write_buf, 1024, "#EXTINF:%u,\n%s%s-%u.ts\n", segment_duration, http_prefix, output_prefix, i);<br />
+      snprintf(write_buf, 1024, "#EXTINF:%u,\n%s%s-%u.ts\n", actual_segment_durations[i-1], http_prefix, output_prefix, i);<br />
         if (fwrite(write_buf, strlen(write_buf), 1, index_fp) != 1) {<br />
             fprintf(stderr, "Could not write to m3u8 index file, will not continue writing to index file\n");<br />
             free(write_buf);<br />
@@ -194,6 +196,8 @@<br />
             fprintf(stderr, "Maximum number of ts files (%s) invalid\n", argv[6]);<br />
             exit(1);<br />
         }<br />
+    } else {<br />
+      max_tsfiles = MAX_TS_FILES_DEFAULT;<br />
     }<br />
 <br />
     remove_filename = malloc(sizeof(char) * (strlen(output_prefix) + 15));<br />
@@ -280,13 +284,15 @@<br />
 <br />
     dump_format(oc, 0, output_prefix, 1);<br />
 <br />
-    codec = avcodec_find_decoder(video_st->codec->codec_id);<br />
-    if (!codec) {<br />
+    if (video_index >=0) {<br />
+      codec = avcodec_find_decoder(video_st->codec->codec_id);<br />
+      if (!codec) {<br />
         fprintf(stderr, "Could not find video decoder, key frames will not be honored\n");<br />
-    }<br />
+      }<br />
 <br />
-    if (avcodec_open(video_st->codec, codec) < 0) {<br />
+      if (avcodec_open(video_st->codec, codec) < 0) {<br />
         fprintf(stderr, "Could not open video decoder, key frames will not be honored\n");<br />
+      }<br />
     }<br />
 <br />
     snprintf(output_filename, strlen(output_prefix) + 15, "%s-%u.ts", output_prefix, output_index++);<br />
@@ -300,9 +306,11 @@<br />
         exit(1);<br />
     }<br />
 <br />
-    write_index = !write_index_file(index, tmp_index, segment_duration, output_prefix, http_prefix, first_segment, last_segment, 0, max_tsfiles);<br />
+    unsigned int *actual_segment_durations = malloc(sizeof(unsigned int) * MAX_TS_FILES_DEFAULT);<br />
+    write_index = !write_index_file(index, tmp_index, segment_duration, output_prefix, http_prefix, first_segment, last_segment, 0, max_tsfiles, actual_segment_durations);<br />
 <br />
     do {<br />
+	unsigned int current_segment_duration;<br />
         double segment_time;<br />
         AVPacket packet;<br />
 <br />
@@ -327,6 +335,8 @@<br />
             segment_time = prev_segment_time;<br />
         }<br />
 <br />
+	current_segment_duration = (int) round(segment_time - prev_segment_time);<br />
+	actual_segment_durations[last_segment] = (current_segment_duration > 0 ? current_segment_duration: 1);<br />
         if (segment_time - prev_segment_time >= segment_duration) {<br />
             put_flush_packet(oc->pb);<br />
             url_fclose(oc->pb);<br />
@@ -340,7 +350,7 @@<br />
             }<br />
 <br />
             if (write_index) {<br />
-                write_index = !write_index_file(index, tmp_index, segment_duration, output_prefix, http_prefix, first_segment, ++last_segment, 0, max_tsfiles);<br />
+	      write_index = !write_index_file(index, tmp_index, segment_duration, output_prefix, http_prefix, first_segment, ++last_segment, 0, max_tsfiles, actual_segment_durations);<br />
             }<br />
 <br />
             if (remove_file) {<br />
@@ -372,7 +382,9 @@<br />
 <br />
     av_write_trailer(oc);<br />
 <br />
-    avcodec_close(video_st->codec);<br />
+    if (video_index >= 0) {<br />
+      avcodec_close(video_st->codec);<br />
+    }<br />
 <br />
     for(i = 0; i < oc->nb_streams; i++) {<br />
         av_freep(&oc->streams[i]->codec);<br />
@@ -391,7 +403,7 @@<br />
     }<br />
 <br />
     if (write_index) {<br />
-        write_index_file(index, tmp_index, segment_duration, output_prefix, http_prefix, first_segment, ++last_segment, 1, max_tsfiles);<br />
+      write_index_file(index, tmp_index, segment_duration, output_prefix, http_prefix, first_segment, ++last_segment, 1, max_tsfiles, actual_segment_durations);<br />
     }<br />
 <br />
     if (remove_file) {<br />
@@ -399,6 +411,8 @@<br />
         remove(remove_filename);<br />
     }<br />
 <br />
+    free(actual_segment_durations);<br />
+<br />
     return 0;<br />
 }<br />
 <br />
</code></p>]]></description>
         <link>http://urlgrey.net/archives/2010/05/opensource_segm.php</link>
         <guid>http://urlgrey.net/archives/2010/05/opensource_segm.php</guid>
         <category>MythTV</category>
         <pubDate>Thu, 20 May 2010 20:26:22 -0800</pubDate>
      </item>
            <item>
         <title>MTU Settings for Comcast High-Speed Internet</title>
         <description><![CDATA[<p>I've subscribed to Comcast's High-Speed Cable Internet service for several years.  In the last year I've seen a lot of problems with my connection when performing large uploads.  This includes uploading photos to photo-sharing sites and streaming audio and video from home to my mobile devices.  The behavior I encountered was that the uploads would work for a short period (i.e. 10 seconds) and then the Motorola SBV5220 broadband VOIP modem would reset.  Considering that the modem provides our Internet <i>and</i> home phone service, it was highly disruptive to have the modem reset.</p>

<p>I had assumed that the resets were triggered by Comcast deliberately as a way of discouraging their users from generating upstream traffic (i.e. file sharing).  It suffices to say that calling Comcast technical support was less than helpful.</p>

<p>I accessed the diagnostics page for my Motorola modem (http://192.168.100.1/) to see if any useful information might be gleaned.  It appeared that everything was normal:</p>

<blockquote>
Downstream  	Value
Frequency 	717000000 Hz 
Signal to Noise Ratio 	36 dB 
Downstream Modulation 	QAM256
Network Access Control Object 	ON
Power Level 	2 dBmV  

<p>Upstream 	Value<br />
Channel ID 	1<br />
Frequency 	30600000 Hz<br />
Ranging Service ID 	2379<br />
Symbol Rate 	5.120 Msym/s<br />
Power Level 	46 dBmV<br />
Upstream Modulation 	[3] QPSK<br />
[3] 64QAM</p>

<p>Signal Stats 	Value<br />
Total Unerrored Codewords 	2619232444<br />
Total Correctable Codewords 	6<br />
Total Uncorrectable Codewords 	0<br />
</blockquote></p>

<p>I then began to tinker with the Maximum Transmission Unit (MTU) setting on my wireless router.  I have always left this configuration setting to "Auto", which usually results in an MTU value of 1500 bytes.  Lo and behold, adjusting the MTU to a lower value has resulted in a <b>significantly</b> more stable connection.  I am currently using an MTU value of 1300 bytes, which is fairly low.  I tested the stability of my connection with some of broadband speed test websites, such as <a href="http://www.speedtest.net/">SpeedTest.Net</a>.</p>

<p>The MTU value specifies the maximum packet size that the router will transmit.  When a router receives a packet that exceeds the MTU, it must either fragment the packet into 2 or more smaller packets that meet the MTU requirements, or it must respond to the sender of the large packet with a message indicating that the packet was too large.  Using a low MTU value can lead to more packets which results in more communication overhead.  For this reason I might increase the MTU in the future.  But in my experience, a lower MTU value on my Comcast connection has led to a greater stability which is definitely preferred.</p>]]></description>
         <link>http://urlgrey.net/archives/2010/05/mtu_settings_fo.php</link>
         <guid>http://urlgrey.net/archives/2010/05/mtu_settings_fo.php</guid>
         <category>Computing</category>
         <pubDate>Wed, 12 May 2010 12:09:52 -0800</pubDate>
      </item>
            <item>
         <title>Apple HTTP Live Streaming of MythTV Recordings</title>
         <description><![CDATA[<p>A little over a month ago I added support for <a href="http://devworld.apple.com/iphone/library/documentation/NetworkingInternet/Conceptual/StreamingMediaGuide/Introduction/Introduction.html">Apple HTTP Live Streaming</a> to the <a href="http://code.google.com/p/mythpodcaster/">MythPodcaster</a> project.  MythPodcaster supports multiple output encodings for a single MythTV DVR recording, so it's possible to create multiple encodings targeted at different bitrates (i.e. low, medium, high) and use the Apple iPod/iPhone/iPad to automatically adapt to network conditions when streaming audio or video.  This is a great feature that Apple included in the HTTP Live Streaming <a href="http://tools.ietf.org/html/draft-pantos-http-live-streaming-02">specification</a>.  The device accesses the media through a master M3U8 playlist that enumerates all of the encodings for a given clip (i.e. low, medium, high) and the bitrates that each encoding requires.  The device then identifies which encoding is best suited for current network conditions and automatically shifts the quality up and down as network conditions change.</p>

<p>I've used the Open-Source <a href="http://www.ioncannon.net/programming/452/iphone-http-streaming-with-ffmpeg-and-an-open-source-segmenter/">FFMPEG-based segmenter</a> to produce segmented encodings in the MythPodcaster project.  I made some <a href="http://www.ioncannon.net/programming/452/iphone-http-streaming-with-ffmpeg-and-an-open-source-segmenter/comment-page-2/#comment-166454">minor changes</a> to the segmenter so that it can segment audio-only input files.</p>

<p>What all of this means is that I can have audio and video encodings at various bitrates for all of my DVR recordings and play them on demand with a quality level that is appropriate for the network conditions (high for WiFi access, medium or low for 3G).  The current state of wireless and mobile video technology is truly amazing!</p>]]></description>
         <link>http://urlgrey.net/archives/2010/04/apple_http_live.php</link>
         <guid>http://urlgrey.net/archives/2010/04/apple_http_live.php</guid>
         <category>MythTV</category>
         <pubDate>Mon, 05 Apr 2010 12:17:45 -0800</pubDate>
      </item>
            <item>
         <title>Updated MythPodcaster Release</title>
         <description><![CDATA[<p>Updated MythPodcaster release to address a bug that caused transcoded clips to not be deleted when zero recordings of the programs exist in the recordings database table.</p>

<p>Download the updated build from the <a href="http://code.google.com/p/mythpodcaster/">MythPodcaster</a> site.</p>]]></description>
         <link>http://urlgrey.net/archives/2009/10/updated_mythpod.php</link>
         <guid>http://urlgrey.net/archives/2009/10/updated_mythpod.php</guid>
         <category>MythTV</category>
         <pubDate>Tue, 27 Oct 2009 14:11:55 -0800</pubDate>
      </item>
            <item>
         <title>First Release of MythPodcaster</title>
         <description><![CDATA[<p>Today I released the first build of MythPodcaster, which is an application I wrote to automatically generate Podcasts (a.k.a. RSS Feeds) from MythTV recordings.  With MythPodcaster running on my <a href="http://www.mythtv.org/">MythTV</a> DVR, I can have new episodes of my favorite programs retrieved automatically by iTunes running on my desktop computer.  I can view the video clips directly on my desktop, or I can have them automatically transferred to my iPod for viewing anywhere.  Or, with the RSS reader available on the iPod Touch and iPhone, I can stream the recordings directly from my MythTV.  You can find out more at the <a href="http://code.google.com/p/mythpodcaster/">web-page I've created for the MythPodcaster project</a>.</p>]]></description>
         <link>http://urlgrey.net/archives/2009/10/first_release_o.php</link>
         <guid>http://urlgrey.net/archives/2009/10/first_release_o.php</guid>
         <category>MythTV</category>
         <pubDate>Sun, 18 Oct 2009 12:44:13 -0800</pubDate>
      </item>
            <item>
         <title>CBS College Sports and Notre Dame Applications for iPhone with Live Games</title>
         <description><![CDATA[<p>I strongly recommend that people check out the new CBS College Sports application for the iPhone and iPod Touch (<a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=329804098&mt=8">iTunes Store</a>).  You can watch live streaming video covering the Southeastern Conference football & basketball games each week.  A similar application (<a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=328471028&mt=8">iTunes Store</a>) is also available for Notre Dame University that shows live coverage of each broadcast Notre Dame football game.  You'll be amazed by the video-quality and information included in the applications!</p>]]></description>
         <link>http://urlgrey.net/archives/2009/09/cbs_college_spo.php</link>
         <guid>http://urlgrey.net/archives/2009/09/cbs_college_spo.php</guid>
         <category>Computing</category>
         <pubDate>Mon, 28 Sep 2009 17:30:36 -0800</pubDate>
      </item>
            <item>
         <title>Unable to Record HD Content over IEEE 1394 (Firewire)</title>
         <description><![CDATA[<p>Natalie & I recently transferred our cable television service to our new home, which gave <a href="http://www.comcast.com/">Comcast</a> license to force upon us an HD cable-box upgrade.  I was excited to learn that the cable-box is the well regarded <a href="http://www.motorola.com/staticfiles/Business/Products/TV%20Video%20Distribution/Set-tops/QAM%20Set-tops/Digital-Analog%20QAM%20Set-tops/DCT6200/_Documents/Static%20Files/DCT6200_New.pdf?localeId=33">Motorola 6200</a>.  The 6200 includes two <a href="http://en.wikipedia.org/wiki/IEEE_1394_interface">IEEE 1394 (Firewire)</a> outputs on the back panel which should provide a raw audio/video feed in native HD resolution when possible.</p>

<p>But I excitement quickly changed to disappointment upon learning that Comcast has applied <a href="http://en.wikipedia.org/wiki/Digital_Transmission_Content_Protection">5C content protection</a> to their HD channels, which means that unauthorized devices (such as our <a href="http://www.mythtv.org/">MythTV</a>) are not authorized to record or view the content via the Firewire port.  This means that our HD-capable cable-box is effectively no different from a cheaper standard-definition cable-box.  I've chosen to record HD content from a broadcast antenna, which generally offers better video quality at no cost.  But it's frustrating that Comcast and other cable providers offer HD with the caveat that it can only be viewed with select devices.  It's a total bait-and-switch.</p>]]></description>
         <link>http://urlgrey.net/archives/2009/08/unable_to_recor.php</link>
         <guid>http://urlgrey.net/archives/2009/08/unable_to_recor.php</guid>
         <category>MythTV</category>
         <pubDate>Tue, 18 Aug 2009 13:17:43 -0800</pubDate>
      </item>
            <item>
         <title>Tracking the Minutia of our Lives</title>
         <description><![CDATA[<p>I've been working on a side-project that involves tracking in great detail many of the minor activities that we engage in day-to-day.  I've created a specialized networked device to record and display information related to these activities.  Information about the activities is stored in a relational database on a remote server.  The idea is that the information can be collected for weeks or months, and then trends can be identified so that lifestyle changes can be made with good results.</p>

<p>Monitoring and tracking our activities is becoming incredibly popular.  WIRED Magazine recently had an <a href="http://wired.com/medtech/health/magazine/17-07/lbnp_knowthyself">issue with the title 'Living by Numbers'</a> in which they described many popular applications and products that enable people to quantify the details of their life.  There are huge benefits to knowing more about how we live, but systems that are involved must be designed with privacy in mind.</p>

<p>But with more data comes more problems.  What if the details of your body temperature, diet, or geographic movements find their way into the hands of a prospective employer, insurance agent, or any individual or entity who may not have your best interests at heart?  Securing that data is paramount.  And I think the easiest way to secure that data is to own it in its entirety.  <a href="http://en.wikipedia.org/wiki/Cloud_computing">Cloud Computing</a> (GMail, Google Documents, Twitter, Facebook, MySpace, etc) may make it easy to access, share, and compare your data, but it provides control and ownership of that data to an external entity whose security measures are a complete unknown.</p>

<p>So, I think that it's very important that data related your day-to-day activities be kept as close to you, the rightful owner, as possible.  As we design and develop tools to capture and record this data, we must provide additional tools that allow the owners to access and transfer their data as they see fit.</p>]]></description>
         <link>http://urlgrey.net/archives/2009/08/tracking_the_mi.php</link>
         <guid>http://urlgrey.net/archives/2009/08/tracking_the_mi.php</guid>
         <category>Computing</category>
         <pubDate>Thu, 06 Aug 2009 17:15:19 -0800</pubDate>
      </item>
            <item>
         <title>Decline in Blogging Activity</title>
         <description><![CDATA[<p>I haven't posted to this blog in a very long time.  In fact, it has been over a year.  I think this is due to several factors, but the most important being a shift to a private wiki (<a href="http://moinmo.in/">MoinMoin</a>) for my personal note-taking.  So, most of the notes that I would have posted to this blog in years past are now being posted to a wiki that I maintain on my private home network.  The wiki has been a great tool: I can publish any information I want without the content needing to be in a finished state.  But a downside is that I'm not sharing information that others could really benefit from.  In the future I'll make more of an effort to transfer my more polished work from the private wiki to the public blog.  I believe that having control over how and when information is made public is a great liberty that no one should take for granted.</p>]]></description>
         <link>http://urlgrey.net/archives/2009/07/decline_in_blog.php</link>
         <guid>http://urlgrey.net/archives/2009/07/decline_in_blog.php</guid>
         <category>Computing</category>
         <pubDate>Thu, 30 Jul 2009 16:53:07 -0800</pubDate>
      </item>
            <item>
         <title>Audio Distortion with the Hauppauge PVR-150 and MythTV</title>
         <description><![CDATA[I've been using the Hauppauge (pronounced <i>hop-awg</i>) <a href="http://www.hauppauge.com/pages/products/data_pvr150.html">PVR-150</a> to record standard-quality television from our Comcast Digital Cable service.  So, far, the quality and performance of the card has been outstanding, especially when considering the cost of the card (~$75).  It comes with a hardware <a href="http://en.wikipedia.org/wiki/MPEG-2">MPEG-2</a> encoder that imposes hardly any load on the <a href="http://www.mythtv.org">MythTV</a> backend when recording because the compression and encoding of the video & audio is performed in hardware.  This leaves plenty of system resources for other tasks, such as playback or transcoding into other media formats.<p>

But there has been one problem that occurs intermittently: the audio on live & recorded programs will sound like it's being projected from a tin can.  The sound is discernible, but wrong.  Enduring an hour-long program with bad sound can be difficult.<p>

At first, I wasn't sure if the sound distortion was coming from the digital cable box, the PVR-150 encoder card, or MythTV playback.  We had never experienced this kind of audio distortion with our old Tivo service using the same digital cable box, so I had to rule out the cable box.  Also, we never had any problems when using the PVR-150 tuner input, which combines video & audio in a single input.  I had recently switched from the tuner input to the composite audio & video input on the PVR-150 due to the generally higher quality they deliver in comparison to coaxial feeds.  So, I concluded that problem was with the PVR-150 composite audio input.<p>

I'd noticed that leaving and then promptly returning to the channel would resolve the problem.  But this is not possible when recording programs while away.  After reading several posting on MythTV user lists, I decided to modify the channel-change script to fork a background that re-establishes the audio input 2 seconds after the channel-change script returns.  This has worked successfully for a week now, which is a marked improvement over where we were.<p>

The following shows the channel-change script:<p>

  <pre class="mtc_block"><span class="shell_string def_String"><span class="regexp_Quote regexp_MetaSymb def_Symbol"><span class="def_PairStart def_Special">[</span></span>scott@eowyn ~<span class="regexp_Quote regexp_MetaSymb def_Symbol"><span class="def_PairEnd def_Special">]</span></span></span><span class="shell_var def_Var">$</span> cat <span class="shell_path def_Path def_URI">/usr/local/bin/change_chan</span><span class="shell_command def_Keyword">.</span>sh 
<span class="def_Comment def_Syntax">#!/bin/sh</span>

<span class="def_Comment def_Syntax"># send infrared signals to change the current channel</span>
<span class="shell_var def_Var">REMOTE_NAME</span><span class="shell_symb def_Symbol">=</span>comcast
<span class="shell_command def_Keyword">for</span> digit <span class="shell_command def_Keyword">in</span> $<span class="def_PairStart def_Special"><span class="shell_symb_struct def_SymbolStrong def_Symbol">(</span></span><span class="shell_command_sys def_KeywordStrong def_Keyword">echo</span> <span class="shell_var def_Var">$1</span> <span class="shell_symb_inout def_Label">|</span> <span class="shell_command_sys def_KeywordStrong def_Keyword">sed</span> <span class="shell_op def_Operator def_Symbol">-e</span> <span class="shell_string def_String"><span class="def_PairStart def_Special">'</span><span class="shell_string def_String"><span class="shell_string def_String"><span class="def_PairStart def_Special"><span class="regexp_SpecArea def_Keyword">s</span><span class="def_StringEdge def_String">/</span></span><span class="regexp_MetaSymb def_Symbol">.</span><span class="def_StringEdge def_String">/</span></span>&amp; <span class="def_PairEnd def_Special"><span class="def_StringEdge def_String">/</span><span class="regexp_SpecArea def_Keyword">g</span></span></span><span class="def_PairEnd def_Special">'</span></span><span class="def_PairEnd def_Special"><span class="shell_symb_struct def_SymbolStrong def_Symbol">)</span></span><span class="shell_symb_struct def_SymbolStrong def_Symbol">;</span> <span class="def_PairStart def_Special"><span class="shell_command def_Keyword">do</span></span> 
  <span class="shell_path def_Path def_URI">/usr/local/bin/irsend</span> SEND_ONCE <span class="shell_var def_Var">$REMOTE_NAME</span> <span class="shell_var def_Var">$digit</span>
  sleep <span class="def_NumberDec def_Number">0</span><span class="shell_command def_Keyword">.</span><span class="def_NumberDec def_Number">4</span>
<span class="def_PairEnd def_Special"><span class="shell_command def_Keyword">done</span></span>
<span class="shell_path def_Path def_URI">/usr/local/bin/irsend</span> SEND_ONCE <span class="shell_var def_Var">$REMOTE_NAME</span> <span class="shell_string def_String"><span class="def_PairStart def_Special">&quot;</span>ok<span class="def_PairEnd def_Special">&quot;</span></span>

<span class="def_Comment def_Syntax"># start audio <span class="def_TODO def_Error">fix script in the background</span></span>
<span class="shell_path def_Path def_URI">/usr/local/bin/ivtv_audio_fix</span><span class="shell_command def_Keyword">.</span>sh <span class="shell_symb_struct def_SymbolStrong def_Symbol">&amp;</span></pre>
<p>

And the following shows the contents of the audio fix-it script that runs in the background after the channel-change process has finished.<p>

  <pre class="mtc_block"><span class="shell_string def_String"><span class="regexp_Quote regexp_MetaSymb def_Symbol"><span class="def_PairStart def_Special">[</span></span>scott@eowyn ~<span class="regexp_Quote regexp_MetaSymb def_Symbol"><span class="def_PairEnd def_Special">]</span></span></span><span class="shell_var def_Var">$</span> cat <span class="shell_path def_Path def_URI">/usr/local/bin/ivtv_audio_fix</span><span class="shell_command def_Keyword">.</span>sh 
<span class="def_Comment def_Syntax">#!/bin/sh</span>

sleep <span class="def_NumberDec def_Number">2</span>

<span class="def_Comment def_Syntax"># reset the audio input to source 1</span>
<span class="shell_path def_Path def_URI">/usr/local/bin/v4l2</span>-ctl --<span class="shell_command_sys def_KeywordStrong def_Keyword">set</span>-audio-input <span class="def_NumberDec def_Number">1</span></pre>
<p>

I'll also mention that I don't notice any glitches in the audio despite the fact that the fix-it script runs 2 seconds after the channel has been changed.
]]></description>
         <link>http://urlgrey.net/archives/2008/06/audio_distortio.php</link>
         <guid>http://urlgrey.net/archives/2008/06/audio_distortio.php</guid>
         <category>MythTV</category>
         <pubDate>Sat, 07 Jun 2008 16:16:43 -0800</pubDate>
      </item>
            <item>
         <title>OpenGL Vsync on MythTV</title>
         <description><![CDATA[<p>I had enabled Open Vsync on our <a href="http://www.mythtv.org/">MythTV</a> frontend during the initial configuration with the belief that there couldn't be any harm in adding an additional method of vertical synchronization.  I changed my mind when I began noticing strange delays in the video playback on my <a href="http://www.nvidia.com/page/fx_5200.html">NVidia FX 5200</a> with XVMC.  After changing channels, there would be about 3-5 glitches in video playback for 30 seconds, followed by okay playback.  I was okay with it until we began seeing much more dramatic choppiness in playback coupled with higher CPU utilization (typically 18-20%, but as high as 70%).</p>

<p>I searched the web for the symptoms and saw a lot of people reporting problems with video playback when OpenGL Vsync is enabled (<a href="http://readlist.com/lists/mythtv.org/mythtv-users/6/32272.html">here</a> and <a href="http://mythtv.org/pipermail/mythtv-dev/2007-June/055670.html">here</a>).  Since disabling OpenGL Vsync, I've not seen any delays in playback.  I might re-enable <strong>UseEvents</strong> in <em>/etc/X11/xorg.conf</em>, but it's currently set to <strong>False</strong>.</p>]]></description>
         <link>http://urlgrey.net/archives/2008/04/opengl_vsync_on.php</link>
         <guid>http://urlgrey.net/archives/2008/04/opengl_vsync_on.php</guid>
         <category>MythTV</category>
         <pubDate>Fri, 25 Apr 2008 09:53:26 -0800</pubDate>
      </item>
            <item>
         <title>Using XvMC with MythTV and an NVidia FX 5200</title>
         <description><![CDATA[Yesterday I wrote about my foray into <a href="http://urlgrey.net/archives/2008/03/using_opengl_wi.php">using the proprietary NVidia Linux display driver</a> on my <a href="http://www.mythtv.org/">MythTV</a> box to get better hardware acceleration.  This initially meant using OpenGL for rendering of the MyhTV menus.  The responsiveness of the menus was greatly improved; however, the <i>mythfrontend</i> process continued to use around 70% of the CPU.  This was surprising, especially considering that it's a Pentium 4 3.0 GHz CPU with HyperThreading.  I determined that playback of the recordings and live programming was <b>not </b> using the MPEG-2 acceleration present in the NVidia FX 5200 graphics card, which meant the MPEG-2 decoding was being performed entirely on the CPU.  This resulted in a higher system load and arguably lower-quality output.
<p>

I found the <a href="http://www.mythtv.org/wiki/index.php/XvMC#Nvidia">XvMC</a> section of the MythTV wiki describing how to use X-Video Motion Compensation (XvMC) to utilize hardware acceleration when decoding MPEG-2 video.  It actually took me several hours to get XvMC working, but I'll summarize the effective steps below:
<p>

First, install the NVidia display driver for Linux.  The x.org driver doesn't support XvMC, so there's no way around it.  My <a href="http://urlgrey.net/archives/2008/03/using_opengl_wi.php">previous post</a> has information on how to do this.
<p>

First, set-up the <i>/etc/X11/xorg.conf</i> file for the NVidia driver.  XvMC worked only when NVAGP was set to '1'.  You find explanations of these options on the <a href="http://http.download.nvidia.com/XFree86/Linux-x86/1.0-9629/README/appendix-d.html">NVidia support site</a>.  The relevant section of my <i>/etc/X11/xorg.conf</i> follows:<p>

<pre class="mtc_block"><span class="def_Syntax">Section</span> <span class="def_String">&quot;Device&quot;</span>
    <span class="def_Syntax">Identifier    </span> <span class="def_String">&quot;Videocard0&quot;</span>
    <span class="def_Syntax">Driver        </span> <span class="def_String">&quot;nvidia&quot;</span>
    <span class="def_Syntax">Option </span> <span class="def_String">&quot;NVAGP&quot;</span>                 <span class="def_String">&quot;1&quot;</span>
    <span class="def_Syntax">Option </span> <span class="def_String">&quot;NoLogo&quot;</span>                <span class="def_String">&quot;True&quot;</span>
    <span class="def_Syntax">Option </span> <span class="def_String">&quot;RenderAccel&quot;</span>           <span class="def_String">&quot;True&quot;</span>
    <span class="def_Syntax">Option </span> <span class="def_String">&quot;XvmcUsesTextures&quot;</span>      <span class="def_String">&quot;True&quot;</span>
    <span class="def_Syntax">Option </span> <span class="def_String">&quot;UseEdidDpi&quot;</span>            <span class="def_String">&quot;False&quot;</span>
    <span class="def_Syntax">Option </span> <span class="def_String">&quot;DPI&quot;</span>                   <span class="def_String">&quot;100 x 100&quot;</span>
    <span class="def_Syntax">Option </span> <span class="def_String">&quot;UseEvents&quot;</span>             <span class="def_String">&quot;False&quot;</span>
    <span class="def_Syntax">Option </span> <span class="def_String">&quot;DPMS&quot;</span>                  <span class="def_String">&quot;False&quot;</span>
EndSection</pre>
<p>

Next, create or edit the file <i>/etc/X11/XvMCConfig</i>.  Following are some shell commands that show my system setup:
<p>

<pre class="mtc_block"><span class="shell_string def_String"><span class="regexp_Quote regexp_MetaSymb def_Symbol"><span class="def_PairStart def_Special">[</span></span>scott@eowyn lib<span class="regexp_Quote regexp_MetaSymb def_Symbol"><span class="def_PairEnd def_Special">]</span></span></span><span class="shell_var def_Var">$</span> <span class="shell_command_sys def_KeywordStrong def_Keyword">cd</span> <span class="shell_path def_Path def_URI">/usr/lib</span>
<span class="shell_string def_String"><span class="regexp_Quote regexp_MetaSymb def_Symbol"><span class="def_PairStart def_Special">[</span></span>scott@eowyn lib<span class="regexp_Quote regexp_MetaSymb def_Symbol"><span class="def_PairEnd def_Special">]</span></span></span><span class="shell_var def_Var">$</span> ll libXvMCNVIDIA<span class="regexp_MetaSymb def_Symbol">*</span>
-r--r--r-- <span class="def_NumberDec def_Number">1</span> root root <span class="def_NumberDec def_Number">152808</span> <span class="def_NumberDec def_Number">2008</span>-<span class="def_NumberDec def_Number">03</span>-<span class="def_NumberDec def_Number">31</span> <span class="def_NumberDec def_Number">08</span><span class="shell_symb def_Symbol">:</span><span class="def_NumberDec def_Number">47</span> libXvMCNVIDIA<span class="shell_command def_Keyword">.</span>a
lrwxrwxrwx <span class="def_NumberDec def_Number">1</span> root root     <span class="def_NumberDec def_Number">23</span> <span class="def_NumberDec def_Number">2008</span>-<span class="def_NumberDec def_Number">03</span>-<span class="def_NumberDec def_Number">31</span> <span class="def_NumberDec def_Number">08</span><span class="shell_symb def_Symbol">:</span><span class="def_NumberDec def_Number">47</span> libXvMCNVIDIA_dynamic<span class="shell_command def_Keyword">.</span>so<span class="shell_command def_Keyword">.</span><span class="def_NumberDec def_Number">1</span> -<span class="shell_symb_inout def_Label">&gt;</span> libXvMCNVIDIA<span class="shell_command def_Keyword">.</span>so<span class="shell_command def_Keyword">.</span><span class="def_NumberDec def_Number">169</span><span class="shell_command def_Keyword">.</span><span class="def_NumberDec def_Number">12</span>
-rwxr-xr-x <span class="def_NumberDec def_Number">1</span> root root <span class="def_NumberDec def_Number">139604</span> <span class="def_NumberDec def_Number">2008</span>-<span class="def_NumberDec def_Number">03</span>-<span class="def_NumberDec def_Number">31</span> <span class="def_NumberDec def_Number">08</span><span class="shell_symb def_Symbol">:</span><span class="def_NumberDec def_Number">47</span> libXvMCNVIDIA<span class="shell_command def_Keyword">.</span>so<span class="shell_command def_Keyword">.</span><span class="def_NumberDec def_Number">169</span><span class="shell_command def_Keyword">.</span><span class="def_NumberDec def_Number">12</span>
<span class="shell_string def_String"><span class="regexp_Quote regexp_MetaSymb def_Symbol"><span class="def_PairStart def_Special">[</span></span>scott@eowyn lib<span class="regexp_Quote regexp_MetaSymb def_Symbol"><span class="def_PairEnd def_Special">]</span></span></span><span class="shell_var def_Var">$</span> cat <span class="shell_path def_Path def_URI">/etc/X11/XvMCConfig</span> 
libXvMCNVIDIA_dynamic<span class="shell_command def_Keyword">.</span>so<span class="shell_command def_Keyword">.</span><span class="def_NumberDec def_Number">1</span></pre>
<p>

To confirm that XvMC is working in X Windows, start up X Windows (i.e. startx), create a shell window and run <i>xdpyinfo</i> to look for the XvMC info:
<p>

<pre class="mtc_block"><span class="shell_string def_String"><span class="regexp_Quote regexp_MetaSymb def_Symbol"><span class="def_PairStart def_Special">[</span></span>scott@eowyn lib<span class="regexp_Quote regexp_MetaSymb def_Symbol"><span class="def_PairEnd def_Special">]</span></span></span><span class="shell_var def_Var">$</span> xdpyinfo <span class="shell_symb_inout def_Label">|</span> grep XVideo
     XVideo
     XVideo-MotionCompensation</pre>
<p>

The next step is to instruct mythfrontend to use XvMC for playback.  I did this by choosing a playback profile in the mythfrontend via the <i>Setup -> TV Settings -> Playback</i> menus.  The <i>CPU--</i> profile uses 'ivtv' for Standard Definition (SD) Television, and 'xvmc' for higher definition content.  I'm only recording SD content right now, but would like to use 'xvmc' to lower the CPU load.  So, I created a new playback profile that uses 'xvmc' for all content.
<p>

I'll also mention that the picture became skewed on my 16:9 Sony 32" flat-panel television.  I corrected this by adding scaling values of X=2, Y=3 in the <i>Setup -> TV Settings -> Playback</i> menu.  This shifted the picture left and down to fill the screen.  I'm also using the DVI output of the NVidia FX 5200 card.  I've got a DVI-to-HDMI cable that delivers a pure digital signal to the television.  The clarity is phenomenal.
<p>

After making all of these changes, I was able to confirm that XvMC was in use simply by looking at the CPU utilization of the 'mythfrontend' process with 'top'.  Before I enabled XvMC, CPU utilization was at 68-72% when playing video.  After switching to XvMC, utilization is merely 18-20%.  That's more than a 300% reduction in CPU utilization!  Since I use the MythTV machine for the backend and frontend, the reduction in CPU utilization opens up the possibility of adding another encoder card, or running some additional services such as ZoneMinder.
]]></description>
         <link>http://urlgrey.net/archives/2008/04/using_xvmc_with.php</link>
         <guid>http://urlgrey.net/archives/2008/04/using_xvmc_with.php</guid>
         <category>MythTV</category>
         <pubDate>Tue, 01 Apr 2008 11:16:04 -0800</pubDate>
      </item>
            <item>
         <title>Using OpenGL with MythTV</title>
         <description><![CDATA[<p>While fine-tuning our <a href="http://www.mythtv.org/">MythTV</a> system, I noticed that the default menu-renderer is <a href="http://trolltech.com/products/qt">QT</a>.  There's nothing wrong with QT, except that it doesn't offer hardware acceleration that <a href="http://www.opengl.org/">OpenGL</a> does.  So, using QT creates a higher system load on the MythTV frontend.  This takes away CPU cycles that could be better spent, and provides a UI that is less smooth.</p>

<p>So, I enabled OpenGL menu-rendering for MythTV (0.21) only to find the menu transition taking a horrendous amount of time.  There was an OpenGL fade that occurred on each screen transition that would take about 5 second to complete.  This is when I realized that I should have installed the vendor's X Windows driver.</p>

<p>My MythTV machine has an <a href="http://www.nvidia.com/page/fx_5200.html">NVidia GeForce FX 5200 graphics card</a> installed.  It's a few years old, but works perfectly for this purpose: fanless, hardware OpenGL rendering & MPEG-2 decoding, and DVI output.  I went to the NVidia support site and downloaded the display driver.  I then installed it and marveled at how much it improved everything.  The system load was greatly reduced because the OpenGL rendering occurred in hardware, menu navigation was very quick, and a lovely fade effect occurs upon each screen transition.</p>

<p>So, the lesson learned was to install the NVidia display drivers when choosing OpenGL menu rendering with MythTV.  OpenGL is a great improvement over QT, and having display drivers that can take advantage of hardware acceleration is a must.</p>]]></description>
         <link>http://urlgrey.net/archives/2008/03/using_opengl_wi.php</link>
         <guid>http://urlgrey.net/archives/2008/03/using_opengl_wi.php</guid>
         <category>MythTV</category>
         <pubDate>Mon, 31 Mar 2008 12:41:56 -0800</pubDate>
      </item>
      
   </channel>
</rss>
