Skip to content

Commit

Permalink
added: async compressing and writing of png screenshots
Browse files Browse the repository at this point in the history
git-svn-id: https://xbmc.svn.sourceforge.net/svnroot/xbmc/trunk@25730 568bbfeb-2a22-0410-94d2-cc84cf5bfa90
  • Loading branch information
bobo1on1 committed Dec 15, 2009
1 parent 767a90c commit 48b06a4
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 11 deletions.
18 changes: 18 additions & 0 deletions xbmc/Picture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,3 +129,21 @@ int CPicture::ConvertFile(const CStdString &srcFile, const CStdString &destFile,
}
return ret;
}

CThumbnailWriter::CThumbnailWriter(unsigned char* buffer, int width, int height, int stride, const CStdString& thumbFile)
{
m_buffer = buffer;
m_width = width;
m_height = height;
m_stride = stride;
m_thumbFile = thumbFile;
}

bool CThumbnailWriter::DoWork()
{
if (!CPicture::CreateThumbnailFromSurface(m_buffer, m_width, m_height, m_stride, m_thumbFile))
CLog::Log(LOGERROR, "Unable to write screenshot %s", m_thumbFile.c_str());

delete m_buffer;
}

18 changes: 18 additions & 0 deletions xbmc/Picture.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
*
*/
#include "StdString.h"
#include "Job.h"

class CPicture
{
Expand All @@ -32,3 +33,20 @@ class CPicture
static bool CreateThumbnail(const CStdString& file, const CStdString& thumbFile, bool checkExistence = false);
static bool CacheImage(const CStdString& sourceFile, const CStdString& destFile);
};

//this class calls CreateThumbnailFromSurface in a CJob, so a png file can be written without halting the render thread
class CThumbnailWriter : public CJob
{
public:
//WARNING: buffer is deleted from DoWork()
CThumbnailWriter(unsigned char* buffer, int width, int height, int stride, const CStdString& thumbFile);
bool DoWork();

private:
unsigned char* m_buffer;
int m_width;
int m_height;
int m_stride;
CStdString m_thumbFile;
};

38 changes: 29 additions & 9 deletions xbmc/Util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@
#include "utils/TimeUtils.h"
#include "utils/log.h"
#include "Picture.h"
#include "JobManager.h"
#include "guilib/GUITexture.h"

using namespace std;
using namespace DIRECTORY;
Expand Down Expand Up @@ -1843,7 +1845,7 @@ void CUtil::Tokenize(const CStdString& path, vector<CStdString>& tokens, const s
}
}

void CUtil::TakeScreenshot(const CStdString &filename)
void CUtil::TakeScreenshot(const CStdString &filename, bool sync)
{
#ifdef HAS_DX
LPDIRECT3DSURFACE9 lpSurface = NULL;
Expand Down Expand Up @@ -1901,13 +1903,13 @@ void CUtil::TakeScreenshot(const CStdString &filename)

int width = viewport[2] - viewport[0];
int height = viewport[3] - viewport[1];
unsigned char* pixels = (unsigned char*)malloc(width * height * 4);
unsigned char* pixels = new unsigned char[width * height * 4];

//read pixels from the backbuffer
glReadPixels(viewport[0], viewport[1], viewport[2], viewport[3], GL_BGRA, GL_UNSIGNED_BYTE, (GLvoid*)pixels);

//make a new buffer and copy the read image to it with the Y axis inverted
unsigned char* outpixels = (unsigned char*)malloc(width * height * 4);
unsigned char* outpixels = new unsigned char[width * height * 4];
for (int y = 0; y < height; y++)
memcpy(outpixels + y * width * 4, pixels + (height - y - 1) * width * 4, width * 4);

Expand All @@ -1916,14 +1918,32 @@ void CUtil::TakeScreenshot(const CStdString &filename)
for (int i = 0; i < width * height; i++)
*(alphaptr += 4) = 0xFF;

//write .png file
CPicture::CreateThumbnailFromSurface(outpixels, width, height, width * 4, filename);
delete pixels;

free(outpixels);
free(pixels);
//if sync is true, the png file needs to be completely written when this function returns
if (sync)
{
if (!CPicture::CreateThumbnailFromSurface(outpixels, width, height, width * 4, filename))
CLog::Log(LOGERROR, "Unable to write screenshot %s", filename.c_str());

g_graphicsContext.EndPaint();
delete outpixels;
}
else
{
//make sure the file exists to avoid concurrency issues
int fd = open(filename.c_str(), O_WRONLY);
if (fd != -1)
close(fd);
else
CLog::Log(LOGERROR, "Unable to create file %s", filename.c_str());

//write .png file asynchronous with CThumbnailWriter, prevents stalling of the render thread
//outpixels is deleted from CThumbnailWriter
CThumbnailWriter* thumbnailwriter = new CThumbnailWriter(outpixels, width, height, width * 4, filename);
CJobManager::GetInstance().AddJob(thumbnailwriter, NULL);
}

g_graphicsContext.EndPaint();
#endif

}
Expand Down Expand Up @@ -1954,7 +1974,7 @@ void CUtil::TakeScreenshot()

if (!file.IsEmpty())
{
TakeScreenshot(file);
TakeScreenshot(file, false);
if (savingScreenshots)
screenShots.push_back(file);
if (promptUser)
Expand Down
2 changes: 1 addition & 1 deletion xbmc/Util.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ class CUtil
static void PlayDVD();
static CStdString GetNextFilename(const CStdString &fn_template, int max);
static void TakeScreenshot();
static void TakeScreenshot(const CStdString &filename);
static void TakeScreenshot(const CStdString &filename, bool sync);
static void Tokenize(const CStdString& path, std::vector<CStdString>& tokens, const std::string& delimiters);
static void ClearCache();
static void StatToStatI64(struct _stati64 *result, struct stat *stat);
Expand Down
2 changes: 1 addition & 1 deletion xbmc/lib/libGoAhead/XBMChttp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2882,7 +2882,7 @@ int CXbmcHttp::xbmcTakeScreenshot(int numParas, CStdString paras[])
if (numParas>5)
{
CStdString tmpFile = "special://temp/temp.png";
CUtil::TakeScreenshot(tmpFile);
CUtil::TakeScreenshot(tmpFile, true);
int height, width;
if (paras[4]=="")
if (paras[3]=="")
Expand Down

0 comments on commit 48b06a4

Please sign in to comment.