diff --git a/mythtv/libs/libmythtv/analogsignalmonitor.cpp b/mythtv/libs/libmythtv/analogsignalmonitor.cpp
index 4e0775d..af933e1 100644
a
|
b
|
|
16 | 16 | |
17 | 17 | #define LOC QString("AnalogSM(%1): ").arg(channel->GetDevice()) |
18 | 18 | |
| 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 | */ |
19 | 24 | AnalogSignalMonitor::AnalogSignalMonitor( |
20 | 25 | int db_cardnum, V4LChannel *_channel, uint64_t _flags) : |
21 | 26 | 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) |
23 | 28 | { |
24 | 29 | int videofd = channel->GetFd(); |
25 | 30 | if (videofd >= 0) |
… |
… |
AnalogSignalMonitor::AnalogSignalMonitor( |
36 | 41 | } |
37 | 42 | } |
38 | 43 | |
39 | | bool AnalogSignalMonitor::handleHDPVR(int videofd) |
| 44 | bool AnalogSignalMonitor::VerifyHDPVRaudio(int videofd) |
40 | 45 | { |
41 | | struct v4l2_encoder_cmd command; |
42 | | struct pollfd polls; |
| 46 | struct v4l2_queryctrl qctrl; |
| 47 | qctrl.id = V4L2_CID_MPEG_AUDIO_ENCODING; |
43 | 48 | |
44 | | if (m_stage == 0) |
| 49 | int audtype = V4L2_MPEG_AUDIO_ENCODING_AC3; |
| 50 | |
| 51 | if (ioctl(videofd, VIDIOC_QUERYCTRL, &qctrl) != 0) |
45 | 52 | { |
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; |
59 | 56 | } |
60 | 57 | |
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) |
62 | 73 | { |
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 | } |
64 | 78 | |
65 | | polls.fd = videofd; |
66 | | polls.events = POLLIN; |
67 | | polls.revents = 0; |
| 79 | current_audio = ext_ctrls.controls->value; |
68 | 80 | |
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) |
70 | 94 | { |
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 | ); |
74 | 100 | } |
75 | 101 | else |
76 | 102 | { |
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 | ); |
85 | 109 | } |
| 110 | |
| 111 | return false; |
86 | 112 | } |
87 | 113 | |
88 | | if (m_stage == 2) |
89 | | { |
90 | | LOG(VB_RECORD, LOG_INFO, "hd-pvr data ready. Stop encoding"); |
| 114 | return true; |
| 115 | } |
91 | 116 | |
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 | | } |
| 117 | bool AnalogSignalMonitor::handleHDPVR(int videofd) |
| 118 | { |
| 119 | struct v4l2_encoder_cmd command; |
| 120 | struct pollfd polls; |
101 | 121 | |
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; |
107 | 125 | |
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) |
110 | 138 | { |
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; |
114 | 143 | } |
115 | 144 | else |
116 | 145 | { |
117 | 146 | QMutexLocker locker(&statusLock); |
118 | | signalStrength.SetValue(75); |
| 147 | signalStrength.SetValue(60 + m_lock_cnt); |
119 | 148 | } |
120 | 149 | } |
| 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 | } |
121 | 158 | |
122 | | return (m_stage == 4); |
| 159 | return false; |
123 | 160 | } |
124 | 161 | |
125 | 162 | void AnalogSignalMonitor::UpdateValues(void) |
diff --git a/mythtv/libs/libmythtv/analogsignalmonitor.h b/mythtv/libs/libmythtv/analogsignalmonitor.h
index dd0154c..97f0065 100644
a
|
b
|
class AnalogSignalMonitor : public SignalMonitor |
19 | 19 | virtual void UpdateValues(void); |
20 | 20 | |
21 | 21 | private: |
| 22 | bool VerifyHDPVRaudio(int videofd); |
22 | 23 | bool handleHDPVR(int videofd); |
23 | 24 | |
24 | 25 | bool m_usingv4l2; |
25 | 26 | QString m_card; |
26 | 27 | QString m_driver; |
27 | 28 | 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; |
29 | 33 | }; |
30 | 34 | |
31 | 35 | #endif // _ANALOG_SIGNAL_MONITOR_H_ |
diff --git a/mythtv/libs/libmythtv/mpegrecorder.cpp b/mythtv/libs/libmythtv/mpegrecorder.cpp
index 0e133ab..95673a5 100644
a
|
b
|
void MpegRecorder::run(void) |
1001 | 1001 | |
1002 | 1002 | if (_device_read_buffer) |
1003 | 1003 | { |
1004 | | len = _device_read_buffer->Read( |
1005 | | &(buffer[remainder]), bufferSize - remainder); |
| 1004 | len = _device_read_buffer->Read |
| 1005 | (&(buffer[remainder]), bufferSize - remainder); |
1006 | 1006 | |
1007 | 1007 | // Check for DRB errors |
1008 | 1008 | if (_device_read_buffer->IsErrored()) |
… |
… |
bool MpegRecorder::StartEncoding(void) |
1318 | 1318 | if (_device_read_buffer) |
1319 | 1319 | { |
1320 | 1320 | _device_read_buffer->Reset(videodevice.toAscii().constData(), readfd); |
| 1321 | _device_read_buffer->SetRequestPause(false); |
1321 | 1322 | _device_read_buffer->Start(); |
1322 | 1323 | } |
1323 | 1324 | |
… |
… |
void MpegRecorder::StopEncoding(void) |
1338 | 1339 | command.cmd = V4L2_ENC_CMD_STOP; |
1339 | 1340 | command.flags = V4L2_ENC_CMD_STOP_AT_GOP_END; |
1340 | 1341 | |
| 1342 | if (_device_read_buffer) |
| 1343 | _device_read_buffer->SetRequestPause(true); |
| 1344 | |
1341 | 1345 | bool stopped = 0 == ioctl(readfd, VIDIOC_ENCODER_CMD, &command); |
1342 | 1346 | if (stopped) |
1343 | 1347 | { |
… |
… |
void MpegRecorder::StopEncoding(void) |
1362 | 1366 | } |
1363 | 1367 | |
1364 | 1368 | // close the fd so streamoff/streamon work in V4LChannel |
1365 | | close(readfd); |
| 1369 | close(readfd); |
1366 | 1370 | readfd = -1; |
1367 | 1371 | } |
1368 | 1372 | |