Project

General

Profile

Files » xine-plugin-0.9.4-grab.patch

durchflieger, 01/29/2012 07:05 PM

View differences:

xineLib.c
cXineLib::cXineLib(cPlugin *const plugin, const cXineSettings &settings, cMutex &osdMutex, cXineRemote *const remote)
: cThread()
, m_plugin(plugin)
, m_xine_version(0)
, m_settings(settings)
, m_osdFlushRequired(false)
, fd_fifo0_serv(-1)
......
bool cXineLib::checkXineVersion()
{
int32_t version = 0;
execFuncGetVersion(version);
m_xine_version = 0;
execFuncGetVersion(m_xine_version);
if (MIN_XINE_VDR_VERSION <= version /* && version <= MAX_XINE_VDR_VERSION */)
if (MIN_XINE_VDR_VERSION <= m_xine_version /* && version <= MAX_XINE_VDR_VERSION */)
return true;
xfprintf(stderr, "vdr-xine: Client reports unsupported version %d => disconnecting!\n", version);
xfprintf(stderr, "vdr-xine: Client reports unsupported version %d => disconnecting!\n", m_xine_version);
disconnect();
return false;
......
#ifndef PNMTOJPEG
#define PNMTOJPEG "pnmtojpeg"
#endif
#ifndef XINE_VERSION_CODE
#define XINE_VERSION_CODE XINE_MAJOR_VERSION*10000+XINE_MINOR_VERSION*100+XINE_SUB_VERSION
#endif
uchar *cXineLib::execFuncGrabImage(const char *FileName, int &Size, bool Jpeg, int Quality, int SizeX, int SizeY)
{
if (!isConnected())
......
DLOG("cXineLib::execFuncGrabImage");
cMutexLock ioLock(&m_ioMutex);
int videoX = -1;
int videoY = -1;
int videoW = -1;
int videoH = -1;
int zoomX = 100;
int zoomY = 100;
execFuncVideoSize(videoX, videoY, videoW, videoH, zoomX, zoomY);
if (!isConnected())
return NULL;
data_grab_image_t data;
data.header.func = func_grab_image;
data.header.len = sizeof (data);
if (sizeof (data) == xwrite(fd_control, &data, sizeof (data)))
enum funcs grab_func;
#if XINE_VERSION_CODE >= 10201
if (m_xine_version >= 905)
{
result_union_t resultUnion;
off_t n = xread(fd_result, (char *)&resultUnion, sizeof (resultUnion.header));
if (n != sizeof (resultUnion.header))
data_grab_image_v2_t data;
data.header.func = func_grab_image_v2;
data.header.len = sizeof (data);
data.width = SizeX;
data.height = SizeY;
data.jpeg = Jpeg;
data.quality = Quality;
if (sizeof (data) != xwrite(fd_control, &data, sizeof (data)))
return NULL;
if (data.header.func != resultUnion.header.func)
return NULL;
result_grab_image_t *result = &resultUnion.grab_image;
n = xread(fd_result, (char *)result + sizeof (result->header), sizeof (*result) - sizeof (result->header));
if (n != sizeof (*result) - sizeof (result->header))
grab_func = func_grab_image_v2;
}
else
#endif
{
data_grab_image_t data;
data.header.func = func_grab_image;
data.header.len = sizeof (data);
if (sizeof (data) != xwrite(fd_control, &data, sizeof (data)))
return NULL;
grab_func = func_grab_image;
}
const size_t frameSize = result->header.len - sizeof (*result);
result_union_t resultUnion;
off_t n = xread(fd_result, (char *)&resultUnion, sizeof (resultUnion.header));
if (n != sizeof (resultUnion.header))
return NULL;
// ::fprintf(stderr, "frameSize: %d\n", frameSize);
if (frameSize <= 0)
return NULL;
uint8_t *img = (uint8_t *)::malloc(frameSize);
if (!img)
return NULL;
if (frameSize != (size_t)xread(fd_result, img, frameSize))
if (grab_func != resultUnion.header.func)
return NULL;
result_grab_image_t *result = &resultUnion.grab_image;
n = xread(fd_result, (char *)result + sizeof (result->header), sizeof (*result) - sizeof (result->header));
if (n != sizeof (*result) - sizeof (result->header))
return NULL;
const size_t frameSize = result->header.len - sizeof (*result);
if (frameSize <= 0)
return NULL;
uint8_t *img = (uint8_t *)::malloc(frameSize);
if (!img)
return NULL;
if (frameSize != (size_t)xread(fd_result, img, frameSize))
{
::free(img);
return NULL;
}
if (XINE_IMGFMT_YUY2 == result->format)
{
uint8_t *img2 = (uint8_t *)::malloc(frameSize);
if (!img2)
{
::free(img);
return NULL;
}
if (XINE_IMGFMT_YUY2 == result->format)
::memset(img2, 0x80, frameSize);
uint8_t *src = img;
uint8_t *dstY = img2;
uint8_t *dstU = dstY + result->height * result->width;
uint8_t *dstV = dstU + result->height * ((result->width + 1) / 2);
for (int y = 0; y < result->height; y++)
{
uint8_t *img2 = (uint8_t *)::malloc(frameSize);
if (!img2)
for (int x = 0; x < (result->width + 1) / 2; x++)
{
::free(img);
return NULL;
*dstY++ = *src++;
*dstU++ = *src++;
*dstY++ = *src++;
*dstV++ = *src++;
}
}
::memset(img2, 0x80, frameSize);
uint8_t *src = img;
uint8_t *dstY = img2;
uint8_t *dstU = dstY + result->height * result->width;
uint8_t *dstV = dstU + result->height * ((result->width + 1) / 2);
for (int y = 0; y < result->height; y++)
{
for (int x = 0; x < (result->width + 1) / 2; x++)
{
*dstY++ = *src++;
*dstU++ = *src++;
*dstY++ = *src++;
*dstV++ = *src++;
}
}
::free(img);
img = img2;
}
else if (XINE_IMGFMT_YV12 != result->format) /* xinelib already returns complete result */
{
Size = frameSize;
return (uchar *)img;
}
::free(img);
const char *grabName;
char *tempName = NULL;
if (FileName)
grabName = FileName;
else
{
char prefix[6];
::snprintf(prefix, 6, "%d", (int)::getpid());
tempName = ::tempnam(NULL, prefix);
grabName = tempName;
}
img = img2;
}
int videoX = result->crop_left;
int videoY = result->crop_top;
int videoW = result->width - result->crop_left - result->crop_right;
int videoH = result->height - result->crop_top - result->crop_bottom;
FILE *tmpFile = 0;
int outfd = -1;
int iRn;
int iRd;
if (FileName)
{
outfd = ::open(FileName, O_CREAT /* | O_EXCL */ | O_TRUNC | O_RDWR, 0644);
}
else
{
tmpFile = ::tmpfile();
if (tmpFile)
outfd = fileno(tmpFile);
}
if (videoW > videoH)
{
iRn = videoH;
iRd = (videoW * 20000 + result->ratio) / (2 * result->ratio);
}
else
{
iRn = (videoH * 2 * result->ratio + 10000) / 20000;
iRd = videoW;
}
if (-1 == outfd)
{
if (tmpFile)
::fclose(tmpFile); // removes file, too
}
else
{
/*
if (-1 == videoX || -1 == videoY || videoW <= 0 || videoH <= 0)
{
videoX = 0;
videoY = 0;
videoW = result->width;
videoH = result->height;
}
*/
videoX = result->crop_left;
videoY = result->crop_top;
videoW = result->width - result->crop_left - result->crop_right;
videoH = result->height - result->crop_top - result->crop_bottom;
int oRn = SizeY * (m_noSignalStream16x9 ? 16 : 4);
int oRd = SizeX * (m_noSignalStream16x9 ? 9 : 3);
int iRn;
int iRd;
const char *const chromass = (XINE_IMGFMT_YV12 == result->format) ? "420_MPEG2" : "422";
char *cmd = NULL;
if (videoW > videoH)
{
iRn = videoH;
iRd = (videoW * 20000 + result->ratio) / (2 * result->ratio);
}
else
{
iRn = (videoH * 2 * result->ratio + 10000) / 20000;
iRd = videoW;
}
if (Jpeg)
{
::asprintf(&cmd, Y4MSCALER " -v 0 -I chromass=%s -I active=%dx%d+%d+%d -O chromass=444 -O size=%dx%d -O sar=%d:%d "
"| " Y4MTOPPM " -v 0 -L "
"| " PNMTOJPEG " -quality=%d "
">%s"
, chromass, videoW, videoH, videoX, videoY, SizeX, SizeY, oRn, oRd
, Quality
, grabName);
}
else
{
::asprintf(&cmd, Y4MSCALER " -v 0 -I chromass=%s -I active=%dx%d+%d+%d -O chromass=444 -O size=%dx%d -O sar=%d:%d "
"| " Y4MTOPPM " -v 0 -L "
">%s"
, chromass, videoW, videoH, videoX, videoY, SizeX, SizeY, oRn, oRd
, grabName);
}
int oRn = SizeY * (m_noSignalStream16x9 ? 16 : 4);
int oRd = SizeX * (m_noSignalStream16x9 ? 9 : 3);
xfprintf(stderr, "cmd: %s\n", cmd);
const char *const chromass = (XINE_IMGFMT_YV12 == result->format) ? "420_MPEG2" : "422";
char *cmd = 0;
if (Jpeg)
{
::asprintf(&cmd, Y4MSCALER " -I chromass=%s -I active=%dx%d+%d+%d -O chromass=444 -O size=%dx%d -O sar=%d:%d "
"| " Y4MTOPPM " -L "
"| " PNMTOJPEG " -quality=%d "
">&%d"
, chromass, videoW, videoH, videoX, videoY, SizeX, SizeY, oRn, oRd
, Quality
, outfd);
}
else
{
::asprintf(&cmd, Y4MSCALER " -I chromass=%s -I active=%dx%d+%d+%d -O chromass=444 -O size=%dx%d -O sar=%d:%d "
"| " Y4MTOPPM " -L "
">&%d"
, chromass, videoW, videoH, videoX, videoY, SizeX, SizeY, oRn, oRd
, outfd);
}
// ::fprintf(stderr, "ratio: %d\n", result->ratio);
xfprintf(stderr, "cmd: %s\n", cmd);
FILE *f = ::popen(cmd, "w");
if (f)
{
::fprintf(f, "YUV4MPEG2 W%d H%d F%d:%d I%c A%d:%d\nFRAME\n"
, result->width, result->height
, 25, 1
, "ptb"[result->interlaced]
, iRn, iRd);
FILE *f = ::popen(cmd, "w");
if (f)
{
::fprintf(f, "YUV4MPEG2 W%d H%d F%d:%d I%c A%d:%d\nFRAME\n"
, result->width, result->height
, 25, 1
, "ptb"[result->interlaced]
, iRn, iRd);
if (frameSize == ::fwrite(img, 1, frameSize, f))
{
::pclose(f); // close the pipe here
::free(img);
img = NULL;
if (frameSize == ::fwrite(img, 1, frameSize, f))
if (tempName) // grab the image in one go
{
int fd = ::open(tempName, O_RDONLY);
if (fd != -1)
{
::pclose(f); // close the pipe here
::free(img);
img = NULL;
Size = (int) ::lseek (fd, 0, SEEK_END);
::lseek (fd, 0, SEEK_SET);
if (tmpFile) // grab the image in one go
if (Size != -1)
{
Size = (int) lseek (outfd, 0, SEEK_END);
lseek (outfd, 0, SEEK_SET);
if (Size != -1)
img = (uint8_t *)::malloc(Size);
if (img && Size != ::read(fd, img, Size))
{
img = (uint8_t *)::malloc(Size);
if (img && Size != ::read(outfd, img, Size))
{
::free(img);
img = NULL;
}
::free(img);
img = NULL;
}
}
else // file is persistent so don't care about it's content
{
Size = -1;
img = (uint8_t *)-1;
}
}
else
{
::pclose(f);
::free(img);
img = NULL;
::close(fd);
}
}
else
else // file is persistent so don't care about it's content
{
::free(img);
img = NULL;
Size = -1;
img = (uint8_t *)-1;
}
::free(cmd);
if (tmpFile)
::fclose(tmpFile); // removes file, too
else
::close(outfd);
return (uchar *)img;
}
else
{
::pclose(f);
::free(img);
img = NULL;
}
}
else
{
::free(img);
img = NULL;
}
::free(cmd);
if (tempName)
{
::unlink(tempName);
::free(tempName);
}
return NULL;
return (uchar *)img;
}
bool cXineLib::execFuncGetVersion(int32_t &version)
xineLib.h
cMutex m_shutdownMutex;
cCondVar m_shutdownCondVar;
int32_t m_xine_version;
const cXineSettings &m_settings;
bool osdUpdateLocked(const char *const funcName);
(1-1/3)