Ticket #6611: hdpvr-signalmonitor-v2.1.patch
File hdpvr-signalmonitor-v2.1.patch, 11.5 KB (added by , 14 years ago) |
---|
-
libs/libmythtv/analogsignalmonitor.cpp
old new 2 2 // Copyright (c) 2005, Daniel Thor Kristjansson 3 3 4 4 #include <cerrno> 5 5 #include <unistd.h> 6 6 #include <sys/ioctl.h> 7 #include <poll.h> 7 8 8 9 #include "videodev_myth.h" 9 10 #include "mythcontext.h" 10 11 #include "analogsignalmonitor.h" 11 12 #include "v4lchannel.h" 12 13 13 14 #define LOC QString("AnalogSM(%1): ").arg(channel->GetDevice()) 14 15 #define LOC_ERR QString("AnalogSM(%1), Error: ").arg(channel->GetDevice()) 15 16 16 AnalogSignalMonitor::AnalogSignalMonitor( 17 int db_cardnum, V4LChannel *_channel, uint64_t _flags) : 17 AnalogSignalMonitor::AnalogSignalMonitor(int db_cardnum, 18 V4LChannel *_channel, 19 uint64_t _flags) : 18 20 SignalMonitor(db_cardnum, _channel, _flags), 19 usingv4l2(false) 21 m_usingv4l2(false), 22 m_stage(0) 20 23 { 21 24 int videofd = channel->GetFd(); 22 25 if (videofd >= 0) 23 usingv4l2 = CardUtil::hasV4L2(videofd); 26 { 27 m_usingv4l2 = CardUtil::hasV4L2(videofd); 28 CardUtil::GetV4LInfo(videofd, m_card, m_driver, m_version); 29 VERBOSE(VB_RECORD, LOC + QString("card '%1' driver '%2' version '%3'") 30 .arg(m_card).arg(m_driver).arg(m_version)); 31 } 32 } 33 34 bool AnalogSignalMonitor::handleHDPVR(int videofd) 35 { 36 struct v4l2_encoder_cmd command; 37 struct pollfd polls; 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 { 50 VERBOSE(VB_IMPORTANT, LOC_ERR + "Start encoding failed" + ENO); 51 command.cmd = V4L2_ENC_CMD_STOP; 52 ioctl(videofd, VIDIOC_ENCODER_CMD, &command); 53 } 54 } 55 56 if (m_stage == 1) 57 { 58 VERBOSE(VB_RECORD, LOC + "hd-pvr wait for data"); 59 60 polls.fd = videofd; 61 polls.events = POLLIN; 62 polls.revents = 0; 63 64 if (poll(&polls, 1, 1500) > 0) 65 { 66 m_stage = 2; 67 QMutexLocker locker(&statusLock); 68 signalStrength.SetValue(25); 69 } 70 else 71 { 72 VERBOSE(VB_RECORD, LOC + "Poll timed-out. Resetting"); 73 memset(&command, 0, sizeof(struct v4l2_encoder_cmd)); 74 command.cmd = V4L2_ENC_CMD_STOP; 75 ioctl(videofd, VIDIOC_ENCODER_CMD, &command); 76 m_stage = 0; 77 78 QMutexLocker locker(&statusLock); 79 signalStrength.SetValue(0); 80 } 81 } 82 83 if (m_stage == 2) 84 { 85 VERBOSE(VB_RECORD, LOC + "hd-pvr data ready. Stop encoding"); 86 87 command.cmd = V4L2_ENC_CMD_STOP; 88 if (ioctl(videofd, VIDIOC_ENCODER_CMD, &command) == 0) 89 m_stage = 3; 90 else 91 { 92 QMutexLocker locker(&statusLock); 93 signalStrength.SetValue(50); 94 } 95 } 96 else 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); 24 117 } 25 118 26 119 void AnalogSignalMonitor::UpdateValues(void) 27 120 { 28 121 if (!running || exit) … … void AnalogSignalMonitor::UpdateValues(v 34 127 35 128 if (!IsChannelTuned()) 36 129 return; 37 130 38 131 bool isLocked = false; 39 if ( usingv4l2)132 if (m_usingv4l2) 40 133 { 41 struct v4l2_tuner tuner; 42 bzero(&tuner, sizeof(tuner)); 43 44 if (ioctl(videofd, VIDIOC_G_TUNER, &tuner, 0) < 0) 45 { 46 VERBOSE(VB_IMPORTANT, 47 LOC_ERR + "Failed to probe signal (v4l2)" + ENO); 48 } 134 if (m_driver == "hdpvr") 135 isLocked = handleHDPVR(videofd); 49 136 else 50 137 { 51 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 } 52 150 } 53 151 } 54 152 else 55 153 { 56 154 struct video_tuner tuner; … … void AnalogSignalMonitor::UpdateValues(v 68 166 } 69 167 70 168 { 71 169 QMutexLocker locker(&statusLock); 72 170 signalLock.SetValue(isLocked); 73 signalStrength.SetValue(isLocked ? 100 : 0); 171 if (isLocked) 172 signalStrength.SetValue(100); 74 173 } 75 174 76 175 EmitStatus(); 77 176 if (IsAllGood()) 78 177 SendMessageAllGood(); -
libs/libmythtv/analogsignalmonitor.h
old new class AnalogSignalMonitor : public Signa 17 17 uint64_t _flags = kSigMon_WaitForSig); 18 18 19 19 virtual void UpdateValues(void); 20 20 21 21 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; 23 29 }; 24 30 25 31 #endif // _ANALOG_SIGNAL_MONITOR_H_ -
libs/libmythtv/mpegrecorder.cpp
old new void MpegRecorder::StartRecording(void) 1042 1042 _last_gop_seen = 0; 1043 1043 _frames_written_count = 0; 1044 1044 1045 1045 if (driver == "hdpvr") 1046 1046 { 1047 if (curRecording->recgroup == "LiveTV")1048 {1049 // Don't bother checking resolution, always use best bitrate1050 int maxbitrate = std::max(high_mpeg4peakbitrate,1051 high_mpeg4avgbitrate);1052 SetBitrate(high_mpeg4avgbitrate, maxbitrate, "LiveTV");1053 }1054 1055 1047 int progNum = 1; 1056 1048 MPEGStreamData *sd = new MPEGStreamData(progNum, true); 1057 1049 sd->SetRecordingType(_recording_type); 1058 1050 SetStreamData(sd); 1059 1051 … … bool MpegRecorder::StartEncoding(int fd) 1523 1515 1524 1516 struct v4l2_encoder_cmd command; 1525 1517 memset(&command, 0, sizeof(struct v4l2_encoder_cmd)); 1526 1518 command.cmd = V4L2_ENC_CMD_START; 1527 1519 1528 if (driver == "hdpvr" && curRecording->recgroup != "LiveTV")1520 if (driver == "hdpvr") 1529 1521 HandleResolutionChanges(); 1530 1522 1531 1523 VERBOSE(VB_RECORD, LOC + "StartEncoding"); 1532 1524 1533 1525 if (ioctl(fd, VIDIOC_ENCODER_CMD, &command) == 0) … … void MpegRecorder::HandleSingleProgramPM 1632 1624 1633 1625 for (uint i = 0; i < _scratch.size(); i++) 1634 1626 DTVRecorder::BufferedWrite(_scratch[i]); 1635 1627 } 1636 1628 1637 /// After a resolution change, it can take the HD-PVR a few1638 /// seconds before it is usable again.1639 bool MpegRecorder::WaitFor_HDPVR(void)1640 {1641 struct v4l2_encoder_cmd command;1642 struct v4l2_format vfmt;1643 struct pollfd polls;1644 int idx;1645 1646 // Tell it to start encoding, then wait for it to actually feed us1647 // some data.1648 QMutexLocker locker(&start_stop_encoding_lock);1649 1650 // Sleep any less than 1.5 seconds, and the HD-PVR will1651 // return the old resolution, when the resolution is changing.1652 usleep(1500 * 1000);1653 1654 memset(&command, 0, sizeof(struct v4l2_encoder_cmd));1655 command.cmd = V4L2_ENC_CMD_START;1656 1657 for (idx = 0; idx < 20; ++idx)1658 {1659 if (ioctl(readfd, VIDIOC_ENCODER_CMD, &command) == 0)1660 break;1661 usleep(100 * 1000);1662 }1663 1664 if (idx == 20)1665 return false;1666 1667 polls.fd = readfd;1668 polls.events = POLLIN;1669 polls.revents = 0;1670 1671 if (poll(&polls, 1, 5000) <= 0)1672 return false;1673 1674 // HD-PVR should now be "ready"1675 command.cmd = V4L2_ENC_CMD_STOP;1676 1677 if (ioctl(readfd, VIDIOC_ENCODER_CMD, &command) < 0)1678 return false;1679 1680 memset(&vfmt, 0, sizeof(vfmt));1681 vfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;1682 1683 for (idx = 0; idx < 20; ++idx)1684 {1685 if (0 == ioctl(chanfd, VIDIOC_G_FMT, &vfmt))1686 return true;1687 // Typically takes 0.9 seconds after a resolution change1688 usleep(100 * 1000);1689 }1690 1691 VERBOSE(VB_RECORD, LOC + "WaitForHDPVR failed");1692 return false;1693 }1694 1695 1629 void MpegRecorder::SetBitrate(int bitrate, int maxbitrate, 1696 1630 const QString & reason) 1697 1631 { 1698 1632 if (maxbitrate == bitrate) 1699 1633 { … … void MpegRecorder::HandleResolutionChang 1727 1661 uint pix = 0; 1728 1662 struct v4l2_format vfmt; 1729 1663 memset(&vfmt, 0, sizeof(vfmt)); 1730 1664 vfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1731 1665 1732 if (driver == "hdpvr")1733 WaitFor_HDPVR();1734 1735 1666 if (0 == ioctl(chanfd, VIDIOC_G_FMT, &vfmt)) 1736 1667 { 1737 1668 VERBOSE(VB_RECORD, LOC + QString("Got Resolution %1x%2") 1738 1669 .arg(vfmt.fmt.pix.width).arg(vfmt.fmt.pix.height)); 1739 1670 pix = vfmt.fmt.pix.width * vfmt.fmt.pix.height; -
libs/libmythtv/mpegrecorder.h
old new class MpegRecorder : public DTVRecorder, 84 84 bool StartEncoding(int fd); 85 85 bool StopEncoding(int fd); 86 86 87 87 void ResetForNewFile(void); 88 88 89 bool WaitFor_HDPVR(void);90 89 void SetBitrate(int bitrate, int maxbitrate, const QString & reason); 91 90 void HandleResolutionChanges(void); 92 91 93 92 inline bool CheckCC(uint pid, uint cc); 94 93 -
libs/libmythtv/signalmonitor.cpp
old new SignalMonitor *SignalMonitor::Init(QStri 94 94 signalMonitor = new DVBSignalMonitor(db_cardnum, dvbc); 95 95 } 96 96 #endif 97 97 98 98 #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") 102 100 { 103 101 V4LChannel *chan = dynamic_cast<V4LChannel*>(channel); 104 102 if (chan) 105 103 signalMonitor = new AnalogSignalMonitor(db_cardnum, chan); 106 104 } 107 105 #endif 108 #endif109 106 110 107 #ifdef USING_HDHOMERUN 111 108 if (cardtype.toUpper() == "HDHOMERUN") 112 109 { 113 110 HDHRChannel *hdhrc = dynamic_cast<HDHRChannel*>(channel); -
libs/libmythtv/signalmonitor.h
old new inline QString sm_flags_to_string(uint64 304 304 inline bool SignalMonitor::IsRequired(const QString &cardtype) 305 305 { 306 306 return (CardUtil::IsDVBCardType(cardtype) || 307 307 (cardtype.toUpper() == "HDTV") || 308 308 (cardtype.toUpper() == "HDHOMERUN") || 309 (cardtype.toUpper() == "HDPVR") || 309 310 (cardtype.toUpper() == "FIREWIRE") || 310 311 (cardtype.toUpper() == "FREEBOX")); 311 312 } 312 313 313 314 inline bool SignalMonitor::IsSupported(const QString &cardtype)