BitmapToolkit Scol plugin
MediaPlayer.h
Go to the documentation of this file.
1/*
2-----------------------------------------------------------------------------
3This source file is part of OpenSpace3D
4For the latest info, see http://www.openspace3d.com
5
6Copyright (c) 2016 I-maginer
7
8This program is free software; you can redistribute it and/or modify it under
9the terms of the GNU Lesser General Public License as published by the Free Software
10Foundation; either version 2 of the License, or (at your option) any later
11version.
12
13This program is distributed in the hope that it will be useful, but WITHOUT
14ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
16
17You should have received a copy of the GNU Lesser General Public License along with
18this program; if not, write to the Free Software Foundation, Inc., 59 Temple
19Place - Suite 330, Boston, MA 02111-1307, USA, or go to
20http://www.gnu.org/copyleft/lesser.txt
21
22-----------------------------------------------------------------------------
23*/
24
25#ifndef __BTK_MEDIAPLAYER_H__
26#define __BTK_MEDIAPLAYER_H__
27
28extern "C"
29{
30 #include <libavformat/avformat.h>
31 #include <libswscale/swscale.h>
32 #include <libswresample/swresample.h>
33 #include <libavutil/opt.h>
34}
35
36#include <opencv2/opencv.hpp>
37#include <boost/thread.hpp>
38#include <boost/array.hpp>
39#include <boost/circular_buffer.hpp>
40#include <queue>
41#include <list>
42#include <memory>
43
44#include "Prerequisites.h"
45
46#define MAX_OUT_BUFFER 262144
47
54public:
55 static const int VIDEO_SIZE_AUTO = 0;
56 static const int STREAM_UNDEFINED = -1;
57 static const int BUFFER_COUNT = 2;
58 static const AVPixelFormat DEST_PIXEL_FORMAT = AV_PIX_FMT_BGR24;
59
60 // Time base used internally to represent stream timestamps.
61 static const AVRational TIME_BASE;
62 // Redeclare AV_TIME_BASE_Q to work around VS2010's lack of C99 support
63 static const AVRational FF_AV_TIME_BASE_Q;
64
65 // Amount of time in TIME_BASE units beyond which we consider video/audio have desynced
66 static const int AV_SYNC_THRESHOLD = 16;
67
68 // Number of tolerated consecutive read errors before failing
69 static const int MAX_READ_ERRORS = 30;
70
78
85
86protected:
87private:
88
93 class PacketQueue
94 {
95 public:
98 static uint8_t* FLUSH_DATA;
101 static uint8_t* QUIT_DATA;
102 protected:
103 private:
104 std::queue<AVPacket*> mQueue;
105 boost::mutex mMutex;
106 boost::condition_variable mCond;
107 size_t mCapacity;
108 // Total size of the packet's data (not the number of packets !)
109 size_t mSize;
110
111 public:
112 PacketQueue(size_t capacity);
113 virtual ~PacketQueue();
114
118 AVPacket* Pop();
119
123 AVPacket* TryPop();
124
128 bool Push(AVPacket* packet);
129
132 void Flush(AVPacket* packet);
133
134 bool Empty();
135
136 size_t Size();
137
138 size_t MaxSize();
139
140 protected:
141 private:
142 void Clear();
143 };
144
147 class Clock
148 {
149 public:
150 protected:
151 private:
152 int64_t mInitialTime;
153 int64_t mPauseTime;
154 int64_t mSystemTime;
155 bool mRunning;
156
157 boost::mutex mMutex;
158
159 public:
162 Clock();
163
167 int64_t Get();
168
172 void Reset(int64_t initialTime);
173
176 void Pause();
177
180 void Resume();
181
184 bool IsPaused();
185
189 static int64_t GetSysTime();
190 protected:
191 private:
192 };
193
194 struct AudioFrame
195 {
196 public:
197 std::unique_ptr<char> data;
198 size_t size;
199 int64_t pts;
200
201 AudioFrame();
202 AudioFrame(const AudioFrame&);
203 AudioFrame(AudioFrame&&);
204 AudioFrame& operator=(AudioFrame&&);
205 };
206
207
208 // List of every MediaPlayer instance, used for Android pause function
209 static std::list<MediaPlayer*> players;
210
211 // Used to pause/unpause all players at once
212 static bool globallyPaused;
213
214 std::string mFile;
215 FILE* mFilePtr;
216 AVIOContext* mIoContext;
217 AVFormatContext* mContext;
218
219 AVCodecContext* mVideoCtx;
220 AVCodecContext* mAudioCtx;
221 int mVideoStream;
222 int mAudioStream;
223
224 // Desired size of the final bitmap, set by the user
225 int mUserW, mUserH;
226 // Actual size of the bitmap, computed from the user's desired values
227 int mFinalW, mFinalH;
228 // Current size of the source video
229 int mSourceW, mSourceH;
230 // Set to true when the user has changed the requested size
231 bool mSizeChanged;
232 // Prevent user size changes while new size is being computed
233 boost::mutex mSizeMutex;
234 // Set by the user via Stop
235 bool mStopped;
236 // Toggled via Play / Pause
237 bool mPaused;
238 // If true, loop media playback.
239 bool mLoop;
240 // Whether there is a new frame available
241 bool mUpdated;
242 // Video clock in milliseconds, used for synchonization
243 int64_t mVideoClock;
244 // Presentation timestamp (PTS) of the current video frame, in the current video stream's time base.
245 int64_t mVideoPts;
246 // Requested timestamp to seek to, in the current video stream's time base.
247 int64_t mSeekPts;
248 // Set to true when the decoding thread needs to seek to mSeekPos
249 bool mSeekRequested;
250 // Guards to prevent audio/video from possibly messing up and waiting too long when seeking backwards
251 bool mSeekInProgressAudio;
252 bool mSeekInProgressVideo;
253 bool mSeekCompletedAudio;
254 bool mIsLocal;
255 // System clock that both audio and video sync to
256 Clock mSystemClock;
257
258 cv::Mat mFrameBuffer;
259 cv::Mat mFrameRetrieveBuffer;
260 AVFrame* mFrame;
261 SwsContext* mScalerCtx;
262 AVFrame* mVideoBuffer;
263
264 // LoadThread
265 boost::thread mOpenThread;
266
267 // Audio thread related
268 boost::thread mAudioThread;
269 boost::mutex mAudioMutex;
270 PacketQueue mAudioPktQ;
271 boost::circular_buffer<AudioFrame> mAudioFrameQ;
272 Clock mAudioClock;
273
274 SwrContext* mResampleCtx;
275 uint64_t mOutChannelLayout;
276 AVSampleFormat mOutSampleFormat;
277 int mOutSampleRate;
278
279 PacketQueue mVideoPktQ;
280
281 boost::thread mDecodingThread;
282 boost::condition_variable mPauseCond;
283
284 // Video thread related
285 boost::thread mVideoThread;
286 boost::mutex mVideoMutex;
287
288public:
292 static void InitFFmpeg();
293
297 static void DeInitFFmpeg();
298
302 static void SetGlobalPause(bool pause);
303
308 static bool IsValidPlayer(MediaPlayer* player);
309
312 MediaPlayer();
313 virtual ~MediaPlayer();
314
319 void Open(std::string path);
320
326 void OpenUrl(std::string url);
327
330 void Close();
331
335 bool IsReady();
336
340 State GetState();
341
345 bool HasAudio();
346
350 bool HasVideo();
351
355 long GetLength();
356
360 bool IsSeekable();
361
365 bool IsLiveStream();
366
371 void GetSize(int& width, int& height);
372
377 void GetSourceSize(int& width, int& height);
378
383 void SetSize(int width, int height);
384
389 void SetAudioFormat(AudioFormats format, int sampleRate);
390
394 void Play(long startPosition = 0);
395
398 void Pause();
399
402 void Stop();
403
407 void SetLoop(bool loop);
408
412 void SetCurrentTime(long time);
413
417 long GetCurrentTime();
418
423 bool GetFrame(ObjBitmap* scolBitmap);
424
429 bool GetFrame(cv::Mat &buffer);
430
434 cv::Mat GetFrame();
435
441 int GetAudioThreaded(char* destBuffer, size_t length);
442
447 int SetVideoStream(int streamIndex = -1);
448
453 int SetAudioStream(int streamIndex = -1);
454
455 std::vector<std::string> ListStreams(AVMediaType type);
456
457protected:
458private:
459
460 // Custom callbacks for FFmpeg file I/O
461 static int FileRead(void* player, uint8_t* buf, int buf_size);
462 static int FileWrite(void* player, uint8_t* buf, int buf_size);
463 static int64_t FileSeek(void* player, int64_t offset, int whence);
464
471 int SetStream(AVMediaType type, int index = -1);
472
478 int GetActualStreamIndex(int streamIndex, AVMediaType streamType);
479
480 long GetStreamDuration(int index);
481
484 void Reset();
485
488 void SendQuitPacket();
489
490 void OpenFileThread(std::string path);
491 void OpenUrlThread(std::string url, bool close);
492
493 void DecodingThread();
494 void VideoThread();
495 void AudioThread();
496
497 void ComputeSize(int sourceW, int sourceH);
498
504 void SetAudioFormat(uint64_t channelLayout, AVSampleFormat format, int sampleRate);
505 void AllocResampler(uint64_t outChannelLayout, AVSampleFormat outSampleFormat, int outSampleRate, AVCodecContext* context);
506
507 int64_t SynchronizeVideo(AVFrame *srcFrame, int64_t pts);
511 void SynchronizeAudio(int64_t pts);
512};
513
514
515#endif //__BTK_MEDIAPLAYER_H__
This class provides media playback functionality.
Definition MediaPlayer.h:53
int GetAudioThreaded(char *destBuffer, size_t length)
Get decoded audio data from the media (using the dedicated audio thread).
void OpenUrl(std::string url)
Open the media at the given URL.
int SetVideoStream(int streamIndex=-1)
Select the video stream to play from the current file.
bool HasAudio()
Check whether the player has an audio track selected and ready to play.
static const int VIDEO_SIZE_AUTO
Definition MediaPlayer.h:55
static const int AV_SYNC_THRESHOLD
Definition MediaPlayer.h:66
static const int BUFFER_COUNT
Definition MediaPlayer.h:57
static const int STREAM_UNDEFINED
Definition MediaPlayer.h:56
State GetState()
Get the current state of this player.
static const AVRational TIME_BASE
Definition MediaPlayer.h:51
void Play(long startPosition=0)
Play/resume the currently loaded media.
void SetAudioFormat(AudioFormats format, int sampleRate)
Set the output format for audio.
bool IsLiveStream()
Check whether the current media is a live stream.
static const AVPixelFormat DEST_PIXEL_FORMAT
Definition MediaPlayer.h:58
bool IsReady()
Check whether the player has a media ready to play.
std::vector< std::string > ListStreams(AVMediaType type)
void Stop()
Stop media playback.
bool HasVideo()
Check whether the player has a video track selected and ready to play.
MediaPlayer()
Create an empty player.
void GetSize(int &width, int &height)
Get the current size of the video (after resize)
void GetSourceSize(int &width, int &height)
Get the original size of the video (before resize)
long GetCurrentTime()
Get the current playback time of the media.
int SetAudioStream(int streamIndex=-1)
Select the audio stream to play from the current file.
void SetLoop(bool loop)
Set whether media playback should loop or not.
static const int MAX_READ_ERRORS
Definition MediaPlayer.h:69
bool IsSeekable()
Check whether the file or stream is seekable.
void SetCurrentTime(long time)
Set the current playback time of the media.
long GetLength()
Get the length of the current media stream.
static const AVRational FF_AV_TIME_BASE_Q
Definition MediaPlayer.h:53
static void DeInitFFmpeg()
Free resources allocated by init. Call this when you're done with MediaPlayer.
void Pause()
Pause the current media playback.
virtual ~MediaPlayer()
void Close()
Close the current media file, if any.
cv::Mat GetFrame()
Get the current decoded video frame.
static void InitFFmpeg()
Init FFmpeg functionalities. Call this before any other MediaPlayer functions.
void Open(std::string path)
Open the media file at the given path. If a media was already loaded, it will be replaced by the new ...
void SetSize(int width, int height)
Set the target size for the video.
static bool IsValidPlayer(MediaPlayer *player)
Check whether a media player is still valid.
static void SetGlobalPause(bool pause)
Pause/unpause every MediaPlayer.