Merge "EffectProxy: Check offload reply size"
diff --git a/cmds/stagefright/Android.mk b/cmds/stagefright/Android.mk
index 40726a3..b28d509 100644
--- a/cmds/stagefright/Android.mk
+++ b/cmds/stagefright/Android.mk
@@ -129,7 +129,7 @@
LOCAL_SHARED_LIBRARIES := \
libstagefright liblog libutils libbinder libstagefright_foundation \
- libmedia libgui libcutils libui
+ libmedia libgui libcutils
LOCAL_C_INCLUDES:= \
frameworks/av/media/libstagefright \
@@ -153,7 +153,7 @@
LOCAL_SHARED_LIBRARIES := \
libstagefright liblog libutils libbinder libstagefright_foundation \
- libmedia libgui libcutils libui
+ libmedia libaudioclient libgui libcutils
LOCAL_C_INCLUDES:= \
frameworks/av/media/libstagefright \
@@ -186,7 +186,6 @@
libmedia \
libgui \
libcutils \
- libui \
libRScpp \
LOCAL_C_INCLUDES:= \
@@ -218,7 +217,7 @@
LOCAL_SHARED_LIBRARIES := \
libstagefright liblog libutils libbinder libstagefright_foundation \
- libmedia libgui libcutils libui libc
+ libcutils libc
LOCAL_C_INCLUDES:= \
frameworks/av/media/libstagefright \
diff --git a/include/media/IMediaPlayer.h b/include/media/IMediaPlayer.h
index 0fd8933..661eaa2 100644
--- a/include/media/IMediaPlayer.h
+++ b/include/media/IMediaPlayer.h
@@ -65,7 +65,7 @@
virtual status_t setSyncSettings(const AVSyncSettings& sync, float videoFpsHint) = 0;
virtual status_t getSyncSettings(AVSyncSettings* sync /* nonnull */,
float* videoFps /* nonnull */) = 0;
- virtual status_t seekTo(int msec) = 0;
+ virtual status_t seekTo(int msec, bool precise = false) = 0;
virtual status_t getCurrentPosition(int* msec) = 0;
virtual status_t getDuration(int* msec) = 0;
virtual status_t reset() = 0;
diff --git a/include/media/MediaPlayerInterface.h b/include/media/MediaPlayerInterface.h
index 4977efd..b488159 100644
--- a/include/media/MediaPlayerInterface.h
+++ b/include/media/MediaPlayerInterface.h
@@ -205,7 +205,7 @@
*videoFps = -1.f;
return OK;
}
- virtual status_t seekTo(int msec) = 0;
+ virtual status_t seekTo(int msec, bool precise = false) = 0;
virtual status_t getCurrentPosition(int *msec) = 0;
virtual status_t getDuration(int *msec) = 0;
virtual status_t reset() = 0;
diff --git a/include/media/mediaplayer.h b/include/media/mediaplayer.h
index 389ec01..c556f0a 100644
--- a/include/media/mediaplayer.h
+++ b/include/media/mediaplayer.h
@@ -233,7 +233,7 @@
float* videoFps /* nonnull */);
status_t getVideoWidth(int *w);
status_t getVideoHeight(int *h);
- status_t seekTo(int msec);
+ status_t seekTo(int msec, bool precise = false);
status_t getCurrentPosition(int *msec);
status_t getDuration(int *msec);
status_t reset();
@@ -257,7 +257,7 @@
private:
void clear_l();
- status_t seekTo_l(int msec);
+ status_t seekTo_l(int msec, bool precise);
status_t prepareAsync_l();
status_t getDuration_l(int *msec);
status_t attachNewPlayer(const sp<IMediaPlayer>& player);
@@ -274,7 +274,9 @@
void* mCookie;
media_player_states mCurrentState;
int mCurrentPosition;
+ bool mCurrentSeekPrecise;
int mSeekPosition;
+ int mSeekPrecise;
bool mPrepareSync;
status_t mPrepareStatus;
audio_stream_type_t mStreamType;
diff --git a/include/media/stagefright/AudioSource.h b/include/media/stagefright/AudioSource.h
index 2ec89a4..f20c2cd 100644
--- a/include/media/stagefright/AudioSource.h
+++ b/include/media/stagefright/AudioSource.h
@@ -89,6 +89,8 @@
int64_t mPrevSampleTimeUs;
int64_t mInitialReadTimeUs;
int64_t mNumFramesReceived;
+ int64_t mNumFramesSkipped;
+ int64_t mNumFramesLost;
int64_t mNumClientOwnedBuffers;
List<MediaBuffer * > mBuffersReceived;
diff --git a/media/audioserver/Android.mk b/media/audioserver/Android.mk
index 91cc902..c620e7c 100644
--- a/media/audioserver/Android.mk
+++ b/media/audioserver/Android.mk
@@ -11,7 +11,6 @@
libbinder \
libcutils \
liblog \
- libmedia \
libmedialogservice \
libradioservice \
libsoundtriggerservice \
diff --git a/media/libaudioclient/Android.mk b/media/libaudioclient/Android.mk
new file mode 100644
index 0000000..348ab50
--- /dev/null
+++ b/media/libaudioclient/Android.mk
@@ -0,0 +1,50 @@
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES += \
+ AudioEffect.cpp \
+ AudioPolicy.cpp \
+ AudioRecord.cpp \
+ AudioSystem.cpp \
+ AudioTrack.cpp \
+ AudioTrackShared.cpp \
+ IAudioFlinger.cpp \
+ IAudioFlingerClient.cpp \
+ IAudioPolicyService.cpp \
+ IAudioPolicyServiceClient.cpp \
+ IAudioRecord.cpp \
+ IAudioTrack.cpp \
+ IEffect.cpp \
+ IEffectClient.cpp \
+ ToneGenerator.cpp \
+
+LOCAL_SHARED_LIBRARIES := \
+ liblog libcutils libutils libbinder \
+ libdl libaudioutils \
+
+LOCAL_EXPORT_SHARED_LIBRARY_HEADERS := libbinder
+
+# for memory heap analysis
+LOCAL_STATIC_LIBRARIES := libc_malloc_debug_backtrace libc_logging
+
+LOCAL_MODULE:= libaudioclient
+
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
+
+LOCAL_C_INCLUDES := \
+ $(TOP)/frameworks/native/include/media/openmax \
+ $(TOP)/frameworks/av/include/media/ \
+ $(TOP)/frameworks/av/media/libstagefright \
+ $(TOP)/frameworks/av/media/libmedia/aidl \
+ $(call include-path-for, audio-utils)
+
+LOCAL_EXPORT_C_INCLUDE_DIRS := \
+ frameworks/av/include/media \
+ frameworks/av/media/libmedia/aidl
+
+LOCAL_CFLAGS += -Werror -Wno-error=deprecated-declarations -Wall
+LOCAL_SANITIZE := unsigned-integer-overflow signed-integer-overflow
+
+include $(BUILD_SHARED_LIBRARY)
+
diff --git a/media/libmedia/AudioEffect.cpp b/media/libaudioclient/AudioEffect.cpp
similarity index 100%
rename from media/libmedia/AudioEffect.cpp
rename to media/libaudioclient/AudioEffect.cpp
diff --git a/media/libmedia/AudioPolicy.cpp b/media/libaudioclient/AudioPolicy.cpp
similarity index 100%
rename from media/libmedia/AudioPolicy.cpp
rename to media/libaudioclient/AudioPolicy.cpp
diff --git a/media/libmedia/AudioRecord.cpp b/media/libaudioclient/AudioRecord.cpp
similarity index 100%
rename from media/libmedia/AudioRecord.cpp
rename to media/libaudioclient/AudioRecord.cpp
diff --git a/media/libmedia/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
similarity index 100%
rename from media/libmedia/AudioSystem.cpp
rename to media/libaudioclient/AudioSystem.cpp
diff --git a/media/libmedia/AudioTrack.cpp b/media/libaudioclient/AudioTrack.cpp
similarity index 100%
rename from media/libmedia/AudioTrack.cpp
rename to media/libaudioclient/AudioTrack.cpp
diff --git a/media/libmedia/AudioTrackShared.cpp b/media/libaudioclient/AudioTrackShared.cpp
similarity index 100%
rename from media/libmedia/AudioTrackShared.cpp
rename to media/libaudioclient/AudioTrackShared.cpp
diff --git a/media/libmedia/IAudioFlinger.cpp b/media/libaudioclient/IAudioFlinger.cpp
similarity index 100%
rename from media/libmedia/IAudioFlinger.cpp
rename to media/libaudioclient/IAudioFlinger.cpp
diff --git a/media/libmedia/IAudioFlingerClient.cpp b/media/libaudioclient/IAudioFlingerClient.cpp
similarity index 100%
rename from media/libmedia/IAudioFlingerClient.cpp
rename to media/libaudioclient/IAudioFlingerClient.cpp
diff --git a/media/libmedia/IAudioPolicyService.cpp b/media/libaudioclient/IAudioPolicyService.cpp
similarity index 100%
rename from media/libmedia/IAudioPolicyService.cpp
rename to media/libaudioclient/IAudioPolicyService.cpp
diff --git a/media/libmedia/IAudioPolicyServiceClient.cpp b/media/libaudioclient/IAudioPolicyServiceClient.cpp
similarity index 100%
rename from media/libmedia/IAudioPolicyServiceClient.cpp
rename to media/libaudioclient/IAudioPolicyServiceClient.cpp
diff --git a/media/libmedia/IAudioRecord.cpp b/media/libaudioclient/IAudioRecord.cpp
similarity index 100%
rename from media/libmedia/IAudioRecord.cpp
rename to media/libaudioclient/IAudioRecord.cpp
diff --git a/media/libmedia/IAudioTrack.cpp b/media/libaudioclient/IAudioTrack.cpp
similarity index 100%
rename from media/libmedia/IAudioTrack.cpp
rename to media/libaudioclient/IAudioTrack.cpp
diff --git a/media/libmedia/IEffect.cpp b/media/libaudioclient/IEffect.cpp
similarity index 100%
rename from media/libmedia/IEffect.cpp
rename to media/libaudioclient/IEffect.cpp
diff --git a/media/libmedia/IEffectClient.cpp b/media/libaudioclient/IEffectClient.cpp
similarity index 100%
rename from media/libmedia/IEffectClient.cpp
rename to media/libaudioclient/IEffectClient.cpp
diff --git a/media/libmedia/ToneGenerator.cpp b/media/libaudioclient/ToneGenerator.cpp
similarity index 100%
rename from media/libmedia/ToneGenerator.cpp
rename to media/libaudioclient/ToneGenerator.cpp
diff --git a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
index 8aed146..2dfdfde 100644
--- a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
+++ b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
@@ -2349,8 +2349,12 @@
case EQ_PARAM_BAND_LEVEL:
param2 = *pParamTemp;
- if (param2 >= FIVEBAND_NUMBANDS) {
+ if (param2 < 0 || param2 >= FIVEBAND_NUMBANDS) {
status = -EINVAL;
+ if (param2 < 0) {
+ android_errorWriteLog(0x534e4554, "32438598");
+ ALOGW("\tERROR Equalizer_getParameter() EQ_PARAM_BAND_LEVEL band %d", param2);
+ }
break;
}
*(int16_t *)pValue = (int16_t)EqualizerGetBandLevel(pContext, param2);
@@ -2360,8 +2364,12 @@
case EQ_PARAM_CENTER_FREQ:
param2 = *pParamTemp;
- if (param2 >= FIVEBAND_NUMBANDS) {
+ if (param2 < 0 || param2 >= FIVEBAND_NUMBANDS) {
status = -EINVAL;
+ if (param2 < 0) {
+ android_errorWriteLog(0x534e4554, "32436341");
+ ALOGW("\tERROR Equalizer_getParameter() EQ_PARAM_CENTER_FREQ band %d", param2);
+ }
break;
}
*(int32_t *)pValue = EqualizerGetCentreFrequency(pContext, param2);
@@ -2371,8 +2379,12 @@
case EQ_PARAM_BAND_FREQ_RANGE:
param2 = *pParamTemp;
- if (param2 >= FIVEBAND_NUMBANDS) {
+ if (param2 < 0 || param2 >= FIVEBAND_NUMBANDS) {
status = -EINVAL;
+ if (param2 < 0) {
+ android_errorWriteLog(0x534e4554, "32247948");
+ ALOGW("\tERROR Equalizer_getParameter() EQ_PARAM_BAND_FREQ_RANGE band %d", param2);
+ }
break;
}
EqualizerGetBandFreqRange(pContext, param2, (uint32_t *)pValue, ((uint32_t *)pValue + 1));
diff --git a/media/libmedia/Android.mk b/media/libmedia/Android.mk
index ba31cfa..41e4792 100644
--- a/media/libmedia/Android.mk
+++ b/media/libmedia/Android.mk
@@ -10,26 +10,17 @@
aidl/android/IOMXBufferSource.aidl
LOCAL_SRC_FILES += \
- AudioTrack.cpp \
- AudioTrackShared.cpp \
- IAudioFlinger.cpp \
- IAudioFlingerClient.cpp \
- IAudioTrack.cpp \
- IAudioRecord.cpp \
ICrypto.cpp \
IDataSource.cpp \
IDrm.cpp \
IDrmClient.cpp \
IHDCP.cpp \
- AudioRecord.cpp \
- AudioSystem.cpp \
mediaplayer.cpp \
IMediaCodecList.cpp \
IMediaCodecService.cpp \
IMediaDrmService.cpp \
IMediaHTTPConnection.cpp \
IMediaHTTPService.cpp \
- IMediaLogService.cpp \
IMediaExtractor.cpp \
IMediaExtractorService.cpp \
IMediaPlayerService.cpp \
@@ -53,11 +44,8 @@
mediametadataretriever.cpp \
MidiDeviceInfo.cpp \
MidiIoWrapper.cpp \
- ToneGenerator.cpp \
JetPlayer.cpp \
IOMX.cpp \
- IAudioPolicyService.cpp \
- IAudioPolicyServiceClient.cpp \
MediaScanner.cpp \
MediaScannerClient.cpp \
CharacterEncodingDetector.cpp \
@@ -66,18 +54,13 @@
MediaResource.cpp \
MediaResourcePolicy.cpp \
OMXBuffer.cpp \
- IEffect.cpp \
- IEffectClient.cpp \
- AudioEffect.cpp \
Visualizer.cpp \
- MemoryLeakTrackUtil.cpp \
StringArray.cpp \
- AudioPolicy.cpp
LOCAL_SHARED_LIBRARIES := \
libui liblog libcutils libutils libbinder libsonivox libicuuc libicui18n libexpat \
libcamera_client libstagefright_foundation \
- libgui libdl libaudioutils
+ libgui libdl libaudioutils libaudioclient
LOCAL_EXPORT_SHARED_LIBRARY_HEADERS := libbinder
diff --git a/media/libmedia/IMediaPlayer.cpp b/media/libmedia/IMediaPlayer.cpp
index f8345e4..41b6988 100644
--- a/media/libmedia/IMediaPlayer.cpp
+++ b/media/libmedia/IMediaPlayer.cpp
@@ -246,11 +246,12 @@
return reply.readInt32();
}
- status_t seekTo(int msec)
+ status_t seekTo(int msec, bool precise)
{
Parcel data, reply;
data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
data.writeInt32(msec);
+ data.writeBool(precise);
remote()->transact(SEEK_TO, data, &reply);
return reply.readInt32();
}
@@ -573,7 +574,9 @@
} break;
case SEEK_TO: {
CHECK_INTERFACE(IMediaPlayer, data, reply);
- reply->writeInt32(seekTo(data.readInt32()));
+ int msec = data.readInt32();
+ bool precise = data.readBool();
+ reply->writeInt32(seekTo(msec, precise));
return NO_ERROR;
} break;
case GET_CURRENT_POSITION: {
diff --git a/media/libmedia/mediaplayer.cpp b/media/libmedia/mediaplayer.cpp
index fbe749c..846a24c 100644
--- a/media/libmedia/mediaplayer.cpp
+++ b/media/libmedia/mediaplayer.cpp
@@ -55,7 +55,9 @@
mStreamType = AUDIO_STREAM_MUSIC;
mAudioAttributesParcel = NULL;
mCurrentPosition = -1;
+ mCurrentSeekPrecise = false;
mSeekPosition = -1;
+ mSeekPrecise = false;
mCurrentState = MEDIA_PLAYER_IDLE;
mPrepareSync = false;
mPrepareStatus = NO_ERROR;
@@ -100,7 +102,9 @@
void MediaPlayer::clear_l()
{
mCurrentPosition = -1;
+ mCurrentSeekPrecise = false;
mSeekPosition = -1;
+ mSeekPrecise = false;
mVideoWidth = mVideoHeight = 0;
mRetransmitEndpointValid = false;
}
@@ -508,9 +512,9 @@
return getDuration_l(msec);
}
-status_t MediaPlayer::seekTo_l(int msec)
+status_t MediaPlayer::seekTo_l(int msec, bool precise)
{
- ALOGV("seekTo %d", msec);
+ ALOGV("seekTo (%d, %d)", msec, precise);
if ((mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER_STARTED | MEDIA_PLAYER_PREPARED |
MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_PLAYBACK_COMPLETE) ) ) {
if ( msec < 0 ) {
@@ -537,12 +541,14 @@
// cache duration
mCurrentPosition = msec;
+ mCurrentSeekPrecise = precise;
if (mSeekPosition < 0) {
mSeekPosition = msec;
- return mPlayer->seekTo(msec);
+ mSeekPrecise = precise;
+ return mPlayer->seekTo(msec, precise);
}
else {
- ALOGV("Seek in progress - queue up seekTo[%d]", msec);
+ ALOGV("Seek in progress - queue up seekTo[%d, %d]", msec, precise);
return NO_ERROR;
}
}
@@ -551,11 +557,11 @@
return INVALID_OPERATION;
}
-status_t MediaPlayer::seekTo(int msec)
+status_t MediaPlayer::seekTo(int msec, bool precise)
{
mLockThreadId = getThreadId();
Mutex::Autolock _l(mLock);
- status_t result = seekTo_l(msec);
+ status_t result = seekTo_l(msec, precise);
mLockThreadId = 0;
return result;
@@ -869,14 +875,16 @@
break;
case MEDIA_SEEK_COMPLETE:
ALOGV("Received seek complete");
- if (mSeekPosition != mCurrentPosition) {
- ALOGV("Executing queued seekTo(%d)", mSeekPosition);
+ if (mSeekPosition != mCurrentPosition || (!mSeekPrecise && mCurrentSeekPrecise)) {
+ ALOGV("Executing queued seekTo(%d, %d)", mCurrentPosition, mCurrentSeekPrecise);
mSeekPosition = -1;
- seekTo_l(mCurrentPosition);
+ mSeekPrecise = false;
+ seekTo_l(mCurrentPosition, mCurrentSeekPrecise);
}
else {
ALOGV("All seeks complete - return to regularly scheduled program");
mCurrentPosition = mSeekPosition = -1;
+ mCurrentSeekPrecise = mSeekPrecise = false;
}
break;
case MEDIA_BUFFERING_UPDATE:
diff --git a/media/libmediaplayerservice/Android.mk b/media/libmediaplayerservice/Android.mk
index 97e7404..1786e6b 100644
--- a/media/libmediaplayerservice/Android.mk
+++ b/media/libmediaplayerservice/Android.mk
@@ -26,6 +26,7 @@
libdl \
libgui \
libmedia \
+ libaudioclient \
libmediautils \
libmemunreachable \
libstagefright \
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index f619e1d..3ff9d98 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -1121,12 +1121,12 @@
return OK;
}
-status_t MediaPlayerService::Client::seekTo(int msec)
+status_t MediaPlayerService::Client::seekTo(int msec, bool precise)
{
ALOGV("[%d] seekTo(%d)", mConnId, msec);
sp<MediaPlayerBase> p = getPlayer();
if (p == 0) return UNKNOWN_ERROR;
- return p->seekTo(msec);
+ return p->seekTo(msec, precise);
}
status_t MediaPlayerService::Client::reset()
diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h
index 601b046..ef82b48 100644
--- a/media/libmediaplayerservice/MediaPlayerService.h
+++ b/media/libmediaplayerservice/MediaPlayerService.h
@@ -298,7 +298,7 @@
virtual status_t setSyncSettings(const AVSyncSettings& rate, float videoFpsHint);
virtual status_t getSyncSettings(AVSyncSettings* rate /* nonnull */,
float* videoFps /* nonnull */);
- virtual status_t seekTo(int msec);
+ virtual status_t seekTo(int msec, bool precise = false);
virtual status_t getCurrentPosition(int* msec);
virtual status_t getDuration(int* msec);
virtual status_t reset();
diff --git a/media/libmediaplayerservice/TestPlayerStub.h b/media/libmediaplayerservice/TestPlayerStub.h
index 55bf2c8..c0d6a59 100644
--- a/media/libmediaplayerservice/TestPlayerStub.h
+++ b/media/libmediaplayerservice/TestPlayerStub.h
@@ -87,7 +87,7 @@
virtual status_t stop() {return mPlayer->stop();}
virtual status_t pause() {return mPlayer->pause();}
virtual bool isPlaying() {return mPlayer->isPlaying();}
- virtual status_t seekTo(int msec) {return mPlayer->seekTo(msec);}
+ virtual status_t seekTo(int msec, bool precise = false) {return mPlayer->seekTo(msec, precise);}
virtual status_t getCurrentPosition(int *p) {
return mPlayer->getCurrentPosition(p);
}
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
index 4554472..c0a5682 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
@@ -665,8 +665,8 @@
} else {
timeUs = mVideoLastDequeueTimeUs;
}
- readBuffer(trackType, timeUs, &actualTimeUs, formatChange);
- readBuffer(counterpartType, -1, NULL, !formatChange);
+ readBuffer(trackType, timeUs, false /* precise */, &actualTimeUs, formatChange);
+ readBuffer(counterpartType, -1, false /* precise */, NULL, !formatChange);
ALOGV("timeUs %lld actualTimeUs %lld", (long long)timeUs, (long long)actualTimeUs);
break;
@@ -759,7 +759,7 @@
CHECK(msg->findInt64("timeUs", &timeUs));
int64_t subTimeUs;
- readBuffer(type, timeUs, &subTimeUs);
+ readBuffer(type, timeUs, false /* precise */, &subTimeUs);
int64_t delayUs = subTimeUs - timeUs;
if (msg->what() == kWhatFetchSubtitleData) {
@@ -790,7 +790,7 @@
}
int64_t nextSubTimeUs;
- readBuffer(type, -1, &nextSubTimeUs);
+ readBuffer(type, -1, false /* precise */, &nextSubTimeUs);
sp<ABuffer> buffer;
status_t dequeueStatus = packets->dequeueAccessUnit(&buffer);
@@ -1186,9 +1186,10 @@
return INVALID_OPERATION;
}
-status_t NuPlayer::GenericSource::seekTo(int64_t seekTimeUs) {
+status_t NuPlayer::GenericSource::seekTo(int64_t seekTimeUs, bool precise) {
sp<AMessage> msg = new AMessage(kWhatSeek, this);
msg->setInt64("seekTimeUs", seekTimeUs);
+ msg->setInt32("precise", precise);
sp<AMessage> response;
status_t err = msg->postAndAwaitResponse(&response);
@@ -1201,10 +1202,12 @@
void NuPlayer::GenericSource::onSeek(const sp<AMessage>& msg) {
int64_t seekTimeUs;
+ int32_t precise;
CHECK(msg->findInt64("seekTimeUs", &seekTimeUs));
+ CHECK(msg->findInt32("precise", &precise));
sp<AMessage> response = new AMessage;
- status_t err = doSeek(seekTimeUs);
+ status_t err = doSeek(seekTimeUs, precise);
response->setInt32("err", err);
sp<AReplyToken> replyID;
@@ -1212,7 +1215,7 @@
response->postReply(replyID);
}
-status_t NuPlayer::GenericSource::doSeek(int64_t seekTimeUs) {
+status_t NuPlayer::GenericSource::doSeek(int64_t seekTimeUs, bool precise) {
mBufferingMonitor->updateDequeuedBufferTime(-1ll);
// If the Widevine source is stopped, do not attempt to read any
@@ -1222,10 +1225,12 @@
}
if (mVideoTrack.mSource != NULL) {
int64_t actualTimeUs;
- readBuffer(MEDIA_TRACK_TYPE_VIDEO, seekTimeUs, &actualTimeUs);
+ readBuffer(MEDIA_TRACK_TYPE_VIDEO, seekTimeUs, precise, &actualTimeUs);
- seekTimeUs = actualTimeUs;
- mVideoLastDequeueTimeUs = seekTimeUs;
+ if (!precise) {
+ seekTimeUs = actualTimeUs;
+ }
+ mVideoLastDequeueTimeUs = actualTimeUs;
}
if (mAudioTrack.mSource != NULL) {
@@ -1250,7 +1255,8 @@
sp<ABuffer> NuPlayer::GenericSource::mediaBufferToABuffer(
MediaBuffer* mb,
media_track_type trackType,
- int64_t /* seekTimeUs */,
+ int64_t seekTimeUs,
+ bool precise,
int64_t *actualTimeUs) {
bool audio = trackType == MEDIA_TRACK_TYPE_AUDIO;
size_t outLength = mb->range_length();
@@ -1288,15 +1294,11 @@
CHECK(mb->meta_data()->findInt64(kKeyTime, &timeUs));
meta->setInt64("timeUs", timeUs);
-#if 0
- // Temporarily disable pre-roll till we have a full solution to handle
- // both single seek and continous seek gracefully.
- if (seekTimeUs > timeUs) {
+ if (precise && seekTimeUs > timeUs) {
sp<AMessage> extra = new AMessage;
extra->setInt64("resume-at-mediaTimeUs", seekTimeUs);
meta->setMessage("extra", extra);
}
-#endif
if (trackType == MEDIA_TRACK_TYPE_VIDEO) {
int32_t layerId;
@@ -1372,7 +1374,8 @@
}
void NuPlayer::GenericSource::readBuffer(
- media_track_type trackType, int64_t seekTimeUs, int64_t *actualTimeUs, bool formatChange) {
+ media_track_type trackType, int64_t seekTimeUs, bool precise,
+ int64_t *actualTimeUs, bool formatChange) {
// Do not read data if Widevine source is stopped
if (mStopRead) {
return;
@@ -1466,7 +1469,7 @@
queueDiscontinuityIfNeeded(seeking, formatChange, trackType, track);
sp<ABuffer> buffer = mediaBufferToABuffer(
- mbuf, trackType, seekTimeUs,
+ mbuf, trackType, seekTimeUs, precise,
numBuffers == 0 ? actualTimeUs : NULL);
track->mPackets->queueAccessUnit(buffer);
formatChange = false;
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.h b/media/libmediaplayerservice/nuplayer/GenericSource.h
index 0957778..f9db6a5 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.h
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.h
@@ -71,7 +71,7 @@
virtual sp<AMessage> getTrackInfo(size_t trackIndex) const;
virtual ssize_t getSelectedTrack(media_track_type type) const;
virtual status_t selectTrack(size_t trackIndex, bool select, int64_t timeUs);
- virtual status_t seekTo(int64_t seekTimeUs);
+ virtual status_t seekTo(int64_t seekTimeUs, bool precise = false);
virtual status_t setBuffers(bool audio, Vector<MediaBuffer *> &buffers);
@@ -258,7 +258,7 @@
status_t doSelectTrack(size_t trackIndex, bool select, int64_t timeUs);
void onSeek(const sp<AMessage>& msg);
- status_t doSeek(int64_t seekTimeUs);
+ status_t doSeek(int64_t seekTimeUs, bool precise);
void onPrepareAsync();
@@ -278,13 +278,15 @@
MediaBuffer *mbuf,
media_track_type trackType,
int64_t seekTimeUs,
+ bool precise,
int64_t *actualTimeUs = NULL);
void postReadBuffer(media_track_type trackType);
void onReadBuffer(const sp<AMessage>& msg);
void readBuffer(
media_track_type trackType,
- int64_t seekTimeUs = -1ll, int64_t *actualTimeUs = NULL, bool formatChange = false);
+ int64_t seekTimeUs = -1ll, bool precise = false,
+ int64_t *actualTimeUs = NULL, bool formatChange = false);
void queueDiscontinuityIfNeeded(
bool seeking, bool formatChange, media_track_type trackType, Track *track);
diff --git a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp
index ebba93c..1a6a233 100644
--- a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp
@@ -214,8 +214,8 @@
return (err == OK || err == BAD_VALUE) ? (status_t)OK : err;
}
-status_t NuPlayer::HTTPLiveSource::seekTo(int64_t seekTimeUs) {
- return mLiveSession->seekTo(seekTimeUs);
+status_t NuPlayer::HTTPLiveSource::seekTo(int64_t seekTimeUs, bool precise) {
+ return mLiveSession->seekTo(seekTimeUs, precise);
}
void NuPlayer::HTTPLiveSource::pollForRawData(
diff --git a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h
index 574937d..be3b4f0 100644
--- a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h
+++ b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h
@@ -47,7 +47,7 @@
virtual sp<AMessage> getTrackInfo(size_t trackIndex) const;
virtual ssize_t getSelectedTrack(media_track_type /* type */) const;
virtual status_t selectTrack(size_t trackIndex, bool select, int64_t timeUs);
- virtual status_t seekTo(int64_t seekTimeUs);
+ virtual status_t seekTo(int64_t seekTimeUs, bool precise = false);
protected:
virtual ~HTTPLiveSource();
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index c3b2609..cbc32b1 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -420,9 +420,10 @@
(new AMessage(kWhatReset, this))->post();
}
-void NuPlayer::seekToAsync(int64_t seekTimeUs, bool needNotify) {
+void NuPlayer::seekToAsync(int64_t seekTimeUs, bool precise, bool needNotify) {
sp<AMessage> msg = new AMessage(kWhatSeek, this);
msg->setInt64("seekTimeUs", seekTimeUs);
+ msg->setInt32("precise", precise);
msg->setInt32("needNotify", needNotify);
msg->post();
}
@@ -1197,12 +1198,14 @@
case kWhatSeek:
{
int64_t seekTimeUs;
+ int32_t precise;
int32_t needNotify;
CHECK(msg->findInt64("seekTimeUs", &seekTimeUs));
+ CHECK(msg->findInt32("precise", &precise));
CHECK(msg->findInt32("needNotify", &needNotify));
- ALOGV("kWhatSeek seekTimeUs=%lld us, needNotify=%d",
- (long long)seekTimeUs, needNotify);
+ ALOGV("kWhatSeek seekTimeUs=%lld us, precise=%d, needNotify=%d",
+ (long long)seekTimeUs, precise, needNotify);
if (!mStarted) {
// Seek before the player is started. In order to preview video,
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h
index a002f6f..725f806 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h
@@ -70,7 +70,7 @@
// Will notify the driver through "notifySeekComplete" once finished
// and needNotify is true.
- void seekToAsync(int64_t seekTimeUs, bool needNotify = false);
+ void seekToAsync(int64_t seekTimeUs, bool precise = false, bool needNotify = false);
status_t setVideoScalingMode(int32_t mode);
status_t getTrackInfo(Parcel* reply) const;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
index 6974207..d2452af 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
@@ -711,6 +711,10 @@
flags = AUDIO_OUTPUT_FLAG_NONE;
}
+ // TODO: This is a temporary fix to flush audio buffers in renderer. The real
+ // fix should be to wait for all buffers rendered normally, then open a new
+ // AudioSink.
+ mRenderer->flush(true /* audio */, false /* notifyComplete */);
status_t err = mRenderer->openAudioSink(
format, false /* offloadOnly */, hasVideo, flags, NULL /* isOffloaed */);
if (err != OK) {
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
index 0f4dce9..7f287e3 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
@@ -208,7 +208,7 @@
mAtEOS = false;
mState = STATE_STOPPED_AND_PREPARING;
mIsAsyncPrepare = false;
- mPlayer->seekToAsync(0, true /* needNotify */);
+ mPlayer->seekToAsync(0, false /* precise */, true /* needNotify */);
while (mState == STATE_STOPPED_AND_PREPARING) {
mCondition.wait(mLock);
}
@@ -233,7 +233,7 @@
mAtEOS = false;
mState = STATE_STOPPED_AND_PREPARING;
mIsAsyncPrepare = true;
- mPlayer->seekToAsync(0, true /* needNotify */);
+ mPlayer->seekToAsync(0, false /* precise */, true /* needNotify */);
return OK;
default:
return INVALID_OPERATION;
@@ -382,8 +382,8 @@
return mPlayer->getSyncSettings(sync, videoFps);
}
-status_t NuPlayerDriver::seekTo(int msec) {
- ALOGD("seekTo(%p) %d ms at state %d", this, msec, mState);
+status_t NuPlayerDriver::seekTo(int msec, bool precise) {
+ ALOGD("seekTo(%p) (%d ms, %d) at state %d", this, msec, precise, mState);
Mutex::Autolock autoLock(mLock);
int64_t seekTimeUs = msec * 1000ll;
@@ -398,7 +398,7 @@
mSeekInProgress = true;
// seeks can take a while, so we essentially paused
notifyListener_l(MEDIA_PAUSED);
- mPlayer->seekToAsync(seekTimeUs, true /* needNotify */);
+ mPlayer->seekToAsync(seekTimeUs, precise, true /* needNotify */);
break;
}
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
index 58008f0..034b3f9 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
@@ -53,7 +53,7 @@
virtual status_t getPlaybackSettings(AudioPlaybackRate *rate);
virtual status_t setSyncSettings(const AVSyncSettings &sync, float videoFpsHint);
virtual status_t getSyncSettings(AVSyncSettings *sync, float *videoFps);
- virtual status_t seekTo(int msec);
+ virtual status_t seekTo(int msec, bool precise = false);
virtual status_t getCurrentPosition(int *msec);
virtual status_t getDuration(int *msec);
virtual status_t reset();
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerSource.h b/media/libmediaplayerservice/nuplayer/NuPlayerSource.h
index 3a96138..b62fbfd 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerSource.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerSource.h
@@ -104,7 +104,7 @@
return INVALID_OPERATION;
}
- virtual status_t seekTo(int64_t /* seekTimeUs */) {
+ virtual status_t seekTo(int64_t /* seekTimeUs */, bool /* precise */ = false) {
return INVALID_OPERATION;
}
diff --git a/media/libmediaplayerservice/nuplayer/RTSPSource.cpp b/media/libmediaplayerservice/nuplayer/RTSPSource.cpp
index 7ce909d..f430f03 100644
--- a/media/libmediaplayerservice/nuplayer/RTSPSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/RTSPSource.cpp
@@ -279,10 +279,11 @@
return OK;
}
-status_t NuPlayer::RTSPSource::seekTo(int64_t seekTimeUs) {
+status_t NuPlayer::RTSPSource::seekTo(int64_t seekTimeUs, bool precise) {
sp<AMessage> msg = new AMessage(kWhatPerformSeek, this);
msg->setInt32("generation", ++mSeekGeneration);
msg->setInt64("timeUs", seekTimeUs);
+ msg->setInt32("precise", precise);
sp<AMessage> response;
status_t err = msg->postAndAwaitResponse(&response);
@@ -465,8 +466,11 @@
}
int64_t seekTimeUs;
+ int32_t precise;
CHECK(msg->findInt64("timeUs", &seekTimeUs));
+ CHECK(msg->findInt32("precise", &precise));
+ // TODO: add "precise" to performSeek.
performSeek(seekTimeUs);
return;
} else if (msg->what() == kWhatPollBuffering) {
diff --git a/media/libmediaplayerservice/nuplayer/RTSPSource.h b/media/libmediaplayerservice/nuplayer/RTSPSource.h
index c7834ef..f2d9cc0 100644
--- a/media/libmediaplayerservice/nuplayer/RTSPSource.h
+++ b/media/libmediaplayerservice/nuplayer/RTSPSource.h
@@ -49,7 +49,7 @@
virtual status_t dequeueAccessUnit(bool audio, sp<ABuffer> *accessUnit);
virtual status_t getDuration(int64_t *durationUs);
- virtual status_t seekTo(int64_t seekTimeUs);
+ virtual status_t seekTo(int64_t seekTimeUs, bool precise = false);
void onMessageReceived(const sp<AMessage> &msg);
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index 4eacff5..9207d05 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -88,6 +88,7 @@
libgui \
liblog \
libmedia \
+ libaudioclient \
libmediautils \
libnetd_client \
libsonivox \
diff --git a/media/libstagefright/AudioSource.cpp b/media/libstagefright/AudioSource.cpp
index efdee77..4ccd2d0 100644
--- a/media/libstagefright/AudioSource.cpp
+++ b/media/libstagefright/AudioSource.cpp
@@ -62,6 +62,8 @@
mPrevSampleTimeUs(0),
mInitialReadTimeUs(0),
mNumFramesReceived(0),
+ mNumFramesSkipped(0),
+ mNumFramesLost(0),
mNumClientOwnedBuffers(0) {
ALOGV("sampleRate: %u, outSampleRate: %u, channelCount: %u",
sampleRate, outSampleRate, channelCount);
@@ -295,11 +297,27 @@
}
status_t AudioSource::dataCallback(const AudioRecord::Buffer& audioBuffer) {
- int64_t timeUs = systemTime() / 1000ll;
- // Estimate the real sampling time of the 1st sample in this buffer
- // from AudioRecord's latency. (Apply this adjustment first so that
- // the start time logic is not affected.)
- timeUs -= mRecord->latency() * 1000LL;
+ int64_t timeUs, position, timeNs;
+ ExtendedTimestamp ts;
+ ExtendedTimestamp::Location location;
+ const int32_t usPerSec = 1000000;
+
+ if (mRecord->getTimestamp(&ts) == OK &&
+ ts.getBestTimestamp(&position, &timeNs, ExtendedTimestamp::TIMEBASE_MONOTONIC,
+ &location) == OK) {
+ // Use audio timestamp.
+ timeUs = timeNs / 1000 -
+ (position - mNumFramesSkipped -
+ mNumFramesReceived + mNumFramesLost) * usPerSec / mSampleRate;
+ } else {
+ // This should not happen in normal case.
+ ALOGW("Failed to get audio timestamp, fallback to use systemclock");
+ timeUs = systemTime() / 1000ll;
+ // Estimate the real sampling time of the 1st sample in this buffer
+ // from AudioRecord's latency. (Apply this adjustment first so that
+ // the start time logic is not affected.)
+ timeUs -= mRecord->latency() * 1000LL;
+ }
ALOGV("dataCallbackTimestamp: %" PRId64 " us", timeUs);
Mutex::Autolock autoLock(mLock);
@@ -308,10 +326,15 @@
return OK;
}
+ const size_t bufferSize = audioBuffer.size;
+
// Drop retrieved and previously lost audio data.
if (mNumFramesReceived == 0 && timeUs < mStartTimeUs) {
(void) mRecord->getInputFramesLost();
- ALOGV("Drop audio data at %" PRId64 "/%" PRId64 " us", timeUs, mStartTimeUs);
+ int64_t receievedFrames = bufferSize / mRecord->frameSize();
+ ALOGV("Drop audio data(%" PRId64 " frames) at %" PRId64 "/%" PRId64 " us",
+ receievedFrames, timeUs, mStartTimeUs);
+ mNumFramesSkipped += receievedFrames;
return OK;
}
@@ -320,11 +343,7 @@
// Initial delay
if (mStartTimeUs > 0) {
mStartTimeUs = timeUs - mStartTimeUs;
- } else {
- // Assume latency is constant.
- mStartTimeUs += mRecord->latency() * 1000;
}
-
mPrevSampleTimeUs = mStartTimeUs;
}
@@ -354,6 +373,7 @@
MediaBuffer *lostAudioBuffer = new MediaBuffer(bufferSize);
memset(lostAudioBuffer->data(), 0, bufferSize);
lostAudioBuffer->set_range(0, bufferSize);
+ mNumFramesLost += bufferSize / mRecord->frameSize();
queueInputBuffer_l(lostAudioBuffer, timeUs);
}
@@ -362,7 +382,6 @@
return OK;
}
- const size_t bufferSize = audioBuffer.size;
MediaBuffer *buffer = new MediaBuffer(bufferSize);
memcpy((uint8_t *) buffer->data(),
audioBuffer.i16, audioBuffer.size);
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index 5c37d73..e617b24 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -1339,12 +1339,30 @@
static_cast<CodecBase::PortDescription *>(obj.get());
size_t numBuffers = portDesc->countBuffers();
+
+ size_t totalSize = 0;
+ for (size_t i = 0; i < numBuffers; ++i) {
+ if (portIndex == kPortIndexInput && mCrypto != NULL) {
+ totalSize += portDesc->bufferAt(i)->capacity();
+ }
+ }
+
+ if (totalSize) {
+ mDealer = new MemoryDealer(totalSize, "MediaCodec");
+ }
+
for (size_t i = 0; i < numBuffers; ++i) {
BufferInfo info;
info.mBufferID = portDesc->bufferIDAt(i);
info.mOwnedByClient = false;
+ sp<MediaCodecBuffer> buffer = portDesc->bufferAt(i);
+ if (portIndex == kPortIndexInput && mCrypto != NULL) {
+ info.mSharedEncryptedBuffer = mDealer->allocate(buffer->capacity());
+ buffer = new SharedMemoryBuffer(
+ mInputFormat, info.mSharedEncryptedBuffer);
+ }
buffers->push_back(info);
- mPortBufferArrays[portIndex].push_back(portDesc->bufferAt(i));
+ mPortBufferArrays[portIndex].push_back(buffer);
}
if (portIndex == kPortIndexOutput) {
@@ -2386,17 +2404,6 @@
sp<MediaCodecBuffer> buffer = static_cast<MediaCodecBuffer *>(obj.get());
Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
- if (portIndex == kPortIndexInput && mCrypto != NULL && mDealer == NULL) {
- // Lazy initialization for encrypted buffers.
- size_t capacity = buffer->capacity();
- size_t totalSize = capacity * buffers->size();
-
- mDealer = new MemoryDealer(totalSize, "MediaCodec");
- for (size_t i = 0; i < buffers->size(); ++i) {
- BufferInfo *info = &buffers->editItemAt(i);
- info->mSharedEncryptedBuffer = mDealer->allocate(capacity);
- }
- }
for (size_t i = 0; i < buffers->size(); ++i) {
BufferInfo *info = &buffers->editItemAt(i);
diff --git a/media/libstagefright/NuMediaExtractor.cpp b/media/libstagefright/NuMediaExtractor.cpp
index ad27856..e3270ed 100644
--- a/media/libstagefright/NuMediaExtractor.cpp
+++ b/media/libstagefright/NuMediaExtractor.cpp
@@ -51,7 +51,8 @@
for (size_t i = 0; i < mSelectedTracks.size(); ++i) {
TrackInfo *info = &mSelectedTracks.editItemAt(i);
- CHECK_EQ((status_t)OK, info->mSource->stop());
+ status_t err = info->mSource->stop();
+ ALOGE_IF(err != OK, "error %d stopping track %zu", err, i);
}
mSelectedTracks.clear();
diff --git a/media/libstagefright/http/Android.mk b/media/libstagefright/http/Android.mk
index b3ca6d5..a7bd6a2 100644
--- a/media/libstagefright/http/Android.mk
+++ b/media/libstagefright/http/Android.mk
@@ -13,9 +13,9 @@
$(TOP)/frameworks/base/core/jni \
LOCAL_SHARED_LIBRARIES := \
- libstagefright liblog libutils libbinder libstagefright_foundation \
- libandroid_runtime \
- libmedia
+ liblog libutils libbinder \
+ libandroid_runtime \
+ libmedia
LOCAL_MODULE:= libstagefright_http_support
diff --git a/media/libstagefright/httplive/LiveSession.cpp b/media/libstagefright/httplive/LiveSession.cpp
index 8b9472e..e654a01 100644
--- a/media/libstagefright/httplive/LiveSession.cpp
+++ b/media/libstagefright/httplive/LiveSession.cpp
@@ -518,9 +518,10 @@
return err;
}
-status_t LiveSession::seekTo(int64_t timeUs) {
+status_t LiveSession::seekTo(int64_t timeUs, bool precise) {
sp<AMessage> msg = new AMessage(kWhatSeek, this);
msg->setInt64("timeUs", timeUs);
+ msg->setInt32("precise", precise);
sp<AMessage> response;
status_t err = msg->postAndAwaitResponse(&response);
@@ -1441,7 +1442,10 @@
void LiveSession::onSeek(const sp<AMessage> &msg) {
int64_t timeUs;
+ int32_t precise;
CHECK(msg->findInt64("timeUs", &timeUs));
+ CHECK(msg->findInt32("precise", &precise));
+ // TODO: add "precise" to changeConfiguration.
changeConfiguration(timeUs);
}
diff --git a/media/libstagefright/httplive/LiveSession.h b/media/libstagefright/httplive/LiveSession.h
index 65a824e..4dc529c 100644
--- a/media/libstagefright/httplive/LiveSession.h
+++ b/media/libstagefright/httplive/LiveSession.h
@@ -86,7 +86,7 @@
status_t disconnect();
// Blocks until seek is complete.
- status_t seekTo(int64_t timeUs);
+ status_t seekTo(int64_t timeUs, bool precise);
status_t getDuration(int64_t *durationUs) const;
size_t getTrackCount() const;
diff --git a/media/libstagefright/id3/ID3.cpp b/media/libstagefright/id3/ID3.cpp
index bffed52..9105084 100644
--- a/media/libstagefright/id3/ID3.cpp
+++ b/media/libstagefright/id3/ID3.cpp
@@ -839,20 +839,21 @@
}
}
-static size_t StringSize(const uint8_t *start, uint8_t encoding) {
+// return includes terminator; if unterminated, returns > limit
+static size_t StringSize(const uint8_t *start, size_t limit, uint8_t encoding) {
+
if (encoding == 0x00 || encoding == 0x03) {
// ISO 8859-1 or UTF-8
- return strlen((const char *)start) + 1;
+ return strnlen((const char *)start, limit) + 1;
}
// UCS-2
size_t n = 0;
- while (start[n] != '\0' || start[n + 1] != '\0') {
+ while ((n+1 < limit) && (start[n] != '\0' || start[n + 1] != '\0')) {
n += 2;
}
-
- // Add size of null termination.
- return n + 2;
+ n += 2;
+ return n;
}
const void *
@@ -873,11 +874,19 @@
if (mVersion == ID3_V2_3 || mVersion == ID3_V2_4) {
uint8_t encoding = data[0];
- mime->setTo((const char *)&data[1]);
- size_t mimeLen = strlen((const char *)&data[1]) + 1;
+ size_t consumed = 1;
+
+ // *always* in an 8-bit encoding
+ size_t mimeLen = StringSize(&data[consumed], size - consumed, 0x00);
+ if (mimeLen > size - consumed) {
+ ALOGW("bogus album art size: mime");
+ return NULL;
+ }
+ mime->setTo((const char *)&data[consumed]);
+ consumed += mimeLen;
#if 0
- uint8_t picType = data[1 + mimeLen];
+ uint8_t picType = data[consumed];
if (picType != 0x03) {
// Front Cover Art
it.next();
@@ -885,20 +894,30 @@
}
#endif
- size_t descLen = StringSize(&data[2 + mimeLen], encoding);
-
- if (size < 2 ||
- size - 2 < mimeLen ||
- size - 2 - mimeLen < descLen) {
- ALOGW("bogus album art sizes");
+ consumed++;
+ if (consumed >= size) {
+ ALOGW("bogus album art size: pic type");
return NULL;
}
- *length = size - 2 - mimeLen - descLen;
- return &data[2 + mimeLen + descLen];
+ size_t descLen = StringSize(&data[consumed], size - consumed, encoding);
+ consumed += descLen;
+
+ if (consumed >= size) {
+ ALOGW("bogus album art size: description");
+ return NULL;
+ }
+
+ *length = size - consumed;
+
+ return &data[consumed];
} else {
uint8_t encoding = data[0];
+ if (size <= 5) {
+ return NULL;
+ }
+
if (!memcmp(&data[1], "PNG", 3)) {
mime->setTo("image/png");
} else if (!memcmp(&data[1], "JPG", 3)) {
@@ -918,7 +937,10 @@
}
#endif
- size_t descLen = StringSize(&data[5], encoding);
+ size_t descLen = StringSize(&data[5], size - 5, encoding);
+ if (descLen > size - 5) {
+ return NULL;
+ }
*length = size - 5 - descLen;
diff --git a/media/libstagefright/matroska/MatroskaExtractor.cpp b/media/libstagefright/matroska/MatroskaExtractor.cpp
index b060628..a974671 100644
--- a/media/libstagefright/matroska/MatroskaExtractor.cpp
+++ b/media/libstagefright/matroska/MatroskaExtractor.cpp
@@ -377,6 +377,16 @@
*actualFrameTimeUs = -1ll;
+ if (seekTimeUs > INT64_MAX / 1000ll ||
+ seekTimeUs < INT64_MIN / 1000ll ||
+ (mExtractor->mSeekPreRollNs > 0 &&
+ (seekTimeUs * 1000ll) < INT64_MIN + mExtractor->mSeekPreRollNs) ||
+ (mExtractor->mSeekPreRollNs < 0 &&
+ (seekTimeUs * 1000ll) > INT64_MAX + mExtractor->mSeekPreRollNs)) {
+ ALOGE("cannot seek to %lld", (long long) seekTimeUs);
+ return;
+ }
+
const int64_t seekTimeNs = seekTimeUs * 1000ll - mExtractor->mSeekPreRollNs;
mkvparser::Segment* const pSegment = mExtractor->mSegment;
diff --git a/media/utils/Android.mk b/media/utils/Android.mk
index 54d22b1..f482d1a 100644
--- a/media/utils/Android.mk
+++ b/media/utils/Android.mk
@@ -19,6 +19,7 @@
LOCAL_SRC_FILES := \
BatteryNotifier.cpp \
ISchedulingPolicyService.cpp \
+ MemoryLeakTrackUtil.cpp \
SchedulingPolicyService.cpp
LOCAL_SHARED_LIBRARIES := \
@@ -26,6 +27,7 @@
libcutils \
liblog \
libutils \
+ libmemunreachable \
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
diff --git a/media/libmedia/MemoryLeakTrackUtil.cpp b/media/utils/MemoryLeakTrackUtil.cpp
similarity index 100%
rename from media/libmedia/MemoryLeakTrackUtil.cpp
rename to media/utils/MemoryLeakTrackUtil.cpp
diff --git a/services/audioflinger/Android.mk b/services/audioflinger/Android.mk
index 1657c08..e2a93ad 100644
--- a/services/audioflinger/Android.mk
+++ b/services/audioflinger/Android.mk
@@ -36,6 +36,7 @@
LOCAL_C_INCLUDES := \
$(TOPDIR)frameworks/av/services/audiopolicy \
+ $(TOPDIR)frameworks/av/services/medialog \
$(TOPDIR)external/sonic \
$(call include-path-for, audio-utils)
@@ -48,7 +49,8 @@
libutils \
liblog \
libbinder \
- libmedia \
+ libaudioclient \
+ libmedialogservice \
libmediautils \
libnbaio \
libpowermanager \
diff --git a/services/audiopolicy/Android.mk b/services/audiopolicy/Android.mk
index 91cc3d2..5f02a98 100644
--- a/services/audiopolicy/Android.mk
+++ b/services/audiopolicy/Android.mk
@@ -30,7 +30,7 @@
libutils \
liblog \
libbinder \
- libmedia \
+ libaudioclient \
libhardware_legacy \
libserviceutility
diff --git a/services/camera/libcameraservice/api1/client2/Parameters.cpp b/services/camera/libcameraservice/api1/client2/Parameters.cpp
index 8ce84ae..9a7839b 100644
--- a/services/camera/libcameraservice/api1/client2/Parameters.cpp
+++ b/services/camera/libcameraservice/api1/client2/Parameters.cpp
@@ -958,21 +958,40 @@
return NO_INIT;
}
+ // Get supported preview fps ranges.
+ Vector<Size> supportedPreviewSizes;
+ Vector<FpsRange> supportedPreviewFpsRanges;
+ const Size PREVIEW_SIZE_BOUND = { MAX_PREVIEW_WIDTH, MAX_PREVIEW_HEIGHT };
+ status_t res = getFilteredSizes(PREVIEW_SIZE_BOUND, &supportedPreviewSizes);
+ if (res != OK) return res;
+ for (size_t i=0; i < availableFpsRanges.count; i += 2) {
+ if (!isFpsSupported(supportedPreviewSizes,
+ HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, availableFpsRanges.data.i32[i+1])) {
+ continue;
+ }
+ FpsRange fpsRange = {availableFpsRanges.data.i32[i], availableFpsRanges.data.i32[i+1]};
+ supportedPreviewFpsRanges.add(fpsRange);
+ }
+ if (supportedPreviewFpsRanges.size() == 0) {
+ ALOGE("Supported preview fps range is empty");
+ return NO_INIT;
+ }
+
int32_t bestStillCaptureFpsRange[2] = {
- availableFpsRanges.data.i32[0], availableFpsRanges.data.i32[1]
+ supportedPreviewFpsRanges[0].low, supportedPreviewFpsRanges[0].high
};
int32_t curRange =
bestStillCaptureFpsRange[1] - bestStillCaptureFpsRange[0];
- for (size_t i = 2; i < availableFpsRanges.count; i += 2) {
+ for (size_t i = 1; i < supportedPreviewFpsRanges.size(); i ++) {
int32_t nextRange =
- availableFpsRanges.data.i32[i + 1] -
- availableFpsRanges.data.i32[i];
+ supportedPreviewFpsRanges[i].high -
+ supportedPreviewFpsRanges[i].low;
if ( (nextRange > curRange) || // Maximize size of FPS range first
(nextRange == curRange && // Then minimize low-end FPS
- bestStillCaptureFpsRange[0] > availableFpsRanges.data.i32[i])) {
+ bestStillCaptureFpsRange[0] > supportedPreviewFpsRanges[i].low)) {
- bestStillCaptureFpsRange[0] = availableFpsRanges.data.i32[i];
- bestStillCaptureFpsRange[1] = availableFpsRanges.data.i32[i + 1];
+ bestStillCaptureFpsRange[0] = supportedPreviewFpsRanges[i].low;
+ bestStillCaptureFpsRange[1] = supportedPreviewFpsRanges[i].high;
curRange = nextRange;
}
}
@@ -2900,6 +2919,7 @@
}
// Get min frame duration for each size and check if the given fps range can be supported.
+ const int32_t FPS_MARGIN = 1;
for (size_t i = 0 ; i < sizes.size(); i++) {
int64_t minFrameDuration = getMinFrameDurationNs(sizes[i], format);
if (minFrameDuration <= 0) {
@@ -2908,6 +2928,8 @@
return false;
}
int32_t maxSupportedFps = 1e9 / minFrameDuration;
+ // Add some margin here for the case where the hal supports 29.xxxfps.
+ maxSupportedFps += FPS_MARGIN;
if (fps > maxSupportedFps) {
return false;
}
diff --git a/services/camera/libcameraservice/api1/client2/Parameters.h b/services/camera/libcameraservice/api1/client2/Parameters.h
index 5ada30c..c8ecbba 100644
--- a/services/camera/libcameraservice/api1/client2/Parameters.h
+++ b/services/camera/libcameraservice/api1/client2/Parameters.h
@@ -115,6 +115,11 @@
int32_t height;
};
+ struct FpsRange {
+ int32_t low;
+ int32_t high;
+ };
+
int32_t exposureCompensation;
bool autoExposureLock;
bool autoWhiteBalanceLock;
diff --git a/services/medialog/Android.mk b/services/medialog/Android.mk
index 88f98cf..a1da63d 100644
--- a/services/medialog/Android.mk
+++ b/services/medialog/Android.mk
@@ -2,9 +2,9 @@
include $(CLEAR_VARS)
-LOCAL_SRC_FILES := MediaLogService.cpp
+LOCAL_SRC_FILES := MediaLogService.cpp IMediaLogService.cpp
-LOCAL_SHARED_LIBRARIES := libmedia libbinder libutils liblog libnbaio
+LOCAL_SHARED_LIBRARIES := libbinder libutils liblog libnbaio
LOCAL_MULTILIB := $(AUDIOSERVER_MULTILIB)
diff --git a/media/libmedia/IMediaLogService.cpp b/services/medialog/IMediaLogService.cpp
similarity index 100%
rename from media/libmedia/IMediaLogService.cpp
rename to services/medialog/IMediaLogService.cpp
diff --git a/services/radio/Android.mk b/services/radio/Android.mk
index 219c372..b4cda19 100644
--- a/services/radio/Android.mk
+++ b/services/radio/Android.mk
@@ -26,7 +26,7 @@
libutils \
libbinder \
libcutils \
- libmedia \
+ libaudioclient \
libhardware \
libradio \
libradio_metadata
diff --git a/services/soundtrigger/Android.mk b/services/soundtrigger/Android.mk
index 2533132..5d01999 100644
--- a/services/soundtrigger/Android.mk
+++ b/services/soundtrigger/Android.mk
@@ -30,7 +30,7 @@
libcutils \
libhardware \
libsoundtrigger \
- libmedia \
+ libaudioclient \
libserviceutility
diff --git a/services/soundtrigger/SoundTriggerHalHidl.cpp b/services/soundtrigger/SoundTriggerHalHidl.cpp
index e71d742..726ef18 100644
--- a/services/soundtrigger/SoundTriggerHalHidl.cpp
+++ b/services/soundtrigger/SoundTriggerHalHidl.cpp
@@ -19,7 +19,6 @@
#include <utils/Log.h>
#include "SoundTriggerHalHidl.h"
-#include <hidl/IServiceManager.h>
#include <hwbinder/IPCThreadState.h>
#include <hwbinder/ProcessState.h>
@@ -29,14 +28,6 @@
using android::hardware::ProcessState;
using android::hardware::audio::common::V2_0::AudioDevice;
-pthread_once_t SoundTriggerHalHidl::sOnceControl = PTHREAD_ONCE_INIT;
-
-void SoundTriggerHalHidl::sOnceInit()
-{
- ProcessState::self()->setThreadPoolMaxThreadCount(1);
- ProcessState::self()->startThreadPool();
-}
-
/* static */
sp<SoundTriggerHalInterface> SoundTriggerHalInterface::connectModule(const char *moduleName)
{
@@ -270,11 +261,6 @@
{
}
-void SoundTriggerHalHidl::onFirstRef()
-{
- pthread_once(&sOnceControl, &sOnceInit);
-}
-
SoundTriggerHalHidl::~SoundTriggerHalHidl()
{
}
diff --git a/services/soundtrigger/SoundTriggerHalHidl.h b/services/soundtrigger/SoundTriggerHalHidl.h
index 60404dc..e578dda 100644
--- a/services/soundtrigger/SoundTriggerHalHidl.h
+++ b/services/soundtrigger/SoundTriggerHalHidl.h
@@ -82,9 +82,6 @@
*/
virtual int stopAllRecognitions();
- // RefBase
- virtual void onFirstRef();
-
// ISoundTriggerHwCallback
virtual ::android::hardware::Return<void> recognitionCallback(
const ISoundTriggerHwCallback::RecognitionEvent& event, CallbackCookie cookie);