2016-08-27 15:51:23 +00:00
|
|
|
#ifndef ENGINE_CLIENT_VIDEO_H
|
|
|
|
#define ENGINE_CLIENT_VIDEO_H
|
|
|
|
|
2021-04-30 22:42:37 +00:00
|
|
|
#include <base/system.h>
|
|
|
|
|
|
|
|
#if defined(CONF_BACKEND_OPENGL_ES)
|
2020-09-26 19:41:58 +00:00
|
|
|
#define GL_GLEXT_PROTOTYPES
|
2021-05-01 00:39:06 +00:00
|
|
|
#include <GLES3/gl3.h>
|
2020-09-26 19:41:58 +00:00
|
|
|
#define glOrtho glOrthof
|
2016-08-27 15:51:23 +00:00
|
|
|
#else
|
2020-09-26 19:41:58 +00:00
|
|
|
#include "SDL_opengl.h"
|
2016-08-27 15:51:23 +00:00
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
extern "C" {
|
|
|
|
#include <libavcodec/avcodec.h>
|
|
|
|
#include <libavformat/avformat.h>
|
|
|
|
#include <libavutil/imgutils.h>
|
|
|
|
#include <libavutil/opt.h>
|
|
|
|
#include <libswresample/swresample.h>
|
|
|
|
#include <libswscale/swscale.h>
|
2016-08-27 15:51:23 +00:00
|
|
|
};
|
|
|
|
|
2019-10-26 11:54:25 +00:00
|
|
|
#include <engine/shared/demo.h>
|
2020-09-26 19:41:58 +00:00
|
|
|
#include <engine/shared/video.h>
|
2019-11-02 08:09:00 +00:00
|
|
|
#define ALEN 2048
|
2016-08-30 23:39:59 +00:00
|
|
|
|
2020-12-02 18:11:19 +00:00
|
|
|
extern LOCK g_WriteLock;
|
|
|
|
|
2016-08-27 19:10:27 +00:00
|
|
|
// a wrapper around a single output AVStream
|
2020-09-26 19:41:58 +00:00
|
|
|
typedef struct OutputStream
|
|
|
|
{
|
2020-06-22 21:59:37 +00:00
|
|
|
AVStream *pSt;
|
|
|
|
AVCodecContext *pEnc;
|
2016-08-27 19:10:27 +00:00
|
|
|
|
2016-08-30 23:39:59 +00:00
|
|
|
/* pts of the next frame that will be generated */
|
2020-07-08 14:59:32 +00:00
|
|
|
int64 NextPts;
|
2020-06-22 21:59:37 +00:00
|
|
|
int SamplesCount;
|
2016-08-27 19:10:27 +00:00
|
|
|
|
2020-06-22 21:59:37 +00:00
|
|
|
AVFrame *pFrame;
|
|
|
|
AVFrame *pTmpFrame;
|
2016-08-27 19:10:27 +00:00
|
|
|
|
2020-06-22 21:59:37 +00:00
|
|
|
struct SwsContext *pSwsCtx;
|
|
|
|
struct SwrContext *pSwrCtx;
|
2016-08-27 19:10:27 +00:00
|
|
|
} OutputStream;
|
2016-08-27 15:51:23 +00:00
|
|
|
|
2016-08-30 23:39:59 +00:00
|
|
|
class CVideo : public IVideo
|
2016-08-27 15:51:23 +00:00
|
|
|
{
|
|
|
|
public:
|
2020-09-26 19:41:58 +00:00
|
|
|
CVideo(class CGraphics_Threaded *pGraphics, class IStorage *pStorage, class IConsole *pConsole, int width, int height, const char *name);
|
2016-08-27 15:51:23 +00:00
|
|
|
~CVideo();
|
|
|
|
|
2020-06-22 21:59:37 +00:00
|
|
|
virtual void Start();
|
|
|
|
virtual void Stop();
|
|
|
|
virtual void Pause(bool Pause);
|
|
|
|
virtual bool IsRecording() { return m_Recording; }
|
2016-08-30 23:39:59 +00:00
|
|
|
|
2020-06-22 21:59:37 +00:00
|
|
|
virtual void NextVideoFrame();
|
|
|
|
virtual void NextVideoFrameThread();
|
|
|
|
virtual bool FrameRendered() { return !m_NextFrame; }
|
2016-08-27 15:51:23 +00:00
|
|
|
|
2020-06-22 21:59:37 +00:00
|
|
|
virtual void NextAudioFrame(void (*Mix)(short *pFinalOut, unsigned Frames));
|
|
|
|
virtual void NextAudioFrameTimeline();
|
|
|
|
virtual bool AudioFrameRendered() { return !m_NextAudioFrame; }
|
2016-08-27 15:51:23 +00:00
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
static IVideo *Current() { return IVideo::ms_pCurrentVideo; }
|
2016-08-27 15:51:23 +00:00
|
|
|
|
2019-11-12 13:41:30 +00:00
|
|
|
static void Init() { av_log_set_level(AV_LOG_DEBUG); }
|
2016-08-27 19:10:27 +00:00
|
|
|
|
2016-08-27 15:51:23 +00:00
|
|
|
private:
|
2020-06-22 21:59:37 +00:00
|
|
|
void FillVideoFrame();
|
|
|
|
void ReadRGBFromGL();
|
2016-08-27 19:10:27 +00:00
|
|
|
|
2020-06-22 21:59:37 +00:00
|
|
|
void FillAudioFrame();
|
2016-08-30 23:39:59 +00:00
|
|
|
|
2020-09-13 20:49:50 +00:00
|
|
|
bool OpenVideo();
|
|
|
|
bool OpenAudio();
|
2020-06-22 21:59:37 +00:00
|
|
|
AVFrame *AllocPicture(enum AVPixelFormat PixFmt, int Width, int Height);
|
2020-09-26 19:41:58 +00:00
|
|
|
AVFrame *AllocAudioFrame(enum AVSampleFormat SampleFmt, uint64 ChannelLayout, int SampleRate, int NbSamples);
|
2016-08-27 19:10:27 +00:00
|
|
|
|
2020-12-02 18:11:19 +00:00
|
|
|
void WriteFrame(OutputStream *pStream) REQUIRES(g_WriteLock);
|
2020-09-26 19:41:58 +00:00
|
|
|
void FinishFrames(OutputStream *pStream);
|
2020-06-22 21:59:37 +00:00
|
|
|
void CloseStream(OutputStream *pStream);
|
2016-08-27 19:10:27 +00:00
|
|
|
|
2020-09-13 20:49:50 +00:00
|
|
|
bool AddStream(OutputStream *pStream, AVFormatContext *pOC, AVCodec **ppCodec, enum AVCodecID CodecId);
|
2016-08-27 15:51:23 +00:00
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
class CGraphics_Threaded *m_pGraphics;
|
|
|
|
class IStorage *m_pStorage;
|
|
|
|
class IConsole *m_pConsole;
|
2016-08-27 15:51:23 +00:00
|
|
|
|
|
|
|
int m_Width;
|
|
|
|
int m_Height;
|
2019-09-27 03:06:02 +00:00
|
|
|
char m_Name[256];
|
2019-10-31 14:01:12 +00:00
|
|
|
//FILE *m_dbgfile;
|
2020-06-22 21:59:37 +00:00
|
|
|
int m_Vseq;
|
2020-09-26 19:41:58 +00:00
|
|
|
short m_aBuffer[ALEN * 2];
|
2020-06-22 21:59:37 +00:00
|
|
|
int m_Vframe;
|
2016-08-27 15:51:23 +00:00
|
|
|
|
2016-08-31 16:07:27 +00:00
|
|
|
int m_FPS;
|
|
|
|
|
2016-08-30 23:39:59 +00:00
|
|
|
bool m_Started;
|
2016-08-27 15:51:23 +00:00
|
|
|
bool m_Recording;
|
2016-08-30 23:39:59 +00:00
|
|
|
|
|
|
|
bool m_ProcessingVideoFrame;
|
|
|
|
bool m_ProcessingAudioFrame;
|
|
|
|
|
|
|
|
bool m_NextFrame;
|
2020-06-22 21:59:37 +00:00
|
|
|
bool m_NextAudioFrame;
|
2016-08-27 15:51:23 +00:00
|
|
|
|
2016-08-27 19:10:27 +00:00
|
|
|
bool m_HasAudio;
|
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
GLubyte *m_pPixels;
|
2016-08-27 15:51:23 +00:00
|
|
|
|
2016-08-27 19:10:27 +00:00
|
|
|
OutputStream m_VideoStream;
|
|
|
|
OutputStream m_AudioStream;
|
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
AVCodec *m_VideoCodec;
|
|
|
|
AVCodec *m_AudioCodec;
|
2016-08-27 19:10:27 +00:00
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
AVDictionary *m_pOptDict;
|
2016-08-27 19:10:27 +00:00
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
AVFormatContext *m_pFormatContext;
|
|
|
|
AVOutputFormat *m_pFormat;
|
2016-08-27 19:10:27 +00:00
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
uint8_t *m_pRGB;
|
2016-08-27 15:51:23 +00:00
|
|
|
|
2016-08-30 23:39:59 +00:00
|
|
|
int m_SndBufferSize;
|
2016-08-27 15:51:23 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|