Skip to content

Commit

Permalink
Merge pull request #17 from trcwm/master
Browse files Browse the repository at this point in the history
Added superficial FPS support
  • Loading branch information
trcwm authored Sep 28, 2017
2 parents cb86496 + bba28c0 commit 654debe
Show file tree
Hide file tree
Showing 17 changed files with 258 additions and 36 deletions.
10 changes: 7 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,13 @@
cmake_minimum_required(VERSION 3.1)
project (openpnp-capture)

set(POSITION_INDEPENDENT_CODE TRUE)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
# make sure the libjpegturbo is compiled with the
# position independent flag -fPIC
IF (UNIX)
set(POSITION_INDEPENDENT_CODE TRUE)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
ENDIF()

# make CMAKE search the current cmake dir inside the
# current project
Expand Down
21 changes: 20 additions & 1 deletion common/context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,8 @@ int32_t Context::openStream(CapDeviceID id, CapFormatID formatID)

if (!s->open(this, device, device->m_formats[formatID].width,
device->m_formats[formatID].height,
device->m_formats[formatID].fourcc))
device->m_formats[formatID].fourcc,
device->m_formats[formatID].fps))
{
LOG(LOG_ERR, "Could not open stream for device %s\n", device->m_name.c_str());
return -1;
Expand Down Expand Up @@ -267,6 +268,24 @@ uint32_t Context::getStreamFrameCount(int32_t streamID)
return stream->getFrameCount();
}

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

Stream *stream = m_streams[streamID];
if (stream == nullptr)
{
LOG(LOG_ERR, "setStreamFrameRate was called with an unknown stream ID\n");
return false;
}

return stream->setFrameRate(fps);
}

#if 0
/** Lookup a stream by ID and return a pointer
to it if it exists. If it doesnt exist,
Expand Down
5 changes: 5 additions & 0 deletions common/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,11 @@ class Context
/** returns the number of frames captured during the lifetime of the stream */
uint32_t getStreamFrameCount(int32_t streamID);

/** set the frame rate of a stream
returns false if the camera does not support the frame rate
*/
bool setStreamFrameRate(int32_t streamID, uint32_t fps);

/** Get the minimum and maximum settings for a property.
@param streamID the ID of the stream.
@param propertyID the ID of the property.
Expand Down
19 changes: 19 additions & 0 deletions common/libmain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,25 @@ DLLPUBLIC uint32_t Cap_getStreamFrameCount(CapContext ctx, CapStream stream)
return 0;
}

#if 0

// not used for now..

DLLPUBLIC CapResult Cap_setFrameRate(CapContext ctx, CapStream stream, uint32_t fps)
{
if (ctx != 0)
{
Context *c = reinterpret_cast<Context*>(ctx);
if (!c->setStreamFrameRate(stream, fps))
{
return CAPRESULT_ERR;
}
return CAPRESULT_OK;
}
return CAPRESULT_ERR;
}
#endif

DLLPUBLIC CapResult Cap_getPropertyLimits(CapContext ctx, CapStream stream, CapPropertyID propID, int32_t *min, int32_t *max)
{
if (ctx != 0)
Expand Down
9 changes: 8 additions & 1 deletion common/stream.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ class Stream
/** Open a capture stream to a device and request a specific (internal) stream format.
When succesfully opened, capturing starts immediately.
*/
virtual bool open(Context *owner, deviceInfo *device, uint32_t width, uint32_t height, uint32_t fourCC) = 0;
virtual bool open(Context *owner, deviceInfo *device, uint32_t width, uint32_t height,
uint32_t fourCC, uint32_t fps) = 0;

/** Close a capture stream */
virtual void close() {};
Expand All @@ -64,6 +65,12 @@ class Stream
*/
bool captureFrame(uint8_t *RGBbufferPtr, uint32_t RGBbufferBytes);

/** Set the frame rate of this stream.
Returns false if the camera does not support the desired
frame rate.
*/
virtual bool setFrameRate(uint32_t fps) = 0;

/** Returns true if the stream is open and capturing */
bool isOpen() const
{
Expand Down
1 change: 0 additions & 1 deletion include/openpnp-capture.h
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,6 @@ DLLPUBLIC CapResult Cap_closeStream(CapContext ctx, CapStream stream);
*/
DLLPUBLIC uint32_t Cap_isOpenStream(CapContext ctx, CapStream stream);


/**********************************************************************************
FRAME CAPTURING / INFO
**********************************************************************************/
Expand Down
33 changes: 33 additions & 0 deletions linux/platformcontext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,9 @@ bool PlatformContext::enumerateDevices()
uint32_t index = 0;
fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

// FIXME: add FPS information
// https://linuxtv.org/downloads/v4l-dvb-apis/uapi/v4l/vidioc-enum-frameintervals.html

bool tryMore = true;
while(tryMore)
{
Expand All @@ -137,6 +140,7 @@ bool PlatformContext::enumerateDevices()
while(queryFrameSize(fd, frmindex, fmtdesc.pixelformat, &cinfo.width, &cinfo.height))
{
frmindex++;
cinfo.fps = findMaxFrameRate(fd, fmtdesc.pixelformat, cinfo.width, cinfo.height);
dinfo->m_formats.push_back(cinfo);
LOG(LOG_INFO, " %d x %d\n", cinfo.width, cinfo.height);
}
Expand Down Expand Up @@ -171,7 +175,36 @@ bool PlatformContext::queryFrameSize(int fd, uint32_t index, uint32_t pixelforma
*width = 0;
*height = 0;
}

return true;
}
return false;
}

uint32_t PlatformContext::findMaxFrameRate(int fd, uint32_t pixelformat,
uint32_t width, uint32_t height)
{
uint32_t fps = 0;

// now search the frame rates
v4l2_frmivalenum ivals;
ivals.pixel_format = pixelformat;
ivals.width = width;
ivals.height = height;
ivals.index = 0;
while (ioctl(fd, VIDIOC_ENUM_FRAMEINTERVALS, &ivals) != -1)
{
if (ivals.type == V4L2_FRMIVAL_TYPE_DISCRETE)
{
LOG(LOG_INFO," FPS %d/%d", ivals.discrete.denominator, ivals.discrete.numerator);
uint32_t v = ivals.discrete.denominator/ivals.discrete.numerator;
if (fps < v)
{
fps = v;
}
}
ivals.index++;
}

return fps;
}
2 changes: 2 additions & 0 deletions linux/platformcontext.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ class PlatformContext : public Context
protected:
bool queryFrameSize(int fd, uint32_t index, uint32_t pixelformat, uint32_t *width, uint32_t *height);

uint32_t findMaxFrameRate(int fd, uint32_t pixelformat, uint32_t width, uint32_t height);

/** Enumerate V4L capture devices and put their
information into the m_devices array
Expand Down
79 changes: 71 additions & 8 deletions linux/platformstream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ void captureThreadFunction(PlatformStream *stream, int fd, size_t bufferSizeByte
void captureThreadFunctionAsync(PlatformStream *stream, int fd, size_t bufferSizeBytes)
{
//https://linuxtv.org/downloads/v4l-dvb-apis/uapi/v4l/capture.c.html
const uint32_t nBuffers = 5;
const uint32_t nBuffers = 8;

if (stream == nullptr)
{
Expand Down Expand Up @@ -255,7 +255,7 @@ void captureThreadFunctionAsync(PlatformStream *stream, int fd, size_t bufferSiz
FD_SET(fd, &fds);

/* Timeout. */
tv.tv_sec = 2;
tv.tv_sec = 5;
tv.tv_usec = 0;

result = select(fd + 1, &fds, NULL, NULL, &tv);
Expand Down Expand Up @@ -348,8 +348,6 @@ void PlatformStream::close()
m_isOpen = false;
m_quitThread = true;

::close(m_deviceHandle);

if (m_helperThread != nullptr)
{
m_helperThread->join();
Expand All @@ -359,6 +357,8 @@ void PlatformStream::close()
m_helperThread = nullptr;
}

::close(m_deviceHandle);

m_deviceHandle = -1;
}

Expand All @@ -367,7 +367,7 @@ void test(size_t bufferSizeBytes)

}

bool PlatformStream::open(Context *owner, deviceInfo *device, uint32_t width, uint32_t height, uint32_t fourCC)
bool PlatformStream::open(Context *owner, deviceInfo *device, uint32_t width, uint32_t height, uint32_t fourCC, uint32_t fps)
{
if (m_isOpen)
{
Expand Down Expand Up @@ -452,13 +452,14 @@ bool PlatformStream::open(Context *owner, deviceInfo *device, uint32_t width, ui
LOG(LOG_INFO, "Width = %d pixels\n", m_fmt.fmt.pix.width);
LOG(LOG_INFO, "Height = %d pixels\n", m_fmt.fmt.pix.height);
LOG(LOG_INFO, "FOURCC = %s\n", fourCCToString(m_fmt.fmt.pix.pixelformat).c_str());
LOG(LOG_INFO, "FPS = %d\n", fps);

// set the desired frame rate
v4l2_streamparm sparam;
CLEAR(sparam);
sparam.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
sparam.parm.capture.timeperframe.numerator = 1;
sparam.parm.capture.timeperframe.denominator = 10;
sparam.parm.capture.timeperframe.denominator = fps;
if (xioctl(m_deviceHandle, VIDIOC_S_PARM, &sparam) == -1)
{
LOG(LOG_CRIT, "Could not set the frame rate (errno = %d)\n", errno);
Expand Down Expand Up @@ -563,6 +564,25 @@ void PlatformStream::threadSubmitBuffer(void *ptr, size_t bytes)
}
}

bool PlatformStream::setFrameRate(uint32_t fps)
{
struct v4l2_streamparm param;
CLEAR(param);

param.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

param.parm.capture.timeperframe.numerator = 1;
param.parm.capture.timeperframe.denominator = fps;

if (xioctl(m_deviceHandle, VIDIOC_S_PARM, &param) == -1)
{
LOG(LOG_ERR,"setFrameRate failed on VIDIOC_S_PARM (errno %d)\n", errno);
return false;
}

return true;
}

uint32_t PlatformStream::getFOURCC()
{
if (m_isOpen)
Expand Down Expand Up @@ -594,6 +614,18 @@ bool PlatformStream::setProperty(uint32_t propID, int32_t value)
case CAPPROPID_WHITEBALANCE:
ctrl.id = V4L2_CID_WHITE_BALANCE_TEMPERATURE;
break;
case CAPPROPID_BRIGHTNESS:
ctrl.id = V4L2_CID_BRIGHTNESS;
break;
case CAPPROPID_CONTRAST:
ctrl.id = V4L2_CID_CONTRAST;
break;
case CAPPROPID_SATURATION:
ctrl.id = V4L2_CID_SATURATION;
break;
case CAPPROPID_GAMMA:
ctrl.id = V4L2_CID_GAMMA;
break;
default:
return false;
}
Expand Down Expand Up @@ -630,6 +662,10 @@ bool PlatformStream::setAutoProperty(uint32_t propID, bool enabled)
ctrl.id = V4L2_CID_AUTO_WHITE_BALANCE;
ctrl.value = enabled ? 1:0;
break;
case CAPPROPID_GAIN:
ctrl.id = V4L2_CID_AUTOGAIN;
ctrl.value = enabled ? 1:0;
break;
default:
return false;
}
Expand Down Expand Up @@ -665,7 +701,19 @@ bool PlatformStream::getPropertyLimits(uint32_t propID, int32_t *emin, int32_t *
break;
case CAPPROPID_WHITEBALANCE:
ctrl.id = V4L2_CID_WHITE_BALANCE_TEMPERATURE;
break;
break;
case CAPPROPID_BRIGHTNESS:
ctrl.id = V4L2_CID_BRIGHTNESS;
break;
case CAPPROPID_CONTRAST:
ctrl.id = V4L2_CID_CONTRAST;
break;
case CAPPROPID_SATURATION:
ctrl.id = V4L2_CID_SATURATION;
break;
case CAPPROPID_GAMMA:
ctrl.id = V4L2_CID_GAMMA;
break;
default:
return false;
}
Expand Down Expand Up @@ -698,7 +746,19 @@ bool PlatformStream::getProperty(uint32_t propID, int32_t &value)
break;
case CAPPROPID_WHITEBALANCE:
ctrl.id = V4L2_CID_WHITE_BALANCE_TEMPERATURE;
break;
break;
case CAPPROPID_BRIGHTNESS:
ctrl.id = V4L2_CID_BRIGHTNESS;
break;
case CAPPROPID_CONTRAST:
ctrl.id = V4L2_CID_CONTRAST;
break;
case CAPPROPID_SATURATION:
ctrl.id = V4L2_CID_SATURATION;
break;
case CAPPROPID_GAMMA:
ctrl.id = V4L2_CID_GAMMA;
break;
default:
return false;
}
Expand Down Expand Up @@ -730,6 +790,9 @@ bool PlatformStream::getAutoProperty(uint32_t propID, bool &enabled)
case CAPPROPID_WHITEBALANCE:
ctrl.id = V4L2_CID_AUTO_WHITE_BALANCE;
break;
case CAPPROPID_GAIN:
ctrl.id = V4L2_CID_AUTOGAIN;
break;
default:
return false;
}
Expand Down
5 changes: 4 additions & 1 deletion linux/platformstream.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@ class PlatformStream : public Stream
/** Open a capture stream to a device and request a specific (internal) stream format.
When succesfully opened, capturing starts immediately.
*/
virtual bool open(Context *owner, deviceInfo *device, uint32_t width, uint32_t height, uint32_t fourCC) override;
virtual bool open(Context *owner, deviceInfo *device, uint32_t width, uint32_t height,
uint32_t fourCC, uint32_t fps) override;

/** Close a capture stream */
virtual void close() override;
Expand All @@ -113,6 +114,8 @@ class PlatformStream : public Stream
virtual bool getProperty(uint32_t propID, int32_t &value) override;
virtual bool getAutoProperty(uint32_t propID, bool &enabled) override;

virtual bool setFrameRate(uint32_t fps) override;

/** called by the capture thread/function to query if it
should quit */
bool getThreadQuitState() const
Expand Down
Loading

0 comments on commit 654debe

Please sign in to comment.