summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvinash Malipatil <avinashmp@google.com>2023-03-22 12:49:39 +0000
committerAvinash Malipatil <avinashmp@google.com>2023-04-05 17:19:21 +0000
commit7a5fc2963d77634dbc5ee736a386839f6268f057 (patch)
tree197c5f4b8d54b2a8c9f2c4442c576468177ed42e
parent982e54e3fea845dd9c853b8133c9092b4355edc6 (diff)
downloadImsMedia-7a5fc2963d77634dbc5ee736a386839f6268f057.tar.gz
Fix video distortion in TX encoded frames.
Video encoder input format has stride not equal to the image width which caused distorted video encoder output. Enhanced image rotation utility and pause image source to accept output image stride and added padding in output buffers. Bug: 266388412 Test: atest ImsMediaNativeTests, tested for all standard resolutions using Media Test App. Change-Id: I1d8ed477e4cb7d4746a32b0f52e64e4660a0014a
-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);
}