diff -r -u -N -X diff.exclude -x release.19703.0116c -x release.19703.0116d release.19703.0116c/mythtv/libs/libmythtv/DeviceReadBuffer.cpp release.19703.0116d/mythtv/libs/libmythtv/DeviceReadBuffer.cpp
|
|
|
196 | 196 | used += len; |
197 | 197 | writePtr += len; |
198 | 198 | writePtr = (writePtr == endPtr) ? buffer : writePtr; |
199 | | #if REPORT_RING_STATS |
200 | 199 | max_used = max(used, max_used); |
| 200 | #if REPORT_RING_STATS |
201 | 201 | avg_used = ((avg_used * avg_cnt) + used) / ++avg_cnt; |
202 | 202 | #endif |
203 | 203 | } |
diff -r -u -N -X diff.exclude -x release.19703.0116c -x release.19703.0116d release.19703.0116c/mythtv/libs/libmythtv/DeviceReadBuffer.h release.19703.0116d/mythtv/libs/libmythtv/DeviceReadBuffer.h
|
|
|
40 | 40 | void Reset(const QString &streamName, int streamfd); |
41 | 41 | void Stop(void); |
42 | 42 | |
| 43 | size_t GetMaxUsed() const { return max_used; }; |
| 44 | |
43 | 45 | void SetRequestPause(bool request); |
44 | 46 | bool IsPaused(void) const; |
45 | 47 | bool WaitForUnpause(int timeout); |
diff -r -u -N -X diff.exclude -x release.19703.0116c -x release.19703.0116d release.19703.0116c/mythtv/libs/libmythtv/ThreadedFileWriter.cpp release.19703.0116d/mythtv/libs/libmythtv/ThreadedFileWriter.cpp
|
|
|
134 | 134 | rpos(0), wpos(0), |
135 | 135 | written(0), |
136 | 136 | // buffer |
137 | | buf(NULL), tfw_buf_size(0) |
| 137 | buf(NULL), tfw_buf_size(0), |
| 138 | tfw_highwater_mark(0) |
138 | 139 | { |
139 | 140 | } |
140 | 141 | |
… |
… |
|
160 | 161 | |
161 | 162 | tfw_buf_size = TFW_DEF_BUF_SIZE; |
162 | 163 | tfw_min_write_size = TFW_MIN_WRITE_SIZE; |
| 164 | tfw_highwater_mark = 0; |
163 | 165 | pthread_create(&writer, NULL, boot_writer, this); |
164 | 166 | pthread_create(&syncer, NULL, boot_syncer, this); |
165 | 167 | return true; |
… |
… |
|
192 | 194 | delete [] buf; |
193 | 195 | buf = NULL; |
194 | 196 | } |
| 197 | |
| 198 | VERBOSE(VB_GENERAL, LOC + QString("Buffer size = %1 KB hwm = %2 KB") |
| 199 | .arg(tfw_buf_size / 1024).arg(tfw_highwater_mark/1024)); |
195 | 200 | } |
196 | 201 | |
197 | 202 | /** \fn ThreadedFileWriter::Write(const void*, uint) |
… |
… |
|
434 | 439 | uint ThreadedFileWriter::BufUsed(void) |
435 | 440 | { |
436 | 441 | QMutexLocker locker(&buflock); |
437 | | return (wpos >= rpos) ? wpos - rpos : tfw_buf_size - rpos + wpos; |
| 442 | uint result = (wpos >= rpos) ? wpos - rpos : tfw_buf_size - rpos + wpos; |
| 443 | if (result > tfw_highwater_mark) |
| 444 | tfw_highwater_mark=result; |
| 445 | return result; |
438 | 446 | } |
439 | 447 | |
440 | 448 | /** \fn ThreadedFileWriter::BufFree(void) |
diff -r -u -N -X diff.exclude -x release.19703.0116c -x release.19703.0116d release.19703.0116c/mythtv/libs/libmythtv/ThreadedFileWriter.h release.19703.0116d/mythtv/libs/libmythtv/ThreadedFileWriter.h
|
|
|
58 | 58 | // buffer |
59 | 59 | char *buf; |
60 | 60 | unsigned long tfw_buf_size; |
| 61 | unsigned long tfw_highwater_mark; |
61 | 62 | |
62 | 63 | // threads |
63 | 64 | pthread_t writer; |
diff -r -u -N -X diff.exclude -x release.19703.0116c -x release.19703.0116d release.19703.0116c/mythtv/libs/libmythtv/dvbrecorder.cpp release.19703.0116d/mythtv/libs/libmythtv/dvbrecorder.cpp
|
|
|
337 | 337 | { |
338 | 338 | VERBOSE(VB_RECORD, LOC + "Close() fd("<<_stream_fd<<") -- begin"); |
339 | 339 | |
| 340 | uint hwm = _stream_handler->GetMaxUsed(); |
| 341 | VERBOSE(VB_GENERAL,QString( LOC + "DVB Stats: pkts=%1 hwm=%2 KB Errors: trnsprt=%3 seq=%4") |
| 342 | .arg(_total_packet_count) |
| 343 | .arg(hwm/1024) |
| 344 | .arg(_transport_error_count) |
| 345 | .arg(_continuity_error_count)); |
| 346 | |
340 | 347 | DVBStreamHandler::Return(_stream_handler); |
341 | 348 | |
342 | 349 | VERBOSE(VB_RECORD, LOC + "Close() fd("<<_stream_fd<<") -- end"); |
… |
… |
|
381 | 388 | |
382 | 389 | _continuity_error_count = 0; |
383 | 390 | _stream_overflow_count = 0; |
| 391 | _transport_error_count = 0; |
| 392 | _bad_packet_count = 0; |
| 393 | _total_packet_count = 0; |
384 | 394 | |
385 | 395 | _request_recording = true; |
386 | 396 | _recording = true; |
… |
… |
|
524 | 534 | QString("PID 0x%1 discontinuity detected").arg(pid,0,16)); |
525 | 535 | _continuity_error_count++; |
526 | 536 | } |
| 537 | if (tspacket.TransportError()) |
| 538 | { |
| 539 | _transport_error_count++; |
| 540 | } |
| 541 | _total_packet_count++; |
527 | 542 | |
528 | 543 | // Sync recording start to first keyframe |
529 | 544 | if (_wait_for_keyframe_option && _first_keyframe < 0) |
… |
… |
|
558 | 573 | QString("PID 0x%1 discontinuity detected").arg(pid,0,16)); |
559 | 574 | _continuity_error_count++; |
560 | 575 | } |
| 576 | if (tspacket.TransportError()) |
| 577 | { |
| 578 | _transport_error_count++; |
| 579 | } |
| 580 | |
| 581 | _total_packet_count++; |
561 | 582 | |
562 | 583 | // Only create fake keyframe[s] if there are no audio/video streams |
563 | 584 | if (_input_pmt && _has_no_av) |
diff -r -u -N -X diff.exclude -x release.19703.0116c -x release.19703.0116d release.19703.0116c/mythtv/libs/libmythtv/dvbrecorder.h release.19703.0116d/mythtv/libs/libmythtv/dvbrecorder.h
|
|
|
130 | 130 | mutable uint _continuity_error_count; |
131 | 131 | mutable uint _stream_overflow_count; |
132 | 132 | mutable uint _bad_packet_count; |
| 133 | mutable uint _transport_error_count; |
| 134 | mutable uint _total_packet_count; |
133 | 135 | |
134 | 136 | // Constants |
135 | 137 | static const int TSPACKETS_BETWEEN_PSIP_SYNC; |
diff -r -u -N -X diff.exclude -x release.19703.0116c -x release.19703.0116d release.19703.0116c/mythtv/libs/libmythtv/dvbstreamhandler.cpp release.19703.0116d/mythtv/libs/libmythtv/dvbstreamhandler.cpp
|
|
|
97 | 97 | _dvbchannel(NULL), |
98 | 98 | |
99 | 99 | _pid_lock(true), |
100 | | _listener_lock(true) |
| 100 | _listener_lock(true), |
| 101 | _max_used(0) |
101 | 102 | { |
102 | 103 | } |
103 | 104 | |
… |
… |
|
196 | 197 | } |
197 | 198 | } |
198 | 199 | |
| 200 | uint DVBStreamHandler::GetMaxUsed(void) |
| 201 | { |
| 202 | QMutexLocker locker(&_start_stop_lock); |
| 203 | if (_device_read_buffer) |
| 204 | { |
| 205 | _max_used = _device_read_buffer->GetMaxUsed(); |
| 206 | } |
| 207 | return _max_used; |
| 208 | } |
| 209 | |
199 | 210 | void DVBStreamHandler::Stop(void) |
200 | 211 | { |
201 | 212 | QMutexLocker locker(&_start_stop_lock); |
… |
… |
|
203 | 214 | if (IsRunning()) |
204 | 215 | { |
205 | 216 | if (_device_read_buffer) |
| 217 | { |
206 | 218 | _device_read_buffer->Stop(); |
| 219 | _max_used = _device_read_buffer->GetMaxUsed(); |
| 220 | } |
207 | 221 | SetRunning(false); |
208 | 222 | pthread_join(_reader_thread, NULL); |
209 | 223 | } |
… |
… |
|
243 | 257 | return; |
244 | 258 | bzero(buffer, buffer_size); |
245 | 259 | |
| 260 | VERBOSE(VB_GENERAL, QString(LOC + "HD Ringbuffer size = %1 KB").arg(buffer_size / 1024)); |
| 261 | |
246 | 262 | int dvr_fd = open(_dvr_dev_path.ascii(), O_RDONLY | O_NONBLOCK); |
247 | 263 | if (dvr_fd < 0) |
248 | 264 | { |
… |
… |
|
348 | 364 | if (_device_read_buffer->IsRunning()) |
349 | 365 | _device_read_buffer->Stop(); |
350 | 366 | |
| 367 | _max_used=_device_read_buffer->GetMaxUsed(); |
| 368 | |
351 | 369 | delete _device_read_buffer; |
352 | 370 | _device_read_buffer = NULL; |
353 | 371 | } |
diff -r -u -N -X diff.exclude -x release.19703.0116c -x release.19703.0116d release.19703.0116c/mythtv/libs/libmythtv/dvbstreamhandler.h release.19703.0116d/mythtv/libs/libmythtv/dvbstreamhandler.h
|
|
|
70 | 70 | // ReaderPausedCB |
71 | 71 | virtual void ReaderPaused(int fd) { (void) fd; } |
72 | 72 | |
| 73 | uint GetMaxUsed(); |
| 74 | |
73 | 75 | private: |
74 | 76 | DVBStreamHandler(uint); |
75 | 77 | ~DVBStreamHandler(); |
… |
… |
|
118 | 120 | mutable QMutex _listener_lock; |
119 | 121 | vector<MPEGStreamData*> _stream_data_list; |
120 | 122 | |
| 123 | uint _max_used; |
| 124 | |
121 | 125 | // for caching TS monitoring supported value. |
122 | 126 | static QMutex _rec_supports_ts_monitoring_lock; |
123 | 127 | static QMap<uint,bool> _rec_supports_ts_monitoring; |
diff -r -u -N -X diff.exclude -x release.19703.0116c -x release.19703.0116d release.19703.0116c/mythtv/libs/libmythtv/hdhomerun/hdhomerun_video.c release.19703.0116d/mythtv/libs/libmythtv/hdhomerun/hdhomerun_video.c
|
|
|
49 | 49 | volatile uint32_t network_error_count; |
50 | 50 | volatile uint32_t sequence_error_count; |
51 | 51 | volatile uint32_t overflow_error_count; |
| 52 | volatile uint32_t buffer_highwater_mark; |
52 | 53 | volatile uint8_t sequence[0x2000]; |
53 | 54 | }; |
54 | 55 | |
… |
… |
|
286 | 287 | head -= vs->buffer_size; |
287 | 288 | } |
288 | 289 | |
| 290 | /* update buffer_highwater_mark */ |
| 291 | /* head - where things will be inserted */ |
| 292 | /* tail - where things will be removed */ |
| 293 | size_t tail = vs->tail; |
| 294 | uint32_t space_used; |
| 295 | if (head > tail) { |
| 296 | space_used = head - tail; |
| 297 | } else { |
| 298 | /* head < tail */ |
| 299 | space_used = (head + vs->buffer_size) - tail; |
| 300 | } |
| 301 | |
| 302 | if (space_used > vs->buffer_highwater_mark) { |
| 303 | vs->buffer_highwater_mark = space_used; |
| 304 | } |
| 305 | |
289 | 306 | /* Check for buffer overflow. */ |
290 | 307 | if (head == vs->tail) { |
291 | 308 | vs->overflow_error_count++; |
… |
… |
|
367 | 384 | vs->network_error_count = 0; |
368 | 385 | vs->sequence_error_count = 0; |
369 | 386 | vs->overflow_error_count = 0; |
| 387 | vs->buffer_highwater_mark = 0; |
370 | 388 | |
371 | 389 | pthread_mutex_unlock(&vs->lock); |
372 | 390 | } |
… |
… |
|
376 | 394 | struct hdhomerun_video_stats_t stats; |
377 | 395 | hdhomerun_video_get_stats(vs, &stats); |
378 | 396 | |
379 | | hdhomerun_debug_printf(vs->dbg, "video sock: pkt=%ld net=%ld te=%ld miss=%ld drop=%ld\n", |
| 397 | hdhomerun_debug_printf(vs->dbg, "video sock: pkt=%ld net=%ld te=%ld miss=%ld drop=%ld hwm=%ld\n", |
380 | 398 | stats.packet_count, stats.network_error_count, |
381 | 399 | stats.transport_error_count, stats.sequence_error_count, |
382 | | stats.overflow_error_count |
| 400 | stats.overflow_error_count, stats.buffer_highwater_mark |
383 | 401 | ); |
384 | 402 | } |
385 | 403 | |
… |
… |
|
394 | 412 | stats->transport_error_count = vs->transport_error_count; |
395 | 413 | stats->sequence_error_count = vs->sequence_error_count; |
396 | 414 | stats->overflow_error_count = vs->overflow_error_count; |
| 415 | stats->buffer_highwater_mark = vs->buffer_highwater_mark; |
397 | 416 | |
398 | 417 | pthread_mutex_unlock(&vs->lock); |
399 | 418 | } |
diff -r -u -N -X diff.exclude -x release.19703.0116c -x release.19703.0116d release.19703.0116c/mythtv/libs/libmythtv/hdhomerun/hdhomerun_video.h release.19703.0116d/mythtv/libs/libmythtv/hdhomerun/hdhomerun_video.h
|
|
|
41 | 41 | uint32_t transport_error_count; |
42 | 42 | uint32_t sequence_error_count; |
43 | 43 | uint32_t overflow_error_count; |
| 44 | uint32_t buffer_highwater_mark; |
44 | 45 | }; |
45 | 46 | |
46 | 47 | #define TS_PACKET_SIZE 188 |
diff -r -u -N -X diff.exclude -x release.19703.0116c -x release.19703.0116d release.19703.0116c/mythtv/libs/libmythtv/hdhrrecorder.cpp release.19703.0116d/mythtv/libs/libmythtv/hdhrrecorder.cpp
|
|
|
116 | 116 | memset(_continuity_counter, 0xff, sizeof(_continuity_counter)); |
117 | 117 | |
118 | 118 | _stream_handler = HDHRStreamHandler::Get(_channel->GetDeviceId(), _channel->GetTuner(), _channel->GetDevice()); |
| 119 | _stream_handler->GetStats(&_start_stats, false); |
119 | 120 | |
120 | 121 | VERBOSE(VB_RECORD, LOC + "HDHR opened successfully"); |
121 | 122 | |
… |
… |
|
128 | 129 | |
129 | 130 | if (IsOpen()) |
130 | 131 | { |
| 132 | hdhomerun_video_stats_t end_stats; |
| 133 | _stream_handler->GetStats(&end_stats, true); |
| 134 | |
| 135 | VERBOSE(VB_GENERAL,QString( LOC + "HDHR Stats: pkts=%1 hwm=%6 KB Errors: net=%2 trnsprt=%3 seq=%4 ovflow=%5") |
| 136 | .arg(end_stats.packet_count - _start_stats.packet_count) |
| 137 | .arg(end_stats.network_error_count - _start_stats.network_error_count) |
| 138 | .arg(end_stats.transport_error_count - _start_stats.transport_error_count) |
| 139 | .arg(end_stats.sequence_error_count - _start_stats.sequence_error_count) |
| 140 | .arg(end_stats.overflow_error_count - _start_stats.overflow_error_count) |
| 141 | .arg(end_stats.buffer_highwater_mark / 1024)); /* buffer_highwater_mark is absolute */ |
| 142 | |
131 | 143 | HDHRStreamHandler::Return(_stream_handler); |
132 | 144 | } |
133 | 145 | else |
diff -r -u -N -X diff.exclude -x release.19703.0116c -x release.19703.0116d release.19703.0116c/mythtv/libs/libmythtv/hdhrrecorder.h release.19703.0116d/mythtv/libs/libmythtv/hdhrrecorder.h
|
|
|
92 | 92 | ProgramMapTable *_input_pmt; |
93 | 93 | bool _has_no_av; |
94 | 94 | |
| 95 | hdhomerun_video_stats_t _start_stats; |
| 96 | |
95 | 97 | unsigned char _stream_id[0x1fff]; |
96 | 98 | unsigned char _pid_status[0x1fff]; |
97 | 99 | unsigned char _continuity_counter[0x1fff]; |
diff -r -u -N -X diff.exclude -x release.19703.0116c -x release.19703.0116d release.19703.0116c/mythtv/libs/libmythtv/hdhrstreamhandler.cpp release.19703.0116d/mythtv/libs/libmythtv/hdhrstreamhandler.cpp
|
|
|
102 | 102 | _listener_lock(true), |
103 | 103 | _hdhr_lock(true) |
104 | 104 | { |
| 105 | memset(&_last_stats, 0, sizeof(_last_stats)); |
105 | 106 | } |
106 | 107 | |
107 | 108 | HDHRStreamHandler::~HDHRStreamHandler() |
… |
… |
|
286 | 287 | return (QString::null != TunerSet("target", "0.0.0.0:0")); |
287 | 288 | } |
288 | 289 | |
| 290 | void HDHRStreamHandler::GetStats(hdhomerun_video_stats_t* stats, bool use_cache) { |
| 291 | QMutexLocker locker(&_hdhr_lock); |
| 292 | if (_video_socket) { |
| 293 | hdhomerun_video_get_stats(_video_socket, &_last_stats); |
| 294 | memcpy(stats, &_last_stats, sizeof(hdhomerun_video_stats_t)); |
| 295 | } else if (use_cache) { |
| 296 | memcpy(stats, &_last_stats, sizeof(hdhomerun_video_stats_t)); |
| 297 | } else { |
| 298 | memset(stats, 0, sizeof(hdhomerun_video_stats_t)); |
| 299 | } |
| 300 | } |
| 301 | |
289 | 302 | QString HDHRStreamHandler::GetTunerStatus() { |
290 | 303 | return TunerGet("status"); |
291 | 304 | } |
… |
… |
|
494 | 507 | hdhomerun_video_sock_t* tmp_video_socket; |
495 | 508 | { |
496 | 509 | QMutexLocker locker(&_hdhr_lock); |
| 510 | hdhomerun_video_get_stats(_video_socket, &_last_stats); |
497 | 511 | tmp_video_socket = _video_socket; |
498 | 512 | _video_socket=NULL; |
499 | 513 | } |
diff -r -u -N -X diff.exclude -x release.19703.0116c -x release.19703.0116d release.19703.0116c/mythtv/libs/libmythtv/hdhrstreamhandler.h release.19703.0116d/mythtv/libs/libmythtv/hdhrstreamhandler.h
|
|
|
50 | 50 | DTVSignalMonitor *sigmon, |
51 | 51 | HDHRChannel *dvbchan); |
52 | 52 | |
| 53 | void GetStats(hdhomerun_video_stats_t* stats, bool use_cache); |
| 54 | |
53 | 55 | // ReaderPausedCB |
54 | 56 | virtual void ReaderPaused(int fd) { (void) fd; } |
55 | 57 | |
… |
… |
|
106 | 108 | private: |
107 | 109 | hdhomerun_control_sock_t *_control_socket; |
108 | 110 | hdhomerun_video_sock_t *_video_socket; |
| 111 | hdhomerun_video_stats_t _last_stats; |
109 | 112 | uint _device_id; |
110 | 113 | uint _device_ip; |
111 | 114 | uint _tuner; |