Merge "do not use paused postition if it's not available" into lmp-mr1-dev
diff --git a/include/media/stagefright/ACodec.h b/include/media/stagefright/ACodec.h
index 4d4ce90..371e2c8 100644
--- a/include/media/stagefright/ACodec.h
+++ b/include/media/stagefright/ACodec.h
@@ -131,6 +131,7 @@
enum {
kFlagIsSecure = 1,
kFlagPushBlankBuffersToNativeWindowOnShutdown = 2,
+ kFlagIsGrallocUsageProtected = 4,
};
struct BufferInfo {
@@ -282,6 +283,8 @@
status_t setupAC3Codec(bool encoder, int32_t numChannels, int32_t sampleRate);
+ status_t setupEAC3Codec(bool encoder, int32_t numChannels, int32_t sampleRate);
+
status_t selectAudioPortFormat(
OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat);
diff --git a/include/media/stagefright/MediaDefs.h b/include/media/stagefright/MediaDefs.h
index e67d4d5..13695d5 100644
--- a/include/media/stagefright/MediaDefs.h
+++ b/include/media/stagefright/MediaDefs.h
@@ -47,6 +47,7 @@
extern const char *MEDIA_MIMETYPE_AUDIO_AAC_ADTS;
extern const char *MEDIA_MIMETYPE_AUDIO_MSGSM;
extern const char *MEDIA_MIMETYPE_AUDIO_AC3;
+extern const char *MEDIA_MIMETYPE_AUDIO_EAC3;
extern const char *MEDIA_MIMETYPE_CONTAINER_MPEG4;
extern const char *MEDIA_MIMETYPE_CONTAINER_WAV;
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp
index d9646d9..ca3832d 100644
--- a/media/libmedia/AudioRecord.cpp
+++ b/media/libmedia/AudioRecord.cpp
@@ -167,10 +167,6 @@
return INVALID_OPERATION;
}
- // handle default values first.
- if (inputSource == AUDIO_SOURCE_DEFAULT) {
- inputSource = AUDIO_SOURCE_MIC;
- }
if (pAttributes == NULL) {
memset(&mAttributes, 0, sizeof(audio_attributes_t));
mAttributes.source = inputSource;
diff --git a/media/libmediaplayerservice/MidiFile.cpp b/media/libmediaplayerservice/MidiFile.cpp
index 749ef96..60cbd3c 100644
--- a/media/libmediaplayerservice/MidiFile.cpp
+++ b/media/libmediaplayerservice/MidiFile.cpp
@@ -293,7 +293,7 @@
{
ALOGV("MidiFile::isPlaying, mState=%d", int(mState));
if (!mEasHandle || mPaused) return false;
- return (mState == EAS_STATE_PLAY);
+ return (mState == EAS_STATE_PLAY || (mState == EAS_STATE_READY && mRender));
}
status_t MidiFile::getCurrentPosition(int* position)
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
index dd79b50..76b80bb 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
@@ -391,6 +391,7 @@
notifyFlagsChanged(
(mIsSecure ? FLAG_SECURE : 0)
+ | (mDecryptHandle != NULL ? FLAG_PROTECTED : 0)
| FLAG_CAN_PAUSE
| FLAG_CAN_SEEK_BACKWARD
| FLAG_CAN_SEEK_FORWARD
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index a28591e..e02a2d5 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -1190,6 +1190,10 @@
if (mSourceFlags & Source::FLAG_SECURE) {
format->setInt32("secure", true);
}
+
+ if (mSourceFlags & Source::FLAG_PROTECTED) {
+ format->setInt32("protected", true);
+ }
}
if (audio) {
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index 53dfa48..80b8493 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -39,6 +39,15 @@
static const int64_t kOffloadPauseMaxUs = 10000000ll;
// static
+const NuPlayer::Renderer::PcmInfo NuPlayer::Renderer::AUDIO_PCMINFO_INITIALIZER = {
+ AUDIO_CHANNEL_NONE,
+ AUDIO_OUTPUT_FLAG_NONE,
+ AUDIO_FORMAT_INVALID,
+ 0, // mNumChannels
+ 0 // mSampleRate
+};
+
+// static
const int64_t NuPlayer::Renderer::kMinPositionUpdateDelayUs = 100000ll;
NuPlayer::Renderer::Renderer(
@@ -76,6 +85,7 @@
mAudioOffloadPauseTimeoutGeneration(0),
mAudioOffloadTornDown(false),
mCurrentOffloadInfo(AUDIO_INFO_INITIALIZER),
+ mCurrentPcmInfo(AUDIO_PCMINFO_INITIALIZER),
mTotalBuffersQueued(0),
mLastAudioBufferDrained(0) {
}
@@ -1448,6 +1458,8 @@
// no change from previous configuration, everything ok.
return OK;
}
+ mCurrentPcmInfo = AUDIO_PCMINFO_INITIALIZER;
+
ALOGV("openAudioSink: try to open AudioSink in offload mode");
uint32_t offloadFlags = flags;
offloadFlags |= AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD;
@@ -1489,6 +1501,20 @@
ALOGV("openAudioSink: open AudioSink in NON-offload mode");
uint32_t pcmFlags = flags;
pcmFlags &= ~AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD;
+
+ const PcmInfo info = {
+ (audio_channel_mask_t)channelMask,
+ (audio_output_flags_t)pcmFlags,
+ AUDIO_FORMAT_PCM_16_BIT, // TODO: change to audioFormat
+ numChannels,
+ sampleRate
+ };
+ if (memcmp(&mCurrentPcmInfo, &info, sizeof(info)) == 0) {
+ ALOGV("openAudioSink: no change in pcm mode");
+ // no change from previous configuration, everything ok.
+ return OK;
+ }
+
audioSinkChanged = true;
mAudioSink->close();
mCurrentOffloadInfo = AUDIO_INFO_INITIALIZER;
@@ -1503,8 +1529,10 @@
(audio_output_flags_t)pcmFlags);
if (err != OK) {
ALOGW("openAudioSink: non offloaded open failed status: %d", err);
+ mCurrentPcmInfo = AUDIO_PCMINFO_INITIALIZER;
return err;
}
+ mCurrentPcmInfo = info;
mAudioSink->start();
}
if (audioSinkChanged) {
@@ -1519,6 +1547,7 @@
void NuPlayer::Renderer::onCloseAudioSink() {
mAudioSink->close();
mCurrentOffloadInfo = AUDIO_INFO_INITIALIZER;
+ mCurrentPcmInfo = AUDIO_PCMINFO_INITIALIZER;
}
} // namespace android
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
index c6e3457..23907c8 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
@@ -181,6 +181,16 @@
bool mAudioOffloadTornDown;
audio_offload_info_t mCurrentOffloadInfo;
+ struct PcmInfo {
+ audio_channel_mask_t mChannelMask;
+ audio_output_flags_t mFlags;
+ audio_format_t mFormat;
+ int32_t mNumChannels;
+ int32_t mSampleRate;
+ };
+ PcmInfo mCurrentPcmInfo;
+ static const PcmInfo AUDIO_PCMINFO_INITIALIZER;
+
int32_t mTotalBuffersQueued;
int32_t mLastAudioBufferDrained;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerSource.h b/media/libmediaplayerservice/nuplayer/NuPlayerSource.h
index 2b0ac47..5bf9187 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerSource.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerSource.h
@@ -39,6 +39,7 @@
FLAG_CAN_SEEK = 8, // the "seek bar"
FLAG_DYNAMIC_DURATION = 16,
FLAG_SECURE = 32,
+ FLAG_PROTECTED = 64,
};
enum {
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index e1b3b4d..87606a5 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -670,7 +670,7 @@
usage = 0;
}
- if (mFlags & kFlagIsSecure) {
+ if (mFlags & kFlagIsGrallocUsageProtected) {
usage |= GRALLOC_USAGE_PROTECTED;
}
@@ -1106,6 +1106,8 @@
"video_decoder.mpeg2", "video_encoder.mpeg2" },
{ MEDIA_MIMETYPE_AUDIO_AC3,
"audio_decoder.ac3", "audio_encoder.ac3" },
+ { MEDIA_MIMETYPE_AUDIO_EAC3,
+ "audio_decoder.eac3", "audio_encoder.eac3" },
};
static const size_t kNumMimeToRole =
@@ -1262,6 +1264,16 @@
mStoreMetaDataInOutputBuffers = false;
if (video && !encoder) {
inputFormat->setInt32("adaptive-playback", false);
+
+ int32_t usageProtected;
+ if (msg->findInt32("protected", &usageProtected) && usageProtected) {
+ if (!haveNativeWindow) {
+ ALOGE("protected output buffers must be sent to an ANativeWindow");
+ return PERMISSION_DENIED;
+ }
+ mFlags |= kFlagIsGrallocUsageProtected;
+ mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
+ }
}
if (!encoder && video && haveNativeWindow) {
sp<NativeWindowWrapper> windowWrapper(
@@ -1530,6 +1542,15 @@
} else {
err = setupAC3Codec(encoder, numChannels, sampleRate);
}
+ } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_EAC3)) {
+ int32_t numChannels;
+ int32_t sampleRate;
+ if (!msg->findInt32("channel-count", &numChannels)
+ || !msg->findInt32("sample-rate", &sampleRate)) {
+ err = INVALID_OPERATION;
+ } else {
+ err = setupEAC3Codec(encoder, numChannels, sampleRate);
+ }
}
if (err != OK) {
@@ -1815,6 +1836,44 @@
sizeof(def));
}
+status_t ACodec::setupEAC3Codec(
+ bool encoder, int32_t numChannels, int32_t sampleRate) {
+ status_t err = setupRawAudioFormat(
+ encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
+
+ if (err != OK) {
+ return err;
+ }
+
+ if (encoder) {
+ ALOGW("EAC3 encoding is not supported.");
+ return INVALID_OPERATION;
+ }
+
+ OMX_AUDIO_PARAM_ANDROID_EAC3TYPE def;
+ InitOMXParams(&def);
+ def.nPortIndex = kPortIndexInput;
+
+ err = mOMX->getParameter(
+ mNode,
+ (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
+ &def,
+ sizeof(def));
+
+ if (err != OK) {
+ return err;
+ }
+
+ def.nChannels = numChannels;
+ def.nSampleRate = sampleRate;
+
+ return mOMX->setParameter(
+ mNode,
+ (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
+ &def,
+ sizeof(def));
+}
+
static OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
bool isAMRWB, int32_t bps) {
if (isAMRWB) {
@@ -3490,6 +3549,24 @@
break;
}
+ case OMX_AUDIO_CodingAndroidEAC3:
+ {
+ OMX_AUDIO_PARAM_ANDROID_EAC3TYPE params;
+ InitOMXParams(¶ms);
+ params.nPortIndex = portIndex;
+
+ CHECK_EQ((status_t)OK, mOMX->getParameter(
+ mNode,
+ (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
+ ¶ms,
+ sizeof(params)));
+
+ notify->setString("mime", MEDIA_MIMETYPE_AUDIO_EAC3);
+ notify->setInt32("channel-count", params.nChannels);
+ notify->setInt32("sample-rate", params.nSampleRate);
+ break;
+ }
+
case OMX_AUDIO_CodingAndroidOPUS:
{
OMX_AUDIO_PARAM_ANDROID_OPUSTYPE params;
@@ -4627,6 +4704,7 @@
if (componentName.endsWith(".secure")) {
mCodec->mFlags |= kFlagIsSecure;
+ mCodec->mFlags |= kFlagIsGrallocUsageProtected;
mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
}
diff --git a/media/libstagefright/HTTPBase.cpp b/media/libstagefright/HTTPBase.cpp
index 32291c8..0c2ff15 100644
--- a/media/libstagefright/HTTPBase.cpp
+++ b/media/libstagefright/HTTPBase.cpp
@@ -36,7 +36,8 @@
mTotalTransferBytes(0),
mPrevBandwidthMeasureTimeUs(0),
mPrevEstimatedBandWidthKbps(0),
- mBandWidthCollectFreqMs(5000) {
+ mBandWidthCollectFreqMs(5000),
+ mMaxBandwidthHistoryItems(100) {
}
void HTTPBase::addBandwidthMeasurement(
@@ -50,7 +51,7 @@
mTotalTransferBytes += numBytes;
mBandwidthHistory.push_back(entry);
- if (++mNumBandwidthHistoryItems > 100) {
+ if (++mNumBandwidthHistoryItems > mMaxBandwidthHistoryItems) {
BandwidthEntry *entry = &*mBandwidthHistory.begin();
mTotalTransferTimeUs -= entry->mDelayUs;
mTotalTransferBytes -= entry->mNumBytes;
@@ -104,6 +105,10 @@
return OK;
}
+void HTTPBase::setBandwidthHistorySize(size_t numHistoryItems) {
+ mMaxBandwidthHistoryItems = numHistoryItems;
+}
+
// static
void HTTPBase::RegisterSocketUserTag(int sockfd, uid_t uid, uint32_t kTag) {
int res = qtaguid_tagSocket(sockfd, kTag, uid);
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index e1c8a41..c2381b4 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -1014,11 +1014,13 @@
// Notify mCrypto of video resolution changes
if (mCrypto != NULL) {
- int32_t height, width;
- if (mOutputFormat->findInt32("height", &height) &&
- mOutputFormat->findInt32("width", &width)) {
- mCrypto->notifyResolution(width, height);
- }
+ int32_t left, top, right, bottom, width, height;
+ if (mOutputFormat->findRect("crop", &left, &top, &right, &bottom)) {
+ mCrypto->notifyResolution(right - left + 1, bottom - top + 1);
+ } else if (mOutputFormat->findInt32("width", &width)
+ && mOutputFormat->findInt32("height", &height)) {
+ mCrypto->notifyResolution(width, height);
+ }
}
break;
diff --git a/media/libstagefright/MediaDefs.cpp b/media/libstagefright/MediaDefs.cpp
index d48dd84..c5a6939 100644
--- a/media/libstagefright/MediaDefs.cpp
+++ b/media/libstagefright/MediaDefs.cpp
@@ -45,6 +45,7 @@
const char *MEDIA_MIMETYPE_AUDIO_AAC_ADTS = "audio/aac-adts";
const char *MEDIA_MIMETYPE_AUDIO_MSGSM = "audio/gsm";
const char *MEDIA_MIMETYPE_AUDIO_AC3 = "audio/ac3";
+const char *MEDIA_MIMETYPE_AUDIO_EAC3 = "audio/eac3";
const char *MEDIA_MIMETYPE_CONTAINER_MPEG4 = "video/mp4";
const char *MEDIA_MIMETYPE_CONTAINER_WAV = "audio/x-wav";
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 844bd14..b783222 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/src/pvdec_api.cpp
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/pvdec_api.cpp
@@ -247,10 +247,13 @@
video->vol[idx]->useReverseVLC = 0;
video->intra_acdcPredDisable = 1;
video->vol[idx]->scalability = 0;
- video->size = (int32)width * height;
- video->displayWidth = video->width = width;
- video->displayHeight = video->height = height;
+ video->displayWidth = width;
+ video->displayHeight = height;
+ video->width = (width + 15) & -16;
+ video->height = (height + 15) & -16;
+ video->size = (int32)video->width * video->height;
+
#ifdef PV_ANNEX_IJKT_SUPPORT
video->modified_quant = 0;
video->advanced_INTRA = 0;
diff --git a/media/libstagefright/httplive/LiveSession.cpp b/media/libstagefright/httplive/LiveSession.cpp
index 0b18666..9daab3b 100644
--- a/media/libstagefright/httplive/LiveSession.cpp
+++ b/media/libstagefright/httplive/LiveSession.cpp
@@ -49,6 +49,9 @@
namespace android {
+// Number of recently-read bytes to use for bandwidth estimation
+const size_t LiveSession::kBandwidthHistoryBytes = 200 * 1024;
+
LiveSession::LiveSession(
const sp<AMessage> ¬ify, uint32_t flags,
const sp<IMediaHTTPService> &httpService)
@@ -84,6 +87,13 @@
mPacketSources2.add(indexToType(i), new AnotherPacketSource(NULL /* meta */));
mBuffering[i] = false;
}
+
+ size_t numHistoryItems = kBandwidthHistoryBytes /
+ PlaylistFetcher::kDownloadBlockSize + 1;
+ if (numHistoryItems < 5) {
+ numHistoryItems = 5;
+ }
+ mHTTPDataSource->setBandwidthHistorySize(numHistoryItems);
}
LiveSession::~LiveSession() {
@@ -145,10 +155,24 @@
}
}
+ int32_t targetDuration = 0;
+ sp<AMessage> meta = packetSource->getLatestEnqueuedMeta();
+ if (meta != NULL) {
+ meta->findInt32("targetDuration", &targetDuration);
+ }
+
+ int64_t targetDurationUs = targetDuration * 1000000ll;
+ if (targetDurationUs == 0 ||
+ targetDurationUs > PlaylistFetcher::kMinBufferedDurationUs) {
+ // Fetchers limit buffering to
+ // min(3 * targetDuration, kMinBufferedDurationUs)
+ targetDurationUs = PlaylistFetcher::kMinBufferedDurationUs;
+ }
+
if (mBuffering[idx]) {
if (mSwitchInProgress
|| packetSource->isFinished(0)
- || packetSource->getEstimatedDurationUs() > 10000000ll) {
+ || packetSource->getEstimatedDurationUs() > targetDurationUs) {
mBuffering[idx] = false;
}
}
@@ -859,7 +883,11 @@
// Only resize when we don't know the size.
size_t bufferRemaining = buffer->capacity() - buffer->size();
if (bufferRemaining == 0 && getSizeErr != OK) {
- bufferRemaining = 32768;
+ size_t bufferIncrement = buffer->size() / 2;
+ if (bufferIncrement < 32768) {
+ bufferIncrement = 32768;
+ }
+ bufferRemaining = bufferIncrement;
ALOGV("increasing download buffer to %zu bytes",
buffer->size() + bufferRemaining);
diff --git a/media/libstagefright/httplive/LiveSession.h b/media/libstagefright/httplive/LiveSession.h
index 896a8fc..dfb5e59 100644
--- a/media/libstagefright/httplive/LiveSession.h
+++ b/media/libstagefright/httplive/LiveSession.h
@@ -114,6 +114,8 @@
kWhatSwitchDown = 'sDwn',
};
+ static const size_t kBandwidthHistoryBytes;
+
struct BandwidthItem {
size_t mPlaylistIndex;
unsigned long mBandwidth;
diff --git a/media/libstagefright/httplive/PlaylistFetcher.cpp b/media/libstagefright/httplive/PlaylistFetcher.cpp
index d8eed5b..4a97803 100644
--- a/media/libstagefright/httplive/PlaylistFetcher.cpp
+++ b/media/libstagefright/httplive/PlaylistFetcher.cpp
@@ -49,8 +49,9 @@
// static
const int64_t PlaylistFetcher::kMinBufferedDurationUs = 10000000ll;
const int64_t PlaylistFetcher::kMaxMonitorDelayUs = 3000000ll;
-const int32_t PlaylistFetcher::kDownloadBlockSize = 2048;
-const int32_t PlaylistFetcher::kNumSkipFrames = 10;
+// LCM of 188 (size of a TS packet) & 1k works well
+const int32_t PlaylistFetcher::kDownloadBlockSize = 47 * 1024;
+const int32_t PlaylistFetcher::kNumSkipFrames = 5;
PlaylistFetcher::PlaylistFetcher(
const sp<AMessage> ¬ify,
@@ -561,7 +562,7 @@
// Don't resume if we would stop within a resume threshold.
int32_t discontinuitySeq;
int64_t latestTimeUs = 0, stopTimeUs = 0;
- sp<AMessage> latestMeta = packetSource->getLatestDequeuedMeta();
+ sp<AMessage> latestMeta = packetSource->getLatestEnqueuedMeta();
if (latestMeta != NULL
&& latestMeta->findInt32("discontinuitySeq", &discontinuitySeq)
&& discontinuitySeq == mDiscontinuitySeq
@@ -610,7 +611,12 @@
int32_t targetDurationSecs;
int64_t targetDurationUs = kMinBufferedDurationUs;
if (mPlaylist != NULL) {
- CHECK(mPlaylist->meta()->findInt32("target-duration", &targetDurationSecs));
+ if (mPlaylist->meta() == NULL || !mPlaylist->meta()->findInt32(
+ "target-duration", &targetDurationSecs)) {
+ ALOGE("Playlist is missing required EXT-X-TARGETDURATION tag");
+ notifyError(ERROR_MALFORMED);
+ return;
+ }
targetDurationUs = targetDurationSecs * 1000000ll;
}
@@ -1159,6 +1165,11 @@
accessUnit->meta()->setInt32("discard", discard);
}
+ int32_t targetDurationSecs;
+ if (mPlaylist->meta()->findInt32("target-duration", &targetDurationSecs)) {
+ accessUnit->meta()->setInt32("targetDuration", targetDurationSecs);
+ }
+
accessUnit->meta()->setInt32("discontinuitySeq", mDiscontinuitySeq);
accessUnit->meta()->setInt64("segmentStartTimeUs", getSegmentStartTimeUs(mSeqNumber));
return accessUnit;
@@ -1668,7 +1679,7 @@
int64_t PlaylistFetcher::resumeThreshold(const sp<AMessage> &msg) {
int64_t durationUs, threshold;
- if (msg->findInt64("durationUs", &durationUs)) {
+ if (msg->findInt64("durationUs", &durationUs) && durationUs > 0) {
return kNumSkipFrames * durationUs;
}
diff --git a/media/libstagefright/httplive/PlaylistFetcher.h b/media/libstagefright/httplive/PlaylistFetcher.h
index 78c358f..67161a9 100644
--- a/media/libstagefright/httplive/PlaylistFetcher.h
+++ b/media/libstagefright/httplive/PlaylistFetcher.h
@@ -34,6 +34,9 @@
struct String8;
struct PlaylistFetcher : public AHandler {
+ static const int64_t kMinBufferedDurationUs;
+ static const int32_t kDownloadBlockSize;
+
enum {
kWhatStarted,
kWhatPaused,
@@ -92,9 +95,7 @@
kWhatDownloadNext = 'dlnx',
};
- static const int64_t kMinBufferedDurationUs;
static const int64_t kMaxMonitorDelayUs;
- static const int32_t kDownloadBlockSize;
static const int32_t kNumSkipFrames;
static bool bufferStartsWithTsSyncByte(const sp<ABuffer>& buffer);
diff --git a/media/libstagefright/include/HTTPBase.h b/media/libstagefright/include/HTTPBase.h
index 1c3cd5e..0c66e27 100644
--- a/media/libstagefright/include/HTTPBase.h
+++ b/media/libstagefright/include/HTTPBase.h
@@ -48,6 +48,8 @@
virtual status_t setBandwidthStatCollectFreq(int32_t freqMs);
+ virtual void setBandwidthHistorySize(size_t numHistoryItems);
+
static void RegisterSocketUserTag(int sockfd, uid_t uid, uint32_t kTag);
static void UnRegisterSocketUserTag(int sockfd);
@@ -55,7 +57,7 @@
static void UnRegisterSocketUserMark(int sockfd);
protected:
- void addBandwidthMeasurement(size_t numBytes, int64_t delayUs);
+ virtual void addBandwidthMeasurement(size_t numBytes, int64_t delayUs);
private:
struct BandwidthEntry {
@@ -69,6 +71,7 @@
size_t mNumBandwidthHistoryItems;
int64_t mTotalTransferTimeUs;
size_t mTotalTransferBytes;
+ size_t mMaxBandwidthHistoryItems;
enum {
kMinBandwidthCollectFreqMs = 1000, // 1 second
diff --git a/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp b/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
index c579d4c..f266fe7 100644
--- a/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
+++ b/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
@@ -218,12 +218,19 @@
}
if (mLatestEnqueuedMeta == NULL) {
- mLatestEnqueuedMeta = buffer->meta();
+ mLatestEnqueuedMeta = buffer->meta()->dup();
} else {
int64_t latestTimeUs = 0;
+ int64_t frameDeltaUs = 0;
CHECK(mLatestEnqueuedMeta->findInt64("timeUs", &latestTimeUs));
if (lastQueuedTimeUs > latestTimeUs) {
- mLatestEnqueuedMeta = buffer->meta();
+ mLatestEnqueuedMeta = buffer->meta()->dup();
+ frameDeltaUs = lastQueuedTimeUs - latestTimeUs;
+ mLatestEnqueuedMeta->setInt64("durationUs", frameDeltaUs);
+ } else if (!mLatestEnqueuedMeta->findInt64("durationUs", &frameDeltaUs)) {
+ // For B frames
+ frameDeltaUs = latestTimeUs - lastQueuedTimeUs;
+ mLatestEnqueuedMeta->setInt64("durationUs", frameDeltaUs);
}
}
}
diff --git a/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp b/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp
index 532cf2f..4ce165b 100644
--- a/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp
+++ b/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp
@@ -149,7 +149,9 @@
// when output format changes, input buffer size does not actually change
if (updateInputSize) {
- inDef->nBufferSize = max(outDef->nBufferSize / mMinCompressionRatio, mMinInputBufferSize);
+ inDef->nBufferSize = max(
+ outDef->nBufferSize / mMinCompressionRatio,
+ max(mMinInputBufferSize, inDef->nBufferSize));
}
if (updateCrop) {
@@ -388,30 +390,21 @@
uint32_t newHeight = video_def->nFrameHeight;
if (newWidth != oldWidth || newHeight != oldHeight) {
bool outputPort = (newParams->nPortIndex == kOutputPortIndex);
- def->format.video.nFrameWidth =
- (mIsAdaptive && outputPort) ? mAdaptiveMaxWidth : newWidth;
- def->format.video.nFrameHeight =
- (mIsAdaptive && outputPort) ? mAdaptiveMaxHeight : newHeight;
if (outputPort) {
- def->format.video.nStride = def->format.video.nFrameWidth;
- def->format.video.nSliceHeight = def->format.video.nFrameHeight;
- def->nBufferSize =
- def->format.video.nStride * def->format.video.nSliceHeight * 3 / 2;
-
-
- OMX_PARAM_PORTDEFINITIONTYPE *inDef = &editPortInfo(kInputPortIndex)->mDef;
- // increase input buffer size if required
- inDef->nBufferSize =
- max(def->nBufferSize / mMinCompressionRatio, inDef->nBufferSize);
-
+ // only update (essentially crop) if size changes
mWidth = newWidth;
mHeight = newHeight;
- mCropLeft = 0;
- mCropTop = 0;
- mCropWidth = newWidth;
- mCropHeight = newHeight;
+
+ updatePortDefinitions(true /* updateCrop */, true /* updateInputSize */);
+ // reset buffer size based on frame size
+ newParams->nBufferSize = def->nBufferSize;
+ } else {
+ // For input port, we only set nFrameWidth and nFrameHeight. Buffer size
+ // is updated when configuring the output port using the max-frame-size,
+ // though client can still request a larger size.
+ def->format.video.nFrameWidth = newWidth;
+ def->format.video.nFrameHeight = newHeight;
}
- newParams->nBufferSize = def->nBufferSize;
}
return SimpleSoftOMXComponent::internalSetParameter(index, params);
}
diff --git a/services/audioflinger/Android.mk b/services/audioflinger/Android.mk
index 697fb37..f0196c6 100644
--- a/services/audioflinger/Android.mk
+++ b/services/audioflinger/Android.mk
@@ -19,7 +19,13 @@
# FIXME Move this library to frameworks/native
LOCAL_MODULE := libserviceutility
-include $(BUILD_STATIC_LIBRARY)
+LOCAL_SHARED_LIBRARIES := \
+ libcutils \
+ libutils \
+ liblog \
+ libbinder
+
+include $(BUILD_SHARED_LIBRARY)
include $(CLEAR_VARS)
@@ -51,13 +57,13 @@
libhardware \
libhardware_legacy \
libeffects \
- libpowermanager
+ libpowermanager \
+ libserviceutility
LOCAL_STATIC_LIBRARIES := \
libscheduling_policy \
libcpustats \
- libmedia_helper \
- libserviceutility
+ libmedia_helper
LOCAL_MODULE:= libaudioflinger
LOCAL_32_BIT_ONLY := true
diff --git a/services/audioflinger/PatchPanel.cpp b/services/audioflinger/PatchPanel.cpp
index 7544052..4f0c6b1 100644
--- a/services/audioflinger/PatchPanel.cpp
+++ b/services/audioflinger/PatchPanel.cpp
@@ -166,7 +166,9 @@
if (*handle == mPatches[index]->mHandle) {
ALOGV("createAudioPatch() removing patch handle %d", *handle);
halHandle = mPatches[index]->mHalHandle;
+ Patch *removedPatch = mPatches[index];
mPatches.removeAt(index);
+ delete removedPatch;
break;
}
}
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index dacb12c..9fccda1 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -4083,6 +4083,10 @@
track->mRetryCount = kMaxTrackRetriesDirect;
mActiveTrack = t;
mixerStatus = MIXER_TRACKS_READY;
+ if (usesHwAvSync() && mHwPaused) {
+ doHwResume = true;
+ mHwPaused = false;
+ }
}
} else {
// clear effect chain input buffer if the last active track started underruns
@@ -4111,9 +4115,6 @@
track->mState = TrackBase::STOPPED;
}
if (track->isStopped()) {
- if (track->mState == TrackBase::FLUSHED) {
- flushHw_l();
- }
track->reset();
}
tracksToRemove->add(track);
@@ -4130,6 +4131,10 @@
android_atomic_or(CBLK_DISABLED, &cblk->mFlags);
} else if (last) {
mixerStatus = MIXER_TRACKS_ENABLED;
+ if (usesHwAvSync() && !mHwPaused && !mStandby) {
+ doHwPause = true;
+ mHwPaused = true;
+ }
}
}
}
@@ -4192,7 +4197,7 @@
void AudioFlinger::DirectOutputThread::threadLoop_sleepTime()
{
// do not write to HAL when paused
- if (mHwPaused) {
+ if (mHwPaused || (usesHwAvSync() && mStandby)) {
sleepTime = idleSleepTime;
return;
}
@@ -4237,7 +4242,7 @@
trackPaused = mTracks[mTracks.size() - 1]->isPaused();
}
- return !mStandby && !trackPaused;
+ return !mStandby && !(trackPaused || (usesHwAvSync() && mHwPaused));
}
// getTrackName_l() must be called with ThreadBase::mLock held
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index f5d0e27..1088843 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -710,6 +710,9 @@
audio_patch_handle_t *handle);
virtual status_t releaseAudioPatch_l(const audio_patch_handle_t handle);
+ bool usesHwAvSync() const { return (mType == DIRECT) && (mOutput != NULL) &&
+ (mOutput->flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC); }
+
private:
friend class AudioFlinger; // for numerous
diff --git a/services/audiopolicy/Android.mk b/services/audiopolicy/Android.mk
index 6512c38..188fc89 100644
--- a/services/audiopolicy/Android.mk
+++ b/services/audiopolicy/Android.mk
@@ -30,7 +30,8 @@
libbinder \
libmedia \
libhardware \
- libhardware_legacy
+ libhardware_legacy \
+ libserviceutility
ifneq ($(USE_LEGACY_AUDIO_POLICY), 1)
LOCAL_SHARED_LIBRARIES += \
@@ -38,8 +39,7 @@
endif
LOCAL_STATIC_LIBRARIES := \
- libmedia_helper \
- libserviceutility
+ libmedia_helper
LOCAL_MODULE:= libaudiopolicyservice
diff --git a/services/audiopolicy/AudioPolicyEffects.cpp b/services/audiopolicy/AudioPolicyEffects.cpp
index 4fbe042..e6ace20 100644
--- a/services/audiopolicy/AudioPolicyEffects.cpp
+++ b/services/audiopolicy/AudioPolicyEffects.cpp
@@ -658,6 +658,10 @@
loadInputEffectConfigurations(root, effects);
loadStreamEffectConfigurations(root, effects);
+ for (size_t i = 0; i < effects.size(); i++) {
+ delete effects[i];
+ }
+
config_free(root);
free(root);
free(data);
diff --git a/services/audiopolicy/AudioPolicyInterfaceImplLegacy.cpp b/services/audiopolicy/AudioPolicyInterfaceImplLegacy.cpp
index 4bc3c7f..b8846c6 100644
--- a/services/audiopolicy/AudioPolicyInterfaceImplLegacy.cpp
+++ b/services/audiopolicy/AudioPolicyInterfaceImplLegacy.cpp
@@ -241,14 +241,21 @@
if (mpAudioPolicy == NULL) {
return NO_INIT;
}
+
+ audio_source_t inputSource = attr->source;
+
// already checked by client, but double-check in case the client wrapper is bypassed
- if (attr->source >= AUDIO_SOURCE_CNT && attr->source != AUDIO_SOURCE_HOTWORD &&
- attr->source != AUDIO_SOURCE_FM_TUNER) {
+ if (inputSource >= AUDIO_SOURCE_CNT && inputSource != AUDIO_SOURCE_HOTWORD &&
+ inputSource != AUDIO_SOURCE_FM_TUNER) {
return BAD_VALUE;
}
- if (((attr->source == AUDIO_SOURCE_HOTWORD) && !captureHotwordAllowed()) ||
- ((attr->source == AUDIO_SOURCE_FM_TUNER) && !captureFmTunerAllowed())) {
+ if (inputSource == AUDIO_SOURCE_DEFAULT) {
+ inputSource = AUDIO_SOURCE_MIC;
+ }
+
+ if (((inputSource == AUDIO_SOURCE_HOTWORD) && !captureHotwordAllowed()) ||
+ ((inputSource == AUDIO_SOURCE_FM_TUNER) && !captureFmTunerAllowed())) {
return BAD_VALUE;
}
@@ -256,7 +263,7 @@
{
Mutex::Autolock _l(mLock);
// the audio_in_acoustics_t parameter is ignored by get_input()
- *input = mpAudioPolicy->get_input(mpAudioPolicy, attr->source, samplingRate,
+ *input = mpAudioPolicy->get_input(mpAudioPolicy, inputSource, samplingRate,
format, channelMask, (audio_in_acoustics_t) 0);
audioPolicyEffects = mAudioPolicyEffects;
}
@@ -266,7 +273,7 @@
if (audioPolicyEffects != 0) {
// create audio pre processors according to input source
- status_t status = audioPolicyEffects->addInputEffects(*input, attr->source, session);
+ status_t status = audioPolicyEffects->addInputEffects(*input, inputSource, session);
if (status != NO_ERROR && status != ALREADY_EXISTS) {
ALOGW("Failed to add effects on input %d", input);
}
diff --git a/services/audiopolicy/AudioPolicyManager.cpp b/services/audiopolicy/AudioPolicyManager.cpp
index a3389e0..0349327 100644
--- a/services/audiopolicy/AudioPolicyManager.cpp
+++ b/services/audiopolicy/AudioPolicyManager.cpp
@@ -596,6 +596,9 @@
}
handleIncallSonification((audio_stream_type_t)stream, false, true);
}
+
+ // force reevaluating accessibility routing when call starts
+ mpClientInterface->invalidateStream(AUDIO_STREAM_ACCESSIBILITY);
}
// store previous phone state for management of sonification strategy below
@@ -1290,6 +1293,11 @@
outputDesc->mPolicyMix->mRegistrationId);
}
+ // force reevaluating accessibility routing when ringtone or alarm starts
+ if (strategy == STRATEGY_SONIFICATION) {
+ mpClientInterface->invalidateStream(AUDIO_STREAM_ACCESSIBILITY);
+ }
+
if (waitMs > muteWaitMs) {
usleep((waitMs - muteWaitMs) * 2 * 1000);
}
@@ -1432,10 +1440,16 @@
// handle legacy remote submix case where the address was not always specified
String8 address = String8("");
bool isSoundTrigger = false;
- audio_source_t halInputSource = attr->source;
+ audio_source_t inputSource = attr->source;
+ audio_source_t halInputSource;
AudioMix *policyMix = NULL;
- if (attr->source == AUDIO_SOURCE_REMOTE_SUBMIX &&
+ if (inputSource == AUDIO_SOURCE_DEFAULT) {
+ inputSource = AUDIO_SOURCE_MIC;
+ }
+ halInputSource = inputSource;
+
+ if (inputSource == AUDIO_SOURCE_REMOTE_SUBMIX &&
strncmp(attr->tags, "addr=", strlen("addr=")) == 0) {
device = AUDIO_DEVICE_IN_REMOTE_SUBMIX;
address = String8(attr->tags + strlen("addr="));
@@ -1451,9 +1465,9 @@
policyMix = &mPolicyMixes[index]->mMix;
*inputType = API_INPUT_MIX_EXT_POLICY_REROUTE;
} else {
- device = getDeviceAndMixForInputSource(attr->source, &policyMix);
+ device = getDeviceAndMixForInputSource(inputSource, &policyMix);
if (device == AUDIO_DEVICE_NONE) {
- ALOGW("getInputForAttr() could not find device for source %d", attr->source);
+ ALOGW("getInputForAttr() could not find device for source %d", inputSource);
return BAD_VALUE;
}
if (policyMix != NULL) {
@@ -1475,7 +1489,7 @@
*inputType = API_INPUT_LEGACY;
}
// adapt channel selection to input source
- switch (attr->source) {
+ switch (inputSource) {
case AUDIO_SOURCE_VOICE_UPLINK:
channelMask = AUDIO_CHANNEL_IN_VOICE_UPLINK;
break;
@@ -1488,7 +1502,7 @@
default:
break;
}
- if (attr->source == AUDIO_SOURCE_HOTWORD) {
+ if (inputSource == AUDIO_SOURCE_HOTWORD) {
ssize_t index = mSoundTriggerSessions.indexOfKey(session);
if (index >= 0) {
*input = mSoundTriggerSessions.valueFor(session);
@@ -1551,7 +1565,7 @@
}
sp<AudioInputDescriptor> inputDesc = new AudioInputDescriptor(profile);
- inputDesc->mInputSource = attr->source;
+ inputDesc->mInputSource = inputSource;
inputDesc->mRefCount = 0;
inputDesc->mOpenRefCount = 1;
inputDesc->mSamplingRate = samplingRate;
@@ -2047,12 +2061,23 @@
{
for (size_t i = 0; i < mInputs.size(); i++) {
const sp<AudioInputDescriptor> inputDescriptor = mInputs.valueAt(i);
- if ((inputDescriptor->mInputSource == (int)source ||
- (source == AUDIO_SOURCE_VOICE_RECOGNITION &&
- inputDescriptor->mInputSource == AUDIO_SOURCE_HOTWORD))
- && (inputDescriptor->mRefCount > 0)) {
+ if (inputDescriptor->mRefCount == 0) {
+ continue;
+ }
+ if (inputDescriptor->mInputSource == (int)source) {
return true;
}
+ // AUDIO_SOURCE_HOTWORD is equivalent to AUDIO_SOURCE_VOICE_RECOGNITION only if it
+ // corresponds to an active capture triggered by a hardware hotword recognition
+ if ((source == AUDIO_SOURCE_VOICE_RECOGNITION) &&
+ (inputDescriptor->mInputSource == AUDIO_SOURCE_HOTWORD)) {
+ // FIXME: we should not assume that the first session is the active one and keep
+ // activity count per session. Same in startInput().
+ ssize_t index = mSoundTriggerSessions.indexOfKey(inputDescriptor->mSessions.itemAt(0));
+ if (index >= 0) {
+ return true;
+ }
+ }
}
return false;
}
@@ -3423,29 +3448,15 @@
}
void AudioPolicyManager::findIoHandlesByAddress(sp<AudioOutputDescriptor> desc /*in*/,
+ const audio_devices_t device /*in*/,
const String8 address /*in*/,
SortedVector<audio_io_handle_t>& outputs /*out*/) {
- // look for a match on the given address on the addresses of the outputs:
- // find the address by finding the patch that maps to this output
- ssize_t patchIdx = mAudioPatches.indexOfKey(desc->mPatchHandle);
- //ALOGV(" inspecting output %d (patch %d) for supported device=0x%x",
- // outputIdx, patchIdx, desc->mProfile->mSupportedDevices.types());
- if (patchIdx >= 0) {
- const sp<AudioPatch> patchDesc = mAudioPatches.valueAt(patchIdx);
- const int numSinks = patchDesc->mPatch.num_sinks;
- for (ssize_t j=0; j < numSinks; j++) {
- if (patchDesc->mPatch.sinks[j].type == AUDIO_PORT_TYPE_DEVICE) {
- const char* patchAddr =
- patchDesc->mPatch.sinks[j].ext.device.address;
- if (strncmp(patchAddr,
- address.string(), AUDIO_DEVICE_MAX_ADDRESS_LEN) == 0) {
- ALOGV("findIoHandlesByAddress(): adding opened output %d on same address %s",
- desc->mIoHandle, patchDesc->mPatch.sinks[j].ext.device.address);
- outputs.add(desc->mIoHandle);
- break;
- }
- }
- }
+ sp<DeviceDescriptor> devDesc =
+ desc->mProfile->mSupportedDevices.getDevice(device, address);
+ if (devDesc != 0) {
+ ALOGV("findIoHandlesByAddress(): adding opened output %d on same address %s",
+ desc->mIoHandle, address.string());
+ outputs.add(desc->mIoHandle);
}
}
@@ -3469,7 +3480,7 @@
outputs.add(mOutputs.keyAt(i));
} else {
ALOGV(" checking address match due to device 0x%x", device);
- findIoHandlesByAddress(desc, address, outputs);
+ findIoHandlesByAddress(desc, device, address, outputs);
}
}
}
@@ -3697,7 +3708,7 @@
// exact match on device
if (deviceDistinguishesOnAddress(device) &&
(desc->mProfile->mSupportedDevices.types() == device)) {
- findIoHandlesByAddress(desc, address, outputs);
+ findIoHandlesByAddress(desc, device, address, outputs);
} else if (!(desc->mProfile->mSupportedDevices.types()
& mAvailableOutputDevices.types())) {
ALOGV("checkOutputsForDevice(): disconnecting adding output %d",
@@ -5288,7 +5299,7 @@
for (size_t i = 0; i < mInputs.size(); i++) {
const sp<AudioInputDescriptor> desc = mInputs.valueAt(i);
if (desc->mRefCount > 0) {
- return count++;
+ count++;
}
}
return count;
diff --git a/services/audiopolicy/AudioPolicyManager.h b/services/audiopolicy/AudioPolicyManager.h
index 2059f58..0fa182b 100644
--- a/services/audiopolicy/AudioPolicyManager.h
+++ b/services/audiopolicy/AudioPolicyManager.h
@@ -594,7 +594,7 @@
// change the route of the specified output. Returns the number of ms we have slept to
// allow new routing to take effect in certain cases.
- uint32_t setOutputDevice(audio_io_handle_t output,
+ virtual uint32_t setOutputDevice(audio_io_handle_t output,
audio_devices_t device,
bool force = false,
int delayMs = 0,
@@ -877,11 +877,13 @@
#endif //AUDIO_POLICY_TEST
static float volIndexToAmpl(audio_devices_t device, const StreamDescriptor& streamDesc,
int indexInUi);
+ static bool isVirtualInputDevice(audio_devices_t device);
+ uint32_t nextUniqueId();
+ uint32_t nextAudioPortGeneration();
private:
// updates device caching and output for streams that can influence the
// routing of notifications
void handleNotificationRoutingForStream(audio_stream_type_t stream);
- static bool isVirtualInputDevice(audio_devices_t device);
static bool deviceDistinguishesOnAddress(audio_devices_t device);
// find the outputs on a given output descriptor that have the given address.
// to be called on an AudioOutputDescriptor whose supported devices (as defined
@@ -889,10 +891,9 @@
// see deviceDistinguishesOnAddress(audio_devices_t) for whether the device type is one
// where addresses are used to distinguish between one connected device and another.
void findIoHandlesByAddress(sp<AudioOutputDescriptor> desc /*in*/,
+ const audio_devices_t device /*in*/,
const String8 address /*in*/,
SortedVector<audio_io_handle_t>& outputs /*out*/);
- uint32_t nextUniqueId();
- uint32_t nextAudioPortGeneration();
uint32_t curAudioPortGeneration() const { return mAudioPortGeneration; }
// internal method to return the output handle for the given device and format
audio_io_handle_t getOutputForDevice(
diff --git a/services/soundtrigger/Android.mk b/services/soundtrigger/Android.mk
index 572ae56..ecc49ae 100644
--- a/services/soundtrigger/Android.mk
+++ b/services/soundtrigger/Android.mk
@@ -32,9 +32,7 @@
libcutils \
libhardware \
libsoundtrigger \
- libmedia
-
-LOCAL_STATIC_LIBRARIES := \
+ libmedia \
libserviceutility
LOCAL_C_INCLUDES += \