Skip to content

Commit

Permalink
Created platform dependent and independent classes for better separat…
Browse files Browse the repository at this point in the history
…ion.

Platform independent stuff is now in 'common', while the platform dependent stuff is in the corresponding platform directory (win, linux mac).
  • Loading branch information
trcwm committed Jul 10, 2017
1 parent 7c0b9fa commit 8839e04
Show file tree
Hide file tree
Showing 16 changed files with 704 additions and 583 deletions.
10 changes: 6 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,12 @@ include_directories(include)
IF (WIN32)

# add files for WIN32
set (SOURCE win/libmain.cpp
win/context.cpp
win/logging.cpp
win/stream.cpp)
set (SOURCE common/libmain.cpp
common/context.cpp
common/logging.cpp
common/stream.cpp
win/platformcontext.cpp
win/platformstream.cpp)

# add windows-specific test application
add_subdirectory(win/tests)
Expand Down
221 changes: 221 additions & 0 deletions common/context.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
/*
OpenPnp-Capture: a video capture subsystem.
Windows platform code
Created by Niels Moseley on 7/6/17.
Copyright © 2017 Niels Moseley. All rights reserved.
Platform/implementation specific structures
and typedefs.
*/

//#include <Mfidl.h>
//#include <Mfapi.h>

#include <vector>
#include "context.h"
#include "logging.h"
#include "stream.h"

#ifdef _WIN32
#include "../win/platformstream.h"
#elif __linux__
#include "../linux/platformstream.h"
#endif

Context::Context() :
m_streamCounter(0)
{
//NOTE: derived platform dependent class must enumerate
// the devices here and place them in m_devices.
}

Context::~Context()
{
LOG(LOG_DEBUG, "Context destroyed\n");
}

const char* Context::getDeviceName(CapDeviceID id) const
{
if (id >= m_devices.size())
{
return NULL; // no such device ID!
}
return m_devices[id].m_name.c_str();
}

uint32_t Context::getDeviceCount() const
{
return m_devices.size();
}


int32_t Context::openStream(CapDeviceID id)
{
deviceInfo *device = nullptr;

if (m_devices.size() > id)
{
device = &m_devices[id];
}
else
{
LOG(LOG_ERR, "openStream: No devices found\n", device->m_name.c_str());
return -1;
}


Stream *s = new PlatformStream();
if (!s->open(this, device, 0,0,0))
{
LOG(LOG_ERR, "Could not open stream for device %s\n", device->m_name.c_str());
return -1;
}
else
{
printf("[DBG ] FOURCC = ");
uint32_t fcc = s->getFOURCC();
for(uint32_t i=0; i<4; i++)
{
printf("%c", (fcc & 0xff));
fcc >>= 8;
}
printf("\n");
}

int32_t streamID = storeStream(s);
return streamID;
}

bool Context::closeStream(int32_t streamID)
{
if (streamID < 0)
{
LOG(LOG_ERR, "closeStream was called with a negative stream ID\n");
return false;
}

// remove stream from collection
Stream *streamPtr = lookupStreamByID(streamID);
if (streamPtr != nullptr)
{
delete streamPtr;
}
else
{
LOG(LOG_ERR, "could not delete stream with ID %d.\n", streamID);
}

if (!removeStream(streamID))
{
LOG(LOG_ERR, "could not remove stream with ID %d from m_streams.\n", streamID);
}

return true;
}

uint32_t Context::isOpenStream(int32_t streamID)
{
if (streamID < 0)
{
LOG(LOG_ERR, "isOpenStream was called with a negative stream ID\n");
return 0;
}

if (static_cast<uint32_t>(streamID) >= m_streams.size())
{
LOG(LOG_ERR, "isOpenStream was called with an out-of-bounds stream ID\n");
return 0;
}

return m_streams[streamID]->isOpen() ? 1 : 0;
}

bool Context::captureFrame(int32_t streamID, uint8_t *RGBbufferPtr, size_t RGBbufferBytes)
{
if (streamID < 0)
{
LOG(LOG_ERR, "captureFrame was called with a negative stream ID\n");
return false;
}

if (static_cast<uint32_t>(streamID) >= m_streams.size())
{
LOG(LOG_ERR, "captureFrame was called with an out-of-bounds stream ID\n");
return false;
}

return m_streams[streamID]->captureFrame(RGBbufferPtr, RGBbufferBytes);
}

bool Context::hasNewFrame(int32_t streamID)
{
if (streamID < 0)
{
LOG(LOG_ERR, "hasNewFrame was called with a negative stream ID\n");
return false;
}

if (static_cast<uint32_t>(streamID) >= m_streams.size())
{
LOG(LOG_ERR, "hasNewFrame was called with an out-of-bounds stream ID\n");
return false;
}

return m_streams[streamID]->hasNewFrame();
}

uint32_t Context::getStreamFrameCount(int32_t streamID)
{
if (streamID < 0)
{
LOG(LOG_ERR, "getStreamFrameCount was called with a negative stream ID\n");
return 0;
}

if (static_cast<uint32_t>(streamID) >= m_streams.size())
{
LOG(LOG_ERR, "getStreamFrameCount was called with an out-of-bounds stream ID\n");
return 0;
}

return m_streams[streamID]->getFrameCount();
}

/** Lookup a stream by ID and return a pointer
to it if it exists. If it doesnt exist,
return NULL */
Stream* Context::lookupStreamByID(int32_t ID)
{
auto it = m_streams.find(ID);
if (it != m_streams.end())
{
return it->second;
}
return nullptr;
}

/** Store a stream pointer in the m_streams map
and return its unique ID */
int32_t Context::storeStream(Stream *stream)
{
int32_t ID = m_streamCounter++;
m_streams.insert(std::pair<int32_t,Stream*>(ID, stream));
return ID;
}

/** Remove a stream from the m_streams map.
Return true if this was successful */
bool Context::removeStream(int32_t ID)
{
auto it = m_streams.find(ID);
if (it != m_streams.end())
{
m_streams.erase(it);
return true;
}
return false;
}
71 changes: 31 additions & 40 deletions common/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,11 @@
OpenPnp-Capture: a video capture subsystem.
Windows platform code
Created by Niels Moseley on 7/6/17.
Created by Niels Moseley on 7/11/17.
Copyright © 2017 Niels Moseley. All rights reserved.
Platform/implementation specific structures
and typedefs.
Platform independent context class to keep track
of the global state.
*/

Expand All @@ -17,45 +15,26 @@

#define _CRT_SECURE_NO_WARNINGS

#pragma comment(lib, "strmiids")
//#pragma comment(lib, "Mfplat")
//#pragma comment(lib, "Mf.lib")

#include <windows.h>
#include <dshow.h>
#include <vector>
#include <string>
#include <map>
#include <stdint.h>

#include "openpnp-capture.h"

class Stream;
#ifdef _WIN32
#pragma comment(lib, "strmiids")
#include "../win/deviceinfo.h"
#elif __linux__
#include "../linux/deviceinfo.h"
#else
#include "../mac/deviceinfo.h"
#endif

/** device information struct/object */
struct deviceInfo
{
deviceInfo() : m_moniker(0) {}
~deviceInfo()
{
if (m_moniker != nullptr)
{
//FIXME: not sure what to do with
// IMoniker* here. When I call
// ->Release(), the program crashes ?
// even an additional AddRef was
// applied.. ? Documentation unclear.
}
}

std::string m_name; ///< UTF-8 printable name
std::wstring m_filterName; ///< DirectShow internal device name
std::wstring m_devicePath; ///< unique device path
IMoniker* m_moniker; ///< DirectShow object for capture device
};

class Stream; // pre-declaration

/** context class keeps track of all the platform dependent
/** context base class keeps track of all the platform independent
objects and information */

class Context
Expand Down Expand Up @@ -105,8 +84,12 @@ class Context

protected:
/** Enumerate DirectShow capture devices and put their
information into the m_devices array */
bool enumerateDevices();
information into the m_devices array
Implement this function in a platform-dependent
derived class.
*/
virtual bool enumerateDevices() = 0;

/** Lookup a stream by ID and return a pointer
to it if it exists. If it doesnt exist,
Expand All @@ -123,11 +106,19 @@ class Context



/** Convert a wide character string to an UTF-8 string */
std::string wstringToString(const std::wstring &wstr);
/** Convert a wide character string to an UTF-8 string
Implement this function in a platform-dependent
derived class.
*/
virtual std::string wstringToString(const std::wstring &wstr) = 0;

/** Convert a wide charater string to an UTF-8 string */
std::string wcharPtrToString(const wchar_t *str);
/** Convert a wide charater string to an UTF-8 string
Implement this function in a platform-dependent
derived class.
*/
virtual std::string wcharPtrToString(const wchar_t *str) = 0;


std::vector<deviceInfo> m_devices; ///< list of enumerated devices
Expand Down
8 changes: 7 additions & 1 deletion common/libmain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,15 @@
#include "context.h"
#include "logging.h"

#ifdef _WIN32
#include "../win/platformcontext.h"
#elif __linux__
#include "../linux/platformcontext.h"
#endif

DLLPUBLIC CapContext Cap_createContext()
{
Context *ctx = new Context();
Context *ctx = new PlatformContext();
return ctx;
}

Expand Down
File renamed without changes.
File renamed without changes.
Loading

0 comments on commit 8839e04

Please sign in to comment.