channels/rdpgfx: parse H264 bitmap stream and meta block
This commit is contained in:
parent
f7e5365719
commit
6f1acb01dd
@ -48,39 +48,47 @@ int rdpgfx_decode_planar(RDPGFX_PLUGIN* gfx, RDPGFX_SURFACE_COMMAND* cmd)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int rdpgfx_read_h264_metablock(RDPGFX_PLUGIN* gfx, wStream* s)
|
||||
int rdpgfx_read_h264_metablock(RDPGFX_PLUGIN* gfx, wStream* s, RDPGFX_H264_METABLOCK* meta)
|
||||
{
|
||||
UINT32 index;
|
||||
RDPGFX_RECT16* regionRect;
|
||||
RDPGFX_H264_METABLOCK metablock;
|
||||
RDPGFX_H264_QUANT_QUALITY* quantQualityVal;
|
||||
|
||||
Stream_Read_UINT32(s, metablock.numRegionRects); /* numRegionRects (4 bytes) */
|
||||
|
||||
metablock.regionRects = (RDPGFX_RECT16*) malloc(metablock.numRegionRects * sizeof(RDPGFX_RECT16));
|
||||
|
||||
if (!metablock.regionRects)
|
||||
if (Stream_GetRemainingLength(s) < 4)
|
||||
return -1;
|
||||
|
||||
metablock.quantQualityVals = (RDPGFX_H264_QUANT_QUALITY*) malloc(metablock.numRegionRects * sizeof(RDPGFX_H264_QUANT_QUALITY));
|
||||
Stream_Read_UINT32(s, meta->numRegionRects); /* numRegionRects (4 bytes) */
|
||||
|
||||
if (!metablock.quantQualityVals)
|
||||
if (Stream_GetRemainingLength(s) < (meta->numRegionRects * 8))
|
||||
return -1;
|
||||
|
||||
printf("H264_METABLOCK: numRegionRects: %d\n", (int) metablock.numRegionRects);
|
||||
meta->regionRects = (RDPGFX_RECT16*) malloc(meta->numRegionRects * sizeof(RDPGFX_RECT16));
|
||||
|
||||
for (index = 0; index < metablock.numRegionRects; index++)
|
||||
if (!meta->regionRects)
|
||||
return -1;
|
||||
|
||||
meta->quantQualityVals = (RDPGFX_H264_QUANT_QUALITY*) malloc(meta->numRegionRects * sizeof(RDPGFX_H264_QUANT_QUALITY));
|
||||
|
||||
if (!meta->quantQualityVals)
|
||||
return -1;
|
||||
|
||||
printf("H264_METABLOCK: numRegionRects: %d\n", (int) meta->numRegionRects);
|
||||
|
||||
for (index = 0; index < meta->numRegionRects; index++)
|
||||
{
|
||||
regionRect = &(metablock.regionRects[index]);
|
||||
regionRect = &(meta->regionRects[index]);
|
||||
rdpgfx_read_rect16(s, regionRect);
|
||||
|
||||
printf("regionRects[%d]: left: %d top: %d right: %d bottom: %d\n",
|
||||
index, regionRect->left, regionRect->top, regionRect->right, regionRect->bottom);
|
||||
}
|
||||
|
||||
for (index = 0; index < metablock.numRegionRects; index++)
|
||||
if (Stream_GetRemainingLength(s) < (meta->numRegionRects * 2))
|
||||
return -1;
|
||||
|
||||
for (index = 0; index < meta->numRegionRects; index++)
|
||||
{
|
||||
quantQualityVal = &(metablock.quantQualityVals[index]);
|
||||
quantQualityVal = &(meta->quantQualityVals[index]);
|
||||
Stream_Read_UINT8(s, quantQualityVal->qpVal); /* qpVal (1 byte) */
|
||||
Stream_Read_UINT8(s, quantQualityVal->qualityVal); /* qualityVal (1 byte) */
|
||||
|
||||
@ -92,22 +100,41 @@ int rdpgfx_read_h264_metablock(RDPGFX_PLUGIN* gfx, wStream* s)
|
||||
index, quantQualityVal->qp, quantQualityVal->r, quantQualityVal->p, quantQualityVal->qualityVal);
|
||||
}
|
||||
|
||||
free(metablock.regionRects);
|
||||
free(metablock.quantQualityVals);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int rdpgfx_decode_h264(RDPGFX_PLUGIN* gfx, RDPGFX_SURFACE_COMMAND* cmd)
|
||||
{
|
||||
int status;
|
||||
wStream* s;
|
||||
RDPGFX_H264_BITMAP_STREAM h264;
|
||||
RdpgfxClientContext* context = (RdpgfxClientContext*) gfx->iface.pInterface;
|
||||
|
||||
s = Stream_New(cmd->data, cmd->length);
|
||||
|
||||
rdpgfx_read_h264_metablock(gfx, s);
|
||||
if (!s)
|
||||
return -1;
|
||||
|
||||
status = rdpgfx_read_h264_metablock(gfx, s, &(h264.meta));
|
||||
|
||||
if (status < 0)
|
||||
return -1;
|
||||
|
||||
h264.data = Stream_Pointer(s);
|
||||
h264.length = (UINT32) Stream_GetRemainingLength(s);
|
||||
|
||||
Stream_Free(s, FALSE);
|
||||
|
||||
cmd->extra = (void*) &h264;
|
||||
|
||||
if (context && context->SurfaceCommand)
|
||||
{
|
||||
context->SurfaceCommand(context, cmd);
|
||||
}
|
||||
|
||||
free(h264.meta.regionRects);
|
||||
free(h264.meta.quantQualityVals);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -427,11 +427,15 @@ int rdpgfx_recv_wire_to_surface_1_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream
|
||||
cmd.data = pdu.bitmapData;
|
||||
|
||||
if (cmd.codecId == RDPGFX_CODECID_H264)
|
||||
rdpgfx_decode(gfx, &cmd);
|
||||
|
||||
if (context && context->SurfaceCommand)
|
||||
{
|
||||
context->SurfaceCommand(context, &cmd);
|
||||
rdpgfx_decode(gfx, &cmd);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (context && context->SurfaceCommand)
|
||||
{
|
||||
context->SurfaceCommand(context, &cmd);
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
@ -339,6 +339,12 @@ int xf_SurfaceCommand_H264(xfContext* xfc, RdpgfxClientContext* context, RDPGFX_
|
||||
BYTE* DstData = NULL;
|
||||
xfGfxSurface* surface;
|
||||
RECTANGLE_16 invalidRect;
|
||||
RDPGFX_H264_BITMAP_STREAM* h264;
|
||||
|
||||
h264 = (RDPGFX_H264_BITMAP_STREAM*) cmd->extra;
|
||||
|
||||
if (!h264)
|
||||
return -1;
|
||||
|
||||
surface = (xfGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId);
|
||||
|
||||
@ -348,7 +354,7 @@ int xf_SurfaceCommand_H264(xfContext* xfc, RdpgfxClientContext* context, RDPGFX_
|
||||
DstData = surface->data;
|
||||
|
||||
#if 1
|
||||
status = h264_decompress(xfc->h264, cmd->data, cmd->length, &DstData,
|
||||
status = h264_decompress(xfc->h264, h264->data, h264->length, &DstData,
|
||||
PIXEL_FORMAT_XRGB32, surface->scanline, cmd->left, cmd->top, cmd->width, cmd->height);
|
||||
#else
|
||||
status = -1;
|
||||
|
@ -179,6 +179,7 @@ struct _RDPGFX_SURFACE_COMMAND
|
||||
UINT32 height;
|
||||
UINT32 length;
|
||||
BYTE* data;
|
||||
void* extra;
|
||||
};
|
||||
typedef struct _RDPGFX_SURFACE_COMMAND RDPGFX_SURFACE_COMMAND;
|
||||
|
||||
@ -353,5 +354,13 @@ struct _RDPGFX_H264_METABLOCK
|
||||
};
|
||||
typedef struct _RDPGFX_H264_METABLOCK RDPGFX_H264_METABLOCK;
|
||||
|
||||
struct _RDPGFX_H264_BITMAP_STREAM
|
||||
{
|
||||
RDPGFX_H264_METABLOCK meta;
|
||||
UINT32 length;
|
||||
BYTE* data;
|
||||
};
|
||||
typedef struct _RDPGFX_H264_BITMAP_STREAM RDPGFX_H264_BITMAP_STREAM;
|
||||
|
||||
#endif /* FREERDP_CHANNEL_RDPGFX_H */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user