MythTV  0.26-pre
analogsignalmonitor.cpp
Go to the documentation of this file.
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends