瀏覽代碼

Video playback is now time-based, using video file timings

Ivan Savenko 2 年之前
父節點
當前提交
a9fefffc65
共有 2 個文件被更改,包括 35 次插入58 次删除
  1. 28 22
      client/CVideoHandler.cpp
  2. 7 36
      client/CVideoHandler.h

+ 28 - 22
client/CVideoHandler.cpp

@@ -18,6 +18,14 @@
 extern CGuiHandler GH; //global gui handler
 
 #ifndef DISABLE_VIDEO
+
+extern "C" {
+#include <libavformat/avformat.h>
+#include <libavcodec/avcodec.h>
+#include <libavutil/imgutils.h>
+#include <libswscale/swscale.h>
+}
+
 //reads events and returns true on key down
 static bool keyDown()
 {
@@ -56,22 +64,20 @@ static si64 lodSeek(void * opaque, si64 pos, int whence)
 }
 
 CVideoPlayer::CVideoPlayer()
-{
-	stream = -1;
-	format = nullptr;
-	codecContext = nullptr;
-	codec = nullptr;
-	frame = nullptr;
-	sws = nullptr;
-	context = nullptr;
-	texture = nullptr;
-	dest = nullptr;
-	destRect = CSDL_Ext::genRect(0,0,0,0);
-	pos = CSDL_Ext::genRect(0,0,0,0);
-	refreshWait = 0;
-	refreshCount = 0;
-	doLoop = false;
-}
+	: stream(-1)
+	, format (nullptr)
+	, codecContext(nullptr)
+	, codec(nullptr)
+	, frame(nullptr)
+	, sws(nullptr)
+	, context(nullptr)
+	, texture(nullptr)
+	, dest(nullptr)
+	, destRect(0,0,0,0)
+	, pos(0,0,0,0)
+	, frameTime(0)
+	, doLoop(false)
+{}
 
 bool CVideoPlayer::open(std::string fname, bool scale)
 {
@@ -85,9 +91,8 @@ bool CVideoPlayer::open(std::string fname, bool loop, bool useOverlay, bool scal
 	close();
 
 	this->fname = fname;
-	refreshWait = 3;
-	refreshCount = -1;
 	doLoop = loop;
+	frameTime = 0;
 
 	ResourceID resource(std::string("Video/") + fname, EResType::VIDEO);
 
@@ -254,6 +259,7 @@ bool CVideoPlayer::nextFrame()
 			if (doLoop && !gotError)
 			{
 				// Rewind
+				frameTime = 0;
 				if (av_seek_frame(format, stream, 0, AVSEEK_FLAG_BYTE) < 0)
 					break;
 				gotError = true;
@@ -354,9 +360,11 @@ void CVideoPlayer::update( int x, int y, SDL_Surface *dst, bool forceRedraw, boo
 	if (sws == nullptr)
 		return;
 
-	if (refreshCount <= 0)
+	double frameEndTime = (frame->pts + frame->pkt_duration) * av_q2d(format->streams[stream]->time_base);
+	frameTime += GH.mainFPSmng->getElapsedMilliseconds() / 1000.0;
+
+	if (frameTime >= frameEndTime )
 	{
-		refreshCount = refreshWait;
 		if (nextFrame())
 			show(x,y,dst,update);
 		else
@@ -374,8 +382,6 @@ void CVideoPlayer::update( int x, int y, SDL_Surface *dst, bool forceRedraw, boo
 	{
 		redraw(x, y, dst, update);
 	}
-
-	refreshCount --;
 }
 
 void CVideoPlayer::close()

+ 7 - 36
client/CVideoHandler.h

@@ -56,39 +56,11 @@ public:
 
 #include "../lib/filesystem/CInputStream.h"
 
-extern "C" {
-#include <libavformat/avformat.h>
-#include <libavcodec/avcodec.h>
-#include <libavutil/imgutils.h>
-#include <libswscale/swscale.h>
-}
-
-//compatibility for libav 9.18 in ubuntu 14.04, 52.66.100 is ffmpeg 2.2.3
-#if (LIBAVUTIL_VERSION_INT < AV_VERSION_INT(52, 66, 100))
-inline AVFrame * av_frame_alloc()
-{
-	return avcodec_alloc_frame();
-}
-
-inline void av_frame_free(AVFrame ** frame)
-{
-	av_free(*frame);
-	*frame = nullptr;
-}
-#endif // VCMI_USE_OLD_AVUTIL
-
-//fix for travis-ci
-#if (LIBAVUTIL_VERSION_INT < AV_VERSION_INT(52, 0, 0))
-	#define AVPixelFormat PixelFormat
-	#define AV_PIX_FMT_NONE PIX_FMT_NONE
-	#define AV_PIX_FMT_YUV420P PIX_FMT_YUV420P
-	#define AV_PIX_FMT_BGR565 PIX_FMT_BGR565
-	#define AV_PIX_FMT_BGR24 PIX_FMT_BGR24
-	#define AV_PIX_FMT_BGR32 PIX_FMT_BGR32
-	#define AV_PIX_FMT_RGB565 PIX_FMT_RGB565
-	#define AV_PIX_FMT_RGB24 PIX_FMT_RGB24
-	#define AV_PIX_FMT_RGB32 PIX_FMT_RGB32
-#endif
+struct AVFormatContext;
+struct AVCodecContext;
+struct AVCodec;
+struct AVFrame;
+struct AVIOContext;
 
 class CVideoPlayer : public IMainVideoPlayer
 {
@@ -108,8 +80,8 @@ class CVideoPlayer : public IMainVideoPlayer
 	Rect destRect;			// valid when dest is used
 	Rect pos;				// destination on screen
 
-	int refreshWait; // Wait several refresh before updating the image
-	int refreshCount;
+	/// video playback currnet progress, in seconds
+	double frameTime;
 	bool doLoop;				// loop through video
 
 	bool playVideo(int x, int y, bool stopOnKey);
@@ -141,4 +113,3 @@ public:
 };
 
 #endif
-