MythTV master
mythstreamingbuffer.cpp
Go to the documentation of this file.
2
3// Qt
4#include <QUrl>
5
6// MythTV
8
9// FFmpeg
10extern "C" {
11#include "libavformat/avio.h"
12}
13
14#define LOC QString("StreamRingBuf(%1): ").arg(m_filename)
15
18{
19 m_startReadAhead = false;
21}
22
24{
26
27 m_rwLock.lockForWrite();
28 if (m_context)
29 avio_closep(&m_context);
30 m_rwLock.unlock();
31}
32
34{
35 m_rwLock.lockForRead();
36 bool result = m_context;
37 m_rwLock.unlock();
38 return result;
39}
40
42{
43 return 0;
44}
45
54bool MythStreamingBuffer::OpenFile(const QString &Filename, std::chrono::milliseconds /*Retry*/)
55{
57
58 m_rwLock.lockForWrite();
59
60 m_safeFilename = Filename;
61 m_filename = Filename;
62
63 // TODO check whether local area file
64
65 QUrl url = m_filename;
66 if (url.path().endsWith(QLatin1String("m3u8"), Qt::CaseInsensitive))
67 url.setScheme("hls+http");
68
69 int res = avio_open(&m_context, url.toString().toLatin1(), AVIO_FLAG_READ);
70 if (res < 0 || !m_context)
71 {
72 LOG(VB_GENERAL, LOG_ERR, LOC + QString("Failed to open stream (%1) (error %2)")
73 .arg(m_filename, QString::number(res)));
74 m_lastError = QObject::tr("Failed to open stream (%1)").arg(res);
75 m_rwLock.unlock();
76 return false;
77 }
78
79 m_streamed = (m_context->seekable & AVIO_SEEKABLE_NORMAL) == 0;
80 m_allowSeeks = !m_streamed && avio_seek(m_context, 0, SEEK_SET) >= 0;
81
82 LOG(VB_GENERAL, LOG_INFO, LOC + QString("Opened %1 (allow seeks: %2")
84
85 m_rwLock.unlock();
86 return true;
87}
88
89long long MythStreamingBuffer::SeekInternal(long long Position, int Whence)
90{
91 if (!m_context)
92 return 0;
93
94 m_posLock.lockForWrite();
95 int64_t seek = avio_seek(m_context, Position, Whence);
96 m_posLock.unlock();
97
98 if (seek < 0)
99 {
100 m_ateof = true;
101 return 0;
102 }
103 return seek;
104}
105
107{
108 int len = 0;
109
110 if (m_context)
111 {
112 while (len < static_cast<int>(Size))
113 {
114 int ret = avio_read(m_context, static_cast<unsigned char*>(Buffer) + len,
115 static_cast<int>(Size) - len);
116 if (ret < 0)
117 {
118 if (ret == AVERROR_EOF)
119 m_ateof = true;
120 errno = ret;
121 break;
122 }
123 if (ret == 0) // nothing read, exit early
124 break; // should EOF be set ??
125 len += ret;
126 }
127 }
128 return len;
129}
130
132{
133 long long result = -1;
134 m_rwLock.lockForRead();
135 if (m_context)
136 result = avio_size(m_context);
137 m_rwLock.unlock();
138 return result;
139}
void KillReadAheadThread(void)
Stops the read-ahead thread, and waits for it to stop.
QReadWriteLock m_posLock
static void AVFormatInitNetwork(void)
QReadWriteLock m_rwLock
long long GetReadPosition(void) const override
bool OpenFile(const QString &Filename, std::chrono::milliseconds Retry=kDefaultOpenTimeout) override
bool IsOpen(void) const override
MythStreamingBuffer(const QString &Filename)
long long GetRealFileSizeInternal(void) const override
struct AVIOContext * m_context
int SafeRead(void *Buffer, uint Size) override
long long SeekInternal(long long Position, int Whence) override
unsigned int uint
Definition: freesurround.h:24
QString boolToQString(bool val)
This is equivalent to QVariant(bool).toString()
Definition: mythlogging.h:86
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
@ kMythBufferHTTP
#define LOC