MythTV  master
streamingringbuffer.cpp
Go to the documentation of this file.
1 #include <QUrl>
2 #include "mythcorecontext.h"
3 #include "mythlogging.h"
4 
5 #include "streamingringbuffer.h"
6 
7 #define LOC QString("StreamRingBuf(%1): ").arg(m_filename)
8 
9 StreamingRingBuffer::StreamingRingBuffer(const QString &lfilename)
11 {
12  m_startReadAhead = false;
14 }
15 
17 {
19 
20  m_rwLock.lockForWrite();
21  if (m_context)
22  ffurl_close(m_context);
23  m_rwLock.unlock();
24 }
25 
27 {
28  bool result;
29  m_rwLock.lockForRead();
30  result = (bool)m_context;
31  m_rwLock.unlock();
32  return result;
33 }
34 
36 {
37  return 0;
38 }
39 
48 bool StreamingRingBuffer::OpenFile(const QString &lfilename, uint /*retry_ms*/)
49 {
51 
52  m_rwLock.lockForWrite();
53 
54  m_safeFilename = lfilename;
55  m_filename = lfilename;
56 
57  // TODO check whether local area file
58 
59  QUrl url = m_filename;
60  if (url.path().endsWith(QLatin1String("m3u8"), Qt::CaseInsensitive))
61  {
62  url.setScheme("hls+http");
63  }
64 
65  int res = ffurl_open(&m_context, url.toString().toLatin1(), AVIO_FLAG_READ,
66  nullptr, nullptr);
67  if (res >=0 && m_context &&
68  !m_context->is_streamed && ffurl_seek(m_context, 0, SEEK_SET) >= 0)
69  {
70  m_streamed = false;
71  m_allowSeeks = true;
72  }
73 
74  LOG(VB_GENERAL, LOG_INFO, LOC + QString("Trying %1 (allow seeks: %2")
75  .arg(m_filename).arg(m_allowSeeks));
76 
77  if (res < 0 || !m_context)
78  {
79  LOG(VB_GENERAL, LOG_ERR, LOC +
80  QString("Failed to open stream (error %1)") .arg(res));
81  m_lastError = QObject::tr("Failed to open stream (%1)").arg(res);
82  m_rwLock.unlock();
83  return false;
84  }
85 
86  m_rwLock.unlock();
87 
88  return true;
89 }
90 
91 long long StreamingRingBuffer::SeekInternal(long long pos, int whence)
92 {
93  if (!m_context)
94  return 0;
95 
96  m_posLock.lockForWrite();
97  int seek = ffurl_seek(m_context, pos, whence);
98  m_posLock.unlock();
99 
100  if (seek < 0)
101  {
102  m_ateof = true;
103  return 0;
104  }
105  return pos;
106 }
107 
109 {
110  uint len = 0;
111 
112  if (m_context)
113  {
114  while (len < sz)
115  {
116  int ret = ffurl_read(m_context, (unsigned char*)data + len, sz - len);
117  if (ret < 0)
118  {
119  if (ret == AVERROR_EOF)
120  {
121  m_ateof = true;
122  }
123  errno = ret;
124  break;
125  }
126  if (ret == 0) // nothing read, exit early
127  break; // should EOF be set ??
128  len += ret;
129  }
130  }
131  return len;
132 }
133 
135 {
136  long long result = -1;
137  m_rwLock.lockForRead();
138  if (m_context)
139  result = ffurl_size(m_context);
140  m_rwLock.unlock();
141  return result;
142 }
long long GetReadPosition(void) const override
Returns how far into the file we have read.
bool IsOpen(void) const override
Returns true if open for either reading or writing.
QReadWriteLock m_rwLock
bool
Definition: pxsup2dast.c:30
unsigned int uint
Definition: compat.h:140
int safe_read(void *data, uint sz) override
static void AVFormatInitNetwork(void)
void KillReadAheadThread(void)
Stops the read-ahead thread, and waits for it to stop.
Definition: ringbuffer.cpp:694
QReadWriteLock m_posLock
StreamingRingBuffer(const QString &lfilename)
long long SeekInternal(long long pos, int whence) override
#define LOG(_MASK_, _LEVEL_, _STRING_)
Definition: mythlogging.h:41
bool OpenFile(const QString &lfilename, uint retry_ms=kDefaultOpenTimeout) override
Opens a network stream for reading.
Implements a file/stream reader/writer.
long long GetRealFileSizeInternal(void) const override
#define LOC