mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40:04 +00:00 
			
		
		
		
	core: Add video dumper interface
The VideoFrame is rotated while copying, to put the pixels in their correct positions (OpenGL seems to return the image in reverted order by default)
This commit is contained in:
		
							parent
							
								
									2f0ea48da4
								
							
						
					
					
						commit
						3f64aaabbd
					
				
					 3 changed files with 87 additions and 0 deletions
				
			
		|  | @ -36,6 +36,8 @@ add_library(core STATIC | |||
|     core.h | ||||
|     core_timing.cpp | ||||
|     core_timing.h | ||||
|     dumping/backend.cpp | ||||
|     dumping/backend.h | ||||
|     file_sys/archive_backend.cpp | ||||
|     file_sys/archive_backend.h | ||||
|     file_sys/archive_extsavedata.cpp | ||||
|  |  | |||
							
								
								
									
										26
									
								
								src/core/dumping/backend.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								src/core/dumping/backend.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,26 @@ | |||
| // Copyright 2018 Citra Emulator Project
 | ||||
| // Licensed under GPLv2 or any later version
 | ||||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #include <cstring> | ||||
| #include "core/dumping/backend.h" | ||||
| 
 | ||||
| namespace VideoDumper { | ||||
| 
 | ||||
| VideoFrame::VideoFrame(std::size_t width_, std::size_t height_, u8* data_) | ||||
|     : width(width_), height(height_), stride(width * 4), data(width * height * 4) { | ||||
|     // While copying, rotate the image to put the pixels in correct order
 | ||||
|     // (As OpenGL returns pixel data starting from the lowest position)
 | ||||
|     for (std::size_t i = 0; i < height; i++) { | ||||
|         for (std::size_t j = 0; j < width; j++) { | ||||
|             for (std::size_t k = 0; k < 4; k++) { | ||||
|                 data[i * stride + j * 4 + k] = data_[(height - i - 1) * stride + j * 4 + k]; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| Backend::~Backend() = default; | ||||
| NullBackend::~NullBackend() = default; | ||||
| 
 | ||||
| } // namespace VideoDumper
 | ||||
							
								
								
									
										59
									
								
								src/core/dumping/backend.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								src/core/dumping/backend.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,59 @@ | |||
| // Copyright 2018 Citra Emulator Project
 | ||||
| // Licensed under GPLv2 or any later version
 | ||||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include <string> | ||||
| #include <vector> | ||||
| #include "audio_core/audio_types.h" | ||||
| #include "common/common_types.h" | ||||
| #include "core/frontend/framebuffer_layout.h" | ||||
| 
 | ||||
| namespace VideoDumper { | ||||
| /**
 | ||||
|  * Frame dump data for a single screen | ||||
|  * data is in RGB888 format, left to right then top to bottom | ||||
|  */ | ||||
| class VideoFrame { | ||||
| public: | ||||
|     std::size_t width; | ||||
|     std::size_t height; | ||||
|     u32 stride; | ||||
|     std::vector<u8> data; | ||||
| 
 | ||||
|     VideoFrame(std::size_t width_ = 0, std::size_t height_ = 0, u8* data_ = nullptr); | ||||
| }; | ||||
| 
 | ||||
| class Backend { | ||||
| public: | ||||
|     virtual ~Backend(); | ||||
|     virtual bool StartDumping(const std::string& path, const std::string& format, | ||||
|                               const Layout::FramebufferLayout& layout) = 0; | ||||
|     virtual void AddVideoFrame(const VideoFrame& frame) = 0; | ||||
|     virtual void AddAudioFrame(const AudioCore::StereoFrame16& frame) = 0; | ||||
|     virtual void AddAudioSample(const std::array<s16, 2>& sample) = 0; | ||||
|     virtual void StopDumping() = 0; | ||||
|     virtual bool IsDumping() const = 0; | ||||
|     virtual Layout::FramebufferLayout GetLayout() const = 0; | ||||
| }; | ||||
| 
 | ||||
| class NullBackend : public Backend { | ||||
| public: | ||||
|     ~NullBackend() override; | ||||
|     bool StartDumping(const std::string& /*path*/, const std::string& /*format*/, | ||||
|                       const Layout::FramebufferLayout& /*layout*/) override { | ||||
|         return false; | ||||
|     } | ||||
|     void AddVideoFrame(const VideoFrame& /*frame*/) override {} | ||||
|     void AddAudioFrame(const AudioCore::StereoFrame16& /*frame*/) override {} | ||||
|     void AddAudioSample(const std::array<s16, 2>& /*sample*/) override {} | ||||
|     void StopDumping() override {} | ||||
|     bool IsDumping() const override { | ||||
|         return false; | ||||
|     } | ||||
|     Layout::FramebufferLayout GetLayout() const override { | ||||
|         return Layout::FramebufferLayout{}; | ||||
|     } | ||||
| }; | ||||
| } // namespace VideoDumper
 | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue