Ticket #6611: hdpvr-signalmonitor.patch

File hdpvr-signalmonitor.patch, 9.1 KB (added by jppoet@…, 3 years ago)

HD-PVR signal monitor

  • 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 "videodev_myth.h" 
    910#include "mythcontext.h" 
    1011#include "analogsignalmonitor.h" 
    1112#include "v4lchannel.h" 
    1213 
    13 #define LOC QString("AnalogSM: ").arg(channel->GetDevice()) 
    14 #define LOC_ERR QString("AnalogSM, Error: ").arg(channel->GetDevice()) 
     14#define LOC QString("AnalogSM: %1 ").arg(channel->GetDevice()) 
     15#define LOC_ERR QString("AnalogSM, Error: %1 ").arg(channel->GetDevice()) 
    1516 
    16 AnalogSignalMonitor::AnalogSignalMonitor( 
    17     int db_cardnum, V4LChannel *_channel, uint64_t _flags) : 
     17AnalogSignalMonitor::AnalogSignalMonitor(int db_cardnum, V4LChannel *_channel, 
     18                                        uint64_t _flags) : 
    1819    SignalMonitor(db_cardnum, _channel, _flags), 
    19     usingv4l2(false) 
     20    m_usingv4l2(false), 
     21    m_stage(0) 
    2022{ 
    2123    int videofd = channel->GetFd(); 
    2224    if (videofd >= 0) 
    23         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    int    idx; 
     38 
     39    if (m_stage == 0) 
     40    { 
     41        VERBOSE(VB_RECORD, LOC + "hd-pvr start encoding"); 
     42        // Tell it to start encoding, then wait for it to actually feed us 
     43        // some data. 
     44        memset(&command, 0, sizeof(struct v4l2_encoder_cmd)); 
     45        command.cmd = V4L2_ENC_CMD_START; 
     46        if (ioctl(videofd, VIDIOC_ENCODER_CMD, &command) == 0) 
     47            m_stage = 1; 
     48        else 
     49            VERBOSE(VB_IMPORTANT, LOC_ERR + "Start encoding failed" + ENO); 
     50    } 
     51 
     52    if (m_stage == 1) 
     53    { 
     54        VERBOSE(VB_RECORD, LOC + "hd-pvr wait for data"); 
     55 
     56        polls.fd      = videofd; 
     57        polls.events  = POLLIN; 
     58        polls.revents = 0; 
     59 
     60        if (poll(&polls, 1, 1500) > 0) 
     61            m_stage = 2; 
     62        else 
     63        { 
     64            VERBOSE(VB_RECORD, LOC + "Poll timed-out.  Resetting"); 
     65            memset(&command, 0, sizeof(struct v4l2_encoder_cmd)); 
     66            command.cmd = V4L2_ENC_CMD_STOP; 
     67            ioctl(videofd, VIDIOC_ENCODER_CMD, &command); 
     68            m_stage = 0; 
     69        } 
     70    } 
     71 
     72    if (m_stage == 2) 
     73    { 
     74        VERBOSE(VB_RECORD, LOC + "hd-pvr data ready.  Stop encoding"); 
     75 
     76        command.cmd = V4L2_ENC_CMD_STOP; 
     77        if (ioctl(videofd, VIDIOC_ENCODER_CMD, &command) == 0) 
     78            m_stage = 3; 
     79    } 
     80 
     81    if (m_stage == 3) 
     82    { 
     83        struct v4l2_format vfmt; 
     84        memset(&vfmt, 0, sizeof(vfmt)); 
     85        vfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 
     86             
     87        VERBOSE(VB_RECORD, LOC + "hd-pvr waiting for valid resolution"); 
     88        if ((ioctl(videofd, VIDIOC_G_FMT, &vfmt) == 0) && vfmt.fmt.pix.width) 
     89            m_stage = 4; 
     90    } 
     91 
     92    return (m_stage == 4); 
    2493} 
    2594 
    2695void AnalogSignalMonitor::UpdateValues(void) 
    void AnalogSignalMonitor::UpdateValues(v 
    33102        return; 
    34103 
    35104    bool isLocked = false; 
    36     if (usingv4l2) 
     105    if (m_usingv4l2) 
    37106    { 
    38         struct v4l2_tuner tuner; 
    39         bzero(&tuner, sizeof(tuner)); 
    40  
    41         if (ioctl(videofd, VIDIOC_G_TUNER, &tuner, 0) < 0) 
    42         { 
    43             VERBOSE(VB_IMPORTANT, 
    44                     LOC_ERR + "Failed to probe signal (v4l2)" + ENO); 
    45         } 
     107        if (m_driver == "hdpvr") 
     108            isLocked = handleHDPVR(videofd); 
    46109        else 
    47110        { 
    48             isLocked = tuner.signal; 
     111            struct v4l2_tuner tuner; 
     112            bzero(&tuner, sizeof(tuner)); 
     113 
     114            if (ioctl(videofd, VIDIOC_G_TUNER, &tuner, 0) < 0) 
     115            { 
     116                VERBOSE(VB_IMPORTANT, 
     117                        LOC_ERR + "Failed to probe signal (v4l2)" + ENO); 
     118            } 
     119            else 
     120            { 
     121                isLocked = tuner.signal; 
     122            } 
    49123        } 
    50124    } 
    51125    else  
  • 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) 
    10411041 
    10421042    if (driver == "hdpvr") 
    10431043    { 
    1044         if (curRecording->recgroup == "LiveTV") 
    1045         { 
    1046             // Don't bother checking resolution, always use best bitrate 
    1047             int maxbitrate = std::max(high_mpeg4peakbitrate, 
    1048                                       high_mpeg4avgbitrate); 
    1049             SetBitrate(high_mpeg4avgbitrate, maxbitrate, "LiveTV"); 
    1050         } 
    1051  
    10521044        int progNum = 1; 
    10531045        MPEGStreamData *sd = new MPEGStreamData(progNum, true); 
    10541046        sd->SetRecordingType(_recording_type); 
    bool MpegRecorder::StartEncoding(int fd) 
    14921484    memset(&command, 0, sizeof(struct v4l2_encoder_cmd)); 
    14931485    command.cmd = V4L2_ENC_CMD_START; 
    14941486 
    1495     if (driver == "hdpvr" && curRecording->recgroup != "LiveTV") 
     1487    if (driver == "hdpvr") 
    14961488        HandleResolutionChanges(); 
    14971489 
    14981490    VERBOSE(VB_RECORD, LOC + "StartEncoding"); 
    void MpegRecorder::HandleSingleProgramPM 
    16151607        DTVRecorder::BufferedWrite(*(reinterpret_cast<TSPacket*>(&buf[i]))); 
    16161608} 
    16171609 
    1618 /// After a resolution change, it can take the HD-PVR a few 
    1619 /// seconds before it is usable again. 
    1620 bool MpegRecorder::WaitFor_HDPVR(void) 
    1621 { 
    1622     struct v4l2_encoder_cmd command; 
    1623     struct v4l2_format vfmt; 
    1624     struct pollfd polls; 
    1625     int    idx; 
    1626  
    1627     // Tell it to start encoding, then wait for it to actually feed us 
    1628     // some data. 
    1629     QMutexLocker locker(&start_stop_encoding_lock); 
    1630  
    1631     // Sleep any less than 1.5 seconds, and the HD-PVR will 
    1632     // return the old resolution, when the resolution is changing. 
    1633     usleep(1500 * 1000); 
    1634  
    1635     memset(&command, 0, sizeof(struct v4l2_encoder_cmd)); 
    1636     command.cmd = V4L2_ENC_CMD_START; 
    1637  
    1638     for (idx = 0; idx < 20; ++idx) 
    1639     { 
    1640         if (ioctl(readfd, VIDIOC_ENCODER_CMD, &command) == 0) 
    1641             break; 
    1642         usleep(100 * 1000); 
    1643     } 
    1644  
    1645     if (idx == 20) 
    1646         return false; 
    1647  
    1648     polls.fd      = readfd; 
    1649     polls.events  = POLLIN; 
    1650     polls.revents = 0; 
    1651  
    1652     if (poll(&polls, 1, 5000) <= 0) 
    1653         return false; 
    1654  
    1655     // HD-PVR should now be "ready" 
    1656     command.cmd = V4L2_ENC_CMD_STOP; 
    1657  
    1658     if (ioctl(readfd, VIDIOC_ENCODER_CMD, &command) < 0) 
    1659         return false; 
    1660  
    1661     memset(&vfmt, 0, sizeof(vfmt)); 
    1662     vfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 
    1663  
    1664     for (idx = 0; idx < 20; ++idx) 
    1665     { 
    1666         if (0 == ioctl(chanfd, VIDIOC_G_FMT, &vfmt)) 
    1667             return true; 
    1668         // Typically takes 0.9 seconds after a resolution change 
    1669         usleep(100 * 1000); 
    1670     } 
    1671  
    1672     VERBOSE(VB_RECORD, LOC + "WaitForHDPVR failed"); 
    1673     return false; 
    1674 } 
    1675  
    16761610void MpegRecorder::SetBitrate(int bitrate, int maxbitrate, 
    16771611                              const QString & reason) 
    16781612{ 
    void MpegRecorder::HandleResolutionChang 
    17101644    memset(&vfmt, 0, sizeof(vfmt)); 
    17111645    vfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 
    17121646             
    1713     if (driver == "hdpvr") 
    1714         WaitFor_HDPVR(); 
    1715  
    17161647    if (0 == ioctl(chanfd, VIDIOC_G_FMT, &vfmt)) 
    17171648    { 
    17181649        VERBOSE(VB_RECORD, LOC + QString("Got Resolution %1x%2") 
  • libs/libmythtv/mpegrecorder.h

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

    old new inline bool SignalMonitor::IsRequired(co 
    287287    return (CardUtil::IsDVBCardType(cardtype) || 
    288288            (cardtype.toUpper() == "HDTV")      || 
    289289            (cardtype.toUpper() == "HDHOMERUN") || 
     290            (cardtype.toUpper() == "HDPVR") || 
    290291            (cardtype.toUpper() == "FIREWIRE")  || 
    291292            (cardtype.toUpper() == "FREEBOX")); 
    292293} 
    inline bool SignalMonitor::IsSupported(c 
    295296{ 
    296297    return (IsRequired(cardtype)        || 
    297298            (cardtype.toUpper() == "V4L") || 
     299            (cardtype.toUpper() == "HDPVR") || 
    298300            (cardtype.toUpper() == "MPEG")); 
    299301} 
    300302