22#include <freerdp/config.h> 
   25#include <winpr/stream.h> 
   26#include <freerdp/log.h> 
   27#include <freerdp/utils/profiler.h> 
   29#include "rdpgfx_common.h" 
   31#include "rdpgfx_codec.h" 
   33#define TAG CHANNELS_TAG("rdpgfx.client") 
   45  UINT error = ERROR_INVALID_DATA;
 
   46  meta->regionRects = NULL;
 
   47  meta->quantQualityVals = NULL;
 
   49  if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
 
   52  Stream_Read_UINT32(s, meta->numRegionRects); 
 
   54  if (!Stream_CheckAndLogRequiredLengthOfSize(TAG, s, meta->numRegionRects, 8ull))
 
   59  if (!meta->regionRects)
 
   61    WLog_ERR(TAG, 
"malloc failed!");
 
   62    error = CHANNEL_RC_NO_MEMORY;
 
   66  meta->quantQualityVals =
 
   69  if (!meta->quantQualityVals)
 
   71    WLog_ERR(TAG, 
"malloc failed!");
 
   72    error = CHANNEL_RC_NO_MEMORY;
 
   76  WLog_DBG(TAG, 
"H264_METABLOCK: numRegionRects: %" PRIu32 
"", meta->numRegionRects);
 
   78  for (UINT32 index = 0; index < meta->numRegionRects; index++)
 
   80    regionRect = &(meta->regionRects[index]);
 
   82    if ((error = rdpgfx_read_rect16(s, regionRect)))
 
   84      WLog_ERR(TAG, 
"rdpgfx_read_rect16 failed with error %" PRIu32 
"!", error);
 
   89             "regionRects[%" PRIu32 
"]: left: %" PRIu16 
" top: %" PRIu16 
" right: %" PRIu16
 
   90             " bottom: %" PRIu16 
"",
 
   91             index, regionRect->left, regionRect->top, regionRect->right, regionRect->bottom);
 
   94  if (!Stream_CheckAndLogRequiredLengthOfSize(TAG, s, meta->numRegionRects, 2ull))
 
   96    error = ERROR_INVALID_DATA;
 
  100  for (UINT32 index = 0; index < meta->numRegionRects; index++)
 
  102    quantQualityVal = &(meta->quantQualityVals[index]);
 
  103    Stream_Read_UINT8(s, quantQualityVal->qpVal);      
 
  104    Stream_Read_UINT8(s, quantQualityVal->qualityVal); 
 
  105    quantQualityVal->qp = quantQualityVal->qpVal & 0x3F;
 
  106    quantQualityVal->r = (quantQualityVal->qpVal >> 6) & 1;
 
  107    quantQualityVal->p = (quantQualityVal->qpVal >> 7) & 1;
 
  109             "quantQualityVals[%" PRIu32 
"]: qp: %" PRIu8 
" r: %" PRIu8 
" p: %" PRIu8
 
  110             " qualityVal: %" PRIu8 
"",
 
  111             index, quantQualityVal->qp, quantQualityVal->r, quantQualityVal->p,
 
  112             quantQualityVal->qualityVal);
 
  115  return CHANNEL_RC_OK;
 
  117  free_h264_metablock(meta);
 
  130  RdpgfxClientContext* context = gfx->context;
 
  131  wStream* s = Stream_New(cmd->data, cmd->length);
 
  135    WLog_ERR(TAG, 
"Stream_New failed!");
 
  136    return CHANNEL_RC_NO_MEMORY;
 
  139  if ((error = rdpgfx_read_h264_metablock(gfx, s, &(h264.meta))))
 
  141    Stream_Free(s, FALSE);
 
  142    WLog_ERR(TAG, 
"rdpgfx_read_h264_metablock failed with error %" PRIu32 
"!", error);
 
  146  h264.data = Stream_Pointer(s);
 
  147  h264.length = (UINT32)Stream_GetRemainingLength(s);
 
  148  Stream_Free(s, FALSE);
 
  149  cmd->extra = (
void*)&h264;
 
  153    IFCALLRET(context->SurfaceCommand, error, context, cmd);
 
  156      WLog_ERR(TAG, 
"context->SurfaceCommand failed with error %" PRIu32 
"", error);
 
  159  free_h264_metablock(&h264.meta);
 
  177  RdpgfxClientContext* context = gfx->context;
 
  178  wStream* s = Stream_New(cmd->data, cmd->length);
 
  182    WLog_ERR(TAG, 
"Stream_New failed!");
 
  183    return CHANNEL_RC_NO_MEMORY;
 
  186  if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
 
  188    error = ERROR_INVALID_DATA;
 
  192  Stream_Read_UINT32(s, tmp);
 
  193  h264.cbAvc420EncodedBitstream1 = tmp & 0x3FFFFFFFUL;
 
  194  h264.LC = (tmp >> 30UL) & 0x03UL;
 
  198    error = ERROR_INVALID_DATA;
 
  202  pos1 = Stream_GetPosition(s);
 
  204  if ((error = rdpgfx_read_h264_metablock(gfx, s, &(h264.bitstream[0].meta))))
 
  206    WLog_ERR(TAG, 
"rdpgfx_read_h264_metablock failed with error %" PRIu32 
"!", error);
 
  210  pos2 = Stream_GetPosition(s);
 
  211  h264.bitstream[0].data = Stream_Pointer(s);
 
  215    const size_t bitstreamLen = 1ULL * h264.cbAvc420EncodedBitstream1 - pos2 + pos1;
 
  217    if ((bitstreamLen > UINT32_MAX) || !Stream_CheckAndLogRequiredLength(TAG, s, bitstreamLen))
 
  219      error = ERROR_INVALID_DATA;
 
  223    h264.bitstream[0].length = (UINT32)bitstreamLen;
 
  224    Stream_Seek(s, bitstreamLen);
 
  226    if ((error = rdpgfx_read_h264_metablock(gfx, s, &(h264.bitstream[1].meta))))
 
  228      WLog_ERR(TAG, 
"rdpgfx_read_h264_metablock failed with error %" PRIu32 
"!", error);
 
  232    h264.bitstream[1].data = Stream_Pointer(s);
 
  234    const size_t len = Stream_GetRemainingLength(s);
 
  235    if (len > UINT32_MAX)
 
  237    h264.bitstream[1].length = (UINT32)len;
 
  241    const size_t len = Stream_GetRemainingLength(s);
 
  242    if (len > UINT32_MAX)
 
  244    h264.bitstream[0].length = (UINT32)len;
 
  247  cmd->extra = (
void*)&h264;
 
  251    IFCALLRET(context->SurfaceCommand, error, context, cmd);
 
  254      WLog_ERR(TAG, 
"context->SurfaceCommand failed with error %" PRIu32 
"", error);
 
  258  Stream_Free(s, FALSE);
 
  259  free_h264_metablock(&h264.bitstream[0].meta);
 
  260  free_h264_metablock(&h264.bitstream[1].meta);
 
  272  UINT error = CHANNEL_RC_OK;
 
  273  RdpgfxClientContext* context = gfx->context;
 
  274  PROFILER_ENTER(context->SurfaceProfiler)
 
  276  switch (cmd->codecId)
 
  278    case RDPGFX_CODECID_AVC420:
 
  279      if ((error = rdpgfx_decode_AVC420(gfx, cmd)))
 
  280        WLog_ERR(TAG, 
"rdpgfx_decode_AVC420 failed with error %" PRIu32 
"", error);
 
  284    case RDPGFX_CODECID_AVC444:
 
  285    case RDPGFX_CODECID_AVC444v2:
 
  286      if ((error = rdpgfx_decode_AVC444(gfx, cmd)))
 
  287        WLog_ERR(TAG, 
"rdpgfx_decode_AVC444 failed with error %" PRIu32 
"", error);
 
  294        IFCALLRET(context->SurfaceCommand, error, context, cmd);
 
  297          WLog_ERR(TAG, 
"context->SurfaceCommand failed with error %" PRIu32 
"", error);
 
  303  PROFILER_EXIT(context->SurfaceProfiler)