Fix a locking problem with inner locks to protect the race condition when
the producer media nodes would access the suppliers in their own thread without having any locks held, while the window could replace the suppliers. I think since I delayed the deletion of the suppliers in the controllers, this problem was only theoretical... but this is just more clean. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25734 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -791,17 +791,12 @@ h->start_time = 0;
|
|||||||
"playlistFrame: %Ld\n", fFrame, playlistFrame);
|
"playlistFrame: %Ld\n", fFrame, playlistFrame);
|
||||||
bool forceOrWasCached = forceSendingBuffer;
|
bool forceOrWasCached = forceSendingBuffer;
|
||||||
|
|
||||||
if (fManager->LockWithTimeout(5000) == B_OK) {
|
err = fSupplier->FillBuffer(playlistFrame,
|
||||||
// we need to lock the manager, or our
|
buffer->Data(), &mf, forceOrWasCached);
|
||||||
// fSupplier might work on bad data
|
|
||||||
err = fSupplier->FillBuffer(playlistFrame,
|
|
||||||
buffer->Data(), &mf, forceOrWasCached);
|
|
||||||
fManager->Unlock();
|
|
||||||
} else {
|
|
||||||
err = B_ERROR;
|
|
||||||
}
|
|
||||||
// clean the buffer if something went wrong
|
// clean the buffer if something went wrong
|
||||||
if (err != B_OK) {
|
if (err != B_OK) {
|
||||||
|
// TODO: should use "back value" according
|
||||||
|
// to color space!
|
||||||
memset(buffer->Data(), 0, h->size_used);
|
memset(buffer->Data(), 0, h->size_used);
|
||||||
err = B_OK;
|
err = B_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,7 +43,9 @@ struct PlayingInterval {
|
|||||||
|
|
||||||
|
|
||||||
ProxyAudioSupplier::ProxyAudioSupplier(PlaybackManager* playbackManager)
|
ProxyAudioSupplier::ProxyAudioSupplier(PlaybackManager* playbackManager)
|
||||||
: fPlaybackManager(playbackManager)
|
: fSupplierLock("audio supplier lock")
|
||||||
|
|
||||||
|
, fPlaybackManager(playbackManager)
|
||||||
, fVideoFrameRate(25.0)
|
, fVideoFrameRate(25.0)
|
||||||
|
|
||||||
, fSupplier(NULL)
|
, fSupplier(NULL)
|
||||||
@@ -98,6 +100,8 @@ ProxyAudioSupplier::GetFrames(void* buffer, int64 frameCount,
|
|||||||
TRACE("GetFrames() - LOCKING THE PLAYBACK MANAGER TIMED OUT!!!\n");
|
TRACE("GetFrames() - LOCKING THE PLAYBACK MANAGER TIMED OUT!!!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BAutolock _(fSupplierLock);
|
||||||
|
|
||||||
// retrieve the audio data for each interval.
|
// retrieve the audio data for each interval.
|
||||||
int64 framesRead = 0;
|
int64 framesRead = 0;
|
||||||
while (!playingIntervals.IsEmpty()) {
|
while (!playingIntervals.IsEmpty()) {
|
||||||
@@ -165,6 +169,8 @@ ProxyAudioSupplier::SetFormat(const media_format& format)
|
|||||||
TRACE("SetFormat(%s)\n", string);
|
TRACE("SetFormat(%s)\n", string);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
BAutolock _(fSupplierLock);
|
||||||
|
|
||||||
fAudioResampler.SetFormat(format);
|
fAudioResampler.SetFormat(format);
|
||||||
|
|
||||||
// In case SetSupplier was called before, we need
|
// In case SetSupplier was called before, we need
|
||||||
@@ -199,6 +205,8 @@ ProxyAudioSupplier::SetSupplier(AudioTrackSupplier* supplier,
|
|||||||
//videoFrameRate);
|
//videoFrameRate);
|
||||||
TRACE("SetSupplier(%p, %.1f)\n", supplier, videoFrameRate);
|
TRACE("SetSupplier(%p, %.1f)\n", supplier, videoFrameRate);
|
||||||
|
|
||||||
|
BAutolock _(fSupplierLock);
|
||||||
|
|
||||||
fSupplier = supplier;
|
fSupplier = supplier;
|
||||||
fVideoFrameRate = videoFrameRate;
|
fVideoFrameRate = videoFrameRate;
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#ifndef PROXY_AUDIO_SUPPLIER_H
|
#ifndef PROXY_AUDIO_SUPPLIER_H
|
||||||
#define PROXY_AUDIO_SUPPLIER_H
|
#define PROXY_AUDIO_SUPPLIER_H
|
||||||
|
|
||||||
|
#include <Locker.h>
|
||||||
|
|
||||||
#include "AudioResampler.h"
|
#include "AudioResampler.h"
|
||||||
#include "AudioSupplier.h"
|
#include "AudioSupplier.h"
|
||||||
@@ -45,6 +46,8 @@ private:
|
|||||||
void* _SkipFrames(void* buffer, int64 frames) const;
|
void* _SkipFrames(void* buffer, int64 frames) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
BLocker fSupplierLock;
|
||||||
|
|
||||||
PlaybackManager* fPlaybackManager;
|
PlaybackManager* fPlaybackManager;
|
||||||
float fVideoFrameRate;
|
float fVideoFrameRate;
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,8 @@
|
|||||||
|
|
||||||
|
|
||||||
ProxyVideoSupplier::ProxyVideoSupplier()
|
ProxyVideoSupplier::ProxyVideoSupplier()
|
||||||
: fSupplier(NULL)
|
: fSupplierLock("video supplier lock")
|
||||||
|
, fSupplier(NULL)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -26,6 +27,7 @@ status_t
|
|||||||
ProxyVideoSupplier::FillBuffer(int64 startFrame, void* buffer,
|
ProxyVideoSupplier::FillBuffer(int64 startFrame, void* buffer,
|
||||||
const media_format* format, bool& wasCached)
|
const media_format* format, bool& wasCached)
|
||||||
{
|
{
|
||||||
|
BAutolock _(fSupplierLock);
|
||||||
//printf("ProxyVideoSupplier::FillBuffer(%lld)\n", startFrame);
|
//printf("ProxyVideoSupplier::FillBuffer(%lld)\n", startFrame);
|
||||||
if (fSupplier == NULL)
|
if (fSupplier == NULL)
|
||||||
return B_NO_INIT;
|
return B_NO_INIT;
|
||||||
@@ -60,6 +62,8 @@ ProxyVideoSupplier::DeleteCaches()
|
|||||||
void
|
void
|
||||||
ProxyVideoSupplier::SetSupplier(VideoTrackSupplier* supplier)
|
ProxyVideoSupplier::SetSupplier(VideoTrackSupplier* supplier)
|
||||||
{
|
{
|
||||||
|
BAutolock _(fSupplierLock);
|
||||||
|
|
||||||
fSupplier = supplier;
|
fSupplier = supplier;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#ifndef PROXY_VIDEO_SUPPLIER_H
|
#ifndef PROXY_VIDEO_SUPPLIER_H
|
||||||
#define PROXY_VIDEO_SUPPLIER_H
|
#define PROXY_VIDEO_SUPPLIER_H
|
||||||
|
|
||||||
|
#include <Locker.h>
|
||||||
|
|
||||||
#include "VideoSupplier.h"
|
#include "VideoSupplier.h"
|
||||||
|
|
||||||
@@ -26,6 +27,8 @@ public:
|
|||||||
void SetSupplier(VideoTrackSupplier* supplier);
|
void SetSupplier(VideoTrackSupplier* supplier);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
BLocker fSupplierLock;
|
||||||
|
|
||||||
VideoTrackSupplier* fSupplier;
|
VideoTrackSupplier* fSupplier;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user