mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-29 15:52:07 +00:00
Bug 1119681 - [RTSP] Add time stamps to RTSP live streams. r=ettseng, r=bechen
This commit is contained in:
parent
72310a0d5d
commit
31fa7b90c2
@ -491,7 +491,8 @@ RtspMediaResource::RtspMediaResource(MediaDecoder* aDecoder,
|
||||
nsIChannel* aChannel, nsIURI* aURI, const nsACString& aContentType)
|
||||
: BaseMediaResource(aDecoder, aChannel, aURI, aContentType)
|
||||
, mIsConnected(false)
|
||||
, mRealTime(false)
|
||||
, mIsLiveStream(false)
|
||||
, mHasTimestamp(true)
|
||||
, mIsSuspend(true)
|
||||
{
|
||||
#ifndef NECKO_PROTOCOL_rtsp
|
||||
@ -639,9 +640,6 @@ RtspMediaResource::OnMediaDataAvailable(uint8_t aTrackIdx,
|
||||
uint32_t frameType;
|
||||
meta->GetTimeStamp(&time);
|
||||
meta->GetFrameType(&frameType);
|
||||
if (mRealTime) {
|
||||
time = 0;
|
||||
}
|
||||
mTrackBuffer[aTrackIdx]->WriteBuffer(data.BeginReading(), length, time,
|
||||
frameType);
|
||||
return NS_OK;
|
||||
@ -727,7 +725,7 @@ RtspMediaResource::OnConnected(uint8_t aTrackIdx,
|
||||
// If the durationUs is 0, imply the stream is live stream.
|
||||
if (durationUs) {
|
||||
// Not live stream.
|
||||
mRealTime = false;
|
||||
mIsLiveStream = false;
|
||||
mDecoder->SetInfinite(false);
|
||||
mDecoder->SetDuration((double)(durationUs) / USECS_PER_S);
|
||||
} else {
|
||||
@ -740,7 +738,7 @@ RtspMediaResource::OnConnected(uint8_t aTrackIdx,
|
||||
NS_DispatchToMainThread(event);
|
||||
return NS_ERROR_FAILURE;
|
||||
} else {
|
||||
mRealTime = true;
|
||||
mIsLiveStream = true;
|
||||
bool seekable = false;
|
||||
mDecoder->SetInfinite(true);
|
||||
mDecoder->SetMediaSeekable(seekable);
|
||||
|
@ -92,8 +92,10 @@ public:
|
||||
return mMediaStreamController;
|
||||
}
|
||||
|
||||
// Even it is a live stream, as long as it provides valid timestamps,
|
||||
// we tell state machine it's not a live stream.
|
||||
virtual bool IsRealTime() MOZ_OVERRIDE {
|
||||
return mRealTime;
|
||||
return !mHasTimestamp;
|
||||
}
|
||||
|
||||
// Called by RtspOmxReader, dispatch a runnable to notify mDecoder.
|
||||
@ -154,7 +156,7 @@ public:
|
||||
virtual double GetDownloadRate(bool* aIsReliable) MOZ_OVERRIDE { *aIsReliable = false; return 0; }
|
||||
|
||||
virtual int64_t GetLength() MOZ_OVERRIDE {
|
||||
if (mRealTime) {
|
||||
if (mIsLiveStream) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
@ -247,8 +249,10 @@ private:
|
||||
// A flag that indicates the |RtspMediaResource::OnConnected| has already been
|
||||
// called.
|
||||
bool mIsConnected;
|
||||
// live stream
|
||||
bool mRealTime;
|
||||
// Whether it's a live stream.
|
||||
bool mIsLiveStream;
|
||||
// Whether it provides timestamps.
|
||||
bool mHasTimestamp;
|
||||
// Indicate the rtsp controller is suspended or not. Main thread only.
|
||||
bool mIsSuspend;
|
||||
};
|
||||
|
@ -233,6 +233,9 @@ struct RtspConnectionHandler : public AHandler {
|
||||
}
|
||||
|
||||
void pause() {
|
||||
if (!mSeekable) {
|
||||
return;
|
||||
}
|
||||
AString request = "PAUSE ";
|
||||
request.append(mSessionURL);
|
||||
request.append(" RTSP/1.0\r\n");
|
||||
|
@ -51,8 +51,9 @@ RTSPSource::RTSPSource(
|
||||
mDisconnectReplyID(0),
|
||||
mLatestPausedUnit(0),
|
||||
mPlayPending(false),
|
||||
mSeekGeneration(0)
|
||||
|
||||
mSeekGeneration(0),
|
||||
mDisconnectedToPauseLiveStream(false),
|
||||
mPlayOnConnected(false)
|
||||
{
|
||||
CHECK(aListener != NULL);
|
||||
|
||||
@ -71,6 +72,8 @@ RTSPSource::~RTSPSource()
|
||||
|
||||
void RTSPSource::start()
|
||||
{
|
||||
mDisconnectedToPauseLiveStream = false;
|
||||
|
||||
if (mLooper == NULL) {
|
||||
mLooper = new ALooper;
|
||||
mLooper->setName("rtsp");
|
||||
@ -95,6 +98,9 @@ void RTSPSource::start()
|
||||
|
||||
void RTSPSource::stop()
|
||||
{
|
||||
if (mState == DISCONNECTED) {
|
||||
return;
|
||||
}
|
||||
sp<AMessage> msg = new AMessage(kWhatDisconnect, mReflector->id());
|
||||
|
||||
sp<AMessage> dummy;
|
||||
@ -113,6 +119,14 @@ void RTSPSource::play()
|
||||
void RTSPSource::pause()
|
||||
{
|
||||
LOGI("RTSPSource::pause()");
|
||||
|
||||
// Live streams can't be paused, so we have to disconnect now.
|
||||
if (isLiveStream()) {
|
||||
mDisconnectedToPauseLiveStream = true;
|
||||
stop();
|
||||
return;
|
||||
}
|
||||
|
||||
sp<AMessage> msg = new AMessage(kWhatPerformPause, mReflector->id());
|
||||
msg->post();
|
||||
}
|
||||
@ -212,6 +226,7 @@ status_t RTSPSource::seekTo(int64_t seekTimeUs) {
|
||||
void RTSPSource::performPlay(int64_t playTimeUs) {
|
||||
if (mState == DISCONNECTED) {
|
||||
LOGI("We are in a idle state, restart play");
|
||||
mPlayOnConnected = true;
|
||||
start();
|
||||
return;
|
||||
}
|
||||
@ -641,6 +656,11 @@ void RTSPSource::onConnected(bool isSeekable)
|
||||
}
|
||||
|
||||
mState = CONNECTED;
|
||||
|
||||
if (mPlayOnConnected) {
|
||||
mPlayOnConnected = false;
|
||||
play();
|
||||
}
|
||||
}
|
||||
|
||||
void RTSPSource::onDisconnected(const sp<AMessage> &msg) {
|
||||
@ -659,7 +679,9 @@ void RTSPSource::onDisconnected(const sp<AMessage> &msg) {
|
||||
if (mDisconnectReplyID != 0) {
|
||||
finishDisconnectIfPossible();
|
||||
}
|
||||
if (mListener) {
|
||||
// If the disconnection is caused by pausing live stream,
|
||||
// do not report back to the controller.
|
||||
if (mListener && !mDisconnectedToPauseLiveStream) {
|
||||
nsresult reason = (err == OK) ? NS_OK : NS_ERROR_NET_TIMEOUT;
|
||||
mListener->OnDisconnected(0, reason);
|
||||
// Break the cycle reference between RtspController and us.
|
||||
@ -728,7 +750,9 @@ void RTSPSource::onTrackDataAvailable(size_t trackIndex)
|
||||
|
||||
void RTSPSource::onTrackEndOfStream(size_t trackIndex)
|
||||
{
|
||||
if (!mListener) {
|
||||
// If we are disconnecting to pretend pausing a live stream,
|
||||
// do not report the end of stream.
|
||||
if (!mListener || mDisconnectedToPauseLiveStream) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -741,4 +765,11 @@ void RTSPSource::onTrackEndOfStream(size_t trackIndex)
|
||||
|
||||
mListener->OnMediaDataAvailable(trackIndex, data, data.Length(), 0, meta.get());
|
||||
}
|
||||
|
||||
|
||||
bool RTSPSource::isLiveStream() {
|
||||
int64_t duration = 0;
|
||||
getDuration(&duration);
|
||||
return duration == 0;
|
||||
}
|
||||
} // namespace android
|
||||
|
@ -152,6 +152,18 @@ private:
|
||||
|
||||
void onTrackEndOfStream(size_t trackIndex);
|
||||
|
||||
bool isLiveStream();
|
||||
|
||||
// This flag is set if we have just disconnected
|
||||
// in order to pretend pausing a live stream.
|
||||
bool mDisconnectedToPauseLiveStream;
|
||||
|
||||
// While performing a play operation, if the current state of RTSP connection
|
||||
// is disconnected, we will start over establishing connection to the server.
|
||||
// In this case (mPlayOnConnected = true), we have to perform play again when
|
||||
// onConnected, to ensure we complete the play operation.
|
||||
bool mPlayOnConnected;
|
||||
|
||||
nsMainThreadPtrHandle<nsIStreamingProtocolListener> mListener;
|
||||
int mPrintCount;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user