Okay, I got it working, as far as I can tell; the patch against this
morning's source (Version 8516) is enclosed.

Details

* The packager copies a bunch of huge .svn directories containing .png
  files into the applications.  The enclosed packager script still
  contains the RecursiveCopy routine that tries (unsucessfully) to
  undo the damage.  This issue is still unresolved.

* As noted in numerous places in my patch, the project's use of 

    #define always_inline

  is problematic.  That practice should end; for now it's worked
  around through careful management of #include order and a
  strategically-placed #undef always_inline

* You need Apple's FirewireSDK20 installed in its default location in
  order to build.

* The changes I made in mythcontext.cpp were the only way I could get
  commercial flagging to work.  Otherwise the prefix path that gets
  used is somewhere in the build disk image.  The change in
  jobqueue.cpp was half-finished and I'm not sure that it's necessary
  at all, but when the backend stopped complaining about not being
  able to launch the flagger I figured, "why mess with success?"

* Unless you know you have distcc working, you may need to uncomment
  the '--disable-distcc' line in the packager script.

* You also might want to swap the activation of these two lines in the
  packager:

   #    &Syscall([ '/usr/bin/make' ]) or die;
        &Syscall([ '/usr/bin/make -j5' ]) or die;

* In the packager script the bug that causes the script to fail has
  been resolved, but I commented out the line that unmounts the disk
  image because it was more convenient for development.

Index: configure
===================================================================
--- configure	(revision 8516)
+++ configure	(working copy)
@@ -1996,7 +1996,7 @@
 fi
 
 
-if test x"$firewire_cable_box" = x"yes" ; then
+if test x"$firewire_cable_box" = x"yes" -a x$darwin == x"" ; then
     firewire_cable_box="no"
     if has_library libiec61883 -a has_library libavc1394 ; then
         if test x`which pkg-config 2>/dev/null` != x"" ; then
@@ -2692,6 +2692,16 @@
 echo "#endif" >> $TMPH
 
 if test "$optimize" = "small"; then
+  # This is completely broken; the MacOS headers (and, presumably,
+  # other legitimate headers) use constructs like:
+  # 
+  #   static __inline__ __attribute__((always_inline)) 
+  #   return_type function_name() { ... }
+  # 
+  # which naturally is disrupted by any attempt to #define
+  # always_inline.  MythTv should use some other symbol for that
+  # purpose, preferably an ALL_UPPERCASE symbol beginning with MYTH_
+
   echo "#define always_inline"  >> $TMPH
 fi
 
@@ -2797,7 +2807,9 @@
 
 if test x"$firewire_cable_box" = x"yes" ; then
   CCONFIG="$CCONFIG using_firewire"
-  echo "CONFIG_FIREWIRE_LIBS=-lraw1394 -liec61883 -lavc1394" >> $MYTH_CONFIG_MAK
+  if test x"$darwin" != x"yes" ; then
+      echo "CONFIG_FIREWIRE_LIBS=-lraw1394 -liec61883 -lavc1394" >>  $MYTH_CONFIG_MAK
+  fi
 fi
 
 if test x"$dbox2_dvb_box" = x"yes" ; then
Index: libs/libmythtv/firewirechannel.cpp
===================================================================
--- libs/libmythtv/firewirechannel.cpp	(revision 8516)
+++ libs/libmythtv/firewirechannel.cpp	(working copy)
@@ -10,19 +10,71 @@
 #include "mythcontext.h"
 #include "firewirechannel.h"
 
+#ifdef CONFIG_DARWIN
+# include "selectavcdevice.h"
+# undef always_inline
+# include <AVCVideoServices/AVCVideoServices.h>
+#endif 
+
 class TVRec;
 
+#ifdef CONFIG_DARWIN
+namespace
+{
+  bool find_tunable_device(AVS::AVCDevice* d)
+  {
+      return d->isAttached && d->hasMonitorOrTunerSubunit;
+  }
+}
+#endif 
 
 FirewireChannel::FirewireChannel(FireWireDBOptions firewire_opts, TVRec *parent)
-    : ChannelBase(parent),fw_opts(firewire_opts)
+  : ChannelBase(parent),fw_opts(firewire_opts)
+#ifdef CONFIG_DARWIN
+  , device_controller(parent->DemandDeviceController())
+  , tunable_device(0)
+#endif 
+  , isopen(false)
 {
 	
-    isopen = false;
-    fwhandle = NULL;
     channelnames[0] = "MPEG2TS";
 
+#ifdef CONFIG_DARWIN
+    if (!this->device_controller)
+        return;
+#else 
+    fwhandle = NULL;
+#endif
+
     if (externalChanger[currentcapchannel].isEmpty())
     {
+#ifdef CONFIG_DARWIN
+        this->tunable_device = SelectAVCDevice(device_controller, find_tunable_device);
+        if (!this->tunable_device)
+        {
+            VERBOSE(VB_IMPORTANT,
+                    QString("FireWireChannel: unable to find an attached device that supports channel changes"));
+            return;
+        }
+
+        if (this->tunable_device->isOpened())
+        {
+            VERBOSE(VB_RECORD, QString("FirewireChannel: device already open") );
+        }
+        else
+        {
+            VERBOSE(VB_RECORD, QString("FirewireChannel: opening device") );
+            IOReturn err = this->tunable_device->openDevice();
+            if (err)
+            {
+                VERBOSE(VB_IMPORTANT,
+                        QString("FireWireChannel: couldn't open tuner device: %1").arg(err));
+                return;
+            }
+        }
+
+        this->isopen = true;
+#else 
         if ((fw_opts.model == "DCT-6200") || (fw_opts.model == "SA3250HD"))
         {
             if ((fwhandle = raw1394_new_handle_on_port(fw_opts.port)) == NULL)
@@ -42,22 +94,55 @@
             VERBOSE(VB_IMPORTANT, "FireWireChannel: internal channel "
                     "changer only supported by DCT-6200 and SA3250HD models");
         }
+#endif 
     }
 }
 
 FirewireChannel::~FirewireChannel(void)
 {
+#ifdef CONFIG_DARWIN
+    if (this->isopen)
+        this->tunable_device->closeDevice();
+#else 
     if (isopen)
     {
         VERBOSE(VB_GENERAL,QString("FireWireChannel: releasing raw1394 handle"));
         raw1394_destroy_handle(fwhandle);
     }
+#endif 
 }
 
 bool FirewireChannel::SetChannelByString(const QString &chan)
 {
+     int channel = chan.toInt();
+#ifdef CONFIG_DARWIN
+     if (!this->isopen)
+         return true;
+
+     // If the tuner is off, try to turn it on.
+     UInt8 power_state;
+     IOReturn err = this->tunable_device->GetPowerState(&power_state);
+     if (err == kIOReturnSuccess && power_state == kAVCPowerStateOff)
+     {
+         tunable_device->SetPowerState(kAVCPowerStateOn);
+        
+         // Give it time to power up.
+         usleep(2000000); // Sleep for two seconds
+     }
+
+     AVS::PanelSubunitController panel(tunable_device);
+     err = panel.Tune(channel);
+     if (err != kIOReturnSuccess)
+     {
+         VERBOSE(VB_GENERAL, QString("FirewireChannel: Tuning failed: %1").arg((int)err));
+         VERBOSE(VB_GENERAL, QString("Ignoring error per apple example"));
+         //         return false;
+     }
+     // Give it time to transition.        
+     usleep(1000000); // Sleep for one second
+     return true;
+#else 
      int dig[3];
-     int channel = chan.toInt();
      quadlet_t cmd[3];
 
      inputChannel[currentcapchannel] = chan;
@@ -125,6 +210,7 @@
          return false;
      }
      return true;
+#endif 
 }
 
 bool FirewireChannel::Open()
Index: libs/libmythtv/jobqueue.cpp
===================================================================
--- libs/libmythtv/jobqueue.cpp	(revision 8516)
+++ libs/libmythtv/jobqueue.cpp	(working copy)
@@ -2008,7 +2008,13 @@
     gContext->LogEntry("commflag", LP_NOTICE, msg, logDesc);
 
     int breaksFound = 0;
-    QString path = gContext->GetInstallPrefix() + "/bin/mythcommflag";
+    QString path = gContext->GetInstallPrefix() 
+#ifdef CONFIG_DARWIN
+        
+#else 
+        + "/bin/mythcommflag"
+#endif 
+        ;
     QString cmd = QString("%1 -j %2 -V %3")
                           .arg(path).arg(jobID).arg(print_verbose_messages);
 
Index: libs/libmythtv/libmythtv.pro
===================================================================
--- libs/libmythtv/libmythtv.pro	(revision 8516)
+++ libs/libmythtv/libmythtv.pro	(working copy)
@@ -48,6 +48,12 @@
     QMAKE_CXXFLAGS += -F/System/Library/Frameworks/$${FC}.framework/Frameworks
     LIBS           += -framework $$join(FWKS," -framework ")
 
+    using_backend {
+        AVSDIR = /Developer/FireWireSDK20/Examples/AVCVideoServices/Framework
+        QMAKE_CXXFLAGS += -F$${AVSDIR}
+        LIBS += -F$${AVSDIR} -framework AVCVideoServices
+    }
+
     QMAKE_LFLAGS_SHLIB += -seg1addr 0xC9000000
 }
 
@@ -307,6 +313,9 @@
     HEADERS += frequencies.h
     SOURCES += frequencies.c
 
+    macx:HEADERS +=               selectavcdevice.h
+    macx:SOURCES +=               selectavcdevice.cpp
+
     DEFINES += USING_BACKEND
 }
 
Index: libs/libmythtv/firewirechannel.h
===================================================================
--- libs/libmythtv/firewirechannel.h	(revision 8516)
+++ libs/libmythtv/firewirechannel.h	(working copy)
@@ -12,8 +12,19 @@
 #include <qstring.h>
 #include "tv_rec.h"
 #include "channelbase.h"
-#include <libavc1394/avc1394.h>
 
+#include "mythconfig.h"
+
+#ifdef CONFIG_DARWIN
+namespace AVS
+{
+  class AVCDeviceController;
+  class AVCDevice;
+}
+#else 
+# include <libavc1394/avc1394.h>
+#endif 
+
 using namespace std;
 
 // 6200 defines for channel changes, taken from contrib/6200ch.c
@@ -60,8 +71,13 @@
 
   private:
     FireWireDBOptions  fw_opts;
+#ifdef CONFIG_DARWIN
+    AVS::AVCDeviceController* device_controller;
+    AVS::AVCDevice* tunable_device;
+#else 
     nodeid_t           fwnode;
     raw1394handle_t    fwhandle;
+#endif 
     bool               isopen;
 };
 
Index: libs/libmythtv/tv_rec.cpp
===================================================================
--- libs/libmythtv/tv_rec.cpp	(revision 8516)
+++ libs/libmythtv/tv_rec.cpp	(working copy)
@@ -68,6 +68,13 @@
 #include "dbox2channel.h"
 #endif
 
+#ifdef CONFIG_DARWIN
+// This include and its associated #undef must come last to avoid
+// interfering with the bogus #define always_inline used by MythTV.
+# undef always_inline
+# include <AVCVideoServices/AVCVideoServices.h>
+#endif 
+
 #define LOC QString("TVRec(%1): ").arg(cardid)
 #define LOC_ERR QString("TVRec(%1) Error: ").arg(cardid)
 
@@ -124,6 +131,9 @@
       tvchain(NULL),
       // RingBuffer info
       ringBuffer(NULL), rbFilePrefix(""), rbFileExt("mpg")
+#ifdef CONFIG_DARWIN
+    , device_controller(NULL)
+#endif
 {
 }
 
@@ -284,6 +294,10 @@
         dummyRecorder = NULL;
     }
 
+#ifdef CONFIG_DARWIN
+    AVS::DestroyAVCDeviceController(this->device_controller);
+#endif
+
     SetRingBuffer(NULL);
 }
 
@@ -3690,9 +3704,28 @@
     return true;
 }
 
+#ifdef CONFIG_DARWIN
+AVS::AVCDeviceController* TVRec::DemandDeviceController() const
+{
+    if (!this->device_controller)
+    {
+        IOReturn err = AVS::CreateAVCDeviceController(&this->device_controller);
+
+        if (err)
+        {
+            VERBOSE(
+                VB_IMPORTANT, 
+                LOC_ERR + QString("unable to open device controller: ").arg(err));
+        }
+    }
+    return this->device_controller;
+}
+#endif
+ 
 QString TuningRequest::toString(void) const
 {
     return QString("Program(%1) channel(%2) input(%3) flags(%4)")
         .arg((program != 0) ? "yes" : "no").arg(channel).arg(input)
         .arg(TVRec::FlagToString(flags));
 }
+
Index: libs/libmythtv/firewirerecorder.cpp
===================================================================
--- libs/libmythtv/firewirerecorder.cpp	(revision 8516)
+++ libs/libmythtv/firewirerecorder.cpp	(working copy)
@@ -18,6 +18,12 @@
 #include "tspacket.h"
 #include "tv_rec.h"
 
+#ifdef CONFIG_DARWIN
+# include "selectavcdevice.h"
+# undef always_inline
+# include <AVCVideoServices/AVCVideoServices.h>
+#endif 
+
 // callback function for libiec61883
 int read_tspacket (unsigned char *tspacket, int /*len*/,
                    uint dropped, void *callback_data)
@@ -43,18 +49,211 @@
 
     return 1;
 }
-
+ 
 void FirewireRecorder::deleteLater(void)
 {
     Close();
     DTVRecorder::deleteLater();
 }
 
+#ifdef CONFIG_DARWIN
+
+// Various message callbacks.
+void FirewireRecorder::MPEGNoData(void *pRefCon)
+{
+    
+    FirewireRecorder* self = static_cast<FirewireRecorder*>(pRefCon);
+
+    VERBOSE(
+        VB_IMPORTANT, 
+        QString("Firewire: No Input in %1 seconds (time)").arg(FIREWIRE_TIMEOUT));
+	
+    self->_error = true;
+}
+
+namespace
+{
+  void (*my_mpeg_no_data)(void*);
+
+  IOReturn mpeg_no_data(void* pRefCon)
+  {
+      my_mpeg_no_data(pRefCon);
+      return 0;
+  }
+
+  void avs_log_message(char *pString)
+  {
+      // I don't know what QString does with plain char*, but surely it
+      // treats char const* as an NTBS.
+      char const* s = pString;
+
+      VERBOSE(VB_GENERAL,QString("Firewire MPEG2Receiver log: %1")
+              .arg(s));
+  }
+
+  void avs_message_received(
+      UInt32 msg, UInt32 param1, UInt32 param2, void *pRefCon)
+  {
+      (void)pRefCon;
+
+      VERBOSE(VB_RECORD,QString("Firewire MPEG2Receiver message: %1")
+              .arg(msg));
+
+      switch (msg)
+      {
+      case AVS::kMpeg2ReceiverAllocateIsochPort:
+          VERBOSE(
+              VB_RECORD,
+              QString("Firewire MPEG2Receiver allocated channel: %1, speed %2")
+                  .arg(param2).arg(param1)
+          );
+          break;
+
+      case AVS::kMpeg2ReceiverDCLOverrun:
+          VERBOSE(
+              VB_IMPORTANT,
+              QString("Firewire MPEG2Receiver DCL Overrun")
+          );
+          break;
+
+      case AVS::kMpeg2ReceiverReceivedBadPacket:
+          VERBOSE(
+              VB_IMPORTANT,
+              QString("Firewire MPEG2Receiver Received Bad Packet ")
+          );
+          break;
+
+      default:
+          break;
+      }
+  }
+
+  IOReturn tspacket_callback(UInt32 tsPacketCount, UInt32 **ppBuf,void *pRefCon)
+  {
+      for (UInt32 i = 0; i < tsPacketCount; ++i)
+      {
+          void* packet = ppBuf[i];
+          int ok = read_tspacket( 
+              static_cast<unsigned char *>(packet), 
+              AVS::kMPEG2TSPacketSize,
+              0, // dropped
+              pRefCon);
+
+          // This is based on knowledge of what read_tspacket does --
+          // the only way it fails is with a NULL callback_data
+          // argument.
+          if (!ok)
+              return kIOReturnBadArgument;
+      }
+
+      return 0;
+  }
+
+  bool find_capture_device(AVS::AVCDevice* d)
+  {
+      // We'd check isMPEGDevice, but it turns out that for the
+      // DCT-6200, Apple doesn't set that flag.  So instead we rule
+      // out DV devices.
+      // A more general OSX AVCRecorder class that also handles DV
+      // devices might not check either flag.
+      return d->isAttached && !d->isDVDevice 
+//          && (d->hasTapeSubunit || d->hasMonitorOrTunerSubunit)
+          ;
+  }
+
+  IOReturn device_controller_notification(AVS::AVCDeviceController *, void *, AVS::AVCDevice*)
+  {
+      return 0;
+  }	
+}
+#endif 
+
 bool FirewireRecorder::Open() {
 
      if (isopen)
          return true;
     
+#ifdef CONFIG_DARWIN
+     AVS::AVCDeviceController* device_controller = tvrec->DemandDeviceController();
+     if (!device_controller)
+         return false;
+
+     VERBOSE(VB_RECORD,QString("Firewire: Looking for a device from which we can capture MPEG"));
+     this->capture_device = SelectAVCDevice(device_controller, find_capture_device);
+     if (!this->capture_device)
+     {
+         VERBOSE(VB_IMPORTANT, QString("Firewire: No suitable device found") );
+         this->Close();
+         return false;
+     }
+     
+     if (this->capture_device->isOpened())
+     {
+         VERBOSE(VB_RECORD, QString("Firewire: device already open") );
+     }
+     else
+     {
+         VERBOSE(VB_RECORD, QString("Firewire: opening device") );
+         IOReturn err = this->capture_device->openDevice();
+         if (err)
+         {
+             VERBOSE(VB_IMPORTANT,
+                     QString("FireWire: couldn't open capture device: %1").arg(err));
+             this->Close();
+             return false;
+         }
+     }
+
+     VERBOSE(VB_GENERAL,QString("Firewire: Creating logger object"));
+
+     // If we don't set this immediately, Close() will refuse to clean
+     // up after whatever mess we make here
+     this->isopen = true;
+
+     this->message_log = new AVS::StringLogger(avs_log_message);
+     if (!this->message_log)
+     {
+         VERBOSE(VB_IMPORTANT, QString("Firewire: Couldn't create logger") );
+         this->Close();
+         return false;
+     }
+
+     VERBOSE(VB_GENERAL,QString("Firewire: Creating MPEG-2 device stream"));
+     
+     // This not only builds an MPEG2Receiver object but also starts dedicated real-time threads.
+     this->video_stream = capture_device->CreateMPEGReceiverForDevicePlug(
+         0,                // Plug number.  Why is zero always OK?  I
+                           // don't know, but that's what Apple's
+                           // examples do.
+         tspacket_callback,
+         this,
+         avs_message_received,
+         this,
+         this->message_log,
+         AVS::kCyclesPerReceiveSegment,
+         // Why multiply by 2 instead of using the default,
+         // kNumReceiveSegments?  Because it's what Apple's only
+         // example of the use of this function does.
+         AVS::kNumReceiveSegments*2);
+         
+     if (!this->video_stream)
+     {
+         VERBOSE(VB_IMPORTANT, QString("Firewire: Couldn't create MPEG-2 device stream") );
+         this->Close();
+         return false;
+     }
+
+	// We could set the channel to receive on, but it doesn't seem
+	// like we need to, and if the device is already transmitting it
+	// could lead to inefficiency because the device stream is smart
+	// enough to avoid allocating new bandwidth.
+
+	// Register a no-data notification callback
+    my_mpeg_no_data = &FirewireRecorder::MPEGNoData;
+	video_stream->pMPEGReceiver->registerNoDataNotificationCallback(
+        mpeg_no_data, this, FIREWIRE_TIMEOUT * 1000);
+	
+#else 
      VERBOSE(VB_GENERAL,QString("Firewire: Initializing Port: %1, Node: %2, Speed: %3")
                                .arg(fwport)
                                .arg(fwnode)
@@ -110,6 +309,7 @@
      
      isopen = true;
      fwfd = raw1394_get_fd(fwhandle); 
+#endif 
      return true;
 }
 
@@ -117,9 +317,24 @@
 {
     if (!isopen)
         return;
-
+    
     isopen = false;
 
+#ifdef CONFIG_DARWIN
+    if (this->video_stream)
+    {
+        VERBOSE(VB_RECORD, "Firewire: Stopping device stream");
+        this->capture_device->StopAVCDeviceStream(this->video_stream);
+        VERBOSE(VB_RECORD, "Firewire: Destroying device stream");
+        this->capture_device->DestroyAVCDeviceStream(this->video_stream);
+        this->video_stream = 0;
+    }
+
+    delete this->message_log;
+    this->message_log = 0;
+
+    this->capture_device->closeDevice();
+#else 
     VERBOSE(VB_RECORD, "Firewire: releasing iec61883_mpeg2 object");
     iec61883_mpeg2_close(fwmpeg);
 
@@ -133,12 +348,10 @@
 
     VERBOSE(VB_RECORD, "Firewire: releasing raw1394 handle");
     raw1394_destroy_handle(fwhandle);
+#endif 
 }
 
 void FirewireRecorder::StartRecording(void) {
-
-    struct timeval tv;
-    fd_set rfds;
   
     VERBOSE(VB_RECORD, QString("StartRecording"));
 
@@ -150,19 +363,37 @@
     _request_recording = true;
     _recording = true;
    
+#ifdef CONFIG_DARWIN
+    this->capture_device->StartAVCDeviceStream(this->video_stream);
+#else 
+    struct timeval tv;
+    fd_set rfds;
+
     iec61883_mpeg2_recv_start(fwmpeg,fwchannel);
+#endif 
     lastpacket = time(NULL);
     while(_request_recording) {
        if (PauseAndWait())
            continue;
 
        if (time(NULL) - lastpacket > FIREWIRE_TIMEOUT) {
-            VERBOSE(VB_IMPORTANT, QString("Firewire: No Input in %1 seconds [P:%2 N:%3] (time)").arg(FIREWIRE_TIMEOUT).arg(fwport).arg(fwnode));
+#ifdef CONFIG_DARWIN
+           this->MPEGNoData(this);
+           this->capture_device->StopAVCDeviceStream(this->video_stream);
+#else 
+            VERBOSE(
+                VB_IMPORTANT, 
+                QString("Firewire: No Input in %1 seconds [P:%2 N:%3] (time)")
+                .arg(FIREWIRE_TIMEOUT).arg(fwport).arg(fwnode));
             iec61883_mpeg2_recv_stop(fwmpeg);
             _error = true;
+#endif 
             return;
        }
 
+#ifdef CONFIG_DARWIN
+		usleep(100);
+#else 
        FD_ZERO (&rfds);
        FD_SET (fwfd, &rfds);
        tv.tv_sec = FIREWIRE_TIMEOUT;
@@ -182,10 +413,17 @@
             _error = true;
             return;
        }
+#endif 
     }        
 
+#ifdef CONFIG_DARWIN
+    VERBOSE(VB_RECORD, "Firewire: Stopping video stream");
+    this->capture_device->StopAVCDeviceStream(this->video_stream);
+#else 
     iec61883_mpeg2_recv_stop(fwmpeg);
+#endif 
     FinishRecording();
+
     _recording = false;
 }  
 
@@ -207,15 +445,24 @@
     (void)profile;
 }
 
-void FirewireRecorder::SetOption(const QString &name, const QString &value) {
-
+void FirewireRecorder::SetOption(const QString &name, const QString &value) 
+{
+#ifdef CONFIG_DARWIN
+    (void)name;
+    (void)value;
+#else 
     if (name == "model") {
         fwmodel = value;
     }
+#endif 
 }
 
-void FirewireRecorder::SetOption(const QString &name, int value) {
-
+void FirewireRecorder::SetOption(const QString &name, int value) 
+{
+#ifdef CONFIG_DARWIN
+    (void)name;
+    (void)value;
+#else 
     if (name == "port") {
 	fwport = value;
     } else if (name == "node") {
@@ -233,8 +480,10 @@
             fwconnection = FIREWIRE_CONNECTION_P2P;
         }
     }
+#endif 
 }
 
+#ifndef CONFIG_DARWIN
 QString FirewireRecorder::FirewireSpeedString (int speed) {
     switch(speed) {
         case RAW1394_ISO_SPEED_100:
@@ -247,6 +496,7 @@
                return(QString("Invalid (%1)").arg(speed));
      }
 }
+#endif 
 
 // documented in recorderbase.cpp
 bool FirewireRecorder::PauseAndWait(int timeout)
@@ -255,7 +505,12 @@
     {
         if (!paused)
         {
+#ifdef CONFIG_DARWIN
+            VERBOSE(VB_RECORD, "Firewire: Stopping video stream");
+            this->capture_device->StopAVCDeviceStream(this->video_stream);
+#else 
             iec61883_mpeg2_recv_stop(fwmpeg);
+#endif 
             paused = true;
             pauseWait.wakeAll();
             if (tvrec)
@@ -265,7 +520,12 @@
     }
     if (!request_pause && paused)
     {
+#ifdef CONFIG_DARWIN
+        VERBOSE(VB_RECORD, "Firewire: Restarting video stream");
+        this->capture_device->StartAVCDeviceStream(this->video_stream);
+#else 
         iec61883_mpeg2_recv_start(fwmpeg, fwchannel);
+#endif 
         paused = false;
     }
     return paused;
Index: libs/libmythtv/tv_rec.h
===================================================================
--- libs/libmythtv/tv_rec.h	(revision 8516)
+++ libs/libmythtv/tv_rec.h	(working copy)
@@ -14,6 +14,8 @@
 #include "programinfo.h"
 #include "tv.h"
 
+#include "mythconfig.h"
+
 class QSocket;
 class NuppelVideoRecorder;
 class RingBuffer;
@@ -126,6 +128,13 @@
 };
 typedef MythDeque<TuningRequest> TuningQueue;
 
+#ifdef CONFIG_DARWIN
+namespace AVS
+{
+  class AVCDeviceController;
+}
+#endif
+ 
 class TVRec : public QObject
 {
     friend class TuningRequest;
@@ -220,6 +229,10 @@
     void RingBufferChanged(RingBuffer *rb, ProgramInfo *pginfo);
     void RecorderPaused(void);
 
+#ifdef CONFIG_DARWIN
+    AVS::AVCDeviceController* DemandDeviceController() const;
+#endif
+
   public slots:
     void SignalMonitorAllGood() { triggerEventLoop.wakeAll(); }
     void SetPMTObject(const PMTObject*) 
@@ -357,6 +370,10 @@
     QString      rbFilePrefix;
     QString      rbFileExt;
 
+#ifdef CONFIG_DARWIN
+    mutable AVS::AVCDeviceController* device_controller;
+#endif
+
   public:
     static const uint kEITScanStartTimeout;
     static const uint kSignalMonitoringRate;
Index: libs/libmythtv/firewirerecorder.h
===================================================================
--- libs/libmythtv/firewirerecorder.h	(revision 8516)
+++ libs/libmythtv/firewirerecorder.h	(working copy)
@@ -9,9 +9,22 @@
 
 #include "dtvrecorder.h"
 #include "mpeg/tspacket.h"
-#include <libraw1394/raw1394.h>
-#include <libiec61883/iec61883.h>
 
+#include "mythconfig.h"
+
+#ifdef CONFIG_DARWIN
+namespace AVS
+{
+  class AVCDeviceController;
+  class AVCDevice;
+  class StringLogger;
+  class AVCDeviceStream;
+}
+#else 
+# include <libraw1394/raw1394.h>
+# include <libiec61883/iec61883.h>
+#endif 
+
 #include <time.h>
 
 #define FIREWIRE_TIMEOUT 15
@@ -32,10 +45,19 @@
   public:
     FirewireRecorder(TVRec *rec) :
         DTVRecorder(rec, "FirewireRecorder"),
-        fwport(-1),     fwchannel(-1), fwspeed(-1),   fwbandwidth(-1),
+#ifdef CONFIG_DARWIN
+        capture_device(NULL),
+        message_log(NULL),
+        video_stream(NULL),
+#else
+        fwport(-1),     
+        fwchannel(-1), fwspeed(-1),   fwbandwidth(-1),
         fwfd(-1),       fwconnection(FIREWIRE_CONNECTION_P2P),
         fwoplug(-1),    fwiplug(-1),   fwmodel(""),   fwnode(0),
-        fwhandle(NULL), fwmpeg(NULL),  isopen(false), lastpacket(0) {;}
+        fwhandle(NULL), fwmpeg(NULL),  
+#endif 
+        isopen(false), lastpacket(0) 
+    {;}
         
     ~FirewireRecorder() { Close(); }
 
@@ -49,21 +71,37 @@
 
     void SetOption(const QString &name, const QString &value);
     void SetOption(const QString &name, int value);
+#ifndef CONFIG_DARWIN
     QString FirewireSpeedString(int speed);
+#endif 
 
     bool PauseAndWait(int timeout = 100);
 
   public slots:
     void deleteLater(void);
-        
+
   private:
     void Close(void);
-    int fwport, fwchannel, fwspeed, fwbandwidth, fwfd, fwconnection;
+
+#ifdef CONFIG_DARWIN
+    static void MPEGNoData(void*);
+
+    AVS::AVCDevice* capture_device;
+    AVS::StringLogger* message_log;
+    AVS::AVCDeviceStream* video_stream;
+#else 
+    int fwport;
+    int fwchannel;
+#endif 
+
+#ifndef CONFIG_DARWIN
+    int fwspeed, fwbandwidth, fwfd, fwconnection;
     int fwoplug, fwiplug;
     QString fwmodel;
     nodeid_t fwnode;
     raw1394handle_t fwhandle;
     iec61883_mpeg2_t fwmpeg;
+#endif 
     bool isopen;
     time_t lastpacket;
 };
Index: libs/libmyth/mythcontext.cpp
===================================================================
--- libs/libmyth/mythcontext.cpp	(revision 8516)
+++ libs/libmyth/mythcontext.cpp	(working copy)
@@ -290,20 +290,20 @@
     QDir prefixDir(appPath.left(appPath.findRev("/")));
 #endif
 
-    if (QDir(m_installprefix).isRelative())
+    if (prefixDir.path().contains(".app/Contents/MacOS"))
     {
+        prefixDir.cd("../Resources");
+        if (QDir(prefixDir.canonicalPath() + "/share").exists())
+            m_installprefix = prefixDir.canonicalPath();
+    }
+    else if (QDir(m_installprefix).isRelative())
+    {
         // If the PREFIX is relative, evaluate it relative to our
         // executable directory. This can be fragile on Unix, so
         // use relative PREFIX values with care.
         prefixDir.cd(m_installprefix);
         m_installprefix = prefixDir.canonicalPath();
     }
-    else if (prefixDir.path().contains(".app/Contents/MacOS"))
-    {
-        prefixDir.cd("../Resources");
-        if (QDir(prefixDir.canonicalPath() + "/share").exists())
-            m_installprefix = prefixDir.canonicalPath();
-    }
     VERBOSE(VB_ALL, QString("Using runtime prefix = %1")
             .arg(m_installprefix));
 }
Index: libs/libavcodec/libpostproc/postprocess.c
===================================================================
--- libs/libavcodec/libpostproc/postprocess.c	(revision 8516)
+++ libs/libavcodec/libpostproc/postprocess.c	(working copy)
@@ -113,6 +113,15 @@
 
 #if defined(__GNUC__) && (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ > 0)
 #    define attribute_used __attribute__((used))
+// This is completely broken; the MacOS headers (and, presumably,
+// other legitimate headers) use constructs like:
+// 
+//   static __inline__ __attribute__((always_inline)) 
+//   return_type function_name() { ... }
+// 
+// which naturally is disrupted by any attempt to #define
+// always_inline.  MythTv should use some other symbol for that
+// purpose, preferably an ALL_UPPERCASE symbol beginning with MYTH_
 #    define always_inline __attribute__((always_inline)) inline
 #else
 #    define attribute_used
Index: libs/libavutil/common.h
===================================================================
--- libs/libavutil/common.h	(revision 8516)
+++ libs/libavutil/common.h	(working copy)
@@ -67,6 +67,16 @@
 
 #ifndef always_inline
 #if defined(__GNUC__) && (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ > 0)
+// This is completely broken; the MacOS headers (and, presumably,
+// other legitimate headers) use constructs like:
+// 
+//   static __inline__ __attribute__((always_inline)) 
+//   return_type function_name() { ... }
+// 
+// which naturally is disrupted by any attempt to #define
+// always_inline.  MythTv should use some other symbol for that
+// purpose, preferably an ALL_UPPERCASE symbol beginning with MYTH_
+
 #    define always_inline __attribute__((always_inline)) inline
 #else
 #    define always_inline inline
Index: programs/programs-libs.pro
===================================================================
--- programs/programs-libs.pro	(revision 8516)
+++ programs/programs-libs.pro	(working copy)
@@ -1,3 +1,4 @@
+include ( ../../avcvideoservices.pro )
 INCLUDEPATH += ../../libs/ ../../libs/libmyth ../../libs/libmythtv  ../..
 INCLUDEPATH += ../../libs/libavutil ../../libs/libavformat ../../libs/libavcodec
 
@@ -22,4 +23,3 @@
 
 DEPENDPATH += ../../libs/libmyth ../../libs/libmythtv ../../libs/libsavcodec
 DEPENDPATH += ../../libs/libavutil ../../libs/libavformat
-
Index: contrib/osx-packager.pl
===================================================================
--- contrib/osx-packager.pl	(revision 8516)
+++ contrib/osx-packager.pl	(working copy)
@@ -153,7 +153,7 @@
 #   },
   {
     'url'
-    =>  'ftp://ftp.iasi.roedu.net/mirrors/ftp.trolltech.com/qt/sources/qt-mac-free-3.3.4.tar.gz',
+    =>  'ftp://ftp.iasi.roedu.net/mirrors/ftp.trolltech.com/qt/sources/qt-mac-free-3.3.5.tar.gz',
     'conf-cmd'
     =>  'echo yes | ./configure',
     'conf'
@@ -185,7 +185,13 @@
     =>  [
           'sub-src',
           'qmake-install',
-          'moc-install'
+          'moc-install',
+         
+         # we need this.  If the library isn't copied to
+         # $PREFIX/build/lib then it gets its references modified in
+         # place.  That will screw up linking the next time around, as
+         # the references can't be found in the expected location.
+          'src-install'
         ],
   },
   
@@ -205,6 +211,22 @@
     =>  [
           '--disable-nls',
         ],
+    'post-conf' 
+    # correct a bug that prevents compilation.  This patch is already
+    # in the exif developers' CVS repository.  Why they haven't
+    # released a new version with the fix, I don't know.
+    =>  'echo "--- libexif/libexif/libexif/exif-utils.c2005/03/10 20:48:211.10
++++ libexif/libexif/libexif/exif-utils.c2005/03/31 12:24:311.11
+@@ -83,7 +83,7 @@
+ }
+ }
+ 
+-static ExifSShort
++ExifSShort
+ exif_get_sshort (const unsigned char *buf, ExifByteOrder order)
+ {
+ if (!buf) return 0;
+" | patch -u --verbose libexif/exif-utils.c'
   },
   
 );
@@ -227,6 +249,10 @@
    -distclean       throw away all intermediate files and exit
    -thirdclean      do a clean rebuild of third party packages
    -thirdskip       don't rebuild the third party packages
+   -skip            don't rebuild MythTV
+   -tarball         make a tarball of the build directory ($PREFIX)
+   -forcemake       re-run all make steps
+   -forceconfigure  re-run all configure steps
    -clean           do a clean rebuild of MythTV
    -svnbranch <str> build a specified Subversion branch,   instead of HEAD
    -svnrev <str>    build a specified Subversion revision, instead of HEAD
@@ -292,6 +318,10 @@
                          'distclean',
                          'thirdclean',
                          'thirdskip',
+                         'skip',
+                         'tarball',
+                         'forcemake',
+                         'forceconfigure',
                          'clean',
                          'svnbranch=s',
                          'svnrev=s',
@@ -394,6 +424,8 @@
   'mythtv'
   =>  [
         '--prefix=' . $PREFIX,
+#       '--disable-firewire',
+#       '--disable-distcc',
       ],
 );
 
@@ -522,7 +554,7 @@
   
   # Configure
   chdir($dirname);
-  unless (-e '.osx-config')
+  unless (! $OPT{'forceconfigure'} && -e '.osx-config')
   {
     &Verbose("Configuring $sw");
     my (@configure, $munge);
@@ -556,7 +588,7 @@
   }
   
   # Build and install
-  unless (-e '.osx-built')
+  unless (! $OPT{'forcemake'} && -e '.osx-built')
   {
     &Verbose("Making $sw");
     my (@make);
@@ -581,7 +613,16 @@
 
 
 ### build MythTV
-
+if ( $OPT{'skip'} )
+{
+    &Verbose("Using previous install of MythTV");
+    if (-e "$PREFIX/../build.tar.gz")
+    {
+        &Syscall("cd $PREFIX/.. && tar xzf build.tar.gz");
+    }
+}
+else
+{
 # Clean any previously installed libraries
 &Verbose("Cleaning previous installs of MythTV");
 my @mythlibs = glob "$PREFIX/lib/libmyth*";
@@ -677,10 +718,13 @@
     &Verbose("Configuring $comp");
     my @config = './configure';
     push(@config, @{ $conf{$comp} }) if $conf{$comp};
+    # For debugging MythTV
+    # push @config, '--compile-type=debug';
     if ( $comp eq 'mythtv' && $backend )
     {
       push @config, '--enable-backend'
     }
+    push @config, '"'
     &Syscall([ @config ]) or die;
   }
   &Verbose("Running qmake for $comp");
@@ -719,7 +763,8 @@
   }
   
   &Verbose("Making $comp");
-  &Syscall([ '/usr/bin/make' ]) or die;
+#    &Syscall([ '/usr/bin/make' ]) or die;
+    &Syscall([ '/usr/bin/make -j5' ]) or die;
   # install
   # This requires a change from the compiled-in relative
   # PREFIX to our absolute path of the temp install location.
@@ -732,14 +777,22 @@
   &Verbose("Installing $comp");
   &Syscall([ '/usr/bin/make',
              'install' ]) or die;
+  }
 }
 
+symlink("$SRCDIR/myth-svn/mythtv/libs", "$PREFIX/lib/mythtv");
+
 ### Build version string
 our $VERS = `find $PREFIX/lib -name 'libmyth-[0-9].[0-9][0-9].[0-9].dylib'`;
 chomp $VERS;
 $VERS =~ s/^.*\-(.*)\.dylib$/$1/s;
 $VERS .= '.' . $OPT{'version'} if $OPT{'version'};
 
+if ( $OPT{'tarball'} )
+{
+  &Syscall("tar czf $PREFIX/../build.tar.gz $PREFIX");
+}
+    
 ### Create each package.
 ### Note that this is a bit of a waste of disk space,
 ### because there are now multiple copies of each library.
@@ -756,12 +809,10 @@
   # Get a fresh copy of the app
   &Verbose("Building self-contained $target");
   &Syscall([ 'rm', '-fr', $finalTarget ]) or die;
-  &Syscall([ '/bin/cp', '-R',
-             "$PREFIX/bin/$builtTarget.app",
-             $finalTarget ]) or die;
+  &RecursiveCopy("$PREFIX/bin/$builtTarget.app", $finalTarget);
   
   # write a custom Info.plist
-  &FrontendPlist($finalTarget, $VERS);
+  &AppPlist($finalTarget, $builtTarget, $VERS);
   
   # Make frameworks from Myth libraries
   &Verbose("Installing frameworks into $target");
@@ -791,13 +842,11 @@
   &Verbose("Installing resources into MythFrontend");
   mkdir "$finalTarget/Contents/Resources";
   mkdir "$finalTarget/Contents/Resources/lib";
-  &Syscall([ '/bin/cp', '-R',
-             "$PREFIX/lib/mythtv",
-             "$finalTarget/Contents/Resources/lib" ]) or die;
+  &RecursiveCopy("$PREFIX/lib/mythtv",
+                 "$finalTarget/Contents/Resources/lib");
   mkdir "$finalTarget/Contents/Resources/share";
-  &Syscall([ '/bin/cp', '-R',
-             "$PREFIX/share/mythtv",
-             "$finalTarget/Contents/Resources/share" ]) or die;
+  &RecursiveCopy( "$PREFIX/share/mythtv",
+                  "$finalTarget/Contents/Resources/share" );
  }
 }
 
@@ -813,7 +862,18 @@
 exit 0;
 
 
+sub RecursiveCopy
+{
+    my ($src, $dst) = @_;
 
+    &Syscall([ '/bin/cp', '-R', "$src", "$dst"]) or die;
+    my @files = map { chomp $_; $_ } `find . -name .svn`;
+    if (scalar @files)
+    {
+        &Syscall([ '/bin/rm', '-f', '-r', @files ]);
+    }
+}
+
 ######################################
 ## MakeFramework copies a dylib into a
 ## framework bundle.
@@ -880,14 +940,17 @@
 
 
 ######################################
-## FrontendPlist .
+## AppPlist .
 ######################################
 
-sub FrontendPlist
+sub AppPlist
 {
-  my ($path, $vers) = @_;
+  my ($path, $builttarget, $vers) = @_;
   
-  &Verbose("Writing Info.plist for MythFrontend");
+  my $bundlename = $path;
+  $bundlename =~ s|^(.*)([^/]*)[.]app$|$2|;
+
+  &Verbose("Writing Info.plist for $bundlename");
   my $plist;
   $path .= '/Contents/Info.plist';
   unless (open($plist, ">$path"))
@@ -901,11 +964,11 @@
 <plist version="1.0">
 <dict>
   <key>CFBundleExecutable</key>
-  <string>mythfrontend</string>
+  <string>$builttarget</string>
   <key>CFBundleIconFile</key>
   <string>application.icns</string>
   <key>CFBundleIdentifier</key>
-  <string>org.mythtv.macx.mythfrontend</string>
+  <string>org.mythtv.macx.$builttarget</string>
   <key>CFBundleInfoDictionaryVersion</key>
   <string>6.0</string>
   <key>CFBundlePackageType</key>
@@ -921,7 +984,7 @@
   <key>CFBundleGetInfoString</key>
   <string>$vers, MythTV project, www.mythtv.org</string>
   <key>CFBundleName</key>
-  <string>MythFrontend</string>
+  <string>$bundlename</string>
   <key>NSHumanReadableCopyright</key>
   <string>MythTV project, www.mythtv.org</string>
 </dict>
@@ -939,7 +1002,7 @@
 APPLMyth
 END
   close($plist);
-} # end FrontendPlist
+} # end AppPlist
 
 ######################################
 ## FindLibraryFile locates a dylib.
@@ -984,8 +1047,11 @@
       chomp $dep;
       $dep =~ s/\s+(.*) \(.*\)$/$1/;
       
+      # /usr/lib/libstdc++, for example, contains quantifiers that must be escaped
+      $dep =~ s/([+*?])/\\$1/;
+      
       # otool sometimes lists the framework as depending on itself
-      next if ($file =~ m,/Versions/A/$dep,);
+      next if ($file =~ m|/Versions/A/$dep|);
 
       # Any dependency which is already package relative can be ignored
       next if $dep =~ m/[EMAIL PROTECTED]/;
@@ -1149,7 +1215,7 @@
     my $device = HDImageDevice();
     if ($device)
     {
-        System('hdiutil', 'detach', $device, '-force');
+#        Syscall(['hdiutil', 'detach', $device, '-force']);
     }
 }
 
Index: setup/setup.pro
===================================================================
--- setup/setup.pro	(revision 8516)
+++ setup/setup.pro	(working copy)
@@ -1,5 +1,6 @@
 include ( ../config.mak )
 include ( ../settings.pro )
+include ( ../avcvideoservices.pro )
 
 TEMPLATE = app
 CONFIG += thread
Enjoy,
Dave

-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com
_______________________________________________
mythtv-dev mailing list
[email protected]
http://mythtv.org/cgi-bin/mailman/listinfo/mythtv-dev

Reply via email to