Ticket #10765: HD-PVR-signalmonitor-v2a.patch

File HD-PVR-signalmonitor-v2a.patch, 8.9 KB (added by jpoet, 12 years ago)

Move m_stable_time init to the ctor.

  • mythtv/libs/libmythtv/analogsignalmonitor.cpp

    diff --git a/mythtv/libs/libmythtv/analogsignalmonitor.cpp b/mythtv/libs/libmythtv/analogsignalmonitor.cpp
    index 4e0775d..af933e1 100644
    a b  
    1616
    1717#define LOC QString("AnalogSM(%1): ").arg(channel->GetDevice())
    1818
     19/* m_stable_time is used to designate how long we need to see a stable
     20 * resolution reported from the HD-PVR driver, before we consider it a
     21 * good lock.  In my testing 2 seconds is safe, while 1 second worked
     22 * most of the time.  --jp
     23 */
    1924AnalogSignalMonitor::AnalogSignalMonitor(
    2025    int db_cardnum, V4LChannel *_channel, uint64_t _flags) :
    2126    SignalMonitor(db_cardnum, _channel, _flags),
    22     m_usingv4l2(false), m_stage(0)
     27    m_usingv4l2(false), m_width(0), m_stable_time(2000), m_lock_cnt(0)
    2328{
    2429    int videofd = channel->GetFd();
    2530    if (videofd >= 0)
    AnalogSignalMonitor::AnalogSignalMonitor( 
    3641    }
    3742}
    3843
    39 bool AnalogSignalMonitor::handleHDPVR(int videofd)
     44bool AnalogSignalMonitor::VerifyHDPVRaudio(int videofd)
    4045{
    41     struct v4l2_encoder_cmd command;
    42     struct pollfd polls;
     46    struct v4l2_queryctrl qctrl;
     47    qctrl.id = V4L2_CID_MPEG_AUDIO_ENCODING;
    4348
    44     if (m_stage == 0)
     49    int audtype = V4L2_MPEG_AUDIO_ENCODING_AC3;
     50
     51    if (ioctl(videofd, VIDIOC_QUERYCTRL, &qctrl) != 0)
    4552    {
    46         LOG(VB_RECORD, LOG_INFO, "hd-pvr start encoding");
    47         // Tell it to start encoding, then wait for it to actually feed us
    48         // some data.
    49         memset(&command, 0, sizeof(struct v4l2_encoder_cmd));
    50         command.cmd = V4L2_ENC_CMD_START;
    51         if (ioctl(videofd, VIDIOC_ENCODER_CMD, &command) == 0)
    52             m_stage = 1;
    53         else
    54         {
    55             LOG(VB_GENERAL, LOG_ERR, "Start encoding failed" + ENO);
    56             command.cmd = V4L2_ENC_CMD_STOP;
    57             ioctl(videofd, VIDIOC_ENCODER_CMD, &command);
    58         }
     53        LOG(VB_GENERAL, LOG_ERR, LOC +
     54            "Unable to get supported audio codecs for verification." + ENO);
     55        return false;
    5956    }
    6057
    61     if (m_stage == 1)
     58    int  current_audio;
     59    uint audio_enc = max(min(audtype - 1, qctrl.maximum), qctrl.minimum);
     60
     61    struct v4l2_ext_control  ext_ctrl;
     62    struct v4l2_ext_controls ext_ctrls;
     63
     64    memset(&ext_ctrl, 0, sizeof(struct v4l2_ext_control));
     65    ext_ctrl.id = V4L2_CID_MPEG_AUDIO_ENCODING;
     66
     67    ext_ctrls.reserved[0] = ext_ctrls.reserved[1] = 0;
     68    ext_ctrls.count = 1;
     69    ext_ctrls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
     70    ext_ctrls.controls = &ext_ctrl;
     71
     72    if (ioctl(videofd, VIDIOC_G_EXT_CTRLS, &ext_ctrls) != 0)
    6273    {
    63         LOG(VB_RECORD, LOG_INFO, "hd-pvr wait for data");
     74        LOG(VB_GENERAL, LOG_ERR, LOC +
     75            "Unable to get current audio codecs for verification." + ENO);
     76        return false;
     77    }
    6478
    65         polls.fd      = videofd;
    66         polls.events  = POLLIN;
    67         polls.revents = 0;
     79    current_audio = ext_ctrls.controls->value;
    6880
    69         if (poll(&polls, 1, 1500) > 0)
     81    if (audtype - 1 != current_audio)
     82    {
     83        LOG(VB_GENERAL, LOG_ERR, LOC + QString("Audio desired %1, current %2 "
     84                                               "min %3 max %4")
     85            .arg(audtype - 1)
     86            .arg(current_audio)
     87            .arg(qctrl.minimum)
     88            .arg(qctrl.maximum)
     89            );
     90
     91        ext_ctrl.id = V4L2_CID_MPEG_AUDIO_ENCODING;
     92        ext_ctrl.value = audtype - 1;
     93        if (ioctl(videofd, VIDIOC_S_EXT_CTRLS, &ext_ctrls) == 0)
    7094        {
    71             m_stage = 2;
    72             QMutexLocker locker(&statusLock);
    73             signalStrength.SetValue(25);
     95            LOG(VB_GENERAL, LOG_ERR, LOC + QString("Changed audio encoding "
     96                                                   "from %1 to %2.")
     97                .arg(current_audio)
     98                .arg(audtype - 1)
     99                );
    74100        }
    75101        else
    76102        {
    77             LOG(VB_RECORD, LOG_INFO, "Poll timed-out.  Resetting");
    78             memset(&command, 0, sizeof(struct v4l2_encoder_cmd));
    79             command.cmd = V4L2_ENC_CMD_STOP;
    80             ioctl(videofd, VIDIOC_ENCODER_CMD, &command);
    81             m_stage = 0;
    82 
    83             QMutexLocker locker(&statusLock);
    84             signalStrength.SetValue(0);
     103            LOG(VB_GENERAL, LOG_ERR, LOC + QString("Failed to changed audio "
     104                                                   "encoding from %1 to %2."
     105                                                   + ENO)
     106                .arg(current_audio)
     107                .arg(audtype - 1)
     108                );
    85109        }
     110
     111        return false;
    86112    }
    87113
    88     if (m_stage == 2)
    89     {
    90         LOG(VB_RECORD, LOG_INFO, "hd-pvr data ready.  Stop encoding");
     114    return true;
     115}
    91116
    92         command.cmd = V4L2_ENC_CMD_STOP;
    93         if (ioctl(videofd, VIDIOC_ENCODER_CMD, &command) == 0)
    94             m_stage = 3;
    95         else
    96         {
    97             QMutexLocker locker(&statusLock);
    98             signalStrength.SetValue(50);
    99         }
    100     }
     117bool AnalogSignalMonitor::handleHDPVR(int videofd)
     118{
     119    struct v4l2_encoder_cmd command;
     120    struct pollfd polls;
    101121
    102     if (m_stage == 3)
    103     {
    104         struct v4l2_format vfmt;
    105         memset(&vfmt, 0, sizeof(vfmt));
    106         vfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
     122    struct v4l2_format vfmt;
     123    memset(&vfmt, 0, sizeof(vfmt));
     124    vfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    107125
    108         LOG(VB_RECORD, LOG_INFO, "hd-pvr waiting for valid resolution");
    109         if ((ioctl(videofd, VIDIOC_G_FMT, &vfmt) == 0) && vfmt.fmt.pix.width)
     126    if ((ioctl(videofd, VIDIOC_G_FMT, &vfmt) == 0) &&
     127        vfmt.fmt.pix.width && m_width == vfmt.fmt.pix.width &&
     128        VerifyHDPVRaudio(videofd))
     129    {
     130        if (!m_timer.isRunning())
     131        {
     132            LOG(VB_RECORD, LOG_ERR, QString("hd-pvr resolution %1 x %2")
     133                .arg(vfmt.fmt.pix.width).arg(vfmt.fmt.pix.height));
     134            ++m_lock_cnt;
     135            m_timer.start();
     136        }
     137        else if (m_timer.elapsed() > m_stable_time)
    110138        {
    111             LOG(VB_RECORD, LOG_INFO, QString("hd-pvr resolution %1 x %2")
    112                     .arg(vfmt.fmt.pix.width).arg(vfmt.fmt.pix.height));
    113             m_stage = 4;
     139            LOG(VB_RECORD, LOG_ERR, QString("hd-pvr stable at %1 x %2")
     140                .arg(vfmt.fmt.pix.width).arg(vfmt.fmt.pix.height));
     141            m_timer.stop();
     142            return true;
    114143        }
    115144        else
    116145        {
    117146            QMutexLocker locker(&statusLock);
    118             signalStrength.SetValue(75);
     147            signalStrength.SetValue(60 + m_lock_cnt);
    119148        }
    120149    }
     150    else
     151    {
     152        LOG(VB_RECORD, LOG_ERR, "hd-pvr waiting for valid resolution");
     153        m_width = vfmt.fmt.pix.width;
     154        m_timer.stop();
     155        QMutexLocker locker(&statusLock);
     156        signalStrength.SetValue(20 + m_lock_cnt);
     157    }
    121158
    122     return (m_stage == 4);
     159    return false;
    123160}
    124161
    125162void AnalogSignalMonitor::UpdateValues(void)
  • mythtv/libs/libmythtv/analogsignalmonitor.h

    diff --git a/mythtv/libs/libmythtv/analogsignalmonitor.h b/mythtv/libs/libmythtv/analogsignalmonitor.h
    index dd0154c..97f0065 100644
    a b class AnalogSignalMonitor : public SignalMonitor 
    1919    virtual void UpdateValues(void);
    2020
    2121  private:
     22    bool VerifyHDPVRaudio(int videofd);
    2223    bool handleHDPVR(int videofd);
    2324
    2425    bool     m_usingv4l2;
    2526    QString  m_card;
    2627    QString  m_driver;
    2728    uint32_t m_version;
    28     int      m_stage;
     29    uint     m_width;
     30    uint     m_stable_time;
     31    uint     m_lock_cnt;
     32    MythTimer m_timer;
    2933};
    3034
    3135#endif // _ANALOG_SIGNAL_MONITOR_H_
  • mythtv/libs/libmythtv/mpegrecorder.cpp

    diff --git a/mythtv/libs/libmythtv/mpegrecorder.cpp b/mythtv/libs/libmythtv/mpegrecorder.cpp
    index 0e133ab..95673a5 100644
    a b void MpegRecorder::run(void) 
    10011001
    10021002        if (_device_read_buffer)
    10031003        {
    1004             len = _device_read_buffer->Read(
    1005                     &(buffer[remainder]), bufferSize - remainder);
     1004            len = _device_read_buffer->Read
     1005                  (&(buffer[remainder]), bufferSize - remainder);
    10061006
    10071007            // Check for DRB errors
    10081008            if (_device_read_buffer->IsErrored())
    bool MpegRecorder::StartEncoding(void) 
    13181318    if (_device_read_buffer)
    13191319    {
    13201320        _device_read_buffer->Reset(videodevice.toAscii().constData(), readfd);
     1321        _device_read_buffer->SetRequestPause(false);
    13211322        _device_read_buffer->Start();
    13221323    }
    13231324
    void MpegRecorder::StopEncoding(void) 
    13381339    command.cmd   = V4L2_ENC_CMD_STOP;
    13391340    command.flags = V4L2_ENC_CMD_STOP_AT_GOP_END;
    13401341
     1342    if (_device_read_buffer)
     1343        _device_read_buffer->SetRequestPause(true);
     1344
    13411345    bool stopped = 0 == ioctl(readfd, VIDIOC_ENCODER_CMD, &command);
    13421346    if (stopped)
    13431347    {
    void MpegRecorder::StopEncoding(void) 
    13621366    }
    13631367
    13641368    // close the fd so streamoff/streamon work in V4LChannel
    1365     close(readfd);   
     1369    close(readfd);
    13661370    readfd = -1;
    13671371}
    13681372