Bug 1140995 - part1: At end of stream, send the last video frame to decoded stream with deviation usec if the last video frame's duration is 0. r=jwwang

This commit is contained in:
Benjamin Chen 2015-04-22 18:19:19 +08:00
parent f80d860292
commit 72eb06adee
3 changed files with 30 additions and 1 deletions

View File

@ -313,7 +313,8 @@ MediaDecoder::DecodedStreamData::DecodedStreamData(MediaDecoder* aDecoder,
mHaveSentFinishVideo(false),
mStream(aStream),
mHaveBlockedForPlayState(false),
mHaveBlockedForStateMachineNotPlaying(false)
mHaveBlockedForStateMachineNotPlaying(false),
mEOSVideoCompensation(false)
{
mListener = new DecodedStreamGraphListener(mStream, this);
mStream->AddListener(mListener);

View File

@ -455,6 +455,9 @@ public:
// We also have an explicit blocker on the stream when
// mDecoderStateMachine is non-null and MediaDecoderStateMachine is false.
bool mHaveBlockedForStateMachineNotPlaying;
// True if we need to send a compensation video frame to ensure the
// StreamTime going forward.
bool mEOSVideoCompensation;
};
class DecodedStreamGraphListener : public MediaStreamListener {

View File

@ -390,6 +390,16 @@ static void WriteVideoToMediaStream(MediaStream* aStream,
aOutput->AppendFrame(image.forget(), duration, aIntrinsicSize);
}
static bool ZeroDurationAtLastChunk(VideoSegment& aInput)
{
// Get the last video frame's start time in VideoSegment aInput.
// If the start time is equal to the duration of aInput, means the last video
// frame's duration is zero.
StreamTime lastVideoStratTime;
aInput.GetLastFrame(&lastVideoStratTime);
return lastVideoStratTime == aInput.GetDuration();
}
void MediaDecoderStateMachine::SendStreamData()
{
MOZ_ASSERT(OnTaskQueue());
@ -500,10 +510,25 @@ void MediaDecoderStateMachine::SendStreamData()
v->mTime, v->GetEndTime());
}
}
// Check the output is not empty.
if (output.GetLastFrame()) {
stream->mEOSVideoCompensation = ZeroDurationAtLastChunk(output);
}
if (output.GetDuration() > 0) {
mediaStream->AppendToTrack(videoTrackId, &output);
}
if (VideoQueue().IsFinished() && !stream->mHaveSentFinishVideo) {
if (stream->mEOSVideoCompensation) {
VideoSegment endSegment;
// Calculate the deviation clock time from DecodedStream.
int64_t deviation_usec = mediaStream->StreamTimeToMicroseconds(1);
WriteVideoToMediaStream(mediaStream, stream->mLastVideoImage,
stream->mNextVideoTime + deviation_usec, stream->mNextVideoTime,
stream->mLastVideoImageDisplaySize, &endSegment);
stream->mNextVideoTime += deviation_usec;
MOZ_ASSERT(endSegment.GetDuration() > 0);
mediaStream->AppendToTrack(videoTrackId, &endSegment);
}
mediaStream->EndTrack(videoTrackId);
stream->mHaveSentFinishVideo = true;
}