H264_CONTEXT* h264_context_new(BOOL Compressor) { H264_CONTEXT* h264; h264 = (H264_CONTEXT*) calloc(1, sizeof(H264_CONTEXT)); if (h264) { h264->Compressor = Compressor; #ifdef WITH_OPENH264 { static EVideoFormatType videoFormat = videoFormatI420; SDecodingParam sDecParam; long status; WelsCreateDecoder(&h264->pDecoder); if (!h264->pDecoder) { printf("Failed to create OpenH264 decoder\n"); goto EXCEPTION; } ZeroMemory(&sDecParam, sizeof(sDecParam)); sDecParam.iOutputColorFormat = videoFormatARGB; status = (*h264->pDecoder)->Initialize(h264->pDecoder, &sDecParam); if (status != 0) { printf("Failed to initialize OpenH264 decoder (status=%ld)\n", status); goto EXCEPTION; } status = (*h264->pDecoder)->SetOption(h264->pDecoder, DECODER_OPTION_DATAFORMAT, &videoFormat); if (status != 0) { printf("Failed to set data format option on OpenH264 decoder (status=%ld)\n", status); } } #endif h264_context_reset(h264); } return h264; EXCEPTION: #ifdef WITH_OPENH264 if (h264->pDecoder) { WelsDestroyDecoder(h264->pDecoder); } #endif free(h264); return NULL; }
static int shadow_encoder_init_h264(rdpShadowEncoder* encoder) { if (!encoder->h264) encoder->h264 = h264_context_new(TRUE); if (!encoder->h264) goto fail; if (!h264_context_reset(encoder->h264, encoder->width, encoder->height)) goto fail; encoder->h264->RateControlMode = encoder->server->h264RateControlMode; encoder->h264->BitRate = encoder->server->h264BitRate; encoder->h264->FrameRate = encoder->server->h264FrameRate; encoder->h264->QP = encoder->server->h264QP; encoder->codecs |= FREERDP_CODEC_AVC420; return 1; fail: h264_context_free(encoder->h264); return -1; }
BOOL freerdp_client_codecs_reset(rdpCodecs* codecs, UINT32 flags, UINT32 width, UINT32 height) { BOOL rc = TRUE; if (!freerdp_client_codecs_prepare(codecs, flags)) return FALSE; if (flags & FREERDP_CODEC_INTERLEAVED) { if (codecs->interleaved) { rc &= bitmap_interleaved_context_reset(codecs->interleaved); } } if (flags & FREERDP_CODEC_PLANAR) { if (codecs->planar) { rc &= freerdp_bitmap_planar_context_reset(codecs->planar); } } if (flags & FREERDP_CODEC_NSCODEC) { if (codecs->nsc) { rc &= nsc_context_reset(codecs->nsc, width, height); } } if (flags & FREERDP_CODEC_REMOTEFX) { if (codecs->rfx) { rc &= rfx_context_reset(codecs->rfx, width, height); } } if (flags & FREERDP_CODEC_CLEARCODEC) { if (codecs->clear) { rc &= clear_context_reset(codecs->clear); } } if (flags & FREERDP_CODEC_ALPHACODEC) { } if (flags & FREERDP_CODEC_PROGRESSIVE) { if (codecs->progressive) { rc &= progressive_context_reset(codecs->progressive); } } if (flags & (FREERDP_CODEC_AVC420 | FREERDP_CODEC_AVC444)) { if (codecs->h264) { rc &= h264_context_reset(codecs->h264, width, height); } } return rc; }
BOOL freerdp_client_codecs_reset(rdpCodecs* codecs, UINT32 flags) { if (flags & FREERDP_CODEC_INTERLEAVED) { if (codecs->interleaved) { bitmap_interleaved_context_reset(codecs->interleaved); } } if (flags & FREERDP_CODEC_PLANAR) { if (codecs->planar) { freerdp_bitmap_planar_context_reset(codecs->planar); } } if (flags & FREERDP_CODEC_NSCODEC) { if (codecs->nsc) { nsc_context_reset(codecs->nsc); } } if (flags & FREERDP_CODEC_REMOTEFX) { if (codecs->rfx) { rfx_context_reset(codecs->rfx); } } if (flags & FREERDP_CODEC_CLEARCODEC) { if (codecs->clear) { clear_context_reset(codecs->clear); } } if (flags & FREERDP_CODEC_ALPHACODEC) { } if (flags & FREERDP_CODEC_PROGRESSIVE) { if (codecs->progressive) { progressive_context_reset(codecs->progressive); } } if (flags & FREERDP_CODEC_H264) { if (codecs->h264) { h264_context_reset(codecs->h264); } } return TRUE; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT gdi_SurfaceCommand_AVC444(rdpGdi* gdi, RdpgfxClientContext* context, const RDPGFX_SURFACE_COMMAND* cmd) { #ifdef WITH_GFX_H264 INT32 rc; UINT status = CHANNEL_RC_OK; UINT32 i; gdiGfxSurface* surface; RDPGFX_AVC444_BITMAP_STREAM* bs; RDPGFX_AVC420_BITMAP_STREAM* avc1; RDPGFX_H264_METABLOCK* meta1; RDPGFX_AVC420_BITMAP_STREAM* avc2; RDPGFX_H264_METABLOCK* meta2; RECTANGLE_16* regionRects = NULL; surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); if (!surface) { WLog_ERR(TAG, "%s: unable to retrieve surfaceData for surfaceId=%"PRIu32"", __FUNCTION__, cmd->surfaceId); return ERROR_NOT_FOUND; } if (!surface->h264) { surface->h264 = h264_context_new(FALSE); if (!surface->h264) { WLog_ERR(TAG, "%s: unable to create h264 context", __FUNCTION__); return ERROR_NOT_ENOUGH_MEMORY; } if (!h264_context_reset(surface->h264, surface->width, surface->height)) return ERROR_INTERNAL_ERROR; } bs = (RDPGFX_AVC444_BITMAP_STREAM*) cmd->extra; if (!bs) return ERROR_INTERNAL_ERROR; avc1 = &bs->bitstream[0]; avc2 = &bs->bitstream[1]; meta1 = &avc1->meta; meta2 = &avc2->meta; rc = avc444_decompress(surface->h264, bs->LC, meta1->regionRects, meta1->numRegionRects, avc1->data, avc1->length, meta2->regionRects, meta2->numRegionRects, avc2->data, avc2->length, surface->data, surface->format, surface->scanline, surface->width, surface->height, cmd->codecId); if (rc < 0) { WLog_WARN(TAG, "avc444_decompress failure: %"PRIu32", ignoring update.", status); return CHANNEL_RC_OK; } for (i = 0; i < meta1->numRegionRects; i++) { region16_union_rect(&(surface->invalidRegion), &(surface->invalidRegion), &(meta1->regionRects[i])); } IFCALL(context->UpdateSurfaceArea, context, surface->surfaceId, meta1->numRegionRects, meta1->regionRects); for (i = 0; i < meta2->numRegionRects; i++) { region16_union_rect(&(surface->invalidRegion), &(surface->invalidRegion), &(meta2->regionRects[i])); } IFCALL(context->UpdateSurfaceArea, context, surface->surfaceId, meta2->numRegionRects, meta2->regionRects); if (!gdi->inGfxFrame) { status = CHANNEL_RC_NOT_INITIALIZED; IFCALLRET(context->UpdateSurfaces, status, context); } free(regionRects); return status; #else return ERROR_NOT_SUPPORTED; #endif }
static PresentationContext *PresentationContext_new(VideoClientContext *video, BYTE PresentationId, UINT32 x, UINT32 y, UINT32 width, UINT32 height) { VideoClientContextPriv *priv = video->priv; PresentationContext *ret = calloc(1, sizeof(*ret)); if (!ret) return NULL; ret->video = video; ret->PresentationId = PresentationId; ret->h264 = h264_context_new(FALSE); if (!ret->h264) { WLog_ERR(TAG, "unable to create a h264 context"); goto error_h264; } h264_context_reset(ret->h264, width, height); ret->currentSample = Stream_New(NULL, 4096); if (!ret->currentSample) { WLog_ERR(TAG, "unable to create current packet stream"); goto error_currentSample; } ret->surfaceData = BufferPool_Take(priv->surfacePool, width * height * 4); if (!ret->surfaceData) { WLog_ERR(TAG, "unable to allocate surfaceData"); goto error_surfaceData; } ret->surface = video->createSurface(video, ret->surfaceData, x, y, width, height); if (!ret->surface) { WLog_ERR(TAG, "unable to create surface"); goto error_surface; } ret->yuv = yuv_context_new(FALSE); if (!ret->yuv) { WLog_ERR(TAG, "unable to create YUV decoder"); goto error_yuv; } yuv_context_reset(ret->yuv, width, height); ret->refCounter = 1; return ret; error_yuv: video->deleteSurface(video, ret->surface); error_surface: BufferPool_Return(priv->surfacePool, ret->surfaceData); error_surfaceData: Stream_Free(ret->currentSample, TRUE); error_currentSample: h264_context_free(ret->h264); error_h264: free(ret); return NULL; }