diff options
author | Maniac <na@na.na> | 2015-07-03 22:29:41 +0200 |
---|---|---|
committer | Maniac <na@na.na> | 2015-07-03 22:29:41 +0200 |
commit | da407909879f82c15f786bda3fedda0cae892100 (patch) | |
tree | 143c2b842028c38e8f7facfe576567039459afd9 /osd.c | |
download | vdr-plugin-mpv-da407909879f82c15f786bda3fedda0cae892100.tar.gz vdr-plugin-mpv-da407909879f82c15f786bda3fedda0cae892100.tar.bz2 |
import 0.0.40.0.4
Diffstat (limited to 'osd.c')
-rw-r--r-- | osd.c | 182 |
1 files changed, 182 insertions, 0 deletions
@@ -0,0 +1,182 @@ +////////////////////////////////////////////////////////////////////////////// +/// /// +/// This file is part of the VDR mpv plugin and licensed under AGPLv3 /// +/// /// +/// See the README file for copyright information /// +/// /// +////////////////////////////////////////////////////////////////////////////// + +#include <sys/mman.h> + +#include "osd.h" + +cMpvOsdProvider::cMpvOsdProvider(cMpvPlayer *player) +{ + Player = player; +} + +cOsd *cMpvOsdProvider::CreateOsd(int Left, int Top, uint Level) +{ + return new cMpvOsd(Left, Top, Level, Player); +} + +bool cMpvOsdProvider::ProvidesTrueColor() +{ + return true; +} + +cMpvOsd::cMpvOsd(int Left, int Top, uint Level, cMpvPlayer *player) +:cOsd(Left, Top, Level) +{ + Player = player; + + int OsdAreaWidth = OsdWidth() + cOsd::Left(); + int OsdAreaHeight = OsdHeight() + cOsd::Top(); + fdOsd = open ("/tmp/vdr_mpv_osd", O_CREAT | O_RDWR, S_IWUSR | S_IRUSR); + lseek(fdOsd, OsdAreaWidth*OsdAreaHeight*4, SEEK_SET); + write(fdOsd, "", 1); + pOsd = (char*) mmap (NULL, OsdAreaWidth*OsdAreaHeight*4, PROT_WRITE, MAP_SHARED, fdOsd, 0); + + SetActive(true); +} + +cMpvOsd::~cMpvOsd() +{ + dsyslog("[mpv] %s\n", __FUNCTION__); + SetActive(false); + + if (cMpvPlayer::PlayerIsRunning()) + Player->OsdClose(); + + munmap(pOsd, sizeof(pOsd)); + close(fdOsd); + remove("/tmp/vdr_mpv_osd"); +} + +void cMpvOsd::SetActive(bool On) +{ + if (On == Active()) + { + return; + } + cOsd::SetActive(On); + + if (!On) + { + if (cMpvPlayer::PlayerIsRunning()) + Player->OsdClose(); + cOsd::SetActive(false); + } +} + +void cMpvOsd::WriteToMpv(int sw, int sh, int x, int y, int w, int h, const uint8_t * argb) +{ + if (!cMpvPlayer::PlayerIsRunning()) + return; + int sx; + int sy; + int pos; + char cmd[64]; + + for (sy = 0; sy < h; ++sy) { + for (sx = 0; sx < w; ++sx) { + pos=0; + pos = pos + ((sy+y)*sw*4); + pos = pos + ((sx+x)*4); + pOsd[pos + 0] = argb[(w * sy + sx) * 4 + 0]; + pOsd[pos + 1] = argb[(w * sy + sx) * 4 + 1]; + pOsd[pos + 2] = argb[(w * sy + sx) * 4 + 2]; + pOsd[pos + 3] = argb[(w * sy + sx) * 4 + 3]; + } + } + snprintf (cmd, sizeof(cmd), "overlay_add 1 0 0 @%d 0 \"bgra\" %d %d %d\n", fdOsd, sw, sh, sw*4); + Player->SendCommand (cmd); +} + +void cMpvOsd::Flush() +{ + cPixmapMemory *pm; + if (!cMpvPlayer::PlayerIsRunning()) + cOsd::SetActive(false); + if (!Active()) + return; + + int OsdAreaWidth = Width() + Left(); + int OsdAreaHeight = Height()+ Top(); + + if (IsTrueColor()) + { + LOCK_PIXMAPS; + while ((pm = dynamic_cast<cPixmapMemory *>(RenderPixmaps()))) + { + int x; + int y; + int w; + int h; + + x = Left() + pm->ViewPort().X(); + y = Top() + pm->ViewPort().Y(); + w = pm->ViewPort().Width(); + h = pm->ViewPort().Height(); + + WriteToMpv(OsdAreaWidth, OsdAreaHeight, x, y, w, h, pm->Data()); + + DestroyPixmap(pm); + } + } + else + { + cBitmap *bitmap; + int i; + + // draw all bitmaps + for (i = 0; (bitmap = GetBitmap(i)); ++i) + { + uint8_t *argb; + int x; + int y; + int w; + int h; + int x1; + int y1; + int x2; + int y2; + + if (!bitmap->Dirty(x1, y1, x2, y2)) + { + continue; // nothing dirty continue + } + // convert and upload only dirty areas + w = x2 - x1 + 1; + h = y2 - y1 + 1; + if (1) // just for the case it makes trouble + { + if (w > OsdAreaWidth) + { + w = OsdAreaWidth; + x2 = x1 + OsdAreaWidth - 1; + } + if (h > OsdAreaHeight) + { + h = OsdAreaHeight; + y2 = y1 + OsdAreaHeight - 1; + } + } + argb = (uint8_t *) malloc(w * h * sizeof(uint32_t)); + for (y = y1; y <= y2; ++y) + { + for (x = x1; x <= x2; ++x) + { + ((uint32_t *) argb)[x - x1 + (y - y1) * w] = + bitmap->GetColor(x, y); + } + } + WriteToMpv(OsdAreaWidth, OsdAreaHeight, Left() + bitmap->X0() + x1, Top() + bitmap->Y0() + y1, w, h, argb); + + bitmap->Clean(); + // FIXME: reuse argb + free(argb); + } + } +} + |