summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
Diffstat (limited to 'media')
-rw-r--r--media/libmedia/Android.mk7
-rw-r--r--media/libmedia/AudioSystem.cpp1
-rw-r--r--media/libmedia/AudioTrack.cpp55
-rw-r--r--media/libmedia/AudioTrackShared.cpp5
-rw-r--r--media/libmedia/CharacterEncodingDetector.cpp2
-rw-r--r--media/libmedia/IDataSource.cpp108
-rw-r--r--media/libmedia/IMediaLogService.cpp4
-rw-r--r--media/libmedia/IMediaMetadataRetriever.cpp18
-rw-r--r--media/libmedia/IMediaPlayer.cpp17
-rw-r--r--media/libmedia/IResourceManagerService.cpp3
-rw-r--r--media/libmedia/MediaProfiles.cpp1
-rw-r--r--media/libmedia/MediaResource.cpp2
-rw-r--r--media/libmedia/MediaResourcePolicy.cpp2
-rw-r--r--media/libmedia/MemoryLeakTrackUtil.cpp2
-rw-r--r--media/libmedia/ToneGenerator.cpp1
-rw-r--r--media/libmedia/mediametadataretriever.cpp12
-rw-r--r--media/libmedia/mediaplayer.cpp20
-rw-r--r--media/libmediaplayerservice/Android.mk3
-rw-r--r--media/libmediaplayerservice/Crypto.cpp2
-rw-r--r--media/libmediaplayerservice/Drm.cpp4
-rw-r--r--media/libmediaplayerservice/Drm.h4
-rw-r--r--media/libmediaplayerservice/MediaPlayerFactory.cpp12
-rw-r--r--media/libmediaplayerservice/MediaPlayerFactory.h6
-rw-r--r--media/libmediaplayerservice/MediaPlayerService.cpp17
-rw-r--r--media/libmediaplayerservice/MediaPlayerService.h5
-rw-r--r--media/libmediaplayerservice/MediaRecorderClient.cpp2
-rw-r--r--media/libmediaplayerservice/MediaRecorderClient.h2
-rw-r--r--media/libmediaplayerservice/MetadataRetrieverClient.cpp20
-rw-r--r--media/libmediaplayerservice/MetadataRetrieverClient.h3
-rw-r--r--media/libmediaplayerservice/RemoteDisplay.h2
-rw-r--r--media/libmediaplayerservice/StagefrightRecorder.cpp1
-rw-r--r--media/libmediaplayerservice/StagefrightRecorder.h2
-rw-r--r--media/libmediaplayerservice/VideoFrameScheduler.h2
-rw-r--r--media/libmediaplayerservice/nuplayer/Android.mk4
-rw-r--r--media/libmediaplayerservice/nuplayer/GenericSource.cpp32
-rw-r--r--media/libmediaplayerservice/nuplayer/GenericSource.h7
-rw-r--r--media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp140
-rw-r--r--media/libmediaplayerservice/nuplayer/HTTPLiveSource.h9
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayer.cpp52
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayer.h4
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerCCDecoder.cpp1
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp26
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h2
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.cpp13
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.h5
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.cpp11
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.h2
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp22
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerDriver.h2
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp8
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerSource.h3
-rw-r--r--media/libmediaplayerservice/tests/Android.mk3
-rw-r--r--media/libmediaplayerservice/tests/DrmSessionManager_test.cpp18
-rw-r--r--media/libstagefright/AACExtractor.cpp2
-rw-r--r--media/libstagefright/ACodec.cpp81
-rw-r--r--media/libstagefright/Android.mk4
-rw-r--r--media/libstagefright/AwesomePlayer.cpp8
-rw-r--r--media/libstagefright/CallbackDataSource.cpp143
-rw-r--r--media/libstagefright/CameraSource.cpp8
-rw-r--r--media/libstagefright/DataSource.cpp5
-rw-r--r--media/libstagefright/FLACExtractor.cpp4
-rw-r--r--media/libstagefright/FileSource.cpp2
-rw-r--r--media/libstagefright/HTTPBase.cpp4
-rw-r--r--media/libstagefright/MP3Extractor.cpp10
-rw-r--r--media/libstagefright/MPEG4Extractor.cpp22
-rw-r--r--media/libstagefright/MPEG4Writer.cpp8
-rw-r--r--media/libstagefright/MediaCodec.cpp17
-rw-r--r--media/libstagefright/MediaCodecListOverrides.cpp20
-rw-r--r--media/libstagefright/MediaCodecListOverrides.h2
-rw-r--r--media/libstagefright/MediaCodecSource.cpp1
-rw-r--r--media/libstagefright/MediaDefs.cpp1
-rw-r--r--media/libstagefright/MediaSync.cpp5
-rw-r--r--media/libstagefright/MidiExtractor.cpp2
-rw-r--r--media/libstagefright/NuCachedSource2.cpp10
-rw-r--r--media/libstagefright/OMXCodec.cpp81
-rw-r--r--media/libstagefright/OggExtractor.cpp18
-rw-r--r--media/libstagefright/SampleTable.cpp2
-rw-r--r--media/libstagefright/StagefrightMetadataRetriever.cpp41
-rw-r--r--media/libstagefright/Utils.cpp24
-rw-r--r--media/libstagefright/VBRISeeker.cpp4
-rw-r--r--media/libstagefright/codecs/avcdec/SoftAVCDec.cpp4
-rw-r--r--media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp4
-rw-r--r--media/libstagefright/codecs/avcenc/SoftAVCEnc.h2
-rw-r--r--media/libstagefright/codecs/hevcdec/SoftHEVC.cpp4
-rw-r--r--media/libstagefright/codecs/mpeg2dec/SoftMPEG2.cpp29
-rw-r--r--media/libstagefright/codecs/mpeg2dec/SoftMPEG2.h1
-rw-r--r--media/libstagefright/colorconversion/Android.mk3
-rw-r--r--media/libstagefright/filters/Android.mk3
-rw-r--r--media/libstagefright/filters/ColorConvert.cpp4
-rw-r--r--media/libstagefright/filters/GraphicBufferListener.cpp2
-rw-r--r--media/libstagefright/filters/MediaFilter.cpp2
-rw-r--r--media/libstagefright/foundation/Android.mk3
-rw-r--r--media/libstagefright/http/Android.mk3
-rw-r--r--media/libstagefright/httplive/Android.mk3
-rw-r--r--media/libstagefright/httplive/LiveSession.cpp205
-rw-r--r--media/libstagefright/httplive/LiveSession.h17
-rw-r--r--media/libstagefright/httplive/M3UParser.cpp37
-rw-r--r--media/libstagefright/httplive/M3UParser.h6
-rw-r--r--media/libstagefright/httplive/PlaylistFetcher.cpp406
-rw-r--r--media/libstagefright/httplive/PlaylistFetcher.h11
-rw-r--r--media/libstagefright/id3/Android.mk6
-rw-r--r--media/libstagefright/include/AwesomePlayer.h10
-rw-r--r--media/libstagefright/include/CallbackDataSource.h79
-rw-r--r--media/libstagefright/include/MPEG2PSExtractor.h2
-rw-r--r--media/libstagefright/include/MPEG2TSExtractor.h2
-rw-r--r--media/libstagefright/include/OMX.h2
-rw-r--r--media/libstagefright/include/OMXNodeInstance.h2
-rw-r--r--media/libstagefright/include/SampleIterator.h2
-rw-r--r--media/libstagefright/include/StagefrightMetadataRetriever.h5
-rw-r--r--media/libstagefright/include/TimedEventQueue.h2
-rw-r--r--media/libstagefright/include/VBRISeeker.h2
-rw-r--r--media/libstagefright/include/XINGSeeker.h2
-rw-r--r--media/libstagefright/matroska/Android.mk3
-rw-r--r--media/libstagefright/mpeg2ts/ATSParser.cpp29
-rw-r--r--media/libstagefright/mpeg2ts/ATSParser.h4
-rw-r--r--media/libstagefright/mpeg2ts/Android.mk3
-rw-r--r--media/libstagefright/mpeg2ts/AnotherPacketSource.cpp8
-rw-r--r--media/libstagefright/mpeg2ts/AnotherPacketSource.h1
-rw-r--r--media/libstagefright/mpeg2ts/ESQueue.cpp44
-rw-r--r--media/libstagefright/mpeg2ts/ESQueue.h4
-rw-r--r--media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp3
-rw-r--r--media/libstagefright/omx/Android.mk2
-rw-r--r--media/libstagefright/omx/FrameDropper.cpp9
-rw-r--r--media/libstagefright/omx/GraphicBufferSource.h4
-rw-r--r--media/libstagefright/omx/SimpleSoftOMXComponent.cpp10
-rw-r--r--media/libstagefright/omx/tests/Android.mk6
-rw-r--r--media/libstagefright/omx/tests/FrameDropper_test.cpp3
-rw-r--r--media/libstagefright/rtsp/ARTPWriter.h2
-rw-r--r--media/libstagefright/rtsp/Android.mk6
-rw-r--r--media/libstagefright/rtsp/MyHandler.h16
-rw-r--r--media/libstagefright/tests/Android.mk9
-rw-r--r--media/libstagefright/tests/DummyRecorder.h2
-rw-r--r--media/libstagefright/tests/MediaCodecListOverrides_test.cpp4
-rw-r--r--media/libstagefright/timedtext/Android.mk3
-rw-r--r--media/libstagefright/timedtext/test/Android.mk3
-rw-r--r--media/libstagefright/timedtext/test/TimedTextSRTSource_test.cpp4
-rw-r--r--media/libstagefright/webm/Android.mk6
-rw-r--r--media/libstagefright/wifi-display/Android.mk3
-rw-r--r--media/libstagefright/wifi-display/VideoFormats.cpp7
-rw-r--r--media/libstagefright/wifi-display/rtp/RTPSender.cpp8
-rw-r--r--media/libstagefright/wifi-display/source/Converter.cpp2
-rw-r--r--media/libstagefright/wifi-display/source/Converter.h2
-rw-r--r--media/libstagefright/wifi-display/source/PlaybackSession.cpp24
-rw-r--r--media/libstagefright/wifi-display/source/PlaybackSession.h2
-rw-r--r--media/libstagefright/wifi-display/source/WifiDisplaySource.cpp2
-rw-r--r--media/libstagefright/wifi-display/source/WifiDisplaySource.h2
-rw-r--r--media/libstagefright/yuv/Android.mk4
147 files changed, 1714 insertions, 635 deletions
diff --git a/media/libmedia/Android.mk b/media/libmedia/Android.mk
index 3b260d6..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)
@@ -19,6 +22,7 @@ LOCAL_SRC_FILES:= \
IAudioTrack.cpp \
IAudioRecord.cpp \
ICrypto.cpp \
+ IDataSource.cpp \
IDrm.cpp \
IDrmClient.cpp \
IHDCP.cpp \
@@ -83,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 d32db7c..055556f 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -56,6 +56,24 @@ static int64_t getNowUs()
return convertTimespecToUs(tv);
}
+// FIXME: we don't use the pitch setting in the time stretcher (not working);
+// instead we emulate it using our sample rate converter.
+static const bool kFixPitch = true; // enable pitch fix
+static inline uint32_t adjustSampleRate(uint32_t sampleRate, float pitch)
+{
+ return kFixPitch ? (sampleRate * pitch + 0.5) : sampleRate;
+}
+
+static inline float adjustSpeed(float speed, float pitch)
+{
+ return kFixPitch ? (speed / pitch) : speed;
+}
+
+static inline float adjustPitch(float pitch)
+{
+ return kFixPitch ? AUDIO_TIMESTRETCH_PITCH_NORMAL : pitch;
+}
+
// Must match similar computation in createTrack_l in Threads.cpp.
// TODO: Move to a common library
static size_t calculateMinFrameCount(
@@ -703,13 +721,15 @@ status_t AudioTrack::setSampleRate(uint32_t rate)
if (AudioSystem::getSamplingRate(mOutput, &afSamplingRate) != NO_ERROR) {
return NO_INIT;
}
- if (rate == 0 || rate > afSamplingRate * AUDIO_RESAMPLER_DOWN_RATIO_MAX) {
+ // pitch is emulated by adjusting speed and sampleRate
+ const uint32_t effectiveSampleRate = adjustSampleRate(rate, mPitch);
+ if (rate == 0 || effectiveSampleRate > afSamplingRate * AUDIO_RESAMPLER_DOWN_RATIO_MAX) {
return BAD_VALUE;
}
// TODO: Should we also check if the buffer size is compatible?
mSampleRate = rate;
- mProxy->setSampleRate(rate);
+ mProxy->setSampleRate(effectiveSampleRate);
return NO_ERROR;
}
@@ -739,12 +759,6 @@ uint32_t AudioTrack::getSampleRate() const
status_t AudioTrack::setPlaybackRate(float speed, float pitch)
{
- if (speed < AUDIO_TIMESTRETCH_SPEED_MIN
- || speed > AUDIO_TIMESTRETCH_SPEED_MAX
- || pitch < AUDIO_TIMESTRETCH_PITCH_MIN
- || pitch > AUDIO_TIMESTRETCH_PITCH_MAX) {
- return BAD_VALUE;
- }
AutoMutex lock(mLock);
if (speed == mSpeed && pitch == mPitch) {
return NO_ERROR;
@@ -755,14 +769,25 @@ status_t AudioTrack::setPlaybackRate(float speed, float pitch)
if (mFlags & AUDIO_OUTPUT_FLAG_FAST) {
return INVALID_OPERATION;
}
+ // pitch is emulated by adjusting speed and sampleRate
+ const uint32_t effectiveRate = adjustSampleRate(mSampleRate, pitch);
+ const float effectiveSpeed = adjustSpeed(speed, pitch);
+ const float effectivePitch = adjustPitch(pitch);
+ if (effectiveSpeed < AUDIO_TIMESTRETCH_SPEED_MIN
+ || effectiveSpeed > AUDIO_TIMESTRETCH_SPEED_MAX
+ || effectivePitch < AUDIO_TIMESTRETCH_PITCH_MIN
+ || effectivePitch > AUDIO_TIMESTRETCH_PITCH_MAX) {
+ return BAD_VALUE;
+ }
// Check if the buffer size is compatible.
- if (!isSampleRateSpeedAllowed_l(mSampleRate, speed)) {
+ if (!isSampleRateSpeedAllowed_l(effectiveRate, effectiveSpeed)) {
ALOGV("setPlaybackRate(%f, %f) failed", speed, pitch);
return BAD_VALUE;
}
mSpeed = speed;
mPitch = pitch;
- mProxy->setPlaybackRate(speed, pitch);
+ mProxy->setPlaybackRate(effectiveSpeed, effectivePitch);
+ mProxy->setSampleRate(effectiveRate); // FIXME: not quite "atomic" with setPlaybackRate
return NO_ERROR;
}
@@ -1317,8 +1342,11 @@ status_t AudioTrack::createTrack_l()
gain_from_float(mVolume[AUDIO_INTERLEAVE_RIGHT])));
mProxy->setSendLevel(mSendLevel);
- mProxy->setSampleRate(mSampleRate);
- mProxy->setPlaybackRate(mSpeed, mPitch);
+ const uint32_t effectiveSampleRate = adjustSampleRate(mSampleRate, mPitch);
+ const float effectiveSpeed = adjustSpeed(mSpeed, mPitch);
+ const float effectivePitch = adjustPitch(mPitch);
+ mProxy->setSampleRate(effectiveSampleRate);
+ mProxy->setPlaybackRate(effectiveSpeed, effectivePitch);
mProxy->setMinimum(mNotificationFramesAct);
mDeathNotifier = new DeathNotifier(this);
@@ -1635,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/IDataSource.cpp b/media/libmedia/IDataSource.cpp
new file mode 100644
index 0000000..76d1d68
--- /dev/null
+++ b/media/libmedia/IDataSource.cpp
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "IDataSource"
+#include <utils/Log.h>
+#include <utils/Timers.h>
+
+#include <media/IDataSource.h>
+
+#include <binder/IMemory.h>
+#include <binder/Parcel.h>
+#include <media/stagefright/foundation/ADebug.h>
+
+namespace android {
+
+enum {
+ GET_IMEMORY = IBinder::FIRST_CALL_TRANSACTION,
+ READ_AT,
+ GET_SIZE,
+ CLOSE,
+};
+
+struct BpDataSource : public BpInterface<IDataSource> {
+ BpDataSource(const sp<IBinder>& impl) : BpInterface<IDataSource>(impl) {}
+
+ virtual sp<IMemory> getIMemory() {
+ Parcel data, reply;
+ data.writeInterfaceToken(IDataSource::getInterfaceDescriptor());
+ remote()->transact(GET_IMEMORY, data, &reply);
+ sp<IBinder> binder = reply.readStrongBinder();
+ return interface_cast<IMemory>(binder);
+ }
+
+ virtual ssize_t readAt(off64_t offset, size_t size) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IDataSource::getInterfaceDescriptor());
+ data.writeInt64(offset);
+ data.writeInt64(size);
+ remote()->transact(READ_AT, data, &reply);
+ return reply.readInt64();
+ }
+
+ virtual status_t getSize(off64_t* size) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IDataSource::getInterfaceDescriptor());
+ remote()->transact(GET_SIZE, data, &reply);
+ status_t err = reply.readInt32();
+ *size = reply.readInt64();
+ return err;
+ }
+
+ virtual void close() {
+ Parcel data, reply;
+ data.writeInterfaceToken(IDataSource::getInterfaceDescriptor());
+ remote()->transact(CLOSE, data, &reply);
+ }
+};
+
+IMPLEMENT_META_INTERFACE(DataSource, "android.media.IDataSource");
+
+status_t BnDataSource::onTransact(
+ uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
+ switch (code) {
+ case GET_IMEMORY: {
+ CHECK_INTERFACE(IDataSource, data, reply);
+ reply->writeStrongBinder(IInterface::asBinder(getIMemory()));
+ return NO_ERROR;
+ } break;
+ case READ_AT: {
+ CHECK_INTERFACE(IDataSource, data, reply);
+ off64_t offset = (off64_t) data.readInt64();
+ size_t size = (size_t) data.readInt64();
+ reply->writeInt64(readAt(offset, size));
+ return NO_ERROR;
+ } break;
+ case GET_SIZE: {
+ CHECK_INTERFACE(IDataSource, data, reply);
+ off64_t size;
+ status_t err = getSize(&size);
+ reply->writeInt32(err);
+ reply->writeInt64(size);
+ return NO_ERROR;
+ } break;
+ case CLOSE: {
+ CHECK_INTERFACE(IDataSource, data, reply);
+ close();
+ return NO_ERROR;
+ } break;
+ default:
+ return BBinder::onTransact(code, data, reply, flags);
+ }
+}
+
+} // namespace android
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/IMediaMetadataRetriever.cpp b/media/libmedia/IMediaMetadataRetriever.cpp
index 551cffe..9765f0d 100644
--- a/media/libmedia/IMediaMetadataRetriever.cpp
+++ b/media/libmedia/IMediaMetadataRetriever.cpp
@@ -20,6 +20,7 @@
#include <sys/types.h>
#include <binder/Parcel.h>
+#include <media/IDataSource.h>
#include <media/IMediaHTTPService.h>
#include <media/IMediaMetadataRetriever.h>
#include <utils/String8.h>
@@ -65,6 +66,7 @@ enum {
DISCONNECT = IBinder::FIRST_CALL_TRANSACTION,
SET_DATA_SOURCE_URL,
SET_DATA_SOURCE_FD,
+ SET_DATA_SOURCE_CALLBACK,
GET_FRAME_AT_TIME,
EXTRACT_ALBUM_ART,
EXTRACT_METADATA,
@@ -125,6 +127,15 @@ public:
return reply.readInt32();
}
+ status_t setDataSource(const sp<IDataSource>& source)
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(IMediaMetadataRetriever::getInterfaceDescriptor());
+ data.writeStrongBinder(IInterface::asBinder(source));
+ remote()->transact(SET_DATA_SOURCE_CALLBACK, data, &reply);
+ return reply.readInt32();
+ }
+
sp<IMemory> getFrameAtTime(int64_t timeUs, int option)
{
ALOGV("getTimeAtTime: time(%" PRId64 " us) and option(%d)", timeUs, option);
@@ -235,6 +246,13 @@ status_t BnMediaMetadataRetriever::onTransact(
reply->writeInt32(setDataSource(fd, offset, length));
return NO_ERROR;
} break;
+ case SET_DATA_SOURCE_CALLBACK: {
+ CHECK_INTERFACE(IMediaMetadataRetriever, data, reply);
+ sp<IDataSource> source =
+ interface_cast<IDataSource>(data.readStrongBinder());
+ reply->writeInt32(setDataSource(source));
+ return NO_ERROR;
+ } break;
case GET_FRAME_AT_TIME: {
CHECK_INTERFACE(IMediaMetadataRetriever, data, reply);
int64_t timeUs = data.readInt64();
diff --git a/media/libmedia/IMediaPlayer.cpp b/media/libmedia/IMediaPlayer.cpp
index ce3009a..0091078 100644
--- a/media/libmedia/IMediaPlayer.cpp
+++ b/media/libmedia/IMediaPlayer.cpp
@@ -21,6 +21,7 @@
#include <binder/Parcel.h>
+#include <media/IDataSource.h>
#include <media/IMediaHTTPService.h>
#include <media/IMediaPlayer.h>
#include <media/IStreamSource.h>
@@ -35,6 +36,7 @@ enum {
SET_DATA_SOURCE_URL,
SET_DATA_SOURCE_FD,
SET_DATA_SOURCE_STREAM,
+ SET_DATA_SOURCE_CALLBACK,
PREPARE_ASYNC,
START,
STOP,
@@ -121,6 +123,14 @@ public:
return reply.readInt32();
}
+ status_t setDataSource(const sp<IDataSource> &source) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
+ data.writeStrongBinder(IInterface::asBinder(source));
+ remote()->transact(SET_DATA_SOURCE_CALLBACK, data, &reply);
+ return reply.readInt32();
+ }
+
// pass the buffered IGraphicBufferProducer to the media player service
status_t setVideoSurfaceTexture(const sp<IGraphicBufferProducer>& bufferProducer)
{
@@ -406,6 +416,13 @@ status_t BnMediaPlayer::onTransact(
reply->writeInt32(setDataSource(source));
return NO_ERROR;
}
+ case SET_DATA_SOURCE_CALLBACK: {
+ CHECK_INTERFACE(IMediaPlayer, data, reply);
+ sp<IDataSource> source =
+ interface_cast<IDataSource>(data.readStrongBinder());
+ reply->writeInt32(setDataSource(source));
+ return NO_ERROR;
+ }
case SET_VIDEO_SURFACETEXTURE: {
CHECK_INTERFACE(IMediaPlayer, data, reply);
sp<IGraphicBufferProducer> bufferProducer =
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/libmedia/mediametadataretriever.cpp b/media/libmedia/mediametadataretriever.cpp
index 873808a..9a76f58 100644
--- a/media/libmedia/mediametadataretriever.cpp
+++ b/media/libmedia/mediametadataretriever.cpp
@@ -129,6 +129,18 @@ status_t MediaMetadataRetriever::setDataSource(int fd, int64_t offset, int64_t l
return mRetriever->setDataSource(fd, offset, length);
}
+status_t MediaMetadataRetriever::setDataSource(
+ const sp<IDataSource>& dataSource)
+{
+ ALOGV("setDataSource(IDataSource)");
+ Mutex::Autolock _l(mLock);
+ if (mRetriever == 0) {
+ ALOGE("retriever is not initialized");
+ return INVALID_OPERATION;
+ }
+ return mRetriever->setDataSource(dataSource);
+}
+
sp<IMemory> MediaMetadataRetriever::getFrameAtTime(int64_t timeUs, int option)
{
ALOGV("getFrameAtTime: time(%" PRId64 " us) option(%d)", timeUs, option);
diff --git a/media/libmedia/mediaplayer.cpp b/media/libmedia/mediaplayer.cpp
index 5dd8c02..9a276ae 100644
--- a/media/libmedia/mediaplayer.cpp
+++ b/media/libmedia/mediaplayer.cpp
@@ -33,6 +33,7 @@
#include <media/mediaplayer.h>
#include <media/AudioSystem.h>
+#include <media/IDataSource.h>
#include <binder/MemoryBase.h>
@@ -195,6 +196,22 @@ status_t MediaPlayer::setDataSource(const sp<IStreamSource> &source)
return err;
}
+status_t MediaPlayer::setDataSource(const sp<IDataSource> &source)
+{
+ ALOGV("setDataSource(IDataSource)");
+ status_t err = UNKNOWN_ERROR;
+ const sp<IMediaPlayerService>& service(getMediaPlayerService());
+ if (service != 0) {
+ sp<IMediaPlayer> player(service->create(this, mAudioSessionId));
+ if ((NO_ERROR != doSetRetransmitEndpoint(player)) ||
+ (NO_ERROR != player->setDataSource(source))) {
+ player.clear();
+ }
+ err = attachNewPlayer(player);
+ }
+ return err;
+}
+
status_t MediaPlayer::invoke(const Parcel& request, Parcel *reply)
{
Mutex::Autolock _l(mLock);
@@ -840,6 +857,9 @@ void MediaPlayer::notify(int msg, int ext1, int ext2, const Parcel *obj)
case MEDIA_SUBTITLE_DATA:
ALOGV("Received subtitle data message");
break;
+ case MEDIA_META_DATA:
+ ALOGV("Received timed metadata message");
+ break;
default:
ALOGV("unrecognized message: (%d, %d, %d)", msg, ext1, ext2);
break;
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/MediaPlayerFactory.cpp b/media/libmediaplayerservice/MediaPlayerFactory.cpp
index 48884b9..ca33aed 100644
--- a/media/libmediaplayerservice/MediaPlayerFactory.cpp
+++ b/media/libmediaplayerservice/MediaPlayerFactory.cpp
@@ -131,6 +131,11 @@ player_type MediaPlayerFactory::getPlayerType(const sp<IMediaPlayer>& client,
GET_PLAYER_TYPE_IMPL(client, source);
}
+player_type MediaPlayerFactory::getPlayerType(const sp<IMediaPlayer>& client,
+ const sp<DataSource> &source) {
+ GET_PLAYER_TYPE_IMPL(client, source);
+}
+
#undef GET_PLAYER_TYPE_IMPL
sp<MediaPlayerBase> MediaPlayerFactory::createPlayer(
@@ -273,6 +278,13 @@ class NuPlayerFactory : public MediaPlayerFactory::IFactory {
return 1.0;
}
+ virtual float scoreFactory(const sp<IMediaPlayer>& /*client*/,
+ const sp<DataSource>& /*source*/,
+ float /*curScore*/) {
+ // Only NuPlayer supports setting a DataSource source directly.
+ return 1.0;
+ }
+
virtual sp<MediaPlayerBase> createPlayer() {
ALOGV(" create NuPlayer");
return new NuPlayerDriver;
diff --git a/media/libmediaplayerservice/MediaPlayerFactory.h b/media/libmediaplayerservice/MediaPlayerFactory.h
index 55ff918..7f9b3b5 100644
--- a/media/libmediaplayerservice/MediaPlayerFactory.h
+++ b/media/libmediaplayerservice/MediaPlayerFactory.h
@@ -43,6 +43,10 @@ class MediaPlayerFactory {
const sp<IStreamSource> &/*source*/,
float /*curScore*/) { return 0.0; }
+ virtual float scoreFactory(const sp<IMediaPlayer>& /*client*/,
+ const sp<DataSource> &/*source*/,
+ float /*curScore*/) { return 0.0; }
+
virtual sp<MediaPlayerBase> createPlayer() = 0;
};
@@ -57,6 +61,8 @@ class MediaPlayerFactory {
int64_t length);
static player_type getPlayerType(const sp<IMediaPlayer>& client,
const sp<IStreamSource> &source);
+ static player_type getPlayerType(const sp<IMediaPlayer>& client,
+ const sp<DataSource> &source);
static sp<MediaPlayerBase> createPlayer(player_type playerType,
void* cookie,
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index f113e21..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];
@@ -790,6 +790,19 @@ status_t MediaPlayerService::Client::setDataSource(
return mStatus;
}
+status_t MediaPlayerService::Client::setDataSource(
+ const sp<IDataSource> &source) {
+ sp<DataSource> dataSource = DataSource::CreateFromIDataSource(source);
+ player_type playerType = MediaPlayerFactory::getPlayerType(this, dataSource);
+ sp<MediaPlayerBase> p = setDataSource_pre(playerType);
+ if (p == NULL) {
+ return NO_INIT;
+ }
+ // now set data source
+ setDataSource_post(p, p->setDataSource(dataSource));
+ return mStatus;
+}
+
void MediaPlayerService::Client::disconnectNativeWindow() {
if (mConnectedWindow != NULL) {
status_t err = native_window_api_disconnect(mConnectedWindow.get(),
@@ -1448,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 4ce4b81..6ddfe14 100644
--- a/media/libmediaplayerservice/MediaPlayerService.h
+++ b/media/libmediaplayerservice/MediaPlayerService.h
@@ -35,6 +35,7 @@
namespace android {
class AudioTrack;
+class IDataSource;
class IMediaRecorder;
class IMediaMetadataRetriever;
class IOMX;
@@ -292,6 +293,8 @@ private:
virtual status_t setDataSource(int fd, int64_t offset, int64_t length);
virtual status_t setDataSource(const sp<IStreamSource> &source);
+ virtual status_t setDataSource(const sp<IDataSource> &source);
+
sp<MediaPlayerBase> setDataSource_pre(player_type playerType);
void setDataSource_post(const sp<MediaPlayerBase>& p,
@@ -301,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 715cc0c..6ef4c1f 100644
--- a/media/libmediaplayerservice/MetadataRetrieverClient.cpp
+++ b/media/libmediaplayerservice/MetadataRetrieverClient.cpp
@@ -34,6 +34,7 @@
#include <media/IMediaHTTPService.h>
#include <media/MediaMetadataRetrieverInterface.h>
#include <media/MediaPlayerInterface.h>
+#include <media/stagefright/DataSource.h>
#include <private/media/VideoFrame.h>
#include "MetadataRetrieverClient.h"
#include "StagefrightMetadataRetriever.h"
@@ -56,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];
@@ -173,6 +174,23 @@ status_t MetadataRetrieverClient::setDataSource(int fd, int64_t offset, int64_t
return status;
}
+status_t MetadataRetrieverClient::setDataSource(
+ const sp<IDataSource>& source)
+{
+ ALOGV("setDataSource(IDataSource)");
+ Mutex::Autolock lock(mLock);
+
+ sp<DataSource> dataSource = DataSource::CreateFromIDataSource(source);
+ player_type playerType =
+ MediaPlayerFactory::getPlayerType(NULL /* client */, dataSource);
+ ALOGV("player type = %d", playerType);
+ sp<MediaMetadataRetrieverBase> p = createRetriever(playerType);
+ if (p == NULL) return NO_INIT;
+ status_t ret = p->setDataSource(dataSource);
+ if (ret == NO_ERROR) mRetriever = p;
+ return ret;
+}
+
sp<IMemory> MetadataRetrieverClient::getFrameAtTime(int64_t timeUs, int option)
{
ALOGV("getFrameAtTime: time(%lld us) option(%d)", timeUs, option);
diff --git a/media/libmediaplayerservice/MetadataRetrieverClient.h b/media/libmediaplayerservice/MetadataRetrieverClient.h
index 9d3fbe9..e71a29e 100644
--- a/media/libmediaplayerservice/MetadataRetrieverClient.h
+++ b/media/libmediaplayerservice/MetadataRetrieverClient.h
@@ -49,11 +49,12 @@ public:
const KeyedVector<String8, String8> *headers);
virtual status_t setDataSource(int fd, int64_t offset, int64_t length);
+ virtual status_t setDataSource(const sp<IDataSource>& source);
virtual sp<IMemory> getFrameAtTime(int64_t timeUs, int option);
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 6609874..20193c3 100644
--- a/media/libmediaplayerservice/nuplayer/Android.mk
+++ b/media/libmediaplayerservice/nuplayer/Android.mk
@@ -16,6 +16,7 @@ LOCAL_SRC_FILES:= \
StreamingSource.cpp \
LOCAL_C_INCLUDES := \
+ $(TOP)/frameworks/av/media/libstagefright \
$(TOP)/frameworks/av/media/libstagefright/httplive \
$(TOP)/frameworks/av/media/libstagefright/include \
$(TOP)/frameworks/av/media/libstagefright/mpeg2ts \
@@ -24,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 5a31b74..b7a88e7 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
@@ -124,6 +124,12 @@ status_t NuPlayer::GenericSource::setDataSource(
return OK;
}
+status_t NuPlayer::GenericSource::setDataSource(const sp<DataSource>& source) {
+ resetDataSource();
+ mDataSource = source;
+ return OK;
+}
+
sp<MetaData> NuPlayer::GenericSource::getFileFormatMeta() const {
return mFileMeta;
}
@@ -377,20 +383,20 @@ void NuPlayer::GenericSource::onPrepareAsync() {
notifyPreparedAndCleanup(UNKNOWN_ERROR);
return;
}
+ }
- if (mDataSource->flags() & DataSource::kIsCachingDataSource) {
- mCachedSource = static_cast<NuCachedSource2 *>(mDataSource.get());
- }
-
- // For widevine or other cached streaming cases, we need to wait for
- // enough buffering before reporting prepared.
- // Note that even when URL doesn't start with widevine://, mIsWidevine
- // could still be set to true later, if the streaming or file source
- // is sniffed to be widevine. We don't want to buffer for file source
- // in that case, so must check the flag now.
- mIsStreaming = (mIsWidevine || mCachedSource != NULL);
+ if (mDataSource->flags() & DataSource::kIsCachingDataSource) {
+ mCachedSource = static_cast<NuCachedSource2 *>(mDataSource.get());
}
+ // For widevine or other cached streaming cases, we need to wait for
+ // enough buffering before reporting prepared.
+ // Note that even when URL doesn't start with widevine://, mIsWidevine
+ // could still be set to true later, if the streaming or file source
+ // is sniffed to be widevine. We don't want to buffer for file source
+ // in that case, so must check the flag now.
+ mIsStreaming = (mIsWidevine || mCachedSource != NULL);
+
// init extractor from data source
status_t err = initFromDataSource();
@@ -697,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) {
@@ -784,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/GenericSource.h b/media/libmediaplayerservice/nuplayer/GenericSource.h
index 862ee5f..7fab051 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.h
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.h
@@ -31,12 +31,13 @@ class DecryptHandle;
class DrmManagerClient;
struct AnotherPacketSource;
struct ARTSPController;
-struct DataSource;
+class DataSource;
+class IDataSource;
struct IMediaHTTPService;
struct MediaSource;
class MediaBuffer;
struct NuCachedSource2;
-struct WVMExtractor;
+class WVMExtractor;
struct NuPlayer::GenericSource : public NuPlayer::Source {
GenericSource(const sp<AMessage> &notify, bool uidValid, uid_t uid);
@@ -48,6 +49,8 @@ struct NuPlayer::GenericSource : public NuPlayer::Source {
status_t setDataSource(int fd, int64_t offset, int64_t length);
+ status_t setDataSource(const sp<DataSource>& dataSource);
+
virtual void prepareAsync();
virtual void start();
diff --git a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp
index 0476c9b..39b8d09 100644
--- a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp
@@ -22,7 +22,6 @@
#include "AnotherPacketSource.h"
#include "LiveDataSource.h"
-#include "LiveSession.h"
#include <media/IMediaHTTPService.h>
#include <media/stagefright/foundation/ABuffer.h>
@@ -30,6 +29,7 @@
#include <media/stagefright/foundation/AMessage.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/MetaData.h>
+#include <media/stagefright/MediaDefs.h>
namespace android {
@@ -44,7 +44,10 @@ NuPlayer::HTTPLiveSource::HTTPLiveSource(
mFlags(0),
mFinalResult(OK),
mOffset(0),
- mFetchSubtitleDataGeneration(0) {
+ mFetchSubtitleDataGeneration(0),
+ mFetchMetaDataGeneration(0),
+ mHasMetadata(false),
+ mMetadataSelected(false) {
if (headers) {
mExtraHeaders = *headers;
@@ -142,19 +145,49 @@ sp<AMessage> NuPlayer::HTTPLiveSource::getTrackInfo(size_t trackIndex) const {
ssize_t NuPlayer::HTTPLiveSource::getSelectedTrack(media_track_type type) const {
if (mLiveSession == NULL) {
return -1;
+ } else if (type == MEDIA_TRACK_TYPE_METADATA) {
+ // MEDIA_TRACK_TYPE_METADATA is always last track
+ // mMetadataSelected can only be true when mHasMetadata is true
+ return mMetadataSelected ? (mLiveSession->getTrackCount() - 1) : -1;
} else {
return mLiveSession->getSelectedTrack(type);
}
}
status_t NuPlayer::HTTPLiveSource::selectTrack(size_t trackIndex, bool select, int64_t /*timeUs*/) {
- status_t err = mLiveSession->selectTrack(trackIndex, select);
+ if (mLiveSession == NULL) {
+ return INVALID_OPERATION;
+ }
+
+ status_t err = INVALID_OPERATION;
+ bool postFetchMsg = false, isSub = false;
+ if (trackIndex != mLiveSession->getTrackCount() - 1) {
+ err = mLiveSession->selectTrack(trackIndex, select);
+ postFetchMsg = select;
+ isSub = true;
+ } else {
+ // metadata track
+ if (mHasMetadata) {
+ if (mMetadataSelected && !select) {
+ err = OK;
+ } else if (!mMetadataSelected && select) {
+ postFetchMsg = true;
+ err = OK;
+ } else {
+ err = BAD_VALUE; // behave as LiveSession::selectTrack
+ }
+
+ mMetadataSelected = select;
+ }
+ }
if (err == OK) {
- mFetchSubtitleDataGeneration++;
- if (select) {
- sp<AMessage> msg = new AMessage(kWhatFetchSubtitleData, this);
- msg->setInt32("generation", mFetchSubtitleDataGeneration);
+ int32_t &generation = isSub ? mFetchSubtitleDataGeneration : mFetchMetaDataGeneration;
+ generation++;
+ if (postFetchMsg) {
+ int32_t what = isSub ? kWhatFetchSubtitleData : kWhatFetchMetaData;
+ sp<AMessage> msg = new AMessage(what, this);
+ msg->setInt32("generation", generation);
msg->post();
}
}
@@ -169,6 +202,49 @@ status_t NuPlayer::HTTPLiveSource::seekTo(int64_t seekTimeUs) {
return mLiveSession->seekTo(seekTimeUs);
}
+void NuPlayer::HTTPLiveSource::pollForRawData(
+ const sp<AMessage> &msg, int32_t currentGeneration,
+ LiveSession::StreamType fetchType, int32_t pushWhat) {
+
+ int32_t generation;
+ CHECK(msg->findInt32("generation", &generation));
+
+ if (generation != currentGeneration) {
+ return;
+ }
+
+ sp<ABuffer> buffer;
+ while (mLiveSession->dequeueAccessUnit(fetchType, &buffer) == OK) {
+
+ sp<AMessage> notify = dupNotify();
+ notify->setInt32("what", pushWhat);
+ notify->setBuffer("buffer", buffer);
+
+ int64_t timeUs, baseUs, delayUs;
+ CHECK(buffer->meta()->findInt64("baseUs", &baseUs));
+ CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
+ delayUs = baseUs + timeUs - ALooper::GetNowUs();
+
+ if (fetchType == LiveSession::STREAMTYPE_SUBTITLES) {
+ notify->post();
+ msg->post(delayUs > 0ll ? delayUs : 0ll);
+ return;
+ } else if (fetchType == LiveSession::STREAMTYPE_METADATA) {
+ if (delayUs < -1000000ll) { // 1 second
+ continue;
+ }
+ notify->post();
+ // push all currently available metadata buffers in each invocation of pollForRawData
+ // continue;
+ } else {
+ TRESPASS();
+ }
+ }
+
+ // try again in 1 second
+ msg->post(1000000ll);
+}
+
void NuPlayer::HTTPLiveSource::onMessageReceived(const sp<AMessage> &msg) {
switch (msg->what()) {
case kWhatSessionNotify:
@@ -179,33 +255,24 @@ void NuPlayer::HTTPLiveSource::onMessageReceived(const sp<AMessage> &msg) {
case kWhatFetchSubtitleData:
{
- int32_t generation;
- CHECK(msg->findInt32("generation", &generation));
+ pollForRawData(
+ msg, mFetchSubtitleDataGeneration,
+ /* fetch */ LiveSession::STREAMTYPE_SUBTITLES,
+ /* push */ kWhatSubtitleData);
+
+ break;
+ }
- if (generation != mFetchSubtitleDataGeneration) {
- // stale
+ case kWhatFetchMetaData:
+ {
+ if (!mMetadataSelected) {
break;
}
- sp<ABuffer> buffer;
- if (mLiveSession->dequeueAccessUnit(
- LiveSession::STREAMTYPE_SUBTITLES, &buffer) == OK) {
- sp<AMessage> notify = dupNotify();
- notify->setInt32("what", kWhatSubtitleData);
- notify->setBuffer("buffer", buffer);
- notify->post();
-
- int64_t timeUs, baseUs, durationUs, delayUs;
- CHECK(buffer->meta()->findInt64("baseUs", &baseUs));
- CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
- CHECK(buffer->meta()->findInt64("durationUs", &durationUs));
- delayUs = baseUs + timeUs - ALooper::GetNowUs();
-
- msg->post(delayUs > 0ll ? delayUs : 0ll);
- } else {
- // try again in 1 second
- msg->post(1000000ll);
- }
+ pollForRawData(
+ msg, mFetchMetaDataGeneration,
+ /* fetch */ LiveSession::STREAMTYPE_METADATA,
+ /* push */ kWhatTimedMetaData);
break;
}
@@ -309,6 +376,19 @@ void NuPlayer::HTTPLiveSource::onSessionNotify(const sp<AMessage> &msg) {
break;
}
+ case LiveSession::kWhatMetadataDetected:
+ {
+ if (!mHasMetadata) {
+ mHasMetadata = true;
+
+ sp<AMessage> notify = dupNotify();
+ // notification without buffer triggers MEDIA_INFO_METADATA_UPDATE
+ notify->setInt32("what", kWhatTimedMetaData);
+ notify->post();
+ }
+ break;
+ }
+
case LiveSession::kWhatError:
{
break;
diff --git a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h
index bbb8981..9e0ec2f 100644
--- a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h
+++ b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h
@@ -21,6 +21,8 @@
#include "NuPlayer.h"
#include "NuPlayerSource.h"
+#include "LiveSession.h"
+
namespace android {
struct LiveSession;
@@ -60,6 +62,7 @@ private:
enum {
kWhatSessionNotify,
kWhatFetchSubtitleData,
+ kWhatFetchMetaData,
};
sp<IMediaHTTPService> mHTTPService;
@@ -71,8 +74,14 @@ private:
sp<ALooper> mLiveLooper;
sp<LiveSession> mLiveSession;
int32_t mFetchSubtitleDataGeneration;
+ int32_t mFetchMetaDataGeneration;
+ bool mHasMetadata;
+ bool mMetadataSelected;
void onSessionNotify(const sp<AMessage> &msg);
+ void pollForRawData(
+ const sp<AMessage> &msg, int32_t currentGeneration,
+ LiveSession::StreamType fetchType, int32_t pushWhat);
DISALLOW_EVIL_CONSTRUCTORS(HTTPLiveSource);
};
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index 02d9f32..a028b01 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -285,6 +285,22 @@ void NuPlayer::setDataSourceAsync(int fd, int64_t offset, int64_t length) {
msg->post();
}
+void NuPlayer::setDataSourceAsync(const sp<DataSource> &dataSource) {
+ sp<AMessage> msg = new AMessage(kWhatSetDataSource, this);
+ sp<AMessage> notify = new AMessage(kWhatSourceNotify, this);
+
+ sp<GenericSource> source = new GenericSource(notify, mUIDValid, mUID);
+ status_t err = source->setDataSource(dataSource);
+
+ if (err != OK) {
+ ALOGE("Failed to set data source!");
+ source = NULL;
+ }
+
+ msg->setObject("source", source);
+ msg->post();
+}
+
void NuPlayer::prepareAsync() {
(new AMessage(kWhatPrepare, this))->post();
}
@@ -955,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 */,
@@ -1320,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));
@@ -1403,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();
@@ -1554,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);
@@ -1843,6 +1861,17 @@ void NuPlayer::onSourceNotify(const sp<AMessage> &msg) {
break;
}
+ case Source::kWhatTimedMetaData:
+ {
+ sp<ABuffer> buffer;
+ if (!msg->findBuffer("buffer", &buffer)) {
+ notifyListener(MEDIA_INFO, MEDIA_INFO_METADATA_UPDATE, 0);
+ } else {
+ sendTimedMetaData(buffer);
+ }
+ break;
+ }
+
case Source::kWhatTimedTextData:
{
int32_t generation;
@@ -1951,6 +1980,19 @@ void NuPlayer::sendSubtitleData(const sp<ABuffer> &buffer, int32_t baseIndex) {
notifyListener(MEDIA_SUBTITLE_DATA, 0, 0, &in);
}
+void NuPlayer::sendTimedMetaData(const sp<ABuffer> &buffer) {
+ int64_t timeUs;
+ CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
+
+ Parcel in;
+ in.writeInt64(timeUs);
+ in.writeInt32(buffer->size());
+ in.writeInt32(buffer->size());
+ in.write(buffer->data(), buffer->size());
+
+ notifyListener(MEDIA_META_DATA, 0, 0, &in);
+}
+
void NuPlayer::sendTimedTextData(const sp<ABuffer> &buffer) {
const void *data;
size_t size = 0;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h
index 2bc20d7..14bdb01 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h
@@ -26,6 +26,7 @@ namespace android {
struct ABuffer;
struct AMessage;
+class IDataSource;
class MetaData;
struct NuPlayerDriver;
@@ -45,6 +46,8 @@ struct NuPlayer : public AHandler {
void setDataSourceAsync(int fd, int64_t offset, int64_t length);
+ void setDataSourceAsync(const sp<DataSource> &source);
+
void prepareAsync();
void setVideoSurfaceTextureAsync(
@@ -246,6 +249,7 @@ private:
bool audio, bool video, const sp<AMessage> &reply);
void sendSubtitleData(const sp<ABuffer> &buffer, int32_t baseIndex);
+ void sendTimedMetaData(const sp<ABuffer> &buffer);
void sendTimedTextData(const sp<ABuffer> &buffer);
void writeTrackInfo(Parcel* reply, const sp<AMessage> format) const;
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 97e9269..262f5d5 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.h
@@ -26,7 +26,7 @@ namespace android {
struct ABuffer;
struct MediaCodec;
-struct MediaBuffer;
+class MediaBuffer;
struct NuPlayer::DecoderBase : public AHandler {
DecoderBase(const sp<AMessage> &notify);
@@ -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/NuPlayerDriver.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
index 1fa9cef..04a324c 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
@@ -135,6 +135,25 @@ status_t NuPlayerDriver::setDataSource(const sp<IStreamSource> &source) {
return mAsyncResult;
}
+status_t NuPlayerDriver::setDataSource(const sp<DataSource> &source) {
+ ALOGV("setDataSource(%p) callback source", this);
+ Mutex::Autolock autoLock(mLock);
+
+ if (mState != STATE_IDLE) {
+ return INVALID_OPERATION;
+ }
+
+ mState = STATE_SET_DATASOURCE_PENDING;
+
+ mPlayer->setDataSourceAsync(source);
+
+ while (mState == STATE_SET_DATASOURCE_PENDING) {
+ mCondition.wait(mLock);
+ }
+
+ return mAsyncResult;
+}
+
status_t NuPlayerDriver::setVideoSurfaceTexture(
const sp<IGraphicBufferProducer> &bufferProducer) {
ALOGV("setVideoSurfaceTexture(%p)", this);
@@ -369,6 +388,9 @@ status_t NuPlayerDriver::seekTo(int msec) {
{
mAtEOS = false;
mSeekInProgress = true;
+ if (mState == STATE_PAUSED) {
+ mStartupSeekTimeUs = seekTimeUs;
+ }
// seeks can take a while, so we essentially paused
notifyListener_l(MEDIA_PAUSED);
mPlayer->seekToAsync(seekTimeUs, true /* needNotify */);
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
index e53abcd..65f170e 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
@@ -39,6 +39,8 @@ struct NuPlayerDriver : public MediaPlayerInterface {
virtual status_t setDataSource(const sp<IStreamSource> &source);
+ virtual status_t setDataSource(const sp<DataSource>& dataSource);
+
virtual status_t setVideoSurfaceTexture(
const sp<IGraphicBufferProducer> &bufferProducer);
virtual status_t prepare();
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/nuplayer/NuPlayerSource.h b/media/libmediaplayerservice/nuplayer/NuPlayerSource.h
index d9f14a2..ef1ba13 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerSource.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerSource.h
@@ -28,7 +28,7 @@
namespace android {
struct ABuffer;
-struct MediaBuffer;
+class MediaBuffer;
struct NuPlayer::Source : public AHandler {
enum Flags {
@@ -53,6 +53,7 @@ struct NuPlayer::Source : public AHandler {
kWhatCacheStats,
kWhatSubtitleData,
kWhatTimedTextData,
+ kWhatTimedMetaData,
kWhatQueueDecoderShutdown,
kWhatDrmNoLicense,
kWhatInstantiateSecureDecoders,
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/AACExtractor.cpp b/media/libstagefright/AACExtractor.cpp
index 196f6ee..45e8a30 100644
--- a/media/libstagefright/AACExtractor.cpp
+++ b/media/libstagefright/AACExtractor.cpp
@@ -360,7 +360,7 @@ bool SniffAAC(
pos += len;
ALOGV("skipped ID3 tag, new starting offset is %lld (0x%016llx)",
- pos, pos);
+ (long long)pos, (long long)pos);
}
uint8_t header[2];
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 45f6339..da22f11 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -629,14 +629,23 @@ status_t ACodec::configureOutputBuffersFromNativeWindow(
return err;
}
- err = native_window_set_buffers_geometry(
+ err = native_window_set_buffers_dimensions(
mNativeWindow.get(),
def.format.video.nFrameWidth,
- def.format.video.nFrameHeight,
+ def.format.video.nFrameHeight);
+
+ if (err != 0) {
+ ALOGE("native_window_set_buffers_dimensions failed: %s (%d)",
+ strerror(-err), -err);
+ return err;
+ }
+
+ err = native_window_set_buffers_format(
+ mNativeWindow.get(),
def.format.video.eColorFormat);
if (err != 0) {
- ALOGE("native_window_set_buffers_geometry failed: %s (%d)",
+ ALOGE("native_window_set_buffers_format failed: %s (%d)",
strerror(-err), -err);
return err;
}
@@ -990,7 +999,7 @@ ACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
CHECK_EQ(metaData->eType, kMetadataBufferTypeGrallocSource);
ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
- oldest - &mBuffers[kPortIndexOutput][0],
+ (unsigned)(oldest - &mBuffers[kPortIndexOutput][0]),
mDequeueCounter - oldest->mDequeuedAt,
metaData->pHandle,
oldest->mGraphicBuffer->handle, oldest->mData->base());
@@ -1598,7 +1607,7 @@ status_t ACodec::configureCodec(
err = setupG711Codec(encoder, sampleRate, numChannels);
}
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
- int32_t numChannels, sampleRate, compressionLevel = -1;
+ int32_t numChannels = 0, sampleRate = 0, compressionLevel = -1;
if (encoder &&
(!msg->findInt32("channel-count", &numChannels)
|| !msg->findInt32("sample-rate", &sampleRate))) {
@@ -3926,9 +3935,7 @@ void ACodec::sendFormatChange(const sp<AMessage> &reply) {
if (mSkipCutBuffer != NULL) {
size_t prevbufsize = mSkipCutBuffer->size();
if (prevbufsize != 0) {
- ALOGW("Replacing SkipCutBuffer holding %d "
- "bytes",
- prevbufsize);
+ ALOGW("Replacing SkipCutBuffer holding %zu bytes", prevbufsize);
}
}
mSkipCutBuffer = new SkipCutBuffer(
@@ -3984,10 +3991,16 @@ status_t ACodec::pushBlankBuffersToNativeWindow() {
return err;
}
- err = native_window_set_buffers_geometry(mNativeWindow.get(), 1, 1,
- HAL_PIXEL_FORMAT_RGBX_8888);
+ err = native_window_set_buffers_dimensions(mNativeWindow.get(), 1, 1);
+ if (err != NO_ERROR) {
+ ALOGE("error pushing blank frames: set_buffers_dimensions failed: %s (%d)",
+ strerror(-err), -err);
+ goto error;
+ }
+
+ err = native_window_set_buffers_format(mNativeWindow.get(), HAL_PIXEL_FORMAT_RGBX_8888);
if (err != NO_ERROR) {
- ALOGE("error pushing blank frames: set_buffers_geometry failed: %s (%d)",
+ ALOGE("error pushing blank frames: set_buffers_format failed: %s (%d)",
strerror(-err), -err);
goto error;
}
@@ -4218,7 +4231,7 @@ bool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
// there is a possibility that this is an outstanding message for a
// codec that we have already destroyed
- if (mCodec->mNode == NULL) {
+ if (mCodec->mNode == 0) {
ALOGI("ignoring message as already freed component: %s",
msg->debugString().c_str());
return true;
@@ -4290,13 +4303,13 @@ bool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
bool ACodec::BaseState::onOMXEvent(
OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
if (event != OMX_EventError) {
- ALOGV("[%s] EVENT(%d, 0x%08lx, 0x%08lx)",
+ ALOGV("[%s] EVENT(%d, 0x%08x, 0x%08x)",
mCodec->mComponentName.c_str(), event, data1, data2);
return false;
}
- ALOGE("[%s] ERROR(0x%08lx)", mCodec->mComponentName.c_str(), data1);
+ ALOGE("[%s] ERROR(0x%08x)", mCodec->mComponentName.c_str(), data1);
// verify OMX component sends back an error we expect.
OMX_ERRORTYPE omxError = (OMX_ERRORTYPE)data1;
@@ -4310,7 +4323,7 @@ bool ACodec::BaseState::onOMXEvent(
}
bool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID) {
- ALOGV("[%s] onOMXEmptyBufferDone %p",
+ ALOGV("[%s] onOMXEmptyBufferDone %u",
mCodec->mComponentName.c_str(), bufferID);
BufferInfo *info =
@@ -4436,7 +4449,7 @@ void ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
}
if (buffer != info->mData) {
- ALOGV("[%s] Needs to copy input data for buffer %p. (%p != %p)",
+ ALOGV("[%s] Needs to copy input data for buffer %u. (%p != %p)",
mCodec->mComponentName.c_str(),
bufferID,
buffer.get(), info->mData.get());
@@ -4446,18 +4459,18 @@ void ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
}
if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
- ALOGV("[%s] calling emptyBuffer %p w/ codec specific data",
+ ALOGV("[%s] calling emptyBuffer %u w/ codec specific data",
mCodec->mComponentName.c_str(), bufferID);
} else if (flags & OMX_BUFFERFLAG_EOS) {
- ALOGV("[%s] calling emptyBuffer %p w/ EOS",
+ ALOGV("[%s] calling emptyBuffer %u w/ EOS",
mCodec->mComponentName.c_str(), bufferID);
} else {
#if TRACK_BUFFER_TIMING
- ALOGI("[%s] calling emptyBuffer %p w/ time %lld us",
- mCodec->mComponentName.c_str(), bufferID, timeUs);
+ ALOGI("[%s] calling emptyBuffer %u w/ time %lld us",
+ mCodec->mComponentName.c_str(), bufferID, (long long)timeUs);
#else
- ALOGV("[%s] calling emptyBuffer %p w/ time %lld us",
- mCodec->mComponentName.c_str(), bufferID, timeUs);
+ ALOGV("[%s] calling emptyBuffer %u w/ time %lld us",
+ mCodec->mComponentName.c_str(), bufferID, (long long)timeUs);
#endif
}
@@ -4511,7 +4524,7 @@ void ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
mCodec->mComponentName.c_str());
}
- ALOGV("[%s] calling emptyBuffer %p signalling EOS",
+ ALOGV("[%s] calling emptyBuffer %u signalling EOS",
mCodec->mComponentName.c_str(), bufferID);
CHECK_EQ(mCodec->mOMX->emptyBuffer(
@@ -4812,7 +4825,7 @@ void ACodec::UninitializedState::stateEntered() {
}
mCodec->mNativeWindow.clear();
- mCodec->mNode = NULL;
+ mCodec->mNode = 0;
mCodec->mOMX.clear();
mCodec->mQuirks = 0;
mCodec->mFlags = 0;
@@ -4890,7 +4903,7 @@ void ACodec::UninitializedState::onSetup(
bool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
ALOGV("onAllocateComponent");
- CHECK(mCodec->mNode == NULL);
+ CHECK(mCodec->mNode == 0);
OMXClient client;
CHECK_EQ(client.connect(), (status_t)OK);
@@ -4938,7 +4951,7 @@ bool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
}
sp<CodecObserver> observer = new CodecObserver;
- IOMX::node_id node = NULL;
+ IOMX::node_id node = 0;
status_t err = OMX_ErrorComponentNotFound;
for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
@@ -4958,10 +4971,10 @@ bool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
ALOGW("Allocating component '%s' failed, try next one.", componentName.c_str());
}
- node = NULL;
+ node = 0;
}
- if (node == NULL) {
+ if (node == 0) {
if (!mime.empty()) {
ALOGE("Unable to instantiate a %scoder for type '%s' with err %#x.",
encoder ? "en" : "de", mime.c_str(), err);
@@ -5109,7 +5122,7 @@ bool ACodec::LoadedState::onConfigureComponent(
const sp<AMessage> &msg) {
ALOGV("onConfigureComponent");
- CHECK(mCodec->mNode != NULL);
+ CHECK(mCodec->mNode != 0);
AString mime;
CHECK(msg->findString("mime", &mime));
@@ -5449,7 +5462,7 @@ void ACodec::ExecutingState::submitRegularOutputBuffers() {
CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
}
- ALOGV("[%s] calling fillBuffer %p",
+ ALOGV("[%s] calling fillBuffer %u",
mCodec->mComponentName.c_str(), info->mBufferID);
CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
@@ -5523,7 +5536,7 @@ bool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
case kWhatFlush:
{
ALOGV("[%s] ExecutingState flushing now "
- "(codec owns %d/%d input, %d/%d output).",
+ "(codec owns %zu/%zu input, %zu/%zu output).",
mCodec->mComponentName.c_str(),
mCodec->countBuffersOwnedByComponent(kPortIndexInput),
mCodec->mBuffers[kPortIndexInput].size(),
@@ -5705,7 +5718,7 @@ bool ACodec::ExecutingState::onOMXEvent(
} else if (data2 == OMX_IndexConfigCommonOutputCrop) {
mCodec->mSentFormat = false;
} else {
- ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08lx",
+ ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08x",
mCodec->mComponentName.c_str(), data2);
}
@@ -6035,8 +6048,8 @@ bool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
bool ACodec::FlushingState::onOMXEvent(
OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
- ALOGV("[%s] FlushingState onOMXEvent(%d,%ld)",
- mCodec->mComponentName.c_str(), event, data1);
+ ALOGV("[%s] FlushingState onOMXEvent(%u,%d)",
+ mCodec->mComponentName.c_str(), event, (OMX_S32)data1);
switch (event) {
case OMX_EventCmdComplete:
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index b0eeb7f..45581f3 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -12,6 +12,7 @@ LOCAL_SRC_FILES:= \
AudioPlayer.cpp \
AudioSource.cpp \
AwesomePlayer.cpp \
+ CallbackDataSource.cpp \
CameraSource.cpp \
CameraSourceTimeLapse.cpp \
ClockEstimator.cpp \
@@ -122,7 +123,8 @@ LOCAL_SHARED_LIBRARIES += \
libdl \
libRScpp \
-LOCAL_CFLAGS += -Wno-multichar
+LOCAL_CFLAGS += -Wno-multichar -Werror -Wall
+LOCAL_CLANG := true
LOCAL_MODULE:= libstagefright
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 87eef1e..c14625d 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -360,7 +360,7 @@ status_t AwesomePlayer::setDataSource(
return setDataSource_l(dataSource);
}
-status_t AwesomePlayer::setDataSource(const sp<IStreamSource> &source) {
+status_t AwesomePlayer::setDataSource(const sp<IStreamSource> &source __unused) {
return INVALID_OPERATION;
}
@@ -422,7 +422,7 @@ status_t AwesomePlayer::setDataSource_l(const sp<MediaExtractor> &extractor) {
mBitrate = totalBitRate;
- ALOGV("mBitrate = %lld bits/sec", mBitrate);
+ ALOGV("mBitrate = %lld bits/sec", (long long)mBitrate);
{
Mutex::Autolock autoLock(mStatsLock);
@@ -1722,7 +1722,7 @@ void AwesomePlayer::finishSeekIfNecessary(int64_t videoTimeUs) {
// we are now resuming. Signal new position to media time provider.
// Cannot signal another SEEK_COMPLETE, as existing clients may not expect
// multiple SEEK_COMPLETE responses to a single seek() request.
- if (mSeekNotificationSent && abs(mSeekTimeUs - videoTimeUs) > 10000) {
+ if (mSeekNotificationSent && llabs((long long)(mSeekTimeUs - videoTimeUs)) > 10000) {
// notify if we are resuming more than 10ms away from desired seek time
notifyListener_l(MEDIA_SKIPPED);
}
@@ -2358,7 +2358,7 @@ status_t AwesomePlayer::finishSetDataSource_l() {
}
CHECK_GE(metaDataSize, 0ll);
- ALOGV("metaDataSize = %lld bytes", metaDataSize);
+ ALOGV("metaDataSize = %lld bytes", (long long)metaDataSize);
}
usleep(200000);
diff --git a/media/libstagefright/CallbackDataSource.cpp b/media/libstagefright/CallbackDataSource.cpp
new file mode 100644
index 0000000..41f0175
--- /dev/null
+++ b/media/libstagefright/CallbackDataSource.cpp
@@ -0,0 +1,143 @@
+/*
+ * Copyright 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "CallbackDataSource"
+#include <utils/Log.h>
+
+#include "include/CallbackDataSource.h"
+
+#include <binder/IMemory.h>
+#include <media/IDataSource.h>
+#include <media/stagefright/foundation/ADebug.h>
+
+#include <algorithm>
+
+namespace android {
+
+CallbackDataSource::CallbackDataSource(
+ const sp<IDataSource>& binderDataSource)
+ : mIDataSource(binderDataSource) {
+ // Set up the buffer to read into.
+ mMemory = mIDataSource->getIMemory();
+}
+
+CallbackDataSource::~CallbackDataSource() {
+ ALOGV("~CallbackDataSource");
+ mIDataSource->close();
+}
+
+status_t CallbackDataSource::initCheck() const {
+ if (mMemory == NULL) {
+ return UNKNOWN_ERROR;
+ }
+ return OK;
+}
+
+ssize_t CallbackDataSource::readAt(off64_t offset, void* data, size_t size) {
+ if (mMemory == NULL) {
+ return -1;
+ }
+
+ // IDataSource can only read up to mMemory->size() bytes at a time, but this
+ // method should be able to read any number of bytes, so read in a loop.
+ size_t totalNumRead = 0;
+ size_t numLeft = size;
+ const size_t bufferSize = mMemory->size();
+
+ while (numLeft > 0) {
+ size_t numToRead = std::min(numLeft, bufferSize);
+ ssize_t numRead =
+ mIDataSource->readAt(offset + totalNumRead, numToRead);
+ // A negative return value represents an error. Pass it on.
+ if (numRead < 0) {
+ return numRead;
+ }
+ // A zero return value signals EOS. Return the bytes read so far.
+ if (numRead == 0) {
+ return totalNumRead;
+ }
+ if ((size_t)numRead > numToRead) {
+ return ERROR_OUT_OF_RANGE;
+ }
+ CHECK(numRead >= 0 && (size_t)numRead <= bufferSize);
+ memcpy(((uint8_t*)data) + totalNumRead, mMemory->pointer(), numRead);
+ numLeft -= numRead;
+ totalNumRead += numRead;
+ }
+
+ return totalNumRead;
+}
+
+status_t CallbackDataSource::getSize(off64_t *size) {
+ status_t err = mIDataSource->getSize(size);
+ if (err != OK) {
+ return err;
+ }
+ if (*size < 0) {
+ // IDataSource will set size to -1 to indicate unknown size, but
+ // DataSource returns ERROR_UNSUPPORTED for that.
+ return ERROR_UNSUPPORTED;
+ }
+ return OK;
+}
+
+TinyCacheSource::TinyCacheSource(const sp<DataSource>& source)
+ : mSource(source), mCachedOffset(0), mCachedSize(0) {
+}
+
+status_t TinyCacheSource::initCheck() const {
+ return mSource->initCheck();
+}
+
+ssize_t TinyCacheSource::readAt(off64_t offset, void* data, size_t size) {
+ if (size >= kCacheSize) {
+ return mSource->readAt(offset, data, size);
+ }
+
+ // Check if the cache satisfies the read.
+ if (offset >= mCachedOffset && offset + size <= mCachedOffset + mCachedSize) {
+ memcpy(data, &mCache[offset - mCachedOffset], size);
+ return size;
+ }
+
+ // Fill the cache and copy to the caller.
+ const ssize_t numRead = mSource->readAt(offset, mCache, kCacheSize);
+ if (numRead <= 0) {
+ return numRead;
+ }
+ if ((size_t)numRead > kCacheSize) {
+ return ERROR_OUT_OF_RANGE;
+ }
+
+ mCachedSize = numRead;
+ mCachedOffset = offset;
+ CHECK(mCachedSize <= kCacheSize && mCachedOffset >= 0);
+ const size_t numToReturn = std::min(size, (size_t)numRead);
+ memcpy(data, mCache, numToReturn);
+
+ return numToReturn;
+}
+
+status_t TinyCacheSource::getSize(off64_t *size) {
+ return mSource->getSize(size);
+}
+
+uint32_t TinyCacheSource::flags() {
+ return mSource->flags();
+}
+
+} // namespace android
diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp
index ad12bdd..1b788f3 100644
--- a/media/libstagefright/CameraSource.cpp
+++ b/media/libstagefright/CameraSource.cpp
@@ -851,11 +851,11 @@ status_t CameraSource::read(
}
void CameraSource::dataCallbackTimestamp(int64_t timestampUs,
- int32_t msgType, const sp<IMemory> &data) {
- ALOGV("dataCallbackTimestamp: timestamp %" PRId64 " us", timestampUs);
+ int32_t msgType __unused, const sp<IMemory> &data) {
+ ALOGV("dataCallbackTimestamp: timestamp %lld us", (long long)timestampUs);
Mutex::Autolock autoLock(mLock);
if (!mStarted || (mNumFramesReceived == 0 && timestampUs < mStartTimeUs)) {
- ALOGV("Drop frame at %" PRId64 "/%" PRId64 " us", timestampUs, mStartTimeUs);
+ ALOGV("Drop frame at %lld/%lld us", (long long)timestampUs, (long long)mStartTimeUs);
releaseOneRecordingFrame(data);
return;
}
@@ -913,7 +913,7 @@ void CameraSource::ProxyListener::dataCallbackTimestamp(
mSource->dataCallbackTimestamp(timestamp / 1000, msgType, dataPtr);
}
-void CameraSource::DeathNotifier::binderDied(const wp<IBinder>& who) {
+void CameraSource::DeathNotifier::binderDied(const wp<IBinder>& who __unused) {
ALOGI("Camera recording proxy died");
}
diff --git a/media/libstagefright/DataSource.cpp b/media/libstagefright/DataSource.cpp
index f7dcf35..75ef288 100644
--- a/media/libstagefright/DataSource.cpp
+++ b/media/libstagefright/DataSource.cpp
@@ -19,6 +19,7 @@
#include "include/AMRExtractor.h"
#include "include/AACExtractor.h"
+#include "include/CallbackDataSource.h"
#include "include/DRMExtractor.h"
#include "include/FLACExtractor.h"
#include "include/HTTPBase.h"
@@ -281,6 +282,10 @@ sp<DataSource> DataSource::CreateMediaHTTP(const sp<IMediaHTTPService> &httpServ
}
}
+sp<DataSource> DataSource::CreateFromIDataSource(const sp<IDataSource> &source) {
+ return new TinyCacheSource(new CallbackDataSource(source));
+}
+
String8 DataSource::getMIMEType() const {
return String8("application/octet-stream");
}
diff --git a/media/libstagefright/FLACExtractor.cpp b/media/libstagefright/FLACExtractor.cpp
index fa7251c..8b972b7 100644
--- a/media/libstagefright/FLACExtractor.cpp
+++ b/media/libstagefright/FLACExtractor.cpp
@@ -651,10 +651,10 @@ MediaBuffer *FLACParser::readBuffer(bool doSeek, FLAC__uint64 sample)
if (doSeek) {
// We implement the seek callback, so this works without explicit flush
if (!FLAC__stream_decoder_seek_absolute(mDecoder, sample)) {
- ALOGE("FLACParser::readBuffer seek to sample %llu failed", sample);
+ ALOGE("FLACParser::readBuffer seek to sample %lld failed", (long long)sample);
return NULL;
}
- ALOGV("FLACParser::readBuffer seek to sample %llu succeeded", sample);
+ ALOGV("FLACParser::readBuffer seek to sample %lld succeeded", (long long)sample);
} else {
if (!FLAC__stream_decoder_process_single(mDecoder)) {
ALOGE("FLACParser::readBuffer process_single failed");
diff --git a/media/libstagefright/FileSource.cpp b/media/libstagefright/FileSource.cpp
index f0db76b..565f156 100644
--- a/media/libstagefright/FileSource.cpp
+++ b/media/libstagefright/FileSource.cpp
@@ -111,7 +111,7 @@ ssize_t FileSource::readAt(off64_t offset, void *data, size_t size) {
} else {
off64_t result = lseek64(mFd, offset + mOffset, SEEK_SET);
if (result == -1) {
- ALOGE("seek to %lld failed", offset + mOffset);
+ ALOGE("seek to %lld failed", (long long)(offset + mOffset));
return UNKNOWN_ERROR;
}
diff --git a/media/libstagefright/HTTPBase.cpp b/media/libstagefright/HTTPBase.cpp
index 77a652a..068a77f 100644
--- a/media/libstagefright/HTTPBase.cpp
+++ b/media/libstagefright/HTTPBase.cpp
@@ -34,10 +34,10 @@ HTTPBase::HTTPBase()
: mNumBandwidthHistoryItems(0),
mTotalTransferTimeUs(0),
mTotalTransferBytes(0),
+ mMaxBandwidthHistoryItems(100),
mPrevBandwidthMeasureTimeUs(0),
mPrevEstimatedBandWidthKbps(0),
- mBandWidthCollectFreqMs(5000),
- mMaxBandwidthHistoryItems(100) {
+ mBandWidthCollectFreqMs(5000) {
}
void HTTPBase::addBandwidthMeasurement(
diff --git a/media/libstagefright/MP3Extractor.cpp b/media/libstagefright/MP3Extractor.cpp
index 4a63152..55e3c19 100644
--- a/media/libstagefright/MP3Extractor.cpp
+++ b/media/libstagefright/MP3Extractor.cpp
@@ -82,7 +82,7 @@ static bool Resync(
*inout_pos += len;
ALOGV("skipped ID3 tag, new starting offset is %lld (0x%016llx)",
- *inout_pos, *inout_pos);
+ (long long)*inout_pos, (long long)*inout_pos);
}
if (post_id3_pos != NULL) {
@@ -103,9 +103,9 @@ static bool Resync(
uint8_t *tmp = buf;
do {
- if (pos >= *inout_pos + kMaxBytesChecked) {
+ if (pos >= (off64_t)(*inout_pos + kMaxBytesChecked)) {
// Don't scan forever.
- ALOGV("giving up at offset %lld", pos);
+ ALOGV("giving up at offset %lld", (long long)pos);
break;
}
@@ -155,7 +155,7 @@ static bool Resync(
continue;
}
- ALOGV("found possible 1st frame at %lld (header = 0x%08x)", pos, header);
+ ALOGV("found possible 1st frame at %lld (header = 0x%08x)", (long long)pos, header);
// We found what looks like a valid frame,
// now find its successors.
@@ -186,7 +186,7 @@ static bool Resync(
break;
}
- ALOGV("found subsequent frame #%d at %lld", j + 2, test_pos);
+ ALOGV("found subsequent frame #%d at %lld", j + 2, (long long)test_pos);
test_pos += test_frame_size;
}
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index 28a9ed9..6573afc 100644
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -503,7 +503,7 @@ status_t MPEG4Extractor::readMetaData() {
} else if (offset <= orig_offset) {
// only continue parsing if the offset was advanced,
// otherwise we might end up in an infinite loop
- ALOGE("did not advance: 0x%lld->0x%lld", orig_offset, offset);
+ ALOGE("did not advance: %lld->%lld", (long long)orig_offset, (long long)offset);
err = ERROR_MALFORMED;
break;
} else if (err == UNKNOWN_ERROR) {
@@ -761,7 +761,7 @@ static void convertTimeToDate(int64_t time_1904, String8 *s) {
}
status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
- ALOGV("entering parseChunk %lld/%d", *offset, depth);
+ ALOGV("entering parseChunk %lld/%d", (long long)*offset, depth);
uint32_t hdr[2];
if (mDataSource->readAt(*offset, hdr, 8) < 8) {
return ERROR_IO;
@@ -805,7 +805,7 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
char chunk[5];
MakeFourCCString(chunk_type, chunk);
- ALOGV("chunk: %s @ %lld, %d", chunk, *offset, depth);
+ ALOGV("chunk: %s @ %lld, %d", chunk, (long long)*offset, depth);
if (kUseHexDump) {
static const char kWhitespace[] = " ";
@@ -1724,7 +1724,7 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
char buffer[23];
if (chunk_data_size != 7 &&
chunk_data_size != 23) {
- ALOGE("Incorrect D263 box size %lld", chunk_data_size);
+ ALOGE("Incorrect D263 box size %lld", (long long)chunk_data_size);
return ERROR_MALFORMED;
}
@@ -2015,7 +2015,7 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
if (mFileMetaData != NULL) {
ALOGV("chunk_data_size = %lld and data_offset = %lld",
- chunk_data_size, data_offset);
+ (long long)chunk_data_size, (long long)data_offset);
sp<ABuffer> buffer = new ABuffer(chunk_data_size + 1);
if (mDataSource->readAt(
data_offset, buffer->data(), chunk_data_size) != (ssize_t)chunk_data_size) {
@@ -2433,7 +2433,7 @@ status_t MPEG4Extractor::parseITunesMetaData(off64_t offset, size_t size) {
uint32_t metadataKey = 0;
char chunk[5];
MakeFourCCString(mPath[4], chunk);
- ALOGV("meta: %s @ %lld", chunk, offset);
+ ALOGV("meta: %s @ %lld", chunk, (long long)offset);
switch ((int32_t)mPath[4]) {
case FOURCC(0xa9, 'a', 'l', 'b'):
{
@@ -2937,7 +2937,7 @@ status_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio(
}
if (kUseHexDump) {
- printf("ESD of size %d\n", csd_size);
+ printf("ESD of size %zu\n", csd_size);
hexdump(csd, csd_size);
}
@@ -3344,7 +3344,7 @@ status_t MPEG4Source::parseChunk(off64_t *offset) {
char chunk[5];
MakeFourCCString(chunk_type, chunk);
- ALOGV("MPEG4Source chunk %s @ %llx", chunk, *offset);
+ ALOGV("MPEG4Source chunk %s @ %#llx", chunk, (long long)*offset);
off64_t chunk_data_size = *offset + chunk_size - data_offset;
@@ -3801,7 +3801,7 @@ status_t MPEG4Source::parseTrackFragmentRun(off64_t offset, off64_t size) {
sampleCtsOffset = 0;
}
- if (size < (off64_t)sampleCount * bytesPerSample) {
+ if (size < (off64_t)(sampleCount * bytesPerSample)) {
return -EINVAL;
}
@@ -4553,7 +4553,7 @@ static bool BetterSniffMPEG4(
char chunkstring[5];
MakeFourCCString(chunkType, chunkstring);
- ALOGV("saw chunk type %s, size %" PRIu64 " @ %lld", chunkstring, chunkSize, offset);
+ ALOGV("saw chunk type %s, size %" PRIu64 " @ %lld", chunkstring, chunkSize, (long long)offset);
switch (chunkType) {
case FOURCC('f', 't', 'y', 'p'):
{
@@ -4616,7 +4616,7 @@ static bool BetterSniffMPEG4(
*meta = new AMessage;
(*meta)->setInt64("meta-data-size", moovAtomEndOffset);
- ALOGV("found metadata size: %lld", moovAtomEndOffset);
+ ALOGV("found metadata size: %lld", (long long)moovAtomEndOffset);
}
return true;
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index 3d83e83..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 */
@@ -372,8 +374,8 @@ MPEG4Writer::MPEG4Writer(int fd)
mLatitudex10000(0),
mLongitudex10000(0),
mAreGeoTagsAvailable(false),
- mMetaKeys(new AMessage()),
- mStartTimeOffsetMs(-1) {
+ mStartTimeOffsetMs(-1),
+ mMetaKeys(new AMessage()) {
addDeviceMeta();
}
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index eedd7f4..93864e4 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -304,10 +304,10 @@ MediaCodec::MediaCodec(const sp<ALooper> &looper)
mCodec(NULL),
mReplyID(0),
mFlags(0),
- mResourceManagerClient(new ResourceManagerClient(this)),
- mResourceManagerService(new ResourceManagerServiceProxy()),
mStickyError(OK),
mSoftRenderer(NULL),
+ mResourceManagerClient(new ResourceManagerClient(this)),
+ mResourceManagerService(new ResourceManagerServiceProxy()),
mBatteryStatNotified(false),
mIsVideo(false),
mVideoWidth(0),
@@ -316,7 +316,8 @@ MediaCodec::MediaCodec(const sp<ALooper> &looper)
mDequeueInputReplyID(0),
mDequeueOutputTimeoutGeneration(0),
mDequeueOutputReplyID(0),
- mHaveInputSurface(false) {
+ mHaveInputSurface(false),
+ mHavePendingInputBuffers(false) {
}
MediaCodec::~MediaCodec() {
@@ -1376,7 +1377,11 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
if (mFlags & kFlagIsAsync) {
if (!mHaveInputSurface) {
- onInputBufferAvailable();
+ if (mState == FLUSHED) {
+ mHavePendingInputBuffers = true;
+ } else {
+ onInputBufferAvailable();
+ }
}
} else if (mFlags & kFlagDequeueInputPending) {
CHECK(handleDequeueInputBuffer(mDequeueInputReplyID));
@@ -1644,6 +1649,10 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
if (mState == FLUSHED) {
setState(STARTED);
+ if (mHavePendingInputBuffers) {
+ onInputBufferAvailable();
+ mHavePendingInputBuffers = false;
+ }
mCodec->signalResume();
PostReplyWithError(replyID, OK);
break;
diff --git a/media/libstagefright/MediaCodecListOverrides.cpp b/media/libstagefright/MediaCodecListOverrides.cpp
index 3c54f34..265b1ea 100644
--- a/media/libstagefright/MediaCodecListOverrides.cpp
+++ b/media/libstagefright/MediaCodecListOverrides.cpp
@@ -130,7 +130,7 @@ static size_t doProfileCodecs(
while (err == OK && codecs.size() < kMaxInstances) {
sp<ALooper> looper = new ALooper;
looper->setName("MediaCodec_looper");
- ALOGV("doProfileCodecs for codec #%u", codecs.size());
+ ALOGV("doProfileCodecs for codec #%zu", codecs.size());
ALOGV("doProfileCodecs start looper");
looper->start(
false /* runOnCallingThread */, false /* canCallJava */, ANDROID_PRIORITY_AUDIO);
@@ -234,7 +234,7 @@ void profileCodecs(
if (max > 0) {
CodecSettings settings;
char maxStr[32];
- sprintf(maxStr, "%u", max);
+ sprintf(maxStr, "%zu", max);
settings.add("max-supported-instances", maxStr);
AString key = name;
@@ -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/MediaCodecListOverrides.h b/media/libstagefright/MediaCodecListOverrides.h
index f97ce63..c6cc2ea 100644
--- a/media/libstagefright/MediaCodecListOverrides.h
+++ b/media/libstagefright/MediaCodecListOverrides.h
@@ -26,7 +26,7 @@
namespace android {
-class MediaCodecInfo;
+struct MediaCodecInfo;
bool splitString(const AString &s, const AString &delimiter, AString *s1, AString *s2);
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/MediaDefs.cpp b/media/libstagefright/MediaDefs.cpp
index c48a5ae..b0a65d2 100644
--- a/media/libstagefright/MediaDefs.cpp
+++ b/media/libstagefright/MediaDefs.cpp
@@ -62,5 +62,6 @@ const char *MEDIA_MIMETYPE_TEXT_3GPP = "text/3gpp-tt";
const char *MEDIA_MIMETYPE_TEXT_SUBRIP = "application/x-subrip";
const char *MEDIA_MIMETYPE_TEXT_VTT = "text/vtt";
const char *MEDIA_MIMETYPE_TEXT_CEA_608 = "text/cea-608";
+const char *MEDIA_MIMETYPE_DATA_METADATA = "application/octet-stream";
} // namespace android
diff --git a/media/libstagefright/MediaSync.cpp b/media/libstagefright/MediaSync.cpp
index 7b6c7d9..ec956c4 100644
--- a/media/libstagefright/MediaSync.cpp
+++ b/media/libstagefright/MediaSync.cpp
@@ -115,6 +115,11 @@ status_t MediaSync::configureAudioTrack(
return INVALID_OPERATION;
}
+ if (audioTrack != NULL && nativeSampleRateInHz <= 0) {
+ ALOGE("configureAudioTrack: native sample rate should be positive.");
+ return BAD_VALUE;
+ }
+
mAudioTrack = audioTrack;
mNativeSampleRateInHz = nativeSampleRateInHz;
diff --git a/media/libstagefright/MidiExtractor.cpp b/media/libstagefright/MidiExtractor.cpp
index 66fab77..f6b8c84 100644
--- a/media/libstagefright/MidiExtractor.cpp
+++ b/media/libstagefright/MidiExtractor.cpp
@@ -217,7 +217,7 @@ status_t MidiEngine::releaseBuffers() {
}
status_t MidiEngine::seekTo(int64_t positionUs) {
- ALOGV("seekTo %lld", positionUs);
+ ALOGV("seekTo %lld", (long long)positionUs);
EAS_RESULT result = EAS_Locate(mEasData, mEasHandle, positionUs / 1000, false);
return result == EAS_SUCCESS ? OK : UNKNOWN_ERROR;
}
diff --git a/media/libstagefright/NuCachedSource2.cpp b/media/libstagefright/NuCachedSource2.cpp
index 8d70e50..1c53b40 100644
--- a/media/libstagefright/NuCachedSource2.cpp
+++ b/media/libstagefright/NuCachedSource2.cpp
@@ -503,7 +503,7 @@ void NuCachedSource2::restartPrefetcherIfNecessary_l(
ssize_t NuCachedSource2::readAt(off64_t offset, void *data, size_t size) {
Mutex::Autolock autoSerializer(mSerializer);
- ALOGV("readAt offset %lld, size %zu", offset, size);
+ ALOGV("readAt offset %lld, size %zu", (long long)offset, size);
Mutex::Autolock autoLock(mLock);
if (mDisconnecting) {
@@ -579,7 +579,7 @@ size_t NuCachedSource2::approxDataRemaining_l(status_t *finalStatus) const {
ssize_t NuCachedSource2::readInternal(off64_t offset, void *data, size_t size) {
CHECK_LE(size, (size_t)mHighwaterThresholdBytes);
- ALOGV("readInternal offset %lld size %zu", offset, size);
+ ALOGV("readInternal offset %lld size %zu", (long long)offset, size);
Mutex::Autolock autoLock(mLock);
@@ -640,7 +640,7 @@ status_t NuCachedSource2::seekInternal_l(off64_t offset) {
return OK;
}
- ALOGI("new range: offset= %lld", offset);
+ ALOGI("new range: offset= %lld", (long long)offset);
mCacheOffset = offset;
@@ -719,10 +719,10 @@ void NuCachedSource2::updateCacheParamsFromString(const char *s) {
mKeepAliveIntervalUs = kDefaultKeepAliveIntervalUs;
}
- ALOGV("lowwater = %zu bytes, highwater = %zu bytes, keepalive = %" PRId64 " us",
+ ALOGV("lowwater = %zu bytes, highwater = %zu bytes, keepalive = %lld us",
mLowwaterThresholdBytes,
mHighwaterThresholdBytes,
- mKeepAliveIntervalUs);
+ (long long)mKeepAliveIntervalUs);
}
// static
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index 4d30069..8d4bab8 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -1057,7 +1057,7 @@ status_t OMXCodec::getVideoProfileLevel(
const sp<MetaData>& meta,
const CodecProfileLevel& defaultProfileLevel,
CodecProfileLevel &profileLevel) {
- CODEC_LOGV("Default profile: %ld, level %ld",
+ CODEC_LOGV("Default profile: %u, level #x%x",
defaultProfileLevel.mProfile, defaultProfileLevel.mLevel);
// Are the default profile and level overwriten?
@@ -1283,7 +1283,7 @@ status_t OMXCodec::setVideoOutputFormat(
success = success && meta->findInt32(kKeyHeight, &height);
CHECK(success);
- CODEC_LOGV("setVideoOutputFormat width=%ld, height=%ld", width, height);
+ CODEC_LOGV("setVideoOutputFormat width=%d, height=%d", width, height);
OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused;
if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
@@ -1650,7 +1650,7 @@ status_t OMXCodec::allocateBuffersOnPort(OMX_U32 portIndex) {
return err;
}
- CODEC_LOGV("allocating %lu buffers of size %lu on %s port",
+ CODEC_LOGV("allocating %u buffers of size %u on %s port",
def.nBufferCountActual, def.nBufferSize,
portIndex == kPortIndexInput ? "input" : "output");
@@ -1723,7 +1723,7 @@ status_t OMXCodec::allocateBuffersOnPort(OMX_U32 portIndex) {
mPortBuffers[portIndex].push(info);
- CODEC_LOGV("allocated buffer %p on %s port", buffer,
+ CODEC_LOGV("allocated buffer %u on %s port", buffer,
portIndex == kPortIndexInput ? "input" : "output");
}
@@ -1745,7 +1745,7 @@ status_t OMXCodec::allocateBuffersOnPort(OMX_U32 portIndex) {
if (mSkipCutBuffer != NULL) {
size_t prevbuffersize = mSkipCutBuffer->size();
if (prevbuffersize != 0) {
- ALOGW("Replacing SkipCutBuffer holding %d bytes", prevbuffersize);
+ ALOGW("Replacing SkipCutBuffer holding %zu bytes", prevbuffersize);
}
}
mSkipCutBuffer = new SkipCutBuffer(delay * frameSize, padding * frameSize);
@@ -1825,14 +1825,23 @@ status_t OMXCodec::allocateOutputBuffersFromNativeWindow() {
return err;
}
- err = native_window_set_buffers_geometry(
+ err = native_window_set_buffers_dimensions(
mNativeWindow.get(),
def.format.video.nFrameWidth,
- def.format.video.nFrameHeight,
+ def.format.video.nFrameHeight);
+
+ if (err != 0) {
+ ALOGE("native_window_set_buffers_dimensions failed: %s (%d)",
+ strerror(-err), -err);
+ return err;
+ }
+
+ err = native_window_set_buffers_format(
+ mNativeWindow.get(),
def.format.video.eColorFormat);
if (err != 0) {
- ALOGE("native_window_set_buffers_geometry failed: %s (%d)",
+ ALOGE("native_window_set_buffers_format failed: %s (%d)",
strerror(-err), -err);
return err;
}
@@ -1873,7 +1882,7 @@ status_t OMXCodec::allocateOutputBuffersFromNativeWindow() {
}
}
- ALOGV("native_window_set_usage usage=0x%lx", usage);
+ ALOGV("native_window_set_usage usage=0x%x", usage);
err = native_window_set_usage(
mNativeWindow.get(), usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP);
if (err != 0) {
@@ -2069,10 +2078,16 @@ status_t OMXCodec::pushBlankBuffersToNativeWindow() {
return err;
}
- err = native_window_set_buffers_geometry(mNativeWindow.get(), 1, 1,
- HAL_PIXEL_FORMAT_RGBX_8888);
+ err = native_window_set_buffers_dimensions(mNativeWindow.get(), 1, 1);
+ if (err != NO_ERROR) {
+ ALOGE("error pushing blank frames: set_buffers_dimensions failed: %s (%d)",
+ strerror(-err), -err);
+ goto error;
+ }
+
+ err = native_window_set_buffers_format(mNativeWindow.get(), HAL_PIXEL_FORMAT_RGBX_8888);
if (err != NO_ERROR) {
- ALOGE("error pushing blank frames: set_buffers_geometry failed: %s (%d)",
+ ALOGE("error pushing blank frames: set_buffers_format failed: %s (%d)",
strerror(-err), -err);
goto error;
}
@@ -2708,7 +2723,7 @@ void OMXCodec::onCmdComplete(OMX_COMMANDTYPE cmd, OMX_U32 data) {
default:
{
- CODEC_LOGV("CMD_COMPLETE(%d, %ld)", cmd, data);
+ CODEC_LOGV("CMD_COMPLETE(%d, %u)", cmd, data);
break;
}
}
@@ -2734,7 +2749,7 @@ void OMXCodec::onStateChange(OMX_STATETYPE newState) {
if (countBuffersWeOwn(mPortBuffers[kPortIndexInput]) !=
mPortBuffers[kPortIndexInput].size()) {
ALOGE("Codec did not return all input buffers "
- "(received %d / %d)",
+ "(received %zu / %zu)",
countBuffersWeOwn(mPortBuffers[kPortIndexInput]),
mPortBuffers[kPortIndexInput].size());
TRESPASS();
@@ -2743,7 +2758,7 @@ void OMXCodec::onStateChange(OMX_STATETYPE newState) {
if (countBuffersWeOwn(mPortBuffers[kPortIndexOutput]) !=
mPortBuffers[kPortIndexOutput].size()) {
ALOGE("Codec did not return all output buffers "
- "(received %d / %d)",
+ "(received %zu / %zu)",
countBuffersWeOwn(mPortBuffers[kPortIndexOutput]),
mPortBuffers[kPortIndexOutput].size());
TRESPASS();
@@ -2847,7 +2862,7 @@ status_t OMXCodec::freeBuffersOnPort(
CHECK(info->mStatus == OWNED_BY_US
|| info->mStatus == OWNED_BY_NATIVE_WINDOW);
- CODEC_LOGV("freeing buffer %p on port %ld", info->mBuffer, portIndex);
+ CODEC_LOGV("freeing buffer %u on port %u", info->mBuffer, portIndex);
status_t err = freeBuffer(portIndex, i);
@@ -2894,7 +2909,7 @@ status_t OMXCodec::freeBuffer(OMX_U32 portIndex, size_t bufIndex) {
}
void OMXCodec::onPortSettingsChanged(OMX_U32 portIndex) {
- CODEC_LOGV("PORT_SETTINGS_CHANGED(%ld)", portIndex);
+ CODEC_LOGV("PORT_SETTINGS_CHANGED(%u)", portIndex);
CHECK(mState == EXECUTING || mState == EXECUTING_TO_IDLE);
CHECK_EQ(portIndex, (OMX_U32)kPortIndexOutput);
@@ -2921,7 +2936,7 @@ bool OMXCodec::flushPortAsync(OMX_U32 portIndex) {
CHECK(mState == EXECUTING || mState == RECONFIGURING
|| mState == EXECUTING_TO_IDLE);
- CODEC_LOGV("flushPortAsync(%ld): we own %d out of %d buffers already.",
+ CODEC_LOGV("flushPortAsync(%u): we own %zu out of %zu buffers already.",
portIndex, countBuffersWeOwn(mPortBuffers[portIndex]),
mPortBuffers[portIndex].size());
@@ -2950,7 +2965,7 @@ void OMXCodec::disablePortAsync(OMX_U32 portIndex) {
CHECK_EQ((int)mPortStatus[portIndex], (int)ENABLED);
mPortStatus[portIndex] = DISABLING;
- CODEC_LOGV("sending OMX_CommandPortDisable(%ld)", portIndex);
+ CODEC_LOGV("sending OMX_CommandPortDisable(%u)", portIndex);
status_t err =
mOMX->sendCommand(mNode, OMX_CommandPortDisable, portIndex);
CHECK_EQ(err, (status_t)OK);
@@ -2964,7 +2979,7 @@ status_t OMXCodec::enablePortAsync(OMX_U32 portIndex) {
CHECK_EQ((int)mPortStatus[portIndex], (int)DISABLED);
mPortStatus[portIndex] = ENABLING;
- CODEC_LOGV("sending OMX_CommandPortEnable(%ld)", portIndex);
+ CODEC_LOGV("sending OMX_CommandPortEnable(%u)", portIndex);
return mOMX->sendCommand(mNode, OMX_CommandPortEnable, portIndex);
}
@@ -3037,7 +3052,7 @@ OMXCodec::BufferInfo *OMXCodec::findInputBufferByDataPointer(void *ptr) {
if (info->mData == ptr) {
CODEC_LOGV(
- "input buffer data ptr = %p, buffer_id = %p",
+ "input buffer data ptr = %p, buffer_id = %u",
ptr,
info->mBuffer);
@@ -3147,7 +3162,7 @@ bool OMXCodec::drainInputBuffer(BufferInfo *info) {
if (srcBuffer->meta_data()->findInt64(
kKeyTargetTime, &targetTimeUs)
&& targetTimeUs >= 0) {
- CODEC_LOGV("targetTimeUs = %lld us", targetTimeUs);
+ CODEC_LOGV("targetTimeUs = %lld us", (long long)targetTimeUs);
mTargetTimeUs = targetTimeUs;
} else {
mTargetTimeUs = -1;
@@ -3181,7 +3196,7 @@ bool OMXCodec::drainInputBuffer(BufferInfo *info) {
if (offset == 0) {
CODEC_LOGE(
"Codec's input buffers are too small to accomodate "
- "buffer read from source (info->mSize = %d, srcLength = %d)",
+ "buffer read from source (info->mSize = %zu, srcLength = %zu)",
info->mSize, srcBuffer->range_length());
srcBuffer->release();
@@ -3287,10 +3302,10 @@ bool OMXCodec::drainInputBuffer(BufferInfo *info) {
info = findEmptyInputBuffer();
}
- CODEC_LOGV("Calling emptyBuffer on buffer %p (length %d), "
+ CODEC_LOGV("Calling emptyBuffer on buffer %u (length %zu), "
"timestamp %lld us (%.2f secs)",
info->mBuffer, offset,
- timestampUs, timestampUs / 1E6);
+ (long long)timestampUs, timestampUs / 1E6);
err = mOMX->emptyBuffer(
mNode, info->mBuffer, 0, offset,
@@ -3315,7 +3330,7 @@ void OMXCodec::fillOutputBuffer(BufferInfo *info) {
return;
}
- CODEC_LOGV("Calling fillBuffer on buffer %p", info->mBuffer);
+ CODEC_LOGV("Calling fillBuffer on buffer %u", info->mBuffer);
status_t err = mOMX->fillBuffer(mNode, info->mBuffer);
if (err != OK) {
@@ -3372,7 +3387,7 @@ status_t OMXCodec::waitForBufferFilled_l() {
}
status_t err = mBufferFilled.waitRelative(mLock, kBufferFilledEventTimeOutNs);
if (err != OK) {
- CODEC_LOGE("Timed out waiting for output buffers: %d/%d",
+ CODEC_LOGE("Timed out waiting for output buffers: %zu/%zu",
countBuffersWeOwn(mPortBuffers[kPortIndexInput]),
countBuffersWeOwn(mPortBuffers[kPortIndexOutput]));
}
@@ -3627,7 +3642,7 @@ void OMXCodec::setG711Format(int32_t sampleRate, int32_t numChannels) {
void OMXCodec::setImageOutputFormat(
OMX_COLOR_FORMATTYPE format, OMX_U32 width, OMX_U32 height) {
- CODEC_LOGV("setImageOutputFormat(%ld, %ld)", width, height);
+ CODEC_LOGV("setImageOutputFormat(%u, %u)", width, height);
#if 0
OMX_INDEXTYPE index;
@@ -4281,14 +4296,14 @@ void OMXCodec::initOutputFormat(const sp<MetaData> &inputFormat) {
if ((OMX_U32)numChannels != params.nChannels) {
ALOGV("Codec outputs a different number of channels than "
"the input stream contains (contains %d channels, "
- "codec outputs %ld channels).",
+ "codec outputs %u channels).",
numChannels, params.nChannels);
}
if (sampleRate != (int32_t)params.nSamplingRate) {
ALOGV("Codec outputs at different sampling rate than "
"what the input stream contains (contains data at "
- "%d Hz, codec outputs %lu Hz)",
+ "%d Hz, codec outputs %u Hz)",
sampleRate, params.nSamplingRate);
}
@@ -4390,8 +4405,7 @@ void OMXCodec::initOutputFormat(const sp<MetaData> &inputFormat) {
mNode, OMX_IndexConfigCommonOutputCrop,
&rect, sizeof(rect));
- CODEC_LOGI(
- "video dimensions are %ld x %ld",
+ CODEC_LOGI("video dimensions are %u x %u",
video_def->nFrameWidth, video_def->nFrameHeight);
if (err == OK) {
@@ -4409,8 +4423,7 @@ void OMXCodec::initOutputFormat(const sp<MetaData> &inputFormat) {
rect.nLeft + rect.nWidth - 1,
rect.nTop + rect.nHeight - 1);
- CODEC_LOGI(
- "Crop rect is %ld x %ld @ (%ld, %ld)",
+ CODEC_LOGI("Crop rect is %u x %u @ (%d, %d)",
rect.nWidth, rect.nHeight, rect.nLeft, rect.nTop);
} else {
mOutputFormat->setRect(
diff --git a/media/libstagefright/OggExtractor.cpp b/media/libstagefright/OggExtractor.cpp
index 6e32494..d577034 100644
--- a/media/libstagefright/OggExtractor.cpp
+++ b/media/libstagefright/OggExtractor.cpp
@@ -250,7 +250,7 @@ status_t MyVorbisExtractor::findNextPage(
if (!memcmp(signature, "OggS", 4)) {
if (*pageOffset > startOffset) {
ALOGV("skipped %lld bytes of junk to reach next frame",
- *pageOffset - startOffset);
+ (long long)(*pageOffset - startOffset));
}
return OK;
@@ -277,7 +277,7 @@ status_t MyVorbisExtractor::findPrevGranulePosition(
prevGuess = 0;
}
- ALOGV("backing up %lld bytes", pageOffset - prevGuess);
+ ALOGV("backing up %lld bytes", (long long)(pageOffset - prevGuess));
status_t err = findNextPage(prevGuess, &prevPageOffset);
if (err != OK) {
@@ -295,7 +295,7 @@ status_t MyVorbisExtractor::findPrevGranulePosition(
}
ALOGV("prevPageOffset at %lld, pageOffset at %lld",
- prevPageOffset, pageOffset);
+ (long long)prevPageOffset, (long long)pageOffset);
for (;;) {
Page prevPage;
@@ -320,7 +320,7 @@ status_t MyVorbisExtractor::seekToTime(int64_t timeUs) {
off64_t pos = timeUs * approxBitrate() / 8000000ll;
- ALOGV("seeking to offset %lld", pos);
+ ALOGV("seeking to offset %lld", (long long)pos);
return seekToOffset(pos);
}
@@ -348,7 +348,7 @@ status_t MyVorbisExtractor::seekToTime(int64_t timeUs) {
const TOCEntry &entry = mTableOfContents.itemAt(left);
ALOGV("seeking to entry %zu / %zu at offset %lld",
- left, mTableOfContents.size(), entry.mPageOffset);
+ left, mTableOfContents.size(), (long long)entry.mPageOffset);
return seekToOffset(entry.mPageOffset);
}
@@ -391,8 +391,8 @@ ssize_t MyVorbisExtractor::readPage(off64_t offset, Page *page) {
ssize_t n;
if ((n = mSource->readAt(offset, header, sizeof(header)))
< (ssize_t)sizeof(header)) {
- ALOGV("failed to read %zu bytes at offset 0x%016llx, got %zd bytes",
- sizeof(header), offset, n);
+ ALOGV("failed to read %zu bytes at offset %#016llx, got %zd bytes",
+ sizeof(header), (long long)offset, n);
if (n < 0) {
return n;
@@ -505,8 +505,8 @@ status_t MyVorbisExtractor::readNextPacket(MediaBuffer **out, bool conf) {
packetSize);
if (n < (ssize_t)packetSize) {
- ALOGV("failed to read %zu bytes at 0x%016llx, got %zd bytes",
- packetSize, dataOffset, n);
+ ALOGV("failed to read %zu bytes at %#016llx, got %zd bytes",
+ packetSize, (long long)dataOffset, n);
return ERROR_IO;
}
diff --git a/media/libstagefright/SampleTable.cpp b/media/libstagefright/SampleTable.cpp
index aba64d5..7f98485 100644
--- a/media/libstagefright/SampleTable.cpp
+++ b/media/libstagefright/SampleTable.cpp
@@ -230,7 +230,7 @@ status_t SampleTable::setSampleToChunkParams(
return ERROR_MALFORMED;
}
- if (SIZE_MAX / sizeof(SampleToChunkEntry) <= mNumSampleToChunkOffsets)
+ if (SIZE_MAX / sizeof(SampleToChunkEntry) <= (size_t)mNumSampleToChunkOffsets)
return ERROR_OUT_OF_RANGE;
mSampleToChunkEntries =
diff --git a/media/libstagefright/StagefrightMetadataRetriever.cpp b/media/libstagefright/StagefrightMetadataRetriever.cpp
index 820b2fc..e9566f2 100644
--- a/media/libstagefright/StagefrightMetadataRetriever.cpp
+++ b/media/libstagefright/StagefrightMetadataRetriever.cpp
@@ -47,10 +47,7 @@ StagefrightMetadataRetriever::StagefrightMetadataRetriever()
StagefrightMetadataRetriever::~StagefrightMetadataRetriever() {
ALOGV("~StagefrightMetadataRetriever()");
-
- delete mAlbumArt;
- mAlbumArt = NULL;
-
+ clearMetadata();
mClient.disconnect();
}
@@ -60,11 +57,7 @@ status_t StagefrightMetadataRetriever::setDataSource(
const KeyedVector<String8, String8> *headers) {
ALOGV("setDataSource(%s)", uri);
- mParsedMetaData = false;
- mMetaData.clear();
- delete mAlbumArt;
- mAlbumArt = NULL;
-
+ clearMetadata();
mSource = DataSource::CreateFromURI(httpService, uri, headers);
if (mSource == NULL) {
@@ -92,11 +85,7 @@ status_t StagefrightMetadataRetriever::setDataSource(
ALOGV("setDataSource(%d, %" PRId64 ", %" PRId64 ")", fd, offset, length);
- mParsedMetaData = false;
- mMetaData.clear();
- delete mAlbumArt;
- mAlbumArt = NULL;
-
+ clearMetadata();
mSource = new FileSource(fd, offset, length);
status_t err;
@@ -117,6 +106,23 @@ status_t StagefrightMetadataRetriever::setDataSource(
return OK;
}
+status_t StagefrightMetadataRetriever::setDataSource(
+ const sp<DataSource>& source) {
+ ALOGV("setDataSource(DataSource)");
+
+ clearMetadata();
+ mSource = source;
+ mExtractor = MediaExtractor::Create(mSource);
+
+ if (mExtractor == NULL) {
+ ALOGE("Failed to instantiate a MediaExtractor.");
+ mSource.clear();
+ return UNKNOWN_ERROR;
+ }
+
+ return OK;
+}
+
static bool isYUV420PlanarSupported(
OMXClient *client,
const sp<MetaData> &trackMeta) {
@@ -635,4 +641,11 @@ void StagefrightMetadataRetriever::parseMetaData() {
}
}
+void StagefrightMetadataRetriever::clearMetadata() {
+ mParsedMetaData = false;
+ mMetaData.clear();
+ delete mAlbumArt;
+ mAlbumArt = NULL;
+}
+
} // namespace android
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/VBRISeeker.cpp b/media/libstagefright/VBRISeeker.cpp
index e988f6d..8a0fcac 100644
--- a/media/libstagefright/VBRISeeker.cpp
+++ b/media/libstagefright/VBRISeeker.cpp
@@ -122,7 +122,7 @@ sp<VBRISeeker> VBRISeeker::CreateFromSource(
seeker->mSegments.push(numBytes);
- ALOGV("entry #%zu: %u offset 0x%016llx", i, numBytes, offset);
+ ALOGV("entry #%zu: %u offset %#016llx", i, numBytes, (long long)offset);
offset += numBytes;
}
@@ -163,7 +163,7 @@ bool VBRISeeker::getOffsetForTime(int64_t *timeUs, off64_t *pos) {
*pos += mSegments.itemAt(segmentIndex++);
}
- ALOGV("getOffsetForTime %" PRId64 " us => 0x%016llx", *timeUs, *pos);
+ ALOGV("getOffsetForTime %lld us => 0x%016llx", (long long)*timeUs, (long long)*pos);
*timeUs = nowUs;
diff --git a/media/libstagefright/codecs/avcdec/SoftAVCDec.cpp b/media/libstagefright/codecs/avcdec/SoftAVCDec.cpp
index 8388472..08e956a 100644
--- a/media/libstagefright/codecs/avcdec/SoftAVCDec.cpp
+++ b/media/libstagefright/codecs/avcdec/SoftAVCDec.cpp
@@ -191,7 +191,7 @@ status_t SoftAVC::setParams(size_t stride) {
s_ctl_ip.u4_size = sizeof(ivd_ctl_set_config_ip_t);
s_ctl_op.u4_size = sizeof(ivd_ctl_set_config_op_t);
- ALOGV("Set the run-time (dynamic) parameters stride = %u", stride);
+ ALOGV("Set the run-time (dynamic) parameters stride = %zu", stride);
status = ivdec_api_function(mCodecCtx, (void *)&s_ctl_ip, (void *)&s_ctl_op);
if (status != IV_SUCCESS) {
@@ -452,7 +452,7 @@ status_t SoftAVC::initDecoder() {
uint32_t bufferSize = displaySizeY * 3 / 2;
mFlushOutBuffer = (uint8_t *)ivd_aligned_malloc(128, bufferSize);
if (NULL == mFlushOutBuffer) {
- ALOGE("Could not allocate flushOutputBuffer of size %zu", bufferSize);
+ ALOGE("Could not allocate flushOutputBuffer of size %u", bufferSize);
return NO_MEMORY;
}
diff --git a/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp b/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp
index bf5e353..06b2163 100644
--- a/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp
+++ b/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp
@@ -681,7 +681,7 @@ OMX_ERRORTYPE SoftAVC::initEncoder() {
/* Allocate array to hold memory records */
mMemRecords = (iv_mem_rec_t *)malloc(mNumMemRecords * sizeof(iv_mem_rec_t));
if (NULL == mMemRecords) {
- ALOGE("Unable to allocate memory for hold memory records: Size %d",
+ ALOGE("Unable to allocate memory for hold memory records: Size %zu",
mNumMemRecords * sizeof(iv_mem_rec_t));
mSignalledError = true;
notify(OMX_EventError, OMX_ErrorUndefined, 0, 0);
@@ -744,7 +744,7 @@ OMX_ERRORTYPE SoftAVC::initEncoder() {
ps_mem_rec->pv_base = ive_aligned_malloc(
ps_mem_rec->u4_mem_alignment, ps_mem_rec->u4_mem_size);
if (ps_mem_rec->pv_base == NULL) {
- ALOGE("Allocation failure for mem record id %d size %d\n", i,
+ ALOGE("Allocation failure for mem record id %zu size %u\n", i,
ps_mem_rec->u4_mem_size);
mSignalledError = true;
notify(OMX_EventError, OMX_ErrorUndefined, 0, 0);
diff --git a/media/libstagefright/codecs/avcenc/SoftAVCEnc.h b/media/libstagefright/codecs/avcenc/SoftAVCEnc.h
index c4e26a9..2b35d45 100644
--- a/media/libstagefright/codecs/avcenc/SoftAVCEnc.h
+++ b/media/libstagefright/codecs/avcenc/SoftAVCEnc.h
@@ -25,7 +25,7 @@
namespace android {
-struct MediaBuffer;
+class MediaBuffer;
#define CODEC_MAX_CORES 4
#define LEN_STATUS_BUFFER (10 * 1024)
diff --git a/media/libstagefright/codecs/hevcdec/SoftHEVC.cpp b/media/libstagefright/codecs/hevcdec/SoftHEVC.cpp
index cddd176..5c05a0e 100644
--- a/media/libstagefright/codecs/hevcdec/SoftHEVC.cpp
+++ b/media/libstagefright/codecs/hevcdec/SoftHEVC.cpp
@@ -143,7 +143,7 @@ status_t SoftHEVC::setParams(size_t stride) {
s_ctl_ip.u4_size = sizeof(ivd_ctl_set_config_ip_t);
s_ctl_op.u4_size = sizeof(ivd_ctl_set_config_op_t);
- ALOGV("Set the run-time (dynamic) parameters stride = %u", stride);
+ ALOGV("Set the run-time (dynamic) parameters stride = %zu", stride);
status = ivdec_api_function(mCodecCtx, (void *)&s_ctl_ip,
(void *)&s_ctl_op);
@@ -408,7 +408,7 @@ status_t SoftHEVC::initDecoder() {
uint32_t bufferSize = displaySizeY * 3 / 2;
mFlushOutBuffer = (uint8_t *)ivd_aligned_malloc(128, bufferSize);
if (NULL == mFlushOutBuffer) {
- ALOGE("Could not allocate flushOutputBuffer of size %zu", bufferSize);
+ ALOGE("Could not allocate flushOutputBuffer of size %u", bufferSize);
return NO_MEMORY;
}
diff --git a/media/libstagefright/codecs/mpeg2dec/SoftMPEG2.cpp b/media/libstagefright/codecs/mpeg2dec/SoftMPEG2.cpp
index fb7394b..78b3ab4 100644
--- a/media/libstagefright/codecs/mpeg2dec/SoftMPEG2.cpp
+++ b/media/libstagefright/codecs/mpeg2dec/SoftMPEG2.cpp
@@ -156,7 +156,7 @@ status_t SoftMPEG2::setParams(size_t stride) {
s_ctl_ip.u4_size = sizeof(ivd_ctl_set_config_ip_t);
s_ctl_op.u4_size = sizeof(ivd_ctl_set_config_op_t);
- ALOGV("Set the run-time (dynamic) parameters stride = %u", stride);
+ ALOGV("Set the run-time (dynamic) parameters stride = %zu", stride);
status = ivdec_api_function(mCodecCtx, (void *)&s_ctl_ip, (void *)&s_ctl_op);
if (status != IV_SUCCESS) {
@@ -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;
@@ -394,7 +396,7 @@ status_t SoftMPEG2::initDecoder() {
uint32_t bufferSize = displaySizeY * 3 / 2;
mFlushOutBuffer = (uint8_t *)ivd_aligned_malloc(128, bufferSize);
if (NULL == mFlushOutBuffer) {
- ALOGE("Could not allocate flushOutputBuffer of size %zu", bufferSize);
+ ALOGE("Could not allocate flushOutputBuffer of size %u", bufferSize);
return NO_MEMORY;
}
@@ -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/colorconversion/Android.mk b/media/libstagefright/colorconversion/Android.mk
index 59a64ba..4f7c48f 100644
--- a/media/libstagefright/colorconversion/Android.mk
+++ b/media/libstagefright/colorconversion/Android.mk
@@ -9,6 +9,9 @@ LOCAL_C_INCLUDES := \
$(TOP)/frameworks/native/include/media/openmax \
$(TOP)/hardware/msm7k
+LOCAL_CFLAGS += -Werror
+LOCAL_CLANG := true
+
LOCAL_MODULE:= libstagefright_color_conversion
include $(BUILD_STATIC_LIBRARY)
diff --git a/media/libstagefright/filters/Android.mk b/media/libstagefright/filters/Android.mk
index 36ab444..179f054 100644
--- a/media/libstagefright/filters/Android.mk
+++ b/media/libstagefright/filters/Android.mk
@@ -20,7 +20,8 @@ LOCAL_C_INCLUDES := \
intermediates := $(call intermediates-dir-for,STATIC_LIBRARIES,libRS,TARGET,)
LOCAL_C_INCLUDES += $(intermediates)
-LOCAL_CFLAGS += -Wno-multichar
+LOCAL_CFLAGS += -Wno-multichar -Werror -Wall
+LOCAL_CLANG := true
LOCAL_MODULE:= libstagefright_mediafilter
diff --git a/media/libstagefright/filters/ColorConvert.cpp b/media/libstagefright/filters/ColorConvert.cpp
index a5039f9..a8d5dd2 100644
--- a/media/libstagefright/filters/ColorConvert.cpp
+++ b/media/libstagefright/filters/ColorConvert.cpp
@@ -93,8 +93,8 @@ void convertYUV420spToRGB888(
void convertRGBAToARGB(
uint8_t *src, int32_t width, int32_t height, uint32_t stride,
uint8_t *dest) {
- for (size_t i = 0; i < height; ++i) {
- for (size_t j = 0; j < width; ++j) {
+ for (int32_t i = 0; i < height; ++i) {
+ for (int32_t j = 0; j < width; ++j) {
uint8_t r = *src++;
uint8_t g = *src++;
uint8_t b = *src++;
diff --git a/media/libstagefright/filters/GraphicBufferListener.cpp b/media/libstagefright/filters/GraphicBufferListener.cpp
index 66374ba..a606315 100644
--- a/media/libstagefright/filters/GraphicBufferListener.cpp
+++ b/media/libstagefright/filters/GraphicBufferListener.cpp
@@ -40,7 +40,7 @@ status_t GraphicBufferListener::init(
status_t err = mConsumer->setMaxAcquiredBufferCount(bufferCount);
if (err != NO_ERROR) {
- ALOGE("Unable to set BQ max acquired buffer count to %u: %d",
+ ALOGE("Unable to set BQ max acquired buffer count to %zu: %d",
bufferCount, err);
return err;
}
diff --git a/media/libstagefright/filters/MediaFilter.cpp b/media/libstagefright/filters/MediaFilter.cpp
index 0a09575..ecbda36 100644
--- a/media/libstagefright/filters/MediaFilter.cpp
+++ b/media/libstagefright/filters/MediaFilter.cpp
@@ -804,7 +804,7 @@ void MediaFilter::onSignalEndOfInputStream() {
eosBuf->mGeneration = mGeneration;
eosBuf->mData->setRange(0, 0);
postDrainThisBuffer(eosBuf);
- ALOGV("Posted EOS on output buffer %zu", eosBuf->mBufferID);
+ ALOGV("Posted EOS on output buffer %u", eosBuf->mBufferID);
}
mPortEOS[kPortIndexOutput] = true;
diff --git a/media/libstagefright/foundation/Android.mk b/media/libstagefright/foundation/Android.mk
index 08355c7..c68264c 100644
--- a/media/libstagefright/foundation/Android.mk
+++ b/media/libstagefright/foundation/Android.mk
@@ -29,7 +29,8 @@ 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 7f3307d..5fb51c1 100644
--- a/media/libstagefright/http/Android.mk
+++ b/media/libstagefright/http/Android.mk
@@ -21,7 +21,8 @@ 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 93b7935..2639deb 100644
--- a/media/libstagefright/httplive/Android.mk
+++ b/media/libstagefright/httplive/Android.mk
@@ -12,7 +12,8 @@ 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 := \
libbinder \
diff --git a/media/libstagefright/httplive/LiveSession.cpp b/media/libstagefright/httplive/LiveSession.cpp
index 4886000..764ff82 100644
--- a/media/libstagefright/httplive/LiveSession.cpp
+++ b/media/libstagefright/httplive/LiveSession.cpp
@@ -38,6 +38,7 @@
#include <media/stagefright/FileSource.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/MediaHTTP.h>
+#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MetaData.h>
#include <media/stagefright/Utils.h>
@@ -66,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
@@ -80,6 +81,9 @@ private:
Mutex mLock;
List<BandwidthEntry> mBandwidthHistory;
+ List<int32_t> mPrevEstimates;
+ bool mHasNewSample;
+ bool mIsStable;
int64_t mTotalTransferTimeUs;
size_t mTotalTransferBytes;
@@ -87,6 +91,8 @@ private:
};
LiveSession::BandwidthEstimator::BandwidthEstimator() :
+ mHasNewSample(false),
+ mIsStable(true),
mTotalTransferTimeUs(0),
mTotalTransferBytes(0) {
}
@@ -101,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.
@@ -115,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;
}
@@ -135,6 +171,8 @@ const char *LiveSession::getKeyForStream(StreamType type) {
return "timeUsAudio";
case STREAMTYPE_SUBTITLES:
return "timeUsSubtitle";
+ case STREAMTYPE_METADATA:
+ return "timeUsMetadata"; // unused
default:
TRESPASS();
}
@@ -150,12 +188,30 @@ const char *LiveSession::getNameForStream(StreamType type) {
return "audio";
case STREAMTYPE_SUBTITLES:
return "subs";
+ case STREAMTYPE_METADATA:
+ return "metadata";
default:
break;
}
return "unknown";
}
+//static
+ATSParser::SourceType LiveSession::getSourceTypeForStream(StreamType type) {
+ switch (type) {
+ case STREAMTYPE_VIDEO:
+ return ATSParser::VIDEO;
+ case STREAMTYPE_AUDIO:
+ return ATSParser::AUDIO;
+ case STREAMTYPE_METADATA:
+ return ATSParser::META;
+ case STREAMTYPE_SUBTITLES:
+ default:
+ TRESPASS();
+ }
+ return ATSParser::NUM_SOURCE_TYPES; // should not reach here
+}
+
LiveSession::LiveSession(
const sp<AMessage> &notify, uint32_t flags,
const sp<IMediaHTTPService> &httpService)
@@ -187,12 +243,13 @@ LiveSession::LiveSession(
mUpSwitchMargin(kUpSwitchMarginUs),
mFirstTimeUsValid(false),
mFirstTimeUs(0),
- mLastSeekTimeUs(0) {
+ mLastSeekTimeUs(0),
+ mHasMetadata(false) {
mStreams[kAudioIndex] = StreamItem("audio");
mStreams[kVideoIndex] = StreamItem("video");
mStreams[kSubtitleIndex] = StreamItem("subtitles");
- for (size_t i = 0; i < kMaxStreams; ++i) {
+ for (size_t i = 0; i < kNumSources; ++i) {
mPacketSources.add(indexToType(i), new AnotherPacketSource(NULL /* meta */));
mPacketSources2.add(indexToType(i), new AnotherPacketSource(NULL /* meta */));
}
@@ -204,6 +261,20 @@ LiveSession::~LiveSession() {
}
}
+int64_t LiveSession::calculateMediaTimeUs(
+ int64_t firstTimeUs, int64_t timeUs, int32_t discontinuitySeq) {
+ if (timeUs >= firstTimeUs) {
+ timeUs -= firstTimeUs;
+ } else {
+ timeUs = 0;
+ }
+ timeUs += mLastSeekTimeUs;
+ if (mDiscontinuityOffsetTimesUs.indexOfKey(discontinuitySeq) >= 0) {
+ timeUs += mDiscontinuityOffsetTimesUs.valueFor(discontinuitySeq);
+ }
+ return timeUs;
+}
+
status_t LiveSession::dequeueAccessUnit(
StreamType stream, sp<ABuffer> *accessUnit) {
status_t finalResult = OK;
@@ -236,7 +307,6 @@ status_t LiveSession::dequeueAccessUnit(
status_t err = packetSource->dequeueAccessUnit(accessUnit);
- StreamItem& strm = mStreams[streamIdx];
if (err == INFO_DISCONTINUITY) {
// adaptive streaming, discontinuities in the playlist
int32_t type;
@@ -256,6 +326,7 @@ status_t LiveSession::dequeueAccessUnit(
if (stream == STREAMTYPE_AUDIO || stream == STREAMTYPE_VIDEO) {
int64_t timeUs, originalTimeUs;
int32_t discontinuitySeq = 0;
+ StreamItem& strm = mStreams[streamIdx];
CHECK((*accessUnit)->meta()->findInt64("timeUs", &timeUs));
originalTimeUs = timeUs;
(*accessUnit)->meta()->findInt32("discontinuitySeq", &discontinuitySeq);
@@ -299,15 +370,7 @@ status_t LiveSession::dequeueAccessUnit(
}
strm.mLastDequeuedTimeUs = timeUs;
- if (timeUs >= firstTimeUs) {
- timeUs -= firstTimeUs;
- } else {
- timeUs = 0;
- }
- timeUs += mLastSeekTimeUs;
- if (mDiscontinuityOffsetTimesUs.indexOfKey(discontinuitySeq) >= 0) {
- timeUs += mDiscontinuityOffsetTimesUs.valueFor(discontinuitySeq);
- }
+ timeUs = calculateMediaTimeUs(firstTimeUs, timeUs, discontinuitySeq);
ALOGV("[%s] dequeueAccessUnit: time %lld us, original %lld us",
streamStr, (long long)timeUs, (long long)originalTimeUs);
@@ -323,6 +386,17 @@ status_t LiveSession::dequeueAccessUnit(
(*accessUnit)->meta()->setInt32(
"trackIndex", mPlaylist->getSelectedIndex());
(*accessUnit)->meta()->setInt64("baseUs", mRealTimeBaseUs);
+ } else if (stream == STREAMTYPE_METADATA) {
+ HLSTime mdTime((*accessUnit)->meta());
+ if (mDiscontinuityAbsStartTimesUs.indexOfKey(mdTime.mSeq) < 0) {
+ packetSource->requeueAccessUnit((*accessUnit));
+ return -EAGAIN;
+ } else {
+ int64_t firstTimeUs = mDiscontinuityAbsStartTimesUs.valueFor(mdTime.mSeq);
+ int64_t timeUs = calculateMediaTimeUs(firstTimeUs, mdTime.mTimeUs, mdTime.mSeq);
+ (*accessUnit)->meta()->setInt64("timeUs", timeUs);
+ (*accessUnit)->meta()->setInt64("baseUs", mRealTimeBaseUs);
+ }
}
} else {
ALOGI("[%s] encountered error %d", streamStr, err);
@@ -728,6 +802,17 @@ void LiveSession::onMessageReceived(const sp<AMessage> &msg) {
break;
}
+ case PlaylistFetcher::kWhatMetadataDetected:
+ {
+ if (!mHasMetadata) {
+ mHasMetadata = true;
+ sp<AMessage> notify = mNotify->dup();
+ notify->setInt32("what", kWhatMetadataDetected);
+ notify->post();
+ }
+ break;
+ }
+
default:
TRESPASS();
}
@@ -788,7 +873,7 @@ int LiveSession::SortByBandwidth(const BandwidthItem *a, const BandwidthItem *b)
// static
LiveSession::StreamType LiveSession::indexToType(int idx) {
- CHECK(idx >= 0 && idx < kMaxStreams);
+ CHECK(idx >= 0 && idx < kNumSources);
return (StreamType)(1 << idx);
}
@@ -801,6 +886,8 @@ ssize_t LiveSession::typeToIndex(int32_t type) {
return 1;
case STREAMTYPE_SUBTITLES:
return 2;
+ case STREAMTYPE_METADATA:
+ return 3;
default:
return -1;
};
@@ -1179,6 +1266,45 @@ static double uniformRand() {
}
#endif
+bool LiveSession::UriIsSameAsIndex(const AString &uri, int32_t i, bool newUri) {
+ ALOGI("[timed_id3] i %d UriIsSameAsIndex newUri %s, %s", i,
+ newUri ? "true" : "false",
+ newUri ? mStreams[i].mNewUri.c_str() : mStreams[i].mUri.c_str());
+ return i >= 0
+ && ((!newUri && uri == mStreams[i].mUri)
+ || (newUri && uri == mStreams[i].mNewUri));
+}
+
+sp<AnotherPacketSource> LiveSession::getPacketSourceForStreamIndex(
+ size_t trackIndex, bool newUri) {
+ StreamType type = indexToType(trackIndex);
+ sp<AnotherPacketSource> source = NULL;
+ if (newUri) {
+ source = mPacketSources2.valueFor(type);
+ source->clear();
+ } else {
+ source = mPacketSources.valueFor(type);
+ };
+ return source;
+}
+
+sp<AnotherPacketSource> LiveSession::getMetadataSource(
+ sp<AnotherPacketSource> sources[kNumSources], uint32_t streamMask, bool newUri) {
+ // todo: One case where the following strategy can fail is when audio and video
+ // are in separate playlists, both are transport streams, and the metadata
+ // is actually contained in the audio stream.
+ ALOGV("[timed_id3] getMetadataSourceForUri streamMask %x newUri %s",
+ streamMask, newUri ? "true" : "false");
+
+ if ((sources[kVideoIndex] != NULL) // video fetcher; or ...
+ || (!(streamMask & STREAMTYPE_VIDEO) && sources[kAudioIndex] != NULL)) {
+ // ... audio fetcher for audio only variant
+ return getPacketSourceForStreamIndex(kMetaDataIndex, newUri);
+ }
+
+ return NULL;
+}
+
bool LiveSession::resumeFetcher(
const AString &uri, uint32_t streamMask, int64_t timeUs, bool newUri) {
ssize_t index = mFetcherInfos.indexOfKey(uri);
@@ -1188,18 +1314,11 @@ bool LiveSession::resumeFetcher(
}
bool resume = false;
- sp<AnotherPacketSource> sources[kMaxStreams];
+ sp<AnotherPacketSource> sources[kNumSources];
for (size_t i = 0; i < kMaxStreams; ++i) {
- if ((streamMask & indexToType(i))
- && ((!newUri && uri == mStreams[i].mUri)
- || (newUri && uri == mStreams[i].mNewUri))) {
+ if ((streamMask & indexToType(i)) && UriIsSameAsIndex(uri, i, newUri)) {
resume = true;
- if (newUri) {
- sources[i] = mPacketSources2.valueFor(indexToType(i));
- sources[i]->clear();
- } else {
- sources[i] = mPacketSources.valueFor(indexToType(i));
- }
+ sources[i] = getPacketSourceForStreamIndex(i, newUri);
}
}
@@ -1214,6 +1333,7 @@ bool LiveSession::resumeFetcher(
sources[kAudioIndex],
sources[kVideoIndex],
sources[kSubtitleIndex],
+ getMetadataSource(sources, streamMask, newUri),
timeUs, -1, -1, seekMode);
}
@@ -1424,7 +1544,7 @@ size_t LiveSession::getTrackCount() const {
if (mPlaylist == NULL) {
return 0;
} else {
- return mPlaylist->getTrackCount();
+ return mPlaylist->getTrackCount() + (mHasMetadata ? 1 : 0);
}
}
@@ -1432,6 +1552,13 @@ sp<AMessage> LiveSession::getTrackInfo(size_t trackIndex) const {
if (mPlaylist == NULL) {
return NULL;
} else {
+ if (trackIndex == mPlaylist->getTrackCount() && mHasMetadata) {
+ sp<AMessage> format = new AMessage();
+ format->setInt32("type", MEDIA_TRACK_TYPE_METADATA);
+ format->setString("language", "und");
+ format->setString("mime", MEDIA_MIMETYPE_DATA_METADATA);
+ return format;
+ }
return mPlaylist->getTrackInfo(trackIndex);
}
}
@@ -1768,7 +1895,7 @@ void LiveSession::onChangeConfiguration3(const sp<AMessage> &msg) {
HLSTime startTime;
SeekMode seekMode = kSeekModeExactPosition;
- sp<AnotherPacketSource> sources[kMaxStreams];
+ sp<AnotherPacketSource> sources[kNumSources];
if (i == kSubtitleIndex || (!pickTrack && !switching)) {
startTime = latestMediaSegmentStartTime();
@@ -1797,8 +1924,8 @@ void LiveSession::onChangeConfiguration3(const sp<AMessage> &msg) {
}
}
- if (j != kSubtitleIndex && meta != NULL
- && !meta->findInt32("discontinuity", &type)) {
+ if ((j == kAudioIndex || j == kVideoIndex)
+ && meta != NULL && !meta->findInt32("discontinuity", &type)) {
HLSTime tmpTime(meta);
if (startTime < tmpTime) {
startTime = tmpTime;
@@ -1838,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
@@ -1851,8 +1978,9 @@ void LiveSession::onChangeConfiguration3(const sp<AMessage> &msg) {
sources[kAudioIndex],
sources[kVideoIndex],
sources[kSubtitleIndex],
+ getMetadataSource(sources, mNewStreamMask, switching),
startTime.mTimeUs < 0 ? mLastSeekTimeUs : startTime.mTimeUs,
- startTime.getSegmentTimeUs(true /* midpoint */),
+ startTime.getSegmentTimeUs(),
startTime.mSeq,
seekMode);
}
@@ -2203,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 {
@@ -2215,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
@@ -2228,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/LiveSession.h b/media/libstagefright/httplive/LiveSession.h
index ed74bc2..56cd702 100644
--- a/media/libstagefright/httplive/LiveSession.h
+++ b/media/libstagefright/httplive/LiveSession.h
@@ -23,12 +23,14 @@
#include <utils/String8.h>
+#include "mpeg2ts/ATSParser.h"
+
namespace android {
struct ABuffer;
struct AReplyToken;
struct AnotherPacketSource;
-struct DataSource;
+class DataSource;
struct HTTPBase;
struct IMediaHTTPService;
struct LiveDataSource;
@@ -47,12 +49,15 @@ struct LiveSession : public AHandler {
kVideoIndex = 1,
kSubtitleIndex = 2,
kMaxStreams = 3,
+ kMetaDataIndex = 3,
+ kNumSources = 4,
};
enum StreamType {
STREAMTYPE_AUDIO = 1 << kAudioIndex,
STREAMTYPE_VIDEO = 1 << kVideoIndex,
STREAMTYPE_SUBTITLES = 1 << kSubtitleIndex,
+ STREAMTYPE_METADATA = 1 << kMetaDataIndex,
};
enum SeekMode {
@@ -66,6 +71,7 @@ struct LiveSession : public AHandler {
uint32_t flags,
const sp<IMediaHTTPService> &httpService);
+ int64_t calculateMediaTimeUs(int64_t firstTimeUs, int64_t timeUs, int32_t discontinuitySeq);
status_t dequeueAccessUnit(StreamType stream, sp<ABuffer> *accessUnit);
status_t getStreamFormat(StreamType stream, sp<AMessage> *format);
@@ -92,6 +98,7 @@ struct LiveSession : public AHandler {
static const char *getKeyForStream(StreamType type);
static const char *getNameForStream(StreamType type);
+ static ATSParser::SourceType getSourceTypeForStream(StreamType type);
enum {
kWhatStreamsChanged,
@@ -101,6 +108,7 @@ struct LiveSession : public AHandler {
kWhatBufferingStart,
kWhatBufferingEnd,
kWhatBufferingUpdate,
+ kWhatMetadataDetected,
};
protected:
@@ -233,6 +241,8 @@ private:
bool mFirstTimeUsValid;
int64_t mFirstTimeUs;
int64_t mLastSeekTimeUs;
+ bool mHasMetadata;
+
KeyedVector<size_t, int64_t> mDiscontinuityAbsStartTimesUs;
KeyedVector<size_t, int64_t> mDiscontinuityOffsetTimesUs;
@@ -268,6 +278,11 @@ private:
sp<M3UParser> fetchPlaylist(
const char *url, uint8_t *curPlaylistHash, bool *unchanged);
+ bool UriIsSameAsIndex( const AString &uri, int32_t index, bool newUri);
+ sp<AnotherPacketSource> getPacketSourceForStreamIndex(size_t trackIndex, bool newUri);
+ sp<AnotherPacketSource> getMetadataSource(
+ sp<AnotherPacketSource> sources[kNumSources], uint32_t streamMask, bool newUri);
+
bool resumeFetcher(
const AString &uri, uint32_t streamMask,
int64_t timeUs = -1ll, bool newUri = false);
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 ce79cc2..8350c1b 100644
--- a/media/libstagefright/httplive/PlaylistFetcher.cpp
+++ b/media/libstagefright/httplive/PlaylistFetcher.cpp
@@ -17,6 +17,7 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "PlaylistFetcher"
#include <utils/Log.h>
+#include <utils/misc.h>
#include "PlaylistFetcher.h"
@@ -159,6 +160,7 @@ PlaylistFetcher::PlaylistFetcher(
mDiscontinuitySeq(-1ll),
mStartTimeUsRelative(false),
mLastPlaylistFetchTimeUs(-1ll),
+ mPlaylistTimeUs(-1ll),
mSeqNumber(-1),
mNumRetries(0),
mStartup(true),
@@ -174,7 +176,8 @@ PlaylistFetcher::PlaylistFetcher(
mFirstTimeUs(-1ll),
mVideoBuffer(new AnotherPacketSource(NULL)),
mThresholdRatio(-1.0f),
- mDownloadState(new DownloadState()) {
+ mDownloadState(new DownloadState()),
+ mHasMetadata(false) {
memset(mPlaylistHash, 0, sizeof(mPlaylistHash));
mHTTPDataSource = mSession->getHTTPDataSource();
}
@@ -189,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);
@@ -220,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);
@@ -255,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;
@@ -470,6 +460,7 @@ void PlaylistFetcher::startAsync(
const sp<AnotherPacketSource> &audioSource,
const sp<AnotherPacketSource> &videoSource,
const sp<AnotherPacketSource> &subtitleSource,
+ const sp<AnotherPacketSource> &metadataSource,
int64_t startTimeUs,
int64_t segmentStartTimeUs,
int32_t startDiscontinuitySeq,
@@ -493,6 +484,11 @@ void PlaylistFetcher::startAsync(
streamTypeMask |= LiveSession::STREAMTYPE_SUBTITLES;
}
+ if (metadataSource != NULL) {
+ msg->setPointer("metadataSource", metadataSource.get());
+ // metadataSource does not affect streamTypeMask.
+ }
+
msg->setInt32("streamTypeMask", streamTypeMask);
msg->setInt64("startTimeUs", startTimeUs);
msg->setInt64("segmentStartTimeUs", segmentStartTimeUs);
@@ -637,6 +633,15 @@ status_t PlaylistFetcher::onStart(const sp<AMessage> &msg) {
static_cast<AnotherPacketSource *>(ptr));
}
+ void *ptr;
+ // metadataSource is not part of streamTypeMask
+ if ((streamTypeMask & (LiveSession::STREAMTYPE_AUDIO | LiveSession::STREAMTYPE_VIDEO))
+ && msg->findPointer("metadataSource", &ptr)) {
+ mPacketSources.add(
+ LiveSession::STREAMTYPE_METADATA,
+ static_cast<AnotherPacketSource *>(ptr));
+ }
+
mStreamTypeMask = streamTypeMask;
mSegmentStartTimeUs = segmentStartTimeUs;
@@ -733,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;
@@ -848,6 +844,7 @@ status_t PlaylistFetcher::refreshPlaylist() {
if (!mPlaylist->isComplete()) {
updateTargetDuration();
}
+ mPlaylistTimeUs = ALooper::GetNowUs();
}
mLastPlaylistFetchTimeUs = ALooper::GetNowUs();
@@ -867,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);
@@ -932,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();
@@ -972,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) {
@@ -1010,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;
@@ -1141,7 +1137,7 @@ bool PlaylistFetcher::initDownloadState(
}
queueDiscontinuity(
- ATSParser::DISCONTINUITY_FORMATCHANGE,
+ ATSParser::DISCONTINUITY_FORMAT_ONLY,
NULL /* extra */);
if (mStartup && mStartTimeUsRelative && mFirstPTSValid) {
@@ -1155,6 +1151,8 @@ bool PlaylistFetcher::initDownloadState(
// set mStartTimeUs=0, and take all samples from now on.
mStartTimeUs = 0;
mFirstPTSValid = false;
+ mIDRFound = false;
+ mVideoBuffer->clear();
}
}
@@ -1315,11 +1313,11 @@ void PlaylistFetcher::onDownloadNext() {
if (bufferStartsWithTsSyncByte(buffer)) {
// If we don't see a stream in the program table after fetching a full ts segment
// mark it as nonexistent.
- const size_t kNumTypes = ATSParser::NUM_SOURCE_TYPES;
- ATSParser::SourceType srcTypes[kNumTypes] =
+ ATSParser::SourceType srcTypes[] =
{ ATSParser::VIDEO, ATSParser::AUDIO };
- LiveSession::StreamType streamTypes[kNumTypes] =
+ LiveSession::StreamType streamTypes[] =
{ LiveSession::STREAMTYPE_VIDEO, LiveSession::STREAMTYPE_AUDIO };
+ const size_t kNumTypes = NELEM(srcTypes);
for (size_t i = 0; i < kNumTypes; i++) {
ATSParser::SourceType srcType = srcTypes[i];
@@ -1391,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));
+
+ int64_t itemDurationUs;
+ CHECK(itemMeta->findInt64("durationUs", &itemDurationUs));
- anchorTimeUs -= itemDurationUs;
- --index;
+ 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()) {
@@ -1448,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()) {
@@ -1476,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(
@@ -1491,17 +1508,37 @@ 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;
}
+bool PlaylistFetcher::isStartTimeReached(int64_t timeUs) {
+ if (!mFirstPTSValid) {
+ mFirstTimeUs = timeUs;
+ mFirstPTSValid = true;
+ }
+ bool startTimeReached = true;
+ if (mStartTimeUsRelative) {
+ FLOGV("startTimeUsRelative, timeUs (%lld) - %lld = %lld",
+ (long long)timeUs,
+ (long long)mFirstTimeUs,
+ (long long)(timeUs - mFirstTimeUs));
+ timeUs -= mFirstTimeUs;
+ if (timeUs < 0) {
+ FLOGV("clamp negative timeUs to 0");
+ timeUs = 0;
+ }
+ startTimeReached = (timeUs >= mStartTimeUs);
+ }
+ return startTimeReached;
+}
+
status_t PlaylistFetcher::extractAndQueueAccessUnitsFromTs(const sp<ABuffer> &buffer) {
if (mTSParser == NULL) {
// Use TS_TIMESTAMPS_ARE_ABSOLUTE so pts carry over between fetchers.
@@ -1539,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);
@@ -1548,10 +1638,9 @@ status_t PlaylistFetcher::extractAndQueueAccessUnitsFromTs(const sp<ABuffer> &bu
ALOGE("MPEG2 Transport streams do not contain subtitles.");
return ERROR_MALFORMED;
}
+
const char *key = LiveSession::getKeyForStream(stream);
- ATSParser::SourceType type =
- (stream == LiveSession::STREAMTYPE_AUDIO) ?
- ATSParser::AUDIO : ATSParser::VIDEO;
+ ATSParser::SourceType type =LiveSession::getSourceTypeForStream(stream);
sp<AnotherPacketSource> source =
static_cast<AnotherPacketSource *>(
@@ -1574,92 +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) {
- if (!mFirstPTSValid) {
- mFirstTimeUs = timeUs;
- mFirstPTSValid = true;
- }
- bool startTimeReached = true;
- if (mStartTimeUsRelative) {
- FLOGV("startTimeUsRelative, timeUs (%lld) - %lld = %lld",
- (long long)timeUs,
- (long long)mFirstTimeUs,
- (long long)(timeUs - mFirstTimeUs));
- timeUs -= mFirstTimeUs;
- if (timeUs < 0) {
- FLOGV("clamp negative timeUs to 0");
- timeUs = 0;
- }
- startTimeReached = (timeUs >= mStartTimeUs);
- }
+ 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();
@@ -1680,7 +1694,8 @@ status_t PlaylistFetcher::extractAndQueueAccessUnitsFromTs(const sp<ABuffer> &bu
if (mStartTimeUsNotify != NULL) {
uint32_t streamMask = 0;
mStartTimeUsNotify->findInt32("streamMask", (int32_t *) &streamMask);
- if (!(streamMask & mPacketSources.keyAt(i))) {
+ if ((mStreamTypeMask & mPacketSources.keyAt(i))
+ && !(streamMask & mPacketSources.keyAt(i))) {
streamMask |= mPacketSources.keyAt(i);
mStartTimeUsNotify->setInt32("streamMask", streamMask);
FSLOGV(stream, "found start point, timeUs=%lld, streamMask becomes %x",
@@ -1721,6 +1736,11 @@ status_t PlaylistFetcher::extractAndQueueAccessUnitsFromTs(const sp<ABuffer> &bu
FSLOGV(stream, "queueAccessUnit (saved), timeUs=%lld",
(long long)bufferTimeUs);
}
+ } else if (stream == LiveSession::STREAMTYPE_METADATA && !mHasMetadata) {
+ mHasMetadata = true;
+ sp<AMessage> notify = mNotify->dup();
+ notify->setInt32("what", kWhatMetadataDetected);
+ notify->post();
}
setAccessUnitProperties(accessUnit, source);
@@ -1794,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;
}
@@ -1905,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;
@@ -1948,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;
}
@@ -2016,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 f64d160..1f5e9b0 100644
--- a/media/libstagefright/httplive/PlaylistFetcher.h
+++ b/media/libstagefright/httplive/PlaylistFetcher.h
@@ -27,7 +27,7 @@ namespace android {
struct ABuffer;
struct AnotherPacketSource;
-struct DataSource;
+class DataSource;
struct HTTPBase;
struct LiveDataSource;
struct M3UParser;
@@ -49,6 +49,7 @@ struct PlaylistFetcher : public AHandler {
kWhatPreparationFailed,
kWhatStartedAt,
kWhatStopReached,
+ kWhatMetadataDetected,
};
PlaylistFetcher(
@@ -66,6 +67,7 @@ struct PlaylistFetcher : public AHandler {
const sp<AnotherPacketSource> &audioSource,
const sp<AnotherPacketSource> &videoSource,
const sp<AnotherPacketSource> &subtitleSource,
+ const sp<AnotherPacketSource> &metadataSource,
int64_t startTimeUs = -1ll, // starting timestamps
int64_t segmentStartTimeUs = -1ll, // starting position within playlist
// startTimeUs!=segmentStartTimeUs only when playlist is live
@@ -136,6 +138,7 @@ private:
KeyedVector<AString, sp<ABuffer> > mAESKeyForURI;
int64_t mLastPlaylistFetchTimeUs;
+ int64_t mPlaylistTimeUs;
sp<M3UParser> mPlaylist;
int32_t mSeqNumber;
int32_t mNumRetries;
@@ -177,6 +180,8 @@ private:
sp<DownloadState> mDownloadState;
+ bool mHasMetadata;
+
// Set first to true if decrypting the first segment of a playlist segment. When
// first is true, reset the initialization vector based on the available
// information in the manifest; otherwise, use the initialization vector as
@@ -222,6 +227,7 @@ private:
const sp<ABuffer> &accessUnit,
const sp<AnotherPacketSource> &source,
bool discard = false);
+ bool isStartTimeReached(int64_t timeUs);
status_t extractAndQueueAccessUnitsFromTs(const sp<ABuffer> &buffer);
status_t extractAndQueueAccessUnits(
@@ -233,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 2194c38..68bd017 100644
--- a/media/libstagefright/id3/Android.mk
+++ b/media/libstagefright/id3/Android.mk
@@ -4,7 +4,8 @@ include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
ID3.cpp
-LOCAL_CFLAGS += -Werror
+LOCAL_CFLAGS += -Werror -Wall
+LOCAL_CLANG := true
LOCAL_MODULE := libstagefright_id3
@@ -17,7 +18,8 @@ include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
testid3.cpp
-LOCAL_CFLAGS += -Werror
+LOCAL_CFLAGS += -Werror -Wall
+LOCAL_CLANG := true
LOCAL_SHARED_LIBRARIES := \
libstagefright libutils liblog libbinder libstagefright_foundation
diff --git a/media/libstagefright/include/AwesomePlayer.h b/media/libstagefright/include/AwesomePlayer.h
index 77d65e0..8bba804 100644
--- a/media/libstagefright/include/AwesomePlayer.h
+++ b/media/libstagefright/include/AwesomePlayer.h
@@ -31,20 +31,20 @@
namespace android {
-struct AudioPlayer;
+class AudioPlayer;
struct ClockEstimator;
-struct DataSource;
-struct MediaBuffer;
+class IDataSource;
+class MediaBuffer;
struct MediaExtractor;
struct MediaSource;
struct NuCachedSource2;
-struct IGraphicBufferProducer;
+class IGraphicBufferProducer;
class DrmManagerClinet;
class DecryptHandle;
class TimedTextDriver;
-struct WVMExtractor;
+class WVMExtractor;
struct AwesomeRenderer : public RefBase {
AwesomeRenderer() {}
diff --git a/media/libstagefright/include/CallbackDataSource.h b/media/libstagefright/include/CallbackDataSource.h
new file mode 100644
index 0000000..1a21dd3
--- /dev/null
+++ b/media/libstagefright/include/CallbackDataSource.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_CALLBACKDATASOURCE_H
+#define ANDROID_CALLBACKDATASOURCE_H
+
+#include <media/stagefright/DataSource.h>
+#include <media/stagefright/foundation/ADebug.h>
+
+namespace android {
+
+class IDataSource;
+class IMemory;
+
+// A stagefright DataSource that wraps a binder IDataSource. It's a "Callback"
+// DataSource because it calls back to the IDataSource for data.
+class CallbackDataSource : public DataSource {
+public:
+ CallbackDataSource(const sp<IDataSource>& iDataSource);
+ virtual ~CallbackDataSource();
+
+ // DataSource implementation.
+ virtual status_t initCheck() const;
+ virtual ssize_t readAt(off64_t offset, void *data, size_t size);
+ virtual status_t getSize(off64_t *size);
+
+private:
+ sp<IDataSource> mIDataSource;
+ sp<IMemory> mMemory;
+
+ DISALLOW_EVIL_CONSTRUCTORS(CallbackDataSource);
+};
+
+
+// A caching DataSource that wraps a CallbackDataSource. For reads smaller
+// than kCacheSize it will read up to kCacheSize ahead and cache it.
+// This reduces the number of binder round trips to the IDataSource and has a significant
+// impact on time taken for filetype sniffing and metadata extraction.
+class TinyCacheSource : public DataSource {
+public:
+ TinyCacheSource(const sp<DataSource>& source);
+
+ virtual status_t initCheck() const;
+ virtual ssize_t readAt(off64_t offset, void* data, size_t size);
+ virtual status_t getSize(off64_t* size);
+ virtual uint32_t flags();
+
+private:
+ // 2kb comes from experimenting with the time-to-first-frame from a MediaPlayer
+ // with an in-memory MediaDataSource source on a Nexus 5. Beyond 2kb there was
+ // no improvement.
+ enum {
+ kCacheSize = 2048,
+ };
+
+ sp<DataSource> mSource;
+ uint8_t mCache[kCacheSize];
+ off64_t mCachedOffset;
+ size_t mCachedSize;
+
+ DISALLOW_EVIL_CONSTRUCTORS(TinyCacheSource);
+};
+
+}; // namespace android
+
+#endif // ANDROID_CALLBACKDATASOURCE_H
diff --git a/media/libstagefright/include/MPEG2PSExtractor.h b/media/libstagefright/include/MPEG2PSExtractor.h
index fb76564..22cb02d 100644
--- a/media/libstagefright/include/MPEG2PSExtractor.h
+++ b/media/libstagefright/include/MPEG2PSExtractor.h
@@ -28,7 +28,7 @@ namespace android {
struct ABuffer;
struct AMessage;
struct Track;
-struct String8;
+class String8;
struct MPEG2PSExtractor : public MediaExtractor {
MPEG2PSExtractor(const sp<DataSource> &source);
diff --git a/media/libstagefright/include/MPEG2TSExtractor.h b/media/libstagefright/include/MPEG2TSExtractor.h
index db1187d..4dd340c 100644
--- a/media/libstagefright/include/MPEG2TSExtractor.h
+++ b/media/libstagefright/include/MPEG2TSExtractor.h
@@ -30,7 +30,7 @@ struct AnotherPacketSource;
struct ATSParser;
class DataSource;
struct MPEG2TSSource;
-struct String8;
+class String8;
struct MPEG2TSExtractor : public MediaExtractor {
MPEG2TSExtractor(const sp<DataSource> &source);
diff --git a/media/libstagefright/include/OMX.h b/media/libstagefright/include/OMX.h
index e8c4970..b5487fa 100644
--- a/media/libstagefright/include/OMX.h
+++ b/media/libstagefright/include/OMX.h
@@ -24,7 +24,7 @@
namespace android {
struct OMXMaster;
-class OMXNodeInstance;
+struct OMXNodeInstance;
class OMX : public BnOMX,
public IBinder::DeathRecipient {
diff --git a/media/libstagefright/include/OMXNodeInstance.h b/media/libstagefright/include/OMXNodeInstance.h
index 104dcfc..d87b408 100644
--- a/media/libstagefright/include/OMXNodeInstance.h
+++ b/media/libstagefright/include/OMXNodeInstance.h
@@ -27,7 +27,7 @@ namespace android {
class IOMXObserver;
struct OMXMaster;
-struct GraphicBufferSource;
+class GraphicBufferSource;
struct OMXNodeInstance {
OMXNodeInstance(
diff --git a/media/libstagefright/include/SampleIterator.h b/media/libstagefright/include/SampleIterator.h
index 60c9e7e..7053247 100644
--- a/media/libstagefright/include/SampleIterator.h
+++ b/media/libstagefright/include/SampleIterator.h
@@ -18,7 +18,7 @@
namespace android {
-struct SampleTable;
+class SampleTable;
struct SampleIterator {
SampleIterator(SampleTable *table);
diff --git a/media/libstagefright/include/StagefrightMetadataRetriever.h b/media/libstagefright/include/StagefrightMetadataRetriever.h
index 6632c27..fd739d0 100644
--- a/media/libstagefright/include/StagefrightMetadataRetriever.h
+++ b/media/libstagefright/include/StagefrightMetadataRetriever.h
@@ -25,7 +25,7 @@
namespace android {
-struct DataSource;
+class DataSource;
class MediaExtractor;
struct StagefrightMetadataRetriever : public MediaMetadataRetrieverInterface {
@@ -38,6 +38,7 @@ struct StagefrightMetadataRetriever : public MediaMetadataRetrieverInterface {
const KeyedVector<String8, String8> *headers);
virtual status_t setDataSource(int fd, int64_t offset, int64_t length);
+ virtual status_t setDataSource(const sp<DataSource>& source);
virtual VideoFrame *getFrameAtTime(int64_t timeUs, int option);
virtual MediaAlbumArt *extractAlbumArt();
@@ -53,6 +54,8 @@ private:
MediaAlbumArt *mAlbumArt;
void parseMetaData();
+ // Delete album art and clear metadata.
+ void clearMetadata();
StagefrightMetadataRetriever(const StagefrightMetadataRetriever &);
diff --git a/media/libstagefright/include/TimedEventQueue.h b/media/libstagefright/include/TimedEventQueue.h
index 2963150..890f7e8 100644
--- a/media/libstagefright/include/TimedEventQueue.h
+++ b/media/libstagefright/include/TimedEventQueue.h
@@ -46,7 +46,7 @@ struct TimedEventQueue {
virtual void fire(TimedEventQueue *queue, int64_t now_us) = 0;
private:
- friend class TimedEventQueue;
+ friend struct TimedEventQueue;
event_id mEventID;
diff --git a/media/libstagefright/include/VBRISeeker.h b/media/libstagefright/include/VBRISeeker.h
index 1a2bf9f..c57d571 100644
--- a/media/libstagefright/include/VBRISeeker.h
+++ b/media/libstagefright/include/VBRISeeker.h
@@ -24,7 +24,7 @@
namespace android {
-struct DataSource;
+class DataSource;
struct VBRISeeker : public MP3Seeker {
static sp<VBRISeeker> CreateFromSource(
diff --git a/media/libstagefright/include/XINGSeeker.h b/media/libstagefright/include/XINGSeeker.h
index c408576..cce04f0 100644
--- a/media/libstagefright/include/XINGSeeker.h
+++ b/media/libstagefright/include/XINGSeeker.h
@@ -22,7 +22,7 @@
namespace android {
-struct DataSource;
+class DataSource;
struct XINGSeeker : public MP3Seeker {
static sp<XINGSeeker> CreateFromSource(
diff --git a/media/libstagefright/matroska/Android.mk b/media/libstagefright/matroska/Android.mk
index 446ff8c..1e8c2b2 100644
--- a/media/libstagefright/matroska/Android.mk
+++ b/media/libstagefright/matroska/Android.mk
@@ -8,7 +8,8 @@ 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/ATSParser.cpp b/media/libstagefright/mpeg2ts/ATSParser.cpp
index 0a868bc..5411821 100644
--- a/media/libstagefright/mpeg2ts/ATSParser.cpp
+++ b/media/libstagefright/mpeg2ts/ATSParser.cpp
@@ -132,6 +132,7 @@ struct ATSParser::Stream : public RefBase {
bool isAudio() const;
bool isVideo() const;
+ bool isMeta() const;
protected:
virtual ~Stream();
@@ -146,6 +147,7 @@ private:
sp<ABuffer> mBuffer;
sp<AnotherPacketSource> mSource;
bool mPayloadStarted;
+ bool mEOSReached;
uint64_t mPrevPTS;
@@ -567,6 +569,7 @@ ATSParser::Stream::Stream(
mPCR_PID(PCR_PID),
mExpectedContinuityCounter(-1),
mPayloadStarted(false),
+ mEOSReached(false),
mPrevPTS(0),
mQueue(NULL) {
switch (mStreamType) {
@@ -602,6 +605,11 @@ ATSParser::Stream::Stream(
ElementaryStreamQueue::AC3);
break;
+ case STREAMTYPE_METADATA:
+ mQueue = new ElementaryStreamQueue(
+ ElementaryStreamQueue::METADATA);
+ break;
+
default:
break;
}
@@ -720,6 +728,13 @@ bool ATSParser::Stream::isAudio() const {
}
}
+bool ATSParser::Stream::isMeta() const {
+ if (mStreamType == STREAMTYPE_METADATA) {
+ return true;
+ }
+ return false;
+}
+
void ATSParser::Stream::signalDiscontinuity(
DiscontinuityType type, const sp<AMessage> &extra) {
mExpectedContinuityCounter = -1;
@@ -766,6 +781,8 @@ void ATSParser::Stream::signalEOS(status_t finalResult) {
if (mSource != NULL) {
mSource->signalEOS(finalResult);
}
+ mEOSReached = true;
+ flush();
}
status_t ATSParser::Stream::parsePES(ABitReader *br) {
@@ -976,6 +993,10 @@ void ATSParser::Stream::onPayloadData(
status_t err = mQueue->appendData(data, size, timeUs);
+ if (mEOSReached) {
+ mQueue->signalEOS();
+ }
+
if (err != OK) {
return;
}
@@ -1029,6 +1050,14 @@ sp<MediaSource> ATSParser::Stream::getSource(SourceType type) {
break;
}
+ case META:
+ {
+ if (isMeta()) {
+ return mSource;
+ }
+ break;
+ }
+
default:
break;
}
diff --git a/media/libstagefright/mpeg2ts/ATSParser.h b/media/libstagefright/mpeg2ts/ATSParser.h
index a1405bd..87ab1a0 100644
--- a/media/libstagefright/mpeg2ts/ATSParser.h
+++ b/media/libstagefright/mpeg2ts/ATSParser.h
@@ -74,7 +74,8 @@ struct ATSParser : public RefBase {
enum SourceType {
VIDEO = 0,
AUDIO = 1,
- NUM_SOURCE_TYPES = 2
+ META = 2,
+ NUM_SOURCE_TYPES = 3
};
sp<MediaSource> getSource(SourceType type);
bool hasSource(SourceType type) const;
@@ -90,6 +91,7 @@ struct ATSParser : public RefBase {
STREAMTYPE_MPEG2_AUDIO = 0x04,
STREAMTYPE_MPEG2_AUDIO_ADTS = 0x0f,
STREAMTYPE_MPEG4_VIDEO = 0x10,
+ STREAMTYPE_METADATA = 0x15,
STREAMTYPE_H264 = 0x1b,
// From ATSC A/53 Part 3:2009, 6.7.1
diff --git a/media/libstagefright/mpeg2ts/Android.mk b/media/libstagefright/mpeg2ts/Android.mk
index c17a0b7..16b0160 100644
--- a/media/libstagefright/mpeg2ts/Android.mk
+++ b/media/libstagefright/mpeg2ts/Android.mk
@@ -13,7 +13,8 @@ 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/mpeg2ts/AnotherPacketSource.cpp b/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
index a4f8739..87ec860 100644
--- a/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
+++ b/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
@@ -73,7 +73,7 @@ void AnotherPacketSource::setFormat(const sp<MetaData> &meta) {
} else if (!strncasecmp("video/", mime, 6)) {
mIsVideo = true;
} else {
- CHECK(!strncasecmp("text/", mime, 5));
+ CHECK(!strncasecmp("text/", mime, 5) || !strncasecmp("application/", mime, 12));
}
}
@@ -146,6 +146,12 @@ status_t AnotherPacketSource::dequeueAccessUnit(sp<ABuffer> *buffer) {
return mEOSResult;
}
+void AnotherPacketSource::requeueAccessUnit(const sp<ABuffer> &buffer) {
+ // TODO: update corresponding book keeping info.
+ Mutex::Autolock autoLock(mLock);
+ mBuffers.push_front(buffer);
+}
+
status_t AnotherPacketSource::read(
MediaBuffer **out, const ReadOptions *) {
*out = NULL;
diff --git a/media/libstagefright/mpeg2ts/AnotherPacketSource.h b/media/libstagefright/mpeg2ts/AnotherPacketSource.h
index fa7dd6a..08cd92e 100644
--- a/media/libstagefright/mpeg2ts/AnotherPacketSource.h
+++ b/media/libstagefright/mpeg2ts/AnotherPacketSource.h
@@ -67,6 +67,7 @@ struct AnotherPacketSource : public MediaSource {
void signalEOS(status_t result);
status_t dequeueAccessUnit(sp<ABuffer> *buffer);
+ void requeueAccessUnit(const sp<ABuffer> &buffer);
bool isFinished(int64_t duration) const;
diff --git a/media/libstagefright/mpeg2ts/ESQueue.cpp b/media/libstagefright/mpeg2ts/ESQueue.cpp
index a279049..f28a1fd 100644
--- a/media/libstagefright/mpeg2ts/ESQueue.cpp
+++ b/media/libstagefright/mpeg2ts/ESQueue.cpp
@@ -38,7 +38,8 @@ namespace android {
ElementaryStreamQueue::ElementaryStreamQueue(Mode mode, uint32_t flags)
: mMode(mode),
- mFlags(flags) {
+ mFlags(flags),
+ mEOSReached(false) {
}
sp<MetaData> ElementaryStreamQueue::getFormat() {
@@ -244,6 +245,11 @@ static bool IsSeeminglyValidMPEGAudioHeader(const uint8_t *ptr, size_t size) {
status_t ElementaryStreamQueue::appendData(
const void *data, size_t size, int64_t timeUs) {
+
+ if (mEOSReached) {
+ ALOGE("appending data after EOS");
+ return ERROR_MALFORMED;
+ }
if (mBuffer == NULL || mBuffer->size() == 0) {
switch (mMode) {
case H264:
@@ -409,6 +415,7 @@ status_t ElementaryStreamQueue::appendData(
}
case PCM_AUDIO:
+ case METADATA:
{
break;
}
@@ -493,6 +500,8 @@ sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnit() {
return dequeueAccessUnitMPEG4Video();
case PCM_AUDIO:
return dequeueAccessUnitPCMAudio();
+ case METADATA:
+ return dequeueAccessUnitMetadata();
default:
CHECK_EQ((unsigned)mMode, (unsigned)MPEG_AUDIO);
return dequeueAccessUnitMPEGAudio();
@@ -1274,4 +1283,37 @@ sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitMPEG4Video() {
return NULL;
}
+void ElementaryStreamQueue::signalEOS() {
+ if (!mEOSReached) {
+ if (mMode == MPEG_VIDEO) {
+ const char *theEnd = "\x00\x00\x01\x00";
+ appendData(theEnd, 4, 0);
+ }
+ mEOSReached = true;
+ } else {
+ ALOGW("EOS already signaled");
+ }
+}
+
+sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitMetadata() {
+ size_t size = mBuffer->size();
+ if (!size) {
+ return NULL;
+ }
+
+ sp<ABuffer> accessUnit = new ABuffer(size);
+ int64_t timeUs = fetchTimestamp(size);
+ accessUnit->meta()->setInt64("timeUs", timeUs);
+
+ memcpy(accessUnit->data(), mBuffer->data(), size);
+ mBuffer->setRange(0, 0);
+
+ if (mFormat == NULL) {
+ mFormat = new MetaData;
+ mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_DATA_METADATA);
+ }
+
+ return accessUnit;
+}
+
} // namespace android
diff --git a/media/libstagefright/mpeg2ts/ESQueue.h b/media/libstagefright/mpeg2ts/ESQueue.h
index 45b4624..e9f96b7 100644
--- a/media/libstagefright/mpeg2ts/ESQueue.h
+++ b/media/libstagefright/mpeg2ts/ESQueue.h
@@ -37,6 +37,7 @@ struct ElementaryStreamQueue {
MPEG_VIDEO,
MPEG4_VIDEO,
PCM_AUDIO,
+ METADATA,
};
enum Flags {
@@ -46,6 +47,7 @@ struct ElementaryStreamQueue {
ElementaryStreamQueue(Mode mode, uint32_t flags = 0);
status_t appendData(const void *data, size_t size, int64_t timeUs);
+ void signalEOS();
void clear(bool clearFormat);
sp<ABuffer> dequeueAccessUnit();
@@ -60,6 +62,7 @@ private:
Mode mMode;
uint32_t mFlags;
+ bool mEOSReached;
sp<ABuffer> mBuffer;
List<RangeInfo> mRangeInfos;
@@ -73,6 +76,7 @@ private:
sp<ABuffer> dequeueAccessUnitMPEGVideo();
sp<ABuffer> dequeueAccessUnitMPEG4Video();
sp<ABuffer> dequeueAccessUnitPCMAudio();
+ sp<ABuffer> dequeueAccessUnitMetadata();
// consume a logical (compressed) access unit of size "size",
// returns its timestamp in us (or -1 if no time information).
diff --git a/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp b/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp
index 33cfd1d..74cb5d8 100644
--- a/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp
+++ b/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp
@@ -204,6 +204,9 @@ status_t MPEG2TSExtractor::feedMore() {
ssize_t n = mDataSource->readAt(mOffset, packet, kTSPacketSize);
if (n < (ssize_t)kTSPacketSize) {
+ if (n >= 0) {
+ mParser->signalEOS(ERROR_END_OF_STREAM);
+ }
return (n < 0) ? (status_t)n : ERROR_END_OF_STREAM;
}
diff --git a/media/libstagefright/omx/Android.mk b/media/libstagefright/omx/Android.mk
index 07ea605..5f0f567 100644
--- a/media/libstagefright/omx/Android.mk
+++ b/media/libstagefright/omx/Android.mk
@@ -31,6 +31,8 @@ LOCAL_SHARED_LIBRARIES := \
libdl
LOCAL_MODULE:= libstagefright_omx
+LOCAL_CFLAGS += -Werror -Wall
+LOCAL_CLANG := true
include $(BUILD_SHARED_LIBRARY)
diff --git a/media/libstagefright/omx/FrameDropper.cpp b/media/libstagefright/omx/FrameDropper.cpp
index 9fba0b7..9a4952e 100644
--- a/media/libstagefright/omx/FrameDropper.cpp
+++ b/media/libstagefright/omx/FrameDropper.cpp
@@ -50,20 +50,23 @@ bool FrameDropper::shouldDrop(int64_t timeUs) {
if (mDesiredMinTimeUs < 0) {
mDesiredMinTimeUs = timeUs + mMinIntervalUs;
- ALOGV("first frame %lld, next desired frame %lld", timeUs, mDesiredMinTimeUs);
+ ALOGV("first frame %lld, next desired frame %lld",
+ (long long)timeUs, (long long)mDesiredMinTimeUs);
return false;
}
if (timeUs < (mDesiredMinTimeUs - kMaxJitterUs)) {
ALOGV("drop frame %lld, desired frame %lld, diff %lld",
- timeUs, mDesiredMinTimeUs, mDesiredMinTimeUs - timeUs);
+ (long long)timeUs, (long long)mDesiredMinTimeUs,
+ (long long)(mDesiredMinTimeUs - timeUs));
return true;
}
int64_t n = (timeUs - mDesiredMinTimeUs + kMaxJitterUs) / mMinIntervalUs;
mDesiredMinTimeUs += (n + 1) * mMinIntervalUs;
ALOGV("keep frame %lld, next desired frame %lld, diff %lld",
- timeUs, mDesiredMinTimeUs, mDesiredMinTimeUs - timeUs);
+ (long long)timeUs, (long long)mDesiredMinTimeUs,
+ (long long)(mDesiredMinTimeUs - timeUs));
return false;
}
diff --git a/media/libstagefright/omx/GraphicBufferSource.h b/media/libstagefright/omx/GraphicBufferSource.h
index 1067472..718d2ee 100644
--- a/media/libstagefright/omx/GraphicBufferSource.h
+++ b/media/libstagefright/omx/GraphicBufferSource.h
@@ -30,7 +30,7 @@
namespace android {
-class FrameDropper;
+struct FrameDropper;
/*
* This class is used to feed OMX codecs from a Surface via BufferQueue.
@@ -240,7 +240,7 @@ private:
Vector<CodecBuffer> mCodecBuffers;
////
- friend class AHandlerReflector<GraphicBufferSource>;
+ friend struct AHandlerReflector<GraphicBufferSource>;
enum {
kWhatRepeatLastFrame,
diff --git a/media/libstagefright/omx/SimpleSoftOMXComponent.cpp b/media/libstagefright/omx/SimpleSoftOMXComponent.cpp
index 801a1bd..04303c4 100644
--- a/media/libstagefright/omx/SimpleSoftOMXComponent.cpp
+++ b/media/libstagefright/omx/SimpleSoftOMXComponent.cpp
@@ -598,7 +598,7 @@ void SimpleSoftOMXComponent::checkTransitions() {
if (port->mTransition == PortInfo::DISABLING) {
if (port->mBuffers.empty()) {
- ALOGV("Port %d now disabled.", i);
+ ALOGV("Port %zu now disabled.", i);
port->mTransition = PortInfo::NONE;
notify(OMX_EventCmdComplete, OMX_CommandPortDisable, i, NULL);
@@ -607,7 +607,7 @@ void SimpleSoftOMXComponent::checkTransitions() {
}
} else if (port->mTransition == PortInfo::ENABLING) {
if (port->mDef.bPopulated == OMX_TRUE) {
- ALOGV("Port %d now enabled.", i);
+ ALOGV("Port %zu now enabled.", i);
port->mTransition = PortInfo::NONE;
port->mDef.bEnabled = OMX_TRUE;
@@ -628,14 +628,14 @@ void SimpleSoftOMXComponent::addPort(const OMX_PARAM_PORTDEFINITIONTYPE &def) {
info->mTransition = PortInfo::NONE;
}
-void SimpleSoftOMXComponent::onQueueFilled(OMX_U32 portIndex) {
+void SimpleSoftOMXComponent::onQueueFilled(OMX_U32 portIndex __unused) {
}
-void SimpleSoftOMXComponent::onPortFlushCompleted(OMX_U32 portIndex) {
+void SimpleSoftOMXComponent::onPortFlushCompleted(OMX_U32 portIndex __unused) {
}
void SimpleSoftOMXComponent::onPortEnableCompleted(
- OMX_U32 portIndex, bool enabled) {
+ OMX_U32 portIndex __unused, bool enabled __unused) {
}
List<SimpleSoftOMXComponent::BufferInfo *> &
diff --git a/media/libstagefright/omx/tests/Android.mk b/media/libstagefright/omx/tests/Android.mk
index 9be637a..02e97f1 100644
--- a/media/libstagefright/omx/tests/Android.mk
+++ b/media/libstagefright/omx/tests/Android.mk
@@ -11,7 +11,8 @@ 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
@@ -37,4 +38,7 @@ LOCAL_SHARED_LIBRARIES := \
LOCAL_C_INCLUDES := \
frameworks/av/media/libstagefright/omx \
+LOCAL_CFLAGS += -Werror -Wall
+LOCAL_CLANG := true
+
include $(BUILD_NATIVE_TEST)
diff --git a/media/libstagefright/omx/tests/FrameDropper_test.cpp b/media/libstagefright/omx/tests/FrameDropper_test.cpp
index 4ac72c4..f966b5e 100644
--- a/media/libstagefright/omx/tests/FrameDropper_test.cpp
+++ b/media/libstagefright/omx/tests/FrameDropper_test.cpp
@@ -100,7 +100,8 @@ protected:
for (size_t i = 0; i < size; ++i) {
int jitter = GetJitter(i);
int64_t testTimeUs = frames[i].timeUs + jitter;
- printf("time %lld, testTime %lld, jitter %d\n", frames[i].timeUs, testTimeUs, jitter);
+ printf("time %lld, testTime %lld, jitter %d\n",
+ (long long)frames[i].timeUs, (long long)testTimeUs, jitter);
EXPECT_EQ(frames[i].shouldDrop, mFrameDropper->shouldDrop(testTimeUs));
}
}
diff --git a/media/libstagefright/rtsp/ARTPWriter.h b/media/libstagefright/rtsp/ARTPWriter.h
index fdc8d23..be8bc13 100644
--- a/media/libstagefright/rtsp/ARTPWriter.h
+++ b/media/libstagefright/rtsp/ARTPWriter.h
@@ -32,7 +32,7 @@
namespace android {
struct ABuffer;
-struct MediaBuffer;
+class MediaBuffer;
struct ARTPWriter : public MediaWriter {
ARTPWriter(int fd);
diff --git a/media/libstagefright/rtsp/Android.mk b/media/libstagefright/rtsp/Android.mk
index 9fedb71..c5e8c35 100644
--- a/media/libstagefright/rtsp/Android.mk
+++ b/media/libstagefright/rtsp/Android.mk
@@ -31,7 +31,8 @@ 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
@@ -54,7 +55,8 @@ LOCAL_C_INCLUDES:= \
frameworks/av/media/libstagefright \
$(TOP)/frameworks/native/include/media/openmax
-LOCAL_CFLAGS += -Wno-multichar
+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 51e1c78..111e6c5 100644
--- a/media/libstagefright/tests/Android.mk
+++ b/media/libstagefright/tests/Android.mk
@@ -31,6 +31,9 @@ LOCAL_C_INCLUDES := \
frameworks/av/media/libstagefright/include \
$(TOP)/frameworks/native/include/media/openmax \
+LOCAL_CFLAGS += -Werror -Wall
+LOCAL_CLANG := true
+
LOCAL_32_BIT_ONLY := true
include $(BUILD_NATIVE_TEST)
@@ -60,6 +63,9 @@ LOCAL_C_INCLUDES := \
frameworks/av/media/libstagefright/include \
$(TOP)/frameworks/native/include/media/openmax \
+LOCAL_CFLAGS += -Werror -Wall
+LOCAL_CLANG := true
+
include $(BUILD_NATIVE_TEST)
include $(CLEAR_VARS)
@@ -87,6 +93,9 @@ LOCAL_C_INCLUDES := \
LOCAL_32_BIT_ONLY := true
+LOCAL_CFLAGS += -Werror -Wall
+LOCAL_CLANG := true
+
include $(BUILD_NATIVE_TEST)
# Include subdirectory makefiles
diff --git a/media/libstagefright/tests/DummyRecorder.h b/media/libstagefright/tests/DummyRecorder.h
index 1cbea1b..cd4d0ee 100644
--- a/media/libstagefright/tests/DummyRecorder.h
+++ b/media/libstagefright/tests/DummyRecorder.h
@@ -24,7 +24,7 @@
namespace android {
-class MediaSource;
+struct MediaSource;
class MediaBuffer;
class DummyRecorder {
diff --git a/media/libstagefright/tests/MediaCodecListOverrides_test.cpp b/media/libstagefright/tests/MediaCodecListOverrides_test.cpp
index cacaa84..170cde3 100644
--- a/media/libstagefright/tests/MediaCodecListOverrides_test.cpp
+++ b/media/libstagefright/tests/MediaCodecListOverrides_test.cpp
@@ -278,7 +278,7 @@ TEST_F(MediaCodecListOverridesTest, exportResultsToExistingFile) {
rewind(f);
char *buf = (char *)malloc(size);
- EXPECT_EQ(1, fread(buf, size, 1, f));
+ EXPECT_EQ((size_t)1, fread(buf, size, 1, f));
overrides.setTo(buf, size);
fclose(f);
free(buf);
@@ -303,7 +303,7 @@ TEST_F(MediaCodecListOverridesTest, exportResultsToEmptyFile) {
rewind(f);
char *buf = (char *)malloc(size);
- EXPECT_EQ(1, fread(buf, size, 1, f));
+ EXPECT_EQ((size_t)1, fread(buf, size, 1, f));
overrides.setTo(buf, size);
fclose(f);
free(buf);
diff --git a/media/libstagefright/timedtext/Android.mk b/media/libstagefright/timedtext/Android.mk
index 6a8b9fc..58fb12f 100644
--- a/media/libstagefright/timedtext/Android.mk
+++ b/media/libstagefright/timedtext/Android.mk
@@ -9,7 +9,8 @@ LOCAL_SRC_FILES:= \
TimedTextSRTSource.cpp \
TimedTextPlayer.cpp
-LOCAL_CFLAGS += -Wno-multichar -Werror
+LOCAL_CFLAGS += -Wno-multichar -Werror -Wall
+LOCAL_CLANG := true
LOCAL_C_INCLUDES:= \
$(TOP)/frameworks/av/include/media/stagefright/timedtext \
diff --git a/media/libstagefright/timedtext/test/Android.mk b/media/libstagefright/timedtext/test/Android.mk
index 9a9fde2..e0e0e0d 100644
--- a/media/libstagefright/timedtext/test/Android.mk
+++ b/media/libstagefright/timedtext/test/Android.mk
@@ -26,4 +26,7 @@ LOCAL_SHARED_LIBRARIES := \
libstagefright_foundation \
libutils
+LOCAL_CFLAGS += -Werror -Wall
+LOCAL_CLANG := true
+
include $(BUILD_NATIVE_TEST)
diff --git a/media/libstagefright/timedtext/test/TimedTextSRTSource_test.cpp b/media/libstagefright/timedtext/test/TimedTextSRTSource_test.cpp
index 3a06d61..211e732 100644
--- a/media/libstagefright/timedtext/test/TimedTextSRTSource_test.cpp
+++ b/media/libstagefright/timedtext/test/TimedTextSRTSource_test.cpp
@@ -63,10 +63,10 @@ public:
}
virtual ssize_t readAt(off64_t offset, void *data, size_t size) {
- if (offset >= mSize) return 0;
+ if ((size_t)offset >= mSize) return 0;
ssize_t avail = mSize - offset;
- if (avail > size) {
+ if ((size_t)avail > size) {
avail = size;
}
memcpy(data, mData + offset, avail);
diff --git a/media/libstagefright/webm/Android.mk b/media/libstagefright/webm/Android.mk
index 7081463..bc53c56 100644
--- a/media/libstagefright/webm/Android.mk
+++ b/media/libstagefright/webm/Android.mk
@@ -1,8 +1,10 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
-LOCAL_CPPFLAGS += -D__STDINT_LIMITS \
- -Werror
+LOCAL_CPPFLAGS += -D__STDINT_LIMITS
+
+LOCAL_CFLAGS += -Werror -Wall
+LOCAL_CLANG := true
LOCAL_SRC_FILES:= EbmlUtil.cpp \
WebmElement.cpp \
diff --git a/media/libstagefright/wifi-display/Android.mk b/media/libstagefright/wifi-display/Android.mk
index f70454a..fb28624 100644
--- a/media/libstagefright/wifi-display/Android.mk
+++ b/media/libstagefright/wifi-display/Android.mk
@@ -30,6 +30,9 @@ LOCAL_SHARED_LIBRARIES:= \
libui \
libutils \
+LOCAL_CFLAGS += -Wno-multichar -Werror -Wall
+LOCAL_CLANG := true
+
LOCAL_MODULE:= libstagefright_wfd
LOCAL_MODULE_TAGS:= optional
diff --git a/media/libstagefright/wifi-display/VideoFormats.cpp b/media/libstagefright/wifi-display/VideoFormats.cpp
index 2f4af5b..dbc511c 100644
--- a/media/libstagefright/wifi-display/VideoFormats.cpp
+++ b/media/libstagefright/wifi-display/VideoFormats.cpp
@@ -248,8 +248,8 @@ void VideoFormats::getProfileLevel(
}
if (bestProfile == -1 || bestLevel == -1) {
- ALOGE("Profile or level not set for resolution type %d, index %d",
- type, index);
+ ALOGE("Profile or level not set for resolution type %d, index %zu",
+ type, index);
bestProfile = PROFILE_CBP;
bestLevel = LEVEL_31;
}
@@ -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;
@@ -507,7 +506,7 @@ bool VideoFormats::PickBestFormat(
continue;
}
- ALOGV("type %u, index %u, %u x %u %c%u supported",
+ ALOGV("type %zu, index %zu, %zu x %zu %c%zu supported",
i, j, width, height, interlaced ? 'i' : 'p', framesPerSecond);
uint32_t score = width * height * framesPerSecond;
diff --git a/media/libstagefright/wifi-display/rtp/RTPSender.cpp b/media/libstagefright/wifi-display/rtp/RTPSender.cpp
index 4e72533..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 =
@@ -672,8 +670,8 @@ status_t RTPSender::onRTCPData(const sp<ABuffer> &buffer) {
default:
{
- ALOGW("Unknown RTCP packet type %u of size %d",
- (unsigned)data[1], headerLength);
+ ALOGW("Unknown RTCP packet type %u of size %zu",
+ (unsigned)data[1], headerLength);
break;
}
}
@@ -764,7 +762,7 @@ status_t RTPSender::parseTSFB(const uint8_t *data, size_t size) {
return OK;
}
-status_t RTPSender::parseAPP(const uint8_t *data, size_t size) {
+status_t RTPSender::parseAPP(const uint8_t *data, size_t size __unused) {
if (!memcmp("late", &data[8], 4)) {
int64_t avgLatencyUs = (int64_t)U64_AT(&data[12]);
int64_t maxLatencyUs = (int64_t)U64_AT(&data[20]);
diff --git a/media/libstagefright/wifi-display/source/Converter.cpp b/media/libstagefright/wifi-display/source/Converter.cpp
index 8368945..471152e 100644
--- a/media/libstagefright/wifi-display/source/Converter.cpp
+++ b/media/libstagefright/wifi-display/source/Converter.cpp
@@ -747,7 +747,7 @@ status_t Converter::doMoreWork() {
buffer->meta()->setInt64("timeUs", timeUs);
ALOGV("[%s] time %lld us (%.2f secs)",
- mIsVideo ? "video" : "audio", timeUs, timeUs / 1E6);
+ mIsVideo ? "video" : "audio", (long long)timeUs, timeUs / 1E6);
memcpy(buffer->data(), outbuf->base() + offset, size);
diff --git a/media/libstagefright/wifi-display/source/Converter.h b/media/libstagefright/wifi-display/source/Converter.h
index 5876e07..b182990 100644
--- a/media/libstagefright/wifi-display/source/Converter.h
+++ b/media/libstagefright/wifi-display/source/Converter.h
@@ -23,7 +23,7 @@
namespace android {
struct ABuffer;
-struct IGraphicBufferProducer;
+class IGraphicBufferProducer;
struct MediaCodec;
#define ENABLE_SILENCE_DETECTION 0
diff --git a/media/libstagefright/wifi-display/source/PlaybackSession.cpp b/media/libstagefright/wifi-display/source/PlaybackSession.cpp
index 6080943..5e2f0bf 100644
--- a/media/libstagefright/wifi-display/source/PlaybackSession.cpp
+++ b/media/libstagefright/wifi-display/source/PlaybackSession.cpp
@@ -508,7 +508,7 @@ void WifiDisplaySource::PlaybackSession::onMessageReceived(
} else if (what == Converter::kWhatEOS) {
CHECK_EQ(what, Converter::kWhatEOS);
- ALOGI("output EOS on track %d", trackIndex);
+ ALOGI("output EOS on track %zu", trackIndex);
ssize_t index = mTracks.indexOfKey(trackIndex);
CHECK_GE(index, 0);
@@ -581,7 +581,7 @@ void WifiDisplaySource::PlaybackSession::onMessageReceived(
CHECK(msg->findSize("trackIndex", &trackIndex));
if (what == Track::kWhatStopped) {
- ALOGI("Track %d stopped", trackIndex);
+ ALOGI("Track %zu stopped", trackIndex);
sp<Track> track = mTracks.valueFor(trackIndex);
looper()->unregisterHandler(track->id());
@@ -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/PlaybackSession.h b/media/libstagefright/wifi-display/source/PlaybackSession.h
index 2824143..4cd1a75 100644
--- a/media/libstagefright/wifi-display/source/PlaybackSession.h
+++ b/media/libstagefright/wifi-display/source/PlaybackSession.h
@@ -26,7 +26,7 @@ namespace android {
struct ABuffer;
struct IHDCP;
-struct IGraphicBufferProducer;
+class IGraphicBufferProducer;
struct MediaPuller;
struct MediaSource;
struct MediaSender;
diff --git a/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp b/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp
index 14d0951..332fe16 100644
--- a/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp
+++ b/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp
@@ -881,7 +881,7 @@ status_t WifiDisplaySource::onReceiveM3Response(
&framesPerSecond,
&interlaced));
- ALOGI("Picked video resolution %u x %u %c%u",
+ ALOGI("Picked video resolution %zu x %zu %c%zu",
width, height, interlaced ? 'i' : 'p', framesPerSecond);
ALOGI("Picked AVC profile %d, level %d",
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 bb86dfc..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)