VirtualBox

source: vbox/trunk/src/VBox/Main/src-client/VideoRecUtils.cpp@ 75267

Last change on this file since 75267 was 74999, checked in by vboxsync, 6 years ago

VideoRec/Main: SCM fixes.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.5 KB
Line 
1/* $Id: VideoRecUtils.cpp 74999 2018-10-23 13:50:28Z vboxsync $ */
2/** @file
3 * Video recording utility code.
4 */
5
6/*
7 * Copyright (C) 2012-2018 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#include "VideoRec.h"
19#include "VideoRecUtils.h"
20
21#include <iprt/asm.h>
22#include <iprt/assert.h>
23#include <iprt/critsect.h>
24#include <iprt/path.h>
25#include <iprt/semaphore.h>
26#include <iprt/thread.h>
27#include <iprt/time.h>
28
29
30/**
31 * Convert an image to YUV420p format.
32 *
33 * @return true on success, false on failure.
34 * @param aDstBuf The destination image buffer.
35 * @param aDstWidth Width (in pixel) of destination buffer.
36 * @param aDstHeight Height (in pixel) of destination buffer.
37 * @param aSrcBuf The source image buffer.
38 * @param aSrcWidth Width (in pixel) of source buffer.
39 * @param aSrcHeight Height (in pixel) of source buffer.
40 */
41template <class T>
42inline bool videoRecColorConvWriteYUV420p(uint8_t *aDstBuf, unsigned aDstWidth, unsigned aDstHeight,
43 uint8_t *aSrcBuf, unsigned aSrcWidth, unsigned aSrcHeight)
44{
45 RT_NOREF(aDstWidth, aDstHeight);
46
47 AssertReturn(!(aSrcWidth & 1), false);
48 AssertReturn(!(aSrcHeight & 1), false);
49
50 bool fRc = true;
51 T iter1(aSrcWidth, aSrcHeight, aSrcBuf);
52 T iter2 = iter1;
53 iter2.skip(aSrcWidth);
54 unsigned cPixels = aSrcWidth * aSrcHeight;
55 unsigned offY = 0;
56 unsigned offU = cPixels;
57 unsigned offV = cPixels + cPixels / 4;
58 unsigned const cyHalf = aSrcHeight / 2;
59 unsigned const cxHalf = aSrcWidth / 2;
60 for (unsigned i = 0; i < cyHalf && fRc; ++i)
61 {
62 for (unsigned j = 0; j < cxHalf; ++j)
63 {
64 unsigned red, green, blue;
65 fRc = iter1.getRGB(&red, &green, &blue);
66 AssertReturn(fRc, false);
67 aDstBuf[offY] = ((66 * red + 129 * green + 25 * blue + 128) >> 8) + 16;
68 unsigned u = (((-38 * red - 74 * green + 112 * blue + 128) >> 8) + 128) / 4;
69 unsigned v = (((112 * red - 94 * green - 18 * blue + 128) >> 8) + 128) / 4;
70
71 fRc = iter1.getRGB(&red, &green, &blue);
72 AssertReturn(fRc, false);
73 aDstBuf[offY + 1] = ((66 * red + 129 * green + 25 * blue + 128) >> 8) + 16;
74 u += (((-38 * red - 74 * green + 112 * blue + 128) >> 8) + 128) / 4;
75 v += (((112 * red - 94 * green - 18 * blue + 128) >> 8) + 128) / 4;
76
77 fRc = iter2.getRGB(&red, &green, &blue);
78 AssertReturn(fRc, false);
79 aDstBuf[offY + aSrcWidth] = ((66 * red + 129 * green + 25 * blue + 128) >> 8) + 16;
80 u += (((-38 * red - 74 * green + 112 * blue + 128) >> 8) + 128) / 4;
81 v += (((112 * red - 94 * green - 18 * blue + 128) >> 8) + 128) / 4;
82
83 fRc = iter2.getRGB(&red, &green, &blue);
84 AssertReturn(fRc, false);
85 aDstBuf[offY + aSrcWidth + 1] = ((66 * red + 129 * green + 25 * blue + 128) >> 8) + 16;
86 u += (((-38 * red - 74 * green + 112 * blue + 128) >> 8) + 128) / 4;
87 v += (((112 * red - 94 * green - 18 * blue + 128) >> 8) + 128) / 4;
88
89 aDstBuf[offU] = u;
90 aDstBuf[offV] = v;
91 offY += 2;
92 ++offU;
93 ++offV;
94 }
95
96 iter1.skip(aSrcWidth);
97 iter2.skip(aSrcWidth);
98 offY += aSrcWidth;
99 }
100
101 return true;
102}
103
104/**
105 * Convert an image to RGB24 format
106 * @returns true on success, false on failure
107 * @param aWidth width of image
108 * @param aHeight height of image
109 * @param aDestBuf an allocated memory buffer large enough to hold the
110 * destination image (i.e. width * height * 12bits)
111 * @param aSrcBuf the source image as an array of bytes
112 */
113template <class T>
114inline bool videoRecColorConvWriteRGB24(unsigned aWidth, unsigned aHeight,
115 uint8_t *aDestBuf, uint8_t *aSrcBuf)
116{
117 enum { PIX_SIZE = 3 };
118 bool rc = true;
119 AssertReturn(0 == (aWidth & 1), false);
120 AssertReturn(0 == (aHeight & 1), false);
121 T iter(aWidth, aHeight, aSrcBuf);
122 unsigned cPixels = aWidth * aHeight;
123 for (unsigned i = 0; i < cPixels && rc; ++i)
124 {
125 unsigned red, green, blue;
126 rc = iter.getRGB(&red, &green, &blue);
127 if (rc)
128 {
129 aDestBuf[i * PIX_SIZE ] = red;
130 aDestBuf[i * PIX_SIZE + 1] = green;
131 aDestBuf[i * PIX_SIZE + 2] = blue;
132 }
133 }
134 return rc;
135}
136
137/**
138 * Converts a RGB to YUV buffer.
139 *
140 * @returns IPRT status code.
141 * @param uPixelFormat Pixel format to use for conversion.
142 * @param paDst Pointer to destination buffer.
143 * @param uDstWidth Width (X, in pixels) of destination buffer.
144 * @param uDstHeight Height (Y, in pixels) of destination buffer.
145 * @param paSrc Pointer to source buffer.
146 * @param uSrcWidth Width (X, in pixels) of source buffer.
147 * @param uSrcHeight Height (Y, in pixels) of source buffer.
148 */
149int videoRecRGBToYUV(uint32_t uPixelFormat,
150 uint8_t *paDst, uint32_t uDstWidth, uint32_t uDstHeight,
151 uint8_t *paSrc, uint32_t uSrcWidth, uint32_t uSrcHeight)
152{
153 switch (uPixelFormat)
154 {
155 case VIDEORECPIXELFMT_RGB32:
156 if (!videoRecColorConvWriteYUV420p<ColorConvBGRA32Iter>(paDst, uDstWidth, uDstHeight,
157 paSrc, uSrcWidth, uSrcHeight))
158 return VERR_INVALID_PARAMETER;
159 break;
160 case VIDEORECPIXELFMT_RGB24:
161 if (!videoRecColorConvWriteYUV420p<ColorConvBGR24Iter>(paDst, uDstWidth, uDstHeight,
162 paSrc, uSrcWidth, uSrcHeight))
163 return VERR_INVALID_PARAMETER;
164 break;
165 case VIDEORECPIXELFMT_RGB565:
166 if (!videoRecColorConvWriteYUV420p<ColorConvBGR565Iter>(paDst, uDstWidth, uDstHeight,
167 paSrc, uSrcWidth, uSrcHeight))
168 return VERR_INVALID_PARAMETER;
169 break;
170 default:
171 AssertFailed();
172 return VERR_NOT_SUPPORTED;
173 }
174 return VINF_SUCCESS;
175}
176
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette