diff --git a/mythtv/libs/libmythtv/analogsignalmonitor.cpp b/mythtv/libs/libmythtv/analogsignalmonitor.cpp
index 4e0775d..b1d9bbb 100644
a
|
b
|
|
19 | 19 | AnalogSignalMonitor::AnalogSignalMonitor( |
20 | 20 | int db_cardnum, V4LChannel *_channel, uint64_t _flags) : |
21 | 21 | SignalMonitor(db_cardnum, _channel, _flags), |
22 | | m_usingv4l2(false), m_stage(0) |
| 22 | m_usingv4l2(false), m_width(0), m_lock_cnt(0) |
23 | 23 | { |
24 | 24 | int videofd = channel->GetFd(); |
25 | 25 | if (videofd >= 0) |
… |
… |
AnalogSignalMonitor::AnalogSignalMonitor( |
34 | 34 | LOG(VB_RECORD, LOG_INFO, QString("card '%1' driver '%2' version '%3'") |
35 | 35 | .arg(m_card).arg(m_driver).arg(m_version)); |
36 | 36 | } |
| 37 | m_stable_time = 2000; // Desire a stable signal for 2 second |
37 | 38 | } |
38 | 39 | |
39 | | bool AnalogSignalMonitor::handleHDPVR(int videofd) |
| 40 | bool AnalogSignalMonitor::VerifyHDPVRaudio(int videofd) |
40 | 41 | { |
41 | | struct v4l2_encoder_cmd command; |
42 | | struct pollfd polls; |
| 42 | struct v4l2_queryctrl qctrl; |
| 43 | qctrl.id = V4L2_CID_MPEG_AUDIO_ENCODING; |
43 | 44 | |
44 | | if (m_stage == 0) |
| 45 | int audtype = V4L2_MPEG_AUDIO_ENCODING_AC3; |
| 46 | |
| 47 | if (ioctl(videofd, VIDIOC_QUERYCTRL, &qctrl) != 0) |
45 | 48 | { |
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 | | } |
| 49 | LOG(VB_GENERAL, LOG_ERR, LOC + |
| 50 | "Unable to get supported audio codecs for verification." + ENO); |
| 51 | return false; |
59 | 52 | } |
60 | 53 | |
61 | | if (m_stage == 1) |
| 54 | int current_audio; |
| 55 | uint audio_enc = max(min(audtype - 1, qctrl.maximum), qctrl.minimum); |
| 56 | |
| 57 | struct v4l2_ext_control ext_ctrl; |
| 58 | struct v4l2_ext_controls ext_ctrls; |
| 59 | |
| 60 | memset(&ext_ctrl, 0, sizeof(struct v4l2_ext_control)); |
| 61 | ext_ctrl.id = V4L2_CID_MPEG_AUDIO_ENCODING; |
| 62 | |
| 63 | ext_ctrls.reserved[0] = ext_ctrls.reserved[1] = 0; |
| 64 | ext_ctrls.count = 1; |
| 65 | ext_ctrls.ctrl_class = V4L2_CTRL_CLASS_MPEG; |
| 66 | ext_ctrls.controls = &ext_ctrl; |
| 67 | |
| 68 | if (ioctl(videofd, VIDIOC_G_EXT_CTRLS, &ext_ctrls) != 0) |
62 | 69 | { |
63 | | LOG(VB_RECORD, LOG_INFO, "hd-pvr wait for data"); |
| 70 | LOG(VB_GENERAL, LOG_ERR, LOC + |
| 71 | "Unable to get current audio codecs for verification." + ENO); |
| 72 | return false; |
| 73 | } |
64 | 74 | |
65 | | polls.fd = videofd; |
66 | | polls.events = POLLIN; |
67 | | polls.revents = 0; |
| 75 | current_audio = ext_ctrls.controls->value; |
68 | 76 | |
69 | | if (poll(&polls, 1, 1500) > 0) |
| 77 | if (audtype - 1 != current_audio) |
| 78 | { |
| 79 | LOG(VB_GENERAL, LOG_ERR, LOC + QString("Audio desired %1, current %2 " |
| 80 | "min %3 max %4") |
| 81 | .arg(audtype - 1) |
| 82 | .arg(current_audio) |
| 83 | .arg(qctrl.minimum) |
| 84 | .arg(qctrl.maximum) |
| 85 | ); |
| 86 | |
| 87 | ext_ctrl.id = V4L2_CID_MPEG_AUDIO_ENCODING; |
| 88 | ext_ctrl.value = audtype - 1; |
| 89 | if (ioctl(videofd, VIDIOC_S_EXT_CTRLS, &ext_ctrls) == 0) |
70 | 90 | { |
71 | | m_stage = 2; |
72 | | QMutexLocker locker(&statusLock); |
73 | | signalStrength.SetValue(25); |
| 91 | LOG(VB_GENERAL, LOG_ERR, LOC + QString("Changed audio encoding " |
| 92 | "from %1 to %2.") |
| 93 | .arg(current_audio) |
| 94 | .arg(audtype - 1) |
| 95 | ); |
74 | 96 | } |
75 | 97 | else |
76 | 98 | { |
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); |
| 99 | LOG(VB_GENERAL, LOG_ERR, LOC + QString("Failed to changed audio " |
| 100 | "encoding from %1 to %2." |
| 101 | + ENO) |
| 102 | .arg(current_audio) |
| 103 | .arg(audtype - 1) |
| 104 | ); |
85 | 105 | } |
| 106 | |
| 107 | return false; |
86 | 108 | } |
87 | 109 | |
88 | | if (m_stage == 2) |
89 | | { |
90 | | LOG(VB_RECORD, LOG_INFO, "hd-pvr data ready. Stop encoding"); |
| 110 | return true; |
| 111 | } |
91 | 112 | |
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 | | } |
| 113 | bool AnalogSignalMonitor::handleHDPVR(int videofd) |
| 114 | { |
| 115 | struct v4l2_encoder_cmd command; |
| 116 | struct pollfd polls; |
101 | 117 | |
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; |
| 118 | struct v4l2_format vfmt; |
| 119 | memset(&vfmt, 0, sizeof(vfmt)); |
| 120 | vfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
107 | 121 | |
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) |
| 122 | if ((ioctl(videofd, VIDIOC_G_FMT, &vfmt) == 0) && |
| 123 | vfmt.fmt.pix.width && m_width == vfmt.fmt.pix.width && |
| 124 | VerifyHDPVRaudio(videofd)) |
| 125 | { |
| 126 | if (!m_timer.isRunning()) |
| 127 | { |
| 128 | LOG(VB_RECORD, LOG_ERR, QString("hd-pvr resolution %1 x %2") |
| 129 | .arg(vfmt.fmt.pix.width).arg(vfmt.fmt.pix.height)); |
| 130 | ++m_lock_cnt; |
| 131 | m_timer.start(); |
| 132 | } |
| 133 | else if (m_timer.elapsed() > m_stable_time) |
110 | 134 | { |
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; |
| 135 | LOG(VB_RECORD, LOG_ERR, QString("hd-pvr stable at %1 x %2") |
| 136 | .arg(vfmt.fmt.pix.width).arg(vfmt.fmt.pix.height)); |
| 137 | m_timer.stop(); |
| 138 | return true; |
114 | 139 | } |
115 | 140 | else |
116 | 141 | { |
117 | 142 | QMutexLocker locker(&statusLock); |
118 | | signalStrength.SetValue(75); |
| 143 | signalStrength.SetValue(60 + m_lock_cnt); |
119 | 144 | } |
120 | 145 | } |
| 146 | else |
| 147 | { |
| 148 | LOG(VB_RECORD, LOG_ERR, "hd-pvr waiting for valid resolution"); |
| 149 | m_width = vfmt.fmt.pix.width; |
| 150 | m_timer.stop(); |
| 151 | QMutexLocker locker(&statusLock); |
| 152 | signalStrength.SetValue(20 + m_lock_cnt); |
| 153 | } |
121 | 154 | |
122 | | return (m_stage == 4); |
| 155 | return false; |
123 | 156 | } |
124 | 157 | |
125 | 158 | 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 | |