summaryrefslogtreecommitdiffstats
path: root/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'media/libmediaplayerservice/nuplayer/NuPlayer.cpp')
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayer.cpp193
1 files changed, 48 insertions, 145 deletions
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 @@ namespace android {
////////////////////////////////////////////////////////////////////////////////
NuPlayer::NuPlayer()
- : mEOS(false),
- mAudioEOS(false),
+ : mAudioEOS(false),
mVideoEOS(false),
+ mScanSourcesPending(false),
mFlushingAudio(NONE),
mFlushingVideo(NONE) {
}
@@ -54,9 +59,15 @@ void NuPlayer::setListener(const wp<MediaPlayerBase> &listener) {
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 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
CHECK(mSource == NULL);
- void *ptr;
- CHECK(msg->findPointer("source", &ptr));
-
- mSource = static_cast<IStreamSource *>(ptr);
- mSource->decStrong(this);
+ sp<RefBase> obj;
+ CHECK(msg->findObject("source", &obj));
- mStreamListener = new NuPlayerStreamListener(mSource, id());
- mTSParser = new ATSParser;
+ mSource = static_cast<Source *>(obj.get());
break;
}
@@ -139,7 +146,7 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
case kWhatStart:
{
- mStreamListener->start();
+ mSource->start();
mRenderer = new Renderer(
mAudioSink,
@@ -148,31 +155,27 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
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 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
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 @@ void NuPlayer::finishFlushIfPossible() {
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));
- }
- }
- }
-}
-
-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;
+ if (scanSourcesAgain && !mScanSourcesPending) {
+ mScanSourcesPending = true;
+ (new AMessage(kWhatScanSources, id()))->post();
}
-
- 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 @@ status_t NuPlayer::instantiateDecoder(
*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 @@ status_t NuPlayer::feedDecoderInputData(bool audio, const sp<AMessage> &msg) {
}
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);