|
MythTV
0.26-pre
|
00001 // -*- Mode: c++ -*- 00002 // Copyright (c) 2005, Daniel Thor Kristjansson 00003 00004 #include <cerrno> 00005 #include <unistd.h> 00006 #include <sys/ioctl.h> 00007 #include <poll.h> 00008 00009 #ifdef USING_V4L1 00010 #include <linux/videodev.h> 00011 #endif // USING_V4L1 00012 00013 #include "mythlogging.h" 00014 #include "analogsignalmonitor.h" 00015 #include "v4lchannel.h" 00016 00017 #define LOC QString("AnalogSM(%1): ").arg(channel->GetDevice()) 00018 00019 AnalogSignalMonitor::AnalogSignalMonitor( 00020 int db_cardnum, V4LChannel *_channel, uint64_t _flags) : 00021 SignalMonitor(db_cardnum, _channel, _flags), 00022 m_usingv4l2(false), m_stage(0) 00023 { 00024 int videofd = channel->GetFd(); 00025 if (videofd >= 0) 00026 { 00027 uint32_t caps; 00028 if (!CardUtil::GetV4LInfo(videofd, m_card, m_driver, m_version, caps)) 00029 { 00030 videofd = -1; 00031 return; 00032 } 00033 m_usingv4l2 = !!(caps & V4L2_CAP_VIDEO_CAPTURE); 00034 LOG(VB_RECORD, LOG_INFO, QString("card '%1' driver '%2' version '%3'") 00035 .arg(m_card).arg(m_driver).arg(m_version)); 00036 } 00037 } 00038 00039 bool AnalogSignalMonitor::handleHDPVR(int videofd) 00040 { 00041 struct v4l2_encoder_cmd command; 00042 struct pollfd polls; 00043 00044 if (m_stage == 0) 00045 { 00046 LOG(VB_RECORD, LOG_INFO, "hd-pvr start encoding"); 00047 // Tell it to start encoding, then wait for it to actually feed us 00048 // some data. 00049 memset(&command, 0, sizeof(struct v4l2_encoder_cmd)); 00050 command.cmd = V4L2_ENC_CMD_START; 00051 if (ioctl(videofd, VIDIOC_ENCODER_CMD, &command) == 0) 00052 m_stage = 1; 00053 else 00054 { 00055 LOG(VB_GENERAL, LOG_ERR, "Start encoding failed" + ENO); 00056 command.cmd = V4L2_ENC_CMD_STOP; 00057 ioctl(videofd, VIDIOC_ENCODER_CMD, &command); 00058 } 00059 } 00060 00061 if (m_stage == 1) 00062 { 00063 LOG(VB_RECORD, LOG_INFO, "hd-pvr wait for data"); 00064 00065 polls.fd = videofd; 00066 polls.events = POLLIN; 00067 polls.revents = 0; 00068 00069 if (poll(&polls, 1, 1500) > 0) 00070 { 00071 m_stage = 2; 00072 QMutexLocker locker(&statusLock); 00073 signalStrength.SetValue(25); 00074 } 00075 else 00076 { 00077 LOG(VB_RECORD, LOG_INFO, "Poll timed-out. Resetting"); 00078 memset(&command, 0, sizeof(struct v4l2_encoder_cmd)); 00079 command.cmd = V4L2_ENC_CMD_STOP; 00080 ioctl(videofd, VIDIOC_ENCODER_CMD, &command); 00081 m_stage = 0; 00082 00083 QMutexLocker locker(&statusLock); 00084 signalStrength.SetValue(0); 00085 } 00086 } 00087 00088 if (m_stage == 2) 00089 { 00090 LOG(VB_RECORD, LOG_INFO, "hd-pvr data ready. Stop encoding"); 00091 00092 command.cmd = V4L2_ENC_CMD_STOP; 00093 if (ioctl(videofd, VIDIOC_ENCODER_CMD, &command) == 0) 00094 m_stage = 3; 00095 else 00096 { 00097 QMutexLocker locker(&statusLock); 00098 signalStrength.SetValue(50); 00099 } 00100 } 00101 00102 if (m_stage == 3) 00103 { 00104 struct v4l2_format vfmt; 00105 memset(&vfmt, 0, sizeof(vfmt)); 00106 vfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 00107 00108 LOG(VB_RECORD, LOG_INFO, "hd-pvr waiting for valid resolution"); 00109 if ((ioctl(videofd, VIDIOC_G_FMT, &vfmt) == 0) && vfmt.fmt.pix.width) 00110 { 00111 LOG(VB_RECORD, LOG_INFO, QString("hd-pvr resolution %1 x %2") 00112 .arg(vfmt.fmt.pix.width).arg(vfmt.fmt.pix.height)); 00113 m_stage = 4; 00114 } 00115 else 00116 { 00117 QMutexLocker locker(&statusLock); 00118 signalStrength.SetValue(75); 00119 } 00120 } 00121 00122 return (m_stage == 4); 00123 } 00124 00125 void AnalogSignalMonitor::UpdateValues(void) 00126 { 00127 SignalMonitor::UpdateValues(); 00128 00129 { 00130 QMutexLocker locker(&statusLock); 00131 if (!scriptStatus.IsGood()) 00132 return; 00133 } 00134 00135 if (!running || exit) 00136 return; 00137 00138 int videofd = channel->GetFd(); 00139 if (videofd < 0) 00140 return; 00141 00142 bool isLocked = false; 00143 if (m_usingv4l2) 00144 { 00145 if (m_driver == "hdpvr") 00146 isLocked = handleHDPVR(videofd); 00147 else 00148 { 00149 struct v4l2_tuner tuner; 00150 memset(&tuner, 0, sizeof(tuner)); 00151 00152 if (ioctl(videofd, VIDIOC_G_TUNER, &tuner, 0) < 0) 00153 { 00154 LOG(VB_GENERAL, LOG_ERR, "Failed to probe signal (v4l2)" + ENO); 00155 } 00156 else 00157 { 00158 isLocked = tuner.signal; 00159 } 00160 } 00161 } 00162 #ifdef USING_V4L1 00163 else 00164 { 00165 struct video_tuner tuner; 00166 memset(&tuner, 0, sizeof(tuner)); 00167 00168 if (ioctl(videofd, VIDIOCGTUNER, &tuner, 0) < 0) 00169 { 00170 LOG(VB_GENERAL, LOG_ERR, "Failed to probe signal (v4l1)" + ENO); 00171 } 00172 else 00173 { 00174 isLocked = tuner.signal; 00175 } 00176 } 00177 #endif // USING_V4L1 00178 00179 { 00180 QMutexLocker locker(&statusLock); 00181 signalLock.SetValue(isLocked); 00182 if (isLocked) 00183 signalStrength.SetValue(100); 00184 } 00185 00186 EmitStatus(); 00187 if (IsAllGood()) 00188 SendMessageAllGood(); 00189 } 00190
1.7.6.1