Loading media/codec2/components/aom/C2SoftAomDec.cpp +5 −128 Original line number Diff line number Diff line Loading @@ -505,124 +505,6 @@ void C2SoftAomDec::process(const std::unique_ptr<C2Work>& work, } } static void copyOutputBufferToYuvPlanarFrame( uint8_t *dstY, uint8_t *dstU, uint8_t *dstV, const uint8_t *srcY, const uint8_t *srcU, const uint8_t *srcV, size_t srcYStride, size_t srcUStride, size_t srcVStride, size_t dstYStride, size_t dstUVStride, uint32_t width, uint32_t height) { for (size_t i = 0; i < height; ++i) { memcpy(dstY, srcY, width); srcY += srcYStride; dstY += dstYStride; } for (size_t i = 0; i < height / 2; ++i) { memcpy(dstV, srcV, width / 2); srcV += srcVStride; dstV += dstUVStride; } for (size_t i = 0; i < height / 2; ++i) { memcpy(dstU, srcU, width / 2); srcU += srcUStride; dstU += dstUVStride; } } static void convertYUV420Planar16ToY410(uint32_t *dst, const uint16_t *srcY, const uint16_t *srcU, const uint16_t *srcV, size_t srcYStride, size_t srcUStride, size_t srcVStride, size_t dstStride, size_t width, size_t height) { // Converting two lines at a time, slightly faster for (size_t y = 0; y < height; y += 2) { uint32_t *dstTop = (uint32_t *) dst; uint32_t *dstBot = (uint32_t *) (dst + dstStride); uint16_t *ySrcTop = (uint16_t*) srcY; uint16_t *ySrcBot = (uint16_t*) (srcY + srcYStride); uint16_t *uSrc = (uint16_t*) srcU; uint16_t *vSrc = (uint16_t*) srcV; uint32_t u01, v01, y01, y23, y45, y67, uv0, uv1; size_t x = 0; for (; x < width - 3; x += 4) { u01 = *((uint32_t*)uSrc); uSrc += 2; v01 = *((uint32_t*)vSrc); vSrc += 2; y01 = *((uint32_t*)ySrcTop); ySrcTop += 2; y23 = *((uint32_t*)ySrcTop); ySrcTop += 2; y45 = *((uint32_t*)ySrcBot); ySrcBot += 2; y67 = *((uint32_t*)ySrcBot); ySrcBot += 2; uv0 = (u01 & 0x3FF) | ((v01 & 0x3FF) << 20); uv1 = (u01 >> 16) | ((v01 >> 16) << 20); *dstTop++ = 3 << 30 | ((y01 & 0x3FF) << 10) | uv0; *dstTop++ = 3 << 30 | ((y01 >> 16) << 10) | uv0; *dstTop++ = 3 << 30 | ((y23 & 0x3FF) << 10) | uv1; *dstTop++ = 3 << 30 | ((y23 >> 16) << 10) | uv1; *dstBot++ = 3 << 30 | ((y45 & 0x3FF) << 10) | uv0; *dstBot++ = 3 << 30 | ((y45 >> 16) << 10) | uv0; *dstBot++ = 3 << 30 | ((y67 & 0x3FF) << 10) | uv1; *dstBot++ = 3 << 30 | ((y67 >> 16) << 10) | uv1; } // There should be at most 2 more pixels to process. Note that we don't // need to consider odd case as the buffer is always aligned to even. if (x < width) { u01 = *uSrc; v01 = *vSrc; y01 = *((uint32_t*)ySrcTop); y45 = *((uint32_t*)ySrcBot); uv0 = (u01 & 0x3FF) | ((v01 & 0x3FF) << 20); *dstTop++ = ((y01 & 0x3FF) << 10) | uv0; *dstTop++ = ((y01 >> 16) << 10) | uv0; *dstBot++ = ((y45 & 0x3FF) << 10) | uv0; *dstBot++ = ((y45 >> 16) << 10) | uv0; } srcY += srcYStride * 2; srcU += srcUStride; srcV += srcVStride; dst += dstStride * 2; } return; } static void convertYUV420Planar16ToYUV420Planar( uint8_t *dstY, uint8_t *dstU, uint8_t *dstV, const uint16_t *srcY, const uint16_t *srcU, const uint16_t *srcV, size_t srcYStride, size_t srcUStride, size_t srcVStride, size_t dstYStride, size_t dstUVStride, size_t width, size_t height) { for (size_t y = 0; y < height; ++y) { for (size_t x = 0; x < width; ++x) { dstY[x] = (uint8_t)(srcY[x] >> 2); } srcY += srcYStride; dstY += dstYStride; } for (size_t y = 0; y < (height + 1) / 2; ++y) { for (size_t x = 0; x < (width + 1) / 2; ++x) { dstU[x] = (uint8_t)(srcU[x] >> 2); dstV[x] = (uint8_t)(srcV[x] >> 2); } srcU += srcUStride; srcV += srcVStride; dstU += dstUVStride; dstV += dstUVStride; } return; } bool C2SoftAomDec::outputBuffer( const std::shared_ptr<C2BlockPool> &pool, const std::unique_ptr<C2Work> &work) Loading Loading @@ -711,21 +593,16 @@ bool C2SoftAomDec::outputBuffer( dstYStride / sizeof(uint32_t), mWidth, mHeight); } else { convertYUV420Planar16ToYUV420Planar(dstY, dstU, dstV, srcY, srcU, srcV, srcYStride / 2, srcUStride / 2, srcVStride / 2, dstYStride, dstUVStride, convertYUV420Planar16ToYV12(dstY, dstU, dstV, srcY, srcU, srcV, srcYStride / 2, srcUStride / 2, srcVStride / 2, dstYStride, dstUVStride, mWidth, mHeight); } } else { const uint8_t *srcY = (const uint8_t *)img->planes[AOM_PLANE_Y]; const uint8_t *srcU = (const uint8_t *)img->planes[AOM_PLANE_U]; const uint8_t *srcV = (const uint8_t *)img->planes[AOM_PLANE_V]; copyOutputBufferToYuvPlanarFrame( dstY, dstU, dstV, srcY, srcU, srcV, srcYStride, srcUStride, srcVStride, dstYStride, dstUVStride, mWidth, mHeight); convertYUV420Planar8ToYV12(dstY, dstU, dstV, srcY, srcU, srcV, srcYStride, srcUStride, srcVStride, dstYStride, dstUVStride, mWidth, mHeight); } finishWork(*(int64_t*)img->user_priv, work, std::move(block)); block = nullptr; Loading media/codec2/components/base/SimpleC2Component.cpp +172 −0 Original line number Diff line number Diff line Loading @@ -29,7 +29,179 @@ #include <SimpleC2Component.h> namespace android { constexpr uint8_t kNeutralUVBitDepth8 = 128; constexpr uint16_t kNeutralUVBitDepth10 = 512; void convertYUV420Planar8ToYV12(uint8_t *dstY, uint8_t *dstU, uint8_t *dstV, const uint8_t *srcY, const uint8_t *srcU, const uint8_t *srcV, size_t srcYStride, size_t srcUStride, size_t srcVStride, size_t dstYStride, size_t dstUVStride, uint32_t width, uint32_t height, bool isMonochrome) { for (size_t i = 0; i < height; ++i) { memcpy(dstY, srcY, width); srcY += srcYStride; dstY += dstYStride; } if (isMonochrome) { // Fill with neutral U/V values. for (size_t i = 0; i < height / 2; ++i) { memset(dstV, kNeutralUVBitDepth8, width / 2); memset(dstU, kNeutralUVBitDepth8, width / 2); dstV += dstUVStride; dstU += dstUVStride; } return; } for (size_t i = 0; i < height / 2; ++i) { memcpy(dstV, srcV, width / 2); srcV += srcVStride; dstV += dstUVStride; } for (size_t i = 0; i < height / 2; ++i) { memcpy(dstU, srcU, width / 2); srcU += srcUStride; dstU += dstUVStride; } } void convertYUV420Planar16ToY410(uint32_t *dst, const uint16_t *srcY, const uint16_t *srcU, const uint16_t *srcV, size_t srcYStride, size_t srcUStride, size_t srcVStride, size_t dstStride, size_t width, size_t height) { // Converting two lines at a time, slightly faster for (size_t y = 0; y < height; y += 2) { uint32_t *dstTop = (uint32_t *)dst; uint32_t *dstBot = (uint32_t *)(dst + dstStride); uint16_t *ySrcTop = (uint16_t *)srcY; uint16_t *ySrcBot = (uint16_t *)(srcY + srcYStride); uint16_t *uSrc = (uint16_t *)srcU; uint16_t *vSrc = (uint16_t *)srcV; uint32_t u01, v01, y01, y23, y45, y67, uv0, uv1; size_t x = 0; for (; x < width - 3; x += 4) { u01 = *((uint32_t *)uSrc); uSrc += 2; v01 = *((uint32_t *)vSrc); vSrc += 2; y01 = *((uint32_t *)ySrcTop); ySrcTop += 2; y23 = *((uint32_t *)ySrcTop); ySrcTop += 2; y45 = *((uint32_t *)ySrcBot); ySrcBot += 2; y67 = *((uint32_t *)ySrcBot); ySrcBot += 2; uv0 = (u01 & 0x3FF) | ((v01 & 0x3FF) << 20); uv1 = (u01 >> 16) | ((v01 >> 16) << 20); *dstTop++ = 3 << 30 | ((y01 & 0x3FF) << 10) | uv0; *dstTop++ = 3 << 30 | ((y01 >> 16) << 10) | uv0; *dstTop++ = 3 << 30 | ((y23 & 0x3FF) << 10) | uv1; *dstTop++ = 3 << 30 | ((y23 >> 16) << 10) | uv1; *dstBot++ = 3 << 30 | ((y45 & 0x3FF) << 10) | uv0; *dstBot++ = 3 << 30 | ((y45 >> 16) << 10) | uv0; *dstBot++ = 3 << 30 | ((y67 & 0x3FF) << 10) | uv1; *dstBot++ = 3 << 30 | ((y67 >> 16) << 10) | uv1; } // There should be at most 2 more pixels to process. Note that we don't // need to consider odd case as the buffer is always aligned to even. if (x < width) { u01 = *uSrc; v01 = *vSrc; y01 = *((uint32_t *)ySrcTop); y45 = *((uint32_t *)ySrcBot); uv0 = (u01 & 0x3FF) | ((v01 & 0x3FF) << 20); *dstTop++ = ((y01 & 0x3FF) << 10) | uv0; *dstTop++ = ((y01 >> 16) << 10) | uv0; *dstBot++ = ((y45 & 0x3FF) << 10) | uv0; *dstBot++ = ((y45 >> 16) << 10) | uv0; } srcY += srcYStride * 2; srcU += srcUStride; srcV += srcVStride; dst += dstStride * 2; } } void convertYUV420Planar16ToYV12(uint8_t *dstY, uint8_t *dstU, uint8_t *dstV, const uint16_t *srcY, const uint16_t *srcU, const uint16_t *srcV, size_t srcYStride, size_t srcUStride, size_t srcVStride, size_t dstYStride, size_t dstUVStride, size_t width, size_t height, bool isMonochrome) { for (size_t y = 0; y < height; ++y) { for (size_t x = 0; x < width; ++x) { dstY[x] = (uint8_t)(srcY[x] >> 2); } srcY += srcYStride; dstY += dstYStride; } if (isMonochrome) { // Fill with neutral U/V values. for (size_t y = 0; y < (height + 1) / 2; ++y) { memset(dstV, kNeutralUVBitDepth8, (width + 1) / 2); memset(dstU, kNeutralUVBitDepth8, (width + 1) / 2); dstV += dstUVStride; dstU += dstUVStride; } return; } for (size_t y = 0; y < (height + 1) / 2; ++y) { for (size_t x = 0; x < (width + 1) / 2; ++x) { dstU[x] = (uint8_t)(srcU[x] >> 2); dstV[x] = (uint8_t)(srcV[x] >> 2); } srcU += srcUStride; srcV += srcVStride; dstU += dstUVStride; dstV += dstUVStride; } } void convertYUV420Planar16ToP010(uint16_t *dstY, uint16_t *dstUV, const uint16_t *srcY, const uint16_t *srcU, const uint16_t *srcV, size_t srcYStride, size_t srcUStride, size_t srcVStride, size_t dstYStride, size_t dstUVStride, size_t width, size_t height, bool isMonochrome) { for (size_t y = 0; y < height; ++y) { for (size_t x = 0; x < width; ++x) { dstY[x] = srcY[x] << 6; } srcY += srcYStride; dstY += dstYStride; } if (isMonochrome) { // Fill with neutral U/V values. for (size_t y = 0; y < (height + 1) / 2; ++y) { for (size_t x = 0; x < (width + 1) / 2; ++x) { dstUV[2 * x] = kNeutralUVBitDepth10 << 6; dstUV[2 * x + 1] = kNeutralUVBitDepth10 << 6; } dstUV += dstUVStride; } return; } for (size_t y = 0; y < (height + 1) / 2; ++y) { for (size_t x = 0; x < (width + 1) / 2; ++x) { dstUV[2 * x] = srcU[x] << 6; dstUV[2 * x + 1] = srcV[x] << 6; } srcU += srcUStride; srcV += srcVStride; dstUV += dstUVStride; } } std::unique_ptr<C2Work> SimpleC2Component::WorkQueue::pop_front() { std::unique_ptr<C2Work> work = std::move(mQueue.front().work); mQueue.pop_front(); Loading media/codec2/components/base/include/SimpleC2Component.h +18 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,24 @@ namespace android { void convertYUV420Planar8ToYV12(uint8_t *dstY, uint8_t *dstU, uint8_t *dstV, const uint8_t *srcY, const uint8_t *srcU, const uint8_t *srcV, size_t srcYStride, size_t srcUStride, size_t srcVStride, size_t dstYStride, size_t dstUVStride, uint32_t width, uint32_t height, bool isMonochrome = false); void convertYUV420Planar16ToY410(uint32_t *dst, const uint16_t *srcY, const uint16_t *srcU, const uint16_t *srcV, size_t srcYStride, size_t srcUStride, size_t srcVStride, size_t dstStride, size_t width, size_t height); void convertYUV420Planar16ToYV12(uint8_t *dstY, uint8_t *dstU, uint8_t *dstV, const uint16_t *srcY, const uint16_t *srcU, const uint16_t *srcV, size_t srcYStride, size_t srcUStride, size_t srcVStride, size_t dstYStride, size_t dstUVStride, size_t width, size_t height, bool isMonochrome = false); void convertYUV420Planar16ToP010(uint16_t *dstY, uint16_t *dstUV, const uint16_t *srcY, const uint16_t *srcU, const uint16_t *srcV, size_t srcYStride, size_t srcUStride, size_t srcVStride, size_t dstYStride, size_t dstUVStride, size_t width, size_t height, bool isMonochrome = false); class SimpleC2Component : public C2Component, public std::enable_shared_from_this<SimpleC2Component> { public: Loading media/codec2/components/gav1/C2SoftGav1Dec.cpp +12 −159 Original line number Diff line number Diff line Loading @@ -28,11 +28,6 @@ #include <media/stagefright/foundation/MediaDefs.h> namespace android { namespace { constexpr uint8_t NEUTRAL_UV_VALUE = 128; } // namespace // codecname set and passed in as a compile flag from Android.bp constexpr char COMPONENT_NAME[] = CODECNAME; Loading Loading @@ -545,150 +540,6 @@ void C2SoftGav1Dec::process(const std::unique_ptr<C2Work> &work, } } static void copyOutputBufferToYV12Frame(uint8_t *dstY, uint8_t *dstU, uint8_t *dstV, const uint8_t *srcY, const uint8_t *srcU, const uint8_t *srcV, size_t srcYStride, size_t srcUStride, size_t srcVStride, size_t dstYStride, size_t dstUVStride, uint32_t width, uint32_t height, bool isMonochrome) { for (size_t i = 0; i < height; ++i) { memcpy(dstY, srcY, width); srcY += srcYStride; dstY += dstYStride; } if (isMonochrome) { // Fill with neutral U/V values. for (size_t i = 0; i < height / 2; ++i) { memset(dstV, NEUTRAL_UV_VALUE, width / 2); memset(dstU, NEUTRAL_UV_VALUE, width / 2); dstV += dstUVStride; dstU += dstUVStride; } return; } for (size_t i = 0; i < height / 2; ++i) { memcpy(dstV, srcV, width / 2); srcV += srcVStride; dstV += dstUVStride; } for (size_t i = 0; i < height / 2; ++i) { memcpy(dstU, srcU, width / 2); srcU += srcUStride; dstU += dstUVStride; } } static void convertYUV420Planar16ToY410(uint32_t *dst, const uint16_t *srcY, const uint16_t *srcU, const uint16_t *srcV, size_t srcYStride, size_t srcUStride, size_t srcVStride, size_t dstStride, size_t width, size_t height) { // Converting two lines at a time, slightly faster for (size_t y = 0; y < height; y += 2) { uint32_t *dstTop = (uint32_t *)dst; uint32_t *dstBot = (uint32_t *)(dst + dstStride); uint16_t *ySrcTop = (uint16_t *)srcY; uint16_t *ySrcBot = (uint16_t *)(srcY + srcYStride); uint16_t *uSrc = (uint16_t *)srcU; uint16_t *vSrc = (uint16_t *)srcV; uint32_t u01, v01, y01, y23, y45, y67, uv0, uv1; size_t x = 0; for (; x < width - 3; x += 4) { u01 = *((uint32_t *)uSrc); uSrc += 2; v01 = *((uint32_t *)vSrc); vSrc += 2; y01 = *((uint32_t *)ySrcTop); ySrcTop += 2; y23 = *((uint32_t *)ySrcTop); ySrcTop += 2; y45 = *((uint32_t *)ySrcBot); ySrcBot += 2; y67 = *((uint32_t *)ySrcBot); ySrcBot += 2; uv0 = (u01 & 0x3FF) | ((v01 & 0x3FF) << 20); uv1 = (u01 >> 16) | ((v01 >> 16) << 20); *dstTop++ = 3 << 30 | ((y01 & 0x3FF) << 10) | uv0; *dstTop++ = 3 << 30 | ((y01 >> 16) << 10) | uv0; *dstTop++ = 3 << 30 | ((y23 & 0x3FF) << 10) | uv1; *dstTop++ = 3 << 30 | ((y23 >> 16) << 10) | uv1; *dstBot++ = 3 << 30 | ((y45 & 0x3FF) << 10) | uv0; *dstBot++ = 3 << 30 | ((y45 >> 16) << 10) | uv0; *dstBot++ = 3 << 30 | ((y67 & 0x3FF) << 10) | uv1; *dstBot++ = 3 << 30 | ((y67 >> 16) << 10) | uv1; } // There should be at most 2 more pixels to process. Note that we don't // need to consider odd case as the buffer is always aligned to even. if (x < width) { u01 = *uSrc; v01 = *vSrc; y01 = *((uint32_t *)ySrcTop); y45 = *((uint32_t *)ySrcBot); uv0 = (u01 & 0x3FF) | ((v01 & 0x3FF) << 20); *dstTop++ = ((y01 & 0x3FF) << 10) | uv0; *dstTop++ = ((y01 >> 16) << 10) | uv0; *dstBot++ = ((y45 & 0x3FF) << 10) | uv0; *dstBot++ = ((y45 >> 16) << 10) | uv0; } srcY += srcYStride * 2; srcU += srcUStride; srcV += srcVStride; dst += dstStride * 2; } } static void convertYUV420Planar16ToYUV420Planar( uint8_t *dstY, uint8_t *dstU, uint8_t *dstV, const uint16_t *srcY, const uint16_t *srcU, const uint16_t *srcV, size_t srcYStride, size_t srcUStride, size_t srcVStride, size_t dstYStride, size_t dstUVStride, size_t width, size_t height, bool isMonochrome) { for (size_t y = 0; y < height; ++y) { for (size_t x = 0; x < width; ++x) { dstY[x] = (uint8_t)(srcY[x] >> 2); } srcY += srcYStride; dstY += dstYStride; } if (isMonochrome) { // Fill with neutral U/V values. for (size_t y = 0; y < (height + 1) / 2; ++y) { memset(dstV, NEUTRAL_UV_VALUE, (width + 1) / 2); memset(dstU, NEUTRAL_UV_VALUE, (width + 1) / 2); dstV += dstUVStride; dstU += dstUVStride; } return; } for (size_t y = 0; y < (height + 1) / 2; ++y) { for (size_t x = 0; x < (width + 1) / 2; ++x) { dstU[x] = (uint8_t)(srcU[x] >> 2); dstV[x] = (uint8_t)(srcV[x] >> 2); } srcU += srcUStride; srcV += srcVStride; dstU += dstUVStride; dstV += dstUVStride; } } void C2SoftGav1Dec::getVuiParams(const libgav1::DecoderBuffer *buffer) { VuiColorAspects vuiColorAspects; vuiColorAspects.primaries = buffer->color_primary; Loading Loading @@ -841,22 +692,24 @@ bool C2SoftGav1Dec::outputBuffer(const std::shared_ptr<C2BlockPool> &pool, const uint16_t *srcV = (const uint16_t *)buffer->plane[2]; if (format == HAL_PIXEL_FORMAT_RGBA_1010102) { convertYUV420Planar16ToY410( (uint32_t *)dstY, srcY, srcU, srcV, srcYStride / 2, srcUStride / 2, srcVStride / 2, dstYStride / sizeof(uint32_t), mWidth, mHeight); convertYUV420Planar16ToY410((uint32_t *)dstY, srcY, srcU, srcV, srcYStride / 2, srcUStride / 2, srcVStride / 2, dstYStride / sizeof(uint32_t), mWidth, mHeight); } else if (format == HAL_PIXEL_FORMAT_YCBCR_P010) { convertYUV420Planar16ToP010((uint16_t *)dstY, (uint16_t *)dstU, srcY, srcU, srcV, srcYStride / 2, srcUStride / 2, srcVStride / 2, dstYStride / 2, dstUVStride / 2, mWidth, mHeight, isMonochrome); } else { convertYUV420Planar16ToYUV420Planar( dstY, dstU, dstV, srcY, srcU, srcV, srcYStride / 2, srcUStride / 2, srcVStride / 2, dstYStride, dstUVStride, mWidth, mHeight, isMonochrome); convertYUV420Planar16ToYV12(dstY, dstU, dstV, srcY, srcU, srcV, srcYStride / 2, srcUStride / 2, srcVStride / 2, dstYStride, dstUVStride, mWidth, mHeight, isMonochrome); } } else { const uint8_t *srcY = (const uint8_t *)buffer->plane[0]; const uint8_t *srcU = (const uint8_t *)buffer->plane[1]; const uint8_t *srcV = (const uint8_t *)buffer->plane[2]; copyOutputBufferToYV12Frame( dstY, dstU, dstV, srcY, srcU, srcV, srcYStride, srcUStride, srcVStride, dstYStride, dstUVStride, mWidth, mHeight, isMonochrome); convertYUV420Planar8ToYV12(dstY, dstU, dstV, srcY, srcU, srcV, srcYStride, srcUStride, srcVStride, dstYStride, dstUVStride, mWidth, mHeight, isMonochrome); } finishWork(buffer->user_private_data, work, std::move(block)); block = nullptr; Loading media/codec2/components/mpeg4_h263/C2SoftMpeg4Dec.cpp +11 −39 Original line number Diff line number Diff line Loading @@ -419,40 +419,6 @@ bool C2SoftMpeg4Dec::handleResChange(const std::unique_ptr<C2Work> &work) { return resChanged; } /* TODO: can remove temporary copy after library supports writing to display * buffer Y, U and V plane pointers using stride info. */ static void copyOutputBufferToYuvPlanarFrame( uint8_t *dstY, uint8_t *dstU, uint8_t *dstV, uint8_t *src, size_t dstYStride, size_t dstUVStride, size_t srcYStride, uint32_t width, uint32_t height) { size_t srcUVStride = srcYStride / 2; uint8_t *srcStart = src; size_t vStride = align(height, 16); for (size_t i = 0; i < height; ++i) { memcpy(dstY, src, width); src += srcYStride; dstY += dstYStride; } /* U buffer */ src = srcStart + vStride * srcYStride; for (size_t i = 0; i < height / 2; ++i) { memcpy(dstU, src, width / 2); src += srcUVStride; dstU += dstUVStride; } /* V buffer */ src = srcStart + vStride * srcYStride * 5 / 4; for (size_t i = 0; i < height / 2; ++i) { memcpy(dstV, src, width / 2); src += srcUVStride; dstV += dstUVStride; } } void C2SoftMpeg4Dec::process( const std::unique_ptr<C2Work> &work, const std::shared_ptr<C2BlockPool> &pool) { Loading Loading @@ -636,11 +602,17 @@ void C2SoftMpeg4Dec::process( C2PlanarLayout layout = wView.layout(); size_t dstYStride = layout.planes[C2PlanarLayout::PLANE_Y].rowInc; size_t dstUVStride = layout.planes[C2PlanarLayout::PLANE_U].rowInc; (void)copyOutputBufferToYuvPlanarFrame( outputBufferY, outputBufferU, outputBufferV, mOutputBuffer[mNumSamplesOutput & 1], dstYStride, dstUVStride, align(mWidth, 16), mWidth, mHeight); size_t srcYStride = align(mWidth, 16); size_t srcUStride = srcYStride / 2; size_t srcVStride = srcYStride / 2; size_t vStride = align(mHeight, 16); const uint8_t *srcY = (const uint8_t *)mOutputBuffer[mNumSamplesOutput & 1]; const uint8_t *srcU = (const uint8_t *)srcY + vStride * srcYStride; const uint8_t *srcV = (const uint8_t *)srcY + vStride * srcYStride * 5 / 4; convertYUV420Planar8ToYV12(outputBufferY, outputBufferU, outputBufferV, srcY, srcU, srcV, srcYStride, srcUStride, srcVStride, dstYStride, dstUVStride, mWidth, mHeight); inPos += inSize - (size_t)tmpInSize; finishWork(workIndex, work); Loading Loading
media/codec2/components/aom/C2SoftAomDec.cpp +5 −128 Original line number Diff line number Diff line Loading @@ -505,124 +505,6 @@ void C2SoftAomDec::process(const std::unique_ptr<C2Work>& work, } } static void copyOutputBufferToYuvPlanarFrame( uint8_t *dstY, uint8_t *dstU, uint8_t *dstV, const uint8_t *srcY, const uint8_t *srcU, const uint8_t *srcV, size_t srcYStride, size_t srcUStride, size_t srcVStride, size_t dstYStride, size_t dstUVStride, uint32_t width, uint32_t height) { for (size_t i = 0; i < height; ++i) { memcpy(dstY, srcY, width); srcY += srcYStride; dstY += dstYStride; } for (size_t i = 0; i < height / 2; ++i) { memcpy(dstV, srcV, width / 2); srcV += srcVStride; dstV += dstUVStride; } for (size_t i = 0; i < height / 2; ++i) { memcpy(dstU, srcU, width / 2); srcU += srcUStride; dstU += dstUVStride; } } static void convertYUV420Planar16ToY410(uint32_t *dst, const uint16_t *srcY, const uint16_t *srcU, const uint16_t *srcV, size_t srcYStride, size_t srcUStride, size_t srcVStride, size_t dstStride, size_t width, size_t height) { // Converting two lines at a time, slightly faster for (size_t y = 0; y < height; y += 2) { uint32_t *dstTop = (uint32_t *) dst; uint32_t *dstBot = (uint32_t *) (dst + dstStride); uint16_t *ySrcTop = (uint16_t*) srcY; uint16_t *ySrcBot = (uint16_t*) (srcY + srcYStride); uint16_t *uSrc = (uint16_t*) srcU; uint16_t *vSrc = (uint16_t*) srcV; uint32_t u01, v01, y01, y23, y45, y67, uv0, uv1; size_t x = 0; for (; x < width - 3; x += 4) { u01 = *((uint32_t*)uSrc); uSrc += 2; v01 = *((uint32_t*)vSrc); vSrc += 2; y01 = *((uint32_t*)ySrcTop); ySrcTop += 2; y23 = *((uint32_t*)ySrcTop); ySrcTop += 2; y45 = *((uint32_t*)ySrcBot); ySrcBot += 2; y67 = *((uint32_t*)ySrcBot); ySrcBot += 2; uv0 = (u01 & 0x3FF) | ((v01 & 0x3FF) << 20); uv1 = (u01 >> 16) | ((v01 >> 16) << 20); *dstTop++ = 3 << 30 | ((y01 & 0x3FF) << 10) | uv0; *dstTop++ = 3 << 30 | ((y01 >> 16) << 10) | uv0; *dstTop++ = 3 << 30 | ((y23 & 0x3FF) << 10) | uv1; *dstTop++ = 3 << 30 | ((y23 >> 16) << 10) | uv1; *dstBot++ = 3 << 30 | ((y45 & 0x3FF) << 10) | uv0; *dstBot++ = 3 << 30 | ((y45 >> 16) << 10) | uv0; *dstBot++ = 3 << 30 | ((y67 & 0x3FF) << 10) | uv1; *dstBot++ = 3 << 30 | ((y67 >> 16) << 10) | uv1; } // There should be at most 2 more pixels to process. Note that we don't // need to consider odd case as the buffer is always aligned to even. if (x < width) { u01 = *uSrc; v01 = *vSrc; y01 = *((uint32_t*)ySrcTop); y45 = *((uint32_t*)ySrcBot); uv0 = (u01 & 0x3FF) | ((v01 & 0x3FF) << 20); *dstTop++ = ((y01 & 0x3FF) << 10) | uv0; *dstTop++ = ((y01 >> 16) << 10) | uv0; *dstBot++ = ((y45 & 0x3FF) << 10) | uv0; *dstBot++ = ((y45 >> 16) << 10) | uv0; } srcY += srcYStride * 2; srcU += srcUStride; srcV += srcVStride; dst += dstStride * 2; } return; } static void convertYUV420Planar16ToYUV420Planar( uint8_t *dstY, uint8_t *dstU, uint8_t *dstV, const uint16_t *srcY, const uint16_t *srcU, const uint16_t *srcV, size_t srcYStride, size_t srcUStride, size_t srcVStride, size_t dstYStride, size_t dstUVStride, size_t width, size_t height) { for (size_t y = 0; y < height; ++y) { for (size_t x = 0; x < width; ++x) { dstY[x] = (uint8_t)(srcY[x] >> 2); } srcY += srcYStride; dstY += dstYStride; } for (size_t y = 0; y < (height + 1) / 2; ++y) { for (size_t x = 0; x < (width + 1) / 2; ++x) { dstU[x] = (uint8_t)(srcU[x] >> 2); dstV[x] = (uint8_t)(srcV[x] >> 2); } srcU += srcUStride; srcV += srcVStride; dstU += dstUVStride; dstV += dstUVStride; } return; } bool C2SoftAomDec::outputBuffer( const std::shared_ptr<C2BlockPool> &pool, const std::unique_ptr<C2Work> &work) Loading Loading @@ -711,21 +593,16 @@ bool C2SoftAomDec::outputBuffer( dstYStride / sizeof(uint32_t), mWidth, mHeight); } else { convertYUV420Planar16ToYUV420Planar(dstY, dstU, dstV, srcY, srcU, srcV, srcYStride / 2, srcUStride / 2, srcVStride / 2, dstYStride, dstUVStride, convertYUV420Planar16ToYV12(dstY, dstU, dstV, srcY, srcU, srcV, srcYStride / 2, srcUStride / 2, srcVStride / 2, dstYStride, dstUVStride, mWidth, mHeight); } } else { const uint8_t *srcY = (const uint8_t *)img->planes[AOM_PLANE_Y]; const uint8_t *srcU = (const uint8_t *)img->planes[AOM_PLANE_U]; const uint8_t *srcV = (const uint8_t *)img->planes[AOM_PLANE_V]; copyOutputBufferToYuvPlanarFrame( dstY, dstU, dstV, srcY, srcU, srcV, srcYStride, srcUStride, srcVStride, dstYStride, dstUVStride, mWidth, mHeight); convertYUV420Planar8ToYV12(dstY, dstU, dstV, srcY, srcU, srcV, srcYStride, srcUStride, srcVStride, dstYStride, dstUVStride, mWidth, mHeight); } finishWork(*(int64_t*)img->user_priv, work, std::move(block)); block = nullptr; Loading
media/codec2/components/base/SimpleC2Component.cpp +172 −0 Original line number Diff line number Diff line Loading @@ -29,7 +29,179 @@ #include <SimpleC2Component.h> namespace android { constexpr uint8_t kNeutralUVBitDepth8 = 128; constexpr uint16_t kNeutralUVBitDepth10 = 512; void convertYUV420Planar8ToYV12(uint8_t *dstY, uint8_t *dstU, uint8_t *dstV, const uint8_t *srcY, const uint8_t *srcU, const uint8_t *srcV, size_t srcYStride, size_t srcUStride, size_t srcVStride, size_t dstYStride, size_t dstUVStride, uint32_t width, uint32_t height, bool isMonochrome) { for (size_t i = 0; i < height; ++i) { memcpy(dstY, srcY, width); srcY += srcYStride; dstY += dstYStride; } if (isMonochrome) { // Fill with neutral U/V values. for (size_t i = 0; i < height / 2; ++i) { memset(dstV, kNeutralUVBitDepth8, width / 2); memset(dstU, kNeutralUVBitDepth8, width / 2); dstV += dstUVStride; dstU += dstUVStride; } return; } for (size_t i = 0; i < height / 2; ++i) { memcpy(dstV, srcV, width / 2); srcV += srcVStride; dstV += dstUVStride; } for (size_t i = 0; i < height / 2; ++i) { memcpy(dstU, srcU, width / 2); srcU += srcUStride; dstU += dstUVStride; } } void convertYUV420Planar16ToY410(uint32_t *dst, const uint16_t *srcY, const uint16_t *srcU, const uint16_t *srcV, size_t srcYStride, size_t srcUStride, size_t srcVStride, size_t dstStride, size_t width, size_t height) { // Converting two lines at a time, slightly faster for (size_t y = 0; y < height; y += 2) { uint32_t *dstTop = (uint32_t *)dst; uint32_t *dstBot = (uint32_t *)(dst + dstStride); uint16_t *ySrcTop = (uint16_t *)srcY; uint16_t *ySrcBot = (uint16_t *)(srcY + srcYStride); uint16_t *uSrc = (uint16_t *)srcU; uint16_t *vSrc = (uint16_t *)srcV; uint32_t u01, v01, y01, y23, y45, y67, uv0, uv1; size_t x = 0; for (; x < width - 3; x += 4) { u01 = *((uint32_t *)uSrc); uSrc += 2; v01 = *((uint32_t *)vSrc); vSrc += 2; y01 = *((uint32_t *)ySrcTop); ySrcTop += 2; y23 = *((uint32_t *)ySrcTop); ySrcTop += 2; y45 = *((uint32_t *)ySrcBot); ySrcBot += 2; y67 = *((uint32_t *)ySrcBot); ySrcBot += 2; uv0 = (u01 & 0x3FF) | ((v01 & 0x3FF) << 20); uv1 = (u01 >> 16) | ((v01 >> 16) << 20); *dstTop++ = 3 << 30 | ((y01 & 0x3FF) << 10) | uv0; *dstTop++ = 3 << 30 | ((y01 >> 16) << 10) | uv0; *dstTop++ = 3 << 30 | ((y23 & 0x3FF) << 10) | uv1; *dstTop++ = 3 << 30 | ((y23 >> 16) << 10) | uv1; *dstBot++ = 3 << 30 | ((y45 & 0x3FF) << 10) | uv0; *dstBot++ = 3 << 30 | ((y45 >> 16) << 10) | uv0; *dstBot++ = 3 << 30 | ((y67 & 0x3FF) << 10) | uv1; *dstBot++ = 3 << 30 | ((y67 >> 16) << 10) | uv1; } // There should be at most 2 more pixels to process. Note that we don't // need to consider odd case as the buffer is always aligned to even. if (x < width) { u01 = *uSrc; v01 = *vSrc; y01 = *((uint32_t *)ySrcTop); y45 = *((uint32_t *)ySrcBot); uv0 = (u01 & 0x3FF) | ((v01 & 0x3FF) << 20); *dstTop++ = ((y01 & 0x3FF) << 10) | uv0; *dstTop++ = ((y01 >> 16) << 10) | uv0; *dstBot++ = ((y45 & 0x3FF) << 10) | uv0; *dstBot++ = ((y45 >> 16) << 10) | uv0; } srcY += srcYStride * 2; srcU += srcUStride; srcV += srcVStride; dst += dstStride * 2; } } void convertYUV420Planar16ToYV12(uint8_t *dstY, uint8_t *dstU, uint8_t *dstV, const uint16_t *srcY, const uint16_t *srcU, const uint16_t *srcV, size_t srcYStride, size_t srcUStride, size_t srcVStride, size_t dstYStride, size_t dstUVStride, size_t width, size_t height, bool isMonochrome) { for (size_t y = 0; y < height; ++y) { for (size_t x = 0; x < width; ++x) { dstY[x] = (uint8_t)(srcY[x] >> 2); } srcY += srcYStride; dstY += dstYStride; } if (isMonochrome) { // Fill with neutral U/V values. for (size_t y = 0; y < (height + 1) / 2; ++y) { memset(dstV, kNeutralUVBitDepth8, (width + 1) / 2); memset(dstU, kNeutralUVBitDepth8, (width + 1) / 2); dstV += dstUVStride; dstU += dstUVStride; } return; } for (size_t y = 0; y < (height + 1) / 2; ++y) { for (size_t x = 0; x < (width + 1) / 2; ++x) { dstU[x] = (uint8_t)(srcU[x] >> 2); dstV[x] = (uint8_t)(srcV[x] >> 2); } srcU += srcUStride; srcV += srcVStride; dstU += dstUVStride; dstV += dstUVStride; } } void convertYUV420Planar16ToP010(uint16_t *dstY, uint16_t *dstUV, const uint16_t *srcY, const uint16_t *srcU, const uint16_t *srcV, size_t srcYStride, size_t srcUStride, size_t srcVStride, size_t dstYStride, size_t dstUVStride, size_t width, size_t height, bool isMonochrome) { for (size_t y = 0; y < height; ++y) { for (size_t x = 0; x < width; ++x) { dstY[x] = srcY[x] << 6; } srcY += srcYStride; dstY += dstYStride; } if (isMonochrome) { // Fill with neutral U/V values. for (size_t y = 0; y < (height + 1) / 2; ++y) { for (size_t x = 0; x < (width + 1) / 2; ++x) { dstUV[2 * x] = kNeutralUVBitDepth10 << 6; dstUV[2 * x + 1] = kNeutralUVBitDepth10 << 6; } dstUV += dstUVStride; } return; } for (size_t y = 0; y < (height + 1) / 2; ++y) { for (size_t x = 0; x < (width + 1) / 2; ++x) { dstUV[2 * x] = srcU[x] << 6; dstUV[2 * x + 1] = srcV[x] << 6; } srcU += srcUStride; srcV += srcVStride; dstUV += dstUVStride; } } std::unique_ptr<C2Work> SimpleC2Component::WorkQueue::pop_front() { std::unique_ptr<C2Work> work = std::move(mQueue.front().work); mQueue.pop_front(); Loading
media/codec2/components/base/include/SimpleC2Component.h +18 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,24 @@ namespace android { void convertYUV420Planar8ToYV12(uint8_t *dstY, uint8_t *dstU, uint8_t *dstV, const uint8_t *srcY, const uint8_t *srcU, const uint8_t *srcV, size_t srcYStride, size_t srcUStride, size_t srcVStride, size_t dstYStride, size_t dstUVStride, uint32_t width, uint32_t height, bool isMonochrome = false); void convertYUV420Planar16ToY410(uint32_t *dst, const uint16_t *srcY, const uint16_t *srcU, const uint16_t *srcV, size_t srcYStride, size_t srcUStride, size_t srcVStride, size_t dstStride, size_t width, size_t height); void convertYUV420Planar16ToYV12(uint8_t *dstY, uint8_t *dstU, uint8_t *dstV, const uint16_t *srcY, const uint16_t *srcU, const uint16_t *srcV, size_t srcYStride, size_t srcUStride, size_t srcVStride, size_t dstYStride, size_t dstUVStride, size_t width, size_t height, bool isMonochrome = false); void convertYUV420Planar16ToP010(uint16_t *dstY, uint16_t *dstUV, const uint16_t *srcY, const uint16_t *srcU, const uint16_t *srcV, size_t srcYStride, size_t srcUStride, size_t srcVStride, size_t dstYStride, size_t dstUVStride, size_t width, size_t height, bool isMonochrome = false); class SimpleC2Component : public C2Component, public std::enable_shared_from_this<SimpleC2Component> { public: Loading
media/codec2/components/gav1/C2SoftGav1Dec.cpp +12 −159 Original line number Diff line number Diff line Loading @@ -28,11 +28,6 @@ #include <media/stagefright/foundation/MediaDefs.h> namespace android { namespace { constexpr uint8_t NEUTRAL_UV_VALUE = 128; } // namespace // codecname set and passed in as a compile flag from Android.bp constexpr char COMPONENT_NAME[] = CODECNAME; Loading Loading @@ -545,150 +540,6 @@ void C2SoftGav1Dec::process(const std::unique_ptr<C2Work> &work, } } static void copyOutputBufferToYV12Frame(uint8_t *dstY, uint8_t *dstU, uint8_t *dstV, const uint8_t *srcY, const uint8_t *srcU, const uint8_t *srcV, size_t srcYStride, size_t srcUStride, size_t srcVStride, size_t dstYStride, size_t dstUVStride, uint32_t width, uint32_t height, bool isMonochrome) { for (size_t i = 0; i < height; ++i) { memcpy(dstY, srcY, width); srcY += srcYStride; dstY += dstYStride; } if (isMonochrome) { // Fill with neutral U/V values. for (size_t i = 0; i < height / 2; ++i) { memset(dstV, NEUTRAL_UV_VALUE, width / 2); memset(dstU, NEUTRAL_UV_VALUE, width / 2); dstV += dstUVStride; dstU += dstUVStride; } return; } for (size_t i = 0; i < height / 2; ++i) { memcpy(dstV, srcV, width / 2); srcV += srcVStride; dstV += dstUVStride; } for (size_t i = 0; i < height / 2; ++i) { memcpy(dstU, srcU, width / 2); srcU += srcUStride; dstU += dstUVStride; } } static void convertYUV420Planar16ToY410(uint32_t *dst, const uint16_t *srcY, const uint16_t *srcU, const uint16_t *srcV, size_t srcYStride, size_t srcUStride, size_t srcVStride, size_t dstStride, size_t width, size_t height) { // Converting two lines at a time, slightly faster for (size_t y = 0; y < height; y += 2) { uint32_t *dstTop = (uint32_t *)dst; uint32_t *dstBot = (uint32_t *)(dst + dstStride); uint16_t *ySrcTop = (uint16_t *)srcY; uint16_t *ySrcBot = (uint16_t *)(srcY + srcYStride); uint16_t *uSrc = (uint16_t *)srcU; uint16_t *vSrc = (uint16_t *)srcV; uint32_t u01, v01, y01, y23, y45, y67, uv0, uv1; size_t x = 0; for (; x < width - 3; x += 4) { u01 = *((uint32_t *)uSrc); uSrc += 2; v01 = *((uint32_t *)vSrc); vSrc += 2; y01 = *((uint32_t *)ySrcTop); ySrcTop += 2; y23 = *((uint32_t *)ySrcTop); ySrcTop += 2; y45 = *((uint32_t *)ySrcBot); ySrcBot += 2; y67 = *((uint32_t *)ySrcBot); ySrcBot += 2; uv0 = (u01 & 0x3FF) | ((v01 & 0x3FF) << 20); uv1 = (u01 >> 16) | ((v01 >> 16) << 20); *dstTop++ = 3 << 30 | ((y01 & 0x3FF) << 10) | uv0; *dstTop++ = 3 << 30 | ((y01 >> 16) << 10) | uv0; *dstTop++ = 3 << 30 | ((y23 & 0x3FF) << 10) | uv1; *dstTop++ = 3 << 30 | ((y23 >> 16) << 10) | uv1; *dstBot++ = 3 << 30 | ((y45 & 0x3FF) << 10) | uv0; *dstBot++ = 3 << 30 | ((y45 >> 16) << 10) | uv0; *dstBot++ = 3 << 30 | ((y67 & 0x3FF) << 10) | uv1; *dstBot++ = 3 << 30 | ((y67 >> 16) << 10) | uv1; } // There should be at most 2 more pixels to process. Note that we don't // need to consider odd case as the buffer is always aligned to even. if (x < width) { u01 = *uSrc; v01 = *vSrc; y01 = *((uint32_t *)ySrcTop); y45 = *((uint32_t *)ySrcBot); uv0 = (u01 & 0x3FF) | ((v01 & 0x3FF) << 20); *dstTop++ = ((y01 & 0x3FF) << 10) | uv0; *dstTop++ = ((y01 >> 16) << 10) | uv0; *dstBot++ = ((y45 & 0x3FF) << 10) | uv0; *dstBot++ = ((y45 >> 16) << 10) | uv0; } srcY += srcYStride * 2; srcU += srcUStride; srcV += srcVStride; dst += dstStride * 2; } } static void convertYUV420Planar16ToYUV420Planar( uint8_t *dstY, uint8_t *dstU, uint8_t *dstV, const uint16_t *srcY, const uint16_t *srcU, const uint16_t *srcV, size_t srcYStride, size_t srcUStride, size_t srcVStride, size_t dstYStride, size_t dstUVStride, size_t width, size_t height, bool isMonochrome) { for (size_t y = 0; y < height; ++y) { for (size_t x = 0; x < width; ++x) { dstY[x] = (uint8_t)(srcY[x] >> 2); } srcY += srcYStride; dstY += dstYStride; } if (isMonochrome) { // Fill with neutral U/V values. for (size_t y = 0; y < (height + 1) / 2; ++y) { memset(dstV, NEUTRAL_UV_VALUE, (width + 1) / 2); memset(dstU, NEUTRAL_UV_VALUE, (width + 1) / 2); dstV += dstUVStride; dstU += dstUVStride; } return; } for (size_t y = 0; y < (height + 1) / 2; ++y) { for (size_t x = 0; x < (width + 1) / 2; ++x) { dstU[x] = (uint8_t)(srcU[x] >> 2); dstV[x] = (uint8_t)(srcV[x] >> 2); } srcU += srcUStride; srcV += srcVStride; dstU += dstUVStride; dstV += dstUVStride; } } void C2SoftGav1Dec::getVuiParams(const libgav1::DecoderBuffer *buffer) { VuiColorAspects vuiColorAspects; vuiColorAspects.primaries = buffer->color_primary; Loading Loading @@ -841,22 +692,24 @@ bool C2SoftGav1Dec::outputBuffer(const std::shared_ptr<C2BlockPool> &pool, const uint16_t *srcV = (const uint16_t *)buffer->plane[2]; if (format == HAL_PIXEL_FORMAT_RGBA_1010102) { convertYUV420Planar16ToY410( (uint32_t *)dstY, srcY, srcU, srcV, srcYStride / 2, srcUStride / 2, srcVStride / 2, dstYStride / sizeof(uint32_t), mWidth, mHeight); convertYUV420Planar16ToY410((uint32_t *)dstY, srcY, srcU, srcV, srcYStride / 2, srcUStride / 2, srcVStride / 2, dstYStride / sizeof(uint32_t), mWidth, mHeight); } else if (format == HAL_PIXEL_FORMAT_YCBCR_P010) { convertYUV420Planar16ToP010((uint16_t *)dstY, (uint16_t *)dstU, srcY, srcU, srcV, srcYStride / 2, srcUStride / 2, srcVStride / 2, dstYStride / 2, dstUVStride / 2, mWidth, mHeight, isMonochrome); } else { convertYUV420Planar16ToYUV420Planar( dstY, dstU, dstV, srcY, srcU, srcV, srcYStride / 2, srcUStride / 2, srcVStride / 2, dstYStride, dstUVStride, mWidth, mHeight, isMonochrome); convertYUV420Planar16ToYV12(dstY, dstU, dstV, srcY, srcU, srcV, srcYStride / 2, srcUStride / 2, srcVStride / 2, dstYStride, dstUVStride, mWidth, mHeight, isMonochrome); } } else { const uint8_t *srcY = (const uint8_t *)buffer->plane[0]; const uint8_t *srcU = (const uint8_t *)buffer->plane[1]; const uint8_t *srcV = (const uint8_t *)buffer->plane[2]; copyOutputBufferToYV12Frame( dstY, dstU, dstV, srcY, srcU, srcV, srcYStride, srcUStride, srcVStride, dstYStride, dstUVStride, mWidth, mHeight, isMonochrome); convertYUV420Planar8ToYV12(dstY, dstU, dstV, srcY, srcU, srcV, srcYStride, srcUStride, srcVStride, dstYStride, dstUVStride, mWidth, mHeight, isMonochrome); } finishWork(buffer->user_private_data, work, std::move(block)); block = nullptr; Loading
media/codec2/components/mpeg4_h263/C2SoftMpeg4Dec.cpp +11 −39 Original line number Diff line number Diff line Loading @@ -419,40 +419,6 @@ bool C2SoftMpeg4Dec::handleResChange(const std::unique_ptr<C2Work> &work) { return resChanged; } /* TODO: can remove temporary copy after library supports writing to display * buffer Y, U and V plane pointers using stride info. */ static void copyOutputBufferToYuvPlanarFrame( uint8_t *dstY, uint8_t *dstU, uint8_t *dstV, uint8_t *src, size_t dstYStride, size_t dstUVStride, size_t srcYStride, uint32_t width, uint32_t height) { size_t srcUVStride = srcYStride / 2; uint8_t *srcStart = src; size_t vStride = align(height, 16); for (size_t i = 0; i < height; ++i) { memcpy(dstY, src, width); src += srcYStride; dstY += dstYStride; } /* U buffer */ src = srcStart + vStride * srcYStride; for (size_t i = 0; i < height / 2; ++i) { memcpy(dstU, src, width / 2); src += srcUVStride; dstU += dstUVStride; } /* V buffer */ src = srcStart + vStride * srcYStride * 5 / 4; for (size_t i = 0; i < height / 2; ++i) { memcpy(dstV, src, width / 2); src += srcUVStride; dstV += dstUVStride; } } void C2SoftMpeg4Dec::process( const std::unique_ptr<C2Work> &work, const std::shared_ptr<C2BlockPool> &pool) { Loading Loading @@ -636,11 +602,17 @@ void C2SoftMpeg4Dec::process( C2PlanarLayout layout = wView.layout(); size_t dstYStride = layout.planes[C2PlanarLayout::PLANE_Y].rowInc; size_t dstUVStride = layout.planes[C2PlanarLayout::PLANE_U].rowInc; (void)copyOutputBufferToYuvPlanarFrame( outputBufferY, outputBufferU, outputBufferV, mOutputBuffer[mNumSamplesOutput & 1], dstYStride, dstUVStride, align(mWidth, 16), mWidth, mHeight); size_t srcYStride = align(mWidth, 16); size_t srcUStride = srcYStride / 2; size_t srcVStride = srcYStride / 2; size_t vStride = align(mHeight, 16); const uint8_t *srcY = (const uint8_t *)mOutputBuffer[mNumSamplesOutput & 1]; const uint8_t *srcU = (const uint8_t *)srcY + vStride * srcYStride; const uint8_t *srcV = (const uint8_t *)srcY + vStride * srcYStride * 5 / 4; convertYUV420Planar8ToYV12(outputBufferY, outputBufferU, outputBufferV, srcY, srcU, srcV, srcYStride, srcUStride, srcVStride, dstYStride, dstUVStride, mWidth, mHeight); inPos += inSize - (size_t)tmpInSize; finishWork(workIndex, work); Loading