1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-11-27 22:49:25 +02:00

- removed support for ancient versions of ffmpeg

- some cleanup in Linux video player
This commit is contained in:
Ivan Savenko
2013-02-05 23:11:48 +00:00
parent 60c18f1bb8
commit 3f309f0c5e
3 changed files with 14 additions and 147 deletions

View File

@@ -574,21 +574,12 @@ bool CVideoPlayer::playVideo(int x, int y, SDL_Surface *dst, bool stopOnKey)
#ifndef DISABLE_VIDEO #ifndef DISABLE_VIDEO
#if LIBAVCODEC_VERSION_INT > AV_VERSION_INT(52, 117, 0)
// Define a set of functions to read data // Define a set of functions to read data
static int lodRead(void* opaque, uint8_t* buf, int size) static int lodRead(void* opaque, uint8_t* buf, int size)
{ {
auto video = reinterpret_cast<CVideoPlayer *>(opaque); auto video = reinterpret_cast<CVideoPlayer *>(opaque);
vstd::amin(size, video->length - video->offset); return video->data->read(buf, size);
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) 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); auto video = reinterpret_cast<CVideoPlayer *>(opaque);
if (whence & AVSEEK_SIZE) if (whence & AVSEEK_SIZE)
return video->length; return video->data->getSize();
video->offset = pos; return video->data->seek(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;
}
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() CVideoPlayer::CVideoPlayer()
{ {
format = NULL; format = NULL;
@@ -679,20 +601,11 @@ CVideoPlayer::CVideoPlayer()
overlay = NULL; overlay = NULL;
dest = NULL; dest = NULL;
context = nullptr; context = nullptr;
buffer = nullptr;
// Register codecs. TODO: May be overkill. Should call a // Register codecs. TODO: May be overkill. Should call a
// combination of av_register_input_format() / // combination of av_register_input_format() /
// av_register_output_format() / av_register_protocol() instead. // av_register_output_format() / av_register_protocol() instead.
av_register_all(); 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) bool CVideoPlayer::open(std::string fname)
@@ -707,30 +620,20 @@ bool CVideoPlayer::open(std::string fname, bool loop, bool useOverlay)
close(); close();
this->fname = fname; this->fname = fname;
offset = 0;
refreshWait = 3; refreshWait = 3;
refreshCount = -1; refreshCount = -1;
doLoop = loop; doLoop = loop;
ResourceID resource(std::string("Video/") + fname, EResType::VIDEO); ResourceID resource(std::string("Video/") + fname, EResType::VIDEO);
if (CResourceHandler::get()->existsResource(resource)) if (!CResourceHandler::get()->existsResource(resource))
{
auto extracted = CResourceHandler::get()->loadData(resource);
data = (char *)extracted.first.release();
length = extracted.second;
}
else
{
data = nullptr;
length = 0;
return false; return false;
}
#if LIBAVCODEC_VERSION_INT > AV_VERSION_INT(52, 117, 0) data = CResourceHandler::get()->load(resource);
static const int BUFFER_SIZE = 4096; 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); context = avio_alloc_context( buffer, BUFFER_SIZE, 0, (void *)this, lodRead, NULL, lodSeek);
format = avformat_alloc_context(); 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; // filename is not needed - file was already open and stored in this->data;
int avfopen = avformat_open_input(&format, "dummyFilename", nullptr, nullptr); 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) if (avfopen != 0)
{ {
return false; return false;
@@ -769,11 +657,7 @@ bool CVideoPlayer::open(std::string fname, bool loop, bool useOverlay)
stream = -1; stream = -1;
for(ui32 i=0; i<format->nb_streams; i++) 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) if (format->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO)
#endif
{ {
stream = i; stream = i;
break; break;
@@ -888,7 +772,6 @@ bool CVideoPlayer::nextFrame()
while(!frameFinished) while(!frameFinished)
{ {
int ret = av_read_frame(format, &packet); int ret = av_read_frame(format, &packet);
if (ret < 0) if (ret < 0)
{ {
@@ -912,11 +795,7 @@ bool CVideoPlayer::nextFrame()
{ {
// Decode video frame // 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); avcodec_decode_video2(codecContext, frame, &frameFinished, &packet);
#endif
// Did we get a video frame? // Did we get a video frame?
if (frameFinished) if (frameFinished)
@@ -1048,13 +927,11 @@ void CVideoPlayer::close()
#endif #endif
} }
#if LIBAVCODEC_VERSION_INT > AV_VERSION_INT(52, 117, 0)
if (context) if (context)
{ {
av_free(context); av_free(context);
context = nullptr; context = nullptr;
} }
#endif
} }
// Plays a video. Only works for overlays. // Plays a video. Only works for overlays.

View File

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

View File

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