mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 856562 - Fix decode race in gstreamer backend r=alessandro.d
This commit is contained in:
parent
99768370bd
commit
57bdc4503a
@ -423,34 +423,28 @@ void GStreamerReader::NotifyBytesConsumed()
|
|||||||
mLastReportedByteOffset = mByteOffset;
|
mLastReportedByteOffset = mByteOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GStreamerReader::WaitForDecodedData(int* aCounter)
|
|
||||||
{
|
|
||||||
ReentrantMonitorAutoEnter mon(mGstThreadsMonitor);
|
|
||||||
|
|
||||||
/* Report consumed bytes from here as we can't do it from gst threads */
|
|
||||||
NotifyBytesConsumed();
|
|
||||||
while(*aCounter == 0) {
|
|
||||||
if (mReachedEos) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
mon.Wait();
|
|
||||||
NotifyBytesConsumed();
|
|
||||||
}
|
|
||||||
(*aCounter)--;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GStreamerReader::DecodeAudioData()
|
bool GStreamerReader::DecodeAudioData()
|
||||||
{
|
{
|
||||||
NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
|
NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
|
||||||
|
|
||||||
if (!WaitForDecodedData(&mAudioSinkBufferCount)) {
|
GstBuffer *buffer = nullptr;
|
||||||
mAudioQueue.Finish();
|
|
||||||
return false;
|
{
|
||||||
|
ReentrantMonitorAutoEnter mon(mGstThreadsMonitor);
|
||||||
|
|
||||||
|
if (mReachedEos) {
|
||||||
|
mAudioQueue.Finish();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mAudioSinkBufferCount) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer = gst_app_sink_pull_buffer(mAudioAppSink);
|
||||||
|
mAudioSinkBufferCount--;
|
||||||
}
|
}
|
||||||
|
|
||||||
GstBuffer* buffer = gst_app_sink_pull_buffer(mAudioAppSink);
|
|
||||||
int64_t timestamp = GST_BUFFER_TIMESTAMP(buffer);
|
int64_t timestamp = GST_BUFFER_TIMESTAMP(buffer);
|
||||||
timestamp = gst_segment_to_stream_time(&mAudioSegment,
|
timestamp = gst_segment_to_stream_time(&mAudioSegment,
|
||||||
GST_FORMAT_TIME, timestamp);
|
GST_FORMAT_TIME, timestamp);
|
||||||
@ -479,49 +473,53 @@ bool GStreamerReader::DecodeVideoFrame(bool &aKeyFrameSkip,
|
|||||||
{
|
{
|
||||||
NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
|
NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
|
||||||
|
|
||||||
GstBuffer* buffer = nullptr;
|
GstBuffer *buffer = nullptr;
|
||||||
int64_t timestamp, nextTimestamp;
|
|
||||||
while (true)
|
|
||||||
{
|
{
|
||||||
if (!WaitForDecodedData(&mVideoSinkBufferCount)) {
|
ReentrantMonitorAutoEnter mon(mGstThreadsMonitor);
|
||||||
|
|
||||||
|
if (mReachedEos) {
|
||||||
mVideoQueue.Finish();
|
mVideoQueue.Finish();
|
||||||
break;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!mVideoSinkBufferCount) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
mDecoder->NotifyDecodedFrames(0, 1);
|
mDecoder->NotifyDecodedFrames(0, 1);
|
||||||
|
|
||||||
buffer = gst_app_sink_pull_buffer(mVideoAppSink);
|
buffer = gst_app_sink_pull_buffer(mVideoAppSink);
|
||||||
bool isKeyframe = !GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_DISCONT);
|
mVideoSinkBufferCount--;
|
||||||
if ((aKeyFrameSkip && !isKeyframe)) {
|
}
|
||||||
gst_buffer_unref(buffer);
|
|
||||||
buffer = nullptr;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
timestamp = GST_BUFFER_TIMESTAMP(buffer);
|
bool isKeyframe = !GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_DISCONT);
|
||||||
{
|
if ((aKeyFrameSkip && !isKeyframe)) {
|
||||||
ReentrantMonitorAutoEnter mon(mGstThreadsMonitor);
|
gst_buffer_unref(buffer);
|
||||||
timestamp = gst_segment_to_stream_time(&mVideoSegment,
|
return true;
|
||||||
GST_FORMAT_TIME, timestamp);
|
}
|
||||||
}
|
|
||||||
NS_ASSERTION(GST_CLOCK_TIME_IS_VALID(timestamp),
|
|
||||||
"frame has invalid timestamp");
|
|
||||||
timestamp = nextTimestamp = GST_TIME_AS_USECONDS(timestamp);
|
|
||||||
if (GST_CLOCK_TIME_IS_VALID(GST_BUFFER_DURATION(buffer)))
|
|
||||||
nextTimestamp += GST_TIME_AS_USECONDS(GST_BUFFER_DURATION(buffer));
|
|
||||||
else if (fpsNum && fpsDen)
|
|
||||||
/* add 1-frame duration */
|
|
||||||
nextTimestamp += gst_util_uint64_scale(GST_USECOND, fpsNum, fpsDen);
|
|
||||||
|
|
||||||
if (timestamp < aTimeThreshold) {
|
int64_t timestamp = GST_BUFFER_TIMESTAMP(buffer);
|
||||||
LOG(PR_LOG_DEBUG, ("skipping frame %" GST_TIME_FORMAT
|
{
|
||||||
" threshold %" GST_TIME_FORMAT,
|
ReentrantMonitorAutoEnter mon(mGstThreadsMonitor);
|
||||||
GST_TIME_ARGS(timestamp), GST_TIME_ARGS(aTimeThreshold)));
|
timestamp = gst_segment_to_stream_time(&mVideoSegment,
|
||||||
gst_buffer_unref(buffer);
|
GST_FORMAT_TIME, timestamp);
|
||||||
buffer = nullptr;
|
}
|
||||||
continue;
|
NS_ASSERTION(GST_CLOCK_TIME_IS_VALID(timestamp),
|
||||||
}
|
"frame has invalid timestamp");
|
||||||
|
int64_t nextTimestamp = timestamp = GST_TIME_AS_USECONDS(timestamp);
|
||||||
|
if (GST_CLOCK_TIME_IS_VALID(GST_BUFFER_DURATION(buffer)))
|
||||||
|
nextTimestamp += GST_TIME_AS_USECONDS(GST_BUFFER_DURATION(buffer));
|
||||||
|
else if (fpsNum && fpsDen)
|
||||||
|
/* add 1-frame duration */
|
||||||
|
nextTimestamp += gst_util_uint64_scale(GST_USECOND, fpsNum, fpsDen);
|
||||||
|
|
||||||
break;
|
if (timestamp < aTimeThreshold) {
|
||||||
|
LOG(PR_LOG_DEBUG, ("skipping frame %" GST_TIME_FORMAT
|
||||||
|
" threshold %" GST_TIME_FORMAT,
|
||||||
|
GST_TIME_ARGS(timestamp), GST_TIME_ARGS(aTimeThreshold)));
|
||||||
|
gst_buffer_unref(buffer);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!buffer)
|
if (!buffer)
|
||||||
@ -570,8 +568,7 @@ bool GStreamerReader::DecodeVideoFrame(bool &aKeyFrameSkip,
|
|||||||
b.mPlanes[i].mSkip = 0;
|
b.mPlanes[i].mSkip = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isKeyframe = !GST_BUFFER_FLAG_IS_SET(buffer,
|
isKeyframe = !GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_DELTA_UNIT);
|
||||||
GST_BUFFER_FLAG_DELTA_UNIT);
|
|
||||||
/* XXX ? */
|
/* XXX ? */
|
||||||
int64_t offset = 0;
|
int64_t offset = 0;
|
||||||
VideoData* video = VideoData::Create(mInfo, image, offset,
|
VideoData* video = VideoData::Create(mInfo, image, offset,
|
||||||
|
@ -50,7 +50,6 @@ public:
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
void ReadAndPushData(guint aLength);
|
void ReadAndPushData(guint aLength);
|
||||||
bool WaitForDecodedData(int* counter);
|
|
||||||
void NotifyBytesConsumed();
|
void NotifyBytesConsumed();
|
||||||
int64_t QueryDuration();
|
int64_t QueryDuration();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user