vdr-plugin-softhddevice-drm-gles 1.7.3-98a2ef7
grab.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: AGPL-3.0-or-later AND BSD-3-Clause
2
3/*
4 * Portions of this file are derived from Raspberry Pi SAND conversion code:
5 *
6 * Copyright (c) 2018 Raspberry Pi (Trading) Ltd.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * * Neither the name of the copyright holder nor the
17 * names of its contributors may be used to endorse or promote products
18 * derived from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
24 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 *
31 * Authors: John Cox
32 */
33
50extern "C" {
51#include <libavutil/imgutils.h>
52#include <libswscale/swscale.h>
53}
54
55#include <sys/mman.h>
56
57#include <drm_fourcc.h>
58
59#include "drmbuffer.h"
60#include "grab.h"
61#include "logger.h"
62#include "videorender.h"
63
69/****************************************************************************************
70 * Image data conversion helpers
71 ***************************************************************************************/
72#define OPAQUE 0xff
73#define TRANSPARENT 0x00
74#define UNMULTIPLY(color, alpha) ((0xff * color) / alpha)
75#define BLEND(back, front, alpha) ((front * alpha) + (back * (255 - alpha))) / 255
76
77// --- Begin Raspberry Pi BSD-licensed code ---
78
82void Sand128ToPlanarY8(uint8_t *dst, const unsigned int dstStride, const uint8_t *src,
83 unsigned int stride1, unsigned int stride2,
84 unsigned int w, unsigned int h)
85{
86 const unsigned int mask = stride1 - 1;
87
88 if (w < stride1) {
89 // All in one sand stripe
90 const uint8_t *p = src;
91 for (unsigned int i = 0; i != h; ++i, dst += dstStride, p += stride1) {
92 memcpy(dst, p, w);
93 }
94 } else {
95 const unsigned int sstride = stride1 * stride2;
96 const uint8_t *p1 = src;
97 const uint8_t *p2 = p1 + sstride;
98 const unsigned int w1 = stride1;
99 const unsigned int w3 = w & mask;
100 const unsigned int w2 = w - (w1 + w3);
101
102 for (unsigned int i = 0; i != h; ++i, dst += dstStride, p1 += stride1, p2 += stride1) {
103 unsigned int j;
104 const uint8_t *p = p2;
105 uint8_t *d = dst;
106 memcpy(d, p1, w1);
107 d += w1;
108 for (j = 0; j < w2; j += stride1, d += stride1, p += sstride) {
109 memcpy(d, p, stride1);
110 }
111 memcpy(d, p, w3);
112 }
113 }
114}
115
119static void Sand30ToPlanarY16(uint8_t *dst, const unsigned int dstStride,
120 const uint8_t *src,
121 unsigned int stride1, unsigned int stride2,
122 unsigned int w, unsigned int h)
123{
124 const unsigned int x1 = (w / 3) * 4;
125 const unsigned int xrem1 = w - (x1 >> 2) * 3;
126 const unsigned int mask = stride1 - 1;
127
128 const uint8_t *p0 = src;
129 const unsigned int sliceInc = ((stride2 - 1) * stride1) >> 2;
130
131 if (x1 == 0)
132 return;
133
134 for (unsigned int i = 0; i != h; ++i, dst += dstStride, p0 += stride1) {
135 unsigned int x = 0;
136 const uint32_t *p = (const uint32_t *)p0;
137 uint16_t *d = (uint16_t *)dst;
138
139 while (x != x1) {
140 const uint32_t p3 = *p++;
141 *d++ = p3 & 0x3ff;
142 *d++ = (p3 >> 10) & 0x3ff;
143 *d++ = (p3 >> 20) & 0x3ff;
144
145 if (((x += 4) & mask) == 0)
146 p += sliceInc;
147 }
148
149 if (xrem1 != 0) {
150 const uint32_t p3 = *p;
151
152 *d++ = p3 & 0x3ff;
153 if (xrem1 == 2)
154 *d++ = (p3 >> 10) & 0x3ff;
155 }
156 }
157}
158
162static void Sand30ToPlanarC16(uint8_t *dstU, const unsigned int dstStrideU,
163 uint8_t *dstV, const unsigned int dstStrideV,
164 const uint8_t *src,
165 unsigned int stride1, unsigned int stride2,
166 unsigned int w, unsigned int h)
167{
168 const unsigned int x1 = (w / 3) * 8;
169 const unsigned int xrem1 = w - (x1 >> 3) * 3;
170 const unsigned int mask = stride1 - 1;
171
172 const uint8_t *p0 = src;
173 const unsigned int sliceInc = ((stride2 - 1) * stride1) >> 2;
174
175 if (x1 == 0)
176 return;
177
178 for (unsigned int i = 0; i != h; ++i, dstU += dstStrideU, dstV += dstStrideV, p0 += stride1) {
179 unsigned int x = 0;
180 const uint32_t *p = (const uint32_t *)p0;
181 uint16_t *du = (uint16_t *)dstU;
182 uint16_t *dv = (uint16_t *)dstV;
183
184 while (x != x1) {
185 const uint32_t p3a = *p++;
186 const uint32_t p3b = *p++;
187
188 *du++ = p3a & 0x3ff;
189 *dv++ = (p3a >> 10) & 0x3ff;
190 *du++ = (p3a >> 20) & 0x3ff;
191 *dv++ = p3b & 0x3ff;
192 *du++ = (p3b >> 10) & 0x3ff;
193 *dv++ = (p3b >> 20) & 0x3ff;
194
195 if (((x += 8) & mask) == 0)
196 p += sliceInc;
197 }
198
199 if (xrem1 != 0) {
200 const uint32_t p3a = *p++;
201 const uint32_t p3b = *p++;
202
203 *du++ = p3a & 0x3ff;
204 *dv++ = (p3a >> 10) & 0x3ff;
205 if (xrem1 == 2) {
206 *du++ = (p3a >> 20) & 0x3ff;
207 *dv++ = p3b & 0x3ff;
208 }
209 }
210 }
211}
212// --- End Raspberry Pi BSD-licensed code ---
213
218{
219 switch (pixFmt) {
220 case DRM_FORMAT_NV12:
221 return AV_PIX_FMT_NV12;
223 return AV_PIX_FMT_YUV420P;
225 return AV_PIX_FMT_RGBA;
226 case DRM_FORMAT_P030:
228 default:
229 return AV_PIX_FMT_NONE;
230 }
231
232 return AV_PIX_FMT_NONE;
233}
234
249static uint8_t *ScaleRgb24(uint8_t *src, int *size, int srcW, int srcH, int dstW, int dstH)
250{
251 struct SwsContext *swsCtx;
252 int dstBufsize = 0;
253 int ret;
254
255 uint8_t *dstData[4];
256 int dstLinesize[4];
257 uint8_t *srcData[4] = {src, NULL, NULL, NULL};
258 int srcLinesize[4] = {3 * srcW, 0, 0, 0};
259
263 if (!swsCtx) {
264 LOGERROR("%s: Could not create swsCtx", __FUNCTION__);
265 return NULL;
266 }
267
269 LOGERROR("%s: Could not alloc dst image", __FUNCTION__);
271 return NULL;
272 }
273 dstBufsize = ret;
274
276 (const uint8_t * const*)srcData, srcLinesize, 0, srcH,
278
280 *size = dstBufsize;
281
282 LOGDEBUG2(L_GRAB, "%s: return scaled image at %p size %d", __FUNCTION__, dstData[0], dstBufsize);
283 return dstData[0];
284}
285
300static void AlphaBlend(uint8_t *result, uint8_t *front, uint8_t *back, const unsigned int width, const unsigned int height)
301{
302 for (unsigned long index = 0; index < width * height; index++) {
303 const uint8_t frontAlpha = front[3];
304
305 if (frontAlpha == TRANSPARENT) {
306 for (int i = 0; i < 3; i++) {
307 result[i] = back[i];
308 }
309 back += 3;
310 front += 4;
311 result += 3;
312 continue;
313 }
314
315 if (frontAlpha == OPAQUE) {
316 for (int i = 0; i < 3; i++) {
317 result[i] = front[i];
318 }
319 back += 3;
320 front += 4;
321 result += 3;
322 continue;
323 }
324
325 const uint8_t backR = back[0];
326 const uint8_t backG = back[1];
327 const uint8_t backB = back[2];
328
332
336
337 result[0] = R;
338 result[1] = G;
339 result[2] = B;
340
341 back += 3;
342 front += 4;
343 result += 3;
344 }
345}
346
361static int BlitVideo(uint8_t *dst, uint8_t *src, int dstW, int dstH, int dstX, int dstY, int srcW, int srcH)
362{
363 int srcStride = srcW * 3;
364 int dstStride = dstW * 3;
365
366 if ((dstX + srcW > dstW) || (dstY + srcH > dstH)) {
367 LOGDEBUG2(L_GRAB, "%s: wrong dimensions, cropping not supported!", __FUNCTION__);
368 return -1;
369 }
370
371 // blit the (scaled) image into dst
372 for (int y = 0; y < srcH; y++) {
373 memcpy(&dst[((dstY + y) * dstStride + dstX * 3)], &src[y * srcStride], srcStride);
374 }
375
376 return 0;
377}
378
382extern "C" uint8_t * CreateJpeg(uint8_t * image, int *size, int quality,
383 int width, int height)
384{
385 return (uint8_t *) RgbToJpeg((uchar *) image, width, height, *size, quality);
386}
387
390/*****************************************************************************
391 * cGrabBuffer class
392 ****************************************************************************/
393
398{
399 // early return, because the grab buffer wasn't set
400 if (m_outputRect.IsEmpty())
401 return;
402
403 // free the allocated memory
404 for (int plane = 0; plane < m_numPlanes; plane++) {
405 if (m_size[plane]) {
406 LOGDEBUG2(L_GRAB, "%s: %s: free buf %p (plane %d)", m_identifier, __FUNCTION__, m_pPlane[plane], plane);
408 }
409 }
410
411 // reset member variables
412 m_width = 0;
413 m_height = 0;
414 m_pixFmt = 0;
415 m_modifier = 0;
416 m_numPlanes = 0;
417
418 for (int i = 0; i < 4; i++) {
419 m_offset[i] = 0;
420 m_pitch[i] = 0;
421 m_size[i] = 0;
422 m_pPlane[i] = nullptr;
423 }
424}
425
430{
431 FreeInput(); // input should already be freed and reset after ConvertToRgb
432
433 m_outputRect.Set(0, 0, 0, 0);
434 m_outputSize = 0;
435 m_pOutputData = nullptr; // result needs to be freed by the caller of GetGrabbedData()
436}
437
444{
445 if (src->GetScreenRect().IsEmpty())
446 return;
447
448 void *src_buffer = nullptr;
449 void *dst_buffer = nullptr;
450
451 // planes aren't mmapped, do it (PRIME)
452 if (!src->Plane(0)) {
453 for (int object = 0; object < src->NumObjects(); object++) {
454
455 // memcpy mmapped data
456 dst_buffer = malloc(src->Size(object));
457 if (!dst_buffer) {
458 LOGERROR("%s: %s: cannot allocate destination buffer (%d): %m", m_identifier, __FUNCTION__, errno);
459 // @todo handle possible leaks of previous objects
460 return;
461 }
462
463 src_buffer = mmap(NULL, src->Size(object), PROT_READ, MAP_SHARED, src->DmaBufHandle(object), 0);
464 if (src_buffer == MAP_FAILED) {
466 LOGERROR("%s: %s: cannot map buffer size %d prime_fd %d (%d): %m",
467 m_identifier, __FUNCTION__, src->Size(object), src->DmaBufHandle(object), errno);
468 // @todo handle possible leaks of previous objects
469 return;
470 }
471
472 memcpy(dst_buffer, src_buffer, src->Size(object));
473 munmap(src_buffer, src->Size(object));
474
475 for (int plane = 0; plane < src->NumPlanes(); plane++) {
476 if (src->ObjectIndex(plane) == object)
478 }
479 }
480 } else {
481 for (int plane = 0; plane < src->NumPlanes(); plane++) {
482 if (!src->Size(plane)) {
483 m_pPlane[plane] = m_pPlane[0];
484 continue;
485 }
486
487 dst_buffer = malloc(src->Size(plane));
488 if (!dst_buffer) {
489 LOGERROR("%s: %s: cannot allocate destination buffer (%d): %m", m_identifier, __FUNCTION__, errno);
490 return;
491 }
492 memcpy(dst_buffer, src->Plane(plane), src->Size(plane));
494 }
495 }
496
497 m_width = src->Width();
498 m_height = src->Height();
499 m_pixFmt = src->PixFmt();
500 m_modifier = src->Modifier();
501 m_numPlanes = src->NumPlanes();
502
503 for (int i = 0; i < src->NumPlanes(); i++) {
504 m_offset[i] = src->Offset(i);
505 m_pitch[i] = src->Pitch(i);
506 m_size[i] = src->Size(i);
507 }
508
509 m_outputRect.Set(src->GetScreenRect().Point(), src->GetScreenRect().Size());
510
511 LOGDEBUG2(L_GRAB, "%s: %s: Set input buffer: %dx%d pixFmt %d modifier %d num planes %d with %dx%d at %d|%d",
513 for (int plane = 0; plane < m_numPlanes; plane++) {
514 LOGDEBUG2(L_GRAB, "%s: %s: Copied plane %d address %p pitch %d offset %d size %d",
516 }
517}
518
529{
530 uint8_t *srcData[4] = {nullptr};
531 uint8_t *dstData[4] = {nullptr};;
532 int srcLinesize[4] = {0};
533 int dstLinesize[4] = {0};
534 int dstW = GetOutputWidth();
535 int dstH = GetOutputHeight();
537
538 int srcW = m_width;
539 int srcH = m_height;
540
542 if (srcPixFmt == AV_PIX_FMT_NONE) {
543 LOGERROR("%s: %s: pixel format is not supported!", m_identifier, __FUNCTION__);
544 return NULL;
545 }
546
547 int dstBufsize = 0;
548 struct SwsContext *swsCtx;
549 int ret;
550
551 // planes aren't mmapped, return
552 if (!m_pPlane[0]) {
553 LOGERROR("%s: %s: prime data is not mapped!", m_identifier, __FUNCTION__);
554 return NULL;
555 }
556
557 // convert yuv to rgb
561 if (!swsCtx) {
562 LOGERROR("%s: %s: Could not create swsCtx", m_identifier, __FUNCTION__);
563 return NULL;
564 }
565
567 LOGERROR("%s: %s: Could not alloc dst image", m_identifier, __FUNCTION__);
569 return NULL;
570 }
571 dstBufsize = ret;
572
573 // De-tile sand format
574 uint8_t *tmpData[4] = {0};
575 int tmpLinesize[4] = {0};
576 int tmpImgSize = 0;
578 if (m_pixFmt == DRM_FORMAT_NV12) {
579 int stride1 = 128;
580
582 if (tmpImgSize < 0) {
583 LOGERROR("%s: %s: Could not alloc tmp image", m_identifier, __FUNCTION__);
585 return NULL;
586 }
587
589 m_pPlane[0] + m_offset[0],
590 stride1, m_pitch[0],
591 srcW, srcH);
593 m_pPlane[1] + m_offset[1],
594 stride1, m_pitch[1],
595 srcW, srcH / 2);
596
597 srcData[0] = tmpData[0];
598 srcData[1] = tmpData[1];
599 srcLinesize[0] = tmpLinesize[0];
600 srcLinesize[1] = tmpLinesize[1];
601 } else if (m_pixFmt == DRM_FORMAT_P030) {
602 int stride1 = 128;
603
605 if (tmpImgSize < 0) {
606 LOGERROR("%s: %s: Could not alloc tmp image", m_identifier, __FUNCTION__);
608 return NULL;
609 }
610
612 m_pPlane[0] + m_offset[0],
613 stride1, m_pitch[0],
614 srcW, srcH);
616 tmpData[2], tmpLinesize[2],
617 m_pPlane[1] + m_offset[1],
618 stride1, m_pitch[1],
619 srcW / 2, srcH / 2);
620
621 srcData[0] = tmpData[0];
622 srcData[1] = tmpData[1];
623 srcData[2] = tmpData[2];
624 srcLinesize[0] = tmpLinesize[0];
625 srcLinesize[1] = tmpLinesize[1];
626 srcLinesize[2] = tmpLinesize[2];
627 }
628 } else {
629 // copy src pitches and data
630 for (int i = 0; i < m_numPlanes; i++) {
632 srcData[i] = m_pPlane[i] + m_offset[i];
633 }
634 }
635
636 // scale image
638
640 *size = dstBufsize;
641
642 if (tmpImgSize > 0)
643 av_freep(&tmpData[0]);
644
645 LOGDEBUG2(L_GRAB, "%s: %s: return image at %p size %d", m_identifier, __FUNCTION__, dstData[0], dstBufsize);
646
647 return dstData[0];
648}
649
650
651
652/*****************************************************************************
653 * cSoftHdGrab class
654 ****************************************************************************/
655
666bool cSoftHdGrab::Start(bool jpeg, int quality, int width, int height, int screenWidth, int screenHeight)
667{
668 m_active = true;
669
670 LOGDEBUG2(L_GRAB, "Starting grab for %s image (%dx%d, quality %d)", jpeg ? "jpg" : "pnm", width, height, quality);
671
672 // always clear the buffers in case sth. unexpected happend
674
675 m_isJpeg = jpeg;
678
679 // Set defaults
680 m_quality = quality < 0 ? 95 : quality;
681 m_grabbedWidth = width > 0 ? width : screenWidth;
682 m_grabbedHeight = height > 0 ? height : screenHeight;
683 m_grabbedImage = nullptr;
684
685 if (m_pRender->TriggerGrab()) {
686 Finish();
687 LOGDEBUG2(L_GRAB, "Grabbing %s image (%dx%d, quality %d) failed", jpeg ? "jpg" : "pnm", width, height, quality);
688 return false;
689 }
690
691 return true;
692}
693
701{
703 m_active = false;
704}
705
706uint8_t *cSoftHdGrab::GetGrabbedVideoData(int *size, int *width, int *height, int *x, int *y)
707{
709 return GetGrabbedData(size, width, height, x, y, grab);
710}
711
712uint8_t *cSoftHdGrab::GetGrabbedPipData(int *size, int *width, int *height, int *x, int *y)
713{
715 return GetGrabbedData(size, width, height, x, y, grab);
716}
717
718uint8_t *cSoftHdGrab::GetGrabbedOsdData(int *size, int *width, int *height, int *x, int *y)
719{
721 return GetGrabbedData(size, width, height, x, y, grab);
722}
723
724
738uint8_t *cSoftHdGrab::GetGrabbedData(int *size, int *width, int *height, int *x, int *y, cGrabBuffer *grab)
739{
740 int psize = 0;
741
742 // early return if no grab buffer is set
743 if (!grab->IsSet()) {
744 grab->SetOutputData(NULL);
745 grab->SetOutputSize(0);
746 return nullptr;
747 }
748
749 // result's width and height are original dimensions how buffer is presented on the screen
750 uint8_t *result = grab->ConvertToRgb(&psize);
751 grab->FreeInput();
752
753 grab->SetOutputData(result);
754 grab->SetOutputSize(psize);
755
756 if (size)
757 *size = grab->GetOutputSize();
758 if (width)
759 *width = grab->GetOutputWidth();
760 if (height)
761 *height = grab->GetOutputHeight();
762 if (x)
763 *x = grab->GetOutputX();
764 if (y)
765 *y = grab->GetOutputY();
766
767 return grab->GetOutputData();
768}
769
786{
787 int screenSize = m_screenWidth * m_screenHeight * 3; // we want a RGB24
788
789 int videoSize = 0; // data size of the grabbed video
790 int videoWidth = m_screenWidth; // width of the grabbed video
791 int videoHeight = m_screenHeight; // height of the grabbed video
792 int videoX = 0, videoY = 0; // x, y of the grabbed video
793
794 int pipSize = 0; // data size of the grabbed pip video
795 int pipWidth = m_screenWidth; // width of the grabbed pip video
796 int pipHeight = m_screenHeight; // height of the grabbed pip video
797 int pipX = 0, pipY = 0; // x, y of the grabbed pip video
798
799 // fetch video data
800 // Video comes as RGB, width and height is original screen dimension (video is maybe scaled)
802 if (!video) {
803 LOGDEBUG2(L_GRAB, "%s: no video data available, create black screen!", __FUNCTION__);
804 video = (uint8_t *)calloc(1, screenSize);
805 }
806
807 // fetch pip data
808 // Pip video comes as RGB, width and height is original screen dimension (video is maybe scaled)
810 if (!pip)
811 LOGDEBUG2(L_GRAB, "%s: no pip data available, skip it", __FUNCTION__);
812
813 // fetch osd data
814 // OSD comes as ARGB, width and height is original screen dimension (osd is always fullscreen)
816 if (!osd)
817 LOGDEBUG2(L_GRAB, "%s: no osd data available, skip it", __FUNCTION__);
818
819 // blit the video into a full black screen if scaled
820 uint8_t *videoResult = video;
821
823 if (needsScaling) {
827 free(video);
828 Finish();
829 LOGDEBUG2(L_GRAB, "grab failed during VIDEO blit");
830 return false;
831 }
832 free(video);
833 }
834
835 // blit the pip video into the main video if available
836 if (pip) {
839 free(pip);
840 Finish();
841 LOGDEBUG2(L_GRAB, "grab failed during PIP blit");
842 return false;
843 }
844 free(pip);
845 }
846
847 // alphablend fullscreen video/pip with osd if available
849 if (osd) {
853 free(osd);
854 }
855
856 // scale result to requested size width + height, if it differs from fullscreen
859
861 if (needsScaling) {
863 free(result);
864 }
865
866 // make jpeg or pnm
867 if (m_isJpeg) {
869 } else { // add header to raw data
870 char buf[64];
871 int n = snprintf(buf, sizeof(buf), "P6\n%d\n%d\n255\n", m_grabbedWidth, m_grabbedHeight);
876 }
877
879 LOGDEBUG2(L_GRAB, "Finished %s image (%dx%d, quality %d) at %p (size %d)", m_isJpeg ? "jpg" : "pnm", m_grabbedWidth, m_grabbedHeight, m_isJpeg ? m_quality : 0, m_grabbedImage, m_grabbedSize);
880
881 return true;
882}
DRM Buffer.
Definition drmbuffer.h:33
Grabbing Buffer.
Definition grab.h:32
int m_outputSize
size of grabbed data
Definition grab.h:55
int GetOutputWidth(void)
Definition grab.h:49
const char * m_identifier
Definition grab.h:69
int m_numPlanes
Definition grab.h:63
uint32_t m_width
Definition grab.h:59
uint32_t m_pitch[4]
Definition grab.h:66
uint32_t m_offset[4]
Definition grab.h:65
void Clear(void)
Clear the grab buffer (input and output data)
Definition grab.cpp:429
uint8_t * m_pOutputData
pointer to grabbed image
Definition grab.h:54
void Set(cDrmBuffer *)
Set the grab buffer and the dimensions how it is presented on the screen.
Definition grab.cpp:443
uint64_t m_modifier
Definition grab.h:62
void FreeInput(void)
Free the grab input buffer.
Definition grab.cpp:397
cRect m_outputRect
rect of the grabbed data
Definition grab.h:56
uint32_t m_pixFmt
Definition grab.h:61
uint32_t m_size[4]
Definition grab.h:67
uint8_t * m_pPlane[4]
Definition grab.h:64
uint8_t * ConvertToRgb(int *)
Convert a grabbed buffer to rgb format image.
Definition grab.cpp:528
uint32_t m_height
Definition grab.h:60
int GetOutputHeight(void)
Definition grab.h:50
int m_screenWidth
pixel screenwidth
Definition grab.h:100
uint8_t * GetGrabbedOsdData(int *, int *, int *, int *, int *)
Definition grab.cpp:718
int m_quality
quality of the jpeg image
Definition grab.h:97
uint8_t * m_grabbedImage
pointer to the finished grabbed image
Definition grab.h:92
std::atomic< bool > m_active
true, if a grab process is currently running
Definition grab.h:94
int m_grabbedWidth
pixel width of the grabbed image
Definition grab.h:98
int m_screenHeight
pixel screenheight
Definition grab.h:101
uint8_t * GetGrabbedData(int *, int *, int *, int *, int *, cGrabBuffer *)
Convert the cloned drm buffer data to RGB(void, pip) or ARGB (osd) and return a pointer to the raw da...
Definition grab.cpp:738
bool Start(bool, int, int, int, int, int)
Start a grab in the video renderer.
Definition grab.cpp:666
uint8_t * GetGrabbedVideoData(int *, int *, int *, int *, int *)
Definition grab.cpp:706
uint8_t * GetGrabbedPipData(int *, int *, int *, int *, int *)
Definition grab.cpp:712
int m_grabbedSize
data size of the grabbed image
Definition grab.h:93
bool m_isJpeg
true, if a jpeg image was requested
Definition grab.h:96
bool ProcessGrab(void)
Start the conversion.
Definition grab.cpp:785
int m_grabbedHeight
pixel height of the grabbed image
Definition grab.h:99
cVideoRender * m_pRender
pointer to cVideoRender object
Definition grab.h:91
void Finish(void)
Clean up.
Definition grab.cpp:700
cGrabBuffer * GetGrabbedPipBuffer(void)
cGrabBuffer * GetGrabbedVideoBuffer(void)
cGrabBuffer * GetGrabbedOsdBuffer(void)
int TriggerGrab(void)
Trigger a screen grab.
void ClearGrabBuffers(void)
Clear the grab drm buffers.
DRM Buffer Header File.
int plane
Grabbing Interface Header File.
#define UNMULTIPLY(color, alpha)
Definition grab.cpp:74
#define LOGDEBUG2
log to LOG_DEBUG and add a prefix
Definition logger.h:48
static void Sand30ToPlanarC16(uint8_t *dstU, const unsigned int dstStrideU, uint8_t *dstV, const unsigned int dstStrideV, const uint8_t *src, unsigned int stride1, unsigned int stride2, unsigned int w, unsigned int h)
Convert the chroma (UV plane) from SAND to linear buffer (10bit)
Definition grab.cpp:162
#define BLEND(back, front, alpha)
Definition grab.cpp:75
#define LOGERROR
log to LOG_ERR
Definition logger.h:40
static uint8_t * ScaleRgb24(uint8_t *src, int *size, int srcW, int srcH, int dstW, int dstH)
Scale an image.
Definition grab.cpp:249
void Sand128ToPlanarY8(uint8_t *dst, const unsigned int dstStride, const uint8_t *src, unsigned int stride1, unsigned int stride2, unsigned int w, unsigned int h)
Convert the luma (Y plane) from SAND to linear buffer (8bit)
Definition grab.cpp:82
#define TRANSPARENT
Definition grab.cpp:73
static void Sand30ToPlanarY16(uint8_t *dst, const unsigned int dstStride, const uint8_t *src, unsigned int stride1, unsigned int stride2, unsigned int w, unsigned int h)
Convert the luma (Y plane) from SAND to linear buffer (10bit)
Definition grab.cpp:119
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.
Definition grab.cpp:361
uint8_t * CreateJpeg(uint8_t *image, int *size, int quality, int width, int height)
Call rgb to jpeg for C Plugin.
Definition grab.cpp:382
#define OPAQUE
Definition grab.cpp:72
enum AVPixelFormat DrmFormatToAVFormat(uint32_t pixFmt)
Convert a DRM format to a ffmpeg AV format.
Definition grab.cpp:217
static void AlphaBlend(uint8_t *result, uint8_t *front, uint8_t *back, const unsigned int width, const unsigned int height)
Blend two images.
Definition grab.cpp:300
@ L_GRAB
grabbing logs
Definition logger.h:73
Logger Header File.
Video Renderer (Display) Header File.