summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvinash Malipatil <avinashmp@google.com>2023-04-06 05:36:50 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2023-04-06 05:36:50 +0000
commitf6468f74dc790769112edfd528ff8db787e50612 (patch)
tree197c5f4b8d54b2a8c9f2c4442c576468177ed42e
parentfc8eaff4a97cb934b9f422dc35018cfe7f8a615d (diff)
parent7a5fc2963d77634dbc5ee736a386839f6268f057 (diff)
downloadImsMedia-f6468f74dc790769112edfd528ff8db787e50612.tar.gz
Fix video distortion in TX encoded frames. am: 7a5fc2963d
Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/modules/ImsMedia/+/22198403 Change-Id: I13ba05db19975dd411bce43d3aacf3a3a29456fc Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r--service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/utils/ImsMediaImageRotate.h38
-rw-r--r--service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/video/android/ImsMediaPauseImageSource.h5
-rw-r--r--service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/video/android/ImsMediaVideoSource.h1
-rw-r--r--service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/utils/ImsMediaImageRotate.cpp81
-rw-r--r--service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/android/ImsMediaPauseImageSource.cpp46
-rw-r--r--service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/android/ImsMediaVideoSource.cpp47
-rw-r--r--tests/native/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/utils/ImsMediaImageRotateTest.cpp98
7 files changed, 249 insertions, 67 deletions
diff --git a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/utils/ImsMediaImageRotate.h b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/utils/ImsMediaImageRotate.h
index 939cd670..a0d46ddf 100644
--- a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/utils/ImsMediaImageRotate.h
+++ b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/utils/ImsMediaImageRotate.h
@@ -24,7 +24,7 @@ class ImsMediaImageRotate
public:
/**
* @brief Rotates YUVImage_420_Planar Image by 90 degrees and flips.
- * Supports zero pixel and zero row stride.
+ * Supports input row stride equal to width.
*
* Source Image Destination Image
* + - - - - + + - - - - +
@@ -33,17 +33,18 @@ public:
* | 7 8 9 | | 7 4 1 |
* + - - - - + + - - - - +
*
- * @param pbDst Destination buffer with size nDstWidth*nDstHeight*1.5.
+ * @param pOutBuffer Pointer to output buffer with size nDstWidth*nDstHeight*1.5.
* @param pbSrc Source buffer with size nDstWidth*nDstHeight*1.5.
* @param nSrcWidth Source Image width.
* @param nSrcHeight Source Image height.
*/
static void YUV420_Planar_Rotate90_Flip(
- uint8_t* pbDst, uint8_t* pbSrc, uint16_t nSrcWidth, uint16_t nSrcHeight);
+ uint8_t* pOutBuffer, uint8_t* pbSrc, uint16_t nSrcWidth, uint16_t nSrcHeight);
/**
* @brief Rotates YUVImage_420_888 Image by 90 degrees.
- * Supports zero pixel stride and zero row stride.
+ * Supports input row stride equal to width and adds padding when outputStride is not same
+ * as output image width.
*
* Source Image Destination Image
* + - - - - + + - - - - +
@@ -52,18 +53,22 @@ public:
* | 7 8 9 | | 9 6 3 |
* + - - - - + + - - - - +
*
- * @param pbDst Destination buffer with size nDstWidth*nDstHeight*1.5.
+ * @param pOutBuffer Pointer to output buffer with size outputStride*nDstHeight*1.5.
+ * @param nOutBufSize size of output buffer.
+ * @param outputStride Stride of the output image >= nDstWidth.
* @param pYPlane Y-Plane data of size nDstWidth*nDstHeight.
* @param pUVPlane UV-Plane data of size (nDstWidth*nDstHeight)/2.
* @param nSrcWidth Source Image width.
* @param nSrcHeight Source Image height.
+ *
+ * @return -1 on error and 0 on success.
*/
- static void YUV420_SP_Rotate90(uint8_t* pbDst, uint8_t* pYPlane, uint8_t* pUVPlane,
- uint16_t nSrcWidth, uint16_t nSrcHeight);
+ static int YUV420_SP_Rotate90(uint8_t* pOutBuffer, size_t nOutBufSize, uint16_t outputStride,
+ uint8_t* pYPlane, uint8_t* pUVPlane, uint16_t nSrcWidth, uint16_t nSrcHeight);
/**
* @brief Rotates YUVImage_420_888 Image by 90 degrees and flip.
- * Supports zero pixel stride and zero row stride.
+ * Supports input row stride equal to width.
*
* Source Image Destination Image
* + - - - - + + - - - - +
@@ -72,18 +77,19 @@ public:
* | 7 8 9 | | 7 4 1 |
* + - - - - + + - - - - +
*
- * @param pbDst Destination buffer with size nDstWidth*nDstHeight*1.5.
+ * @param pOutBuffer Pointer to output buffer with size nDstWidth*nDstHeight*1.5.
* @param pYPlane Y-Plane data of size nDstWidth*nDstHeight.
* @param pUVPlane UV-Plane data of size (nDstWidth*nDstHeight)/2.
* @param nSrcWidth Source Image width.
* @param nSrcHeight Source Image height.
*/
- static void YUV420_SP_Rotate90_Flip(uint8_t* pbDst, uint8_t* pYPlane, uint8_t* pUVPlane,
+ static void YUV420_SP_Rotate90_Flip(uint8_t* pOutBuffer, uint8_t* pYPlane, uint8_t* pUVPlane,
uint16_t nSrcWidth, uint16_t nSrcHeight);
/**
* @brief Rotates YUVImage_420_888 Image by 270 degrees.
- * Supports zero pixel stride and zero row stride.
+ * Supports input row stride equal to width and adds padding when outputStride is not same
+ * as output image width.
*
* Source Image Destination Image
* + - - - - + + - - - - +
@@ -92,14 +98,18 @@ public:
* | 7 8 9 | | 1 4 7 |
* + - - - - + + - - - - +
*
- * @param pbDst Destination buffer with size nDstWidth*nDstHeight*1.5.
+ * @param pOutBuffer Pointer to output buffer with size nDstWidth*nDstHeight*1.5.
+ * @param nOutBufSize size of output buffer.
+ * @param outputStride Stride of the output image >= nDstWidth.
* @param pYPlane Y-Plane data of size nDstWidth*nDstHeight.
* @param pUVPlane UV-Plane data of size (nDstWidth*nDstHeight)/2.
* @param nSrcWidth Source Image width.
* @param nSrcHeight Source Image height.
+ *
+ * @return -1 on error and 0 on success.
*/
- static void YUV420_SP_Rotate270(uint8_t* pbDst, uint8_t* pYPlane, uint8_t* pUVPlane,
- uint16_t nSrcWidth, uint16_t nSrcHeight);
+ static int YUV420_SP_Rotate270(uint8_t* pOutBuffer, size_t nOutBufSize, uint16_t outputStride,
+ uint8_t* pYPlane, uint8_t* pUVPlane, uint16_t nSrcWidth, uint16_t nSrcHeight);
};
#endif // IMS_MEDIA_IMAGE_ROTATE \ No newline at end of file
diff --git a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/video/android/ImsMediaPauseImageSource.h b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/video/android/ImsMediaPauseImageSource.h
index 723499b9..66022fc2 100644
--- a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/video/android/ImsMediaPauseImageSource.h
+++ b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/video/android/ImsMediaPauseImageSource.h
@@ -31,10 +31,11 @@ public:
*
* @param width width of the video frames.
* @param height height of the video frames.
+ * @param stride stride of the video frames.
*
* @return returns true if the image is loaded and false in case of failure.
*/
- bool Initialize(int width, int height);
+ bool Initialize(int width, int height, int stride);
/**
* @brief Image YUV buffer loaded in memory is freed.
@@ -58,7 +59,7 @@ private:
AAsset* getImageAsset();
const char* getImageFilePath();
- int8_t* ConvertRgbaToYuv(int8_t* pixels, int width, int height);
+ int8_t* ConvertRgbaToYuv(int8_t* pixels, int width, int height, int stride);
};
#endif // IMSMEDIA_JPEG_SOURCE_H_INCLUDED
diff --git a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/video/android/ImsMediaVideoSource.h b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/video/android/ImsMediaVideoSource.h
index f74a9caf..83a6d7ac 100644
--- a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/video/android/ImsMediaVideoSource.h
+++ b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/video/android/ImsMediaVideoSource.h
@@ -167,6 +167,7 @@ private:
uint32_t mCameraZoom;
uint32_t mWidth;
uint32_t mHeight;
+ int32_t mCodecStride;
uint32_t mFramerate;
uint32_t mBitrate;
uint32_t mIntraInterval;
diff --git a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/utils/ImsMediaImageRotate.cpp b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/utils/ImsMediaImageRotate.cpp
index 90947c19..46d01ceb 100644
--- a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/utils/ImsMediaImageRotate.cpp
+++ b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/utils/ImsMediaImageRotate.cpp
@@ -15,13 +15,14 @@
*/
#include "ImsMediaImageRotate.h"
+#include <ImsMediaTrace.h>
void ImsMediaImageRotate::YUV420_Planar_Rotate90_Flip(
uint8_t* pbDst, uint8_t* pbSrc, uint16_t nSrcWidth, uint16_t nSrcHeight)
{
uint16_t x, y;
uint64_t srcIdx, dstIdx;
- const uint64_t size = nSrcWidth * nSrcHeight;
+ const size_t size = nSrcWidth * nSrcHeight;
dstIdx = size - 1;
// Rotate Y buffer
@@ -57,41 +58,59 @@ void ImsMediaImageRotate::YUV420_Planar_Rotate90_Flip(
}
}
-void ImsMediaImageRotate::YUV420_SP_Rotate90(uint8_t* pbDst, uint8_t* pYPlane, uint8_t* pUVPlane,
- uint16_t nSrcWidth, uint16_t nSrcHeight)
+int ImsMediaImageRotate::YUV420_SP_Rotate90(uint8_t* pOutBuffer, size_t nOutBufSize,
+ uint16_t outputStride, uint8_t* pYPlane, uint8_t* pUVPlane, uint16_t nSrcWidth,
+ uint16_t nSrcHeight)
{
- uint16_t x, y;
- uint64_t srcIdx, dstIdx;
- const uint64_t size = nSrcWidth * nSrcHeight;
- dstIdx = size - 1;
+ uint16_t x, y, nDstWidth = nSrcHeight, nDstHt = nSrcWidth, nPadWidth = outputStride - nDstWidth;
+ uint64_t srcIdx, dstIdx = (outputStride * nDstHt) - 1;
+ const size_t dstSize = outputStride * nDstHt * 1.5f;
+
+ if (nOutBufSize < (dstSize - nPadWidth))
+ {
+ IMLOGE4("Output buffer size is not sufficient. \
+ Required(outputStride[%d] * outputHeight[%d] * 1.5 = %d) but passed[%d]",
+ outputStride, nDstHt, dstSize, nOutBufSize);
+ return -1;
+ }
+
+ if (nDstWidth > outputStride)
+ {
+ IMLOGE2("Destination width[%d] cannot be bigger than stride[%d]", nDstWidth, outputStride);
+ return -1;
+ }
// Rotate Y buffer
for (y = 0; y < nSrcWidth; y++)
{
+ dstIdx -= nPadWidth;
srcIdx = nSrcWidth - y - 1;
for (x = 0; x < nSrcHeight; x++)
{
- pbDst[dstIdx] = pYPlane[srcIdx]; // Y
+ pOutBuffer[dstIdx] = pYPlane[srcIdx]; // Y
srcIdx += nSrcWidth;
dstIdx--;
}
}
- dstIdx = (size * 1.5f) - 1;
+ dstIdx = dstSize - 1;
nSrcWidth /= 2;
nSrcHeight /= 2;
// Rotate UV buffer
for (y = 0; y < nSrcWidth; y++)
{
+ dstIdx -= nPadWidth;
srcIdx = (nSrcWidth - y - 1) * 2;
for (x = 0; x < nSrcHeight; x++)
{
- pbDst[dstIdx--] = pUVPlane[srcIdx + 1]; // V
- pbDst[dstIdx--] = pUVPlane[srcIdx]; // U
+ pOutBuffer[dstIdx--] = pUVPlane[srcIdx + 1]; // V
+ pOutBuffer[dstIdx--] = pUVPlane[srcIdx]; // U
srcIdx += nSrcWidth * 2;
}
}
+
+ return 0;
}
void ImsMediaImageRotate::YUV420_SP_Rotate90_Flip(uint8_t* pbDst, uint8_t* pYPlane,
@@ -99,7 +118,7 @@ void ImsMediaImageRotate::YUV420_SP_Rotate90_Flip(uint8_t* pbDst, uint8_t* pYPla
{
uint16_t x, y;
uint64_t srcIdx, dstIdx;
- const uint64_t size = nSrcWidth * nSrcHeight;
+ const size_t size = nSrcWidth * nSrcHeight;
dstIdx = size - 1;
@@ -132,40 +151,58 @@ void ImsMediaImageRotate::YUV420_SP_Rotate90_Flip(uint8_t* pbDst, uint8_t* pYPla
}
}
-void ImsMediaImageRotate::YUV420_SP_Rotate270(uint8_t* pbDst, uint8_t* pYPlane, uint8_t* pUVPlane,
- uint16_t nSrcWidth, uint16_t nSrcHeight)
+int ImsMediaImageRotate::YUV420_SP_Rotate270(uint8_t* pOutBuffer, size_t nOutBufSize,
+ uint16_t outputStride, uint8_t* pYPlane, uint8_t* pUVPlane, uint16_t nSrcWidth,
+ uint16_t nSrcHeight)
{
- uint16_t x, y;
- uint64_t srcIdx, dstIdx;
- const uint64_t size = nSrcWidth * nSrcHeight;
+ uint16_t x, y, nDstWth = nSrcHeight, nDstHt = nSrcWidth, nPadWidth = outputStride - nDstWth;
+ uint64_t srcIdx, dstIdx = outputStride * nDstHt - 1;
+ const size_t size = nSrcWidth * nSrcHeight;
+ const size_t dstSize = outputStride * nDstHt * 1.5f;
- dstIdx = size - 1;
+ if (nOutBufSize < (dstSize - nPadWidth))
+ {
+ IMLOGE4("Output buffer size is not sufficient. \
+ Required(outputStride[%d] * outputHeight[%d] * 1.5 = %d) but passed[%d]",
+ outputStride, nDstHt, dstSize, nOutBufSize);
+ return -1;
+ }
+
+ if (nDstWth > outputStride)
+ {
+ IMLOGE2("Destination width[%d] cannot be bigger than stride[%d]", nDstWth, outputStride);
+ return -1;
+ }
// Rotate Y buffer
for (y = 0; y < nSrcWidth; y++)
{
+ dstIdx -= nPadWidth;
srcIdx = size - nSrcWidth + y;
for (x = 0; x < nSrcHeight; x++)
{
- pbDst[dstIdx] = pYPlane[srcIdx]; // Y
+ pOutBuffer[dstIdx] = pYPlane[srcIdx]; // Y
srcIdx -= nSrcWidth;
dstIdx--;
}
}
- dstIdx = (size * 1.5f) - 1;
+ dstIdx = dstSize - 1;
nSrcWidth /= 2;
nSrcHeight /= 2;
// Rotate UV buffer
for (y = 0; y < nSrcWidth; y++)
{
+ dstIdx -= nPadWidth;
srcIdx = (size / 2) - (nSrcWidth - y) * 2;
for (x = 0; x < nSrcHeight; x++)
{
- pbDst[dstIdx--] = pUVPlane[srcIdx + 1]; // V
- pbDst[dstIdx--] = pUVPlane[srcIdx]; // U
+ pOutBuffer[dstIdx--] = pUVPlane[srcIdx + 1]; // V
+ pOutBuffer[dstIdx--] = pUVPlane[srcIdx]; // U
srcIdx -= nSrcWidth * 2;
}
}
+
+ return 0;
} \ No newline at end of file
diff --git a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/android/ImsMediaPauseImageSource.cpp b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/android/ImsMediaPauseImageSource.cpp
index 29a472aa..58c2f9fa 100644
--- a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/android/ImsMediaPauseImageSource.cpp
+++ b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/android/ImsMediaPauseImageSource.cpp
@@ -63,9 +63,10 @@ void ImsMediaPauseImageSource::Uninitialize()
}
}
-bool ImsMediaPauseImageSource::Initialize(int width, int height)
+bool ImsMediaPauseImageSource::Initialize(int width, int height, int stride)
{
- IMLOGD2("[ImsMediaPauseImageSource] Init(width:%d, height:%d)", width, height);
+ IMLOGD3("[ImsMediaPauseImageSource] Init(width:%d, height:%d, stride:%d)", width, height,
+ stride);
mWidth = width;
mHeight = height;
@@ -105,12 +106,12 @@ bool ImsMediaPauseImageSource::Initialize(int width, int height)
* (AndroidBitmapFormat)AImageDecoderHeaderInfo_getAndroidBitmapFormat(info);
*/
- size_t stride = AImageDecoder_getMinimumStride(decoder); // Image decoder does not
+ size_t decStride = AImageDecoder_getMinimumStride(decoder); // Image decoder does not
// use padding by default
- size_t size = height * stride;
+ size_t size = height * decStride;
int8_t* pixels = reinterpret_cast<int8_t*>(malloc(size));
- result = AImageDecoder_decodeImage(decoder, pixels, stride, size);
+ result = AImageDecoder_decodeImage(decoder, pixels, decStride, size);
if (result != ANDROID_IMAGE_DECODER_SUCCESS)
{
IMLOGE0("[ImsMediaPauseImageSource] error occurred, and the file could not be decoded.");
@@ -119,7 +120,7 @@ bool ImsMediaPauseImageSource::Initialize(int width, int height)
return false;
}
- mYuvImageBuffer = ConvertRgbaToYuv(pixels, width, height);
+ mYuvImageBuffer = ConvertRgbaToYuv(pixels, width, height, stride);
AImageDecoder_delete(decoder);
free(pixels);
@@ -141,7 +142,8 @@ size_t ImsMediaPauseImageSource::GetYuvImage(uint8_t* buffer, size_t len)
return mBufferSize;
}
- IMLOGE0("[ImsMediaPauseImageSource] buffer size is smaller. Cannot copy");
+ IMLOGE2("[ImsMediaPauseImageSource] buffer size is smaller. Expected Bufsize[%d], passed[%d]",
+ mBufferSize, len);
return 0;
}
@@ -200,31 +202,27 @@ const char* ImsMediaPauseImageSource::getImageFilePath()
return nullptr;
}
-int8_t* ImsMediaPauseImageSource::ConvertRgbaToYuv(int8_t* pixels, int width, int height)
+int8_t* ImsMediaPauseImageSource::ConvertRgbaToYuv(
+ int8_t* pixels, int width, int height, int stride)
{
// src array must be integer array, data have no padding alignment
int32_t* pSrcArray = reinterpret_cast<int32_t*>(pixels);
- mBufferSize = width * height * 1.5;
+ mBufferSize = stride * height * 1.5;
int8_t* pDstArray = reinterpret_cast<int8_t*>(malloc(mBufferSize));
int32_t nYIndex = 0;
- int32_t nUVIndex = width * height;
- int32_t r, g, b;
+ int32_t nUVIndex = stride * height;
+ int32_t r, g, b, padLen = stride - width;
double y, u, v;
for (int32_t j = 0; j < height; j++)
{
+ int32_t nIndex = width * j;
for (int32_t i = 0; i < width; i++)
{
- int32_t nIndex = width * j + i;
-
- /*
- * TODO: Decode alpha
- * a = (pSrcArray[nIndex] & 0xff000000) >> 24;
- */
-
r = (pSrcArray[nIndex] & 0xff0000) >> 16;
g = (pSrcArray[nIndex] & 0xff00) >> 8;
b = (pSrcArray[nIndex] & 0xff) >> 0;
+ nIndex++;
// rgb to yuv
y = 0.257 * r + 0.504 * g + 0.098 * b + 16;
@@ -240,7 +238,19 @@ int8_t* ImsMediaPauseImageSource::ConvertRgbaToYuv(int8_t* pixels, int width, in
pDstArray[nUVIndex++] = (uint8_t)((u < 0) ? 0 : ((u > 255) ? 255 : u));
}
}
+
+ // Add padding if stride > width
+ if (padLen > 0)
+ {
+ nYIndex += padLen;
+
+ if (j % 2 == 0)
+ {
+ nUVIndex += padLen;
+ }
+ }
}
+ mBufferSize -= padLen;
return pDstArray;
}
diff --git a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/android/ImsMediaVideoSource.cpp b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/android/ImsMediaVideoSource.cpp
index a035443f..591b6d05 100644
--- a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/android/ImsMediaVideoSource.cpp
+++ b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/android/ImsMediaVideoSource.cpp
@@ -220,6 +220,26 @@ bool ImsMediaVideoSource::Start()
return false;
}
+ mCodecStride = mWidth;
+ AMediaFormat* encoderInputFormat = AMediaCodec_getInputFormat(mCodec);
+
+ if (encoderInputFormat != nullptr)
+ {
+ // Check if encoder is initialized with the expected configurations.
+ int32_t width = 0, height = 0;
+ AMediaFormat_getInt32(encoderInputFormat, AMEDIAFORMAT_KEY_WIDTH, &width);
+ AMediaFormat_getInt32(encoderInputFormat, AMEDIAFORMAT_KEY_HEIGHT, &height);
+ AMediaFormat_getInt32(encoderInputFormat, AMEDIAFORMAT_KEY_STRIDE, &mCodecStride);
+ AMediaFormat_delete(encoderInputFormat);
+
+ // TODO: More configuration checks should be added
+ if (mWidth != width || mHeight != height || width > mCodecStride)
+ {
+ IMLOGE0("Encoder doesn't support requested configuration.");
+ return false;
+ }
+ }
+
err = AMediaCodec_start(mCodec);
if (err != AMEDIA_OK)
@@ -273,7 +293,7 @@ bool ImsMediaVideoSource::Start()
}
else if (mVideoMode == kVideoModePauseImage)
{
- mPauseImageSource.Initialize(mWidth, mHeight);
+ mPauseImageSource.Initialize(mWidth, mHeight, mCodecStride);
// start encoder output thread
if (mCodec != nullptr)
{
@@ -355,7 +375,6 @@ void ImsMediaVideoSource::onCameraFrame(AImage* pImage)
{
size_t buffCapacity = 0;
uint8_t* encoderBuf = AMediaCodec_getInputBuffer(mCodec, index, &buffCapacity);
-
if (!encoderBuf || !buffCapacity)
{
IMLOGE1("[onCameraFrame] returned null buffer pointer or buffCapacity[%d]",
@@ -363,7 +382,7 @@ void ImsMediaVideoSource::onCameraFrame(AImage* pImage)
return;
}
- int32_t width, height, ylen, uvlen;
+ int32_t width, height, ylen, uvlen, result = 0;
uint8_t *yPlane, *uvPlane;
AImage_getWidth(pImage, &width);
AImage_getHeight(pImage, &height);
@@ -384,15 +403,15 @@ void ImsMediaVideoSource::onCameraFrame(AImage* pImage)
{
case ACAMERA_LENS_FACING_FRONT:
{
- ImsMediaImageRotate::YUV420_SP_Rotate270(
- encoderBuf, yPlane, uvPlane, width, height);
+ result = ImsMediaImageRotate::YUV420_SP_Rotate270(
+ encoderBuf, buffCapacity, mCodecStride, yPlane, uvPlane, width, height);
}
break;
case ACAMERA_LENS_FACING_BACK:
{
- ImsMediaImageRotate::YUV420_SP_Rotate90(
- encoderBuf, yPlane, uvPlane, width, height);
+ result = ImsMediaImageRotate::YUV420_SP_Rotate90(
+ encoderBuf, buffCapacity, mCodecStride, yPlane, uvPlane, width, height);
}
break;
@@ -408,8 +427,18 @@ void ImsMediaVideoSource::onCameraFrame(AImage* pImage)
IMLOGD_PACKET1(IM_PACKET_LOG_VIDEO, "[onCameraFrame] queue buffer size[%d]", ylen + uvlen);
- AMediaCodec_queueInputBuffer(
- mCodec, index, 0, ylen + uvlen, ImsMediaTimer::GetTimeInMicroSeconds(), 0);
+ if (result == 0)
+ {
+ AMediaCodec_queueInputBuffer(
+ mCodec, index, 0, ylen + uvlen, ImsMediaTimer::GetTimeInMicroSeconds(), 0);
+ }
+ else
+ {
+ IMLOGE5("Camera image resolution[%dx%d]. Encoder resolution[%dx%d] buffer size[%d]",
+ width, height, mWidth, mHeight, buffCapacity);
+ AMediaCodec_queueInputBuffer(mCodec, index, 0, 0, 0, 0);
+ return;
+ }
}
else
{
diff --git a/tests/native/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/utils/ImsMediaImageRotateTest.cpp b/tests/native/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/utils/ImsMediaImageRotateTest.cpp
index 60dc69fb..a5cbd157 100644
--- a/tests/native/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/utils/ImsMediaImageRotateTest.cpp
+++ b/tests/native/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/utils/ImsMediaImageRotateTest.cpp
@@ -72,6 +72,76 @@ TEST_F(ImsMediaImageRotateTest, Rotate90FlipTest_ZeroImageSize)
EXPECT_EQ(memcmp(output_img, exp_img, 0), 0);
}
+TEST_F(ImsMediaImageRotateTest, Rotate90Test)
+{
+ const uint16_t img_width = 4, img_height = 4;
+ const uint32_t img_buf_size = img_width * img_height * 1.5f;
+
+ // Input image Y buffer
+ uint8_t input_img_y[] = {0, 1, 2, 3, 10, 11, 12, 13, 20, 21, 22, 23, 30, 31, 32, 33};
+
+ // Input image UV buffer
+ uint8_t input_img_uv[] = {80, 90, 81, 91, 82, 92, 83, 93};
+
+ // Expected output Y buffer
+ uint8_t exp_img[img_buf_size] = {30, 20, 10, 0, 31, 21, 11, 1, 32, 22, 12, 2, 33, 23, 13, 3, 82,
+ 92, 80, 90, 83, 93, 81, 91};
+
+ // Output image buffer to be verified
+ uint8_t output_img[img_buf_size] = {0};
+
+ ImsMediaImageRotate::YUV420_SP_Rotate90(
+ output_img, img_buf_size, img_height, input_img_y, input_img_uv, img_width, img_height);
+
+ EXPECT_EQ(memcmp(output_img, exp_img, img_buf_size), 0);
+}
+
+TEST_F(ImsMediaImageRotateTest, Rotate90WithOutputStrideTest)
+{
+ const uint16_t img_width = 4, img_height = 4, outimg_stride = 6;
+ const uint32_t img_buf_size = outimg_stride * img_width * 1.5f;
+
+ // Input image Y buffer
+ uint8_t input_img_y[] = {0, 1, 2, 3, 10, 11, 12, 13, 20, 21, 22, 23, 30, 31, 32, 33};
+
+ // Input image UV buffer
+ uint8_t input_img_uv[] = {80, 90, 81, 91, 82, 92, 83, 93};
+
+ // Expected output Y buffer
+ uint8_t exp_img[img_buf_size] = {30, 20, 10, 0, 0, 0, 31, 21, 11, 1, 0, 0, 32, 22, 12, 2, 0, 0,
+ 33, 23, 13, 3, 0, 0, 82, 92, 80, 90, 0, 0, 83, 93, 81, 91, 0, 0};
+
+ // Output image buffer to be verified
+ uint8_t output_img[img_buf_size] = {0};
+
+ ImsMediaImageRotate::YUV420_SP_Rotate90(output_img, img_buf_size, outimg_stride, input_img_y,
+ input_img_uv, img_width, img_height);
+
+ EXPECT_EQ(memcmp(output_img, exp_img, img_buf_size), 0);
+}
+
+TEST_F(ImsMediaImageRotateTest, Rotate90Flip_ZeroImageSize)
+{
+ const uint16_t img_width = 0, img_height = 0;
+
+ // Input image Y buffer
+ uint8_t input_img_y[0] = {};
+
+ // Input image UV buffer
+ uint8_t input_img_uv[0] = {};
+
+ // Expected output Y buffer
+ uint8_t exp_img[0] = {};
+
+ // Output image buffer to be verified
+ uint8_t output_img[0] = {};
+
+ ImsMediaImageRotate::YUV420_SP_Rotate90(
+ output_img, 0, img_height, input_img_y, input_img_uv, img_width, img_height);
+
+ EXPECT_EQ(memcmp(output_img, exp_img, 0), 0);
+}
+
TEST_F(ImsMediaImageRotateTest, Rotate270Test)
{
const uint16_t img_width = 4, img_height = 4;
@@ -91,7 +161,31 @@ TEST_F(ImsMediaImageRotateTest, Rotate270Test)
uint8_t output_img[img_buf_size] = {0};
ImsMediaImageRotate::YUV420_SP_Rotate270(
- output_img, input_img_y, input_img_uv, img_width, img_height);
+ output_img, img_buf_size, img_height, input_img_y, input_img_uv, img_width, img_height);
+
+ EXPECT_EQ(memcmp(output_img, exp_img, img_buf_size), 0);
+}
+
+TEST_F(ImsMediaImageRotateTest, Rotate270WithOutStrideTest)
+{
+ const uint16_t img_width = 4, img_height = 4, outimg_stride = 6;
+ const uint32_t img_buf_size = outimg_stride * img_width * 1.5f;
+
+ // Input image Y buffer
+ uint8_t input_img_y[] = {0, 1, 2, 3, 10, 11, 12, 13, 20, 21, 22, 23, 30, 31, 32, 33};
+
+ // Input image UV buffer
+ uint8_t input_img_uv[] = {80, 90, 81, 91, 82, 92, 83, 93};
+
+ // Expected output Y buffer
+ uint8_t exp_img[img_buf_size] = {3, 13, 23, 33, 0, 0, 2, 12, 22, 32, 0, 0, 1, 11, 21, 31, 0, 0,
+ 0, 10, 20, 30, 0, 0, 81, 91, 83, 93, 0, 0, 80, 90, 82, 92, 0, 0};
+
+ // Output image buffer to be verified
+ uint8_t output_img[img_buf_size] = {0};
+
+ ImsMediaImageRotate::YUV420_SP_Rotate270(output_img, img_buf_size, outimg_stride, input_img_y,
+ input_img_uv, img_width, img_height);
EXPECT_EQ(memcmp(output_img, exp_img, img_buf_size), 0);
}
@@ -113,7 +207,7 @@ TEST_F(ImsMediaImageRotateTest, Rotate270Test_ZeroImageSize)
uint8_t output_img[0] = {};
ImsMediaImageRotate::YUV420_SP_Rotate270(
- output_img, input_img_y, input_img_uv, img_width, img_height);
+ output_img, 0, img_height, input_img_y, input_img_uv, img_width, img_height);
EXPECT_EQ(memcmp(output_img, exp_img, 0), 0);
}