From 9be9934b8c2598ed7c2533f2fddee9de40268db5 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sat, 25 Aug 2018 12:38:04 -0700 Subject: [PATCH] Add reference frame invalidation for the software decoder --- app/streaming/video/decoder.h | 1 + app/streaming/video/ffmpeg-renderers/dxva2.cpp | 5 +++++ app/streaming/video/ffmpeg-renderers/dxva2.h | 1 + app/streaming/video/ffmpeg-renderers/renderer.h | 2 ++ app/streaming/video/ffmpeg-renderers/sdl.cpp | 6 ++++++ app/streaming/video/ffmpeg-renderers/vaapi.cpp | 6 ++++++ app/streaming/video/ffmpeg-renderers/vaapi.h | 1 + app/streaming/video/ffmpeg-renderers/vdpau.cpp | 5 +++++ app/streaming/video/ffmpeg-renderers/vdpau.h | 1 + app/streaming/video/ffmpeg-renderers/vt.mm | 5 +++++ app/streaming/video/ffmpeg.cpp | 5 +++++ app/streaming/video/ffmpeg.h | 1 + app/streaming/video/sl.cpp | 6 ++++++ app/streaming/video/sl.h | 1 + 14 files changed, 46 insertions(+) diff --git a/app/streaming/video/decoder.h b/app/streaming/video/decoder.h index 04f8b7be..806ef90a 100644 --- a/app/streaming/video/decoder.h +++ b/app/streaming/video/decoder.h @@ -19,6 +19,7 @@ public: int frameRate, bool enableVsync) = 0; virtual bool isHardwareAccelerated() = 0; + virtual int getDecoderCapabilities() = 0; virtual int submitDecodeUnit(PDECODE_UNIT du) = 0; virtual void renderFrame(SDL_UserEvent* event) = 0; virtual void dropFrame(SDL_UserEvent* event) = 0; diff --git a/app/streaming/video/ffmpeg-renderers/dxva2.cpp b/app/streaming/video/ffmpeg-renderers/dxva2.cpp index 217b63d0..ea457184 100644 --- a/app/streaming/video/ffmpeg-renderers/dxva2.cpp +++ b/app/streaming/video/ffmpeg-renderers/dxva2.cpp @@ -619,6 +619,11 @@ bool DXVA2Renderer::needsTestFrame() return false; } +int DXVA2Renderer::getDecoderCapabilities() +{ + return 0; +} + void DXVA2Renderer::renderFrameAtVsync(AVFrame *frame) { IDirect3DSurface9* surface = reinterpret_cast(frame->data[3]); diff --git a/app/streaming/video/ffmpeg-renderers/dxva2.h b/app/streaming/video/ffmpeg-renderers/dxva2.h index 013461f2..3ffecc2e 100644 --- a/app/streaming/video/ffmpeg-renderers/dxva2.h +++ b/app/streaming/video/ffmpeg-renderers/dxva2.h @@ -24,6 +24,7 @@ public: virtual bool prepareDecoderContext(AVCodecContext* context); virtual void renderFrameAtVsync(AVFrame* frame); virtual bool needsTestFrame(); + virtual int getDecoderCapabilities(); private: bool initializeDecoder(); diff --git a/app/streaming/video/ffmpeg-renderers/renderer.h b/app/streaming/video/ffmpeg-renderers/renderer.h index 23304bb9..9bba8416 100644 --- a/app/streaming/video/ffmpeg-renderers/renderer.h +++ b/app/streaming/video/ffmpeg-renderers/renderer.h @@ -18,6 +18,7 @@ public: virtual bool prepareDecoderContext(AVCodecContext* context) = 0; virtual void renderFrameAtVsync(AVFrame* frame) = 0; virtual bool needsTestFrame() = 0; + virtual int getDecoderCapabilities() = 0; }; class SdlRenderer : public IFFmpegRenderer { @@ -33,6 +34,7 @@ public: virtual bool prepareDecoderContext(AVCodecContext* context); virtual void renderFrameAtVsync(AVFrame* frame); virtual bool needsTestFrame(); + virtual int getDecoderCapabilities(); private: SDL_Renderer* m_Renderer; diff --git a/app/streaming/video/ffmpeg-renderers/sdl.cpp b/app/streaming/video/ffmpeg-renderers/sdl.cpp index dee1901d..1adcbaf5 100644 --- a/app/streaming/video/ffmpeg-renderers/sdl.cpp +++ b/app/streaming/video/ffmpeg-renderers/sdl.cpp @@ -36,6 +36,12 @@ bool SdlRenderer::needsTestFrame() return false; } +int SdlRenderer::getDecoderCapabilities() +{ + // The FFmpeg CPU decoder can handle reference frame invalidation + return CAPABILITY_REFERENCE_FRAME_INVALIDATION_AVC | CAPABILITY_REFERENCE_FRAME_INVALIDATION_HEVC; +} + bool SdlRenderer::initialize(SDL_Window* window, int, int width, diff --git a/app/streaming/video/ffmpeg-renderers/vaapi.cpp b/app/streaming/video/ffmpeg-renderers/vaapi.cpp index 9793c5d7..27f365a9 100644 --- a/app/streaming/video/ffmpeg-renderers/vaapi.cpp +++ b/app/streaming/video/ffmpeg-renderers/vaapi.cpp @@ -149,6 +149,12 @@ VAAPIRenderer::needsTestFrame() return true; } +int +VAAPIRenderer::getDecoderCapabilities() +{ + return 0; +} + void VAAPIRenderer::renderFrameAtVsync(AVFrame* frame) { diff --git a/app/streaming/video/ffmpeg-renderers/vaapi.h b/app/streaming/video/ffmpeg-renderers/vaapi.h index 5609e9cb..7ce9ea58 100644 --- a/app/streaming/video/ffmpeg-renderers/vaapi.h +++ b/app/streaming/video/ffmpeg-renderers/vaapi.h @@ -39,6 +39,7 @@ public: virtual bool prepareDecoderContext(AVCodecContext* context); virtual void renderFrameAtVsync(AVFrame* frame); virtual bool needsTestFrame(); + virtual int getDecoderCapabilities(); private: int m_WindowSystem; diff --git a/app/streaming/video/ffmpeg-renderers/vdpau.cpp b/app/streaming/video/ffmpeg-renderers/vdpau.cpp index da390b1e..7017f23f 100644 --- a/app/streaming/video/ffmpeg-renderers/vdpau.cpp +++ b/app/streaming/video/ffmpeg-renderers/vdpau.cpp @@ -230,6 +230,11 @@ bool VDPAURenderer::needsTestFrame() return true; } +int VDPAURenderer::getDecoderCapabilities() +{ + return 0; +} + void VDPAURenderer::renderFrameAtVsync(AVFrame* frame) { VdpStatus status; diff --git a/app/streaming/video/ffmpeg-renderers/vdpau.h b/app/streaming/video/ffmpeg-renderers/vdpau.h index 04282c6b..83adbd8a 100644 --- a/app/streaming/video/ffmpeg-renderers/vdpau.h +++ b/app/streaming/video/ffmpeg-renderers/vdpau.h @@ -22,6 +22,7 @@ public: virtual bool prepareDecoderContext(AVCodecContext* context); virtual void renderFrameAtVsync(AVFrame* frame); virtual bool needsTestFrame(); + virtual int getDecoderCapabilities(); private: uint32_t m_VideoWidth, m_VideoHeight; diff --git a/app/streaming/video/ffmpeg-renderers/vt.mm b/app/streaming/video/ffmpeg-renderers/vt.mm index 7962ebbf..fe00eeda 100644 --- a/app/streaming/video/ffmpeg-renderers/vt.mm +++ b/app/streaming/video/ffmpeg-renderers/vt.mm @@ -196,6 +196,11 @@ public: return false; } + virtual int getDecoderCapabilities() override + { + return 0; + } + private: void setupDisplayLayer() { diff --git a/app/streaming/video/ffmpeg.cpp b/app/streaming/video/ffmpeg.cpp index 98a17f6b..65537ec5 100644 --- a/app/streaming/video/ffmpeg.cpp +++ b/app/streaming/video/ffmpeg.cpp @@ -27,6 +27,11 @@ bool FFmpegVideoDecoder::isHardwareAccelerated() return m_HwDecodeCfg != nullptr; } +int FFmpegVideoDecoder::getDecoderCapabilities() +{ + return m_Renderer->getDecoderCapabilities(); +} + enum AVPixelFormat FFmpegVideoDecoder::ffGetFormat(AVCodecContext* context, const enum AVPixelFormat* pixFmts) { diff --git a/app/streaming/video/ffmpeg.h b/app/streaming/video/ffmpeg.h index dc692a3a..360844a8 100644 --- a/app/streaming/video/ffmpeg.h +++ b/app/streaming/video/ffmpeg.h @@ -20,6 +20,7 @@ public: int maxFps, bool enableVsync) override; virtual bool isHardwareAccelerated() override; + virtual int getDecoderCapabilities() override; virtual int submitDecodeUnit(PDECODE_UNIT du) override; virtual void renderFrame(SDL_UserEvent* event) override; virtual void dropFrame(SDL_UserEvent* event) override; diff --git a/app/streaming/video/sl.cpp b/app/streaming/video/sl.cpp index a7b051bb..aac98db8 100644 --- a/app/streaming/video/sl.cpp +++ b/app/streaming/video/sl.cpp @@ -25,6 +25,12 @@ SLVideoDecoder::isHardwareAccelerated() return true; } +int +SLVideoDecoder::getDecoderCapabilities() +{ + return 0; +} + bool SLVideoDecoder::initialize(StreamingPreferences::VideoDecoderSelection vds, SDL_Window*, diff --git a/app/streaming/video/sl.h b/app/streaming/video/sl.h index 810f340b..70f955b9 100644 --- a/app/streaming/video/sl.h +++ b/app/streaming/video/sl.h @@ -17,6 +17,7 @@ public: int frameRate, bool enableVsync); virtual bool isHardwareAccelerated(); + virtual int getDecoderCapabilities(); virtual int submitDecodeUnit(PDECODE_UNIT du); // Unused since rendering is done directly from the decode thread