From 3f309f0c5e37e89bd23b3fdafc745f018b0cac96 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Tue, 5 Feb 2013 23:11:48 +0000 Subject: [PATCH] - removed support for ancient versions of ffmpeg - some cleanup in Linux video player --- client/CVideoHandler.cpp | 137 ++-------------------------- client/CVideoHandler.h | 19 +--- lib/Filesystem/CFileInputStream.cpp | 5 +- 3 files changed, 14 insertions(+), 147 deletions(-) diff --git a/client/CVideoHandler.cpp b/client/CVideoHandler.cpp index 17766eaa2..23b415677 100644 --- a/client/CVideoHandler.cpp +++ b/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(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(opaque); if (whence & AVSEEK_SIZE) - return video->length; + return video->data->getSize(); - video->offset = pos; - vstd::amin(video->offset, video->length); - return video->offset; + return video->data->seek(pos); } -#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; -} - -static int lodClose(URLContext* h) -{ - return 0; -} - -// 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; inb_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. diff --git a/client/CVideoHandler.h b/client/CVideoHandler.h index 396a9bea4..b934f69f6 100644 --- a/client/CVideoHandler.h +++ b/client/CVideoHandler.h @@ -217,20 +217,14 @@ public: #ifndef DISABLE_VIDEO +#include "../lib/Filesystem/CInputStream.h" + #include #include #if SDL_VERSION_ATLEAST(1,3,0) #include #endif -//Workaround for compile error in ffmpeg (UINT_64C was not declared) -#define __STDC_CONSTANT_MACROS -#ifdef _STDINT_H -#undef _STDINT_H -#endif -#include - - extern "C" { #include #include @@ -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 data; }; #endif diff --git a/lib/Filesystem/CFileInputStream.cpp b/lib/Filesystem/CFileInputStream.cpp index 414c72d94..2909f6471 100644 --- a/lib/Filesystem/CFileInputStream.cpp +++ b/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()