diff options
78 files changed, 437 insertions, 337 deletions
diff --git a/include/media/MediaCodecInfo.h b/include/media/MediaCodecInfo.h index 895a13a..4067b47 100644 --- a/include/media/MediaCodecInfo.h +++ b/include/media/MediaCodecInfo.h @@ -32,7 +32,7 @@ namespace android { struct AMessage; -struct Parcel; +class Parcel; struct CodecCapabilities; typedef KeyedVector<AString, AString> CodecSettings; diff --git a/include/media/stagefright/MediaCodecSource.h b/include/media/stagefright/MediaCodecSource.h index 7b8f59d..9d1f222 100644 --- a/include/media/stagefright/MediaCodecSource.h +++ b/include/media/stagefright/MediaCodecSource.h @@ -23,7 +23,7 @@ namespace android { -class ALooper; +struct ALooper; class AMessage; struct AReplyToken; class IGraphicBufferProducer; diff --git a/include/media/stagefright/Utils.h b/include/media/stagefright/Utils.h index 215ca7c..0ce1603 100644 --- a/include/media/stagefright/Utils.h +++ b/include/media/stagefright/Utils.h @@ -71,7 +71,7 @@ struct HLSTime { sp<AMessage> mMeta; HLSTime(const sp<AMessage> &meta = NULL); - int64_t getSegmentTimeUs(bool midpoint = false) const; + int64_t getSegmentTimeUs() const; }; bool operator <(const HLSTime &t0, const HLSTime &t1); diff --git a/include/media/stagefright/foundation/AMessage.h b/include/media/stagefright/foundation/AMessage.h index 4c6bd21..83b9444 100644 --- a/include/media/stagefright/foundation/AMessage.h +++ b/include/media/stagefright/foundation/AMessage.h @@ -28,7 +28,7 @@ namespace android { struct ABuffer; struct AHandler; struct AString; -struct Parcel; +class Parcel; struct AReplyToken : public RefBase { AReplyToken(const sp<ALooper> &looper) diff --git a/include/media/stagefright/foundation/AString.h b/include/media/stagefright/foundation/AString.h index 822dbb3..2f6d532 100644 --- a/include/media/stagefright/foundation/AString.h +++ b/include/media/stagefright/foundation/AString.h @@ -24,7 +24,7 @@ namespace android { class String8; -struct Parcel; +class Parcel; struct AString { AString(); diff --git a/include/media/stagefright/timedtext/TimedTextDriver.h b/include/media/stagefright/timedtext/TimedTextDriver.h index 37ef674..6f7c693 100644 --- a/include/media/stagefright/timedtext/TimedTextDriver.h +++ b/include/media/stagefright/timedtext/TimedTextDriver.h @@ -24,7 +24,7 @@ namespace android { -class ALooper; +struct ALooper; struct IMediaHTTPService; class MediaPlayerBase; class MediaSource; diff --git a/media/libmedia/Android.mk b/media/libmedia/Android.mk index 78baa43..0c18828 100644 --- a/media/libmedia/Android.mk +++ b/media/libmedia/Android.mk @@ -7,6 +7,9 @@ LOCAL_SRC_FILES:= \ LOCAL_MODULE:= libmedia_helper LOCAL_MODULE_TAGS := optional +LOCAL_C_FLAGS += -Werror -Wall +LOCAL_CLANG := true + include $(BUILD_STATIC_LIBRARY) include $(CLEAR_VARS) @@ -84,5 +87,8 @@ LOCAL_C_INCLUDES := \ $(call include-path-for, audio-effects) \ $(call include-path-for, audio-utils) +LOCAL_CFLAGS += -Werror -Wall +LOCAL_CLANG := true + include $(BUILD_SHARED_LIBRARY) diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp index e9ee169..2ed50e8 100644 --- a/media/libmedia/AudioSystem.cpp +++ b/media/libmedia/AudioSystem.cpp @@ -477,7 +477,6 @@ void AudioSystem::AudioFlingerClient::ioConfigChanged(int event, audio_io_handle const void *param2) { ALOGV("ioConfigChanged() event %d", event); const OutputDescriptor *desc; - audio_stream_type_t stream; if (ioHandle == AUDIO_IO_HANDLE_NONE) return; diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp index 30d4355..055556f 100644 --- a/media/libmedia/AudioTrack.cpp +++ b/media/libmedia/AudioTrack.cpp @@ -1663,7 +1663,8 @@ nsecs_t AudioTrack::processAudioBuffer() // AudioSystem cache. We should not exit here but after calling the callback so // that the upper layers can recreate the track if (!isOffloadedOrDirect_l() || (mSequence == mObservedSequence)) { - status_t status = restoreTrack_l("processAudioBuffer"); + status_t status __unused = restoreTrack_l("processAudioBuffer"); + // FIXME unused status // after restoration, continue below to make sure that the loop and buffer events // are notified because they have been cleared from mCblk->mFlags above. } diff --git a/media/libmedia/AudioTrackShared.cpp b/media/libmedia/AudioTrackShared.cpp index ba67b40..aee9fc2 100644 --- a/media/libmedia/AudioTrackShared.cpp +++ b/media/libmedia/AudioTrackShared.cpp @@ -619,8 +619,9 @@ status_t ServerProxy::obtainBuffer(Buffer* buffer, bool ackFlush) // Rather than shutting down on a corrupt flush, just treat it as a full flush if (!(0 <= filled && (size_t) filled <= mFrameCount)) { ALOGE("mFlush %#x -> %#x, front %#x, rear %#x, mask %#x, newFront %#x, " - "filled %d=%#x", - mFlush, flush, front, rear, mask, newFront, filled, filled); + "filled %zd=%#x", + mFlush, flush, front, rear, + (unsigned)mask, newFront, filled, (unsigned)filled); newFront = rear; } mFlush = flush; diff --git a/media/libmedia/CharacterEncodingDetector.cpp b/media/libmedia/CharacterEncodingDetector.cpp index 41994dc..3020136 100644 --- a/media/libmedia/CharacterEncodingDetector.cpp +++ b/media/libmedia/CharacterEncodingDetector.cpp @@ -89,7 +89,6 @@ void CharacterEncodingDetector::detectAndConvert() { // try combined detection of artist/album/title etc. char buf[1024]; buf[0] = 0; - int idx; bool allprintable = true; for (int i = 0; i < size; i++) { const char *name = mNames.getEntry(i); @@ -169,7 +168,6 @@ void CharacterEncodingDetector::detectAndConvert() { const char *name = mNames.getEntry(i); uint8_t* src = (uint8_t *)mValues.getEntry(i); int len = strlen((char *)src); - uint8_t* dest = src; ALOGV("@@@ checking %s", name); const char *s = mValues.getEntry(i); diff --git a/media/libmedia/IMediaLogService.cpp b/media/libmedia/IMediaLogService.cpp index 230749e..1536337 100644 --- a/media/libmedia/IMediaLogService.cpp +++ b/media/libmedia/IMediaLogService.cpp @@ -45,7 +45,7 @@ public: data.writeStrongBinder(IInterface::asBinder(shared)); data.writeInt64((int64_t) size); data.writeCString(name); - status_t status = remote()->transact(REGISTER_WRITER, data, &reply); + status_t status __unused = remote()->transact(REGISTER_WRITER, data, &reply); // FIXME ignores status } @@ -53,7 +53,7 @@ public: Parcel data, reply; data.writeInterfaceToken(IMediaLogService::getInterfaceDescriptor()); data.writeStrongBinder(IInterface::asBinder(shared)); - status_t status = remote()->transact(UNREGISTER_WRITER, data, &reply); + status_t status __unused = remote()->transact(UNREGISTER_WRITER, data, &reply); // FIXME ignores status } diff --git a/media/libmedia/IResourceManagerService.cpp b/media/libmedia/IResourceManagerService.cpp index 95a2d1c..7ae946d 100644 --- a/media/libmedia/IResourceManagerService.cpp +++ b/media/libmedia/IResourceManagerService.cpp @@ -38,11 +38,9 @@ enum { template <typename T> static void writeToParcel(Parcel *data, const Vector<T> &items) { size_t size = items.size(); - size_t sizePosition = data->dataPosition(); // truncates size, but should be okay for this usecase data->writeUint32(static_cast<uint32_t>(size)); for (size_t i = 0; i < size; i++) { - size_t position = data->dataPosition(); items[i].writeToParcel(data); } } @@ -121,7 +119,6 @@ status_t BnResourceManagerService::onTransact( switch (code) { case CONFIG: { CHECK_INTERFACE(IResourceManagerService, data, reply); - int pid = data.readInt32(); sp<IResourceManagerClient> client( interface_cast<IResourceManagerClient>(data.readStrongBinder())); Vector<MediaResourcePolicy> policies; diff --git a/media/libmedia/MediaProfiles.cpp b/media/libmedia/MediaProfiles.cpp index 47f9258..ae0061f 100644 --- a/media/libmedia/MediaProfiles.cpp +++ b/media/libmedia/MediaProfiles.cpp @@ -532,7 +532,6 @@ void MediaProfiles::checkAndAddRequiredProfilesIfNecessary() { CHECK(refIndex != -1); RequiredProfileRefInfo *info; camcorder_quality refQuality; - VideoCodec *codec = NULL; // Check high and low from either camcorder profile, timelapse profile // or high speed profile, but not all of them. Default, check camcorder profile diff --git a/media/libmedia/MediaResource.cpp b/media/libmedia/MediaResource.cpp index 8be01bc..eea2c43 100644 --- a/media/libmedia/MediaResource.cpp +++ b/media/libmedia/MediaResource.cpp @@ -50,7 +50,7 @@ void MediaResource::writeToParcel(Parcel *parcel) const { String8 MediaResource::toString() const { String8 str; - str.appendFormat("%s/%s:%llu", mType.string(), mSubType.string(), mValue); + str.appendFormat("%s/%s:%llu", mType.string(), mSubType.string(), (unsigned long long)mValue); return str; } diff --git a/media/libmedia/MediaResourcePolicy.cpp b/media/libmedia/MediaResourcePolicy.cpp index 2bb996a..139a38c 100644 --- a/media/libmedia/MediaResourcePolicy.cpp +++ b/media/libmedia/MediaResourcePolicy.cpp @@ -42,7 +42,7 @@ void MediaResourcePolicy::writeToParcel(Parcel *parcel) const { String8 MediaResourcePolicy::toString() const { String8 str; - str.appendFormat("%s:%llu", mType.string(), mValue); + str.appendFormat("%s:%llu", mType.string(), (unsigned long long)mValue); return str; } diff --git a/media/libmedia/MemoryLeakTrackUtil.cpp b/media/libmedia/MemoryLeakTrackUtil.cpp index d31f721..554dbae 100644 --- a/media/libmedia/MemoryLeakTrackUtil.cpp +++ b/media/libmedia/MemoryLeakTrackUtil.cpp @@ -173,7 +173,7 @@ void dumpMemoryAddresses(int fd) #else // Does nothing -void dumpMemoryAddresses(int fd) {} +void dumpMemoryAddresses(int fd __unused) {} #endif } // namespace android diff --git a/media/libmedia/ToneGenerator.cpp b/media/libmedia/ToneGenerator.cpp index 2cc4685..6da5348 100644 --- a/media/libmedia/ToneGenerator.cpp +++ b/media/libmedia/ToneGenerator.cpp @@ -984,7 +984,6 @@ void ToneGenerator::stopTone() { if ((mStartTime.tv_sec != 0) && (clock_gettime(CLOCK_MONOTONIC, &stopTime) == 0)) { time_t sec = stopTime.tv_sec - mStartTime.tv_sec; long nsec = stopTime.tv_nsec - mStartTime.tv_nsec; - long durationMs; if (nsec < 0) { --sec; nsec += 1000000000; diff --git a/media/libmediaplayerservice/Android.mk b/media/libmediaplayerservice/Android.mk index 4b31715..2c4e719 100644 --- a/media/libmediaplayerservice/Android.mk +++ b/media/libmediaplayerservice/Android.mk @@ -54,6 +54,9 @@ LOCAL_C_INCLUDES := \ $(TOP)/frameworks/native/include/media/openmax \ $(TOP)/external/tremolo/Tremolo \ +LOCAL_CFLAGS += -Werror -Wall +LOCAL_CLANG := true + LOCAL_MODULE:= libmediaplayerservice LOCAL_32_BIT_ONLY := true diff --git a/media/libmediaplayerservice/Crypto.cpp b/media/libmediaplayerservice/Crypto.cpp index f639193..147d35f 100644 --- a/media/libmediaplayerservice/Crypto.cpp +++ b/media/libmediaplayerservice/Crypto.cpp @@ -89,7 +89,7 @@ void Crypto::findFactoryForScheme(const uint8_t uuid[16]) { // first check cache Vector<uint8_t> uuidVector; - uuidVector.appendArray(uuid, sizeof(uuid)); + uuidVector.appendArray(uuid, sizeof(uuid[0]) * 16); ssize_t index = mUUIDToLibraryPathMap.indexOfKey(uuidVector); if (index >= 0) { if (loadLibraryForScheme(mUUIDToLibraryPathMap[index], uuid)) { diff --git a/media/libmediaplayerservice/Drm.cpp b/media/libmediaplayerservice/Drm.cpp index 62cf3e5..8ca8769 100644 --- a/media/libmediaplayerservice/Drm.cpp +++ b/media/libmediaplayerservice/Drm.cpp @@ -209,7 +209,7 @@ void Drm::findFactoryForScheme(const uint8_t uuid[16]) { // first check cache Vector<uint8_t> uuidVector; - uuidVector.appendArray(uuid, sizeof(uuid)); + uuidVector.appendArray(uuid, sizeof(uuid[0]) * 16); ssize_t index = mUUIDToLibraryPathMap.indexOfKey(uuidVector); if (index >= 0) { if (loadLibraryForScheme(mUUIDToLibraryPathMap[index], uuid)) { @@ -776,7 +776,7 @@ status_t Drm::signRSA(Vector<uint8_t> const &sessionId, return mPlugin->signRSA(sessionId, algorithm, message, wrappedKey, signature); } -void Drm::binderDied(const wp<IBinder> &the_late_who) +void Drm::binderDied(const wp<IBinder> &the_late_who __unused) { mEventLock.lock(); mListener.clear(); diff --git a/media/libmediaplayerservice/Drm.h b/media/libmediaplayerservice/Drm.h index 1591738..c4013b8 100644 --- a/media/libmediaplayerservice/Drm.h +++ b/media/libmediaplayerservice/Drm.h @@ -26,8 +26,8 @@ namespace android { -struct DrmFactory; -struct DrmPlugin; +class DrmFactory; +class DrmPlugin; struct DrmSessionClientInterface; struct Drm : public BnDrm, diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp index 8e2e214..87003c5 100644 --- a/media/libmediaplayerservice/MediaPlayerService.cpp +++ b/media/libmediaplayerservice/MediaPlayerService.cpp @@ -413,7 +413,7 @@ status_t MediaPlayerService::AudioOutput::dump(int fd, const Vector<String16>& a return NO_ERROR; } -status_t MediaPlayerService::Client::dump(int fd, const Vector<String16>& args) const +status_t MediaPlayerService::Client::dump(int fd, const Vector<String16>& args) { const size_t SIZE = 256; char buffer[SIZE]; @@ -1461,8 +1461,6 @@ status_t MediaPlayerService::AudioOutput::open( } ALOGV("open(%u, %d, 0x%x, 0x%x, %d, %d 0x%x)", sampleRate, channelCount, channelMask, format, bufferCount, mSessionId, flags); - uint32_t afSampleRate; - size_t afFrameCount; size_t frameCount; // offloading is only supported in callback mode for now. diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h index 2a95ce1..6ddfe14 100644 --- a/media/libmediaplayerservice/MediaPlayerService.h +++ b/media/libmediaplayerservice/MediaPlayerService.h @@ -304,7 +304,7 @@ private: int ext1, int ext2, const Parcel *obj); pid_t pid() const { return mPid; } - virtual status_t dump(int fd, const Vector<String16>& args) const; + virtual status_t dump(int fd, const Vector<String16>& args); int getAudioSessionId() { return mAudioSessionId; } diff --git a/media/libmediaplayerservice/MediaRecorderClient.cpp b/media/libmediaplayerservice/MediaRecorderClient.cpp index 4d4de9b..319ebb0 100644 --- a/media/libmediaplayerservice/MediaRecorderClient.cpp +++ b/media/libmediaplayerservice/MediaRecorderClient.cpp @@ -325,7 +325,7 @@ status_t MediaRecorderClient::setClientName(const String16& clientName) { return mRecorder->setClientName(clientName); } -status_t MediaRecorderClient::dump(int fd, const Vector<String16>& args) const { +status_t MediaRecorderClient::dump(int fd, const Vector<String16>& args) { if (mRecorder != NULL) { return mRecorder->dump(fd, args); } diff --git a/media/libmediaplayerservice/MediaRecorderClient.h b/media/libmediaplayerservice/MediaRecorderClient.h index a444b6c..b45344b 100644 --- a/media/libmediaplayerservice/MediaRecorderClient.h +++ b/media/libmediaplayerservice/MediaRecorderClient.h @@ -54,7 +54,7 @@ public: virtual status_t init(); virtual status_t close(); virtual status_t release(); - virtual status_t dump(int fd, const Vector<String16>& args) const; + virtual status_t dump(int fd, const Vector<String16>& args); virtual sp<IGraphicBufferProducer> querySurfaceMediaSource(); private: diff --git a/media/libmediaplayerservice/MetadataRetrieverClient.cpp b/media/libmediaplayerservice/MetadataRetrieverClient.cpp index 80804a7..6ef4c1f 100644 --- a/media/libmediaplayerservice/MetadataRetrieverClient.cpp +++ b/media/libmediaplayerservice/MetadataRetrieverClient.cpp @@ -57,7 +57,7 @@ MetadataRetrieverClient::~MetadataRetrieverClient() disconnect(); } -status_t MetadataRetrieverClient::dump(int fd, const Vector<String16>& /*args*/) const +status_t MetadataRetrieverClient::dump(int fd, const Vector<String16>& /*args*/) { const size_t SIZE = 256; char buffer[SIZE]; diff --git a/media/libmediaplayerservice/MetadataRetrieverClient.h b/media/libmediaplayerservice/MetadataRetrieverClient.h index ce52b91..e71a29e 100644 --- a/media/libmediaplayerservice/MetadataRetrieverClient.h +++ b/media/libmediaplayerservice/MetadataRetrieverClient.h @@ -54,7 +54,7 @@ public: virtual sp<IMemory> extractAlbumArt(); virtual const char* extractMetadata(int keyCode); - virtual status_t dump(int fd, const Vector<String16>& args) const; + virtual status_t dump(int fd, const Vector<String16>& args); private: friend class MediaPlayerService; diff --git a/media/libmediaplayerservice/RemoteDisplay.h b/media/libmediaplayerservice/RemoteDisplay.h index 82a0116..1a48981 100644 --- a/media/libmediaplayerservice/RemoteDisplay.h +++ b/media/libmediaplayerservice/RemoteDisplay.h @@ -28,7 +28,7 @@ namespace android { struct ALooper; struct ANetworkSession; -struct IRemoteDisplayClient; +class IRemoteDisplayClient; struct WifiDisplaySource; struct RemoteDisplay : public BnRemoteDisplay { diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp index 55763f0..fb21c73 100644 --- a/media/libmediaplayerservice/StagefrightRecorder.cpp +++ b/media/libmediaplayerservice/StagefrightRecorder.cpp @@ -916,7 +916,6 @@ sp<MediaSource> StagefrightRecorder::createAudioSource() { } sp<AMessage> format = new AMessage; - const char *mime; switch (mAudioEncoder) { case AUDIO_ENCODER_AMR_NB: case AUDIO_ENCODER_DEFAULT: diff --git a/media/libmediaplayerservice/StagefrightRecorder.h b/media/libmediaplayerservice/StagefrightRecorder.h index f34c229..8fa5bfa 100644 --- a/media/libmediaplayerservice/StagefrightRecorder.h +++ b/media/libmediaplayerservice/StagefrightRecorder.h @@ -37,7 +37,7 @@ struct AudioSource; class MediaProfiles; class IGraphicBufferProducer; class SurfaceMediaSource; -class ALooper; +struct ALooper; struct StagefrightRecorder : public MediaRecorderBase { StagefrightRecorder(); diff --git a/media/libmediaplayerservice/VideoFrameScheduler.h b/media/libmediaplayerservice/VideoFrameScheduler.h index 84b27b4..b1765c9 100644 --- a/media/libmediaplayerservice/VideoFrameScheduler.h +++ b/media/libmediaplayerservice/VideoFrameScheduler.h @@ -24,7 +24,7 @@ namespace android { -struct ISurfaceComposer; +class ISurfaceComposer; struct VideoFrameScheduler : public RefBase { VideoFrameScheduler(); diff --git a/media/libmediaplayerservice/nuplayer/Android.mk b/media/libmediaplayerservice/nuplayer/Android.mk index fca08e2..20193c3 100644 --- a/media/libmediaplayerservice/nuplayer/Android.mk +++ b/media/libmediaplayerservice/nuplayer/Android.mk @@ -25,6 +25,9 @@ LOCAL_C_INCLUDES := \ $(TOP)/frameworks/av/media/libmediaplayerservice \ $(TOP)/frameworks/native/include/media/openmax +LOCAL_CFLAGS += -Werror -Wall +LOCAL_CLANG := true + LOCAL_MODULE:= libstagefright_nuplayer LOCAL_MODULE_TAGS := eng diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp index 8f1cd57..b7a88e7 100644 --- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp +++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp @@ -703,7 +703,7 @@ void NuPlayer::GenericSource::onPollBuffering() { stopBufferingIfNecessary(); } } else if (cachedDataRemaining >= 0) { - ALOGV("onPollBuffering: cachedDataRemaining %d bytes", + ALOGV("onPollBuffering: cachedDataRemaining %zd bytes", cachedDataRemaining); if (cachedDataRemaining < kLowWaterMarkBytes) { @@ -790,7 +790,7 @@ void NuPlayer::GenericSource::onMessageReceived(const sp<AMessage> &msg) { } readBuffer(trackType, timeUs, &actualTimeUs, formatChange); readBuffer(counterpartType, -1, NULL, formatChange); - ALOGV("timeUs %lld actualTimeUs %lld", timeUs, actualTimeUs); + ALOGV("timeUs %lld actualTimeUs %lld", (long long)timeUs, (long long)actualTimeUs); break; } diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp index 1bd4e57..a028b01 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp @@ -971,7 +971,7 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { CHECK(msg->findInt32("needNotify", &needNotify)); ALOGV("kWhatSeek seekTimeUs=%lld us, needNotify=%d", - seekTimeUs, needNotify); + (long long)seekTimeUs, needNotify); mDeferredActions.push_back( new FlushDecoderAction(FLUSH_CMD_FLUSH /* audio */, @@ -1336,8 +1336,6 @@ void NuPlayer::updateVideoSize( } int32_t displayWidth, displayHeight; - int32_t cropLeft, cropTop, cropRight, cropBottom; - if (outputFormat != NULL) { int32_t width, height; CHECK(outputFormat->findInt32("width", &width)); @@ -1419,7 +1417,11 @@ void NuPlayer::flushDecoder(bool audio, bool needShutdown) { // Make sure we don't continue to scan sources until we finish flushing. ++mScanSourcesGeneration; - mScanSourcesPending = false; + if (mScanSourcesPending) { + mDeferredActions.push_back( + new SimpleAction(&NuPlayer::performScanSources)); + mScanSourcesPending = false; + } decoder->signalFlush(); @@ -1570,7 +1572,7 @@ void NuPlayer::processDeferredActions() { void NuPlayer::performSeek(int64_t seekTimeUs, bool needNotify) { ALOGV("performSeek seekTimeUs=%lld us (%.2f secs), needNotify(%d)", - seekTimeUs, + (long long)seekTimeUs, seekTimeUs / 1E6, needNotify); diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerCCDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerCCDecoder.cpp index cf3e8ad..ac3c6b6 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerCCDecoder.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerCCDecoder.cpp @@ -51,6 +51,7 @@ static bool isNullPad(CCData *cc) { return cc->mData1 < 0x10 && cc->mData2 < 0x10; } +static void dumpBytePair(const sp<ABuffer> &ccBuf) __attribute__ ((unused)); static void dumpBytePair(const sp<ABuffer> &ccBuf) { size_t offset = 0; AString out; diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp index d521c64..65e80c3 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp @@ -82,14 +82,16 @@ void NuPlayer::Decoder::onMessageReceived(const sp<AMessage> &msg) { switch (msg->what()) { case kWhatCodecNotify: { + int32_t cbID; + CHECK(msg->findInt32("callbackID", &cbID)); + + ALOGV("[%s] kWhatCodecNotify: cbID = %d, paused = %d", + mIsAudio ? "audio" : "video", cbID, mPaused); + if (mPaused) { break; } - int32_t cbID; - CHECK(msg->findInt32("callbackID", &cbID)); - - ALOGV("kWhatCodecNotify: cbID = %d", cbID); switch (cbID) { case MediaCodec::CB_INPUT_AVAILABLE: { @@ -356,11 +358,14 @@ void NuPlayer::Decoder::onShutdown(bool notifyComplete) { } } -void NuPlayer::Decoder::doRequestBuffers() { +/* + * returns true if we should request more data + */ +bool NuPlayer::Decoder::doRequestBuffers() { // mRenderer is only NULL if we have a legacy widevine source that // is not yet ready. In this case we must not fetch input. if (isDiscontinuityPending() || mRenderer == NULL) { - return; + return false; } status_t err = OK; while (err == OK && !mDequeuedInputBuffers.empty()) { @@ -380,10 +385,8 @@ void NuPlayer::Decoder::doRequestBuffers() { } } - if (err == -EWOULDBLOCK - && mSource->feedMoreTSData() == OK) { - scheduleRequestBuffers(); - } + return err == -EWOULDBLOCK + && mSource->feedMoreTSData() == OK; } void NuPlayer::Decoder::handleError(int32_t err) @@ -846,9 +849,6 @@ void NuPlayer::Decoder::finishHandleDiscontinuity(bool flushOnTimeChange) { doFlush(false /* notifyComplete */); signalResume(false /* notifyComplete */); } - - // restart fetching input - scheduleRequestBuffers(); } // Notify NuPlayer to either shutdown decoder, or rescan sources diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h index 0c0e90c..9f0ef1b5 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h @@ -45,7 +45,7 @@ protected: virtual void onResume(bool notifyComplete); virtual void onFlush(); virtual void onShutdown(bool notifyComplete); - virtual void doRequestBuffers(); + virtual bool doRequestBuffers(); private: enum { diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.cpp index 4636f0a..36b41ec 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.cpp @@ -103,16 +103,13 @@ void NuPlayer::DecoderBase::onRequestInputBuffers() { return; } - doRequestBuffers(); -} + // doRequestBuffers() return true if we should request more data + if (doRequestBuffers()) { + mRequestInputBuffersPending = true; -void NuPlayer::DecoderBase::scheduleRequestBuffers() { - if (mRequestInputBuffersPending) { - return; + sp<AMessage> msg = new AMessage(kWhatRequestInputBuffers, this); + msg->post(10 * 1000ll); } - mRequestInputBuffersPending = true; - sp<AMessage> msg = new AMessage(kWhatRequestInputBuffers, this); - msg->post(10 * 1000ll); } void NuPlayer::DecoderBase::onMessageReceived(const sp<AMessage> &msg) { diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.h b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.h index 331a2a8..262f5d5 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.h @@ -69,8 +69,7 @@ protected: virtual void onShutdown(bool notifyComplete) = 0; void onRequestInputBuffers(); - void scheduleRequestBuffers(); - virtual void doRequestBuffers() = 0; + virtual bool doRequestBuffers() = 0; virtual void handleError(int32_t err); sp<AMessage> mNotify; diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.cpp index 563de5e..fdb9039 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.cpp @@ -113,7 +113,10 @@ bool NuPlayer::DecoderPassThrough::isDoneFetching() const { return mCachedBytes >= kMaxCachedBytes || mReachedEOS || mPaused; } -void NuPlayer::DecoderPassThrough::doRequestBuffers() { +/* + * returns true if we should request more data + */ +bool NuPlayer::DecoderPassThrough::doRequestBuffers() { status_t err = OK; while (!isDoneFetching()) { sp<AMessage> msg = new AMessage(); @@ -126,10 +129,8 @@ void NuPlayer::DecoderPassThrough::doRequestBuffers() { onInputBufferFetched(msg); } - if (err == -EWOULDBLOCK - && mSource->feedMoreTSData() == OK) { - scheduleRequestBuffers(); - } + return err == -EWOULDBLOCK + && mSource->feedMoreTSData() == OK; } status_t NuPlayer::DecoderPassThrough::dequeueAccessUnit(sp<ABuffer> *accessUnit) { diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.h b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.h index 173cfbd..b7dcb8d 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.h @@ -45,7 +45,7 @@ protected: virtual void onResume(bool notifyComplete); virtual void onFlush(); virtual void onShutdown(bool notifyComplete); - virtual void doRequestBuffers(); + virtual bool doRequestBuffers(); private: enum { diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp index 827bdc1..f8be16a 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp @@ -856,7 +856,7 @@ void NuPlayer::Renderer::onDrainVideoQueue() { if (tooLate) { ALOGV("video late by %lld us (%.2f secs)", - mVideoLateByUs, mVideoLateByUs / 1E6); + (long long)mVideoLateByUs, mVideoLateByUs / 1E6); } else { int64_t mediaUs = 0; mMediaClock->getMediaTime(realTimeUs, &mediaUs); @@ -1178,7 +1178,7 @@ void NuPlayer::Renderer::onPause() { ALOGW("Renderer::onPause() called while already paused!"); return; } - int64_t currentPositionUs; + { Mutex::Autolock autoLock(mLock); ++mAudioDrainGeneration; @@ -1196,7 +1196,7 @@ void NuPlayer::Renderer::onPause() { startAudioOffloadPauseTimeout(); } - ALOGV("now paused audio queue has %d entries, video has %d entries", + ALOGV("now paused audio queue has %zu entries, video has %zu entries", mAudioQueue.size(), mVideoQueue.size()); } @@ -1289,7 +1289,7 @@ int64_t NuPlayer::Renderer::getPlayedOutAudioDurationUs(int64_t nowUs) { CHECK_EQ(res, (status_t)OK); numFramesPlayedAt = nowUs; numFramesPlayedAt += 1000LL * mAudioSink->latency() / 2; /* XXX */ - //ALOGD("getPosition: %d %lld", numFramesPlayed, numFramesPlayedAt); + //ALOGD("getPosition: %u %lld", numFramesPlayed, (long long)numFramesPlayedAt); } //CHECK_EQ(numFramesPlayed & (1 << 31), 0); // can't be negative until 12.4 hrs, test diff --git a/media/libmediaplayerservice/tests/Android.mk b/media/libmediaplayerservice/tests/Android.mk index 7bc78ff..8cbf782 100644 --- a/media/libmediaplayerservice/tests/Android.mk +++ b/media/libmediaplayerservice/tests/Android.mk @@ -18,6 +18,9 @@ LOCAL_C_INCLUDES := \ frameworks/av/include \ frameworks/av/media/libmediaplayerservice \ +LOCAL_CFLAGS += -Werror -Wall +LOCAL_CLANG := true + LOCAL_32_BIT_ONLY := true include $(BUILD_NATIVE_TEST) diff --git a/media/libmediaplayerservice/tests/DrmSessionManager_test.cpp b/media/libmediaplayerservice/tests/DrmSessionManager_test.cpp index d3e760b..de350a1 100644 --- a/media/libmediaplayerservice/tests/DrmSessionManager_test.cpp +++ b/media/libmediaplayerservice/tests/DrmSessionManager_test.cpp @@ -98,17 +98,17 @@ protected: mDrmSessionManager->addSession(kTestPid2, mTestDrm2, mSessionId2); mDrmSessionManager->addSession(kTestPid2, mTestDrm2, mSessionId3); const PidSessionInfosMap& map = sessionMap(); - EXPECT_EQ(2, map.size()); + EXPECT_EQ(2u, map.size()); ssize_t index1 = map.indexOfKey(kTestPid1); ASSERT_GE(index1, 0); const SessionInfos& infos1 = map[index1]; - EXPECT_EQ(1, infos1.size()); + EXPECT_EQ(1u, infos1.size()); ExpectEqSessionInfo(infos1[0], mTestDrm1, mSessionId1, 0); ssize_t index2 = map.indexOfKey(kTestPid2); ASSERT_GE(index2, 0); const SessionInfos& infos2 = map[index2]; - EXPECT_EQ(2, infos2.size()); + EXPECT_EQ(2u, infos2.size()); ExpectEqSessionInfo(infos2[0], mTestDrm2, mSessionId2, 1); ExpectEqSessionInfo(infos2[1], mTestDrm2, mSessionId3, 2); } @@ -185,11 +185,11 @@ TEST_F(DrmSessionManagerTest, removeSession) { mDrmSessionManager->removeSession(mSessionId2); const PidSessionInfosMap& map = sessionMap(); - EXPECT_EQ(2, map.size()); + EXPECT_EQ(2u, map.size()); const SessionInfos& infos1 = map.valueFor(kTestPid1); const SessionInfos& infos2 = map.valueFor(kTestPid2); - EXPECT_EQ(1, infos1.size()); - EXPECT_EQ(1, infos2.size()); + EXPECT_EQ(1u, infos1.size()); + EXPECT_EQ(1u, infos2.size()); // mSessionId2 has been removed. ExpectEqSessionInfo(infos2[0], mTestDrm2, mSessionId3, 2); } @@ -207,7 +207,7 @@ TEST_F(DrmSessionManagerTest, removeDrm) { const PidSessionInfosMap& map = sessionMap(); const SessionInfos& infos2 = map.valueFor(kTestPid2); - EXPECT_EQ(1, infos2.size()); + EXPECT_EQ(1u, infos2.size()); // mTestDrm2 has been removed. ExpectEqSessionInfo(infos2[0], drm, sessionId, 3); } @@ -220,7 +220,7 @@ TEST_F(DrmSessionManagerTest, reclaimSession) { EXPECT_FALSE(mDrmSessionManager->reclaimSession(50)); EXPECT_TRUE(mDrmSessionManager->reclaimSession(10)); - EXPECT_EQ(1, mTestDrm1->reclaimedSessions().size()); + EXPECT_EQ(1u, mTestDrm1->reclaimedSessions().size()); EXPECT_TRUE(isEqualSessionId(mSessionId1, mTestDrm1->reclaimedSessions()[0])); mDrmSessionManager->removeSession(mSessionId1); @@ -233,7 +233,7 @@ TEST_F(DrmSessionManagerTest, reclaimSession) { mDrmSessionManager->addSession(15, drm, sessionId); EXPECT_TRUE(mDrmSessionManager->reclaimSession(18)); - EXPECT_EQ(1, mTestDrm2->reclaimedSessions().size()); + EXPECT_EQ(1u, mTestDrm2->reclaimedSessions().size()); // mSessionId2 is reclaimed. EXPECT_TRUE(isEqualSessionId(mSessionId2, mTestDrm2->reclaimedSessions()[0])); } diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk index 85ef401..45581f3 100644 --- a/media/libstagefright/Android.mk +++ b/media/libstagefright/Android.mk @@ -123,7 +123,7 @@ LOCAL_SHARED_LIBRARIES += \ libdl \ libRScpp \ -LOCAL_CFLAGS += -Wno-multichar -Werror +LOCAL_CFLAGS += -Wno-multichar -Werror -Wall LOCAL_CLANG := true LOCAL_MODULE:= libstagefright diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp index 003b09a..beb12ec 100644 --- a/media/libstagefright/MPEG4Writer.cpp +++ b/media/libstagefright/MPEG4Writer.cpp @@ -63,9 +63,11 @@ static const uint8_t kNalUnitTypeSeqParamSet = 0x07; static const uint8_t kNalUnitTypePicParamSet = 0x08; static const int64_t kInitialDelayTimeUs = 700000LL; -static const char kMetaKey_Model[] = "com.android.model"; static const char kMetaKey_Version[] = "com.android.version"; +#ifdef SHOW_MODEL_BUILD +static const char kMetaKey_Model[] = "com.android.model"; static const char kMetaKey_Build[] = "com.android.build"; +#endif static const char kMetaKey_CaptureFps[] = "com.android.capture.fps"; /* uncomment to include model and build in meta */ diff --git a/media/libstagefright/MediaCodecListOverrides.cpp b/media/libstagefright/MediaCodecListOverrides.cpp index 867a223..265b1ea 100644 --- a/media/libstagefright/MediaCodecListOverrides.cpp +++ b/media/libstagefright/MediaCodecListOverrides.cpp @@ -302,10 +302,10 @@ void exportResultsToXML(const char *fileName, const KeyedVector<AString, CodecSe char *buf = (char *)malloc(size); if (fread(buf, size, 1, f) == 1) { overrides.setTo(buf, size); -#if LOG_NDEBUG == 0 - ALOGV("Existing overrides:"); - printLongString(buf, size); -#endif + if (!LOG_NDEBUG) { + ALOGV("Existing overrides:"); + printLongString(buf, size); + } } else { ALOGE("Failed to read %s", fileName); } @@ -385,10 +385,10 @@ void exportResultsToXML(const char *fileName, const KeyedVector<AString, CodecSe } } -#if LOG_NDEBUG == 0 - ALOGV("New overrides:"); - printLongString(overrides.c_str(), overrides.size()); -#endif + if (!LOG_NDEBUG) { + ALOGV("New overrides:"); + printLongString(overrides.c_str(), overrides.size()); + } f = fopen(fileName, "wb"); if (f == NULL) { diff --git a/media/libstagefright/MediaCodecSource.cpp b/media/libstagefright/MediaCodecSource.cpp index 6568d25..b272448 100644 --- a/media/libstagefright/MediaCodecSource.cpp +++ b/media/libstagefright/MediaCodecSource.cpp @@ -682,7 +682,6 @@ void MediaCodecSource::onMessageReceived(const sp<AMessage> &msg) { size_t size; int64_t timeUs; int32_t flags; - native_handle_t* handle = NULL; CHECK(msg->findInt32("index", &index)); CHECK(msg->findSize("offset", &offset)); diff --git a/media/libstagefright/Utils.cpp b/media/libstagefright/Utils.cpp index dfe8ad1..0d8e64a 100644 --- a/media/libstagefright/Utils.cpp +++ b/media/libstagefright/Utils.cpp @@ -852,14 +852,32 @@ HLSTime::HLSTime(const sp<AMessage>& meta) : } } -int64_t HLSTime::getSegmentTimeUs(bool midpoint) const { +int64_t HLSTime::getSegmentTimeUs() const { int64_t segmentStartTimeUs = -1ll; if (mMeta != NULL) { CHECK(mMeta->findInt64("segmentStartTimeUs", &segmentStartTimeUs)); - if (midpoint) { + + int64_t segmentFirstTimeUs; + if (mMeta->findInt64("segmentFirstTimeUs", &segmentFirstTimeUs)) { + segmentStartTimeUs += mTimeUs - segmentFirstTimeUs; + } + + // adjust segment time by playlist age (for live streaming) + int64_t playlistTimeUs; + if (mMeta->findInt64("playlistTimeUs", &playlistTimeUs)) { + int64_t playlistAgeUs = ALooper::GetNowUs() - playlistTimeUs; + int64_t durationUs; CHECK(mMeta->findInt64("segmentDurationUs", &durationUs)); - segmentStartTimeUs += durationUs / 2; + + // round to nearest whole segment + playlistAgeUs = (playlistAgeUs + durationUs / 2) + / durationUs * durationUs; + + segmentStartTimeUs -= playlistAgeUs; + if (segmentStartTimeUs < 0) { + segmentStartTimeUs = 0; + } } } return segmentStartTimeUs; diff --git a/media/libstagefright/codecs/mpeg2dec/SoftMPEG2.cpp b/media/libstagefright/codecs/mpeg2dec/SoftMPEG2.cpp index e382f4c..78b3ab4 100644 --- a/media/libstagefright/codecs/mpeg2dec/SoftMPEG2.cpp +++ b/media/libstagefright/codecs/mpeg2dec/SoftMPEG2.cpp @@ -245,6 +245,7 @@ status_t SoftMPEG2::setFlushMode() { return UNKNOWN_ERROR; } + mWaitForI = true; mIsInFlush = true; return OK; } @@ -257,6 +258,7 @@ status_t SoftMPEG2::initDecoder() { UWORD32 u4_share_disp_buf; mNumCores = GetCPUCoreCount(); + mWaitForI = true; /* Initialize number of ref and reorder modes (for MPEG2) */ u4_num_reorder_frames = 16; @@ -448,6 +450,8 @@ status_t SoftMPEG2::reInitDecoder() { void SoftMPEG2::onReset() { SoftVideoDecoderOMXComponent::onReset(); + mWaitForI = true; + resetDecoder(); resetPlugin(); } @@ -710,11 +714,22 @@ void SoftMPEG2::onQueueFilled(OMX_U32 portIndex) { outHeader->nTimeStamp = mTimeStamps[timeStampIdx]; mTimeStampsValid[timeStampIdx] = false; - outInfo->mOwnedByUs = false; - outQueue.erase(outQueue.begin()); - outInfo = NULL; - notifyFillBufferDone(outHeader); - outHeader = NULL; + /* mWaitForI waits for the first I picture. Once made FALSE, it + has to remain false till explicitly set to TRUE. */ + mWaitForI = mWaitForI && !(IV_I_FRAME == s_dec_op.e_pic_type); + + if (mWaitForI) { + s_dec_op.u4_output_present = false; + } else { + ALOGV("Output timestamp: %lld, res: %ux%u", + (long long)outHeader->nTimeStamp, mWidth, mHeight); + DUMP_TO_FILE(mOutFile, outHeader->pBuffer, outHeader->nFilledLen); + outInfo->mOwnedByUs = false; + outQueue.erase(outQueue.begin()); + outInfo = NULL; + notifyFillBufferDone(outHeader); + outHeader = NULL; + } } else { /* If in flush mode and no output is returned by the codec, * then come out of flush mode */ diff --git a/media/libstagefright/codecs/mpeg2dec/SoftMPEG2.h b/media/libstagefright/codecs/mpeg2dec/SoftMPEG2.h index f7b1961..a625e08 100644 --- a/media/libstagefright/codecs/mpeg2dec/SoftMPEG2.h +++ b/media/libstagefright/codecs/mpeg2dec/SoftMPEG2.h @@ -105,6 +105,7 @@ private: // codec. So the codec is switching to decode the new resolution. bool mChangingResolution; bool mFlushNeeded; + bool mWaitForI; status_t initDecoder(); status_t deInitDecoder(); diff --git a/media/libstagefright/filters/Android.mk b/media/libstagefright/filters/Android.mk index c3eaa54..179f054 100644 --- a/media/libstagefright/filters/Android.mk +++ b/media/libstagefright/filters/Android.mk @@ -20,7 +20,7 @@ LOCAL_C_INCLUDES := \ intermediates := $(call intermediates-dir-for,STATIC_LIBRARIES,libRS,TARGET,) LOCAL_C_INCLUDES += $(intermediates) -LOCAL_CFLAGS += -Wno-multichar -Werror +LOCAL_CFLAGS += -Wno-multichar -Werror -Wall LOCAL_CLANG := true LOCAL_MODULE:= libstagefright_mediafilter diff --git a/media/libstagefright/foundation/Android.mk b/media/libstagefright/foundation/Android.mk index 3c95f0b..c68264c 100644 --- a/media/libstagefright/foundation/Android.mk +++ b/media/libstagefright/foundation/Android.mk @@ -29,7 +29,7 @@ LOCAL_SHARED_LIBRARIES := \ liblog \ libpowermanager -LOCAL_CFLAGS += -Wno-multichar -Werror +LOCAL_CFLAGS += -Wno-multichar -Werror -Wall LOCAL_CLANG := true LOCAL_MODULE:= libstagefright_foundation diff --git a/media/libstagefright/http/Android.mk b/media/libstagefright/http/Android.mk index a627898..5fb51c1 100644 --- a/media/libstagefright/http/Android.mk +++ b/media/libstagefright/http/Android.mk @@ -21,7 +21,7 @@ LOCAL_MODULE:= libstagefright_http_support LOCAL_CFLAGS += -Wno-multichar -LOCAL_CFLAGS += -Werror +LOCAL_CFLAGS += -Werror -Wall LOCAL_CLANG := true include $(BUILD_SHARED_LIBRARY) diff --git a/media/libstagefright/httplive/Android.mk b/media/libstagefright/httplive/Android.mk index a30be66..2639deb 100644 --- a/media/libstagefright/httplive/Android.mk +++ b/media/libstagefright/httplive/Android.mk @@ -12,7 +12,7 @@ LOCAL_C_INCLUDES:= \ $(TOP)/frameworks/av/media/libstagefright \ $(TOP)/frameworks/native/include/media/openmax -LOCAL_CFLAGS += -Werror +LOCAL_CFLAGS += -Werror -Wall LOCAL_CLANG := true LOCAL_SHARED_LIBRARIES := \ diff --git a/media/libstagefright/httplive/LiveSession.cpp b/media/libstagefright/httplive/LiveSession.cpp index 203444a..764ff82 100644 --- a/media/libstagefright/httplive/LiveSession.cpp +++ b/media/libstagefright/httplive/LiveSession.cpp @@ -67,7 +67,7 @@ struct LiveSession::BandwidthEstimator : public RefBase { BandwidthEstimator(); void addBandwidthMeasurement(size_t numBytes, int64_t delayUs); - bool estimateBandwidth(int32_t *bandwidth); + bool estimateBandwidth(int32_t *bandwidth, bool *isStable = NULL); private: // Bandwidth estimation parameters @@ -81,6 +81,9 @@ private: Mutex mLock; List<BandwidthEntry> mBandwidthHistory; + List<int32_t> mPrevEstimates; + bool mHasNewSample; + bool mIsStable; int64_t mTotalTransferTimeUs; size_t mTotalTransferBytes; @@ -88,6 +91,8 @@ private: }; LiveSession::BandwidthEstimator::BandwidthEstimator() : + mHasNewSample(false), + mIsStable(true), mTotalTransferTimeUs(0), mTotalTransferBytes(0) { } @@ -102,6 +107,7 @@ void LiveSession::BandwidthEstimator::addBandwidthMeasurement( mTotalTransferTimeUs += delayUs; mTotalTransferBytes += numBytes; mBandwidthHistory.push_back(entry); + mHasNewSample = true; // trim old samples, keeping at least kMaxBandwidthHistoryItems samples, // and total transfer time at least kMaxBandwidthHistoryWindowUs. @@ -116,14 +122,43 @@ void LiveSession::BandwidthEstimator::addBandwidthMeasurement( } } -bool LiveSession::BandwidthEstimator::estimateBandwidth(int32_t *bandwidthBps) { +bool LiveSession::BandwidthEstimator::estimateBandwidth(int32_t *bandwidthBps, bool *isStable) { AutoMutex autoLock(mLock); if (mBandwidthHistory.size() < 2) { return false; } + if (!mHasNewSample) { + *bandwidthBps = *(--mPrevEstimates.end()); + if (isStable) { + *isStable = mIsStable; + } + return true; + } + *bandwidthBps = ((double)mTotalTransferBytes * 8E6 / mTotalTransferTimeUs); + mPrevEstimates.push_back(*bandwidthBps); + while (mPrevEstimates.size() > 3) { + mPrevEstimates.erase(mPrevEstimates.begin()); + } + mHasNewSample = false; + + int32_t minEstimate = -1, maxEstimate = -1; + List<int32_t>::iterator it; + for (it = mPrevEstimates.begin(); it != mPrevEstimates.end(); it++) { + int32_t estimate = *it; + if (minEstimate < 0 || minEstimate > estimate) { + minEstimate = estimate; + } + if (maxEstimate < 0 || maxEstimate < estimate) { + maxEstimate = estimate; + } + } + mIsStable = (maxEstimate <= minEstimate * 4 / 3); + if (isStable) { + *isStable = mIsStable; + } return true; } @@ -1930,7 +1965,7 @@ void LiveSession::onChangeConfiguration3(const sp<AMessage> &msg) { fetcher->getFetcherID(), (long long)startTime.mTimeUs, (long long)mLastSeekTimeUs, - (long long)startTime.getSegmentTimeUs(true /* midpoint */), + (long long)startTime.getSegmentTimeUs(), seekMode); // Set the target segment start time to the middle point of the @@ -1945,7 +1980,7 @@ void LiveSession::onChangeConfiguration3(const sp<AMessage> &msg) { sources[kSubtitleIndex], getMetadataSource(sources, mNewStreamMask, switching), startTime.mTimeUs < 0 ? mLastSeekTimeUs : startTime.mTimeUs, - startTime.getSegmentTimeUs(true /* midpoint */), + startTime.getSegmentTimeUs(), startTime.mSeq, seekMode); } @@ -2296,7 +2331,8 @@ bool LiveSession::switchBandwidthIfNeeded(bool bufferHigh, bool bufferLow) { } int32_t bandwidthBps; - if (mBandwidthEstimator->estimateBandwidth(&bandwidthBps)) { + bool isStable; + if (mBandwidthEstimator->estimateBandwidth(&bandwidthBps, &isStable)) { ALOGV("bandwidth estimated at %.2f kbps", bandwidthBps / 1024.0f); mLastBandwidthBps = bandwidthBps; } else { @@ -2308,12 +2344,18 @@ bool LiveSession::switchBandwidthIfNeeded(bool bufferHigh, bool bufferLow) { // canSwithDown and canSwitchUp can't both be true. // we only want to switch up when measured bw is 120% higher than current variant, // and we only want to switch down when measured bw is below current variant. - bool canSwithDown = bufferLow + bool canSwitchDown = bufferLow && (bandwidthBps < (int32_t)curBandwidth); bool canSwitchUp = bufferHigh && (bandwidthBps > (int32_t)curBandwidth * 12 / 10); - if (canSwithDown || canSwitchUp) { + if (canSwitchDown || canSwitchUp) { + // bandwidth estimating has some delay, if we have to downswitch when + // it hasn't stabilized, be very conservative on bandwidth. + if (!isStable && canSwitchDown) { + bandwidthBps /= 2; + } + ssize_t bandwidthIndex = getBandwidthIndex(bandwidthBps); // it's possible that we're checking for canSwitchUp case, but the returned @@ -2321,7 +2363,7 @@ bool LiveSession::switchBandwidthIfNeeded(bool bufferHigh, bool bufferLow) { // of measured bw. In that case we don't want to do anything, since we have // both enough buffer and enough bw. if ((canSwitchUp && bandwidthIndex > mCurBandwidthIndex) - || (canSwithDown && bandwidthIndex < mCurBandwidthIndex)) { + || (canSwitchDown && bandwidthIndex < mCurBandwidthIndex)) { // if not yet prepared, just restart again with new bw index. // this is faster and playback experience is cleaner. changeConfiguration( diff --git a/media/libstagefright/httplive/M3UParser.cpp b/media/libstagefright/httplive/M3UParser.cpp index ef9145c..ff2bb27 100644 --- a/media/libstagefright/httplive/M3UParser.cpp +++ b/media/libstagefright/httplive/M3UParser.cpp @@ -250,6 +250,9 @@ M3UParser::M3UParser( mIsVariantPlaylist(false), mIsComplete(false), mIsEvent(false), + mFirstSeqNumber(-1), + mLastSeqNumber(-1), + mTargetDurationUs(-1ll), mDiscontinuitySeq(0), mDiscontinuityCount(0), mSelectedIndex(-1) { @@ -283,6 +286,19 @@ size_t M3UParser::getDiscontinuitySeq() const { return mDiscontinuitySeq; } +int64_t M3UParser::getTargetDuration() const { + return mTargetDurationUs; +} + +int32_t M3UParser::getFirstSeqNumber() const { + return mFirstSeqNumber; +} + +void M3UParser::getSeqNumberRange(int32_t *firstSeq, int32_t *lastSeq) const { + *firstSeq = mFirstSeqNumber; + *lastSeq = mLastSeqNumber; +} + sp<AMessage> M3UParser::meta() { return mMeta; } @@ -664,11 +680,22 @@ status_t M3UParser::parse(const void *_data, size_t size) { } // error checking of all fields that's required to appear once - // (currently only checking "target-duration") - int32_t targetDurationSecs; - if (!mIsVariantPlaylist && (mMeta == NULL || !mMeta->findInt32( - "target-duration", &targetDurationSecs))) { - return ERROR_MALFORMED; + // (currently only checking "target-duration"), and + // initialization of playlist properties (eg. mTargetDurationUs) + if (!mIsVariantPlaylist) { + int32_t targetDurationSecs; + if (mMeta == NULL || !mMeta->findInt32( + "target-duration", &targetDurationSecs)) { + ALOGE("Media playlist missing #EXT-X-TARGETDURATION"); + return ERROR_MALFORMED; + } + mTargetDurationUs = targetDurationSecs * 1000000ll; + + mFirstSeqNumber = 0; + if (mMeta != NULL) { + mMeta->findInt32("media-sequence", &mFirstSeqNumber); + } + mLastSeqNumber = mFirstSeqNumber + mItems.size() - 1; } return OK; diff --git a/media/libstagefright/httplive/M3UParser.h b/media/libstagefright/httplive/M3UParser.h index fef361f..fa648ed 100644 --- a/media/libstagefright/httplive/M3UParser.h +++ b/media/libstagefright/httplive/M3UParser.h @@ -36,6 +36,9 @@ struct M3UParser : public RefBase { bool isComplete() const; bool isEvent() const; size_t getDiscontinuitySeq() const; + int64_t getTargetDuration() const; + int32_t getFirstSeqNumber() const; + void getSeqNumberRange(int32_t *firstSeq, int32_t *lastSeq) const; sp<AMessage> meta(); @@ -70,6 +73,9 @@ private: bool mIsVariantPlaylist; bool mIsComplete; bool mIsEvent; + int32_t mFirstSeqNumber; + int32_t mLastSeqNumber; + int64_t mTargetDurationUs; size_t mDiscontinuitySeq; int32_t mDiscontinuityCount; diff --git a/media/libstagefright/httplive/PlaylistFetcher.cpp b/media/libstagefright/httplive/PlaylistFetcher.cpp index a4e523d..8350c1b 100644 --- a/media/libstagefright/httplive/PlaylistFetcher.cpp +++ b/media/libstagefright/httplive/PlaylistFetcher.cpp @@ -160,6 +160,7 @@ PlaylistFetcher::PlaylistFetcher( mDiscontinuitySeq(-1ll), mStartTimeUsRelative(false), mLastPlaylistFetchTimeUs(-1ll), + mPlaylistTimeUs(-1ll), mSeqNumber(-1), mNumRetries(0), mStartup(true), @@ -191,14 +192,9 @@ int32_t PlaylistFetcher::getFetcherID() const { int64_t PlaylistFetcher::getSegmentStartTimeUs(int32_t seqNumber) const { CHECK(mPlaylist != NULL); - int32_t firstSeqNumberInPlaylist; - if (mPlaylist->meta() == NULL || !mPlaylist->meta()->findInt32( - "media-sequence", &firstSeqNumberInPlaylist)) { - firstSeqNumberInPlaylist = 0; - } - - int32_t lastSeqNumberInPlaylist = - firstSeqNumberInPlaylist + (int32_t)mPlaylist->size() - 1; + int32_t firstSeqNumberInPlaylist, lastSeqNumberInPlaylist; + mPlaylist->getSeqNumberRange( + &firstSeqNumberInPlaylist, &lastSeqNumberInPlaylist); CHECK_GE(seqNumber, firstSeqNumberInPlaylist); CHECK_LE(seqNumber, lastSeqNumberInPlaylist); @@ -222,14 +218,9 @@ int64_t PlaylistFetcher::getSegmentStartTimeUs(int32_t seqNumber) const { int64_t PlaylistFetcher::getSegmentDurationUs(int32_t seqNumber) const { CHECK(mPlaylist != NULL); - int32_t firstSeqNumberInPlaylist; - if (mPlaylist->meta() == NULL || !mPlaylist->meta()->findInt32( - "media-sequence", &firstSeqNumberInPlaylist)) { - firstSeqNumberInPlaylist = 0; - } - - int32_t lastSeqNumberInPlaylist = - firstSeqNumberInPlaylist + (int32_t)mPlaylist->size() - 1; + int32_t firstSeqNumberInPlaylist, lastSeqNumberInPlaylist; + mPlaylist->getSeqNumberRange( + &firstSeqNumberInPlaylist, &lastSeqNumberInPlaylist); CHECK_GE(seqNumber, firstSeqNumberInPlaylist); CHECK_LE(seqNumber, lastSeqNumberInPlaylist); @@ -257,10 +248,7 @@ int64_t PlaylistFetcher::delayUsToRefreshPlaylist() const { return (~0llu >> 1); } - int32_t targetDurationSecs; - CHECK(mPlaylist->meta()->findInt32("target-duration", &targetDurationSecs)); - - int64_t targetDurationUs = targetDurationSecs * 1000000ll; + int64_t targetDurationUs = mPlaylist->getTargetDuration(); int64_t minPlaylistAgeUs; @@ -750,24 +738,15 @@ void PlaylistFetcher::queueDiscontinuity( } void PlaylistFetcher::onMonitorQueue() { - bool downloadMore = false; - // in the middle of an unfinished download, delay // playlist refresh as it'll change seq numbers if (!mDownloadState->hasSavedState()) { refreshPlaylist(); } - int32_t targetDurationSecs; int64_t targetDurationUs = kMinBufferedDurationUs; if (mPlaylist != NULL) { - 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; + targetDurationUs = mPlaylist->getTargetDuration(); } int64_t bufferedDurationUs = 0ll; @@ -865,6 +844,7 @@ status_t PlaylistFetcher::refreshPlaylist() { if (!mPlaylist->isComplete()) { updateTargetDuration(); } + mPlaylistTimeUs = ALooper::GetNowUs(); } mLastPlaylistFetchTimeUs = ALooper::GetNowUs(); @@ -884,9 +864,7 @@ bool PlaylistFetcher::shouldPauseDownload() { } // Calculate threshold to abort current download - int32_t targetDurationSecs; - CHECK(mPlaylist->meta()->findInt32("target-duration", &targetDurationSecs)); - int64_t targetDurationUs = targetDurationSecs * 1000000ll; + int64_t targetDurationUs = mPlaylist->getTargetDuration(); int64_t thresholdUs = -1; { AutoMutex _l(mThresholdLock); @@ -949,12 +927,8 @@ bool PlaylistFetcher::initDownloadState( bool discontinuity = false; if (mPlaylist != NULL) { - if (mPlaylist->meta() != NULL) { - mPlaylist->meta()->findInt32("media-sequence", &firstSeqNumberInPlaylist); - } - - lastSeqNumberInPlaylist = - firstSeqNumberInPlaylist + (int32_t)mPlaylist->size() - 1; + mPlaylist->getSeqNumberRange( + &firstSeqNumberInPlaylist, &lastSeqNumberInPlaylist); if (mDiscontinuitySeq < 0) { mDiscontinuitySeq = mPlaylist->getDiscontinuitySeq(); @@ -989,11 +963,18 @@ bool PlaylistFetcher::initDownloadState( // to media time 0) is used to determine the start segment; mStartTimeUs (absolute // timestamps coming from the media container) is used to determine the position // inside a segments. - mSeqNumber = getSeqNumberForTime(mSegmentStartTimeUs); if (mStreamTypeMask != LiveSession::STREAMTYPE_SUBTITLES && mSeekMode != LiveSession::kSeekModeNextSample) { // avoid double fetch/decode - mSeqNumber += 1; + // Use (mSegmentStartTimeUs + 1/2 * targetDurationUs) to search + // for the starting segment in new variant. + // If the two variants' segments are aligned, this gives the + // next segment. If they're not aligned, this gives the segment + // that overlaps no more than 1/2 * targetDurationUs. + mSeqNumber = getSeqNumberForTime(mSegmentStartTimeUs + + mPlaylist->getTargetDuration() / 2); + } else { + mSeqNumber = getSeqNumberForTime(mSegmentStartTimeUs); } ssize_t minSeq = getSeqNumberForDiscontinuity(mDiscontinuitySeq); if (mSeqNumber < minSeq) { @@ -1027,11 +1008,9 @@ bool PlaylistFetcher::initDownloadState( // refresh in increasing fraction (1/2, 1/3, ...) of the // playlist's target duration or 3 seconds, whichever is less int64_t delayUs = kMaxMonitorDelayUs; - if (mPlaylist != NULL && mPlaylist->meta() != NULL) { - int32_t targetDurationSecs; - CHECK(mPlaylist->meta()->findInt32("target-duration", &targetDurationSecs)); - delayUs = mPlaylist->size() * targetDurationSecs * - 1000000ll / (1 + mNumRetries); + if (mPlaylist != NULL) { + delayUs = mPlaylist->size() * mPlaylist->getTargetDuration() + / (1 + mNumRetries); } if (delayUs > kMaxMonitorDelayUs) { delayUs = kMaxMonitorDelayUs; @@ -1158,7 +1137,7 @@ bool PlaylistFetcher::initDownloadState( } queueDiscontinuity( - ATSParser::DISCONTINUITY_FORMATCHANGE, + ATSParser::DISCONTINUITY_FORMAT_ONLY, NULL /* extra */); if (mStartup && mStartTimeUsRelative && mFirstPTSValid) { @@ -1172,6 +1151,8 @@ bool PlaylistFetcher::initDownloadState( // set mStartTimeUs=0, and take all samples from now on. mStartTimeUs = 0; mFirstPTSValid = false; + mIDRFound = false; + mVideoBuffer->clear(); } } @@ -1408,42 +1389,67 @@ void PlaylistFetcher::onDownloadNext() { } } -int32_t PlaylistFetcher::getSeqNumberWithAnchorTime( - int64_t anchorTimeUs, int64_t targetDiffUs) const { - int32_t firstSeqNumberInPlaylist, lastSeqNumberInPlaylist; - if (mPlaylist->meta() == NULL - || !mPlaylist->meta()->findInt32("media-sequence", &firstSeqNumberInPlaylist)) { - firstSeqNumberInPlaylist = 0; +/* + * returns true if we need to adjust mSeqNumber + */ +bool PlaylistFetcher::adjustSeqNumberWithAnchorTime(int64_t anchorTimeUs) { + int32_t firstSeqNumberInPlaylist = mPlaylist->getFirstSeqNumber(); + + int64_t minDiffUs, maxDiffUs; + if (mSeekMode == LiveSession::kSeekModeNextSample) { + minDiffUs = -mPlaylist->getTargetDuration(); + maxDiffUs = 0ll; + } else { + minDiffUs = -mPlaylist->getTargetDuration() / 2; + maxDiffUs = mPlaylist->getTargetDuration(); } - lastSeqNumberInPlaylist = firstSeqNumberInPlaylist + mPlaylist->size() - 1; - int32_t index = mSeqNumber - firstSeqNumberInPlaylist - 1; - // adjust anchorTimeUs to within targetDiffUs from mStartTimeUs - while (index >= 0 && anchorTimeUs - mStartTimeUs > targetDiffUs) { - sp<AMessage> itemMeta; - CHECK(mPlaylist->itemAt(index, NULL /* uri */, &itemMeta)); + int32_t oldSeqNumber = mSeqNumber; + ssize_t index = mSeqNumber - firstSeqNumberInPlaylist; - int64_t itemDurationUs; - CHECK(itemMeta->findInt64("durationUs", &itemDurationUs)); + // adjust anchorTimeUs to within (minDiffUs, maxDiffUs) from mStartTimeUs + int64_t diffUs = anchorTimeUs - mStartTimeUs; + if (diffUs > maxDiffUs) { + while (index > 0 && diffUs > maxDiffUs) { + --index; + + sp<AMessage> itemMeta; + CHECK(mPlaylist->itemAt(index, NULL /* uri */, &itemMeta)); + + int64_t itemDurationUs; + CHECK(itemMeta->findInt64("durationUs", &itemDurationUs)); + + diffUs -= itemDurationUs; + } + } else if (diffUs < minDiffUs) { + while (index + 1 < (ssize_t) mPlaylist->size() + && diffUs < minDiffUs) { + ++index; + + sp<AMessage> itemMeta; + CHECK(mPlaylist->itemAt(index, NULL /* uri */, &itemMeta)); - anchorTimeUs -= itemDurationUs; - --index; + int64_t itemDurationUs; + CHECK(itemMeta->findInt64("durationUs", &itemDurationUs)); + + diffUs += itemDurationUs; + } } - int32_t newSeqNumber = firstSeqNumberInPlaylist + index + 1; - if (newSeqNumber <= lastSeqNumberInPlaylist) { - return newSeqNumber; - } else { - return lastSeqNumberInPlaylist; + mSeqNumber = firstSeqNumberInPlaylist + index; + + if (mSeqNumber != oldSeqNumber) { + FLOGV("guessed wrong seg number: diff %lld out of [%lld, %lld]", + (long long) anchorTimeUs - mStartTimeUs, + (long long) minDiffUs, + (long long) maxDiffUs); + return true; } + return false; } int32_t PlaylistFetcher::getSeqNumberForDiscontinuity(size_t discontinuitySeq) const { - int32_t firstSeqNumberInPlaylist; - if (mPlaylist->meta() == NULL || !mPlaylist->meta()->findInt32( - "media-sequence", &firstSeqNumberInPlaylist)) { - firstSeqNumberInPlaylist = 0; - } + int32_t firstSeqNumberInPlaylist = mPlaylist->getFirstSeqNumber(); size_t index = 0; while (index < mPlaylist->size()) { @@ -1465,12 +1471,6 @@ int32_t PlaylistFetcher::getSeqNumberForDiscontinuity(size_t discontinuitySeq) c } int32_t PlaylistFetcher::getSeqNumberForTime(int64_t timeUs) const { - int32_t firstSeqNumberInPlaylist; - if (mPlaylist->meta() == NULL || !mPlaylist->meta()->findInt32( - "media-sequence", &firstSeqNumberInPlaylist)) { - firstSeqNumberInPlaylist = 0; - } - size_t index = 0; int64_t segmentStartUs = 0; while (index < mPlaylist->size()) { @@ -1493,7 +1493,7 @@ int32_t PlaylistFetcher::getSeqNumberForTime(int64_t timeUs) const { index = mPlaylist->size() - 1; } - return firstSeqNumberInPlaylist + index; + return mPlaylist->getFirstSeqNumber() + index; } const sp<ABuffer> &PlaylistFetcher::setAccessUnitProperties( @@ -1508,14 +1508,13 @@ const sp<ABuffer> &PlaylistFetcher::setAccessUnitProperties( 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)); + accessUnit->meta()->setInt64("segmentFirstTimeUs", mSegmentFirstPTS); accessUnit->meta()->setInt64("segmentDurationUs", getSegmentDurationUs(mSeqNumber)); + if (!mPlaylist->isComplete() && !mPlaylist->isEvent()) { + accessUnit->meta()->setInt64("playlistTimeUs", mPlaylistTimeUs); + } return accessUnit; } @@ -1577,6 +1576,59 @@ status_t PlaylistFetcher::extractAndQueueAccessUnitsFromTs(const sp<ABuffer> &bu // setRange to indicate consumed bytes. buffer->setRange(buffer->offset() + offset, buffer->size() - offset); + if (mSegmentFirstPTS < 0ll) { + // get the smallest first PTS from all streams present in this parser + for (size_t i = mPacketSources.size(); i-- > 0;) { + const LiveSession::StreamType stream = mPacketSources.keyAt(i); + if (stream == LiveSession::STREAMTYPE_SUBTITLES) { + ALOGE("MPEG2 Transport streams do not contain subtitles."); + return ERROR_MALFORMED; + } + ATSParser::SourceType type =LiveSession::getSourceTypeForStream(stream); + sp<AnotherPacketSource> source = + static_cast<AnotherPacketSource *>( + mTSParser->getSource(type).get()); + + if (source == NULL) { + continue; + } + sp<AMessage> meta = source->getMetaAfterLastDequeued(0); + if (meta != NULL) { + int64_t timeUs; + CHECK(meta->findInt64("timeUs", &timeUs)); + if (mSegmentFirstPTS < 0ll || timeUs < mSegmentFirstPTS) { + mSegmentFirstPTS = timeUs; + } + } + } + if (mSegmentFirstPTS < 0ll) { + // didn't find any TS packet, can return early + return OK; + } + if (!mStartTimeUsRelative) { + // mStartup + // mStartup is true until we have queued a packet for all the streams + // we are fetching. We queue packets whose timestamps are greater than + // mStartTimeUs. + // mSegmentStartTimeUs >= 0 + // mSegmentStartTimeUs is non-negative when adapting or switching tracks + // adjustSeqNumberWithAnchorTime(timeUs) == true + // we guessed a seq number that's either too large or too small. + // If this happens, we'll adjust mSeqNumber and restart fetching from new + // location. Note that we only want to adjust once, so set mSegmentStartTimeUs + // to -1 so that we don't enter this chunk next time. + if (mStartup && mSegmentStartTimeUs >= 0 + && adjustSeqNumberWithAnchorTime(mSegmentFirstPTS)) { + mStartTimeUsNotify = mNotify->dup(); + mStartTimeUsNotify->setInt32("what", kWhatStartedAt); + mStartTimeUsNotify->setString("uri", mURI); + mIDRFound = false; + mSegmentStartTimeUs = -1; + return -EAGAIN; + } + } + } + status_t err = OK; for (size_t i = mPacketSources.size(); i-- > 0;) { sp<AnotherPacketSource> packetSource = mPacketSources.valueAt(i); @@ -1611,76 +1663,17 @@ status_t PlaylistFetcher::extractAndQueueAccessUnitsFromTs(const sp<ABuffer> &bu int64_t timeUs; CHECK(accessUnit->meta()->findInt64("timeUs", &timeUs)); - if (mSegmentFirstPTS < 0ll) { - mSegmentFirstPTS = timeUs; - if (!mStartTimeUsRelative) { - int32_t firstSeqNumberInPlaylist; - if (mPlaylist->meta() == NULL || !mPlaylist->meta()->findInt32( - "media-sequence", &firstSeqNumberInPlaylist)) { - firstSeqNumberInPlaylist = 0; - } - - int32_t targetDurationSecs; - CHECK(mPlaylist->meta()->findInt32("target-duration", &targetDurationSecs)); - int64_t targetDurationUs = targetDurationSecs * 1000000ll; - // mStartup - // mStartup is true until we have queued a packet for all the streams - // we are fetching. We queue packets whose timestamps are greater than - // mStartTimeUs. - // mSegmentStartTimeUs >= 0 - // mSegmentStartTimeUs is non-negative when adapting or switching tracks - // mSeqNumber > firstSeqNumberInPlaylist - // don't decrement mSeqNumber if it already points to the 1st segment - // timeUs - mStartTimeUs > targetDurationUs: - // This and the 2 above conditions should only happen when adapting in a live - // stream; the old fetcher has already fetched to mStartTimeUs; the new fetcher - // would start fetching after timeUs, which should be greater than mStartTimeUs; - // the old fetcher would then continue fetching data until timeUs. We don't want - // timeUs to be too far ahead of mStartTimeUs because we want the old fetcher to - // stop as early as possible. The definition of being "too far ahead" is - // arbitrary; here we use targetDurationUs as threshold. - int64_t targetDiffUs = (mSeekMode == LiveSession::kSeekModeNextSample - ? 0 : targetDurationUs); - if (mStartup && mSegmentStartTimeUs >= 0 - && mSeqNumber > firstSeqNumberInPlaylist - && timeUs - mStartTimeUs > targetDiffUs) { - // we just guessed a starting timestamp that is too high when adapting in a - // live stream; re-adjust based on the actual timestamp extracted from the - // media segment; if we didn't move backward after the re-adjustment - // (newSeqNumber), start at least 1 segment prior. - int32_t newSeqNumber = getSeqNumberWithAnchorTime( - timeUs, targetDiffUs); - - FLOGV("guessed wrong seq number: timeUs=%lld, mStartTimeUs=%lld, " - "targetDurationUs=%lld, mSeqNumber=%d, newSeq=%d, firstSeq=%d", - (long long)timeUs, - (long long)mStartTimeUs, - (long long)targetDurationUs, - mSeqNumber, - newSeqNumber, - firstSeqNumberInPlaylist); - - if (newSeqNumber >= mSeqNumber) { - --mSeqNumber; - } else { - mSeqNumber = newSeqNumber; - } - mStartTimeUsNotify = mNotify->dup(); - mStartTimeUsNotify->setInt32("what", kWhatStartedAt); - mStartTimeUsNotify->setString("uri", mURI); - mIDRFound = false; - return -EAGAIN; - } - } - } if (mStartup) { bool startTimeReached = isStartTimeReached(timeUs); if (!startTimeReached || (isAvc && !mIDRFound)) { // buffer up to the closest preceding IDR frame in the next segement, // or the closest succeeding IDR frame after the exact position - FSLOGV(stream, "timeUs=%lld, mStartTimeUs=%lld, mIDRFound=%d", - (long long)timeUs, (long long)mStartTimeUs, mIDRFound); + FSLOGV(stream, "timeUs(%lld)-mStartTimeUs(%lld)=%lld, mIDRFound=%d", + (long long)timeUs, + (long long)mStartTimeUs, + (long long)timeUs - mStartTimeUs, + mIDRFound); if (isAvc) { if (IsIDR(accessUnit)) { mVideoBuffer->clear(); @@ -1821,7 +1814,6 @@ status_t PlaylistFetcher::extractAndQueueAccessUnits( buffer->meta()->setInt64("segmentStartTimeUs", getSegmentStartTimeUs(mSeqNumber)); buffer->meta()->setInt32("discontinuitySeq", mDiscontinuitySeq); buffer->meta()->setInt32("subtitleGeneration", mSubtitleGeneration); - packetSource->queueAccessUnit(buffer); return OK; } @@ -1932,6 +1924,18 @@ status_t PlaylistFetcher::extractAndQueueAccessUnits( mFirstTimeUs = timeUs; } + if (mSegmentFirstPTS < 0ll) { + mSegmentFirstPTS = timeUs; + if (!mStartTimeUsRelative) { + // Duplicated logic from how we handle .ts playlists. + if (mStartup && mSegmentStartTimeUs >= 0 + && adjustSeqNumberWithAnchorTime(timeUs)) { + mSegmentStartTimeUs = -1; + return -EAGAIN; + } + } + } + size_t offset = 0; while (offset < buffer->size()) { const uint8_t *adtsHeader = buffer->data() + offset; @@ -1975,25 +1979,6 @@ status_t PlaylistFetcher::extractAndQueueAccessUnits( } if (mStartTimeUsNotify != NULL) { - int32_t targetDurationSecs; - CHECK(mPlaylist->meta()->findInt32("target-duration", &targetDurationSecs)); - int64_t targetDurationUs = targetDurationSecs * 1000000ll; - - int64_t targetDiffUs =(mSeekMode == LiveSession::kSeekModeNextSample - ? 0 : targetDurationUs); - // Duplicated logic from how we handle .ts playlists. - if (mStartup && mSegmentStartTimeUs >= 0 - && timeUs - mStartTimeUs > targetDiffUs) { - int32_t newSeqNumber = getSeqNumberWithAnchorTime( - timeUs, targetDiffUs); - if (newSeqNumber >= mSeqNumber) { - --mSeqNumber; - } else { - mSeqNumber = newSeqNumber; - } - return -EAGAIN; - } - mStartTimeUsNotify->setInt32("streamMask", LiveSession::STREAMTYPE_AUDIO); mStartup = false; } @@ -2043,13 +2028,9 @@ void PlaylistFetcher::updateDuration() { } void PlaylistFetcher::updateTargetDuration() { - int32_t targetDurationSecs; - CHECK(mPlaylist->meta()->findInt32("target-duration", &targetDurationSecs)); - int64_t targetDurationUs = targetDurationSecs * 1000000ll; - sp<AMessage> msg = mNotify->dup(); msg->setInt32("what", kWhatTargetDurationUpdate); - msg->setInt64("targetDurationUs", targetDurationUs); + msg->setInt64("targetDurationUs", mPlaylist->getTargetDuration()); msg->post(); } diff --git a/media/libstagefright/httplive/PlaylistFetcher.h b/media/libstagefright/httplive/PlaylistFetcher.h index 95de9c3..1f5e9b0 100644 --- a/media/libstagefright/httplive/PlaylistFetcher.h +++ b/media/libstagefright/httplive/PlaylistFetcher.h @@ -138,6 +138,7 @@ private: KeyedVector<AString, sp<ABuffer> > mAESKeyForURI; int64_t mLastPlaylistFetchTimeUs; + int64_t mPlaylistTimeUs; sp<M3UParser> mPlaylist; int32_t mSeqNumber; int32_t mNumRetries; @@ -238,8 +239,7 @@ private: void queueDiscontinuity( ATSParser::DiscontinuityType type, const sp<AMessage> &extra); - int32_t getSeqNumberWithAnchorTime( - int64_t anchorTimeUs, int64_t targetDurationUs) const; + bool adjustSeqNumberWithAnchorTime(int64_t anchorTimeUs); int32_t getSeqNumberForDiscontinuity(size_t discontinuitySeq) const; int32_t getSeqNumberForTime(int64_t timeUs) const; diff --git a/media/libstagefright/id3/Android.mk b/media/libstagefright/id3/Android.mk index f791899..68bd017 100644 --- a/media/libstagefright/id3/Android.mk +++ b/media/libstagefright/id3/Android.mk @@ -4,7 +4,7 @@ include $(CLEAR_VARS) LOCAL_SRC_FILES := \ ID3.cpp -LOCAL_CFLAGS += -Werror +LOCAL_CFLAGS += -Werror -Wall LOCAL_CLANG := true LOCAL_MODULE := libstagefright_id3 @@ -18,7 +18,7 @@ include $(CLEAR_VARS) LOCAL_SRC_FILES := \ testid3.cpp -LOCAL_CFLAGS += -Werror +LOCAL_CFLAGS += -Werror -Wall LOCAL_CLANG := true LOCAL_SHARED_LIBRARIES := \ diff --git a/media/libstagefright/matroska/Android.mk b/media/libstagefright/matroska/Android.mk index 771952b..1e8c2b2 100644 --- a/media/libstagefright/matroska/Android.mk +++ b/media/libstagefright/matroska/Android.mk @@ -8,7 +8,7 @@ LOCAL_C_INCLUDES:= \ $(TOP)/external/libvpx/libwebm \ $(TOP)/frameworks/native/include/media/openmax \ -LOCAL_CFLAGS += -Wno-multichar -Werror +LOCAL_CFLAGS += -Wno-multichar -Werror -Wall LOCAL_CLANG := true LOCAL_MODULE:= libstagefright_matroska diff --git a/media/libstagefright/mpeg2ts/Android.mk b/media/libstagefright/mpeg2ts/Android.mk index 0dcb3c5..16b0160 100644 --- a/media/libstagefright/mpeg2ts/Android.mk +++ b/media/libstagefright/mpeg2ts/Android.mk @@ -13,7 +13,7 @@ LOCAL_C_INCLUDES:= \ $(TOP)/frameworks/av/media/libstagefright \ $(TOP)/frameworks/native/include/media/openmax -LOCAL_CFLAGS += -Werror +LOCAL_CFLAGS += -Werror -Wall LOCAL_CLANG := true LOCAL_MODULE:= libstagefright_mpeg2ts diff --git a/media/libstagefright/omx/Android.mk b/media/libstagefright/omx/Android.mk index 71cbcfc..5f0f567 100644 --- a/media/libstagefright/omx/Android.mk +++ b/media/libstagefright/omx/Android.mk @@ -31,7 +31,7 @@ LOCAL_SHARED_LIBRARIES := \ libdl LOCAL_MODULE:= libstagefright_omx -LOCAL_CFLAGS += -Werror +LOCAL_CFLAGS += -Werror -Wall LOCAL_CLANG := true include $(BUILD_SHARED_LIBRARY) diff --git a/media/libstagefright/omx/tests/Android.mk b/media/libstagefright/omx/tests/Android.mk index f7280f6..02e97f1 100644 --- a/media/libstagefright/omx/tests/Android.mk +++ b/media/libstagefright/omx/tests/Android.mk @@ -11,7 +11,7 @@ LOCAL_C_INCLUDES := \ $(TOP)/frameworks/av/media/libstagefright \ $(TOP)/frameworks/native/include/media/openmax -LOCAL_CFLAGS += -Werror +LOCAL_CFLAGS += -Werror -Wall LOCAL_CLANG := true LOCAL_MODULE := omx_tests @@ -38,7 +38,7 @@ LOCAL_SHARED_LIBRARIES := \ LOCAL_C_INCLUDES := \ frameworks/av/media/libstagefright/omx \ -LOCAL_CFLAGS += -Werror +LOCAL_CFLAGS += -Werror -Wall LOCAL_CLANG := true include $(BUILD_NATIVE_TEST) diff --git a/media/libstagefright/rtsp/Android.mk b/media/libstagefright/rtsp/Android.mk index 12a946c..c5e8c35 100644 --- a/media/libstagefright/rtsp/Android.mk +++ b/media/libstagefright/rtsp/Android.mk @@ -31,7 +31,7 @@ ifeq ($(TARGET_ARCH),arm) LOCAL_CFLAGS += -Wno-psabi endif -LOCAL_CFLAGS += -Werror +LOCAL_CFLAGS += -Werror -Wall LOCAL_CLANG := true LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk @@ -55,7 +55,7 @@ LOCAL_C_INCLUDES:= \ frameworks/av/media/libstagefright \ $(TOP)/frameworks/native/include/media/openmax -LOCAL_CFLAGS += -Wno-multichar -Werror +LOCAL_CFLAGS += -Wno-multichar -Werror -Wall LOCAL_CLANG := true LOCAL_MODULE_TAGS := optional diff --git a/media/libstagefright/rtsp/MyHandler.h b/media/libstagefright/rtsp/MyHandler.h index 0642343..00f071b 100644 --- a/media/libstagefright/rtsp/MyHandler.h +++ b/media/libstagefright/rtsp/MyHandler.h @@ -651,7 +651,7 @@ struct MyHandler : public AHandler { int32_t result; CHECK(msg->findInt32("result", &result)); - ALOGI("SETUP(%d) completed with result %d (%s)", + ALOGI("SETUP(%zu) completed with result %d (%s)", index, result, strerror(-result)); if (result == OK) { @@ -1012,7 +1012,7 @@ struct MyHandler : public AHandler { int32_t eos; if (msg->findInt32("eos", &eos)) { - ALOGI("received BYE on track index %d", trackIndex); + ALOGI("received BYE on track index %zu", trackIndex); if (!mAllTracksHaveTime && dataReceivedOnAllChannels()) { ALOGI("No time established => fake existing data"); @@ -1564,7 +1564,7 @@ private: new APacketSource(mSessionDesc, index); if (source->initCheck() != OK) { - ALOGW("Unsupported format. Ignoring track #%d.", index); + ALOGW("Unsupported format. Ignoring track #%zu.", index); sp<AMessage> reply = new AMessage('setu', this); reply->setSize("index", index); @@ -1606,7 +1606,7 @@ private: info->mTimeScale = timescale; info->mEOSReceived = false; - ALOGV("track #%d URL=%s", mTracks.size(), trackURL.c_str()); + ALOGV("track #%zu URL=%s", mTracks.size(), trackURL.c_str()); AString request = "SETUP "; request.append(trackURL); @@ -1731,8 +1731,8 @@ private: } void onTimeUpdate(int32_t trackIndex, uint32_t rtpTime, uint64_t ntpTime) { - ALOGV("onTimeUpdate track %d, rtpTime = 0x%08x, ntpTime = 0x%016llx", - trackIndex, rtpTime, ntpTime); + ALOGV("onTimeUpdate track %d, rtpTime = 0x%08x, ntpTime = %#016llx", + trackIndex, rtpTime, (long long)ntpTime); int64_t ntpTimeUs = (int64_t)(ntpTime * 1E6 / (1ll << 32)); @@ -1851,8 +1851,8 @@ private: return false; } - ALOGV("track %d rtpTime=%d mediaTimeUs = %lld us (%.2f secs)", - trackIndex, rtpTime, mediaTimeUs, mediaTimeUs / 1E6); + ALOGV("track %d rtpTime=%u mediaTimeUs = %lld us (%.2f secs)", + trackIndex, rtpTime, (long long)mediaTimeUs, mediaTimeUs / 1E6); accessUnit->meta()->setInt64("timeUs", mediaTimeUs); diff --git a/media/libstagefright/tests/Android.mk b/media/libstagefright/tests/Android.mk index 532106b..111e6c5 100644 --- a/media/libstagefright/tests/Android.mk +++ b/media/libstagefright/tests/Android.mk @@ -31,7 +31,7 @@ LOCAL_C_INCLUDES := \ frameworks/av/media/libstagefright/include \ $(TOP)/frameworks/native/include/media/openmax \ -LOCAL_CFLAGS += -Werror +LOCAL_CFLAGS += -Werror -Wall LOCAL_CLANG := true LOCAL_32_BIT_ONLY := true @@ -63,7 +63,7 @@ LOCAL_C_INCLUDES := \ frameworks/av/media/libstagefright/include \ $(TOP)/frameworks/native/include/media/openmax \ -LOCAL_CFLAGS += -Werror +LOCAL_CFLAGS += -Werror -Wall LOCAL_CLANG := true include $(BUILD_NATIVE_TEST) @@ -93,7 +93,7 @@ LOCAL_C_INCLUDES := \ LOCAL_32_BIT_ONLY := true -LOCAL_CFLAGS += -Werror +LOCAL_CFLAGS += -Werror -Wall LOCAL_CLANG := true include $(BUILD_NATIVE_TEST) diff --git a/media/libstagefright/timedtext/Android.mk b/media/libstagefright/timedtext/Android.mk index 1202a4d..58fb12f 100644 --- a/media/libstagefright/timedtext/Android.mk +++ b/media/libstagefright/timedtext/Android.mk @@ -9,7 +9,7 @@ LOCAL_SRC_FILES:= \ TimedTextSRTSource.cpp \ TimedTextPlayer.cpp -LOCAL_CFLAGS += -Wno-multichar -Werror +LOCAL_CFLAGS += -Wno-multichar -Werror -Wall LOCAL_CLANG := true LOCAL_C_INCLUDES:= \ diff --git a/media/libstagefright/timedtext/test/Android.mk b/media/libstagefright/timedtext/test/Android.mk index 06ea307..e0e0e0d 100644 --- a/media/libstagefright/timedtext/test/Android.mk +++ b/media/libstagefright/timedtext/test/Android.mk @@ -26,7 +26,7 @@ LOCAL_SHARED_LIBRARIES := \ libstagefright_foundation \ libutils -LOCAL_CFLAGS += -Werror +LOCAL_CFLAGS += -Werror -Wall LOCAL_CLANG := true include $(BUILD_NATIVE_TEST) diff --git a/media/libstagefright/webm/Android.mk b/media/libstagefright/webm/Android.mk index c9fb83c..bc53c56 100644 --- a/media/libstagefright/webm/Android.mk +++ b/media/libstagefright/webm/Android.mk @@ -3,7 +3,7 @@ include $(CLEAR_VARS) LOCAL_CPPFLAGS += -D__STDINT_LIMITS -LOCAL_CFLAGS += -Werror +LOCAL_CFLAGS += -Werror -Wall LOCAL_CLANG := true LOCAL_SRC_FILES:= EbmlUtil.cpp \ diff --git a/media/libstagefright/wifi-display/Android.mk b/media/libstagefright/wifi-display/Android.mk index 0d9ba6f..fb28624 100644 --- a/media/libstagefright/wifi-display/Android.mk +++ b/media/libstagefright/wifi-display/Android.mk @@ -30,7 +30,7 @@ LOCAL_SHARED_LIBRARIES:= \ libui \ libutils \ -LOCAL_CFLAGS += -Wno-multichar -Werror +LOCAL_CFLAGS += -Wno-multichar -Werror -Wall LOCAL_CLANG := true LOCAL_MODULE:= libstagefright_wfd diff --git a/media/libstagefright/wifi-display/VideoFormats.cpp b/media/libstagefright/wifi-display/VideoFormats.cpp index 27393fb..dbc511c 100644 --- a/media/libstagefright/wifi-display/VideoFormats.cpp +++ b/media/libstagefright/wifi-display/VideoFormats.cpp @@ -382,7 +382,6 @@ bool VideoFormats::parseFormatSpec(const char *spec) { disableAll(); unsigned native, dummy; - unsigned res[3]; size_t size = strlen(spec); size_t offset = 0; diff --git a/media/libstagefright/wifi-display/rtp/RTPSender.cpp b/media/libstagefright/wifi-display/rtp/RTPSender.cpp index a4eb378..c66a898 100644 --- a/media/libstagefright/wifi-display/rtp/RTPSender.cpp +++ b/media/libstagefright/wifi-display/rtp/RTPSender.cpp @@ -252,8 +252,6 @@ status_t RTPSender::queueTSPackets( int64_t timeUs; CHECK(tsPackets->meta()->findInt64("timeUs", &timeUs)); - const size_t numTSPackets = tsPackets->size() / 188; - size_t srcOffset = 0; while (srcOffset < tsPackets->size()) { sp<ABuffer> udpPacket = diff --git a/media/libstagefright/wifi-display/source/PlaybackSession.cpp b/media/libstagefright/wifi-display/source/PlaybackSession.cpp index b37a46c..5e2f0bf 100644 --- a/media/libstagefright/wifi-display/source/PlaybackSession.cpp +++ b/media/libstagefright/wifi-display/source/PlaybackSession.cpp @@ -821,21 +821,27 @@ void WifiDisplaySource::PlaybackSession::schedulePullExtractor() { return; } + int64_t delayUs = 1000000; // default delay is 1 sec int64_t sampleTimeUs; status_t err = mExtractor->getSampleTime(&sampleTimeUs); - int64_t nowUs = ALooper::GetNowUs(); + if (err == OK) { + int64_t nowUs = ALooper::GetNowUs(); - if (mFirstSampleTimeRealUs < 0ll) { - mFirstSampleTimeRealUs = nowUs; - mFirstSampleTimeUs = sampleTimeUs; - } + if (mFirstSampleTimeRealUs < 0ll) { + mFirstSampleTimeRealUs = nowUs; + mFirstSampleTimeUs = sampleTimeUs; + } - int64_t whenUs = sampleTimeUs - mFirstSampleTimeUs + mFirstSampleTimeRealUs; + int64_t whenUs = sampleTimeUs - mFirstSampleTimeUs + mFirstSampleTimeRealUs; + delayUs = whenUs - nowUs; + } else { + ALOGW("could not get sample time (%d)", err); + } sp<AMessage> msg = new AMessage(kWhatPullExtractorSample, this); msg->setInt32("generation", mPullExtractorGeneration); - msg->post(whenUs - nowUs); + msg->post(delayUs); mPullExtractorPending = true; } diff --git a/media/libstagefright/wifi-display/source/WifiDisplaySource.h b/media/libstagefright/wifi-display/source/WifiDisplaySource.h index 0f779e4..c417cf5 100644 --- a/media/libstagefright/wifi-display/source/WifiDisplaySource.h +++ b/media/libstagefright/wifi-display/source/WifiDisplaySource.h @@ -29,7 +29,7 @@ namespace android { struct AReplyToken; struct IHDCP; -struct IRemoteDisplayClient; +class IRemoteDisplayClient; struct ParsedMessage; // Represents the RTSP server acting as a wifi display source. diff --git a/media/libstagefright/yuv/Android.mk b/media/libstagefright/yuv/Android.mk index 5b36825..dc67288 100644 --- a/media/libstagefright/yuv/Android.mk +++ b/media/libstagefright/yuv/Android.mk @@ -12,7 +12,7 @@ LOCAL_SHARED_LIBRARIES := \ LOCAL_MODULE:= libstagefright_yuv -LOCAL_CFLAGS += -Werror +LOCAL_CFLAGS += -Werror -Wall LOCAL_CLANG := true include $(BUILD_SHARED_LIBRARY) |