Added AVC444v2 client support.
This commit is contained in:
parent
9fd3974817
commit
b0d3cfda4d
@ -276,6 +276,7 @@ UINT rdpgfx_decode(RDPGFX_PLUGIN* gfx, RDPGFX_SURFACE_COMMAND* cmd)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case RDPGFX_CODECID_AVC444:
|
case RDPGFX_CODECID_AVC444:
|
||||||
|
case RDPGFX_CODECID_AVC444v2:
|
||||||
if ((error = rdpgfx_decode_AVC444(gfx, cmd)))
|
if ((error = rdpgfx_decode_AVC444(gfx, cmd)))
|
||||||
WLog_ERR(TAG, "rdpgfx_decode_AVC444 failed with error %"PRIu32"", error);
|
WLog_ERR(TAG, "rdpgfx_decode_AVC444 failed with error %"PRIu32"", error);
|
||||||
|
|
||||||
|
@ -104,6 +104,8 @@ static UINT rdpgfx_send_caps_advertise_pdu(RDPGFX_CHANNEL_CALLBACK* callback)
|
|||||||
|
|
||||||
capsSets[pdu.capsSetCount] = *capsSet;
|
capsSets[pdu.capsSetCount] = *capsSet;
|
||||||
capsSets[pdu.capsSetCount++].version = RDPGFX_CAPVERSION_102;
|
capsSets[pdu.capsSetCount++].version = RDPGFX_CAPVERSION_102;
|
||||||
|
capsSets[pdu.capsSetCount] = *capsSet;
|
||||||
|
capsSets[pdu.capsSetCount++].version = RDPGFX_CAPVERSION_103;
|
||||||
}
|
}
|
||||||
|
|
||||||
header.pduLength = RDPGFX_HEADER_SIZE + 2 + (pdu.capsSetCount *
|
header.pduLength = RDPGFX_HEADER_SIZE + 2 + (pdu.capsSetCount *
|
||||||
@ -271,11 +273,13 @@ static UINT rdpgfx_recv_reset_graphics_pdu(RDPGFX_CHANNEL_CALLBACK* callback,
|
|||||||
Stream_Seek(s, pad); /* pad (total size is 340 bytes) */
|
Stream_Seek(s, pad); /* pad (total size is 340 bytes) */
|
||||||
WLog_DBG(TAG, "RecvResetGraphicsPdu: width: %"PRIu32" height: %"PRIu32" count: %"PRIu32"",
|
WLog_DBG(TAG, "RecvResetGraphicsPdu: width: %"PRIu32" height: %"PRIu32" count: %"PRIu32"",
|
||||||
pdu.width, pdu.height, pdu.monitorCount);
|
pdu.width, pdu.height, pdu.monitorCount);
|
||||||
|
|
||||||
for (index = 0; index < pdu.monitorCount; index++)
|
for (index = 0; index < pdu.monitorCount; index++)
|
||||||
{
|
{
|
||||||
monitor = &(pdu.monitorDefArray[index]);
|
monitor = &(pdu.monitorDefArray[index]);
|
||||||
WLog_DBG(TAG, "RecvResetGraphicsPdu: monitor left:%"PRIi32" top:%"PRIi32" right:%"PRIi32" left:%"PRIi32" flags:0x%"PRIx32"",
|
WLog_DBG(TAG,
|
||||||
monitor->left, monitor->top, monitor->right, monitor->bottom, monitor->flags);
|
"RecvResetGraphicsPdu: monitor left:%"PRIi32" top:%"PRIi32" right:%"PRIi32" left:%"PRIi32" flags:0x%"PRIx32"",
|
||||||
|
monitor->left, monitor->top, monitor->right, monitor->bottom, monitor->flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context)
|
if (context)
|
||||||
|
@ -88,6 +88,9 @@ const char* rdpgfx_get_codec_id_string(UINT16 codecId)
|
|||||||
case RDPGFX_CODECID_AVC444:
|
case RDPGFX_CODECID_AVC444:
|
||||||
return "RDPGFX_CODECID_AVC444";
|
return "RDPGFX_CODECID_AVC444";
|
||||||
|
|
||||||
|
case RDPGFX_CODECID_AVC444v2:
|
||||||
|
return "RDPGFX_CODECID_AVC444v2";
|
||||||
|
|
||||||
case RDPGFX_CODECID_ALPHA:
|
case RDPGFX_CODECID_ALPHA:
|
||||||
return "RDPGFX_CODECID_ALPHA";
|
return "RDPGFX_CODECID_ALPHA";
|
||||||
|
|
||||||
|
@ -93,8 +93,9 @@ typedef struct _RDPGFX_HEADER RDPGFX_HEADER;
|
|||||||
#define RDPGFX_CAPVERSION_81 0x00080105 /** [MS-RDPEGFX] 2.2.3.2 */
|
#define RDPGFX_CAPVERSION_81 0x00080105 /** [MS-RDPEGFX] 2.2.3.2 */
|
||||||
#define RDPGFX_CAPVERSION_10 0x000A0002 /** [MS-RDPEGFX] 2.2.3.3 */
|
#define RDPGFX_CAPVERSION_10 0x000A0002 /** [MS-RDPEGFX] 2.2.3.3 */
|
||||||
#define RDPGFX_CAPVERSION_102 0x000A0200 /** [MS-RDPEGFX] 2.2.3.4 */
|
#define RDPGFX_CAPVERSION_102 0x000A0200 /** [MS-RDPEGFX] 2.2.3.4 */
|
||||||
|
#define RDPGFX_CAPVERSION_103 0x000A0301 /** [MS-RDPEGFX] 2.2.3.5 */
|
||||||
|
|
||||||
#define RDPGFX_NUMBER_CAPSETS 4
|
#define RDPGFX_NUMBER_CAPSETS 5
|
||||||
#define RDPGFX_CAPSET_SIZE 12
|
#define RDPGFX_CAPSET_SIZE 12
|
||||||
|
|
||||||
struct _RDPGFX_CAPSET
|
struct _RDPGFX_CAPSET
|
||||||
@ -144,6 +145,7 @@ typedef struct _RDPGFX_CAPSET_VERSION10 RDPGFX_CAPSET_VERSION10;
|
|||||||
#define RDPGFX_CODECID_AVC420 0x000B
|
#define RDPGFX_CODECID_AVC420 0x000B
|
||||||
#define RDPGFX_CODECID_ALPHA 0x000C
|
#define RDPGFX_CODECID_ALPHA 0x000C
|
||||||
#define RDPGFX_CODECID_AVC444 0x000E
|
#define RDPGFX_CODECID_AVC444 0x000E
|
||||||
|
#define RDPGFX_CODECID_AVC444v2 0x000F
|
||||||
|
|
||||||
#define RDPGFX_WIRE_TO_SURFACE_PDU_1_SIZE 17
|
#define RDPGFX_WIRE_TO_SURFACE_PDU_1_SIZE 17
|
||||||
|
|
||||||
|
@ -103,7 +103,8 @@ FREERDP_API INT32 avc444_decompress(H264_CONTEXT* h264, BYTE op,
|
|||||||
RECTANGLE_16* auxRegionRects, UINT32 numAuxRegionRect,
|
RECTANGLE_16* auxRegionRects, UINT32 numAuxRegionRect,
|
||||||
const BYTE* pAuxSrcData, UINT32 AuxSrcSize,
|
const BYTE* pAuxSrcData, UINT32 AuxSrcSize,
|
||||||
BYTE* pDstData, DWORD DstFormat,
|
BYTE* pDstData, DWORD DstFormat,
|
||||||
UINT32 nDstStep, UINT32 nDstWidth, UINT32 nDstHeight);
|
UINT32 nDstStep, UINT32 nDstWidth, UINT32 nDstHeight,
|
||||||
|
UINT32 codecId);
|
||||||
|
|
||||||
FREERDP_API BOOL h264_context_reset(H264_CONTEXT* h264, UINT32 width, UINT32 height);
|
FREERDP_API BOOL h264_context_reset(H264_CONTEXT* h264, UINT32 width, UINT32 height);
|
||||||
|
|
||||||
|
@ -63,6 +63,13 @@ typedef struct
|
|||||||
UINT32 height;
|
UINT32 height;
|
||||||
} prim_size_t; /* like IppiSize */
|
} prim_size_t; /* like IppiSize */
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
AVC444_LUMA,
|
||||||
|
AVC444_CHROMAv1,
|
||||||
|
AVC444_CHROMAv2
|
||||||
|
} avc444_frame_type;
|
||||||
|
|
||||||
/* Function prototypes for all of the supported primitives. */
|
/* Function prototypes for all of the supported primitives. */
|
||||||
typedef pstatus_t (*__copy_t)(
|
typedef pstatus_t (*__copy_t)(
|
||||||
const void* pSrc,
|
const void* pSrc,
|
||||||
@ -181,10 +188,10 @@ typedef pstatus_t (*__RGBToYUV444_8u_P3AC4R_t)(
|
|||||||
BYTE* pDst[3], UINT32 dstStep[3],
|
BYTE* pDst[3], UINT32 dstStep[3],
|
||||||
const prim_size_t* roi);
|
const prim_size_t* roi);
|
||||||
typedef pstatus_t (*__YUV420CombineToYUV444_t)(
|
typedef pstatus_t (*__YUV420CombineToYUV444_t)(
|
||||||
const BYTE* pMainSrc[3], const UINT32 srcMainStep[3],
|
avc444_frame_type type,
|
||||||
const BYTE* pAuxSrc[3], const UINT32 srcAuxStep[3],
|
const BYTE* pSrc[3], const UINT32 srcStep[3],
|
||||||
BYTE* pDst[3], const UINT32 dstStep[3],
|
BYTE* pDst[3], const UINT32 dstStep[3],
|
||||||
const prim_size_t* roi);
|
const RECTANGLE_16* roi);
|
||||||
typedef pstatus_t (*__YUV444SplitToYUV420_t)(
|
typedef pstatus_t (*__YUV444SplitToYUV420_t)(
|
||||||
const BYTE* pSrc[3], const UINT32 srcStep[3],
|
const BYTE* pSrc[3], const UINT32 srcStep[3],
|
||||||
BYTE* pMainDst[3], const UINT32 dstMainStep[3],
|
BYTE* pMainDst[3], const UINT32 dstMainStep[3],
|
||||||
|
@ -1702,16 +1702,14 @@ static BOOL avc444_process_rects(H264_CONTEXT* h264, const BYTE* pSrcData,
|
|||||||
UINT32 SrcSize, BYTE* pDstData, UINT32 DstFormat, UINT32 nDstStep,
|
UINT32 SrcSize, BYTE* pDstData, UINT32 DstFormat, UINT32 nDstStep,
|
||||||
UINT32 nDstWidth, UINT32 nDstHeight,
|
UINT32 nDstWidth, UINT32 nDstHeight,
|
||||||
const RECTANGLE_16* rects, UINT32 nrRects,
|
const RECTANGLE_16* rects, UINT32 nrRects,
|
||||||
BOOL main)
|
avc444_frame_type type)
|
||||||
{
|
{
|
||||||
const primitives_t* prims = primitives_get();
|
const primitives_t* prims = primitives_get();
|
||||||
UINT32 x;
|
UINT32 x;
|
||||||
const BYTE* pYUVPoint[3] = { NULL, NULL, NULL };
|
|
||||||
BYTE* pYUVDstPoint[3];
|
|
||||||
UINT32* piDstStride = h264->iYUV444Stride;
|
UINT32* piDstStride = h264->iYUV444Stride;
|
||||||
BYTE** ppYUVDstData = h264->pYUV444Data;
|
BYTE** ppYUVDstData = h264->pYUV444Data;
|
||||||
const UINT32* piStride = h264->iStride;
|
const UINT32* piStride = h264->iStride;
|
||||||
BYTE** ppYUVData = h264->pYUVData;
|
const BYTE** ppYUVData = (const BYTE**)h264->pYUVData;
|
||||||
|
|
||||||
if (h264->subsystem->Decompress(h264, pSrcData, SrcSize) < 0)
|
if (h264->subsystem->Decompress(h264, pSrcData, SrcSize) < 0)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -1722,42 +1720,14 @@ static BOOL avc444_process_rects(H264_CONTEXT* h264, const BYTE* pSrcData,
|
|||||||
for (x = 0; x < nrRects; x++)
|
for (x = 0; x < nrRects; x++)
|
||||||
{
|
{
|
||||||
const RECTANGLE_16* rect = &rects[x];
|
const RECTANGLE_16* rect = &rects[x];
|
||||||
prim_size_t roi;
|
|
||||||
|
|
||||||
if (!check_rect(h264, rect, nDstWidth, nDstHeight))
|
if (!check_rect(h264, rect, nDstWidth, nDstHeight))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
pYUVPoint[0] = ppYUVData[0] + rect->top * piStride[0] +
|
if (prims->YUV420CombineToYUV444(type, ppYUVData, piStride,
|
||||||
rect->left;
|
ppYUVDstData, piDstStride,
|
||||||
pYUVPoint[1] = ppYUVData[1] + rect->top / 2 * piStride[1] +
|
rect) != PRIMITIVES_SUCCESS)
|
||||||
rect->left / 2;
|
return FALSE;
|
||||||
pYUVPoint[2] = ppYUVData[2] + rect->top / 2 * piStride[2] +
|
|
||||||
rect->left / 2;
|
|
||||||
pYUVDstPoint[0] = ppYUVDstData[0] + rect->top * piDstStride[0] +
|
|
||||||
rect->left;
|
|
||||||
pYUVDstPoint[1] = ppYUVDstData[1] + rect->top * piDstStride[1] +
|
|
||||||
rect->left;
|
|
||||||
pYUVDstPoint[2] = ppYUVDstData[2] + rect->top * piDstStride[2] +
|
|
||||||
rect->left;
|
|
||||||
roi.width = rect->right - rect->left + 1;
|
|
||||||
roi.height = rect->bottom - rect->top + 1;
|
|
||||||
|
|
||||||
if (main)
|
|
||||||
{
|
|
||||||
if (prims->YUV420CombineToYUV444(pYUVPoint, piStride,
|
|
||||||
NULL, NULL,
|
|
||||||
pYUVDstPoint, piDstStride,
|
|
||||||
&roi) != PRIMITIVES_SUCCESS)
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (prims->YUV420CombineToYUV444(NULL, NULL,
|
|
||||||
pYUVPoint, piStride,
|
|
||||||
pYUVDstPoint, piDstStride,
|
|
||||||
&roi) != PRIMITIVES_SUCCESS)
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!avc_yuv_to_rgb(h264, rects, nrRects, nDstWidth,
|
if (!avc_yuv_to_rgb(h264, rects, nrRects, nDstWidth,
|
||||||
@ -1789,9 +1759,11 @@ INT32 avc444_decompress(H264_CONTEXT* h264, BYTE op,
|
|||||||
RECTANGLE_16* auxRegionRects, UINT32 numAuxRegionRect,
|
RECTANGLE_16* auxRegionRects, UINT32 numAuxRegionRect,
|
||||||
const BYTE* pAuxSrcData, UINT32 AuxSrcSize,
|
const BYTE* pAuxSrcData, UINT32 AuxSrcSize,
|
||||||
BYTE* pDstData, DWORD DstFormat,
|
BYTE* pDstData, DWORD DstFormat,
|
||||||
UINT32 nDstStep, UINT32 nDstWidth, UINT32 nDstHeight)
|
UINT32 nDstStep, UINT32 nDstWidth, UINT32 nDstHeight,
|
||||||
|
UINT32 codecId)
|
||||||
{
|
{
|
||||||
INT32 status = -1;
|
INT32 status = -1;
|
||||||
|
avc444_frame_type chroma = (codecId == RDPGFX_CODECID_AVC444) ? AVC444_CHROMAv1 : AVC444_CHROMAv2;
|
||||||
|
|
||||||
if (!h264 || !regionRects ||
|
if (!h264 || !regionRects ||
|
||||||
!pSrcData || !pDstData)
|
!pSrcData || !pDstData)
|
||||||
@ -1803,11 +1775,11 @@ INT32 avc444_decompress(H264_CONTEXT* h264, BYTE op,
|
|||||||
* Chroma420 in stream 2 */
|
* Chroma420 in stream 2 */
|
||||||
if (!avc444_process_rects(h264, pSrcData, SrcSize, pDstData, DstFormat, nDstStep, nDstWidth,
|
if (!avc444_process_rects(h264, pSrcData, SrcSize, pDstData, DstFormat, nDstStep, nDstWidth,
|
||||||
nDstHeight,
|
nDstHeight,
|
||||||
regionRects, numRegionRects, TRUE))
|
regionRects, numRegionRects, AVC444_LUMA))
|
||||||
status = -1;
|
status = -1;
|
||||||
else if (!avc444_process_rects(h264, pAuxSrcData, AuxSrcSize, pDstData, DstFormat, nDstStep,
|
else if (!avc444_process_rects(h264, pAuxSrcData, AuxSrcSize, pDstData, DstFormat, nDstStep,
|
||||||
nDstWidth, nDstHeight,
|
nDstWidth, nDstHeight,
|
||||||
auxRegionRects, numAuxRegionRect, FALSE))
|
auxRegionRects, numAuxRegionRect, chroma))
|
||||||
status = -1;
|
status = -1;
|
||||||
else
|
else
|
||||||
status = 0;
|
status = 0;
|
||||||
@ -1817,7 +1789,7 @@ INT32 avc444_decompress(H264_CONTEXT* h264, BYTE op,
|
|||||||
case 2: /* Chroma420 in stream 1 */
|
case 2: /* Chroma420 in stream 1 */
|
||||||
if (!avc444_process_rects(h264, pSrcData, SrcSize, pDstData, DstFormat, nDstStep, nDstWidth,
|
if (!avc444_process_rects(h264, pSrcData, SrcSize, pDstData, DstFormat, nDstStep, nDstWidth,
|
||||||
nDstHeight,
|
nDstHeight,
|
||||||
regionRects, numRegionRects, FALSE))
|
regionRects, numRegionRects, chroma))
|
||||||
status = -1;
|
status = -1;
|
||||||
else
|
else
|
||||||
status = 0;
|
status = 0;
|
||||||
@ -1827,7 +1799,7 @@ INT32 avc444_decompress(H264_CONTEXT* h264, BYTE op,
|
|||||||
case 1: /* YUV420 in stream 1 */
|
case 1: /* YUV420 in stream 1 */
|
||||||
if (!avc444_process_rects(h264, pSrcData, SrcSize, pDstData, DstFormat, nDstStep, nDstWidth,
|
if (!avc444_process_rects(h264, pSrcData, SrcSize, pDstData, DstFormat, nDstStep, nDstWidth,
|
||||||
nDstHeight,
|
nDstHeight,
|
||||||
regionRects, numRegionRects, TRUE))
|
regionRects, numRegionRects, AVC444_LUMA))
|
||||||
status = -1;
|
status = -1;
|
||||||
else
|
else
|
||||||
status = 0;
|
status = 0;
|
||||||
|
@ -113,7 +113,7 @@ static UINT gdi_OutputUpdate(rdpGdi* gdi, gdiGfxSurface* surface)
|
|||||||
&(surface->invalidRegion), &surfaceRect);
|
&(surface->invalidRegion), &surfaceRect);
|
||||||
|
|
||||||
if (!(rects = region16_rects(&surface->invalidRegion, &nbRects)) || !nbRects)
|
if (!(rects = region16_rects(&surface->invalidRegion, &nbRects)) || !nbRects)
|
||||||
return CHANNEL_RC_OK;
|
return CHANNEL_RC_OK;
|
||||||
|
|
||||||
update->BeginPaint(gdi->context);
|
update->BeginPaint(gdi->context);
|
||||||
|
|
||||||
@ -137,7 +137,6 @@ static UINT gdi_OutputUpdate(rdpGdi* gdi, gdiGfxSurface* surface)
|
|||||||
}
|
}
|
||||||
|
|
||||||
update->EndPaint(gdi->context);
|
update->EndPaint(gdi->context);
|
||||||
|
|
||||||
region16_clear(&(surface->invalidRegion));
|
region16_clear(&(surface->invalidRegion));
|
||||||
return CHANNEL_RC_OK;
|
return CHANNEL_RC_OK;
|
||||||
}
|
}
|
||||||
@ -213,11 +212,12 @@ static UINT gdi_SurfaceCommand_Uncompressed(rdpGdi* gdi,
|
|||||||
UINT status = CHANNEL_RC_OK;
|
UINT status = CHANNEL_RC_OK;
|
||||||
gdiGfxSurface* surface;
|
gdiGfxSurface* surface;
|
||||||
RECTANGLE_16 invalidRect;
|
RECTANGLE_16 invalidRect;
|
||||||
|
|
||||||
surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId);
|
surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId);
|
||||||
|
|
||||||
if (!surface)
|
if (!surface)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "%s: unable to retrieve surfaceData for surfaceId=%"PRIu32"", __FUNCTION__, cmd->surfaceId);
|
WLog_ERR(TAG, "%s: unable to retrieve surfaceData for surfaceId=%"PRIu32"", __FUNCTION__,
|
||||||
|
cmd->surfaceId);
|
||||||
return ERROR_NOT_FOUND;
|
return ERROR_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -253,11 +253,12 @@ static UINT gdi_SurfaceCommand_RemoteFX(rdpGdi* gdi,
|
|||||||
{
|
{
|
||||||
UINT status = CHANNEL_RC_OK;
|
UINT status = CHANNEL_RC_OK;
|
||||||
gdiGfxSurface* surface;
|
gdiGfxSurface* surface;
|
||||||
|
|
||||||
surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId);
|
surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId);
|
||||||
|
|
||||||
if (!surface)
|
if (!surface)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "%s: unable to retrieve surfaceData for surfaceId=%"PRIu32"", __FUNCTION__, cmd->surfaceId);
|
WLog_ERR(TAG, "%s: unable to retrieve surfaceData for surfaceId=%"PRIu32"", __FUNCTION__,
|
||||||
|
cmd->surfaceId);
|
||||||
return ERROR_NOT_FOUND;
|
return ERROR_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -294,11 +295,12 @@ static UINT gdi_SurfaceCommand_ClearCodec(rdpGdi* gdi,
|
|||||||
UINT status = CHANNEL_RC_OK;
|
UINT status = CHANNEL_RC_OK;
|
||||||
gdiGfxSurface* surface;
|
gdiGfxSurface* surface;
|
||||||
RECTANGLE_16 invalidRect;
|
RECTANGLE_16 invalidRect;
|
||||||
|
|
||||||
surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId);
|
surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId);
|
||||||
|
|
||||||
if (!surface)
|
if (!surface)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "%s: unable to retrieve surfaceData for surfaceId=%"PRIu32"", __FUNCTION__, cmd->surfaceId);
|
WLog_ERR(TAG, "%s: unable to retrieve surfaceData for surfaceId=%"PRIu32"", __FUNCTION__,
|
||||||
|
cmd->surfaceId);
|
||||||
return ERROR_NOT_FOUND;
|
return ERROR_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -342,11 +344,12 @@ static UINT gdi_SurfaceCommand_Planar(rdpGdi* gdi, RdpgfxClientContext* context,
|
|||||||
BYTE* DstData = NULL;
|
BYTE* DstData = NULL;
|
||||||
gdiGfxSurface* surface;
|
gdiGfxSurface* surface;
|
||||||
RECTANGLE_16 invalidRect;
|
RECTANGLE_16 invalidRect;
|
||||||
|
|
||||||
surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId);
|
surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId);
|
||||||
|
|
||||||
if (!surface)
|
if (!surface)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "%s: unable to retrieve surfaceData for surfaceId=%"PRIu32"", __FUNCTION__, cmd->surfaceId);
|
WLog_ERR(TAG, "%s: unable to retrieve surfaceData for surfaceId=%"PRIu32"", __FUNCTION__,
|
||||||
|
cmd->surfaceId);
|
||||||
return ERROR_NOT_FOUND;
|
return ERROR_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -390,11 +393,12 @@ static UINT gdi_SurfaceCommand_AVC420(rdpGdi* gdi,
|
|||||||
gdiGfxSurface* surface;
|
gdiGfxSurface* surface;
|
||||||
RDPGFX_H264_METABLOCK* meta;
|
RDPGFX_H264_METABLOCK* meta;
|
||||||
RDPGFX_AVC420_BITMAP_STREAM* bs;
|
RDPGFX_AVC420_BITMAP_STREAM* bs;
|
||||||
|
|
||||||
surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId);
|
surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId);
|
||||||
|
|
||||||
if (!surface)
|
if (!surface)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "%s: unable to retrieve surfaceData for surfaceId=%"PRIu32"", __FUNCTION__, cmd->surfaceId);
|
WLog_ERR(TAG, "%s: unable to retrieve surfaceData for surfaceId=%"PRIu32"", __FUNCTION__,
|
||||||
|
cmd->surfaceId);
|
||||||
return ERROR_NOT_FOUND;
|
return ERROR_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -449,11 +453,12 @@ static UINT gdi_SurfaceCommand_AVC444(rdpGdi* gdi, RdpgfxClientContext* context,
|
|||||||
RDPGFX_AVC420_BITMAP_STREAM* avc2;
|
RDPGFX_AVC420_BITMAP_STREAM* avc2;
|
||||||
RDPGFX_H264_METABLOCK* meta2;
|
RDPGFX_H264_METABLOCK* meta2;
|
||||||
RECTANGLE_16* regionRects = NULL;
|
RECTANGLE_16* regionRects = NULL;
|
||||||
|
|
||||||
surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId);
|
surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId);
|
||||||
|
|
||||||
if (!surface)
|
if (!surface)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "%s: unable to retrieve surfaceData for surfaceId=%"PRIu32"", __FUNCTION__, cmd->surfaceId);
|
WLog_ERR(TAG, "%s: unable to retrieve surfaceData for surfaceId=%"PRIu32"", __FUNCTION__,
|
||||||
|
cmd->surfaceId);
|
||||||
return ERROR_NOT_FOUND;
|
return ERROR_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -473,7 +478,7 @@ static UINT gdi_SurfaceCommand_AVC444(rdpGdi* gdi, RdpgfxClientContext* context,
|
|||||||
avc2->data, avc2->length,
|
avc2->data, avc2->length,
|
||||||
surface->data, surface->format,
|
surface->data, surface->format,
|
||||||
surface->scanline, surface->width,
|
surface->scanline, surface->width,
|
||||||
surface->height);
|
surface->height, cmd->codecId);
|
||||||
|
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
{
|
{
|
||||||
@ -517,11 +522,12 @@ static UINT gdi_SurfaceCommand_Alpha(rdpGdi* gdi, RdpgfxClientContext* context,
|
|||||||
UINT32 color;
|
UINT32 color;
|
||||||
gdiGfxSurface* surface;
|
gdiGfxSurface* surface;
|
||||||
RECTANGLE_16 invalidRect;
|
RECTANGLE_16 invalidRect;
|
||||||
|
|
||||||
surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId);
|
surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId);
|
||||||
|
|
||||||
if (!surface)
|
if (!surface)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "%s: unable to retrieve surfaceData for surfaceId=%"PRIu32"", __FUNCTION__, cmd->surfaceId);
|
WLog_ERR(TAG, "%s: unable to retrieve surfaceData for surfaceId=%"PRIu32"", __FUNCTION__,
|
||||||
|
cmd->surfaceId);
|
||||||
return ERROR_NOT_FOUND;
|
return ERROR_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -561,17 +567,17 @@ static UINT gdi_SurfaceCommand_Progressive(rdpGdi* gdi,
|
|||||||
INT32 rc;
|
INT32 rc;
|
||||||
UINT status = CHANNEL_RC_OK;
|
UINT status = CHANNEL_RC_OK;
|
||||||
gdiGfxSurface* surface;
|
gdiGfxSurface* surface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Note: Since this comes via a Wire-To-Surface-2 PDU the
|
* Note: Since this comes via a Wire-To-Surface-2 PDU the
|
||||||
* cmd's top/left/right/bottom/width/height members are always zero!
|
* cmd's top/left/right/bottom/width/height members are always zero!
|
||||||
* The update region is determined during decompression.
|
* The update region is determined during decompression.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId);
|
surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId);
|
||||||
|
|
||||||
if (!surface)
|
if (!surface)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "%s: unable to retrieve surfaceData for surfaceId=%"PRIu32"", __FUNCTION__, cmd->surfaceId);
|
WLog_ERR(TAG, "%s: unable to retrieve surfaceData for surfaceId=%"PRIu32"", __FUNCTION__,
|
||||||
|
cmd->surfaceId);
|
||||||
return ERROR_NOT_FOUND;
|
return ERROR_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -649,6 +655,7 @@ static UINT gdi_SurfaceCommand(RdpgfxClientContext* context,
|
|||||||
status = gdi_SurfaceCommand_AVC420(gdi, context, cmd);
|
status = gdi_SurfaceCommand_AVC420(gdi, context, cmd);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case RDPGFX_CODECID_AVC444v2:
|
||||||
case RDPGFX_CODECID_AVC444:
|
case RDPGFX_CODECID_AVC444:
|
||||||
status = gdi_SurfaceCommand_AVC444(gdi, context, cmd);
|
status = gdi_SurfaceCommand_AVC444(gdi, context, cmd);
|
||||||
break;
|
break;
|
||||||
|
@ -30,91 +30,154 @@
|
|||||||
#include <freerdp/codec/color.h>
|
#include <freerdp/codec/color.h>
|
||||||
#include "prim_internal.h"
|
#include "prim_internal.h"
|
||||||
|
|
||||||
/**
|
static pstatus_t general_LumaToYUV444(const BYTE* pSrcRaw[3], const UINT32 srcStep[3],
|
||||||
* @brief general_YUV420CombineToYUV444
|
BYTE* pDstRaw[3], const UINT32 dstStep[3],
|
||||||
*
|
const RECTANGLE_16* roi)
|
||||||
* @param pMainSrc Pointer to luma YUV420 data
|
{
|
||||||
* @param srcMainStep Step width in luma YUV420 data
|
UINT32 x, y;
|
||||||
* @param pAuxSrc Pointer to chroma YUV420 data
|
const UINT32 nWidth = roi->right - roi->left;
|
||||||
* @param srcAuxStep Step width in chroma YUV420 data
|
const UINT32 nHeight = roi->bottom - roi->top;
|
||||||
* @param pDst Pointer to YUV444 data
|
const UINT32 halfWidth = (nWidth + 1) / 2;
|
||||||
* @param dstStep Step width in YUV444 data
|
const UINT32 halfHeight = (nHeight + 1) / 2;
|
||||||
* @param roi Region of source to combine in destination.
|
const UINT32 oddY = 1;
|
||||||
*
|
const UINT32 evenY = 0;
|
||||||
* @return PRIMITIVES_SUCCESS on success, an error code otherwise.
|
const UINT32 oddX = 1;
|
||||||
*/
|
const UINT32 evenX = 0;
|
||||||
static pstatus_t general_YUV420CombineToYUV444(
|
const BYTE* pSrc[3] =
|
||||||
const BYTE* pMainSrc[3], const UINT32 srcMainStep[3],
|
{
|
||||||
const BYTE* pAuxSrc[3], const UINT32 srcAuxStep[3],
|
pSrcRaw[0] + roi->top* srcStep[0] + roi->left,
|
||||||
BYTE* pDst[3], const UINT32 dstStep[3],
|
pSrcRaw[1] + roi->top / 2 * srcStep[1] + roi->left / 2,
|
||||||
const prim_size_t* roi)
|
pSrcRaw[2] + roi->top / 2 * srcStep[2] + roi->left / 2
|
||||||
|
};
|
||||||
|
BYTE* pDst[3] =
|
||||||
|
{
|
||||||
|
pDstRaw[0] + roi->top* dstStep[0] + roi->left,
|
||||||
|
pDstRaw[1] + roi->top* dstStep[1] + roi->left,
|
||||||
|
pDstRaw[2] + roi->top* dstStep[2] + roi->left
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Y data is already here... */
|
||||||
|
/* B1 */
|
||||||
|
for (y = 0; y < nHeight; y++)
|
||||||
|
{
|
||||||
|
const BYTE* Ym = pSrc[0] + srcStep[0] * y;
|
||||||
|
BYTE* pY = pDst[0] + dstStep[0] * y;
|
||||||
|
memcpy(pY, Ym, nWidth);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The first half of U, V are already here part of this frame. */
|
||||||
|
/* B2 and B3 */
|
||||||
|
for (y = 0; y < halfHeight; y++)
|
||||||
|
{
|
||||||
|
const UINT32 val2y = (2 * y + evenY);
|
||||||
|
const UINT32 val2y1 = val2y + oddY;
|
||||||
|
const BYTE* Um = pSrc[1] + srcStep[1] * y;
|
||||||
|
const BYTE* Vm = pSrc[2] + srcStep[2] * y;
|
||||||
|
BYTE* pU = pDst[1] + dstStep[1] * val2y;
|
||||||
|
BYTE* pV = pDst[2] + dstStep[2] * val2y;
|
||||||
|
BYTE* pU1 = pDst[1] + dstStep[1] * val2y1;
|
||||||
|
BYTE* pV1 = pDst[2] + dstStep[2] * val2y1;
|
||||||
|
|
||||||
|
for (x = 0; x < halfWidth; x++)
|
||||||
|
{
|
||||||
|
const UINT32 val2x = 2 * x + evenX;
|
||||||
|
const UINT32 val2x1 = val2x + oddX;
|
||||||
|
pU[val2x] = Um[x];
|
||||||
|
pV[val2x] = Vm[x];
|
||||||
|
pU[val2x1] = Um[x];
|
||||||
|
pV[val2x1] = Vm[x];
|
||||||
|
pU1[val2x] = Um[x];
|
||||||
|
pV1[val2x] = Vm[x];
|
||||||
|
pU1[val2x1] = Um[x];
|
||||||
|
pV1[val2x1] = Vm[x];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return PRIMITIVES_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static pstatus_t general_ChromaFilter(BYTE* pDst[3], const UINT32 dstStep[3],
|
||||||
|
const RECTANGLE_16* roi)
|
||||||
|
{
|
||||||
|
const UINT32 oddY = 1;
|
||||||
|
const UINT32 evenY = 0;
|
||||||
|
const UINT32 nWidth = roi->right - roi->left;
|
||||||
|
const UINT32 nHeight = roi->bottom - roi->top;
|
||||||
|
const UINT32 halfHeight = (nHeight + 1) / 2;
|
||||||
|
const UINT32 halfWidth = (nWidth + 1) / 2;
|
||||||
|
UINT32 x, y;
|
||||||
|
|
||||||
|
/* Filter */
|
||||||
|
for (y = roi->top; y < halfHeight + roi->top; y++)
|
||||||
|
{
|
||||||
|
const UINT32 val2y = (y * 2 + evenY);
|
||||||
|
const UINT32 val2y1 = val2y + oddY;
|
||||||
|
BYTE* pU1 = pDst[1] + dstStep[1] * val2y1;
|
||||||
|
BYTE* pV1 = pDst[2] + dstStep[2] * val2y1;
|
||||||
|
BYTE* pU = pDst[1] + dstStep[1] * val2y;
|
||||||
|
BYTE* pV = pDst[2] + dstStep[2] * val2y;
|
||||||
|
|
||||||
|
if (val2y1 > nHeight)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (x = roi->left; x < halfWidth + roi->left; x++)
|
||||||
|
{
|
||||||
|
const UINT32 val2x = (x * 2);
|
||||||
|
const UINT32 val2x1 = val2x + 1;
|
||||||
|
const INT32 up = pU[val2x] * 4;
|
||||||
|
const INT32 vp = pV[val2x] * 4;
|
||||||
|
INT32 u2020;
|
||||||
|
INT32 v2020;
|
||||||
|
|
||||||
|
if (val2x1 > nWidth)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
u2020 = up - pU[val2x1] - pU1[val2x] - pU1[val2x1];
|
||||||
|
v2020 = vp - pV[val2x1] - pV1[val2x] - pV1[val2x1];
|
||||||
|
pU[val2x] = CLIP(u2020);
|
||||||
|
pV[val2x] = CLIP(v2020);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return PRIMITIVES_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static pstatus_t general_ChromaV1ToYUV444(const BYTE* pSrcRaw[3], const UINT32 srcStep[3],
|
||||||
|
BYTE* pDstRaw[3], const UINT32 dstStep[3],
|
||||||
|
const RECTANGLE_16* roi)
|
||||||
{
|
{
|
||||||
const UINT32 mod = 16;
|
const UINT32 mod = 16;
|
||||||
UINT32 uY = 0;
|
UINT32 uY = 0;
|
||||||
UINT32 vY = 0;
|
UINT32 vY = 0;
|
||||||
UINT32 x, y;
|
UINT32 x, y;
|
||||||
UINT32 nWidth, nHeight;
|
const UINT32 nWidth = roi->right - roi->left;
|
||||||
UINT32 halfWidth, halfHeight;
|
const UINT32 nHeight = roi->bottom - roi->top;
|
||||||
|
const UINT32 halfWidth = (nWidth) / 2;
|
||||||
|
const UINT32 halfHeight = (nHeight) / 2;
|
||||||
const UINT32 oddY = 1;
|
const UINT32 oddY = 1;
|
||||||
const UINT32 evenY = 0;
|
const UINT32 evenY = 0;
|
||||||
const UINT32 oddX = 1;
|
const UINT32 oddX = 1;
|
||||||
const UINT32 evenX = 0;
|
|
||||||
/* The auxilary frame is aligned to multiples of 16x16.
|
/* The auxilary frame is aligned to multiples of 16x16.
|
||||||
* We need the padded height for B4 and B5 conversion. */
|
* We need the padded height for B4 and B5 conversion. */
|
||||||
const UINT32 padHeigth = roi->height + 16 - roi->height % 16;
|
const UINT32 padHeigth = nHeight + 16 - nHeight % 16;
|
||||||
nWidth = roi->width;
|
const BYTE* pSrc[3] =
|
||||||
nHeight = roi->height;
|
|
||||||
halfWidth = (nWidth) / 2;
|
|
||||||
halfHeight = (nHeight) / 2;
|
|
||||||
|
|
||||||
if (pMainSrc && pMainSrc[0] && pMainSrc[1] && pMainSrc[2])
|
|
||||||
{
|
{
|
||||||
/* Y data is already here... */
|
pSrcRaw[0] + roi->top* srcStep[0] + roi->left,
|
||||||
/* B1 */
|
pSrcRaw[1] + roi->top / 2 * srcStep[1] + roi->left / 2,
|
||||||
for (y = 0; y < nHeight; y++)
|
pSrcRaw[2] + roi->top / 2 * srcStep[2] + roi->left / 2
|
||||||
{
|
};
|
||||||
const BYTE* Ym = pMainSrc[0] + srcMainStep[0] * y;
|
BYTE* pDst[3] =
|
||||||
BYTE* pY = pDst[0] + dstStep[0] * y;
|
{
|
||||||
memcpy(pY, Ym, nWidth);
|
pDstRaw[0] + roi->top* dstStep[0] + roi->left,
|
||||||
}
|
pDstRaw[1] + roi->top* dstStep[1] + roi->left,
|
||||||
|
pDstRaw[2] + roi->top* dstStep[2] + roi->left
|
||||||
/* The first half of U, V are already here part of this frame. */
|
};
|
||||||
/* B2 and B3 */
|
|
||||||
for (y = 0; y < halfHeight; y++)
|
|
||||||
{
|
|
||||||
const UINT32 val2y = (2 * y + evenY);
|
|
||||||
const UINT32 val2y1 = val2y + oddY;
|
|
||||||
const BYTE* Um = pMainSrc[1] + srcMainStep[1] * y;
|
|
||||||
const BYTE* Vm = pMainSrc[2] + srcMainStep[2] * y;
|
|
||||||
BYTE* pU = pDst[1] + dstStep[1] * val2y;
|
|
||||||
BYTE* pV = pDst[2] + dstStep[2] * val2y;
|
|
||||||
BYTE* pU1 = pDst[1] + dstStep[1] * val2y1;
|
|
||||||
BYTE* pV1 = pDst[2] + dstStep[2] * val2y1;
|
|
||||||
|
|
||||||
for (x = 0; x < halfWidth; x++)
|
|
||||||
{
|
|
||||||
const UINT32 val2x = 2 * x + evenX;
|
|
||||||
const UINT32 val2x1 = val2x + oddX;
|
|
||||||
pU[val2x] = Um[x];
|
|
||||||
pV[val2x] = Vm[x];
|
|
||||||
pU[val2x1] = Um[x];
|
|
||||||
pV[val2x1] = Vm[x];
|
|
||||||
pU1[val2x] = Um[x];
|
|
||||||
pV1[val2x] = Vm[x];
|
|
||||||
pU1[val2x1] = Um[x];
|
|
||||||
pV1[val2x1] = Vm[x];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!pAuxSrc || !pAuxSrc[0] || !pAuxSrc[1] || !pAuxSrc[2])
|
|
||||||
return PRIMITIVES_SUCCESS;
|
|
||||||
|
|
||||||
/* The second half of U and V is a bit more tricky... */
|
/* The second half of U and V is a bit more tricky... */
|
||||||
/* B4 and B5 */
|
/* B4 and B5 */
|
||||||
for (y = 0; y < padHeigth; y++)
|
for (y = 0; y < padHeigth; y++)
|
||||||
{
|
{
|
||||||
const BYTE* Ya = pAuxSrc[0] + srcAuxStep[0] * y;
|
const BYTE* Ya = pSrc[0] + srcStep[0] * y;
|
||||||
BYTE* pX;
|
BYTE* pX;
|
||||||
|
|
||||||
if ((y) % mod < (mod + 1) / 2)
|
if ((y) % mod < (mod + 1) / 2)
|
||||||
@ -143,8 +206,8 @@ static pstatus_t general_YUV420CombineToYUV444(
|
|||||||
for (y = 0; y < halfHeight; y++)
|
for (y = 0; y < halfHeight; y++)
|
||||||
{
|
{
|
||||||
const UINT32 val2y = (y * 2 + evenY);
|
const UINT32 val2y = (y * 2 + evenY);
|
||||||
const BYTE* Ua = pAuxSrc[1] + srcAuxStep[1] * y;
|
const BYTE* Ua = pSrc[1] + srcStep[1] * y;
|
||||||
const BYTE* Va = pAuxSrc[2] + srcAuxStep[2] * y;
|
const BYTE* Va = pSrc[2] + srcStep[2] * y;
|
||||||
BYTE* pU = pDst[1] + dstStep[1] * val2y;
|
BYTE* pU = pDst[1] + dstStep[1] * val2y;
|
||||||
BYTE* pV = pDst[2] + dstStep[2] * val2y;
|
BYTE* pV = pDst[2] + dstStep[2] * val2y;
|
||||||
|
|
||||||
@ -157,38 +220,102 @@ static pstatus_t general_YUV420CombineToYUV444(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Filter */
|
/* Filter */
|
||||||
for (y = 0; y < halfHeight; y++)
|
return general_ChromaFilter(pDst, dstStep, roi);
|
||||||
{
|
}
|
||||||
const UINT32 val2y = (y * 2 + evenY);
|
|
||||||
const UINT32 val2y1 = val2y + oddY;
|
|
||||||
BYTE* pU1 = pDst[1] + dstStep[1] * val2y1;
|
|
||||||
BYTE* pV1 = pDst[2] + dstStep[2] * val2y1;
|
|
||||||
BYTE* pU = pDst[1] + dstStep[1] * val2y;
|
|
||||||
BYTE* pV = pDst[2] + dstStep[2] * val2y;
|
|
||||||
|
|
||||||
if (val2y1 > nHeight)
|
static pstatus_t general_ChromaV2ToYUV444(const BYTE* pSrc[3], const UINT32 srcStep[3],
|
||||||
continue;
|
BYTE* pDst[3], const UINT32 dstStep[3],
|
||||||
|
const RECTANGLE_16* roi)
|
||||||
|
{
|
||||||
|
UINT32 x, y;
|
||||||
|
const UINT32 nWidth = roi->right - roi->left;
|
||||||
|
const UINT32 nHeight = roi->bottom - roi->top;
|
||||||
|
const UINT32 halfWidth = (nWidth + 1) / 2;
|
||||||
|
const UINT32 halfHeight = (nHeight + 1) / 2;
|
||||||
|
const UINT32 quaterWidth = (nWidth + 3) / 4;
|
||||||
|
const UINT32 quaterHeight = (nHeight + 3) / 4;
|
||||||
|
|
||||||
|
/* B4 and B5: odd UV values for width/2, height */
|
||||||
|
for (y = 0; y < nHeight; y++)
|
||||||
|
{
|
||||||
|
const UINT32 yTop = y + roi->top;
|
||||||
|
const BYTE* pYaU = pSrc[0] + srcStep[0] * yTop + roi->left / 2;
|
||||||
|
const BYTE* pYaV = pYaU + srcStep[0] / 2;
|
||||||
|
BYTE* pU = pDst[1] + dstStep[1] * yTop + roi->left;
|
||||||
|
BYTE* pV = pDst[2] + dstStep[2] * yTop + roi->left;
|
||||||
|
|
||||||
for (x = 0; x < halfWidth; x++)
|
for (x = 0; x < halfWidth; x++)
|
||||||
{
|
{
|
||||||
const UINT32 val2x = (x * 2);
|
const UINT32 odd = 2 * x + 1;
|
||||||
const UINT32 val2x1 = val2x + 1;
|
pU[odd] = *pYaU++;
|
||||||
const INT32 up = pU[val2x] * 4;
|
pV[odd] = *pYaV++;
|
||||||
const INT32 vp = pV[val2x] * 4;
|
|
||||||
INT32 u2020;
|
|
||||||
INT32 v2020;
|
|
||||||
|
|
||||||
if (val2x1 > nWidth)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
u2020 = up - pU[val2x1] - pU1[val2x] - pU1[val2x1];
|
|
||||||
v2020 = vp - pV[val2x1] - pV1[val2x] - pV1[val2x1];
|
|
||||||
pU[val2x] = CLIP(u2020);
|
|
||||||
pV[val2x] = CLIP(v2020);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return PRIMITIVES_SUCCESS;
|
/* B6 - B9 */
|
||||||
|
for (y = 0; y < halfHeight; y++)
|
||||||
|
{
|
||||||
|
const BYTE* pUaU = pSrc[1] + srcStep[1] * (y + roi->top / 2) + roi->left / 4;
|
||||||
|
const BYTE* pUaV = pUaU + srcStep[1] / 2;
|
||||||
|
const BYTE* pVaU = pSrc[2] + srcStep[2] * (y + roi->top / 2) + roi->left / 4;
|
||||||
|
const BYTE* pVaV = pVaU + srcStep[2] / 2;
|
||||||
|
BYTE* pU = pDst[1] + dstStep[1] * (2 * y + 1 + roi->top) + roi->left;
|
||||||
|
BYTE* pV = pDst[2] + dstStep[2] * (2 * y + 1 + roi->top) + roi->left;
|
||||||
|
|
||||||
|
for (x = 0; x < quaterWidth; x++)
|
||||||
|
{
|
||||||
|
pU[4 * x + 0] = *pUaU++;
|
||||||
|
pV[4 * x + 0] = *pUaV++;
|
||||||
|
pU[4 * x + 2] = *pVaU++;
|
||||||
|
pV[4 * x + 2] = *pVaV++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return general_ChromaFilter(pDst, dstStep, roi);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief general_YUV420CombineToYUV444
|
||||||
|
*
|
||||||
|
* @param pMainSrc Pointer to luma YUV420 data
|
||||||
|
* @param srcMainStep Step width in luma YUV420 data
|
||||||
|
* @param pAuxSrc Pointer to chroma YUV420 data
|
||||||
|
* @param srcAuxStep Step width in chroma YUV420 data
|
||||||
|
* @param pDst Pointer to YUV444 data
|
||||||
|
* @param dstStep Step width in YUV444 data
|
||||||
|
* @param roi Region of source to combine in destination.
|
||||||
|
*
|
||||||
|
* @return PRIMITIVES_SUCCESS on success, an error code otherwise.
|
||||||
|
*/
|
||||||
|
static pstatus_t general_YUV420CombineToYUV444(
|
||||||
|
avc444_frame_type type,
|
||||||
|
const BYTE* pSrc[3], const UINT32 srcStep[3],
|
||||||
|
BYTE* pDst[3], const UINT32 dstStep[3],
|
||||||
|
const RECTANGLE_16* roi)
|
||||||
|
{
|
||||||
|
if (!pSrc || !pSrc[0] || !pSrc[1] || !pSrc[2])
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (!pDst || !pDst[0] || !pDst[1] || !pDst[2])
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (!roi)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case AVC444_LUMA:
|
||||||
|
return general_LumaToYUV444(pSrc, srcStep, pDst, dstStep, roi);
|
||||||
|
|
||||||
|
case AVC444_CHROMAv1:
|
||||||
|
return general_ChromaV1ToYUV444(pSrc, srcStep, pDst, dstStep, roi);
|
||||||
|
|
||||||
|
case AVC444_CHROMAv2:
|
||||||
|
return general_ChromaV2ToYUV444(pSrc, srcStep, pDst, dstStep, roi);
|
||||||
|
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static pstatus_t general_YUV444SplitToYUV420(
|
static pstatus_t general_YUV444SplitToYUV420(
|
||||||
@ -704,21 +831,19 @@ static pstatus_t general_RGBToYUV420_8u_P3AC4R(
|
|||||||
}
|
}
|
||||||
|
|
||||||
static INLINE pstatus_t general_RGBToAVC444YUV_BGRX(
|
static INLINE pstatus_t general_RGBToAVC444YUV_BGRX(
|
||||||
const BYTE* pSrc, UINT32 srcFormat, UINT32 srcStep,
|
const BYTE* pSrc, UINT32 srcFormat, UINT32 srcStep,
|
||||||
BYTE* pDst1[3], const UINT32 dst1Step[3],
|
BYTE* pDst1[3], const UINT32 dst1Step[3],
|
||||||
BYTE* pDst2[3], const UINT32 dst2Step[3],
|
BYTE* pDst2[3], const UINT32 dst2Step[3],
|
||||||
const prim_size_t* roi)
|
const prim_size_t* roi)
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Note:
|
* Note:
|
||||||
* Read information in function general_RGBToAVC444YUV_ANY below !
|
* Read information in function general_RGBToAVC444YUV_ANY below !
|
||||||
*/
|
*/
|
||||||
|
|
||||||
UINT32 x, y, n, numRows, numCols;
|
UINT32 x, y, n, numRows, numCols;
|
||||||
BOOL evenRow = TRUE;
|
BOOL evenRow = TRUE;
|
||||||
BYTE *b1, *b2, *b3, *b4, *b5, *b6, *b7;
|
BYTE* b1, *b2, *b3, *b4, *b5, *b6, *b7;
|
||||||
const BYTE* pMaxSrc = pSrc + (roi->height - 1) * srcStep;
|
const BYTE* pMaxSrc = pSrc + (roi->height - 1) * srcStep;
|
||||||
|
|
||||||
numRows = (roi->height + 1) & ~1;
|
numRows = (roi->height + 1) & ~1;
|
||||||
numCols = (roi->width + 1) & ~1;
|
numCols = (roi->width + 1) & ~1;
|
||||||
|
|
||||||
@ -726,7 +851,6 @@ static INLINE pstatus_t general_RGBToAVC444YUV_BGRX(
|
|||||||
{
|
{
|
||||||
const BYTE* src = y < roi->height ? pSrc + y * srcStep : pMaxSrc;
|
const BYTE* src = y < roi->height ? pSrc + y * srcStep : pMaxSrc;
|
||||||
UINT32 i = y >> 1;
|
UINT32 i = y >> 1;
|
||||||
|
|
||||||
b1 = pDst1[0] + y * dst1Step[0];
|
b1 = pDst1[0] + y * dst1Step[0];
|
||||||
|
|
||||||
if (evenRow)
|
if (evenRow)
|
||||||
@ -746,11 +870,9 @@ static INLINE pstatus_t general_RGBToAVC444YUV_BGRX(
|
|||||||
for (x = 0; x < numCols; x += 2)
|
for (x = 0; x < numCols; x += 2)
|
||||||
{
|
{
|
||||||
BYTE R, G, B, Y1, Y2, U1, U2, V1, V2;
|
BYTE R, G, B, Y1, Y2, U1, U2, V1, V2;
|
||||||
|
|
||||||
B = src[0];
|
B = src[0];
|
||||||
G = src[1];
|
G = src[1];
|
||||||
R = src[2];
|
R = src[2];
|
||||||
|
|
||||||
Y1 = Y2 = RGB2Y(R, G, B);
|
Y1 = Y2 = RGB2Y(R, G, B);
|
||||||
U1 = U2 = RGB2U(R, G, B);
|
U1 = U2 = RGB2U(R, G, B);
|
||||||
V1 = V2 = RGB2V(R, G, B);
|
V1 = V2 = RGB2V(R, G, B);
|
||||||
@ -791,10 +913,10 @@ static INLINE pstatus_t general_RGBToAVC444YUV_BGRX(
|
|||||||
}
|
}
|
||||||
|
|
||||||
static INLINE pstatus_t general_RGBToAVC444YUV_ANY(
|
static INLINE pstatus_t general_RGBToAVC444YUV_ANY(
|
||||||
const BYTE* pSrc, UINT32 srcFormat, UINT32 srcStep,
|
const BYTE* pSrc, UINT32 srcFormat, UINT32 srcStep,
|
||||||
BYTE* pDst1[3], const UINT32 dst1Step[3],
|
BYTE* pDst1[3], const UINT32 dst1Step[3],
|
||||||
BYTE* pDst2[3], const UINT32 dst2Step[3],
|
BYTE* pDst2[3], const UINT32 dst2Step[3],
|
||||||
const prim_size_t* roi)
|
const prim_size_t* roi)
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Note: According to [MS-RDPEGFX 2.2.4.4 RFX_AVC420_BITMAP_STREAM] the
|
* Note: According to [MS-RDPEGFX 2.2.4.4 RFX_AVC420_BITMAP_STREAM] the
|
||||||
@ -803,7 +925,6 @@ static INLINE pstatus_t general_RGBToAVC444YUV_ANY(
|
|||||||
* Hence the passed destination YUV420/CHROMA420 buffers must have been
|
* Hence the passed destination YUV420/CHROMA420 buffers must have been
|
||||||
* allocated accordingly !!
|
* allocated accordingly !!
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* [MS-RDPEGFX 3.3.8.3.2 YUV420p Stream Combination] defines the following "Bx areas":
|
* [MS-RDPEGFX 3.3.8.3.2 YUV420p Stream Combination] defines the following "Bx areas":
|
||||||
*
|
*
|
||||||
@ -853,13 +974,11 @@ static INLINE pstatus_t general_RGBToAVC444YUV_ANY(
|
|||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const UINT32 bpp = GetBytesPerPixel(srcFormat);
|
const UINT32 bpp = GetBytesPerPixel(srcFormat);
|
||||||
UINT32 x, y, n, numRows, numCols;
|
UINT32 x, y, n, numRows, numCols;
|
||||||
BOOL evenRow = TRUE;
|
BOOL evenRow = TRUE;
|
||||||
BYTE *b1, *b2, *b3, *b4, *b5, *b6, *b7;
|
BYTE* b1, *b2, *b3, *b4, *b5, *b6, *b7;
|
||||||
const BYTE* pMaxSrc = pSrc + (roi->height - 1) * srcStep;
|
const BYTE* pMaxSrc = pSrc + (roi->height - 1) * srcStep;
|
||||||
|
|
||||||
numRows = (roi->height + 1) & ~1;
|
numRows = (roi->height + 1) & ~1;
|
||||||
numCols = (roi->width + 1) & ~1;
|
numCols = (roi->width + 1) & ~1;
|
||||||
|
|
||||||
@ -867,7 +986,6 @@ static INLINE pstatus_t general_RGBToAVC444YUV_ANY(
|
|||||||
{
|
{
|
||||||
const BYTE* src = y < roi->height ? pSrc + y * srcStep : pMaxSrc;
|
const BYTE* src = y < roi->height ? pSrc + y * srcStep : pMaxSrc;
|
||||||
UINT32 i = y >> 1;
|
UINT32 i = y >> 1;
|
||||||
|
|
||||||
b1 = pDst1[0] + y * dst1Step[0];
|
b1 = pDst1[0] + y * dst1Step[0];
|
||||||
|
|
||||||
if (evenRow)
|
if (evenRow)
|
||||||
@ -888,10 +1006,8 @@ static INLINE pstatus_t general_RGBToAVC444YUV_ANY(
|
|||||||
{
|
{
|
||||||
BYTE R, G, B, Y1, Y2, U1, U2, V1, V2;
|
BYTE R, G, B, Y1, Y2, U1, U2, V1, V2;
|
||||||
UINT32 color;
|
UINT32 color;
|
||||||
|
|
||||||
color = ReadColor(src, srcFormat);
|
color = ReadColor(src, srcFormat);
|
||||||
SplitColor(color, srcFormat, &R, &G, &B, NULL, NULL);
|
SplitColor(color, srcFormat, &R, &G, &B, NULL, NULL);
|
||||||
|
|
||||||
Y1 = Y2 = RGB2Y(R, G, B);
|
Y1 = Y2 = RGB2Y(R, G, B);
|
||||||
U1 = U2 = RGB2U(R, G, B);
|
U1 = U2 = RGB2U(R, G, B);
|
||||||
V1 = V2 = RGB2V(R, G, B);
|
V1 = V2 = RGB2V(R, G, B);
|
||||||
@ -900,7 +1016,6 @@ static INLINE pstatus_t general_RGBToAVC444YUV_ANY(
|
|||||||
{
|
{
|
||||||
color = ReadColor(src + bpp, srcFormat);
|
color = ReadColor(src + bpp, srcFormat);
|
||||||
SplitColor(color, srcFormat, &R, &G, &B, NULL, NULL);
|
SplitColor(color, srcFormat, &R, &G, &B, NULL, NULL);
|
||||||
|
|
||||||
Y2 = RGB2Y(R, G, B);
|
Y2 = RGB2Y(R, G, B);
|
||||||
U2 = RGB2U(R, G, B);
|
U2 = RGB2U(R, G, B);
|
||||||
V2 = RGB2V(R, G, B);
|
V2 = RGB2V(R, G, B);
|
||||||
@ -932,10 +1047,10 @@ static INLINE pstatus_t general_RGBToAVC444YUV_ANY(
|
|||||||
}
|
}
|
||||||
|
|
||||||
static INLINE pstatus_t general_RGBToAVC444YUV(
|
static INLINE pstatus_t general_RGBToAVC444YUV(
|
||||||
const BYTE* pSrc, UINT32 srcFormat, UINT32 srcStep,
|
const BYTE* pSrc, UINT32 srcFormat, UINT32 srcStep,
|
||||||
BYTE* pDst1[3], const UINT32 dst1Step[3],
|
BYTE* pDst1[3], const UINT32 dst1Step[3],
|
||||||
BYTE* pDst2[3], const UINT32 dst2Step[3],
|
BYTE* pDst2[3], const UINT32 dst2Step[3],
|
||||||
const prim_size_t* roi)
|
const prim_size_t* roi)
|
||||||
{
|
{
|
||||||
switch (srcFormat)
|
switch (srcFormat)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user