screenshot: add bmp format and options to dump fb and scale

git-svn-id: file:///home/bas/coolstream_public_svn/THIRDPARTY/applications/neutrino-beta@2054 e54a6e83-5905-42d5-8d5c-058d10e6a962
This commit is contained in:
focus
2012-01-12 15:14:46 +00:00
parent b2638dacf7
commit 14bb685b1e
2 changed files with 70 additions and 4 deletions

View File

@@ -3,6 +3,8 @@
Copyright (C) 2011 CoolStream International Ltd Copyright (C) 2011 CoolStream International Ltd
parts based on AiO Screengrabber (C) Seddi seddi@ihad.tv
License: GPLv2 License: GPLv2
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
@@ -55,6 +57,11 @@ CScreenShot::CScreenShot(const std::string fname, screenshot_format_t fmt)
filename = fname; filename = fname;
pixel_data = NULL; pixel_data = NULL;
fd = NULL; fd = NULL;
xres = 0;
yres = 0;
get_video = true;
get_osd = false;
scale_to_video = false;
} }
CScreenShot::~CScreenShot() CScreenShot::~CScreenShot()
@@ -68,15 +75,20 @@ bool CScreenShot::GetData()
bool res = false; bool res = false;
mutex.lock(); mutex.lock();
#ifdef USE_NEVIS_GXA
CFrameBuffer::getInstance()->setActive(false);
#endif
#if 0 // to enable after libcs/drivers update #if 0 // to enable after libcs/drivers update
res = videoDecoder->GetScreenImage(pixel_data, xres, yres); res = videoDecoder->GetScreenImage(pixel_data, xres, yres, get_video, get_osd, scale_to_video);
#endif #endif
#ifdef USE_NEVIS_GXA #ifdef USE_NEVIS_GXA
/* sort of hack. GXA used to transfer/convert live image to RGB, /* sort of hack. GXA used to transfer/convert live image to RGB,
* so setup GXA back */ * so setup GXA back */
CFrameBuffer::getInstance()->setupGXA(); CFrameBuffer::getInstance()->setupGXA();
CFrameBuffer::getInstance()->add_gxa_sync_marker();
CFrameBuffer::getInstance()->setActive(true);
#endif #endif
mutex.unlock(); mutex.unlock();
if (!res) { if (!res) {
@@ -94,6 +106,8 @@ bool CScreenShot::Start()
bool ret = false; bool ret = false;
if(GetData()) if(GetData())
ret = (start() == 0); ret = (start() == 0);
else
delete this;
return ret; return ret;
} }
@@ -125,6 +139,7 @@ bool CScreenShot::StartSync()
bool CScreenShot::SaveFile() bool CScreenShot::SaveFile()
{ {
bool ret = true; bool ret = true;
switch (format) { switch (format) {
case FORMAT_PNG: case FORMAT_PNG:
ret = SavePng(); ret = SavePng();
@@ -134,7 +149,11 @@ bool CScreenShot::SaveFile()
case FORMAT_JPG: case FORMAT_JPG:
ret = SaveJpg(); ret = SaveJpg();
break; break;
case FORMAT_BMP:
ret = SaveBmp();
break;
} }
cs_free_uncached((void *) pixel_data); cs_free_uncached((void *) pixel_data);
return ret; return ret;
} }
@@ -195,7 +214,7 @@ bool CScreenShot::SavePng()
png_set_compression_level(png_ptr, Z_BEST_SPEED); png_set_compression_level(png_ptr, Z_BEST_SPEED);
png_set_bgr(png_ptr); png_set_bgr(png_ptr);
png_set_invert_alpha(png_ptr); //png_set_invert_alpha(png_ptr);
png_write_info(png_ptr, info_ptr); png_write_info(png_ptr, info_ptr);
png_write_image(png_ptr, row_pointers); png_write_image(png_ptr, row_pointers);
png_write_end(png_ptr, info_ptr); png_write_end(png_ptr, info_ptr);
@@ -234,6 +253,7 @@ bool CScreenShot::SaveJpg()
{ {
int quality = 90; int quality = 90;
TIMER_START();
if(!OpenFile()) if(!OpenFile())
return false; return false;
@@ -283,9 +303,43 @@ bool CScreenShot::SaveJpg()
jpeg_finish_compress(&cinfo); jpeg_finish_compress(&cinfo);
jpeg_destroy_compress(&cinfo); jpeg_destroy_compress(&cinfo);
fclose(fd); fclose(fd);
TIMER_STOP(filename.c_str());
return true; return true;
} }
/* save screenshot in bmp format, return true if success, or false */
bool CScreenShot::SaveBmp()
{
TIMER_START();
if(!OpenFile())
return false;
unsigned char hdr[14 + 40];
unsigned int i = 0;
#define PUT32(x) hdr[i++] = ((x)&0xFF); hdr[i++] = (((x)>>8)&0xFF); hdr[i++] = (((x)>>16)&0xFF); hdr[i++] = (((x)>>24)&0xFF);
#define PUT16(x) hdr[i++] = ((x)&0xFF); hdr[i++] = (((x)>>8)&0xFF);
#define PUT8(x) hdr[i++] = ((x)&0xFF);
PUT8('B'); PUT8('M');
PUT32((((xres * yres) * 3 + 3) &~ 3) + 14 + 40);
PUT16(0); PUT16(0); PUT32(14 + 40);
PUT32(40); PUT32(xres); PUT32(yres);
PUT16(1);
PUT16(4*8); // bits
PUT32(0); PUT32(0); PUT32(0); PUT32(0); PUT32(0); PUT32(0);
#undef PUT32
#undef PUT16
#undef PUT8
fwrite(hdr, 1, i, fd);
int y;
for (y=yres-1; y>=0 ; y-=1) {
fwrite(pixel_data+(y*xres*4),xres*4,1,fd);
}
fclose(fd);
TIMER_STOP(filename.c_str());
return true;
}
bool sectionsd_getActualEPGServiceKey(const t_channel_id uniqueServiceKey, CEPGData * epgdata); bool sectionsd_getActualEPGServiceKey(const t_channel_id uniqueServiceKey, CEPGData * epgdata);
bool sectionsd_getEPGidShort(event_id_t epgID, CShortEPGData * epgdata); bool sectionsd_getEPGidShort(event_id_t epgID, CShortEPGData * epgdata);
@@ -328,7 +382,7 @@ void CScreenShot::MakeFileName(const t_channel_id channel_id)
gettimeofday(&tv, NULL); gettimeofday(&tv, NULL);
strftime(&(fname[pos]), sizeof(fname) - pos - 1, "_%Y%m%d_%H%M%S", localtime(&tv.tv_sec)); strftime(&(fname[pos]), sizeof(fname) - pos - 1, "_%Y%m%d_%H%M%S", localtime(&tv.tv_sec));
pos = strlen(fname); pos = strlen(fname);
snprintf(&(fname[pos]), sizeof(fname) - pos - 1, "_%d", (int) tv.tv_usec/1000); snprintf(&(fname[pos]), sizeof(fname) - pos - 1, "_%03d", (int) tv.tv_usec/1000);
switch (format) { switch (format) {
case FORMAT_PNG: case FORMAT_PNG:
@@ -339,6 +393,9 @@ void CScreenShot::MakeFileName(const t_channel_id channel_id)
case FORMAT_JPG: case FORMAT_JPG:
strcat(fname, ".jpg"); strcat(fname, ".jpg");
break; break;
case FORMAT_BMP:
strcat(fname, ".bmp");
break;
} }
printf("CScreenShot::MakeFileName: [%s]\n", fname); printf("CScreenShot::MakeFileName: [%s]\n", fname);
filename = std::string(fname); filename = std::string(fname);

View File

@@ -29,7 +29,8 @@ class CScreenShot : public OpenThreads::Thread
public: public:
typedef enum { typedef enum {
FORMAT_PNG, FORMAT_PNG,
FORMAT_JPG FORMAT_JPG,
FORMAT_BMP,
} screenshot_format_t; } screenshot_format_t;
private: private:
@@ -38,6 +39,9 @@ class CScreenShot : public OpenThreads::Thread
unsigned char * pixel_data; unsigned char * pixel_data;
int xres; int xres;
int yres; int yres;
bool get_osd;
bool get_video;
bool scale_to_video;
FILE *fd; FILE *fd;
bool GetData(); bool GetData();
@@ -46,6 +50,7 @@ class CScreenShot : public OpenThreads::Thread
bool SavePng(); bool SavePng();
bool SaveJpg(); bool SaveJpg();
bool SaveBmp();
void run(); void run();
public: public:
@@ -53,6 +58,10 @@ class CScreenShot : public OpenThreads::Thread
~CScreenShot(); ~CScreenShot();
void MakeFileName(const t_channel_id channel_id); void MakeFileName(const t_channel_id channel_id);
void SetSize(int w, int h) { xres = w; yres = h; }
void EnableVideo(bool enable) { get_video = enable; }
void EnableOSD(bool enable) { get_osd = enable; }
void ScaleToVideo(bool enable) { scale_to_video = enable; }
bool Start(); bool Start();
bool StartSync(); bool StartSync();
}; };