Ticket #6611: hdpvr-signalmonitor-trunk-25379.patch
File hdpvr-signalmonitor-trunk-25379.patch, 10.1 KB (added by , 14 years ago) |
---|
-
libs/libmythtv/analogsignalmonitor.cpp
old new 4 4 #include <cerrno> 5 5 #include <unistd.h> 6 6 #include <sys/ioctl.h> 7 #include <poll.h> 7 8 8 9 #include <linux/videodev.h> 9 10 … … 17 18 AnalogSignalMonitor::AnalogSignalMonitor( 18 19 int db_cardnum, V4LChannel *_channel, uint64_t _flags) : 19 20 SignalMonitor(db_cardnum, _channel, _flags), 20 usingv4l2(false)21 m_usingv4l2(false), m_stage(0) 21 22 { 22 23 int videofd = channel->GetFd(); 23 24 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 33 bool 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); 25 117 } 26 118 27 119 void AnalogSignalMonitor::UpdateValues(void) … … void AnalogSignalMonitor::UpdateValues(v 37 129 return; 38 130 39 131 bool isLocked = false; 40 if ( usingv4l2)132 if (m_usingv4l2) 41 133 { 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); 50 136 else 51 137 { 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 } 53 150 } 54 151 } 55 152 else … … void AnalogSignalMonitor::UpdateValues(v 71 168 { 72 169 QMutexLocker locker(&statusLock); 73 170 signalLock.SetValue(isLocked); 74 signalStrength.SetValue(isLocked ? 100 : 0); 171 if (isLocked) 172 signalStrength.SetValue(100); 75 173 } 76 174 77 175 EmitStatus(); -
libs/libmythtv/analogsignalmonitor.h
old new class AnalogSignalMonitor : public Signa 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) 1043 1043 1044 1044 if (driver == "hdpvr") 1045 1045 { 1046 if (curRecording->GetRecordingGroup() == "LiveTV")1047 {1048 // Don't bother checking resolution, always use best bitrate1049 int maxbitrate = std::max(high_mpeg4peakbitrate,1050 high_mpeg4avgbitrate);1051 SetBitrate(high_mpeg4avgbitrate, maxbitrate, "LiveTV");1052 }1053 1054 1046 int progNum = 1; 1055 1047 MPEGStreamData *sd = new MPEGStreamData(progNum, true); 1056 1048 sd->SetRecordingType(_recording_type); … … bool MpegRecorder::StartEncoding(int fd) 1530 1522 memset(&command, 0, sizeof(struct v4l2_encoder_cmd)); 1531 1523 command.cmd = V4L2_ENC_CMD_START; 1532 1524 1533 if (driver == "hdpvr" && curRecording->GetRecordingGroup() != "LiveTV")1525 if (driver == "hdpvr") 1534 1526 HandleResolutionChanges(); 1535 1527 1536 1528 VERBOSE(VB_RECORD, LOC + "StartEncoding"); … … void MpegRecorder::HandleSingleProgramPM 1620 1612 DTVRecorder::BufferedWrite(_scratch[i]); 1621 1613 } 1622 1614 1623 /// After a resolution change, it can take the HD-PVR a few1624 /// 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 us1633 // some data.1634 QMutexLocker locker(&start_stop_encoding_lock);1635 1636 // Sleep any less than 1.5 seconds, and the HD-PVR will1637 // 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 change1674 usleep(100 * 1000);1675 }1676 1677 VERBOSE(VB_RECORD, LOC + "WaitForHDPVR failed");1678 return false;1679 }1680 1681 1615 void MpegRecorder::SetBitrate(int bitrate, int maxbitrate, 1682 1616 const QString & reason) 1683 1617 { … … void MpegRecorder::HandleResolutionChang 1715 1649 memset(&vfmt, 0, sizeof(vfmt)); 1716 1650 vfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1717 1651 1718 if (driver == "hdpvr")1719 WaitFor_HDPVR();1720 1721 1652 if (0 == ioctl(chanfd, VIDIOC_G_FMT, &vfmt)) 1722 1653 { 1723 1654 VERBOSE(VB_RECORD, LOC + QString("Got Resolution %1x%2") -
libs/libmythtv/mpegrecorder.h
old new class MpegRecorder : public DTVRecorder, 85 85 86 86 void ResetForNewFile(void); 87 87 88 bool WaitFor_HDPVR(void);89 88 void SetBitrate(int bitrate, int maxbitrate, const QString & reason); 90 89 void HandleResolutionChanges(void); 91 90 -
libs/libmythtv/signalmonitor.cpp
old new SignalMonitor *SignalMonitor::Init(QStri 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") -
libs/libmythtv/signalmonitor.h
old new inline bool SignalMonitor::IsRequired(co 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 }