19 changes: 3 additions & 16 deletions mythtv/libs/libmythtv/videobuffers.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,7 @@ class VideoBuffers

void Init(uint numdecode, bool extra_for_pause,
uint need_free, uint needprebuffer_normal,
uint needprebuffer_small, uint keepprebuffer,
bool enable_frame_locking = false);
uint needprebuffer_small, uint keepprebuffer);

bool CreateBuffers(VideoFrameType type, int width, int height,
vector<unsigned char*> bufs,
Expand All @@ -80,8 +79,7 @@ class VideoBuffers

void SetPrebuffering(bool normal);

VideoFrame *GetNextFreeFrame(bool with_lock, bool allow_unsafe,
BufferType enqueue_to = kVideoBuffer_limbo);
VideoFrame *GetNextFreeFrame(BufferType enqueue_to = kVideoBuffer_limbo);
void ReleaseFrame(VideoFrame *frame);
void DeLimboFrame(VideoFrame *frame);
void StartDisplayingFrame(void);
Expand Down Expand Up @@ -123,12 +121,6 @@ class VideoBuffers
uint size() const { return numbuffers; }
uint allocSize() const { return buffers.size(); }

void LockFrame(const VideoFrame *, const char* owner);
void LockFrames(vector<const VideoFrame*>&, const char* owner);
bool TryLockFrame(const VideoFrame *, const char* owner);
void UnlockFrame(const VideoFrame *, const char* owner);
void UnlockFrames(vector<const VideoFrame*>&, const char* owner);

void Clear(uint i);
void Clear(void);

Expand All @@ -139,8 +131,7 @@ class VideoBuffers
private:
frame_queue_t *queue(BufferType type);
const frame_queue_t *queue(BufferType type) const;
VideoFrame *GetNextFreeFrameInternal(
bool with_lock, bool allow_unsafe, BufferType enqueue_to);
VideoFrame *GetNextFreeFrameInternal(BufferType enqueue_to);

frame_queue_t available, used, limbo, pause, displayed, decode;
vbuffer_map_t vbufferMap; // videobuffers to buffer's index
Expand All @@ -160,10 +151,6 @@ class VideoBuffers
uint vpos;

mutable QMutex global_lock;

bool use_frame_locks;
QMutex frame_lock;
frame_lock_map_t frame_locks;
};

#endif // __VIDEOBUFFERS_H__
25 changes: 2 additions & 23 deletions mythtv/libs/libmythtv/videoout_null.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,11 @@ VideoOutputNull::~VideoOutputNull()
VERBOSE(VB_PLAYBACK, "~VideoOutputNull()");
QMutexLocker locker(&global_lock);

vbuffers.LockFrame(&av_pause_frame, "DeletePauseFrame");
if (av_pause_frame.buf)
{
delete [] av_pause_frame.buf;
memset(&av_pause_frame, 0, sizeof(av_pause_frame));
}
vbuffers.UnlockFrame(&av_pause_frame, "DeletePauseFrame");

vbuffers.DeleteBuffers();
}
Expand All @@ -61,8 +59,6 @@ void VideoOutputNull::Zoom(ZoomDirection direction)

void VideoOutputNull::CreatePauseFrame(void)
{
vbuffers.LockFrame(&av_pause_frame, "CreatePauseFrame");

if (av_pause_frame.buf)
{
delete [] av_pause_frame.buf;
Expand All @@ -78,8 +74,6 @@ void VideoOutputNull::CreatePauseFrame(void)
av_pause_frame.frameNumber = vbuffers.GetScratchFrame()->frameNumber;

clear(&av_pause_frame);

vbuffers.UnlockFrame(&av_pause_frame, "CreatePauseFrame");
}

bool VideoOutputNull::InputChanged(const QSize &input_size,
Expand Down Expand Up @@ -191,9 +185,7 @@ void VideoOutputNull::PrepareFrame(VideoFrame *buffer, FrameScanType t,
if (!buffer)
buffer = vbuffers.GetScratchFrame();

vbuffers.LockFrame(buffer, "PrepareFrame");
framesPlayed = buffer->frameNumber + 1;
vbuffers.UnlockFrame(buffer, "PrepareFrame");
}

void VideoOutputNull::Show(FrameScanType )
Expand All @@ -209,33 +201,20 @@ void VideoOutputNull::UpdatePauseFrame(void)
QMutexLocker locker(&global_lock);

// Try used frame first, then fall back to scratch frame.
vbuffers.LockFrame(&av_pause_frame, "UpdatePauseFrame -- pause");

vbuffers.begin_lock(kVideoBuffer_used);
VideoFrame *used_frame = NULL;
if (vbuffers.size(kVideoBuffer_used) > 0)
{
used_frame = vbuffers.head(kVideoBuffer_used);
if (!vbuffers.TryLockFrame(used_frame, "UpdatePauseFrame -- used"))
used_frame = NULL;
}

if (used_frame)
{
CopyFrame(&av_pause_frame, used_frame);
vbuffers.UnlockFrame(used_frame, "UpdatePauseFrame -- used");
}
vbuffers.end_lock();

if (!used_frame &&
vbuffers.TryLockFrame(vbuffers.GetScratchFrame(),
"UpdatePauseFrame -- scratch"))
if (!used_frame)
{
vbuffers.GetScratchFrame()->frameNumber = framesPlayed - 1;
CopyFrame(&av_pause_frame, vbuffers.GetScratchFrame());
vbuffers.UnlockFrame(vbuffers.GetScratchFrame(),
"UpdatePauseFrame -- scratch");
}
vbuffers.UnlockFrame(&av_pause_frame, "UpdatePauseFrame - used");
}

void VideoOutputNull::ProcessFrame(VideoFrame *frame, OSD *osd,
Expand Down
2 changes: 1 addition & 1 deletion mythtv/libs/libmythtv/videoout_opengl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ void VideoOutputOpenGL::InitOSD(void)
bool VideoOutputOpenGL::CreateBuffers(void)
{
QMutexLocker locker(&gl_context_lock);
vbuffers.Init(31, true, 1, 12, 4, 2, false);
vbuffers.Init(31, true, 1, 12, 4, 2);
return vbuffers.CreateBuffers(FMT_YV12,
window.GetVideoDim().width(),
window.GetVideoDim().height());
Expand Down
2 changes: 1 addition & 1 deletion mythtv/libs/libmythtv/videoout_vdpau.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ bool VideoOutputVDPAU::InitBuffers(void)
const QSize video_dim = codec_is_std(video_codec_id) ?
window.GetVideoDim() : window.GetActualVideoDim();

vbuffers.Init(m_buffer_size, false, 2, 1, 4, 1, false);
vbuffers.Init(m_buffer_size, false, 2, 1, 4, 1);

bool ok = false;
if (codec_is_vdpau(video_codec_id))
Expand Down
52 changes: 5 additions & 47 deletions mythtv/libs/libmythtv/videoout_xv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -517,8 +517,6 @@ int VideoOutputXv::GrabSuitableXvPort(MythXDisplay* disp, Window root,
*/
void VideoOutputXv::CreatePauseFrame(VOSType subtype)
{
vbuffers.LockFrame(&av_pause_frame, "CreatePauseFrame");

if (av_pause_frame.buf)
{
delete [] av_pause_frame.buf;
Expand All @@ -534,8 +532,6 @@ void VideoOutputXv::CreatePauseFrame(VOSType subtype)
av_pause_frame.frameNumber = vbuffers.GetScratchFrame()->frameNumber;

clear(&av_pause_frame);

vbuffers.UnlockFrame(&av_pause_frame, "CreatePauseFrame");
}

/**
Expand All @@ -551,7 +547,7 @@ bool VideoOutputXv::InitVideoBuffers(bool use_xv, bool use_shm)

// Create ffmpeg VideoFrames
if (!done)
vbuffers.Init(31, true, 1, 12, 4, 2, false);
vbuffers.Init(31, true, 1, 12, 4, 2);

// Fall back to XVideo if there is an xv_port
if (!done && use_xv)
Expand Down Expand Up @@ -1339,11 +1335,6 @@ void VideoOutputXv::StopEmbedding(void)
MoveResize();
}

VideoFrame *VideoOutputXv::GetNextFreeFrame(bool /*allow_unsafe*/)
{
return vbuffers.GetNextFreeFrame(false, false);
}

/**
* \fn VideoOutputXv::DiscardFrame(VideoFrame *frame)
* Frame is ready to be reused by decoder added to the
Expand Down Expand Up @@ -1390,10 +1381,8 @@ void VideoOutputXv::PrepareFrameXv(VideoFrame *frame)
XvImage *image = NULL;
{
QMutexLocker locker(&global_lock);
vbuffers.LockFrame(frame, "PrepareFrameXv");
framesPlayed = frame->frameNumber + 1;
image = (XvImage*) xv_buffers[frame->buf];
vbuffers.UnlockFrame(frame, "PrepareFrameXv");
}

if (vbuffers.GetScratchFrame() == frame)
Expand All @@ -1410,14 +1399,10 @@ void VideoOutputXv::PrepareFrameMem(VideoFrame *buffer, FrameScanType /*scan*/)
if (!buffer)
buffer = vbuffers.GetScratchFrame();

vbuffers.LockFrame(buffer, "PrepareFrameMem");

framesPlayed = buffer->frameNumber + 1;
int width = buffer->width;
int height = buffer->height;

vbuffers.UnlockFrame(buffer, "PrepareFrameMem");

// bad way to throttle frame display for non-Xv mode.
// calculate fps we can do and skip enough frames so we don't exceed.
if (non_xv_frames_shown == 0)
Expand Down Expand Up @@ -1463,7 +1448,6 @@ void VideoOutputXv::PrepareFrameMem(VideoFrame *buffer, FrameScanType /*scan*/)
avpicture_fill(&image_out, (uint8_t *)sbuf, PIX_FMT_YUV420P,
out_width, out_height);

vbuffers.LockFrame(buffer, "PrepareFrameMem");
if ((out_width == width) &&
(out_height == height))
{
Expand All @@ -1481,7 +1465,6 @@ void VideoOutputXv::PrepareFrameMem(VideoFrame *buffer, FrameScanType /*scan*/)
sws_scale(scontext, image_in.data, image_in.linesize, 0, height,
image_out.data, image_out.linesize);
}
vbuffers.UnlockFrame(buffer, "PrepareFrameMem");

avpicture_fill(&image_in, (uint8_t *)XJ_non_xv_image->data,
non_xv_av_format, out_width, out_height);
Expand Down Expand Up @@ -1606,14 +1589,9 @@ void VideoOutputXv::ShowXVideo(FrameScanType scan)
{
VideoFrame *frame = GetLastShownFrame();

vbuffers.LockFrame(frame, "ShowXVideo");

XvImage *image = (XvImage*) xv_buffers[frame->buf];
if (!image)
{
vbuffers.UnlockFrame(frame, "ShowXVideo");
return;
}

const QRect video_rect = window.GetVideoRect();
const QRect display_video_rect = (vsz_enabled && chroma_osd) ?
Expand All @@ -1632,10 +1610,8 @@ void VideoOutputXv::ShowXVideo(FrameScanType scan)
dest_y += xv_dest_y_incr;
}

vbuffers.UnlockFrame(frame, "ShowXVideo");
{
QMutexLocker locker(&global_lock);
vbuffers.LockFrame(frame, "ShowXVideo");
int video_height = (3 != field) ?
(video_rect.height()/2) : video_rect.height();
disp->Lock();
Expand All @@ -1647,7 +1623,6 @@ void VideoOutputXv::ShowXVideo(FrameScanType scan)
display_video_rect.width(),
display_video_rect.height(), False);
disp->Unlock();
vbuffers.UnlockFrame(frame, "ShowXVideo");
}
}

Expand Down Expand Up @@ -1793,33 +1768,22 @@ void VideoOutputXv::UpdatePauseFrame(void)
if (VideoOutputSubType() <= XVideo)
{
// Try used frame first, then fall back to scratch frame.
vbuffers.LockFrame(&av_pause_frame, "UpdatePauseFrame -- pause");

vbuffers.begin_lock(kVideoBuffer_used);

VideoFrame *used_frame = NULL;
if (vbuffers.size(kVideoBuffer_used) > 0)
{
used_frame = vbuffers.head(kVideoBuffer_used);
if (!vbuffers.TryLockFrame(used_frame, "UpdatePauseFrame -- used"))
used_frame = NULL;
}

if (used_frame)
{
CopyFrame(&av_pause_frame, used_frame);
vbuffers.UnlockFrame(used_frame, "UpdatePauseFrame -- used");
}

vbuffers.end_lock();

if (!used_frame &&
vbuffers.TryLockFrame(vbuffers.GetScratchFrame(),
"UpdatePauseFrame -- scratch"))
if (!used_frame)
{
vbuffers.GetScratchFrame()->frameNumber = framesPlayed - 1;
CopyFrame(&av_pause_frame, vbuffers.GetScratchFrame());
vbuffers.UnlockFrame(vbuffers.GetScratchFrame(),
"UpdatePauseFrame -- scratch");
}
vbuffers.UnlockFrame(&av_pause_frame, "UpdatePauseFrame - used");
}
}

Expand All @@ -1836,14 +1800,10 @@ void VideoOutputXv::ProcessFrameMem(VideoFrame *frame, OSD *osd,
vector<const VideoFrame*> locks;
locks.push_back(frame);
locks.push_back(&av_pause_frame);
vbuffers.LockFrames(locks, "ProcessFrameMem -- pause");
CopyFrame(frame, &av_pause_frame);
vbuffers.UnlockFrames(locks, "ProcessFrameMem -- pause");
pauseframe = true;
}

vbuffers.LockFrame(frame, "ProcessFrameMem");

bool safepauseframe = pauseframe && !IsBobDeint();
if (!pauseframe || safepauseframe)
{
Expand Down Expand Up @@ -1873,8 +1833,6 @@ void VideoOutputXv::ProcessFrameMem(VideoFrame *frame, OSD *osd,
{
m_deintFilter->ProcessFrame(frame, scan);
}

vbuffers.UnlockFrame(frame, "ProcessFrameMem");
}

// this is documented in videooutbase.cpp
Expand Down
1 change: 0 additions & 1 deletion mythtv/libs/libmythtv/videoout_xv.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,6 @@ class VideoOutputXv : public VideoOutput

private:
virtual bool hasFullScreenOSD(void) const { return chroma_osd; }
VideoFrame *GetNextFreeFrame(bool allow_unsafe);
void DiscardFrame(VideoFrame*);
void DiscardFrames(bool next_frame_keyframe);

Expand Down
9 changes: 2 additions & 7 deletions mythtv/libs/libmythtv/videooutbase.h
Original file line number Diff line number Diff line change
Expand Up @@ -182,14 +182,9 @@ class VideoOutput

/**
* \brief Blocks until it is possible to return a frame for decoding onto.
* \param with_lock if true frames are properly locked, but this means you
* must unlock them when you are done, so this is disabled by default.
* \param allow_unsafe if true then that are queued for display can be
* returned as frames to decode onto, this defaults to false.
*/
virtual VideoFrame *GetNextFreeFrame(bool with_lock = false,
bool allow_unsafe = false)
{ return vbuffers.GetNextFreeFrame(with_lock, allow_unsafe); }
virtual VideoFrame *GetNextFreeFrame(void)
{ return vbuffers.GetNextFreeFrame(); }
/// \brief Releases a frame from the ready for decoding queue onto the
/// queue of frames ready for display.
virtual void ReleaseFrame(VideoFrame *frame) { vbuffers.ReleaseFrame(frame); }
Expand Down