|
MythTV
0.26-pre
|
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 }
1.7.6.1