summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohns <johns98@gmx.net>2015-06-30 08:12:09 (GMT)
committerJohns <johns98@gmx.net>2015-06-30 08:12:09 (GMT)
commitec58e456072d962a18cb50f4324d266ba4a2aae8 (patch)
tree1dab1b0faa267b7b73de336f5a5876a2632608ec
parent396d5fac055aae8afeb4626d2b56e4bf989f8fd6 (diff)
downloadvdr-plugin-softhddevice-ec58e456072d962a18cb50f4324d266ba4a2aae8.tar.gz
vdr-plugin-softhddevice-ec58e456072d962a18cb50f4324d266ba4a2aae8.tar.bz2
Fix bug: wrong and crash, if vdr draws pixmaps outside OSD.
-rw-r--r--ChangeLog1
-rw-r--r--softhddev.c14
-rw-r--r--softhddev.h5
-rw-r--r--softhddevice.cpp119
-rw-r--r--video.c129
-rw-r--r--video.h5
6 files changed, 200 insertions, 73 deletions
diff --git a/ChangeLog b/ChangeLog
index c138a66..67f53a3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,7 @@
User johns
Date:
+ Fix bug: wrong and crash, if vdr draws pixmaps outside OSD.
Fix bug: wrong version number check for av_frame_alloc(), ...
Workaround for ffmpeg 2.6 artifacts.
Fix bug: brightness and .. are calculated wrong.
diff --git a/softhddev.c b/softhddev.c
index a44f020..bc0a3a4 100644
--- a/softhddev.c
+++ b/softhddev.c
@@ -2866,17 +2866,21 @@ void OsdClose(void)
/**
** Draw an OSD pixmap.
**
+** @param xi x-coordinate in argb image
+** @param yi y-coordinate in argb image
+** @paran height height in pixel in argb image
+** @paran width width in pixel in argb image
+** @param pitch pitch of argb image
+** @param argb 32bit ARGB image data
** @param x x-coordinate on screen of argb image
** @param y y-coordinate on screen of argb image
-** @paran height height in pixel of argb image
-** @paran width width in pixel of argb image
-** @param argb height * width 32bit ARGB image data
*/
-void OsdDrawARGB(int x, int y, int height, int width, const uint8_t * argb)
+void OsdDrawARGB(int xi, int yi, int height, int width, int pitch,
+ const uint8_t * argb, int x, int y)
{
// wakeup display for showing remote learning dialog
VideoDisplayWakeup();
- VideoOsdDrawARGB(x, y, height, width, argb);
+ VideoOsdDrawARGB(xi, yi, height, width, pitch, argb, x, y);
}
//////////////////////////////////////////////////////////////////////////////
diff --git a/softhddev.h b/softhddev.h
index a793503..efb2e25 100644
--- a/softhddev.h
+++ b/softhddev.h
@@ -1,7 +1,7 @@
///
/// @file softhddev.h @brief software HD device plugin header file.
///
-/// Copyright (c) 2011 - 2014 by Johns. All Rights Reserved.
+/// Copyright (c) 2011 - 2015 by Johns. All Rights Reserved.
///
/// Contributor(s):
///
@@ -34,7 +34,8 @@ extern "C"
/// C plugin close osd
extern void OsdClose(void);
/// C plugin draw osd pixmap
- extern void OsdDrawARGB(int, int, int, int, const uint8_t *);
+ extern void OsdDrawARGB(int, int, int, int, int, const uint8_t *, int,
+ int);
/// C plugin play audio packet
extern int PlayAudio(const uint8_t *, int, uint8_t);
diff --git a/softhddevice.cpp b/softhddevice.cpp
index e933955..7310a1f 100644
--- a/softhddevice.cpp
+++ b/softhddevice.cpp
@@ -1,7 +1,7 @@
///
/// @file softhddevice.cpp @brief A software HD device plugin for VDR.
///
-/// Copyright (c) 2011 - 2013 by Johns. All Rights Reserved.
+/// Copyright (c) 2011 - 2015 by Johns. All Rights Reserved.
///
/// Contributor(s):
///
@@ -431,6 +431,8 @@ void cSoftOsd::Flush(void)
// draw all bitmaps
for (i = 0; (bitmap = GetBitmap(i)); ++i) {
uint8_t *argb;
+ int xs;
+ int ys;
int x;
int y;
int w;
@@ -449,22 +451,52 @@ void cSoftOsd::Flush(void)
} else if (!bitmap->Dirty(x1, y1, x2, y2)) {
continue; // nothing dirty continue
}
- // convert and upload only dirty areas
+ // convert and upload only visible dirty areas
+ xs = bitmap->X0() + Left();
+ ys = bitmap->Y0() + Top();
+ // FIXME: negtative position bitmaps
w = x2 - x1 + 1;
h = y2 - y1 + 1;
+ // clip to screen
if (1) { // just for the case it makes trouble
int width;
int height;
double video_aspect;
+ if (xs < 0) {
+ if (xs + x1 < 0) {
+ x1 -= xs + x1;
+ w += xs + x1;
+ if (w <= 0) {
+ continue;
+ }
+ }
+ xs = 0;
+ }
+ if (ys < 0) {
+ if (ys + y1 < 0) {
+ y1 -= ys + y1;
+ h += ys + y1;
+ if (h <= 0) {
+ continue;
+ }
+ }
+ ys = 0;
+ }
::GetOsdSize(&width, &height, &video_aspect);
- if (w > width) {
- w = width;
- x2 = x1 + width - 1;
+ if (w > width - xs - x1) {
+ w = width - xs - x1;
+ if (w <= 0) {
+ continue;
+ }
+ x2 = x1 + w - 1;
}
- if (h > height) {
- h = height;
- y2 = y1 + height - 1;
+ if (h > height - ys - y1) {
+ h = height - ys - y1;
+ if (h <= 0) {
+ continue;
+ }
+ y2 = y1 + h - 1;
}
}
#ifdef DEBUG
@@ -482,10 +514,10 @@ void cSoftOsd::Flush(void)
}
#ifdef OSD_DEBUG
dsyslog("[softhddev]%s: draw %dx%d%+d%+d bm\n", __FUNCTION__, w, h,
- Left() + bitmap->X0() + x1, Top() + bitmap->Y0() + y1);
+ xs + x1, ys + y1);
#endif
- OsdDrawARGB(Left() + bitmap->X0() + x1, Top() + bitmap->Y0() + y1,
- w, h, argb);
+ OsdDrawARGB(0, 0, w, h, w * sizeof(uint32_t), argb, xs + x1,
+ ys + y1);
bitmap->Clean();
// FIXME: reuse argb
@@ -497,21 +529,76 @@ void cSoftOsd::Flush(void)
LOCK_PIXMAPS;
while ((pm = (dynamic_cast < cPixmapMemory * >(RenderPixmaps())))) {
+ int xp;
+ int yp;
+ int stride;
int x;
int y;
int w;
int h;
- x = Left() + pm->ViewPort().X();
- y = Top() + pm->ViewPort().Y();
+ x = pm->ViewPort().X();
+ y = pm->ViewPort().Y();
w = pm->ViewPort().Width();
h = pm->ViewPort().Height();
+ stride = w * sizeof(tColor);
+
+ // clip to osd
+ xp = 0;
+ if (x < 0) {
+ xp = -x;
+ w -= xp;
+ x = 0;
+ }
+
+ yp = 0;
+ if (y < 0) {
+ yp = -y;
+ h -= yp;
+ y = 0;
+ }
+
+ if (w > Width() - x) {
+ w = Width() - x;
+ }
+ if (h > Height() - y) {
+ h = Height() - y;
+ }
+ x += Left();
+ y += Top();
+
+ // clip to screen
+ if (1) { // just for the case it makes trouble
+ // and it can happen!
+ int width;
+ int height;
+ double video_aspect;
+
+ if (x < 0) {
+ w += x;
+ xp += -x;
+ x = 0;
+ }
+ if (y < 0) {
+ h += y;
+ yp += -y;
+ y = 0;
+ }
+
+ ::GetOsdSize(&width, &height, &video_aspect);
+ if (w > width - x) {
+ w = width - x;
+ }
+ if (h > height - y) {
+ h = height - y;
+ }
+ }
#ifdef OSD_DEBUG
- dsyslog("[softhddev]%s: draw %dx%d%+d%+d %p\n", __FUNCTION__, w, h, x,
- y, pm->Data());
+ dsyslog("[softhddev]%s: draw %dx%d%+d%+d*%d -> %+d%+d %p\n",
+ __FUNCTION__, w, h, xp, yp, stride, x, y, pm->Data());
#endif
- OsdDrawARGB(x, y, w, h, pm->Data());
+ OsdDrawARGB(xp, yp, w, h, stride, pm->Data(), x, y);
#if APIVERSNUM >= 20110
DestroyPixmap(pm);
diff --git a/video.c b/video.c
index 08d0bca..e0ef3d9 100644
--- a/video.c
+++ b/video.c
@@ -1,7 +1,7 @@
///
/// @file video.c @brief Video module
///
-/// Copyright (c) 2009 - 2014 by Johns. All Rights Reserved.
+/// Copyright (c) 2009 - 2015 by Johns. All Rights Reserved.
///
/// Contributor(s):
///
@@ -280,7 +280,8 @@ typedef struct _video_module_
void (*const OsdClear) (void); ///< clear OSD
/// draw OSD ARGB area
- void (*const OsdDrawARGB) (int, int, int, int, const uint8_t *);
+ void (*const OsdDrawARGB) (int, int, int, int, int, const uint8_t *, int,
+ int);
void (*const OsdInit) (int, int); ///< initialize OSD
void (*const OsdExit) (void); ///< cleanup OSD
@@ -887,17 +888,22 @@ static void GlxOsdExit(void)
///
/// Upload ARGB image to texture.
///
-/// @param x x coordinate of image in osd texture
-/// @param y y coordinate of image in osd texture
-/// @param width width of image
-/// @param height height of image
-/// @param argb argb image
+/// @param xi x-coordinate in argb image
+/// @param yi y-coordinate in argb image
+/// @paran height height in pixel in argb image
+/// @paran width width in pixel in argb image
+/// @param pitch pitch of argb image
+/// @param argb 32bit ARGB image data
+/// @param x x-coordinate on screen of argb image
+/// @param y y-coordinate on screen of argb image
///
/// @note looked by caller
///
-static void GlxOsdDrawARGB(int x, int y, int width, int height,
- const uint8_t * argb)
+static void GlxOsdDrawARGB(int xi, int yi, int width, int height, int pitch,
+ const uint8_t * argb, int x, int y)
{
+ uint8_t *tmp;
+
#ifdef DEBUG
uint32_t start;
uint32_t end;
@@ -918,9 +924,21 @@ static void GlxOsdDrawARGB(int x, int y, int width, int height,
Error(_("video/glx: can't make glx context current\n"));
return;
}
- GlxUploadOsdTexture(x, y, width, height, argb);
- glXMakeCurrent(XlibDisplay, None, NULL);
+ // FIXME: faster way
+ tmp = malloc(width * height * 4);
+ if (tmp) {
+ int i;
+ for (i = 0; i < height; ++i) {
+ memcpy(tmp + i * width * 4, argb + xi * 4 + (i + yi) * pitch,
+ width * 4);
+ }
+
+ GlxUploadOsdTexture(x, y, width, height, tmp);
+ glXMakeCurrent(XlibDisplay, None, NULL);
+
+ free(tmp);
+ }
#ifdef DEBUG
end = GetMsTicks();
@@ -1331,11 +1349,11 @@ static int AutoCropTolerance; ///< auto-crop tolerance
///
/// @param data Y plane pixel data
/// @param length number of pixel to check
-/// @param stride offset of pixels
+/// @param pitch offset of pixels
///
/// @note 8 pixel are checked at once, all values must be 8 aligned
///
-static int AutoCropIsBlackLineY(const uint8_t * data, int length, int stride)
+static int AutoCropIsBlackLineY(const uint8_t * data, int length, int pitch)
{
int n;
int o;
@@ -1343,13 +1361,13 @@ static int AutoCropIsBlackLineY(const uint8_t * data, int length, int stride)
const uint64_t *p;
#ifdef DEBUG
- if ((size_t) data & 0x7 || stride & 0x7) {
+ if ((size_t) data & 0x7 || pitch & 0x7) {
abort();
}
#endif
p = (const uint64_t *)data;
n = length; // FIXME: can remove n
- o = stride / 8;
+ o = pitch / 8;
r = 0UL;
while (--n >= 0) {
@@ -5438,16 +5456,19 @@ static void VaapiOsdClear(void)
///
/// Upload ARGB to subpicture image.
///
-/// @param x x position of image in osd
-/// @param y y position of image in osd
-/// @param width width of image
-/// @param height height of image
-/// @param argb argb image
+/// @param xi x-coordinate in argb image
+/// @param yi y-coordinate in argb image
+/// @paran height height in pixel in argb image
+/// @paran width width in pixel in argb image
+/// @param pitch pitch of argb image
+/// @param argb 32bit ARGB image data
+/// @param x x-coordinate on screen of argb image
+/// @param y y-coordinate on screen of argb image
///
/// @note looked by caller
///
-static void VaapiOsdDrawARGB(int x, int y, int width, int height,
- const uint8_t * argb)
+static void VaapiOsdDrawARGB(int xi, int yi, int width, int height, int pitch,
+ const uint8_t * argb, int x, int y)
{
#ifdef DEBUG
uint32_t start;
@@ -5474,7 +5495,7 @@ static void VaapiOsdDrawARGB(int x, int y, int width, int height,
// copy argb to image
for (o = 0; o < height; ++o) {
memcpy(image_buffer + (x + (y + o) * VaOsdImage.width) * 4,
- argb + o * width * 4, width * 4);
+ argb + xi * 4 + (o + yi) * pitch, width * 4);
}
if (vaUnmapBuffer(VaDisplay, VaOsdImage.buf) != VA_STATUS_SUCCESS) {
@@ -9240,16 +9261,19 @@ static void VdpauOsdClear(void)
///
/// Upload ARGB to subpicture image.
///
-/// @param x x position of image in osd
-/// @param y y position of image in osd
-/// @param width width of image
-/// @param height height of image
-/// @param argb argb image
+/// @param xi x-coordinate in argb image
+/// @param yi y-coordinate in argb image
+/// @paran height height in pixel in argb image
+/// @paran width width in pixel in argb image
+/// @param pitch pitch of argb image
+/// @param argb 32bit ARGB image data
+/// @param x x-coordinate on screen of argb image
+/// @param y y-coordinate on screen of argb image
///
/// @note looked by caller
///
-static void VdpauOsdDrawARGB(int x, int y, int width, int height,
- const uint8_t * argb)
+static void VdpauOsdDrawARGB(int xi, int yi, int width, int height, int pitch,
+ const uint8_t * argb, int x, int y)
{
VdpStatus status;
void const *data[1];
@@ -9283,8 +9307,8 @@ static void VdpauOsdDrawARGB(int x, int y, int width, int height,
dst_rect.y0 = y;
dst_rect.x1 = dst_rect.x0 + width;
dst_rect.y1 = dst_rect.y0 + height;
- data[0] = argb;
- pitches[0] = width * 4;
+ data[0] = argb + xi * 4 + yi * pitch;
+ pitches[0] = pitch;
#ifdef USE_BITMAP
status =
@@ -9499,20 +9523,26 @@ static void NoopOsdInit( __attribute__ ((unused))
///
/// Draw OSD ARGB image.
///
-/// @param x x position of image in osd
-/// @param y y position of image in osd
-/// @param width width of image
-/// @param height height of image
-/// @param argb argb image
+/// @param xi x-coordinate in argb image
+/// @param yi y-coordinate in argb image
+/// @paran height height in pixel in argb image
+/// @paran width width in pixel in argb image
+/// @param pitch pitch of argb image
+/// @param argb 32bit ARGB image data
+/// @param x x-coordinate on screen of argb image
+/// @param y y-coordinate on screen of argb image
///
/// @note looked by caller
///
static void NoopOsdDrawARGB( __attribute__ ((unused))
- int x, __attribute__ ((unused))
- int y, __attribute__ ((unused))
+ int xi, __attribute__ ((unused))
+ int yi, __attribute__ ((unused))
int width, __attribute__ ((unused))
int height, __attribute__ ((unused))
- const uint8_t * argb)
+ int pitch, __attribute__ ((unused))
+ const uint8_t * argb, __attribute__ ((unused))
+ int x, __attribute__ ((unused))
+ int y)
{
}
@@ -9631,14 +9661,17 @@ void VideoOsdClear(void)
///
/// Draw an OSD ARGB image.
///
-/// @param x x position of image in osd
-/// @param y y position of image in osd
-/// @param width width of image
-/// @param height height of image
-/// @param argb argb image
+/// @param xi x-coordinate in argb image
+/// @param yi y-coordinate in argb image
+/// @paran height height in pixel in argb image
+/// @paran width width in pixel in argb image
+/// @param pitch pitch of argb image
+/// @param argb 32bit ARGB image data
+/// @param x x-coordinate on screen of argb image
+/// @param y y-coordinate on screen of argb image
///
-void VideoOsdDrawARGB(int x, int y, int width, int height,
- const uint8_t * argb)
+void VideoOsdDrawARGB(int xi, int yi, int width, int height, int pitch,
+ const uint8_t * argb, int x, int y)
{
VideoThreadLock();
// update dirty area
@@ -9663,7 +9696,7 @@ void VideoOsdDrawARGB(int x, int y, int width, int height,
Debug(4, "video: osd dirty %dx%d%+d%+d -> %dx%d%+d%+d\n", width, height, x,
y, OsdDirtyWidth, OsdDirtyHeight, OsdDirtyX, OsdDirtyY);
- VideoUsedModule->OsdDrawARGB(x, y, width, height, argb);
+ VideoUsedModule->OsdDrawARGB(xi, yi, width, height, pitch, argb, x, y);
OsdShown = 1;
VideoThreadUnlock();
diff --git a/video.h b/video.h
index 0587393..baa16dc 100644
--- a/video.h
+++ b/video.h
@@ -1,7 +1,7 @@
///
/// @file video.h @brief Video module header file
///
-/// Copyright (c) 2009 - 2013 by Johns. All Rights Reserved.
+/// Copyright (c) 2009 - 2015 by Johns. All Rights Reserved.
///
/// Contributor(s):
///
@@ -168,7 +168,8 @@ extern void VideoSetAutoCrop(int, int, int);
extern void VideoOsdClear(void);
/// Draw an OSD ARGB image.
-extern void VideoOsdDrawARGB(int, int, int, int, const uint8_t *);
+extern void VideoOsdDrawARGB(int, int, int, int, int, const uint8_t *, int,
+ int);
/// Get OSD size.
extern void VideoGetOsdSize(int *, int *);