MythTV master
mythinteractivebuffer.cpp
Go to the documentation of this file.
1// Std
2#include <cstdio>
3
4// Qt
5#include <QWriteLocker>
6
7// Mythtv
9
11#include "mheg/netstream.h"
12
13#define LOC QString("InteractiveBuf: ")
14
17 m_parent(Parent)
18{
19 m_startReadAhead = true;
21}
22
24{
26 delete m_stream;
27 delete m_parent;
28}
29
31{
32 return m_stream ? m_stream->IsOpen() : false;
33}
34
41bool MythInteractiveBuffer::OpenFile(const QString &Url, std::chrono::milliseconds /*Retry*/)
42{
43 if (!NetStream::IsSupported(Url))
44 {
45 LOG(VB_GENERAL, LOG_ERR, LOC + QString("Unsupported URL '%1'").arg(Url));
46 return false;
47 }
48
49 std::unique_ptr<NetStream> stream(new NetStream(Url, NetStream::kNeverCache));
50 if (!stream || !stream->IsOpen())
51 {
52 LOG(VB_GENERAL, LOG_ERR, LOC + QString("Failed to open '%1'").arg(Url));
53 return false;
54 }
55
56 if (!stream->WaitTillReady(30s))
57 {
58 LOG(VB_GENERAL, LOG_ERR, LOC + QString("Stream not ready '%1'").arg(Url));
59 return false;
60 }
61
62 if (m_parent)
63 m_parent->Pause();
64
65 QWriteLocker locker(&m_rwLock);
66
67 m_safeFilename = Url;
68 m_filename = Url;
69
70 delete m_stream;
71 m_stream = stream.release();
72
73 // The initial bitrate needs to be set with consideration for low bit rate
74 // streams (e.g. radio @ 64Kbps) such that fill_min bytes are received
75 // in a reasonable time period to enable decoders to peek the first few KB
76 // to determine type & settings.
77 m_rawBitrate = 128; // remotefile
79
80 locker.unlock();
81 Reset(true, false, true);
82
83 LOG(VB_GENERAL, LOG_INFO, LOC + QString("Opened '%1'").arg(Url));
84 return true;
85}
86
88{
89 return m_stream ? m_stream->GetReadPosition() : 0;
90}
91
92long long MythInteractiveBuffer::SeekInternal(long long Position, int Whence)
93{
94 long long result = -1;
95 if (!m_stream)
96 return result;
97
98 QWriteLocker locker(&m_posLock);
99
100 // Optimize no-op seeks
101 if (m_readAheadRunning && ((Whence == SEEK_SET && Position == m_readPos) ||
102 (Whence == SEEK_CUR && Position == 0)))
103 {
104 result = m_readPos;
105 return result;
106 }
107
108 switch (Whence)
109 {
110 case SEEK_SET: break;
111 case SEEK_CUR:
112 Position += m_stream->GetReadPosition();
113 break;
114 case SEEK_END:
115 Position += m_stream->GetSize();
116 break;
117 default:
118 errno = EINVAL;
119 m_generalWait.wakeAll();
120 return result;
121 }
122
123 result = m_stream->Seek(Position);
124 if (result >= 0)
125 {
126 m_readPos = result;
127 m_ignoreReadPos = -1;
130 m_readAdjust = 0;
131 }
132
133 m_generalWait.wakeAll();
134 return result;
135}
136
138{
139 if (m_stream)
140 return m_stream->safe_read(Buffer, Size, 1000);
141 m_ateof = true;
142 return 0;
143}
144
146{
147 return m_stream ? m_stream->GetSize() : -1;
148}
149
151{
152 MythMediaBuffer *parent = m_parent;
153 if (parent && IsOpen())
154 parent->Unpause();
155 m_parent = nullptr;
156 return parent;
157}
MythMediaBuffer * TakeBuffer(void)
long long SeekInternal(long long Position, int Whence) override
bool OpenFile(const QString &Url, std::chrono::milliseconds Retry=kDefaultOpenTimeout) override
Opens a BBC NetStream for reading.
int SafeRead(void *Buffer, uint Size) override
MythMediaBuffer * m_parent
bool IsOpen(void) const override
long long GetReadPosition(void) const override
long long GetRealFileSizeInternal(void) const override
void Reset(bool Full=false, bool ToAdjust=false, bool ResetInternal=false)
Resets the read-ahead thread and our position in the file.
void KillReadAheadThread(void)
Stops the read-ahead thread, and waits for it to stop.
long long m_ignoreReadPos
void Pause(void)
Pauses the read-ahead thread.
long long m_readAdjust
QReadWriteLock m_posLock
friend class MythInteractiveBuffer
void Unpause(void)
Unpauses the read-ahead thread.
QReadWriteLock m_rwLock
void ResetReadAhead(long long NewInternal)
Restart the read-ahead thread at the 'newinternal' position.
void CalcReadAheadThresh(void)
Calculates m_fillMin, m_fillThreshold, and m_readBlockSize from the estimated effective bitrate of th...
QWaitCondition m_generalWait
Condition to signal that the read ahead thread is running.
Stream content from a URI.
Definition: netstream.h:32
qlonglong GetSize() const
Definition: netstream.cpp:628
qlonglong Seek(qlonglong pos)
Definition: netstream.cpp:600
int safe_read(void *data, unsigned sz, unsigned millisecs=0)
Definition: netstream.cpp:568
bool IsOpen() const
Definition: netstream.cpp:537
@ kNeverCache
Definition: netstream.h:36
static bool IsSupported(const QUrl &url)
RingBuffer interface.
Definition: netstream.cpp:529
qlonglong GetReadPosition() const
Definition: netstream.cpp:621
unsigned int uint
Definition: freesurround.h:24
#define LOC
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
@ kMythBufferMHEG