diff --git a/mythtv/filters/yadif/yadif.pro b/mythtv/filters/yadif/yadif.pro
index 8d679a8..b9aa60f 100644
--- a/mythtv/filters/yadif/yadif.pro
+++ b/mythtv/filters/yadif/yadif.pro
@@ -12,3 +12,7 @@ contains(ARCH_X86, yes) {
 }
 
 macx:debug:DEFINES -= MMX
+macx {
+	CC            = gcc-4.0
+	CXX           = g++-4.0
+}
diff --git a/mythtv/libs/libmythtv/decoderbase.h b/mythtv/libs/libmythtv/decoderbase.h
index fe16fe9..d936b24 100644
--- a/mythtv/libs/libmythtv/decoderbase.h
+++ b/mythtv/libs/libmythtv/decoderbase.h
@@ -18,7 +18,7 @@ class TeletextViewer;
 class MythPlayer;
 class AudioPlayer;
 
-const int kDecoderProbeBufferSize = 256 * 1024;
+const int kDecoderProbeBufferSize = 65536;
 
 /// Track types
 typedef enum TrackTypes
diff --git a/mythtv/libs/libmythui/AppleRemote.cpp b/mythtv/libs/libmythui/AppleRemote.cpp
index 76d9e34..c3bb946 100644
--- a/mythtv/libs/libmythui/AppleRemote.cpp
+++ b/mythtv/libs/libmythui/AppleRemote.cpp
@@ -6,6 +6,7 @@
 #include <stdlib.h>
 #include <ctype.h>
 #include <sys/errno.h>
+#include <sys/sysctl.h>
 #include <sysexits.h>
 #include <mach/mach.h>
 #include <mach/mach_error.h>
@@ -14,16 +15,31 @@
 #include <IOKit/hid/IOHIDLib.h>
 #include <IOKit/hid/IOHIDKeys.h>
 #include <CoreFoundation/CoreFoundation.h>
+#include <CoreServices/CoreServices.h>
 
 #include <sstream>
+#include <QTimer>
+
+
 
 #include "mythverbose.h"
 
 AppleRemote*      AppleRemote::_instance = 0;
 const int         AppleRemote::REMOTE_SWITCH_COOKIE = 19;
+// For ATV v2.3 onwards
+const int         LONG_PRESS_COUNT = 10;
+const int         KEY_RESPONSE_TIME = 150;  // msecs before we send a key up event
 
 const QString     LOC = "AppleRemote::";
 
+typedef struct _ATV_IR_EVENT {
+    UInt32    time_ms32;
+    UInt32    time_ls32; // units of microsecond
+    UInt32    unknown1;
+    UInt32    keycode;
+    UInt32    unknown2;
+} ATV_IR_EVENT;
+
 static io_object_t _findAppleRemoteDevice(const char *devName);
 
 AppleRemote::Listener::~Listener()
@@ -41,6 +57,8 @@ AppleRemote * AppleRemote::Get()
 AppleRemote::~AppleRemote()
 {
     stopListening();
+    if (usingNewAtv)
+        delete mCallbackTimer;
 }
 
 bool AppleRemote::isListeningToRemote()
@@ -108,8 +126,55 @@ AppleRemote::AppleRemote() : openInExclusiveMode(true),
                              hidDeviceInterface(0),
                              queue(0),
                              remoteId(0),
-                             _listener(0)
+                             _listener(0),
+                             usingNewAtv(false),
+                             mLastEvent(AppleRemote::Undefined),
+                             mEventCount(0),
+                             mKeyIsDown(false)
 {
+    SInt32 macVersion;
+    size_t len = 512;
+    char hw_model[512] = "unknown";
+
+    // Figure out if we're running on the Apple TV, past version 2.3
+    Gestalt(gestaltSystemVersion, &macVersion);
+
+
+    if (macVersion < 0x1050) // OSX 10.4 / AppleTV
+    {
+        sysctlbyname("hw.model", &hw_model, &len, NULL, 0);
+
+        if ( strstr(hw_model,"AppleTV1,1") )
+        {
+            FILE* inpipe;
+
+            //Find the build version of the AppleTV OS
+            inpipe = popen("sw_vers -buildVersion", "r");
+            char linebuf[1000];
+            if (inpipe)
+            {
+                if ( fgets(linebuf, sizeof(linebuf) - 1, inpipe) )
+                {
+                    if ( !( strstr(linebuf,"8N5107") || // v1.0
+                            strstr(linebuf,"8N5239") || // v1.1
+                            strstr(linebuf,"8N5400") || // v2.0
+                            strstr(linebuf,"8N5455") || // v2.01
+                            strstr(linebuf,"8N5461") || // v2.02
+                            strstr(linebuf,"8N5519") || // v2.1
+                            strstr(linebuf,"8N5622") )) // v2.2
+                    {
+                        VERBOSE(VB_IMPORTANT, LOC + "::AppleRemote detected Apple TV > v2.3");
+                        usingNewAtv = true;
+                        mCallbackTimer = new QTimer(this);
+                        connect(mCallbackTimer, SIGNAL(timeout()), this, SLOT(TimeoutHandler()));
+                        mCallbackTimer->setSingleShot(true);
+                        mCallbackTimer->setInterval(KEY_RESPONSE_TIME);
+                    }
+                }
+            }
+            pclose(inpipe);
+        }
+    }
     _initCookieMap();
 }
 
@@ -124,6 +189,8 @@ AppleRemote::AppleRemote() : openInExclusiveMode(true),
 ///
 void AppleRemote::_initCookieMap()
 {
+    if (!usingNewAtv)
+    {
     // 10.4 sequences:
     cookieToButtonMapping["14_12_11_6_5_"]        = Up;
     cookieToButtonMapping["14_13_11_6_5_"]        = Down;
@@ -175,12 +242,6 @@ void AppleRemote::_initCookieMap()
     cookieToButtonMapping["19_15_19_15_"]         = PlayHold;
 
     // ATV 2.30
-    cookieToButtonMapping["80"]                   = Up;
-    cookieToButtonMapping["48"]                   = Down;
-    cookieToButtonMapping["64"]                   = Menu;
-    cookieToButtonMapping["32"]                   = Select;
-    cookieToButtonMapping["96"]                   = Right;
-    cookieToButtonMapping["16"]                   = Left;
 
     // 10.6 sequences:
     cookieToButtonMapping["33_31_30_21_20_2_"]            = Up;
@@ -198,6 +259,17 @@ void AppleRemote::_initCookieMap()
     cookieToButtonMapping["33_21_20_8_2_33_21_20_8_2_"]   = PlayPause;
     cookieToButtonMapping["33_21_20_3_2_33_21_20_3_2_"]   = Select;
     cookieToButtonMapping["33_21_20_11_2_33_21_20_11_2_"] = PlayHold;
+    }
+    else
+    {
+        // ATV 2.30
+        cookieToButtonMapping["17_9_280_80"]                   = Up;
+        cookieToButtonMapping["17_9_280_48"]                   = Down;
+        cookieToButtonMapping["17_9_280_64"]                   = Menu;
+        cookieToButtonMapping["17_9_280_32"]                   = Select;
+        cookieToButtonMapping["17_9_280_96"]                   = Right;
+        cookieToButtonMapping["17_9_280_16"]                   = Left;
+    }
 }
 
 static io_object_t _findAppleRemoteDevice(const char *devName)
@@ -373,39 +445,207 @@ void AppleRemote::_queueCallbackFunction(IOReturn result,
     SInt32            sumOfValues = 0;
     std::stringstream cookieString;
 
-    while (result == kIOReturnSuccess)
+    if (!usingNewAtv)
     {
-        IOHIDEventStruct event;
+        while (result == kIOReturnSuccess)
+        {
+            IOHIDEventStruct event;
+
+            result = (*queue)->getNextEvent(queue, &event, zeroTime, 0);
+            if (result != kIOReturnSuccess)
+                break;
+
+            if (REMOTE_SWITCH_COOKIE == (int)event.elementCookie)
+            {
+                remoteId=event.value;
+                _handleEventWithCookieString("19_",0);
+            }
+            else
+            {
+                sumOfValues+=event.value;
+                cookieString << std::dec << (int)event.elementCookie << "_";
+            }
+        }
+        _handleEventWithCookieString(cookieString.str(), sumOfValues);
+    }
+    else // AppleTV from v2.3 onwards
+    {
+        if (mCallbackTimer->isActive())
+        {
+            mCallbackTimer->stop();
+        }
 
-        result = (*queue)->getNextEvent(queue, &event, zeroTime, 0);
-        if (result != kIOReturnSuccess)
-            break;
+        IOHIDEventStruct event;
+        UInt32 key_code = 0;
 
-        if (REMOTE_SWITCH_COOKIE == (int)event.elementCookie)
+        while (result == kIOReturnSuccess)
         {
-            remoteId=event.value;
-            _handleEventWithCookieString("19_",0);
+            result = (*queue)->getNextEvent(queue, &event, zeroTime, 0);
+            if (result != kIOReturnSuccess) {
+                continue;
+            }
+
+            if ( ((int)event.elementCookie == 280) && (event.longValueSize == 20)) {
+                ATV_IR_EVENT* atv_ir_event = (ATV_IR_EVENT*)event.longValue;
+                key_code = atv_ir_event->keycode;
+            }
+
+            if (((int)event.elementCookie) != 5 ) {
+                sumOfValues += event.value;
+                cookieString << std::dec << (int)event.elementCookie << "_";
+            }
         }
-        else
-        {
-            sumOfValues+=event.value;
-            cookieString << std::dec << (int)event.elementCookie << "_";
+        char endCode[10] = "17_9_280_";
+        if (strcmp(cookieString.str().c_str(), endCode) == 0) {
+
+            cookieString << std::dec << (int) ( (key_code & 0x00007F00) >> 8);
+
+            sumOfValues = 1;
+            _handleEventWithCookieString(cookieString.str(), sumOfValues);
         }
     }
-
-    _handleEventWithCookieString(cookieString.str(), sumOfValues);
 }
 
 void AppleRemote::_handleEventWithCookieString(std::string cookieString,
-                                          SInt32 sumOfValues)
+                                                SInt32 sumOfValues)
 {
     std::map<std::string,AppleRemote::Event>::iterator ii;
 
     ii = cookieToButtonMapping.find(cookieString);
-    if (ii != cookieToButtonMapping.end() && _listener)
+
+
+    if (ii != cookieToButtonMapping.end() )
+    {
+        AppleRemote::Event event = ii->second;
+
+        if (!usingNewAtv) {
+            if (_listener)
+            {
+                _listener->appleRemoteButton(event, sumOfValues>0);
+            }
+        }
+        else
+        {
+            // With the ATV from 2.3 onwards, we just get IR events. We need to simulate the
+            // key up and hold events
+
+            if (mLastEvent == Undefined)    // new event
+            {
+                mEventCount = 1;
+                // Need to figure out if this is a long press or a short press,
+                // so can't just send a key down event right now. It will be
+                // scheduled to run
+            }
+            else if (event != mLastEvent)   // a new event, faster than timer
+            {
+                mEventCount = 1;
+                mKeyIsDown = true;
+
+                if (_listener)
+                {
+                    // Only send key up events for events that have separateRelease
+                    // defined as true in AppleRemoteListener.cpp
+                    if (mLastEvent == Up || mLastEvent == Down ||
+                        mLastEvent == LeftHold || mLastEvent == RightHold)
+                    {
+                        _listener->appleRemoteButton(mLastEvent, /*pressedDown*/false);
+                    }
+                    _listener->appleRemoteButton(event, mKeyIsDown);
+                }
+            }
+            else // Same event again
+            {
+                mEventCount+=1;
+                AppleRemote::Event newEvent = Undefined;
+
+                // Can the event have a hold state?
+                switch (event)
+                {
+                    case Right:
+                        newEvent = RightHold;
+                        break;
+                    case Left:
+                        newEvent = LeftHold;
+                        break;
+                    case Menu:
+                        newEvent = MenuHold;
+                        break;
+                    case Select:
+                        newEvent = PlayHold;
+                        break;
+                    default:
+                        newEvent = event;
+                }
+
+                if (newEvent == event) // Doesn't have a long press
+                {
+                    if (mKeyIsDown)
+                    {
+                        if (_listener)
+                        {
+                            // Only send key up events for events that have separateRelease
+                            // defined as true in AppleRemoteListener.cpp
+                            if (mLastEvent == Up || mLastEvent == Down ||
+                                mLastEvent == LeftHold || mLastEvent == RightHold)
+                            {
+                                _listener->appleRemoteButton(mLastEvent, /*pressedDown*/false);
+                            }
+                        }
+                    }
+
+                    mKeyIsDown = true;
+                    if (_listener)
+                    {
+                        _listener->appleRemoteButton(newEvent, mKeyIsDown);
+                    }
+                }
+                else if (mEventCount == LONG_PRESS_COUNT)
+                {
+                    mKeyIsDown = true;
+                    if (_listener)
+                    {
+                        _listener->appleRemoteButton(newEvent, mKeyIsDown);
+                    }
+                }
+            }
+
+            mLastEvent = event;
+            mCallbackTimer->start();
+        }
+    }
+}
+
+// Calls key down / up events on the ATV > v2.3
+void AppleRemote::TimeoutHandler()
+{
+    if (_listener)
     {
-        AppleRemote::Event buttonid = ii->second;
-        if (_listener)
-            _listener->appleRemoteButton(buttonid, sumOfValues>0);
+        _listener->appleRemoteButton(mLastEvent, !mKeyIsDown);
+    }
+
+    mKeyIsDown = !mKeyIsDown;
+
+    if (!mKeyIsDown)
+    {
+        mEventCount = 0;
+        mLastEvent = Undefined;
+    }
+    else
+    {
+        // Schedule a key up event for events that have separateRelease
+        // defined as true in AppleRemoteListener.cpp
+
+        if (mLastEvent == Up || mLastEvent == Down ||
+            mLastEvent == LeftHold || mLastEvent == RightHold)
+        {
+            mCallbackTimer->start();
+        }
+        else
+        {
+            mKeyIsDown = false;
+            mEventCount = 0;
+            mLastEvent = Undefined;
+        }
+
     }
 }
diff --git a/mythtv/libs/libmythui/AppleRemote.h b/mythtv/libs/libmythui/AppleRemote.h
index 23b43a3..419e5e5 100644
--- a/mythtv/libs/libmythui/AppleRemote.h
+++ b/mythtv/libs/libmythui/AppleRemote.h
@@ -5,6 +5,7 @@
 #include <vector>
 #include <map>
 #include <QThread>
+#include <QTimer>
 
 #include <IOKit/IOKitLib.h>
 #include <IOKit/IOCFPlugIn.h>
@@ -14,6 +15,7 @@
 
 class AppleRemote : public QThread
 {
+    Q_OBJECT
 public:
     enum Event
     { // label/meaning on White ... and Aluminium remote
@@ -28,7 +30,8 @@ public:
         MenuHold,
         PlayHold,  // was PlaySleep
         ControlSwitched,
-        PlayPause      // Play or Pause
+        PlayPause,      // Play or Pause
+        Undefined       // Used to handle the Apple TV > v2.3
     };
 
     class Listener
@@ -66,17 +69,28 @@ private:
     int                    remoteId;
     Listener*              _listener;
 
+    bool                   usingNewAtv;
+    AppleRemote::Event     mLastEvent;
+    int                    mEventCount;
+    bool                   mKeyIsDown;
+    QTimer*                mCallbackTimer;
+
     void        _initCookieMap();
     bool        _initCookies();
     bool        _createDeviceInterface(io_object_t hidDevice);
     bool        _openDevice();
 
-    static void QueueCallbackFunction(void* target, IOReturn result, 
+    static void QueueCallbackFunction(void* target, IOReturn result,
                                       void* refcon, void* sender);
     void        _queueCallbackFunction(IOReturn result,
                                        void* refcon, void* sender);
     void        _handleEventWithCookieString(std::string cookieString,
                                              SInt32 sumOfValues);
+
+private slots:
+    // Key event handling on the ATV v2.3 and above
+    void        TimeoutHandler();
+
 };
 
 #endif // APPLEREMOTE
diff --git a/mythtv/libs/libmythui/libmythui.pro b/mythtv/libs/libmythui/libmythui.pro
index 2b9ac75..c139e69 100644
--- a/mythtv/libs/libmythui/libmythui.pro
+++ b/mythtv/libs/libmythui/libmythui.pro
@@ -2,7 +2,7 @@ include ( ../../settings.pro )
 
 TEMPLATE = lib
 TARGET = mythui-$$LIBVERSION
-CONFIG += thread dll
+CONFIG += qt thread dll
 target.path = $${LIBDIR}
 INSTALLS = target
 
