diff --git a/plugins/GSdx/GSCapture.cpp b/plugins/GSdx/GSCapture.cpp index e7fc337522..b9c32b35df 100644 --- a/plugins/GSdx/GSCapture.cpp +++ b/plugins/GSdx/GSCapture.cpp @@ -382,11 +382,16 @@ GSCapture::GSCapture() : m_capturing(false), m_frame(0) , m_out_dir("/tmp/GSdx_Capture") // FIXME Later add an option { +#ifdef __linux__ + m_worker = NULL; +#endif } GSCapture::~GSCapture() { EndCapture(); + + delete m_worker; } bool GSCapture::BeginCapture(float fps) @@ -490,6 +495,8 @@ bool GSCapture::BeginCapture(float fps) m_size.x = 1280; m_size.y = 1024; + m_worker = new GSPng::Worker(); + #endif m_capturing = true; @@ -523,12 +530,9 @@ bool GSCapture::DeliverFrame(const void* bits, int pitch, bool rgba) #elif __linux__ - try { - std::string out_file = m_out_dir + format("/frame.%010d.png", m_frame); - GSPng::Save(GSPng::RGB_PNG, out_file, (char*)bits, m_size.x, m_size.y, pitch); - } catch (...) { - // Don't care. Likely a wrong setup. Bonus for the futur - } + std::string out_file = m_out_dir + format("/frame.%010d.png", m_frame); + //GSPng::Save(GSPng::RGB_PNG, out_file, (char*)bits, m_size.x, m_size.y, pitch); + m_worker->Push(shared_ptr(new GSPng::Transaction(GSPng::RGB_PNG, out_file, (char*)bits, m_size.x, m_size.y, pitch))); m_frame++; @@ -562,6 +566,9 @@ bool GSCapture::EndCapture() } #elif __linux__ + if (m_worker) { + m_worker->Wait(); + } m_frame = 0; diff --git a/plugins/GSdx/GSCapture.h b/plugins/GSdx/GSCapture.h index b479c3b83c..5e95a26d51 100644 --- a/plugins/GSdx/GSCapture.h +++ b/plugins/GSdx/GSCapture.h @@ -25,6 +25,7 @@ #ifndef _CX11_ #include "GSThread.h" #endif +#include "GSPng.h" #ifdef _WINDOWS #include "GSCaptureDlg.h" @@ -47,6 +48,10 @@ class GSCapture CComPtr m_graph; CComPtr m_src; + #elif __linux__ + + GSPng::Worker* m_worker; + #endif public: diff --git a/plugins/GSdx/GSPng.cpp b/plugins/GSdx/GSPng.cpp index 0c7965f16a..630cf2d64a 100644 --- a/plugins/GSdx/GSPng.cpp +++ b/plugins/GSdx/GSPng.cpp @@ -159,4 +159,25 @@ namespace GSPng { } #endif } + + Transaction::Transaction(GSPng::Format fmt, const string& file, char* image, int w, int h, int pitch) + : m_fmt(fmt), m_file(file), m_w(w), m_h(h), m_pitch(pitch) + { + // Note: yes it would be better to use shared pointer + m_image = (char*)_aligned_malloc(pitch*h, 32); + if (m_image) + memcpy(m_image, image, pitch*h); + } + + Transaction::~Transaction() + { + if (m_image) + _aligned_free(m_image); + } + + void Worker::Process(shared_ptr& item) + { + Save(item->m_fmt, item->m_file, item->m_image, item->m_w, item->m_h, item->m_pitch); + } + } diff --git a/plugins/GSdx/GSPng.h b/plugins/GSdx/GSPng.h index 6163a1655a..5d0c48556a 100644 --- a/plugins/GSdx/GSPng.h +++ b/plugins/GSdx/GSPng.h @@ -18,9 +18,12 @@ * */ +#pragma once + #ifdef ENABLE_OGL_PNG #include "png++/png.hpp" #endif +#include "GSThread_CXX11.h" namespace GSPng { enum Format { @@ -34,5 +37,30 @@ namespace GSPng { R32I_PNG, }; + class Transaction + { + public: + Format m_fmt; + const std::string m_file; + char* m_image; + int m_w; + int m_h; + int m_pitch; + + Transaction(GSPng::Format fmt, const string& file, char* image, int w, int h, int pitch); + ~Transaction(); + }; + void Save(GSPng::Format fmt, const string& file, char* image, int w, int h, int pitch); + + class Worker : public GSJobQueue > + { + public: + Worker() {}; + virtual ~Worker() {}; + + void Process(shared_ptr& item); + + int GetPixels(bool reset) {return 0;} + }; }