From 9501b6c58ec9fac3fce231ede68fd6e1c2946a78 Mon Sep 17 00:00:00 2001 From: erbth Date: Thu, 17 Jul 2014 16:25:34 +0200 Subject: [PATCH] OpenH264 first frame decode fix --- channels/rdpgfx/client/rdpgfx_codec.c | 6 +++ client/X11/xf_gfx.c | 10 +++- libfreerdp/codec/h264.c | 76 +++++++++++++++++++++++---- 3 files changed, 82 insertions(+), 10 deletions(-) diff --git a/channels/rdpgfx/client/rdpgfx_codec.c b/channels/rdpgfx/client/rdpgfx_codec.c index 4881db399..d621eea42 100644 --- a/channels/rdpgfx/client/rdpgfx_codec.c +++ b/channels/rdpgfx/client/rdpgfx_codec.c @@ -72,15 +72,19 @@ int rdpgfx_read_h264_metablock(RDPGFX_PLUGIN* gfx, wStream* s, RDPGFX_H264_METAB if (!meta->quantQualityVals) return -1; +#if 0 printf("H264_METABLOCK: numRegionRects: %d\n", (int) meta->numRegionRects); +#endif for (index = 0; index < meta->numRegionRects; index++) { regionRect = &(meta->regionRects[index]); rdpgfx_read_rect16(s, regionRect); +#if 0 printf("regionRects[%d]: left: %d top: %d right: %d bottom: %d\n", index, regionRect->left, regionRect->top, regionRect->right, regionRect->bottom); +#endif } if (Stream_GetRemainingLength(s) < (meta->numRegionRects * 2)) @@ -96,8 +100,10 @@ int rdpgfx_read_h264_metablock(RDPGFX_PLUGIN* gfx, wStream* s, RDPGFX_H264_METAB quantQualityVal->r = (quantQualityVal->qpVal >> 6) & 1; quantQualityVal->p = (quantQualityVal->qpVal >> 7) & 1; +#if 0 printf("quantQualityVals[%d]: qp: %d r: %d p: %d qualityVal: %d\n", index, quantQualityVal->qp, quantQualityVal->r, quantQualityVal->p, quantQualityVal->qualityVal); +#endif } return 1; diff --git a/client/X11/xf_gfx.c b/client/X11/xf_gfx.c index bf04042f6..da4d41101 100644 --- a/client/X11/xf_gfx.c +++ b/client/X11/xf_gfx.c @@ -297,6 +297,7 @@ int xf_SurfaceCommand_ClearCodec(xfContext* xfc, RdpgfxClientContext* context, R region16_union_rect(&(xfc->invalidRegion), &(xfc->invalidRegion), &invalidRect); + if (!xfc->inGfxFrame) xf_OutputUpdate(xfc); @@ -397,9 +398,12 @@ int xf_SurfaceCommand_H264(xfContext* xfc, RdpgfxClientContext* context, RDPGFX_ region16_init(&updateRegion); region16_intersect_rect(&updateRegion, &clippingRects, &updateRect); + updateRects = (RECTANGLE_16*) region16_rects(&updateRegion, &nbUpdateRects); +#if 0 printf("numRegionRects: %d nbUpdateRects: %d\n", meta->numRegionRects, nbUpdateRects); +#endif for (j = 0; j < nbUpdateRects; j++) { @@ -410,14 +414,17 @@ int xf_SurfaceCommand_H264(xfContext* xfc, RdpgfxClientContext* context, RDPGFX_ /* update region from decoded H264 buffer */ +#if 0 printf("nXDst: %d nYDst: %d nWidth: %d nHeight: %d decoded: width: %d height: %d cmd: left: %d top: %d right: %d bottom: %d\n", nXDst, nYDst, nWidth, nHeight, h264->width, h264->height, cmd->left, cmd->top, cmd->right, cmd->bottom); +#endif freerdp_image_copy(surface->data, PIXEL_FORMAT_XRGB32, surface->scanline, nXDst, nYDst, nWidth, nHeight, h264->data, PIXEL_FORMAT_XRGB32, h264->scanline, nXDst, nYDst); + region16_union_rect(&(xfc->invalidRegion), &(xfc->invalidRegion), &updateRects[j]); } @@ -430,8 +437,9 @@ int xf_SurfaceCommand_H264(xfContext* xfc, RdpgfxClientContext* context, RDPGFX_ cmd->left, cmd->top, cmd->width, cmd->height, 0xFF0000); #endif - if (!xfc->inGfxFrame) + if (!xfc->inGfxFrame){ xf_OutputUpdate(xfc); + } return 1; } diff --git a/libfreerdp/codec/h264.c b/libfreerdp/codec/h264.c index 4b0d1de68..c532bc81c 100644 --- a/libfreerdp/codec/h264.c +++ b/libfreerdp/codec/h264.c @@ -28,9 +28,9 @@ #include #include -#define USE_GRAY_SCALE 1 +#define USE_GRAY_SCALE 0 #define USE_UPCONVERT 0 -#define USE_TRACE 1 +#define USE_TRACE 0 static BYTE clip(int x) { @@ -189,11 +189,12 @@ int freerdp_image_copy_yuv420p_to_xrgb(BYTE* pDstData, int nDstStep, int nXDst, { int x, y; BYTE* pDstPixel8; - BYTE *pY, *pU, *pV; + BYTE *pY, *pU, *pV, *pUv, *pVv; + int temp1=0,temp2=0; pY = pSrcData[0]; - pU = pSrcData[1]; - pV = pSrcData[0]; + pUv = pU = pSrcData[1]; + pVv = pV = pSrcData[2]; pDstPixel8 = &pDstData[(nYDst * nDstStep) + (nXDst * 4)]; @@ -201,13 +202,33 @@ int freerdp_image_copy_yuv420p_to_xrgb(BYTE* pDstData, int nDstStep, int nXDst, { for (x = 0; x < nWidth; x++) { - *((UINT32*) pDstPixel8) = RGB32(*pY, *pY, *pY); +/* *((UINT32*) pDstPixel8) = RGB32(*pY, *pY, *pY);*/ + *((UINT32*) pDstPixel8) = YUV_to_RGB(*pY,*pU,*pV); pDstPixel8 += 4; pY++; + + if(temp1){ + temp1=0; + pU++; + pV++; + }else{ + temp1=1; + } } pDstPixel8 += (nDstStep - (nWidth * 4)); pY += (nSrcStep[0] - nWidth); + if(temp2){ + temp2=0; + pU += (nSrcStep[1] - nWidth / 2); + pV += (nSrcStep[1] - nWidth / 2); + pUv = pU; + pVv = pV; + }else{ + temp2=1; + pU = pUv; + pV = pVv; + } } return 1; @@ -282,7 +303,7 @@ int h264_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize, pSrcData = h264_strip_nal_unit_au_delimiter(pSrcData, &SrcSize); -#if 1 +#if 0 printf("h264_decompress: pSrcData=%p, SrcSize=%u, pDstData=%p, nDstStep=%d, nXDst=%d, nYDst=%d, nWidth=%d, nHeight=%d)\n", pSrcData, SrcSize, *ppDstData, nDstStep, nXDst, nYDst, nWidth, nHeight); #endif @@ -335,9 +356,17 @@ int h264_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize, pYUVData, &sBufferInfo); + + state = (*h264->pDecoder)->DecodeFrame2( + h264->pDecoder, + NULL, + 0, + pYUVData, + &sBufferInfo); + pSystemBuffer = &sBufferInfo.UsrData.sSystemBuffer; -#if 1 +#if 0 printf("h264_decompress: state=%u, pYUVData=[%p,%p,%p], bufferStatus=%d, width=%d, height=%d, format=%d, stride=[%d,%d]\n", state, pYUVData[0], pYUVData[1], pYUVData[2], sBufferInfo.iBufferStatus, pSystemBuffer->iWidth, pSystemBuffer->iHeight, pSystemBuffer->iFormat, @@ -387,7 +416,6 @@ int h264_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize, fclose(fp); } - g_H264FrameId++; if (h264_prepare_rgb_buffer(h264, pSystemBuffer->iWidth, pSystemBuffer->iHeight) < 0) return -1; @@ -395,6 +423,35 @@ int h264_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize, freerdp_image_copy_yuv420p_to_xrgb(h264->data, h264->scanline, 0, 0, h264->width, h264->height, pYUVData, pSystemBuffer->iStride, 0, 0); + if (g_H264DumpFrames) + { + FILE* fp; + BYTE* srcp; + char buf[4096]; + + snprintf(buf, sizeof(buf), "/tmp/wlog/H264_%d_rgb.ppm", g_H264FrameId); + fp = fopen(buf, "wb"); + fwrite("P6\n", 1, 3, fp); + snprintf(buf, sizeof(buf), "%d %d\n", pSystemBuffer->iWidth, pSystemBuffer->iHeight); + fwrite(buf, 1, strlen(buf), fp); + fwrite("255\n", 1, 4, fp); + + srcp = h264->data; + + for (j = 0; j < h264->height; j++) + { + for(i=0;iwidth;i++){ + fwrite(srcp, 1, 3, fp); + srcp += 4; + } + } + + fflush(fp); + fclose(fp); + } + + g_H264FrameId++; + return 1; #if USE_UPCONVERT @@ -499,6 +556,7 @@ H264_CONTEXT* h264_context_new(BOOL Compressor) printf("Failed to set data format option on OpenH264 decoder (status=%ld)\n", status); } + #if USE_TRACE status = (*h264->pDecoder)->SetOption(h264->pDecoder, DECODER_OPTION_TRACE_LEVEL, &traceLevel); if (status != 0)