am 05aa0827: Merge "Some tweaks to HTTP live / nuplayer behaviour" into honeycomb
* commit '05aa082770d812c5921d6b2f9b3559f1fd1536a8': Some tweaks to HTTP live / nuplayer behaviour
This commit is contained in:
@@ -75,7 +75,10 @@ MAKE_COMPARATOR(GT,>)
|
||||
#define CHECK_GE(x,y) CHECK_OP(x,y,GE,>=)
|
||||
#define CHECK_GT(x,y) CHECK_OP(x,y,GT,>)
|
||||
|
||||
#define TRESPASS() LOG_ALWAYS_FATAL("Should not be here.")
|
||||
#define TRESPASS() \
|
||||
LOG_ALWAYS_FATAL( \
|
||||
__FILE__ ":" LITERAL_TO_STRING(__LINE__) \
|
||||
" Should not be here.");
|
||||
|
||||
} // namespace android
|
||||
|
||||
|
||||
@@ -40,9 +40,9 @@ NuPlayer::Renderer::Renderer(
|
||||
mAnchorTimeRealUs(-1),
|
||||
mFlushingAudio(false),
|
||||
mFlushingVideo(false),
|
||||
mHasAudio(mAudioSink != NULL),
|
||||
mHasVideo(true),
|
||||
mSyncQueues(mHasAudio && mHasVideo),
|
||||
mHasAudio(false),
|
||||
mHasVideo(false),
|
||||
mSyncQueues(false),
|
||||
mPaused(false) {
|
||||
}
|
||||
|
||||
@@ -360,6 +360,12 @@ void NuPlayer::Renderer::onQueueBuffer(const sp<AMessage> &msg) {
|
||||
int32_t audio;
|
||||
CHECK(msg->findInt32("audio", &audio));
|
||||
|
||||
if (audio) {
|
||||
mHasAudio = true;
|
||||
} else {
|
||||
mHasVideo = true;
|
||||
}
|
||||
|
||||
if (dropBufferWhileFlushing(audio, msg)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -506,8 +506,21 @@ rinse_repeat:
|
||||
|
||||
LOGE("This doesn't look like a transport stream...");
|
||||
|
||||
mDataSource->queueEOS(ERROR_UNSUPPORTED);
|
||||
return;
|
||||
mBandwidthItems.removeAt(bandwidthIndex);
|
||||
|
||||
if (mBandwidthItems.isEmpty()) {
|
||||
mDataSource->queueEOS(ERROR_UNSUPPORTED);
|
||||
return;
|
||||
}
|
||||
|
||||
LOGI("Retrying with a different bandwidth stream.");
|
||||
|
||||
mLastPlaylistFetchTimeUs = -1;
|
||||
bandwidthIndex = getBandwidthIndex();
|
||||
mPrevBandwidthIndex = bandwidthIndex;
|
||||
mSeqNumber = -1;
|
||||
|
||||
goto rinse_repeat;
|
||||
}
|
||||
|
||||
if ((size_t)mPrevBandwidthIndex != bandwidthIndex) {
|
||||
|
||||
@@ -75,6 +75,10 @@ private:
|
||||
struct ATSParser::Stream : public RefBase {
|
||||
Stream(Program *program, unsigned elementaryPID, unsigned streamType);
|
||||
|
||||
unsigned type() const { return mStreamType; }
|
||||
unsigned pid() const { return mElementaryPID; }
|
||||
void setPID(unsigned pid) { mElementaryPID = pid; }
|
||||
|
||||
void parse(
|
||||
unsigned payload_unit_start_indicator,
|
||||
ABitReader *br);
|
||||
@@ -95,6 +99,7 @@ private:
|
||||
sp<ABuffer> mBuffer;
|
||||
sp<AnotherPacketSource> mSource;
|
||||
bool mPayloadStarted;
|
||||
DiscontinuityType mPendingDiscontinuity;
|
||||
|
||||
ElementaryStreamQueue mQueue;
|
||||
|
||||
@@ -107,6 +112,8 @@ private:
|
||||
|
||||
void extractAACFrames(const sp<ABuffer> &buffer);
|
||||
|
||||
void deferDiscontinuity(DiscontinuityType type);
|
||||
|
||||
DISALLOW_EVIL_CONSTRUCTORS(Stream);
|
||||
};
|
||||
|
||||
@@ -155,6 +162,11 @@ void ATSParser::Program::signalEOS(status_t finalResult) {
|
||||
}
|
||||
}
|
||||
|
||||
struct StreamInfo {
|
||||
unsigned mType;
|
||||
unsigned mPID;
|
||||
};
|
||||
|
||||
void ATSParser::Program::parseProgramMap(ABitReader *br) {
|
||||
unsigned table_id = br->getBits(8);
|
||||
LOGV(" table_id = %u", table_id);
|
||||
@@ -188,6 +200,8 @@ void ATSParser::Program::parseProgramMap(ABitReader *br) {
|
||||
|
||||
br->skipBits(program_info_length * 8); // skip descriptors
|
||||
|
||||
Vector<StreamInfo> infos;
|
||||
|
||||
// infoBytesRemaining is the number of bytes that make up the
|
||||
// variable length section of ES_infos. It does not include the
|
||||
// final CRC.
|
||||
@@ -231,24 +245,48 @@ void ATSParser::Program::parseProgramMap(ABitReader *br) {
|
||||
CHECK_EQ(info_bytes_remaining, 0u);
|
||||
#endif
|
||||
|
||||
ssize_t index = mStreams.indexOfKey(elementaryPID);
|
||||
#if 0 // XXX revisit
|
||||
CHECK_LT(index, 0);
|
||||
mStreams.add(elementaryPID,
|
||||
new Stream(this, elementaryPID, streamType));
|
||||
#else
|
||||
if (index < 0) {
|
||||
mStreams.add(elementaryPID,
|
||||
new Stream(this, elementaryPID, streamType));
|
||||
}
|
||||
#endif
|
||||
StreamInfo info;
|
||||
info.mType = streamType;
|
||||
info.mPID = elementaryPID;
|
||||
infos.push(info);
|
||||
|
||||
infoBytesRemaining -= 5 + ES_info_length;
|
||||
}
|
||||
|
||||
CHECK_EQ(infoBytesRemaining, 0u);
|
||||
|
||||
MY_LOGV(" CRC = 0x%08x", br->getBits(32));
|
||||
|
||||
bool PIDsChanged = false;
|
||||
for (size_t i = 0; i < infos.size(); ++i) {
|
||||
StreamInfo &info = infos.editItemAt(i);
|
||||
|
||||
ssize_t index = mStreams.indexOfKey(info.mPID);
|
||||
|
||||
if (index >= 0 && mStreams.editValueAt(index)->type() != info.mType) {
|
||||
LOGI("uh oh. stream PIDs have changed.");
|
||||
PIDsChanged = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (PIDsChanged) {
|
||||
mStreams.clear();
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < infos.size(); ++i) {
|
||||
StreamInfo &info = infos.editItemAt(i);
|
||||
|
||||
ssize_t index = mStreams.indexOfKey(info.mPID);
|
||||
|
||||
if (index < 0) {
|
||||
sp<Stream> stream = new Stream(this, info.mPID, info.mType);
|
||||
mStreams.add(info.mPID, stream);
|
||||
|
||||
if (PIDsChanged) {
|
||||
stream->signalDiscontinuity(DISCONTINUITY_FORMATCHANGE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sp<MediaSource> ATSParser::Program::getSource(SourceType type) {
|
||||
@@ -290,6 +328,7 @@ ATSParser::Stream::Stream(
|
||||
mStreamType(streamType),
|
||||
mBuffer(new ABuffer(192 * 1024)),
|
||||
mPayloadStarted(false),
|
||||
mPendingDiscontinuity(DISCONTINUITY_NONE),
|
||||
mQueue(streamType == 0x1b
|
||||
? ElementaryStreamQueue::H264 : ElementaryStreamQueue::AAC) {
|
||||
mBuffer->setRange(0, 0);
|
||||
@@ -336,9 +375,13 @@ void ATSParser::Stream::signalDiscontinuity(DiscontinuityType type) {
|
||||
{
|
||||
mQueue.clear(true);
|
||||
|
||||
if (mStreamType == 0x1b && mSource != NULL) {
|
||||
if (mStreamType == 0x1b) {
|
||||
// Don't signal discontinuities on audio streams.
|
||||
mSource->queueDiscontinuity(type);
|
||||
if (mSource != NULL) {
|
||||
mSource->queueDiscontinuity(type);
|
||||
} else {
|
||||
deferDiscontinuity(type);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -352,6 +395,8 @@ void ATSParser::Stream::signalDiscontinuity(DiscontinuityType type) {
|
||||
|
||||
if (mSource != NULL) {
|
||||
mSource->queueDiscontinuity(type);
|
||||
} else {
|
||||
deferDiscontinuity(type);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -362,6 +407,13 @@ void ATSParser::Stream::signalDiscontinuity(DiscontinuityType type) {
|
||||
}
|
||||
}
|
||||
|
||||
void ATSParser::Stream::deferDiscontinuity(DiscontinuityType type) {
|
||||
if (type > mPendingDiscontinuity) {
|
||||
// Only upgrade discontinuities.
|
||||
mPendingDiscontinuity = type;
|
||||
}
|
||||
}
|
||||
|
||||
void ATSParser::Stream::signalEOS(status_t finalResult) {
|
||||
if (mSource != NULL) {
|
||||
mSource->signalEOS(finalResult);
|
||||
@@ -558,6 +610,11 @@ void ATSParser::Stream::onPayloadData(
|
||||
LOGV("created source!");
|
||||
mSource = new AnotherPacketSource(meta);
|
||||
|
||||
if (mPendingDiscontinuity != DISCONTINUITY_NONE) {
|
||||
mSource->queueDiscontinuity(mPendingDiscontinuity);
|
||||
mPendingDiscontinuity = DISCONTINUITY_NONE;
|
||||
}
|
||||
|
||||
mSource->queueAccessUnit(accessUnit);
|
||||
}
|
||||
} else if (mQueue.getFormat() != NULL) {
|
||||
|
||||
@@ -33,6 +33,7 @@ struct MediaSource;
|
||||
|
||||
struct ATSParser : public RefBase {
|
||||
enum DiscontinuityType {
|
||||
DISCONTINUITY_NONE,
|
||||
DISCONTINUITY_HTTPLIVE,
|
||||
DISCONTINUITY_SEEK,
|
||||
DISCONTINUITY_FORMATCHANGE
|
||||
|
||||
Reference in New Issue
Block a user