Bug 973139 - Don't treat EOS of one stream as EOS of all streams when decoding with GStreamer. r=alessandro.d

This commit is contained in:
Chris Pearce 2014-02-15 22:32:12 +13:00
parent 059e59780e
commit 7c0659c348
2 changed files with 25 additions and 11 deletions

View File

@ -81,7 +81,8 @@ GStreamerReader::GStreamerReader(AbstractMediaDecoder* aDecoder)
mVideoSinkBufferCount(0),
mAudioSinkBufferCount(0),
mGstThreadsMonitor("media.gst.threads"),
mReachedEos(false),
mReachedAudioEos(false),
mReachedVideoEos(false),
#if GST_VERSION_MAJOR >= 1
mConfigureAlignment(true),
#endif
@ -534,7 +535,8 @@ nsresult GStreamerReader::ResetDecode()
mVideoSinkBufferCount = 0;
mAudioSinkBufferCount = 0;
mReachedEos = false;
mReachedAudioEos = false;
mReachedVideoEos = false;
#if GST_VERSION_MAJOR >= 1
mConfigureAlignment = true;
#endif
@ -553,7 +555,7 @@ bool GStreamerReader::DecodeAudioData()
{
ReentrantMonitorAutoEnter mon(mGstThreadsMonitor);
if (mReachedEos) {
if (mReachedAudioEos && !mAudioSinkBufferCount) {
return false;
}
@ -637,7 +639,7 @@ bool GStreamerReader::DecodeVideoFrame(bool &aKeyFrameSkip,
{
ReentrantMonitorAutoEnter mon(mGstThreadsMonitor);
if (mReachedEos) {
if (mReachedVideoEos && !mVideoSinkBufferCount) {
return false;
}
@ -691,7 +693,7 @@ bool GStreamerReader::DecodeVideoFrame(bool &aKeyFrameSkip,
"frame has invalid timestamp");
timestamp = GST_TIME_AS_USECONDS(timestamp);
int64_t duration;
int64_t duration = 0;
if (GST_CLOCK_TIME_IS_VALID(GST_BUFFER_DURATION(buffer)))
duration = GST_TIME_AS_USECONDS(GST_BUFFER_DURATION(buffer));
else if (fpsNum && fpsDen)
@ -709,7 +711,7 @@ bool GStreamerReader::DecodeVideoFrame(bool &aKeyFrameSkip,
if (!buffer)
/* no more frames */
return false;
return true;
#if GST_VERSION_MAJOR >= 1
if (mConfigureAlignment && buffer->pool) {
@ -1060,16 +1062,24 @@ void GStreamerReader::NewAudioBuffer()
void GStreamerReader::EosCb(GstAppSink* aSink, gpointer aUserData)
{
GStreamerReader* reader = reinterpret_cast<GStreamerReader*>(aUserData);
reader->Eos();
reader->Eos(aSink);
}
void GStreamerReader::Eos()
void GStreamerReader::Eos(GstAppSink* aSink)
{
/* We reached the end of the stream */
{
ReentrantMonitorAutoEnter mon(mGstThreadsMonitor);
/* Potentially unblock DecodeVideoFrame and DecodeAudioData */
mReachedEos = true;
if (aSink == mVideoAppSink) {
mReachedVideoEos = true;
} else if (aSink == mAudioAppSink) {
mReachedAudioEos = true;
} else {
// Assume this is an error causing an EOS.
mReachedAudioEos = true;
mReachedVideoEos = true;
}
mon.NotifyAll();
}

View File

@ -154,7 +154,10 @@ private:
/* Called at end of stream, when decoding has finished */
static void EosCb(GstAppSink* aSink, gpointer aUserData);
void Eos();
/* Notifies that a sink will no longer receive any more data. If nullptr
* is passed to this, we'll assume all streams have reached EOS (for example
* an error has occurred). */
void Eos(GstAppSink* aSink = nullptr);
/* Called when an element is added inside playbin. We use it to find the
* decodebin instance.
@ -221,7 +224,8 @@ private:
/* bool used to signal when gst has detected the end of stream and
* DecodeAudioData and DecodeVideoFrame should not expect any more data
*/
bool mReachedEos;
bool mReachedAudioEos;
bool mReachedVideoEos;
#if GST_VERSION_MAJOR >= 1
bool mConfigureAlignment;
#endif