summaryrefslogtreecommitdiffstats
path: root/media/libmediaplayerservice
diff options
context:
space:
mode:
Diffstat (limited to 'media/libmediaplayerservice')
-rw-r--r--media/libmediaplayerservice/MediaPlayerService.cpp13
-rw-r--r--media/libmediaplayerservice/MediaPlayerService.h1
-rw-r--r--media/libmediaplayerservice/MetadataRetrieverClient.cpp1
-rw-r--r--media/libmediaplayerservice/StagefrightRecorder.cpp4
-rw-r--r--media/libmediaplayerservice/nuplayer/GenericSource.cpp34
-rw-r--r--media/libmediaplayerservice/nuplayer/GenericSource.h2
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayer.cpp8
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayer.h2
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerCCDecoder.cpp6
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp43
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h5
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerStreamListener.cpp11
-rw-r--r--media/libmediaplayerservice/nuplayer/RTSPSource.cpp32
-rw-r--r--media/libmediaplayerservice/nuplayer/RTSPSource.h4
-rw-r--r--media/libmediaplayerservice/nuplayer/StreamingSource.cpp2
15 files changed, 123 insertions, 45 deletions
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 1e911c2..61afe99 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -237,7 +237,8 @@ void unmarshallAudioAttributes(const Parcel& parcel, audio_attributes_t *attribu
// copying array size -1, array for tags was calloc'd, no need to NULL-terminate it
size_t tagSize = realTagSize > AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - 1 ?
AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - 1 : realTagSize;
- utf16_to_utf8(tags.string(), tagSize, attributes->tags);
+ utf16_to_utf8(tags.string(), tagSize, attributes->tags,
+ sizeof(attributes->tags) / sizeof(attributes->tags[0]));
}
} else {
ALOGE("unmarshallAudioAttributes() received unflattened tags, ignoring tag values");
@@ -558,6 +559,12 @@ void MediaPlayerService::removeClient(wp<Client> client)
mClients.remove(client);
}
+bool MediaPlayerService::hasClient(wp<Client> client)
+{
+ Mutex::Autolock lock(mLock);
+ return mClients.indexOf(client) != NAME_NOT_FOUND;
+}
+
MediaPlayerService::Client::Client(
const sp<MediaPlayerService>& service, pid_t pid,
int32_t connId, const sp<IMediaPlayerClient>& client,
@@ -1054,6 +1061,10 @@ status_t MediaPlayerService::Client::setNextPlayer(const sp<IMediaPlayer>& playe
ALOGV("setNextPlayer");
Mutex::Autolock l(mLock);
sp<Client> c = static_cast<Client*>(player.get());
+ if (c != NULL && !mService->hasClient(c)) {
+ return BAD_VALUE;
+ }
+
mNextClient = c;
if (c != NULL) {
diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h
index ff8f550..2bd7ec5 100644
--- a/media/libmediaplayerservice/MediaPlayerService.h
+++ b/media/libmediaplayerservice/MediaPlayerService.h
@@ -227,6 +227,7 @@ public:
virtual status_t dump(int fd, const Vector<String16>& args);
void removeClient(wp<Client> client);
+ bool hasClient(wp<Client> client);
// For battery usage tracking purpose
struct BatteryUsageInfo {
diff --git a/media/libmediaplayerservice/MetadataRetrieverClient.cpp b/media/libmediaplayerservice/MetadataRetrieverClient.cpp
index 7bd99cc..f725b90 100644
--- a/media/libmediaplayerservice/MetadataRetrieverClient.cpp
+++ b/media/libmediaplayerservice/MetadataRetrieverClient.cpp
@@ -228,6 +228,7 @@ sp<IMemory> MetadataRetrieverClient::getFrameAtTime(int64_t timeUs, int option)
ALOGV("rotation: %d", frameCopy->mRotationAngle);
frameCopy->mData = (uint8_t *)frameCopy + sizeof(VideoFrame);
memcpy(frameCopy->mData, frame->mData, frame->mSize);
+ frameCopy->mData = 0;
delete frame; // Fix memory leakage
return mThumbnail;
}
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index d182a68..442dba1 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -1743,7 +1743,7 @@ status_t StagefrightRecorder::setupMPEG4orWEBMRecording() {
if (mOutputFormat == OUTPUT_FORMAT_WEBM) {
writer = new WebmWriter(mOutputFd);
} else {
- writer = mp4writer = new MPEG4Writer(mOutputFd);
+ writer = mp4writer = AVFactory::get()->CreateMPEG4Writer(mOutputFd);
}
if (mVideoSource < VIDEO_SOURCE_LIST_END) {
@@ -1814,6 +1814,8 @@ status_t StagefrightRecorder::setupMPEG4orWEBMRecording() {
void StagefrightRecorder::setupMPEG4orWEBMMetaData(sp<MetaData> *meta) {
int64_t startTimeUs = systemTime() / 1000;
(*meta)->setInt64(kKeyTime, startTimeUs);
+ int64_t startTimeBootUs = systemTime(SYSTEM_TIME_BOOTTIME) / 1000;
+ (*meta)->setInt64(kKeyTimeBoot, startTimeBootUs);
(*meta)->setInt32(kKeyFileType, mOutputFormat);
(*meta)->setInt32(kKeyBitRate, mTotalBitRate);
if (mMovieTimeScale > 0) {
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
index beda8bd..949c12f 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
@@ -232,6 +232,9 @@ status_t NuPlayer::GenericSource::initFromDataSource() {
for (size_t i = 0; i < numtracks; ++i) {
sp<MediaSource> track = extractor->getTrack(i);
+ if (track == NULL) {
+ continue;
+ }
sp<MetaData> meta = extractor->getTrackMetaData(i);
@@ -274,24 +277,27 @@ status_t NuPlayer::GenericSource::initFromDataSource() {
}
}
- if (track != NULL) {
- mSources.push(track);
- int64_t durationUs;
- if (meta->findInt64(kKeyDuration, &durationUs)) {
- if (durationUs > mDurationUs) {
- mDurationUs = durationUs;
- }
+ mSources.push(track);
+ int64_t durationUs;
+ if (meta->findInt64(kKeyDuration, &durationUs)) {
+ if (durationUs > mDurationUs) {
+ mDurationUs = durationUs;
}
+ }
- int32_t bitrate;
- if (totalBitrate >= 0 && meta->findInt32(kKeyBitRate, &bitrate)) {
- totalBitrate += bitrate;
- } else {
- totalBitrate = -1;
- }
+ int32_t bitrate;
+ if (totalBitrate >= 0 && meta->findInt32(kKeyBitRate, &bitrate)) {
+ totalBitrate += bitrate;
+ } else {
+ totalBitrate = -1;
}
}
+ if (mSources.size() == 0) {
+ ALOGE("b/23705695");
+ return UNKNOWN_ERROR;
+ }
+
mBitrate = totalBitrate;
return OK;
@@ -339,7 +345,7 @@ int64_t NuPlayer::GenericSource::getLastReadPosition() {
status_t NuPlayer::GenericSource::setBuffers(
bool audio, Vector<MediaBuffer *> &buffers) {
- if ((mIsSecure || mUseSetBuffers) && !audio) {
+ if (mIsSecure && !audio && mVideoTrack.mSource != NULL) {
return mVideoTrack.mSource->setBuffers(buffers);
}
return INVALID_OPERATION;
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.h b/media/libmediaplayerservice/nuplayer/GenericSource.h
index 9f8556e..5deb61e 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.h
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.h
@@ -42,7 +42,7 @@ class WVMExtractor;
struct NuPlayer::GenericSource : public NuPlayer::Source {
GenericSource(const sp<AMessage> &notify, bool uidValid, uid_t uid);
- virtual status_t setDataSource(
+ status_t setDataSource(
const sp<IMediaHTTPService> &httpService,
const char *url,
const KeyedVector<String8, String8> *headers);
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index 1835101..ef2e6ec 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -681,10 +681,9 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
// If the video decoder is not set (perhaps audio only in this case)
// do not perform a seek as it is not needed.
int64_t currentPositionUs = 0;
- if (getCurrentPosition(&currentPositionUs) == OK) {
- mDeferredActions.push_back(
- new SeekAction(currentPositionUs));
- }
+ getCurrentPosition(&currentPositionUs);
+ mDeferredActions.push_back(
+ new SeekAction(currentPositionUs));
}
// If there is a new surface texture, instantiate decoders
@@ -1157,6 +1156,7 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
mRenderer->flush(
false /* audio */, false /* notifyComplete */);
}
+ mRenderer->signalAudioTearDownComplete();
int64_t positionUs;
if (!msg->findInt64("positionUs", &positionUs)) {
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h
index 1c51c4b..725a1b2 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h
@@ -247,7 +247,7 @@ protected:
void finishFlushIfPossible();
void onStart(int64_t startPositionUs = -1);
- void onResume();
+ virtual void onResume();
void onPause();
bool audioDecoderStillNeeded();
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerCCDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerCCDecoder.cpp
index ac3c6b6..2c07f28 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerCCDecoder.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerCCDecoder.cpp
@@ -235,6 +235,12 @@ bool NuPlayer::CCDecoder::parseSEINalUnit(
payload_size += last_byte;
} while (last_byte == 0xFF);
+ if (payload_size > SIZE_MAX / 8
+ || !br.atLeastNumBitsLeft(payload_size * 8)) {
+ ALOGV("Malformed SEI payload");
+ break;
+ }
+
// sei_payload()
if (payload_type == 4) {
bool isCC = false;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index 2336eb7..8afdefe 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -127,7 +127,7 @@ NuPlayer::Renderer::Renderer(
mAudioRenderingStartGeneration(0),
mRenderingDataDelivered(false),
mAudioOffloadPauseTimeoutGeneration(0),
- mAudioTornDown(false),
+ mAudioTearingDown(false),
mCurrentOffloadInfo(AUDIO_INFO_INITIALIZER),
mCurrentPcmInfo(AUDIO_PCMINFO_INITIALIZER),
mTotalBuffersQueued(0),
@@ -626,6 +626,12 @@ void NuPlayer::Renderer::onMessageReceived(const sp<AMessage> &msg) {
break;
}
+ case kWhatAudioTearDownComplete:
+ {
+ onAudioTearDownComplete();
+ break;
+ }
+
case kWhatAudioOffloadPauseTimeout:
{
int32_t generation;
@@ -780,6 +786,7 @@ size_t NuPlayer::Renderer::fillAudioBuffer(void *buffer, size_t size) {
mAudioFirstAnchorTimeMediaUs + getPlayedOutAudioDurationUs(nowUs);
// we don't know how much data we are queueing for offloaded tracks.
mMediaClock->updateAnchor(nowMediaUs, nowUs, INT64_MAX);
+ mAnchorTimeMediaUs = nowMediaUs;
}
// for non-offloaded audio, we need to compute the frames written because
@@ -836,7 +843,7 @@ void NuPlayer::Renderer::drainAudioQueueUntilLastEOS() {
bool NuPlayer::Renderer::onDrainAudioQueue() {
// do not drain audio during teardown as queued buffers may be invalid.
- if (mAudioTornDown) {
+ if (mAudioTearingDown) {
return false;
}
// TODO: This call to getPosition checks if AudioTrack has been created
@@ -850,18 +857,6 @@ bool NuPlayer::Renderer::onDrainAudioQueue() {
// immediately after start. Investigate error message
// "vorbis_dsp_synthesis returned -135", along with RTSP.
uint32_t numFramesPlayed;
- if(!mAudioSink->ready() && !mAudioQueue.empty()) {
- while (!mAudioQueue.empty()) {
- QueueEntry *entry = &*mAudioQueue.begin();
- if (entry->mBuffer == NULL) {
- notifyEOS(true /* audio */, entry->mFinalResult);
- }
- mAudioQueue.erase(mAudioQueue.begin());
- entry = NULL;
- }
- return false;
- }
-
if (mAudioSink->getPosition(&numFramesPlayed) != OK) {
// When getPosition fails, renderer will not reschedule the draining
// unless new samples are queued.
@@ -1591,7 +1586,7 @@ void NuPlayer::Renderer::onResume() {
notifyAudioTearDown();
}
//Update anchor time after resuming playback.
- if (offloadingAudio()) {
+ if (offloadingAudio() && status == NO_ERROR) {
int64_t nowUs = ALooper::GetNowUs();
int64_t nowMediaUs =
mAudioFirstAnchorTimeMediaUs + getPlayedOutAudioDurationUs(nowUs);
@@ -1717,10 +1712,10 @@ int64_t NuPlayer::Renderer::getPlayedOutAudioDurationUs(int64_t nowUs) {
}
void NuPlayer::Renderer::onAudioTearDown(AudioTearDownReason reason) {
- if (mAudioTornDown) {
+ if (mAudioTearingDown) {
return;
}
- mAudioTornDown = true;
+ mAudioTearingDown = true;
int64_t currentPositionUs;
sp<AMessage> notify = mNotify->dup();
@@ -1760,6 +1755,11 @@ status_t NuPlayer::Renderer::onOpenAudioSink(
bool isStreaming) {
ALOGV("openAudioSink: offloadOnly(%d) offloadingAudio(%d)",
offloadOnly, offloadingAudio());
+
+ if (mAudioTearingDown) {
+ ALOGW("openAudioSink: not opening now!, would happen after teardown");
+ return OK;
+ }
bool audioSinkChanged = false;
int32_t numChannels;
@@ -1957,7 +1957,6 @@ status_t NuPlayer::Renderer::onOpenAudioSink(
if (audioSinkChanged) {
onAudioSinkChanged();
}
- mAudioTornDown = false;
return OK;
}
@@ -1967,5 +1966,13 @@ void NuPlayer::Renderer::onCloseAudioSink() {
mCurrentPcmInfo = AUDIO_PCMINFO_INITIALIZER;
}
+void NuPlayer::Renderer::signalAudioTearDownComplete() {
+ (new AMessage(kWhatAudioTearDownComplete, this))->post();
+}
+
+void NuPlayer::Renderer::onAudioTearDownComplete() {
+ mAudioTearingDown = false;
+}
+
} // namespace android
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
index e872227..a84e673 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
@@ -83,6 +83,7 @@ struct NuPlayer::Renderer : public AHandler {
bool *isOffloaded,
bool isStreaming);
void closeAudioSink();
+ void signalAudioTearDownComplete();
enum {
kWhatEOS = 'eos ',
@@ -92,6 +93,7 @@ struct NuPlayer::Renderer : public AHandler {
kWhatMediaRenderingStart = 'mdrd',
kWhatAudioTearDown = 'adTD',
kWhatAudioOffloadPauseTimeout = 'aOPT',
+ kWhatAudioTearDownComplete = 'aTDC',
};
enum AudioTearDownReason {
@@ -184,7 +186,7 @@ protected:
int64_t mLastPositionUpdateUs;
int32_t mAudioOffloadPauseTimeoutGeneration;
- bool mAudioTornDown;
+ bool mAudioTearingDown;
audio_offload_info_t mCurrentOffloadInfo;
struct PcmInfo {
@@ -257,6 +259,7 @@ protected:
uint32_t flags,
bool isStreaming);
void onCloseAudioSink();
+ void onAudioTearDownComplete();
void notifyEOS(bool audio, status_t finalResult, int64_t delayUs = 0);
void notifyFlushComplete(bool audio);
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerStreamListener.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerStreamListener.cpp
index f53afbd..ee70306 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerStreamListener.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerStreamListener.cpp
@@ -144,8 +144,17 @@ ssize_t NuPlayer::NuPlayerStreamListener::read(
copy = size;
}
+ if (entry->mIndex >= mBuffers.size()) {
+ return ERROR_MALFORMED;
+ }
+
+ sp<IMemory> mem = mBuffers.editItemAt(entry->mIndex);
+ if (mem == NULL || mem->size() < copy || mem->size() - copy < entry->mOffset) {
+ return ERROR_MALFORMED;
+ }
+
memcpy(data,
- (const uint8_t *)mBuffers.editItemAt(entry->mIndex)->pointer()
+ (const uint8_t *)mem->pointer()
+ entry->mOffset,
copy);
diff --git a/media/libmediaplayerservice/nuplayer/RTSPSource.cpp b/media/libmediaplayerservice/nuplayer/RTSPSource.cpp
index 35567a5..4962520 100644
--- a/media/libmediaplayerservice/nuplayer/RTSPSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/RTSPSource.cpp
@@ -24,6 +24,7 @@
#include "MyHandler.h"
#include "SDPLoader.h"
+#include <cutils/properties.h>
#include <media/IMediaHTTPService.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MetaData.h>
@@ -32,6 +33,7 @@
namespace android {
const int64_t kNearEOSTimeoutUs = 2000000ll; // 2 secs
+const uint32_t kMaxNumKeepDamagedAccessUnits = 30;
NuPlayer::RTSPSource::RTSPSource(
const sp<AMessage> &notify,
@@ -54,7 +56,10 @@ NuPlayer::RTSPSource::RTSPSource(
mBuffering(false),
mSeekGeneration(0),
mEOSTimeoutAudio(0),
- mEOSTimeoutVideo(0) {
+ mEOSTimeoutVideo(0),
+ mVideoTrackIndex(-1),
+ mKeepDamagedAccessUnits(false),
+ mNumKeepDamagedAccessUnits(0) {
if (headers) {
mExtraHeaders = *headers;
@@ -433,11 +438,22 @@ void NuPlayer::RTSPSource::onMessageReceived(const sp<AMessage> &msg) {
sp<ABuffer> accessUnit;
CHECK(msg->findBuffer("accessUnit", &accessUnit));
+ bool isVideo = trackIndex == (size_t)mVideoTrackIndex;
int32_t damaged;
if (accessUnit->meta()->findInt32("damaged", &damaged)
&& damaged) {
- ALOGI("dropping damaged access unit.");
- break;
+ if (isVideo && mKeepDamagedAccessUnits
+ && mNumKeepDamagedAccessUnits < kMaxNumKeepDamagedAccessUnits) {
+ ALOGI("keep a damaged access unit.");
+ ++mNumKeepDamagedAccessUnits;
+ } else {
+ ALOGI("dropping damaged access unit.");
+ break;
+ }
+ } else {
+ if (isVideo) {
+ mNumKeepDamagedAccessUnits = 0;
+ }
}
if (mTSParser != NULL) {
@@ -613,6 +629,16 @@ void NuPlayer::RTSPSource::onConnected() {
bool isAudio = !strncasecmp(mime, "audio/", 6);
bool isVideo = !strncasecmp(mime, "video/", 6);
+ if (isVideo) {
+ mVideoTrackIndex = i;
+ char value[PROPERTY_VALUE_MAX];
+ if (property_get("rtsp.video.keep-damaged-au", value, NULL)
+ && !strcasecmp(mime, value)) {
+ ALOGV("enable to keep damaged au for %s", mime);
+ mKeepDamagedAccessUnits = true;
+ }
+ }
+
TrackInfo info;
info.mTimeScale = timeScale;
info.mRTPTime = 0;
diff --git a/media/libmediaplayerservice/nuplayer/RTSPSource.h b/media/libmediaplayerservice/nuplayer/RTSPSource.h
index 6438a1e..c431174 100644
--- a/media/libmediaplayerservice/nuplayer/RTSPSource.h
+++ b/media/libmediaplayerservice/nuplayer/RTSPSource.h
@@ -118,6 +118,10 @@ private:
sp<AReplyToken> mSeekReplyID;
+ int32_t mVideoTrackIndex;
+ bool mKeepDamagedAccessUnits;
+ uint32_t mNumKeepDamagedAccessUnits;
+
sp<AnotherPacketSource> getSource(bool audio);
void onConnected();
diff --git a/media/libmediaplayerservice/nuplayer/StreamingSource.cpp b/media/libmediaplayerservice/nuplayer/StreamingSource.cpp
index 136eda5..b9c915e 100644
--- a/media/libmediaplayerservice/nuplayer/StreamingSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/StreamingSource.cpp
@@ -18,6 +18,8 @@
#define LOG_TAG "StreamingSource"
#include <utils/Log.h>
+#include <inttypes.h>
+
#include "StreamingSource.h"
#include "ATSParser.h"