MythTV master
httplivestreambuffer.h
Go to the documentation of this file.
1/*****************************************************************************
2 * httplivestreambuffer.cpp
3 * MythTV
4 *
5 * Created by Jean-Yves Avenard on 6/05/12.
6 * Copyright (c) 2012 Bubblestuff Pty Ltd. All rights reserved.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21 *****************************************************************************/
22
23#ifndef MythXCode_hlsbuffer_h
24#define MythXCode_hlsbuffer_h
25
26#include "libmythbase/mythconfig.h"
28
30class HLSStream;
31class HLSSegment;
32class StreamWorker;
33class PlaylistWorker;
34class HLSPlayback;
35
36using StreamsList = QList<HLSStream*>;
37
39{
40public:
41 explicit HLSRingBuffer(const QString &lfilename);
42 HLSRingBuffer(const QString &lfilename, bool open);
43 ~HLSRingBuffer() override;
44
45 bool IsOpen(void) const override; // RingBuffer
46 long long GetReadPosition(void) const override; // RingBuffer
47 bool OpenFile(const QString &lfilename,
48 std::chrono::milliseconds retry_ms = kDefaultOpenTimeout) override; // RingBuffer
49 bool IsStreamed(void) override { return false; } // RingBuffer
50 bool IsSeekingAllowed(void) override { return !m_error; } // RingBuffer
51 bool IsBookmarkAllowed(void) override { return true; } // RingBuffer
52 static bool IsHTTPLiveStreaming(QByteArray *s);
53 static bool TestForHTTPLiveStreaming(const QString &filename);
54 bool SaveToDisk(const QString &filename, int segstart = 0, int segend = -1);
55 int NumStreams(void) const;
56 void Interrupt(void);
57 void Continue(void);
58 int DurationForBytes(uint size);
59
60protected:
61 int SafeRead(void *data, uint sz) override; // RingBuffer
62 long long GetRealFileSizeInternal(void) const override; // RingBuffer
63 long long SeekInternal(long long pos, int whence) override; // RingBuffer
64
65private:
66 void FreeStreamsList(QList<HLSStream*> *streams) const;
67 HLSStream *GetStreamForSegment(int segnum) const;
68 HLSStream *GetStream(int wanted, const StreamsList *streams = nullptr) const;
69 HLSStream *GetFirstStream(const StreamsList *streams = nullptr) const;
70 HLSStream *GetLastStream(const StreamsList *streams = nullptr) const;
71 HLSStream *FindStream(const HLSStream *hls_new, const StreamsList *streams = nullptr) const;
72 HLSStream *GetCurrentStream(void) const;
73 static QString ParseAttributes(const QString &line, const char *attr);
74 static int ParseDecimalValue(const QString &line, int &target);
75 static int ParseSegmentInformation(const HLSStream *hls, const QString &line,
76 int &duration, QString &title);
77 static int ParseTargetDuration(HLSStream *hls, const QString &line);
78 HLSStream *ParseStreamInformation(const QString &line, const QString &uri) const;
79 static int ParseMediaSequence(HLSStream *hls, const QString &line);
80 int ParseKey(HLSStream *hls, const QString &line);
81 static int ParseProgramDateTime(HLSStream *hls, const QString &line);
82 static int ParseAllowCache(HLSStream *hls, const QString &line);
83 static int ParseVersion(const QString &line, int &version);
84 static int ParseEndList(HLSStream *hls);
85 static int ParseDiscontinuity(HLSStream *hls, const QString &line);
86 int ParseM3U8(const QByteArray *buffer, StreamsList *streams = nullptr);
87 int Prefetch(int count);
88 void SanityCheck(const HLSStream *hls) const;
89 HLSSegment *GetSegment(int segnum, std::chrono::milliseconds timeout = 1s);
90 int NumSegments(void) const;
91 int ChooseSegment(int stream) const;
92 int64_t SizeMedia(void) const;
93 void WaitUntilBuffered(void);
94 void SanitizeStreams(StreamsList *streams = nullptr);
95
96 // private member variables
97 QString m_m3u8; // M3U8 url
98 QByteArray m_peeked;
99
101
102 /* state */
103 StreamsList m_streams; // bandwidth adaptation
104 mutable QMutex m_lock; // protect general class members
105 bool m_meta {false}; // meta playlist
106 bool m_error {false}; // parsing error
107#if CONFIG_LIBCRYPTO
108 bool m_aesmsg {false}; // only print one time that the media is encrypted
109#endif
110 int m_startup {0}; // starting segment (where seek start)
116 int64_t m_bitrate {0};
122 bool m_seektoend {false};
123
124 friend class StreamWorker;
126 friend class PlaylistWorker;
128 FILE *m_fd {nullptr};
129 bool m_interrupted {false};
130 bool m_killed {false};
131};
132
133#endif
bool OpenFile(const QString &lfilename, std::chrono::milliseconds retry_ms=kDefaultOpenTimeout) override
Opens an HTTP Live Stream for reading.
void SanitizeStreams(StreamsList *streams=nullptr)
Streams may not be all starting at the same sequence number, so attempt to align their starting seque...
static int ParseDecimalValue(const QString &line, int &target)
Return the decimal argument in a line of type: blah:<decimal> presence of value <decimal> is compulso...
int64_t m_bitrate
assumed bitrate of playback used for the purpose of calculating length and seek position.
int ParseM3U8(const QByteArray *buffer, StreamsList *streams=nullptr)
bool IsBookmarkAllowed(void) override
long long GetRealFileSizeInternal(void) const override
HLSSegment * GetSegment(int segnum, std::chrono::milliseconds timeout=1s)
Retrieve segment [segnum] from any available streams.
void WaitUntilBuffered(void)
Wait until we have enough segments buffered to allow smooth playback Do not wait if VOD and at end of...
static int ParseSegmentInformation(const HLSStream *hls, const QString &line, int &duration, QString &title)
static int ParseMediaSequence(HLSStream *hls, const QString &line)
long long GetReadPosition(void) const override
int NumSegments(void) const
bool IsStreamed(void) override
HLSRingBuffer(const QString &lfilename)
HLSStream * GetLastStream(const StreamsList *streams=nullptr) const
static QString ParseAttributes(const QString &line, const char *attr)
int ChooseSegment(int stream) const
static int ParseDiscontinuity(HLSStream *hls, const QString &line)
static int ParseAllowCache(HLSStream *hls, const QString &line)
HLSStream * FindStream(const HLSStream *hls_new, const StreamsList *streams=nullptr) const
bool IsOpen(void) const override
HLSPlayback * m_playback
int DurationForBytes(uint size)
returns an estimated duration in ms for size amount of data returns 0 if we can't estimate the durati...
static bool TestForHTTPLiveStreaming(const QString &filename)
static int ParseTargetDuration(HLSStream *hls, const QString &line)
HLSStream * GetCurrentStream(void) const
return the stream we are currently streaming from
int ParseKey(HLSStream *hls, const QString &line)
HLSStream * GetStream(int wanted, const StreamsList *streams=nullptr) const
static int ParseVersion(const QString &line, int &version)
PlaylistWorker * m_playlistworker
void FreeStreamsList(QList< HLSStream * > *streams) const
StreamWorker * m_streamworker
HLSStream * GetStreamForSegment(int segnum) const
static int ParseProgramDateTime(HLSStream *hls, const QString &line)
int Prefetch(int count)
Preferetch the first x segments of the stream.
bool m_seektoend
FFmpeg seek to the end of the stream in order to determine the length of the video.
static bool IsHTTPLiveStreaming(QByteArray *s)
int SafeRead(void *data, uint sz) override
int64_t SizeMedia(void) const
long long SeekInternal(long long pos, int whence) override
HLSStream * ParseStreamInformation(const QString &line, const QString &uri) const
static int ParseEndList(HLSStream *hls)
void SanityCheck(const HLSStream *hls) const
int NumStreams(void) const
HLSStream * GetFirstStream(const StreamsList *streams=nullptr) const
bool SaveToDisk(const QString &filename, int segstart=0, int segend=-1)
bool IsSeekingAllowed(void) override
static constexpr std::chrono::milliseconds kDefaultOpenTimeout
unsigned int uint
Definition: freesurround.h:24
QList< HLSStream * > StreamsList
string version
Definition: giantbomb.py:185
int FILE
Definition: mythburn.py:138