-
Notifications
You must be signed in to change notification settings - Fork 35
Expand file tree
/
Copy pathStream.hpp
More file actions
199 lines (169 loc) · 7.03 KB
/
Stream.hpp
File metadata and controls
199 lines (169 loc) · 7.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
/*
* Stream.hpp
* sfeMovie project
*
* Copyright (C) 2010-2015 Lucas Soltic
* lucas.soltic@orange.fr
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef SFEMOVIE_STREAM_HPP
#define SFEMOVIE_STREAM_HPP
#include "Macros.hpp"
#include "Timer.hpp"
#include <list>
#include <memory>
#include <SFML/System.hpp>
#include <sfeMovie/Movie.hpp>
extern "C"
{
#include <libavformat/avformat.h>
}
namespace sfe
{
class Stream : public Timer::Observer
{
public:
struct DataSource
{
virtual void requestMoreData(Stream& starvingStream) = 0;
virtual void resetEndOfFileStatus() = 0;
};
/** @return a textual description of the given FFmpeg stream
*/
static std::string AVStreamDescription(AVStream* stream);
/** Create a stream from the given FFmpeg stream
*
* At the end of the constructor, the stream is guaranteed
* to have all of its fields set and the decoder loaded
*
* @param stream the FFmpeg stream
* @param dataSource the encoded data provider for this stream
*/
Stream(AVFormatContext*& formatCtx, AVStream*& stream, DataSource& dataSource, std::shared_ptr<Timer> timer);
/** Default destructor
*/
virtual ~Stream();
/** Connect this stream against the reference timer to receive playback events; this allows this
* stream to be played
*/
void connect();
/** Disconnect this stream from the reference timer ; this disables this stream
*/
void disconnect();
/** Called by the demuxer to provide the stream with encoded data
*
* @return packet the encoded data usable by this stream
*/
virtual void pushEncodedData(AVPacket* packet);
/** Reinsert an AVPacket at the beginning of the queue
*
* This is used for packets that contain several frames, but whose next frames
* cannot be decoded yet. These packets are repushed to be decoded when possible.
*
* @param packet the packet to re-insert at the beginning of the queue
*/
virtual void prependEncodedData(AVPacket* packet);
/** Return the oldest encoded data that was pushed to this stream
*
* If no packet is stored when this method is called, it will ask the
* data source to feed this stream first
*
* @return the oldest encoded data, or nullptr if no data could be read from the media
*/
virtual AVPacket* popEncodedData();
/** Empty the encoded data queue, destroy all the packets and flush the decoding pipeline
* @warning Subclasses overriding this method must also call the Stream implementation
*/
virtual void flushBuffers();
/** Used by the demuxer to know if this stream should be fed with more data
*
* The default implementation returns true if the packet list contains less than 10 packets
*
* @return true if the demuxer should give more data to this stream, false otherwise
*/
virtual bool needsMoreData() const;
/** Get the stream kind (either audio, video or subtitle stream)
*
* @return the kind of stream represented by this stream
*/
virtual MediaType getStreamKind() const;
/** Give the stream's status
*
* @return The stream's status (Playing, Paused or Stopped)
*/
Status getStatus() const;
/** Return the stream's language code
*
* @return the language code of the stream as ISO 639-2 format
*/
std::string getLanguage() const;
/** Compute the stream position in the media, by possibly fetching a packet
*
* @param[out] position the current stream position, if available
* @return true if stream position could be computed and @ref position is set, false otherwise
*/
bool computeEncodedPosition(sf::Time& position);
/** Compute how much time would be covered by the given packet, it's the diff between
* the current packet pts, and the next packet pts
*/
sf::Time packetDuration(const AVPacket* packet) const;
/** Discard the data not needed to start playback at the given position
*
* Every single bit of unneeded data must be discarded as streams synchronization accuracy will
* depend on this
*
* @param targetPosition the position for which the stream is expected to be ready to play
* @return true is fast forwarding could be done successfully, false otherwise
*/
virtual bool fastForward(sf::Time targetPosition) = 0;
/** @return a textual description of the current stream
*/
std::string description() const;
/** Update the current stream's status and eventually decode frames
*/
virtual void update() = 0;
/** @return true if the given packet is for the current stream
*/
bool canUsePacket(AVPacket* packet) const;
/** @return true if this stream never requests packets and let
* itself be fed, false otherwise. Default implementation always
* returns false
*/
virtual bool isPassive() const;
protected:
// Timer::Observer interface
void didPlay(const Timer& timer, Status previousStatus) override;
void didPause(const Timer& timer, Status previousStatus) override;
void didStop(const Timer& timer, Status previousStatus) override;
bool didSeek(const Timer& timer, sf::Time oldPosition) override;
/** @return true if any raw packet for the current stream is queued
*/
bool hasPackets();
void setStatus(Status status);
AVFormatContext* & m_formatCtx;
AVStream*& m_stream;
DataSource& m_dataSource;
std::shared_ptr<Timer> m_timer;
AVCodec* m_codec;
int m_streamID;
std::string m_language;
std::list <AVPacket*> m_packetList;
Status m_status;
sf::Mutex m_readerMutex;
};
}
#endif