MythTV  0.26-pre
streamingringbuffer.cpp
Go to the documentation of this file.
00001 #include <QUrl>
00002 #include "mythcorecontext.h"
00003 #include "mythlogging.h"
00004 
00005 #include "streamingringbuffer.h"
00006 
00007 #define LOC QString("StreamRingBuf(%1): ").arg(filename)
00008 
00009 StreamingRingBuffer::StreamingRingBuffer(const QString &lfilename)
00010   : RingBuffer(kRingBuffer_HTTP), m_context(NULL), m_streamed(true),
00011     m_allowSeeks(false)
00012 {
00013     startreadahead = false;
00014     OpenFile(lfilename);
00015 }
00016 
00017 StreamingRingBuffer::~StreamingRingBuffer()
00018 {
00019     rwlock.lockForWrite();
00020     if (m_context)
00021         ffurl_close(m_context);
00022     rwlock.unlock();
00023 }
00024 
00025 bool StreamingRingBuffer::IsOpen(void) const
00026 {
00027     bool result;
00028     rwlock.lockForRead();
00029     result = (bool)m_context;
00030     rwlock.unlock();
00031     return result;
00032 }
00033 
00034 long long StreamingRingBuffer::GetReadPosition(void) const
00035 {
00036     return 0;
00037 }
00038 
00039 bool StreamingRingBuffer::OpenFile(const QString &lfilename, uint retry_ms)
00040 {
00041     avcodeclock->lock();
00042     av_register_all();
00043     avcodeclock->unlock();
00044 
00045     rwlock.lockForWrite();
00046 
00047     safefilename = lfilename;
00048     filename = lfilename;
00049 
00050     // TODO check whether local area file
00051 
00052     QUrl url = filename;
00053     if (url.path().endsWith(QLatin1String("m3u8"), Qt::CaseInsensitive))
00054     {
00055         url.setScheme("hls+http");
00056     }
00057 
00058     int res = ffurl_open(&m_context, url.toString().toAscii(), AVIO_FLAG_READ,
00059                          NULL, NULL);
00060     if (res >=0 && m_context &&
00061         !m_context->is_streamed && ffurl_seek(m_context, 0, SEEK_SET) >= 0)
00062     {
00063         m_streamed   = false;
00064         m_allowSeeks = true;
00065     }
00066 
00067     LOG(VB_GENERAL, LOG_INFO, LOC + QString("Trying %1 (allow seeks: %2")
00068         .arg(filename).arg(m_allowSeeks));
00069 
00070     rwlock.unlock();
00071 
00072     if (res < 0 || !m_context)
00073     {
00074         LOG(VB_GENERAL, LOG_ERR, LOC +
00075             QString("Failed to open stream (error %1)") .arg(res));
00076         return false;
00077     }
00078 
00079     return true;
00080 }
00081 
00082 long long StreamingRingBuffer::Seek(long long pos, int whence, bool has_lock)
00083 {
00084     if (!m_context)
00085         return 0;
00086 
00087     poslock.lockForWrite();
00088     int seek = ffurl_seek(m_context, pos, whence);
00089     poslock.unlock();
00090 
00091     if (seek < 0)
00092     {
00093         ateof = true;
00094         return 0;
00095     }
00096     return pos;
00097 }
00098 
00099 int StreamingRingBuffer::safe_read(void *data, uint sz)
00100 {
00101     if (m_context)
00102         return ffurl_read_complete(m_context, (unsigned char*)data, sz);
00103     return 0;
00104 }
00105 
00106 long long StreamingRingBuffer::GetRealFileSize(void) const
00107 {
00108     long long result = -1;
00109     rwlock.lockForRead();
00110     if (m_context)
00111         result = ffurl_size(m_context);
00112     rwlock.unlock();
00113     return result;
00114 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends