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  m_rwLock.lockForRead();
29  bool result = (bool)m_context;
30  m_rwLock.unlock();
31  return result;
32 }
33 
35 {
36  return 0;
37 }
38 
47 bool StreamingRingBuffer::OpenFile(const QString &lfilename, uint /*retry_ms*/)
48 {
50 
51  m_rwLock.lockForWrite();
52 
53  m_safeFilename = lfilename;
54  m_filename = lfilename;
55 
56  // TODO check whether local area file
57 
58  QUrl url = m_filename;
59  if (url.path().endsWith(QLatin1String("m3u8"), Qt::CaseInsensitive))
60  {
61  url.setScheme("hls+http");
62  }
63 
64  int res = ffurl_open(&m_context, url.toString().toLatin1(), AVIO_FLAG_READ,
65  nullptr, nullptr);
66  if (res >=0 && m_context &&
67  !m_context->is_streamed && ffurl_seek(m_context, 0, SEEK_SET) >= 0)
68  {
69  m_streamed = false;
70  m_allowSeeks = true;
71  }
72 
73  LOG(VB_GENERAL, LOG_INFO, LOC + QString("Trying %1 (allow seeks: %2")
74  .arg(m_filename).arg(m_allowSeeks));
75 
76  if (res < 0 || !m_context)
77  {
78  LOG(VB_GENERAL, LOG_ERR, LOC +
79  QString("Failed to open stream (error %1)") .arg(res));
80  m_lastError = QObject::tr("Failed to open stream (%1)").arg(res);
81  m_rwLock.unlock();
82  return false;
83  }
84 
85  m_rwLock.unlock();
86 
87  return true;
88 }
89 
90 long long StreamingRingBuffer::SeekInternal(long long pos, int whence)
91 {
92  if (!m_context)
93  return 0;
94 
95  m_posLock.lockForWrite();
96  int seek = ffurl_seek(m_context, pos, whence);
97  m_posLock.unlock();
98 
99  if (seek < 0)
100  {
101  m_ateof = true;
102  return 0;
103  }
104  return pos;
105 }
106 
108 {
109  uint len = 0;
110 
111  if (m_context)
112  {
113  while (len < sz)
114  {
115  int ret = ffurl_read(m_context, (unsigned char*)data + len, sz - len);
116  if (ret < 0)
117  {
118  if (ret == AVERROR_EOF)
119  {
120  m_ateof = true;
121  }
122  errno = ret;
123  break;
124  }
125  if (ret == 0) // nothing read, exit early
126  break; // should EOF be set ??
127  len += ret;
128  }
129  }
130  return len;
131 }
132 
134 {
135  long long result = -1;
136  m_rwLock.lockForRead();
137  if (m_context)
138  result = ffurl_size(m_context);
139  m_rwLock.unlock();
140  return result;
141 }
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
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
unsigned int uint
Definition: compat.h:140
#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