Merge "Dump ABI for libmediametrics"
diff --git a/media/codec2/components/aac/C2SoftAacEnc.cpp b/media/codec2/components/aac/C2SoftAacEnc.cpp
index 8e3852c..1dc676b 100644
--- a/media/codec2/components/aac/C2SoftAacEnc.cpp
+++ b/media/codec2/components/aac/C2SoftAacEnc.cpp
@@ -157,7 +157,7 @@
mSentCodecSpecificData(false),
mInputTimeSet(false),
mInputSize(0),
- mInputTimeUs(0),
+ mNextFrameTimestampUs(0),
mSignalledError(false),
mOutIndex(0u) {
}
@@ -183,7 +183,7 @@
mSentCodecSpecificData = false;
mInputTimeSet = false;
mInputSize = 0u;
- mInputTimeUs = 0;
+ mNextFrameTimestampUs = 0;
mSignalledError = false;
return C2_OK;
}
@@ -201,7 +201,7 @@
mSentCodecSpecificData = false;
mInputTimeSet = false;
mInputSize = 0u;
- mInputTimeUs = 0;
+ mNextFrameTimestampUs = 0;
return C2_OK;
}
@@ -365,17 +365,18 @@
capacity = view.capacity();
}
if (!mInputTimeSet && capacity > 0) {
- mInputTimeUs = work->input.ordinal.timestamp;
+ mNextFrameTimestampUs = work->input.ordinal.timestamp;
mInputTimeSet = true;
}
size_t numFrames = (capacity + mInputSize + (eos ? mNumBytesPerInputFrame - 1 : 0))
/ mNumBytesPerInputFrame;
- ALOGV("capacity = %zu; mInputSize = %zu; numFrames = %zu mNumBytesPerInputFrame = %u",
- capacity, mInputSize, numFrames, mNumBytesPerInputFrame);
+ ALOGV("capacity = %zu; mInputSize = %zu; numFrames = %zu "
+ "mNumBytesPerInputFrame = %u inputTS = %lld",
+ capacity, mInputSize, numFrames,
+ mNumBytesPerInputFrame, work->input.ordinal.timestamp.peekll());
std::shared_ptr<C2LinearBlock> block;
- std::shared_ptr<C2Buffer> buffer;
std::unique_ptr<C2WriteView> wView;
uint8_t *outPtr = temp;
size_t outAvailable = 0u;
@@ -442,7 +443,11 @@
const std::shared_ptr<C2Buffer> mBuffer;
};
- C2WorkOrdinalStruct outOrdinal = work->input.ordinal;
+ struct OutputBuffer {
+ std::shared_ptr<C2Buffer> buffer;
+ c2_cntr64_t timestampUs;
+ };
+ std::list<OutputBuffer> outputBuffers;
while (encoderErr == AACENC_OK && inargs.numInSamples > 0) {
if (numFrames && !block) {
@@ -473,29 +478,22 @@
&outargs);
if (encoderErr == AACENC_OK) {
- if (buffer) {
- outOrdinal.frameIndex = mOutIndex++;
- outOrdinal.timestamp = mInputTimeUs;
- cloneAndSend(
- inputIndex,
- work,
- FillWork(C2FrameData::FLAG_INCOMPLETE, outOrdinal, buffer));
- buffer.reset();
- }
-
if (outargs.numOutBytes > 0) {
mInputSize = 0;
int consumed = (capacity / sizeof(int16_t)) - inargs.numInSamples
+ outargs.numInSamples;
- mInputTimeUs = work->input.ordinal.timestamp
+ c2_cntr64_t currentFrameTimestampUs = mNextFrameTimestampUs;
+ mNextFrameTimestampUs = work->input.ordinal.timestamp
+ (consumed * 1000000ll / channelCount / sampleRate);
- buffer = createLinearBuffer(block, 0, outargs.numOutBytes);
+ std::shared_ptr<C2Buffer> buffer = createLinearBuffer(block, 0, outargs.numOutBytes);
#if defined(LOG_NDEBUG) && !LOG_NDEBUG
hexdump(outPtr, std::min(outargs.numOutBytes, 256));
#endif
outPtr = temp;
outAvailable = 0;
block.reset();
+
+ outputBuffers.push_back({buffer, currentFrameTimestampUs});
} else {
mInputSize += outargs.numInSamples * sizeof(int16_t);
}
@@ -506,8 +504,9 @@
inargs.numInSamples -= outargs.numInSamples;
}
}
- ALOGV("encoderErr = %d mInputSize = %zu inargs.numInSamples = %d, mInputTimeUs = %lld",
- encoderErr, mInputSize, inargs.numInSamples, mInputTimeUs.peekll());
+ ALOGV("encoderErr = %d mInputSize = %zu "
+ "inargs.numInSamples = %d, mNextFrameTimestampUs = %lld",
+ encoderErr, mInputSize, inargs.numInSamples, mNextFrameTimestampUs.peekll());
}
if (eos && inBufferSize[0] > 0) {
@@ -542,10 +541,27 @@
&outargs);
}
- outOrdinal.frameIndex = mOutIndex++;
- outOrdinal.timestamp = mInputTimeUs;
+ while (outputBuffers.size() > 1) {
+ const OutputBuffer& front = outputBuffers.front();
+ C2WorkOrdinalStruct ordinal = work->input.ordinal;
+ ordinal.frameIndex = mOutIndex++;
+ ordinal.timestamp = front.timestampUs;
+ cloneAndSend(
+ inputIndex,
+ work,
+ FillWork(C2FrameData::FLAG_INCOMPLETE, ordinal, front.buffer));
+ outputBuffers.pop_front();
+ }
+ std::shared_ptr<C2Buffer> buffer;
+ C2WorkOrdinalStruct ordinal = work->input.ordinal;
+ ordinal.frameIndex = mOutIndex++;
+ if (!outputBuffers.empty()) {
+ ordinal.timestamp = outputBuffers.front().timestampUs;
+ buffer = outputBuffers.front().buffer;
+ }
+ // Mark the end of frame
FillWork((C2FrameData::flags_t)(eos ? C2FrameData::FLAG_END_OF_STREAM : 0),
- outOrdinal, buffer)(work);
+ ordinal, buffer)(work);
}
c2_status_t C2SoftAacEnc::drain(
@@ -569,7 +585,7 @@
mSentCodecSpecificData = false;
mInputTimeSet = false;
mInputSize = 0u;
- mInputTimeUs = 0;
+ mNextFrameTimestampUs = 0;
// TODO: we don't have any pending work at this time to drain.
return C2_OK;
diff --git a/media/codec2/components/aac/C2SoftAacEnc.h b/media/codec2/components/aac/C2SoftAacEnc.h
index a38be19..2655039 100644
--- a/media/codec2/components/aac/C2SoftAacEnc.h
+++ b/media/codec2/components/aac/C2SoftAacEnc.h
@@ -56,7 +56,7 @@
bool mSentCodecSpecificData;
bool mInputTimeSet;
size_t mInputSize;
- c2_cntr64_t mInputTimeUs;
+ c2_cntr64_t mNextFrameTimestampUs;
bool mSignalledError;
std::atomic_uint64_t mOutIndex;
diff --git a/media/extractors/ogg/OggExtractor.cpp b/media/extractors/ogg/OggExtractor.cpp
index 72b94bb..298dab1 100644
--- a/media/extractors/ogg/OggExtractor.cpp
+++ b/media/extractors/ogg/OggExtractor.cpp
@@ -1062,8 +1062,15 @@
size_t size = buffer->range_length();
if (size < kOpusHeaderSize
- || memcmp(data, "OpusHead", 8)
- || /* version = */ data[8] != 1) {
+ || memcmp(data, "OpusHead", 8)) {
+ return AMEDIA_ERROR_MALFORMED;
+ }
+ // allow both version 0 and 1. Per the opus specification:
+ // An earlier draft of the specification described a version 0, but the only difference
+ // between version 1 and version 0 is that version 0 did not specify the semantics for
+ // handling the version field
+ if ( /* version = */ data[8] > 1) {
+ ALOGW("no support for opus version %d", data[8]);
return AMEDIA_ERROR_MALFORMED;
}
diff --git a/media/libeffects/lvm/lib/Common/lib/VectorArithmetic.h b/media/libeffects/lvm/lib/Common/lib/VectorArithmetic.h
index 7468a90..10eedd9 100644
--- a/media/libeffects/lvm/lib/Common/lib/VectorArithmetic.h
+++ b/media/libeffects/lvm/lib/Common/lib/VectorArithmetic.h
@@ -53,6 +53,7 @@
LVM_INT16 NrFrames,
LVM_INT32 NrChannels);
void Copy_Float_Stereo_Mc( const LVM_FLOAT *src,
+ LVM_FLOAT *StereoOut,
LVM_FLOAT *dst,
LVM_INT16 NrFrames,
LVM_INT32 NrChannels);
diff --git a/media/libeffects/lvm/lib/Common/src/Copy_16.c b/media/libeffects/lvm/lib/Common/src/Copy_16.c
index 3858450..3eb3c14 100644
--- a/media/libeffects/lvm/lib/Common/src/Copy_16.c
+++ b/media/libeffects/lvm/lib/Common/src/Copy_16.c
@@ -117,30 +117,31 @@
}
}
-// Merge a multichannel source with stereo contained in dst, to dst.
+// Merge a multichannel source with stereo contained in StereoOut, to dst.
void Copy_Float_Stereo_Mc(const LVM_FLOAT *src,
+ LVM_FLOAT *StereoOut,
LVM_FLOAT *dst,
LVM_INT16 NrFrames, /* Number of frames*/
LVM_INT32 NrChannels)
{
LVM_INT16 ii, jj;
- LVM_FLOAT *src_st = dst + 2 * (NrFrames - 1);
- // repack dst which carries stereo information
+ // pack dst with stereo information of StereoOut
// together with the upper channels of src.
+ StereoOut += 2 * (NrFrames - 1);
dst += NrChannels * (NrFrames - 1);
src += NrChannels * (NrFrames - 1);
for (ii = NrFrames; ii != 0; ii--)
{
- dst[1] = src_st[1];
- dst[0] = src_st[0]; // copy 1 before 0 is required for NrChannels == 3.
+ dst[1] = StereoOut[1];
+ dst[0] = StereoOut[0]; // copy 1 before 0 is required for NrChannels == 3.
for (jj = 2; jj < NrChannels; jj++)
{
dst[jj] = src[jj];
}
dst -= NrChannels;
src -= NrChannels;
- src_st -= 2;
+ StereoOut -= 2;
}
}
#endif
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Private.h b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Private.h
index ab8ccd1..c8df8e4 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Private.h
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Private.h
@@ -60,7 +60,11 @@
#define LVCS_COMPGAINFRAME 64 /* Compressor gain update interval */
/* Memory */
+#ifdef SUPPORT_MC
+#define LVCS_SCRATCHBUFFERS 8 /* Number of buffers required for inplace processing */
+#else
#define LVCS_SCRATCHBUFFERS 6 /* Number of buffers required for inplace processing */
+#endif
#ifdef SUPPORT_MC
/*
* The Concert Surround module applies processing only on the first two
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Process.c b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Process.c
index ef1d9eb..56fb04f 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Process.c
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Process.c
@@ -106,7 +106,7 @@
* The Concert Surround module carries out processing only on L, R.
*/
pInput = pScratch + (2 * NrFrames);
- pStIn = pScratch + (LVCS_SCRATCHBUFFERS * NrFrames);
+ pStIn = pScratch + ((LVCS_SCRATCHBUFFERS - 2) * NrFrames);
/* The first two channel data is extracted from the input data and
* copied into pInput buffer
*/
@@ -303,13 +303,45 @@
*/
if (pInstance->Params.OperatingMode != LVCS_OFF)
{
+#ifdef SUPPORT_MC
+ LVM_FLOAT *pStereoOut;
+ /*
+ * LVCS_Process_CS uses output buffer to store intermediate outputs of StereoEnhancer,
+ * Equalizer, ReverbGenerator and BypassMixer.
+ * So, to avoid i/o data overlapping, when i/o buffers are common, use scratch buffer
+ * to store intermediate outputs.
+ */
+ if (pOutData == pInData)
+ {
+ /*
+ * Scratch memory is used in 4 chunks of (2 * NrFrames) size.
+ * First chunk of memory is used by LVCS_StereoEnhancer and LVCS_ReverbGenerator,
+ * second and fourth are used as input buffers by pInput and pStIn in LVCS_Process_CS.
+ * Hence, pStereoOut is pointed to use unused third portion of scratch memory.
+ */
+ pStereoOut = (LVM_FLOAT *) \
+ pInstance->MemoryTable. \
+ Region[LVCS_MEMREGION_TEMPORARY_FAST].pBaseAddress +
+ ((LVCS_SCRATCHBUFFERS - 4) * NrFrames);
+ }
+ else
+ {
+ pStereoOut = pOutData;
+ }
+
/*
* Call CS process function
*/
err = LVCS_Process_CS(hInstance,
pInData,
+ pStereoOut,
+ NrFrames);
+#else
+ err = LVCS_Process_CS(hInstance,
+ pInData,
pOutData,
NumSamples);
+#endif
/*
@@ -329,10 +361,17 @@
if(NumSamples < LVCS_COMPGAINFRAME)
{
+#ifdef SUPPORT_MC
+ NonLinComp_Float(Gain, /* Compressor gain setting */
+ pStereoOut,
+ pStereoOut,
+ (LVM_INT32)(2 * NrFrames));
+#else
NonLinComp_Float(Gain, /* Compressor gain setting */
pOutData,
pOutData,
(LVM_INT32)(2 * NumSamples));
+#endif
}
else
{
@@ -361,7 +400,11 @@
FinalGain = Gain;
Gain = pInstance->CompressGain;
+#ifdef SUPPORT_MC
+ pOutPtr = pStereoOut;
+#else
pOutPtr = pOutData;
+#endif
while(SampleToProcess > 0)
{
@@ -428,6 +471,7 @@
}
#ifdef SUPPORT_MC
Copy_Float_Stereo_Mc(pInData,
+ pStereoOut,
pOutData,
NrFrames,
channels);