浏览代码

- removed support for ancient versions of ffmpeg
- some cleanup in Linux video player

Ivan Savenko 12 年之前
父节点
当前提交
3f309f0c5e
共有 3 个文件被更改,包括 14 次插入147 次删除
  1. 7 130
      client/CVideoHandler.cpp
  2. 5 14
      client/CVideoHandler.h
  3. 2 3
      lib/Filesystem/CFileInputStream.cpp

+ 7 - 130
client/CVideoHandler.cpp

@@ -574,21 +574,12 @@ bool CVideoPlayer::playVideo(int x, int y, SDL_Surface *dst, bool stopOnKey)
 
 #ifndef DISABLE_VIDEO
 
-#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);
-
-	if (size < 0)
-		return -1;
-
-	memcpy(buf, video->data + video->offset, size);
-	video->offset += size;
-	return size;
+	return video->data->read(buf, size);
 }
 
 static si64 lodSeek(void * opaque, si64 pos, int whence)
@@ -596,80 +587,11 @@ 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 lodOpen(URLContext *context, const char *filename, int flags)
-{
-	CVideoPlayer *video;
-
-	// Retrieve pointer to CVideoPlayer object
-	filename += strlen(protocol_name) + 1;
-	video = (CVideoPlayer *)(uintptr_t)strtoull(filename, NULL, 16);
-
-	// TODO: check flags ?
-
-	context->priv_data = video;
-
-	return 0;
-}
+		return video->data->getSize();
 
-static int lodClose(URLContext* h)
-{
-	return 0;
+	return video->data->seek(pos);
 }
 
-// Define a set of functions to read data
-static int lodRead(URLContext *context, ui8 *buf, int size)
-{
-	CVideoPlayer *video = (CVideoPlayer *)context->priv_data;
-
-	vstd::amin(size, video->length - video->offset);
-
-	if (size < 0)
-		return -1;
-
-	// TODO: can we avoid that copy ?
-	memcpy(buf, video->data + video->offset, size);
-
-	video->offset += size;
-
-	return size;
-}
-
-static si64 lodSeek(URLContext *context, si64 pos, int whence)
-{
-	CVideoPlayer *video = (CVideoPlayer *)context->priv_data;
-
-	if (whence & AVSEEK_SIZE)
-		return video->length;
-
-	video->offset = pos;
-	vstd::amin(video->offset, video->length);
-	return video->offset;
-}
-
-static URLProtocol lod_protocol =
-{
-	protocol_name,
-	lodOpen,
-	lodRead,
-	NULL,						// no write
-	lodSeek,
-	lodClose
-};
-
-#endif
-
 CVideoPlayer::CVideoPlayer()
 {
 	format = NULL;
@@ -679,20 +601,11 @@ CVideoPlayer::CVideoPlayer()
 	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
-	av_register_protocol2(&lod_protocol, sizeof(lod_protocol));
-#else
-	av_register_protocol(&lod_protocol);
-#endif
 }
 
 bool CVideoPlayer::open(std::string fname)
@@ -707,30 +620,20 @@ bool CVideoPlayer::open(std::string fname, bool loop, bool useOverlay)
 	close();
 
 	this->fname = fname;
-	offset = 0;
 	refreshWait = 3;
 	refreshCount = -1;
 	doLoop = loop;
 
 	ResourceID resource(std::string("Video/") + fname, EResType::VIDEO);
 
-	if (CResourceHandler::get()->existsResource(resource))
-	{
-		auto extracted = CResourceHandler::get()->loadData(resource);
-		data = (char *)extracted.first.release();
-		length = extracted.second;
-	}
-	else
-	{
-		data = nullptr;
-		length = 0;
+	if (!CResourceHandler::get()->existsResource(resource))
 		return false;
-	}
 
-#if LIBAVCODEC_VERSION_INT > AV_VERSION_INT(52, 117, 0)
+	data = CResourceHandler::get()->load(resource);
 
 	static const int BUFFER_SIZE = 4096;
-	buffer  = (unsigned char *)av_malloc(BUFFER_SIZE);// will be freed by ffmpeg
+
+	unsigned char * 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();
@@ -738,21 +641,6 @@ bool CVideoPlayer::open(std::string fname, bool loop, bool useOverlay)
 	// 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)
 	{
 		return false;
@@ -769,11 +657,7 @@ bool CVideoPlayer::open(std::string fname, bool loop, bool useOverlay)
 	stream = -1;
 	for(ui32 i=0; i<format->nb_streams; i++)
 	{
-#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(53, 0, 0)
-		if (format->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO)
-#else
 		if (format->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO)
-#endif
 		{
 			stream = i;
 			break;
@@ -888,7 +772,6 @@ bool CVideoPlayer::nextFrame()
 
 	while(!frameFinished)
 	{
-
 		int ret = av_read_frame(format, &packet);
 		if (ret < 0)
 		{
@@ -912,11 +795,7 @@ bool CVideoPlayer::nextFrame()
 			{
 				// Decode video frame
 
-#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52, 25, 0)
-				avcodec_decode_video(codecContext, frame, &frameFinished, packet.data, packet.size);
-#else
 				avcodec_decode_video2(codecContext, frame, &frameFinished, &packet);
-#endif
 
 				// Did we get a video frame?
 				if (frameFinished)
@@ -1048,13 +927,11 @@ void CVideoPlayer::close()
 #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.

+ 5 - 14
client/CVideoHandler.h

@@ -217,20 +217,14 @@ public:
 
 #ifndef DISABLE_VIDEO
 
+#include "../lib/Filesystem/CInputStream.h"
+
 #include <SDL.h>
 #include <SDL_video.h>
 #if SDL_VERSION_ATLEAST(1,3,0)
 #include <SDL_compat.h>
 #endif
 
-//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>
@@ -238,7 +232,6 @@ extern "C" {
 
 class CVideoPlayer : public IMainVideoPlayer
 {
-private:
 	int stream;					// stream index in video
 	AVFormatContext *format;
 	AVCodecContext *codecContext; // codec context for stream
@@ -246,7 +239,6 @@ private:
 	AVFrame *frame; 
 	struct SwsContext *sws;
 
-	unsigned char* buffer;
 	AVIOContext * context;
 
 	// Destination. Either overlay or dest.
@@ -282,10 +274,9 @@ public:
 	bool wait(){return false;};
 	int curFrame() const {return -1;};
 	int frameCount() const {return -1;};
-	
-	const char *data;			// video buffer
-	int length;					// video size
-	ui32 offset;		// current data offset
+
+	// public to allow access from ffmpeg IO functions
+	std::unique_ptr<CInputStream> data;
 };
 
 #endif

+ 2 - 3
lib/Filesystem/CFileInputStream.cpp

@@ -49,9 +49,8 @@ si64 CFileInputStream::read(ui8 * data, si64 size)
 
 si64 CFileInputStream::seek(si64 position)
 {
-    si64 origin = tell();
-    fileStream.seekg(dataStart + std::min(position, dataSize));
-    return tell() - origin;
+	fileStream.seekg(dataStart + std::min(position, dataSize));
+	return tell();
 }
 
 si64 CFileInputStream::tell()