Merge "WriterTest: Add extractor validation"
diff --git a/apex/manifest_codec.json b/apex/manifest_codec.json
index 83a5178..eef5a6c 100644
--- a/apex/manifest_codec.json
+++ b/apex/manifest_codec.json
@@ -1,4 +1,7 @@
{
"name": "com.android.media.swcodec",
- "version": 290000000
+ "version": 290000000,
+ "requireNativeLibs": [
+ ":sphal"
+ ]
}
diff --git a/drm/mediacas/plugins/clearkey/ClearKeyFetcher.cpp b/drm/mediacas/plugins/clearkey/ClearKeyFetcher.cpp
index cb69f91..466e571 100644
--- a/drm/mediacas/plugins/clearkey/ClearKeyFetcher.cpp
+++ b/drm/mediacas/plugins/clearkey/ClearKeyFetcher.cpp
@@ -62,8 +62,8 @@
}
ALOGV("descriptor_size=%zu", container.descriptor_size());
- // Sanity check to verify that the BroadcastEncryptor is sending a properly
- // formed EcmContainer. If it contains two Ecms, the ids should have different
+ // Validate that the BroadcastEncryptor is sending a properly formed
+ // EcmContainer. If it contains two Ecms, the ids should have different
// parity (one odd, one even). This does not necessarily affect decryption
// but indicates a problem with Ecm generation.
if (container.descriptor_size() == 2) {
diff --git a/media/OWNERS b/media/OWNERS
index 1afc253..bd83ad9 100644
--- a/media/OWNERS
+++ b/media/OWNERS
@@ -8,7 +8,6 @@
hunga@google.com
jiabin@google.com
jmtrivi@google.com
-krocard@google.com
lajos@google.com
marcone@google.com
mnaganov@google.com
diff --git a/media/codec2/components/aom/C2SoftAomDec.cpp b/media/codec2/components/aom/C2SoftAomDec.cpp
index 36137e6..bb050c8 100644
--- a/media/codec2/components/aom/C2SoftAomDec.cpp
+++ b/media/codec2/components/aom/C2SoftAomDec.cpp
@@ -504,30 +504,28 @@
}
static void copyOutputBufferToYuvPlanarFrame(
- uint8_t *dst, const uint8_t *srcY, const uint8_t *srcU, const uint8_t *srcV,
+ 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) {
- uint8_t* dstStart = dst;
for (size_t i = 0; i < height; ++i) {
- memcpy(dst, srcY, width);
+ memcpy(dstY, srcY, width);
srcY += srcYStride;
- dst += dstYStride;
+ dstY += dstYStride;
}
- dst = dstStart + dstYStride * height;
for (size_t i = 0; i < height / 2; ++i) {
- memcpy(dst, srcV, width / 2);
+ memcpy(dstV, srcV, width / 2);
srcV += srcVStride;
- dst += dstUVStride;
+ dstV += dstUVStride;
}
- dst = dstStart + (dstYStride * height) + (dstUVStride * height / 2);
for (size_t i = 0; i < height / 2; ++i) {
- memcpy(dst, srcU, width / 2);
+ memcpy(dstU, srcU, width / 2);
srcU += srcUStride;
- dst += dstUVStride;
+ dstU += dstUVStride;
}
}
@@ -594,16 +592,12 @@
return;
}
-static void convertYUV420Planar16ToYUV420Planar(uint8_t *dst,
+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) {
-
- uint8_t *dstY = (uint8_t *)dst;
- size_t dstYSize = dstYStride * height;
- size_t dstUVSize = dstUVStride * height / 2;
- uint8_t *dstV = dstY + dstYSize;
- uint8_t *dstU = dstV + dstUVSize;
+ 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) {
@@ -694,7 +688,9 @@
block->width(), block->height(), mWidth, mHeight,
(int)*(int64_t*)img->user_priv);
- uint8_t* dst = const_cast<uint8_t*>(wView.data()[C2PlanarLayout::PLANE_Y]);
+ uint8_t* dstY = const_cast<uint8_t*>(wView.data()[C2PlanarLayout::PLANE_Y]);
+ uint8_t* dstU = const_cast<uint8_t*>(wView.data()[C2PlanarLayout::PLANE_U]);
+ uint8_t* dstV = const_cast<uint8_t*>(wView.data()[C2PlanarLayout::PLANE_V]);
size_t srcYStride = img->stride[AOM_PLANE_Y];
size_t srcUStride = img->stride[AOM_PLANE_U];
size_t srcVStride = img->stride[AOM_PLANE_V];
@@ -708,13 +704,14 @@
const uint16_t *srcV = (const uint16_t *)img->planes[AOM_PLANE_V];
if (format == HAL_PIXEL_FORMAT_RGBA_1010102) {
- convertYUV420Planar16ToY410((uint32_t *)dst, srcY, srcU, srcV, srcYStride / 2,
+ convertYUV420Planar16ToY410((uint32_t *)dstY, srcY, srcU, srcV, srcYStride / 2,
srcUStride / 2, srcVStride / 2,
dstYStride / sizeof(uint32_t),
mWidth, mHeight);
} else {
- convertYUV420Planar16ToYUV420Planar(dst, srcY, srcU, srcV, srcYStride / 2,
- srcUStride / 2, srcVStride / 2,
+ convertYUV420Planar16ToYUV420Planar(dstY, dstU, dstV,
+ srcY, srcU, srcV,
+ srcYStride / 2, srcUStride / 2, srcVStride / 2,
dstYStride, dstUVStride,
mWidth, mHeight);
}
@@ -723,7 +720,7 @@
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(
- dst, srcY, srcU, srcV,
+ dstY, dstU, dstV, srcY, srcU, srcV,
srcYStride, srcUStride, srcVStride,
dstYStride, dstUVStride,
mWidth, mHeight);
diff --git a/media/codec2/components/gav1/C2SoftGav1Dec.cpp b/media/codec2/components/gav1/C2SoftGav1Dec.cpp
index ec5f549..b638a04 100644
--- a/media/codec2/components/gav1/C2SoftGav1Dec.cpp
+++ b/media/codec2/components/gav1/C2SoftGav1Dec.cpp
@@ -470,33 +470,28 @@
}
}
-static void copyOutputBufferToYV12Frame(uint8_t *dst, const uint8_t *srcY,
- const uint8_t *srcU,
- const uint8_t *srcV, size_t srcYStride,
- size_t srcUStride, size_t srcVStride,
+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) {
- const size_t dstYStride = align(width, 16);
- const size_t dstUVStride = align(dstYStride / 2, 16);
- uint8_t *const dstStart = dst;
for (size_t i = 0; i < height; ++i) {
- memcpy(dst, srcY, width);
+ memcpy(dstY, srcY, width);
srcY += srcYStride;
- dst += dstYStride;
+ dstY += dstYStride;
}
- dst = dstStart + dstYStride * height;
for (size_t i = 0; i < height / 2; ++i) {
- memcpy(dst, srcV, width / 2);
+ memcpy(dstV, srcV, width / 2);
srcV += srcVStride;
- dst += dstUVStride;
+ dstV += dstUVStride;
}
- dst = dstStart + (dstYStride * height) + (dstUVStride * height / 2);
for (size_t i = 0; i < height / 2; ++i) {
- memcpy(dst, srcU, width / 2);
+ memcpy(dstU, srcU, width / 2);
srcU += srcUStride;
- dst += dstUVStride;
+ dstU += dstUVStride;
}
}
@@ -568,15 +563,11 @@
}
static void convertYUV420Planar16ToYUV420Planar(
- uint8_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) {
- uint8_t *dstY = (uint8_t *)dst;
- size_t dstYSize = dstStride * height;
- size_t dstUVStride = align(dstStride / 2, 16);
- size_t dstUVSize = dstUVStride * height / 2;
- uint8_t *dstV = dstY + dstYSize;
- uint8_t *dstU = dstV + dstUVSize;
+ 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) {
@@ -584,7 +575,7 @@
}
srcY += srcYStride;
- dstY += dstStride;
+ dstY += dstYStride;
}
for (size_t y = 0; y < (height + 1) / 2; ++y) {
@@ -679,11 +670,17 @@
ALOGV("provided (%dx%d) required (%dx%d), out frameindex %d", block->width(),
block->height(), mWidth, mHeight, (int)buffer->user_private_data);
- uint8_t *dst = const_cast<uint8_t *>(wView.data()[C2PlanarLayout::PLANE_Y]);
+ uint8_t *dstY = const_cast<uint8_t *>(wView.data()[C2PlanarLayout::PLANE_Y]);
+ uint8_t *dstU = const_cast<uint8_t *>(wView.data()[C2PlanarLayout::PLANE_U]);
+ uint8_t *dstV = const_cast<uint8_t *>(wView.data()[C2PlanarLayout::PLANE_V]);
size_t srcYStride = buffer->stride[0];
size_t srcUStride = buffer->stride[1];
size_t srcVStride = buffer->stride[2];
+ C2PlanarLayout layout = wView.layout();
+ size_t dstYStride = layout.planes[C2PlanarLayout::PLANE_Y].rowInc;
+ size_t dstUVStride = layout.planes[C2PlanarLayout::PLANE_U].rowInc;
+
if (buffer->bitdepth == 10) {
const uint16_t *srcY = (const uint16_t *)buffer->plane[0];
const uint16_t *srcU = (const uint16_t *)buffer->plane[1];
@@ -691,19 +688,24 @@
if (format == HAL_PIXEL_FORMAT_RGBA_1010102) {
convertYUV420Planar16ToY410(
- (uint32_t *)dst, srcY, srcU, srcV, srcYStride / 2, srcUStride / 2,
+ (uint32_t *)dstY, srcY, srcU, srcV, srcYStride / 2, srcUStride / 2,
srcVStride / 2, align(mWidth, 16), mWidth, mHeight);
} else {
- convertYUV420Planar16ToYUV420Planar(dst, srcY, srcU, srcV, srcYStride / 2,
- srcUStride / 2, srcVStride / 2,
- align(mWidth, 16), mWidth, mHeight);
+ convertYUV420Planar16ToYUV420Planar(dstY, dstU, dstV,
+ srcY, srcU, srcV,
+ srcYStride / 2, srcUStride / 2, srcVStride / 2,
+ dstYStride, dstUVStride,
+ mWidth, mHeight);
}
} 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(dst, srcY, srcU, srcV, srcYStride, srcUStride,
- srcVStride, mWidth, mHeight);
+ copyOutputBufferToYV12Frame(dstY, dstU, dstV,
+ srcY, srcU, srcV,
+ srcYStride, srcUStride, srcVStride,
+ dstYStride, dstUVStride,
+ mWidth, mHeight);
}
finishWork(buffer->user_private_data, work, std::move(block));
block = nullptr;
diff --git a/media/codec2/components/mpeg4_h263/C2SoftMpeg4Dec.cpp b/media/codec2/components/mpeg4_h263/C2SoftMpeg4Dec.cpp
index 7e6685e..d453a0a 100644
--- a/media/codec2/components/mpeg4_h263/C2SoftMpeg4Dec.cpp
+++ b/media/codec2/components/mpeg4_h263/C2SoftMpeg4Dec.cpp
@@ -467,34 +467,34 @@
/* 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 *dst, uint8_t *src,
+ 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;
- uint8_t *dstStart = dst;
+
size_t vStride = align(height, 16);
for (size_t i = 0; i < height; ++i) {
- memcpy(dst, src, width);
+ memcpy(dstY, src, width);
src += srcYStride;
- dst += dstYStride;
+ dstY += dstYStride;
}
+
/* U buffer */
src = srcStart + vStride * srcYStride;
- dst = dstStart + (dstYStride * height) + (dstUVStride * height / 2);
for (size_t i = 0; i < height / 2; ++i) {
- memcpy(dst, src, width / 2);
+ memcpy(dstU, src, width / 2);
src += srcUVStride;
- dst += dstUVStride;
+ dstU += dstUVStride;
}
+
/* V buffer */
src = srcStart + vStride * srcYStride * 5 / 4;
- dst = dstStart + (dstYStride * height);
for (size_t i = 0; i < height / 2; ++i) {
- memcpy(dst, src, width / 2);
+ memcpy(dstV, src, width / 2);
src += srcUVStride;
- dst += dstUVStride;
+ dstV += dstUVStride;
}
}
@@ -675,11 +675,14 @@
}
uint8_t *outputBufferY = wView.data()[C2PlanarLayout::PLANE_Y];
+ uint8_t *outputBufferU = wView.data()[C2PlanarLayout::PLANE_U];
+ uint8_t *outputBufferV = wView.data()[C2PlanarLayout::PLANE_V];
+
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,
+ outputBufferY, outputBufferU, outputBufferV,
mOutputBuffer[mNumSamplesOutput & 1],
dstYStride, dstUVStride,
align(mWidth, 16), mWidth, mHeight);
diff --git a/media/codec2/components/vpx/C2SoftVpxDec.cpp b/media/codec2/components/vpx/C2SoftVpxDec.cpp
index fbc9c8a..65f03fa 100644
--- a/media/codec2/components/vpx/C2SoftVpxDec.cpp
+++ b/media/codec2/components/vpx/C2SoftVpxDec.cpp
@@ -630,31 +630,30 @@
}
static void copyOutputBufferToYuvPlanarFrame(
- uint8_t *dst, const uint8_t *srcY, const uint8_t *srcU, const uint8_t *srcV,
+ 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) {
- uint8_t *dstStart = dst;
for (size_t i = 0; i < height; ++i) {
- memcpy(dst, srcY, width);
+ memcpy(dstY, srcY, width);
srcY += srcYStride;
- dst += dstYStride;
+ dstY += dstYStride;
}
- dst = dstStart + dstYStride * height;
for (size_t i = 0; i < height / 2; ++i) {
- memcpy(dst, srcV, width / 2);
+ memcpy(dstV, srcV, width / 2);
srcV += srcVStride;
- dst += dstUVStride;
+ dstV += dstUVStride;
}
- dst = dstStart + (dstYStride * height) + (dstUVStride * height / 2);
for (size_t i = 0; i < height / 2; ++i) {
- memcpy(dst, srcU, width / 2);
+ memcpy(dstU, srcU, width / 2);
srcU += srcUStride;
- dst += dstUVStride;
+ dstU += dstUVStride;
}
+
}
static void convertYUV420Planar16ToY410(uint32_t *dst,
@@ -720,16 +719,12 @@
return;
}
-static void convertYUV420Planar16ToYUV420Planar(uint8_t *dst,
+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) {
-
- uint8_t *dstY = (uint8_t *)dst;
- size_t dstYSize = dstYStride * height;
- size_t dstUVSize = dstUVStride * height / 2;
- uint8_t *dstV = dstY + dstYSize;
- uint8_t *dstU = dstV + dstUVSize;
+ 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) {
@@ -822,7 +817,10 @@
block->width(), block->height(), mWidth, mHeight,
((c2_cntr64_t *)img->user_priv)->peekll());
- uint8_t *dst = const_cast<uint8_t *>(wView.data()[C2PlanarLayout::PLANE_Y]);
+ uint8_t *dstY = const_cast<uint8_t *>(wView.data()[C2PlanarLayout::PLANE_Y]);
+ uint8_t *dstU = const_cast<uint8_t *>(wView.data()[C2PlanarLayout::PLANE_U]);
+ uint8_t *dstV = const_cast<uint8_t *>(wView.data()[C2PlanarLayout::PLANE_V]);
+
size_t srcYStride = img->stride[VPX_PLANE_Y];
size_t srcUStride = img->stride[VPX_PLANE_U];
size_t srcVStride = img->stride[VPX_PLANE_V];
@@ -841,18 +839,18 @@
constexpr size_t kHeight = 64;
for (; i < mHeight; i += kHeight) {
queue->entries.push_back(
- [dst, srcY, srcU, srcV,
+ [dstY, srcY, srcU, srcV,
srcYStride, srcUStride, srcVStride, dstYStride,
width = mWidth, height = std::min(mHeight - i, kHeight)] {
convertYUV420Planar16ToY410(
- (uint32_t *)dst, srcY, srcU, srcV, srcYStride / 2,
+ (uint32_t *)dstY, srcY, srcU, srcV, srcYStride / 2,
srcUStride / 2, srcVStride / 2, dstYStride / sizeof(uint32_t),
width, height);
});
srcY += srcYStride / 2 * kHeight;
srcU += srcUStride / 2 * (kHeight / 2);
srcV += srcVStride / 2 * (kHeight / 2);
- dst += dstYStride * kHeight;
+ dstY += dstYStride * kHeight;
}
CHECK_EQ(0u, queue->numPending);
queue->numPending = queue->entries.size();
@@ -861,8 +859,9 @@
queue.waitForCondition(queue->cond);
}
} else {
- convertYUV420Planar16ToYUV420Planar(dst, srcY, srcU, srcV, srcYStride / 2,
- srcUStride / 2, srcVStride / 2,
+ convertYUV420Planar16ToYUV420Planar(dstY, dstU, dstV,
+ srcY, srcU, srcV,
+ srcYStride / 2, srcUStride / 2, srcVStride / 2,
dstYStride, dstUVStride,
mWidth, mHeight);
}
@@ -870,8 +869,10 @@
const uint8_t *srcY = (const uint8_t *)img->planes[VPX_PLANE_Y];
const uint8_t *srcU = (const uint8_t *)img->planes[VPX_PLANE_U];
const uint8_t *srcV = (const uint8_t *)img->planes[VPX_PLANE_V];
+
copyOutputBufferToYuvPlanarFrame(
- dst, srcY, srcU, srcV,
+ dstY, dstU, dstV,
+ srcY, srcU, srcV,
srcYStride, srcUStride, srcVStride,
dstYStride, dstUVStride,
mWidth, mHeight);
diff --git a/media/extractors/mp4/ItemTable.cpp b/media/extractors/mp4/ItemTable.cpp
index 0773387..2599c2c 100644
--- a/media/extractors/mp4/ItemTable.cpp
+++ b/media/extractors/mp4/ItemTable.cpp
@@ -546,11 +546,11 @@
continue;
}
ALOGV("Image item id %d uses thumbnail item id %d", mRefs[i], mItemId);
- ImageItem &masterImage = itemIdToItemMap.editValueAt(itemIndex);
- if (!masterImage.thumbnails.empty()) {
+ ImageItem &imageItem = itemIdToItemMap.editValueAt(itemIndex);
+ if (!imageItem.thumbnails.empty()) {
ALOGW("already has thumbnails!");
}
- masterImage.thumbnails.push_back(mItemId);
+ imageItem.thumbnails.push_back(mItemId);
}
break;
}
@@ -929,7 +929,7 @@
status_t IpcoBox::parse(off64_t offset, size_t size) {
ALOGV("%s: offset %lld, size %zu", __FUNCTION__, (long long)offset, size);
- // push dummy as the index is 1-based
+ // push a placeholder as the index is 1-based
mItemProperties->push_back(new ItemProperty());
return parseChunks(offset, size);
}
@@ -1614,17 +1614,17 @@
return BAD_VALUE;
}
- uint32_t masterItemIndex = mDisplayables[imageIndex];
+ uint32_t imageItemIndex = mDisplayables[imageIndex];
- const ImageItem &masterImage = mItemIdToItemMap[masterItemIndex];
- if (masterImage.thumbnails.empty()) {
- *itemIndex = masterItemIndex;
+ const ImageItem &imageItem = mItemIdToItemMap[imageItemIndex];
+ if (imageItem.thumbnails.empty()) {
+ *itemIndex = imageItemIndex;
return OK;
}
- ssize_t thumbItemIndex = mItemIdToItemMap.indexOfKey(masterImage.thumbnails[0]);
+ ssize_t thumbItemIndex = mItemIdToItemMap.indexOfKey(imageItem.thumbnails[0]);
if (thumbItemIndex < 0) {
- // Do not return the master image in this case, fail it so that the
+ // Do not return the image item in this case, fail it so that the
// thumbnail extraction code knows we really don't have it.
return INVALID_OPERATION;
}
diff --git a/media/extractors/mp4/MPEG4Extractor.cpp b/media/extractors/mp4/MPEG4Extractor.cpp
index 2d92f75..342b128 100644
--- a/media/extractors/mp4/MPEG4Extractor.cpp
+++ b/media/extractors/mp4/MPEG4Extractor.cpp
@@ -1069,7 +1069,7 @@
} else if (chunk_type == FOURCC("moov")) {
mInitCheck = OK;
- return UNKNOWN_ERROR; // Return a dummy error.
+ return UNKNOWN_ERROR; // Return a generic error.
}
break;
}
@@ -5515,7 +5515,7 @@
return -EINVAL;
}
- // apply some sanity (vs strict legality) checks
+ // apply some quick (vs strict legality) checks
//
static constexpr uint32_t kMaxTrunSampleCount = 10000;
if (sampleCount > kMaxTrunSampleCount) {
diff --git a/media/libaaudio/examples/utils/dummy.cpp b/media/libaaudio/examples/utils/dummy.cpp
deleted file mode 100644
index 8ef7e36..0000000
--- a/media/libaaudio/examples/utils/dummy.cpp
+++ /dev/null
@@ -1,5 +0,0 @@
-/**
- * Dummy file needed to get Android Studio to scan this folder.
- */
-
-int g_DoNotUseThisVariable = 0;
diff --git a/media/libaaudio/examples/utils/unused.cpp b/media/libaaudio/examples/utils/unused.cpp
new file mode 100644
index 0000000..9a5205e
--- /dev/null
+++ b/media/libaaudio/examples/utils/unused.cpp
@@ -0,0 +1,5 @@
+/**
+ * Unused file required to get Android Studio to scan this folder.
+ */
+
+int g_DoNotUseThisVariable = 0;
diff --git a/media/libaaudio/src/binding/SharedMemoryParcelable.h b/media/libaaudio/src/binding/SharedMemoryParcelable.h
index 4ec38c5..3927f58 100644
--- a/media/libaaudio/src/binding/SharedMemoryParcelable.h
+++ b/media/libaaudio/src/binding/SharedMemoryParcelable.h
@@ -26,7 +26,7 @@
namespace aaudio {
-// Arbitrary limits for sanity checks. TODO remove after debugging.
+// Arbitrary limits for range checks.
#define MAX_SHARED_MEMORIES (32)
#define MAX_MMAP_OFFSET_BYTES (32 * 1024 * 8)
#define MAX_MMAP_SIZE_BYTES (32 * 1024 * 8)
diff --git a/media/libaaudio/src/flowgraph/AudioProcessorBase.h b/media/libaaudio/src/flowgraph/AudioProcessorBase.h
index eda46ae..972932f 100644
--- a/media/libaaudio/src/flowgraph/AudioProcessorBase.h
+++ b/media/libaaudio/src/flowgraph/AudioProcessorBase.h
@@ -267,7 +267,7 @@
AudioFloatInputPort input;
/**
- * Dummy processor. The work happens in the read() method.
+ * Do nothing. The work happens in the read() method.
*
* @param framePosition index of first frame to be processed
* @param numFrames
diff --git a/media/libaudioclient/AudioEffect.cpp b/media/libaudioclient/AudioEffect.cpp
index 2b2506c..61f09ab 100644
--- a/media/libaudioclient/AudioEffect.cpp
+++ b/media/libaudioclient/AudioEffect.cpp
@@ -36,62 +36,10 @@
// ---------------------------------------------------------------------------
AudioEffect::AudioEffect(const String16& opPackageName)
- : mStatus(NO_INIT), mOpPackageName(opPackageName)
+ : mOpPackageName(opPackageName)
{
}
-
-AudioEffect::AudioEffect(const effect_uuid_t *type,
- const String16& opPackageName,
- const effect_uuid_t *uuid,
- int32_t priority,
- effect_callback_t cbf,
- void* user,
- audio_session_t sessionId,
- audio_io_handle_t io,
- const AudioDeviceTypeAddr& device
- )
- : mStatus(NO_INIT), mOpPackageName(opPackageName)
-{
- AutoMutex lock(mConstructLock);
- mStatus = set(type, uuid, priority, cbf, user, sessionId, io, device);
-}
-
-AudioEffect::AudioEffect(const char *typeStr,
- const String16& opPackageName,
- const char *uuidStr,
- int32_t priority,
- effect_callback_t cbf,
- void* user,
- audio_session_t sessionId,
- audio_io_handle_t io,
- const AudioDeviceTypeAddr& device
- )
- : mStatus(NO_INIT), mOpPackageName(opPackageName)
-{
- effect_uuid_t type;
- effect_uuid_t *pType = NULL;
- effect_uuid_t uuid;
- effect_uuid_t *pUuid = NULL;
-
- ALOGV("Constructor string\n - type: %s\n - uuid: %s", typeStr, uuidStr);
-
- if (typeStr != NULL) {
- if (stringToGuid(typeStr, &type) == NO_ERROR) {
- pType = &type;
- }
- }
-
- if (uuidStr != NULL) {
- if (stringToGuid(uuidStr, &uuid) == NO_ERROR) {
- pUuid = &uuid;
- }
- }
-
- AutoMutex lock(mConstructLock);
- mStatus = set(pType, pUuid, priority, cbf, user, sessionId, io, device);
-}
-
status_t AudioEffect::set(const effect_uuid_t *type,
const effect_uuid_t *uuid,
int32_t priority,
@@ -183,6 +131,33 @@
return mStatus;
}
+status_t AudioEffect::set(const char *typeStr,
+ const char *uuidStr,
+ int32_t priority,
+ effect_callback_t cbf,
+ void* user,
+ audio_session_t sessionId,
+ audio_io_handle_t io,
+ const AudioDeviceTypeAddr& device)
+{
+ effect_uuid_t type;
+ effect_uuid_t *pType = nullptr;
+ effect_uuid_t uuid;
+ effect_uuid_t *pUuid = nullptr;
+
+ ALOGV("AudioEffect::set string\n - type: %s\n - uuid: %s",
+ typeStr ? typeStr : "nullptr", uuidStr ? uuidStr : "nullptr");
+
+ if (stringToGuid(typeStr, &type) == NO_ERROR) {
+ pType = &type;
+ }
+ if (stringToGuid(uuidStr, &uuid) == NO_ERROR) {
+ pUuid = &uuid;
+ }
+
+ return set(pType, pUuid, priority, cbf, user, sessionId, io, device);
+}
+
AudioEffect::~AudioEffect()
{
diff --git a/media/libaudioclient/AudioRecord.cpp b/media/libaudioclient/AudioRecord.cpp
index 3d0d622..e42a8cd 100644
--- a/media/libaudioclient/AudioRecord.cpp
+++ b/media/libaudioclient/AudioRecord.cpp
@@ -1022,7 +1022,7 @@
}
if (ssize_t(userSize) < 0 || (buffer == NULL && userSize != 0)) {
- // sanity-check. user is most-likely passing an error code, and it would
+ // Validation. user is most-likely passing an error code, and it would
// make the return value ambiguous (actualSize vs error).
ALOGE("%s(%d) (buffer=%p, size=%zu (%zu)",
__func__, mPortId, buffer, userSize, userSize);
@@ -1249,7 +1249,7 @@
mCbf(EVENT_MORE_DATA, mUserData, &audioBuffer);
size_t readSize = audioBuffer.size;
- // Sanity check on returned size
+ // Validate on returned size
if (ssize_t(readSize) < 0 || readSize > reqSize) {
ALOGE("%s(%d): EVENT_MORE_DATA requested %zu bytes but callback returned %zd bytes",
__func__, mPortId, reqSize, ssize_t(readSize));
diff --git a/media/libaudioclient/AudioTrack.cpp b/media/libaudioclient/AudioTrack.cpp
index 9a66d48..afb44f3 100644
--- a/media/libaudioclient/AudioTrack.cpp
+++ b/media/libaudioclient/AudioTrack.cpp
@@ -1796,7 +1796,7 @@
}
if (ssize_t(userSize) < 0 || (buffer == NULL && userSize != 0)) {
- // Sanity-check: user is most-likely passing an error code, and it would
+ // Validation: user is most-likely passing an error code, and it would
// make the return value ambiguous (actualSize vs error).
ALOGE("%s(%d): AudioTrack::write(buffer=%p, size=%zu (%zd)",
__func__, mPortId, buffer, userSize, userSize);
@@ -2186,7 +2186,7 @@
mUserData, &audioBuffer);
size_t writtenSize = audioBuffer.size;
- // Sanity check on returned size
+ // Validate on returned size
if (ssize_t(writtenSize) < 0 || writtenSize > reqSize) {
ALOGE("%s(%d): EVENT_MORE_DATA requested %zu bytes but callback returned %zd bytes",
__func__, mPortId, reqSize, ssize_t(writtenSize));
diff --git a/media/libaudioclient/IAudioFlinger.cpp b/media/libaudioclient/IAudioFlinger.cpp
index 53d46f1..5879a93 100644
--- a/media/libaudioclient/IAudioFlinger.cpp
+++ b/media/libaudioclient/IAudioFlinger.cpp
@@ -998,7 +998,7 @@
break;
}
- // Whitelist of relevant events to trigger log merging.
+ // List of relevant events that trigger log merging.
// Log merging should activate during audio activity of any kind. This are considered the
// most relevant events.
// TODO should select more wisely the items from the list
diff --git a/media/libaudioclient/OWNERS b/media/libaudioclient/OWNERS
index 482b9fb..034d161 100644
--- a/media/libaudioclient/OWNERS
+++ b/media/libaudioclient/OWNERS
@@ -1,3 +1,4 @@
gkasten@google.com
+hunga@google.com
jmtrivi@google.com
mnaganov@google.com
diff --git a/media/libaudioclient/include/media/AudioEffect.h b/media/libaudioclient/include/media/AudioEffect.h
index f17d737..2f7086a 100644
--- a/media/libaudioclient/include/media/AudioEffect.h
+++ b/media/libaudioclient/include/media/AudioEffect.h
@@ -339,16 +339,21 @@
*
* opPackageName: The package name used for app op checks.
*/
- AudioEffect(const String16& opPackageName);
+ explicit AudioEffect(const String16& opPackageName);
+ /* Terminates the AudioEffect and unregisters it from AudioFlinger.
+ * The effect engine is also destroyed if this AudioEffect was the last controlling
+ * the engine.
+ */
+ ~AudioEffect();
- /* Constructor.
+ /**
+ * Initialize an uninitialized AudioEffect.
*
* Parameters:
*
* type: type of effect created: can be null if uuid is specified. This corresponds to
* the OpenSL ES interface implemented by this effect.
- * opPackageName: The package name used for app op checks.
* uuid: Uuid of effect created: can be null if type is specified. This uuid corresponds to
* a particular implementation of an effect type.
* priority: requested priority for effect control: the priority level corresponds to the
@@ -356,7 +361,7 @@
* higher priorities, 0 being the normal priority.
* cbf: optional callback function (see effect_callback_t)
* user: pointer to context for use by the callback receiver.
- * sessionID: audio session this effect is associated to.
+ * sessionId: audio session this effect is associated to.
* If equal to AUDIO_SESSION_OUTPUT_MIX, the effect will be global to
* the output mix. Otherwise, the effect will be applied to all players
* (AudioTrack or MediaPLayer) within the same audio session.
@@ -365,46 +370,13 @@
* device: An audio device descriptor. Only used when "sessionID" is AUDIO_SESSION_DEVICE.
* Specifies the audio device type and address the effect must be attached to.
* If "sessionID" is AUDIO_SESSION_DEVICE then "io" must be AUDIO_IO_HANDLE_NONE.
+ *
+ * Returned status (from utils/Errors.h) can be:
+ * - NO_ERROR or ALREADY_EXISTS: successful initialization
+ * - INVALID_OPERATION: AudioEffect is already initialized
+ * - BAD_VALUE: invalid parameter
+ * - NO_INIT: audio flinger or audio hardware not initialized
*/
-
- AudioEffect(const effect_uuid_t *type,
- const String16& opPackageName,
- const effect_uuid_t *uuid = NULL,
- int32_t priority = 0,
- effect_callback_t cbf = NULL,
- void* user = NULL,
- audio_session_t sessionId = AUDIO_SESSION_OUTPUT_MIX,
- audio_io_handle_t io = AUDIO_IO_HANDLE_NONE,
- const AudioDeviceTypeAddr& device = {}
- );
-
- /* Constructor.
- * Same as above but with type and uuid specified by character strings
- */
- AudioEffect(const char *typeStr,
- const String16& opPackageName,
- const char *uuidStr = NULL,
- int32_t priority = 0,
- effect_callback_t cbf = NULL,
- void* user = NULL,
- audio_session_t sessionId = AUDIO_SESSION_OUTPUT_MIX,
- audio_io_handle_t io = AUDIO_IO_HANDLE_NONE,
- const AudioDeviceTypeAddr& device = {}
- );
-
- /* Terminates the AudioEffect and unregisters it from AudioFlinger.
- * The effect engine is also destroyed if this AudioEffect was the last controlling
- * the engine.
- */
- ~AudioEffect();
-
- /* Initialize an uninitialized AudioEffect.
- * Returned status (from utils/Errors.h) can be:
- * - NO_ERROR or ALREADY_EXISTS: successful initialization
- * - INVALID_OPERATION: AudioEffect is already initialized
- * - BAD_VALUE: invalid parameter
- * - NO_INIT: audio flinger or audio hardware not initialized
- * */
status_t set(const effect_uuid_t *type,
const effect_uuid_t *uuid = NULL,
int32_t priority = 0,
@@ -412,8 +384,18 @@
void* user = NULL,
audio_session_t sessionId = AUDIO_SESSION_OUTPUT_MIX,
audio_io_handle_t io = AUDIO_IO_HANDLE_NONE,
- const AudioDeviceTypeAddr& device = {}
- );
+ const AudioDeviceTypeAddr& device = {});
+ /*
+ * Same as above but with type and uuid specified by character strings.
+ */
+ status_t set(const char *typeStr,
+ const char *uuidStr = NULL,
+ int32_t priority = 0,
+ effect_callback_t cbf = NULL,
+ void* user = NULL,
+ audio_session_t sessionId = AUDIO_SESSION_OUTPUT_MIX,
+ audio_io_handle_t io = AUDIO_IO_HANDLE_NONE,
+ const AudioDeviceTypeAddr& device = {});
/* Result of constructing the AudioEffect. This must be checked
* before using any AudioEffect API.
@@ -543,19 +525,18 @@
static const uint32_t kMaxPreProcessing = 10;
protected:
- bool mEnabled; // enable state
- audio_session_t mSessionId; // audio session ID
- int32_t mPriority; // priority for effect control
- status_t mStatus; // effect status
- effect_callback_t mCbf; // callback function for status, control and
+ const String16 mOpPackageName; // The package name used for app op checks.
+ bool mEnabled = false; // enable state
+ audio_session_t mSessionId = AUDIO_SESSION_OUTPUT_MIX; // audio session ID
+ int32_t mPriority = 0; // priority for effect control
+ status_t mStatus = NO_INIT; // effect status
+ effect_callback_t mCbf = nullptr; // callback function for status, control and
// parameter changes notifications
- void* mUserData; // client context for callback function
- effect_descriptor_t mDescriptor; // effect descriptor
- int32_t mId; // system wide unique effect engine instance ID
+ void* mUserData = nullptr;// client context for callback function
+ effect_descriptor_t mDescriptor = {}; // effect descriptor
+ int32_t mId = -1; // system wide unique effect engine instance ID
Mutex mLock; // Mutex for mEnabled access
- Mutex mConstructLock; // Mutex for integrality construction
- String16 mOpPackageName; // The package name used for app op checks.
// IEffectClient
virtual void controlStatusChanged(bool controlGranted);
@@ -580,22 +561,12 @@
virtual void controlStatusChanged(bool controlGranted) {
sp<AudioEffect> effect = mEffect.promote();
if (effect != 0) {
- {
- // Got the mConstructLock means the construction of AudioEffect
- // has finished, we should release the mConstructLock immediately.
- AutoMutex lock(effect->mConstructLock);
- }
effect->controlStatusChanged(controlGranted);
}
}
virtual void enableStatusChanged(bool enabled) {
sp<AudioEffect> effect = mEffect.promote();
if (effect != 0) {
- {
- // Got the mConstructLock means the construction of AudioEffect
- // has finished, we should release the mConstructLock immediately.
- AutoMutex lock(effect->mConstructLock);
- }
effect->enableStatusChanged(enabled);
}
}
@@ -606,11 +577,6 @@
void *pReplyData) {
sp<AudioEffect> effect = mEffect.promote();
if (effect != 0) {
- {
- // Got the mConstructLock means the construction of AudioEffect
- // has finished, we should release the mConstructLock immediately.
- AutoMutex lock(effect->mConstructLock);
- }
effect->commandExecuted(
cmdCode, cmdSize, pCmdData, replySize, pReplyData);
}
@@ -620,11 +586,6 @@
virtual void binderDied(const wp<IBinder>& /*who*/) {
sp<AudioEffect> effect = mEffect.promote();
if (effect != 0) {
- {
- // Got the mConstructLock means the construction of AudioEffect
- // has finished, we should release the mConstructLock immediately.
- AutoMutex lock(effect->mConstructLock);
- }
effect->binderDied();
}
}
@@ -638,8 +599,8 @@
sp<IEffect> mIEffect; // IEffect binder interface
sp<EffectClient> mIEffectClient; // IEffectClient implementation
sp<IMemory> mCblkMemory; // shared memory for deferred parameter setting
- effect_param_cblk_t* mCblk; // control block for deferred parameter setting
- pid_t mClientPid;
+ effect_param_cblk_t* mCblk = nullptr; // control block for deferred parameter setting
+ pid_t mClientPid = (pid_t)-1;
};
diff --git a/media/libaudiohal/OWNERS b/media/libaudiohal/OWNERS
index 1456ab6..71b17e6 100644
--- a/media/libaudiohal/OWNERS
+++ b/media/libaudiohal/OWNERS
@@ -1,2 +1 @@
-krocard@google.com
mnaganov@google.com
diff --git a/media/libaudioprocessing/AudioResamplerDyn.cpp b/media/libaudioprocessing/AudioResamplerDyn.cpp
index ec56b00..96d6104 100644
--- a/media/libaudioprocessing/AudioResamplerDyn.cpp
+++ b/media/libaudioprocessing/AudioResamplerDyn.cpp
@@ -636,7 +636,7 @@
const uint32_t phaseWrapLimit = c.mL << c.mShift;
size_t inFrameCount = (phaseIncrement * (uint64_t)outFrameCount + phaseFraction)
/ phaseWrapLimit;
- // sanity check that inFrameCount is in signed 32 bit integer range.
+ // validate that inFrameCount is in signed 32 bit integer range.
ALOG_ASSERT(0 <= inFrameCount && inFrameCount < (1U << 31));
//ALOGV("inFrameCount:%d outFrameCount:%d"
@@ -646,7 +646,7 @@
// NOTE: be very careful when modifying the code here. register
// pressure is very high and a small change might cause the compiler
// to generate far less efficient code.
- // Always sanity check the result with objdump or test-resample.
+ // Always validate the result with objdump or test-resample.
// the following logic is a bit convoluted to keep the main processing loop
// as tight as possible with register allocation.
diff --git a/media/libaudioprocessing/AudioResamplerFirProcess.h b/media/libaudioprocessing/AudioResamplerFirProcess.h
index 9b70a1c..1fcffcc 100644
--- a/media/libaudioprocessing/AudioResamplerFirProcess.h
+++ b/media/libaudioprocessing/AudioResamplerFirProcess.h
@@ -381,7 +381,7 @@
// NOTE: be very careful when modifying the code here. register
// pressure is very high and a small change might cause the compiler
// to generate far less efficient code.
- // Always sanity check the result with objdump or test-resample.
+ // Always validate the result with objdump or test-resample.
if (LOCKED) {
// locked polyphase (no interpolation)
diff --git a/media/libaudioprocessing/AudioResamplerSinc.cpp b/media/libaudioprocessing/AudioResamplerSinc.cpp
index 5a03a0d..f2c386d 100644
--- a/media/libaudioprocessing/AudioResamplerSinc.cpp
+++ b/media/libaudioprocessing/AudioResamplerSinc.cpp
@@ -404,7 +404,7 @@
// NOTE: be very careful when modifying the code here. register
// pressure is very high and a small change might cause the compiler
// to generate far less efficient code.
- // Always sanity check the result with objdump or test-resample.
+ // Always validate the result with objdump or test-resample.
// compute the index of the coefficient on the positive side and
// negative side
diff --git a/media/libeffects/OWNERS b/media/libeffects/OWNERS
index 7f9ae81..b7832ea 100644
--- a/media/libeffects/OWNERS
+++ b/media/libeffects/OWNERS
@@ -1,4 +1,3 @@
hunga@google.com
-krocard@google.com
mnaganov@google.com
rago@google.com
diff --git a/media/libeffects/factory/EffectsConfigLoader.c b/media/libeffects/factory/EffectsConfigLoader.c
index fcef36f..e23530e 100644
--- a/media/libeffects/factory/EffectsConfigLoader.c
+++ b/media/libeffects/factory/EffectsConfigLoader.c
@@ -394,7 +394,7 @@
}
sub_effect_entry_t *subEntry = (sub_effect_entry_t*)gSubEffectList->sub_elem->object;
effect_descriptor_t *subEffectDesc = (effect_descriptor_t*)(subEntry->object);
- // Since we return a dummy descriptor for the proxy during
+ // Since we return a stub descriptor for the proxy during
// get_descriptor call,we replace it with the correspoding
// sw effect descriptor, but with Proxy UUID
// check for Sw desc
diff --git a/media/libeffects/factory/EffectsXmlConfigLoader.cpp b/media/libeffects/factory/EffectsXmlConfigLoader.cpp
index 505be7c..30a9007 100644
--- a/media/libeffects/factory/EffectsXmlConfigLoader.cpp
+++ b/media/libeffects/factory/EffectsXmlConfigLoader.cpp
@@ -283,7 +283,7 @@
}
listPush(effectLoadResult.effectDesc.get(), subEffectList);
- // Since we return a dummy descriptor for the proxy during
+ // Since we return a stub descriptor for the proxy during
// get_descriptor call, we replace it with the corresponding
// sw effect descriptor, but keep the Proxy UUID
*effectLoadResult.effectDesc = *swEffectLoadResult.effectDesc;
diff --git a/media/libeffects/lvm/lib/Common/lib/VectorArithmetic.h b/media/libeffects/lvm/lib/Common/lib/VectorArithmetic.h
index 2af1eeb..b27bac5 100644
--- a/media/libeffects/lvm/lib/Common/lib/VectorArithmetic.h
+++ b/media/libeffects/lvm/lib/Common/lib/VectorArithmetic.h
@@ -37,6 +37,7 @@
LVM_INT16 NrFrames,
LVM_INT32 NrChannels);
void Copy_Float_Stereo_Mc( const LVM_FLOAT *src,
+ LVM_FLOAT *StereoOut,
LVM_FLOAT *dst,
LVM_INT16 NrFrames,
LVM_INT32 NrChannels);
diff --git a/media/libeffects/lvm/lib/Common/src/Copy_16.cpp b/media/libeffects/lvm/lib/Common/src/Copy_16.cpp
index 7cb642f..3a50554 100644
--- a/media/libeffects/lvm/lib/Common/src/Copy_16.cpp
+++ b/media/libeffects/lvm/lib/Common/src/Copy_16.cpp
@@ -116,30 +116,31 @@
}
}
-// Merge a multichannel source with stereo contained in dst, to dst.
+// Merge a multichannel source with stereo contained in StereoOut, to dst.
void Copy_Float_Stereo_Mc(const LVM_FLOAT *src,
+ LVM_FLOAT *StereoOut,
LVM_FLOAT *dst,
LVM_INT16 NrFrames, /* Number of frames*/
LVM_INT32 NrChannels)
{
LVM_INT16 ii, jj;
- LVM_FLOAT *src_st = dst + 2 * (NrFrames - 1);
- // repack dst which carries stereo information
+ // pack dst with stereo information of StereoOut
// together with the upper channels of src.
+ StereoOut += 2 * (NrFrames - 1);
dst += NrChannels * (NrFrames - 1);
src += NrChannels * (NrFrames - 1);
for (ii = NrFrames; ii != 0; ii--)
{
- dst[1] = src_st[1];
- dst[0] = src_st[0]; // copy 1 before 0 is required for NrChannels == 3.
+ dst[1] = StereoOut[1];
+ dst[0] = StereoOut[0]; // copy 1 before 0 is required for NrChannels == 3.
for (jj = 2; jj < NrChannels; jj++)
{
dst[jj] = src[jj];
}
dst -= NrChannels;
src -= NrChannels;
- src_st -= 2;
+ StereoOut -= 2;
}
}
#endif
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Private.h b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Private.h
index 620b341..154ea55 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Private.h
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Private.h
@@ -54,7 +54,11 @@
#define LVCS_COMPGAINFRAME 64 /* Compressor gain update interval */
/* Memory */
+#ifdef SUPPORT_MC
+#define LVCS_SCRATCHBUFFERS 8 /* Number of buffers required for inplace processing */
+#else
#define LVCS_SCRATCHBUFFERS 6 /* Number of buffers required for inplace processing */
+#endif
#ifdef SUPPORT_MC
/*
* The Concert Surround module applies processing only on the first two
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Process.cpp b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Process.cpp
index ded3bfa..8e09be2 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Process.cpp
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Process.cpp
@@ -104,7 +104,7 @@
* The Concert Surround module carries out processing only on L, R.
*/
pInput = pScratch + (2 * NrFrames);
- pStIn = pScratch + (LVCS_SCRATCHBUFFERS * NrFrames);
+ pStIn = pScratch + ((LVCS_SCRATCHBUFFERS - 2) * NrFrames);
/* The first two channel data is extracted from the input data and
* copied into pInput buffer
*/
@@ -232,13 +232,45 @@
*/
if (pInstance->Params.OperatingMode != LVCS_OFF)
{
+#ifdef SUPPORT_MC
+ LVM_FLOAT *pStereoOut;
+ /*
+ * LVCS_Process_CS uses output buffer to store intermediate outputs of StereoEnhancer,
+ * Equalizer, ReverbGenerator and BypassMixer.
+ * So, to avoid i/o data overlapping, when i/o buffers are common, use scratch buffer
+ * to store intermediate outputs.
+ */
+ if (pOutData == pInData)
+ {
+ /*
+ * Scratch memory is used in 4 chunks of (2 * NrFrames) size.
+ * First chunk of memory is used by LVCS_StereoEnhancer and LVCS_ReverbGenerator,
+ * second and fourth are used as input buffers by pInput and pStIn in LVCS_Process_CS.
+ * Hence, pStereoOut is pointed to use unused third portion of scratch memory.
+ */
+ pStereoOut = (LVM_FLOAT *) \
+ pInstance->MemoryTable. \
+ Region[LVCS_MEMREGION_TEMPORARY_FAST].pBaseAddress +
+ ((LVCS_SCRATCHBUFFERS - 4) * NrFrames);
+ }
+ else
+ {
+ pStereoOut = pOutData;
+ }
+
/*
* Call CS process function
*/
err = LVCS_Process_CS(hInstance,
pInData,
+ pStereoOut,
+ NrFrames);
+#else
+ err = LVCS_Process_CS(hInstance,
+ pInData,
pOutData,
NumSamples);
+#endif
/*
* Compress to reduce expansion effect of Concert Sound and correct volume
@@ -257,10 +289,17 @@
if(NumSamples < LVCS_COMPGAINFRAME)
{
+#ifdef SUPPORT_MC
+ NonLinComp_Float(Gain, /* Compressor gain setting */
+ pStereoOut,
+ pStereoOut,
+ (LVM_INT32)(2 * NrFrames));
+#else
NonLinComp_Float(Gain, /* Compressor gain setting */
pOutData,
pOutData,
(LVM_INT32)(2 * NumSamples));
+#endif
}
else
{
@@ -289,7 +328,11 @@
FinalGain = Gain;
Gain = pInstance->CompressGain;
+#ifdef SUPPORT_MC
+ pOutPtr = pStereoOut;
+#else
pOutPtr = pOutData;
+#endif
while(SampleToProcess > 0)
{
@@ -355,6 +398,7 @@
}
#ifdef SUPPORT_MC
Copy_Float_Stereo_Mc(pInData,
+ pStereoOut,
pOutData,
NrFrames,
channels);
diff --git a/media/libeffects/proxy/EffectProxy.cpp b/media/libeffects/proxy/EffectProxy.cpp
index 42e44f0..c010d68 100644
--- a/media/libeffects/proxy/EffectProxy.cpp
+++ b/media/libeffects/proxy/EffectProxy.cpp
@@ -30,7 +30,7 @@
#include <media/EffectsFactoryApi.h>
namespace android {
-// This is a dummy proxy descriptor just to return to Factory during the initial
+// This is a stub proxy descriptor just to return to Factory during the initial
// GetDescriptor call. Later in the factory, it is replaced with the
// SW sub effect descriptor
// proxy UUID af8da7e0-2ca1-11e3-b71d-0002a5d5c51b
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
index 95c973a..de7fe08 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
@@ -118,6 +118,7 @@
updateMetrics("destructor");
logMetrics("destructor");
+ Mutex::Autolock autoLock(mMetricsLock);
if (mAnalyticsItem != NULL) {
delete mAnalyticsItem;
mAnalyticsItem = NULL;
@@ -131,6 +132,8 @@
status_t NuPlayerDriver::setUID(uid_t uid) {
mPlayer->setUID(uid);
mClientUid = uid;
+
+ Mutex::Autolock autoLock(mMetricsLock);
if (mAnalyticsItem) {
mAnalyticsItem->setUid(mClientUid);
}
@@ -544,10 +547,46 @@
}
ALOGV("updateMetrics(%p) from %s at state %d", this, where, mState);
- // gather the final stats for this record
+ // gather the final track statistics for this record
Vector<sp<AMessage>> trackStats;
mPlayer->getStats(&trackStats);
+ // getDuration() uses mLock
+ int duration_ms = -1;
+ getDuration(&duration_ms);
+ mAnalyticsItem->setInt64(kPlayerDuration, duration_ms);
+
+ mPlayer->updateInternalTimers();
+
+ int64_t playingTimeUs;
+ int64_t rebufferingTimeUs;
+ int32_t rebufferingEvents;
+ bool rebufferingAtExit;
+ {
+ Mutex::Autolock autoLock(mLock);
+
+ playingTimeUs = mPlayingTimeUs;
+ rebufferingTimeUs = mRebufferingTimeUs;
+ rebufferingEvents = mRebufferingEvents;
+ rebufferingAtExit = mRebufferingAtExit;
+ }
+
+ // finish the rest of the gathering holding mLock;
+ // some of the fields we read are updated under mLock.
+ // we also avoid any races within mAnalyticsItem machinery
+ Mutex::Autolock autoLock(mMetricsLock);
+
+ mAnalyticsItem->setInt64(kPlayerPlaying, (playingTimeUs+500)/1000 );
+
+ if (mRebufferingEvents != 0) {
+ mAnalyticsItem->setInt64(kPlayerRebuffering, (rebufferingTimeUs+500)/1000 );
+ mAnalyticsItem->setInt32(kPlayerRebufferingCount, rebufferingEvents);
+ mAnalyticsItem->setInt32(kPlayerRebufferingAtExit, rebufferingAtExit);
+
+ }
+
+ mAnalyticsItem->setCString(kPlayerDataSourceType, mPlayer->getDataSourceType());
+
if (trackStats.size() > 0) {
for (size_t i = 0; i < trackStats.size(); ++i) {
const sp<AMessage> &stats = trackStats.itemAt(i);
@@ -592,26 +631,6 @@
}
}
}
-
- // always provide duration and playing time, even if they have 0/unknown values.
-
- // getDuration() uses mLock for mutex -- careful where we use it.
- int duration_ms = -1;
- getDuration(&duration_ms);
- mAnalyticsItem->setInt64(kPlayerDuration, duration_ms);
-
- mPlayer->updateInternalTimers();
-
- mAnalyticsItem->setInt64(kPlayerPlaying, (mPlayingTimeUs+500)/1000 );
-
- if (mRebufferingEvents != 0) {
- mAnalyticsItem->setInt64(kPlayerRebuffering, (mRebufferingTimeUs+500)/1000 );
- mAnalyticsItem->setInt32(kPlayerRebufferingCount, mRebufferingEvents);
- mAnalyticsItem->setInt32(kPlayerRebufferingAtExit, mRebufferingAtExit);
-
- }
-
- mAnalyticsItem->setCString(kPlayerDataSourceType, mPlayer->getDataSourceType());
}
@@ -621,6 +640,9 @@
}
ALOGV("logMetrics(%p) from %s at state %d", this, where, mState);
+ // make sure that the stats are stable while we're writing them.
+ Mutex::Autolock autoLock(mMetricsLock);
+
if (mAnalyticsItem == NULL || mAnalyticsItem->isEnabled() == false) {
return;
}
@@ -779,11 +801,16 @@
status_t NuPlayerDriver::getParameter(int key, Parcel *reply) {
- if (key == FOURCC('m','t','r','X') && mAnalyticsItem != NULL) {
+ if (key == FOURCC('m','t','r','X')) {
// mtrX -- a play on 'metrics' (not matrix)
// gather current info all together, parcel it, and send it back
updateMetrics("api");
- mAnalyticsItem->writeToParcel(reply);
+
+ // ensure mAnalyticsItem stability while writing to parcel
+ Mutex::Autolock autoLock(mMetricsLock);
+ if (mAnalyticsItem != NULL) {
+ mAnalyticsItem->writeToParcel(reply);
+ }
return OK;
}
@@ -1007,12 +1034,15 @@
// when we have an error, add it to the analytics for this playback.
// ext1 is our primary 'error type' value. Only add ext2 when non-zero.
// [test against msg is due to fall through from previous switch value]
- if (msg == MEDIA_ERROR && mAnalyticsItem != NULL) {
- mAnalyticsItem->setInt32(kPlayerError, ext1);
- if (ext2 != 0) {
- mAnalyticsItem->setInt32(kPlayerErrorCode, ext2);
+ if (msg == MEDIA_ERROR) {
+ Mutex::Autolock autoLock(mMetricsLock);
+ if (mAnalyticsItem != NULL) {
+ mAnalyticsItem->setInt32(kPlayerError, ext1);
+ if (ext2 != 0) {
+ mAnalyticsItem->setInt32(kPlayerErrorCode, ext2);
+ }
+ mAnalyticsItem->setCString(kPlayerErrorState, stateString(mState).c_str());
}
- mAnalyticsItem->setCString(kPlayerErrorState, stateString(mState).c_str());
}
mAtEOS = true;
break;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
index ad878f8..37c53b0 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
@@ -142,6 +142,7 @@
uint32_t mPlayerFlags;
MediaAnalyticsItem *mAnalyticsItem;
+ mutable Mutex mMetricsLock;
uid_t mClientUid;
bool mAtEOS;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerStreamListener.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerStreamListener.cpp
index ee70306..7dcee72 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerStreamListener.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerStreamListener.cpp
@@ -34,8 +34,6 @@
mTargetHandler(targetHandler),
mEOS(false),
mSendDataNotification(true) {
- mSource->setListener(this);
-
mMemoryDealer = new MemoryDealer(kNumBuffers * kBufferSize);
for (size_t i = 0; i < kNumBuffers; ++i) {
sp<IMemory> mem = mMemoryDealer->allocate(kBufferSize);
diff --git a/media/libmediaplayerservice/nuplayer/StreamingSource.cpp b/media/libmediaplayerservice/nuplayer/StreamingSource.cpp
index f21d2b3..3250a48 100644
--- a/media/libmediaplayerservice/nuplayer/StreamingSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/StreamingSource.cpp
@@ -79,6 +79,7 @@
void NuPlayer::StreamingSource::start() {
mStreamListener = new NuPlayerStreamListener(mSource, NULL);
+ mSource->setListener(mStreamListener);
uint32_t sourceFlags = mSource->flags();
diff --git a/media/libmediaplayerservice/tests/stagefrightRecorder/Android.bp b/media/libmediaplayerservice/tests/stagefrightRecorder/Android.bp
new file mode 100644
index 0000000..5a52ea5
--- /dev/null
+++ b/media/libmediaplayerservice/tests/stagefrightRecorder/Android.bp
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+cc_test {
+ name: "StagefrightRecorderTest",
+ gtest: true,
+
+ srcs: [
+ "StagefrightRecorderTest.cpp",
+ ],
+
+ include_dirs: [
+ "system/media/audio/include",
+ "frameworks/av/include",
+ "frameworks/av/camera/include",
+ "frameworks/av/media/libmediaplayerservice",
+ "frameworks/av/media/libmediametrics/include",
+ "frameworks/av/media/ndk/include",
+ ],
+
+ shared_libs: [
+ "liblog",
+ "libmedia",
+ "libbinder",
+ "libutils",
+ "libmediaplayerservice",
+ "libstagefright",
+ "libmediandk",
+ ],
+
+ compile_multilib: "32",
+
+ cflags: [
+ "-Werror",
+ "-Wall",
+ ],
+
+ sanitize: {
+ cfi: true,
+ misc_undefined: [
+ "unsigned-integer-overflow",
+ "signed-integer-overflow",
+ ],
+ },
+}
diff --git a/media/libmediaplayerservice/tests/stagefrightRecorder/StagefrightRecorderTest.cpp b/media/libmediaplayerservice/tests/stagefrightRecorder/StagefrightRecorderTest.cpp
new file mode 100644
index 0000000..ac17ef3
--- /dev/null
+++ b/media/libmediaplayerservice/tests/stagefrightRecorder/StagefrightRecorderTest.cpp
@@ -0,0 +1,318 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// #define LOG_NDEBUG 0
+#define LOG_TAG "StagefrightRecorderTest"
+#include <utils/Log.h>
+
+#include <gtest/gtest.h>
+
+#include <chrono>
+#include <ctime>
+#include <iostream>
+#include <string>
+#include <thread>
+
+#include <MediaPlayerService.h>
+#include <media/NdkMediaExtractor.h>
+#include <media/stagefright/MediaCodec.h>
+#include <system/audio-base.h>
+
+#include "StagefrightRecorder.h"
+
+#define OUTPUT_INFO_FILE_NAME "/data/local/tmp/stfrecorder_audio.info"
+#define OUTPUT_FILE_NAME_AUDIO "/data/local/tmp/stfrecorder_audio.raw"
+
+const bool kDebug = false;
+constexpr int32_t kMaxLoopCount = 10;
+constexpr int32_t kClipDurationInSec = 4;
+constexpr int32_t kPauseTimeInSec = 2;
+// Tolerance value for extracted clipduration is maximum 10% of total clipduration
+constexpr int32_t kToleranceValueInUs = kClipDurationInSec * 100000;
+
+using namespace android;
+
+class StagefrightRecorderTest
+ : public ::testing::TestWithParam<std::pair<output_format, audio_encoder>> {
+ public:
+ StagefrightRecorderTest() : mStfRecorder(nullptr), mOutputAudioFp(nullptr) {
+ mExpectedDurationInMs = 0;
+ mExpectedPauseInMs = 0;
+ }
+
+ ~StagefrightRecorderTest() {
+ if (mStfRecorder) free(mStfRecorder);
+ if (mOutputAudioFp) fclose(mOutputAudioFp);
+ }
+
+ void SetUp() override {
+ mStfRecorder = new StagefrightRecorder(String16(LOG_TAG));
+ ASSERT_NE(mStfRecorder, nullptr) << "Failed to create the instance of recorder";
+
+ mOutputAudioFp = fopen(OUTPUT_FILE_NAME_AUDIO, "wb");
+ ASSERT_NE(mOutputAudioFp, nullptr) << "Failed to open output file "
+ << OUTPUT_FILE_NAME_AUDIO << " for stagefright recorder";
+
+ int32_t fd = fileno(mOutputAudioFp);
+ ASSERT_GE(fd, 0) << "Failed to get the file descriptor of the output file for "
+ << OUTPUT_FILE_NAME_AUDIO;
+
+ status_t status = mStfRecorder->setOutputFile(fd);
+ ASSERT_EQ(status, OK) << "Failed to set the output file " << OUTPUT_FILE_NAME_AUDIO
+ << " for stagefright recorder";
+ }
+
+ void TearDown() override {
+ if (mOutputAudioFp) {
+ fclose(mOutputAudioFp);
+ mOutputAudioFp = nullptr;
+ }
+ if (!kDebug) {
+ int32_t status = remove(OUTPUT_FILE_NAME_AUDIO);
+ ASSERT_EQ(status, 0) << "Unable to delete the output file " << OUTPUT_FILE_NAME_AUDIO;
+ }
+ }
+
+ void setAudioRecorderFormat(output_format outputFormat, audio_encoder encoder,
+ audio_source_t audioSource = AUDIO_SOURCE_DEFAULT);
+ void recordMedia(bool isPaused = false, int32_t numStart = 0, int32_t numPause = 0);
+ void dumpInfo();
+ void setupExtractor(AMediaExtractor *extractor, int32_t &trackCount);
+ void validateOutput();
+
+ MediaRecorderBase *mStfRecorder;
+ FILE *mOutputAudioFp;
+ double mExpectedDurationInMs;
+ double mExpectedPauseInMs;
+};
+
+void StagefrightRecorderTest::setAudioRecorderFormat(output_format outputFormat,
+ audio_encoder encoder,
+ audio_source_t audioSource) {
+ status_t status = mStfRecorder->setAudioSource(audioSource);
+ ASSERT_EQ(status, OK) << "Failed to set the audio source: " << audioSource;
+
+ status = mStfRecorder->setOutputFormat(outputFormat);
+ ASSERT_EQ(status, OK) << "Failed to set the output format: " << outputFormat;
+
+ status = mStfRecorder->setAudioEncoder(encoder);
+ ASSERT_EQ(status, OK) << "Failed to set the audio encoder: " << encoder;
+}
+
+void StagefrightRecorderTest::recordMedia(bool isPause, int32_t numStart, int32_t numPause) {
+ status_t status = mStfRecorder->init();
+ ASSERT_EQ(status, OK) << "Failed to initialize stagefright recorder";
+
+ status = mStfRecorder->prepare();
+ ASSERT_EQ(status, OK) << "Failed to preapre the reorder";
+
+ // first start should succeed.
+ status = mStfRecorder->start();
+ ASSERT_EQ(status, OK) << "Failed to start the recorder";
+
+ for (int32_t count = 0; count < numStart; count++) {
+ status = mStfRecorder->start();
+ }
+
+ auto tStart = std::chrono::high_resolution_clock::now();
+ // Recording media for 4 secs
+ std::this_thread::sleep_for(std::chrono::seconds(kClipDurationInSec));
+ auto tEnd = std::chrono::high_resolution_clock::now();
+ mExpectedDurationInMs = std::chrono::duration<double, std::milli>(tEnd - tStart).count();
+
+ if (isPause) {
+ // first pause should succeed.
+ status = mStfRecorder->pause();
+ ASSERT_EQ(status, OK) << "Failed to pause the recorder";
+
+ tStart = std::chrono::high_resolution_clock::now();
+ // Paused recorder for 2 secs
+ std::this_thread::sleep_for(std::chrono::seconds(kPauseTimeInSec));
+
+ for (int32_t count = 0; count < numPause; count++) {
+ status = mStfRecorder->pause();
+ }
+
+ tEnd = std::chrono::high_resolution_clock::now();
+ mExpectedPauseInMs = std::chrono::duration<double, std::milli>(tEnd - tStart).count();
+
+ status = mStfRecorder->resume();
+ ASSERT_EQ(status, OK) << "Failed to resume the recorder";
+
+ auto tStart = std::chrono::high_resolution_clock::now();
+ // Recording media for 4 secs
+ std::this_thread::sleep_for(std::chrono::seconds(kClipDurationInSec));
+ auto tEnd = std::chrono::high_resolution_clock::now();
+ mExpectedDurationInMs += std::chrono::duration<double, std::milli>(tEnd - tStart).count();
+ }
+ status = mStfRecorder->stop();
+ ASSERT_EQ(status, OK) << "Failed to stop the recorder";
+}
+
+void StagefrightRecorderTest::dumpInfo() {
+ FILE *dumpOutput = fopen(OUTPUT_INFO_FILE_NAME, "wb");
+ int32_t dumpFd = fileno(dumpOutput);
+ Vector<String16> args;
+ status_t status = mStfRecorder->dump(dumpFd, args);
+ ASSERT_EQ(status, OK) << "Failed to dump the info for the recorder";
+ fclose(dumpOutput);
+}
+
+void StagefrightRecorderTest::setupExtractor(AMediaExtractor *extractor, int32_t &trackCount) {
+ int32_t fd = open(OUTPUT_FILE_NAME_AUDIO, O_RDONLY);
+ ASSERT_GE(fd, 0) << "Failed to open recorder's output file " << OUTPUT_FILE_NAME_AUDIO
+ << " to validate";
+
+ struct stat buf;
+ int32_t status = fstat(fd, &buf);
+ ASSERT_EQ(status, 0) << "Failed to get properties of input file " << OUTPUT_FILE_NAME_AUDIO
+ << " for extractor";
+
+ size_t fileSize = buf.st_size;
+ ASSERT_GT(fileSize, 0) << "Size of input file " << OUTPUT_FILE_NAME_AUDIO
+ << " to extractor cannot be zero";
+ ALOGV("Size of input file to extractor: %zu", fileSize);
+
+ status = AMediaExtractor_setDataSourceFd(extractor, fd, 0, fileSize);
+ ASSERT_EQ(status, AMEDIA_OK) << "Failed to set data source for extractor";
+
+ trackCount = AMediaExtractor_getTrackCount(extractor);
+ ALOGV("Number of tracks reported by extractor : %d", trackCount);
+}
+
+// Validate recoder's output using extractor
+void StagefrightRecorderTest::validateOutput() {
+ int32_t trackCount = -1;
+ AMediaExtractor *extractor = AMediaExtractor_new();
+ ASSERT_NE(extractor, nullptr) << "Failed to create extractor";
+ ASSERT_NO_FATAL_FAILURE(setupExtractor(extractor, trackCount));
+ ASSERT_EQ(trackCount, 1) << "Expected 1 track, saw " << trackCount;
+
+ for (int32_t idx = 0; idx < trackCount; idx++) {
+ AMediaExtractor_selectTrack(extractor, idx);
+ AMediaFormat *format = AMediaExtractor_getTrackFormat(extractor, idx);
+ ASSERT_NE(format, nullptr) << "Track format is NULL";
+ ALOGI("Track format = %s", AMediaFormat_toString(format));
+
+ int64_t clipDurationUs;
+ AMediaFormat_getInt64(format, AMEDIAFORMAT_KEY_DURATION, &clipDurationUs);
+ int32_t diff = abs((mExpectedDurationInMs * 1000) - clipDurationUs);
+ ASSERT_LE(diff, kToleranceValueInUs)
+ << "Expected duration: " << (mExpectedDurationInMs * 1000)
+ << " Actual duration: " << clipDurationUs << " Difference: " << diff
+ << " Difference is expected to be less than tolerance value: " << kToleranceValueInUs;
+
+ const char *mime = nullptr;
+ AMediaFormat_getString(format, AMEDIAFORMAT_KEY_MIME, &mime);
+ ASSERT_NE(mime, nullptr) << "Track mime is NULL";
+ ALOGI("Track mime = %s", mime);
+
+ int32_t sampleRate, channelCount, bitRate;
+ AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_CHANNEL_COUNT, &channelCount);
+ ALOGI("Channel count reported by extractor: %d", channelCount);
+ AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_SAMPLE_RATE, &sampleRate);
+ ALOGI("Sample Rate reported by extractor: %d", sampleRate);
+ AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_BIT_RATE, &bitRate);
+ ALOGI("Bit Rate reported by extractor: %d", bitRate);
+ }
+}
+
+TEST_F(StagefrightRecorderTest, RecordingAudioSanityTest) {
+ ASSERT_NO_FATAL_FAILURE(setAudioRecorderFormat(OUTPUT_FORMAT_DEFAULT, AUDIO_ENCODER_DEFAULT));
+
+ int32_t maxAmplitude = -1;
+ status_t status = mStfRecorder->getMaxAmplitude(&maxAmplitude);
+ ASSERT_EQ(maxAmplitude, 0) << "Invalid value of max amplitude";
+
+ ASSERT_NO_FATAL_FAILURE(recordMedia());
+
+ // Verify getMetrics() behavior
+ Parcel parcel;
+ status = mStfRecorder->getMetrics(&parcel);
+ ASSERT_EQ(status, OK) << "Failed to get the parcel from getMetrics";
+ ALOGV("Size of the Parcel returned by getMetrics: %zu", parcel.dataSize());
+ ASSERT_GT(parcel.dataSize(), 0) << "Parcel size reports empty record";
+ ASSERT_NO_FATAL_FAILURE(validateOutput());
+ if (kDebug) {
+ ASSERT_NO_FATAL_FAILURE(dumpInfo());
+ }
+}
+
+TEST_P(StagefrightRecorderTest, MultiFormatAudioRecordTest) {
+ output_format outputFormat = GetParam().first;
+ audio_encoder audioEncoder = GetParam().second;
+ ASSERT_NO_FATAL_FAILURE(setAudioRecorderFormat(outputFormat, audioEncoder));
+ ASSERT_NO_FATAL_FAILURE(recordMedia());
+ // TODO(b/161687761)
+ // Skip for AMR-NB/WB output format
+ if (!(outputFormat == OUTPUT_FORMAT_AMR_NB || outputFormat == OUTPUT_FORMAT_AMR_WB)) {
+ ASSERT_NO_FATAL_FAILURE(validateOutput());
+ }
+ if (kDebug) {
+ ASSERT_NO_FATAL_FAILURE(dumpInfo());
+ }
+}
+
+TEST_F(StagefrightRecorderTest, GetActiveMicrophonesTest) {
+ ASSERT_NO_FATAL_FAILURE(
+ setAudioRecorderFormat(OUTPUT_FORMAT_DEFAULT, AUDIO_ENCODER_DEFAULT, AUDIO_SOURCE_MIC));
+
+ status_t status = mStfRecorder->init();
+ ASSERT_EQ(status, OK) << "Init failed for stagefright recorder";
+
+ status = mStfRecorder->prepare();
+ ASSERT_EQ(status, OK) << "Failed to preapre the reorder";
+
+ status = mStfRecorder->start();
+ ASSERT_EQ(status, OK) << "Failed to start the recorder";
+
+ // Record media for 4 secs
+ std::this_thread::sleep_for(std::chrono::seconds(kClipDurationInSec));
+
+ std::vector<media::MicrophoneInfo> activeMicrophones{};
+ status = mStfRecorder->getActiveMicrophones(&activeMicrophones);
+ ASSERT_EQ(status, OK) << "Failed to get Active Microphones";
+ ASSERT_GT(activeMicrophones.size(), 0) << "No active microphones are found";
+
+ status = mStfRecorder->stop();
+ ASSERT_EQ(status, OK) << "Failed to stop the recorder";
+ if (kDebug) {
+ ASSERT_NO_FATAL_FAILURE(dumpInfo());
+ }
+}
+
+TEST_F(StagefrightRecorderTest, MultiStartPauseTest) {
+ ASSERT_NO_FATAL_FAILURE(setAudioRecorderFormat(OUTPUT_FORMAT_DEFAULT, AUDIO_ENCODER_DEFAULT));
+ ASSERT_NO_FATAL_FAILURE(recordMedia(true, kMaxLoopCount, kMaxLoopCount));
+ ASSERT_NO_FATAL_FAILURE(validateOutput());
+ if (kDebug) {
+ ASSERT_NO_FATAL_FAILURE(dumpInfo());
+ }
+}
+
+INSTANTIATE_TEST_SUITE_P(
+ StagefrightRecorderTestAll, StagefrightRecorderTest,
+ ::testing::Values(std::make_pair(OUTPUT_FORMAT_AMR_NB, AUDIO_ENCODER_AMR_NB),
+ std::make_pair(OUTPUT_FORMAT_AMR_WB, AUDIO_ENCODER_AMR_WB),
+ std::make_pair(OUTPUT_FORMAT_AAC_ADTS, AUDIO_ENCODER_AAC),
+ std::make_pair(OUTPUT_FORMAT_OGG, AUDIO_ENCODER_OPUS)));
+
+int main(int argc, char **argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ int status = RUN_ALL_TESTS();
+ ALOGV("Test result = %d\n", status);
+ return status;
+}
diff --git a/media/libnbaio/include/media/nbaio/Pipe.h b/media/libnbaio/include/media/nbaio/Pipe.h
index 0431976..54dc08f 100644
--- a/media/libnbaio/include/media/nbaio/Pipe.h
+++ b/media/libnbaio/include/media/nbaio/Pipe.h
@@ -23,7 +23,7 @@
namespace android {
// Pipe is multi-thread safe for readers (see PipeReader), but safe for only a single writer thread.
-// It cannot UNDERRUN on write, unless we allow designation of a master reader that provides the
+// It cannot UNDERRUN on write, unless we allow designation of a primary reader that provides the
// time-base. Readers can be added and removed dynamically, and it's OK to have no readers.
class Pipe : public NBAIO_Sink {
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index eacaea8..26c36cd 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -887,7 +887,7 @@
sp<DataConverter> converter = mConverter[portIndex];
if (converter != NULL) {
- // here we assume sane conversions of max 4:1, so result fits in int32
+ // here we assume conversions of max 4:1, so result fits in int32
if (portIndex == kPortIndexInput) {
conversionBufferSize = converter->sourceSize(bufSize);
} else {
@@ -2538,15 +2538,15 @@
unsigned int numLayers = 0;
unsigned int numBLayers = 0;
int tags;
- char dummy;
+ char tmp;
OMX_VIDEO_ANDROID_TEMPORALLAYERINGPATTERNTYPE pattern =
OMX_VIDEO_AndroidTemporalLayeringPatternNone;
- if (sscanf(tsSchema.c_str(), "webrtc.vp8.%u-layer%c", &numLayers, &dummy) == 1
+ if (sscanf(tsSchema.c_str(), "webrtc.vp8.%u-layer%c", &numLayers, &tmp) == 1
&& numLayers > 0) {
pattern = OMX_VIDEO_AndroidTemporalLayeringPatternWebRTC;
} else if ((tags = sscanf(tsSchema.c_str(), "android.generic.%u%c%u%c",
- &numLayers, &dummy, &numBLayers, &dummy))
- && (tags == 1 || (tags == 3 && dummy == '+'))
+ &numLayers, &tmp, &numBLayers, &tmp))
+ && (tags == 1 || (tags == 3 && tmp == '+'))
&& numLayers > 0 && numLayers < UINT32_MAX - numBLayers) {
numLayers += numBLayers;
pattern = OMX_VIDEO_AndroidTemporalLayeringPatternAndroid;
@@ -4691,15 +4691,15 @@
unsigned int numLayers = 0;
unsigned int numBLayers = 0;
int tags;
- char dummy;
- if (sscanf(tsSchema.c_str(), "webrtc.vp8.%u-layer%c", &numLayers, &dummy) == 1
+ char tmp;
+ if (sscanf(tsSchema.c_str(), "webrtc.vp8.%u-layer%c", &numLayers, &tmp) == 1
&& numLayers > 0) {
pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
tsType = OMX_VIDEO_AndroidTemporalLayeringPatternWebRTC;
tsLayers = numLayers;
} else if ((tags = sscanf(tsSchema.c_str(), "android.generic.%u%c%u%c",
- &numLayers, &dummy, &numBLayers, &dummy))
- && (tags == 1 || (tags == 3 && dummy == '+'))
+ &numLayers, &tmp, &numBLayers, &tmp))
+ && (tags == 1 || (tags == 3 && tmp == '+'))
&& numLayers > 0 && numLayers < UINT32_MAX - numBLayers) {
pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
// VPX does not have a concept of B-frames, so just count all layers
@@ -7549,8 +7549,8 @@
mInputFormat->setInt64("android._stop-time-offset-us", stopTimeOffsetUs);
}
- int32_t dummy;
- if (params->findInt32("request-sync", &dummy)) {
+ int32_t tmp;
+ if (params->findInt32("request-sync", &tmp)) {
status_t err = requestIDRFrame();
if (err != OK) {
diff --git a/media/libstagefright/codecs/aacdec/DrcPresModeWrap.cpp b/media/libstagefright/codecs/aacdec/DrcPresModeWrap.cpp
index 95d3724..e40a448 100644
--- a/media/libstagefright/codecs/aacdec/DrcPresModeWrap.cpp
+++ b/media/libstagefright/codecs/aacdec/DrcPresModeWrap.cpp
@@ -218,7 +218,7 @@
}
else { // handle other used encoder target levels
- // Sanity check: DRC presentation mode is only specified for max. 5.1 channels
+ // Validation check: DRC presentation mode is only specified for max. 5.1 channels
if (mStreamNrAACChan > 6) {
drcPresMode = 0;
}
@@ -309,7 +309,7 @@
} // switch()
} // if (mEncoderTarget == GPM_ENCODER_TARGET_LEVEL)
- // sanity again
+ // validation check again
if (newHeavy == 1) {
newBoostFactor=127; // not really needed as the same would be done by the decoder anyway
newAttFactor = 127;
diff --git a/media/libstagefright/codecs/amrnb/enc/src/qgain475.cpp b/media/libstagefright/codecs/amrnb/enc/src/qgain475.cpp
index f8da589..08a5c15 100644
--- a/media/libstagefright/codecs/amrnb/enc/src/qgain475.cpp
+++ b/media/libstagefright/codecs/amrnb/enc/src/qgain475.cpp
@@ -1106,7 +1106,7 @@
// the real, quantized gains)
gc_pred(pred_st, MR475, sf1_code_nosharp,
&sf1_exp_gcode0, &sf1_frac_gcode0,
- &sf0_exp_gcode0, &sf0_gcode0); // last two args are dummy
+ &sf0_exp_gcode0, &sf0_gcode0); // last two args are unused
sf1_gcode0 = extract_l(Pow2(14, sf1_frac_gcode0));
tmp = add (tmp, 2);
@@ -1426,7 +1426,7 @@
the real, quantized gains) */
gc_pred(pred_st, MR475, sf1_code_nosharp,
&sf1_exp_gcode0, &sf1_frac_gcode0,
- &sf0_exp_gcode0, &sf0_gcode0, /* dummy args */
+ &sf0_exp_gcode0, &sf0_gcode0, /* unused args */
pOverflow);
sf1_gcode0 = (Word16)(Pow2(14, sf1_frac_gcode0, pOverflow));
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/vop.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/vop.cpp
index 679b091..a11f55e 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/src/vop.cpp
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/vop.cpp
@@ -409,7 +409,9 @@
if (!BitstreamRead1Bits(stream)) return PV_FAIL;
/* video_object_layer_width (13 bits) */
- video->displayWidth = video->width = (int) BitstreamReadBits16(stream, 13);
+ tmpvar = BitstreamReadBits16(stream, 13);
+ if (!tmpvar) return PV_FAIL;
+ video->displayWidth = video->width = tmpvar;
/* round up to a multiple of MB_SIZE. 08/09/2000 */
video->width = (video->width + 15) & -16;
@@ -419,7 +421,9 @@
if (!BitstreamRead1Bits(stream)) return PV_FAIL;
/* video_object_layer_height (13 bits) */
- video->displayHeight = video->height = (int) BitstreamReadBits16(stream, 13);
+ tmpvar = BitstreamReadBits16(stream, 13);
+ if (!tmpvar) return PV_FAIL;
+ video->displayHeight = video->height = tmpvar;
/* round up to a multiple of MB_SIZE. 08/09/2000 */
video->height = (video->height + 15) & -16;
diff --git a/media/libstagefright/foundation/tests/TypeTraits_test.cpp b/media/libstagefright/foundation/tests/TypeTraits_test.cpp
index 1e2049d..d5383d1 100644
--- a/media/libstagefright/foundation/tests/TypeTraits_test.cpp
+++ b/media/libstagefright/foundation/tests/TypeTraits_test.cpp
@@ -30,7 +30,7 @@
enum IA : int32_t { };
};
-// =========== basic sanity tests for type-support templates
+// =========== basic tests for type-support templates
TEST_F(TypeTraitsTest, StaticTests) {
// ============ is_integral_or_enum
diff --git a/media/libstagefright/omx/1.0/Omx.cpp b/media/libstagefright/omx/1.0/Omx.cpp
index eef9ce3..eb15039 100644
--- a/media/libstagefright/omx/1.0/Omx.cpp
+++ b/media/libstagefright/omx/1.0/Omx.cpp
@@ -22,7 +22,7 @@
#include <media/openmax/OMX_AsString.h>
#include <media/stagefright/omx/OMXUtils.h>
-#include <media/stagefright/omx/OMXMaster.h>
+#include <media/stagefright/omx/OMXStore.h>
#include <media/stagefright/omx/OmxGraphicBufferSource.h>
#include <media/stagefright/omx/1.0/WOmxNode.h>
@@ -41,21 +41,21 @@
constexpr size_t kMaxNodeInstances = (1 << 16);
Omx::Omx() :
- mMaster(new OMXMaster()),
+ mStore(new OMXStore()),
mParser() {
(void)mParser.parseXmlFilesInSearchDirs();
(void)mParser.parseXmlPath(mParser.defaultProfilingResultsXmlPath);
}
Omx::~Omx() {
- delete mMaster;
+ delete mStore;
}
Return<void> Omx::listNodes(listNodes_cb _hidl_cb) {
std::list<::android::IOMX::ComponentInfo> list;
char componentName[256];
for (OMX_U32 index = 0;
- mMaster->enumerateComponents(
+ mStore->enumerateComponents(
componentName, sizeof(componentName), index) == OMX_ErrorNone;
++index) {
list.push_back(::android::IOMX::ComponentInfo());
@@ -63,7 +63,7 @@
info.mName = componentName;
::android::Vector<::android::String8> roles;
OMX_ERRORTYPE err =
- mMaster->getRolesOfComponent(componentName, &roles);
+ mStore->getRolesOfComponent(componentName, &roles);
if (err == OMX_ErrorNone) {
for (OMX_U32 i = 0; i < roles.size(); ++i) {
info.mRoles.push_back(roles[i]);
@@ -101,7 +101,7 @@
this, new LWOmxObserver(observer), name.c_str());
OMX_COMPONENTTYPE *handle;
- OMX_ERRORTYPE err = mMaster->makeComponentInstance(
+ OMX_ERRORTYPE err = mStore->makeComponentInstance(
name.c_str(), &OMXNodeInstance::kCallbacks,
instance.get(), &handle);
@@ -208,7 +208,7 @@
OMX_ERRORTYPE err = OMX_ErrorNone;
if (instance->handle() != NULL) {
- err = mMaster->destroyComponentInstance(
+ err = mStore->destroyComponentInstance(
static_cast<OMX_COMPONENTTYPE*>(instance->handle()));
}
return StatusFromOMXError(err);
diff --git a/media/libstagefright/omx/Android.bp b/media/libstagefright/omx/Android.bp
index 7d612b4..f068ba5 100644
--- a/media/libstagefright/omx/Android.bp
+++ b/media/libstagefright/omx/Android.bp
@@ -6,7 +6,7 @@
},
srcs: [
- "OMXMaster.cpp",
+ "OMXStore.cpp",
"OMXNodeInstance.cpp",
"OMXUtils.cpp",
"OmxGraphicBufferSource.cpp",
diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp
index ddb4ba0..f95d3df 100644
--- a/media/libstagefright/omx/OMXNodeInstance.cpp
+++ b/media/libstagefright/omx/OMXNodeInstance.cpp
@@ -22,7 +22,7 @@
#include <inttypes.h>
#include <media/stagefright/omx/OMXNodeInstance.h>
-#include <media/stagefright/omx/OMXMaster.h>
+#include <media/stagefright/omx/OMXStore.h>
#include <media/stagefright/omx/OMXUtils.h>
#include <android/IOMXBufferSource.h>
diff --git a/media/libstagefright/omx/OMXMaster.cpp b/media/libstagefright/omx/OMXStore.cpp
similarity index 89%
rename from media/libstagefright/omx/OMXMaster.cpp
rename to media/libstagefright/omx/OMXStore.cpp
index 8c5ca6e..e8fee42 100644
--- a/media/libstagefright/omx/OMXMaster.cpp
+++ b/media/libstagefright/omx/OMXStore.cpp
@@ -15,10 +15,11 @@
*/
//#define LOG_NDEBUG 0
-#define LOG_TAG "OMXMaster"
+#define LOG_TAG "OMXStore"
+#include <android-base/properties.h>
#include <utils/Log.h>
-#include <media/stagefright/omx/OMXMaster.h>
+#include <media/stagefright/omx/OMXStore.h>
#include <media/stagefright/omx/SoftOMXPlugin.h>
#include <media/stagefright/foundation/ADebug.h>
@@ -29,7 +30,7 @@
namespace android {
-OMXMaster::OMXMaster() {
+OMXStore::OMXStore() {
pid_t pid = getpid();
char filename[20];
@@ -54,19 +55,23 @@
addPlatformPlugin();
}
-OMXMaster::~OMXMaster() {
+OMXStore::~OMXStore() {
clearPlugins();
}
-void OMXMaster::addVendorPlugin() {
+void OMXStore::addVendorPlugin() {
addPlugin("libstagefrighthw.so");
}
-void OMXMaster::addPlatformPlugin() {
+void OMXStore::addPlatformPlugin() {
addPlugin("libstagefright_softomx_plugin.so");
}
-void OMXMaster::addPlugin(const char *libname) {
+void OMXStore::addPlugin(const char *libname) {
+ if (::android::base::GetIntProperty("vendor.media.omx", int64_t(1)) == 0) {
+ return;
+ }
+
void *libHandle = android_load_sphal_library(libname, RTLD_NOW);
if (libHandle == NULL) {
@@ -94,7 +99,7 @@
}
}
-void OMXMaster::addPlugin(OMXPluginBase *plugin) {
+void OMXStore::addPlugin(OMXPluginBase *plugin) {
Mutex::Autolock autoLock(mLock);
OMX_U32 index = 0;
@@ -121,7 +126,7 @@
}
}
-void OMXMaster::clearPlugins() {
+void OMXStore::clearPlugins() {
Mutex::Autolock autoLock(mLock);
mPluginByComponentName.clear();
@@ -143,7 +148,7 @@
mPlugins.clear();
}
-OMX_ERRORTYPE OMXMaster::makeComponentInstance(
+OMX_ERRORTYPE OMXStore::makeComponentInstance(
const char *name,
const OMX_CALLBACKTYPE *callbacks,
OMX_PTR appData,
@@ -172,7 +177,7 @@
return err;
}
-OMX_ERRORTYPE OMXMaster::destroyComponentInstance(
+OMX_ERRORTYPE OMXStore::destroyComponentInstance(
OMX_COMPONENTTYPE *component) {
Mutex::Autolock autoLock(mLock);
@@ -188,7 +193,7 @@
return plugin->destroyComponentInstance(component);
}
-OMX_ERRORTYPE OMXMaster::enumerateComponents(
+OMX_ERRORTYPE OMXStore::enumerateComponents(
OMX_STRING name,
size_t size,
OMX_U32 index) {
@@ -208,7 +213,7 @@
return OMX_ErrorNone;
}
-OMX_ERRORTYPE OMXMaster::getRolesOfComponent(
+OMX_ERRORTYPE OMXStore::getRolesOfComponent(
const char *name,
Vector<String8> *roles) {
Mutex::Autolock autoLock(mLock);
diff --git a/media/libstagefright/omx/OMXUtils.cpp b/media/libstagefright/omx/OMXUtils.cpp
index 1b8493a..d6d280f 100644
--- a/media/libstagefright/omx/OMXUtils.cpp
+++ b/media/libstagefright/omx/OMXUtils.cpp
@@ -354,7 +354,7 @@
DescribeColorFormat2Params describeParams;
InitOMXParams(&describeParams);
describeParams.eColorFormat = (OMX_COLOR_FORMATTYPE)colorFormat;
- // reasonable dummy values
+ // reasonable initial values (that will be overwritten)
describeParams.nFrameWidth = 128;
describeParams.nFrameHeight = 128;
describeParams.nStride = 128;
diff --git a/media/libstagefright/omx/include/media/stagefright/omx/1.0/Omx.h b/media/libstagefright/omx/include/media/stagefright/omx/1.0/Omx.h
index 5a46b26..84ae511 100644
--- a/media/libstagefright/omx/include/media/stagefright/omx/1.0/Omx.h
+++ b/media/libstagefright/omx/include/media/stagefright/omx/1.0/Omx.h
@@ -27,7 +27,7 @@
namespace android {
-struct OMXMaster;
+struct OMXStore;
struct OMXNodeInstance;
namespace hardware {
@@ -51,7 +51,7 @@
using ::android::sp;
using ::android::wp;
-using ::android::OMXMaster;
+using ::android::OMXStore;
using ::android::OMXNodeInstance;
struct Omx : public IOmx, public hidl_death_recipient {
@@ -73,7 +73,7 @@
status_t freeNode(sp<OMXNodeInstance> const& instance);
protected:
- OMXMaster* mMaster;
+ OMXStore* mStore;
Mutex mLock;
KeyedVector<wp<IBase>, sp<OMXNodeInstance> > mLiveNodes;
KeyedVector<OMXNodeInstance*, wp<IBase> > mNode2Observer;
diff --git a/media/libstagefright/omx/include/media/stagefright/omx/OMXNodeInstance.h b/media/libstagefright/omx/include/media/stagefright/omx/OMXNodeInstance.h
index a761ef6..5f32c9e 100644
--- a/media/libstagefright/omx/include/media/stagefright/omx/OMXNodeInstance.h
+++ b/media/libstagefright/omx/include/media/stagefright/omx/OMXNodeInstance.h
@@ -33,7 +33,7 @@
class GraphicBuffer;
class IOMXBufferSource;
class IOMXObserver;
-struct OMXMaster;
+struct OMXStore;
class OMXBuffer;
using IHidlMemory = hidl::memory::V1_0::IMemory;
using hardware::media::omx::V1_0::implementation::Omx;
diff --git a/media/libstagefright/omx/include/media/stagefright/omx/OMXMaster.h b/media/libstagefright/omx/include/media/stagefright/omx/OMXStore.h
similarity index 88%
rename from media/libstagefright/omx/include/media/stagefright/omx/OMXMaster.h
rename to media/libstagefright/omx/include/media/stagefright/omx/OMXStore.h
index 93eaef1..5d6c3ed 100644
--- a/media/libstagefright/omx/include/media/stagefright/omx/OMXMaster.h
+++ b/media/libstagefright/omx/include/media/stagefright/omx/OMXStore.h
@@ -14,9 +14,9 @@
* limitations under the License.
*/
-#ifndef OMX_MASTER_H_
+#ifndef OMX_STORE_H_
-#define OMX_MASTER_H_
+#define OMX_STORE_H_
#include <media/hardware/OMXPluginBase.h>
@@ -27,9 +27,9 @@
namespace android {
-struct OMXMaster : public OMXPluginBase {
- OMXMaster();
- virtual ~OMXMaster();
+struct OMXStore : public OMXPluginBase {
+ OMXStore();
+ virtual ~OMXStore();
virtual OMX_ERRORTYPE makeComponentInstance(
const char *name,
@@ -66,10 +66,10 @@
void addPlugin(OMXPluginBase *plugin);
void clearPlugins();
- OMXMaster(const OMXMaster &);
- OMXMaster &operator=(const OMXMaster &);
+ OMXStore(const OMXStore &);
+ OMXStore &operator=(const OMXStore &);
};
} // namespace android
-#endif // OMX_MASTER_H_
+#endif // OMX_STORE_H_
diff --git a/media/libstagefright/tests/metadatautils/Android.bp b/media/libstagefright/tests/metadatautils/Android.bp
new file mode 100644
index 0000000..69830fc
--- /dev/null
+++ b/media/libstagefright/tests/metadatautils/Android.bp
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+cc_test {
+ name: "MetaDataUtilsTest",
+ gtest: true,
+
+ srcs: [
+ "MetaDataUtilsTest.cpp",
+ ],
+
+ static_libs: [
+ "libstagefright_metadatautils",
+ "libstagefright_esds",
+ ],
+
+ shared_libs: [
+ "liblog",
+ "libutils",
+ "libmediandk",
+ "libstagefright",
+ "libstagefright_foundation",
+ ],
+
+ cflags: [
+ "-Werror",
+ "-Wall",
+ ],
+
+ sanitize: {
+ cfi: true,
+ misc_undefined: [
+ "unsigned-integer-overflow",
+ "signed-integer-overflow",
+ ],
+ },
+}
diff --git a/media/libstagefright/tests/metadatautils/AndroidTest.xml b/media/libstagefright/tests/metadatautils/AndroidTest.xml
new file mode 100644
index 0000000..d6497f3
--- /dev/null
+++ b/media/libstagefright/tests/metadatautils/AndroidTest.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<configuration description="Test module config for MetaDataUtils unit test">
+ <option name="test-suite-tag" value="MetaDataUtilsTest" />
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="cleanup" value="false" />
+ <option name="push" value="MetaDataUtilsTest->/data/local/tmp/MetaDataUtilsTest" />
+ <option name="push-file"
+ key="https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/tests/metadatautils/MetaDataUtilsTestRes-1.0.zip?unzip=true"
+ value="/data/local/tmp/MetaDataUtilsTestRes/" />
+ </target_preparer>
+ <test class="com.android.tradefed.testtype.GTest" >
+ <option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="module-name" value="MetaDataUtilsTest" />
+ <option name="native-test-flag" value="-P /data/local/tmp/MetaDataUtilsTestRes/" />
+ </test>
+</configuration>
diff --git a/media/libstagefright/tests/metadatautils/MetaDataUtilsTest.cpp b/media/libstagefright/tests/metadatautils/MetaDataUtilsTest.cpp
new file mode 100644
index 0000000..9fd5fdb
--- /dev/null
+++ b/media/libstagefright/tests/metadatautils/MetaDataUtilsTest.cpp
@@ -0,0 +1,490 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "MetaDataUtilsTest"
+#include <utils/Log.h>
+
+#include <fstream>
+#include <string>
+
+#include <ESDS.h>
+#include <media/NdkMediaFormat.h>
+#include <media/stagefright/MediaCodecConstants.h>
+#include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/MetaDataBase.h>
+#include <media/stagefright/MetaDataUtils.h>
+#include <media/stagefright/foundation/ABitReader.h>
+
+#include "MetaDataUtilsTestEnvironment.h"
+
+constexpr uint8_t kAdtsCsdSize = 7;
+// from AAC specs: https://www.iso.org/standard/43345.html
+constexpr int32_t kSamplingFreq[] = {96000, 88200, 64000, 48000, 44100, 32000,
+ 24000, 22050, 16000, 12000, 11025, 8000};
+constexpr uint8_t kMaxSamplingFreqIndex = sizeof(kSamplingFreq) / sizeof(kSamplingFreq[0]);
+
+static MetaDataUtilsTestEnvironment *gEnv = nullptr;
+
+using namespace android;
+
+class MetaDataValidate {
+ public:
+ MetaDataValidate() : mInputBuffer(nullptr) {}
+
+ ~MetaDataValidate() {
+ if (mInputBuffer) {
+ delete[] mInputBuffer;
+ mInputBuffer = nullptr;
+ }
+ }
+
+ void SetUpMetaDataValidate(string fileName) {
+ struct stat buf;
+ int8_t err = stat(fileName.c_str(), &buf);
+ ASSERT_EQ(err, 0) << "Failed to get file information for file: " << fileName;
+
+ mInputBufferSize = buf.st_size;
+ FILE *inputFilePtr = fopen(fileName.c_str(), "rb+");
+ ASSERT_NE(inputFilePtr, nullptr) << "Failed to open file: " << fileName;
+
+ mInputBuffer = new uint8_t[mInputBufferSize];
+ ASSERT_NE(mInputBuffer, nullptr)
+ << "Failed to allocate memory of size: " << mInputBufferSize;
+
+ int32_t numBytes =
+ fread((char *)mInputBuffer, sizeof(uint8_t), mInputBufferSize, inputFilePtr);
+ ASSERT_EQ(numBytes, mInputBufferSize) << numBytes << " of " << mInputBufferSize << " read";
+
+ fclose(inputFilePtr);
+ }
+
+ size_t mInputBufferSize;
+ const uint8_t *mInputBuffer;
+};
+
+class AvcCSDTest : public ::testing::TestWithParam<
+ tuple<string /*inputFile*/, size_t /*avcWidth*/, size_t /*avcHeight*/>> {
+ public:
+ AvcCSDTest() : mInputBuffer(nullptr) {}
+
+ ~AvcCSDTest() {
+ if (mInputBuffer) {
+ delete[] mInputBuffer;
+ mInputBuffer = nullptr;
+ }
+ }
+ virtual void SetUp() override {
+ tuple<string, size_t, size_t> params = GetParam();
+ string inputFile = gEnv->getRes() + get<0>(params);
+ mFrameWidth = get<1>(params);
+ mFrameHeight = get<2>(params);
+
+ struct stat buf;
+ int8_t err = stat(inputFile.c_str(), &buf);
+ ASSERT_EQ(err, 0) << "Failed to get information for file: " << inputFile;
+
+ mInputBufferSize = buf.st_size;
+ FILE *inputFilePtr = fopen(inputFile.c_str(), "rb+");
+ ASSERT_NE(inputFilePtr, nullptr) << "Failed to open file: " << inputFile;
+
+ mInputBuffer = new uint8_t[mInputBufferSize];
+ ASSERT_NE(mInputBuffer, nullptr)
+ << "Failed to create a buffer of size: " << mInputBufferSize;
+
+ int32_t numBytes =
+ fread((char *)mInputBuffer, sizeof(uint8_t), mInputBufferSize, inputFilePtr);
+ ASSERT_EQ(numBytes, mInputBufferSize) << numBytes << " of " << mInputBufferSize << " read";
+
+ fclose(inputFilePtr);
+ }
+
+ size_t mFrameWidth;
+ size_t mFrameHeight;
+ size_t mInputBufferSize;
+ const uint8_t *mInputBuffer;
+};
+
+class AvcCSDValidateTest : public MetaDataValidate,
+ public ::testing::TestWithParam<string /*inputFile*/> {
+ public:
+ virtual void SetUp() override {
+ string inputFile = gEnv->getRes() + GetParam();
+
+ ASSERT_NO_FATAL_FAILURE(SetUpMetaDataValidate(inputFile));
+ }
+};
+
+class AacCSDTest
+ : public ::testing::TestWithParam<tuple<uint32_t /*profile*/, uint32_t /*samplingFreqIndex*/,
+ uint32_t /*channelConfig*/>> {
+ public:
+ virtual void SetUp() override {
+ tuple<uint32_t, uint32_t, uint32_t> params = GetParam();
+ mAacProfile = get<0>(params);
+ mAacSamplingFreqIndex = get<1>(params);
+ mAacChannelConfig = get<2>(params);
+ }
+
+ uint32_t mAacProfile;
+ uint32_t mAacSamplingFreqIndex;
+ uint32_t mAacChannelConfig;
+};
+
+class AacADTSTest
+ : public ::testing::TestWithParam<
+ tuple<string /*adtsFile*/, uint32_t /*channelCount*/, uint32_t /*sampleRate*/>> {
+ public:
+ AacADTSTest() : mInputBuffer(nullptr) {}
+
+ virtual void SetUp() override {
+ tuple<string, uint32_t, uint32_t> params = GetParam();
+ string fileName = gEnv->getRes() + get<0>(params);
+ mAacChannelCount = get<1>(params);
+ mAacSampleRate = get<2>(params);
+
+ FILE *filePtr = fopen(fileName.c_str(), "r");
+ ASSERT_NE(filePtr, nullptr) << "Failed to open file: " << fileName;
+
+ mInputBuffer = new uint8_t[kAdtsCsdSize];
+ ASSERT_NE(mInputBuffer, nullptr) << "Failed to allocate a memory of size: " << kAdtsCsdSize;
+
+ int32_t numBytes = fread((void *)mInputBuffer, sizeof(uint8_t), kAdtsCsdSize, filePtr);
+ ASSERT_EQ(numBytes, kAdtsCsdSize)
+ << "Failed to read complete file, bytes read: " << numBytes;
+
+ fclose(filePtr);
+ }
+ int32_t mAacChannelCount;
+ int32_t mAacSampleRate;
+ const uint8_t *mInputBuffer;
+};
+
+class AacCSDValidateTest : public MetaDataValidate,
+ public ::testing::TestWithParam<string /*inputFile*/> {
+ public:
+ virtual void SetUp() override {
+ string inputFile = gEnv->getRes() + GetParam();
+
+ ASSERT_NO_FATAL_FAILURE(SetUpMetaDataValidate(inputFile));
+ }
+};
+
+class VorbisTest : public ::testing::TestWithParam<pair<string /*fileName*/, string /*infoFile*/>> {
+ public:
+ virtual void SetUp() override {
+ pair<string, string> params = GetParam();
+ string inputMediaFile = gEnv->getRes() + params.first;
+ mInputFileStream.open(inputMediaFile, ifstream::in);
+ ASSERT_TRUE(mInputFileStream.is_open()) << "Failed to open data file: " << inputMediaFile;
+
+ string inputInfoFile = gEnv->getRes() + params.second;
+ mInfoFileStream.open(inputInfoFile, ifstream::in);
+ ASSERT_TRUE(mInputFileStream.is_open()) << "Failed to open data file: " << inputInfoFile;
+ ASSERT_FALSE(inputInfoFile.empty()) << "Empty info file: " << inputInfoFile;
+ }
+
+ ~VorbisTest() {
+ if (mInputFileStream.is_open()) mInputFileStream.close();
+ if (mInfoFileStream.is_open()) mInfoFileStream.close();
+ }
+
+ ifstream mInputFileStream;
+ ifstream mInfoFileStream;
+};
+
+TEST_P(AvcCSDTest, AvcCSDValidationTest) {
+ AMediaFormat *csdData = AMediaFormat_new();
+ ASSERT_NE(csdData, nullptr) << "Failed to create AMedia format";
+
+ bool status = MakeAVCCodecSpecificData(csdData, mInputBuffer, mInputBufferSize);
+ ASSERT_TRUE(status) << "Failed to make AVC CSD from AMediaFormat";
+
+ int32_t avcWidth = -1;
+ status = AMediaFormat_getInt32(csdData, AMEDIAFORMAT_KEY_WIDTH, &avcWidth);
+ ASSERT_TRUE(status) << "Failed to get avc width";
+ ASSERT_EQ(avcWidth, mFrameWidth);
+
+ int32_t avcHeight = -1;
+ status = AMediaFormat_getInt32(csdData, AMEDIAFORMAT_KEY_HEIGHT, &avcHeight);
+ ASSERT_TRUE(status) << "Failed to get avc height";
+ ASSERT_EQ(avcHeight, mFrameHeight);
+
+ const char *mimeType = "";
+ status = AMediaFormat_getString(csdData, AMEDIAFORMAT_KEY_MIME, &mimeType);
+ ASSERT_TRUE(status) << "Failed to get the mime type";
+ ASSERT_STREQ(mimeType, MEDIA_MIMETYPE_VIDEO_AVC);
+
+ MetaDataBase *metaData = new MetaDataBase();
+ ASSERT_NE(metaData, nullptr) << "Failed to create MetaData Base";
+
+ status = MakeAVCCodecSpecificData(*metaData, mInputBuffer, mInputBufferSize);
+ ASSERT_TRUE(status) << "Failed to make AVC CSD from MetaDataBase";
+
+ avcWidth = -1;
+ status = metaData->findInt32(kKeyWidth, &avcWidth);
+ ASSERT_TRUE(status) << "Failed to find the width";
+ ASSERT_EQ(avcWidth, mFrameWidth);
+
+ avcHeight = -1;
+ status = metaData->findInt32(kKeyHeight, &avcHeight);
+ ASSERT_TRUE(status) << "Failed to find the height";
+ ASSERT_EQ(avcHeight, mFrameHeight);
+
+ void *csdAMediaFormatBuffer = nullptr;
+ size_t csdAMediaFormatSize;
+ status = AMediaFormat_getBuffer(csdData, AMEDIAFORMAT_KEY_CSD_AVC, &csdAMediaFormatBuffer,
+ &csdAMediaFormatSize);
+ ASSERT_TRUE(status) << "Failed to get the CSD from AMediaFormat";
+ ASSERT_NE(csdAMediaFormatBuffer, nullptr) << "Invalid CSD from AMediaFormat";
+
+ const void *csdMetaDataBaseBuffer = nullptr;
+ size_t csdMetaDataBaseSize = 0;
+ uint32_t mediaType;
+ status = metaData->findData(kKeyAVCC, &mediaType, &csdMetaDataBaseBuffer, &csdMetaDataBaseSize);
+ ASSERT_TRUE(status) << "Failed to get the CSD from MetaDataBase";
+ ASSERT_NE(csdMetaDataBaseBuffer, nullptr) << "Invalid CSD from MetaDataBase";
+ ASSERT_GT(csdMetaDataBaseSize, 0) << "CSD size must be greater than 0";
+ ASSERT_EQ(csdMetaDataBaseSize, csdAMediaFormatSize)
+ << "CSD size of MetaData type and AMediaFormat type must be same";
+
+ int32_t result = memcmp(csdAMediaFormatBuffer, csdMetaDataBaseBuffer, csdAMediaFormatSize);
+ ASSERT_EQ(result, 0) << "CSD from AMediaFormat and MetaDataBase do not match";
+
+ delete metaData;
+ AMediaFormat_delete(csdData);
+}
+
+TEST_P(AvcCSDValidateTest, AvcValidateTest) {
+ AMediaFormat *csdData = AMediaFormat_new();
+ ASSERT_NE(csdData, nullptr) << "Failed to create AMedia format";
+
+ bool status = MakeAVCCodecSpecificData(csdData, mInputBuffer, mInputBufferSize);
+ ASSERT_FALSE(status) << "MakeAVCCodecSpecificData with AMediaFormat succeeds with invalid data";
+
+ MetaDataBase *metaData = new MetaDataBase();
+ ASSERT_NE(metaData, nullptr) << "Failed to create MetaData Base";
+
+ status = MakeAVCCodecSpecificData(*metaData, mInputBuffer, mInputBufferSize);
+ ASSERT_FALSE(status) << "MakeAVCCodecSpecificData with MetaDataBase succeeds with invalid data";
+}
+
+TEST_P(AacCSDTest, AacCSDValidationTest) {
+ AMediaFormat *csdData = AMediaFormat_new();
+ ASSERT_NE(csdData, nullptr) << "Failed to create AMedia format";
+
+ ASSERT_GE(mAacSamplingFreqIndex, 0);
+ ASSERT_LT(mAacSamplingFreqIndex, kMaxSamplingFreqIndex);
+ bool status = MakeAACCodecSpecificData(csdData, mAacProfile, mAacSamplingFreqIndex,
+ mAacChannelConfig);
+ ASSERT_TRUE(status) << "Failed to make AAC CSD from AMediaFormat";
+
+ int32_t sampleRate = -1;
+ status = AMediaFormat_getInt32(csdData, AMEDIAFORMAT_KEY_SAMPLE_RATE, &sampleRate);
+ ASSERT_TRUE(status) << "Failed to get sample rate";
+ ASSERT_EQ(kSamplingFreq[mAacSamplingFreqIndex], sampleRate);
+
+ int32_t channelCount = -1;
+ status = AMediaFormat_getInt32(csdData, AMEDIAFORMAT_KEY_CHANNEL_COUNT, &channelCount);
+ ASSERT_TRUE(status) << "Failed to get channel count";
+ ASSERT_EQ(channelCount, mAacChannelConfig);
+
+ const char *mimeType = "";
+ status = AMediaFormat_getString(csdData, AMEDIAFORMAT_KEY_MIME, &mimeType);
+ ASSERT_TRUE(status) << "Failed to get the mime type";
+ ASSERT_STREQ(mimeType, MEDIA_MIMETYPE_AUDIO_AAC);
+
+ MetaDataBase *metaData = new MetaDataBase();
+ ASSERT_NE(metaData, nullptr) << "Failed to create MetaData Base";
+
+ status = MakeAACCodecSpecificData(*metaData, mAacProfile, mAacSamplingFreqIndex,
+ mAacChannelConfig);
+ ASSERT_TRUE(status) << "Failed to make AAC CSD from MetaDataBase";
+
+ sampleRate = -1;
+ status = metaData->findInt32(kKeySampleRate, &sampleRate);
+ ASSERT_TRUE(status) << "Failed to get sampling rate";
+ ASSERT_EQ(kSamplingFreq[mAacSamplingFreqIndex], sampleRate);
+
+ channelCount = -1;
+ status = metaData->findInt32(kKeyChannelCount, &channelCount);
+ ASSERT_TRUE(status) << "Failed to get channel count";
+ ASSERT_EQ(channelCount, mAacChannelConfig);
+
+ mimeType = "";
+ status = metaData->findCString(kKeyMIMEType, &mimeType);
+ ASSERT_TRUE(status) << "Failed to get mime type";
+ ASSERT_STREQ(mimeType, MEDIA_MIMETYPE_AUDIO_AAC);
+
+ void *csdAMediaFormatBuffer = nullptr;
+ size_t csdAMediaFormatSize = 0;
+ status = AMediaFormat_getBuffer(csdData, AMEDIAFORMAT_KEY_CSD_0, &csdAMediaFormatBuffer,
+ &csdAMediaFormatSize);
+ ASSERT_TRUE(status) << "Failed to get the AMediaFormat CSD";
+ ASSERT_GT(csdAMediaFormatSize, 0) << "CSD size must be greater than 0";
+ ASSERT_NE(csdAMediaFormatBuffer, nullptr) << "Invalid CSD found";
+
+ const void *csdMetaDataBaseBuffer;
+ size_t csdMetaDataBaseSize = 0;
+ uint32_t mediaType;
+ status = metaData->findData(kKeyESDS, &mediaType, &csdMetaDataBaseBuffer, &csdMetaDataBaseSize);
+ ASSERT_TRUE(status) << "Failed to get the ESDS data from MetaDataBase";
+ ASSERT_GT(csdMetaDataBaseSize, 0) << "CSD size must be greater than 0";
+
+ ESDS esds(csdMetaDataBaseBuffer, csdMetaDataBaseSize);
+ status_t result = esds.getCodecSpecificInfo(&csdMetaDataBaseBuffer, &csdMetaDataBaseSize);
+ ASSERT_EQ(result, (status_t)OK) << "Failed to get CSD from ESDS data";
+ ASSERT_NE(csdMetaDataBaseBuffer, nullptr) << "Invalid CSD found";
+ ASSERT_EQ(csdAMediaFormatSize, csdMetaDataBaseSize)
+ << "CSD size do not match between AMediaFormat type and MetaDataBase type";
+
+ int32_t memcmpResult =
+ memcmp(csdAMediaFormatBuffer, csdMetaDataBaseBuffer, csdAMediaFormatSize);
+ ASSERT_EQ(memcmpResult, 0) << "AMediaFormat and MetaDataBase CSDs do not match";
+
+ AMediaFormat_delete(csdData);
+ delete metaData;
+}
+
+TEST_P(AacADTSTest, AacADTSValidationTest) {
+ MetaDataBase *metaData = new MetaDataBase();
+ ASSERT_NE(metaData, nullptr) << "Failed to create meta data";
+
+ bool status = MakeAACCodecSpecificData(*metaData, mInputBuffer, kAdtsCsdSize);
+ ASSERT_TRUE(status) << "Failed to make AAC CSD from MetaDataBase";
+
+ int32_t sampleRate = -1;
+ status = metaData->findInt32(kKeySampleRate, &sampleRate);
+ ASSERT_TRUE(status) << "Failed to get sampling rate";
+ ASSERT_EQ(sampleRate, mAacSampleRate);
+
+ int32_t channelCount = -1;
+ status = metaData->findInt32(kKeyChannelCount, &channelCount);
+ ASSERT_TRUE(status) << "Failed to get channel count";
+ ASSERT_EQ(channelCount, mAacChannelCount);
+
+ const char *mimeType = "";
+ status = metaData->findCString(kKeyMIMEType, &mimeType);
+ ASSERT_TRUE(status) << "Failed to get mime type";
+ ASSERT_STREQ(mimeType, MEDIA_MIMETYPE_AUDIO_AAC);
+
+ delete metaData;
+}
+
+TEST_P(AacCSDValidateTest, AacInvalidInputTest) {
+ MetaDataBase *metaData = new MetaDataBase();
+ ASSERT_NE(metaData, nullptr) << "Failed to create meta data";
+
+ bool status = MakeAACCodecSpecificData(*metaData, mInputBuffer, kAdtsCsdSize);
+ ASSERT_FALSE(status) << "MakeAACCodecSpecificData succeeds with invalid data";
+}
+
+TEST_P(VorbisTest, VorbisCommentTest) {
+ string line;
+ string tag;
+ string key;
+ string value;
+ size_t commentLength;
+ bool status;
+
+ while (getline(mInfoFileStream, line)) {
+ istringstream stringLine(line);
+ stringLine >> tag >> key >> value >> commentLength;
+ ASSERT_GT(commentLength, 0) << "Vorbis comment size must be greater than 0";
+
+ string comment;
+ string dataLine;
+
+ getline(mInputFileStream, dataLine);
+ istringstream dataStringLine(dataLine);
+ dataStringLine >> comment;
+
+ char *buffer = strndup(comment.c_str(), commentLength);
+ ASSERT_NE(buffer, nullptr) << "Failed to allocate buffer of size: " << commentLength;
+
+ AMediaFormat *fileMeta = AMediaFormat_new();
+ ASSERT_NE(fileMeta, nullptr) << "Failed to create AMedia format";
+
+ parseVorbisComment(fileMeta, buffer, commentLength);
+ free(buffer);
+
+ if (!strncasecmp(tag.c_str(), "ANDROID_HAPTIC", sizeof(tag))) {
+ int32_t numChannelExpected = stoi(value);
+ int32_t numChannelFound = -1;
+ status = AMediaFormat_getInt32(fileMeta, key.c_str(), &numChannelFound);
+ ASSERT_TRUE(status) << "Failed to get the channel count";
+ ASSERT_EQ(numChannelExpected, numChannelFound);
+ } else if (!strncasecmp(tag.c_str(), "ANDROID_LOOP", sizeof(tag))) {
+ int32_t loopExpected = !value.compare("true");
+ int32_t loopFound = -1;
+
+ status = AMediaFormat_getInt32(fileMeta, "loop", &loopFound);
+ ASSERT_TRUE(status) << "Failed to get the loop count";
+ ASSERT_EQ(loopExpected, loopFound);
+ } else {
+ const char *tagValue = "";
+ status = AMediaFormat_getString(fileMeta, key.c_str(), &tagValue);
+ ASSERT_TRUE(status) << "Failed to get the tag value";
+ ASSERT_STREQ(value.c_str(), tagValue);
+ }
+ AMediaFormat_delete(fileMeta);
+ }
+}
+
+INSTANTIATE_TEST_SUITE_P(MetaDataUtilsTestAll, AvcCSDTest,
+ ::testing::Values(make_tuple("sps_pps_userdata.h264", 8, 8),
+ make_tuple("sps_userdata_pps.h264", 8, 8),
+ make_tuple("sps_pps_sps_pps.h264", 8, 8)));
+
+// TODO(b/158067691): Add invalid test vectors with incomplete PPS or no PPS
+INSTANTIATE_TEST_SUITE_P(MetaDataUtilsTestAll, AvcCSDValidateTest,
+ ::testing::Values("sps_pps_only_startcode.h264",
+ "sps_incomplete_pps.h264",
+ // TODO(b/158067691) "sps_pps_incomplete.h264",
+ "randomdata.h264",
+ // TODO(b/158067691) "sps.h264",
+ "pps.h264"));
+
+INSTANTIATE_TEST_SUITE_P(MetaDataUtilsTestAll, AacCSDTest,
+ ::testing::Values(make_tuple(AACObjectMain, 1, 1)));
+
+INSTANTIATE_TEST_SUITE_P(MetaDataUtilsTestAll, AacADTSTest,
+ ::testing::Values(make_tuple("loudsoftaacadts", 1, 44100)));
+
+INSTANTIATE_TEST_SUITE_P(MetaDataUtilsTestAll, AacCSDValidateTest,
+ ::testing::Values("loudsoftaacadts_invalidheader",
+ "loudsoftaacadts_invalidprofile",
+ "loudsoftaacadts_invalidchannelconfig"));
+
+// TODO(b/157974508) Add test vector for vorbis thumbnail tag
+// Info file contains TAG, Key, Value and size of the vorbis comment
+INSTANTIATE_TEST_SUITE_P(
+ MetaDataUtilsTestAll, VorbisTest,
+ ::testing::Values(make_pair("vorbiscomment_sintel.dat", "vorbiscomment_sintel.info"),
+ make_pair("vorbiscomment_album.dat", "vorbiscomment_album.info"),
+ make_pair("vorbiscomment_loop.dat", "vorbiscomment_loop.info")));
+
+int main(int argc, char **argv) {
+ gEnv = new MetaDataUtilsTestEnvironment();
+ ::testing::AddGlobalTestEnvironment(gEnv);
+ ::testing::InitGoogleTest(&argc, argv);
+ int status = gEnv->initFromOptions(argc, argv);
+ if (status == 0) {
+ status = RUN_ALL_TESTS();
+ ALOGV("Test result = %d\n", status);
+ }
+ return status;
+}
diff --git a/media/libstagefright/tests/metadatautils/MetaDataUtilsTestEnvironment.h b/media/libstagefright/tests/metadatautils/MetaDataUtilsTestEnvironment.h
new file mode 100644
index 0000000..4d642bc
--- /dev/null
+++ b/media/libstagefright/tests/metadatautils/MetaDataUtilsTestEnvironment.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __METADATA_UTILS_TEST_ENVIRONMENT_H__
+#define __METADATA_UTILS_TEST_ENVIRONMENT_H__
+
+#include <gtest/gtest.h>
+
+#include <getopt.h>
+
+using namespace std;
+
+class MetaDataUtilsTestEnvironment : public::testing::Environment {
+ public:
+ MetaDataUtilsTestEnvironment() : res("/data/local/tmp/") {}
+
+ // Parses the command line arguments
+ int initFromOptions(int argc, char **argv);
+
+ void setRes(const char *_res) { res = _res; }
+
+ const string getRes() const { return res; }
+
+ private:
+ string res;
+};
+
+int MetaDataUtilsTestEnvironment::initFromOptions(int argc, char **argv) {
+ static struct option options[] = {{"path", required_argument, 0, 'P'}, {0, 0, 0, 0}};
+
+ while (true) {
+ int index = 0;
+ int c = getopt_long(argc, argv, "P:", options, &index);
+ if (c == -1) {
+ break;
+ }
+
+ switch (c) {
+ case 'P': {
+ setRes(optarg);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ if (optind < argc) {
+ fprintf(stderr,
+ "unrecognized option: %s\n\n"
+ "usage: %s <gtest options> <test options>\n\n"
+ "test options are:\n\n"
+ "-P, --path: Resource files directory location\n",
+ argv[optind ?: 1], argv[0]);
+ return 2;
+ }
+ return 0;
+}
+
+#endif // __METADATA_UTILS_TEST_ENVIRONMENT_H__
diff --git a/media/libstagefright/tests/metadatautils/README.md b/media/libstagefright/tests/metadatautils/README.md
new file mode 100644
index 0000000..0862a07
--- /dev/null
+++ b/media/libstagefright/tests/metadatautils/README.md
@@ -0,0 +1,39 @@
+## Media Testing ##
+---
+#### MetaDataUtils Test
+The MetaDataUtils Unit Test Suite validates the libstagefright_metadatautils library available in libstagefright.
+
+Run the following steps to build the test suite:
+```
+m MetaDataUtilsTest
+```
+
+The 32-bit binaries will be created in the following path : ${OUT}/data/nativetest/
+
+The 64-bit binaries will be created in the following path : ${OUT}/data/nativetest64/
+
+To test 64-bit binary push binaries from nativetest64.
+```
+adb push ${OUT}/data/nativetest64/MetaDataUtilsTest/MetaDataUtilsTest /data/local/tmp/
+```
+
+To test 32-bit binary push binaries from nativetest.
+```
+adb push ${OUT}/data/nativetest/MetaDataUtilsTest/MetaDataUtilsTest /data/local/tmp/
+```
+
+The resource file for the tests is taken from [here](https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/tests/metadatautils/MetaDataUtilsTestRes-1.0.zip). Download, unzip and push these files into device for testing.
+
+```
+adb push MetaDataUtilsTestRes-1.0 /data/local/tmp/
+```
+
+usage: MetaDataUtilsTest -P \<path_to_folder\>
+```
+adb shell /data/local/tmp/MetaDataUtilsTest -P /data/local/tmp/MetaDataUtilsTestRes-1.0/
+```
+Alternatively, the test can also be run using atest command.
+
+```
+atest MetaDataUtilsTest -- --enable-module-dynamic-download=true
+```
diff --git a/media/utils/EventLogTags.logtags b/media/utils/EventLogTags.logtags
index 67f0ea8..c397f34 100644
--- a/media/utils/EventLogTags.logtags
+++ b/media/utils/EventLogTags.logtags
@@ -31,7 +31,7 @@
# 6: Percent
# Default value for data of type int/long is 2 (bytes).
#
-# See system/core/logcat/event.logtags for the master copy of the tags.
+# See system/core/logcat/event.logtags for the original definition of the tags.
# 61000 - 61199 reserved for audioserver
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 474313f..d6f553b 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -674,8 +674,8 @@
sp<NBLog::Writer> AudioFlinger::newWriter_l(size_t size, const char *name)
{
- // If there is no memory allocated for logs, return a dummy writer that does nothing.
- // Similarly if we can't contact the media.log service, also return a dummy writer.
+ // If there is no memory allocated for logs, return a no-op writer that does nothing.
+ // Similarly if we can't contact the media.log service, also return a no-op writer.
if (mLogMemoryDealer == 0 || sMediaLogService == 0) {
return new NBLog::Writer();
}
@@ -701,7 +701,7 @@
}
}
// Even after garbage-collecting all old writers, there is still not enough memory,
- // so return a dummy writer
+ // so return a no-op writer
return new NBLog::Writer();
}
success:
@@ -1269,9 +1269,9 @@
}
// Now set the master mute in each playback thread. Playback threads
- // assigned to HALs which do not have master mute support will apply master
- // mute during the mix operation. Threads with HALs which do support master
- // mute will simply ignore the setting.
+ // assigned to HALs which do not have master mute support will apply master mute
+ // during the mix operation. Threads with HALs which do support master mute
+ // will simply ignore the setting.
Vector<VolumeInterface *> volumeInterfaces = getAllVolumeInterfaces_l();
for (size_t i = 0; i < volumeInterfaces.size(); i++) {
volumeInterfaces[i]->setMasterMute(muted);
diff --git a/services/audioflinger/OWNERS b/services/audioflinger/OWNERS
index d02d9e0..034d161 100644
--- a/services/audioflinger/OWNERS
+++ b/services/audioflinger/OWNERS
@@ -1,4 +1,4 @@
+gkasten@google.com
hunga@google.com
jmtrivi@google.com
mnaganov@google.com
-gkasten@google.com
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 796596a..1429acd 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -7129,7 +7129,7 @@
const ssize_t availableToRead = mPipeSource->availableToRead();
if (availableToRead >= 0) {
- // PipeSource is the master clock. It is up to the AudioRecord client to keep up.
+ // PipeSource is the primary clock. It is up to the AudioRecord client to keep up.
LOG_ALWAYS_FATAL_IF((size_t)availableToRead > mPipeFramesP2,
"more frames to read than fifo size, %zd > %zu",
availableToRead, mPipeFramesP2);
diff --git a/services/audioflinger/TypedLogger.h b/services/audioflinger/TypedLogger.h
index 6ef19bf..feb71e3 100644
--- a/services/audioflinger/TypedLogger.h
+++ b/services/audioflinger/TypedLogger.h
@@ -80,7 +80,7 @@
// TODO Permit disabling of logging at compile-time.
-// TODO A non-nullptr dummy implementation that is a nop would be faster than checking for nullptr
+// TODO A non-nullptr stub implementation that is a nop would be faster than checking for nullptr
// in the case when logging is enabled at compile-time and enabled at runtime, but it might be
// slower than nullptr check when logging is enabled at compile-time and disabled at runtime.
@@ -129,8 +129,8 @@
namespace android {
extern "C" {
-// TODO consider adding a thread_local NBLog::Writer tlDummyNBLogWriter and then
-// initialize below tlNBLogWriter to &tlDummyNBLogWriter to remove the need to
+// TODO consider adding a thread_local NBLog::Writer tlStubNBLogWriter and then
+// initialize below tlNBLogWriter to &tlStubNBLogWriter to remove the need to
// check for nullptr every time. Also reduces the need to add a new logging macro above
// each time we want to log a new type.
extern thread_local NBLog::Writer *tlNBLogWriter;
diff --git a/services/audiopolicy/OWNERS b/services/audiopolicy/OWNERS
index a8483fa..da9d32f 100644
--- a/services/audiopolicy/OWNERS
+++ b/services/audiopolicy/OWNERS
@@ -1,3 +1,2 @@
jmtrivi@google.com
-krocard@google.com
mnaganov@google.com
diff --git a/services/audiopolicy/service/AudioPolicyEffects.cpp b/services/audiopolicy/service/AudioPolicyEffects.cpp
index 738a279..d5cb395 100644
--- a/services/audiopolicy/service/AudioPolicyEffects.cpp
+++ b/services/audiopolicy/service/AudioPolicyEffects.cpp
@@ -121,8 +121,8 @@
Vector <EffectDesc *> effects = mInputSources.valueAt(index)->mEffects;
for (size_t i = 0; i < effects.size(); i++) {
EffectDesc *effect = effects[i];
- sp<AudioEffect> fx = new AudioEffect(NULL, String16("android"), &effect->mUuid, -1, 0,
- 0, audioSession, input);
+ sp<AudioEffect> fx = new AudioEffect(String16("android"));
+ fx->set(NULL, &effect->mUuid, -1, 0, 0, audioSession, input);
status_t status = fx->initCheck();
if (status != NO_ERROR && status != ALREADY_EXISTS) {
ALOGW("addInputEffects(): failed to create Fx %s on source %d",
@@ -270,8 +270,8 @@
Vector <EffectDesc *> effects = mOutputStreams.valueAt(index)->mEffects;
for (size_t i = 0; i < effects.size(); i++) {
EffectDesc *effect = effects[i];
- sp<AudioEffect> fx = new AudioEffect(NULL, String16("android"), &effect->mUuid, 0, 0, 0,
- audioSession, output);
+ sp<AudioEffect> fx = new AudioEffect(String16("android"));
+ fx->set(NULL, &effect->mUuid, 0, 0, 0, audioSession, output);
status_t status = fx->initCheck();
if (status != NO_ERROR && status != ALREADY_EXISTS) {
ALOGE("addOutputSessionEffects(): failed to create Fx %s on session %d",
@@ -967,11 +967,11 @@
for (const auto& deviceEffectsIter : mDeviceEffects) {
const auto& deviceEffects = deviceEffectsIter.second;
for (const auto& effectDesc : deviceEffects->mEffectDescriptors->mEffects) {
- auto fx = std::make_unique<AudioEffect>(
- EFFECT_UUID_NULL, String16("android"), &effectDesc->mUuid, 0, nullptr,
- nullptr, AUDIO_SESSION_DEVICE, AUDIO_IO_HANDLE_NONE,
- AudioDeviceTypeAddr{deviceEffects->getDeviceType(),
- deviceEffects->getDeviceAddress()});
+ auto fx = std::make_unique<AudioEffect>(String16("android"));
+ fx->set(EFFECT_UUID_NULL, &effectDesc->mUuid, 0, nullptr,
+ nullptr, AUDIO_SESSION_DEVICE, AUDIO_IO_HANDLE_NONE,
+ AudioDeviceTypeAddr{deviceEffects->getDeviceType(),
+ deviceEffects->getDeviceAddress()});
status_t status = fx->initCheck();
if (status != NO_ERROR && status != ALREADY_EXISTS) {
ALOGE("%s(): failed to create Fx %s on port type=%d address=%s", __func__,
diff --git a/services/oboeservice/AAudioServiceStreamShared.cpp b/services/oboeservice/AAudioServiceStreamShared.cpp
index 2ca847a..69420af 100644
--- a/services/oboeservice/AAudioServiceStreamShared.cpp
+++ b/services/oboeservice/AAudioServiceStreamShared.cpp
@@ -105,7 +105,7 @@
}
int32_t capacityInFrames = numBursts * framesPerBurst;
- // Final sanity check.
+ // Final range check.
if (capacityInFrames > MAX_FRAMES_PER_BUFFER) {
ALOGE("calculateBufferCapacity() calc capacity %d > max %d",
capacityInFrames, MAX_FRAMES_PER_BUFFER);