Skip to content

Commit

Permalink
Merge pull request #32 from tshino/enable-default-image
Browse files Browse the repository at this point in the history
Detect and use default image if available
  • Loading branch information
tshino committed Dec 26, 2023
2 parents c115a92 + 24d85cd commit 7380d0c
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 9 deletions.
40 changes: 31 additions & 9 deletions src/softcamcore/DShowSoftcam.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
#include <chrono>
#include <ctime>

#include "Misc.h"


namespace {

Expand Down Expand Up @@ -150,6 +152,8 @@ AM_MEDIA_TYPE* makeMediaType(int width, int height, float framerate)
bool UseDefaultBlankImage = false; // Testing purpose only
int DefaultImageWidth = 0; // Testing purpose only
int DefaultImageHeight = 0; // Testing purpose only

const char DefaultImageSuffix[] = "\\placeholder.png";
const float DefaultFramerate = 60.0f;

} //namespace
Expand Down Expand Up @@ -189,16 +193,21 @@ Softcam::Softcam(LPUNKNOWN lpunk, const GUID& clsid, HRESULT *phr) :
m_default_image(
m_frame_buffer ? DefaultImage{} :
UseDefaultBlankImage ? DefaultImage::makeBlankImage(DefaultImageWidth, DefaultImageHeight) :
DefaultImage{} /* TODO: Read the default image when it's necessary */),
DefaultImage::tryLoad(GetModuleDirectoryPath() + DefaultImageSuffix)),
m_valid(m_frame_buffer || m_default_image),
m_width(m_frame_buffer ? m_frame_buffer.width() : m_default_image ? m_default_image.width() : 0),
m_height(m_frame_buffer ? m_frame_buffer.height() : m_default_image ? m_default_image.height() : 0),
m_framerate(m_frame_buffer ? m_frame_buffer.framerate() : m_default_image ? DefaultFramerate : 0.0f)
{
CAutoLock lock(&m_cStateLock);
LOG("ctor -> frame_buffer:%s(%dx%d) default_image:%s(%dx%d)\n",
m_frame_buffer ? "valid" : "none", m_frame_buffer.width(), m_frame_buffer.height(),
m_default_image ? "valid" : "none", m_default_image.width(), m_default_image.height());

m_paStreams = new CSourceStream*[1];
m_paStreams[0] = new SoftcamStream(phr, this, L"DirectShow Softcam Stream");
// This code is okay though it may look strange as the return value is ignored.
// Calling the SoftcamStream constructor results in calling the CBaseOutputPin
// constructor which registers the instance to this Softcam instance by calling
// CSource::AddPin().
(void)new SoftcamStream(phr, this, L"DirectShow Softcam Stream");
}


Expand Down Expand Up @@ -359,7 +368,7 @@ FrameBuffer* Softcam::getFrameBuffer()
return nullptr;
}

CAutoLock lock(&m_cStateLock);
CAutoLock lock(&m_critsec);
if (!m_frame_buffer)
{
auto fb = FrameBuffer::open();
Expand All @@ -384,10 +393,24 @@ FrameBuffer* Softcam::getFrameBuffer()
void
Softcam::releaseFrameBuffer()
{
CAutoLock lock(&m_cStateLock);
CAutoLock lock(&m_critsec);
m_frame_buffer.release();
}

const DefaultImage*
Softcam::getDefaultImage()
{
CAutoLock lock(&m_critsec);
if (m_default_image)
{
return &m_default_image;
}
else
{
return nullptr;
}
}

SoftcamStream::SoftcamStream(HRESULT *phr,
Softcam *pParent,
LPCWSTR pPinName) :
Expand Down Expand Up @@ -474,10 +497,9 @@ HRESULT SoftcamStream::FillBuffer(IMediaSample *pms)
{
std::memcpy(pData, m_screenshot.get(), size);
}
else
else if (auto def = getParent()->getDefaultImage())
{
// TODO: Write the default image
std::memset(pData, 77, size);
std::memcpy(pData, def->imageBits(), size);
}
}

Expand Down
3 changes: 3 additions & 0 deletions src/softcamcore/DShowSoftcam.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,14 @@ class Softcam : public CSource, public IAMStreamConfig
float framerate() const { return m_framerate; }
void releaseFrameBuffer();

const DefaultImage* getDefaultImage();

// Testing purpose only
static void enableDefaultBlankImage(int width, int height);
static void disableDefaultBlankImage();

private:
CCritSec m_critsec;
FrameBuffer m_frame_buffer;
DefaultImage m_default_image;
const bool m_valid;
Expand Down
38 changes: 38 additions & 0 deletions tests/core_tests/DShowSoftcamTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1003,5 +1003,43 @@ TEST_F(SoftcamStream, CSourceStreamGetMediaTypeNormal)
checkMediaType320x240(&mt);
}

TEST_F(SoftcamStream, getFrameBuffer_must_not_lock_the_filter_state)
{
auto fb = createFrameBufer(320, 240, 60);
SetUpSoftcamStream();

CAutoLock lock(m_softcam->pStateLock()); // 1st lock
std::atomic<int> done{false};
std::thread th([&]
{
// A deadlock occurs if this code attempts to get lock.
m_softcam->getFrameBuffer();
done = true;
});

for (int i = 0; !done && i < 20; i++) { sc::Timer::sleep(0.050f); }
ASSERT_TRUE( done );
th.join();
}

TEST_F(SoftcamStream, releaseFrameBuffer_must_not_lock_the_filter_state)
{
auto fb = createFrameBufer(320, 240, 60);
SetUpSoftcamStream();

CAutoLock lock(m_softcam->pStateLock()); // 1st lock
std::atomic<int> done{false};
std::thread th([&]
{
// A deadlock occurs if this code attempts to get lock.
m_softcam->releaseFrameBuffer();
done = true;
});

for (int i = 0; !done && i < 20; i++) { sc::Timer::sleep(0.050f); }
ASSERT_TRUE( done );
th.join();
}


} //namespace

0 comments on commit 7380d0c

Please sign in to comment.