1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-11-24 08:32:34 +02:00
This commit is contained in:
Laserlicht 2023-10-07 17:19:10 +02:00
parent 63fbaa8380
commit 628de69a63
2 changed files with 79 additions and 0 deletions

View File

@ -127,6 +127,17 @@ bool CVideoPlayer::open(const VideoPath & videoToOpen, bool loop, bool useOverla
}
}
// Find the first audio stream
streamAudio = -1;
for(ui32 i=0; i<format->nb_streams; i++)
{
if (format->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
{
streamAudio = i;
break;
}
}
if (stream < 0)
// No video stream in that file
return false;
@ -134,6 +145,12 @@ bool CVideoPlayer::open(const VideoPath & videoToOpen, bool loop, bool useOverla
// Find the decoder for the video stream
codec = avcodec_find_decoder(format->streams[stream]->codecpar->codec_id);
if(streamAudio > -1)
{
// Find the decoder for the audio stream
codecAudio = avcodec_find_decoder(format->streams[streamAudio]->codecpar->codec_id);
}
if (codec == nullptr)
{
// Unsupported codec
@ -143,6 +160,10 @@ bool CVideoPlayer::open(const VideoPath & videoToOpen, bool loop, bool useOverla
codecContext = avcodec_alloc_context3(codec);
if(!codecContext)
return false;
if (codecAudio != nullptr)
codecContextAudio = avcodec_alloc_context3(codecAudio);
// Get a pointer to the codec context for the video stream
int ret = avcodec_parameters_to_context(codecContext, format->streams[stream]->codecpar);
if (ret < 0)
@ -152,6 +173,17 @@ bool CVideoPlayer::open(const VideoPath & videoToOpen, bool loop, bool useOverla
return false;
}
// Get a pointer to the codec context for the audio stream
if (streamAudio > -1)
{
ret = avcodec_parameters_to_context(codecContextAudio, format->streams[streamAudio]->codecpar);
if (ret < 0)
{
//We cannot get codec from parameters
avcodec_free_context(&codecContextAudio);
}
}
// Open codec
if ( avcodec_open2(codecContext, codec, nullptr) < 0 )
{
@ -162,6 +194,18 @@ bool CVideoPlayer::open(const VideoPath & videoToOpen, bool loop, bool useOverla
// Allocate video frame
frame = av_frame_alloc();
// Open codec
if (codecAudio != nullptr)
{
if ( avcodec_open2(codecContextAudio, codecAudio, nullptr) < 0 )
{
// Could not open codec
codecAudio = nullptr;
}
// Allocate audio frame
frameAudio = av_frame_alloc();
}
//setup scaling
if(scale)
{
@ -231,6 +275,8 @@ bool CVideoPlayer::open(const VideoPath & videoToOpen, bool loop, bool useOverla
if (sws == nullptr)
return false;
playVideoAudio();
return true;
}
@ -435,6 +481,30 @@ void CVideoPlayer::close()
}
}
void CVideoPlayer::playVideoAudio()
{
AVPacket packet;
std::pair<std::unique_ptr<ui8 []>, si64> data;
std::vector<double> samples;
while (av_read_frame(format, &packet) >= 0)
{
avcodec_send_packet(codecContextAudio, &packet);
avcodec_receive_frame(codecContextAudio, frameAudio);
data.second = frameAudio->linesize[0];
data.first = (new ui8[data.second]);
for (int s = 0; s < frameAudio->linesize[0]; s+=sizeof(ui8))
{
ui8 value;
memcpy(&value, &frameAudio->data[0][s], sizeof(ui8));
samples.push_back(value);
data.first.
}
}
}
// Plays a video. Only works for overlays.
bool CVideoPlayer::playVideo(int x, int y, bool stopOnKey)
{

View File

@ -23,6 +23,7 @@ public:
virtual bool nextFrame()=0;
virtual void show(int x, int y, SDL_Surface *dst, bool update = true)=0;
virtual void redraw(int x, int y, SDL_Surface *dst, bool update = true)=0; //reblits buffer
virtual VideoPath videoName()=0;
virtual bool wait()=0;
virtual int curFrame() const =0;
virtual int frameCount() const =0;
@ -46,6 +47,7 @@ public:
void redraw( int x, int y, SDL_Surface *dst, bool update = true ) override {};
void show( int x, int y, SDL_Surface *dst, bool update = true ) override {};
bool nextFrame() override {return false;};
VideoPath videoName() override {return VideoPath();};
void close() override {};
bool wait() override {return false;};
bool open(const VideoPath & name, bool scale = false) override {return false;};
@ -66,10 +68,14 @@ VCMI_LIB_NAMESPACE_END
class CVideoPlayer : public IMainVideoPlayer
{
int stream; // stream index in video
int streamAudio; // stream index in audio
AVFormatContext *format;
AVCodecContext *codecContext; // codec context for stream
AVCodecContext *codecContextAudio; // codec context for stream
const AVCodec *codec;
const AVCodec *codecAudio;
AVFrame *frame;
AVFrame *frameAudio;
struct SwsContext *sws;
AVIOContext * context;
@ -90,6 +96,7 @@ class CVideoPlayer : public IMainVideoPlayer
bool playVideo(int x, int y, bool stopOnKey);
bool open(const VideoPath & fname, bool loop, bool useOverlay = false, bool scale = false);
void playVideoAudio();
public:
CVideoPlayer();
~CVideoPlayer();
@ -106,6 +113,8 @@ public:
// Opens video, calls playVideo, closes video; returns playVideo result (if whole video has been played)
bool openAndPlayVideo(const VideoPath & name, int x, int y, bool stopOnKey = false, bool scale = false) override;
VideoPath videoName() override {return fname;};
//TODO:
bool wait() override {return false;};
int curFrame() const override {return -1;};