Merge "Add support for vp9 playback in mp4"
diff --git a/METADATA b/METADATA
new file mode 100644
index 0000000..d97975c
--- /dev/null
+++ b/METADATA
@@ -0,0 +1,3 @@
+third_party {
+ license_type: NOTICE
+}
diff --git a/camera/CameraParameters.cpp b/camera/CameraParameters.cpp
index 68969cf..e95c91c 100644
--- a/camera/CameraParameters.cpp
+++ b/camera/CameraParameters.cpp
@@ -20,6 +20,7 @@
#include <string.h>
#include <stdlib.h>
+#include <unistd.h>
#include <camera/CameraParameters.h>
#include <system/graphics.h>
diff --git a/camera/CameraParameters2.cpp b/camera/CameraParameters2.cpp
index c29233c..a1cf355 100644
--- a/camera/CameraParameters2.cpp
+++ b/camera/CameraParameters2.cpp
@@ -21,6 +21,7 @@
#include <string.h>
#include <stdlib.h>
+#include <unistd.h>
#include <camera/CameraParameters2.h>
namespace android {
diff --git a/camera/cameraserver/cameraserver.rc b/camera/cameraserver/cameraserver.rc
index a9aae0b..8f51458 100644
--- a/camera/cameraserver/cameraserver.rc
+++ b/camera/cameraserver/cameraserver.rc
@@ -3,5 +3,5 @@
user cameraserver
group audio camera input drmrpc
ioprio rt 4
- writepid /dev/cpuset/camera-daemon/tasks /dev/stune/top-app/tasks
+ task_profiles CameraServiceCapacity MaxPerformance
rlimit rtprio 10 10
diff --git a/drm/libmediadrm/ICrypto.cpp b/drm/libmediadrm/ICrypto.cpp
index a2594aa..8d8d088 100644
--- a/drm/libmediadrm/ICrypto.cpp
+++ b/drm/libmediadrm/ICrypto.cpp
@@ -264,8 +264,12 @@
{
CHECK_INTERFACE(ICrypto, data, reply);
- uint8_t uuid[16];
- data.read(uuid, sizeof(uuid));
+ uint8_t uuid[16] = {0};
+ if (data.read(uuid, sizeof(uuid)) != NO_ERROR) {
+ android_errorWriteLog(0x534e4554, "144767096");
+ reply->writeInt32(BAD_VALUE);
+ return OK;
+ }
size_t opaqueSize = data.readInt32();
void *opaqueData = NULL;
@@ -280,7 +284,11 @@
return NO_MEMORY;
}
- data.read(opaqueData, opaqueSize);
+ if (data.read(opaqueData, opaqueSize) != NO_ERROR) {
+ android_errorWriteLog(0x534e4554, "144767096");
+ reply->writeInt32(BAD_VALUE);
+ return OK;
+ }
reply->writeInt32(createPlugin(uuid, opaqueData, opaqueSize));
free(opaqueData);
diff --git a/drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp b/drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp
index f164f28..3ecf6d5 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp
+++ b/drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp
@@ -136,6 +136,8 @@
return Void();
}
+ base = static_cast<uint8_t *>(static_cast<void *>(destBase->getPointer()));
+
if (destBuffer.offset + destBuffer.size > destBase->getSize()) {
_hidl_cb(Status_V1_2::ERROR_DRM_FRAME_TOO_LARGE, 0, "invalid buffer size");
return Void();
diff --git a/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp b/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp
index d74bc53..7cb5a38 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp
+++ b/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp
@@ -809,6 +809,11 @@
// count - number of secure stops
// list of fixed length secure stops
size_t countBufferSize = sizeof(uint32_t);
+ if (input.size() < countBufferSize) {
+ // SafetyNet logging
+ android_errorWriteLog(0x534e4554, "144766455");
+ return Status::BAD_VALUE;
+ }
uint32_t count = 0;
sscanf(reinterpret_cast<char*>(input.data()), "%04" PRIu32, &count);
diff --git a/media/audioserver/audioserver.rc b/media/audioserver/audioserver.rc
index 5484613..8a31786 100644
--- a/media/audioserver/audioserver.rc
+++ b/media/audioserver/audioserver.rc
@@ -5,7 +5,7 @@
group audio camera drmrpc media mediadrm net_bt net_bt_admin net_bw_acct wakelock
capabilities BLOCK_SUSPEND
ioprio rt 4
- writepid /dev/cpuset/foreground/tasks /dev/stune/foreground/tasks
+ task_profiles ProcessCapacityHigh HighPerformance
onrestart restart vendor.audio-hal
onrestart restart vendor.audio-hal-4-0-msd
# Keep the original service names for backward compatibility
@@ -17,5 +17,19 @@
on property:vts.native_server.on=0
start audioserver
+on property:init.svc.audioserver=stopped
+ stop vendor.audio-hal
+ stop vendor.audio-hal-4-0-msd
+ # Keep the original service names for backward compatibility
+ stop vendor.audio-hal-2-0
+ stop audio-hal-2-0
+
+on property:init.svc.audioserver=running
+ start vendor.audio-hal
+ start vendor.audio-hal-4-0-msd
+ # Keep the original service names for backward compatibility
+ start vendor.audio-hal-2-0
+ start audio-hal-2-0
+
on init
mkdir /dev/socket/audioserver 0775 audioserver audioserver
diff --git a/media/codec2/components/avc/C2SoftAvcDec.cpp b/media/codec2/components/avc/C2SoftAvcDec.cpp
index 2be51dd..932a16a 100644
--- a/media/codec2/components/avc/C2SoftAvcDec.cpp
+++ b/media/codec2/components/avc/C2SoftAvcDec.cpp
@@ -35,6 +35,7 @@
constexpr char COMPONENT_NAME[] = "c2.android.avc.decoder";
constexpr uint32_t kDefaultOutputDelay = 8;
constexpr uint32_t kMaxOutputDelay = 16;
+constexpr uint32_t kMinInputBytes = 4;
} // namespace
class C2SoftAvcDec::IntfImpl : public SimpleInterface<void>::BaseParams {
@@ -500,7 +501,7 @@
status_t C2SoftAvcDec::initDecoder() {
if (OK != createDecoder()) return UNKNOWN_ERROR;
mNumCores = MIN(getCpuCoreCount(), MAX_NUM_CORES);
- mStride = ALIGN128(mWidth);
+ mStride = ALIGN32(mWidth);
mSignalledError = false;
resetPlugin();
(void) setNumCores();
@@ -518,10 +519,20 @@
size_t inSize,
uint32_t tsMarker) {
uint32_t displayStride = mStride;
+ if (outBuffer) {
+ C2PlanarLayout layout;
+ layout = outBuffer->layout();
+ displayStride = layout.planes[C2PlanarLayout::PLANE_Y].rowInc;
+ }
uint32_t displayHeight = mHeight;
size_t lumaSize = displayStride * displayHeight;
size_t chromaSize = lumaSize >> 2;
+ if (mStride != displayStride) {
+ mStride = displayStride;
+ if (OK != setParams(mStride, IVD_DECODE_FRAME)) return false;
+ }
+
ps_decode_ip->u4_size = sizeof(ivd_video_decode_ip_t);
ps_decode_ip->e_cmd = IVD_CMD_VIDEO_DECODE;
if (inBuffer) {
@@ -537,7 +548,7 @@
ps_decode_ip->s_out_buffer.u4_min_out_buf_size[1] = chromaSize;
ps_decode_ip->s_out_buffer.u4_min_out_buf_size[2] = chromaSize;
if (outBuffer) {
- if (outBuffer->width() < displayStride || outBuffer->height() < displayHeight) {
+ if (outBuffer->height() < displayHeight) {
ALOGE("Output buffer too small: provided (%dx%d) required (%ux%u)",
outBuffer->width(), outBuffer->height(), displayStride, displayHeight);
return false;
@@ -755,24 +766,21 @@
ALOGE("not supposed to be here, invalid decoder context");
return C2_CORRUPTED;
}
- if (mStride != ALIGN128(mWidth)) {
- mStride = ALIGN128(mWidth);
- if (OK != setParams(mStride, IVD_DECODE_FRAME)) return C2_CORRUPTED;
- }
if (mOutBlock &&
- (mOutBlock->width() != mStride || mOutBlock->height() != mHeight)) {
+ (mOutBlock->width() != ALIGN32(mWidth) || mOutBlock->height() != mHeight)) {
mOutBlock.reset();
}
if (!mOutBlock) {
uint32_t format = HAL_PIXEL_FORMAT_YV12;
C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
- c2_status_t err = pool->fetchGraphicBlock(mStride, mHeight, format, usage, &mOutBlock);
+ c2_status_t err =
+ pool->fetchGraphicBlock(ALIGN32(mWidth), mHeight, format, usage, &mOutBlock);
if (err != C2_OK) {
ALOGE("fetchGraphicBlock for Output failed with status %d", err);
return err;
}
ALOGV("provided (%dx%d) required (%dx%d)",
- mOutBlock->width(), mOutBlock->height(), mStride, mHeight);
+ mOutBlock->width(), mOutBlock->height(), ALIGN32(mWidth), mHeight);
}
return C2_OK;
@@ -816,7 +824,7 @@
inSize, (int)work->input.ordinal.timestamp.peeku(),
(int)work->input.ordinal.frameIndex.peeku(), work->input.flags);
size_t inPos = 0;
- while (inPos < inSize) {
+ while (inPos < inSize && inSize - inPos >= kMinInputBytes) {
if (C2_OK != ensureDecoderState(pool)) {
mSignalledError = true;
work->workletsProcessed = 1u;
@@ -903,12 +911,12 @@
work->result = C2_CORRUPTED;
return;
}
- continue;
}
if (0 < s_decode_op.u4_pic_wd && 0 < s_decode_op.u4_pic_ht) {
if (mHeaderDecoded == false) {
mHeaderDecoded = true;
- setParams(ALIGN128(s_decode_op.u4_pic_wd), IVD_DECODE_FRAME);
+ mStride = ALIGN32(s_decode_op.u4_pic_wd);
+ setParams(mStride, IVD_DECODE_FRAME);
}
if (s_decode_op.u4_pic_wd != mWidth || s_decode_op.u4_pic_ht != mHeight) {
mWidth = s_decode_op.u4_pic_wd;
@@ -936,16 +944,7 @@
if (s_decode_op.u4_output_present) {
finishWork(s_decode_op.u4_ts, work);
}
- if (0 == s_decode_op.u4_num_bytes_consumed) {
- ALOGD("Bytes consumed is zero. Ignoring remaining bytes");
- break;
- }
inPos += s_decode_op.u4_num_bytes_consumed;
- if (hasPicture && (inSize - inPos)) {
- ALOGD("decoded frame in current access nal, ignoring further trailing bytes %d",
- (int)inSize - (int)inPos);
- break;
- }
}
if (eos) {
drainInternal(DRAIN_COMPONENT_WITH_EOS, pool, work);
diff --git a/media/codec2/components/avc/C2SoftAvcDec.h b/media/codec2/components/avc/C2SoftAvcDec.h
index ed27493..bd84de0 100644
--- a/media/codec2/components/avc/C2SoftAvcDec.h
+++ b/media/codec2/components/avc/C2SoftAvcDec.h
@@ -39,8 +39,7 @@
#define ivdext_ctl_set_num_cores_op_t ih264d_ctl_set_num_cores_op_t
#define ivdext_ctl_get_vui_params_ip_t ih264d_ctl_get_vui_params_ip_t
#define ivdext_ctl_get_vui_params_op_t ih264d_ctl_get_vui_params_op_t
-#define ALIGN64(x) ((((x) + 63) >> 6) << 6)
-#define ALIGN128(x) ((((x) + 127) >> 7) << 7)
+#define ALIGN32(x) ((((x) + 31) >> 5) << 5)
#define MAX_NUM_CORES 4
#define IVDEXT_CMD_CTL_SET_NUM_CORES \
(IVD_CONTROL_API_COMMAND_TYPE_T)IH264D_CMD_CTL_SET_NUM_CORES
diff --git a/media/codec2/components/avc/C2SoftAvcEnc.cpp b/media/codec2/components/avc/C2SoftAvcEnc.cpp
index e3d419c..ab93ce3 100644
--- a/media/codec2/components/avc/C2SoftAvcEnc.cpp
+++ b/media/codec2/components/avc/C2SoftAvcEnc.cpp
@@ -103,7 +103,7 @@
addParameter(
DefineParam(mSize, C2_PARAMKEY_PICTURE_SIZE)
- .withDefault(new C2StreamPictureSizeInfo::input(0u, 320, 240))
+ .withDefault(new C2StreamPictureSizeInfo::input(0u, 16, 16))
.withFields({
C2F(mSize, width).inRange(2, 2560, 2),
C2F(mSize, height).inRange(2, 2560, 2),
@@ -129,7 +129,7 @@
addParameter(
DefineParam(mFrameRate, C2_PARAMKEY_FRAME_RATE)
- .withDefault(new C2StreamFrameRateInfo::output(0u, 30.))
+ .withDefault(new C2StreamFrameRateInfo::output(0u, 1.))
// TODO: More restriction?
.withFields({C2F(mFrameRate, value).greaterThan(0.)})
.withSetter(Setter<decltype(*mFrameRate)>::StrictValueWithNoDeps)
diff --git a/media/codec2/components/g711/Android.bp b/media/codec2/components/g711/Android.bp
index 3ede68c..0101b1a 100644
--- a/media/codec2/components/g711/Android.bp
+++ b/media/codec2/components/g711/Android.bp
@@ -7,6 +7,8 @@
srcs: ["C2SoftG711Dec.cpp"],
+ static_libs: ["codecs_g711dec"],
+
cflags: [
"-DALAW",
],
@@ -20,4 +22,6 @@
],
srcs: ["C2SoftG711Dec.cpp"],
+
+ static_libs: ["codecs_g711dec"],
}
diff --git a/media/codec2/components/g711/C2SoftG711Dec.cpp b/media/codec2/components/g711/C2SoftG711Dec.cpp
index 4ff0793..7f9c34e 100644
--- a/media/codec2/components/g711/C2SoftG711Dec.cpp
+++ b/media/codec2/components/g711/C2SoftG711Dec.cpp
@@ -22,7 +22,7 @@
#include <C2PlatformSupport.h>
#include <SimpleC2Interface.h>
-
+#include <g711Dec.h>
#include "C2SoftG711Dec.h"
namespace android {
@@ -224,53 +224,6 @@
return C2_OK;
}
-#ifdef ALAW
-void C2SoftG711Dec::DecodeALaw(
- int16_t *out, const uint8_t *in, size_t inSize) {
- while (inSize > 0) {
- inSize--;
- int32_t x = *in++;
-
- int32_t ix = x ^ 0x55;
- ix &= 0x7f;
-
- int32_t iexp = ix >> 4;
- int32_t mant = ix & 0x0f;
-
- if (iexp > 0) {
- mant += 16;
- }
-
- mant = (mant << 4) + 8;
-
- if (iexp > 1) {
- mant = mant << (iexp - 1);
- }
-
- *out++ = (x > 127) ? mant : -mant;
- }
-}
-#else
-void C2SoftG711Dec::DecodeMLaw(
- int16_t *out, const uint8_t *in, size_t inSize) {
- while (inSize > 0) {
- inSize--;
- int32_t x = *in++;
-
- int32_t mantissa = ~x;
- int32_t exponent = (mantissa >> 4) & 7;
- int32_t segment = exponent + 1;
- mantissa &= 0x0f;
-
- int32_t step = 4 << segment;
-
- int32_t abs = (0x80l << exponent) + step * mantissa + step / 2 - 4 * 33;
-
- *out++ = (x < 0x80) ? -abs : abs;
- }
-}
-#endif
-
class C2SoftG711DecFactory : public C2ComponentFactory {
public:
C2SoftG711DecFactory() : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
diff --git a/media/codec2/components/g711/C2SoftG711Dec.h b/media/codec2/components/g711/C2SoftG711Dec.h
index 23e8ffc..f93840b 100644
--- a/media/codec2/components/g711/C2SoftG711Dec.h
+++ b/media/codec2/components/g711/C2SoftG711Dec.h
@@ -45,12 +45,6 @@
std::shared_ptr<IntfImpl> mIntf;
bool mSignalledOutputEos;
-#ifdef ALAW
- void DecodeALaw(int16_t *out, const uint8_t *in, size_t inSize);
-#else
- void DecodeMLaw(int16_t *out, const uint8_t *in, size_t inSize);
-#endif
-
C2_DO_NOT_COPY(C2SoftG711Dec);
};
diff --git a/media/codec2/components/hevc/C2SoftHevcDec.cpp b/media/codec2/components/hevc/C2SoftHevcDec.cpp
index 6db4387..23104dc 100644
--- a/media/codec2/components/hevc/C2SoftHevcDec.cpp
+++ b/media/codec2/components/hevc/C2SoftHevcDec.cpp
@@ -497,7 +497,7 @@
status_t C2SoftHevcDec::initDecoder() {
if (OK != createDecoder()) return UNKNOWN_ERROR;
mNumCores = MIN(getCpuCoreCount(), MAX_NUM_CORES);
- mStride = ALIGN128(mWidth);
+ mStride = ALIGN32(mWidth);
mSignalledError = false;
resetPlugin();
(void) setNumCores();
@@ -515,10 +515,20 @@
size_t inSize,
uint32_t tsMarker) {
uint32_t displayStride = mStride;
+ if (outBuffer) {
+ C2PlanarLayout layout;
+ layout = outBuffer->layout();
+ displayStride = layout.planes[C2PlanarLayout::PLANE_Y].rowInc;
+ }
uint32_t displayHeight = mHeight;
size_t lumaSize = displayStride * displayHeight;
size_t chromaSize = lumaSize >> 2;
+ if (mStride != displayStride) {
+ mStride = displayStride;
+ if (OK != setParams(mStride, IVD_DECODE_FRAME)) return false;
+ }
+
ps_decode_ip->u4_size = sizeof(ivd_video_decode_ip_t);
ps_decode_ip->e_cmd = IVD_CMD_VIDEO_DECODE;
if (inBuffer) {
@@ -534,7 +544,7 @@
ps_decode_ip->s_out_buffer.u4_min_out_buf_size[1] = chromaSize;
ps_decode_ip->s_out_buffer.u4_min_out_buf_size[2] = chromaSize;
if (outBuffer) {
- if (outBuffer->width() < displayStride || outBuffer->height() < displayHeight) {
+ if (outBuffer->height() < displayHeight) {
ALOGE("Output buffer too small: provided (%dx%d) required (%ux%u)",
outBuffer->width(), outBuffer->height(), displayStride, displayHeight);
return false;
@@ -752,24 +762,21 @@
ALOGE("not supposed to be here, invalid decoder context");
return C2_CORRUPTED;
}
- if (mStride != ALIGN128(mWidth)) {
- mStride = ALIGN128(mWidth);
- if (OK != setParams(mStride, IVD_DECODE_FRAME)) return C2_CORRUPTED;
- }
if (mOutBlock &&
- (mOutBlock->width() != mStride || mOutBlock->height() != mHeight)) {
+ (mOutBlock->width() != ALIGN32(mWidth) || mOutBlock->height() != mHeight)) {
mOutBlock.reset();
}
if (!mOutBlock) {
uint32_t format = HAL_PIXEL_FORMAT_YV12;
C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
- c2_status_t err = pool->fetchGraphicBlock(mStride, mHeight, format, usage, &mOutBlock);
+ c2_status_t err =
+ pool->fetchGraphicBlock(ALIGN32(mWidth), mHeight, format, usage, &mOutBlock);
if (err != C2_OK) {
ALOGE("fetchGraphicBlock for Output failed with status %d", err);
return err;
}
ALOGV("provided (%dx%d) required (%dx%d)",
- mOutBlock->width(), mOutBlock->height(), mStride, mHeight);
+ mOutBlock->width(), mOutBlock->height(), ALIGN32(mWidth), mHeight);
}
return C2_OK;
@@ -904,7 +911,7 @@
if (0 < s_decode_op.u4_pic_wd && 0 < s_decode_op.u4_pic_ht) {
if (mHeaderDecoded == false) {
mHeaderDecoded = true;
- setParams(ALIGN128(s_decode_op.u4_pic_wd), IVD_DECODE_FRAME);
+ setParams(ALIGN32(s_decode_op.u4_pic_wd), IVD_DECODE_FRAME);
}
if (s_decode_op.u4_pic_wd != mWidth || s_decode_op.u4_pic_ht != mHeight) {
mWidth = s_decode_op.u4_pic_wd;
diff --git a/media/codec2/components/hevc/C2SoftHevcDec.h b/media/codec2/components/hevc/C2SoftHevcDec.h
index aecd101..600d7c1 100644
--- a/media/codec2/components/hevc/C2SoftHevcDec.h
+++ b/media/codec2/components/hevc/C2SoftHevcDec.h
@@ -37,8 +37,7 @@
#define ivdext_ctl_set_num_cores_op_t ihevcd_cxa_ctl_set_num_cores_op_t
#define ivdext_ctl_get_vui_params_ip_t ihevcd_cxa_ctl_get_vui_params_ip_t
#define ivdext_ctl_get_vui_params_op_t ihevcd_cxa_ctl_get_vui_params_op_t
-#define ALIGN64(x) ((((x) + 63) >> 6) << 6)
-#define ALIGN128(x) ((((x) + 127) >> 7) << 7)
+#define ALIGN32(x) ((((x) + 31) >> 5) << 5)
#define MAX_NUM_CORES 4
#define IVDEXT_CMD_CTL_SET_NUM_CORES \
(IVD_CONTROL_API_COMMAND_TYPE_T)IHEVCD_CXA_CMD_CTL_SET_NUM_CORES
diff --git a/media/codec2/components/mpeg2/C2SoftMpeg2Dec.cpp b/media/codec2/components/mpeg2/C2SoftMpeg2Dec.cpp
index df7b403..d62b717 100644
--- a/media/codec2/components/mpeg2/C2SoftMpeg2Dec.cpp
+++ b/media/codec2/components/mpeg2/C2SoftMpeg2Dec.cpp
@@ -564,7 +564,7 @@
if (OK != createDecoder()) return UNKNOWN_ERROR;
mNumCores = MIN(getCpuCoreCount(), MAX_NUM_CORES);
- mStride = ALIGN64(mWidth);
+ mStride = ALIGN32(mWidth);
mSignalledError = false;
resetPlugin();
(void) setNumCores();
@@ -582,10 +582,20 @@
size_t inSize,
uint32_t tsMarker) {
uint32_t displayStride = mStride;
+ if (outBuffer) {
+ C2PlanarLayout layout;
+ layout = outBuffer->layout();
+ displayStride = layout.planes[C2PlanarLayout::PLANE_Y].rowInc;
+ }
uint32_t displayHeight = mHeight;
size_t lumaSize = displayStride * displayHeight;
size_t chromaSize = lumaSize >> 2;
+ if (mStride != displayStride) {
+ mStride = displayStride;
+ if (OK != setParams(mStride)) return false;
+ }
+
ps_decode_ip->u4_size = sizeof(ivd_video_decode_ip_t);
ps_decode_ip->e_cmd = IVD_CMD_VIDEO_DECODE;
if (inBuffer) {
@@ -601,7 +611,7 @@
ps_decode_ip->s_out_buffer.u4_min_out_buf_size[1] = chromaSize;
ps_decode_ip->s_out_buffer.u4_min_out_buf_size[2] = chromaSize;
if (outBuffer) {
- if (outBuffer->width() < displayStride || outBuffer->height() < displayHeight) {
+ if (outBuffer->height() < displayHeight) {
ALOGE("Output buffer too small: provided (%dx%d) required (%ux%u)",
outBuffer->width(), outBuffer->height(), displayStride, displayHeight);
return false;
@@ -826,24 +836,21 @@
ALOGE("not supposed to be here, invalid decoder context");
return C2_CORRUPTED;
}
- if (mStride != ALIGN64(mWidth)) {
- mStride = ALIGN64(mWidth);
- if (OK != setParams(mStride)) return C2_CORRUPTED;
- }
if (mOutBlock &&
- (mOutBlock->width() != mStride || mOutBlock->height() != mHeight)) {
+ (mOutBlock->width() != ALIGN32(mWidth) || mOutBlock->height() != mHeight)) {
mOutBlock.reset();
}
if (!mOutBlock) {
uint32_t format = HAL_PIXEL_FORMAT_YV12;
C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
- c2_status_t err = pool->fetchGraphicBlock(mStride, mHeight, format, usage, &mOutBlock);
+ c2_status_t err =
+ pool->fetchGraphicBlock(ALIGN32(mWidth), mHeight, format, usage, &mOutBlock);
if (err != C2_OK) {
ALOGE("fetchGraphicBlock for Output failed with status %d", err);
return err;
}
ALOGV("provided (%dx%d) required (%dx%d)",
- mOutBlock->width(), mOutBlock->height(), mStride, mHeight);
+ mOutBlock->width(), mOutBlock->height(), ALIGN32(mWidth), mHeight);
}
return C2_OK;
diff --git a/media/codec2/components/mpeg2/C2SoftMpeg2Dec.h b/media/codec2/components/mpeg2/C2SoftMpeg2Dec.h
index 65d3b87..fd66304a 100644
--- a/media/codec2/components/mpeg2/C2SoftMpeg2Dec.h
+++ b/media/codec2/components/mpeg2/C2SoftMpeg2Dec.h
@@ -37,7 +37,7 @@
#define ivdext_ctl_set_num_cores_op_t impeg2d_ctl_set_num_cores_op_t
#define ivdext_ctl_get_seq_info_ip_t impeg2d_ctl_get_seq_info_ip_t
#define ivdext_ctl_get_seq_info_op_t impeg2d_ctl_get_seq_info_op_t
-#define ALIGN64(x) ((((x) + 63) >> 6) << 6)
+#define ALIGN32(x) ((((x) + 31) >> 5) << 5)
#define MAX_NUM_CORES 4
#define IVDEXT_CMD_CTL_SET_NUM_CORES \
(IVD_CONTROL_API_COMMAND_TYPE_T)IMPEG2D_CMD_CTL_SET_NUM_CORES
diff --git a/media/codec2/core/Android.bp b/media/codec2/core/Android.bp
index a7e8997..e3bbfd6 100644
--- a/media/codec2/core/Android.bp
+++ b/media/codec2/core/Android.bp
@@ -18,6 +18,10 @@
"-Werror",
],
+ header_abi_checker: {
+ check_all_apis: true,
+ },
+
header_libs: [
"libcodec2_headers",
"libhardware_headers",
diff --git a/media/codec2/hidl/1.0/utils/Android.bp b/media/codec2/hidl/1.0/utils/Android.bp
index a2930a6..19a7666 100644
--- a/media/codec2/hidl/1.0/utils/Android.bp
+++ b/media/codec2/hidl/1.0/utils/Android.bp
@@ -11,6 +11,7 @@
],
header_libs: [
+ "libbinder_headers",
"libcodec2_internal", // private
],
diff --git a/media/codec2/vndk/Android.bp b/media/codec2/vndk/Android.bp
index 52cc7ad..d4eb8d9 100644
--- a/media/codec2/vndk/Android.bp
+++ b/media/codec2/vndk/Android.bp
@@ -56,7 +56,6 @@
"android.hardware.graphics.mapper@3.0",
"android.hardware.media.bufferpool@2.0",
"libbase",
- "libbinder",
"libcutils",
"libdl",
"libhardware",
diff --git a/media/codecs/g711/decoder/Android.bp b/media/codecs/g711/decoder/Android.bp
new file mode 100644
index 0000000..377833f
--- /dev/null
+++ b/media/codecs/g711/decoder/Android.bp
@@ -0,0 +1,45 @@
+/*
+ * 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_library_static {
+ name: "codecs_g711dec",
+ vendor_available: true,
+ host_supported: true,
+
+ srcs: [
+ "g711DecAlaw.cpp",
+ "g711DecMlaw.cpp",
+ ],
+
+ export_include_dirs: ["."],
+
+ cflags: ["-Werror"],
+
+ sanitize: {
+ misc_undefined: [
+ "signed-integer-overflow",
+ "unsigned-integer-overflow",
+ ],
+ cfi: true,
+ },
+ apex_available: ["com.android.media.swcodec"],
+
+ target: {
+ darwin: {
+ enabled: false,
+ },
+ },
+}
diff --git a/media/codecs/g711/decoder/g711Dec.h b/media/codecs/g711/decoder/g711Dec.h
new file mode 100644
index 0000000..ca357a5
--- /dev/null
+++ b/media/codecs/g711/decoder/g711Dec.h
@@ -0,0 +1,41 @@
+/*
+ * 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 G711_DEC_H_
+#define G711_DEC_H_
+
+/**
+ * @file g711Dec.h
+ * @brief g711 Decoder API: DecodeALaw and DecodeMLaw
+ */
+
+/** Decodes input bytes of size inSize according to ALAW
+ *
+ * @param [in] out <tt>int16_t*</tt>: output buffer to be filled with decoded bytes.
+ * @param [in] in <tt>const uint8_t*</tt>: input buffer containing bytes to be decoded.
+ * @param [in] inSize <tt>size_t</tt>: size of the input buffer.
+ */
+void DecodeALaw(int16_t *out, const uint8_t *in, size_t inSize);
+
+/** Decodes input bytes of size inSize according to MLAW
+ *
+ * @param [in] out <tt>int16_t*</tt>: output buffer to be filled with decoded bytes.
+ * @param [in] in <tt>const uint8_t*</tt>: input buffer containing bytes to be decoded.
+ * @param [in] inSize <tt>size_t</tt>: size of the input buffer.
+ */
+void DecodeMLaw(int16_t *out, const uint8_t *in, size_t inSize);
+
+#endif // G711_DECODER_H_
diff --git a/media/codecs/g711/decoder/g711DecAlaw.cpp b/media/codecs/g711/decoder/g711DecAlaw.cpp
new file mode 100644
index 0000000..e41a7b4
--- /dev/null
+++ b/media/codecs/g711/decoder/g711DecAlaw.cpp
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+#include <stddef.h>
+#include <stdint.h>
+
+void DecodeALaw(int16_t *out, const uint8_t *in, size_t inSize) {
+ if (out != nullptr && in != nullptr) {
+ while (inSize > 0) {
+ inSize--;
+ int32_t x = *in++;
+
+ int32_t ix = x ^ 0x55;
+ ix &= 0x7f;
+
+ int32_t iexp = ix >> 4;
+ int32_t mant = ix & 0x0f;
+
+ if (iexp > 0) {
+ mant += 16;
+ }
+
+ mant = (mant << 4) + 8;
+
+ if (iexp > 1) {
+ mant = mant << (iexp - 1);
+ }
+
+ *out++ = (x > 127) ? mant : -mant;
+ }
+ }
+}
diff --git a/media/codecs/g711/decoder/g711DecMlaw.cpp b/media/codecs/g711/decoder/g711DecMlaw.cpp
new file mode 100644
index 0000000..bb2caea
--- /dev/null
+++ b/media/codecs/g711/decoder/g711DecMlaw.cpp
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+#include <stddef.h>
+#include <stdint.h>
+
+void DecodeMLaw(int16_t *out, const uint8_t *in, size_t inSize) {
+ if (out != nullptr && in != nullptr) {
+ while (inSize > 0) {
+ inSize--;
+ int32_t x = *in++;
+
+ int32_t mantissa = ~x;
+ int32_t exponent = (mantissa >> 4) & 7;
+ int32_t segment = exponent + 1;
+ mantissa &= 0x0f;
+
+ int32_t step = 4 << segment;
+
+ int32_t abs = (0x80l << exponent) + step * mantissa + step / 2 - 4 * 33;
+
+ *out++ = (x < 0x80) ? -abs : abs;
+ }
+ }
+}
diff --git a/media/codecs/g711/fuzzer/Android.bp b/media/codecs/g711/fuzzer/Android.bp
new file mode 100644
index 0000000..1aee7f5
--- /dev/null
+++ b/media/codecs/g711/fuzzer/Android.bp
@@ -0,0 +1,44 @@
+/******************************************************************************
+ *
+ * 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.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+cc_fuzz {
+ name: "g711alaw_dec_fuzzer",
+ host_supported: true,
+ srcs: [
+ "g711_dec_fuzzer.cpp",
+ ],
+ static_libs: [
+ "codecs_g711dec",
+ ],
+ cflags: [
+ "-DALAW",
+ ],
+}
+
+cc_fuzz {
+ name: "g711mlaw_dec_fuzzer",
+ host_supported: true,
+ srcs: [
+ "g711_dec_fuzzer.cpp",
+ ],
+ static_libs: [
+ "codecs_g711dec",
+ ],
+}
diff --git a/media/codecs/g711/fuzzer/README.md b/media/codecs/g711/fuzzer/README.md
new file mode 100644
index 0000000..0c1c36b
--- /dev/null
+++ b/media/codecs/g711/fuzzer/README.md
@@ -0,0 +1,49 @@
+# Fuzzer for libstagefright_g711dec decoder
+
+## Plugin Design Considerations
+The fuzzer plugin for G711 is designed based on the understanding of the
+codec and tries to achieve the following:
+
+##### Maximize code coverage
+G711 supports two types of decoding:
+1. DecodeALaw
+2. DecodeMLaw
+
+These two decoder API's are fuzzed separately using g711alaw_dec_fuzzer and
+g711mlaw_dec_fuzzer respectively.
+
+##### Maximize utilization of input data
+The plugin feeds the entire input data to the codec as expected by decoder API.
+
+## Build
+
+This describes steps to build g711alaw_dec_fuzzer and g711mlaw_dec_fuzzer binary.
+
+### Android
+
+#### Steps to build
+Build the fuzzer
+```
+ $ mm -j$(nproc) g711alaw_dec_fuzzer
+ $ mm -j$(nproc) g711mlaw_dec_fuzzer
+```
+
+#### Steps to run
+Create a directory CORPUS_DIR and copy some g711 files to that folder
+Push this directory to device.
+
+To run on device
+```
+ $ adb sync data
+ $ adb shell /data/fuzz/arm64/g711alaw_dec_fuzzer/g711alaw_dec_fuzzer CORPUS_DIR
+ $ adb shell /data/fuzz/arm64/g711mlaw_dec_fuzzer/g711mlaw_dec_fuzzer CORPUS_DIR
+```
+To run on host
+```
+ $ $ANDROID_HOST_OUT/fuzz/x86_64/g711alaw_dec_fuzzer/g711alaw_dec_fuzzer CORPUS_DIR
+ $ $ANDROID_HOST_OUT/fuzz/x86_64/g711mlaw_dec_fuzzer/g711mlaw_dec_fuzzer CORPUS_DIR
+```
+
+## References:
+ * http://llvm.org/docs/LibFuzzer.html
+ * https://github.com/google/oss-fuzz
diff --git a/media/codecs/g711/fuzzer/g711_dec_fuzzer.cpp b/media/codecs/g711/fuzzer/g711_dec_fuzzer.cpp
new file mode 100644
index 0000000..adfbcf5
--- /dev/null
+++ b/media/codecs/g711/fuzzer/g711_dec_fuzzer.cpp
@@ -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.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include "g711Dec.h"
+
+class Codec {
+ public:
+ Codec() = default;
+ ~Codec() = default;
+ void decodeFrames(const uint8_t *data, size_t size);
+};
+
+void Codec::decodeFrames(const uint8_t *data, size_t size) {
+ size_t outputBufferSize = sizeof(int16_t) * size;
+ int16_t *out = new int16_t[outputBufferSize];
+ if (!out) {
+ return;
+ }
+#ifdef ALAW
+ DecodeALaw(out, data, size);
+#else
+ DecodeMLaw(out, data, size);
+#endif
+ delete[] out;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+ if (size < 1) {
+ return 0;
+ }
+ Codec *codec = new Codec();
+ if (!codec) {
+ return 0;
+ }
+ codec->decodeFrames(data, size);
+ delete codec;
+ return 0;
+}
diff --git a/media/extractors/fuzzers/Android.bp b/media/extractors/fuzzers/Android.bp
new file mode 100644
index 0000000..59e9cd2
--- /dev/null
+++ b/media/extractors/fuzzers/Android.bp
@@ -0,0 +1,371 @@
+/******************************************************************************
+ *
+ * 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.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+cc_library {
+ name: "libextractorfuzzerbase",
+
+ srcs: [
+ "ExtractorFuzzerBase.cpp",
+ ],
+
+ local_include_dirs: [
+ "include",
+ ],
+
+ export_include_dirs: [
+ "include",
+ ],
+
+ static_libs: [
+ "liblog",
+ "libstagefright_foundation",
+ "libmedia",
+ ],
+
+ shared_libs: [
+ "libutils",
+ "libbinder",
+ "libmediandk",
+ ],
+
+ /* GETEXTRACTORDEF is not defined as extractor library is not linked in the
+ * base class. It will be included when the extractor fuzzer binary is
+ * generated.
+ */
+ allow_undefined_symbols: true,
+}
+
+cc_fuzz {
+ name: "mp4_extractor_fuzzer",
+
+ srcs: [
+ "mp4_extractor_fuzzer.cpp",
+ ],
+
+ include_dirs: [
+ "frameworks/av/media/extractors/mp4",
+ ],
+
+ static_libs: [
+ "liblog",
+ "libstagefright_foundation",
+ "libmedia",
+ "libextractorfuzzerbase",
+ "libstagefright_id3",
+ "libstagefright_esds",
+ "libmp4extractor",
+ ],
+
+ shared_libs: [
+ "libutils",
+ "libmediandk",
+ "libbinder",
+ ],
+
+ dictionary: "mp4_extractor_fuzzer.dict",
+}
+
+cc_fuzz {
+ name: "wav_extractor_fuzzer",
+
+ srcs: [
+ "wav_extractor_fuzzer.cpp",
+ ],
+
+ include_dirs: [
+ "frameworks/av/media/extractors/wav",
+ ],
+
+ static_libs: [
+ "liblog",
+ "libstagefright_foundation",
+ "libmedia",
+ "libextractorfuzzerbase",
+ "libfifo",
+ "libwavextractor",
+ ],
+
+ shared_libs: [
+ "libutils",
+ "libmediandk",
+ "libbinder",
+ "libbinder_ndk",
+ "libbase",
+ ],
+}
+
+cc_fuzz {
+ name: "amr_extractor_fuzzer",
+
+ srcs: [
+ "amr_extractor_fuzzer.cpp",
+ ],
+
+ include_dirs: [
+ "frameworks/av/media/extractors/amr",
+ ],
+
+ static_libs: [
+ "liblog",
+ "libstagefright_foundation",
+ "libmedia",
+ "libextractorfuzzerbase",
+ "libamrextractor",
+ ],
+
+ shared_libs: [
+ "libutils",
+ "libmediandk",
+ "libbinder",
+ ],
+
+ dictionary: "amr_extractor_fuzzer.dict",
+}
+
+cc_fuzz {
+ name: "mkv_extractor_fuzzer",
+
+ srcs: [
+ "mkv_extractor_fuzzer.cpp",
+ ],
+
+ include_dirs: [
+ "frameworks/av/media/extractors/mkv",
+ ],
+
+ static_libs: [
+ "liblog",
+ "libstagefright_foundation",
+ "libmedia",
+ "libextractorfuzzerbase",
+ "libwebm",
+ "libstagefright_flacdec",
+ "libstagefright_metadatautils",
+ "libmkvextractor",
+ "libFLAC",
+ ],
+
+ shared_libs: [
+ "libutils",
+ "libmediandk",
+ "libbinder",
+ ],
+
+ dictionary: "mkv_extractor_fuzzer.dict",
+}
+
+cc_fuzz {
+ name: "ogg_extractor_fuzzer",
+
+ srcs: [
+ "ogg_extractor_fuzzer.cpp",
+ ],
+
+ include_dirs: [
+ "frameworks/av/media/extractors/ogg",
+ ],
+
+ static_libs: [
+ "liblog",
+ "libstagefright_foundation",
+ "libmedia",
+ "libextractorfuzzerbase",
+ "libstagefright_metadatautils",
+ "libvorbisidec",
+ "liboggextractor",
+ ],
+
+ shared_libs: [
+ "libutils",
+ "libmediandk",
+ "libbinder",
+ ],
+
+ dictionary: "ogg_extractor_fuzzer.dict",
+}
+
+cc_fuzz {
+ name: "mpeg2ps_extractor_fuzzer",
+
+ srcs: [
+ "mpeg2_extractor_fuzzer.cpp",
+ ],
+
+ include_dirs: [
+ "frameworks/av/media/extractors/mpeg2",
+ "frameworks/av/media/libstagefright",
+ ],
+
+ static_libs: [
+ "liblog",
+ "libstagefright_foundation_without_imemory",
+ "libmedia",
+ "libextractorfuzzerbase",
+ "libstagefright_mpeg2support",
+ "libstagefright_mpeg2extractor",
+ "libstagefright_esds",
+ "libmpeg2extractor",
+ ],
+
+ cflags: [
+ "-DMPEG2PS",
+ ],
+
+ shared_libs: [
+ "libutils",
+ "libmediandk",
+ "libbinder",
+ "android.hardware.cas@1.0",
+ "android.hardware.cas.native@1.0",
+ "android.hidl.token@1.0-utils",
+ "android.hidl.allocator@1.0",
+ "libcrypto",
+ "libhidlmemory",
+ "libhidlbase",
+ ],
+
+ dictionary: "mpeg2ps_extractor_fuzzer.dict",
+}
+
+cc_fuzz {
+ name: "mpeg2ts_extractor_fuzzer",
+
+ srcs: [
+ "mpeg2_extractor_fuzzer.cpp",
+ ],
+
+ include_dirs: [
+ "frameworks/av/media/extractors/mpeg2",
+ "frameworks/av/media/libstagefright",
+ ],
+
+ static_libs: [
+ "liblog",
+ "libstagefright_foundation_without_imemory",
+ "libmedia",
+ "libextractorfuzzerbase",
+ "libstagefright_mpeg2support",
+ "libstagefright_mpeg2extractor",
+ "libstagefright_esds",
+ "libmpeg2extractor",
+ ],
+
+ shared_libs: [
+ "libutils",
+ "libmediandk",
+ "libbinder",
+ "android.hardware.cas@1.0",
+ "android.hardware.cas.native@1.0",
+ "android.hidl.token@1.0-utils",
+ "android.hidl.allocator@1.0",
+ "libcrypto",
+ "libhidlmemory",
+ "libhidlbase",
+ ],
+
+ dictionary: "mpeg2ts_extractor_fuzzer.dict",
+}
+
+cc_fuzz {
+ name: "mp3_extractor_fuzzer",
+
+ srcs: [
+ "mp3_extractor_fuzzer.cpp",
+ ],
+
+ include_dirs: [
+ "frameworks/av/media/extractors/mp3",
+ ],
+
+ static_libs: [
+ "liblog",
+ "libstagefright_foundation",
+ "libmedia",
+ "libextractorfuzzerbase",
+ "libfifo",
+ "libmp3extractor",
+ "libstagefright_id3",
+ ],
+
+ shared_libs: [
+ "libutils",
+ "libmediandk",
+ "libbinder",
+ ],
+}
+
+cc_fuzz {
+ name: "aac_extractor_fuzzer",
+
+ srcs: [
+ "aac_extractor_fuzzer.cpp",
+ ],
+
+ include_dirs: [
+ "frameworks/av/media/extractors/aac",
+ ],
+
+ static_libs: [
+ "liblog",
+ "libstagefright_foundation",
+ "libmedia",
+ "libextractorfuzzerbase",
+ "libaacextractor",
+ "libstagefright_metadatautils",
+ ],
+
+ shared_libs: [
+ "libutils",
+ "libmediandk",
+ "libbinder",
+ ],
+}
+
+cc_fuzz {
+ name: "flac_extractor_fuzzer",
+
+ srcs: [
+ "flac_extractor_fuzzer.cpp",
+ ],
+
+ include_dirs: [
+ "frameworks/av/media/extractors/flac",
+ ],
+
+ static_libs: [
+ "liblog",
+ "libstagefright_foundation",
+ "libmedia",
+ "libextractorfuzzerbase",
+ "libstagefright_metadatautils",
+ "libFLAC",
+ "libflacextractor",
+ ],
+
+ shared_libs: [
+ "libutils",
+ "libmediandk",
+ "libbinder",
+ "libbinder_ndk",
+ "libbase",
+ ],
+
+ dictionary: "flac_extractor_fuzzer.dict",
+}
diff --git a/media/extractors/fuzzers/ExtractorFuzzerBase.cpp b/media/extractors/fuzzers/ExtractorFuzzerBase.cpp
new file mode 100644
index 0000000..cbd6395
--- /dev/null
+++ b/media/extractors/fuzzers/ExtractorFuzzerBase.cpp
@@ -0,0 +1,118 @@
+/*
+ * 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 "ExtractorFuzzerBase"
+#include <utils/Log.h>
+
+#include "ExtractorFuzzerBase.h"
+
+using namespace android;
+
+bool ExtractorFuzzerBase::setDataSource(const uint8_t* data, size_t size) {
+ if ((!data) || (size == 0)) {
+ return false;
+ }
+ mBufferSource = new BufferSource(data, size);
+ mDataSource = reinterpret_cast<DataSource*>(mBufferSource.get());
+ if (!mDataSource) {
+ return false;
+ }
+ return true;
+}
+
+bool ExtractorFuzzerBase::getExtractorDef() {
+ float confidence;
+ void* meta = nullptr;
+ FreeMetaFunc freeMeta = nullptr;
+
+ ExtractorDef extractorDef = GETEXTRACTORDEF();
+ if (extractorDef.def_version == EXTRACTORDEF_VERSION_NDK_V1) {
+ extractorDef.u.v2.sniff(mDataSource->wrap(), &confidence, &meta, &freeMeta);
+ } else if (extractorDef.def_version == EXTRACTORDEF_VERSION_NDK_V2) {
+ extractorDef.u.v3.sniff(mDataSource->wrap(), &confidence, &meta, &freeMeta);
+ }
+
+ if (meta != nullptr && freeMeta != nullptr) {
+ freeMeta(meta);
+ }
+
+ return true;
+}
+
+bool ExtractorFuzzerBase::extractTracks() {
+ MediaBufferGroup* bufferGroup = new MediaBufferGroup();
+ if (!bufferGroup) {
+ return false;
+ }
+ for (size_t trackIndex = 0; trackIndex < mExtractor->countTracks(); ++trackIndex) {
+ MediaTrackHelper* track = mExtractor->getTrack(trackIndex);
+ if (!track) {
+ continue;
+ }
+ extractTrack(track, bufferGroup);
+ delete track;
+ }
+ delete bufferGroup;
+ return true;
+}
+
+void ExtractorFuzzerBase::extractTrack(MediaTrackHelper* track, MediaBufferGroup* bufferGroup) {
+ CMediaTrack* cTrack = wrap(track);
+ if (!cTrack) {
+ return;
+ }
+
+ media_status_t status = cTrack->start(track, bufferGroup->wrap());
+ if (status != AMEDIA_OK) {
+ free(cTrack);
+ return;
+ }
+
+ do {
+ MediaBufferHelper* buffer = nullptr;
+ status = track->read(&buffer);
+ if (buffer) {
+ buffer->release();
+ }
+ } while (status == AMEDIA_OK);
+
+ cTrack->stop(track);
+ free(cTrack);
+}
+
+bool ExtractorFuzzerBase::getTracksMetadata() {
+ AMediaFormat* format = AMediaFormat_new();
+ uint32_t flags = MediaExtractorPluginHelper::kIncludeExtensiveMetaData;
+
+ for (size_t trackIndex = 0; trackIndex < mExtractor->countTracks(); ++trackIndex) {
+ mExtractor->getTrackMetaData(format, trackIndex, flags);
+ }
+
+ AMediaFormat_delete(format);
+ return true;
+}
+
+bool ExtractorFuzzerBase::getMetadata() {
+ AMediaFormat* format = AMediaFormat_new();
+ mExtractor->getMetaData(format);
+ AMediaFormat_delete(format);
+ return true;
+}
+
+void ExtractorFuzzerBase::setDataSourceFlags(uint32_t flags) {
+ mBufferSource->setFlags(flags);
+}
diff --git a/media/extractors/fuzzers/README.md b/media/extractors/fuzzers/README.md
new file mode 100644
index 0000000..4223b5e
--- /dev/null
+++ b/media/extractors/fuzzers/README.md
@@ -0,0 +1,326 @@
+# Fuzzer for extractors
+
+## Table of contents
++ [libextractorfuzzerbase](#ExtractorFuzzerBase)
++ [libmp4extractor](#mp4ExtractorFuzzer)
++ [libwavextractor](#wavExtractorFuzzer)
++ [libamrextractor](#amrExtractorFuzzer)
++ [libmkvextractor](#mkvExtractorFuzzer)
++ [liboggextractor](#oggExtractorFuzzer)
++ [libmpeg2extractor](#mpeg2ExtractorFuzzer)
++ [libmp3extractor](#mp3ExtractorFuzzer)
++ [libaacextractor](#aacExtractorFuzzer)
++ [libflacextractor](#flacExtractor)
+
+# <a name="ExtractorFuzzerBase"></a> Fuzzer for libextractorfuzzerbase
+All the extractors have a common API - creating a data source, extraction
+of all the tracks, etc. These common APIs have been abstracted in a base class
+called `ExtractorFuzzerBase` to ensure code is reused between fuzzer plugins.
+
+Additionally, `ExtractorFuzzerBase` also has support for memory based buffer
+`BufferSource` since the fuzzing engine feeds data using memory buffers and
+usage of standard data source objects like FileSource, HTTPSource, etc. is
+not feasible.
+
+# <a name="mp4ExtractorFuzzer"></a> Fuzzer for libmp4extractor
+
+## Plugin Design Considerations
+The fuzzer plugin for MP4 extractor uses the `ExtractorFuzzerBase` class and
+implements only the `createExtractor` to create the MP4 extractor class.
+
+##### Maximize code coverage
+Dict file (dictionary file) is created for MP4 to ensure that the required MP4
+atoms are present in every input file that goes to the fuzzer.
+This ensures that larger code gets covered as a range of MP4 atoms will be
+present in the input data.
+
+
+## Build
+
+This describes steps to build mp4_extractor_fuzzer binary.
+
+### Android
+
+#### Steps to build
+Build the fuzzer
+```
+ $ mm -j$(nproc) mp4_extractor_fuzzer
+```
+
+#### Steps to run
+Create a directory CORPUS_DIR and copy some MP4 files to that folder
+Push this directory to device.
+
+To run on device
+```
+ $ adb sync data
+ $ adb shell /data/fuzz/arm64/mp4_extractor_fuzzer/mp4_extractor_fuzzer CORPUS_DIR
+```
+
+# <a name="wavExtractorFuzzer"></a> Fuzzer for libwavextractor
+
+## Plugin Design Considerations
+The fuzzer plugin for WAV extractor uses the `ExtractorFuzzerBase` class and
+implements only the `createExtractor` to create the WAV extractor class.
+
+
+## Build
+
+This describes steps to build wav_extractor_fuzzer binary.
+
+### Android
+
+#### Steps to build
+Build the fuzzer
+```
+ $ mm -j$(nproc) wav_extractor_fuzzer
+```
+
+#### Steps to run
+Create a directory CORPUS_DIR and copy some wav files to that folder
+Push this directory to device.
+
+To run on device
+```
+ $ adb sync data
+ $ adb shell /data/fuzz/arm64/wav_extractor_fuzzer/wav_extractor_fuzzer CORPUS_DIR
+```
+
+# <a name="amrExtractorFuzzer"></a> Fuzzer for libamrextractor
+
+## Plugin Design Considerations
+The fuzzer plugin for AMR extractor uses the `ExtractorFuzzerBase` class and
+implements only the `createExtractor` to create the AMR extractor class.
+
+##### Maximize code coverage
+Dict file (dictionary file) is created for AMR to ensure that the required start
+bytes are present in every input file that goes to the fuzzer.
+This ensures that larger code gets covered.
+
+
+## Build
+
+This describes steps to build amr_extractor_fuzzer binary.
+
+### Android
+
+#### Steps to build
+Build the fuzzer
+```
+ $ mm -j$(nproc) amr_extractor_fuzzer
+```
+
+#### Steps to run
+Create a directory CORPUS_DIR and copy some AMR files to that folder
+Push this directory to device.
+
+To run on device
+```
+ $ adb sync data
+ $ adb shell /data/fuzz/arm64/amr_extractor_fuzzer/amr_extractor_fuzzer CORPUS_DIR
+```
+
+# <a name="mkvExtractorFuzzer"></a> Fuzzer for libmkvextractor
+
+## Plugin Design Considerations
+The fuzzer plugin for MKV extractor uses the `ExtractorFuzzerBase` class and
+implements only the `createExtractor` to create the MKV extractor class.
+
+##### Maximize code coverage
+Dict file (dictionary file) is created for MKV to ensure that the required element
+ID's are present in every input file that goes to the fuzzer.
+This ensures that larger code gets covered.
+
+
+## Build
+
+This describes steps to build mkv_extractor_fuzzer binary.
+
+### Android
+
+#### Steps to build
+Build the fuzzer
+```
+ $ mm -j$(nproc) mkv_extractor_fuzzer
+```
+
+#### Steps to run
+Create a directory CORPUS_DIR and copy some mkv files to that folder.
+Push this directory to device.
+
+To run on device
+```
+ $ adb sync data
+ $ adb shell /data/fuzz/arm64/mkv_extractor_fuzzer/mkv_extractor_fuzzer CORPUS_DIR
+```
+
+# <a name="oggExtractorFuzzer"></a> Fuzzer for liboggextractor
+
+## Plugin Design Considerations
+The fuzzer plugin for OGG extractor uses the `ExtractorFuzzerBase` class and
+implements only the `createExtractor` to create the OGG extractor object.
+
+##### Maximize code coverage
+Dict file (dictionary file) is created for OGG to ensure that the required start
+bytes are present in every input file that goes to the fuzzer.
+This ensures that larger code gets covered.
+
+
+## Build
+
+This describes steps to build ogg_extractor_fuzzer binary.
+
+### Android
+
+#### Steps to build
+Build the fuzzer
+```
+ $ mm -j$(nproc) ogg_extractor_fuzzer
+```
+
+#### Steps to run
+Create a directory CORPUS_DIR and copy some ogg files to that folder.
+Push this directory to device.
+
+To run on device
+```
+ $ adb sync data
+ $ adb shell /data/fuzz/arm64/ogg_extractor_fuzzer/ogg_extractor_fuzzer CORPUS_DIR
+```
+
+# <a name="mpeg2ExtractorFuzzer"></a> Fuzzer for libmpeg2extractor
+
+## Plugin Design Considerations
+The fuzzer plugins for MPEG2-PS and MPEG2-TS extractor use the `ExtractorFuzzerBase` class and
+implement only the `createExtractor` to create the MPEG2-PS or MPEG2-TS extractor
+object respectively.
+
+##### Maximize code coverage
+Dict files (dictionary files) are created for MPEG2-PS and MPEG2-TS to ensure that the
+required start bytes are present in every input file that goes to the fuzzer.
+This ensures that larger code gets covered.
+
+##### Other considerations
+Two fuzzer binaries - mpeg2ps_extractor_fuzzer and mpeg2ts_extractor_fuzzer are
+generated based on the presence of a flag - `MPEG2PS`
+
+
+## Build
+
+This describes steps to build mpeg2ps_extractor_fuzzer and mpeg2ts_extractor_fuzzer binary.
+
+### Android
+
+#### Steps to build
+Build the fuzzer
+```
+ $ mm -j$(nproc) mpeg2ps_extractor_fuzzer
+ $ mm -j$(nproc) mpeg2ts_extractor_fuzzer
+```
+
+#### Steps to run
+Create a directory CORPUS_DIR and copy some mpeg2 files to that folder
+Push this directory to device.
+
+To run on device
+```
+ $ adb sync data
+ $ adb shell /data/fuzz/arm64/mpeg2ps_extractor_fuzzer/mpeg2ps_extractor_fuzzer CORPUS_DIR
+ $ adb shell /data/fuzz/arm64/mpeg2ts_extractor_fuzzer/mpeg2ts_extractor_fuzzer CORPUS_DIR
+```
+
+# <a name="mp3ExtractorFuzzer"></a> Fuzzer for libmp3extractor
+
+## Plugin Design Considerations
+The fuzzer plugin for MP3 extractor uses the `ExtractorFuzzerBase` class and
+implements only the `createExtractor` to create the MP3 extractor class.
+
+
+## Build
+
+This describes steps to build mp3_extractor_fuzzer binary.
+
+### Android
+
+#### Steps to build
+Build the fuzzer
+```
+ $ mm -j$(nproc) mp3_extractor_fuzzer
+```
+
+#### Steps to run
+Create a directory CORPUS_DIR and copy some mp3 files to that folder
+Push this directory to device.
+
+To run on device
+```
+ $ adb sync data
+ $ adb shell /data/fuzz/arm64/mp3_extractor_fuzzer/mp3_extractor_fuzzer CORPUS_DIR
+```
+
+# <a name="aacExtractorFuzzer"></a> Fuzzer for libaacextractor
+
+## Plugin Design Considerations
+The fuzzer plugin for AAC extractor uses the `ExtractorFuzzerBase` class and
+implements only the `createExtractor` to create the AAC extractor class.
+
+
+## Build
+
+This describes steps to build aac_extractor_fuzzer binary.
+
+### Android
+
+#### Steps to build
+Build the fuzzer
+```
+ $ mm -j$(nproc) aac_extractor_fuzzer
+```
+
+#### Steps to run
+Create a directory CORPUS_DIR and copy some aac files to that folder
+Push this directory to device.
+
+To run on device
+```
+ $ adb sync data
+ $ adb shell /data/fuzz/arm64/aac_extractor_fuzzer/aac_extractor_fuzzer CORPUS_DIR
+```
+
+# <a name="flacExtractor"></a> Fuzzer for libflacextractor
+
+## Plugin Design Considerations
+The fuzzer plugin for FLAC extractor uses the `ExtractorFuzzerBase` class and
+implements only the `createExtractor` to create the FLAC extractor object.
+
+##### Maximize code coverage
+Dict file (dictionary file) is created for FLAC to ensure that the required start
+bytes are present in every input file that goes to the fuzzer.
+This ensures that larger code gets covered.
+
+
+## Build
+
+This describes steps to build flac_extractor_fuzzer binary.
+
+### Android
+
+#### Steps to build
+Build the fuzzer
+```
+ $ mm -j$(nproc) flac_extractor_fuzzer
+```
+
+#### Steps to run
+Create a directory CORPUS_DIR and copy some flac files to that folder
+Push this directory to device.
+
+To run on device
+```
+ $ adb sync data
+ $ adb shell /data/fuzz/arm64/flac_extractor_fuzzer/flac_extractor_fuzzer CORPUS_DIR
+```
+
+## References:
+ * http://llvm.org/docs/LibFuzzer.html
+ * https://github.com/google/oss-fuzz
diff --git a/media/extractors/fuzzers/aac_extractor_fuzzer.cpp b/media/extractors/fuzzers/aac_extractor_fuzzer.cpp
new file mode 100644
index 0000000..93665f0
--- /dev/null
+++ b/media/extractors/fuzzers/aac_extractor_fuzzer.cpp
@@ -0,0 +1,62 @@
+/******************************************************************************
+ *
+ * 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.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+#include "AACExtractor.h"
+
+#include "ExtractorFuzzerBase.h"
+
+using namespace android;
+
+class AacExtractor : public ExtractorFuzzerBase {
+ public:
+ AacExtractor() = default;
+ ~AacExtractor() = default;
+
+ bool createExtractor();
+};
+
+bool AacExtractor::createExtractor() {
+ mExtractor = new AACExtractor(new DataSourceHelper(mDataSource->wrap()), 0);
+ if (!mExtractor) {
+ return false;
+ }
+ mExtractor->name();
+ return true;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ if ((!data) || (size == 0)) {
+ return 0;
+ }
+ AacExtractor* extractor = new AacExtractor();
+ if (!extractor) {
+ return 0;
+ }
+ if (extractor->setDataSource(data, size)) {
+ if (extractor->createExtractor()) {
+ extractor->getExtractorDef();
+ extractor->getMetadata();
+ extractor->extractTracks();
+ extractor->getTracksMetadata();
+ }
+ }
+ delete extractor;
+ return 0;
+}
diff --git a/media/extractors/fuzzers/amr_extractor_fuzzer.cpp b/media/extractors/fuzzers/amr_extractor_fuzzer.cpp
new file mode 100644
index 0000000..b2f9261
--- /dev/null
+++ b/media/extractors/fuzzers/amr_extractor_fuzzer.cpp
@@ -0,0 +1,62 @@
+/******************************************************************************
+ *
+ * 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.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+#include "ExtractorFuzzerBase.h"
+
+#include "AMRExtractor.h"
+
+using namespace android;
+
+class AmrExtractor : public ExtractorFuzzerBase {
+ public:
+ AmrExtractor() = default;
+ ~AmrExtractor() = default;
+
+ bool createExtractor();
+};
+
+bool AmrExtractor::createExtractor() {
+ mExtractor = new AMRExtractor(new DataSourceHelper(mDataSource->wrap()));
+ if (!mExtractor) {
+ return false;
+ }
+ mExtractor->name();
+ return true;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ if ((!data) || (size == 0)) {
+ return 0;
+ }
+ AmrExtractor* extractor = new AmrExtractor();
+ if (!extractor) {
+ return 0;
+ }
+ if (extractor->setDataSource(data, size)) {
+ if (extractor->createExtractor()) {
+ extractor->getExtractorDef();
+ extractor->getMetadata();
+ extractor->extractTracks();
+ extractor->getTracksMetadata();
+ }
+ }
+ delete extractor;
+ return 0;
+}
diff --git a/media/extractors/fuzzers/amr_extractor_fuzzer.dict b/media/extractors/fuzzers/amr_extractor_fuzzer.dict
new file mode 100644
index 0000000..bc5726c
--- /dev/null
+++ b/media/extractors/fuzzers/amr_extractor_fuzzer.dict
@@ -0,0 +1,2 @@
+# Start code
+kw1="#!AMR"
diff --git a/media/extractors/fuzzers/flac_extractor_fuzzer.cpp b/media/extractors/fuzzers/flac_extractor_fuzzer.cpp
new file mode 100644
index 0000000..61e41cf
--- /dev/null
+++ b/media/extractors/fuzzers/flac_extractor_fuzzer.cpp
@@ -0,0 +1,62 @@
+/******************************************************************************
+ *
+ * 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.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+#include "ExtractorFuzzerBase.h"
+
+#include "FLACExtractor.h"
+
+using namespace android;
+
+class FlacExtractor : public ExtractorFuzzerBase {
+ public:
+ FlacExtractor() = default;
+ ~FlacExtractor() = default;
+
+ bool createExtractor();
+};
+
+bool FlacExtractor::createExtractor() {
+ mExtractor = new FLACExtractor(new DataSourceHelper(mDataSource->wrap()));
+ if (!mExtractor) {
+ return false;
+ }
+ mExtractor->name();
+ return true;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ if ((!data) || (size == 0)) {
+ return 0;
+ }
+ FlacExtractor* extractor = new FlacExtractor();
+ if (!extractor) {
+ return 0;
+ }
+ if (extractor->setDataSource(data, size)) {
+ if (extractor->createExtractor()) {
+ extractor->getExtractorDef();
+ extractor->getMetadata();
+ extractor->extractTracks();
+ extractor->getTracksMetadata();
+ }
+ }
+ delete extractor;
+ return 0;
+}
diff --git a/media/extractors/fuzzers/flac_extractor_fuzzer.dict b/media/extractors/fuzzers/flac_extractor_fuzzer.dict
new file mode 100644
index 0000000..53ad44f
--- /dev/null
+++ b/media/extractors/fuzzers/flac_extractor_fuzzer.dict
@@ -0,0 +1,3 @@
+# Start code (bytes 0-3)
+# The below 4 bytes correspond to "fLaC" in ASCII
+kw1="\x66\x4C\x61\x43"
diff --git a/media/extractors/fuzzers/include/ExtractorFuzzerBase.h b/media/extractors/fuzzers/include/ExtractorFuzzerBase.h
new file mode 100644
index 0000000..abf362b
--- /dev/null
+++ b/media/extractors/fuzzers/include/ExtractorFuzzerBase.h
@@ -0,0 +1,130 @@
+/******************************************************************************
+ *
+ * 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.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+#ifndef __EXTRACTOR_FUZZER_BASE_H__
+#define __EXTRACTOR_FUZZER_BASE_H__
+
+#include <media/DataSource.h>
+#include <media/MediaExtractorPluginHelper.h>
+#include <media/stagefright/MediaBufferGroup.h>
+
+extern "C" {
+android::ExtractorDef GETEXTRACTORDEF();
+}
+
+namespace android {
+
+class ExtractorFuzzerBase {
+ public:
+ ExtractorFuzzerBase() = default;
+ virtual ~ExtractorFuzzerBase() {
+ if (mExtractor) {
+ delete mExtractor;
+ mExtractor = nullptr;
+ }
+ if (mBufferSource) {
+ mBufferSource.clear();
+ mBufferSource = nullptr;
+ }
+ }
+
+ /** Function to create the media extractor component.
+ * To be implemented by the derived class.
+ */
+ virtual bool createExtractor() = 0;
+
+ /** Parent class functions to be reused by derived class.
+ * These are common for all media extractor components.
+ */
+ bool setDataSource(const uint8_t* data, size_t size);
+
+ bool getExtractorDef();
+
+ bool extractTracks();
+
+ bool getMetadata();
+
+ bool getTracksMetadata();
+
+ void setDataSourceFlags(uint32_t flags);
+
+ protected:
+ class BufferSource : public DataSource {
+ public:
+ BufferSource(const uint8_t* data, size_t length) : mData(data), mLength(length) {}
+ virtual ~BufferSource() { mData = nullptr; }
+
+ void setFlags(uint32_t flags) { mFlags = flags; }
+
+ uint32_t flags() { return mFlags; }
+
+ status_t initCheck() const { return mData != nullptr ? OK : NO_INIT; }
+
+ ssize_t readAt(off64_t offset, void* data, size_t size) {
+ if (!mData) {
+ return NO_INIT;
+ }
+
+ Mutex::Autolock autoLock(mLock);
+ if ((offset >= static_cast<off64_t>(mLength)) || (offset < 0)) {
+ return 0; // read beyond bounds.
+ }
+ size_t numAvailable = mLength - static_cast<size_t>(offset);
+ if (size > numAvailable) {
+ size = numAvailable;
+ }
+ return readAt_l(offset, data, size);
+ }
+
+ status_t getSize(off64_t* size) {
+ if (!mData) {
+ return NO_INIT;
+ }
+
+ Mutex::Autolock autoLock(mLock);
+ *size = static_cast<off64_t>(mLength);
+ return OK;
+ }
+
+ protected:
+ ssize_t readAt_l(off64_t offset, void* data, size_t size) {
+ void* result = memcpy(data, mData + offset, size);
+ return result != nullptr ? size : 0;
+ }
+
+ const uint8_t* mData = nullptr;
+ size_t mLength = 0;
+ Mutex mLock;
+ uint32_t mFlags = 0;
+
+ private:
+ DISALLOW_EVIL_CONSTRUCTORS(BufferSource);
+ };
+
+ sp<BufferSource> mBufferSource;
+ DataSource* mDataSource = nullptr;
+ MediaExtractorPluginHelper* mExtractor = nullptr;
+
+ virtual void extractTrack(MediaTrackHelper* track, MediaBufferGroup* bufferGroup);
+};
+
+} // namespace android
+
+#endif // __EXTRACTOR_FUZZER_BASE_H__
diff --git a/media/extractors/fuzzers/mkv_extractor_fuzzer.cpp b/media/extractors/fuzzers/mkv_extractor_fuzzer.cpp
new file mode 100644
index 0000000..14274b7
--- /dev/null
+++ b/media/extractors/fuzzers/mkv_extractor_fuzzer.cpp
@@ -0,0 +1,62 @@
+/******************************************************************************
+ *
+ * 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.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+#include "ExtractorFuzzerBase.h"
+
+#include "MatroskaExtractor.h"
+
+using namespace android;
+
+class MKVExtractor : public ExtractorFuzzerBase {
+ public:
+ MKVExtractor() = default;
+ ~MKVExtractor() = default;
+
+ bool createExtractor();
+};
+
+bool MKVExtractor::createExtractor() {
+ mExtractor = new MatroskaExtractor(new DataSourceHelper(mDataSource->wrap()));
+ if (!mExtractor) {
+ return false;
+ }
+ mExtractor->name();
+ return true;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ if ((!data) || (size == 0)) {
+ return 0;
+ }
+ MKVExtractor* extractor = new MKVExtractor();
+ if (!extractor) {
+ return 0;
+ }
+ if (extractor->setDataSource(data, size)) {
+ if (extractor->createExtractor()) {
+ extractor->getExtractorDef();
+ extractor->getMetadata();
+ extractor->extractTracks();
+ extractor->getTracksMetadata();
+ }
+ }
+ delete extractor;
+ return 0;
+}
diff --git a/media/extractors/fuzzers/mkv_extractor_fuzzer.dict b/media/extractors/fuzzers/mkv_extractor_fuzzer.dict
new file mode 100644
index 0000000..b3815dc
--- /dev/null
+++ b/media/extractors/fuzzers/mkv_extractor_fuzzer.dict
@@ -0,0 +1,244 @@
+# Elements ID's
+kw1="\x42\x86"
+kw2="\x42\xF7"
+kw3="\x42\xF2"
+kw4="\x42\xF3"
+kw5="\x42\x87"
+kw6="\x42\x85"
+kw7="\x18\x53\x80\x67"
+kw8="\x11\x4D\x9B\x74"
+kw9="\x4D\xBB"
+kw10="\x53\xAB"
+kw11="\x53\xAC"
+kw12="\x15\x49\xA9\x66"
+kw13="\x73\xA4"
+kw14="\x73\x84"
+kw15="\x3C\xB9\x23"
+kw16="\x3C\x83\xAB"
+kw17="\x3C\xB9\x23"
+kw18="\x3E\x83\xBB"
+kw19="\x44\x44"
+kw20="\x69\x24"
+kw21="\x69\xFC"
+kw22="\x69\xBF"
+kw23="\x69\xA5"
+kw24="\x2A\xD7\xB1"
+kw25="\x44\x89"
+kw26="\x44\x61"
+kw27="\x7B\xA9"
+kw28="\x4D\x80"
+kw29="\x57\x41"
+kw30="\x1F\x43\xB6\x75"
+kw31="\xE7"
+kw32="\x58\x54"
+kw33="\x58\xD7"
+kw34="\xA7"
+kw35="\xAB"
+kw36="\xA3"
+kw37="\xA0"
+kw38="\xA1"
+kw39="\xA2"
+kw40="\x75\xA1"
+kw41="\x2A\xD7\xB1"
+kw42="\xA6"
+kw43="\xEE"
+kw44="\xA5"
+kw45="\x9A"
+kw46="\xFA"
+kw47="\xFB"
+kw48="\xFD"
+kw49="\xA4"
+kw50="\x75\xA2"
+kw51="\x8E"
+kw52="\xE8"
+kw53="\xCC"
+kw54="\xCD"
+kw55="\xCB"
+kw56="\xCE"
+kw57="\xCF"
+kw58="\xC8"
+kw59="\xC9"
+kw60="\xCA"
+kw61="\xAF"
+kw62="\x16\x54\xAE\x6B"
+kw63="\xAE"
+kw64="\xD7"
+kw65="\x73\xC5"
+kw66="\x83"
+kw67="\xB9"
+kw68="\x88"
+kw69="\x55\xAA"
+kw70="\x9C"
+kw71="\x6D\xE7"
+kw72="\x6D\xF8"
+kw73="\x23\xE3\x83"
+kw74="\x23\x4E\x7A"
+kw75="\x23\x31\x4F"
+kw76="\x53\x7F"
+kw77="\x55\xEE"
+kw78="\x53\x6E"
+kw79="\x22\xB5\x9C"
+kw80="\x22\xB5\x9D"
+kw81="\x86"
+kw82="\x63\xA2"
+kw83="\x25\x86\x88"
+kw84="\x26\xB2\x40"
+kw85="\xAA"
+kw86="\x6F\xAB"
+kw87="\x56\xAA"
+kw88="\x56\xBB"
+kw89="\x66\x24"
+kw90="\x66\xFC"
+kw91="\x66\xBF"
+kw92="\xE0"
+kw93="\x9A"
+kw94="\x9D"
+kw95="\x53\xB8"
+kw96="\x53\xC0"
+kw97="\x53\xB9"
+kw98="\xB0"
+kw99="\xBA"
+kw100="\x54\xAA"
+kw101="\x54\xBB"
+kw102="\x54\xCC"
+kw103="\x54\xDD"
+kw104="\x54\xB0"
+kw105="\x54\xBA"
+kw106="\x54\xB2"
+kw107="\x54\xB3"
+kw108="\x2E\xB5\x24"
+kw109="\x2F\xB5\x23"
+kw110="\x23\x83\xE3"
+kw111="\x55\xB0"
+kw112="\x55\xB1"
+kw113="\x55\xB2"
+kw114="\x55\xB3"
+kw115="\x55\xB4"
+kw116="\x55\xB5"
+kw117="\x55\xB6"
+kw118="\x55\xB7"
+kw119="\x55\xB8"
+kw120="\x55\xB9"
+kw121="\x55\xBA"
+kw122="\x55\xBB"
+kw123="\x55\xBC"
+kw124="\x55\xBD"
+kw125="\x55\xD0"
+kw126="\x55\xD1"
+kw127="\x55\xD2"
+kw128="\x55\xD3"
+kw129="\x55\xD4"
+kw130="\x55\xD5"
+kw131="\x55\xD6"
+kw132="\x55\xD7"
+kw133="\x55\xD8"
+kw134="\x55\xD9"
+kw135="\x55\xDA"
+kw136="\x76\x70"
+kw137="\x76\x71"
+kw138="\x76\x72"
+kw139="\x76\x73"
+kw140="\x76\x74"
+kw141="\x76\x75"
+kw142="\xE1"
+kw143="\xB5"
+kw144="\x78\xB5"
+kw145="\x9F"
+kw146="\x7D\x7B"
+kw147="\x62\x64"
+kw148="\xE2"
+kw149="\xE3"
+kw150="\xE4"
+kw151="\xE5"
+kw152="\xE6"
+kw153="\xE9"
+kw154="\xED"
+kw155="\xC0"
+kw156="\xC1"
+kw157="\xC6"
+kw158="\xC7"
+kw159="\xC4"
+kw160="\x6D\x80"
+kw161="\x62\x40"
+kw162="\x50\x31"
+kw163="\x50\x32"
+kw164="\x50\x33"
+kw165="\x50\x34"
+kw166="\x50\x35"
+kw167="\x42\x54"
+kw168="\x42\x55"
+kw169="\x47\xE1"
+kw170="\x47\xE2"
+kw171="\x47\xE7"
+kw172="\x47\xE8"
+kw173="\x47\xE3"
+kw174="\x47\xE4"
+kw175="\x47\xE5"
+kw176="\x47\xE6"
+kw177="\x1C\x53\xBB\x6B"
+kw178="\xBB"
+kw179="\xB3"
+kw180="\xB7"
+kw181="\xF7"
+kw182="\xF1"
+kw183="\xF0"
+kw184="\xB2"
+kw185="\x53\x78"
+kw186="\xEA"
+kw187="\xDB"
+kw188="\x96"
+kw189="\x97"
+kw190="\x53\x5F"
+kw191="\xEB"
+kw192="\x19\x41\xA4\x69"
+kw193="\x46\x7E"
+kw194="\x46\x6E"
+kw195="\x46\x60"
+kw196="\x46\x5C"
+kw197="\x46\xAE"
+kw198="\x46\x75"
+kw199="\x46\x61"
+kw200="\x46\x62"
+kw201="\x10\x43\xA7\x70"
+kw202="\x45\xB9"
+kw203="\x45\xBC"
+kw204="\x45\xBD"
+kw205="\x45\xDB"
+kw206="\x45\xDD"
+kw207="\xB6"
+kw208="\x73\xC4"
+kw209="\x56\x54"
+kw210="\x91"
+kw211="\x92"
+kw212="\x98"
+kw213="\x45\x98"
+kw214="\x6E\x67"
+kw215="\x6E\xBC"
+kw216="\x63\xC3"
+kw217="\x8F"
+kw218="\x89"
+kw219="\x80"
+kw220="\x85"
+kw221="\x43\x7C"
+kw222="\x43\x7D"
+kw223="\x43\x7E"
+kw224="\x69\x44"
+kw225="\x69\x55"
+kw226="\x45\x0D"
+kw227="\x69\x11"
+kw228="\x69\x22"
+kw229="\x69\x33"
+kw230="\x12\x54\xC3\x67"
+kw231="\x73\x73"
+kw232="\x63\xC0"
+kw233="\x68\xCA"
+kw234="\x63\xCA"
+kw235="\x63\xC5"
+kw236="\x63\xC9"
+kw237="\x67\xC8"
+kw238="\x45\xA3"
+kw239="\x44\x7A"
+kw240="\x44\x7B"
+kw241="\x44\x84"
+kw242="\x44\x87"
+kw243="\x44\x85"
diff --git a/media/extractors/fuzzers/mp3_extractor_fuzzer.cpp b/media/extractors/fuzzers/mp3_extractor_fuzzer.cpp
new file mode 100644
index 0000000..71c154b
--- /dev/null
+++ b/media/extractors/fuzzers/mp3_extractor_fuzzer.cpp
@@ -0,0 +1,62 @@
+/******************************************************************************
+ *
+ * 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.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+#include "ExtractorFuzzerBase.h"
+
+#include "MP3Extractor.h"
+
+using namespace android;
+
+class Mp3Extractor : public ExtractorFuzzerBase {
+ public:
+ Mp3Extractor() = default;
+ ~Mp3Extractor() = default;
+
+ bool createExtractor();
+};
+
+bool Mp3Extractor::createExtractor() {
+ mExtractor = new MP3Extractor(new DataSourceHelper(mDataSource->wrap()), nullptr);
+ if (!mExtractor) {
+ return false;
+ }
+ mExtractor->name();
+ return true;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ if ((!data) || (size == 0)) {
+ return 0;
+ }
+ Mp3Extractor* extractor = new Mp3Extractor();
+ if (!extractor) {
+ return 0;
+ }
+ if (extractor->setDataSource(data, size)) {
+ if (extractor->createExtractor()) {
+ extractor->getExtractorDef();
+ extractor->getMetadata();
+ extractor->extractTracks();
+ extractor->getTracksMetadata();
+ }
+ }
+ delete extractor;
+ return 0;
+}
diff --git a/media/extractors/fuzzers/mp4_extractor_fuzzer.cpp b/media/extractors/fuzzers/mp4_extractor_fuzzer.cpp
new file mode 100644
index 0000000..d2cc133
--- /dev/null
+++ b/media/extractors/fuzzers/mp4_extractor_fuzzer.cpp
@@ -0,0 +1,64 @@
+/******************************************************************************
+ *
+ * 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.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+#include "ExtractorFuzzerBase.h"
+
+#include "MPEG4Extractor.h"
+#include "SampleTable.h"
+
+using namespace android;
+
+class MP4Extractor : public ExtractorFuzzerBase {
+ public:
+ MP4Extractor() = default;
+ ~MP4Extractor() = default;
+
+ bool createExtractor();
+};
+
+bool MP4Extractor::createExtractor() {
+ mExtractor = new MPEG4Extractor(new DataSourceHelper(mDataSource->wrap()));
+ if (!mExtractor) {
+ return false;
+ }
+ mExtractor->name();
+ setDataSourceFlags(DataSourceBase::kWantsPrefetching | DataSourceBase::kIsCachingDataSource);
+ return true;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ if ((!data) || (size == 0)) {
+ return 0;
+ }
+ MP4Extractor* extractor = new MP4Extractor();
+ if (!extractor) {
+ return 0;
+ }
+ if (extractor->setDataSource(data, size)) {
+ if (extractor->createExtractor()) {
+ extractor->getExtractorDef();
+ extractor->getMetadata();
+ extractor->extractTracks();
+ extractor->getTracksMetadata();
+ }
+ }
+ delete extractor;
+ return 0;
+}
diff --git a/media/extractors/fuzzers/mp4_extractor_fuzzer.dict b/media/extractors/fuzzers/mp4_extractor_fuzzer.dict
new file mode 100644
index 0000000..3683649
--- /dev/null
+++ b/media/extractors/fuzzers/mp4_extractor_fuzzer.dict
@@ -0,0 +1,248 @@
+# MP4 Atoms/Boxes
+kw1="ftyp"
+kw2="free"
+kw3="mdat"
+kw4="moov"
+kw5="mvhd"
+kw6="trak"
+kw7="tkhd"
+kw8="edts"
+kw9="elst"
+kw10="mdia"
+kw11="mdhd"
+kw12="hdlr"
+kw13="minf"
+kw14="vmhd"
+kw15="dinf"
+kw16="dref"
+kw17="url "
+kw18="stbl"
+kw19="stsd"
+kw20="avc1"
+kw21="avcC"
+kw22="stts"
+kw23="stss"
+kw24="ctts"
+kw25="stsc"
+kw26="stsz"
+kw27="stco"
+kw28="mp4a"
+kw29="esds"
+kw30="udta"
+kw31="meta"
+kw32="ilst"
+kw33="samr"
+kw34="sawb"
+kw35="ec-3"
+kw36="mp4v"
+kw37="s263"
+kw38="h263"
+kw39="H263"
+kw40="avc1"
+kw41="hvc1"
+kw42="hev1"
+kw43="ac-4"
+kw44="Opus"
+kw45="twos"
+kw46="sowt"
+kw47="alac"
+kw48="fLaC"
+kw49="av01"
+kw50=".mp3"
+kw51="keys"
+kw52="cprt"
+kw53="covr"
+kw54="mvex"
+kw55="moof"
+kw56="traf"
+kw57="mfra"
+kw58="sinf"
+kw59="schi"
+kw60="wave"
+kw61="schm"
+kw62="cbc1"
+kw63="cbcs"
+kw64="cenc"
+kw65="cens"
+kw66="frma"
+kw67="tenc"
+kw68="tref"
+kw69="thmb"
+kw70="pssh"
+kw71="mett"
+kw72="enca"
+kw73="encv"
+kw74="co64"
+kw75="stz2"
+kw76="\xA9xyz"
+kw77="btrt"
+kw78="hvcC"
+kw79="av1C"
+kw80="d263"
+kw81="iloc"
+kw82="iinf"
+kw83="iprp"
+kw84="pitm"
+kw85="idat"
+kw86="iref"
+kw87="ipro"
+kw88="mean"
+kw89="name"
+kw90="data"
+kw91="mehd"
+kw92="text"
+kw93="sbtl"
+kw94="trex"
+kw95="tx3g"
+kw96="colr"
+kw97="titl"
+kw98="perf"
+kw99="auth"
+kw100="gnre"
+kw101="albm"
+kw102="yrrc"
+kw103="ID32"
+kw104="----"
+kw105="sidx"
+kw106="ac-3"
+kw107="qt "
+kw108="mif1"
+kw109="heic"
+kw110="dac4"
+kw111="dec3"
+kw112="dac3"
+kw113="\xA9alb"
+kw114="\xA9ART"
+kw115="aART"
+kw116="\xA9day"
+kw117="\xA9nam"
+kw118="\xA9wrt"
+kw119="\xA9gen"
+kw120="cpil"
+kw121="trkn"
+kw122="disk"
+kw123="nclx"
+kw124="nclc"
+kw125="tfhd"
+kw126="trun"
+kw127="saiz"
+kw128="saio"
+kw129="senc"
+kw130="isom"
+kw131="iso2"
+kw132="3gp4"
+kw133="mp41"
+kw134="mp42"
+kw135="dash"
+kw136="nvr1"
+kw137="MSNV"
+kw138="wmf "
+kw139="3g2a"
+kw140="3g2b"
+kw141="msf1"
+kw142="hevc"
+kw143="pdin"
+kw144="trgr"
+kw145="smhd"
+kw146="hmhd"
+kw147="nmhd"
+kw148="cslg"
+kw149="stsh"
+kw150="padb"
+kw151="stdp"
+kw152="sdtp"
+kw153="sbgp"
+kw154="sgpd"
+kw155="subs"
+kw156="leva"
+kw157="mfhd"
+kw158="tfdt"
+kw159="tfra"
+kw160="mfro"
+kw161="skip"
+kw162="tsel"
+kw163="strk"
+kw164="stri"
+kw165="strd"
+kw166="xml "
+kw167="bxml"
+kw168="fiin"
+kw169="paen"
+kw170="fire"
+kw171="fpar"
+kw172="fecr"
+kw173="segr"
+kw174="gitn"
+kw175="meco"
+kw176="mere"
+kw177="styp"
+kw178="ssix"
+kw179="prft"
+kw180="hint"
+kw181="cdsc"
+kw182="hind"
+kw183="vdep"
+kw184="vplx"
+kw185="msrc"
+kw186="urn "
+kw187="enct"
+kw188="encs"
+kw189="rinf"
+kw190="srpp"
+kw191="stsg"
+kw192="stvi"
+kw193="tims"
+kw194="tsro"
+kw195="snro"
+kw196="rtp "
+kw197="srtp"
+kw198="rtpo"
+kw199="hnti"
+kw200="sdp "
+kw201="trpy"
+kw202="nump"
+kw203="tpyl"
+kw204="totl"
+kw205="npck"
+kw206="tpay"
+kw207="maxr"
+kw208="dmed"
+kw209="dimm"
+kw210="drep"
+kw211="tmin"
+kw212="tmax"
+kw213="pmax"
+kw214="dmax"
+kw215="payt"
+kw216="fdp "
+kw217="fdsa"
+kw218="fdpa"
+kw219="extr"
+kw220="feci"
+kw221="rm2t"
+kw222="sm2t"
+kw223="tPAT"
+kw224="tPMT"
+kw225="tOD "
+kw226="tsti"
+kw227="istm"
+kw228="pm2t"
+kw229="rrtp"
+kw230="rssr"
+kw231="rscr"
+kw232="rsrp"
+kw233="rssr"
+kw234="ccid"
+kw235="sroc"
+kw236="prtp"
+kw237="roll"
+kw238="rash"
+kw239="alst"
+kw240="rap "
+kw241="tele"
+kw242="mp71"
+kw243="iso3"
+kw244="iso4"
+kw245="iso5"
+kw246="resv"
+kw247="iso6"
diff --git a/media/extractors/fuzzers/mpeg2_extractor_fuzzer.cpp b/media/extractors/fuzzers/mpeg2_extractor_fuzzer.cpp
new file mode 100644
index 0000000..c34ffa0
--- /dev/null
+++ b/media/extractors/fuzzers/mpeg2_extractor_fuzzer.cpp
@@ -0,0 +1,70 @@
+/******************************************************************************
+ *
+ * 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.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+#include "ExtractorFuzzerBase.h"
+
+#ifdef MPEG2PS
+#include "MPEG2PSExtractor.h"
+#else
+#include "MPEG2TSExtractor.h"
+#endif
+
+using namespace android;
+
+class MPEG2Extractor : public ExtractorFuzzerBase {
+ public:
+ MPEG2Extractor() = default;
+ ~MPEG2Extractor() = default;
+
+ bool createExtractor();
+};
+
+bool MPEG2Extractor::createExtractor() {
+#ifdef MPEG2PS
+ mExtractor = new MPEG2PSExtractor(new DataSourceHelper(mDataSource->wrap()));
+#else
+ mExtractor = new MPEG2TSExtractor(new DataSourceHelper(mDataSource->wrap()));
+#endif
+ if (!mExtractor) {
+ return false;
+ }
+ mExtractor->name();
+ return true;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ if ((!data) || (size == 0)) {
+ return 0;
+ }
+ MPEG2Extractor* extractor = new MPEG2Extractor();
+ if (!extractor) {
+ return 0;
+ }
+ if (extractor->setDataSource(data, size)) {
+ if (extractor->createExtractor()) {
+ extractor->getExtractorDef();
+ extractor->extractTracks();
+ extractor->extractTracks();
+ extractor->getTracksMetadata();
+ }
+ }
+ delete extractor;
+ return 0;
+}
diff --git a/media/extractors/fuzzers/mpeg2ps_extractor_fuzzer.dict b/media/extractors/fuzzers/mpeg2ps_extractor_fuzzer.dict
new file mode 100644
index 0000000..69d390a
--- /dev/null
+++ b/media/extractors/fuzzers/mpeg2ps_extractor_fuzzer.dict
@@ -0,0 +1,2 @@
+# Start code (bytes 0-3)
+kw1="\x00\x00\x01\xBA"
diff --git a/media/extractors/fuzzers/mpeg2ts_extractor_fuzzer.dict b/media/extractors/fuzzers/mpeg2ts_extractor_fuzzer.dict
new file mode 100644
index 0000000..006a1eb
--- /dev/null
+++ b/media/extractors/fuzzers/mpeg2ts_extractor_fuzzer.dict
@@ -0,0 +1,2 @@
+# Start byte
+kw1="\x47"
diff --git a/media/extractors/fuzzers/ogg_extractor_fuzzer.cpp b/media/extractors/fuzzers/ogg_extractor_fuzzer.cpp
new file mode 100644
index 0000000..033c50b
--- /dev/null
+++ b/media/extractors/fuzzers/ogg_extractor_fuzzer.cpp
@@ -0,0 +1,62 @@
+/******************************************************************************
+ *
+ * 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.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+#include "ExtractorFuzzerBase.h"
+
+#include "OggExtractor.h"
+
+using namespace android;
+
+class OGGExtractor : public ExtractorFuzzerBase {
+ public:
+ OGGExtractor() = default;
+ ~OGGExtractor() = default;
+
+ bool createExtractor();
+};
+
+bool OGGExtractor::createExtractor() {
+ mExtractor = new OggExtractor(new DataSourceHelper(mDataSource->wrap()));
+ if (!mExtractor) {
+ return false;
+ }
+ mExtractor->name();
+ return true;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ if ((!data) || (size == 0)) {
+ return 0;
+ }
+ OGGExtractor* extractor = new OGGExtractor();
+ if (!extractor) {
+ return 0;
+ }
+ if (extractor->setDataSource(data, size)) {
+ if (extractor->createExtractor()) {
+ extractor->getExtractorDef();
+ extractor->getMetadata();
+ extractor->extractTracks();
+ extractor->getTracksMetadata();
+ }
+ }
+ delete extractor;
+ return 0;
+}
diff --git a/media/extractors/fuzzers/ogg_extractor_fuzzer.dict b/media/extractors/fuzzers/ogg_extractor_fuzzer.dict
new file mode 100644
index 0000000..df2fc38
--- /dev/null
+++ b/media/extractors/fuzzers/ogg_extractor_fuzzer.dict
@@ -0,0 +1,3 @@
+# Start code(bytes 0-3)
+# The below 4 bytes correspond to "OggS" in ASCII
+kw1="\x4F\x67\x67\x53"
diff --git a/media/extractors/fuzzers/wav_extractor_fuzzer.cpp b/media/extractors/fuzzers/wav_extractor_fuzzer.cpp
new file mode 100644
index 0000000..1397122
--- /dev/null
+++ b/media/extractors/fuzzers/wav_extractor_fuzzer.cpp
@@ -0,0 +1,62 @@
+/******************************************************************************
+ *
+ * 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.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+#include "ExtractorFuzzerBase.h"
+
+#include "WAVExtractor.h"
+
+using namespace android;
+
+class wavExtractor : public ExtractorFuzzerBase {
+ public:
+ wavExtractor() = default;
+ ~wavExtractor() = default;
+
+ bool createExtractor();
+};
+
+bool wavExtractor::createExtractor() {
+ mExtractor = new WAVExtractor(new DataSourceHelper(mDataSource->wrap()));
+ if (!mExtractor) {
+ return false;
+ }
+ mExtractor->name();
+ return true;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ if ((!data) || (size == 0)) {
+ return 0;
+ }
+ wavExtractor* extractor = new wavExtractor();
+ if (!extractor) {
+ return 0;
+ }
+ if (extractor->setDataSource(data, size)) {
+ if (extractor->createExtractor()) {
+ extractor->getExtractorDef();
+ extractor->getMetadata();
+ extractor->extractTracks();
+ extractor->getTracksMetadata();
+ }
+ }
+ delete extractor;
+ return 0;
+}
diff --git a/media/extractors/mp4/MPEG4Extractor.cpp b/media/extractors/mp4/MPEG4Extractor.cpp
index 92c48f6..2012d94 100644
--- a/media/extractors/mp4/MPEG4Extractor.cpp
+++ b/media/extractors/mp4/MPEG4Extractor.cpp
@@ -1671,7 +1671,7 @@
return ERROR_IO;
}
- uint16_t data_ref_index __unused = U16_AT(&buffer[6]);
+ // we can get data_ref_index value from U16_AT(&buffer[6])
uint16_t version = U16_AT(&buffer[8]);
uint32_t num_channels = U16_AT(&buffer[16]);
@@ -1864,7 +1864,7 @@
return ERROR_IO;
}
- uint16_t data_ref_index __unused = U16_AT(&buffer[6]);
+ // we can get data_ref_index value from U16_AT(&buffer[6])
uint16_t width = U16_AT(&buffer[6 + 18]);
uint16_t height = U16_AT(&buffer[6 + 20]);
@@ -3257,7 +3257,7 @@
}
// skip
- unsigned bsmod __unused = br.getBits(3);
+ br.skipBits(3); // bsmod
unsigned acmod = br.getBits(3);
unsigned lfeon = br.getBits(1);
@@ -3568,19 +3568,18 @@
return ERROR_IO;
}
- uint64_t ctime __unused, mtime __unused, duration __unused;
int32_t id;
if (version == 1) {
- ctime = U64_AT(&buffer[4]);
- mtime = U64_AT(&buffer[12]);
+ // we can get ctime value from U64_AT(&buffer[4])
+ // we can get mtime value from U64_AT(&buffer[12])
id = U32_AT(&buffer[20]);
- duration = U64_AT(&buffer[28]);
+ // we can get duration value from U64_AT(&buffer[28])
} else if (version == 0) {
- ctime = U32_AT(&buffer[4]);
- mtime = U32_AT(&buffer[8]);
+ // we can get ctime value from U32_AT(&buffer[4])
+ // we can get mtime value from U32_AT(&buffer[8])
id = U32_AT(&buffer[12]);
- duration = U32_AT(&buffer[20]);
+ // we can get duration value from U32_AT(&buffer[20])
} else {
return ERROR_UNSUPPORTED;
}
@@ -4462,18 +4461,17 @@
if (objectType == AOT_SBR || objectType == AOT_PS) {//SBR specific config per 14496-3 tbl 1.13
if (br.numBitsLeft() < 4) return ERROR_MALFORMED;
uint32_t extFreqIndex = br.getBits(4);
- int32_t extSampleRate __unused;
if (extFreqIndex == 15) {
if (csd_size < 8) {
return ERROR_MALFORMED;
}
if (br.numBitsLeft() < 24) return ERROR_MALFORMED;
- extSampleRate = br.getBits(24);
+ br.skipBits(24); // extSampleRate
} else {
if (extFreqIndex == 13 || extFreqIndex == 14) {
return ERROR_MALFORMED;
}
- extSampleRate = kSamplingRate[extFreqIndex];
+ //extSampleRate = kSamplingRate[extFreqIndex];
}
//TODO: save the extension sampling rate value in meta data =>
// AMediaFormat_setInt32(mLastTrack->meta, kKeyExtSampleRate, extSampleRate);
@@ -4516,13 +4514,13 @@
objectType == AOT_ER_AAC_LD || objectType == AOT_ER_AAC_SCAL ||
objectType == AOT_ER_BSAC) {
if (br.numBitsLeft() < 2) return ERROR_MALFORMED;
- const int32_t frameLengthFlag __unused = br.getBits(1);
+ br.skipBits(1); // frameLengthFlag
const int32_t dependsOnCoreCoder = br.getBits(1);
if (dependsOnCoreCoder ) {
if (br.numBitsLeft() < 14) return ERROR_MALFORMED;
- const int32_t coreCoderDelay __unused = br.getBits(14);
+ br.skipBits(14); // coreCoderDelay
}
int32_t extensionFlag = -1;
@@ -4554,64 +4552,64 @@
if (br.numBitsLeft() < 32) {
return ERROR_MALFORMED;
}
- const int32_t ElementInstanceTag __unused = br.getBits(4);
- const int32_t Profile __unused = br.getBits(2);
- const int32_t SamplingFrequencyIndex __unused = br.getBits(4);
+ br.skipBits(4); // ElementInstanceTag
+ br.skipBits(2); // Profile
+ br.skipBits(4); // SamplingFrequencyIndex
const int32_t NumFrontChannelElements = br.getBits(4);
const int32_t NumSideChannelElements = br.getBits(4);
const int32_t NumBackChannelElements = br.getBits(4);
const int32_t NumLfeChannelElements = br.getBits(2);
- const int32_t NumAssocDataElements __unused = br.getBits(3);
- const int32_t NumValidCcElements __unused = br.getBits(4);
+ br.skipBits(3); // NumAssocDataElements
+ br.skipBits(4); // NumValidCcElements
const int32_t MonoMixdownPresent = br.getBits(1);
if (MonoMixdownPresent != 0) {
if (br.numBitsLeft() < 4) return ERROR_MALFORMED;
- const int32_t MonoMixdownElementNumber __unused = br.getBits(4);
+ br.skipBits(4); // MonoMixdownElementNumber
}
if (br.numBitsLeft() < 1) return ERROR_MALFORMED;
const int32_t StereoMixdownPresent = br.getBits(1);
if (StereoMixdownPresent != 0) {
if (br.numBitsLeft() < 4) return ERROR_MALFORMED;
- const int32_t StereoMixdownElementNumber __unused = br.getBits(4);
+ br.skipBits(4); // StereoMixdownElementNumber
}
if (br.numBitsLeft() < 1) return ERROR_MALFORMED;
const int32_t MatrixMixdownIndexPresent = br.getBits(1);
if (MatrixMixdownIndexPresent != 0) {
if (br.numBitsLeft() < 3) return ERROR_MALFORMED;
- const int32_t MatrixMixdownIndex __unused = br.getBits(2);
- const int32_t PseudoSurroundEnable __unused = br.getBits(1);
+ br.skipBits(2); // MatrixMixdownIndex
+ br.skipBits(1); // PseudoSurroundEnable
}
int i;
for (i=0; i < NumFrontChannelElements; i++) {
if (br.numBitsLeft() < 5) return ERROR_MALFORMED;
const int32_t FrontElementIsCpe = br.getBits(1);
- const int32_t FrontElementTagSelect __unused = br.getBits(4);
+ br.skipBits(4); // FrontElementTagSelect
channelsNum += FrontElementIsCpe ? 2 : 1;
}
for (i=0; i < NumSideChannelElements; i++) {
if (br.numBitsLeft() < 5) return ERROR_MALFORMED;
const int32_t SideElementIsCpe = br.getBits(1);
- const int32_t SideElementTagSelect __unused = br.getBits(4);
+ br.skipBits(4); // SideElementTagSelect
channelsNum += SideElementIsCpe ? 2 : 1;
}
for (i=0; i < NumBackChannelElements; i++) {
if (br.numBitsLeft() < 5) return ERROR_MALFORMED;
const int32_t BackElementIsCpe = br.getBits(1);
- const int32_t BackElementTagSelect __unused = br.getBits(4);
+ br.skipBits(4); // BackElementTagSelect
channelsNum += BackElementIsCpe ? 2 : 1;
}
channelsEffectiveNum = channelsNum;
for (i=0; i < NumLfeChannelElements; i++) {
if (br.numBitsLeft() < 4) return ERROR_MALFORMED;
- const int32_t LfeElementTagSelect __unused = br.getBits(4);
+ br.skipBits(4); // LfeElementTagSelect
channelsNum += 1;
}
ALOGV("mpeg4 audio channelsNum = %d", channelsNum);
diff --git a/media/extractors/tests/ExtractorUnitTest.cpp b/media/extractors/tests/ExtractorUnitTest.cpp
index f18a7dc..3075571 100644
--- a/media/extractors/tests/ExtractorUnitTest.cpp
+++ b/media/extractors/tests/ExtractorUnitTest.cpp
@@ -107,9 +107,10 @@
mDisableTest = false;
static const std::map<std::string, standardExtractors> mapExtractor = {
- {"aac", AAC}, {"amr", AMR}, {"mp3", MP3}, {"ogg", OGG},
- {"wav", WAV}, {"mkv", MKV}, {"flac", FLAC}, {"midi", MIDI},
- {"mpeg4", MPEG4}, {"mpeg2ts", MPEG2TS}, {"mpeg2ps", MPEG2PS}};
+ {"aac", AAC}, {"amr", AMR}, {"mp3", MP3}, {"ogg", OGG},
+ {"wav", WAV}, {"mkv", MKV}, {"flac", FLAC}, {"midi", MIDI},
+ {"mpeg4", MPEG4}, {"mpeg2ts", MPEG2TS}, {"mpeg2ps", MPEG2PS}, {"mp4", MPEG4},
+ {"webm", MKV}, {"ts", MPEG2TS}, {"mpeg", MPEG2PS}};
// Find the component type
if (mapExtractor.find(writerFormat) != mapExtractor.end()) {
mExtractorName = mapExtractor.at(writerFormat);
@@ -734,6 +735,174 @@
AMediaFormat_delete(trackFormat);
}
+class ExtractorComparison
+ : public ExtractorUnitTest,
+ public ::testing::TestWithParam<pair<string /* InputFile0 */, string /* InputFile1 */>> {
+ public:
+ ~ExtractorComparison() {
+ for (int8_t *extractorOp : mExtractorOutput) {
+ if (extractorOp != nullptr) {
+ free(extractorOp);
+ }
+ }
+ }
+
+ virtual void SetUp() override {
+ string input0 = GetParam().first;
+ string input1 = GetParam().second;
+
+ // Allocate memory to hold extracted data for both extractors
+ struct stat buf;
+ int32_t status = stat((gEnv->getRes() + input0).c_str(), &buf);
+ ASSERT_EQ(status, 0) << "Unable to get file properties";
+
+ // allocating the buffer size as 2x since some
+ // extractors like flac, midi and wav decodes the file.
+ mExtractorOutput[0] = (int8_t *)calloc(1, buf.st_size * 2);
+ ASSERT_NE(mExtractorOutput[0], nullptr)
+ << "Unable to allocate memory for writing extractor's output";
+ mExtractorOuputSize[0] = buf.st_size * 2;
+
+ status = stat((gEnv->getRes() + input1).c_str(), &buf);
+ ASSERT_EQ(status, 0) << "Unable to get file properties";
+
+ // allocate buffer for extractor output, 2x input file size.
+ mExtractorOutput[1] = (int8_t *)calloc(1, buf.st_size * 2);
+ ASSERT_NE(mExtractorOutput[1], nullptr)
+ << "Unable to allocate memory for writing extractor's output";
+ mExtractorOuputSize[1] = buf.st_size * 2;
+ }
+
+ int8_t *mExtractorOutput[2]{};
+ size_t mExtractorOuputSize[2]{};
+};
+
+// Compare output of two extractors for identical content
+TEST_P(ExtractorComparison, ExtractorComparisonTest) {
+ vector<string> inputFileNames = {GetParam().first, GetParam().second};
+ size_t extractedOutputSize[2]{};
+ AMediaFormat *extractorFormat[2]{};
+ int32_t status = OK;
+
+ for (int32_t idx = 0; idx < inputFileNames.size(); idx++) {
+ string containerFormat = inputFileNames[idx].substr(inputFileNames[idx].find(".") + 1);
+ setupExtractor(containerFormat);
+ if (mDisableTest) {
+ ALOGV("Unknown extractor %s. Skipping the test", containerFormat.c_str());
+ return;
+ }
+
+ ALOGV("Validates %s Extractor for %s", containerFormat.c_str(),
+ inputFileNames[idx].c_str());
+ string inputFileName = gEnv->getRes() + inputFileNames[idx];
+
+ status = setDataSource(inputFileName);
+ ASSERT_EQ(status, 0) << "SetDataSource failed for" << containerFormat << "extractor";
+
+ status = createExtractor();
+ ASSERT_EQ(status, 0) << "Extractor creation failed for " << containerFormat << " extractor";
+
+ int32_t numTracks = mExtractor->countTracks();
+ ASSERT_EQ(numTracks, 1) << "This test expects inputs with one track only";
+
+ int32_t trackIdx = 0;
+ MediaTrackHelper *track = mExtractor->getTrack(trackIdx);
+ ASSERT_NE(track, nullptr) << "Failed to get track for index " << trackIdx;
+
+ extractorFormat[idx] = AMediaFormat_new();
+ ASSERT_NE(extractorFormat[idx], nullptr) << "AMediaFormat_new returned null AMediaformat";
+
+ status = track->getFormat(extractorFormat[idx]);
+ ASSERT_EQ(OK, (media_status_t)status) << "Failed to get track meta data";
+
+ CMediaTrack *cTrack = wrap(track);
+ ASSERT_NE(cTrack, nullptr) << "Failed to get track wrapper for index " << trackIdx;
+
+ MediaBufferGroup *bufferGroup = new MediaBufferGroup();
+ status = cTrack->start(track, bufferGroup->wrap());
+ ASSERT_EQ(OK, (media_status_t)status) << "Failed to start the track";
+
+ int32_t offset = 0;
+ while (status != AMEDIA_ERROR_END_OF_STREAM) {
+ MediaBufferHelper *buffer = nullptr;
+ status = track->read(&buffer);
+ ALOGV("track->read Status = %d buffer %p", status, buffer);
+ if (buffer) {
+ ASSERT_LE(offset + buffer->range_length(), mExtractorOuputSize[idx])
+ << "Memory overflow. Extracted output size more than expected";
+
+ memcpy(mExtractorOutput[idx] + offset, buffer->data(), buffer->range_length());
+ extractedOutputSize[idx] += buffer->range_length();
+ offset += buffer->range_length();
+ buffer->release();
+ }
+ }
+ status = cTrack->stop(track);
+ ASSERT_EQ(OK, status) << "Failed to stop the track";
+
+ fclose(mInputFp);
+ delete bufferGroup;
+ delete track;
+ mDataSource.clear();
+ delete mExtractor;
+ mInputFp = nullptr;
+ mExtractor = nullptr;
+ }
+
+ // Compare the meta data from both the extractors
+ const char *mime[2];
+ AMediaFormat_getString(extractorFormat[0], AMEDIAFORMAT_KEY_MIME, &mime[0]);
+ AMediaFormat_getString(extractorFormat[1], AMEDIAFORMAT_KEY_MIME, &mime[1]);
+ ASSERT_STREQ(mime[0], mime[1]) << "Mismatch between extractor's format";
+
+ if (!strncmp(mime[0], "audio/", 6)) {
+ int32_t channelCount0, channelCount1;
+ int32_t sampleRate0, sampleRate1;
+ ASSERT_TRUE(AMediaFormat_getInt32(extractorFormat[0], AMEDIAFORMAT_KEY_CHANNEL_COUNT,
+ &channelCount0));
+ ASSERT_TRUE(AMediaFormat_getInt32(extractorFormat[0], AMEDIAFORMAT_KEY_SAMPLE_RATE,
+ &sampleRate0));
+ ASSERT_TRUE(AMediaFormat_getInt32(extractorFormat[1], AMEDIAFORMAT_KEY_CHANNEL_COUNT,
+ &channelCount1));
+ ASSERT_TRUE(AMediaFormat_getInt32(extractorFormat[1], AMEDIAFORMAT_KEY_SAMPLE_RATE,
+ &sampleRate1));
+ ASSERT_EQ(channelCount0, channelCount1) << "Mismatch between extractor's channelCount";
+ ASSERT_EQ(sampleRate0, sampleRate1) << "Mismatch between extractor's sampleRate";
+ } else if (!strncmp(mime[0], "video/", 6)) {
+ int32_t width0, height0;
+ int32_t width1, height1;
+ ASSERT_TRUE(AMediaFormat_getInt32(extractorFormat[0], AMEDIAFORMAT_KEY_WIDTH, &width0));
+ ASSERT_TRUE(AMediaFormat_getInt32(extractorFormat[0], AMEDIAFORMAT_KEY_HEIGHT, &height0));
+ ASSERT_TRUE(AMediaFormat_getInt32(extractorFormat[1], AMEDIAFORMAT_KEY_WIDTH, &width1));
+ ASSERT_TRUE(AMediaFormat_getInt32(extractorFormat[1], AMEDIAFORMAT_KEY_HEIGHT, &height1));
+ ASSERT_EQ(width0, width1) << "Mismatch between extractor's width";
+ ASSERT_EQ(height0, height1) << "Mismatch between extractor's height";
+ } else {
+ ASSERT_TRUE(false) << "Invalid mime type " << mime[0];
+ }
+
+ for (AMediaFormat *exFormat : extractorFormat) {
+ AMediaFormat_delete(exFormat);
+ }
+
+ // Compare the extracted outputs of both extractor
+ ASSERT_EQ(extractedOutputSize[0], extractedOutputSize[1])
+ << "Extractor's output size doesn't match between " << inputFileNames[0] << "and "
+ << inputFileNames[1] << " extractors";
+ status = memcmp(mExtractorOutput[0], mExtractorOutput[1], extractedOutputSize[0]);
+ ASSERT_EQ(status, 0) << "Extracted content mismatch between " << inputFileNames[0] << "and "
+ << inputFileNames[1] << " extractors";
+}
+
+INSTANTIATE_TEST_SUITE_P(ExtractorComparisonAll, ExtractorComparison,
+ ::testing::Values(make_pair("swirl_144x136_vp9.mp4",
+ "swirl_144x136_vp9.webm"),
+ make_pair("video_480x360_mp4_vp9_333kbps_25fps.mp4",
+ "video_480x360_webm_vp9_333kbps_25fps.webm"),
+ make_pair("video_1280x720_av1_hdr_static_3mbps.mp4",
+ "video_1280x720_av1_hdr_static_3mbps.webm"),
+ make_pair("loudsoftaac.aac", "loudsoftaac.mkv")));
+
INSTANTIATE_TEST_SUITE_P(ConfigParamTestAll, ConfigParamTest,
::testing::Values(make_pair("aac", 0),
make_pair("amr", 1),
diff --git a/media/libaaudio/src/utility/AAudioUtilities.h b/media/libaaudio/src/utility/AAudioUtilities.h
index 76d0457..0dd866d 100644
--- a/media/libaaudio/src/utility/AAudioUtilities.h
+++ b/media/libaaudio/src/utility/AAudioUtilities.h
@@ -21,6 +21,7 @@
#include <functional>
#include <stdint.h>
#include <sys/types.h>
+#include <unistd.h>
#include <utils/Errors.h>
#include <system/audio.h>
diff --git a/media/libaudioclient/AudioRecord.cpp b/media/libaudioclient/AudioRecord.cpp
index 271e186..3d0d622 100644
--- a/media/libaudioclient/AudioRecord.cpp
+++ b/media/libaudioclient/AudioRecord.cpp
@@ -388,6 +388,9 @@
mFramesReadServerOffset -= mFramesRead + framesFlushed;
mFramesRead = 0;
mProxy->clearTimestamp(); // timestamp is invalid until next server push
+ mPreviousTimestamp.clear();
+ mTimestampRetrogradePositionReported = false;
+ mTimestampRetrogradeTimeReported = false;
// reset current position as seen by client to 0
mProxy->setEpoch(mProxy->getEpoch() - mProxy->getPosition());
@@ -570,6 +573,39 @@
timestamp->mPosition[i] += mFramesReadServerOffset;
}
}
+
+ bool timestampRetrogradeTimeReported = false;
+ bool timestampRetrogradePositionReported = false;
+ for (int i = 0; i < ExtendedTimestamp::LOCATION_MAX; ++i) {
+ if (timestamp->mTimeNs[i] >= 0 && mPreviousTimestamp.mTimeNs[i] >= 0) {
+ if (timestamp->mTimeNs[i] < mPreviousTimestamp.mTimeNs[i]) {
+ if (!mTimestampRetrogradeTimeReported) {
+ ALOGD("%s: retrograde time adjusting [%d] current:%lld to previous:%lld",
+ __func__, i, (long long)timestamp->mTimeNs[i],
+ (long long)mPreviousTimestamp.mTimeNs[i]);
+ timestampRetrogradeTimeReported = true;
+ }
+ timestamp->mTimeNs[i] = mPreviousTimestamp.mTimeNs[i];
+ }
+ if (timestamp->mPosition[i] < mPreviousTimestamp.mPosition[i]) {
+ if (!mTimestampRetrogradePositionReported) {
+ ALOGD("%s: retrograde position"
+ " adjusting [%d] current:%lld to previous:%lld",
+ __func__, i, (long long)timestamp->mPosition[i],
+ (long long)mPreviousTimestamp.mPosition[i]);
+ timestampRetrogradePositionReported = true;
+ }
+ timestamp->mPosition[i] = mPreviousTimestamp.mPosition[i];
+ }
+ }
+ }
+ mPreviousTimestamp = *timestamp;
+ if (timestampRetrogradeTimeReported) {
+ mTimestampRetrogradeTimeReported = true;
+ }
+ if (timestampRetrogradePositionReported) {
+ mTimestampRetrogradePositionReported = true;
+ }
}
return status;
}
diff --git a/media/libaudioclient/include/media/AudioRecord.h b/media/libaudioclient/include/media/AudioRecord.h
index 574302b..20a7d14 100644
--- a/media/libaudioclient/include/media/AudioRecord.h
+++ b/media/libaudioclient/include/media/AudioRecord.h
@@ -711,6 +711,10 @@
bool mInOverrun; // whether recorder is currently in overrun state
+ ExtendedTimestamp mPreviousTimestamp{}; // used to detect retrograde motion
+ bool mTimestampRetrogradePositionReported = false; // reduce log spam
+ bool mTimestampRetrogradeTimeReported = false; // reduce log spam
+
private:
class DeathNotifier : public IBinder::DeathRecipient {
public:
diff --git a/media/libcpustats/ThreadCpuUsage.cpp b/media/libcpustats/ThreadCpuUsage.cpp
index 4b7549f..e71a7db 100644
--- a/media/libcpustats/ThreadCpuUsage.cpp
+++ b/media/libcpustats/ThreadCpuUsage.cpp
@@ -21,6 +21,7 @@
#include <stdlib.h>
#include <string.h>
#include <time.h>
+#include <unistd.h>
#include <utils/Log.h>
diff --git a/media/libeffects/config/Android.bp b/media/libeffects/config/Android.bp
index 8476f82..8493e30 100644
--- a/media/libeffects/config/Android.bp
+++ b/media/libeffects/config/Android.bp
@@ -15,6 +15,7 @@
"libtinyxml2",
"libutils",
"libmedia_helper",
+ "libcutils",
],
header_libs: ["libaudio_system_headers"],
diff --git a/media/libeffects/config/include/media/EffectsConfig.h b/media/libeffects/config/include/media/EffectsConfig.h
index ef10e0d..57d4dd7 100644
--- a/media/libeffects/config/include/media/EffectsConfig.h
+++ b/media/libeffects/config/include/media/EffectsConfig.h
@@ -35,11 +35,6 @@
/** Default path of effect configuration file. Relative to DEFAULT_LOCATIONS. */
constexpr const char* DEFAULT_NAME = "audio_effects.xml";
-/** Default path of effect configuration file.
- * The /vendor partition is the recommended one, the others are deprecated.
- */
-constexpr const char* DEFAULT_LOCATIONS[] = {"/odm/etc", "/vendor/etc", "/system/etc"};
-
/** Directories where the effect libraries will be search for. */
constexpr const char* LD_EFFECT_LIBRARY_PATH[] =
#ifdef __LP64__
diff --git a/media/libeffects/config/src/EffectsConfig.cpp b/media/libeffects/config/src/EffectsConfig.cpp
index 85fbf11..26eaaf8 100644
--- a/media/libeffects/config/src/EffectsConfig.cpp
+++ b/media/libeffects/config/src/EffectsConfig.cpp
@@ -27,6 +27,7 @@
#include <media/EffectsConfig.h>
#include <media/TypeConverter.h>
+#include <system/audio_config.h>
using namespace tinyxml2;
@@ -338,7 +339,7 @@
return parseWithPath(path);
}
- for (const std::string& location : DEFAULT_LOCATIONS) {
+ for (const std::string& location : audio_get_configuration_paths()) {
std::string defaultPath = location + '/' + DEFAULT_NAME;
if (access(defaultPath.c_str(), R_OK) != 0) {
continue;
diff --git a/media/libmedia/Android.bp b/media/libmedia/Android.bp
index 778ee44..eefea91 100644
--- a/media/libmedia/Android.bp
+++ b/media/libmedia/Android.bp
@@ -15,6 +15,21 @@
],
}
+cc_library_headers {
+ name: "libmedia_datasource_headers",
+ export_include_dirs: ["include"],
+ host_supported: true,
+ target: {
+ darwin: {
+ enabled: false,
+ },
+ },
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.media",
+ ],
+}
+
filegroup {
name: "libmedia_omx_aidl",
srcs: [
@@ -282,11 +297,13 @@
"bionic_libc_platform_headers",
"libstagefright_headers",
"media_ndk_headers",
+ "jni_headers",
],
export_header_lib_headers: [
"libstagefright_headers",
"media_ndk_headers",
+ "jni_headers",
],
shared_libs: [
@@ -340,3 +357,36 @@
cfi: true,
},
}
+
+cc_library_static {
+ name: "libmedia_ndkformatpriv",
+
+ host_supported: true,
+
+ srcs: [
+ "NdkMediaFormatPriv.cpp",
+ "NdkMediaErrorPriv.cpp",
+ ],
+
+ header_libs: [
+ "libstagefright_foundation_headers",
+ "libstagefright_headers",
+ "media_ndk_headers",
+ ],
+
+ cflags: [
+ "-DEXPORT=__attribute__((visibility(\"default\")))",
+ "-Werror",
+ "-Wall",
+ ],
+
+ export_include_dirs: ["include"],
+
+ target: {
+ darwin: {
+ enabled: false,
+ },
+ },
+
+ apex_available: ["com.android.media"],
+}
diff --git a/media/libmedia/MidiIoWrapper.cpp b/media/libmedia/MidiIoWrapper.cpp
index e71ea2c..da272e3 100644
--- a/media/libmedia/MidiIoWrapper.cpp
+++ b/media/libmedia/MidiIoWrapper.cpp
@@ -18,8 +18,9 @@
#define LOG_TAG "MidiIoWrapper"
#include <utils/Log.h>
-#include <sys/stat.h>
#include <fcntl.h>
+#include <sys/stat.h>
+#include <unistd.h>
#include <media/MidiIoWrapper.h>
#include <media/MediaExtractorPluginApi.h>
diff --git a/media/libmedia/NdkMediaFormatPriv.cpp b/media/libmedia/NdkMediaFormatPriv.cpp
index 3a9fb8b..7983184 100644
--- a/media/libmedia/NdkMediaFormatPriv.cpp
+++ b/media/libmedia/NdkMediaFormatPriv.cpp
@@ -24,8 +24,6 @@
#include <media/NdkMediaFormatPriv.h>
#include <media/stagefright/foundation/AMessage.h>
-#include <jni.h>
-
using namespace android;
namespace android {
diff --git a/media/libmedia/xsd/vts/Android.bp b/media/libmedia/xsd/vts/Android.bp
index 4739504..598e41b 100644
--- a/media/libmedia/xsd/vts/Android.bp
+++ b/media/libmedia/xsd/vts/Android.bp
@@ -31,4 +31,12 @@
"-Wall",
"-Werror",
],
+ data: [
+ ":media_profiles",
+ ],
+ test_suites: [
+ "general-tests",
+ "vts"
+ ],
+ test_config: "vts_mediaProfiles_validate_test.xml",
}
diff --git a/media/libmedia/xsd/vts/vts_mediaProfiles_validate_test.xml b/media/libmedia/xsd/vts/vts_mediaProfiles_validate_test.xml
new file mode 100644
index 0000000..08ab8f4
--- /dev/null
+++ b/media/libmedia/xsd/vts/vts_mediaProfiles_validate_test.xml
@@ -0,0 +1,33 @@
+<?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="Runs vts_mediaProfiles_validate_test.">
+ <option name="test-suite-tag" value="apct" />
+ <option name="test-suite-tag" value="apct-native" />
+
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
+ </target_preparer>
+
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="cleanup" value="true" />
+ <option name="push" value="media_profiles.xsd->/data/local/tmp/media_profiles.xsd" />
+ <option name="push" value="vts_mediaProfiles_validate_test->/data/local/tmp/vts_mediaProfiles_validate_test" />
+ </target_preparer>
+
+ <test class="com.android.tradefed.testtype.GTest" >
+ <option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="module-name" value="vts_mediaProfiles_validate_test" />
+ </test>
+</configuration>
diff --git a/media/libmediahelper/Android.bp b/media/libmediahelper/Android.bp
index 72edeec..ae135af 100644
--- a/media/libmediahelper/Android.bp
+++ b/media/libmediahelper/Android.bp
@@ -2,6 +2,12 @@
name: "libmedia_helper_headers",
vendor_available: true,
export_include_dirs: ["include"],
+ host_supported: true,
+ target: {
+ darwin: {
+ enabled: false,
+ },
+ },
}
cc_library {
@@ -26,4 +32,10 @@
"libmedia_helper_headers",
],
clang: true,
+ host_supported: true,
+ target: {
+ darwin: {
+ enabled: false,
+ },
+ },
}
diff --git a/media/libstagefright/Android.bp b/media/libstagefright/Android.bp
index 18dacb8..abb58be 100644
--- a/media/libstagefright/Android.bp
+++ b/media/libstagefright/Android.bp
@@ -2,6 +2,12 @@
name: "libstagefright_headers",
export_include_dirs: ["include"],
vendor_available: true,
+ host_supported: true,
+ target: {
+ darwin: {
+ enabled: false,
+ },
+ },
}
cc_library_static {
diff --git a/media/libstagefright/MediaExtractorFactory.cpp b/media/libstagefright/MediaExtractorFactory.cpp
index 9e85475..8bce917 100644
--- a/media/libstagefright/MediaExtractorFactory.cpp
+++ b/media/libstagefright/MediaExtractorFactory.cpp
@@ -298,6 +298,12 @@
#endif
"/extractors", NULL, *newList);
+ RegisterExtractors("/system_ext/lib"
+#ifdef __LP64__
+ "64"
+#endif
+ "/extractors", NULL, *newList);
+
newList->sort(compareFunc);
gPlugins = newList;
diff --git a/media/libstagefright/codecs/amrnb/fuzzer/amrnb_dec_fuzzer.cpp b/media/libstagefright/codecs/amrnb/fuzzer/amrnb_dec_fuzzer.cpp
index d4e7e5c..c7a7378 100644
--- a/media/libstagefright/codecs/amrnb/fuzzer/amrnb_dec_fuzzer.cpp
+++ b/media/libstagefright/codecs/amrnb/fuzzer/amrnb_dec_fuzzer.cpp
@@ -26,8 +26,10 @@
constexpr int32_t kBitsPerSample = 16;
constexpr int32_t kOutputBufferSize = kSamplesPerFrame * kBitsPerSample / 8;
const bitstream_format kBitStreamFormats[2] = {MIME_IETF, IF2};
-const int32_t kLocalWmfDecBytesPerFrame[8] = {12, 13, 15, 17, 19, 20, 26, 31};
-const int32_t kLocalIf2DecBytesPerFrame[8] = {13, 14, 16, 18, 19, 21, 26, 31};
+const int32_t kLocalWmfDecBytesPerFrame[16] = {12, 13, 15, 17, 19, 20, 26, 31,
+ 5, 6, 5, 5, 0, 0, 0, 0};
+const int32_t kLocalIf2DecBytesPerFrame[16] = {13, 14, 16, 18, 19, 21, 26, 31,
+ 13, 14, 16, 18, 19, 21, 26, 31};
class Codec {
public:
@@ -52,7 +54,7 @@
bitstream_format bitsreamFormat = kBitStreamFormats[bit];
int32_t frameSize = 0;
/* Find frame type */
- Frame_Type_3GPP frameType = static_cast<Frame_Type_3GPP>((mode >> 3) & 0x07);
+ Frame_Type_3GPP frameType = static_cast<Frame_Type_3GPP>((mode >> 3) & 0x0f);
++data;
--size;
if (bit) {
diff --git a/media/libstagefright/codecs/m4v_h263/dec/Android.bp b/media/libstagefright/codecs/m4v_h263/dec/Android.bp
index b8b83d5..f278f92 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/Android.bp
+++ b/media/libstagefright/codecs/m4v_h263/dec/Android.bp
@@ -5,20 +5,14 @@
shared_libs: ["liblog"],
srcs: [
- "src/adaptive_smooth_no_mmx.cpp",
"src/bitstream.cpp",
"src/block_idct.cpp",
"src/cal_dc_scaler.cpp",
- "src/chvr_filter.cpp",
- "src/chv_filter.cpp",
"src/combined_decode.cpp",
"src/conceal.cpp",
"src/datapart_decode.cpp",
"src/dcac_prediction.cpp",
"src/dec_pred_intra_dc.cpp",
- "src/deringing_chroma.cpp",
- "src/deringing_luma.cpp",
- "src/find_min_max.cpp",
"src/get_pred_adv_b_add.cpp",
"src/get_pred_outside.cpp",
"src/idct.cpp",
@@ -27,9 +21,6 @@
"src/mb_utils.cpp",
"src/packet_util.cpp",
"src/post_filter.cpp",
- "src/post_proc_semaphore.cpp",
- "src/pp_semaphore_chroma_inter.cpp",
- "src/pp_semaphore_luma.cpp",
"src/pvdec_api.cpp",
"src/scaling_tab.cpp",
"src/vlc_decode.cpp",
@@ -43,9 +34,6 @@
export_include_dirs: ["include"],
cflags: [
- "-DOSCL_EXPORT_REF=",
- "-DOSCL_IMPORT_REF=",
-
"-Werror",
],
@@ -76,8 +64,6 @@
local_include_dirs: ["src"],
cflags: [
- "-DOSCL_EXPORT_REF=",
- "-DOSCL_IMPORT_REF=",
],
static_libs: ["libstagefright_m4vh263dec"],
diff --git a/media/libstagefright/codecs/m4v_h263/dec/include/mp4dec_api.h b/media/libstagefright/codecs/m4v_h263/dec/include/mp4dec_api.h
index 6d4868c..06aee07 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/include/mp4dec_api.h
+++ b/media/libstagefright/codecs/m4v_h263/dec/include/mp4dec_api.h
@@ -35,13 +35,13 @@
#define PV_TRUE 1
#define PV_FALSE 0
-/* flag for post-processing 4/25/00 */
-
-#ifdef DEC_NOPOSTPROC
-#undef PV_POSTPROC_ON /* enable compilation of post-processing code */
-#else
-#define PV_POSTPROC_ON
+#ifndef OSCL_IMPORT_REF
+#define OSCL_IMPORT_REF /* empty */
#endif
+#ifndef OSCL_EXPORT_REF
+#define OSCL_EXPORT_REF /* empty */
+#endif
+
#define PV_NO_POST_PROC 0
#define PV_DEBLOCK 1
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/adaptive_smooth_no_mmx.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/adaptive_smooth_no_mmx.cpp
deleted file mode 100644
index e2761eb..0000000
--- a/media/libstagefright/codecs/m4v_h263/dec/src/adaptive_smooth_no_mmx.cpp
+++ /dev/null
@@ -1,421 +0,0 @@
-/* ------------------------------------------------------------------
- * Copyright (C) 1998-2009 PacketVideo
- *
- * 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.
- * -------------------------------------------------------------------
- */
-/*
-
- Description: Separated modules into one function per file and put into
- new template.
-
- Description: Optimizing C code and adding comments. Also changing variable
- names to make them more meaningful.
-
- Who: Date:
- Description:
-
-------------------------------------------------------------------------------
- INPUT AND OUTPUT DEFINITIONS
-
- Inputs:
-
- Rec_Y = pointer to 0th position in buffer containing luminance values
- of type uint8.
- y_start = value of y coordinate of type int that specifies the first
- row of pixels to be used in the filter algorithm.
- x_start = value of x coordinate of type int that specifies the first
- column of pixels to be used in the filter algorithm.
- y_blk_start = value of the y coordinate of type int that specifies the
- row of pixels which contains the start of a block. The row
- specified by y_blk_start+BLK_SIZE is the last row of pixels
- that are used in the filter algorithm.
- x_blk_start = value of the x coordinate of type int that specifies the
- column of pixels which contains the start of a block. The
- column specified by x_blk_start+BLK_SIZE is the last column of
- pixels that are used in the filter algorithm.
- thr = value of type int that is compared to the elements in Rec_Y to
- determine if a particular value in Rec_Y will be modified by
- the filter or not
- width = value of type int that specifies the width of the display
- in pixels (or pels, equivalently).
- max_diff = value of type int that specifies the value that may be added
- or subtracted from the pixel in Rec_Y that is being filtered
- if the filter algorithm decides to change that particular
- pixel's luminance value.
-
-
- Local Stores/Buffers/Pointers Needed:
- None
-
- Global Stores/Buffers/Pointers Needed:
- None
-
- Outputs:
- None
-
- Pointers and Buffers Modified:
- Buffer pointed to by Rec_Y is modified with the filtered
- luminance values.
-
- Local Stores Modified:
- None
-
- Global Stores Modified:
- None
-
-------------------------------------------------------------------------------
- FUNCTION DESCRIPTION
-
- This function implements a motion compensated noise filter using adaptive
- weighted averaging of luminance values. *Rec_Y contains the luminance values
- that are being filtered.
-
- The picture below depicts a 3x3 group of pixel luminance values. The "u", "c",
- and "l" stand for "upper", "center" and "lower", respectively. The location
- of pelc0 is specified by x_start and y_start in the 1-D array "Rec_Y" as
- follows (assuming x_start=0):
-
- location of pelc0 = [(y_start+1) * width] + x_start
-
- Moving up or down 1 row (moving from pelu2 to pelc2, for example) is done by
- incrementing or decrementing "width" elements within Rec_Y.
-
- The coordinates of the upper left hand corner of a block (not the group of
- 9 pixels depicted in the figure below) is specified by
- (y_blk_start, x_blk_start). The width and height of the block is BLKSIZE.
- (y_start,x_start) may be specified independently of (y_blk_start, x_blk_start).
-
- (y_start,x_start)
- -----------|--------------------------
- | | | | |
- | X | pelu1 | pelu2 |
- | pelu0 | | |
- | | | |
- --------------------------------------
- | | | |
- | pelc0 | pelc1 | pelc2 |
- | | | |
- | | | |
- --------------------------------------
- | | | |
- | pell0 | pell1 | pell2 |
- | | | |
- | | | |
- --------------------------------------
-
- The filtering of the luminance values is achieved by comparing the 9
- luminance values to a threshold value ("thr") and then changing the
- luminance value of pelc1 if all of the values are above or all of the values
- are below the threshold. The amount that the luminance value is changed
- depends on a weighted sum of the 9 luminance values. The position of Pelc1
- is then advanced to the right by one (as well as all of the surrounding pixels)
- and the same calculation is performed again for the luminance value of the new
- Pelc1. This continues row-wise until pixels in the last row of the block are
- filtered.
-
-
-------------------------------------------------------------------------------
- REQUIREMENTS
-
- None.
-
-------------------------------------------------------------------------------
- REFERENCES
-
- ..\corelibs\decoder\common\src\post_proc.c
-
-------------------------------------------------------------------------------
- PSEUDO-CODE
-
-------------------------------------------------------------------------------
- RESOURCES USED
- When the code is written for a specific target processor the
- the resources used should be documented below.
-
- STACK USAGE: [stack count for this module] + [variable to represent
- stack usage for each subroutine called]
-
- where: [stack usage variable] = stack usage for [subroutine
- name] (see [filename].ext)
-
- DATA MEMORY USED: x words
-
- PROGRAM MEMORY USED: x words
-
- CLOCK CYCLES: [cycle count equation for this module] + [variable
- used to represent cycle count for each subroutine
- called]
-
- where: [cycle count variable] = cycle count for [subroutine
- name] (see [filename].ext)
-
-------------------------------------------------------------------------------
-*/
-
-
-/*----------------------------------------------------------------------------
-; INCLUDES
-----------------------------------------------------------------------------*/
-#include "mp4dec_lib.h"
-#include "post_proc.h"
-#include "mp4def.h"
-
-#define OSCL_DISABLE_WARNING_CONV_POSSIBLE_LOSS_OF_DATA
-
-/*----------------------------------------------------------------------------
-; MACROS
-; Define module specific macros here
-----------------------------------------------------------------------------*/
-
-
-/*----------------------------------------------------------------------------
-; DEFINES
-; Include all pre-processor statements here. Include conditional
-; compile variables also.
-----------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------
-; LOCAL FUNCTION DEFINITIONS
-; Function Prototype declaration
-----------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------
-; LOCAL STORE/BUFFER/POINTER DEFINITIONS
-; Variable declaration - defined here and used outside this module
-----------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------
-; EXTERNAL FUNCTION REFERENCES
-; Declare functions defined elsewhere and referenced in this module
-----------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------
-; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
-; Declare variables used in this module but defined elsewhere
-----------------------------------------------------------------------------*/
-#ifdef PV_POSTPROC_ON
-/*----------------------------------------------------------------------------
-; FUNCTION CODE
-----------------------------------------------------------------------------*/
-void AdaptiveSmooth_NoMMX(
- uint8 *Rec_Y, /* i/o */
- int y_start, /* i */
- int x_start, /* i */
- int y_blk_start, /* i */
- int x_blk_start, /* i */
- int thr, /* i */
- int width, /* i */
- int max_diff /* i */
-)
-{
-
- /*----------------------------------------------------------------------------
- ; Define all local variables
- ----------------------------------------------------------------------------*/
- int sign_v[15];
- int sum_v[15];
- int *sum_V_ptr;
- int *sign_V_ptr;
- uint8 pelu;
- uint8 pelc;
- uint8 pell;
- uint8 *pelp;
- uint8 oldrow[15];
- int sum;
- int sum1;
- uint8 *Rec_Y_ptr;
- int32 addr_v;
- int row_cntr;
- int col_cntr;
-
- /*----------------------------------------------------------------------------
- ; Function body here
- ----------------------------------------------------------------------------*/
- /* first row
- */
- addr_v = (int32)(y_start + 1) * width; /* y coord of 1st element in the row /
- /containing pelc pixel / */
- Rec_Y_ptr = &Rec_Y[addr_v + x_start]; /* initializing pointer to
- / pelc0 position */
- sum_V_ptr = &sum_v[0]; /* initializing pointer to 0th element of array
- / that will contain weighted sums of pixel
- / luminance values */
- sign_V_ptr = &sign_v[0]; /* initializing pointer to 0th element of
- / array that will contain sums that indicate
- / how many of the 9 pixels are above or below
- / the threshold value (thr) */
- pelp = &oldrow[0]; /* initializing pointer to the 0th element of array
- / that will contain current values of pelc that
- / are saved and used as values of pelu when the
- / next row of pixels are filtered */
-
- pelu = *(Rec_Y_ptr - width); /* assigning value of pelu0 to pelu */
- *pelp++ = pelc = *Rec_Y_ptr; /* assigning value of pelc0 to pelc and
- / storing this value in pelp which
- / will be used as value of pelu0 when
- / next row is filtered */
- pell = *(Rec_Y_ptr + width); /* assigning value of pell0 to pell */
- Rec_Y_ptr++; /* advancing pointer from pelc0 to pelc1 */
- *sum_V_ptr++ = pelu + (pelc << 1) + pell; /* weighted sum of pelu0,
- / pelc0 and pell0 */
- /* sum of 0's and 1's (0 if pixel value is below thr, 1 if value
- /is above thr) */
- *sign_V_ptr++ = INDEX(pelu, thr) + INDEX(pelc, thr) + INDEX(pell, thr);
-
-
- pelu = *(Rec_Y_ptr - width); /* assigning value of pelu1 to pelu */
- *pelp++ = pelc = *Rec_Y_ptr; /* assigning value of pelc1 to pelc and
- / storing this value in pelp which
- / will be used as the value of pelu1 when
- / next row is filtered */
- pell = *(Rec_Y_ptr + width); /* assigning value of pell1 to pell */
- Rec_Y_ptr++; /* advancing pointer from pelc1 to pelc2 */
- *sum_V_ptr++ = pelu + (pelc << 1) + pell; /* weighted sum of pelu1,
- / pelc1 and pell1 */
- /* sum of 0's and 1's (0 if pixel value is below thr, 1 if value
- /is above thr) */
- *sign_V_ptr++ = INDEX(pelu, thr) + INDEX(pelc, thr) + INDEX(pell, thr);
-
- /* The loop below performs the filtering for the first row of
- / pixels in the region. It steps across the remaining pixels in
- / the row and alters the luminance value of pelc1 if necessary,
- / depending on the luminance values of the adjacent pixels*/
-
- for (col_cntr = (x_blk_start + BLKSIZE - 1) - x_start; col_cntr > 0; col_cntr--)
- {
- pelu = *(Rec_Y_ptr - width); /* assigning value of pelu2 to
- / pelu */
- *pelp++ = pelc = *Rec_Y_ptr; /* assigning value of pelc2 to pelc
- / and storing this value in pelp
- / which will be used as value of pelu2
- / when next row is filtered */
- pell = *(Rec_Y_ptr + width); /* assigning value of pell2 to pell */
-
- /* weighted sum of pelu1, pelc1 and pell1 */
- *sum_V_ptr = pelu + (pelc << 1) + pell;
- /* sum of 0's and 1's (0 if pixel value is below thr,
- /1 if value is above thr) */
- *sign_V_ptr = INDEX(pelu, thr) + INDEX(pelc, thr) +
- INDEX(pell, thr);
- /* the value of sum1 indicates how many of the 9 pixels'
- /luminance values are above or equal to thr */
- sum1 = *(sign_V_ptr - 2) + *(sign_V_ptr - 1) + *sign_V_ptr;
-
- /* alter the luminance value of pelc1 if all 9 luminance values
- /are above or equal to thr or if all 9 values are below thr */
- if (sum1 == 0 || sum1 == 9)
- {
- /* sum is a weighted average of the 9 pixel luminance
- /values */
- sum = (*(sum_V_ptr - 2) + (*(sum_V_ptr - 1) << 1) +
- *sum_V_ptr + 8) >> 4;
-
- Rec_Y_ptr--; /* move pointer back to pelc1 */
- /* If luminance value of pelc1 is larger than
- / sum by more than max_diff, then subract max_diff
- / from luminance value of pelc1*/
- if ((int)(*Rec_Y_ptr - sum) > max_diff)
- {
- sum = *Rec_Y_ptr - max_diff;
- }
- /* If luminance value of pelc1 is smaller than
- / sum by more than max_diff, then add max_diff
- / to luminance value of pelc1*/
- else if ((int)(*Rec_Y_ptr - sum) < -max_diff)
- {
- sum = *Rec_Y_ptr + max_diff;
- }
- *Rec_Y_ptr++ = sum; /* assign value of sum to pelc1
- and advance pointer to pelc2 */
- }
- Rec_Y_ptr++; /* advance pointer to new value of pelc2
- / old pelc2 is now treated as pelc1*/
- sum_V_ptr++; /* pointer is advanced so next weighted sum may
- / be saved */
- sign_V_ptr++; /* pointer is advanced so next sum of 0's and
- / 1's may be saved */
- }
-
- /* The nested loops below perform the filtering for the remaining rows */
-
- addr_v = (y_start + 2) * width; /* advance addr_v to the next row
- / (corresponding to pell0)*/
- /* The outer loop steps throught the rows. */
- for (row_cntr = (y_blk_start + BLKSIZE) - (y_start + 2); row_cntr > 0; row_cntr--)
- {
- Rec_Y_ptr = &Rec_Y[addr_v + x_start]; /* advance pointer to
- /the old pell0, which has become the new pelc0 */
- addr_v += width; /* move addr_v down 1 row */
- sum_V_ptr = &sum_v[0]; /* re-initializing pointer */
- sign_V_ptr = &sign_v[0]; /* re-initilaizing pointer */
- pelp = &oldrow[0]; /* re-initializing pointer */
-
- pelu = *pelp; /* setting pelu0 to old value of pelc0 */
- *pelp++ = pelc = *Rec_Y_ptr;
- pell = *(Rec_Y_ptr + width);
- Rec_Y_ptr++;
- *sum_V_ptr++ = pelu + (pelc << 1) + pell;
- *sign_V_ptr++ = INDEX(pelu, thr) + INDEX(pelc, thr) +
- INDEX(pell, thr);
-
- pelu = *pelp; /* setting pelu1 to old value of pelc1 */
- *pelp++ = pelc = *Rec_Y_ptr;
- pell = *(Rec_Y_ptr + width);
- Rec_Y_ptr++;
- *sum_V_ptr++ = pelu + (pelc << 1) + pell;
- *sign_V_ptr++ = INDEX(pelu, thr) + INDEX(pelc, thr) +
- INDEX(pell, thr);
- /* The inner loop steps through the columns */
- for (col_cntr = (x_blk_start + BLKSIZE - 1) - x_start; col_cntr > 0; col_cntr--)
- {
- pelu = *pelp; /* setting pelu2 to old value of pelc2 */
- *pelp++ = pelc = *Rec_Y_ptr;
- pell = *(Rec_Y_ptr + width);
-
- *sum_V_ptr = pelu + (pelc << 1) + pell;
- *sign_V_ptr = INDEX(pelu, thr) + INDEX(pelc, thr) +
- INDEX(pell, thr);
-
- sum1 = *(sign_V_ptr - 2) + *(sign_V_ptr - 1) + *sign_V_ptr;
- /* the "if" statement below is the same as the one in
- / the first loop */
- if (sum1 == 0 || sum1 == 9)
- {
- sum = (*(sum_V_ptr - 2) + (*(sum_V_ptr - 1) << 1) +
- *sum_V_ptr + 8) >> 4;
-
- Rec_Y_ptr--;
- if ((int)(*Rec_Y_ptr - sum) > max_diff)
- {
- sum = *Rec_Y_ptr - max_diff;
- }
- else if ((int)(*Rec_Y_ptr - sum) < -max_diff)
- {
- sum = *Rec_Y_ptr + max_diff;
- }
- *Rec_Y_ptr++ = (uint8) sum;
- }
- Rec_Y_ptr++;
- sum_V_ptr++;
- sign_V_ptr++;
- }
- }
-
- /*----------------------------------------------------------------------------
- ; Return nothing or data or data pointer
- ----------------------------------------------------------------------------*/
- return;
-}
-#endif
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/chv_filter.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/chv_filter.cpp
deleted file mode 100644
index 6593b48..0000000
--- a/media/libstagefright/codecs/m4v_h263/dec/src/chv_filter.cpp
+++ /dev/null
@@ -1,654 +0,0 @@
-/* ------------------------------------------------------------------
- * Copyright (C) 1998-2009 PacketVideo
- *
- * 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.
- * -------------------------------------------------------------------
- */
-/*
-------------------------------------------------------------------------------
- INPUT AND OUTPUT DEFINITIONS
-
- Inputs:
- [input_variable_name] = [description of the input to module, its type
- definition, and length (when applicable)]
-
- Local Stores/Buffers/Pointers Needed:
- [local_store_name] = [description of the local store, its type
- definition, and length (when applicable)]
- [local_buffer_name] = [description of the local buffer, its type
- definition, and length (when applicable)]
- [local_ptr_name] = [description of the local pointer, its type
- definition, and length (when applicable)]
-
- Global Stores/Buffers/Pointers Needed:
- [global_store_name] = [description of the global store, its type
- definition, and length (when applicable)]
- [global_buffer_name] = [description of the global buffer, its type
- definition, and length (when applicable)]
- [global_ptr_name] = [description of the global pointer, its type
- definition, and length (when applicable)]
-
- Outputs:
- [return_variable_name] = [description of data/pointer returned
- by module, its type definition, and length
- (when applicable)]
-
- Pointers and Buffers Modified:
- [variable_bfr_ptr] points to the [describe where the
- variable_bfr_ptr points to, its type definition, and length
- (when applicable)]
- [variable_bfr] contents are [describe the new contents of
- variable_bfr]
-
- Local Stores Modified:
- [local_store_name] = [describe new contents, its type
- definition, and length (when applicable)]
-
- Global Stores Modified:
- [global_store_name] = [describe new contents, its type
- definition, and length (when applicable)]
-
-------------------------------------------------------------------------------
- FUNCTION DESCRIPTION
-
- For fast Deblock filtering
- Newer version (macroblock based processing)
-
-------------------------------------------------------------------------------
- REQUIREMENTS
-
- [List requirements to be satisfied by this module.]
-
-------------------------------------------------------------------------------
- REFERENCES
-
- [List all references used in designing this module.]
-
-------------------------------------------------------------------------------
- PSEUDO-CODE
-
-------------------------------------------------------------------------------
- RESOURCES USED
- When the code is written for a specific target processor the
- the resources used should be documented below.
-
- STACK USAGE: [stack count for this module] + [variable to represent
- stack usage for each subroutine called]
-
- where: [stack usage variable] = stack usage for [subroutine
- name] (see [filename].ext)
-
- DATA MEMORY USED: x words
-
- PROGRAM MEMORY USED: x words
-
- CLOCK CYCLES: [cycle count equation for this module] + [variable
- used to represent cycle count for each subroutine
- called]
-
- where: [cycle count variable] = cycle count for [subroutine
- name] (see [filename].ext)
-
-------------------------------------------------------------------------------
-*/
-
-
-/*----------------------------------------------------------------------------
-; INCLUDES
-----------------------------------------------------------------------------*/
-#include "mp4dec_lib.h"
-#include "post_proc.h"
-
-#define OSCL_DISABLE_WARNING_CONV_POSSIBLE_LOSS_OF_DATA
-
-/*----------------------------------------------------------------------------
-; MACROS
-; Define module specific macros here
-----------------------------------------------------------------------------*/
-//#define FILTER_LEN_8
-
-/*----------------------------------------------------------------------------
-; DEFINES
-; Include all pre-processor statements here. Include conditional
-; compile variables also.
-----------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------
-; LOCAL FUNCTION DEFINITIONS
-; Function Prototype declaration
-
-----------------------------------------------------------------------------
-; LOCAL STORE/BUFFER/POINTER DEFINITIONS
-; Variable declaration - defined here and used outside this module
-----------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------
-; EXTERNAL FUNCTION REFERENCES
-; Declare functions defined elsewhere and referenced in this module
-----------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------
-; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
-; Declare variables used in this module but defined elsewhere
-----------------------------------------------------------------------------*/
-#ifdef PV_POSTPROC_ON
-
-/*************************************************************************
- Function prototype : void CombinedHorzVertFilter( uint8 *rec,
- int width,
- int height,
- int *QP_store,
- int chr,
- uint8 *pp_mod)
- Parameters :
- rec : pointer to the decoded frame buffer.
- width : width of decoded frame.
- height : height of decoded frame
- QP_store: pointer to the array of QP corresponding to the decoded frame.
- It had only one value for each MB.
- chr : luma or color indication
- == 0 luma
- == 1 color
- pp_mod : The semphore used for deblocking
-
- Remark : The function do the deblocking on decoded frames.
- First based on the semaphore info., it is divided into hard and soft filtering.
- To differentiate real and fake edge, it then check the difference with QP to
- decide whether to do the filtering or not.
-
-*************************************************************************/
-
-
-/*----------------------------------------------------------------------------
-; FUNCTION CODE
-----------------------------------------------------------------------------*/
-void CombinedHorzVertFilter(
- uint8 *rec,
- int width,
- int height,
- int16 *QP_store,
- int chr,
- uint8 *pp_mod)
-{
-
- /*----------------------------------------------------------------------------
- ; Define all local variables
- ----------------------------------------------------------------------------*/
- int br, bc, mbr, mbc;
- int QP = 1;
- uint8 *ptr, *ptr_e;
- int pp_w, pp_h;
- int brwidth;
-
- int jVal0, jVal1, jVal2;
- /*----------------------------------------------------------------------------
- ; Function body here
- ----------------------------------------------------------------------------*/
- pp_w = (width >> 3);
- pp_h = (height >> 3);
-
- for (mbr = 0; mbr < pp_h; mbr += 2) /* row of blocks */
- {
- brwidth = mbr * pp_w; /* number of blocks above current block row */
- for (mbc = 0; mbc < pp_w; mbc += 2) /* col of blocks */
- {
- if (!chr)
- QP = QP_store[(brwidth>>2) + (mbc>>1)]; /* QP is per MB based value */
-
- /********* for each block **************/
- /****************** Horiz. Filtering ********************/
- for (br = mbr + 1; br < mbr + 3; br++) /* 2x2 blocks */
- {
- brwidth += pp_w; /* number of blocks above & left current block row */
- /* the profile on ARM920T shows separate these two boundary check is faster than combine them */
- if (br < pp_h) /* boundary : don't do it on the lowest row block */
- for (bc = mbc; bc < mbc + 2; bc++)
- {
- /****** check boundary for deblocking ************/
- if (bc < pp_w) /* boundary : don't do it on the most right col block */
- {
- ptr = rec + (brwidth << 6) + (bc << 3);
- jVal0 = brwidth + bc;
- if (chr) QP = QP_store[jVal0];
-
- ptr_e = ptr + 8; /* pointer to where the loop ends */
-
- if (((pp_mod[jVal0]&0x02)) && ((pp_mod[jVal0-pp_w]&0x02)))
- {
- /* Horiz Hard filter */
- do
- {
- jVal0 = *(ptr - width); /* C */
- jVal1 = *ptr; /* D */
- jVal2 = jVal1 - jVal0;
-
- if (((jVal2 > 0) && (jVal2 < (QP << 1)))
- || ((jVal2 < 0) && (jVal2 > -(QP << 1)))) /* (D-C) compared with 2QP */
- {
- /* differentiate between real and fake edge */
- jVal0 = ((jVal0 + jVal1) >> 1); /* (D+C)/2 */
- *(ptr - width) = (uint8)(jVal0); /* C */
- *ptr = (uint8)(jVal0); /* D */
-
- jVal0 = *(ptr - (width << 1)); /* B */
- jVal1 = *(ptr + width); /* E */
- jVal2 = jVal1 - jVal0; /* E-B */
-
- if (jVal2 > 0)
- {
- jVal0 += ((jVal2 + 3) >> 2);
- jVal1 -= ((jVal2 + 3) >> 2);
- *(ptr - (width << 1)) = (uint8)jVal0; /* store B */
- *(ptr + width) = (uint8)jVal1; /* store E */
- }
- else if (jVal2)
- {
- jVal0 -= ((3 - jVal2) >> 2);
- jVal1 += ((3 - jVal2) >> 2);
- *(ptr - (width << 1)) = (uint8)jVal0; /* store B */
- *(ptr + width) = (uint8)jVal1; /* store E */
- }
-
- jVal0 = *(ptr - (width << 1) - width); /* A */
- jVal1 = *(ptr + (width << 1)); /* F */
- jVal2 = jVal1 - jVal0; /* (F-A) */
-
- if (jVal2 > 0)
- {
- jVal0 += ((jVal2 + 7) >> 3);
- jVal1 -= ((jVal2 + 7) >> 3);
- *(ptr - (width << 1) - width) = (uint8)(jVal0);
- *(ptr + (width << 1)) = (uint8)(jVal1);
- }
- else if (jVal2)
- {
- jVal0 -= ((7 - jVal2) >> 3);
- jVal1 += ((7 - jVal2) >> 3);
- *(ptr - (width << 1) - width) = (uint8)(jVal0);
- *(ptr + (width << 1)) = (uint8)(jVal1);
- }
- }/* a3_0 > 2QP */
- }
- while (++ptr < ptr_e);
- }
- else /* Horiz soft filter*/
- {
- do
- {
- jVal0 = *(ptr - width); /* B */
- jVal1 = *ptr; /* C */
- jVal2 = jVal1 - jVal0; /* C-B */
-
- if (((jVal2 > 0) && (jVal2 < (QP)))
- || ((jVal2 < 0) && (jVal2 > -(QP)))) /* (C-B) compared with QP */
- {
-
- jVal0 = ((jVal0 + jVal1) >> 1); /* (B+C)/2 cannot overflow; ceil() */
- *(ptr - width) = (uint8)(jVal0); /* B = (B+C)/2 */
- *ptr = (uint8)jVal0; /* C = (B+C)/2 */
-
- jVal0 = *(ptr - (width << 1)); /* A */
- jVal1 = *(ptr + width); /* D */
- jVal2 = jVal1 - jVal0; /* D-A */
-
-
- if (jVal2 > 0)
- {
- jVal1 -= ((jVal2 + 7) >> 3);
- jVal0 += ((jVal2 + 7) >> 3);
- *(ptr - (width << 1)) = (uint8)jVal0; /* A */
- *(ptr + width) = (uint8)jVal1; /* D */
- }
- else if (jVal2)
- {
- jVal1 += ((7 - jVal2) >> 3);
- jVal0 -= ((7 - jVal2) >> 3);
- *(ptr - (width << 1)) = (uint8)jVal0; /* A */
- *(ptr + width) = (uint8)jVal1; /* D */
- }
- }
- }
- while (++ptr < ptr_e);
- } /* Soft filter*/
- }/* boundary checking*/
- }/*bc*/
- }/*br*/
- brwidth -= (pp_w << 1);
- /****************** Vert. Filtering ********************/
- for (br = mbr; br < mbr + 2; br++)
- {
- if (br < pp_h)
- for (bc = mbc + 1; bc < mbc + 3; bc++)
- {
- /****** check boundary for deblocking ************/
- if (bc < pp_w)
- {
- ptr = rec + (brwidth << 6) + (bc << 3);
- jVal0 = brwidth + bc;
- if (chr) QP = QP_store[jVal0];
-
- ptr_e = ptr + (width << 3);
-
- if (((pp_mod[jVal0-1]&0x01)) && ((pp_mod[jVal0]&0x01)))
- {
- /* Vert Hard filter */
- do
- {
- jVal1 = *ptr; /* D */
- jVal0 = *(ptr - 1); /* C */
- jVal2 = jVal1 - jVal0; /* D-C */
-
- if (((jVal2 > 0) && (jVal2 < (QP << 1)))
- || ((jVal2 < 0) && (jVal2 > -(QP << 1))))
- {
- jVal1 = (jVal0 + jVal1) >> 1; /* (C+D)/2 */
- *ptr = jVal1;
- *(ptr - 1) = jVal1;
-
- jVal1 = *(ptr + 1); /* E */
- jVal0 = *(ptr - 2); /* B */
- jVal2 = jVal1 - jVal0; /* E-B */
-
- if (jVal2 > 0)
- {
- jVal1 -= ((jVal2 + 3) >> 2); /* E = E -(E-B)/4 */
- jVal0 += ((jVal2 + 3) >> 2); /* B = B +(E-B)/4 */
- *(ptr + 1) = jVal1;
- *(ptr - 2) = jVal0;
- }
- else if (jVal2)
- {
- jVal1 += ((3 - jVal2) >> 2); /* E = E -(E-B)/4 */
- jVal0 -= ((3 - jVal2) >> 2); /* B = B +(E-B)/4 */
- *(ptr + 1) = jVal1;
- *(ptr - 2) = jVal0;
- }
-
- jVal1 = *(ptr + 2); /* F */
- jVal0 = *(ptr - 3); /* A */
-
- jVal2 = jVal1 - jVal0; /* (F-A) */
-
- if (jVal2 > 0)
- {
- jVal1 -= ((jVal2 + 7) >> 3); /* F -= (F-A)/8 */
- jVal0 += ((jVal2 + 7) >> 3); /* A += (F-A)/8 */
- *(ptr + 2) = jVal1;
- *(ptr - 3) = jVal0;
- }
- else if (jVal2)
- {
- jVal1 -= ((jVal2 - 7) >> 3); /* F -= (F-A)/8 */
- jVal0 += ((jVal2 - 7) >> 3); /* A += (F-A)/8 */
- *(ptr + 2) = jVal1;
- *(ptr - 3) = jVal0;
- }
- } /* end of ver hard filetering */
- }
- while ((ptr += width) < ptr_e);
- }
- else /* Vert soft filter*/
- {
- do
- {
- jVal1 = *ptr; /* C */
- jVal0 = *(ptr - 1); /* B */
- jVal2 = jVal1 - jVal0;
-
- if (((jVal2 > 0) && (jVal2 < (QP)))
- || ((jVal2 < 0) && (jVal2 > -(QP))))
- {
-
- jVal1 = (jVal0 + jVal1 + 1) >> 1;
- *ptr = jVal1; /* C */
- *(ptr - 1) = jVal1; /* B */
-
- jVal1 = *(ptr + 1); /* D */
- jVal0 = *(ptr - 2); /* A */
- jVal2 = (jVal1 - jVal0); /* D- A */
-
- if (jVal2 > 0)
- {
- jVal1 -= (((jVal2) + 7) >> 3); /* D -= (D-A)/8 */
- jVal0 += (((jVal2) + 7) >> 3); /* A += (D-A)/8 */
- *(ptr + 1) = jVal1;
- *(ptr - 2) = jVal0;
-
- }
- else if (jVal2)
- {
- jVal1 += ((7 - (jVal2)) >> 3); /* D -= (D-A)/8 */
- jVal0 -= ((7 - (jVal2)) >> 3); /* A += (D-A)/8 */
- *(ptr + 1) = jVal1;
- *(ptr - 2) = jVal0;
- }
- }
- }
- while ((ptr += width) < ptr_e);
- } /* Soft filter*/
- } /* boundary*/
- } /*bc*/
- brwidth += pp_w;
- }/*br*/
- brwidth -= (pp_w << 1);
- }/*mbc*/
- brwidth += (pp_w << 1);
- }/*mbr*/
- /*----------------------------------------------------------------------------
- ; Return nothing or data or data pointer
- ----------------------------------------------------------------------------*/
- return;
-}
-void CombinedHorzVertFilter_NoSoftDeblocking(
- uint8 *rec,
- int width,
- int height,
- int16 *QP_store,
- int chr,
- uint8 *pp_mod)
-{
-
- /*----------------------------------------------------------------------------
- ; Define all local variables
- ----------------------------------------------------------------------------*/
- int br, bc, mbr, mbc;
- int QP = 1;
- uint8 *ptr, *ptr_e;
- int pp_w, pp_h;
- int brwidth;
-
- int jVal0, jVal1, jVal2;
- /*----------------------------------------------------------------------------
- ; Function body here
- ----------------------------------------------------------------------------*/
- pp_w = (width >> 3);
- pp_h = (height >> 3);
-
- for (mbr = 0; mbr < pp_h; mbr += 2) /* row of blocks */
- {
- brwidth = mbr * pp_w; /* number of blocks above current block row */
- for (mbc = 0; mbc < pp_w; mbc += 2) /* col of blocks */
- {
- if (!chr)
- QP = QP_store[(brwidth>>2) + (mbc>>1)]; /* QP is per MB based value */
-
- /********* for each block **************/
- /****************** Horiz. Filtering ********************/
- for (br = mbr + 1; br < mbr + 3; br++) /* 2x2 blocks */
- {
- brwidth += pp_w; /* number of blocks above & left current block row */
- /* the profile on ARM920T shows separate these two boundary check is faster than combine them */
- if (br < pp_h) /* boundary : don't do it on the lowest row block */
- for (bc = mbc; bc < mbc + 2; bc++)
- {
- /****** check boundary for deblocking ************/
- if (bc < pp_w) /* boundary : don't do it on the most right col block */
- {
- ptr = rec + (brwidth << 6) + (bc << 3);
- jVal0 = brwidth + bc;
- if (chr) QP = QP_store[jVal0];
-
- ptr_e = ptr + 8; /* pointer to where the loop ends */
-
- if (((pp_mod[jVal0]&0x02)) && ((pp_mod[jVal0-pp_w]&0x02)))
- {
- /* Horiz Hard filter */
- do
- {
- jVal0 = *(ptr - width); /* C */
- jVal1 = *ptr; /* D */
- jVal2 = jVal1 - jVal0;
-
- if (((jVal2 > 0) && (jVal2 < (QP << 1)))
- || ((jVal2 < 0) && (jVal2 > -(QP << 1)))) /* (D-C) compared with 2QP */
- {
- /* differentiate between real and fake edge */
- jVal0 = ((jVal0 + jVal1) >> 1); /* (D+C)/2 */
- *(ptr - width) = (uint8)(jVal0); /* C */
- *ptr = (uint8)(jVal0); /* D */
-
- jVal0 = *(ptr - (width << 1)); /* B */
- jVal1 = *(ptr + width); /* E */
- jVal2 = jVal1 - jVal0; /* E-B */
-
- if (jVal2 > 0)
- {
- jVal0 += ((jVal2 + 3) >> 2);
- jVal1 -= ((jVal2 + 3) >> 2);
- *(ptr - (width << 1)) = (uint8)jVal0; /* store B */
- *(ptr + width) = (uint8)jVal1; /* store E */
- }
- else if (jVal2)
- {
- jVal0 -= ((3 - jVal2) >> 2);
- jVal1 += ((3 - jVal2) >> 2);
- *(ptr - (width << 1)) = (uint8)jVal0; /* store B */
- *(ptr + width) = (uint8)jVal1; /* store E */
- }
-
- jVal0 = *(ptr - (width << 1) - width); /* A */
- jVal1 = *(ptr + (width << 1)); /* F */
- jVal2 = jVal1 - jVal0; /* (F-A) */
-
- if (jVal2 > 0)
- {
- jVal0 += ((jVal2 + 7) >> 3);
- jVal1 -= ((jVal2 + 7) >> 3);
- *(ptr - (width << 1) - width) = (uint8)(jVal0);
- *(ptr + (width << 1)) = (uint8)(jVal1);
- }
- else if (jVal2)
- {
- jVal0 -= ((7 - jVal2) >> 3);
- jVal1 += ((7 - jVal2) >> 3);
- *(ptr - (width << 1) - width) = (uint8)(jVal0);
- *(ptr + (width << 1)) = (uint8)(jVal1);
- }
- }/* a3_0 > 2QP */
- }
- while (++ptr < ptr_e);
- }
-
- }/* boundary checking*/
- }/*bc*/
- }/*br*/
- brwidth -= (pp_w << 1);
- /****************** Vert. Filtering ********************/
- for (br = mbr; br < mbr + 2; br++)
- {
- if (br < pp_h)
- for (bc = mbc + 1; bc < mbc + 3; bc++)
- {
- /****** check boundary for deblocking ************/
- if (bc < pp_w)
- {
- ptr = rec + (brwidth << 6) + (bc << 3);
- jVal0 = brwidth + bc;
- if (chr) QP = QP_store[jVal0];
-
- ptr_e = ptr + (width << 3);
-
- if (((pp_mod[jVal0-1]&0x01)) && ((pp_mod[jVal0]&0x01)))
- {
- /* Vert Hard filter */
- do
- {
- jVal1 = *ptr; /* D */
- jVal0 = *(ptr - 1); /* C */
- jVal2 = jVal1 - jVal0; /* D-C */
-
- if (((jVal2 > 0) && (jVal2 < (QP << 1)))
- || ((jVal2 < 0) && (jVal2 > -(QP << 1))))
- {
- jVal1 = (jVal0 + jVal1) >> 1; /* (C+D)/2 */
- *ptr = jVal1;
- *(ptr - 1) = jVal1;
-
- jVal1 = *(ptr + 1); /* E */
- jVal0 = *(ptr - 2); /* B */
- jVal2 = jVal1 - jVal0; /* E-B */
-
- if (jVal2 > 0)
- {
- jVal1 -= ((jVal2 + 3) >> 2); /* E = E -(E-B)/4 */
- jVal0 += ((jVal2 + 3) >> 2); /* B = B +(E-B)/4 */
- *(ptr + 1) = jVal1;
- *(ptr - 2) = jVal0;
- }
- else if (jVal2)
- {
- jVal1 += ((3 - jVal2) >> 2); /* E = E -(E-B)/4 */
- jVal0 -= ((3 - jVal2) >> 2); /* B = B +(E-B)/4 */
- *(ptr + 1) = jVal1;
- *(ptr - 2) = jVal0;
- }
-
- jVal1 = *(ptr + 2); /* F */
- jVal0 = *(ptr - 3); /* A */
-
- jVal2 = jVal1 - jVal0; /* (F-A) */
-
- if (jVal2 > 0)
- {
- jVal1 -= ((jVal2 + 7) >> 3); /* F -= (F-A)/8 */
- jVal0 += ((jVal2 + 7) >> 3); /* A += (F-A)/8 */
- *(ptr + 2) = jVal1;
- *(ptr - 3) = jVal0;
- }
- else if (jVal2)
- {
- jVal1 -= ((jVal2 - 7) >> 3); /* F -= (F-A)/8 */
- jVal0 += ((jVal2 - 7) >> 3); /* A += (F-A)/8 */
- *(ptr + 2) = jVal1;
- *(ptr - 3) = jVal0;
- }
- } /* end of ver hard filetering */
- }
- while ((ptr += width) < ptr_e);
- }
-
- } /* boundary*/
- } /*bc*/
- brwidth += pp_w;
- }/*br*/
- brwidth -= (pp_w << 1);
- }/*mbc*/
- brwidth += (pp_w << 1);
- }/*mbr*/
- /*----------------------------------------------------------------------------
- ; Return nothing or data or data pointer
- ----------------------------------------------------------------------------*/
- return;
-}
-#endif
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/chvr_filter.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/chvr_filter.cpp
deleted file mode 100644
index 795cf71..0000000
--- a/media/libstagefright/codecs/m4v_h263/dec/src/chvr_filter.cpp
+++ /dev/null
@@ -1,565 +0,0 @@
-/* ------------------------------------------------------------------
- * Copyright (C) 1998-2009 PacketVideo
- *
- * 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.
- * -------------------------------------------------------------------
- */
-#include "mp4dec_lib.h"
-#include "post_proc.h"
-
-#ifdef PV_POSTPROC_ON
-
-void CombinedHorzVertRingFilter(
- uint8 *rec,
- int width,
- int height,
- int16 *QP_store,
- int chr,
- uint8 *pp_mod)
-{
-
- /*----------------------------------------------------------------------------
- ; Define all local variables
- ----------------------------------------------------------------------------*/
- int index, counter;
- int br, bc, incr, mbr, mbc;
- int QP = 1;
- int v[5];
- uint8 *ptr, *ptr_c, *ptr_n;
- int w1, w2, w3, w4;
- int pp_w, pp_h, brwidth;
- int sum, delta;
- int a3_0, a3_1, a3_2, A3_0;
- /* for Deringing Threshold approach (MPEG4)*/
- int max_diff, thres, v0, h0, min_blk, max_blk;
- int cnthflag;
-
- /*----------------------------------------------------------------------------
- ; Function body here
- ----------------------------------------------------------------------------*/
- /* Calculate the width and height of the area in blocks (divide by 8) */
- pp_w = (width >> 3);
- pp_h = (height >> 3);
-
- /* Set up various values needed for updating pointers into rec */
- w1 = width; /* Offset to next row in pixels */
- w2 = width << 1; /* Offset to two rows in pixels */
- w3 = w1 + w2; /* Offset to three rows in pixels */
- w4 = w2 << 1; /* Offset to four rows in pixels */
- incr = width - BLKSIZE; /* Offset to next row after processing block */
-
- /* Work through the area hortizontally by two rows per step */
- for (mbr = 0; mbr < pp_h; mbr += 2)
- {
- /* brwidth contains the block number of the leftmost block
- * of the current row */
- brwidth = mbr * pp_w;
-
- /* Work through the area vertically by two columns per step */
- for (mbc = 0; mbc < pp_w; mbc += 2)
- {
- /* if the data is luminance info, get the correct
- * quantization paramenter. One parameter per macroblock */
- if (!chr)
- {
- /* brwidth/4 is the macroblock number and mbc/2 is the macroblock col number*/
- QP = QP_store[(brwidth>>2) + (mbc>>1)];
- }
-
- /****************** Horiz. Filtering ********************/
- /* Process four blocks for the filtering */
- /********************************************************/
- /* Loop over two rows of blocks */
- for (br = mbr + 1; br < mbr + 3; br++) /* br is the row counter in blocks */
- {
- /* Set brwidth to the first (leftmost) block number of the next row */
- /* brwidth is used as an index when counting blocks */
- brwidth += pp_w;
-
- /* Loop over two columns of blocks in the row */
- for (bc = mbc; bc < mbc + 2; bc++) /* bc is the column counter in blocks */
- {
- /****** check boundary for deblocking ************/
- /* Execute if the row and column counters are within the area */
- if (br < pp_h && bc < pp_w)
- {
- /* Set the ptr to the first pixel of the first block of the second row
- * brwidth * 64 is the pixel row offset
- * bc * 8 is the pixel column offset */
- ptr = rec + (brwidth << 6) + (bc << 3);
-
- /* Set the index to the current block of the second row counting in blocks */
- index = brwidth + bc;
-
- /* if the data is chrominance info, get the correct
- * quantization paramenter. One parameter per block. */
- if (chr)
- {
- QP = QP_store[index];
- }
-
- /* Execute hard horizontal filter if semaphore for horizontal deblocking
- * is set for the current block and block immediately above it */
- if (((pp_mod[index]&0x02) != 0) && ((pp_mod[index-pp_w]&0x02) != 0))
- { /* Hard filter */
-
- /* Set HorzHflag (bit 4) in the pp_mod location */
- pp_mod[index-pp_w] |= 0x10; /* 4/26/00 reuse pp_mod for HorzHflag*/
-
- /* Filter across the 8 pixels of the block */
- for (index = BLKSIZE; index > 0; index--)
- {
- /* Difference between the current pixel and the pixel above it */
- a3_0 = *ptr - *(ptr - w1);
-
- /* if the magnitude of the difference is greater than the KThH threshold
- * and within the quantization parameter, apply hard filter */
- if ((a3_0 > KThH || a3_0 < -KThH) && a3_0<QP && a3_0> -QP)
- {
- ptr_c = ptr - w3; /* Points to pixel three rows above */
- ptr_n = ptr + w1; /* Points to pixel one row below */
- v[0] = (int)(*(ptr_c - w3));
- v[1] = (int)(*(ptr_c - w2));
- v[2] = (int)(*(ptr_c - w1));
- v[3] = (int)(*ptr_c);
- v[4] = (int)(*(ptr_c + w1));
-
- sum = v[0]
- + v[1]
- + v[2]
- + *ptr_c
- + v[4]
- + (*(ptr_c + w2))
- + (*(ptr_c + w3)); /* Current pixel */
-
- delta = (sum + *ptr_c + 4) >> 3; /* Average pixel values with rounding */
- *(ptr_c) = (uint8) delta;
-
- /* Move pointer down one row of pixels (points to pixel two rows
- * above current pixel) */
- ptr_c += w1;
-
- for (counter = 0; counter < 5; counter++)
- {
- /* Subtract off highest pixel and add in pixel below */
- sum = sum - v[counter] + *ptr_n;
- /* Average the pixel values with rounding */
- delta = (sum + *ptr_c + 4) >> 3;
- *ptr_c = (uint8)(delta);
-
- /* Increment pointers to next pixel row */
- ptr_c += w1;
- ptr_n += w1;
- }
- }
- /* Increment pointer to next pixel */
- ++ptr;
- } /* index*/
- }
- else
- { /* soft filter*/
-
- /* Clear HorzHflag (bit 4) in the pp_mod location */
- pp_mod[index-pp_w] &= 0xef; /* reset 1110,1111 */
-
- for (index = BLKSIZE; index > 0; index--)
- {
- /* Difference between the current pixel and the pixel above it */
- a3_0 = *(ptr) - *(ptr - w1);
-
- /* if the magnitude of the difference is greater than the KTh threshold,
- * apply soft filter */
- if ((a3_0 > KTh || a3_0 < -KTh))
- {
-
- /* Sum of weighted differences */
- a3_0 += ((*(ptr - w2) - *(ptr + w1)) << 1) + (a3_0 << 2);
-
- /* Check if sum is less than the quantization parameter */
- if (PV_ABS(a3_0) < (QP << 3))
- {
- a3_1 = *(ptr - w2) - *(ptr - w3);
- a3_1 += ((*(ptr - w4) - *(ptr - w1)) << 1) + (a3_1 << 2);
-
- a3_2 = *(ptr + w2) - *(ptr + w1);
- a3_2 += ((*(ptr) - *(ptr + w3)) << 1) + (a3_2 << 2);
-
- A3_0 = PV_ABS(a3_0) - PV_MIN(PV_ABS(a3_1), PV_ABS(a3_2));
-
- if (A3_0 > 0)
- {
- A3_0 += A3_0 << 2;
- A3_0 = (A3_0 + 32) >> 6;
- if (a3_0 > 0)
- {
- A3_0 = -A3_0;
- }
-
- delta = (*(ptr - w1) - *(ptr)) >> 1;
- if (delta >= 0)
- {
- if (delta >= A3_0)
- {
- delta = PV_MAX(A3_0, 0);
- }
- }
- else
- {
- if (A3_0 > 0)
- {
- delta = 0;
- }
- else
- {
- delta = PV_MAX(A3_0, delta);
- }
- }
-
- *(ptr - w1) = (uint8)(*(ptr - w1) - delta);
- *(ptr) = (uint8)(*(ptr) + delta);
- }
- } /*threshold*/
- }
- /* Increment pointer to next pixel */
- ++ptr;
- } /*index*/
- } /* Soft filter*/
- }/* boundary checking*/
- }/*bc*/
- }/*br*/
- brwidth -= (pp_w << 1);
-
-
- /****************** Vert. Filtering *********************/
- /* Process four blocks for the filtering */
- /********************************************************/
- /* Loop over two rows of blocks */
- for (br = mbr; br < mbr + 2; br++) /* br is the row counter in blocks */
- {
- for (bc = mbc + 1; bc < mbc + 3; bc++) /* bc is the column counter in blocks */
- {
- /****** check boundary for deblocking ************/
- /* Execute if the row and column counters are within the area */
- if (br < pp_h && bc < pp_w)
- {
- /* Set the ptr to the first pixel of the first block of the second row
- * brwidth * 64 is the pixel row offset
- * bc * 8 is the pixel column offset */
- ptr = rec + (brwidth << 6) + (bc << 3);
-
- /* Set the index to the current block of the second row counting in blocks */
- index = brwidth + bc;
-
- /* if the data is chrominance info, get the correct
- * quantization paramenter. One parameter per block. */
- if (chr)
- {
- QP = QP_store[index];
- }
-
- /* Execute hard vertical filter if semaphore for vertical deblocking
- * is set for the current block and block immediately left of it */
- if (((pp_mod[index-1]&0x01) != 0) && ((pp_mod[index]&0x01) != 0))
- { /* Hard filter */
-
- /* Set VertHflag (bit 5) in the pp_mod location of previous block*/
- pp_mod[index-1] |= 0x20; /* 4/26/00 reuse pp_mod for VertHflag*/
-
- /* Filter across the 8 pixels of the block */
- for (index = BLKSIZE; index > 0; index--)
- {
- /* Difference between the current pixel
- * and the pixel to left of it */
- a3_0 = *ptr - *(ptr - 1);
-
- /* if the magnitude of the difference is greater than the KThH threshold
- * and within the quantization parameter, apply hard filter */
- if ((a3_0 > KThH || a3_0 < -KThH) && a3_0<QP && a3_0> -QP)
- {
- ptr_c = ptr - 3;
- ptr_n = ptr + 1;
- v[0] = (int)(*(ptr_c - 3));
- v[1] = (int)(*(ptr_c - 2));
- v[2] = (int)(*(ptr_c - 1));
- v[3] = (int)(*ptr_c);
- v[4] = (int)(*(ptr_c + 1));
-
- sum = v[0]
- + v[1]
- + v[2]
- + *ptr_c
- + v[4]
- + (*(ptr_c + 2))
- + (*(ptr_c + 3));
-
- delta = (sum + *ptr_c + 4) >> 3;
- *(ptr_c) = (uint8) delta;
-
- /* Move pointer down one pixel to the right */
- ptr_c += 1;
- for (counter = 0; counter < 5; counter++)
- {
- /* Subtract off highest pixel and add in pixel below */
- sum = sum - v[counter] + *ptr_n;
- /* Average the pixel values with rounding */
- delta = (sum + *ptr_c + 4) >> 3;
- *ptr_c = (uint8)(delta);
-
- /* Increment pointers to next pixel */
- ptr_c += 1;
- ptr_n += 1;
- }
- }
- /* Increment pointers to next pixel row */
- ptr += w1;
- } /* index*/
- }
- else
- { /* soft filter*/
-
- /* Clear VertHflag (bit 5) in the pp_mod location */
- pp_mod[index-1] &= 0xdf; /* reset 1101,1111 */
- for (index = BLKSIZE; index > 0; index--)
- {
- /* Difference between the current pixel and the pixel above it */
- a3_0 = *(ptr) - *(ptr - 1);
-
- /* if the magnitude of the difference is greater than the KTh threshold,
- * apply soft filter */
- if ((a3_0 > KTh || a3_0 < -KTh))
- {
-
- /* Sum of weighted differences */
- a3_0 += ((*(ptr - 2) - *(ptr + 1)) << 1) + (a3_0 << 2);
-
- /* Check if sum is less than the quantization parameter */
- if (PV_ABS(a3_0) < (QP << 3))
- {
- a3_1 = *(ptr - 2) - *(ptr - 3);
- a3_1 += ((*(ptr - 4) - *(ptr - 1)) << 1) + (a3_1 << 2);
-
- a3_2 = *(ptr + 2) - *(ptr + 1);
- a3_2 += ((*(ptr) - *(ptr + 3)) << 1) + (a3_2 << 2);
-
- A3_0 = PV_ABS(a3_0) - PV_MIN(PV_ABS(a3_1), PV_ABS(a3_2));
-
- if (A3_0 > 0)
- {
- A3_0 += A3_0 << 2;
- A3_0 = (A3_0 + 32) >> 6;
- if (a3_0 > 0)
- {
- A3_0 = -A3_0;
- }
-
- delta = (*(ptr - 1) - *(ptr)) >> 1;
- if (delta >= 0)
- {
- if (delta >= A3_0)
- {
- delta = PV_MAX(A3_0, 0);
- }
- }
- else
- {
- if (A3_0 > 0)
- {
- delta = 0;
- }
- else
- {
- delta = PV_MAX(A3_0, delta);
- }
- }
-
- *(ptr - 1) = (uint8)(*(ptr - 1) - delta);
- *(ptr) = (uint8)(*(ptr) + delta);
- }
- } /*threshold*/
- }
- ptr += w1;
- } /*index*/
- } /* Soft filter*/
- } /* boundary*/
- } /*bc*/
- /* Increment pointer to next row of pixels */
- brwidth += pp_w;
- }/*br*/
- brwidth -= (pp_w << 1);
-
- /****************** Deringing ***************************/
- /* Process four blocks for the filtering */
- /********************************************************/
- /* Loop over two rows of blocks */
- for (br = mbr; br < mbr + 2; br++)
- {
- /* Loop over two columns of blocks in the row */
- for (bc = mbc; bc < mbc + 2; bc++)
- {
- /* Execute if the row and column counters are within the area */
- if (br < pp_h && bc < pp_w)
- {
- /* Set the index to the current block */
- index = brwidth + bc;
-
- /* Execute deringing if semaphore for deringing (bit-3 of pp_mod)
- * is set for the current block */
- if ((pp_mod[index]&0x04) != 0)
- {
- /* Don't process deringing if on an edge block */
- if (br > 0 && bc > 0 && br < pp_h - 1 && bc < pp_w - 1)
- {
- /* cnthflag = weighted average of HorzHflag of current,
- * one above, previous blocks*/
- cnthflag = ((pp_mod[index] & 0x10) +
- (pp_mod[index-pp_w] & 0x10) +
- ((pp_mod[index-1] >> 1) & 0x10) +
- ((pp_mod[index] >> 1) & 0x10)) >> 4; /* 4/26/00*/
-
- /* Do the deringing if decision flags indicate it's necessary */
- if (cnthflag < 3)
- {
- /* if the data is chrominance info, get the correct
- * quantization paramenter. One parameter per block. */
- if (chr)
- {
- QP = QP_store[index];
- }
-
- /* Set amount to change luminance if it needs to be changed
- * based on quantization parameter */
- max_diff = (QP >> 2) + 4;
-
- /* Set pointer to first pixel of current block */
- ptr = rec + (brwidth << 6) + (bc << 3);
-
- /* Find minimum and maximum value of pixel block */
- FindMaxMin(ptr, &min_blk, &max_blk, incr);
-
- /* threshold determination */
- thres = (max_blk + min_blk + 1) >> 1;
-
- /* If pixel range is greater or equal than DERING_THR, smooth the region */
- if ((max_blk - min_blk) >= DERING_THR) /*smooth 8x8 region*/
-#ifndef NoMMX
- {
- /* smooth all pixels in the block*/
- DeringAdaptiveSmoothMMX(ptr, width, thres, max_diff);
- }
-#else
- {
- /* Setup the starting point of the region to smooth */
- v0 = (br << 3) - 1;
- h0 = (bc << 3) - 1;
-
- /*smooth 8x8 region*/
- AdaptiveSmooth_NoMMX(rec, v0, h0, v0 + 1, h0 + 1, thres, width, max_diff);
- }
-#endif
- }/*cnthflag*/
- } /*dering br==1 or bc==1 (boundary block)*/
- else /* Process the boundary blocks */
- {
- /* Decide to perform deblocking based on the semaphore flags
- * of the neighboring blocks in each case. A certain number of
- * hard filtering flags have to be set in order to signal need
- * for smoothing */
- if (br > 0 && br < pp_h - 1)
- {
- if (bc > 0)
- {
- cnthflag = ((pp_mod[index-pp_w] & 0x10) +
- (pp_mod[index] & 0x10) +
- ((pp_mod[index-1] >> 1) & 0x10)) >> 4;
- }
- else
- {
- cnthflag = ((pp_mod[index] & 0x10) +
- (pp_mod[index-pp_w] & 0x10) +
- ((pp_mod[index] >> 1) & 0x10)) >> 4;
- }
- }
- else if (bc > 0 && bc < pp_w - 1)
- {
- if (br > 0)
- {
- cnthflag = ((pp_mod[index-pp_w] & 0x10) +
- ((pp_mod[index-1] >> 1) & 0x10) +
- ((pp_mod[index] >> 1) & 0x10)) >> 4;
- }
- else
- {
- cnthflag = ((pp_mod[index] & 0x10) +
- ((pp_mod[index-1] >> 1) & 0x10) +
- ((pp_mod[index] >> 1) & 0x10)) >> 4;
- }
- }
- else /* at the corner do default*/
- {
- cnthflag = 0;
- }
-
- /* Do the deringing if decision flags indicate it's necessary */
- if (cnthflag < 2)
- {
-
- /* if the data is chrominance info, get the correct
- * quantization paramenter. One parameter per block. */
- if (chr)
- {
- QP = QP_store[index];
- }
-
- /* Set amount to change luminance if it needs to be changed
- * based on quantization parameter */
- max_diff = (QP >> 2) + 4;
-
- /* Set pointer to first pixel of current block */
- ptr = rec + (brwidth << 6) + (bc << 3);
-
- /* Find minimum and maximum value of pixel block */
- FindMaxMin(ptr, &min_blk, &max_blk, incr);
-
- /* threshold determination */
- thres = (max_blk + min_blk + 1) >> 1;
-
- /* Setup the starting point of the region to smooth
- * This is going to be a 4x4 region */
- v0 = (br << 3) + 1;
- h0 = (bc << 3) + 1;
-
- /* If pixel range is greater or equal than DERING_THR, smooth the region */
- if ((max_blk - min_blk) >= DERING_THR)
- {
- /* Smooth 4x4 region */
- AdaptiveSmooth_NoMMX(rec, v0, h0, v0 - 3, h0 - 3, thres, width, max_diff);
- }
- }/*cnthflag*/
- } /* br==0, bc==0*/
- } /* dering*/
- } /*boundary condition*/
- }/*bc*/
- brwidth += pp_w;
- }/*br*/
- brwidth -= (pp_w << 1);
- }/*mbc*/
- brwidth += (pp_w << 1);
- }/*mbr*/
-
- /*----------------------------------------------------------------------------
- ; Return nothing or data or data pointer
- ----------------------------------------------------------------------------*/
- return ;
-}
-#endif
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/combined_decode.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/combined_decode.cpp
index 6499233..72cbe83 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/src/combined_decode.cpp
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/combined_decode.cpp
@@ -544,30 +544,12 @@
int16 DC_coeff;
PV_STATUS status;
-#ifdef PV_POSTPROC_ON
- /* post-processing */
- uint8 *pp_mod[6];
- int TotalMB = video->nTotalMB;
- int MB_in_width = video->nMBPerRow;
-#endif
int y_pos = video->mbnum_row;
int x_pos = video->mbnum_col;
int32 offset = (int32)(y_pos << 4) * width + (x_pos << 4);
/* Decode each 8-by-8 blocks. comp 0 ~ 3 are luminance blocks, 4 ~ 5 */
/* are chrominance blocks. 04/03/2000. */
-#ifdef PV_POSTPROC_ON
- if (video->postFilterType != PV_NO_POST_PROC)
- {
- /** post-processing ***/
- pp_mod[0] = video->pstprcTypCur + (y_pos << 1) * (MB_in_width << 1) + (x_pos << 1);
- pp_mod[1] = pp_mod[0] + 1;
- pp_mod[2] = pp_mod[0] + (MB_in_width << 1);
- pp_mod[3] = pp_mod[2] + 1;
- pp_mod[4] = video->pstprcTypCur + (TotalMB << 2) + mbnum;
- pp_mod[5] = pp_mod[4] + TotalMB;
- }
-#endif
/* oscl_memset(mblock->block, 0, sizeof(typeMBStore)); Aug 9,2005 */
@@ -645,10 +627,6 @@
}
no_coeff[comp] = ncoeffs[comp];
-#ifdef PV_POSTPROC_ON
- if (video->postFilterType != PV_NO_POST_PROC)
- *pp_mod[comp] = (uint8) PostProcSemaphore(dataBlock);
-#endif
}
MBlockIDCT(video);
}
@@ -677,20 +655,6 @@
BlockIDCT(c_comp + (comp&2)*(width << 2) + 8*(comp&1), mblock->pred_block + (comp&2)*64 + 8*(comp&1), mblock->block[comp], width, ncoeffs[comp],
mblock->bitmapcol[comp], mblock->bitmaprow[comp]);
-#ifdef PV_POSTPROC_ON
- /* for inter just test for ringing */
- if (video->postFilterType != PV_NO_POST_PROC)
- *pp_mod[comp] = (uint8)((ncoeffs[comp] > 3) ? 4 : 0);
-#endif
- }
- else
- {
- /* no IDCT for all zeros blocks 03/28/2002 */
- /* BlockIDCT(); */
-#ifdef PV_POSTPROC_ON
- if (video->postFilterType != PV_NO_POST_PROC)
- *pp_mod[comp] = 0;
-#endif
}
}
@@ -707,20 +671,6 @@
BlockIDCT(video->currVop->uChan + (offset >> 2) + (x_pos << 2), mblock->pred_block + 256, mblock->block[4], width >> 1, ncoeffs[4],
mblock->bitmapcol[4], mblock->bitmaprow[4]);
-#ifdef PV_POSTPROC_ON
- /* for inter just test for ringing */
- if (video->postFilterType != PV_NO_POST_PROC)
- *pp_mod[4] = (uint8)((ncoeffs[4] > 3) ? 4 : 0);
-#endif
- }
- else
- {
- /* no IDCT for all zeros blocks 03/28/2002 */
- /* BlockIDCT(); */
-#ifdef PV_POSTPROC_ON
- if (video->postFilterType != PV_NO_POST_PROC)
- *pp_mod[4] = 0;
-#endif
}
(*DC)[5] = mid_gray;
if (CBP & 1)
@@ -731,20 +681,6 @@
BlockIDCT(video->currVop->vChan + (offset >> 2) + (x_pos << 2), mblock->pred_block + 264, mblock->block[5], width >> 1, ncoeffs[5],
mblock->bitmapcol[5], mblock->bitmaprow[5]);
-#ifdef PV_POSTPROC_ON
- /* for inter just test for ringing */
- if (video->postFilterType != PV_NO_POST_PROC)
- *pp_mod[5] = (uint8)((ncoeffs[5] > 3) ? 4 : 0);
-#endif
- }
- else
- {
- /* no IDCT for all zeros blocks 03/28/2002 */
- /* BlockIDCT(); */
-#ifdef PV_POSTPROC_ON
- if (video->postFilterType != PV_NO_POST_PROC)
- *pp_mod[5] = 0;
-#endif
}
video->QPMB[mbnum] = QP; /* restore the QP values ANNEX_T*/
#else
@@ -759,20 +695,6 @@
BlockIDCT(c_comp + (comp&2)*(width << 2) + 8*(comp&1), mblock->pred_block + (comp&2)*64 + 8*(comp&1), mblock->block[comp], width, ncoeffs[comp],
mblock->bitmapcol[comp], mblock->bitmaprow[comp]);
-#ifdef PV_POSTPROC_ON
- /* for inter just test for ringing */
- if (video->postFilterType != PV_NO_POST_PROC)
- *pp_mod[comp] = (uint8)((ncoeffs[comp] > 3) ? 4 : 0);
-#endif
- }
- else
- {
- /* no IDCT for all zeros blocks 03/28/2002 */
- /* BlockIDCT(); */
-#ifdef PV_POSTPROC_ON
- if (video->postFilterType != PV_NO_POST_PROC)
- *pp_mod[comp] = 0;
-#endif
}
}
@@ -785,20 +707,11 @@
BlockIDCT(video->currVop->uChan + (offset >> 2) + (x_pos << 2), mblock->pred_block + 256, mblock->block[4], width >> 1, ncoeffs[4],
mblock->bitmapcol[4], mblock->bitmaprow[4]);
-#ifdef PV_POSTPROC_ON
- /* for inter just test for ringing */
- if (video->postFilterType != PV_NO_POST_PROC)
- *pp_mod[4] = (uint8)((ncoeffs[4] > 3) ? 4 : 0);
-#endif
}
else
{
/* no IDCT for all zeros blocks 03/28/2002 */
/* BlockIDCT(); */
-#ifdef PV_POSTPROC_ON
- if (video->postFilterType != PV_NO_POST_PROC)
- *pp_mod[4] = 0;
-#endif
}
(*DC)[5] = mid_gray;
if (CBP & 1)
@@ -809,20 +722,11 @@
BlockIDCT(video->currVop->vChan + (offset >> 2) + (x_pos << 2), mblock->pred_block + 264, mblock->block[5], width >> 1, ncoeffs[5],
mblock->bitmapcol[5], mblock->bitmaprow[5]);
-#ifdef PV_POSTPROC_ON
- /* for inter just test for ringing */
- if (video->postFilterType != PV_NO_POST_PROC)
- *pp_mod[5] = (uint8)((ncoeffs[5] > 3) ? 4 : 0);
-#endif
}
else
{
/* no IDCT for all zeros blocks 03/28/2002 */
/* BlockIDCT(); */
-#ifdef PV_POSTPROC_ON
- if (video->postFilterType != PV_NO_POST_PROC)
- *pp_mod[5] = 0;
-#endif
#endif // PV_ANNEX_IJKT_SUPPORT
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/datapart_decode.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/datapart_decode.cpp
index 00db04b..6071f40 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/src/datapart_decode.cpp
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/datapart_decode.cpp
@@ -635,29 +635,9 @@
int QP_tmp = QP;
int y_pos = video->mbnum_row;
-#ifdef PV_POSTPROC_ON
- uint8 *pp_mod[6];
- int TotalMB = video->nTotalMB;
- int MB_in_width = video->nMBPerRow;
-#endif
- /*****
- * Decoding of the 6 blocks (depending on transparent pattern)
- *****/
-#ifdef PV_POSTPROC_ON
- if (video->postFilterType != PV_NO_POST_PROC)
- {
- /** post-processing ***/
- pp_mod[0] = video->pstprcTypCur + (y_pos << 1) * (MB_in_width << 1) + (x_pos << 1);
- pp_mod[1] = pp_mod[0] + 1;
- pp_mod[2] = pp_mod[0] + (MB_in_width << 1);
- pp_mod[3] = pp_mod[2] + 1;
- pp_mod[4] = video->pstprcTypCur + (TotalMB << 2) + mbnum;
- pp_mod[5] = pp_mod[4] + TotalMB;
- }
-#endif
/* oscl_memset(mblock->block, 0, sizeof(typeMBStore)); Aug 9,2005 */
@@ -698,10 +678,6 @@
/* modified to new semaphore for post-proc */
// Future work:: can be combined in the dequant function
// @todo Deblocking Semaphore for INTRA block
-#ifdef PV_POSTPROC_ON
- if (video->postFilterType != PV_NO_POST_PROC)
- *pp_mod[comp] = (uint8) PostProcSemaphore(dataBlock);
-#endif
}
MBlockIDCT(video);
}
@@ -738,10 +714,6 @@
}
/* @todo Deblocking Semaphore for INTRA block, for inter just test for ringing */
-#ifdef PV_POSTPROC_ON
- if (video->postFilterType != PV_NO_POST_PROC)
- *pp_mod[comp] = (uint8)((ncoeffs[comp] > 3) ? 4 : 0);
-#endif
}
(*DC)[4] = mid_gray;
@@ -760,10 +732,6 @@
{
ncoeffs[4] = 0;
}
-#ifdef PV_POSTPROC_ON
- if (video->postFilterType != PV_NO_POST_PROC)
- *pp_mod[4] = (uint8)((ncoeffs[4] > 3) ? 4 : 0);
-#endif
(*DC)[5] = mid_gray;
if (CBP & 1)
{
@@ -780,10 +748,6 @@
{
ncoeffs[5] = 0;
}
-#ifdef PV_POSTPROC_ON
- if (video->postFilterType != PV_NO_POST_PROC)
- *pp_mod[5] = (uint8)((ncoeffs[5] > 3) ? 4 : 0);
-#endif
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/deringing_chroma.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/deringing_chroma.cpp
deleted file mode 100644
index ce779b0..0000000
--- a/media/libstagefright/codecs/m4v_h263/dec/src/deringing_chroma.cpp
+++ /dev/null
@@ -1,215 +0,0 @@
-/* ------------------------------------------------------------------
- * Copyright (C) 1998-2009 PacketVideo
- *
- * 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.
- * -------------------------------------------------------------------
- */
-#include "mp4dec_lib.h"
-#include "post_proc.h"
-
-#ifdef PV_POSTPROC_ON
-
-void Deringing_Chroma(
- uint8 *Rec_C,
- int width,
- int height,
- int16 *QP_store,
- int,
- uint8 *pp_mod
-)
-{
- /*----------------------------------------------------------------------------
- ; Define all local variables
- ----------------------------------------------------------------------------*/
- int thres;
- int v_blk, h_blk;
- int max_diff;
- int v_pel, h_pel;
- int max_blk, min_blk;
- int v0, h0;
- uint8 *ptr;
- int sum, sum1, incr;
- int32 addr_v;
- int sign_v[10], sum_v[10];
- int *ptr2, *ptr3;
- uint8 pelu, pelc, pell;
- incr = width - BLKSIZE;
-
- /*----------------------------------------------------------------------------
- ; Function body here
- ----------------------------------------------------------------------------*/
- /* chrominance */
- /* Do the first line (7 pixels at a time => Don't use MMX)*/
- for (h_blk = 0; h_blk < width; h_blk += BLKSIZE)
- {
- max_diff = (QP_store[h_blk>>3] >> 2) + 4;
- ptr = &Rec_C[h_blk];
- max_blk = min_blk = *ptr;
- FindMaxMin(ptr, &min_blk, &max_blk, width);
- h0 = ((h_blk - 1) >= 1) ? (h_blk - 1) : 1;
-
- if (max_blk - min_blk >= 4)
- {
- thres = (max_blk + min_blk + 1) >> 1;
-
-
- for (v_pel = 1; v_pel < BLKSIZE - 1; v_pel++)
- {
- addr_v = (int32)v_pel * width;
- ptr = &Rec_C[addr_v + h0 - 1];
- ptr2 = &sum_v[0];
- ptr3 = &sign_v[0];
-
- pelu = *(ptr - width);
- pelc = *ptr;
- pell = *(ptr + width);
- ptr++;
- *ptr2++ = pelu + (pelc << 1) + pell;
- *ptr3++ = INDEX(pelu, thres) + INDEX(pelc, thres) + INDEX(pell, thres);
-
- pelu = *(ptr - width);
- pelc = *ptr;
- pell = *(ptr + width);
- ptr++;
- *ptr2++ = pelu + (pelc << 1) + pell;
- *ptr3++ = INDEX(pelu, thres) + INDEX(pelc, thres) + INDEX(pell, thres);
-
- for (h_pel = h0; h_pel < h_blk + BLKSIZE - 1; h_pel++)
- {
- pelu = *(ptr - width);
- pelc = *ptr;
- pell = *(ptr + width);
-
- *ptr2 = pelu + (pelc << 1) + pell;
- *ptr3 = INDEX(pelu, thres) + INDEX(pelc, thres) + INDEX(pell, thres);
-
- sum1 = *(ptr3 - 2) + *(ptr3 - 1) + *ptr3;
- if (sum1 == 0 || sum1 == 9)
- {
- sum = (*(ptr2 - 2) + (*(ptr2 - 1) << 1) + *ptr2 + 8) >> 4;
-
- ptr--;
- if (PV_ABS(*ptr - sum) > max_diff)
- {
- if (sum > *ptr)
- sum = *ptr + max_diff;
- else
- sum = *ptr - max_diff;
- }
- *ptr++ = (uint8) sum;
- }
- ptr++;
- ptr2++;
- ptr3++;
- }
- }
- }
- }
-
- for (v_blk = BLKSIZE; v_blk < height; v_blk += BLKSIZE)
- {
- v0 = v_blk - 1;
- /* Do the first block (pixels=7 => No MMX) */
- max_diff = (QP_store[((((int32)v_blk*width)>>3))>>3] >> 2) + 4;
- ptr = &Rec_C[(int32)v_blk * width];
- max_blk = min_blk = *ptr;
- FindMaxMin(ptr, &min_blk, &max_blk, incr);
-
- if (max_blk - min_blk >= 4)
- {
- thres = (max_blk + min_blk + 1) >> 1;
-
- for (v_pel = v0; v_pel < v_blk + BLKSIZE - 1; v_pel++)
- {
- addr_v = v_pel * width;
- ptr = &Rec_C[addr_v];
- ptr2 = &sum_v[0];
- ptr3 = &sign_v[0];
-
- pelu = *(ptr - width);
- pelc = *ptr;
- pell = *(ptr + width);
- ptr++;
- *ptr2++ = pelu + (pelc << 1) + pell;
- *ptr3++ = INDEX(pelu, thres) + INDEX(pelc, thres) + INDEX(pell, thres);
-
- pelu = *(ptr - width);
- pelc = *ptr;
- pell = *(ptr + width);
- ptr++;
- *ptr2++ = pelu + (pelc << 1) + pell;
- *ptr3++ = INDEX(pelu, thres) + INDEX(pelc, thres) + INDEX(pell, thres);
-
- for (h_pel = 1; h_pel < BLKSIZE - 1; h_pel++)
- {
- pelu = *(ptr - width);
- pelc = *ptr;
- pell = *(ptr + width);
-
- *ptr2 = pelu + (pelc << 1) + pell;
- *ptr3 = INDEX(pelu, thres) + INDEX(pelc, thres) + INDEX(pell, thres);
-
- sum1 = *(ptr3 - 2) + *(ptr3 - 1) + *ptr3;
- if (sum1 == 0 || sum1 == 9)
- {
- sum = (*(ptr2 - 2) + (*(ptr2 - 1) << 1) + *ptr2 + 8) >> 4;
-
- ptr--;
- if (PV_ABS(*ptr - sum) > max_diff)
- {
- if (sum > *ptr)
- sum = *ptr + max_diff;
- else
- sum = *ptr - max_diff;
- }
- *ptr++ = (uint8) sum;
- }
- ptr++;
- ptr2++;
- ptr3++;
- }
- }
- }
-
-
- /* Do the rest in MMX */
- for (h_blk = BLKSIZE; h_blk < width; h_blk += BLKSIZE)
- {
- if ((pp_mod[(v_blk/8)*(width/8)+h_blk/8]&0x4) != 0)
- {
- max_diff = (QP_store[((((int32)v_blk*width)>>3)+h_blk)>>3] >> 2) + 4;
- ptr = &Rec_C[(int32)v_blk * width + h_blk];
- max_blk = min_blk = *ptr;
- FindMaxMin(ptr, &min_blk, &max_blk, incr);
- h0 = h_blk - 1;
-
- if (max_blk - min_blk >= 4)
- {
- thres = (max_blk + min_blk + 1) >> 1;
-#ifdef NoMMX
- AdaptiveSmooth_NoMMX(Rec_C, v0, h0, v_blk, h_blk, thres, width, max_diff);
-#else
- DeringAdaptiveSmoothMMX(&Rec_C[(int32)v0*width+h0], width, thres, max_diff);
-#endif
- }
- }
- }
- } /* macroblock level */
-
- /*----------------------------------------------------------------------------
- ; Return nothing or data or data pointer
- ----------------------------------------------------------------------------*/
- return;
-}
-#endif
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/deringing_luma.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/deringing_luma.cpp
deleted file mode 100644
index b5574b4..0000000
--- a/media/libstagefright/codecs/m4v_h263/dec/src/deringing_luma.cpp
+++ /dev/null
@@ -1,231 +0,0 @@
-/* ------------------------------------------------------------------
- * Copyright (C) 1998-2009 PacketVideo
- *
- * 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.
- * -------------------------------------------------------------------
- */
-#include "mp4dec_lib.h"
-#include "post_proc.h"
-
-#ifdef PV_POSTPROC_ON
-
-void Deringing_Luma(
- uint8 *Rec_Y,
- int width,
- int height,
- int16 *QP_store,
- int,
- uint8 *pp_mod)
-{
- /*----------------------------------------------------------------------------
- ; Define all local variables
- ----------------------------------------------------------------------------*/
- int thres[4], range[4], max_range_blk, max_thres_blk;
- int MB_V, MB_H, BLK_V, BLK_H;
- int v_blk, h_blk;
- int max_diff;
- int max_blk, min_blk;
- int v0, h0;
- uint8 *ptr;
- int thr, blks, incr;
- int mb_indx, blk_indx;
-
- /*----------------------------------------------------------------------------
- ; Function body here
- ----------------------------------------------------------------------------*/
- incr = width - BLKSIZE;
-
- /* Dering the first line of macro blocks */
- for (MB_H = 0; MB_H < width; MB_H += MBSIZE)
- {
- max_diff = (QP_store[(MB_H)>>4] >> 2) + 4;
-
- /* threshold determination */
- max_range_blk = max_thres_blk = 0;
- blks = 0;
-
- for (BLK_V = 0; BLK_V < MBSIZE; BLK_V += BLKSIZE)
- {
- for (BLK_H = 0; BLK_H < MBSIZE; BLK_H += BLKSIZE)
- {
- ptr = &Rec_Y[(int32)(BLK_V) * width + MB_H + BLK_H];
- FindMaxMin(ptr, &min_blk, &max_blk, incr);
-
- thres[blks] = (max_blk + min_blk + 1) >> 1;
- range[blks] = max_blk - min_blk;
-
- if (range[blks] >= max_range_blk)
- {
- max_range_blk = range[blks];
- max_thres_blk = thres[blks];
- }
- blks++;
- }
- }
-
- blks = 0;
- for (v_blk = 0; v_blk < MBSIZE; v_blk += BLKSIZE)
- {
- v0 = ((v_blk - 1) >= 1) ? (v_blk - 1) : 1;
- for (h_blk = MB_H; h_blk < MB_H + MBSIZE; h_blk += BLKSIZE)
- {
- h0 = ((h_blk - 1) >= 1) ? (h_blk - 1) : 1;
-
- /* threshold rearrangement for flat region adjacent to non-flat region */
- if (range[blks]<32 && max_range_blk >= 64)
- thres[blks] = max_thres_blk;
-
- /* threshold rearrangement for deblocking
- (blockiness annoying at DC dominant region) */
- if (max_range_blk >= 16)
- {
- /* adaptive smoothing */
- thr = thres[blks];
-
- AdaptiveSmooth_NoMMX(Rec_Y, v0, h0, v_blk, h_blk,
- thr, width, max_diff);
- }
- blks++;
- } /* block level (Luminance) */
- }
- } /* macroblock level */
-
-
- /* Do the rest of the macro-block-lines */
- for (MB_V = MBSIZE; MB_V < height; MB_V += MBSIZE)
- {
- /* First macro-block */
- max_diff = (QP_store[((((int32)MB_V*width)>>4))>>4] >> 2) + 4;
- /* threshold determination */
- max_range_blk = max_thres_blk = 0;
- blks = 0;
- for (BLK_V = 0; BLK_V < MBSIZE; BLK_V += BLKSIZE)
- {
- for (BLK_H = 0; BLK_H < MBSIZE; BLK_H += BLKSIZE)
- {
- ptr = &Rec_Y[(int32)(MB_V + BLK_V) * width + BLK_H];
- FindMaxMin(ptr, &min_blk, &max_blk, incr);
- thres[blks] = (max_blk + min_blk + 1) >> 1;
- range[blks] = max_blk - min_blk;
-
- if (range[blks] >= max_range_blk)
- {
- max_range_blk = range[blks];
- max_thres_blk = thres[blks];
- }
- blks++;
- }
- }
-
- blks = 0;
- for (v_blk = MB_V; v_blk < MB_V + MBSIZE; v_blk += BLKSIZE)
- {
- v0 = v_blk - 1;
- for (h_blk = 0; h_blk < MBSIZE; h_blk += BLKSIZE)
- {
- h0 = ((h_blk - 1) >= 1) ? (h_blk - 1) : 1;
-
- /* threshold rearrangement for flat region adjacent to non-flat region */
- if (range[blks]<32 && max_range_blk >= 64)
- thres[blks] = max_thres_blk;
-
- /* threshold rearrangement for deblocking
- (blockiness annoying at DC dominant region) */
- if (max_range_blk >= 16)
- {
- /* adaptive smoothing */
- thr = thres[blks];
-
- AdaptiveSmooth_NoMMX(Rec_Y, v0, h0, v_blk, h_blk,
- thr, width, max_diff);
- }
- blks++;
- }
- } /* block level (Luminance) */
-
- /* Rest of the macro-blocks */
- for (MB_H = MBSIZE; MB_H < width; MB_H += MBSIZE)
- {
- max_diff = (QP_store[((((int32)MB_V*width)>>4)+MB_H)>>4] >> 2) + 4;
-
- /* threshold determination */
- max_range_blk = max_thres_blk = 0;
- blks = 0;
-
- mb_indx = (MB_V / 8) * (width / 8) + MB_H / 8;
- for (BLK_V = 0; BLK_V < MBSIZE; BLK_V += BLKSIZE)
- {
- for (BLK_H = 0; BLK_H < MBSIZE; BLK_H += BLKSIZE)
- {
- blk_indx = mb_indx + (BLK_V / 8) * width / 8 + BLK_H / 8;
- /* Update based on pp_mod only */
- if ((pp_mod[blk_indx]&0x4) != 0)
- {
- ptr = &Rec_Y[(int32)(MB_V + BLK_V) * width + MB_H + BLK_H];
- FindMaxMin(ptr, &min_blk, &max_blk, incr);
- thres[blks] = (max_blk + min_blk + 1) >> 1;
- range[blks] = max_blk - min_blk;
-
- if (range[blks] >= max_range_blk)
- {
- max_range_blk = range[blks];
- max_thres_blk = thres[blks];
- }
- }
- blks++;
- }
- }
-
- blks = 0;
- for (v_blk = MB_V; v_blk < MB_V + MBSIZE; v_blk += BLKSIZE)
- {
- v0 = v_blk - 1;
- mb_indx = (v_blk / 8) * (width / 8);
- for (h_blk = MB_H; h_blk < MB_H + MBSIZE; h_blk += BLKSIZE)
- {
- h0 = h_blk - 1;
- blk_indx = mb_indx + h_blk / 8;
- if ((pp_mod[blk_indx]&0x4) != 0)
- {
- /* threshold rearrangement for flat region adjacent to non-flat region */
- if (range[blks]<32 && max_range_blk >= 64)
- thres[blks] = max_thres_blk;
-
- /* threshold rearrangement for deblocking
- (blockiness annoying at DC dominant region) */
- if (max_range_blk >= 16)
- {
- /* adaptive smoothing */
- thr = thres[blks];
-#ifdef NoMMX
- AdaptiveSmooth_NoMMX(Rec_Y, v0, h0, v_blk, h_blk,
- thr, width, max_diff);
-#else
- DeringAdaptiveSmoothMMX(&Rec_Y[v0*width+h0],
- width, thr, max_diff);
-#endif
- }
- }
- blks++;
- }
- } /* block level (Luminance) */
- } /* macroblock level */
- } /* macroblock level */
-
- /*----------------------------------------------------------------------------
- ; Return nothing or data or data pointer
- ----------------------------------------------------------------------------*/
- return;
-}
-#endif
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/find_min_max.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/find_min_max.cpp
deleted file mode 100644
index 1ac88a1..0000000
--- a/media/libstagefright/codecs/m4v_h263/dec/src/find_min_max.cpp
+++ /dev/null
@@ -1,176 +0,0 @@
-/* ------------------------------------------------------------------
- * Copyright (C) 1998-2009 PacketVideo
- *
- * 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.
- * -------------------------------------------------------------------
- */
-/*
-------------------------------------------------------------------------------
- INPUT AND OUTPUT DEFINITIONS
-
- Inputs:
- input_ptr = pointer to the buffer containing values of type UChar
- in a 2D block of data.
- min_ptr = pointer to the minimum value of type Int to be found in a
- square block of size BLKSIZE contained in 2D block of data.
- max_ptr = pointer to the maximum value of type Int to be found in a
- square block of size BLKSIZE contained in 2D block of data.
- incr = value of type Int representing the width of 2D block of data.
-
- Local Stores/Buffers/Pointers Needed:
- None
-
- Global Stores/Buffers/Pointers Needed:
- None
-
- Outputs:
- None
-
- Pointers and Buffers Modified:
- min_ptr points to the found minimum value in the square block of
- size BLKSIZE contained in 2D block of data.
-
- max_ptr points to the found maximum value in the square block of
- size BLKSIZE contained in 2D block of data.
-
- Local Stores Modified:
- None
-
- Global Stores Modified:
- None
-
-------------------------------------------------------------------------------
- FUNCTION DESCRIPTION
-
- This function finds the maximum and the minimum values in a square block of
- data of size BLKSIZE * BLKSIZE. The data is contained in the buffer which
- represents a 2D block of data that is larger than BLKSIZE * BLKSIZE.
- This is illustrated below.
-
- mem loc x + 00h -> o o o o o o o o o o o o o o o o
- mem loc x + 10h -> o o o o o X X X X X X X X o o o
- mem loc x + 20h -> o o o o o X X X X X X X X o o o
- mem loc x + 30h -> o o o o o X X X X X X X X o o o
- mem loc x + 40h -> o o o o o X X X X X X X X o o o
- mem loc x + 50h -> o o o o o X X X X X X X X o o o
- mem loc x + 60h -> o o o o o X X X X X X X X o o o
- mem loc x + 70h -> o o o o o X X X X X X X X o o o
- mem loc x + 80h -> o o o o o X X X X X X X X o o o
- mem loc x + 90h -> o o o o o o o o o o o o o o o o
- mem loc x + A0h -> o o o o o o o o o o o o o o o o
- mem loc x + B0h -> o o o o o o o o o o o o o o o o
-
-For illustration purposes, the diagram assumes that BLKSIZE is equal to 8
-but this is not a requirement. In this diagram, the buffer starts at
-location x but the input pointer, input_ptr, passed into this function
-would be the first row of data to be searched which is at x + 15h. The
-value of incr passed onto this function represents the amount the input_ptr
-needs to be incremented to point to the next row of data.
-
-This function compares each value in a row to the current maximum and
-minimum. After each row, input_ptr is incremented to point to the next row.
-This is repeated until all rows have been processed. When the search is
-complete the location pointed to by min_ptr contains the minimum value
-found and the location pointed to by max_ptr contains the maximum value found.
-
-------------------------------------------------------------------------------
-*/
-
-
-/*----------------------------------------------------------------------------
-; INCLUDES
-----------------------------------------------------------------------------*/
-#include "mp4dec_lib.h"
-#include "post_proc.h"
-
-/*----------------------------------------------------------------------------
-; MACROS
-; Define module specific macros here
-----------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------
-; DEFINES
-; Include all pre-processor statements here. Include conditional
-; compile variables also.
-----------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------
-; LOCAL FUNCTION DEFINITIONS
-; Function Prototype declaration
-----------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------
-; LOCAL STORE/BUFFER/POINTER DEFINITIONS
-; Variable declaration - defined here and used outside this module
-----------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------
-; EXTERNAL FUNCTION REFERENCES
-; Declare functions defined elsewhere and referenced in this module
-----------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------
-; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
-; Declare variables used in this module but defined elsewhere
-----------------------------------------------------------------------------*/
-
-#ifdef PV_POSTPROC_ON
-/*----------------------------------------------------------------------------
-; FUNCTION CODE
-----------------------------------------------------------------------------*/
-void FindMaxMin(
- uint8 *input_ptr,
- int *min_ptr,
- int *max_ptr,
- int incr)
-{
- /*----------------------------------------------------------------------------
- ; Define all local variables
- ----------------------------------------------------------------------------*/
- uint i, j;
- int min, max;
-
- /*----------------------------------------------------------------------------
- ; Function body here
- ----------------------------------------------------------------------------*/
- max = min = *input_ptr;
- /* incr = incr - BLKSIZE; */ /* 09/06/2001, already passed in as width - BLKSIZE */
-
- for (i = BLKSIZE; i > 0; i--)
- {
- for (j = BLKSIZE; j > 0; j--)
- {
- if (*input_ptr > max)
- {
- max = *input_ptr;
- }
- else if (*input_ptr < min)
- {
- min = *input_ptr;
- }
- input_ptr += 1;
- }
-
- /* set pointer to the beginning of the next row*/
- input_ptr += incr;
- }
-
- *max_ptr = max;
- *min_ptr = min;
- /*----------------------------------------------------------------------------
- ; Return nothing or data or data pointer
- ----------------------------------------------------------------------------*/
- return;
-}
-#endif
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/mb_motion_comp.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/mb_motion_comp.cpp
index 877723d..79760f5 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/src/mb_motion_comp.cpp
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/mb_motion_comp.cpp
@@ -154,14 +154,6 @@
int xpred, ypred;
int xsum;
int round1;
-#ifdef PV_POSTPROC_ON // 2/14/2001
- /* Total number of pixels in the VOL */
- int32 size = (int32) video->nTotalMB << 8;
- uint8 *pp_dec_y, *pp_dec_u;
- int ll[4];
- int tmp = 0;
- uint8 msk_deblock = 0;
-#endif
/*----------------------------------------------------------------------------
; Function body here
----------------------------------------------------------------------------*/
@@ -404,43 +396,6 @@
/* Call function to set de-blocking and de-ringing */
/* semaphores for luminance */
-#ifdef PV_POSTPROC_ON
- if (video->postFilterType != PV_NO_POST_PROC)
- {
- if (mode&INTER_1VMASK)
- {
- pp_dec_y = video->pstprcTypCur + imv;
- ll[0] = 1;
- ll[1] = mvwidth - 1;
- ll[2] = 1;
- ll[3] = -mvwidth - 1;
- msk_deblock = pp_semaphore_luma(xpred, ypred, pp_dec_y,
- video->pstprcTypPrv, ll, &tmp, px[0], py[0], mvwidth,
- width, height);
-
- pp_dec_u = video->pstprcTypCur + (size >> 6) +
- ((imv + (xpos >> 3)) >> 2);
-
- pp_semaphore_chroma_inter(xpred, ypred, pp_dec_u,
- video->pstprcTypPrv, dx, dy, mvwidth, height, size,
- tmp, msk_deblock);
- }
- else
- {
- /* Post-processing mode (MBM_INTER8) */
- /* deblocking and deringing) */
- pp_dec_y = video->pstprcTypCur + imv;
- *pp_dec_y = 4;
- *(pp_dec_y + 1) = 4;
- *(pp_dec_y + mvwidth) = 4;
- *(pp_dec_y + mvwidth + 1) = 4;
- pp_dec_u = video->pstprcTypCur + (size >> 6) +
- ((imv + (xpos >> 3)) >> 2);
- *pp_dec_u = 4;
- pp_dec_u[size>>8] = 4;
- }
- }
-#endif
/* xpred and ypred calculation for Chrominance is */
@@ -566,13 +521,6 @@
PIXEL *cv_comp, *cv_prev;
int width, width_uv;
int32 offset;
-#ifdef PV_POSTPROC_ON // 2/14/2001
- int imv;
- int32 size = (int32) video->nTotalMB << 8;
- uint8 *pp_dec_y, *pp_dec_u;
- uint8 *pp_prev1;
- int mvwidth = video->nMBPerRow << 1;
-#endif
width = video->width;
width_uv = width >> 1;
@@ -609,28 +557,6 @@
PutSKIPPED_B(cv_comp, cv_prev, width_uv);
/* 10/24/2000 post_processing semaphore generation */
-#ifdef PV_POSTPROC_ON // 2/14/2001
- if (video->postFilterType != PV_NO_POST_PROC)
- {
- imv = (offset >> 6) - (xpos >> 6) + (xpos >> 3);
- /* Post-processing mode (copy previous MB) */
- pp_prev1 = video->pstprcTypPrv + imv;
- pp_dec_y = video->pstprcTypCur + imv;
- *pp_dec_y = *pp_prev1;
- *(pp_dec_y + 1) = *(pp_prev1 + 1);
- *(pp_dec_y + mvwidth) = *(pp_prev1 + mvwidth);
- *(pp_dec_y + mvwidth + 1) = *(pp_prev1 + mvwidth + 1);
-
- /* chrominance */
- /*4*MB_in_width*MB_in_height*/
- pp_prev1 = video->pstprcTypPrv + (size >> 6) +
- ((imv + (xpos >> 3)) >> 2);
- pp_dec_u = video->pstprcTypCur + (size >> 6) +
- ((imv + (xpos >> 3)) >> 2);
- *pp_dec_u = *pp_prev1;
- pp_dec_u[size>>8] = pp_prev1[size>>8];
- }
-#endif
/*----------------------------------------------------------------------------
; Return nothing or data or data pointer
----------------------------------------------------------------------------*/
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/mp4dec_lib.h b/media/libstagefright/codecs/m4v_h263/dec/src/mp4dec_lib.h
index 9cd4edc..ce6f9c3 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/src/mp4dec_lib.h
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/mp4dec_lib.h
@@ -170,37 +170,6 @@
/*--------------------------------------------------------------------------*/
/* defined in pp_semaphore_chroma_inter.c */
-#ifdef PV_POSTPROC_ON
- void pp_semaphore_chroma_inter(
- int xpred, /* i */
- int ypred, /* i */
- uint8 *pp_dec_u, /* i/o */
- uint8 *pstprcTypPrv, /* i */
- int dx, /* i */
- int dy, /* i */
- int mvwidth, /* i */
- int height, /* i */
- int32 size, /* i */
- int mv_loc, /* i */
- uint8 msk_deblock /* i */
- );
-
- /*--------------------------------------------------------------------------*/
- /* defined in pp_semaphore_luma.c */
- uint8 pp_semaphore_luma(
- int xpred, /* i */
- int ypred, /* i */
- uint8 *pp_dec_y, /* i/o */
- uint8 *pstprcTypPrv, /* i */
- int *ll, /* i */
- int *mv_loc, /* i/o */
- int dx, /* i */
- int dy, /* i */
- int mvwidth, /* i */
- int width, /* i */
- int height /* i */
- );
-#endif
/*--------------------------------------------------------------------------*/
/* defined in get_pred_adv_mb_add.c */
int GetPredAdvancedMB(
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/post_filter.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/post_filter.cpp
index b36050c..37a03a0 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/src/post_filter.cpp
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/post_filter.cpp
@@ -24,152 +24,6 @@
const static int STRENGTH_tab[] = {0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 12};
#endif
-#ifdef PV_POSTPROC_ON
-/*----------------------------------------------------------------------------
-; FUNCTION CODE
-----------------------------------------------------------------------------*/
-void PostFilter(
- VideoDecData *video,
- int filter_type,
- uint8 *output)
-{
- /*----------------------------------------------------------------------------
- ; Define all local variables
- ----------------------------------------------------------------------------*/
- uint8 *pp_mod;
- int16 *QP_store;
- int combined_with_deblock_filter;
- int nTotalMB = video->nTotalMB;
- int width, height;
- int32 size;
- int softDeblocking;
- uint8 *decodedFrame = video->videoDecControls->outputFrame;
- /*----------------------------------------------------------------------------
- ; Function body here
- ----------------------------------------------------------------------------*/
- width = video->width;
- height = video->height;
- size = (int32)width * height;
-
- oscl_memcpy(output, decodedFrame, size);
- oscl_memcpy(output + size, decodedFrame + size, (size >> 2));
- oscl_memcpy(output + size + (size >> 2), decodedFrame + size + (size >> 2), (size >> 2));
-
- if (filter_type == 0)
- return;
-
- /* The softDecoding cutoff corresponds to ~93000 bps for QCIF 15fps clip */
- if (PVGetDecBitrate(video->videoDecControls) > (100*video->frameRate*(size >> 12))) // MC_sofDeblock
- softDeblocking = FALSE;
- else
- softDeblocking = TRUE;
-
- combined_with_deblock_filter = filter_type & PV_DEBLOCK;
- QP_store = video->QPMB;
-
- /* Luma */
- pp_mod = video->pstprcTypCur;
-
- if ((filter_type & PV_DEBLOCK) && (filter_type & PV_DERING))
- {
- CombinedHorzVertRingFilter(output, width, height, QP_store, 0, pp_mod);
- }
- else
- {
- if (filter_type & PV_DEBLOCK)
- {
- if (softDeblocking)
- {
- CombinedHorzVertFilter(output, width, height,
- QP_store, 0, pp_mod);
- }
- else
- {
- CombinedHorzVertFilter_NoSoftDeblocking(output, width, height,
- QP_store, 0, pp_mod);
- }
- }
- if (filter_type & PV_DERING)
- {
- Deringing_Luma(output, width, height, QP_store,
- combined_with_deblock_filter, pp_mod);
-
- }
- }
-
- /* Chroma */
-
- pp_mod += (nTotalMB << 2);
- output += size;
-
- if ((filter_type & PV_DEBLOCK) && (filter_type & PV_DERING))
- {
- CombinedHorzVertRingFilter(output, (int)(width >> 1), (int)(height >> 1), QP_store, (int) 1, pp_mod);
- }
- else
- {
- if (filter_type & PV_DEBLOCK)
- {
- if (softDeblocking)
- {
- CombinedHorzVertFilter(output, (int)(width >> 1),
- (int)(height >> 1), QP_store, (int) 1, pp_mod);
- }
- else
- {
- CombinedHorzVertFilter_NoSoftDeblocking(output, (int)(width >> 1),
- (int)(height >> 1), QP_store, (int) 1, pp_mod);
- }
- }
- if (filter_type & PV_DERING)
- {
- Deringing_Chroma(output, (int)(width >> 1),
- (int)(height >> 1), QP_store,
- combined_with_deblock_filter, pp_mod);
- }
- }
-
- pp_mod += nTotalMB;
- output += (size >> 2);
-
- if ((filter_type & PV_DEBLOCK) && (filter_type & PV_DERING))
- {
- CombinedHorzVertRingFilter(output, (int)(width >> 1), (int)(height >> 1), QP_store, (int) 1, pp_mod);
- }
- else
- {
- if (filter_type & PV_DEBLOCK)
- {
- if (softDeblocking)
- {
- CombinedHorzVertFilter(output, (int)(width >> 1),
- (int)(height >> 1), QP_store, (int) 1, pp_mod);
- }
- else
- {
- CombinedHorzVertFilter_NoSoftDeblocking(output, (int)(width >> 1),
- (int)(height >> 1), QP_store, (int) 1, pp_mod);
- }
- }
- if (filter_type & PV_DERING)
- {
- Deringing_Chroma(output, (int)(width >> 1),
- (int)(height >> 1), QP_store,
- combined_with_deblock_filter, pp_mod);
- }
- }
-
- /* swap current pp_mod to prev_frame pp_mod */
- pp_mod = video->pstprcTypCur;
- video->pstprcTypCur = video->pstprcTypPrv;
- video->pstprcTypPrv = pp_mod;
-
- /*----------------------------------------------------------------------------
- ; Return nothing or data or data pointer
- ----------------------------------------------------------------------------*/
- return;
-}
-#endif
#ifdef PV_ANNEX_IJKT_SUPPORT
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/post_proc_semaphore.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/post_proc_semaphore.cpp
deleted file mode 100644
index 3abc6be..0000000
--- a/media/libstagefright/codecs/m4v_h263/dec/src/post_proc_semaphore.cpp
+++ /dev/null
@@ -1,247 +0,0 @@
-/* ------------------------------------------------------------------
- * Copyright (C) 1998-2009 PacketVideo
- *
- * 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.
- * -------------------------------------------------------------------
- */
-/*
-------------------------------------------------------------------------------
- INPUT AND OUTPUT DEFINITIONS
-
- Inputs:
- q_block = pointer to buffer of inverse quantized DCT coefficients of type
- int for intra-VOP mode or buffer of residual data of type int
- for inter-VOP mode
-
- Local Stores/Buffers/Pointers Needed:
- None
-
- Global Stores/Buffers/Pointers Needed:
- None
-
- Outputs:
- postmode = post processing semaphore with the vertical deblocking,
- horizontal deblocking, and deringing bits set up accordingly
-
- Pointers and Buffers Modified:
- None
-
- Local Stores Modified:
- None
-
- Global Stores Modified:
- None
-
-------------------------------------------------------------------------------
- FUNCTION DESCRIPTION
-
- This function sets up the postmode semaphore based on the contents of the
- buffer pointed to by q_block. The function starts out with the assumption
- that all entries of q_block, except for the first entry (q_block[0]), are
- zero. This case can induce horizontal and vertical blocking artifacts,
- therefore, both horizontal and vertical deblocking bits are enabled.
-
- The following conditions are tested when setting up the horizontal/vertical
- deblocking and deringing bits:
- 1. When only the elements of the top row of the B_SIZE x B_SIZE block
- (q_block[n], n = 0,..., B_SIZE-1) are non-zero, vertical blocking artifacts
- may result, therefore, only the vertical deblocking bit is enabled.
- Otherwise, the vertical deblocking bit is disabled.
- 2. When only the elements of the far left column of the B_SIZE x B_SIZE block
- (q_block[n*B_SIZE], n = 0, ..., B_SIZE-1) are non-zero, horizontal blocking
- artifacts may result, therefore, only the horizontal deblocking bit is
- enabled. Otherwise, the horizontal deblocking bit is disabled.
- 3. If any non-zero elements exist in positions other than q_block[0],
- q_block[1], or q_block[B_SIZE], the deringing bit is enabled. Otherwise,
- it is disabled.
-
- The 3 least significant bits of postmode defines vertical or horizontal
- deblocking and deringing.
-
- The valid values are shown below:
- -------------------------------------------------------
- | Type | Enabled | Disabled |
- -------------------------------------------------------
- | Vertical Deblocking (Bit #0) | 1 | 0 |
- -------------------------------------------------------
- | Horizontal Deblocking (Bit #1) | 1 | 0 |
- -------------------------------------------------------
- | Deringing (Bit #2) | 1 | 0 |
- -------------------------------------------------------
-
-*/
-
-
-/*----------------------------------------------------------------------------
-; INCLUDES
-----------------------------------------------------------------------------*/
-#include "mp4dec_lib.h"
-#include "mp4def.h"
-#include "post_proc.h"
-
-/*----------------------------------------------------------------------------
-; MACROS
-; Define module specific macros here
-----------------------------------------------------------------------------*/
-
-
-/*----------------------------------------------------------------------------
-; DEFINES
-; Include all pre-processor statements here. Include conditional
-; compile variables also.
-----------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------
-; LOCAL FUNCTION DEFINITIONS
-; Function Prototype declaration
-----------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------
-; LOCAL STORE/BUFFER/POINTER DEFINITIONS
-; Variable declaration - defined here and used outside this module
-----------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------
-; EXTERNAL FUNCTION REFERENCES
-; Declare functions defined elsewhere and referenced in this module
-----------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------
-; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
-; Declare variables used in this module but defined elsewhere
-----------------------------------------------------------------------------*/
-#ifdef PV_POSTPROC_ON
-/*----------------------------------------------------------------------------
-; FUNCTION CODE
-----------------------------------------------------------------------------*/
-int PostProcSemaphore(
- int16 *q_block)
-{
- /*----------------------------------------------------------------------------
- ; Define all local variables
- ----------------------------------------------------------------------------*/
- int i, j;
-
- /* Set default value to vertical and horizontal deblocking enabled */
- /* Initial assumption is that only q_block[0] element is non-zero, */
- /* therefore, vertical and horizontal deblocking bits are set to 1 */
- int postmode = 0x3;
-
- /*----------------------------------------------------------------------------
- ; Function body here
- ----------------------------------------------------------------------------*/
- /* Vertical deblocking bit is enabled when only the entire top row of */
- /* the B_SIZE x B_SIZE block, i.e., q_block[n], n = 0,..., B_SIZE-1, */
- /* are non-zero. Since initial assumption is that all elements, except */
- /* q_block[0], is zero, we need to check the remaining elements in the */
- /* top row to determine if all or some are non-zero. */
- if (q_block[1] != 0)
- {
- /* At this point, q_block[0] and q_block[1] are non-zero, while */
- /* q_block[n], n = 2,..., B_SIZE-1, are zero. Therefore, we */
- /* need to disable vertical deblocking */
- postmode &= 0xE;
- }
-
- for (i = 2; i < B_SIZE; i++)
- {
- if (q_block[i])
- {
- /* Check if q_block[n], n = 2,..., B_SIZE-1, are non-zero.*/
- /* If any of them turn out to be non-zero, we need to */
- /* disable vertical deblocking. */
- postmode &= 0xE;
-
- /* Deringing is enabled if any nonzero elements exist in */
- /* positions other than q_block[0], q_block[1] or */
- /* q_block[B_SIZE]. */
- postmode |= 0x4;
-
- break;
- }
- }
-
- /* Horizontal deblocking bit is enabled when only the entire far */
- /* left column, i.e., q_block[n*B_SIZE], n = 0, ..., B_SIZE-1, */
- /* are non-zero. Since initial assumption is that all elements, */
- /* except q_block[0], is zero, we need to check the remaining */
- /* elements in the far left column to determine if all or some */
- /* are non-zero. */
- if (q_block[B_SIZE])
- {
- /* At this point, only q_block[0] and q_block[B_SIZE] are non-zero, */
- /* while q_block[n*B_SIZE], n = 2, 3,..., B_SIZE-1, are zero. */
- /* Therefore, we need to disable horizontal deblocking. */
- postmode &= 0xD;
- }
-
- for (i = 16; i < NCOEFF_BLOCK; i += B_SIZE)
- {
- if (q_block[i])
- {
- /* Check if q_block[n], n = 2*B_SIZE,...,(B_SIZE-1)*B_SIZE, */
- /* are non-zero. If any of them turn out to be non-zero, */
- /* we need to disable horizontal deblocking. */
- postmode &= 0xD;
-
- /* Deringing is enabled if any nonzero elements exist in */
- /* positions other than q_block[0], q_block[1] or */
- /* q_block[B_SIZE]. */
- postmode |= 0x4;
-
- break;
- }
- }
-
- /* At this point, only the first row and far left column elements */
- /* have been tested. If deringing bit is still not set at this */
- /* point, check the rest of q_block to determine if the elements */
- /* are non-zero. If all elements, besides q_block[0], q_block[1], */
- /* or q_block[B_SIZE] are non-zero, deringing bit must be set */
- if ((postmode & 0x4) == 0)
- {
- for (i = 1; i < B_SIZE; i++)
- {
- for (j = 1; j < B_SIZE; j++)
- {
- if (q_block[(i<<3)+j])
- {
- /* At this point, q_block[0] and another q_block */
- /* element are non-zero, therefore, we need to */
- /* disable vertical and horizontal deblocking */
- postmode &= 0xC;
-
- /* Deringing is enabled if any nonzero elements exist in */
- /* positions other than q_block[0], q_block[1] or */
- /* q_block[B_SIZE]. */
- postmode |= 0x4;
-
- /* Set outer FOR loop count to B_SIZE to get out of */
- /* outer FOR loop */
- i = B_SIZE;
-
- /* Get out of inner FOR loop */
- break;
- }
- }
- }
- }
-
- /*----------------------------------------------------------------------------
- ; Return nothing or data or data pointer
- ----------------------------------------------------------------------------*/
- return (postmode);
-}
-
-#endif
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/pp_semaphore_chroma_inter.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/pp_semaphore_chroma_inter.cpp
deleted file mode 100644
index 7c20222..0000000
--- a/media/libstagefright/codecs/m4v_h263/dec/src/pp_semaphore_chroma_inter.cpp
+++ /dev/null
@@ -1,262 +0,0 @@
-/* ------------------------------------------------------------------
- * Copyright (C) 1998-2009 PacketVideo
- *
- * 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.
- * -------------------------------------------------------------------
- */
-/*
-------------------------------------------------------------------------------
- INPUT AND OUTPUT DEFINITIONS
-
- Inputs:
- xpred = x-axis coordinate of the block used for prediction (int)
- ypred = y-axis coordinate of the block used for prediction (int)
- pp_dec_u = pointer to the post processing semaphore for chrominance
- (uint8)
- pstprcTypPrv = pointer the previous frame's post processing type
- (uint8)
- dx = horizontal component of the motion vector (int)
- dy = vertical component of the motion vector (int)
- mvwidth = number of blocks per row in the luminance VOP (int)
- height = luminance VOP height in pixels (int)
- size = total number of pixel in the current luminance VOP (int)
- mv_loc = flag indicating location of the motion compensated
- (x,y) position with respect to the luminance MB (int);
- 0 -> inside MB, 1 -> outside MB
- msk_deblock = flag indicating whether to perform deblocking
- (msk_deblock = 0) or not (msk_deblock = 1) (uint8)
-
- Local Stores/Buffers/Pointers Needed:
- None
-
- Global Stores/Buffers/Pointers Needed:
- None
-
- Outputs:
- None
-
- Pointers and Buffers Modified:
- pp_dec_u contents are the updated semaphore propagation data
-
- Local Stores Modified:
- None
-
- Global Stores Modified:
- None
-
-------------------------------------------------------------------------------
- FUNCTION DESCRIPTION
-
- This functions performs post processing semaphore propagation processing
- after chrominance prediction in interframe processing mode.
-
-*/
-
-
-/*----------------------------------------------------------------------------
-; INCLUDES
-----------------------------------------------------------------------------*/
-#include "mp4dec_api.h"
-#include "mp4def.h"
-
-/*----------------------------------------------------------------------------
-; MACROS
-; Define module specific macros here
-----------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------
-; DEFINES
-; Include all pre-processor statements here. Include conditional
-; compile variables also.
-----------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------
-; LOCAL FUNCTION DEFINITIONS
-; Function Prototype declaration
-----------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------
-; LOCAL STORE/BUFFER/POINTER DEFINITIONS
-; Variable declaration - defined here and used outside this module
-----------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------
-; EXTERNAL FUNCTION REFERENCES
-; Declare functions defined elsewhere and referenced in this module
-----------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------
-; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
-; Declare variables used in this module but defined elsewhere
-----------------------------------------------------------------------------*/
-#ifdef PV_POSTPROC_ON
-#ifdef __cplusplus
-extern "C"
-{
-#endif
- /*----------------------------------------------------------------------------
- ; FUNCTION CODE
- ----------------------------------------------------------------------------*/
- void pp_semaphore_chroma_inter(
- int xpred, /* i */
- int ypred, /* i */
- uint8 *pp_dec_u, /* i/o */
- uint8 *pstprcTypPrv, /* i */
- int dx, /* i */
- int dy, /* i */
- int mvwidth, /* i */
- int height, /* i */
- int32 size, /* i */
- int mv_loc, /* i */
- uint8 msk_deblock /* i */
- )
- {
- /*----------------------------------------------------------------------------
- ; Define all local variables
- ----------------------------------------------------------------------------*/
- int mmvy, mmvx, nmvy, nmvx;
- uint8 *pp_prev1, *pp_prev2, *pp_prev3, *pp_prev4;
-
- /*----------------------------------------------------------------------------
- ; Function body here
- ----------------------------------------------------------------------------*/
-
- /* 09/28/2000, modify semaphore propagation to */
- /* accommodate smart indexing */
- mmvx = xpred >> 4; /* block x coor */
- nmvx = mmvx;
-
- mmvy = ypred >> 4; /* block y coor */
- nmvy = mmvy;
-
- /* Check if MV is outside the frame */
- if (mv_loc == 1)
- {
- /* Perform boundary check */
- if (nmvx < 0)
- {
- nmvx = 0;
- }
- else if (nmvx > mvwidth - 1)
- {
- nmvx = mvwidth - 1;
- }
-
- if (nmvy < 0)
- {
- nmvy = 0;
- }
- else if (nmvy > (height >> 4) - 1)
- {
- nmvy = (height >> 4) - 1;
- }
- }
-
- /* Calculate pointer to first chrominance b semaphores in */
- /* pstprcTypPrv, i.e., first chrominance b semaphore is in */
- /* (pstprcTypPrv + (size>>6)). */
- /* Since total number of chrominance blocks per row in a VOP */
- /* is half of the total number of luminance blocks per row in a */
- /* VOP, we use (mvwidth >> 1) when calculating the row offset. */
- pp_prev1 = pstprcTypPrv + (size >> 6) + nmvx + nmvy * (mvwidth >> 1) ;
-
- /* Check if MV is a multiple of 16 */
- /* 1/5/01, make sure it doesn't go out of bound */
- if (((dy&0xF) != 0) && (mmvy + 1 < (height >> 4) - 1))
- { /* dy is not a multiple of 16 */
-
- /* pp_prev3 is the block below pp_prev1 block */
- pp_prev3 = pp_prev1 + (mvwidth >> 1);
- }
- else
- { /* dy is a multiple of 16 */
- pp_prev3 = pp_prev1;
- }
-
- /* 1/5/01, make sure it doesn't go out of bound */
- if (((dx&0xF) != 0) && (mmvx + 1 < (mvwidth >> 1) - 1))
- { /* dx is not a multiple of 16 */
-
- /* pp_prev2 is the block to the right of pp_prev1 block */
- pp_prev2 = pp_prev1 + 1;
-
- /* pp_prev4 is the block to the right of the block */
- /* below pp_prev1 block */
- pp_prev4 = pp_prev3 + 1;
- }
- else
- { /* dx is a multiple of 16 */
-
- pp_prev2 = pp_prev1;
- pp_prev4 = pp_prev3;
- }
-
- /* Advance offset to location of first Chrominance R semaphore in */
- /* pstprcTypPrv. Since the number of pixels in a Chrominance VOP */
- /* is (number of pixels in Luminance VOP/4), and there are 64 */
- /* pixels in an 8x8 Chrominance block, the offset can be */
- /* calculated as: */
- /* mv_loc = (number of pixels in Luminance VOP/(4*64)) */
- /* = size/256 = size>>8 */
- mv_loc = (size >> 8);
-
- /* 11/3/00, change the propagation for deblocking */
- if (msk_deblock == 0)
- {
-
- /* Deblocking semaphore propagation for Chrominance */
- /* b semaphores */
- *(pp_dec_u) = 0;
-
- /* Advance offset to point to Chrominance r semaphores */
- pp_dec_u += mv_loc;
-
- /* Deblocking semaphore propagation for Chrominance */
- /* r semaphores */
- *(pp_dec_u) = 0;
- }
- else
- {
- /* Deringing semaphore propagation for Chrominance B block */
- if ((*(pp_dec_u)&4) == 0)
- {
- *(pp_dec_u) |= ((*(pp_prev1) | *(pp_prev2) |
- *(pp_prev3) | *(pp_prev4)) & 0x4);
- }
-
- /* Advance offset to point to Chrominance r semaphores */
- pp_dec_u += mv_loc;
- pp_prev1 += mv_loc;
- pp_prev2 += mv_loc;
- pp_prev3 += mv_loc;
- pp_prev4 += mv_loc;
-
- /* Deringing semaphore propagation for Chrominance R */
- if ((*(pp_dec_u)&4) == 0)
- {
- *(pp_dec_u) |= ((*(pp_prev1) | *(pp_prev2) |
- *(pp_prev3) | *(pp_prev4)) & 0x4);
- }
- }
-
- /*----------------------------------------------------------------------------
- ; Return nothing or data or data pointer
- ----------------------------------------------------------------------------*/
- return;
- }
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/pp_semaphore_luma.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/pp_semaphore_luma.cpp
deleted file mode 100644
index b3a1ebd..0000000
--- a/media/libstagefright/codecs/m4v_h263/dec/src/pp_semaphore_luma.cpp
+++ /dev/null
@@ -1,378 +0,0 @@
-/* ------------------------------------------------------------------
- * Copyright (C) 1998-2009 PacketVideo
- *
- * 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.
- * -------------------------------------------------------------------
- */
-/*
-------------------------------------------------------------------------------
- INPUT AND OUTPUT DEFINITIONS
-
- Inputs:
- xpred = x-axis coordinate of the MB used for prediction (int)
- ypred = y-axis coordinate of the MB used for prediction (int)
- pp_dec_y = pointer to the post processing semaphore for current
- luminance frame (uint8)
- pstprcTypPrv = pointer the previous frame's post processing type
- (uint8)
- ll = pointer to the buffer (int)
- mv_loc = flag indicating location of the motion compensated
- (x,y) position with respect to the luminance MB (int);
- 0 -> inside MB, 1 -> outside MB
- dx = horizontal component of the motion vector (int)
- dy = vertical component of the motion vector (int)
- mvwidth = number of blocks per row (int)
- width = luminance VOP width in pixels (int)
- height = luminance VOP height in pixels (int)
-
- Local Stores/Buffers/Pointers Needed:
- None
-
- Global Stores/Buffers/Pointers Needed:
- None
-
- Outputs:
- msk_deblock = flag that indicates whether deblocking is to be
- performed (msk_deblock = 0) or not (msk_deblock =
- 1) (uint8)
-
- Pointers and Buffers Modified:
- pp_dec_y contents are the updated semapohore propagation data
-
- Local Stores Modified:
- None
-
- Global Stores Modified:
- None
-
-------------------------------------------------------------------------------
- FUNCTION DESCRIPTION
-
- This functions performs post processing semaphore propagation processing
- after luminance prediction.
-
-*/
-
-
-/*----------------------------------------------------------------------------
-; INCLUDES
-----------------------------------------------------------------------------*/
-#include "mp4dec_api.h"
-#include "mp4def.h"
-
-/*----------------------------------------------------------------------------
-; MACROS
-; Define module specific macros here
-----------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------
-; DEFINES
-; Include all pre-processor statements here. Include conditional
-; compile variables also.
-----------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------
-; LOCAL FUNCTION DEFINITIONS
-; Function Prototype declaration
-----------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------
-; LOCAL STORE/BUFFER/POINTER DEFINITIONS
-; Variable declaration - defined here and used outside this module
-----------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------
-; EXTERNAL FUNCTION REFERENCES
-; Declare functions defined elsewhere and referenced in this module
-----------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------
-; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
-; Declare variables used in this module but defined elsewhere
-----------------------------------------------------------------------------*/
-#ifdef PV_POSTPROC_ON
-#ifdef __cplusplus
-extern "C"
-{
-#endif
- /*----------------------------------------------------------------------------
- ; FUNCTION CODE
- ----------------------------------------------------------------------------*/
- uint8 pp_semaphore_luma(
- int xpred, /* i */
- int ypred, /* i */
- uint8 *pp_dec_y, /* i/o */
- uint8 *pstprcTypPrv, /* i */
- int *ll, /* i */
- int *mv_loc, /* i/o */
- int dx, /* i */
- int dy, /* i */
- int mvwidth, /* i */
- int width, /* i */
- int height /* i */
- )
- {
- /*----------------------------------------------------------------------------
- ; Define all local variables
- ----------------------------------------------------------------------------*/
- int kk, mmvy, mmvx, nmvx, nmvy;
- uint8 *pp_prev1, *pp_prev2, *pp_prev3, *pp_prev4;
- uint8 msk_deblock = 0; /* 11/3/00 */
-
- /*----------------------------------------------------------------------------
- ; Function body here
- ----------------------------------------------------------------------------*/
- /* Interframe Processing - 1 MV per MB */
-
- /* check whether the MV points outside the frame */
- if (xpred >= 0 && xpred <= ((width << 1) - (2*MB_SIZE)) && ypred >= 0 &&
- ypred <= ((height << 1) - (2*MB_SIZE)))
- { /*****************************/
- /* (x,y) is inside the frame */
- /*****************************/
-
- /* 10/24/2000 post_processing semaphore */
- /* generation */
-
- /* 10/23/2000 no boundary checking*/
- *mv_loc = 0;
-
- /* Calculate block x coordinate. Divide by 16 is for */
- /* converting half-pixel resolution to block */
- mmvx = xpred >> 4;
-
- /* Calculate block y coordinate. Divide by 16 is for */
- /* converting half-pixel resolution to block */
- mmvy = ypred >> 4;
-
- /* Find post processing semaphore location for block */
- /* used for prediction, i.e., */
- /* pp_prev1 = &pstprcTypPrv[mmvy*mvwidth][mmvx] */
- pp_prev1 = pstprcTypPrv + mmvx + mmvy * mvwidth;
-
- /* Check if MV is a multiple of 16 */
- if ((dx&0xF) != 0)
- { /* dx is not a multiple of 16 */
-
- /* pp_prev2 is the block to the right of */
- /* pp_prev1 block */
- pp_prev2 = pp_prev1 + 1;
-
- if ((dy&0xF) != 0)
- { /* dy is not a multiple of 16 */
-
- /* pp_prev3 is the block below */
- /* pp_prev1 block */
- pp_prev3 = pp_prev1 + mvwidth;
- }
- else
- { /* dy is a multiple of 16 */
-
- pp_prev3 = pp_prev1;
- }
-
- /* pp_prev4 is the block to the right of */
- /* pp_prev3 block. */
- pp_prev4 = pp_prev3 + 1;
- }
- else
- { /* dx is a multiple of 16 */
-
- pp_prev2 = pp_prev1;
-
- if ((dy&0xF) != 0)
- { /* dy is not a multiple of 16 */
-
- /* pp_prev3 is the block below */
- /* pp_prev1 block. */
- pp_prev3 = pp_prev1 + mvwidth;
- }
- else
- { /* dy is a multiple of 16 */
-
- pp_prev3 = pp_prev1;
- msk_deblock = 0x3;
- }
-
- pp_prev4 = pp_prev3;
- }
-
- /* Perform post processing semaphore propagation for each */
- /* of the 4 blocks in a MB. */
- for (kk = 0; kk < 4; kk++)
- {
- /* Deringing semaphore propagation */
- if ((*(pp_dec_y) & 4) == 0)
- {
- *(pp_dec_y) |= ((*(pp_prev1) | *(pp_prev2) |
- *(pp_prev3) | *(pp_prev4)) & 0x4);
- }
- /* Deblocking semaphore propagation */
- /* 11/3/00, change the propagation for deblocking */
- if (msk_deblock == 0)
- {
- *(pp_dec_y) = 0;
- }
-
- pp_dec_y += ll[kk];
- pp_prev1 += ll[kk];
- pp_prev2 += ll[kk];
- pp_prev3 += ll[kk];
- pp_prev4 += ll[kk];
- }
-
- }
- else
- { /******************************/
- /* (x,y) is outside the frame */
- /******************************/
-
- /* 10/24/2000 post_processing semaphore */
- /* generation */
-
- /* 10/23/2000 boundary checking*/
- *mv_loc = 1;
-
- /* Perform post processing semaphore propagation for each */
- /* of the 4 blocks in a MB. */
- for (kk = 0; kk < 4; kk++)
- {
- /* Calculate block x coordinate and round (?). */
- /* Divide by 16 is for converting half-pixel */
- /* resolution to block. */
- mmvx = (xpred + ((kk & 1) << 3)) >> 4;
- nmvx = mmvx;
-
- /* Calculate block y coordinate and round (?). */
- /* Divide by 16 is for converting half-pixel */
- /* resolution to block. */
- mmvy = (ypred + ((kk & 2) << 2)) >> 4;
- nmvy = mmvy;
-
- /* Perform boundary checking */
- if (nmvx < 0)
- {
- nmvx = 0;
- }
- else if (nmvx > mvwidth - 1)
- {
- nmvx = mvwidth - 1;
- }
-
- if (nmvy < 0)
- {
- nmvy = 0;
- }
- else if (nmvy > (height >> 3) - 1)
- {
- nmvy = (height >> 3) - 1;
- }
-
- /* Find post processing semaphore location for block */
- /* used for prediction, i.e., */
- /* pp_prev1 = &pstprcTypPrv[nmvy*mvwidth][nmvx] */
- pp_prev1 = pstprcTypPrv + nmvx + nmvy * mvwidth;
-
- /* Check if x component of MV is a multiple of 16 */
- /* and check if block x coordinate is out of bounds */
- if (((dx&0xF) != 0) && (mmvx + 1 < mvwidth - 1))
- { /* dx is not a multiple of 16 and the block */
- /* x coordinate is within the bounds */
-
- /* pp_prev2 is the block to the right of */
- /* pp_prev1 block */
- pp_prev2 = pp_prev1 + 1;
-
- /* Check if y component of MV is a multiple */
- /* of 16 and check if block y coordinate is */
- /* out of bounds */
- if (((dy&0xF) != 0) && (mmvy + 1 < (height >> 3) - 1))
- { /* dy is not a multiple of 16 and */
- /* the block y coordinate is */
- /* within the bounds */
-
- /* pp_prev3 is the block below */
- /* pp_prev1 block */
- pp_prev3 = pp_prev1 + mvwidth;
-
- /* all prediction are from different blocks */
- msk_deblock = 0x3;
- }
- else
- { /* dy is a multiple of 16 or the block */
- /* y coordinate is out of bounds */
-
- pp_prev3 = pp_prev1;
- }
-
- /* pp_prev4 is the block to the right of */
- /* pp_prev3 block. */
- pp_prev4 = pp_prev3 + 1;
- }
- else
- { /* dx is a multiple of 16 or the block x */
- /* coordinate is out of bounds */
-
- pp_prev2 = pp_prev1;
-
- /* Check if y component of MV is a multiple */
- /* of 16 and check if block y coordinate is */
- /* out of bounds */
- if (((dy&0xF) != 0) && (mmvy + 1 < (height >> 3) - 1))
- { /* dy is not a multiple of 16 and */
- /* the block y coordinate is */
- /* within the bounds */
-
- /* pp_prev3 is the block below */
- /* pp_prev1 block. */
- pp_prev3 = pp_prev1 + mvwidth;
- }
- else
- { /* dy is a multiple of 16 or the block */
- /* y coordinate is out of bounds */
-
- pp_prev3 = pp_prev1;
- }
-
- pp_prev4 = pp_prev3;
- }
-
- /* Deringing semaphore propagation */
- if ((*(pp_dec_y)&4) == 0)
- {
- *(pp_dec_y) |= ((*(pp_prev1) |
- *(pp_prev2) | *(pp_prev3) |
- *(pp_prev4)) & 0x4);
- }
- /* Deblocking semaphore propagation */
- /* 11/3/00, change the propaga= */
- /* tion for deblocking */
- if (msk_deblock == 0)
- {
- *(pp_dec_y) = 0;
- }
-
- pp_dec_y += ll[kk];
- }
- }
-
- /*----------------------------------------------------------------------------
- ; Return nothing or data or data pointer
- ----------------------------------------------------------------------------*/
- return (msk_deblock);
- }
-#ifdef __cplusplus
-}
-#endif
-#endif
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/pvdec_api.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/pvdec_api.cpp
index 9c0fcfa..b0828e4 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/src/pvdec_api.cpp
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/pvdec_api.cpp
@@ -512,60 +512,6 @@
video->memoryUsage += (sizeof(MOT) * 8 * nTotalMB);
#endif
-#ifdef PV_POSTPROC_ON
- /* Allocating space for post-processing Mode */
-#ifdef DEC_INTERNAL_MEMORY_OPT
- video->pstprcTypCur = IMEM_pstprcTypCur;
- video->memoryUsage += (nTotalMB * 6);
- if (video->pstprcTypCur == NULL)
- {
- status = PV_FALSE;
- }
- else
- {
- oscl_memset(video->pstprcTypCur, 0, 4*nTotalMB + 2*nTotalMB);
- }
-
- video->pstprcTypPrv = IMEM_pstprcTypPrv;
- video->memoryUsage += (nTotalMB * 6);
- if (video->pstprcTypPrv == NULL)
- {
- status = PV_FALSE;
- }
- else
- {
- oscl_memset(video->pstprcTypPrv, 0, nTotalMB*6);
- }
-
-#else
- if (nTotalMB > INT32_MAX / 6) {
- return PV_FALSE;
- }
- video->pstprcTypCur = (uint8 *) oscl_malloc(nTotalMB * 6);
- video->memoryUsage += (nTotalMB * 6);
- if (video->pstprcTypCur == NULL)
- {
- status = PV_FALSE;
- }
- else
- {
- oscl_memset(video->pstprcTypCur, 0, 4*nTotalMB + 2*nTotalMB);
- }
-
- video->pstprcTypPrv = (uint8 *) oscl_malloc(nTotalMB * 6);
- video->memoryUsage += (nTotalMB * 6);
- if (video->pstprcTypPrv == NULL)
- {
- status = PV_FALSE;
- }
- else
- {
- oscl_memset(video->pstprcTypPrv, 0, nTotalMB*6);
- }
-
-#endif
-
-#endif
/* initialize the decoder library */
video->prevVop->predictionType = I_VOP;
@@ -631,10 +577,6 @@
#ifdef DEC_INTERNAL_MEMORY_OPT
if (video)
{
-#ifdef PV_POSTPROC_ON
- video->pstprcTypCur = NULL;
- video->pstprcTypPrv = NULL;
-#endif
video->acPredFlag = NULL;
video->sliceNo = NULL;
@@ -699,10 +641,6 @@
if (video)
{
-#ifdef PV_POSTPROC_ON
- if (video->pstprcTypCur) oscl_free(video->pstprcTypCur);
- if (video->pstprcTypPrv) oscl_free(video->pstprcTypPrv);
-#endif
if (video->predDC) oscl_free(video->predDC);
video->predDCAC_row = NULL;
if (video->predDCAC_col) oscl_free(video->predDCAC_col);
@@ -830,7 +768,10 @@
OSCL_EXPORT_REF void PVSetPostProcType(VideoDecControls *decCtrl, int mode)
{
VideoDecData *video = (VideoDecData *)decCtrl->videoDecoderData;
- video->postFilterType = mode;
+ if (mode != 0) {
+ ALOGE("Post processing filters are not supported");
+ }
+ video->postFilterType = 0;
}
@@ -1621,43 +1562,8 @@
void PVDecPostProcess(VideoDecControls *decCtrl, uint8 *outputYUV)
{
uint8 *outputBuffer;
-#ifdef PV_POSTPROC_ON
- VideoDecData *video = (VideoDecData *) decCtrl->videoDecoderData;
- int32 tmpvar;
- if (outputYUV)
- {
- outputBuffer = outputYUV;
- }
- else
- {
- if (video->postFilterType)
- {
- outputBuffer = video->currVop->yChan;
- }
- else
- {
- outputBuffer = decCtrl->outputFrame;
- }
- }
-
- if (video->postFilterType)
- {
- /* Post-processing, */
- PostFilter(video, video->postFilterType, outputBuffer);
- }
- else
- {
- if (outputYUV)
- {
- /* Copy decoded frame to the output buffer. */
- tmpvar = (int32)video->width * video->height;
- oscl_memcpy(outputBuffer, decCtrl->outputFrame, tmpvar*3 / 2); /* 3/3/01 */
- }
- }
-#else
outputBuffer = decCtrl->outputFrame;
outputYUV;
-#endif
decCtrl->outputFrame = outputBuffer;
return;
}
diff --git a/media/libstagefright/codecs/m4v_h263/dec/test/Android.bp b/media/libstagefright/codecs/m4v_h263/dec/test/Android.bp
index e335c9b..655491a 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/test/Android.bp
+++ b/media/libstagefright/codecs/m4v_h263/dec/test/Android.bp
@@ -32,7 +32,6 @@
],
cflags: [
- "-DOSCL_IMPORT_REF=",
"-Werror",
"-Wall",
],
diff --git a/media/libstagefright/codecs/m4v_h263/enc/Android.bp b/media/libstagefright/codecs/m4v_h263/enc/Android.bp
index 2738187..846f614 100644
--- a/media/libstagefright/codecs/m4v_h263/enc/Android.bp
+++ b/media/libstagefright/codecs/m4v_h263/enc/Android.bp
@@ -23,10 +23,6 @@
cflags: [
"-DBX_RC",
- "-DOSCL_IMPORT_REF=",
- "-DOSCL_UNUSED_ARG(x)=(void)(x)",
- "-DOSCL_EXPORT_REF=",
-
"-Werror",
],
@@ -55,9 +51,6 @@
cflags: [
"-DBX_RC",
- "-DOSCL_IMPORT_REF=",
- "-DOSCL_UNUSED_ARG(x)=(void)(x)",
- "-DOSCL_EXPORT_REF=",
],
static_libs: ["libstagefright_m4vh263enc"],
@@ -81,8 +74,6 @@
local_include_dirs: ["src"],
cflags: [
- "-DOSCL_EXPORT_REF=",
- "-DOSCL_IMPORT_REF=",
"-DBX_RC",
"-Wall",
"-Werror",
diff --git a/media/libstagefright/codecs/m4v_h263/enc/include/mp4enc_api.h b/media/libstagefright/codecs/m4v_h263/enc/include/mp4enc_api.h
index d5a3ff1..9f824b1 100644
--- a/media/libstagefright/codecs/m4v_h263/enc/include/mp4enc_api.h
+++ b/media/libstagefright/codecs/m4v_h263/enc/include/mp4enc_api.h
@@ -39,6 +39,16 @@
#define PV_TRUE 1
#define PV_FALSE 0
+#ifndef OSCL_IMPORT_REF
+#define OSCL_IMPORT_REF /* empty */
+#endif
+#ifndef OSCL_EXPORT_REF
+#define OSCL_EXPORT_REF /* empty */
+#endif
+#ifndef OSCL_UNUSED_ARG
+#define OSCL_UNUSED_ARG(x) ((void)(x))
+#endif
+
typedef enum
{
SHORT_HEADER,
diff --git a/media/libstagefright/codecs/mp3dec/Android.bp b/media/libstagefright/codecs/mp3dec/Android.bp
index b630524..75b32bd 100644
--- a/media/libstagefright/codecs/mp3dec/Android.bp
+++ b/media/libstagefright/codecs/mp3dec/Android.bp
@@ -2,6 +2,7 @@
name: "libstagefright_mp3dec",
vendor_available: true,
+ host_supported:true,
srcs: [
"src/pvmp3_normalize.cpp",
"src/pvmp3_alias_reduction.cpp",
@@ -72,6 +73,12 @@
"-DOSCL_UNUSED_ARG(x)=(void)(x)",
"-Werror",
],
+
+ target: {
+ darwin: {
+ enabled: false,
+ },
+ },
}
//###############################################################################
diff --git a/media/libstagefright/codecs/mp3dec/fuzzer/Android.bp b/media/libstagefright/codecs/mp3dec/fuzzer/Android.bp
new file mode 100644
index 0000000..2f0eda7
--- /dev/null
+++ b/media/libstagefright/codecs/mp3dec/fuzzer/Android.bp
@@ -0,0 +1,32 @@
+/******************************************************************************
+ *
+ * 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.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+cc_fuzz {
+ name: "mp3_dec_fuzzer",
+ host_supported: true,
+
+ static_libs: [
+ "libstagefright_mp3dec",
+ ],
+
+ srcs: [
+ "mp3_dec_fuzzer.cpp",
+ ],
+}
diff --git a/media/libstagefright/codecs/mp3dec/fuzzer/README.md b/media/libstagefright/codecs/mp3dec/fuzzer/README.md
new file mode 100644
index 0000000..09dd5c3
--- /dev/null
+++ b/media/libstagefright/codecs/mp3dec/fuzzer/README.md
@@ -0,0 +1,56 @@
+# Fuzzer for libstagefright_mp3dec decoder
+
+## Plugin Design Considerations
+The fuzzer plugin for mp3 decoder is designed based on the understanding of the
+codec and tries to achieve the following:
+
+##### Maximize code coverage
+
+This fuzzer makes use of the following config parameters:
+1. Equalizer type (parameter name: `equalizerType`)
+
+| Parameter| Valid Values| Configured Value|
+|------------- |-------------| ----- |
+| `equalizerType` | 0. `flat ` 1. `bass_boost ` 2. `rock ` 3. `pop ` 4. `jazz ` 5. `classical ` 6. `talk ` 7. `flat_ ` | Bits 0, 1 and 2 of first byte of input stream |
+| `crcEnabled` | 0. `false ` 1. `true `| Bit 0 of second byte of input stream |
+
+##### Maximize utilization of input data
+The plugin feeds the entire input data to the codec using a loop.
+ * If the decode operation was successful, the input is advanced by the number
+ of bytes used by the decoder.
+ * If the decode operation was un-successful, the input is advanced by 1 byte
+ till it reaches a valid frame or end of stream.
+
+This ensures that the plugin tolerates any kind of input (empty, huge,
+malformed, etc) and doesnt `exit()` on any input and thereby increasing the
+chance of identifying vulnerabilities.
+
+## Build
+
+This describes steps to build mp3_dec_fuzzer binary.
+
+### Android
+
+#### Steps to build
+Build the fuzzer
+```
+ $ mm -j$(nproc) mp3_dec_fuzzer
+```
+
+#### Steps to run
+Create a directory CORPUS_DIR and copy some mp3 files to that folder.
+Push this directory to device.
+
+To run on device
+```
+ $ adb sync data
+ $ adb shell /data/fuzz/arm64/mp3_dec_fuzzer/mp3_dec_fuzzer CORPUS_DIR
+```
+To run on host
+```
+ $ $ANDROID_HOST_OUT/fuzz/x86_64/mp3_dec_fuzzer/mp3_dec_fuzzer CORPUS_DIR
+```
+
+## References:
+ * http://llvm.org/docs/LibFuzzer.html
+ * https://github.com/google/oss-fuzz
diff --git a/media/libstagefright/codecs/mp3dec/fuzzer/mp3_dec_fuzzer.cpp b/media/libstagefright/codecs/mp3dec/fuzzer/mp3_dec_fuzzer.cpp
new file mode 100644
index 0000000..847c8c4
--- /dev/null
+++ b/media/libstagefright/codecs/mp3dec/fuzzer/mp3_dec_fuzzer.cpp
@@ -0,0 +1,237 @@
+/******************************************************************************
+ *
+ * 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.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+#include <stdlib.h>
+#include <algorithm>
+
+#include <pvmp3decoder_api.h>
+
+constexpr int kMaxFrameSamples = 4608;
+constexpr int kMaxChannels = 2;
+constexpr e_equalization kEqualizerTypes[] = {flat, bass_boost, rock, pop,
+ jazz, classical, talk, flat_};
+
+static bool parseMp3Header(uint32_t header, size_t *frame_size,
+ uint32_t *out_sampling_rate = nullptr, uint32_t *out_channels = nullptr,
+ uint32_t *out_bitrate = nullptr, uint32_t *out_num_samples = nullptr) {
+ *frame_size = 0;
+ if (out_sampling_rate) *out_sampling_rate = 0;
+ if (out_channels) *out_channels = 0;
+ if (out_bitrate) *out_bitrate = 0;
+ if (out_num_samples) *out_num_samples = 0;
+
+ if ((header & 0xffe00000) != 0xffe00000) {
+ return false;
+ }
+ unsigned version = (header >> 19) & 3;
+ if (version == 0x01) {
+ return false;
+ }
+ unsigned layer = (header >> 17) & 3;
+ if (layer == 0x00) {
+ return false;
+ }
+ unsigned bitrate_index = (header >> 12) & 0x0f;
+ if (bitrate_index == 0 || bitrate_index == 0x0f) {
+ return false;
+ }
+ unsigned sampling_rate_index = (header >> 10) & 3;
+ if (sampling_rate_index == 3) {
+ return false;
+ }
+ static const int kSamplingRateV1[] = {44100, 48000, 32000};
+ int sampling_rate = kSamplingRateV1[sampling_rate_index];
+ if (version == 2 /* V2 */) {
+ sampling_rate /= 2;
+ } else if (version == 0 /* V2.5 */) {
+ sampling_rate /= 4;
+ }
+
+ unsigned padding = (header >> 9) & 1;
+
+ if (layer == 3) { // layer I
+ static const int kBitrateV1[] = {32, 64, 96, 128, 160, 192, 224,
+ 256, 288, 320, 352, 384, 416, 448};
+ static const int kBitrateV2[] = {32, 48, 56, 64, 80, 96, 112,
+ 128, 144, 160, 176, 192, 224, 256};
+
+ int bitrate =
+ (version == 3 /* V1 */) ? kBitrateV1[bitrate_index - 1] : kBitrateV2[bitrate_index - 1];
+
+ if (out_bitrate) {
+ *out_bitrate = bitrate;
+ }
+ *frame_size = (12000 * bitrate / sampling_rate + padding) * 4;
+ if (out_num_samples) {
+ *out_num_samples = 384;
+ }
+ } else { // layer II or III
+ static const int kBitrateV1L2[] = {32, 48, 56, 64, 80, 96, 112,
+ 128, 160, 192, 224, 256, 320, 384};
+ static const int kBitrateV1L3[] = {32, 40, 48, 56, 64, 80, 96,
+ 112, 128, 160, 192, 224, 256, 320};
+ static const int kBitrateV2[] = {8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160};
+ int bitrate;
+ if (version == 3 /* V1 */) {
+ bitrate =
+ (layer == 2 /* L2 */) ? kBitrateV1L2[bitrate_index - 1] : kBitrateV1L3[bitrate_index - 1];
+
+ if (out_num_samples) {
+ *out_num_samples = 1152;
+ }
+ } else { // V2 (or 2.5)
+ bitrate = kBitrateV2[bitrate_index - 1];
+ if (out_num_samples) {
+ *out_num_samples = (layer == 1 /* L3 */) ? 576 : 1152;
+ }
+ }
+
+ if (out_bitrate) {
+ *out_bitrate = bitrate;
+ }
+
+ if (version == 3 /* V1 */) {
+ *frame_size = 144000 * bitrate / sampling_rate + padding;
+ } else { // V2 or V2.5
+ size_t tmp = (layer == 1 /* L3 */) ? 72000 : 144000;
+ *frame_size = tmp * bitrate / sampling_rate + padding;
+ }
+ }
+
+ if (out_sampling_rate) {
+ *out_sampling_rate = sampling_rate;
+ }
+
+ if (out_channels) {
+ int channel_mode = (header >> 6) & 3;
+ *out_channels = (channel_mode == 3) ? 1 : 2;
+ }
+
+ return true;
+}
+
+static uint32_t U32_AT(const uint8_t *ptr) {
+ return ptr[0] << 24 | ptr[1] << 16 | ptr[2] << 8 | ptr[3];
+}
+
+static bool checkHeader(uint8 *header, size_t inSize) {
+ size_t frameSize;
+ size_t totalInSize = 0;
+ bool isValidBuffer = false;
+
+ while (totalInSize + 4 < inSize) {
+ isValidBuffer = true;
+ uint32_t val = U32_AT(header + totalInSize);
+ if (!parseMp3Header(val, &frameSize, nullptr, nullptr, nullptr, nullptr)) {
+ return false;
+ }
+ totalInSize += frameSize;
+ }
+
+ return (isValidBuffer);
+}
+
+class Codec {
+ public:
+ Codec() = default;
+ ~Codec() { deInitDecoder(); }
+
+ bool initDecoder();
+ void decodeFrames(uint8_t *data, size_t size);
+ void deInitDecoder();
+
+ private:
+ tPVMP3DecoderExternal *mConfig = nullptr;
+ void *mDecoderBuf = nullptr;
+};
+
+bool Codec::initDecoder() {
+ mConfig = new tPVMP3DecoderExternal{};
+ if (!mConfig) {
+ return false;
+ }
+ size_t decoderBufSize = pvmp3_decoderMemRequirements();
+ mDecoderBuf = malloc(decoderBufSize);
+ if (!mDecoderBuf) {
+ return false;
+ }
+ memset(mDecoderBuf, 0x0, decoderBufSize);
+ pvmp3_InitDecoder(mConfig, mDecoderBuf);
+ return true;
+}
+
+void Codec::decodeFrames(uint8_t *data, size_t size) {
+ uint8_t equalizerTypeValue = (data[0] & 0x7);
+ mConfig->equalizerType = kEqualizerTypes[equalizerTypeValue];
+ mConfig->crcEnabled = data[1] & 0x1;
+
+ while (size > 0) {
+ bool status = checkHeader(data, size);
+ if (!status) {
+ size--;
+ data++;
+ continue;
+ }
+ size_t outBufSize = kMaxFrameSamples * kMaxChannels;
+ size_t usedBytes = 0;
+ int16_t outputBuf[outBufSize];
+ mConfig->inputBufferCurrentLength = size;
+ mConfig->inputBufferUsedLength = 0;
+ mConfig->inputBufferMaxLength = 0;
+ mConfig->pInputBuffer = data;
+ mConfig->pOutputBuffer = outputBuf;
+ mConfig->outputFrameSize = outBufSize / sizeof(int16_t);
+
+ ERROR_CODE decoderErr;
+ decoderErr = pvmp3_framedecoder(mConfig, mDecoderBuf);
+ if (decoderErr != NO_DECODING_ERROR) {
+ size--;
+ data++;
+ } else {
+ usedBytes = std::min((int32_t)size, mConfig->inputBufferUsedLength);
+ size -= usedBytes;
+ data += usedBytes;
+ }
+ }
+}
+
+void Codec::deInitDecoder() {
+ if (mDecoderBuf) {
+ free(mDecoderBuf);
+ mDecoderBuf = nullptr;
+ }
+ delete mConfig;
+ mConfig = nullptr;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+ if (size < 4) {
+ return 0;
+ }
+ Codec *codec = new Codec();
+ if (!codec) {
+ return 0;
+ }
+ if (codec->initDecoder()) {
+ codec->decodeFrames(const_cast<uint8_t *>(data), size);
+ }
+ delete codec;
+ return 0;
+}
diff --git a/media/libstagefright/foundation/AMessage.cpp b/media/libstagefright/foundation/AMessage.cpp
index df66ac6..7752bda 100644
--- a/media/libstagefright/foundation/AMessage.cpp
+++ b/media/libstagefright/foundation/AMessage.cpp
@@ -22,7 +22,6 @@
#include "AMessage.h"
-#include <binder/Parcel.h>
#include <log/log.h>
#include "AAtomizer.h"
@@ -34,6 +33,10 @@
#include <media/stagefright/foundation/hexdump.h>
+#ifndef __ANDROID_VNDK__
+#include <binder/Parcel.h>
+#endif
+
namespace android {
extern ALooperRoster gLooperRoster;
@@ -643,6 +646,7 @@
return s;
}
+#ifndef __ANDROID_VNDK__
// static
sp<AMessage> AMessage::FromParcel(const Parcel &parcel, size_t maxNestingLevel) {
int32_t what = parcel.readInt32();
@@ -809,6 +813,7 @@
}
}
}
+#endif // __ANDROID_VNDK__
sp<AMessage> AMessage::changesFrom(const sp<const AMessage> &other, bool deep) const {
if (other == NULL) {
diff --git a/media/libstagefright/foundation/AString.cpp b/media/libstagefright/foundation/AString.cpp
index a8adff5..4bd186c 100644
--- a/media/libstagefright/foundation/AString.cpp
+++ b/media/libstagefright/foundation/AString.cpp
@@ -23,11 +23,14 @@
#include <stdlib.h>
#include <string.h>
-#include <binder/Parcel.h>
#include <utils/String8.h>
#include "ADebug.h"
#include "AString.h"
+#ifndef __ANDROID_VNDK__
+#include <binder/Parcel.h>
+#endif
+
namespace android {
// static
@@ -362,6 +365,7 @@
return !strcasecmp(mData + mSize - suffixLen, suffix);
}
+#ifndef __ANDROID_VNDK__
// static
AString AString::FromParcel(const Parcel &parcel) {
size_t size = static_cast<size_t>(parcel.readInt32());
@@ -376,6 +380,7 @@
}
return err;
}
+#endif
AString AStringPrintf(const char *format, ...) {
va_list ap;
diff --git a/media/libstagefright/foundation/Android.bp b/media/libstagefright/foundation/Android.bp
index effbb4e..682758a 100644
--- a/media/libstagefright/foundation/Android.bp
+++ b/media/libstagefright/foundation/Android.bp
@@ -2,6 +2,7 @@
name: "libstagefright_foundation_headers",
export_include_dirs: ["include"],
vendor_available: true,
+ host_supported: true,
}
cc_defaults {
@@ -23,7 +24,6 @@
],
header_libs: [
- "libhardware_headers",
"libstagefright_foundation_headers",
"media_ndk_headers",
"media_plugin_headers",
@@ -75,6 +75,17 @@
"hexdump.cpp",
],
+ target: {
+ vendor: {
+ exclude_shared_libs: [
+ "libbinder",
+ ],
+ cflags: [
+ "-DNO_IMEMORY",
+ ],
+ },
+ },
+
clang: true,
sanitize: {
diff --git a/media/libstagefright/foundation/MetaData.cpp b/media/libstagefright/foundation/MetaData.cpp
index 1d0a607..8174597 100644
--- a/media/libstagefright/foundation/MetaData.cpp
+++ b/media/libstagefright/foundation/MetaData.cpp
@@ -17,7 +17,6 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "MetaData"
#include <inttypes.h>
-#include <binder/Parcel.h>
#include <utils/KeyedVector.h>
#include <utils/Log.h>
@@ -29,6 +28,10 @@
#include <media/stagefright/foundation/hexdump.h>
#include <media/stagefright/MetaData.h>
+#ifndef __ANDROID_VNDK__
+#include <binder/Parcel.h>
+#endif
+
namespace android {
@@ -45,6 +48,7 @@
MetaData::~MetaData() {
}
+#ifndef __ANDROID_VNDK__
/* static */
sp<MetaData> MetaData::createFromParcel(const Parcel &parcel) {
@@ -52,6 +56,7 @@
meta->updateFromParcel(parcel);
return meta;
}
+#endif
} // namespace android
diff --git a/media/libstagefright/foundation/MetaDataBase.cpp b/media/libstagefright/foundation/MetaDataBase.cpp
index bfea6f1..4b439c6 100644
--- a/media/libstagefright/foundation/MetaDataBase.cpp
+++ b/media/libstagefright/foundation/MetaDataBase.cpp
@@ -17,7 +17,6 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "MetaDataBase"
#include <inttypes.h>
-#include <binder/Parcel.h>
#include <utils/KeyedVector.h>
#include <utils/Log.h>
@@ -29,6 +28,10 @@
#include <media/stagefright/foundation/hexdump.h>
#include <media/stagefright/MetaDataBase.h>
+#ifndef __ANDROID_VNDK__
+#include <binder/Parcel.h>
+#endif
+
namespace android {
struct MetaDataBase::typed_data {
@@ -449,6 +452,7 @@
}
}
+#ifndef __ANDROID_VNDK__
status_t MetaDataBase::writeToParcel(Parcel &parcel) {
status_t ret;
size_t numItems = mInternalData->mItems.size();
@@ -528,6 +532,7 @@
ALOGW("no metadata in parcel");
return UNKNOWN_ERROR;
}
+#endif
} // namespace android
diff --git a/media/libstagefright/foundation/avc_utils.cpp b/media/libstagefright/foundation/avc_utils.cpp
index e8a6083..8605925 100644
--- a/media/libstagefright/foundation/avc_utils.cpp
+++ b/media/libstagefright/foundation/avc_utils.cpp
@@ -546,11 +546,9 @@
CHECK_NE(video_object_type_indication,
0x21u /* Fine Granularity Scalable */);
- unsigned video_object_layer_verid __unused;
- unsigned video_object_layer_priority __unused;
if (br.getBits(1)) {
- video_object_layer_verid = br.getBits(4);
- video_object_layer_priority = br.getBits(3);
+ br.skipBits(4); //video_object_layer_verid
+ br.skipBits(3); //video_object_layer_priority
}
unsigned aspect_ratio_info = br.getBits(4);
if (aspect_ratio_info == 0x0f /* extended PAR */) {
@@ -609,7 +607,7 @@
unsigned video_object_layer_height = br.getBits(13);
CHECK(br.getBits(1)); // marker_bit
- unsigned interlaced __unused = br.getBits(1);
+ br.skipBits(1); // interlaced
*width = video_object_layer_width;
*height = video_object_layer_height;
@@ -655,7 +653,7 @@
return false;
}
- unsigned protection __unused = (header >> 16) & 1;
+ // we can get protection value from (header >> 16) & 1
unsigned bitrate_index = (header >> 12) & 0x0f;
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/ADebug.h b/media/libstagefright/foundation/include/media/stagefright/foundation/ADebug.h
index ab17a02..e4b99bf 100644
--- a/media/libstagefright/foundation/include/media/stagefright/foundation/ADebug.h
+++ b/media/libstagefright/foundation/include/media/stagefright/foundation/ADebug.h
@@ -148,7 +148,8 @@
static char *GetDebugName(const char *name);
inline static bool isExperimentEnabled(
- const char *name __unused /* nonnull */, bool allow __unused = true) {
+ const char *name __attribute__((unused)) /* nonnull */,
+ bool allow __attribute__((unused)) = true) {
#ifdef ENABLE_STAGEFRIGHT_EXPERIMENTS
if (!strcmp(name, "legacy-adaptive")) {
return getExperimentFlag(allow, name, 2, 1); // every other day
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/AMessage.h b/media/libstagefright/foundation/include/media/stagefright/foundation/AMessage.h
index 742651e..b5d6666 100644
--- a/media/libstagefright/foundation/include/media/stagefright/foundation/AMessage.h
+++ b/media/libstagefright/foundation/include/media/stagefright/foundation/AMessage.h
@@ -63,6 +63,7 @@
AMessage();
AMessage(uint32_t what, const sp<const AHandler> &handler);
+#ifndef __ANDROID_VNDK__
// Construct an AMessage from a parcel.
// nestingAllowed determines how many levels AMessage can be nested inside
// AMessage. The default value here is arbitrarily set to 255.
@@ -87,6 +88,7 @@
// All items in the AMessage must have types that are recognized by
// FromParcel(); otherwise, TRESPASS error will occur.
void writeToParcel(Parcel *parcel) const;
+#endif
void setWhat(uint32_t what);
uint32_t what() const;
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/AString.h b/media/libstagefright/foundation/include/media/stagefright/foundation/AString.h
index 0f6299c..deef0d4 100644
--- a/media/libstagefright/foundation/include/media/stagefright/foundation/AString.h
+++ b/media/libstagefright/foundation/include/media/stagefright/foundation/AString.h
@@ -89,8 +89,10 @@
void tolower();
+#ifndef __ANDROID_VNDK__
static AString FromParcel(const Parcel &parcel);
status_t writeToParcel(Parcel *parcel) const;
+#endif
private:
constexpr static const char *kEmptyString = "";
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/AUtils.h b/media/libstagefright/foundation/include/media/stagefright/foundation/AUtils.h
index af6b357..3b646dc 100644
--- a/media/libstagefright/foundation/include/media/stagefright/foundation/AUtils.h
+++ b/media/libstagefright/foundation/include/media/stagefright/foundation/AUtils.h
@@ -63,7 +63,7 @@
template<class T>
void ENSURE_UNSIGNED_TYPE() {
- T TYPE_MUST_BE_UNSIGNED[(T)-1 < 0 ? -1 : 0] __unused;
+ T TYPE_MUST_BE_UNSIGNED[(T)-1 < 0 ? -1 : 0] __attribute__((unused));
}
// needle is in range [hayStart, hayStart + haySize)
diff --git a/media/libstagefright/foundation/tests/AVCUtils/AVCUtilsTestEnvironment.h b/media/libstagefright/foundation/tests/AVCUtils/AVCUtilsTestEnvironment.h
new file mode 100644
index 0000000..b28a7bc
--- /dev/null
+++ b/media/libstagefright/foundation/tests/AVCUtils/AVCUtilsTestEnvironment.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 __AVC_UTILS_TEST_ENVIRONMENT_H__
+#define __AVC_UTILS_TEST_ENVIRONMENT_H__
+
+#include <gtest/gtest.h>
+
+#include <getopt.h>
+
+using namespace std;
+
+class AVCUtilsTestEnvironment : public::testing::Environment {
+ public:
+ AVCUtilsTestEnvironment() : 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 AVCUtilsTestEnvironment::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 // __AVC_UTILS_TEST_ENVIRONMENT_H__
diff --git a/media/libstagefright/foundation/tests/AVCUtils/AVCUtilsUnitTest.cpp b/media/libstagefright/foundation/tests/AVCUtils/AVCUtilsUnitTest.cpp
new file mode 100644
index 0000000..77a8599
--- /dev/null
+++ b/media/libstagefright/foundation/tests/AVCUtils/AVCUtilsUnitTest.cpp
@@ -0,0 +1,411 @@
+/*
+ * 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 "AVCUtilsUnitTest"
+#include <utils/Log.h>
+
+#include <fstream>
+
+#include "media/stagefright/foundation/ABitReader.h"
+#include "media/stagefright/foundation/avc_utils.h"
+
+#include "AVCUtilsTestEnvironment.h"
+
+constexpr size_t kSmallBufferSize = 2;
+constexpr uint8_t kSPSmask = 0x1f;
+constexpr uint8_t kSPSStartCode = 0x07;
+constexpr uint8_t kConfigVersion = 0x01;
+
+using namespace android;
+
+static AVCUtilsTestEnvironment *gEnv = nullptr;
+
+class MpegAudioUnitTest
+ : public ::testing::TestWithParam<
+ tuple</*audioHeader*/ uint32_t, /*frameSize*/ int32_t, /*sampleRate*/ int32_t,
+ /*numChannels*/ int32_t, /*bitRate*/ int32_t, /*numSamples*/ int32_t>> {};
+
+class VOLDimensionTest
+ : public ::testing::TestWithParam<
+ tuple</*fileName*/ string, /*volWidth*/ int32_t, /*volHeight*/ int32_t>> {};
+
+class AVCUtils {
+ public:
+ bool SetUpAVCUtils(string fileName, string infoFileName) {
+ mInputFile = gEnv->getRes() + fileName;
+ mInputFileStream.open(mInputFile, ifstream::in);
+ if (!mInputFileStream.is_open()) return false;
+
+ mInfoFile = gEnv->getRes() + infoFileName;
+ mInfoFileStream.open(mInfoFile, ifstream::in);
+ if (!mInputFileStream.is_open()) return false;
+ return true;
+ }
+
+ ~AVCUtils() {
+ if (mInputFileStream.is_open()) mInputFileStream.close();
+ if (mInfoFileStream.is_open()) mInfoFileStream.close();
+ }
+
+ string mInputFile;
+ string mInfoFile;
+
+ ifstream mInputFileStream;
+ ifstream mInfoFileStream;
+};
+
+class AVCDimensionTest
+ : public AVCUtils,
+ public ::testing::TestWithParam<
+ tuple</*fileName*/ string, /*infoFileName*/ string,
+ /*avcWidth*/ size_t, /*avcHeight*/ size_t, /*numberOfNALUnits*/ int32_t>> {
+ public:
+ virtual void SetUp() override {
+ tuple<string, string, size_t, size_t, size_t> params = GetParam();
+ string fileName = get<0>(params);
+ string infoFileName = get<1>(params);
+ AVCUtils::SetUpAVCUtils(fileName, infoFileName);
+
+ mFrameWidth = get<2>(params);
+ mFrameHeight = get<3>(params);
+ mNalUnitsExpected = get<4>(params);
+ }
+
+ size_t mFrameWidth;
+ size_t mFrameHeight;
+ int32_t mNalUnitsExpected;
+};
+
+class AvccBoxTest : public AVCDimensionTest {
+ public:
+ virtual void SetUp() override { AVCDimensionTest::SetUp(); }
+};
+
+class AVCFrameTest
+ : public AVCUtils,
+ public ::testing::TestWithParam<pair</*fileName*/ string, /*infoFileName*/ string>> {
+ public:
+ virtual void SetUp() override {
+ string fileName = GetParam().first;
+ string infoFileName = GetParam().second;
+ AVCUtils::SetUpAVCUtils(fileName, infoFileName);
+ }
+};
+
+TEST_P(MpegAudioUnitTest, AudioProfileTest) {
+ tuple<uint32_t, size_t, int, int, int, int> params = GetParam();
+ uint32_t header = get<0>(params);
+
+ size_t audioFrameSize = get<1>(params);
+ int audioSampleRate = get<2>(params);
+ int audioNumChannels = get<3>(params);
+ int audioBitRate = get<4>(params);
+ int audioNumSamples = get<5>(params);
+
+ size_t frameSize = 0;
+ int sampleRate = 0;
+ int numChannels = 0;
+ int bitRate = 0;
+ int numSamples = 0;
+
+ bool status = GetMPEGAudioFrameSize(header, &frameSize, &sampleRate, &numChannels, &bitRate,
+ &numSamples);
+ ASSERT_TRUE(status) << "Failed to get Audio properties";
+
+ ASSERT_EQ(frameSize, audioFrameSize) << "Wrong frame size found";
+
+ ASSERT_EQ(sampleRate, audioSampleRate) << "Wrong sample rate found";
+
+ ASSERT_EQ(numChannels, audioNumChannels) << "Wrong number of channels found";
+
+ ASSERT_EQ(bitRate, audioBitRate) << "Wrong bit rate found";
+
+ ASSERT_EQ(numSamples, audioNumSamples) << "Wrong number of samples found";
+}
+
+TEST_P(VOLDimensionTest, DimensionTest) {
+ tuple<string, int32_t, int32_t> params = GetParam();
+ string inputFile = gEnv->getRes() + get<0>(params);
+ ifstream inputFileStream;
+ inputFileStream.open(inputFile, ifstream::in);
+ ASSERT_TRUE(inputFileStream.is_open()) << "Failed to open: " << inputFile;
+
+ struct stat buf;
+ int8_t err = stat(inputFile.c_str(), &buf);
+ ASSERT_EQ(err, 0) << "Failed to get information for file: " << inputFile;
+
+ size_t fileSize = buf.st_size;
+ ASSERT_NE(fileSize, 0) << "Invalid file size found";
+
+ const uint8_t *volBuffer = new uint8_t[fileSize];
+ ASSERT_NE(volBuffer, nullptr) << "Failed to allocate VOL buffer of size: " << fileSize;
+
+ inputFileStream.read((char *)(volBuffer), fileSize);
+ ASSERT_EQ(inputFileStream.gcount(), fileSize)
+ << "Failed to read complete file, bytes read: " << inputFileStream.gcount();
+
+ int32_t width = get<1>(params);
+ int32_t height = get<2>(params);
+ int32_t volWidth = -1;
+ int32_t volHeight = -1;
+
+ bool status = ExtractDimensionsFromVOLHeader(volBuffer, fileSize, &volWidth, &volHeight);
+ ASSERT_TRUE(status)
+ << "Failed to get VOL dimensions from function: ExtractDimensionsFromVOLHeader()";
+
+ ASSERT_EQ(volWidth, width) << "Expected width: " << width << "Found: " << volWidth;
+
+ ASSERT_EQ(volHeight, height) << "Expected height: " << height << "Found: " << volHeight;
+
+ delete[] volBuffer;
+}
+
+TEST_P(AVCDimensionTest, DimensionTest) {
+ int32_t numNalUnits = 0;
+ int32_t avcWidth = -1;
+ int32_t avcHeight = -1;
+ string line;
+ string type;
+ size_t chunkLength;
+ while (getline(mInfoFileStream, line)) {
+ istringstream stringLine(line);
+ stringLine >> type >> chunkLength;
+ ASSERT_GT(chunkLength, 0) << "Length of the data chunk must be greater than zero";
+
+ const uint8_t *data = new uint8_t[chunkLength];
+ ASSERT_NE(data, nullptr) << "Failed to create a data buffer of size: " << chunkLength;
+
+ const uint8_t *nalStart;
+ size_t nalSize;
+
+ mInputFileStream.read((char *)data, chunkLength);
+ ASSERT_EQ(mInputFileStream.gcount(), chunkLength)
+ << "Failed to read complete file, bytes read: " << mInputFileStream.gcount();
+
+ size_t smallBufferSize = kSmallBufferSize;
+ const uint8_t *sanityData = new uint8_t[smallBufferSize];
+ memcpy((void *)sanityData, (void *)data, smallBufferSize);
+
+ status_t result = getNextNALUnit(&sanityData, &smallBufferSize, &nalStart, &nalSize, true);
+ ASSERT_EQ(result, -EAGAIN) << "Invalid result found when wrong NAL unit passed";
+
+ while (!getNextNALUnit(&data, &chunkLength, &nalStart, &nalSize, true)) {
+ numNalUnits++;
+ // Check if it's an SPS
+ if ((nalStart[0] & kSPSmask) != kSPSStartCode) continue;
+ ASSERT_TRUE(nalSize > 0) << "NAL unit size must be greater than 0";
+
+ sp<ABuffer> spsBuffer = new ABuffer(nalSize);
+ ASSERT_NE(spsBuffer, nullptr) << "ABuffer returned null for size: " << nalSize;
+
+ memcpy(spsBuffer->data(), nalStart, nalSize);
+ FindAVCDimensions(spsBuffer, &avcWidth, &avcHeight);
+ spsBuffer.clear();
+ ASSERT_EQ(avcWidth, mFrameWidth)
+ << "Expected width: " << mFrameWidth << "Found: " << avcWidth;
+
+ ASSERT_EQ(avcHeight, mFrameHeight)
+ << "Expected height: " << mFrameHeight << "Found: " << avcHeight;
+ }
+ delete[] data;
+ }
+ if (mNalUnitsExpected < 0) {
+ ASSERT_GT(numNalUnits, 0) << "Failed to find an NAL Unit";
+ } else {
+ ASSERT_EQ(numNalUnits, mNalUnitsExpected)
+ << "Expected number of NAL units: " << mNalUnitsExpected
+ << " found: " << numNalUnits;
+ }
+}
+
+TEST_P(AvccBoxTest, AvccBoxValidationTest) {
+ int32_t avcWidth = -1;
+ int32_t avcHeight = -1;
+ int32_t accessUnitLength = 0;
+ int32_t profile = -1;
+ int32_t level = -1;
+ string line;
+ string type;
+ size_t chunkLength;
+ while (getline(mInfoFileStream, line)) {
+ istringstream stringLine(line);
+ stringLine >> type >> chunkLength;
+
+ if (type.compare("SPS") && type.compare("PPS")) continue;
+ ASSERT_GT(chunkLength, 0) << "Length of the data chunk must be greater than zero";
+
+ accessUnitLength += chunkLength;
+
+ if (!type.compare("SPS")) {
+ const uint8_t *data = new uint8_t[chunkLength];
+ ASSERT_NE(data, nullptr) << "Failed to create a data buffer of size: " << chunkLength;
+
+ const uint8_t *nalStart;
+ size_t nalSize;
+
+ mInputFileStream.read((char *)data, (uint32_t)chunkLength);
+ ASSERT_EQ(mInputFileStream.gcount(), chunkLength)
+ << "Failed to read complete file, bytes read: " << mInputFileStream.gcount();
+
+ while (!getNextNALUnit(&data, &chunkLength, &nalStart, &nalSize, true)) {
+ // Check if it's an SPS
+ ASSERT_TRUE(nalSize > 0 && (nalStart[0] & kSPSmask) == kSPSStartCode)
+ << "Failed to get SPS";
+
+ ASSERT_GE(nalSize, 4) << "SPS size must be greater than or equal to 4";
+
+ profile = nalStart[1];
+ level = nalStart[3];
+ }
+ delete[] data;
+ }
+ }
+ const uint8_t *accessUnitData = new uint8_t[accessUnitLength];
+ ASSERT_NE(accessUnitData, nullptr) << "Failed to create a buffer of size: " << accessUnitLength;
+
+ mInputFileStream.seekg(0, ios::beg);
+ mInputFileStream.read((char *)accessUnitData, accessUnitLength);
+ ASSERT_EQ(mInputFileStream.gcount(), accessUnitLength)
+ << "Failed to read complete file, bytes read: " << mInputFileStream.gcount();
+
+ sp<ABuffer> accessUnit = new ABuffer(accessUnitLength);
+ ASSERT_NE(accessUnit, nullptr)
+ << "Failed to create an android data buffer of size: " << accessUnitLength;
+
+ memcpy(accessUnit->data(), accessUnitData, accessUnitLength);
+ sp<ABuffer> csdDataBuffer = MakeAVCCodecSpecificData(accessUnit, &avcWidth, &avcHeight);
+ ASSERT_NE(csdDataBuffer, nullptr) << "No data returned from MakeAVCCodecSpecificData()";
+
+ ASSERT_EQ(avcWidth, mFrameWidth) << "Expected width: " << mFrameWidth << "Found: " << avcWidth;
+
+ ASSERT_EQ(avcHeight, mFrameHeight)
+ << "Expected height: " << mFrameHeight << "Found: " << avcHeight;
+
+ uint8_t *csdData = csdDataBuffer->data();
+ ASSERT_EQ(*csdData, kConfigVersion) << "Invalid configuration version";
+
+ ASSERT_GE(csdDataBuffer->size(), 4) << "CSD data size must be greater than or equal to 4";
+
+ ASSERT_EQ(*(csdData + 1), profile)
+ << "Expected AVC profile: " << profile << " found: " << *(csdData + 1);
+
+ ASSERT_EQ(*(csdData + 3), level)
+ << "Expected AVC level: " << level << " found: " << *(csdData + 3);
+ csdDataBuffer.clear();
+ delete[] accessUnitData;
+ accessUnit.clear();
+}
+
+TEST_P(AVCFrameTest, FrameTest) {
+ string line;
+ string type;
+ size_t chunkLength;
+ int32_t frameLayerID;
+ while (getline(mInfoFileStream, line)) {
+ uint32_t layerID = 0;
+ istringstream stringLine(line);
+ stringLine >> type >> chunkLength >> frameLayerID;
+ ASSERT_GT(chunkLength, 0) << "Length of the data chunk must be greater than zero";
+
+ char *data = new char[chunkLength];
+ ASSERT_NE(data, nullptr) << "Failed to allocation data buffer of size: " << chunkLength;
+
+ mInputFileStream.read(data, chunkLength);
+ ASSERT_EQ(mInputFileStream.gcount(), chunkLength)
+ << "Failed to read complete file, bytes read: " << mInputFileStream.gcount();
+
+ if (!type.compare("IDR")) {
+ bool isIDR = IsIDR((uint8_t *)data, chunkLength);
+ ASSERT_TRUE(isIDR);
+
+ layerID = FindAVCLayerId((uint8_t *)data, chunkLength);
+ ASSERT_EQ(layerID, frameLayerID) << "Wrong layer ID found";
+ } else if (!type.compare("P") || !type.compare("B")) {
+ sp<ABuffer> accessUnit = new ABuffer(chunkLength);
+ ASSERT_NE(accessUnit, nullptr) << "Unable to create access Unit";
+
+ memcpy(accessUnit->data(), data, chunkLength);
+ bool isReferenceFrame = IsAVCReferenceFrame(accessUnit);
+ ASSERT_TRUE(isReferenceFrame);
+
+ accessUnit.clear();
+ layerID = FindAVCLayerId((uint8_t *)data, chunkLength);
+ ASSERT_EQ(layerID, frameLayerID) << "Wrong layer ID found";
+ }
+ delete[] data;
+ }
+}
+
+INSTANTIATE_TEST_SUITE_P(AVCUtilsTestAll, MpegAudioUnitTest,
+ ::testing::Values(make_tuple(0xFFFB9204, 418, 44100, 2, 128, 1152),
+ make_tuple(0xFFFB7604, 289, 48000, 2, 96, 1152),
+ make_tuple(0xFFFE5604, 164, 48000, 2, 160, 384)));
+
+// Info File contains the type and length for each chunk/frame
+INSTANTIATE_TEST_SUITE_P(
+ AVCUtilsTestAll, AVCDimensionTest,
+ ::testing::Values(make_tuple("crowd_8x8p50f32_200kbps_bp.h264",
+ "crowd_8x8p50f32_200kbps_bp.info", 8, 8, 11),
+ make_tuple("crowd_640x360p24f300_1000kbps_bp.h264",
+ "crowd_640x360p24f300_1000kbps_bp.info", 640, 360, 11),
+ make_tuple("crowd_1280x720p30f300_5000kbps_bp.h264",
+ "crowd_1280x720p30f300_5000kbps_bp.info", 1280, 720, 12),
+ make_tuple("crowd_1920x1080p50f300_12000kbps_bp.h264",
+ "crowd_1920x1080p50f300_12000kbps_bp.info", 1920, 1080, 14),
+ make_tuple("crowd_3840x2160p60f300_68000kbps_bp.h264",
+ "crowd_3840x2160p60f300_68000kbps_bp.info", 3840, 2160, 14)));
+
+// Info File contains the type and length for each chunk/frame
+INSTANTIATE_TEST_SUITE_P(
+ AVCUtilsTestAll, AvccBoxTest,
+ ::testing::Values(make_tuple("crowd_8x8p50f32_200kbps_bp.h264",
+ "crowd_8x8p50f32_200kbps_bp.info", 8, 8, 11),
+ make_tuple("crowd_1280x720p30f300_5000kbps_bp.h264",
+ "crowd_1280x720p30f300_5000kbps_bp.info", 1280, 720, 12),
+ make_tuple("crowd_1920x1080p50f300_12000kbps_bp.h264",
+ "crowd_1920x1080p50f300_12000kbps_bp.info", 1920, 1080, 14)));
+
+// Info File contains the type and length for each chunk/frame
+INSTANTIATE_TEST_SUITE_P(AVCUtilsTestAll, VOLDimensionTest,
+ ::testing::Values(make_tuple("volData_720_480", 720, 480),
+ make_tuple("volData_1280_720", 1280, 720),
+ make_tuple("volData_1920_1080", 1920, 1080)));
+
+// Info File contains the type, length and layer ID for each chunk/frame
+INSTANTIATE_TEST_SUITE_P(AVCUtilsTestAll, AVCFrameTest,
+ ::testing::Values(make_tuple("crowd_8x8p50f32_200kbps_bp.h264",
+ "crowd_8x8p50f32_200kbps_bp.info"),
+ make_tuple("crowd_640x360p24f300_1000kbps_bp.h264",
+ "crowd_640x360p24f300_1000kbps_bp.info"),
+ make_tuple("crowd_1280x720p30f300_5000kbps_bp.h264",
+ "crowd_1280x720p30f300_5000kbps_bp.info"),
+ make_tuple("crowd_1920x1080p50f300_12000kbps_bp.h264",
+ "crowd_1920x1080p50f300_12000kbps_bp.info"),
+ make_tuple("crowd_3840x2160p60f300_68000kbps_bp.h264",
+ "crowd_3840x2160p60f300_68000kbps_bp.info")));
+
+int main(int argc, char **argv) {
+ gEnv = new AVCUtilsTestEnvironment();
+ ::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/foundation/tests/AVCUtils/Android.bp b/media/libstagefright/foundation/tests/AVCUtils/Android.bp
new file mode 100644
index 0000000..5d0e481
--- /dev/null
+++ b/media/libstagefright/foundation/tests/AVCUtils/Android.bp
@@ -0,0 +1,51 @@
+/*
+ * 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: "AVCUtilsUnitTest",
+ gtest: true,
+
+ srcs: [
+ "AVCUtilsUnitTest.cpp",
+ ],
+
+ shared_libs: [
+ "libutils",
+ "liblog",
+ ],
+
+ static_libs: [
+ "libstagefright",
+ "libstagefright_foundation",
+ ],
+
+ include_dirs: [
+ "frameworks/av/media/libstagefright/foundation",
+ ],
+
+ cflags: [
+ "-Werror",
+ "-Wall",
+ ],
+
+ sanitize: {
+ cfi: true,
+ misc_undefined: [
+ "unsigned-integer-overflow",
+ "signed-integer-overflow",
+ ],
+ },
+}
diff --git a/media/libstagefright/foundation/tests/AVCUtils/AndroidTest.xml b/media/libstagefright/foundation/tests/AVCUtils/AndroidTest.xml
new file mode 100644
index 0000000..6a088a8
--- /dev/null
+++ b/media/libstagefright/foundation/tests/AVCUtils/AndroidTest.xml
@@ -0,0 +1,31 @@
+<?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 AVC Utils unit tests">
+ <option name="test-suite-tag" value="AVCUtilsUnitTest" />
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="cleanup" value="false" />
+ <option name="push" value="AVCUtilsUnitTest->/data/local/tmp/AVCUtilsUnitTest" />
+ <option name="push-file"
+ key="https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/foundation/tests/AVCUtils/AVCUtilsUnitTest.zip?unzip=true"
+ value="/data/local/tmp/AVCUtilsUnitTest/" />
+ </target_preparer>
+
+ <test class="com.android.tradefed.testtype.GTest" >
+ <option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="module-name" value="AVCUtilsUnitTest" />
+ <option name="native-test-flag" value="-P /data/local/tmp/AVCUtilsUnitTest/" />
+ </test>
+</configuration>
diff --git a/media/libstagefright/foundation/tests/AVCUtils/README.md b/media/libstagefright/foundation/tests/AVCUtils/README.md
new file mode 100644
index 0000000..609d72e
--- /dev/null
+++ b/media/libstagefright/foundation/tests/AVCUtils/README.md
@@ -0,0 +1,39 @@
+## Media Testing ##
+---
+#### AVCUtils Test
+The AVC Utility Unit Test Suite validates the avc_utils librariy available in libstagefright/foundation.
+
+Run the following steps to build the test suite:
+```
+m AVCUtilsUnitTest
+```
+
+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/AVCUtilsUnitTest/AVCUtilsUnitTest /data/local/tmp/
+```
+
+To test 32-bit binary push binaries from nativetest.
+```
+adb push ${OUT}/data/nativetest/AVCUtilsUnitTest/AVCUtilsUnitTest /data/local/tmp/
+```
+
+The resource file for the tests is taken from [here](https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/foundation/tests/AVCUtils/AVCUtilsUnitTest.zip). Download, unzip and push these files into device for testing.
+
+```
+adb push AVCUtilsUnitTest /data/local/tmp/
+```
+
+usage: AVCUtilsUnitTest -P \<path_to_folder\>
+```
+adb shell /data/local/tmp/AVCUtilsUnitTest -P /data/local/tmp/AVCUtilsUnitTest/
+```
+Alternatively, the test can also be run using atest command.
+
+```
+atest AVCUtilsUnitTest -- --enable-module-dynamic-download=true
+```
diff --git a/media/libstagefright/foundation/tests/OpusHeader/OpusHeaderTest.cpp b/media/libstagefright/foundation/tests/OpusHeader/OpusHeaderTest.cpp
index d142781..e39c915 100644
--- a/media/libstagefright/foundation/tests/OpusHeader/OpusHeaderTest.cpp
+++ b/media/libstagefright/foundation/tests/OpusHeader/OpusHeaderTest.cpp
@@ -89,17 +89,19 @@
class OpusHeaderWriteTest
: public OpusHeaderTest,
- public ::testing::TestWithParam<pair<int32_t /* ChannelCount */, int32_t /* skipSamples */>> {
-};
+ public ::testing::TestWithParam<tuple<int32_t /* ChannelCount */, int32_t /* skipSamples */,
+ string /* referenceFile */>> {};
TEST_P(OpusHeaderWriteTest, WriteTest) {
+ tuple<int32_t, int32_t, string> params = GetParam();
OpusHeader writtenHeader;
memset(&writtenHeader, 0, sizeof(writtenHeader));
- int32_t channels = GetParam().first;
+ int32_t channels = get<0>(params);
writtenHeader.channels = channels;
writtenHeader.num_streams = channels;
writtenHeader.channel_mapping = ((channels > 8) ? 255 : (channels > 2));
- int32_t skipSamples = GetParam().second;
+ int32_t skipSamples = get<1>(params);
+ string referenceFileName = gEnv->getRes() + get<2>(params);
writtenHeader.skip_samples = skipSamples;
uint64_t codecDelayNs = skipSamples * kNsecPerSec / kOpusSampleRate;
uint8_t headerData[kMaxOpusHeaderSize];
@@ -112,11 +114,29 @@
ofstream ostrm;
ostrm.open(OUTPUT_FILE_NAME, ofstream::binary);
ASSERT_TRUE(ostrm.is_open()) << "Failed to open output file " << OUTPUT_FILE_NAME;
-
- // TODO : Validate bitstream (b/150116402)
- ostrm.write(reinterpret_cast<char *>(headerData), sizeof(headerData));
+ ostrm.write(reinterpret_cast<char *>(headerData), headerSize);
ostrm.close();
+ mEleStream.open(referenceFileName, ifstream::binary);
+ ASSERT_EQ(mEleStream.is_open(), true) << "Failed to open referenceFileName " << get<2>(params);
+
+ struct stat buf;
+ int32_t statStatus = stat(referenceFileName.c_str(), &buf);
+ ASSERT_EQ(statStatus, 0) << "Unable to get file properties";
+
+ size_t fileSize = buf.st_size;
+ mInputBuffer = (uint8_t *)malloc(fileSize);
+ ASSERT_NE(mInputBuffer, nullptr) << "Insufficient memory. Malloc failed for size " << fileSize;
+
+ mEleStream.read(reinterpret_cast<char *>(mInputBuffer), fileSize);
+ ASSERT_EQ(mEleStream.gcount(), fileSize) << "mEleStream.gcount() != bytesCount";
+
+ ASSERT_EQ(fileSize, headerSize)
+ << "Mismatch in size between header generated and reference header";
+ int32_t match = memcmp(reinterpret_cast<char *>(mInputBuffer),
+ reinterpret_cast<char *>(headerData), fileSize);
+ ASSERT_EQ(match, 0) << "Opus header does not match reference file: " << referenceFileName;
+
size_t opusHeadSize = 0;
size_t codecDelayBufSize = 0;
size_t seekPreRollBufSize = 0;
@@ -266,19 +286,20 @@
}
}
-INSTANTIATE_TEST_SUITE_P(OpusHeaderTestAll, OpusHeaderWriteTest,
- ::testing::Values(make_pair(1, 312),
- make_pair(2, 312),
- make_pair(5, 312),
- make_pair(6, 312),
- make_pair(1, 0),
- make_pair(2, 0),
- make_pair(5, 0),
- make_pair(6, 0),
- make_pair(1, 624),
- make_pair(2, 624),
- make_pair(5, 624),
- make_pair(6, 624)));
+INSTANTIATE_TEST_SUITE_P(
+ OpusHeaderTestAll, OpusHeaderWriteTest,
+ ::testing::Values(make_tuple(1, 312, "output_channels_1skipSamples_312.opus"),
+ make_tuple(2, 312, "output_channels_2skipSamples_312.opus"),
+ make_tuple(5, 312, "output_channels_5skipSamples_312.opus"),
+ make_tuple(6, 312, "output_channels_6skipSamples_312.opus"),
+ make_tuple(1, 0, "output_channels_1skipSamples_0.opus"),
+ make_tuple(2, 0, "output_channels_2skipSamples_0.opus"),
+ make_tuple(5, 0, "output_channels_5skipSamples_0.opus"),
+ make_tuple(6, 0, "output_channels_6skipSamples_0.opus"),
+ make_tuple(1, 624, "output_channels_1skipSamples_624.opus"),
+ make_tuple(2, 624, "output_channels_2skipSamples_624.opus"),
+ make_tuple(5, 624, "output_channels_5skipSamples_624.opus"),
+ make_tuple(6, 624, "output_channels_6skipSamples_624.opus")));
INSTANTIATE_TEST_SUITE_P(
OpusHeaderTestAll, OpusHeaderParseTest,
diff --git a/media/libstagefright/id3/Android.bp b/media/libstagefright/id3/Android.bp
index c8173cf..02de2c0 100644
--- a/media/libstagefright/id3/Android.bp
+++ b/media/libstagefright/id3/Android.bp
@@ -4,7 +4,9 @@
srcs: ["ID3.cpp"],
header_libs: [
- "libmedia_headers",
+ "libmedia_datasource_headers",
+ "libstagefright_foundation_headers",
+ "libstagefright_headers",
"media_ndk_headers",
],
@@ -18,6 +20,12 @@
],
cfi: true,
},
+ host_supported: true,
+ target: {
+ darwin: {
+ enabled: false,
+ },
+ },
}
//###############################################################################
diff --git a/media/libstagefright/id3/test/AndroidTest.xml b/media/libstagefright/id3/test/AndroidTest.xml
index 6c6697d..d6ea470 100644
--- a/media/libstagefright/id3/test/AndroidTest.xml
+++ b/media/libstagefright/id3/test/AndroidTest.xml
@@ -19,7 +19,7 @@
<option name="cleanup" value="true" />
<option name="push" value="ID3Test->/data/local/tmp/ID3Test" />
<option name="push-file"
- key="https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/id3/test/ID3Test.zip?unzip=true"
+ key="https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/id3/test/ID3Test-1.1.zip?unzip=true"
value="/data/local/tmp/ID3TestRes/" />
</target_preparer>
diff --git a/media/libstagefright/id3/test/ID3Test.cpp b/media/libstagefright/id3/test/ID3Test.cpp
index a8f1470..8db83cb 100644
--- a/media/libstagefright/id3/test/ID3Test.cpp
+++ b/media/libstagefright/id3/test/ID3Test.cpp
@@ -24,6 +24,7 @@
#include <datasource/FileSource.h>
#include <media/stagefright/foundation/hexdump.h>
+#include <media/MediaExtractorPluginHelper.h>
#include <ID3.h>
#include "ID3TestEnvironment.h"
@@ -42,14 +43,15 @@
string path = gEnv->getRes() + GetParam();
sp<FileSource> file = new FileSource(path.c_str());
ASSERT_EQ(file->initCheck(), (status_t)OK) << "File initialization failed! \n";
- ID3 tag(file.get());
+ DataSourceHelper helper(file->wrap());
+ ID3 tag(&helper);
ASSERT_TRUE(tag.isValid()) << "No valid ID3 tag found for " << path.c_str() << "\n";
ID3::Iterator it(tag, nullptr);
while (!it.done()) {
String8 id;
it.getID(&id);
- ASSERT_GT(id.length(), 0) << "No ID tag found! \n";
+ ASSERT_GT(id.length(), 0) << "Found an ID3 tag of 0 size";
ALOGV("Found ID tag: %s\n", String8(id).c_str());
it.next();
}
@@ -61,10 +63,11 @@
sp<android::FileSource> file = new FileSource(path.c_str());
ASSERT_EQ(file->initCheck(), (status_t)OK) << "File initialization failed! \n";
- ID3 tag(file.get());
+ DataSourceHelper helper(file->wrap());
+ ID3 tag(&helper);
ASSERT_TRUE(tag.isValid()) << "No valid ID3 tag found for " << path.c_str() << "\n";
- ASSERT_TRUE(tag.version() >= versionNumber)
- << "Expected version: " << tag.version() << " Found version: " << versionNumber;
+ ASSERT_EQ(tag.version(), versionNumber)
+ << "Found version: " << tag.version() << " Expected version: " << versionNumber;
}
TEST_P(ID3textTagTest, TextTagTest) {
@@ -73,21 +76,39 @@
sp<android::FileSource> file = new FileSource(path.c_str());
ASSERT_EQ(file->initCheck(), (status_t)OK) << "File initialization failed! \n";
- ID3 tag(file.get());
+ DataSourceHelper helper(file->wrap());
+ ID3 tag(&helper);
ASSERT_TRUE(tag.isValid()) << "No valid ID3 tag found for " << path.c_str() << "\n";
int countTextFrames = 0;
ID3::Iterator it(tag, nullptr);
- while (!it.done()) {
- String8 id;
- it.getID(&id);
- ASSERT_GT(id.length(), 0);
- if (id[0] == 'T') {
- String8 text;
- countTextFrames++;
- it.getString(&text);
- ALOGV("Found text frame %s : %s \n", id.string(), text.string());
+ if (tag.version() != ID3::ID3_V1 && tag.version() != ID3::ID3_V1_1) {
+ while (!it.done()) {
+ String8 id;
+ it.getID(&id);
+ ASSERT_GT(id.length(), 0) << "Found an ID3 tag of 0 size";
+ if (id[0] == 'T') {
+ String8 text;
+ countTextFrames++;
+ it.getString(&text);
+ ALOGV("Found text frame %s : %s \n", id.string(), text.string());
+ }
+ it.next();
}
- it.next();
+ } else {
+ while (!it.done()) {
+ String8 id;
+ String8 text;
+ it.getID(&id);
+ ASSERT_GT(id.length(), 0) << "Found an ID3 tag of 0 size";
+ it.getString(&text);
+ // if the tag has a value
+ if (strcmp(text.string(), "")) {
+ countTextFrames++;
+ ALOGV("ID: %s\n", id.c_str());
+ ALOGV("Text string: %s\n", text.string());
+ }
+ it.next();
+ }
}
ASSERT_EQ(countTextFrames, numTextFrames)
<< "Expected " << numTextFrames << " text frames, found " << countTextFrames;
@@ -99,7 +120,8 @@
sp<android::FileSource> file = new FileSource(path.c_str());
ASSERT_EQ(file->initCheck(), (status_t)OK) << "File initialization failed! \n";
- ID3 tag(file.get());
+ DataSourceHelper helper(file->wrap());
+ ID3 tag(&helper);
ASSERT_TRUE(tag.isValid()) << "No valid ID3 tag found for " << path.c_str() << "\n";
size_t dataSize;
String8 mime;
@@ -109,7 +131,7 @@
if (data) {
ALOGV("Found album art: size = %zu mime = %s \n", dataSize, mime.string());
}
- ASSERT_NE(data, nullptr) << "Expected album art, found none!" << path;
+ ASSERT_NE(data, nullptr) << "Expected album art, found none! " << path;
} else {
ASSERT_EQ(data, nullptr) << "Found album art when expected none!";
}
@@ -124,14 +146,15 @@
sp<android::FileSource> file = new FileSource(path.c_str());
ASSERT_EQ(file->initCheck(), (status_t)OK) << "File initialization failed! \n";
- ID3 tag(file.get());
+ DataSourceHelper helper(file->wrap());
+ ID3 tag(&helper);
ASSERT_TRUE(tag.isValid()) << "No valid ID3 tag found for " << path.c_str() << "\n";
int count = 0;
ID3::Iterator it(tag, nullptr);
while (!it.done()) {
String8 id;
it.getID(&id);
- ASSERT_GT(id.length(), 0);
+ ASSERT_GT(id.length(), 0) << "Found an ID3 tag of 0 size";
// Check if the tag is an "APIC/PIC" tag.
if (String8(id) == "APIC" || String8(id) == "PIC") {
count++;
@@ -144,7 +167,7 @@
hexdump(data, dataSize > 128 ? 128 : dataSize);
#endif
}
- ASSERT_NE(data, nullptr) << "Expected album art, found none!" << path;
+ ASSERT_NE(data, nullptr) << "Expected album art, found none! " << path;
}
it.next();
}
@@ -153,56 +176,67 @@
}
INSTANTIATE_TEST_SUITE_P(id3TestAll, ID3tagTest,
- ::testing::Values("bbb_44100hz_2ch_128kbps_mp3_30sec.mp3",
- "bbb_44100hz_2ch_128kbps_mp3_30sec_1_image.mp3",
- "bbb_44100hz_2ch_128kbps_mp3_30sec_2_image.mp3",
- "bbb_44100hz_2ch_128kbps_mp3_5mins.mp3",
- "bbb_44100hz_2ch_128kbps_mp3_5mins_1_image.mp3",
- "bbb_44100hz_2ch_128kbps_mp3_5mins_2_image.mp3",
- "bbb_44100hz_2ch_128kbps_mp3_5mins_largeSize.mp3",
- "bbb_44100hz_2ch_128kbps_mp3_30sec_moreTextFrames.mp3"));
+ ::testing::Values("bbb_1sec_v23.mp3",
+ "bbb_1sec_1_image.mp3",
+ "bbb_1sec_2_image.mp3",
+ "bbb_2sec_v24.mp3",
+ "bbb_2sec_1_image.mp3",
+ "bbb_2sec_2_image.mp3",
+ "bbb_2sec_largeSize.mp3",
+ "bbb_1sec_v23_3tags.mp3",
+ "bbb_1sec_v1_5tags.mp3",
+ "bbb_2sec_v24_unsynchronizedOneFrame.mp3",
+ "bbb_2sec_v24_unsynchronizedAllFrames.mp3"));
INSTANTIATE_TEST_SUITE_P(
id3TestAll, ID3versionTest,
- ::testing::Values(make_pair("bbb_44100hz_2ch_128kbps_mp3_30sec.mp3", 4),
- make_pair("bbb_44100hz_2ch_128kbps_mp3_30sec_1_image.mp3", 4),
- make_pair("bbb_44100hz_2ch_128kbps_mp3_30sec_2_image.mp3", 4),
- make_pair("bbb_44100hz_2ch_128kbps_mp3_5mins.mp3", 4),
- make_pair("bbb_44100hz_2ch_128kbps_mp3_5mins_1_image.mp3", 4),
- make_pair("bbb_44100hz_2ch_128kbps_mp3_5mins_2_image.mp3", 4),
- make_pair("bbb_44100hz_2ch_128kbps_mp3_5mins_largeSize.mp3", 4),
- make_pair("bbb_44100hz_2ch_128kbps_mp3_30sec_moreTextFrames.mp3", 4)));
+ ::testing::Values(make_pair("bbb_1sec_v23.mp3", ID3::ID3_V2_3),
+ make_pair("bbb_1sec_1_image.mp3", ID3::ID3_V2_3),
+ make_pair("bbb_1sec_2_image.mp3", ID3::ID3_V2_3),
+ make_pair("bbb_2sec_v24.mp3", ID3::ID3_V2_4),
+ make_pair("bbb_2sec_1_image.mp3", ID3::ID3_V2_4),
+ make_pair("bbb_2sec_2_image.mp3", ID3::ID3_V2_4),
+ make_pair("bbb_2sec_largeSize.mp3", ID3::ID3_V2_4),
+ make_pair("bbb_1sec_v23_3tags.mp3", ID3::ID3_V2_3),
+ make_pair("bbb_1sec_v1_5tags.mp3", ID3::ID3_V1_1),
+ make_pair("bbb_1sec_v1_3tags.mp3", ID3::ID3_V1_1),
+ make_pair("bbb_2sec_v24_unsynchronizedOneFrame.mp3", ID3::ID3_V2_4),
+ make_pair("bbb_2sec_v24_unsynchronizedAllFrames.mp3", ID3::ID3_V2_4)));
INSTANTIATE_TEST_SUITE_P(
id3TestAll, ID3textTagTest,
- ::testing::Values(make_pair("bbb_44100hz_2ch_128kbps_mp3_30sec.mp3", 1),
- make_pair("bbb_44100hz_2ch_128kbps_mp3_30sec_1_image.mp3", 1),
- make_pair("bbb_44100hz_2ch_128kbps_mp3_30sec_2_image.mp3", 1),
- make_pair("bbb_44100hz_2ch_128kbps_mp3_5mins.mp3", 1),
- make_pair("bbb_44100hz_2ch_128kbps_mp3_5mins_1_image.mp3", 1),
- make_pair("bbb_44100hz_2ch_128kbps_mp3_5mins_2_image.mp3", 1),
- make_pair("bbb_44100hz_2ch_128kbps_mp3_5mins_largeSize.mp3", 1),
- make_pair("bbb_44100hz_2ch_128kbps_mp3_30sec_moreTextFrames.mp3", 5)));
+ ::testing::Values(
+ make_pair("bbb_1sec_v23.mp3", 1),
+ make_pair("bbb_1sec_1_image.mp3", 1),
+ make_pair("bbb_1sec_2_image.mp3", 1),
+ make_pair("bbb_2sec_v24.mp3", 1),
+ make_pair("bbb_2sec_1_image.mp3", 1),
+ make_pair("bbb_2sec_2_image.mp3", 1),
+ make_pair("bbb_2sec_largeSize.mp3", 1),
+ make_pair("bbb_1sec_v23_3tags.mp3", 3),
+ make_pair("bbb_1sec_v1_5tags.mp3", 5),
+ make_pair("bbb_1sec_v1_3tags.mp3", 3),
+ make_pair("bbb_2sec_v24_unsynchronizedOneFrame.mp3", 3),
+ make_pair("bbb_2sec_v24_unsynchronizedAllFrames.mp3", 3)));
-INSTANTIATE_TEST_SUITE_P(
- id3TestAll, ID3albumArtTest,
- ::testing::Values(make_pair("bbb_44100hz_2ch_128kbps_mp3_30sec.mp3", false),
- make_pair("bbb_44100hz_2ch_128kbps_mp3_30sec_1_image.mp3", true),
- make_pair("bbb_44100hz_2ch_128kbps_mp3_30sec_2_image.mp3", true),
- make_pair("bbb_44100hz_2ch_128kbps_mp3_5mins.mp3", false),
- make_pair("bbb_44100hz_2ch_128kbps_mp3_5mins_1_image.mp3", true),
- make_pair("bbb_44100hz_2ch_128kbps_mp3_5mins_2_image.mp3", true),
- make_pair("bbb_44100hz_2ch_128kbps_mp3_5mins_largeSize.mp3", true)));
+INSTANTIATE_TEST_SUITE_P(id3TestAll, ID3albumArtTest,
+ ::testing::Values(make_pair("bbb_1sec_v23.mp3", false),
+ make_pair("bbb_1sec_1_image.mp3", true),
+ make_pair("bbb_1sec_2_image.mp3", true),
+ make_pair("bbb_2sec_v24.mp3", false),
+ make_pair("bbb_2sec_1_image.mp3", true),
+ make_pair("bbb_2sec_2_image.mp3", true),
+ make_pair("bbb_2sec_largeSize.mp3", true),
+ make_pair("bbb_1sec_v1_5tags.mp3", false)));
-INSTANTIATE_TEST_SUITE_P(
- id3TestAll, ID3multiAlbumArtTest,
- ::testing::Values(make_pair("bbb_44100hz_2ch_128kbps_mp3_30sec.mp3", 0),
- make_pair("bbb_44100hz_2ch_128kbps_mp3_5mins.mp3", 0),
- make_pair("bbb_44100hz_2ch_128kbps_mp3_30sec_1_image.mp3", 1),
- make_pair("bbb_44100hz_2ch_128kbps_mp3_5mins_1_image.mp3", 1),
- make_pair("bbb_44100hz_2ch_128kbps_mp3_30sec_2_image.mp3", 2),
- make_pair("bbb_44100hz_2ch_128kbps_mp3_5mins_2_image.mp3", 2),
- make_pair("bbb_44100hz_2ch_128kbps_mp3_5mins_largeSize.mp3", 3)));
+INSTANTIATE_TEST_SUITE_P(id3TestAll, ID3multiAlbumArtTest,
+ ::testing::Values(make_pair("bbb_1sec_v23.mp3", 0),
+ make_pair("bbb_2sec_v24.mp3", 0),
+ make_pair("bbb_1sec_1_image.mp3", 1),
+ make_pair("bbb_2sec_1_image.mp3", 1),
+ make_pair("bbb_1sec_2_image.mp3", 2),
+ make_pair("bbb_2sec_2_image.mp3", 2),
+ make_pair("bbb_2sec_largeSize.mp3", 3)));
int main(int argc, char **argv) {
gEnv = new ID3TestEnvironment();
diff --git a/media/libstagefright/include/media/stagefright/MetaData.h b/media/libstagefright/include/media/stagefright/MetaData.h
index f625358..68adf346 100644
--- a/media/libstagefright/include/media/stagefright/MetaData.h
+++ b/media/libstagefright/include/media/stagefright/MetaData.h
@@ -41,7 +41,9 @@
friend class BnMediaSource;
friend class BpMediaSource;
friend class BpMediaExtractor;
+#ifndef __ANDROID_VNDK__
static sp<MetaData> createFromParcel(const Parcel &parcel);
+#endif
};
} // namespace android
diff --git a/media/libstagefright/include/media/stagefright/MetaDataBase.h b/media/libstagefright/include/media/stagefright/MetaDataBase.h
index 8dc2dd5..659bd5b 100644
--- a/media/libstagefright/include/media/stagefright/MetaDataBase.h
+++ b/media/libstagefright/include/media/stagefright/MetaDataBase.h
@@ -319,8 +319,10 @@
struct Rect;
struct MetaDataInternal;
MetaDataInternal *mInternalData;
+#ifndef __ANDROID_VNDK__
status_t writeToParcel(Parcel &parcel);
status_t updateFromParcel(const Parcel &parcel);
+#endif
};
} // namespace android
diff --git a/media/libstagefright/rtsp/NetworkUtils.cpp b/media/libstagefright/rtsp/NetworkUtils.cpp
index cc36b78..c053be8 100644
--- a/media/libstagefright/rtsp/NetworkUtils.cpp
+++ b/media/libstagefright/rtsp/NetworkUtils.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#include <unistd.h>
+
//#define LOG_NDEBUG 0
#define LOG_TAG "NetworkUtils"
#include <utils/Log.h>
diff --git a/media/libstagefright/tests/HEVC/Android.bp b/media/libstagefright/tests/HEVC/Android.bp
new file mode 100644
index 0000000..7a6b959
--- /dev/null
+++ b/media/libstagefright/tests/HEVC/Android.bp
@@ -0,0 +1,51 @@
+/*
+ * 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: "HEVCUtilsUnitTest",
+ gtest: true,
+
+ srcs: [
+ "HEVCUtilsUnitTest.cpp",
+ ],
+
+ shared_libs: [
+ "libutils",
+ "liblog",
+ ],
+
+ static_libs: [
+ "libstagefright",
+ "libstagefright_foundation",
+ ],
+
+ include_dirs: [
+ "frameworks/av/media/libstagefright",
+ ],
+
+ cflags: [
+ "-Werror",
+ "-Wall",
+ ],
+
+ sanitize: {
+ cfi: true,
+ misc_undefined: [
+ "unsigned-integer-overflow",
+ "signed-integer-overflow",
+ ],
+ },
+}
diff --git a/media/libstagefright/tests/HEVC/AndroidTest.xml b/media/libstagefright/tests/HEVC/AndroidTest.xml
new file mode 100644
index 0000000..ff850a2
--- /dev/null
+++ b/media/libstagefright/tests/HEVC/AndroidTest.xml
@@ -0,0 +1,31 @@
+<?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 HEVC Utils unit tests">
+ <option name="test-suite-tag" value="HEVCUtilsUnitTest" />
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="cleanup" value="false" />
+ <option name="push" value="HEVCUtilsUnitTest->/data/local/tmp/HEVCUtilsUnitTest" />
+ <option name="push-file"
+ key="https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/foundation/tests/HEVCUtils/HEVCUtilsUnitTest.zip?unzip=true"
+ value="/data/local/tmp/HEVCUtilsUnitTest/" />
+ </target_preparer>
+
+ <test class="com.android.tradefed.testtype.GTest" >
+ <option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="module-name" value="HEVCUtilsUnitTest" />
+ <option name="native-test-flag" value="-P /data/local/tmp/HEVCUtilsUnitTest/" />
+ </test>
+</configuration>
diff --git a/media/libstagefright/tests/HEVC/HEVCUtilsTestEnvironment.h b/media/libstagefright/tests/HEVC/HEVCUtilsTestEnvironment.h
new file mode 100644
index 0000000..e4481e1
--- /dev/null
+++ b/media/libstagefright/tests/HEVC/HEVCUtilsTestEnvironment.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 __HEVC_UTILS_TEST_ENVIRONMENT_H__
+#define __HEVC_UTILS_TEST_ENVIRONMENT_H__
+
+#include <gtest/gtest.h>
+
+#include <getopt.h>
+
+using namespace std;
+
+class HEVCUtilsTestEnvironment : public::testing::Environment {
+ public:
+ HEVCUtilsTestEnvironment() : 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 HEVCUtilsTestEnvironment::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 // __HEVC_UTILS_TEST_ENVIRONMENT_H__
diff --git a/media/libstagefright/tests/HEVC/HEVCUtilsUnitTest.cpp b/media/libstagefright/tests/HEVC/HEVCUtilsUnitTest.cpp
new file mode 100644
index 0000000..324a042
--- /dev/null
+++ b/media/libstagefright/tests/HEVC/HEVCUtilsUnitTest.cpp
@@ -0,0 +1,208 @@
+/*
+ * 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 "HevcUtilityTest"
+#include <utils/Log.h>
+
+#include <fstream>
+
+#include <media/stagefright/foundation/ABitReader.h>
+#include "include/HevcUtils.h"
+
+#include "HEVCUtilsTestEnvironment.h"
+
+using namespace android;
+
+// max size of hvcc box is 2 KB
+constexpr uint32_t kHvccBoxMaxSize = 2048;
+constexpr uint32_t kHvccBoxMinSize = 20;
+constexpr uint32_t kVPSCode = 32;
+constexpr uint32_t kSPSCode = 33;
+constexpr uint32_t kPPSCode = 34;
+constexpr uint32_t kNALSizeLength = 2;
+
+static HEVCUtilsTestEnvironment *gEnv = nullptr;
+
+class HEVCUtilsUnitTest
+ : public ::testing::TestWithParam<
+ tuple</*fileName*/ string, /*infoFileName*/ string, /*numVPSNals*/ size_t,
+ /*numSPSNals*/ size_t, /*numPPSNals*/ size_t, /*frameRate*/ int16_t,
+ /*isHdr*/ bool>> {
+ public:
+ ~HEVCUtilsUnitTest() {
+ if (mMediaFileStream.is_open()) mMediaFileStream.close();
+ if (mInfoFileStream.is_open()) mInfoFileStream.close();
+ }
+
+ virtual void SetUp() override {
+ tuple<string, string, size_t, size_t, size_t, int16_t, bool> params = GetParam();
+ string inputMediaFile = gEnv->getRes() + get<0>(params);
+ mMediaFileStream.open(inputMediaFile, ifstream::in);
+ ASSERT_TRUE(mMediaFileStream.is_open()) << "Failed to open media file: " << inputMediaFile;
+
+ string inputInfoFile = gEnv->getRes() + get<1>(params);
+ mInfoFileStream.open(inputInfoFile, ifstream::in);
+ ASSERT_TRUE(mInfoFileStream.is_open()) << "Failed to open info file: " << inputInfoFile;
+
+ mNumVPSNals = get<2>(params);
+ mNumSPSNals = get<3>(params);
+ mNumPPSNals = get<4>(params);
+ mFrameRate = get<5>(params);
+ mIsHDR = get<6>(params);
+ }
+
+ size_t mNumVPSNals;
+ size_t mNumSPSNals;
+ size_t mNumPPSNals;
+ int16_t mFrameRate;
+ bool mIsHDR;
+ ifstream mMediaFileStream;
+ ifstream mInfoFileStream;
+};
+
+TEST_P(HEVCUtilsUnitTest, NALUnitTest) {
+ HevcParameterSets hevcParams;
+
+ string line;
+ int32_t index = 0;
+ status_t err;
+ while (getline(mInfoFileStream, line)) {
+ string type;
+ int32_t chunkLength;
+
+ istringstream stringLine(line);
+ stringLine >> type >> chunkLength;
+ ASSERT_GT(chunkLength, 0) << "Length of data chunk must be greater than 0";
+
+ char *data = (char *)malloc(chunkLength);
+ ASSERT_NE(data, nullptr) << "Failed to allocate data buffer of size: " << chunkLength;
+
+ mMediaFileStream.read(data, chunkLength);
+ ASSERT_EQ(mMediaFileStream.gcount(), chunkLength)
+ << "Failed to read complete file, bytes read: " << mMediaFileStream.gcount();
+
+ // A valid startcode consists of at least two 0x00 bytes followed by 0x01.
+ int32_t offset = 0;
+ for (; offset + 2 < chunkLength; ++offset) {
+ if (data[offset + 2] == 0x01 && data[offset + 1] == 0x00 && data[offset] == 0x00) {
+ break;
+ }
+ }
+ offset += 3;
+ ASSERT_LE(offset, chunkLength) << "NAL unit offset must not exceed the chunk length";
+
+ uint8_t *nalUnit = (uint8_t *)(data + offset);
+ size_t nalUnitLength = chunkLength - offset;
+
+ // Add NAL units only if they're of type: VPS/SPS/PPS/SEI
+ if (!((type.compare("VPS") && type.compare("SPS") && type.compare("PPS") &&
+ type.compare("SEI")))) {
+ err = hevcParams.addNalUnit(nalUnit, nalUnitLength);
+ ASSERT_EQ(err, (status_t)OK)
+ << "Failed to add NAL Unit type: " << type << " Size: " << nalUnitLength;
+
+ size_t sizeNalUnit = hevcParams.getSize(index);
+ ASSERT_EQ(sizeNalUnit, nalUnitLength) << "Invalid size returned for NAL: " << type;
+
+ uint8_t *destination = (uint8_t *)malloc(nalUnitLength);
+ ASSERT_NE(destination, nullptr)
+ << "Failed to allocate buffer of size: " << nalUnitLength;
+
+ bool status = hevcParams.write(index, destination, nalUnitLength);
+ ASSERT_TRUE(status) << "Unable to write NAL Unit data";
+
+ free(destination);
+ index++;
+ } else {
+ err = hevcParams.addNalUnit(nalUnit, nalUnitLength);
+ ASSERT_NE(err, (status_t)OK) << "Invalid NAL Unit added, type: " << type;
+ }
+ free(data);
+ }
+
+ size_t numNalUnits = hevcParams.getNumNalUnitsOfType(kVPSCode);
+ ASSERT_EQ(numNalUnits, mNumVPSNals) << "Wrong number of VPS NAL Units";
+
+ numNalUnits = hevcParams.getNumNalUnitsOfType(kSPSCode);
+ ASSERT_EQ(numNalUnits, mNumSPSNals) << "Wrong number of SPS NAL Units";
+
+ numNalUnits = hevcParams.getNumNalUnitsOfType(kPPSCode);
+ ASSERT_EQ(numNalUnits, mNumPPSNals) << "Wrong number of PPS NAL Units";
+
+ HevcParameterSets::Info info = hevcParams.getInfo();
+ ASSERT_EQ(info & HevcParameterSets::kInfoIsHdr,
+ (mIsHDR ? HevcParameterSets::kInfoIsHdr : HevcParameterSets::kInfoNone))
+ << "Wrong info about HDR";
+
+ ASSERT_EQ(info & HevcParameterSets::kInfoHasColorDescription,
+ (mIsHDR ? HevcParameterSets::kInfoHasColorDescription : HevcParameterSets::kInfoNone))
+ << "Wrong info about color description";
+
+ // an HEVC file starts with VPS, SPS and PPS NAL units in sequence.
+ uint8_t typeNalUnit = hevcParams.getType(0);
+ ASSERT_EQ(typeNalUnit, kHevcNalUnitTypeVps)
+ << "Expected NAL type: 32(VPS), found: " << typeNalUnit;
+
+ typeNalUnit = hevcParams.getType(1);
+ ASSERT_EQ(typeNalUnit, kHevcNalUnitTypeSps)
+ << "Expected NAL type: 33(SPS), found: " << typeNalUnit;
+
+ typeNalUnit = hevcParams.getType(2);
+ ASSERT_EQ(typeNalUnit, kHevcNalUnitTypePps)
+ << "Expected NAL type: 34(PPS), found: " << typeNalUnit;
+
+ size_t hvccBoxSize = kHvccBoxMaxSize;
+ uint8_t *hvcc = (uint8_t *)malloc(kHvccBoxMaxSize);
+ ASSERT_NE(hvcc, nullptr) << "Failed to allocate a hvcc buffer of size: " << kHvccBoxMaxSize;
+
+ err = hevcParams.makeHvcc(hvcc, &hvccBoxSize, kNALSizeLength);
+ ASSERT_EQ(err, (status_t)OK) << "Unable to create hvcc box";
+
+ ASSERT_GT(hvccBoxSize, kHvccBoxMinSize)
+ << "Hvcc box size must be greater than " << kHvccBoxMinSize;
+
+ int16_t frameRate = hvcc[kHvccBoxMinSize - 1] | (hvcc[kHvccBoxMinSize] << 8);
+ if (frameRate != mFrameRate)
+ cout << "[ WARN ] Expected frame rate: " << mFrameRate << " Found: " << frameRate
+ << endl;
+
+ free(hvcc);
+}
+
+// Info File contains the type and length for each chunk/frame
+INSTANTIATE_TEST_SUITE_P(
+ HEVCUtilsUnitTestAll, HEVCUtilsUnitTest,
+ ::testing::Values(make_tuple("crowd_3840x2160p50f300_32500kbps.hevc",
+ "crowd_3840x2160p50f300_32500kbps.info", 1, 1, 1, 50, false),
+ make_tuple("crowd_1920x1080p24f300_4500kbps.hevc",
+ "crowd_1920x1080p24f300_4500kbps.info", 1, 1, 1, 24, false),
+ make_tuple("crowd_1280x720p24f300_3000kbps.hevc",
+ "crowd_1280x720p24f300_3000kbps.info", 1, 1, 1, 24, false),
+ make_tuple("crowd_640x360p24f300_500kbps.hevc",
+ "crowd_640x360p24f300_500kbps.info", 1, 1, 1, 24, false)));
+
+int main(int argc, char **argv) {
+ gEnv = new HEVCUtilsTestEnvironment();
+ ::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/HEVC/README.md b/media/libstagefright/tests/HEVC/README.md
new file mode 100644
index 0000000..fa0e99c
--- /dev/null
+++ b/media/libstagefright/tests/HEVC/README.md
@@ -0,0 +1,39 @@
+## Media Testing ##
+---
+#### HEVC Utils Test
+The HEVC Utility Unit Test Suite validates the HevcUtils library available in libstagefright.
+
+Run the following steps to build the test suite:
+```
+m HEVCUtilsUnitTest
+```
+
+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/HEVCUtilsUnitTest/HEVCUtilsUnitTest /data/local/tmp/
+```
+
+To test 32-bit binary push binaries from nativetest.
+```
+adb push ${OUT}/data/nativetest/HEVCUtilsUnitTest/HEVCUtilsUnitTest /data/local/tmp/
+```
+
+The resource file for the tests is taken from [here](https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/foundation/tests/HEVCUtils/HEVCUtilsUnitTest.zip). Download, unzip and push these files into device for testing.
+
+```
+adb push HEVCUtilsUnitTest /data/local/tmp/
+```
+
+usage: HEVCUtilsUnitTest -P \<path_to_folder\>
+```
+adb shell /data/local/tmp/HEVCUtilsUnitTest -P /data/local/tmp/HEVCUtilsUnitTest/
+```
+Alternatively, the test can also be run using atest command.
+
+```
+atest HEVCUtilsUnitTest -- --enable-module-dynamic-download=true
+```
diff --git a/media/libstagefright/tests/writer/AndroidTest.xml b/media/libstagefright/tests/writer/AndroidTest.xml
index d831555..a21be8a 100644
--- a/media/libstagefright/tests/writer/AndroidTest.xml
+++ b/media/libstagefright/tests/writer/AndroidTest.xml
@@ -19,12 +19,13 @@
<option name="cleanup" value="true" />
<option name="push" value="writerTest->/data/local/tmp/writerTest" />
<option name="push-file"
- key="https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/tests/writer/Writer.zip?unzip=true"
- value="/data/local/tmp/writerTestRes/" />
+ key="https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/tests/writer/WriterTestRes.zip?unzip=true"
+ value="/data/local/tmp/WriterTestRes/" />
</target_preparer>
<test class="com.android.tradefed.testtype.GTest" >
<option name="native-test-device-path" value="/data/local/tmp" />
<option name="module-name" value="writerTest" />
- <option name="native-test-flag" value="-P /data/local/tmp/writerTestRes/" />
+ <option name="native-test-flag" value="-P /data/local/tmp/WriterTestRes/" />
+ <option name="native-test-flag" value="-C true" />
</test>
</configuration>
diff --git a/media/libstagefright/tests/writer/README.md b/media/libstagefright/tests/writer/README.md
index ae07917..e103613 100644
--- a/media/libstagefright/tests/writer/README.md
+++ b/media/libstagefright/tests/writer/README.md
@@ -19,13 +19,18 @@
adb push ${OUT}/data/nativetest/writerTest/writerTest /data/local/tmp/
-The resource file for the tests is taken from [here](https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/tests/writer/writerTestRes.zip).
+The resource file for the tests is taken from [here](https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/tests/writer/WriterTestRes.zip).
Download and extract the folder. Push all the files in this folder to /data/local/tmp/ on the device.
```
-adb push writerTestRes /data/local/tmp/
+adb push WriterTestRes /data/local/tmp/
```
-usage: writerTest -P \<path_to_res_folder\>
+usage: writerTest -P \<path_to_res_folder\> -C <remove_output_file>
```
-adb shell /data/local/tmp/writerTest -P /data/local/tmp/
+adb shell /data/local/tmp/writerTest -P /data/local/tmp/WriterTestRes/ -C true
+```
+Alternatively, the test can also be run using atest command.
+
+```
+atest writerTest -- --enable-module-dynamic-download=true
```
diff --git a/media/libstagefright/tests/writer/WriterTest.cpp b/media/libstagefright/tests/writer/WriterTest.cpp
index 3fa2aa6..4d8df2d 100644
--- a/media/libstagefright/tests/writer/WriterTest.cpp
+++ b/media/libstagefright/tests/writer/WriterTest.cpp
@@ -107,6 +107,7 @@
}
mBufferInfo.clear();
if (mInputStream.is_open()) mInputStream.close();
+ if (gEnv->cleanUp()) remove(OUTPUT_FILE_NAME);
}
void setupWriterType(string writerFormat) {
diff --git a/media/libstagefright/tests/writer/WriterTestEnvironment.h b/media/libstagefright/tests/writer/WriterTestEnvironment.h
index 99e686f..7da0a62 100644
--- a/media/libstagefright/tests/writer/WriterTestEnvironment.h
+++ b/media/libstagefright/tests/writer/WriterTestEnvironment.h
@@ -25,7 +25,7 @@
class WriterTestEnvironment : public ::testing::Environment {
public:
- WriterTestEnvironment() : res("/data/local/tmp/") {}
+ WriterTestEnvironment() : res("/data/local/tmp/"), deleteOutput(true) {}
// Parses the command line arguments
int initFromOptions(int argc, char **argv);
@@ -34,16 +34,21 @@
const string getRes() const { return res; }
+ bool cleanUp() const { return deleteOutput; }
+
private:
string res;
+ bool deleteOutput;
};
int WriterTestEnvironment::initFromOptions(int argc, char **argv) {
- static struct option options[] = {{"res", required_argument, 0, 'P'}, {0, 0, 0, 0}};
+ static struct option options[] = {{"res", required_argument, 0, 'P'},
+ {"cleanUp", optional_argument, 0, 'C'},
+ {0, 0, 0, 0}};
while (true) {
int index = 0;
- int c = getopt_long(argc, argv, "P:", options, &index);
+ int c = getopt_long(argc, argv, "P:C:", options, &index);
if (c == -1) {
break;
}
@@ -52,6 +57,11 @@
case 'P':
setRes(optarg);
break;
+ case 'C':
+ if (!strcmp(optarg, "false")) {
+ deleteOutput = false;
+ }
+ break;
default:
break;
}
@@ -62,7 +72,8 @@
"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",
+ "-P, --path: Resource files directory location\n"
+ "-C, default:true. Delete output file after test completes\n",
argv[optind ?: 1], argv[0]);
return 2;
}
diff --git a/media/libstagefright/timedtext/TextDescriptions.cpp b/media/libstagefright/timedtext/TextDescriptions.cpp
index 6c94754..2c2d11d 100644
--- a/media/libstagefright/timedtext/TextDescriptions.cpp
+++ b/media/libstagefright/timedtext/TextDescriptions.cpp
@@ -504,7 +504,7 @@
return OK;
}
- parcel->write(tmpData, len);
+ parcel->writeByteArray(len, tmpData);
tmpData += len;
subChunkRemaining -= len;
}
diff --git a/media/libstagefright/timedtext/test/AndroidTest.xml b/media/libstagefright/timedtext/test/AndroidTest.xml
index 8925790..3654e23 100644
--- a/media/libstagefright/timedtext/test/AndroidTest.xml
+++ b/media/libstagefright/timedtext/test/AndroidTest.xml
@@ -25,7 +25,7 @@
<test class="com.android.tradefed.testtype.GTest" >
<option name="native-test-device-path" value="/data/local/tmp" />
- <option name="module-name" value="TimedTextUnitTestt" />
+ <option name="module-name" value="TimedTextUnitTest" />
<option name="native-test-flag" value="-P /data/local/tmp/TimedTextUnitTestRes/" />
</test>
</configuration>
diff --git a/media/libstagefright/timedtext/test/TimedTextUnitTest.cpp b/media/libstagefright/timedtext/test/TimedTextUnitTest.cpp
index 64379d6..d85ae39 100644
--- a/media/libstagefright/timedtext/test/TimedTextUnitTest.cpp
+++ b/media/libstagefright/timedtext/test/TimedTextUnitTest.cpp
@@ -346,6 +346,8 @@
ASSERT_EQ(parcel.readInt32(), fontRecordEntries[i].fontNameLength)
<< "Parcel has invalid value of font name length";
uint8_t fontName[fontRecordEntries[i].fontNameLength];
+ // written with writeByteArray() writes count, then the actual data
+ ASSERT_EQ(parcel.readInt32(), fontRecordEntries[i].fontNameLength);
status = parcel.read((void *)fontName, fontRecordEntries[i].fontNameLength);
ASSERT_EQ(status, 0) << "Failed to read the font name from parcel";
ASSERT_EQ(memcmp(fontName, fontRecordEntries[i].font, fontRecordEntries[i].fontNameLength),
diff --git a/media/libstagefright/xmlparser/MediaCodecsXmlParser.cpp b/media/libstagefright/xmlparser/MediaCodecsXmlParser.cpp
index a232150..3be5e74 100644
--- a/media/libstagefright/xmlparser/MediaCodecsXmlParser.cpp
+++ b/media/libstagefright/xmlparser/MediaCodecsXmlParser.cpp
@@ -1525,7 +1525,7 @@
nodeInfo.attributeList.push_back(Attribute{"rank", rank});
}
nodeList->insert(std::make_pair(
- std::move(order), std::move(nodeInfo)));
+ order, std::move(nodeInfo)));
}
}
}
diff --git a/media/libstagefright/xmlparser/test/Android.bp b/media/libstagefright/xmlparser/test/Android.bp
new file mode 100644
index 0000000..6d97c96
--- /dev/null
+++ b/media/libstagefright/xmlparser/test/Android.bp
@@ -0,0 +1,52 @@
+/*
+ * 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: "XMLParserTest",
+ gtest: true,
+
+ srcs: [
+ "XMLParserTest.cpp",
+ ],
+
+ shared_libs: [
+ "liblog",
+ "libstagefright_xmlparser",
+ ],
+
+ cflags: [
+ "-Werror",
+ "-Wall",
+ ],
+
+ data: [":xmlparsertest_test_files",],
+
+ sanitize: {
+ misc_undefined: [
+ "unsigned-integer-overflow",
+ "signed-integer-overflow",
+ ],
+ cfi: true,
+ },
+}
+
+filegroup {
+ name: "xmlparsertest_test_files",
+ srcs: [
+ "testdata/media_codecs_unit_test.xml",
+ "testdata/media_codecs_unit_test_caller.xml",
+ ],
+}
diff --git a/media/libstagefright/xmlparser/test/AndroidTest.xml b/media/libstagefright/xmlparser/test/AndroidTest.xml
new file mode 100644
index 0000000..2e11b1b
--- /dev/null
+++ b/media/libstagefright/xmlparser/test/AndroidTest.xml
@@ -0,0 +1,28 @@
+<?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 xml parser unit test">
+ <option name="test-suite-tag" value="XMLParserTest" />
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="cleanup" value="true" />
+ <option name="push" value="media_codecs_unit_test.xml->/data/local/tmp/media_codecs_unit_test.xml" />
+ <option name="push" value="media_codecs_unit_test_caller.xml->/data/local/tmp/media_codecs_unit_test_caller.xml" />
+ <option name="push" value="XMLParserTest->/data/local/tmp/XMLParserTest" />
+ </target_preparer>
+ <test class="com.android.tradefed.testtype.GTest" >
+ <option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="module-name" value="XMLParserTest" />
+ </test>
+</configuration>
diff --git a/media/libstagefright/xmlparser/test/README.md b/media/libstagefright/xmlparser/test/README.md
new file mode 100644
index 0000000..e9363fd
--- /dev/null
+++ b/media/libstagefright/xmlparser/test/README.md
@@ -0,0 +1,33 @@
+## Media Testing ##
+---
+#### XML Parser
+The XMLParser Test Suite validates the XMLParser available in libstagefright.
+
+Run the following steps to build the test suite:
+```
+m XMLParserTest
+```
+
+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/XMLParserTest/XMLParserTest /data/local/tmp/
+```
+
+To test 32-bit binary push binaries from nativetest.
+```
+adb push ${OUT}/data/nativetest/XMLParserTest/XMLParserTest /data/local/tmp/
+```
+
+usage: XMLParserTest
+```
+adb shell /data/local/tmp/XMLParserTest
+```
+Alternatively, the test can also be run using atest command.
+
+```
+atest XMLParserTest
+```
diff --git a/media/libstagefright/xmlparser/test/XMLParserTest.cpp b/media/libstagefright/xmlparser/test/XMLParserTest.cpp
new file mode 100644
index 0000000..9ddd374
--- /dev/null
+++ b/media/libstagefright/xmlparser/test/XMLParserTest.cpp
@@ -0,0 +1,392 @@
+/*
+ * 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 "XMLParserTest"
+
+#include <utils/Log.h>
+
+#include <fstream>
+
+#include <media/stagefright/xmlparser/MediaCodecsXmlParser.h>
+
+#include "XMLParserTestEnvironment.h"
+
+#define XML_FILE_NAME "media_codecs_unit_test_caller.xml"
+
+using namespace android;
+
+static XMLParserTestEnvironment *gEnv = nullptr;
+
+struct CodecProperties {
+ string codecName;
+ MediaCodecsXmlParser::CodecProperties codecProp;
+};
+
+struct RoleProperties {
+ string roleName;
+ string typeName;
+ string codecName;
+ bool isEncoder;
+ size_t order;
+ vector<pair<string, string>> attributeMap;
+};
+
+class XMLParseTest : public ::testing::Test {
+ public:
+ ~XMLParseTest() {
+ if (mEleStream.is_open()) mEleStream.close();
+ mInputDataVector.clear();
+ mInputRoleVector.clear();
+ }
+
+ virtual void SetUp() override { setUpDatabase(); }
+
+ void setUpDatabase();
+
+ void setCodecProperties(string codecName, bool isEncoder, int32_t order, set<string> quirkSet,
+ set<string> domainSet, set<string> variantSet, string typeName,
+ vector<pair<string, string>> domain, vector<string> aliases,
+ string rank);
+
+ void setRoleProperties(string roleName, bool isEncoder, int32_t order, string typeName,
+ string codecName, vector<pair<string, string>> domain);
+
+ void setServiceAttribute(map<string, string> serviceAttributeNameValuePair);
+
+ void printCodecMap(const MediaCodecsXmlParser::Codec mcodec);
+
+ void checkRoleMap(int32_t index, bool isEncoder, string typeName, string codecName,
+ vector<pair<string, string>> attrMap);
+
+ bool compareMap(const map<string, string> &lhs, const map<string, string> &rhs);
+
+ ifstream mEleStream;
+ MediaCodecsXmlParser mParser;
+ vector<CodecProperties> mInputDataVector;
+ vector<RoleProperties> mInputRoleVector;
+ map<string, string> mInputServiceAttributeMap;
+};
+
+void XMLParseTest::setUpDatabase() {
+ // The values set below are specific to test vector testdata/media_codecs_unit_test.xml
+ setCodecProperties("test1.decoder", false, 1, {"attribute::disabled", "quirk::quirk1"},
+ {"telephony"}, {}, "audio/mpeg", {}, {"alias1.decoder"}, "4");
+
+ setCodecProperties("test2.decoder", false, 2, {"quirk::quirk1"}, {}, {}, "audio/3gpp", {}, {},
+ "");
+
+ setCodecProperties("test3.decoder", false, 3, {}, {}, {}, "audio/amr-wb",
+ {
+ pair<string, string>("feature-feature1", "feature1Val"),
+ pair<string, string>("feature-feature2", "0"),
+ pair<string, string>("feature-feature3", "0"),
+ },
+ {}, "");
+
+ setCodecProperties("test4.decoder", false, 4, {}, {}, {}, "audio/flac",
+ {pair<string, string>("feature-feature1", "feature1Val")}, {}, "");
+
+ setCodecProperties("test5.decoder", false, 5, {"attribute::attributeQuirk1"}, {}, {},
+ "audio/g711-mlaw", {}, {}, "");
+
+ setCodecProperties("test6.decoder", false, 6, {}, {}, {"variant1", "variant2"},
+ "audio/mp4a-latm",
+ {pair<string, string>("variant1:::variant1Limit1-range",
+ "variant1Limit1Min-variant1Limit1Max"),
+ pair<string, string>("variant1:::variant1Limit2-range",
+ "variant1Limit2Low-variant1Limit2High"),
+ pair<string, string>("variant2:::variant2Limit1", "variant2Limit1Value")},
+ {}, "");
+
+ setCodecProperties(
+ "test7.decoder", false, 7, {}, {}, {}, "audio/vorbis",
+ {
+ pair<string, string>("-min-limit1", "limit1Min"),
+ /*pair<string, string>("limit1-in", "limit1In"),*/
+ pair<string, string>("limit2-range", "limit2Min-limit2Max"),
+ pair<string, string>("limit2-scale", "limit2Scale"),
+ pair<string, string>("limit3-default", "limit3Val3"),
+ pair<string, string>("limit3-ranges", "limit3Val1,limit3Val2,limit3Val3"),
+ },
+ {}, "");
+
+ setCodecProperties("test8.encoder", true, 8, {}, {}, {}, "audio/opus",
+ {pair<string, string>("max-limit1", "limit1Max")}, {}, "");
+
+ setRoleProperties("audio_decoder.mp3", false, 1, "audio/mpeg", "test1.decoder",
+ {pair<string, string>("attribute::disabled", "present"),
+ pair<string, string>("rank", "4")});
+
+ setRoleProperties("audio_decoder.amrnb", false, 2, "audio/3gpp", "test2.decoder", {});
+
+ setRoleProperties("audio_decoder.amrwb", false, 3, "audio/amr-wb", "test3.decoder",
+ {pair<string, string>("feature-feature1", "feature1Val"),
+ pair<string, string>("feature-feature2", "0"),
+ pair<string, string>("feature-feature3", "0")});
+
+ setRoleProperties("audio/flac", false, 4, "audio/flac", "test4.decoder",
+ {pair<string, string>("feature-feature1", "feature1Val")});
+
+ setRoleProperties("audio_decoder.g711mlaw", false, 5, "audio/g711-mlaw", "test5.decoder",
+ {pair<string, string>("attribute::attributeQuirk1", "present")});
+
+ setRoleProperties("audio_decoder.aac", false, 6, "audio/mp4a-latm", "test6.decoder",
+ {pair<string, string>("variant1:::variant1Limit1-range",
+ "variant1Limit1Min-variant1Limit1Max"),
+ pair<string, string>("variant1:::variant1Limit2-range",
+ "variant1Limit2Low-variant1Limit2High"),
+ pair<string, string>("variant2:::variant2Limit1", "variant2Limit1Value")});
+
+ setRoleProperties("audio_decoder.vorbis", false, 7, "audio/vorbis", "test7.decoder",
+ {pair<string, string>("-min-limit1", "limit1Min"),
+ /*pair<string, string>("limit1-in", "limit1In"),*/
+ pair<string, string>("limit2-range", "limit2Min-limit2Max"),
+ pair<string, string>("limit2-scale", "limit2Scale"),
+ pair<string, string>("limit3-default", "limit3Val3"),
+ pair<string, string>("limit3-ranges", "limit3Val1,limit3Val2,limit3Val3")});
+
+ setRoleProperties("audio_encoder.opus", true, 8, "audio/opus", "test8.encoder",
+ {pair<string, string>("max-limit1", "limit1Max")});
+
+ setServiceAttribute(
+ {pair<string, string>("domain-telephony", "0"), pair<string, string>("domain-tv", "0"),
+ pair<string, string>("setting2", "0"), pair<string, string>("variant-variant1", "0")});
+}
+
+bool XMLParseTest::compareMap(const map<string, string> &lhs, const map<string, string> &rhs) {
+ return lhs.size() == rhs.size() && equal(lhs.begin(), lhs.end(), rhs.begin());
+}
+
+void XMLParseTest::setCodecProperties(string codecName, bool isEncoder, int32_t order,
+ set<string> quirkSet, set<string> domainSet,
+ set<string> variantSet, string typeName,
+ vector<pair<string, string>> domain, vector<string> aliases,
+ string rank) {
+ map<string, string> AttributeMapDB;
+ for (const auto &AttrStr : domain) {
+ AttributeMapDB.insert(AttrStr);
+ }
+ map<string, MediaCodecsXmlParser::AttributeMap> TypeMapDataBase;
+ TypeMapDataBase.insert(
+ pair<string, MediaCodecsXmlParser::AttributeMap>(typeName, AttributeMapDB));
+ CodecProperties codecProperty;
+ codecProperty.codecName = codecName;
+ codecProperty.codecProp.isEncoder = isEncoder;
+ codecProperty.codecProp.order = order;
+ codecProperty.codecProp.quirkSet = quirkSet;
+ codecProperty.codecProp.domainSet = domainSet;
+ codecProperty.codecProp.variantSet = variantSet;
+ codecProperty.codecProp.typeMap = TypeMapDataBase;
+ codecProperty.codecProp.aliases = aliases;
+ codecProperty.codecProp.rank = rank;
+ mInputDataVector.push_back(codecProperty);
+}
+
+void XMLParseTest::setRoleProperties(string roleName, bool isEncoder, int32_t order,
+ string typeName, string codecName,
+ vector<pair<string, string>> attributeNameValuePair) {
+ struct RoleProperties roleProperty;
+ roleProperty.roleName = roleName;
+ roleProperty.typeName = typeName;
+ roleProperty.codecName = codecName;
+ roleProperty.isEncoder = isEncoder;
+ roleProperty.order = order;
+ roleProperty.attributeMap = attributeNameValuePair;
+ mInputRoleVector.push_back(roleProperty);
+}
+
+void XMLParseTest::setServiceAttribute(map<string, string> serviceAttributeNameValuePair) {
+ for (const auto &serviceAttrStr : serviceAttributeNameValuePair) {
+ mInputServiceAttributeMap.insert(serviceAttrStr);
+ }
+}
+
+void XMLParseTest::printCodecMap(const MediaCodecsXmlParser::Codec mcodec) {
+ const string &name = mcodec.first;
+ ALOGV("codec name = %s\n", name.c_str());
+ const MediaCodecsXmlParser::CodecProperties &properties = mcodec.second;
+ bool isEncoder = properties.isEncoder;
+ ALOGV("isEncoder = %d\n", isEncoder);
+ size_t order = properties.order;
+ ALOGV("order = %zu\n", order);
+ string rank = properties.rank;
+ ALOGV("rank = %s\n", rank.c_str());
+
+ for (auto &itrQuirkSet : properties.quirkSet) {
+ ALOGV("quirkSet= %s", itrQuirkSet.c_str());
+ }
+
+ for (auto &itrDomainSet : properties.domainSet) {
+ ALOGV("domainSet= %s", itrDomainSet.c_str());
+ }
+
+ for (auto &itrVariantSet : properties.variantSet) {
+ ALOGV("variantSet= %s", itrVariantSet.c_str());
+ }
+
+ map<string, MediaCodecsXmlParser::AttributeMap> TypeMap = properties.typeMap;
+ ALOGV("The TypeMap is :");
+
+ for (auto &itrTypeMap : TypeMap) {
+ ALOGV("itrTypeMap->first\t%s\t", itrTypeMap.first.c_str());
+
+ for (auto &itrAttributeMap : itrTypeMap.second) {
+ ALOGV("AttributeMap->first = %s", itrAttributeMap.first.c_str());
+ ALOGV("AttributeMap->second = %s", itrAttributeMap.second.c_str());
+ }
+ }
+}
+
+void XMLParseTest::checkRoleMap(int32_t index, bool isEncoder, string typeName, string codecName,
+ vector<pair<string, string>> AttributePairMap) {
+ ASSERT_EQ(isEncoder, mInputRoleVector.at(index).isEncoder)
+ << "Invalid RoleMap data. IsEncoder mismatch";
+ ASSERT_EQ(typeName, mInputRoleVector.at(index).typeName)
+ << "Invalid RoleMap data. typeName mismatch";
+ ASSERT_EQ(codecName, mInputRoleVector.at(index).codecName)
+ << "Invalid RoleMap data. codecName mismatch";
+
+ vector<pair<string, string>>::iterator itr_attributeMapDB =
+ (mInputRoleVector.at(index).attributeMap).begin();
+ vector<pair<string, string>>::iterator itr_attributeMap = AttributePairMap.begin();
+ for (; itr_attributeMap != AttributePairMap.end() &&
+ itr_attributeMapDB != mInputRoleVector.at(index).attributeMap.end();
+ ++itr_attributeMap, ++itr_attributeMapDB) {
+ string attributeName = itr_attributeMap->first;
+ string attributeNameDB = itr_attributeMapDB->first;
+ string attributevalue = itr_attributeMap->second;
+ string attributeValueDB = itr_attributeMapDB->second;
+ ASSERT_EQ(attributeName, attributeNameDB)
+ << "Invalid RoleMap data. Attribute name mismatch\t" << attributeName << " != "
+ << "attributeNameDB";
+ ASSERT_EQ(attributevalue, attributeValueDB)
+ << "Invalid RoleMap data. Attribute value mismatch\t" << attributevalue << " != "
+ << "attributeValueDB";
+ }
+}
+
+TEST_F(XMLParseTest, CodecMapParseTest) {
+ string inputFileName = gEnv->getRes() + XML_FILE_NAME;
+ mEleStream.open(inputFileName, ifstream::binary);
+ ASSERT_EQ(mEleStream.is_open(), true) << "Failed to open inputfile " << inputFileName;
+
+ mParser.parseXmlPath(inputFileName);
+ for (const MediaCodecsXmlParser::Codec &mcodec : mParser.getCodecMap()) {
+ printCodecMap(mcodec);
+ const MediaCodecsXmlParser::CodecProperties &properties = mcodec.second;
+ int32_t index = properties.order - 1;
+ ASSERT_GE(index, 0) << "Invalid order";
+ ASSERT_EQ(mInputDataVector.at(index).codecName, mcodec.first.c_str())
+ << "Invalid CodecMap data. codecName mismatch";
+ ASSERT_EQ(properties.isEncoder, mInputDataVector.at(index).codecProp.isEncoder)
+ << "Invalid CodecMap data. isEncoder mismatch";
+ ASSERT_EQ(properties.order, mInputDataVector.at(index).codecProp.order)
+ << "Invalid CodecMap data. order mismatch";
+
+ set<string> quirkSetDB = mInputDataVector.at(index).codecProp.quirkSet;
+ set<string> quirkSet = properties.quirkSet;
+ set<string> quirkDifference;
+ set_difference(quirkSetDB.begin(), quirkSetDB.end(), quirkSet.begin(), quirkSet.end(),
+ inserter(quirkDifference, quirkDifference.end()));
+ ASSERT_EQ(quirkDifference.size(), 0) << "CodecMap:quirk mismatch";
+
+ map<string, MediaCodecsXmlParser::AttributeMap> TypeMapDB =
+ mInputDataVector.at(index).codecProp.typeMap;
+ map<string, MediaCodecsXmlParser::AttributeMap> TypeMap = properties.typeMap;
+ map<string, MediaCodecsXmlParser::AttributeMap>::iterator itr_TypeMapDB = TypeMapDB.begin();
+ map<string, MediaCodecsXmlParser::AttributeMap>::iterator itr_TypeMap = TypeMap.begin();
+
+ ASSERT_EQ(TypeMapDB.size(), TypeMap.size())
+ << "Invalid CodecMap data. Typemap size mismatch";
+
+ for (; itr_TypeMap != TypeMap.end() && itr_TypeMapDB != TypeMapDB.end();
+ ++itr_TypeMap, ++itr_TypeMapDB) {
+ ASSERT_EQ(itr_TypeMap->first, itr_TypeMapDB->first)
+ << "Invalid CodecMap data. type mismatch";
+ bool flag = compareMap(itr_TypeMap->second, itr_TypeMapDB->second);
+ ASSERT_TRUE(flag) << "typeMap mismatch";
+ }
+ ASSERT_EQ(mInputDataVector.at(index).codecProp.rank, properties.rank)
+ << "Invalid CodecMap data. rank mismatch";
+ }
+}
+
+TEST_F(XMLParseTest, RoleMapParseTest) {
+ string inputFileName = gEnv->getRes() + XML_FILE_NAME;
+ mEleStream.open(inputFileName, ifstream::binary);
+ ASSERT_EQ(mEleStream.is_open(), true) << "Failed to open inputfile " << inputFileName;
+
+ mParser.parseXmlPath(inputFileName);
+
+ for (auto &mRole : mParser.getRoleMap()) {
+ typedef pair<string, string> Attribute;
+ const string &roleName = mRole.first;
+ ALOGV("Role map:name = %s\n", roleName.c_str());
+ const MediaCodecsXmlParser::RoleProperties &properties = mRole.second;
+ string type = properties.type;
+ ALOGV("Role map: type = %s\n", type.c_str());
+
+ bool isEncoder = properties.isEncoder;
+ ALOGV("Role map: isEncoder = %d\n", isEncoder);
+
+ multimap<size_t, MediaCodecsXmlParser::NodeInfo> nodeList = properties.nodeList;
+ multimap<size_t, MediaCodecsXmlParser::NodeInfo>::iterator itr_Node;
+ ALOGV("\nThe multimap nodeList is : \n");
+ for (itr_Node = nodeList.begin(); itr_Node != nodeList.end(); ++itr_Node) {
+ ALOGV("itr_Node->first=ORDER=\t%zu\t", itr_Node->first);
+ int32_t index = itr_Node->first - 1;
+ MediaCodecsXmlParser::NodeInfo nodePtr = itr_Node->second;
+ ALOGV("Role map:itr_Node->second.name = %s\n", nodePtr.name.c_str());
+ vector<Attribute> attrList = nodePtr.attributeList;
+ for (auto attrNameValueList = attrList.begin(); attrNameValueList != attrList.end();
+ ++attrNameValueList) {
+ ALOGV("Role map:nodePtr.attributeList->first = %s\n",
+ attrNameValueList->first.c_str());
+ ALOGV("Role map:nodePtr.attributeList->second = %s\n",
+ attrNameValueList->second.c_str());
+ }
+ checkRoleMap(index, isEncoder, properties.type, nodePtr.name.c_str(), attrList);
+ }
+ }
+}
+
+TEST_F(XMLParseTest, ServiceAttributeMapParseTest) {
+ string inputFileName = gEnv->getRes() + XML_FILE_NAME;
+ mEleStream.open(inputFileName, ifstream::binary);
+ ASSERT_EQ(mEleStream.is_open(), true) << "Failed to open inputfile " << inputFileName;
+
+ mParser.parseXmlPath(inputFileName);
+ const auto serviceAttributeMap = mParser.getServiceAttributeMap();
+ for (const auto &attributePair : serviceAttributeMap) {
+ ALOGV("serviceAttribute.key = %s \t serviceAttribute.value = %s",
+ attributePair.first.c_str(), attributePair.second.c_str());
+ }
+ bool flag = compareMap(mInputServiceAttributeMap, serviceAttributeMap);
+ ASSERT_TRUE(flag) << "ServiceMapParseTest: typeMap mismatch";
+}
+
+int main(int argc, char **argv) {
+ gEnv = new XMLParserTestEnvironment();
+ ::testing::AddGlobalTestEnvironment(gEnv);
+ ::testing::InitGoogleTest(&argc, argv);
+ int status = gEnv->initFromOptions(argc, argv);
+ if (status == 0) {
+ status = RUN_ALL_TESTS();
+ ALOGD("XML Parser Test Result = %d\n", status);
+ }
+ return status;
+}
diff --git a/media/libstagefright/xmlparser/test/XMLParserTestEnvironment.h b/media/libstagefright/xmlparser/test/XMLParserTestEnvironment.h
new file mode 100644
index 0000000..61a09e6
--- /dev/null
+++ b/media/libstagefright/xmlparser/test/XMLParserTestEnvironment.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 __XML_PARSER_TEST_ENVIRONMENT_H__
+#define __XML_PARSER_TEST_ENVIRONMENT_H__
+
+#include <gtest/gtest.h>
+
+#include <getopt.h>
+
+using namespace std;
+
+class XMLParserTestEnvironment : public ::testing::Environment {
+ public:
+ XMLParserTestEnvironment() : 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 XMLParserTestEnvironment::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 // __XML_PARSER_TEST_ENVIRONMENT_H__
diff --git a/media/libstagefright/xmlparser/test/testdata/media_codecs_unit_test.xml b/media/libstagefright/xmlparser/test/testdata/media_codecs_unit_test.xml
new file mode 100644
index 0000000..a7299d3
--- /dev/null
+++ b/media/libstagefright/xmlparser/test/testdata/media_codecs_unit_test.xml
@@ -0,0 +1,80 @@
+<?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.
+-->
+
+<!-- REFERENCE : frameworks/av/media/libstagefright/xmlparser/media_codecs.xsd -->
+<Included>
+ <Settings>
+ <Domain name="telephony" enabled="false" />
+ <Domain name="tv" enabled="false" />
+ <Variant name="variant1" enabled="false" />
+ <Setting name="setting1" value="settingValue1" update="true" />
+ <Setting name="setting2" enabled="false" />
+ </Settings>
+ <Decoders>
+ <!-- entry for enabled, domain, rank and update properties -->
+ <MediaCodec name="test1.decoder" type="audio/mpeg" update="false" domain="telephony" enabled="false" rank="4">
+ <Alias name="alias1.decoder" />
+ <Quirk name="quirk1" value="quirk1Value"/>
+ </MediaCodec>
+ <!-- entry for testing Quirk -->
+ <MediaCodec name="test2.decoder" type="audio/3gpp" enabled="true" >
+ <Quirk name="quirk1" value="quirk1Value"/>
+ </MediaCodec>
+ <!-- entry for testing Feature -->
+ <!-- feature2 takes value 0 (feature with same name takes lower feature's value) -->
+ <!-- feature3 gives value as 0 since it's optional -->
+ <!-- optional="true" required="true" is not a valid combination. -->
+ <!-- optional="false" required="false" is not a valid combination. -->
+ <MediaCodec name="test3.decoder" type="audio/amr-wb" >
+ <Feature name="feature1" value="feature1Val" />
+ <Feature name="feature2" value="feature2Val"/>
+ <Feature name="feature2" />
+ <Feature name="feature3" optional="true" required="false" />
+ </MediaCodec>
+ <!-- entry for testing Type -->
+ <MediaCodec name="test4.decoder">
+ <Type name="audio/flac">
+ <Feature name="feature1" value="feature1Val" />
+ </Type>
+ </MediaCodec>
+ <!-- entry for testing Attribute -->
+ <MediaCodec name="test5.decoder" type="audio/g711-mlaw" >
+ <Attribute name="attributeQuirk1" />
+ </MediaCodec>
+ <!-- entry for testing Variant -->
+ <MediaCodec name="test6.decoder" type="audio/mp4a-latm" variant="variant1,variant2" >
+ <Variant name="variant1">
+ <Limit name="variant1Limit1" min="variant1Limit1Min" max="variant1Limit1Max" />
+ <Limit name="variant1Limit2" range="variant1Limit2Low-variant1Limit2High" />
+ </Variant>
+ <Variant name="variant2">
+ <Limit name="variant2Limit1" value="variant2Limit1Value" />
+ </Variant>
+ </MediaCodec>
+ <!-- entry for testing Limit -->
+ <!-- 'in' is present in xsd file but not handled in MediaCodecsXmlParser -->
+ <MediaCodec name="test7.decoder" type="audio/vorbis" >
+ <Limit name="limit1" in="limit1In" min="limit1Min"/>
+ <Limit name="limit2" min="limit2Min" max="limit2Max" scale="limit2Scale" />
+ <Limit name="limit3" ranges="limit3Val1,limit3Val2,limit3Val3" default="limit3Val3" />
+ </MediaCodec>
+ </Decoders>
+ <Encoders>
+ <MediaCodec name="test8.encoder" type="audio/opus">
+ <Limit name="limit1" max="limit1Max" />
+ </MediaCodec>
+ </Encoders>
+</Included>
diff --git a/media/libstagefright/xmlparser/test/testdata/media_codecs_unit_test_caller.xml b/media/libstagefright/xmlparser/test/testdata/media_codecs_unit_test_caller.xml
new file mode 100644
index 0000000..d864ce9
--- /dev/null
+++ b/media/libstagefright/xmlparser/test/testdata/media_codecs_unit_test_caller.xml
@@ -0,0 +1,4 @@
+<!-- entry for testing Include -->
+<MediaCodecs>
+ <Include href="media_codecs_unit_test.xml" />
+</MediaCodecs>
diff --git a/media/libstagefright/xmlparser/vts/Android.bp b/media/libstagefright/xmlparser/vts/Android.bp
index 3f93e9e..132ce82 100644
--- a/media/libstagefright/xmlparser/vts/Android.bp
+++ b/media/libstagefright/xmlparser/vts/Android.bp
@@ -30,4 +30,12 @@
"-Wall",
"-Werror",
],
+ data: [
+ ":media_codecs",
+ ],
+ test_suites: [
+ "general-tests",
+ "vts"
+ ],
+ test_config: "vts_mediaCodecs_validate_test.xml",
}
diff --git a/media/libstagefright/xmlparser/vts/vts_mediaCodecs_validate_test.xml b/media/libstagefright/xmlparser/vts/vts_mediaCodecs_validate_test.xml
new file mode 100644
index 0000000..fbb7cc6
--- /dev/null
+++ b/media/libstagefright/xmlparser/vts/vts_mediaCodecs_validate_test.xml
@@ -0,0 +1,33 @@
+<?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="Runs vts_mediaCodecs_validate_test.">
+ <option name="test-suite-tag" value="apct" />
+ <option name="test-suite-tag" value="apct-native" />
+
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
+ </target_preparer>
+
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="cleanup" value="true" />
+ <option name="push" value="media_codecs.xsd->/data/local/tmp/media_codecs.xsd" />
+ <option name="push" value="vts_mediaCodecs_validate_test->/data/local/tmp/vts_mediaCodecs_validate_test" />
+ </target_preparer>
+
+ <test class="com.android.tradefed.testtype.GTest" >
+ <option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="module-name" value="vts_mediaCodecs_validate_test" />
+ </test>
+</configuration>
diff --git a/media/mediaserver/mediaserver.rc b/media/mediaserver/mediaserver.rc
index f6c325c..cfc4258 100644
--- a/media/mediaserver/mediaserver.rc
+++ b/media/mediaserver/mediaserver.rc
@@ -3,4 +3,4 @@
user media
group audio camera inet net_bt net_bt_admin net_bw_acct drmrpc mediadrm
ioprio rt 4
- writepid /dev/cpuset/foreground/tasks /dev/stune/foreground/tasks
+ task_profiles ProcessCapacityHigh HighPerformance
diff --git a/media/mtp/MtpFfsHandle.cpp b/media/mtp/MtpFfsHandle.cpp
index bd6a6c6..c8b4a03 100644
--- a/media/mtp/MtpFfsHandle.cpp
+++ b/media/mtp/MtpFfsHandle.cpp
@@ -114,11 +114,11 @@
void MtpFfsHandle::advise(int fd) {
for (unsigned i = 0; i < NUM_IO_BUFS; i++) {
if (posix_madvise(mIobuf[i].bufs.data(), MAX_FILE_CHUNK_SIZE,
- POSIX_MADV_SEQUENTIAL | POSIX_MADV_WILLNEED) < 0)
+ POSIX_MADV_SEQUENTIAL | POSIX_MADV_WILLNEED) != 0)
PLOG(ERROR) << "Failed to madvise";
}
if (posix_fadvise(fd, 0, 0,
- POSIX_FADV_SEQUENTIAL | POSIX_FADV_NOREUSE | POSIX_FADV_WILLNEED) < 0)
+ POSIX_FADV_SEQUENTIAL | POSIX_FADV_NOREUSE | POSIX_FADV_WILLNEED) != 0)
PLOG(ERROR) << "Failed to fadvise";
}
diff --git a/media/ndk/Android.bp b/media/ndk/Android.bp
index 24cad4d..be33081 100644
--- a/media/ndk/Android.bp
+++ b/media/ndk/Android.bp
@@ -35,7 +35,13 @@
cc_library_headers {
name: "media_ndk_headers",
vendor_available: true,
- export_include_dirs: ["include"]
+ export_include_dirs: ["include"],
+ host_supported: true,
+ target: {
+ darwin: {
+ enabled: false,
+ },
+ },
}
cc_library_shared {
@@ -70,6 +76,7 @@
],
header_libs: [
+ "jni_headers",
"libmediadrm_headers",
],
@@ -97,6 +104,8 @@
"libmediandk_utils",
],
+ export_header_lib_headers: ["jni_headers"],
+
export_include_dirs: ["include"],
export_shared_lib_headers: [
@@ -182,3 +191,41 @@
"frameworks/av/media/ndk/",
],
}
+
+cc_library_static {
+ name: "libmediandk_format",
+
+ host_supported: true,
+
+ srcs: [
+ "NdkMediaFormat.cpp",
+ ],
+
+ header_libs: [
+ "libstagefright_foundation_headers",
+ ],
+
+ cflags: [
+ "-DEXPORT=__attribute__((visibility(\"default\")))",
+ "-Werror",
+ "-Wall",
+ ],
+
+ export_include_dirs: ["include"],
+
+ sanitize: {
+ misc_undefined: [
+ "unsigned-integer-overflow",
+ "signed-integer-overflow",
+ ],
+ cfi: true,
+ },
+
+ target: {
+ darwin: {
+ enabled: false,
+ },
+ },
+
+ apex_available: ["com.android.media"],
+}
diff --git a/media/ndk/NdkMediaFormat.cpp b/media/ndk/NdkMediaFormat.cpp
index 51138c8..5526bca 100644
--- a/media/ndk/NdkMediaFormat.cpp
+++ b/media/ndk/NdkMediaFormat.cpp
@@ -26,9 +26,6 @@
#include <utils/StrongPointer.h>
#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/AMessage.h>
-#include <android_util_Binder.h>
-
-#include <jni.h>
using namespace android;
diff --git a/media/tests/benchmark/MediaBenchmarkTest/src/androidTest/java/com/android/media/benchmark/tests/EncoderTest.java b/media/tests/benchmark/MediaBenchmarkTest/src/androidTest/java/com/android/media/benchmark/tests/EncoderTest.java
index 48e1422..4202732 100644
--- a/media/tests/benchmark/MediaBenchmarkTest/src/androidTest/java/com/android/media/benchmark/tests/EncoderTest.java
+++ b/media/tests/benchmark/MediaBenchmarkTest/src/androidTest/java/com/android/media/benchmark/tests/EncoderTest.java
@@ -34,6 +34,7 @@
import com.android.media.benchmark.library.Native;
import com.android.media.benchmark.library.Stats;
+import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -57,40 +58,87 @@
public class EncoderTest {
private static final Context mContext =
InstrumentationRegistry.getInstrumentation().getTargetContext();
+ private static final String mFileDirPath = mContext.getFilesDir() + "/";
private static final String mInputFilePath = mContext.getString(R.string.input_file_path);
private static final String mOutputFilePath = mContext.getString(R.string.output_file_path);
private static final String mStatsFile =
mContext.getExternalFilesDir(null) + "/Encoder." + System.currentTimeMillis() + ".csv";
private static final String TAG = "EncoderTest";
- private static final long PER_TEST_TIMEOUT_MS = 120000;
private static final boolean DEBUG = false;
private static final boolean WRITE_OUTPUT = false;
+ private static final long PER_TEST_TIMEOUT_MS = 120000;
private static final int ENCODE_DEFAULT_FRAME_RATE = 25;
- private static final int ENCODE_DEFAULT_BIT_RATE = 8000000 /* 8 Mbps */;
- private static final int ENCODE_MIN_BIT_RATE = 600000 /* 600 Kbps */;
+ private static final int ENCODE_DEFAULT_VIDEO_BIT_RATE = 8000000 /* 8 Mbps */;
+ private static final int ENCODE_MIN_VIDEO_BIT_RATE = 600000 /* 600 Kbps */;
private static final int ENCODE_DEFAULT_AUDIO_BIT_RATE = 128000 /* 128 Kbps */;
+ private static int mColorFormat = COLOR_FormatYUV420Flexible;
+ private static File mDecodedFileQcif;
+ private static File mDecodedFileFullHd;
+ private static File mDecodedFileAudio;
private String mInputFile;
+ private String mMime;
+ private int mBitRate;
+ private int mIFrameInterval;
+ private int mWidth;
+ private int mHeight;
+ private int mProfile;
+ private int mLevel;
+ private int mSampleRate;
+ private int mNumChannel;
+ private static final String DECODE_FULLHD_INPUT = "crowd_1920x1080_25fps_4000kbps_h265.mkv";
+ private static final String DECODE_QCIF_INPUT = "crowd_176x144_25fps_6000kbps_mpeg4.mp4";
+ private static final String DECODE_AUDIO_INPUT = "bbb_48000hz_2ch_100kbps_opus_30sec.webm";
+ private static final String DECODE_FULLHD_UNPACKED = "crowd_1920x1080_25fps_4000kbps_h265.yuv";
+ private static final String DECODE_QCIF_UNPACKED = "crowd_176x144_25fps_6000kbps_mpeg4.yuv";
+ private static final String DECODE_AUDIO_UNPACKED = "bbb_48000hz_2ch_100kbps_opus_30sec.raw";
@Parameterized.Parameters
public static Collection<Object[]> inputFiles() {
return Arrays.asList(new Object[][]{
// Audio Test
- {"bbb_44100hz_2ch_128kbps_aac_30sec.mp4"},
- {"bbb_8000hz_1ch_8kbps_amrnb_30sec.3gp"},
- {"bbb_16000hz_1ch_9kbps_amrwb_30sec.3gp"},
- {"bbb_44100hz_2ch_600kbps_flac_30sec.mp4"},
- {"bbb_48000hz_2ch_100kbps_opus_30sec.webm"},
+ // Parameters: Filename, mimeType, bitrate, width, height, iFrameInterval,
+ // profile, level, sampleRate, channelCount
+ {DECODE_AUDIO_UNPACKED, MediaFormat.MIMETYPE_AUDIO_AAC,
+ ENCODE_DEFAULT_AUDIO_BIT_RATE, -1, -1, -1, -1, -1, 44100, 2},
+ {DECODE_AUDIO_UNPACKED, MediaFormat.MIMETYPE_AUDIO_AMR_NB,
+ ENCODE_DEFAULT_AUDIO_BIT_RATE, -1, -1, -1, -1, -1, 8000, 1},
+ {DECODE_AUDIO_UNPACKED, MediaFormat.MIMETYPE_AUDIO_AMR_WB,
+ ENCODE_DEFAULT_AUDIO_BIT_RATE, -1, -1, -1, -1, -1, 16000, 1},
+ {DECODE_AUDIO_UNPACKED, MediaFormat.MIMETYPE_AUDIO_FLAC,
+ ENCODE_DEFAULT_AUDIO_BIT_RATE, -1, -1, -1, -1, -1, 44100, 2},
+ {DECODE_AUDIO_UNPACKED, MediaFormat.MIMETYPE_AUDIO_OPUS,
+ ENCODE_DEFAULT_AUDIO_BIT_RATE, -1, -1, -1, -1, -1, 48000, 2},
+
// Video Test
- {"crowd_1920x1080_25fps_4000kbps_vp8.webm"},
- {"crowd_1920x1080_25fps_6700kbps_h264.ts"},
- {"crowd_1920x1080_25fps_4000kbps_h265.mkv"},
- {"crowd_1920x1080_25fps_4000kbps_vp9.webm"},
- {"crowd_176x144_25fps_6000kbps_mpeg4.mp4"},
- {"crowd_176x144_25fps_6000kbps_h263.3gp"}});
+ // Parameters: Filename, mimeType, bitrate, width, height, iFrameInterval,
+ // profile, level, sampleRate, channelCount
+ {DECODE_FULLHD_UNPACKED, MediaFormat.MIMETYPE_VIDEO_VP8,
+ ENCODE_DEFAULT_VIDEO_BIT_RATE, 1920, 1080, 1, -1, -1, -1, -1},
+ {DECODE_FULLHD_UNPACKED, MediaFormat.MIMETYPE_VIDEO_AVC,
+ ENCODE_DEFAULT_VIDEO_BIT_RATE, 1920, 1080, 1, -1, -1, -1, -1},
+ {DECODE_FULLHD_UNPACKED, MediaFormat.MIMETYPE_VIDEO_HEVC,
+ ENCODE_DEFAULT_VIDEO_BIT_RATE, 1920, 1080, 1, -1, -1, -1, -1},
+ {DECODE_FULLHD_UNPACKED, MediaFormat.MIMETYPE_VIDEO_VP9,
+ ENCODE_DEFAULT_VIDEO_BIT_RATE, 1920, 1080, 1, -1, -1, -1, -1},
+ {DECODE_QCIF_UNPACKED, MediaFormat.MIMETYPE_VIDEO_MPEG4, ENCODE_MIN_VIDEO_BIT_RATE,
+ 176, 144, 1, -1, -1, -1, -1},
+ {DECODE_QCIF_UNPACKED, MediaFormat.MIMETYPE_VIDEO_H263, ENCODE_MIN_VIDEO_BIT_RATE,
+ 176, 144, 1, -1, -1, -1, -1}});
}
- public EncoderTest(String inputFileName) {
- this.mInputFile = inputFileName;
+ public EncoderTest(String filename, String mime, int bitrate, int width, int height,
+ int frameInterval, int profile, int level, int samplerate,
+ int channelCount) {
+ this.mInputFile = filename;
+ this.mMime = mime;
+ this.mBitRate = bitrate;
+ this.mIFrameInterval = frameInterval;
+ this.mWidth = width;
+ this.mHeight = height;
+ this.mProfile = profile;
+ this.mLevel = level;
+ this.mSampleRate = samplerate;
+ this.mNumChannel = channelCount;
}
@BeforeClass
@@ -101,33 +149,36 @@
Log.d(TAG, "Saving Benchmark results in: " + mStatsFile);
}
- @Test(timeout = PER_TEST_TIMEOUT_MS)
- public void testEncoder() throws Exception {
- int status;
- int frameSize;
- //Parameters for video
- int width = 0;
- int height = 0;
- int profile = 0;
- int level = 0;
- int frameRate = 0;
+ @BeforeClass
+ public static void prepareInput() throws IOException {
- //Parameters for audio
- int bitRate = 0;
- int sampleRate = 0;
- int numChannels = 0;
- File inputFile = new File(mInputFilePath + mInputFile);
- assertTrue("Cannot find " + mInputFile + " in directory " + mInputFilePath,
- inputFile.exists());
+ mDecodedFileFullHd = new File(mFileDirPath + DECODE_FULLHD_UNPACKED);
+ int status = decodeFile(mInputFilePath + DECODE_FULLHD_INPUT, mDecodedFileFullHd);
+ assertEquals("Decoder returned error " + status, 0, status);
+
+ mDecodedFileQcif = new File(mFileDirPath + DECODE_QCIF_UNPACKED);
+ status = decodeFile(mInputFilePath + DECODE_QCIF_INPUT, mDecodedFileQcif);
+ assertEquals("Decoder returned error " + status, 0, status);
+
+ mDecodedFileAudio = new File(mFileDirPath + DECODE_AUDIO_UNPACKED);
+ status = decodeFile(mInputFilePath + DECODE_AUDIO_INPUT, mDecodedFileAudio);
+ assertEquals("Decoder returned error " + status, 0, status);
+ }
+
+ private static int decodeFile(String inputFileName, File outputDecodeFile) throws IOException {
+ int status = -1;
+ File inputFile = new File(inputFileName);
+ assertTrue("Cannot open input file " + inputFileName, inputFile.exists());
FileInputStream fileInput = new FileInputStream(inputFile);
FileDescriptor fileDescriptor = fileInput.getFD();
+ FileOutputStream decodeOutputStream = new FileOutputStream(outputDecodeFile);
+
Extractor extractor = new Extractor();
int trackCount = extractor.setUpExtractor(fileDescriptor);
- assertTrue("Extraction failed. No tracks for file: " + mInputFile, (trackCount > 0));
+ assertTrue("Extraction failed. No tracks for the given input file", (trackCount > 0));
ArrayList<ByteBuffer> inputBuffer = new ArrayList<>();
ArrayList<MediaCodec.BufferInfo> frameInfo = new ArrayList<>();
for (int currentTrack = 0; currentTrack < trackCount; currentTrack++) {
- int colorFormat = COLOR_FormatYUV420Flexible;
extractor.selectExtractorTrack(currentTrack);
MediaFormat format = extractor.getFormat(currentTrack);
// Get samples from extractor
@@ -146,163 +197,135 @@
bufInfo.presentationTimeUs + " size = " + bufInfo.size);
}
} while (sampleSize > 0);
- int tid = android.os.Process.myTid();
- File decodedFile = new File(mContext.getFilesDir() + "/decoder_" + tid + ".out");
- FileOutputStream decodeOutputStream = new FileOutputStream(decodedFile);
Decoder decoder = new Decoder();
decoder.setupDecoder(decodeOutputStream);
status = decoder.decode(inputBuffer, frameInfo, false, format, "");
- assertEquals("Decoder returned error " + status + " for file: " + mInputFile, 0,
- status);
MediaFormat decoderFormat = decoder.getFormat();
+ if (decoderFormat.containsKey(MediaFormat.KEY_COLOR_FORMAT)) {
+ mColorFormat = decoderFormat.getInteger(MediaFormat.KEY_COLOR_FORMAT);
+ }
decoder.deInitCodec();
extractor.unselectExtractorTrack(currentTrack);
inputBuffer.clear();
frameInfo.clear();
- if (decodeOutputStream != null) {
- decodeOutputStream.close();
- }
- String mime = format.getString(MediaFormat.KEY_MIME);
- ArrayList<String> mediaCodecs = CodecUtils.selectCodecs(mime, true);
- assertTrue("No suitable codecs found for file: " + mInputFile + " track : " +
- currentTrack + " mime: " + mime, (mediaCodecs.size() > 0));
- Boolean[] encodeMode = {true, false};
- /* Encoding the decoder's output */
- for (Boolean asyncMode : encodeMode) {
- for (String codecName : mediaCodecs) {
- FileOutputStream encodeOutputStream = null;
- if (WRITE_OUTPUT) {
- File outEncodeFile = new File(mOutputFilePath + "encoder.out");
- if (outEncodeFile.exists()) {
- assertTrue(" Unable to delete existing file" + outEncodeFile.toString(),
- outEncodeFile.delete());
- }
- assertTrue("Unable to create file to write encoder output: " +
- outEncodeFile.toString(), outEncodeFile.createNewFile());
- encodeOutputStream = new FileOutputStream(outEncodeFile);
- }
- File rawFile = new File(mContext.getFilesDir() + "/decoder_" + tid + ".out");
- assertTrue("Cannot open file to write decoded output", rawFile.exists());
- if (DEBUG) {
- Log.i(TAG, "Path of decoded input file: " + rawFile.toString());
- }
- FileInputStream eleStream = new FileInputStream(rawFile);
- if (mime.startsWith("video/")) {
- width = format.getInteger(MediaFormat.KEY_WIDTH);
- height = format.getInteger(MediaFormat.KEY_HEIGHT);
- if (format.containsKey(MediaFormat.KEY_FRAME_RATE)) {
- frameRate = format.getInteger(MediaFormat.KEY_FRAME_RATE);
- } else if (frameRate <= 0) {
- frameRate = ENCODE_DEFAULT_FRAME_RATE;
- }
- if (format.containsKey(MediaFormat.KEY_BIT_RATE)) {
- bitRate = format.getInteger(MediaFormat.KEY_BIT_RATE);
- } else if (bitRate <= 0) {
- if (mime.contains("video/3gpp") || mime.contains("video/mp4v-es")) {
- bitRate = ENCODE_MIN_BIT_RATE;
- } else {
- bitRate = ENCODE_DEFAULT_BIT_RATE;
- }
- }
- if (format.containsKey(MediaFormat.KEY_PROFILE)) {
- profile = format.getInteger(MediaFormat.KEY_PROFILE);
- }
- if (format.containsKey(MediaFormat.KEY_PROFILE)) {
- level = format.getInteger(MediaFormat.KEY_LEVEL);
- }
- if (decoderFormat.containsKey(MediaFormat.KEY_COLOR_FORMAT)) {
- colorFormat = decoderFormat.getInteger(MediaFormat.KEY_COLOR_FORMAT);
- }
- } else {
- sampleRate = format.getInteger(MediaFormat.KEY_SAMPLE_RATE);
- numChannels = format.getInteger(MediaFormat.KEY_CHANNEL_COUNT);
- if (decoderFormat.containsKey(MediaFormat.KEY_BIT_RATE)) {
- bitRate = decoderFormat.getInteger(MediaFormat.KEY_BIT_RATE);
- } else {
- bitRate = ENCODE_DEFAULT_AUDIO_BIT_RATE;
- }
- }
- /*Setup Encode Format*/
- MediaFormat encodeFormat;
- if (mime.startsWith("video/")) {
- frameSize = width * height * 3 / 2;
- encodeFormat = MediaFormat.createVideoFormat(mime, width, height);
- encodeFormat.setInteger(MediaFormat.KEY_FRAME_RATE, frameRate);
- encodeFormat.setInteger(MediaFormat.KEY_BIT_RATE, bitRate);
- encodeFormat.setInteger(MediaFormat.KEY_PROFILE, profile);
- encodeFormat.setInteger(MediaFormat.KEY_LEVEL, level);
- encodeFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 1);
- encodeFormat.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, frameSize);
- encodeFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, colorFormat);
- } else {
- encodeFormat = MediaFormat.createAudioFormat(mime, sampleRate, numChannels);
- encodeFormat.setInteger(MediaFormat.KEY_BIT_RATE, bitRate);
- frameSize = 4096;
- }
- Encoder encoder = new Encoder();
- encoder.setupEncoder(encodeOutputStream, eleStream);
- status = encoder.encode(codecName, encodeFormat, mime, frameRate, sampleRate,
- frameSize, asyncMode);
- encoder.deInitEncoder();
- assertEquals(
- codecName + " encoder returned error " + status + " for " + "file:" +
- " " + mInputFile, 0, status);
- encoder.dumpStatistics(mInputFile, codecName, (asyncMode ? "async" : "sync"),
- extractor.getClipDuration(), mStatsFile);
- Log.i(TAG, "Encoding complete for file: " + mInputFile + " with codec: " +
- codecName + " for aSyncMode = " + asyncMode);
- encoder.resetEncoder();
- eleStream.close();
- if (encodeOutputStream != null) {
- encodeOutputStream.close();
- }
-
- }
- }
- //Cleanup temporary input file
- if (decodedFile.exists()) {
- assertTrue(" Unable to delete decoded file" + decodedFile.toString(),
- decodedFile.delete());
- Log.i(TAG, "Successfully deleted decoded file");
- }
}
extractor.deinitExtractor();
fileInput.close();
+ decodeOutputStream.close();
+ return status;
}
@Test(timeout = PER_TEST_TIMEOUT_MS)
- public void testNativeEncoder() throws Exception {
- File inputFile = new File(mInputFilePath + mInputFile);
- assertTrue("Cannot find " + mInputFile + " in directory " + mInputFilePath,
- inputFile.exists());
- int tid = android.os.Process.myTid();
- final String mDecodedFile = mContext.getFilesDir() + "/decoder_" + tid + ".out";
- FileInputStream fileInput = new FileInputStream(inputFile);
- FileDescriptor fileDescriptor = fileInput.getFD();
- Extractor extractor = new Extractor();
- int trackCount = extractor.setUpExtractor(fileDescriptor);
- assertTrue("Extraction failed. No tracks for file: ", trackCount > 0);
- for (int currentTrack = 0; currentTrack < trackCount; currentTrack++) {
- extractor.selectExtractorTrack(currentTrack);
- MediaFormat format = extractor.getFormat(currentTrack);
- String mime = format.getString(MediaFormat.KEY_MIME);
- ArrayList<String> mediaCodecs = CodecUtils.selectCodecs(mime, true);
- // Encoding the decoder's output
+ public void testEncoder() throws Exception {
+ int status;
+ int frameSize;
+
+ ArrayList<String> mediaCodecs = CodecUtils.selectCodecs(mMime, true);
+ assertTrue("No suitable codecs found for mimetype: " + mMime, (mediaCodecs.size() > 0));
+ Boolean[] encodeMode = {true, false};
+ // Encoding the decoded input file
+ for (Boolean asyncMode : encodeMode) {
for (String codecName : mediaCodecs) {
- Native nativeEncoder = new Native();
- int status = nativeEncoder
- .Encode(mInputFilePath, mInputFile, mDecodedFile, mStatsFile, codecName);
+ FileOutputStream encodeOutputStream = null;
+ if (WRITE_OUTPUT) {
+ File outEncodeFile = new File(mOutputFilePath + "encoder.out");
+ if (outEncodeFile.exists()) {
+ assertTrue(" Unable to delete existing file" + outEncodeFile.toString(),
+ outEncodeFile.delete());
+ }
+ assertTrue("Unable to create file to write encoder output: " +
+ outEncodeFile.toString(), outEncodeFile.createNewFile());
+ encodeOutputStream = new FileOutputStream(outEncodeFile);
+ }
+ File rawFile = new File(mFileDirPath + mInputFile);
+ assertTrue("Cannot open decoded input file", rawFile.exists());
+ if (DEBUG) {
+ Log.i(TAG, "Path of decoded input file: " + rawFile.toString());
+ }
+ FileInputStream eleStream = new FileInputStream(rawFile);
+ // Setup Encode Format
+ MediaFormat encodeFormat;
+ if (mMime.startsWith("video/")) {
+ frameSize = mWidth * mHeight * 3 / 2;
+ encodeFormat = MediaFormat.createVideoFormat(mMime, mWidth, mHeight);
+ encodeFormat.setInteger(MediaFormat.KEY_FRAME_RATE, ENCODE_DEFAULT_FRAME_RATE);
+ encodeFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, mIFrameInterval);
+ encodeFormat.setInteger(MediaFormat.KEY_BIT_RATE, mBitRate);
+ encodeFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, mColorFormat);
+ if (mProfile != -1 && mLevel != -1) {
+ encodeFormat.setInteger(MediaFormat.KEY_PROFILE, mProfile);
+ encodeFormat.setInteger(MediaFormat.KEY_LEVEL, mLevel);
+ }
+ } else {
+ frameSize = 4096;
+ encodeFormat = MediaFormat.createAudioFormat(mMime, mSampleRate, mNumChannel);
+ encodeFormat.setInteger(MediaFormat.KEY_BIT_RATE, mBitRate);
+ }
+ Encoder encoder = new Encoder();
+ encoder.setupEncoder(encodeOutputStream, eleStream);
+ status = encoder.encode(codecName, encodeFormat, mMime, ENCODE_DEFAULT_FRAME_RATE,
+ mSampleRate, frameSize, asyncMode);
+ encoder.deInitEncoder();
assertEquals(
- codecName + " encoder returned error " + status + " for " + "file:" + " " +
- mInputFile, 0, status);
+ codecName + " encoder returned error " + status + " for " + "mime:" + " " +
+ mMime, 0, status);
+ String inputReference;
+ long durationUs;
+ if (mMime.startsWith("video/")) {
+ inputReference =
+ mInputFile + "_" + mWidth + "x" + mHeight + "_" + mBitRate + "bps";
+ durationUs = (((eleStream.getChannel().size() + frameSize - 1) / frameSize) /
+ ENCODE_DEFAULT_FRAME_RATE) * 1000000;
+ } else {
+ inputReference = mInputFile + "_" + mSampleRate + "hz_" + mNumChannel + "ch_" +
+ mBitRate + "bps";
+ durationUs =
+ (eleStream.getChannel().size() / (mSampleRate * mNumChannel)) * 1000000;
+ }
+ encoder.dumpStatistics(inputReference, codecName, (asyncMode ? "async" : "sync"),
+ durationUs, mStatsFile);
+ Log.i(TAG, "Encoding complete for mime: " + mMime + " with codec: " + codecName +
+ " for aSyncMode = " + asyncMode);
+ encoder.resetEncoder();
+ eleStream.close();
+ if (encodeOutputStream != null) {
+ encodeOutputStream.close();
+ }
}
}
- File decodedFile = new File(mDecodedFile);
- // Cleanup temporary input file
- if (decodedFile.exists()) {
- assertTrue("Unable to delete - " + mDecodedFile, decodedFile.delete());
- Log.i(TAG, "Successfully deleted - " + mDecodedFile);
+ }
+
+ @Test(timeout = PER_TEST_TIMEOUT_MS)
+ public void testNativeEncoder() {
+ ArrayList<String> mediaCodecs = CodecUtils.selectCodecs(mMime, true);
+ assertTrue("No suitable codecs found for mimetype: " + mMime, (mediaCodecs.size() > 0));
+ for (String codecName : mediaCodecs) {
+ Native nativeEncoder = new Native();
+ int status = nativeEncoder
+ .Encode(mFileDirPath, mInputFile, mStatsFile, codecName, mMime, mBitRate,
+ mColorFormat, mIFrameInterval, mWidth, mHeight, mProfile, mLevel,
+ mSampleRate, mNumChannel);
+ assertEquals(codecName + " encoder returned error " + status + " for " + "mime:" + " " +
+ mMime, 0, status);
}
- fileInput.close();
+ }
+
+ @AfterClass
+ public static void deleteDecodedFiles() {
+ if (mDecodedFileFullHd.exists()) {
+ assertTrue(" Unable to delete decoded file" + mDecodedFileFullHd.toString(),
+ mDecodedFileFullHd.delete());
+ Log.i(TAG, "Successfully deleted decoded file" + mDecodedFileFullHd.toString());
+ }
+ if (mDecodedFileQcif.exists()) {
+ assertTrue(" Unable to delete decoded file" + mDecodedFileQcif.toString(),
+ mDecodedFileQcif.delete());
+ Log.i(TAG, "Successfully deleted decoded file" + mDecodedFileQcif.toString());
+ }
+ if (mDecodedFileAudio.exists()) {
+ assertTrue(" Unable to delete decoded file" + mDecodedFileAudio.toString(),
+ mDecodedFileAudio.delete());
+ Log.i(TAG, "Successfully deleted decoded file" + mDecodedFileAudio.toString());
+ }
}
}
diff --git a/media/tests/benchmark/MediaBenchmarkTest/src/main/cpp/NativeEncoder.cpp b/media/tests/benchmark/MediaBenchmarkTest/src/main/cpp/NativeEncoder.cpp
index 1277c8b..2f658e3 100644
--- a/media/tests/benchmark/MediaBenchmarkTest/src/main/cpp/NativeEncoder.cpp
+++ b/media/tests/benchmark/MediaBenchmarkTest/src/main/cpp/NativeEncoder.cpp
@@ -30,189 +30,81 @@
#include <stdio.h>
constexpr int32_t ENCODE_DEFAULT_FRAME_RATE = 25;
-constexpr int32_t ENCODE_DEFAULT_AUDIO_BIT_RATE = 128000 /* 128 Kbps */;
-constexpr int32_t ENCODE_DEFAULT_BIT_RATE = 8000000 /* 8 Mbps */;
-constexpr int32_t ENCODE_MIN_BIT_RATE = 600000 /* 600 Kbps */;
extern "C" JNIEXPORT int JNICALL Java_com_android_media_benchmark_library_Native_Encode(
- JNIEnv *env, jobject thiz, jstring jFilePath, jstring jFileName, jstring jOutFilePath,
- jstring jStatsFile, jstring jCodecName) {
+ JNIEnv *env, jobject thiz, jstring jFilePath, jstring jFileName, jstring jStatsFile,
+ jstring jCodecName, jstring jMime, jint jBitRate, jint jColorFormat, jint jFrameInterval,
+ jint jWidth, jint jHeight, jint jProfile, jint jLevel, jint jSampleRate,
+ jint jNumChannels) {
+ UNUSED(thiz);
const char *filePath = env->GetStringUTFChars(jFilePath, nullptr);
const char *fileName = env->GetStringUTFChars(jFileName, nullptr);
- string sFilePath = string(filePath) + string(fileName);
- UNUSED(thiz);
- FILE *inputFp = fopen(sFilePath.c_str(), "rb");
- env->ReleaseStringUTFChars(jFileName, fileName);
- env->ReleaseStringUTFChars(jFilePath, filePath);
- if (!inputFp) {
- ALOGE("Unable to open input file for reading");
+ string inputFile = string(filePath) + string(fileName);
+ const char *codecName = env->GetStringUTFChars(jCodecName, nullptr);
+ string sCodecName = string(codecName);
+ const char *mime = env->GetStringUTFChars(jMime, nullptr);
+
+ ifstream eleStream;
+ eleStream.open(inputFile, ifstream::binary | ifstream::ate);
+ if (!eleStream.is_open()) {
+ ALOGE("%s - File failed to open for reading!", fileName);
+ env->ReleaseStringUTFChars(jFileName, fileName);
return -1;
}
- Decoder *decoder = new Decoder();
- Extractor *extractor = decoder->getExtractor();
- if (!extractor) {
- ALOGE("Extractor creation failed");
- return -1;
- }
+ bool asyncMode[2] = {true, false};
+ for (bool mode : asyncMode) {
+ size_t eleSize = eleStream.tellg();
+ eleStream.seekg(0, ifstream::beg);
- // Read file properties
- struct stat buf;
- stat(sFilePath.c_str(), &buf);
- size_t fileSize = buf.st_size;
- if (fileSize > kMaxBufferSize) {
- ALOGE("File size greater than maximum buffer size");
- return -1;
- }
- int32_t fd = fileno(inputFp);
- int32_t trackCount = extractor->initExtractor(fd, fileSize);
- if (trackCount <= 0) {
- ALOGE("initExtractor failed");
- return -1;
- }
+ // Set encoder params
+ encParameter encParams;
+ encParams.width = jWidth;
+ encParams.height = jHeight;
+ encParams.bitrate = jBitRate;
+ encParams.iFrameInterval = jFrameInterval;
+ encParams.sampleRate = jSampleRate;
+ encParams.numChannels = jNumChannels;
+ encParams.frameRate = ENCODE_DEFAULT_FRAME_RATE;
+ encParams.colorFormat = jColorFormat;
+ encParams.profile = jProfile;
+ encParams.level = jLevel;
- for (int curTrack = 0; curTrack < trackCount; curTrack++) {
- int32_t status = extractor->setupTrackFormat(curTrack);
- if (status != 0) {
- ALOGE("Track Format invalid");
- return -1;
- }
- uint8_t *inputBuffer = (uint8_t *)malloc(fileSize);
- if (!inputBuffer) {
- ALOGE("Insufficient memory");
- return -1;
- }
- vector<AMediaCodecBufferInfo> frameInfo;
- AMediaCodecBufferInfo info;
- uint32_t inputBufferOffset = 0;
-
- // Get frame data
- while (1) {
- status = extractor->getFrameSample(info);
- if (status || !info.size) break;
- // copy the meta data and buffer to be passed to decoder
- if (inputBufferOffset + info.size > kMaxBufferSize) {
- ALOGE("Memory allocated not sufficient");
- free(inputBuffer);
- return -1;
- }
- memcpy(inputBuffer + inputBufferOffset, extractor->getFrameBuf(), info.size);
- frameInfo.push_back(info);
- inputBufferOffset += info.size;
- }
- string decName = "";
- const char *outputFilePath = env->GetStringUTFChars(jOutFilePath, nullptr);
- FILE *outFp = fopen(outputFilePath, "wb");
- if (outFp == nullptr) {
- ALOGE("%s - File failed to open for writing!", outputFilePath);
- free(inputBuffer);
- return -1;
- }
- decoder->setupDecoder();
- status = decoder->decode(inputBuffer, frameInfo, decName, false /*asyncMode */, outFp);
+ Encoder *encoder = new Encoder();
+ encoder->setupEncoder();
+ auto status = encoder->encode(sCodecName, eleStream, eleSize, mode, encParams,
+ const_cast<char *>(mime));
if (status != AMEDIA_OK) {
- ALOGE("Decode returned error");
- free(inputBuffer);
+ ALOGE("Encoder returned error");
return -1;
}
-
- AMediaFormat *decoderFormat = decoder->getFormat();
- AMediaFormat *format = extractor->getFormat();
- if (inputBuffer) {
- free(inputBuffer);
- inputBuffer = nullptr;
+ ALOGV("Encoding complete with codec %s for asyncMode = %d", sCodecName.c_str(), mode);
+ encoder->deInitCodec();
+ const char *statsFile = env->GetStringUTFChars(jStatsFile, nullptr);
+ string inputReference;
+ int64_t clipDurationUs;
+ if (!strncmp(mime, "video/", 6)) {
+ inputReference = string(fileName) + "_" + to_string(jWidth) + "x" + to_string(jHeight) +
+ "_" + to_string(jBitRate) + "bps";
+ int32_t frameSize = jWidth * jHeight * 3 / 2;
+ clipDurationUs =
+ (((eleSize + frameSize - 1) / frameSize) / ENCODE_DEFAULT_FRAME_RATE) * 1000000;
+ } else {
+ inputReference = string(fileName) + "_" + to_string(jSampleRate) + "hz_" +
+ to_string(jNumChannels) + "ch_" + to_string(jBitRate) + "bps";
+ clipDurationUs = (eleSize / (jSampleRate * jNumChannels)) * 1000000;
}
- const char *mime = nullptr;
- AMediaFormat_getString(format, AMEDIAFORMAT_KEY_MIME, &mime);
- if (!mime) {
- ALOGE("Error in AMediaFormat_getString");
- return -1;
- }
- ifstream eleStream;
- eleStream.open(outputFilePath, ifstream::binary | ifstream::ate);
- if (!eleStream.is_open()) {
- ALOGE("%s - File failed to open for reading!", outputFilePath);
- env->ReleaseStringUTFChars(jOutFilePath, outputFilePath);
- return -1;
- }
- const char *codecName = env->GetStringUTFChars(jCodecName, NULL);
- const char *inputReference = env->GetStringUTFChars(jFileName, nullptr);
- string sCodecName = string(codecName);
- string sInputReference = string(inputReference);
-
- bool asyncMode[2] = {true, false};
- for (int i = 0; i < 2; i++) {
- size_t eleSize = eleStream.tellg();
- eleStream.seekg(0, ifstream::beg);
-
- // Get encoder params
- encParameter encParams;
- if (!strncmp(mime, "video/", 6)) {
- AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_WIDTH, &encParams.width);
- AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_HEIGHT, &encParams.height);
- AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_FRAME_RATE, &encParams.frameRate);
- AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_BIT_RATE, &encParams.bitrate);
- if (encParams.bitrate <= 0 || encParams.frameRate <= 0) {
- encParams.frameRate = ENCODE_DEFAULT_FRAME_RATE;
- if (!strcmp(mime, "video/3gpp") || !strcmp(mime, "video/mp4v-es")) {
- encParams.bitrate = ENCODE_MIN_BIT_RATE /* 600 Kbps */;
- } else {
- encParams.bitrate = ENCODE_DEFAULT_BIT_RATE /* 8 Mbps */;
- }
- }
- AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_PROFILE, &encParams.profile);
- AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_LEVEL, &encParams.level);
- AMediaFormat_getInt32(decoderFormat, AMEDIAFORMAT_KEY_COLOR_FORMAT,
- &encParams.colorFormat);
- } else {
- AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_SAMPLE_RATE, &encParams.sampleRate);
- AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_CHANNEL_COUNT,
- &encParams.numChannels);
- encParams.bitrate = ENCODE_DEFAULT_AUDIO_BIT_RATE;
- }
- Encoder *encoder = new Encoder();
- encoder->setupEncoder();
- status = encoder->encode(sCodecName, eleStream, eleSize, asyncMode[i], encParams,
- (char *)mime);
- if (status != AMEDIA_OK) {
- ALOGE("Encoder returned error");
- return -1;
- }
- ALOGV("Encoding complete with codec %s for asyncMode = %d", sCodecName.c_str(),
- asyncMode[i]);
- encoder->deInitCodec();
- const char *statsFile = env->GetStringUTFChars(jStatsFile, nullptr);
- encoder->dumpStatistics(sInputReference, extractor->getClipDuration(), sCodecName,
- (asyncMode[i] ? "async" : "sync"), statsFile);
- env->ReleaseStringUTFChars(jStatsFile, statsFile);
- encoder->resetEncoder();
- delete encoder;
- encoder = nullptr;
- }
- eleStream.close();
- if (outFp) {
- fclose(outFp);
- outFp = nullptr;
- }
- env->ReleaseStringUTFChars(jFileName, inputReference);
- env->ReleaseStringUTFChars(jCodecName, codecName);
- env->ReleaseStringUTFChars(jOutFilePath, outputFilePath);
- if (format) {
- AMediaFormat_delete(format);
- format = nullptr;
- }
- if (decoderFormat) {
- AMediaFormat_delete(decoderFormat);
- decoderFormat = nullptr;
- }
- decoder->deInitCodec();
- decoder->resetDecoder();
+ encoder->dumpStatistics(inputReference, clipDurationUs, sCodecName,
+ (mode ? "async" : "sync"), statsFile);
+ env->ReleaseStringUTFChars(jStatsFile, statsFile);
+ encoder->resetEncoder();
+ delete encoder;
+ encoder = nullptr;
}
- if (inputFp) {
- fclose(inputFp);
- inputFp = nullptr;
- }
- extractor->deInitExtractor();
- delete decoder;
+ eleStream.close();
+ env->ReleaseStringUTFChars(jFilePath, filePath);
+ env->ReleaseStringUTFChars(jFileName, fileName);
+ env->ReleaseStringUTFChars(jMime, mime);
+ env->ReleaseStringUTFChars(jCodecName, codecName);
return 0;
}
diff --git a/media/tests/benchmark/MediaBenchmarkTest/src/main/java/com/android/media/benchmark/library/Native.java b/media/tests/benchmark/MediaBenchmarkTest/src/main/java/com/android/media/benchmark/library/Native.java
index 38b608a..3e3969c 100644
--- a/media/tests/benchmark/MediaBenchmarkTest/src/main/java/com/android/media/benchmark/library/Native.java
+++ b/media/tests/benchmark/MediaBenchmarkTest/src/main/java/com/android/media/benchmark/library/Native.java
@@ -27,6 +27,7 @@
public native int Decode(String inputFilePath, String inputFileName, String statsFile,
String codecName, boolean asyncMode);
- public native int Encode(String inputFilePath, String inputFileName, String outputFilePath,
- String statsFile, String codecName);
+ public native int Encode(String inputFilePath, String inputFileName, String statsFile,
+ String codecName, String mime, int bitRate, int colorFormat, int frameInterval,
+ int width, int height, int profile, int level, int sampleRate, int numChannel);
}
diff --git a/media/tests/benchmark/src/native/encoder/Encoder.cpp b/media/tests/benchmark/src/native/encoder/Encoder.cpp
index 26fb1b9..15c479d 100644
--- a/media/tests/benchmark/src/native/encoder/Encoder.cpp
+++ b/media/tests/benchmark/src/native/encoder/Encoder.cpp
@@ -203,13 +203,13 @@
AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_WIDTH, mParams.width);
AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_HEIGHT, mParams.height);
AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_FRAME_RATE, mParams.frameRate);
+ AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_I_FRAME_INTERVAL, mParams.iFrameInterval);
AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_BIT_RATE, mParams.bitrate);
- AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_I_FRAME_INTERVAL, 1);
- if (mParams.profile && mParams.level) {
+ AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_COLOR_FORMAT, mParams.colorFormat);
+ if (mParams.profile != -1 && mParams.level != -1) {
AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_PROFILE, mParams.profile);
AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_LEVEL, mParams.level);
}
- AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_COLOR_FORMAT, mParams.colorFormat);
} else {
AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_SAMPLE_RATE, mParams.sampleRate);
AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_CHANNEL_COUNT, mParams.numChannels);
diff --git a/media/tests/benchmark/src/native/encoder/Encoder.h b/media/tests/benchmark/src/native/encoder/Encoder.h
index 5ad142b..324317c 100644
--- a/media/tests/benchmark/src/native/encoder/Encoder.h
+++ b/media/tests/benchmark/src/native/encoder/Encoder.h
@@ -23,10 +23,11 @@
#include <queue>
#include <thread>
-#include "media/NdkImage.h"
#include "BenchmarkCommon.h"
#include "Stats.h"
+// constant not defined in NDK api
+constexpr int32_t COLOR_FormatYUV420Flexible = 0x7F420888;
struct encParameter {
int32_t bitrate = -1;
@@ -38,9 +39,10 @@
int32_t width = 0;
int32_t height = 0;
int32_t frameRate = -1;
- int32_t profile = 0;
- int32_t level = 0;
- int32_t colorFormat = AIMAGE_FORMAT_YUV_420_888;
+ int32_t iFrameInterval = 0;
+ int32_t profile = -1;
+ int32_t level = -1;
+ int32_t colorFormat = COLOR_FormatYUV420Flexible;
};
class Encoder : public CallBackHandle {
diff --git a/media/tests/benchmark/tests/EncoderTest.cpp b/media/tests/benchmark/tests/EncoderTest.cpp
index faac847..7e1681d 100644
--- a/media/tests/benchmark/tests/EncoderTest.cpp
+++ b/media/tests/benchmark/tests/EncoderTest.cpp
@@ -23,6 +23,10 @@
#include "Decoder.h"
#include "Encoder.h"
+constexpr int32_t kEncodeDefaultVideoBitRate = 8000000 /* 8 Mbps */;
+constexpr int32_t kEncodeMinVideoBitRate = 600000 /* 600 Kbps */;
+constexpr int32_t kEncodeDefaultAudioBitRate = 128000 /* 128 Kbps */;
+
static BenchmarkTestEnvironment *gEnv = nullptr;
class EncoderTest : public ::testing::TestWithParam<tuple<string, string, bool>> {};
@@ -86,6 +90,7 @@
decoder->setupDecoder();
status = decoder->decode(inputBuffer, frameInfo, decName, false /*asyncMode */, outFp);
ASSERT_EQ(status, AMEDIA_OK) << "Decode returned error : " << status;
+ AMediaFormat *decoderFormat = decoder->getFormat();
ifstream eleStream;
eleStream.open(outputFileName.c_str(), ifstream::binary | ifstream::ate);
@@ -108,11 +113,13 @@
if (encParams.bitrate <= 0 || encParams.frameRate <= 0) {
encParams.frameRate = 25;
if (!strcmp(mime, "video/3gpp") || !strcmp(mime, "video/mp4v-es")) {
- encParams.bitrate = 600000 /* 600 Kbps */;
+ encParams.bitrate = kEncodeMinVideoBitRate;
} else {
- encParams.bitrate = 8000000 /* 8 Mbps */;
+ encParams.bitrate = kEncodeDefaultVideoBitRate;
}
}
+ AMediaFormat_getInt32(decoderFormat, AMEDIAFORMAT_KEY_COLOR_FORMAT,
+ &encParams.colorFormat);
AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_PROFILE, &encParams.profile);
AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_LEVEL, &encParams.level);
} else {
@@ -120,8 +127,7 @@
&encParams.sampleRate));
ASSERT_TRUE(AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_CHANNEL_COUNT,
&encParams.numChannels));
- encParams.bitrate =
- encParams.sampleRate * encParams.numChannels * 16 /* bitsPerSample */;
+ encParams.bitrate = kEncodeDefaultAudioBitRate;
}
encoder->setupEncoder();
@@ -142,6 +148,10 @@
AMediaFormat_delete(format);
format = nullptr;
}
+ if (decoderFormat) {
+ AMediaFormat_delete(decoderFormat);
+ decoderFormat = nullptr;
+ }
encoder->resetEncoder();
decoder->deInitCodec();
free(inputBuffer);
diff --git a/services/audioflinger/FastThread.cpp b/services/audioflinger/FastThread.cpp
index 8b7a124..47fe0b3 100644
--- a/services/audioflinger/FastThread.cpp
+++ b/services/audioflinger/FastThread.cpp
@@ -309,7 +309,7 @@
// compute the delta value of clock_gettime(CLOCK_MONOTONIC)
uint32_t monotonicNs = nsec;
if (sec > 0 && sec < 4) {
- monotonicNs += sec * 1000000000;
+ monotonicNs += sec * 1000000000U; // unsigned to prevent signed overflow.
}
// compute raw CPU load = delta value of clock_gettime(CLOCK_THREAD_CPUTIME_ID)
uint32_t loadNs = 0;
@@ -325,7 +325,7 @@
}
loadNs = nsec;
if (sec > 0 && sec < 4) {
- loadNs += sec * 1000000000;
+ loadNs += sec * 1000000000U; // unsigned to prevent signed overflow.
}
} else {
// first time through the loop
diff --git a/services/audiopolicy/engine/config/include/EngineConfig.h b/services/audiopolicy/engine/config/include/EngineConfig.h
index 7f5ed5e..5d22c24 100644
--- a/services/audiopolicy/engine/config/include/EngineConfig.h
+++ b/services/audiopolicy/engine/config/include/EngineConfig.h
@@ -31,9 +31,6 @@
/** Default path of audio policy usages configuration file. */
constexpr char DEFAULT_PATH[] = "/vendor/etc/audio_policy_engine_configuration.xml";
-/** Directories where the effect libraries will be search for. */
-constexpr const char* POLICY_USAGE_LIBRARY_PATH[] = {"/odm/etc/", "/vendor/etc/", "/system/etc/"};
-
using AttributesVector = std::vector<audio_attributes_t>;
using StreamVector = std::vector<audio_stream_type_t>;
diff --git a/services/audiopolicy/engine/config/src/EngineConfig.cpp b/services/audiopolicy/engine/config/src/EngineConfig.cpp
index 7f8cdd9..4842cb2 100644
--- a/services/audiopolicy/engine/config/src/EngineConfig.cpp
+++ b/services/audiopolicy/engine/config/src/EngineConfig.cpp
@@ -21,6 +21,7 @@
#include <cutils/properties.h>
#include <media/TypeConverter.h>
#include <media/convert.h>
+#include <system/audio_config.h>
#include <utils/Log.h>
#include <libxml/parser.h>
#include <libxml/xinclude.h>
@@ -693,9 +694,6 @@
return deserializeLegacyVolumeCollection(doc, cur, volumeGroups, nbSkippedElements);
}
-static const char *kConfigLocationList[] = {"/odm/etc", "/vendor/etc", "/system/etc"};
-static const int kConfigLocationListSize =
- (sizeof(kConfigLocationList) / sizeof(kConfigLocationList[0]));
static const int gApmXmlConfigFilePathMaxLength = 128;
static constexpr const char *apmXmlConfigFileName = "audio_policy_configuration.xml";
@@ -715,9 +713,9 @@
fileNames.push_back(apmXmlConfigFileName);
for (const char* fileName : fileNames) {
- for (int i = 0; i < kConfigLocationListSize; i++) {
+ for (const auto& path : audio_get_configuration_paths()) {
snprintf(audioPolicyXmlConfigFile, sizeof(audioPolicyXmlConfigFile),
- "%s/%s", kConfigLocationList[i], fileName);
+ "%s/%s", path.c_str(), fileName);
ret = parseLegacyVolumeFile(audioPolicyXmlConfigFile, volumeGroups);
if (ret == NO_ERROR) {
return ret;
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index a72da83..2a2e449 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -48,6 +48,7 @@
#include <private/android_filesystem_config.h>
#include <soundtrigger/SoundTrigger.h>
#include <system/audio.h>
+#include <system/audio_config.h>
#include "AudioPolicyManager.h"
#include <Serializer.h>
#include "TypeConverter.h"
@@ -3708,6 +3709,22 @@
removeAudioPatch(patchDesc->getHandle());
nextAudioPortGeneration();
mpClientInterface->onAudioPatchListUpdate();
+ // SW Bridge
+ if (patch->num_sources > 1 && patch->sources[1].type == AUDIO_PORT_TYPE_MIX) {
+ sp<SwAudioOutputDescriptor> outputDesc =
+ mOutputs.getOutputFromId(patch->sources[1].id);
+ if (outputDesc == NULL) {
+ ALOGE("%s output not found for id %d", __func__, patch->sources[0].id);
+ return BAD_VALUE;
+ }
+ // Reset handle so that setOutputDevice will force new AF patch to reach the sink
+ outputDesc->setPatchHandle(AUDIO_PATCH_HANDLE_NONE);
+ setOutputDevices(outputDesc,
+ getNewOutputDevices(outputDesc, true /*fromCache*/),
+ true, /*force*/
+ 0,
+ NULL);
+ }
} else {
return BAD_VALUE;
}
@@ -4296,12 +4313,6 @@
return mAudioPortGeneration++;
}
-// Treblized audio policy xml config will be located in /odm/etc or /vendor/etc.
-static const char *kConfigLocationList[] =
- {"/odm/etc", "/vendor/etc", "/system/etc"};
-static const int kConfigLocationListSize =
- (sizeof(kConfigLocationList) / sizeof(kConfigLocationList[0]));
-
static status_t deserializeAudioPolicyXmlConfig(AudioPolicyConfig &config) {
char audioPolicyXmlConfigFile[AUDIO_POLICY_XML_CONFIG_FILE_PATH_MAX_LENGTH];
std::vector<const char*> fileNames;
@@ -4323,9 +4334,9 @@
fileNames.push_back(AUDIO_POLICY_XML_CONFIG_FILE_NAME);
for (const char* fileName : fileNames) {
- for (int i = 0; i < kConfigLocationListSize; i++) {
+ for (const auto& path : audio_get_configuration_paths()) {
snprintf(audioPolicyXmlConfigFile, sizeof(audioPolicyXmlConfigFile),
- "%s/%s", kConfigLocationList[i], fileName);
+ "%s/%s", path.c_str(), fileName);
ret = deserializeAudioPolicyFile(audioPolicyXmlConfigFile, &config);
if (ret == NO_ERROR) {
config.setSource(audioPolicyXmlConfigFile);
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index 9eb9a1d..39ed8d5 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -357,7 +357,7 @@
}
virtual const DeviceVector getAvailableOutputDevices() const
{
- return mAvailableOutputDevices;
+ return mAvailableOutputDevices.filterForEngine();
}
virtual const DeviceVector getAvailableInputDevices() const
{
diff --git a/services/camera/libcameraservice/utils/ExifUtils.cpp b/services/camera/libcameraservice/utils/ExifUtils.cpp
index c0afdc1..8a0303a 100644
--- a/services/camera/libcameraservice/utils/ExifUtils.cpp
+++ b/services/camera/libcameraservice/utils/ExifUtils.cpp
@@ -603,13 +603,13 @@
}
bool ExifUtilsImpl::setImageHeight(uint32_t length) {
- SET_LONG(EXIF_IFD_0, EXIF_TAG_IMAGE_LENGTH, length);
+ SET_SHORT(EXIF_IFD_0, EXIF_TAG_IMAGE_LENGTH, length);
SET_LONG(EXIF_IFD_EXIF, EXIF_TAG_PIXEL_Y_DIMENSION, length);
return true;
}
bool ExifUtilsImpl::setImageWidth(uint32_t width) {
- SET_LONG(EXIF_IFD_0, EXIF_TAG_IMAGE_WIDTH, width);
+ SET_SHORT(EXIF_IFD_0, EXIF_TAG_IMAGE_WIDTH, width);
SET_LONG(EXIF_IFD_EXIF, EXIF_TAG_PIXEL_X_DIMENSION, width);
return true;
}
diff --git a/services/mediaanalytics/mediametrics.rc b/services/mediaanalytics/mediametrics.rc
index 1efde5e..2a6c817 100644
--- a/services/mediaanalytics/mediametrics.rc
+++ b/services/mediaanalytics/mediametrics.rc
@@ -3,4 +3,4 @@
user media
group media
ioprio rt 4
- writepid /dev/cpuset/foreground/tasks /dev/stune/foreground/tasks
+ task_profiles ProcessCapacityHigh HighPerformance
diff --git a/services/mediacodec/seccomp_policy/mediacodec-arm.policy b/services/mediacodec/seccomp_policy/mediacodec-arm.policy
index 3870a11..51564ca 100644
--- a/services/mediacodec/seccomp_policy/mediacodec-arm.policy
+++ b/services/mediacodec/seccomp_policy/mediacodec-arm.policy
@@ -23,7 +23,7 @@
# on ARM is statically loaded at 0xffff 0000. See
# http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0211h/Babfeega.html
# for more details.
-mremap: arg3 == 3
+mremap: arg3 == 3 || arg3 == MREMAP_MAYMOVE
munmap: 1
mprotect: 1
madvise: 1
diff --git a/services/mediacodec/seccomp_policy/mediaswcodec-arm.policy b/services/mediacodec/seccomp_policy/mediaswcodec-arm.policy
index 9042cd7..8705cf9 100644
--- a/services/mediacodec/seccomp_policy/mediaswcodec-arm.policy
+++ b/services/mediacodec/seccomp_policy/mediaswcodec-arm.policy
@@ -31,7 +31,7 @@
# on ARM is statically loaded at 0xffff 0000. See
# http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0211h/Babfeega.html
# for more details.
-mremap: arg3 == 3
+mremap: arg3 == 3 || arg3 == MREMAP_MAYMOVE
munmap: 1
prctl: 1
getuid32: 1
diff --git a/services/mediacodec/seccomp_policy/mediaswcodec-arm64.policy b/services/mediacodec/seccomp_policy/mediaswcodec-arm64.policy
index 4faf8b2..85fd28d 100644
--- a/services/mediacodec/seccomp_policy/mediaswcodec-arm64.policy
+++ b/services/mediacodec/seccomp_policy/mediaswcodec-arm64.policy
@@ -35,7 +35,7 @@
# on ARM is statically loaded at 0xffff 0000. See
# http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0211h/Babfeega.html
# for more details.
-mremap: arg3 == 3
+mremap: arg3 == 3 || arg3 == MREMAP_MAYMOVE
munmap: 1
prctl: 1
writev: 1
diff --git a/services/mediaextractor/seccomp_policy/mediaextractor-arm.policy b/services/mediaextractor/seccomp_policy/mediaextractor-arm.policy
index 964acf4..c61393d 100644
--- a/services/mediaextractor/seccomp_policy/mediaextractor-arm.policy
+++ b/services/mediaextractor/seccomp_policy/mediaextractor-arm.policy
@@ -45,6 +45,14 @@
# for dynamically loading extractors
pread64: 1
+# mremap: Ensure |flags| are (MREMAP_MAYMOVE | MREMAP_FIXED) TODO: Once minijail
+# parser support for '<' is in this needs to be modified to also prevent
+# |old_address| and |new_address| from touching the exception vector page, which
+# on ARM is statically loaded at 0xffff 0000. See
+# http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0211h/Babfeega.html
+# for more details.
+mremap: arg3 == 3 || arg3 == MREMAP_MAYMOVE
+
# for FileSource
readlinkat: 1
_llseek: 1
diff --git a/services/oboeservice/SharedMemoryProxy.cpp b/services/oboeservice/SharedMemoryProxy.cpp
index c43ed22..78d4884 100644
--- a/services/oboeservice/SharedMemoryProxy.cpp
+++ b/services/oboeservice/SharedMemoryProxy.cpp
@@ -20,6 +20,7 @@
#include <errno.h>
#include <string.h>
+#include <unistd.h>
#include <aaudio/AAudio.h>
#include "SharedMemoryProxy.h"