Explorar o código

- removed deprecated ffmpeg functions. Fixes #779
- removed hardcoded video name constants

Ivan Savenko %!s(int64=13) %!d(string=hai) anos
pai
achega
e79ac5f1d7

+ 4 - 4
client/BattleInterface/CBattleInterfaceClasses.cpp

@@ -418,7 +418,7 @@ CBattleResultWindow::CBattleResultWindow(const BattleResult &br, const SDL_Rect
 		}
 
 		CCS->musich->playMusic("Music/Win Battle", false);
-		CCS->videoh->open(VIDEO_WIN);
+		CCS->videoh->open("WIN3.BIK");
 		std::string str = CGI->generaltexth->allTexts[text];
 
 		const CGHeroInstance * ourHero = weAreAttacker? owner->attackingHeroInstance : owner->defendingHeroInstance;
@@ -438,21 +438,21 @@ CBattleResultWindow::CBattleResultWindow(const BattleResult &br, const SDL_Rect
 		case 0: //normal victory
 			{
 				CCS->musich->playMusic("Music/LoseCombat", false);
-				CCS->videoh->open(VIDEO_LOSE_BATTLE_START);
+				CCS->videoh->open("LBSTART.BIK");
 				new CLabel(235, 235, FONT_SMALL, CENTER, Colors::Cornsilk, CGI->generaltexth->allTexts[311]);
 				break;
 			}
 		case 1: //flee
 			{
 				CCS->musich->playMusic("Music/Retreat Battle", false);
-				CCS->videoh->open(VIDEO_RETREAT_START);
+				CCS->videoh->open("RTSTART.BIK");
 				new CLabel(235, 235, FONT_SMALL, CENTER, Colors::Cornsilk, CGI->generaltexth->allTexts[310]);
 				break;
 			}
 		case 2: //surrender
 			{
 				CCS->musich->playMusic("Music/Surrender Battle", false);
-				CCS->videoh->open(VIDEO_SURRENDER);
+				CCS->videoh->open("SURRENDER.BIK");
 				new CLabel(235, 235, FONT_SMALL, CENTER, Colors::Cornsilk, CGI->generaltexth->allTexts[309]);
 				break;
 			}

+ 64 - 23
client/CVideoHandler.cpp

@@ -569,23 +569,41 @@ bool CVideoPlayer::playVideo(int x, int y, SDL_Surface *dst, bool stopOnKey)
 
 #ifndef DISABLE_VIDEO
 
-//Workaround for compile error in ffmpeg (UINT_64C was not declared)
-#define __STDC_CONSTANT_MACROS
-#ifdef _STDINT_H
-#undef _STDINT_H
-#endif
-#include <stdint.h>
+#if LIBAVCODEC_VERSION_INT > AV_VERSION_INT(52, 117, 0)
 
+// Define a set of functions to read data
+static int lodRead(void* opaque, uint8_t* buf, int size)
+{
+	auto video = reinterpret_cast<CVideoPlayer *>(opaque);
+
+	vstd::amin(size, video->length - video->offset);
 
-extern "C" {
-#include <libavformat/avformat.h>
-#include <libswscale/swscale.h>
+	if (size < 0)
+		return -1;
+
+	memcpy(buf, video->data + video->offset, size);
+	video->offset += size;
+	return size;
 }
 
+static si64 lodSeek(void * opaque, si64 pos, int whence)
+{
+	auto video = reinterpret_cast<CVideoPlayer *>(opaque);
+
+	if (whence & AVSEEK_SIZE)
+		return video->length;
+
+	video->offset = pos;
+	vstd::amin(video->offset, video->length);
+	return video->offset;
+}
+
+#else
+
 static const char *protocol_name = "lod";
 
 // Open a pseudo file. Name is something like 'lod:0x56432ab6c43df8fe'
-static int lod_open(URLContext *context, const char *filename, int flags)
+static int lodOpen(URLContext *context, const char *filename, int flags)
 {
 	CVideoPlayer *video;
 
@@ -600,13 +618,13 @@ static int lod_open(URLContext *context, const char *filename, int flags)
 	return 0;
 }
 
-static int lod_close(URLContext* h)
+static int lodClose(URLContext* h)
 {
 	return 0;
 }
 
 // Define a set of functions to read data
-static int lod_read(URLContext *context, ui8 *buf, int size)
+static int lodRead(URLContext *context, ui8 *buf, int size)
 {
 	CVideoPlayer *video = (CVideoPlayer *)context->priv_data;
 
@@ -623,7 +641,7 @@ static int lod_read(URLContext *context, ui8 *buf, int size)
 	return size;
 }
 
-static si64 lod_seek(URLContext *context, si64 pos, int whence)
+static si64 lodSeek(URLContext *context, si64 pos, int whence)
 {
 	CVideoPlayer *video = (CVideoPlayer *)context->priv_data;
 
@@ -632,19 +650,21 @@ static si64 lod_seek(URLContext *context, si64 pos, int whence)
 
 	video->offset = pos;
 	vstd::amin(video->offset, video->length);
-	return -1;//video->offset;
+	return video->offset;
 }
 
 static URLProtocol lod_protocol =
 {
 	protocol_name,
-	lod_open,
-	lod_read,
+	lodOpen,
+	lodRead,
 	NULL,						// no write
-	lod_seek,
-	lod_close
+	lodSeek,
+	lodClose
 };
 
+#endif
+
 CVideoPlayer::CVideoPlayer()
 {
 	format = NULL;
@@ -653,17 +673,17 @@ CVideoPlayer::CVideoPlayer()
 	sws = NULL;
 	overlay = NULL;
 	dest = NULL;
+	context = nullptr;
+	buffer = nullptr;
 
 	// Register codecs. TODO: May be overkill. Should call a
 	// combination of av_register_input_format() /
 	// av_register_output_format() / av_register_protocol() instead.
 	av_register_all();
 
+#if LIBAVCODEC_VERSION_INT > AV_VERSION_INT(52, 117, 0)
+#elif LIBAVCODEC_VERSION_INT > AV_VERSION_INT(52, 69, 0)
 	// Register our protocol 'lod' so we can directly read from mmaped memory
-	// TODO: URL protocol marked as deprecated in favor of avioContext
-	// VCMI should to it if URL protocol will be removed from ffmpeg or
-	// when new avioContext will be available in all distros (ETA: late 2012)
-#if LIBAVCODEC_VERSION_INT > AV_VERSION_INT(52, 69, 0)
 	av_register_protocol2(&lod_protocol, sizeof(lod_protocol));
 #else
 	av_register_protocol(&lod_protocol);
@@ -702,17 +722,30 @@ bool CVideoPlayer::open(std::string fname, bool loop, bool useOverlay)
 		return false;
 	}
 
+#if LIBAVCODEC_VERSION_INT > AV_VERSION_INT(52, 117, 0)
+
+	static const int BUFFER_SIZE = 4096;
+	buffer  = (unsigned char *)av_malloc(BUFFER_SIZE);// will be freed by ffmpeg
+	context = avio_alloc_context( buffer, BUFFER_SIZE, 0, (void *)this, lodRead, NULL, lodSeek);
+
+	format = avformat_alloc_context();
+	format->pb = context;
+	// filename is not needed - file was already open and stored in this->data;
+	int avfopen = avformat_open_input(&format, "dummyFilename", nullptr, nullptr);
+
+#else
+
 	std::string filePath;
 	filePath.resize(100);
 	// Create our URL name with the 'lod' protocol as a prefix and a
 	// back pointer to our object. Should be 32 and 64 bits compatible.
 	sprintf(&filePath[0], "%s:0x%016llx", protocol_name, (unsigned long long)(uintptr_t)this);
 
-
 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(53, 0, 0)
 	int avfopen = av_open_input_file(&format, filePath.c_str(), NULL, 0, NULL);
 #else
 	int avfopen = avformat_open_input(&format, filePath.c_str(), NULL, NULL);
+#endif
 #endif
 
 	if (avfopen != 0)
@@ -994,6 +1027,14 @@ void CVideoPlayer::close()
 		avformat_close_input(&format);
 #endif
 	}
+
+#if LIBAVCODEC_VERSION_INT > AV_VERSION_INT(52, 117, 0)
+	if (context)
+	{
+		av_free(context);
+		context = nullptr;
+	}
+#endif
 }
 
 // Plays a video. Only works for overlays.

+ 15 - 22
client/CVideoHandler.h

@@ -213,14 +213,6 @@ public:
 	bool playVideo(int x, int y, SDL_Surface *dst, bool stopOnKey = false); //plays whole opened video; returns: true when whole video has been shown, false when it has been interrupted
 };
 
-#define VIDEO_TAVERN "TAVERN.BIK"
-#define VIDEO_WIN "WIN3.BIK"
-#define VIDEO_LOSE_BATTLE_START "LBSTART.BIK"
-#define VIDEO_LOSE_BATTLE_LOOP "LBLOOP.BIK"
-#define VIDEO_RETREAT_START "RTSTART.BIK"
-#define VIDEO_RETREAT_LOOP "RTLOOP.BIK"
-#define VIDEO_SURRENDER "SURRENDER.BIK"
-
 #else
 
 #ifndef DISABLE_VIDEO
@@ -231,11 +223,18 @@ public:
 #include <SDL_compat.h>
 #endif
 
-typedef struct AVFormatContext AVFormatContext;
-typedef struct AVCodecContext AVCodecContext;
-typedef struct AVCodec AVCodec;
-typedef struct AVFrame AVFrame;
-struct SwsContext;
+//Workaround for compile error in ffmpeg (UINT_64C was not declared)
+#define __STDC_CONSTANT_MACROS
+#ifdef _STDINT_H
+#undef _STDINT_H
+#endif
+#include <stdint.h>
+
+
+extern "C" {
+#include <libavformat/avformat.h>
+#include <libswscale/swscale.h>
+}
 
 class CVideoPlayer : public IMainVideoPlayer
 {
@@ -247,6 +246,9 @@ private:
 	AVFrame *frame; 
 	struct SwsContext *sws;
 
+	unsigned char* buffer;
+	AVIOContext * context;
+
 	// Destination. Either overlay or dest.
 	SDL_Overlay *overlay;
 	SDL_Surface *dest;
@@ -287,13 +289,4 @@ public:
 };
 
 #endif
-
-#define VIDEO_TAVERN "tavern.mjpg"
-#define VIDEO_WIN "win3.mjpg"
-#define VIDEO_LOSE_BATTLE_START "lbstart.mjpg"
-#define VIDEO_LOSE_BATTLE_LOOP "lbloop.mjpg"
-#define VIDEO_RETREAT_START "rtstart.mjpg"
-#define VIDEO_RETREAT_LOOP "rtloop.mjpg"
-#define VIDEO_SURRENDER "surrender.mjpg"
-
 #endif

+ 1 - 1
client/GUIClasses.cpp

@@ -3533,7 +3533,7 @@ CTavernWindow::CTavernWindow(const CGObjectInstance *TavernObj):
 			recruit->block(1);
 	}
 
-	CCS->videoh->open(VIDEO_TAVERN);
+	CCS->videoh->open("TAVERN.BIK");
 }
 
 void CTavernWindow::recruitb()