2
0
Laserlicht 2 жил өмнө
parent
commit
628de69a63

+ 70 - 0
client/CVideoHandler.cpp

@@ -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)
 {

+ 9 - 0
client/CVideoHandler.h

@@ -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;};