mirror of
https://github.com/vcmi/vcmi.git
synced 2024-11-24 08:32:34 +02:00
audio
This commit is contained in:
parent
63fbaa8380
commit
628de69a63
@ -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)
|
||||
{
|
||||
|
@ -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;};
|
||||
|
Loading…
Reference in New Issue
Block a user