Ticket #6611: hdpvr-signalmonitor-trunk-25379.patch

File hdpvr-signalmonitor-trunk-25379.patch, 10.1 KB (added by jpoet, 22 months ago)

Updated for trunk r25379

  • libs/libmythtv/analogsignalmonitor.cpp

    old new  
    44#include <cerrno> 
    55#include <unistd.h> 
    66#include <sys/ioctl.h> 
     7#include <poll.h> 
    78 
    89#include <linux/videodev.h> 
    910 
     
    1718AnalogSignalMonitor::AnalogSignalMonitor( 
    1819    int db_cardnum, V4LChannel *_channel, uint64_t _flags) : 
    1920    SignalMonitor(db_cardnum, _channel, _flags), 
    20     usingv4l2(false) 
     21    m_usingv4l2(false), m_stage(0) 
    2122{ 
    2223    int videofd = channel->GetFd(); 
    2324    if (videofd >= 0) 
    24         usingv4l2 = CardUtil::hasV4L2(videofd); 
     25    { 
     26        m_usingv4l2 = CardUtil::hasV4L2(videofd); 
     27        CardUtil::GetV4LInfo(videofd, m_card, m_driver, m_version); 
     28        VERBOSE(VB_RECORD, LOC + QString("card '%1' driver '%2' version '%3'") 
     29                .arg(m_card).arg(m_driver).arg(m_version)); 
     30    } 
     31} 
     32 
     33bool AnalogSignalMonitor::handleHDPVR(int videofd) 
     34{ 
     35    struct v4l2_encoder_cmd command; 
     36    struct pollfd polls; 
     37 
     38    if (m_stage == 0) 
     39    { 
     40        VERBOSE(VB_RECORD, LOC + "hd-pvr start encoding"); 
     41        // Tell it to start encoding, then wait for it to actually feed us 
     42        // some data. 
     43        memset(&command, 0, sizeof(struct v4l2_encoder_cmd)); 
     44        command.cmd = V4L2_ENC_CMD_START; 
     45        if (ioctl(videofd, VIDIOC_ENCODER_CMD, &command) == 0) 
     46            m_stage = 1; 
     47        else 
     48        { 
     49            VERBOSE(VB_IMPORTANT, LOC_ERR + "Start encoding failed" + ENO); 
     50            command.cmd = V4L2_ENC_CMD_STOP; 
     51            ioctl(videofd, VIDIOC_ENCODER_CMD, &command); 
     52        } 
     53    } 
     54 
     55    if (m_stage == 1) 
     56    { 
     57        VERBOSE(VB_RECORD, LOC + "hd-pvr wait for data"); 
     58 
     59        polls.fd      = videofd; 
     60        polls.events  = POLLIN; 
     61        polls.revents = 0; 
     62 
     63        if (poll(&polls, 1, 1500) > 0) 
     64        { 
     65            m_stage = 2; 
     66            QMutexLocker locker(&statusLock); 
     67            signalStrength.SetValue(25); 
     68        } 
     69        else 
     70        { 
     71            VERBOSE(VB_RECORD, LOC + "Poll timed-out.  Resetting"); 
     72            memset(&command, 0, sizeof(struct v4l2_encoder_cmd)); 
     73            command.cmd = V4L2_ENC_CMD_STOP; 
     74            ioctl(videofd, VIDIOC_ENCODER_CMD, &command); 
     75            m_stage = 0; 
     76 
     77            QMutexLocker locker(&statusLock); 
     78            signalStrength.SetValue(0); 
     79        } 
     80    } 
     81 
     82    if (m_stage == 2) 
     83    { 
     84        VERBOSE(VB_RECORD, LOC + "hd-pvr data ready.  Stop encoding"); 
     85 
     86        command.cmd = V4L2_ENC_CMD_STOP; 
     87        if (ioctl(videofd, VIDIOC_ENCODER_CMD, &command) == 0) 
     88            m_stage = 3; 
     89        else 
     90        { 
     91            QMutexLocker locker(&statusLock); 
     92            signalStrength.SetValue(50); 
     93        } 
     94    } 
     95 
     96    if (m_stage == 3) 
     97    { 
     98        struct v4l2_format vfmt; 
     99        memset(&vfmt, 0, sizeof(vfmt)); 
     100        vfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 
     101 
     102        VERBOSE(VB_RECORD, LOC + "hd-pvr waiting for valid resolution"); 
     103        if ((ioctl(videofd, VIDIOC_G_FMT, &vfmt) == 0) && vfmt.fmt.pix.width) 
     104        { 
     105            VERBOSE(VB_RECORD, LOC + QString("hd-pvr resolution %1 x %2") 
     106                    .arg(vfmt.fmt.pix.width).arg(vfmt.fmt.pix.height)); 
     107            m_stage = 4; 
     108        } 
     109        else 
     110        { 
     111            QMutexLocker locker(&statusLock); 
     112            signalStrength.SetValue(75); 
     113        } 
     114    } 
     115 
     116    return (m_stage == 4); 
    25117} 
    26118 
    27119void AnalogSignalMonitor::UpdateValues(void) 
    void AnalogSignalMonitor::UpdateValues(v 
    37129        return; 
    38130 
    39131    bool isLocked = false; 
    40     if (usingv4l2) 
     132    if (m_usingv4l2) 
    41133    { 
    42         struct v4l2_tuner tuner; 
    43         bzero(&tuner, sizeof(tuner)); 
    44  
    45         if (ioctl(videofd, VIDIOC_G_TUNER, &tuner, 0) < 0) 
    46         { 
    47             VERBOSE(VB_IMPORTANT, 
    48                     LOC_ERR + "Failed to probe signal (v4l2)" + ENO); 
    49         } 
     134        if (m_driver == "hdpvr") 
     135            isLocked = handleHDPVR(videofd); 
    50136        else 
    51137        { 
    52             isLocked = tuner.signal; 
     138            struct v4l2_tuner tuner; 
     139            bzero(&tuner, sizeof(tuner)); 
     140 
     141            if (ioctl(videofd, VIDIOC_G_TUNER, &tuner, 0) < 0) 
     142            { 
     143                VERBOSE(VB_IMPORTANT, 
     144                        LOC_ERR + "Failed to probe signal (v4l2)" + ENO); 
     145            } 
     146            else 
     147            { 
     148                isLocked = tuner.signal; 
     149            } 
    53150        } 
    54151    } 
    55152    else 
    void AnalogSignalMonitor::UpdateValues(v 
    71168    { 
    72169        QMutexLocker locker(&statusLock); 
    73170        signalLock.SetValue(isLocked); 
    74         signalStrength.SetValue(isLocked ? 100 : 0); 
     171        if (isLocked) 
     172            signalStrength.SetValue(100); 
    75173    } 
    76174 
    77175    EmitStatus(); 
  • libs/libmythtv/analogsignalmonitor.h

    old new class AnalogSignalMonitor : public Signa 
    1919    virtual void UpdateValues(void); 
    2020 
    2121  private: 
    22     bool usingv4l2; 
     22    bool handleHDPVR(int videofd); 
     23 
     24    bool     m_usingv4l2; 
     25    QString  m_card; 
     26    QString  m_driver; 
     27    uint32_t m_version; 
     28    int      m_stage; 
    2329}; 
    2430 
    2531#endif // _ANALOG_SIGNAL_MONITOR_H_ 
  • libs/libmythtv/mpegrecorder.cpp

    old new void MpegRecorder::StartRecording(void) 
    10431043 
    10441044    if (driver == "hdpvr") 
    10451045    { 
    1046         if (curRecording->GetRecordingGroup() == "LiveTV") 
    1047         { 
    1048             // Don't bother checking resolution, always use best bitrate 
    1049             int maxbitrate = std::max(high_mpeg4peakbitrate, 
    1050                                       high_mpeg4avgbitrate); 
    1051             SetBitrate(high_mpeg4avgbitrate, maxbitrate, "LiveTV"); 
    1052         } 
    1053  
    10541046        int progNum = 1; 
    10551047        MPEGStreamData *sd = new MPEGStreamData(progNum, true); 
    10561048        sd->SetRecordingType(_recording_type); 
    bool MpegRecorder::StartEncoding(int fd) 
    15301522    memset(&command, 0, sizeof(struct v4l2_encoder_cmd)); 
    15311523    command.cmd = V4L2_ENC_CMD_START; 
    15321524 
    1533     if (driver == "hdpvr" && curRecording->GetRecordingGroup() != "LiveTV") 
     1525    if (driver == "hdpvr") 
    15341526        HandleResolutionChanges(); 
    15351527 
    15361528    VERBOSE(VB_RECORD, LOC + "StartEncoding"); 
    void MpegRecorder::HandleSingleProgramPM 
    16201612        DTVRecorder::BufferedWrite(_scratch[i]); 
    16211613} 
    16221614 
    1623 /// After a resolution change, it can take the HD-PVR a few 
    1624 /// seconds before it is usable again. 
    1625 bool MpegRecorder::WaitFor_HDPVR(void) 
    1626 { 
    1627     struct v4l2_encoder_cmd command; 
    1628     struct v4l2_format vfmt; 
    1629     struct pollfd polls; 
    1630     int    idx; 
    1631  
    1632     // Tell it to start encoding, then wait for it to actually feed us 
    1633     // some data. 
    1634     QMutexLocker locker(&start_stop_encoding_lock); 
    1635  
    1636     // Sleep any less than 1.5 seconds, and the HD-PVR will 
    1637     // return the old resolution, when the resolution is changing. 
    1638     usleep(1500 * 1000); 
    1639  
    1640     memset(&command, 0, sizeof(struct v4l2_encoder_cmd)); 
    1641     command.cmd = V4L2_ENC_CMD_START; 
    1642  
    1643     for (idx = 0; idx < 20; ++idx) 
    1644     { 
    1645         if (ioctl(readfd, VIDIOC_ENCODER_CMD, &command) == 0) 
    1646             break; 
    1647         usleep(100 * 1000); 
    1648     } 
    1649  
    1650     if (idx == 20) 
    1651         return false; 
    1652  
    1653     polls.fd      = readfd; 
    1654     polls.events  = POLLIN; 
    1655     polls.revents = 0; 
    1656  
    1657     if (poll(&polls, 1, 5000) <= 0) 
    1658         return false; 
    1659  
    1660     // HD-PVR should now be "ready" 
    1661     command.cmd = V4L2_ENC_CMD_STOP; 
    1662  
    1663     if (ioctl(readfd, VIDIOC_ENCODER_CMD, &command) < 0) 
    1664         return false; 
    1665  
    1666     memset(&vfmt, 0, sizeof(vfmt)); 
    1667     vfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 
    1668  
    1669     for (idx = 0; idx < 20; ++idx) 
    1670     { 
    1671         if (0 == ioctl(chanfd, VIDIOC_G_FMT, &vfmt)) 
    1672             return true; 
    1673         // Typically takes 0.9 seconds after a resolution change 
    1674         usleep(100 * 1000); 
    1675     } 
    1676  
    1677     VERBOSE(VB_RECORD, LOC + "WaitForHDPVR failed"); 
    1678     return false; 
    1679 } 
    1680  
    16811615void MpegRecorder::SetBitrate(int bitrate, int maxbitrate, 
    16821616                              const QString & reason) 
    16831617{ 
    void MpegRecorder::HandleResolutionChang 
    17151649    memset(&vfmt, 0, sizeof(vfmt)); 
    17161650    vfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 
    17171651 
    1718     if (driver == "hdpvr") 
    1719         WaitFor_HDPVR(); 
    1720  
    17211652    if (0 == ioctl(chanfd, VIDIOC_G_FMT, &vfmt)) 
    17221653    { 
    17231654        VERBOSE(VB_RECORD, LOC + QString("Got Resolution %1x%2") 
  • libs/libmythtv/mpegrecorder.h

    old new class MpegRecorder : public DTVRecorder, 
    8585 
    8686    void ResetForNewFile(void); 
    8787 
    88     bool WaitFor_HDPVR(void); 
    8988    void SetBitrate(int bitrate, int maxbitrate, const QString & reason); 
    9089    void HandleResolutionChanges(void); 
    9190 
  • libs/libmythtv/signalmonitor.cpp

    old new SignalMonitor *SignalMonitor::Init(QStri 
    9696#endif 
    9797 
    9898#ifdef USING_V4L 
    99 #if 0 // Just use ChannelChangeMonitor for these types 
    100     if ((cardtype.toUpper() == "V4L") || 
    101         (cardtype.toUpper() == "MPEG")) 
     99    if ((cardtype.toUpper() == "HDPVR")) 
    102100    { 
    103101        V4LChannel *chan = dynamic_cast<V4LChannel*>(channel); 
    104102        if (chan) 
    105103            signalMonitor = new AnalogSignalMonitor(db_cardnum, chan); 
    106104    } 
    107105#endif 
    108 #endif 
    109106 
    110107#ifdef USING_HDHOMERUN 
    111108    if (cardtype.toUpper() == "HDHOMERUN") 
  • libs/libmythtv/signalmonitor.h

    old new inline bool SignalMonitor::IsRequired(co 
    306306    return (CardUtil::IsDVBCardType(cardtype) || 
    307307            (cardtype.toUpper() == "HDTV")      || 
    308308            (cardtype.toUpper() == "HDHOMERUN") || 
     309            (cardtype.toUpper() == "HDPVR") || 
    309310            (cardtype.toUpper() == "FIREWIRE")  || 
    310311            (cardtype.toUpper() == "FREEBOX")); 
    311312}