Ticket #6422: head.diff

File head.diff, 15.6 KB (added by emlyn.bolton@…, 13 years ago)

UNTESTED patch to head revision for fix with ATV >v 2.3

  • mythtv/filters/yadif/yadif.pro

    diff --git a/mythtv/filters/yadif/yadif.pro b/mythtv/filters/yadif/yadif.pro
    index 8d679a8..b9aa60f 100644
    a b contains(ARCH_X86, yes) { 
    1212}
    1313
    1414macx:debug:DEFINES -= MMX
     15macx {
     16        CC            = gcc-4.0
     17        CXX           = g++-4.0
     18}
  • mythtv/libs/libmythtv/decoderbase.h

    diff --git a/mythtv/libs/libmythtv/decoderbase.h b/mythtv/libs/libmythtv/decoderbase.h
    index fe16fe9..d936b24 100644
    a b class TeletextViewer; 
    1818class MythPlayer;
    1919class AudioPlayer;
    2020
    21 const int kDecoderProbeBufferSize = 256 * 1024;
     21const int kDecoderProbeBufferSize = 65536;
    2222
    2323/// Track types
    2424typedef enum TrackTypes
  • mythtv/libs/libmythui/AppleRemote.cpp

    diff --git a/mythtv/libs/libmythui/AppleRemote.cpp b/mythtv/libs/libmythui/AppleRemote.cpp
    index 76d9e34..c3bb946 100644
    a b  
    66#include <stdlib.h>
    77#include <ctype.h>
    88#include <sys/errno.h>
     9#include <sys/sysctl.h>
    910#include <sysexits.h>
    1011#include <mach/mach.h>
    1112#include <mach/mach_error.h>
     
    1415#include <IOKit/hid/IOHIDLib.h>
    1516#include <IOKit/hid/IOHIDKeys.h>
    1617#include <CoreFoundation/CoreFoundation.h>
     18#include <CoreServices/CoreServices.h>
    1719
    1820#include <sstream>
     21#include <QTimer>
     22
     23
    1924
    2025#include "mythverbose.h"
    2126
    2227AppleRemote*      AppleRemote::_instance = 0;
    2328const int         AppleRemote::REMOTE_SWITCH_COOKIE = 19;
     29// For ATV v2.3 onwards
     30const int         LONG_PRESS_COUNT = 10;
     31const int         KEY_RESPONSE_TIME = 150;  // msecs before we send a key up event
    2432
    2533const QString     LOC = "AppleRemote::";
    2634
     35typedef struct _ATV_IR_EVENT {
     36    UInt32    time_ms32;
     37    UInt32    time_ls32; // units of microsecond
     38    UInt32    unknown1;
     39    UInt32    keycode;
     40    UInt32    unknown2;
     41} ATV_IR_EVENT;
     42
    2743static io_object_t _findAppleRemoteDevice(const char *devName);
    2844
    2945AppleRemote::Listener::~Listener()
    AppleRemote * AppleRemote::Get() 
    4157AppleRemote::~AppleRemote()
    4258{
    4359    stopListening();
     60    if (usingNewAtv)
     61        delete mCallbackTimer;
    4462}
    4563
    4664bool AppleRemote::isListeningToRemote()
    AppleRemote::AppleRemote() : openInExclusiveMode(true), 
    108126                             hidDeviceInterface(0),
    109127                             queue(0),
    110128                             remoteId(0),
    111                              _listener(0)
     129                             _listener(0),
     130                             usingNewAtv(false),
     131                             mLastEvent(AppleRemote::Undefined),
     132                             mEventCount(0),
     133                             mKeyIsDown(false)
    112134{
     135    SInt32 macVersion;
     136    size_t len = 512;
     137    char hw_model[512] = "unknown";
     138
     139    // Figure out if we're running on the Apple TV, past version 2.3
     140    Gestalt(gestaltSystemVersion, &macVersion);
     141
     142
     143    if (macVersion < 0x1050) // OSX 10.4 / AppleTV
     144    {
     145        sysctlbyname("hw.model", &hw_model, &len, NULL, 0);
     146
     147        if ( strstr(hw_model,"AppleTV1,1") )
     148        {
     149            FILE* inpipe;
     150
     151            //Find the build version of the AppleTV OS
     152            inpipe = popen("sw_vers -buildVersion", "r");
     153            char linebuf[1000];
     154            if (inpipe)
     155            {
     156                if ( fgets(linebuf, sizeof(linebuf) - 1, inpipe) )
     157                {
     158                    if ( !( strstr(linebuf,"8N5107") || // v1.0
     159                            strstr(linebuf,"8N5239") || // v1.1
     160                            strstr(linebuf,"8N5400") || // v2.0
     161                            strstr(linebuf,"8N5455") || // v2.01
     162                            strstr(linebuf,"8N5461") || // v2.02
     163                            strstr(linebuf,"8N5519") || // v2.1
     164                            strstr(linebuf,"8N5622") )) // v2.2
     165                    {
     166                        VERBOSE(VB_IMPORTANT, LOC + "::AppleRemote detected Apple TV > v2.3");
     167                        usingNewAtv = true;
     168                        mCallbackTimer = new QTimer(this);
     169                        connect(mCallbackTimer, SIGNAL(timeout()), this, SLOT(TimeoutHandler()));
     170                        mCallbackTimer->setSingleShot(true);
     171                        mCallbackTimer->setInterval(KEY_RESPONSE_TIME);
     172                    }
     173                }
     174            }
     175            pclose(inpipe);
     176        }
     177    }
    113178    _initCookieMap();
    114179}
    115180
    AppleRemote::AppleRemote() : openInExclusiveMode(true), 
    124189///
    125190void AppleRemote::_initCookieMap()
    126191{
     192    if (!usingNewAtv)
     193    {
    127194    // 10.4 sequences:
    128195    cookieToButtonMapping["14_12_11_6_5_"]        = Up;
    129196    cookieToButtonMapping["14_13_11_6_5_"]        = Down;
    void AppleRemote::_initCookieMap() 
    175242    cookieToButtonMapping["19_15_19_15_"]         = PlayHold;
    176243
    177244    // ATV 2.30
    178     cookieToButtonMapping["80"]                   = Up;
    179     cookieToButtonMapping["48"]                   = Down;
    180     cookieToButtonMapping["64"]                   = Menu;
    181     cookieToButtonMapping["32"]                   = Select;
    182     cookieToButtonMapping["96"]                   = Right;
    183     cookieToButtonMapping["16"]                   = Left;
    184245
    185246    // 10.6 sequences:
    186247    cookieToButtonMapping["33_31_30_21_20_2_"]            = Up;
    void AppleRemote::_initCookieMap() 
    198259    cookieToButtonMapping["33_21_20_8_2_33_21_20_8_2_"]   = PlayPause;
    199260    cookieToButtonMapping["33_21_20_3_2_33_21_20_3_2_"]   = Select;
    200261    cookieToButtonMapping["33_21_20_11_2_33_21_20_11_2_"] = PlayHold;
     262    }
     263    else
     264    {
     265        // ATV 2.30
     266        cookieToButtonMapping["17_9_280_80"]                   = Up;
     267        cookieToButtonMapping["17_9_280_48"]                   = Down;
     268        cookieToButtonMapping["17_9_280_64"]                   = Menu;
     269        cookieToButtonMapping["17_9_280_32"]                   = Select;
     270        cookieToButtonMapping["17_9_280_96"]                   = Right;
     271        cookieToButtonMapping["17_9_280_16"]                   = Left;
     272    }
    201273}
    202274
    203275static io_object_t _findAppleRemoteDevice(const char *devName)
    void AppleRemote::_queueCallbackFunction(IOReturn result, 
    373445    SInt32            sumOfValues = 0;
    374446    std::stringstream cookieString;
    375447
    376     while (result == kIOReturnSuccess)
     448    if (!usingNewAtv)
    377449    {
    378         IOHIDEventStruct event;
     450        while (result == kIOReturnSuccess)
     451        {
     452            IOHIDEventStruct event;
     453
     454            result = (*queue)->getNextEvent(queue, &event, zeroTime, 0);
     455            if (result != kIOReturnSuccess)
     456                break;
     457
     458            if (REMOTE_SWITCH_COOKIE == (int)event.elementCookie)
     459            {
     460                remoteId=event.value;
     461                _handleEventWithCookieString("19_",0);
     462            }
     463            else
     464            {
     465                sumOfValues+=event.value;
     466                cookieString << std::dec << (int)event.elementCookie << "_";
     467            }
     468        }
     469        _handleEventWithCookieString(cookieString.str(), sumOfValues);
     470    }
     471    else // AppleTV from v2.3 onwards
     472    {
     473        if (mCallbackTimer->isActive())
     474        {
     475            mCallbackTimer->stop();
     476        }
    379477
    380         result = (*queue)->getNextEvent(queue, &event, zeroTime, 0);
    381         if (result != kIOReturnSuccess)
    382             break;
     478        IOHIDEventStruct event;
     479        UInt32 key_code = 0;
    383480
    384         if (REMOTE_SWITCH_COOKIE == (int)event.elementCookie)
     481        while (result == kIOReturnSuccess)
    385482        {
    386             remoteId=event.value;
    387             _handleEventWithCookieString("19_",0);
     483            result = (*queue)->getNextEvent(queue, &event, zeroTime, 0);
     484            if (result != kIOReturnSuccess) {
     485                continue;
     486            }
     487
     488            if ( ((int)event.elementCookie == 280) && (event.longValueSize == 20)) {
     489                ATV_IR_EVENT* atv_ir_event = (ATV_IR_EVENT*)event.longValue;
     490                key_code = atv_ir_event->keycode;
     491            }
     492
     493            if (((int)event.elementCookie) != 5 ) {
     494                sumOfValues += event.value;
     495                cookieString << std::dec << (int)event.elementCookie << "_";
     496            }
    388497        }
    389         else
    390         {
    391             sumOfValues+=event.value;
    392             cookieString << std::dec << (int)event.elementCookie << "_";
     498        char endCode[10] = "17_9_280_";
     499        if (strcmp(cookieString.str().c_str(), endCode) == 0) {
     500
     501            cookieString << std::dec << (int) ( (key_code & 0x00007F00) >> 8);
     502
     503            sumOfValues = 1;
     504            _handleEventWithCookieString(cookieString.str(), sumOfValues);
    393505        }
    394506    }
    395 
    396     _handleEventWithCookieString(cookieString.str(), sumOfValues);
    397507}
    398508
    399509void AppleRemote::_handleEventWithCookieString(std::string cookieString,
    400                                           SInt32 sumOfValues)
     510                                                SInt32 sumOfValues)
    401511{
    402512    std::map<std::string,AppleRemote::Event>::iterator ii;
    403513
    404514    ii = cookieToButtonMapping.find(cookieString);
    405     if (ii != cookieToButtonMapping.end() && _listener)
     515
     516
     517    if (ii != cookieToButtonMapping.end() )
     518    {
     519        AppleRemote::Event event = ii->second;
     520
     521        if (!usingNewAtv) {
     522            if (_listener)
     523            {
     524                _listener->appleRemoteButton(event, sumOfValues>0);
     525            }
     526        }
     527        else
     528        {
     529            // With the ATV from 2.3 onwards, we just get IR events. We need to simulate the
     530            // key up and hold events
     531
     532            if (mLastEvent == Undefined)    // new event
     533            {
     534                mEventCount = 1;
     535                // Need to figure out if this is a long press or a short press,
     536                // so can't just send a key down event right now. It will be
     537                // scheduled to run
     538            }
     539            else if (event != mLastEvent)   // a new event, faster than timer
     540            {
     541                mEventCount = 1;
     542                mKeyIsDown = true;
     543
     544                if (_listener)
     545                {
     546                    // Only send key up events for events that have separateRelease
     547                    // defined as true in AppleRemoteListener.cpp
     548                    if (mLastEvent == Up || mLastEvent == Down ||
     549                        mLastEvent == LeftHold || mLastEvent == RightHold)
     550                    {
     551                        _listener->appleRemoteButton(mLastEvent, /*pressedDown*/false);
     552                    }
     553                    _listener->appleRemoteButton(event, mKeyIsDown);
     554                }
     555            }
     556            else // Same event again
     557            {
     558                mEventCount+=1;
     559                AppleRemote::Event newEvent = Undefined;
     560
     561                // Can the event have a hold state?
     562                switch (event)
     563                {
     564                    case Right:
     565                        newEvent = RightHold;
     566                        break;
     567                    case Left:
     568                        newEvent = LeftHold;
     569                        break;
     570                    case Menu:
     571                        newEvent = MenuHold;
     572                        break;
     573                    case Select:
     574                        newEvent = PlayHold;
     575                        break;
     576                    default:
     577                        newEvent = event;
     578                }
     579
     580                if (newEvent == event) // Doesn't have a long press
     581                {
     582                    if (mKeyIsDown)
     583                    {
     584                        if (_listener)
     585                        {
     586                            // Only send key up events for events that have separateRelease
     587                            // defined as true in AppleRemoteListener.cpp
     588                            if (mLastEvent == Up || mLastEvent == Down ||
     589                                mLastEvent == LeftHold || mLastEvent == RightHold)
     590                            {
     591                                _listener->appleRemoteButton(mLastEvent, /*pressedDown*/false);
     592                            }
     593                        }
     594                    }
     595
     596                    mKeyIsDown = true;
     597                    if (_listener)
     598                    {
     599                        _listener->appleRemoteButton(newEvent, mKeyIsDown);
     600                    }
     601                }
     602                else if (mEventCount == LONG_PRESS_COUNT)
     603                {
     604                    mKeyIsDown = true;
     605                    if (_listener)
     606                    {
     607                        _listener->appleRemoteButton(newEvent, mKeyIsDown);
     608                    }
     609                }
     610            }
     611
     612            mLastEvent = event;
     613            mCallbackTimer->start();
     614        }
     615    }
     616}
     617
     618// Calls key down / up events on the ATV > v2.3
     619void AppleRemote::TimeoutHandler()
     620{
     621    if (_listener)
    406622    {
    407         AppleRemote::Event buttonid = ii->second;
    408         if (_listener)
    409             _listener->appleRemoteButton(buttonid, sumOfValues>0);
     623        _listener->appleRemoteButton(mLastEvent, !mKeyIsDown);
     624    }
     625
     626    mKeyIsDown = !mKeyIsDown;
     627
     628    if (!mKeyIsDown)
     629    {
     630        mEventCount = 0;
     631        mLastEvent = Undefined;
     632    }
     633    else
     634    {
     635        // Schedule a key up event for events that have separateRelease
     636        // defined as true in AppleRemoteListener.cpp
     637
     638        if (mLastEvent == Up || mLastEvent == Down ||
     639            mLastEvent == LeftHold || mLastEvent == RightHold)
     640        {
     641            mCallbackTimer->start();
     642        }
     643        else
     644        {
     645            mKeyIsDown = false;
     646            mEventCount = 0;
     647            mLastEvent = Undefined;
     648        }
     649
    410650    }
    411651}
  • mythtv/libs/libmythui/AppleRemote.h

    diff --git a/mythtv/libs/libmythui/AppleRemote.h b/mythtv/libs/libmythui/AppleRemote.h
    index 23b43a3..419e5e5 100644
    a b  
    55#include <vector>
    66#include <map>
    77#include <QThread>
     8#include <QTimer>
    89
    910#include <IOKit/IOKitLib.h>
    1011#include <IOKit/IOCFPlugIn.h>
     
    1415
    1516class AppleRemote : public QThread
    1617{
     18    Q_OBJECT
    1719public:
    1820    enum Event
    1921    { // label/meaning on White ... and Aluminium remote
    public: 
    2830        MenuHold,
    2931        PlayHold,  // was PlaySleep
    3032        ControlSwitched,
    31         PlayPause      // Play or Pause
     33        PlayPause,      // Play or Pause
     34        Undefined       // Used to handle the Apple TV > v2.3
    3235    };
    3336
    3437    class Listener
    private: 
    6669    int                    remoteId;
    6770    Listener*              _listener;
    6871
     72    bool                   usingNewAtv;
     73    AppleRemote::Event     mLastEvent;
     74    int                    mEventCount;
     75    bool                   mKeyIsDown;
     76    QTimer*                mCallbackTimer;
     77
    6978    void        _initCookieMap();
    7079    bool        _initCookies();
    7180    bool        _createDeviceInterface(io_object_t hidDevice);
    7281    bool        _openDevice();
    7382
    74     static void QueueCallbackFunction(void* target, IOReturn result, 
     83    static void QueueCallbackFunction(void* target, IOReturn result,
    7584                                      void* refcon, void* sender);
    7685    void        _queueCallbackFunction(IOReturn result,
    7786                                       void* refcon, void* sender);
    7887    void        _handleEventWithCookieString(std::string cookieString,
    7988                                             SInt32 sumOfValues);
     89
     90private slots:
     91    // Key event handling on the ATV v2.3 and above
     92    void        TimeoutHandler();
     93
    8094};
    8195
    8296#endif // APPLEREMOTE
  • mythtv/libs/libmythui/libmythui.pro

    diff --git a/mythtv/libs/libmythui/libmythui.pro b/mythtv/libs/libmythui/libmythui.pro
    index 2b9ac75..c139e69 100644
    a b include ( ../../settings.pro ) 
    22
    33TEMPLATE = lib
    44TARGET = mythui-$$LIBVERSION
    5 CONFIG += thread dll
     5CONFIG += qt thread dll
    66target.path = $${LIBDIR}
    77INSTALLS = target
    88