vdr-plugin-softhddevice-drm-gles 1.6.7
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 dst_buffer = malloc(src->Size(plane));
483 if (!dst_buffer) {
484 LOGERROR("%s: %s: cannot allocate destination buffer (%d): %m", m_identifier, __FUNCTION__, errno);
485 return;
486 }
487 memcpy(dst_buffer, src->Plane(plane), src->Size(plane));
489 }
490 }
491
492 m_width = src->Width();
493 m_height = src->Height();
494 m_pixFmt = src->PixFmt();
495 m_modifier = src->Modifier();
496 m_numPlanes = src->NumPlanes();
497
498 for (int i = 0; i < src->NumPlanes(); i++) {
499 m_offset[i] = src->Offset(i);
500 m_pitch[i] = src->Pitch(i);
501 m_size[i] = src->Size(i);
502 }
503
504 m_outputRect.Set(src->GetScreenRect().Point(), src->GetScreenRect().Size());
505
506 LOGDEBUG2(L_GRAB, "%s: %s: Set input buffer: %dx%d pixFmt %d modifier %d num planes %d with %dx%d at %d|%d",
508 for (int plane = 0; plane < m_numPlanes; plane++) {
509 LOGDEBUG2(L_GRAB, "%s: %s: Copied plane %d address %p pitch %d offset %d size %d",
511 }
512}
513
524{
525 uint8_t *srcData[4] = {nullptr};
526 uint8_t *dstData[4] = {nullptr};;
527 int srcLinesize[4] = {0};
528 int dstLinesize[4] = {0};
529 int dstW = GetOutputWidth();
530 int dstH = GetOutputHeight();
532
533 int srcW = m_width;
534 int srcH = m_height;
535
537 if (srcPixFmt == AV_PIX_FMT_NONE) {
538 LOGERROR("%s: %s: pixel format is not supported!", m_identifier, __FUNCTION__);
539 return NULL;
540 }
541
542 int dstBufsize = 0;
543 struct SwsContext *swsCtx;
544 int ret;
545
546 // planes aren't mmapped, return
547 if (!m_pPlane[0]) {
548 LOGERROR("%s: %s: prime data is not mapped!", m_identifier, __FUNCTION__);
549 return NULL;
550 }
551
552 // convert yuv to rgb
556 if (!swsCtx) {
557 LOGERROR("%s: %s: Could not create swsCtx", m_identifier, __FUNCTION__);
558 return NULL;
559 }
560
562 LOGERROR("%s: %s: Could not alloc dst image", m_identifier, __FUNCTION__);
564 return NULL;
565 }
566 dstBufsize = ret;
567
568 // De-tile sand format
569 uint8_t *tmpData[4] = {0};
570 int tmpLinesize[4] = {0};
571 int tmpImgSize = 0;
573 if (m_pixFmt == DRM_FORMAT_NV12) {
574 int stride1 = 128;
575
577 if (tmpImgSize < 0) {
578 LOGERROR("%s: %s: Could not alloc tmp image", m_identifier, __FUNCTION__);
580 return NULL;
581 }
582
584 m_pPlane[0] + m_offset[0],
585 stride1, m_pitch[0],
586 srcW, srcH);
588 m_pPlane[1] + m_offset[1],
589 stride1, m_pitch[1],
590 srcW, srcH / 2);
591
592 srcData[0] = tmpData[0];
593 srcData[1] = tmpData[1];
594 srcLinesize[0] = tmpLinesize[0];
595 srcLinesize[1] = tmpLinesize[1];
596 } else if (m_pixFmt == DRM_FORMAT_P030) {
597 int stride1 = 128;
598
600 if (tmpImgSize < 0) {
601 LOGERROR("%s: %s: Could not alloc tmp image", m_identifier, __FUNCTION__);
603 return NULL;
604 }
605
607 m_pPlane[0] + m_offset[0],
608 stride1, m_pitch[0],
609 srcW, srcH);
611 tmpData[2], tmpLinesize[2],
612 m_pPlane[1] + m_offset[1],
613 stride1, m_pitch[1],
614 srcW / 2, srcH / 2);
615
616 srcData[0] = tmpData[0];
617 srcData[1] = tmpData[1];
618 srcData[2] = tmpData[2];
619 srcLinesize[0] = tmpLinesize[0];
620 srcLinesize[1] = tmpLinesize[1];
621 srcLinesize[2] = tmpLinesize[2];
622 }
623 } else {
624 // copy src pitches and data
625 for (int i = 0; i < m_numPlanes; i++) {
627 srcData[i] = m_pPlane[i] + m_offset[i];
628 }
629 }
630
631 // scale image
633
635 *size = dstBufsize;
636
637 if (tmpImgSize > 0)
638 av_freep(&tmpData[0]);
639
640 LOGDEBUG2(L_GRAB, "%s: %s: return image at %p size %d", m_identifier, __FUNCTION__, dstData[0], dstBufsize);
641
642 return dstData[0];
643}
644
645
646
647/*****************************************************************************
648 * cSoftHdGrab class
649 ****************************************************************************/
650
661bool cSoftHdGrab::Start(bool jpeg, int quality, int width, int height, int screenWidth, int screenHeight)
662{
663 m_active = true;
664
665 LOGDEBUG2(L_GRAB, "Starting grab for %s image (%dx%d, quality %d)", jpeg ? "jpg" : "pnm", width, height, quality);
666
667 // always clear the buffers in case sth. unexpected happend
669
670 m_isJpeg = jpeg;
673
674 // Set defaults
675 m_quality = quality < 0 ? 95 : quality;
676 m_grabbedWidth = width > 0 ? width : screenWidth;
677 m_grabbedHeight = height > 0 ? height : screenHeight;
678 m_grabbedImage = nullptr;
679
680 if (m_pRender->TriggerGrab()) {
681 Finish();
682 LOGDEBUG2(L_GRAB, "Grabbing %s image (%dx%d, quality %d) failed", jpeg ? "jpg" : "pnm", width, height, quality);
683 return false;
684 }
685
686 return true;
687}
688
696{
698 m_active = false;
699}
700
701uint8_t *cSoftHdGrab::GetGrabbedVideoData(int *size, int *width, int *height, int *x, int *y)
702{
704 return GetGrabbedData(size, width, height, x, y, grab);
705}
706
707uint8_t *cSoftHdGrab::GetGrabbedPipData(int *size, int *width, int *height, int *x, int *y)
708{
710 return GetGrabbedData(size, width, height, x, y, grab);
711}
712
713uint8_t *cSoftHdGrab::GetGrabbedOsdData(int *size, int *width, int *height, int *x, int *y)
714{
716 return GetGrabbedData(size, width, height, x, y, grab);
717}
718
719
733uint8_t *cSoftHdGrab::GetGrabbedData(int *size, int *width, int *height, int *x, int *y, cGrabBuffer *grab)
734{
735 int psize = 0;
736
737 // early return if no grab buffer is set
738 if (!grab->IsSet()) {
739 grab->SetOutputData(NULL);
740 grab->SetOutputSize(0);
741 return nullptr;
742 }
743
744 // result's width and height are original dimensions how buffer is presented on the screen
745 uint8_t *result = grab->ConvertToRgb(&psize);
746 grab->FreeInput();
747
748 grab->SetOutputData(result);
749 grab->SetOutputSize(psize);
750
751 if (size)
752 *size = grab->GetOutputSize();
753 if (width)
754 *width = grab->GetOutputWidth();
755 if (height)
756 *height = grab->GetOutputHeight();
757 if (x)
758 *x = grab->GetOutputX();
759 if (y)
760 *y = grab->GetOutputY();
761
762 return grab->GetOutputData();
763}
764
781{
782 int screenSize = m_screenWidth * m_screenHeight * 3; // we want a RGB24
783
784 int videoSize = 0; // data size of the grabbed video
785 int videoWidth = m_screenWidth; // width of the grabbed video
786 int videoHeight = m_screenHeight; // height of the grabbed video
787 int videoX = 0, videoY = 0; // x, y of the grabbed video
788
789 int pipSize = 0; // data size of the grabbed pip video
790 int pipWidth = m_screenWidth; // width of the grabbed pip video
791 int pipHeight = m_screenHeight; // height of the grabbed pip video
792 int pipX = 0, pipY = 0; // x, y of the grabbed pip video
793
794 // fetch video data
795 // Video comes as RGB, width and height is original screen dimension (video is maybe scaled)
797 if (!video) {
798 LOGDEBUG2(L_GRAB, "%s: no video data available, create black screen!", __FUNCTION__);
799 video = (uint8_t *)calloc(1, screenSize);
800 }
801
802 // fetch pip data
803 // Pip video comes as RGB, width and height is original screen dimension (video is maybe scaled)
805 if (!pip)
806 LOGDEBUG2(L_GRAB, "%s: no pip data available, skip it", __FUNCTION__);
807
808 // fetch osd data
809 // OSD comes as ARGB, width and height is original screen dimension (osd is always fullscreen)
811 if (!osd)
812 LOGDEBUG2(L_GRAB, "%s: no osd data available, skip it", __FUNCTION__);
813
814 // blit the video into a full black screen if scaled
815 uint8_t *videoResult = video;
816
818 if (needsScaling) {
822 free(video);
823 Finish();
824 LOGDEBUG2(L_GRAB, "grab failed during VIDEO blit");
825 return false;
826 }
827 free(video);
828 }
829
830 // blit the pip video into the main video if available
831 if (pip) {
834 free(pip);
835 Finish();
836 LOGDEBUG2(L_GRAB, "grab failed during PIP blit");
837 return false;
838 }
839 free(pip);
840 }
841
842 // alphablend fullscreen video/pip with osd if available
844 if (osd) {
848 free(osd);
849 }
850
851 // scale result to requested size width + height, if it differs from fullscreen
854
856 if (needsScaling) {
858 free(result);
859 }
860
861 // make jpeg or pnm
862 if (m_isJpeg) {
864 } else { // add header to raw data
865 char buf[64];
866 int n = snprintf(buf, sizeof(buf), "P6\n%d\n%d\n255\n", m_grabbedWidth, m_grabbedHeight);
871 }
872
874 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);
875
876 return true;
877}
DRM Buffer.
Definition drmbuffer.h:48
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:523
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:713
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:733
bool Start(bool, int, int, int, int, int)
Start a grab in the video renderer.
Definition grab.cpp:661
uint8_t * GetGrabbedVideoData(int *, int *, int *, int *, int *)
Definition grab.cpp:701
uint8_t * GetGrabbedPipData(int *, int *, int *, int *, int *)
Definition grab.cpp:707
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:780
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:695
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:47
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:39
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:69
Logger Header File.
Video Renderer (Display) Header File.