Merge "ACodec: Reduce the TWOmxNode wrapper in GraphicBufferSource" into rvc-qpr-dev
diff --git a/camera/ndk/impl/ACameraDevice.cpp b/camera/ndk/impl/ACameraDevice.cpp
index c15c5a5..78974ae 100644
--- a/camera/ndk/impl/ACameraDevice.cpp
+++ b/camera/ndk/impl/ACameraDevice.cpp
@@ -1361,31 +1361,11 @@
it->second.isSequenceCompleted = true;
}
- if (it->second.isSequenceCompleted && hasCallback) {
- auto cbIt = mSequenceCallbackMap.find(sequenceId);
- CallbackHolder cbh = cbIt->second;
-
- // send seq complete callback
- sp<AMessage> msg = new AMessage(kWhatCaptureSeqEnd, mHandler);
- msg->setPointer(kContextKey, cbh.mContext);
- msg->setObject(kSessionSpKey, cbh.mSession);
- msg->setPointer(kCallbackFpKey, (void*) cbh.mOnCaptureSequenceCompleted);
- msg->setInt32(kSequenceIdKey, sequenceId);
- msg->setInt64(kFrameNumberKey, lastFrameNumber);
-
- // Clear the session sp before we send out the message
- // This will guarantee the rare case where the message is processed
- // before cbh goes out of scope and causing we call the session
- // destructor while holding device lock
- cbh.mSession.clear();
- postSessionMsgAndCleanup(msg);
- }
}
if (it->second.isSequenceCompleted && it->second.isInflightCompleted) {
- if (mSequenceCallbackMap.find(sequenceId) != mSequenceCallbackMap.end()) {
- mSequenceCallbackMap.erase(sequenceId);
- }
+ sendCaptureSequenceCompletedLocked(sequenceId, lastFrameNumber);
+
it = mSequenceLastFrameNumberMap.erase(it);
ALOGV("%s: Remove holder for sequenceId %d", __FUNCTION__, sequenceId);
} else {
@@ -1412,13 +1392,7 @@
lastCompletedRegularFrameNumber);
if (lastFrameNumber <= lastCompletedRegularFrameNumber) {
if (it->second.isSequenceCompleted) {
- // Check if there is callback for this sequence
- // This should not happen because we always register callback (with nullptr inside)
- if (mSequenceCallbackMap.count(sequenceId) == 0) {
- ALOGW("No callback found for sequenceId %d", sequenceId);
- } else {
- mSequenceCallbackMap.erase(sequenceId);
- }
+ sendCaptureSequenceCompletedLocked(sequenceId, lastFrameNumber);
it = mSequenceLastFrameNumberMap.erase(it);
ALOGV("%s: Remove holder for sequenceId %d", __FUNCTION__, sequenceId);
@@ -1709,5 +1683,33 @@
return ret;
}
+void
+CameraDevice::sendCaptureSequenceCompletedLocked(int sequenceId, int64_t lastFrameNumber) {
+ auto cbIt = mSequenceCallbackMap.find(sequenceId);
+ if (cbIt != mSequenceCallbackMap.end()) {
+ CallbackHolder cbh = cbIt->second;
+ mSequenceCallbackMap.erase(cbIt);
+
+ // send seq complete callback
+ sp<AMessage> msg = new AMessage(kWhatCaptureSeqEnd, mHandler);
+ msg->setPointer(kContextKey, cbh.mContext);
+ msg->setObject(kSessionSpKey, cbh.mSession);
+ msg->setPointer(kCallbackFpKey, (void*) cbh.mOnCaptureSequenceCompleted);
+ msg->setInt32(kSequenceIdKey, sequenceId);
+ msg->setInt64(kFrameNumberKey, lastFrameNumber);
+
+ // Clear the session sp before we send out the message
+ // This will guarantee the rare case where the message is processed
+ // before cbh goes out of scope and causing we call the session
+ // destructor while holding device lock
+ cbh.mSession.clear();
+ postSessionMsgAndCleanup(msg);
+ } else {
+ // Check if there is callback for this sequence
+ // This should not happen because we always register callback (with nullptr inside)
+ ALOGW("No callback found for sequenceId %d", sequenceId);
+ }
+}
+
} // namespace acam
} // namespace android
diff --git a/camera/ndk/impl/ACameraDevice.h b/camera/ndk/impl/ACameraDevice.h
index d937865..3073dfb 100644
--- a/camera/ndk/impl/ACameraDevice.h
+++ b/camera/ndk/impl/ACameraDevice.h
@@ -354,6 +354,7 @@
void checkRepeatingSequenceCompleteLocked(const int sequenceId, const int64_t lastFrameNumber);
void checkAndFireSequenceCompleteLocked();
void removeCompletedCallbackHolderLocked(int64_t lastCompletedRegularFrameNumber);
+ void sendCaptureSequenceCompletedLocked(int sequenceId, int64_t lastFrameNumber);
// Misc variables
int32_t mShadingMapSize[2]; // const after constructor
diff --git a/cmds/stagefright/SimplePlayer.cpp b/cmds/stagefright/SimplePlayer.cpp
index f4b8164..e000633 100644
--- a/cmds/stagefright/SimplePlayer.cpp
+++ b/cmds/stagefright/SimplePlayer.cpp
@@ -272,7 +272,7 @@
status_t SimplePlayer::onPrepare() {
CHECK_EQ(mState, UNPREPARED);
- mExtractor = new NuMediaExtractor;
+ mExtractor = new NuMediaExtractor(NuMediaExtractor::EntryPoint::OTHER);
status_t err = mExtractor->setDataSource(
NULL /* httpService */, mPath.c_str());
diff --git a/cmds/stagefright/codec.cpp b/cmds/stagefright/codec.cpp
index c26e0b9..33c4663 100644
--- a/cmds/stagefright/codec.cpp
+++ b/cmds/stagefright/codec.cpp
@@ -79,7 +79,7 @@
static int64_t kTimeout = 500ll;
- sp<NuMediaExtractor> extractor = new NuMediaExtractor;
+ sp<NuMediaExtractor> extractor = new NuMediaExtractor(NuMediaExtractor::EntryPoint::OTHER);
if (extractor->setDataSource(NULL /* httpService */, path) != OK) {
fprintf(stderr, "unable to instantiate extractor.\n");
return 1;
diff --git a/cmds/stagefright/mediafilter.cpp b/cmds/stagefright/mediafilter.cpp
index b894545..ca058ab 100644
--- a/cmds/stagefright/mediafilter.cpp
+++ b/cmds/stagefright/mediafilter.cpp
@@ -319,7 +319,8 @@
static int64_t kTimeout = 500ll;
- sp<NuMediaExtractor> extractor = new NuMediaExtractor;
+ sp<NuMediaExtractor> extractor = new NuMediaExtractor(NuMediaExtractor::EntryPoint::OTHER);
+
if (extractor->setDataSource(NULL /* httpService */, path) != OK) {
fprintf(stderr, "unable to instantiate extractor.\n");
return 1;
diff --git a/cmds/stagefright/muxer.cpp b/cmds/stagefright/muxer.cpp
index 4a83a4a..bc7e41e 100644
--- a/cmds/stagefright/muxer.cpp
+++ b/cmds/stagefright/muxer.cpp
@@ -62,7 +62,7 @@
int trimEndTimeMs,
int rotationDegrees,
MediaMuxer::OutputFormat container = MediaMuxer::OUTPUT_FORMAT_MPEG_4) {
- sp<NuMediaExtractor> extractor = new NuMediaExtractor;
+ sp<NuMediaExtractor> extractor = new NuMediaExtractor(NuMediaExtractor::EntryPoint::OTHER);
if (extractor->setDataSource(NULL /* httpService */, path) != OK) {
fprintf(stderr, "unable to instantiate extractor. %s\n", path);
return 1;
diff --git a/media/codec2/sfplugin/InputSurfaceWrapper.h b/media/codec2/sfplugin/InputSurfaceWrapper.h
index bb35763..479acb1 100644
--- a/media/codec2/sfplugin/InputSurfaceWrapper.h
+++ b/media/codec2/sfplugin/InputSurfaceWrapper.h
@@ -61,24 +61,24 @@
/// Input Surface configuration
struct Config {
// IN PARAMS (GBS)
- float mMinFps; // minimum fps (repeat frame to achieve this)
- float mMaxFps; // max fps (via frame drop)
- float mCaptureFps; // capture fps
- float mCodedFps; // coded fps
- bool mSuspended; // suspended
- int64_t mTimeOffsetUs; // time offset (input => codec)
- int64_t mSuspendAtUs; // suspend/resume time
- int64_t mStartAtUs; // start time
- bool mStopped; // stopped
- int64_t mStopAtUs; // stop time
+ float mMinFps = 0.0; // minimum fps (repeat frame to achieve this)
+ float mMaxFps = 0.0; // max fps (via frame drop)
+ float mCaptureFps = 0.0; // capture fps
+ float mCodedFps = 0.0; // coded fps
+ bool mSuspended = false; // suspended
+ int64_t mTimeOffsetUs = 0; // time offset (input => codec)
+ int64_t mSuspendAtUs = 0; // suspend/resume time
+ int64_t mStartAtUs = 0; // start time
+ bool mStopped = false; // stopped
+ int64_t mStopAtUs = 0; // stop time
// OUT PARAMS (GBS)
- int64_t mInputDelayUs; // delay between encoder input and surface input
+ int64_t mInputDelayUs = 0; // delay between encoder input and surface input
// IN PARAMS (CODEC WRAPPER)
- float mFixedAdjustedFps; // fixed fps via PTS manipulation
- float mMinAdjustedFps; // minimum fps via PTS manipulation
- uint64_t mUsage; // consumer usage
+ float mFixedAdjustedFps = 0.0; // fixed fps via PTS manipulation
+ float mMinAdjustedFps = 0.0; // minimum fps via PTS manipulation
+ uint64_t mUsage = 0; // consumer usage
};
/**
diff --git a/media/libmedia/IMediaExtractor.cpp b/media/libmedia/IMediaExtractor.cpp
index 39caf53..7ed76d8 100644
--- a/media/libmedia/IMediaExtractor.cpp
+++ b/media/libmedia/IMediaExtractor.cpp
@@ -38,7 +38,8 @@
FLAGS,
SETMEDIACAS,
NAME,
- GETMETRICS
+ GETMETRICS,
+ SETENTRYPOINT
};
class BpMediaExtractor : public BpInterface<IMediaExtractor> {
@@ -142,6 +143,13 @@
}
return nm;
}
+
+ virtual status_t setEntryPoint(EntryPoint entryPoint) {
+ Parcel data, reply;
+ data.writeInterfaceToken(BpMediaExtractor::getInterfaceDescriptor());
+ data.writeInt32(static_cast<int32_t>(entryPoint));
+ return remote()->transact(SETENTRYPOINT, data, &reply);
+ }
};
IMPLEMENT_META_INTERFACE(MediaExtractor, "android.media.IMediaExtractor");
@@ -232,6 +240,16 @@
reply->writeString8(nm);
return NO_ERROR;
}
+ case SETENTRYPOINT: {
+ ALOGV("setEntryPoint");
+ CHECK_INTERFACE(IMediaExtractor, data, reply);
+ int32_t entryPoint;
+ status_t err = data.readInt32(&entryPoint);
+ if (err == OK) {
+ setEntryPoint(EntryPoint(entryPoint));
+ }
+ return err;
+ }
default:
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/media/libmedia/include/android/IMediaExtractor.h b/media/libmedia/include/android/IMediaExtractor.h
index 3e035ad..f9cafde 100644
--- a/media/libmedia/include/android/IMediaExtractor.h
+++ b/media/libmedia/include/android/IMediaExtractor.h
@@ -63,6 +63,15 @@
virtual status_t setMediaCas(const HInterfaceToken &casToken) = 0;
virtual String8 name() = 0;
+
+ enum class EntryPoint {
+ SDK = 1,
+ NDK_WITH_JVM = 2,
+ NDK_NO_JVM = 3,
+ OTHER = 4,
+ };
+
+ virtual status_t setEntryPoint(EntryPoint entryPoint) = 0;
};
diff --git a/media/libstagefright/NuMediaExtractor.cpp b/media/libstagefright/NuMediaExtractor.cpp
index 050d7c2..c638507 100644
--- a/media/libstagefright/NuMediaExtractor.cpp
+++ b/media/libstagefright/NuMediaExtractor.cpp
@@ -50,8 +50,9 @@
mSampleTimeUs(timeUs) {
}
-NuMediaExtractor::NuMediaExtractor()
- : mTotalBitrate(-1LL),
+NuMediaExtractor::NuMediaExtractor(EntryPoint entryPoint)
+ : mEntryPoint(entryPoint),
+ mTotalBitrate(-1LL),
mDurationUs(-1LL) {
}
@@ -93,6 +94,7 @@
if (mImpl == NULL) {
return ERROR_UNSUPPORTED;
}
+ setEntryPointToRemoteMediaExtractor();
status_t err = OK;
if (!mCasToken.empty()) {
@@ -134,6 +136,7 @@
if (mImpl == NULL) {
return ERROR_UNSUPPORTED;
}
+ setEntryPointToRemoteMediaExtractor();
if (!mCasToken.empty()) {
err = mImpl->setMediaCas(mCasToken);
@@ -168,6 +171,7 @@
if (mImpl == NULL) {
return ERROR_UNSUPPORTED;
}
+ setEntryPointToRemoteMediaExtractor();
if (!mCasToken.empty()) {
err = mImpl->setMediaCas(mCasToken);
@@ -468,6 +472,16 @@
}
}
+void NuMediaExtractor::setEntryPointToRemoteMediaExtractor() {
+ if (mImpl == NULL) {
+ return;
+ }
+ status_t err = mImpl->setEntryPoint(mEntryPoint);
+ if (err != OK) {
+ ALOGW("Failed to set entry point with error %d.", err);
+ }
+}
+
ssize_t NuMediaExtractor::fetchAllTrackSamples(
int64_t seekTimeUs, MediaSource::ReadOptions::SeekMode mode) {
TrackInfo *minInfo = NULL;
diff --git a/media/libstagefright/RemoteMediaExtractor.cpp b/media/libstagefright/RemoteMediaExtractor.cpp
index 25e43c2..381eb1a 100644
--- a/media/libstagefright/RemoteMediaExtractor.cpp
+++ b/media/libstagefright/RemoteMediaExtractor.cpp
@@ -39,6 +39,12 @@
static const char *kExtractorFormat = "android.media.mediaextractor.fmt";
static const char *kExtractorMime = "android.media.mediaextractor.mime";
static const char *kExtractorTracks = "android.media.mediaextractor.ntrk";
+static const char *kExtractorEntryPoint = "android.media.mediaextractor.entry";
+
+static const char *kEntryPointSdk = "sdk";
+static const char *kEntryPointWithJvm = "ndk-with-jvm";
+static const char *kEntryPointNoJvm = "ndk-no-jvm";
+static const char *kEntryPointOther = "other";
RemoteMediaExtractor::RemoteMediaExtractor(
MediaExtractor *extractor,
@@ -74,6 +80,9 @@
}
// what else is interesting and not already available?
}
+ // By default, we set the entry point to be "other". Clients of this
+ // class will override this value by calling setEntryPoint.
+ mMetricsItem->setCString(kExtractorEntryPoint, kEntryPointOther);
}
}
@@ -143,6 +152,28 @@
return String8(mExtractor->name());
}
+status_t RemoteMediaExtractor::setEntryPoint(EntryPoint entryPoint) {
+ const char* entryPointString;
+ switch (entryPoint) {
+ case EntryPoint::SDK:
+ entryPointString = kEntryPointSdk;
+ break;
+ case EntryPoint::NDK_WITH_JVM:
+ entryPointString = kEntryPointWithJvm;
+ break;
+ case EntryPoint::NDK_NO_JVM:
+ entryPointString = kEntryPointNoJvm;
+ break;
+ case EntryPoint::OTHER:
+ entryPointString = kEntryPointOther;
+ break;
+ default:
+ return BAD_VALUE;
+ }
+ mMetricsItem->setCString(kExtractorEntryPoint, entryPointString);
+ return OK;
+}
+
////////////////////////////////////////////////////////////////////////////////
// static
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_framedecoder.cpp b/media/libstagefright/codecs/mp3dec/src/pvmp3_framedecoder.cpp
index a5c7f5e..15d2feb 100644
--- a/media/libstagefright/codecs/mp3dec/src/pvmp3_framedecoder.cpp
+++ b/media/libstagefright/codecs/mp3dec/src/pvmp3_framedecoder.cpp
@@ -219,6 +219,11 @@
if (info->error_protection)
{
+ if (!bitsAvailable(&pVars->inputStream, 16))
+ {
+ return SIDE_INFO_ERROR;
+ }
+
/*
* Get crc content
*/
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_get_side_info.cpp b/media/libstagefright/codecs/mp3dec/src/pvmp3_get_side_info.cpp
index d644207..1a3fca5 100644
--- a/media/libstagefright/codecs/mp3dec/src/pvmp3_get_side_info.cpp
+++ b/media/libstagefright/codecs/mp3dec/src/pvmp3_get_side_info.cpp
@@ -73,6 +73,7 @@
#include "pvmp3_get_side_info.h"
#include "pvmp3_crc.h"
+#include "pvmp3_getbits.h"
/*----------------------------------------------------------------------------
@@ -125,12 +126,22 @@
{
if (stereo == 1)
{
+ if (!bitsAvailable(inputStream, 14))
+ {
+ return SIDE_INFO_ERROR;
+ }
+
tmp = getbits_crc(inputStream, 14, crc, info->error_protection);
si->main_data_begin = (tmp << 18) >> 23; /* 9 */
si->private_bits = (tmp << 27) >> 27; /* 5 */
}
else
{
+ if (!bitsAvailable(inputStream, 12))
+ {
+ return SIDE_INFO_ERROR;
+ }
+
tmp = getbits_crc(inputStream, 12, crc, info->error_protection);
si->main_data_begin = (tmp << 20) >> 23; /* 9 */
si->private_bits = (tmp << 29) >> 29; /* 3 */
@@ -139,6 +150,11 @@
for (ch = 0; ch < stereo; ch++)
{
+ if (!bitsAvailable(inputStream, 4))
+ {
+ return SIDE_INFO_ERROR;
+ }
+
tmp = getbits_crc(inputStream, 4, crc, info->error_protection);
si->ch[ch].scfsi[0] = (tmp << 28) >> 31; /* 1 */
si->ch[ch].scfsi[1] = (tmp << 29) >> 31; /* 1 */
@@ -150,6 +166,11 @@
{
for (ch = 0; ch < stereo; ch++)
{
+ if (!bitsAvailable(inputStream, 34))
+ {
+ return SIDE_INFO_ERROR;
+ }
+
si->ch[ch].gran[gr].part2_3_length = getbits_crc(inputStream, 12, crc, info->error_protection);
tmp = getbits_crc(inputStream, 22, crc, info->error_protection);
@@ -160,6 +181,11 @@
if (si->ch[ch].gran[gr].window_switching_flag)
{
+ if (!bitsAvailable(inputStream, 22))
+ {
+ return SIDE_INFO_ERROR;
+ }
+
tmp = getbits_crc(inputStream, 22, crc, info->error_protection);
si->ch[ch].gran[gr].block_type = (tmp << 10) >> 30; /* 2 */;
@@ -192,6 +218,11 @@
}
else
{
+ if (!bitsAvailable(inputStream, 22))
+ {
+ return SIDE_INFO_ERROR;
+ }
+
tmp = getbits_crc(inputStream, 22, crc, info->error_protection);
si->ch[ch].gran[gr].table_select[0] = (tmp << 10) >> 27; /* 5 */;
@@ -204,6 +235,11 @@
si->ch[ch].gran[gr].block_type = 0;
}
+ if (!bitsAvailable(inputStream, 3))
+ {
+ return SIDE_INFO_ERROR;
+ }
+
tmp = getbits_crc(inputStream, 3, crc, info->error_protection);
si->ch[ch].gran[gr].preflag = (tmp << 29) >> 31; /* 1 */
si->ch[ch].gran[gr].scalefac_scale = (tmp << 30) >> 31; /* 1 */
@@ -213,11 +249,21 @@
}
else /* Layer 3 LSF */
{
+ if (!bitsAvailable(inputStream, 8 + stereo))
+ {
+ return SIDE_INFO_ERROR;
+ }
+
si->main_data_begin = getbits_crc(inputStream, 8, crc, info->error_protection);
si->private_bits = getbits_crc(inputStream, stereo, crc, info->error_protection);
for (ch = 0; ch < stereo; ch++)
{
+ if (!bitsAvailable(inputStream, 39))
+ {
+ return SIDE_INFO_ERROR;
+ }
+
tmp = getbits_crc(inputStream, 21, crc, info->error_protection);
si->ch[ch].gran[0].part2_3_length = (tmp << 11) >> 20; /* 12 */
si->ch[ch].gran[0].big_values = (tmp << 23) >> 23; /* 9 */
@@ -230,6 +276,11 @@
if (si->ch[ch].gran[0].window_switching_flag)
{
+ if (!bitsAvailable(inputStream, 22))
+ {
+ return SIDE_INFO_ERROR;
+ }
+
tmp = getbits_crc(inputStream, 22, crc, info->error_protection);
si->ch[ch].gran[0].block_type = (tmp << 10) >> 30; /* 2 */;
@@ -262,6 +313,11 @@
}
else
{
+ if (!bitsAvailable(inputStream, 22))
+ {
+ return SIDE_INFO_ERROR;
+ }
+
tmp = getbits_crc(inputStream, 22, crc, info->error_protection);
si->ch[ch].gran[0].table_select[0] = (tmp << 10) >> 27; /* 5 */;
@@ -274,6 +330,11 @@
si->ch[ch].gran[0].block_type = 0;
}
+ if (!bitsAvailable(inputStream, 2))
+ {
+ return SIDE_INFO_ERROR;
+ }
+
tmp = getbits_crc(inputStream, 2, crc, info->error_protection);
si->ch[ch].gran[0].scalefac_scale = tmp >> 1; /* 1 */
si->ch[ch].gran[0].count1table_select = tmp & 1; /* 1 */
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_getbits.cpp b/media/libstagefright/codecs/mp3dec/src/pvmp3_getbits.cpp
index 8ff7953..4d252ef 100644
--- a/media/libstagefright/codecs/mp3dec/src/pvmp3_getbits.cpp
+++ b/media/libstagefright/codecs/mp3dec/src/pvmp3_getbits.cpp
@@ -113,10 +113,11 @@
uint32 offset;
uint32 bitIndex;
- uint8 Elem; /* Needs to be same type as pInput->pBuffer */
- uint8 Elem1;
- uint8 Elem2;
- uint8 Elem3;
+ uint32 bytesToFetch;
+ uint8 Elem = 0; /* Needs to be same type as pInput->pBuffer */
+ uint8 Elem1 = 0;
+ uint8 Elem2 = 0;
+ uint8 Elem3 = 0;
uint32 returnValue = 0;
if (!neededBits)
@@ -126,10 +127,25 @@
offset = (ptBitStream->usedBits) >> INBUF_ARRAY_INDEX_SHIFT;
- Elem = *(ptBitStream->pBuffer + module(offset , BUFSIZE));
- Elem1 = *(ptBitStream->pBuffer + module(offset + 1, BUFSIZE));
- Elem2 = *(ptBitStream->pBuffer + module(offset + 2, BUFSIZE));
- Elem3 = *(ptBitStream->pBuffer + module(offset + 3, BUFSIZE));
+ /* Remove extra high bits by shifting up */
+ bitIndex = module(ptBitStream->usedBits, INBUF_BIT_WIDTH);
+
+ bytesToFetch = (bitIndex + neededBits + 7 ) >> 3 ;
+
+ switch (bytesToFetch)
+ {
+ case 4:
+ Elem3 = *(ptBitStream->pBuffer + module(offset + 3, BUFSIZE));
+ [[fallthrough]];
+ case 3:
+ Elem2 = *(ptBitStream->pBuffer + module(offset + 2, BUFSIZE));
+ [[fallthrough]];
+ case 2:
+ Elem1 = *(ptBitStream->pBuffer + module(offset + 1, BUFSIZE));
+ [[fallthrough]];
+ case 1:
+ Elem = *(ptBitStream->pBuffer + module(offset, BUFSIZE));
+ }
returnValue = (((uint32)(Elem)) << 24) |
@@ -137,9 +153,6 @@
(((uint32)(Elem2)) << 8) |
((uint32)(Elem3));
- /* Remove extra high bits by shifting up */
- bitIndex = module(ptBitStream->usedBits, INBUF_BIT_WIDTH);
-
/* This line is faster than to mask off the high bits. */
returnValue <<= bitIndex;
@@ -161,22 +174,32 @@
uint32 offset;
uint32 bitIndex;
- uint8 Elem; /* Needs to be same type as pInput->pBuffer */
- uint8 Elem1;
+ uint32 bytesToFetch;
+ uint8 Elem = 0; /* Needs to be same type as pInput->pBuffer */
+ uint8 Elem1 = 0;
uint16 returnValue;
offset = (ptBitStream->usedBits) >> INBUF_ARRAY_INDEX_SHIFT;
- Elem = *(ptBitStream->pBuffer + module(offset , BUFSIZE));
- Elem1 = *(ptBitStream->pBuffer + module(offset + 1, BUFSIZE));
+ /* Remove extra high bits by shifting up */
+ bitIndex = module(ptBitStream->usedBits, INBUF_BIT_WIDTH);
+
+ bytesToFetch = (bitIndex + neededBits + 7 ) >> 3 ;
+
+ if (bytesToFetch > 1)
+ {
+ Elem = *(ptBitStream->pBuffer + module(offset, BUFSIZE));
+ Elem1 = *(ptBitStream->pBuffer + module(offset + 1, BUFSIZE));
+ }
+ else if (bytesToFetch > 0)
+ {
+ Elem = *(ptBitStream->pBuffer + module(offset, BUFSIZE));
+ }
returnValue = (((uint16)(Elem)) << 8) |
((uint16)(Elem1));
- /* Remove extra high bits by shifting up */
- bitIndex = module(ptBitStream->usedBits, INBUF_BIT_WIDTH);
-
ptBitStream->usedBits += neededBits;
/* This line is faster than to mask off the high bits. */
returnValue = (returnValue << (bitIndex));
@@ -197,25 +220,40 @@
uint32 offset;
uint32 bitIndex;
- uint8 Elem; /* Needs to be same type as pInput->pBuffer */
- uint8 Elem1;
- uint8 Elem2;
+ uint32 bytesToFetch;
+ uint8 Elem = 0; /* Needs to be same type as pInput->pBuffer */
+ uint8 Elem1 = 0;
+ uint8 Elem2 = 0;
uint32 returnValue;
offset = (ptBitStream->usedBits) >> INBUF_ARRAY_INDEX_SHIFT;
- Elem = *(ptBitStream->pBuffer + module(offset , BUFSIZE));
- Elem1 = *(ptBitStream->pBuffer + module(offset + 1, BUFSIZE));
- Elem2 = *(ptBitStream->pBuffer + module(offset + 2, BUFSIZE));
+ /* Remove extra high bits by shifting up */
+ bitIndex = module(ptBitStream->usedBits, INBUF_BIT_WIDTH);
+
+ bytesToFetch = (bitIndex + neededBits + 7 ) >> 3 ;
+
+ if (bytesToFetch > 2)
+ {
+ Elem = *(ptBitStream->pBuffer + module(offset, BUFSIZE));
+ Elem1 = *(ptBitStream->pBuffer + module(offset + 1, BUFSIZE));
+ Elem2 = *(ptBitStream->pBuffer + module(offset + 2, BUFSIZE));
+ }
+ else if (bytesToFetch > 1)
+ {
+ Elem = *(ptBitStream->pBuffer + module(offset, BUFSIZE));
+ Elem1 = *(ptBitStream->pBuffer + module(offset + 1, BUFSIZE));
+ }
+ else if (bytesToFetch > 0)
+ {
+ Elem = *(ptBitStream->pBuffer + module(offset, BUFSIZE));
+ }
returnValue = (((uint32)(Elem)) << 16) |
(((uint32)(Elem1)) << 8) |
((uint32)(Elem2));
- /* Remove extra high bits by shifting up */
- bitIndex = module(ptBitStream->usedBits, INBUF_BIT_WIDTH);
-
ptBitStream->usedBits += neededBits;
/* This line is faster than to mask off the high bits. */
returnValue = 0xFFFFFF & (returnValue << (bitIndex));
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_getbits.h b/media/libstagefright/codecs/mp3dec/src/pvmp3_getbits.h
index b058b00..b04fe6d 100644
--- a/media/libstagefright/codecs/mp3dec/src/pvmp3_getbits.h
+++ b/media/libstagefright/codecs/mp3dec/src/pvmp3_getbits.h
@@ -104,6 +104,11 @@
; Function Prototype declaration
----------------------------------------------------------------------------*/
+static inline bool bitsAvailable(tmp3Bits *inputStream, uint32 neededBits)
+{
+ return (inputStream->inputBufferCurrentLength << 3) >= (neededBits + inputStream->usedBits);
+}
+
/*----------------------------------------------------------------------------
; END
----------------------------------------------------------------------------*/
diff --git a/media/libstagefright/include/media/stagefright/NuMediaExtractor.h b/media/libstagefright/include/media/stagefright/NuMediaExtractor.h
index 227cead..d8f2b00 100644
--- a/media/libstagefright/include/media/stagefright/NuMediaExtractor.h
+++ b/media/libstagefright/include/media/stagefright/NuMediaExtractor.h
@@ -47,12 +47,14 @@
SAMPLE_FLAG_ENCRYPTED = 2,
};
+ typedef IMediaExtractor::EntryPoint EntryPoint;
+
// identical to IMediaExtractor::GetTrackMetaDataFlags
enum GetTrackFormatFlags {
kIncludeExtensiveMetaData = 1, // reads sample table and possibly stream headers
};
- NuMediaExtractor();
+ explicit NuMediaExtractor(EntryPoint entryPoint);
status_t setDataSource(
const sp<MediaHTTPService> &httpService,
@@ -128,6 +130,8 @@
uint32_t mTrackFlags; // bitmask of "TrackFlags"
};
+ const EntryPoint mEntryPoint;
+
mutable Mutex mLock;
sp<DataSource> mDataSource;
@@ -139,6 +143,8 @@
int64_t mTotalBitrate; // in bits/sec
int64_t mDurationUs;
+ void setEntryPointToRemoteMediaExtractor();
+
ssize_t fetchAllTrackSamples(
int64_t seekTimeUs = -1ll,
MediaSource::ReadOptions::SeekMode mode =
diff --git a/media/libstagefright/include/media/stagefright/RemoteMediaExtractor.h b/media/libstagefright/include/media/stagefright/RemoteMediaExtractor.h
index 2ce7bc7..25125f2 100644
--- a/media/libstagefright/include/media/stagefright/RemoteMediaExtractor.h
+++ b/media/libstagefright/include/media/stagefright/RemoteMediaExtractor.h
@@ -42,6 +42,7 @@
virtual uint32_t flags() const;
virtual status_t setMediaCas(const HInterfaceToken &casToken);
virtual String8 name();
+ virtual status_t setEntryPoint(EntryPoint entryPoint);
private:
MediaExtractor *mExtractor;
diff --git a/media/ndk/NdkMediaExtractor.cpp b/media/ndk/NdkMediaExtractor.cpp
index 0da0740..0c65e9e 100644
--- a/media/ndk/NdkMediaExtractor.cpp
+++ b/media/ndk/NdkMediaExtractor.cpp
@@ -22,6 +22,7 @@
#include <media/NdkMediaExtractor.h>
#include <media/NdkMediaErrorPriv.h>
#include <media/NdkMediaFormatPriv.h>
+#include "NdkJavaVMHelperPriv.h"
#include "NdkMediaDataSourcePriv.h"
@@ -63,7 +64,10 @@
AMediaExtractor* AMediaExtractor_new() {
ALOGV("ctor");
AMediaExtractor *mData = new AMediaExtractor();
- mData->mImpl = new NuMediaExtractor();
+ mData->mImpl = new NuMediaExtractor(
+ NdkJavaVMHelper::getJNIEnv() != nullptr
+ ? NuMediaExtractor::EntryPoint::NDK_WITH_JVM
+ : NuMediaExtractor::EntryPoint::NDK_NO_JVM );
return mData;
}
diff --git a/services/mediametrics/statsd_extractor.cpp b/services/mediametrics/statsd_extractor.cpp
index 3d5739f..fb0924c 100644
--- a/services/mediametrics/statsd_extractor.cpp
+++ b/services/mediametrics/statsd_extractor.cpp
@@ -71,6 +71,22 @@
metrics_proto.set_tracks(ntrk);
}
+ // android.media.mediaextractor.entry string
+ std::string entry_point_string;
+ if (item->getString("android.media.mediaextractor.entry", &entry_point_string)) {
+ stats::mediametrics::ExtractorData::EntryPoint entry_point;
+ if (entry_point_string == "sdk") {
+ entry_point = stats::mediametrics::ExtractorData_EntryPoint_SDK;
+ } else if (entry_point_string == "ndk-with-jvm") {
+ entry_point = stats::mediametrics::ExtractorData_EntryPoint_NDK_WITH_JVM;
+ } else if (entry_point_string == "ndk-no-jvm") {
+ entry_point = stats::mediametrics::ExtractorData_EntryPoint_NDK_NO_JVM;
+ } else {
+ entry_point = stats::mediametrics::ExtractorData_EntryPoint_OTHER;
+ }
+ metrics_proto.set_entry_point(entry_point);
+ }
+
std::string serialized;
if (!metrics_proto.SerializeToString(&serialized)) {
ALOGE("Failed to serialize extractor metrics");