summaryrefslogtreecommitdiffstats
path: root/media/libmediaplayerservice
diff options
context:
space:
mode:
Diffstat (limited to 'media/libmediaplayerservice')
-rw-r--r--media/libmediaplayerservice/StagefrightRecorder.cpp4
-rw-r--r--media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp6
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayer.cpp66
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayer.h3
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp5
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp18
6 files changed, 98 insertions, 4 deletions
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index 136e6cf..80d5ac2 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -1465,13 +1465,13 @@ status_t StagefrightRecorder::setupCameraSource(
return BAD_VALUE;
}
- mCameraSourceTimeLapse = CameraSourceTimeLapse::CreateFromCamera(
+ mCameraSourceTimeLapse = AVFactory::get()->CreateCameraSourceTimeLapseFromCamera(
mCamera, mCameraProxy, mCameraId, mClientName, mClientUid,
videoSize, mFrameRate, mPreviewSurface,
mTimeBetweenCaptureUs);
*cameraSource = mCameraSourceTimeLapse;
} else {
- *cameraSource = AVFactory::get()->CreateFromCamera(
+ *cameraSource = AVFactory::get()->CreateCameraSourceFromCamera(
mCamera, mCameraProxy, mCameraId, mClientName, mClientUid,
videoSize, mFrameRate,
mPreviewSurface);
diff --git a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp
index 6683481..a57fdc1 100644
--- a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp
@@ -212,7 +212,11 @@ status_t NuPlayer::HTTPLiveSource::selectTrack(size_t trackIndex, bool select, i
}
status_t NuPlayer::HTTPLiveSource::seekTo(int64_t seekTimeUs) {
- return mLiveSession->seekTo(seekTimeUs);
+ if (mLiveSession->isSeekable()) {
+ return mLiveSession->seekTo(seekTimeUs);
+ } else {
+ return INVALID_OPERATION;
+ }
}
void NuPlayer::HTTPLiveSource::pollForRawData(
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index 86c35e2..356c519 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -131,6 +131,23 @@ private:
DISALLOW_EVIL_CONSTRUCTORS(FlushDecoderAction);
};
+struct NuPlayer::InstantiateDecoderAction : public Action {
+ InstantiateDecoderAction(bool audio, sp<DecoderBase> *decoder)
+ : mAudio(audio),
+ mdecoder(decoder) {
+ }
+
+ virtual void execute(NuPlayer *player) {
+ player->instantiateDecoder(mAudio, mdecoder);
+ }
+
+private:
+ bool mAudio;
+ sp<DecoderBase> *mdecoder;
+
+ DISALLOW_EVIL_CONSTRUCTORS(InstantiateDecoderAction);
+};
+
struct NuPlayer::PostMessageAction : public Action {
PostMessageAction(const sp<AMessage> &msg)
: mMessage(msg) {
@@ -226,7 +243,7 @@ bool NuPlayer::IsHTTPLiveURL(const char *url) {
return true;
}
- if (strstr(url,"m3u8")) {
+ if (strstr(url,".m3u8")) {
return true;
}
}
@@ -1093,6 +1110,12 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
int32_t reason;
CHECK(msg->findInt32("reason", &reason));
ALOGV("Tear down audio with reason %d.", reason);
+
+ if (ifDecodedPCMOffload()) {
+ tearDownPCMOffload(msg);
+ break;
+ }
+
mAudioDecoder.clear();
++mAudioDecoderGeneration;
bool needsToCreateAudioDecoder = true;
@@ -2384,4 +2407,45 @@ void NuPlayer::Source::onMessageReceived(const sp<AMessage> & /* msg */) {
TRESPASS();
}
+void NuPlayer::tearDownPCMOffload(const sp<AMessage> &msg) {
+ int32_t reason;
+ CHECK(msg->findInt32("reason", &reason));
+
+ if (mAudioDecoder != NULL) {
+ switch (mFlushingAudio) {
+ case NONE:
+ case FLUSHING_DECODER:
+ mDeferredActions.push_back(
+ new FlushDecoderAction(FLUSH_CMD_SHUTDOWN /* audio */,
+ FLUSH_CMD_NONE /* video */));
+
+ if (reason == Renderer::kDueToError) {
+ mDeferredActions.push_back(
+ new InstantiateDecoderAction(true /* audio */, &mAudioDecoder));
+ }
+
+ int64_t positionUs;
+ if (!msg->findInt64("positionUs", &positionUs)) {
+ positionUs = mPreviousSeekTimeUs;
+ }
+ mDeferredActions.push_back(new SeekAction(positionUs));
+ break;
+ default:
+ ALOGW("tearDownPCMOffload while flushing audio in %d", mFlushingAudio);
+ break;
+ }
+ }
+
+ if (mRenderer != NULL) {
+ closeAudioSink();
+ mRenderer->flush(
+ true /* audio */, false /* notifyComplete */);
+ if (mVideoDecoder != NULL) {
+ mRenderer->flush(
+ false /* audio */, false /* notifyComplete */);
+ }
+ }
+ processDeferredActions();
+}
+
} // namespace android
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h
index 4ed3079..c0aa782 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h
@@ -109,6 +109,7 @@ public:
struct SetSurfaceAction;
struct ResumeDecoderAction;
struct FlushDecoderAction;
+ struct InstantiateDecoderAction;
struct PostMessageAction;
struct SimpleAction;
@@ -279,6 +280,8 @@ protected:
void writeTrackInfo(Parcel* reply, const sp<AMessage> format) const;
+ void tearDownPCMOffload(const sp<AMessage> &msg);
+
DISALLOW_EVIL_CONSTRUCTORS(NuPlayer);
};
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
index 27650d7..f83eaf6 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
@@ -565,6 +565,11 @@ bool NuPlayer::Decoder::handleAnOutputBuffer(
sp<ABuffer> buffer;
mCodec->getOutputBuffer(index, &buffer);
+ if (buffer == NULL) {
+ handleError(UNKNOWN_ERROR);
+ return false;
+ }
+
if (index >= mOutputBuffers.size()) {
for (size_t i = mOutputBuffers.size(); i <= index; ++i) {
mOutputBuffers.add();
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index aa993a9..9d2f134 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -83,6 +83,16 @@ const NuPlayer::Renderer::PcmInfo NuPlayer::Renderer::AUDIO_PCMINFO_INITIALIZER
// static
const int64_t NuPlayer::Renderer::kMinPositionUpdateDelayUs = 100000ll;
+static bool sFrameAccurateAVsync = false;
+
+static void readProperties() {
+ char value[PROPERTY_VALUE_MAX];
+ if (property_get("persist.sys.media.avsync", value, NULL)) {
+ sFrameAccurateAVsync =
+ !strcmp("1", value) || !strcasecmp("true", value);
+ }
+}
+
NuPlayer::Renderer::Renderer(
const sp<MediaPlayerBase::AudioSink> &sink,
const sp<AMessage> &notify,
@@ -124,6 +134,7 @@ NuPlayer::Renderer::Renderer(
mMediaClock = new MediaClock;
mPlaybackRate = mPlaybackSettings.mSpeed;
mMediaClock->setPlaybackRate(mPlaybackRate);
+ readProperties();
}
NuPlayer::Renderer::~Renderer() {
@@ -1065,6 +1076,11 @@ void NuPlayer::Renderer::postDrainVideoQueue() {
ALOGW_IF(delayUs > 500000, "unusually high delayUs: %" PRId64, delayUs);
// post 2 display refreshes before rendering is due
+ // FIXME currently this increases power consumption, so unless frame-accurate
+ // AV sync is requested, post closer to required render time (at 0.63 vsyncs)
+ if (!sFrameAccurateAVsync) {
+ twoVsyncsUs >>= 4;
+ }
msg->post(delayUs > twoVsyncsUs ? delayUs - twoVsyncsUs : 0);
mDrainVideoQueuePending = true;
@@ -1477,6 +1493,8 @@ void NuPlayer::Renderer::onPause() {
}
void NuPlayer::Renderer::onResume() {
+ readProperties();
+
if (!mPaused) {
return;
}