Squashed commit of the following:
commit eaeaa2672d4e0a82891493b2bde8bdd0c0e79a1b
Author: Andreas Huber <andih@google.com>
Date: Thu Dec 23 10:26:48 2010 -0800
Remove lowest bandwidth stream if using the legacy player.
Change-Id: I2f885e26344996de9152f8fda9fd6bdef89bf953
commit 7d652972615b2750fd8f1c21b9fab0e136df2b82
Author: Andreas Huber <andih@google.com>
Date: Thu Dec 23 10:14:36 2010 -0800
Don't clear the packet source's format for legacy discontinuities.
Change-Id: I9bd5a21b9bd28043ad38bd0658ccc8eda3c1079a
commit 2b18a45aac17cbfe1aa089d0f6510957d438dd64
Author: Andreas Huber <andih@google.com>
Date: Thu Dec 23 10:13:55 2010 -0800
Use NuPlayer for HTTP live streaming based on runtime property.
adb shell setprop media.httplive.enable-nuplayer true
Change-Id: I22738df3403985dc8e6992b1ab5da5747309f773
commit 50d899fb7b9ea52c3994b0a58e993998d926aeed
Author: Andreas Huber <andih@google.com>
Date: Wed Dec 22 16:25:22 2010 -0800
Make ACodec a lot less verbose.
Change-Id: I94c7e499b61032321ffaf999f5ad2c913cde6a48
commit b19e1740cb4d02990a56844654b5d019987c6405
Author: Andreas Huber <andih@google.com>
Date: Wed Dec 22 16:22:22 2010 -0800
Wait until we have fresh codec-specific-data before instantiating the decoders
after a discontinuity involving a format change.
Change-Id: I7bcf9b5ae3319f08bf8978a117e8ee5220902e37
commit 06428c006906c9099e430aface3b439ff1d36ecc
Author: Andreas Huber <andih@google.com>
Date: Wed Dec 22 15:20:38 2010 -0800
Disable random seeks in the streaming tool for now.
Change-Id: Ie86fde422dcfc4b2c7a01be51a193fda9c88cd71
commit e19db68f3bea8a61c191f60f6940f30e3a0d5f1b
Author: Andreas Huber <andih@google.com>
Date: Wed Dec 22 15:20:27 2010 -0800
Tweak HTTP live parameters.
Change-Id: If4b71e12485facc523a8a43d8213d0feb190daab
commit 1e9942791538c2256b579d96c6c04264b0d8b087
Author: Andreas Huber <andih@google.com>
Date: Wed Dec 22 14:48:23 2010 -0800
Enable http live streaming through NuPlayer for http URLs containing the string m3u8
Change-Id: I1691fe12ae8f1507fe3673313959cd50bc324624
commit 4c33f96a6e499ee0efe0e70b687094430cb7c1c0
Author: Andreas Huber <andih@google.com>
Date: Wed Dec 22 14:40:27 2010 -0800
Support for HTTP live streaming in NuPlayer.
Change-Id: Iacba1c3ebaeb8d3b972185deaf4cff18c8009c54
commit ddf705ce553708bc5b13d89a878484cf839bd674
Author: Andreas Huber <andih@google.com>
Date: Wed Dec 22 13:42:47 2010 -0800
StreamingSource now a subclass of abstract NuPlayer::Source
Change-Id: Ia6c7c639628910b9d1f37decc55da48b07a70de3
commit 9e04a8406b1882a8e3fdeb7b4d52db5ae70b970a
Author: Andreas Huber <andih@google.com>
Date: Wed Dec 22 13:33:52 2010 -0800
Refactor media data sourcing to NuPlayer::Source.
Change-Id: I1db9fb08c4e527bf7b19c29978cf342c2b0a0bc9
Change-Id: I9610a097481dda58f22142eacda3ac2dba0b63f9
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index 967fa49..24efa35 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -19,9 +19,14 @@
#include <utils/Log.h>
#include "NuPlayer.h"
+
+#include "HTTPLiveSource.h"
#include "NuPlayerDecoder.h"
#include "NuPlayerRenderer.h"
-#include "NuPlayerStreamListener.h"
+#include "NuPlayerSource.h"
+#include "StreamingSource.h"
+
+#include "ATSParser.h"
#include <media/stagefright/foundation/hexdump.h>
#include <media/stagefright/foundation/ABuffer.h>
@@ -37,9 +42,9 @@
////////////////////////////////////////////////////////////////////////////////
NuPlayer::NuPlayer()
- : mEOS(false),
- mAudioEOS(false),
+ : mAudioEOS(false),
mVideoEOS(false),
+ mScanSourcesPending(false),
mFlushingAudio(NONE),
mFlushingVideo(NONE) {
}
@@ -54,9 +59,15 @@
void NuPlayer::setDataSource(const sp<IStreamSource> &source) {
sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
- source->incStrong(this);
- msg->setPointer("source", source.get()); // XXX unsafe.
+ msg->setObject("source", new StreamingSource(source));
+ msg->post();
+}
+void NuPlayer::setDataSource(
+ const char *url, const KeyedVector<String8, String8> *headers) {
+ sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
+
+ msg->setObject("source", new HTTPLiveSource(url));
msg->post();
}
@@ -104,14 +115,10 @@
CHECK(mSource == NULL);
- void *ptr;
- CHECK(msg->findPointer("source", &ptr));
+ sp<RefBase> obj;
+ CHECK(msg->findObject("source", &obj));
- mSource = static_cast<IStreamSource *>(ptr);
- mSource->decStrong(this);
-
- mStreamListener = new NuPlayerStreamListener(mSource, id());
- mTSParser = new ATSParser;
+ mSource = static_cast<Source *>(obj.get());
break;
}
@@ -139,7 +146,7 @@
case kWhatStart:
{
- mStreamListener->start();
+ mSource->start();
mRenderer = new Renderer(
mAudioSink,
@@ -148,31 +155,27 @@
looper()->registerHandler(mRenderer);
(new AMessage(kWhatScanSources, id()))->post();
+ mScanSourcesPending = true;
break;
}
case kWhatScanSources:
{
- instantiateDecoder(
- false,
- &mVideoDecoder,
- false /* ignoreCodecSpecificData */);
+ mScanSourcesPending = false;
+
+ instantiateDecoder(false, &mVideoDecoder);
if (mAudioSink != NULL) {
- instantiateDecoder(
- true,
- &mAudioDecoder,
- false /* ignoreCodecSpecificData */);
+ instantiateDecoder(true, &mAudioDecoder);
}
- if (mEOS) {
+ if (!mSource->feedMoreTSData()) {
break;
}
- feedMoreTSData();
-
if (mAudioDecoder == NULL || mVideoDecoder == NULL) {
msg->post(100000ll);
+ mScanSourcesPending = true;
}
break;
}
@@ -192,9 +195,10 @@
status_t err = feedDecoderInputData(
audio, codecRequest);
- if (err == -EWOULDBLOCK && !mEOS) {
- feedMoreTSData();
- msg->post();
+ if (err == -EWOULDBLOCK) {
+ if (mSource->feedMoreTSData()) {
+ msg->post();
+ }
}
} else if (what == ACodec::kWhatEOS) {
mRenderer->queueEOS(audio, ERROR_END_OF_STREAM);
@@ -322,135 +326,37 @@
mRenderer->signalTimeDiscontinuity();
+ bool scanSourcesAgain = false;
+
if (mFlushingAudio == SHUT_DOWN) {
- instantiateDecoder(
- true,
- &mAudioDecoder,
- true /* ignoreCodecSpecificData */);
- CHECK(mAudioDecoder != NULL);
+ scanSourcesAgain = true;
} else if (mAudioDecoder != NULL) {
mAudioDecoder->signalResume();
}
if (mFlushingVideo == SHUT_DOWN) {
- instantiateDecoder(
- false,
- &mVideoDecoder,
- true /* ignoreCodecSpecificData */);
- CHECK(mVideoDecoder != NULL);
+ scanSourcesAgain = true;
} else if (mVideoDecoder != NULL) {
mVideoDecoder->signalResume();
}
mFlushingAudio = NONE;
mFlushingVideo = NONE;
-}
-void NuPlayer::feedMoreTSData() {
- CHECK(!mEOS);
-
- for (int32_t i = 0; i < 10; ++i) {
- char buffer[188];
- ssize_t n = mStreamListener->read(buffer, sizeof(buffer));
-
- if (n == 0) {
- LOGI("input data EOS reached.");
- mTSParser->signalEOS(ERROR_END_OF_STREAM);
- mEOS = true;
- break;
- } else if (n == INFO_DISCONTINUITY) {
- mTSParser->signalDiscontinuity(ATSParser::DISCONTINUITY_SEEK);
- } else if (n < 0) {
- CHECK_EQ(n, -EWOULDBLOCK);
- break;
- } else {
- if (buffer[0] == 0x00) {
- // XXX legacy
- mTSParser->signalDiscontinuity(
- buffer[1] == 0x00
- ? ATSParser::DISCONTINUITY_SEEK
- : ATSParser::DISCONTINUITY_FORMATCHANGE);
- } else {
- mTSParser->feedTSPacket(buffer, sizeof(buffer));
- }
- }
+ if (scanSourcesAgain && !mScanSourcesPending) {
+ mScanSourcesPending = true;
+ (new AMessage(kWhatScanSources, id()))->post();
}
}
-status_t NuPlayer::dequeueNextAccessUnit(
- ATSParser::SourceType *type, sp<ABuffer> *accessUnit) {
- accessUnit->clear();
-
- status_t audioErr = -EWOULDBLOCK;
- int64_t audioTimeUs;
-
- sp<AnotherPacketSource> audioSource =
- static_cast<AnotherPacketSource *>(
- mTSParser->getSource(ATSParser::MPEG2ADTS_AUDIO).get());
-
- if (audioSource != NULL) {
- audioErr = audioSource->nextBufferTime(&audioTimeUs);
- }
-
- status_t videoErr = -EWOULDBLOCK;
- int64_t videoTimeUs;
-
- sp<AnotherPacketSource> videoSource =
- static_cast<AnotherPacketSource *>(
- mTSParser->getSource(ATSParser::AVC_VIDEO).get());
-
- if (videoSource != NULL) {
- videoErr = videoSource->nextBufferTime(&videoTimeUs);
- }
-
- if (audioErr == -EWOULDBLOCK || videoErr == -EWOULDBLOCK) {
- return -EWOULDBLOCK;
- }
-
- if (audioErr != OK && videoErr != OK) {
- return audioErr;
- }
-
- if (videoErr != OK || (audioErr == OK && audioTimeUs < videoTimeUs)) {
- *type = ATSParser::MPEG2ADTS_AUDIO;
- return audioSource->dequeueAccessUnit(accessUnit);
- } else {
- *type = ATSParser::AVC_VIDEO;
- return videoSource->dequeueAccessUnit(accessUnit);
- }
-}
-
-status_t NuPlayer::dequeueAccessUnit(
- ATSParser::SourceType type, sp<ABuffer> *accessUnit) {
- sp<AnotherPacketSource> source =
- static_cast<AnotherPacketSource *>(mTSParser->getSource(type).get());
-
- if (source == NULL) {
- return -EWOULDBLOCK;
- }
-
- status_t finalResult;
- if (!source->hasBufferAvailable(&finalResult)) {
- return finalResult == OK ? -EWOULDBLOCK : finalResult;
- }
-
- return source->dequeueAccessUnit(accessUnit);
-}
-
-status_t NuPlayer::instantiateDecoder(
- bool audio, sp<Decoder> *decoder, bool ignoreCodecSpecificData) {
+status_t NuPlayer::instantiateDecoder(bool audio, sp<Decoder> *decoder) {
if (*decoder != NULL) {
return OK;
}
- ATSParser::SourceType type =
- audio ? ATSParser::MPEG2ADTS_AUDIO : ATSParser::AVC_VIDEO;
+ sp<MetaData> meta = mSource->getFormat(audio);
- sp<AnotherPacketSource> source =
- static_cast<AnotherPacketSource *>(
- mTSParser->getSource(type).get());
-
- if (source == NULL) {
+ if (meta == NULL) {
return -EWOULDBLOCK;
}
@@ -461,8 +367,7 @@
*decoder = new Decoder(notify, audio ? NULL : mSurface);
looper()->registerHandler(*decoder);
- const sp<MetaData> &meta = source->getFormat();
- (*decoder)->configure(meta, ignoreCodecSpecificData);
+ (*decoder)->configure(meta);
return OK;
}
@@ -479,19 +384,17 @@
}
sp<ABuffer> accessUnit;
- status_t err = dequeueAccessUnit(
- audio ? ATSParser::MPEG2ADTS_AUDIO : ATSParser::AVC_VIDEO,
- &accessUnit);
+ status_t err = mSource->dequeueAccessUnit(audio, &accessUnit);
if (err == -EWOULDBLOCK) {
return err;
} else if (err != OK) {
if (err == INFO_DISCONTINUITY) {
- int32_t formatChange;
- if (!accessUnit->meta()->findInt32(
- "format-change", &formatChange)) {
- formatChange = 0;
- }
+ int32_t type;
+ CHECK(accessUnit->meta()->findInt32("discontinuity", &type));
+
+ bool formatChange =
+ type == ATSParser::DISCONTINUITY_FORMATCHANGE;
LOGI("%s discontinuity (formatChange=%d)",
audio ? "audio" : "video", formatChange);