24#include <libavutil/imgutils.h>
25#include <libswscale/swscale.h>
30#include <drm_fourcc.h>
41#define TRANSPARENT 0x00
42#define UNMULTIPLY(color, alpha) ((0xff * color) / alpha)
43#define BLEND(back, front, alpha) ((front * alpha) + (back * (255 - alpha))) / 255
50 if (buf->
PixFmt() == DRM_FORMAT_NV12)
51 return AV_PIX_FMT_NV12;
53 if (buf->
PixFmt() == DRM_FORMAT_YUV420)
54 return AV_PIX_FMT_YUV420P;
56 if (buf->
PixFmt() == DRM_FORMAT_ARGB8888)
57 return AV_PIX_FMT_RGBA;
59 if (buf->
PixFmt() == DRM_FORMAT_P030)
60 return AV_PIX_FMT_NONE;
62 return AV_PIX_FMT_NONE;
78static uint8_t *
BufToRgb(
cDrmBuffer *buf,
int *size,
int dstW,
int dstH,
enum AVPixelFormat dstPixFmt)
80 uint8_t *srcData[4], *dstData[4];
81 int srcLinesize[4], dstLinesize[4];
83 int srcW = buf->
Width();
87 if (src_pix_fmt == AV_PIX_FMT_NONE) {
88 LOGERROR(
"grab: %s: pixel format is not supported!", __FUNCTION__);
93 struct SwsContext *swsCtx;
100 LOGERROR(
"grab: %s: prime data is not mapped!", __FUNCTION__);
105 swsCtx = sws_getContext(srcW, srcH, src_pix_fmt,
106 dstW, dstH, dstPixFmt,
107 SWS_BILINEAR, NULL, NULL, NULL);
109 LOGERROR(
"grab: %s: Could not create swsCtx", __FUNCTION__);
110 munmap(buffer, buf->
Size(0));
114 if ((ret = av_image_alloc(dstData, dstLinesize, dstW, dstH, dstPixFmt, 1)) < 0) {
115 LOGERROR(
"grab: %s: Could not alloc dst image", __FUNCTION__);
116 munmap(buffer, buf->
Size(0));
117 sws_freeContext(swsCtx);
123 for (
int i = 0; i < buf->
NumPlanes(); i++) {
124 srcLinesize[i] = buf->
Pitch(i);
130 (
const uint8_t *
const*)srcData, srcLinesize, 0, srcH,
131 dstData, dstLinesize);
134 munmap(buffer, buf->
Size(0));
135 sws_freeContext(swsCtx);
138 LOGDEBUG2(
L_GRAB,
"grab: %s: return image at %p size %d", __FUNCTION__, dstData[0], dstBufsize);
156static uint8_t *
ScaleRgb24(uint8_t *src,
int *size,
int srcW,
int srcH,
int dstW,
int dstH)
158 struct SwsContext *swsCtx;
164 uint8_t *srcData[4] = {src, NULL, NULL, NULL};
165 int srcLinesize[4] = {3 * srcW, 0, 0, 0};
167 swsCtx = sws_getContext(srcW, srcH, AV_PIX_FMT_RGB24,
168 dstW, dstH, AV_PIX_FMT_RGB24,
169 SWS_BILINEAR, NULL, NULL, NULL);
171 LOGERROR(
"grab: %s: Could not create swsCtx", __FUNCTION__);
175 if ((ret = av_image_alloc(dstData, dstLinesize, dstW, dstH, AV_PIX_FMT_RGB24, 1)) < 0) {
176 LOGERROR(
"grab: %s: Could not alloc dst image", __FUNCTION__);
177 sws_freeContext(swsCtx);
183 (
const uint8_t *
const*)srcData, srcLinesize, 0, srcH,
184 dstData, dstLinesize);
186 sws_freeContext(swsCtx);
189 LOGDEBUG2(
L_GRAB,
"grab: %s: return scaled image at %p size %d", __FUNCTION__, dstData[0], dstBufsize);
207static void AlphaBlend(uint8_t *result, uint8_t *front, uint8_t *back,
const unsigned int width,
const unsigned int height)
209 for (
unsigned long index = 0; index < width * height; index++) {
210 const uint8_t frontAlpha = front[3];
213 for (
int i = 0; i < 3; i++) {
222 if (frontAlpha ==
OPAQUE) {
223 for (
int i = 0; i < 3; i++) {
224 result[i] = front[i];
232 const uint8_t backR = back[0];
233 const uint8_t backG = back[1];
234 const uint8_t backB = back[2];
236 const uint8_t frontR =
UNMULTIPLY(front[0], frontAlpha);
237 const uint8_t frontG =
UNMULTIPLY(front[1], frontAlpha);
238 const uint8_t frontB =
UNMULTIPLY(front[2], frontAlpha);
240 const uint8_t R =
BLEND(backR, frontR, frontAlpha);
241 const uint8_t G =
BLEND(backG, frontG, frontAlpha);
242 const uint8_t B =
BLEND(backB, frontB, frontAlpha);
268static int BlitVideo(uint8_t *dst, uint8_t *src,
int dstW,
int dstH,
int dstX,
int dstY,
int srcW,
int srcH)
270 int srcStride = srcW * 3;
271 int dstStride = dstW * 3;
273 if ((dstX + srcW > dstW) || (dstY + srcH > dstH)) {
274 LOGDEBUG2(
L_GRAB,
"grab: %s: wrong dimensions, cropping not supported!", __FUNCTION__);
279 for (
int y = 0; y < srcH; y++) {
280 memcpy(&dst[((dstY + y) * dstStride + dstX * 3)], &src[y * srcStride], srcStride);
332bool cSoftHdGrab::Start(
bool jpeg,
int quality,
int width,
int height,
int screenWidth,
int screenHeight)
334 if (width == 0 || height == 0) {
335 LOGDEBUG2(
L_GRAB,
"grab: %s: width and/or height must not be 0!", __FUNCTION__);
339 LOGDEBUG2(
L_GRAB,
"grab: starting grab for %s image (%dx%d, quality %d)", jpeg ?
"jpg" :
"pnm", width, height, quality);
356 LOGDEBUG2(
L_GRAB,
"grab: grabbing %s image (%dx%d, quality %d) failed", jpeg ?
"jpg" :
"pnm", width, height, quality);
392 LOGFATAL(
"grab: %s no valid type, bug!", __FUNCTION__);
404 for (
int plane = 0; plane < buf->
NumPlanes(); plane++) {
405 LOGDEBUG2(
L_GRAB,
"grab: %s: %s plane %d address %p pitch %d offset %d handle %d size %d", __FUNCTION__,
431extern "C" uint8_t *
CreateJpeg(uint8_t * image,
int *size,
int quality,
432 int width,
int height)
434 return (uint8_t *) RgbToJpeg((uchar *) image, width, height, *size, quality);
457 int videoX = 0, videoY = 0;
462 int pipX = 0, pipY = 0;
468 LOGDEBUG2(
L_GRAB,
"grab: %s: no video data available, create black screen!", __FUNCTION__);
469 video = (uint8_t *)calloc(1, screenSize);
476 LOGDEBUG2(
L_GRAB,
"grab: %s: no pip data available, skip it", __FUNCTION__);
482 LOGDEBUG2(
L_GRAB,
"grab: %s: no osd data available, skip it", __FUNCTION__);
485 uint8_t *videoResult = video;
489 videoResult = (uint8_t *)calloc(1, screenSize);
513 uint8_t *result = videoResult;
515 result = (uint8_t *)malloc(screenSize);
522 uint8_t *scaledResult = result;
523 int scaledSize = screenSize;
cRect GetScreenRect(void)
uint32_t PrimeHandle(int idx)
cGrabBuffer - Grab buffer class
void SetData(uint8_t *result)
cRect m_rect
rect of the grabbed data
void FreeDrmBuf(void)
Free the grab buffer.
void SetDrmBuf(cDrmBuffer *)
Set the grab buffer and the dimensions how it is presented on the screen.
struct cDrmBuffer * m_pBuf
pointer to original buffer
cDrmBuffer * GetDrmBuf(void)
uint8_t * GetGrab(int *, int *, int *, int *, int *, Grabtype)
Convert the cloned drm buffer data to RGB(void, pip) or ARGB (osd) and returns a pointer to the raw d...
bool Start(bool, int, int, int, int, int)
Start a grab in the video renderer.
bool ProcessGrab(void)
Start the conversion.
cGrabBuffer * GetGrabbedPipBuffer(void)
cGrabBuffer * GetGrabbedVideoBuffer(void)
cGrabBuffer * GetGrabbedOsdBuffer(void)
int TriggerGrab(void)
Trigger a screen grab.
void ClearGrabBuffers(void)
Clear the grab drm buffers.
#define UNMULTIPLY(color, alpha)
#define BLEND(back, front, alpha)
static uint8_t * ScaleRgb24(uint8_t *src, int *size, int srcW, int srcH, int dstW, int dstH)
Scale an image.
static uint8_t * BufToRgb(cDrmBuffer *buf, int *size, int dstW, int dstH, enum AVPixelFormat dstPixFmt)
Convert a DRM buffer to rgb format image.
enum AVPixelFormat DrmFormatToAVFormat(cDrmBuffer *buf)
Convert a DRM format to a ffmpeg AV format.
static int BlitVideo(uint8_t *dst, uint8_t *src, int dstW, int dstH, int dstX, int dstY, int srcW, int srcH)
Blit the video on black background.
uint8_t * CreateJpeg(uint8_t *image, int *size, int quality, int width, int height)
Call rgb to jpeg for C Plugin.
static void AlphaBlend(uint8_t *result, uint8_t *front, uint8_t *back, const unsigned int width, const unsigned int height)
Blend two images.
const char * GrabtypeToString(Grabtype t)
Logger class header file.
#define LOGFATAL
Logger macros.
Rendering class header file.